From 9bc4373d454885d3b2fc4fa0091c70ae9f1c09ab Mon Sep 17 00:00:00 2001 From: Hossein Mehrabi Date: Tue, 5 Sep 2023 20:27:43 +0330 Subject: [PATCH] refactor: use LsdUtils's breakpoint method instead of @media query breakpoints --- src/components/Article/Article.Body.tsx | 3 - src/components/Article/Article.Heading.tsx | 3 +- .../Article/Footer/Article.Footer.tsx | 3 +- .../Article/Header/Article.Header.tsx | 9 +-- src/components/Episode/Episode.Body.tsx | 3 +- src/components/Episode/Episode.Stats.tsx | 3 +- .../Episode/Footer/Episode.Footer.tsx | 3 +- .../Episode/Header/Episode.Channels.tsx | 5 +- src/components/Footer/Footer.BuPanel.tsx | 11 ++-- src/components/Footer/Footer.Copyright.tsx | 3 +- src/components/Footer/Footer.OrgPanel.tsx | 3 +- src/components/Footer/Footer.Section.tsx | 3 +- .../GlobalAudioPlayer/GlobalAudioPlayer.tsx | 13 +++-- src/components/Grid/Grid.tsx | 2 +- src/components/Hero/Hero.tags.tsx | 3 - src/components/Hero/Hero.tsx | 8 ++- .../LpePlayer/Controls/Controls.tsx | 7 ++- src/components/Main/Main.tsx | 3 +- src/components/NavBar/NavBar.tsx | 8 +-- src/components/NavBar/Navbar.Links.tsx | 5 +- src/components/NavBar/Navbar.MobileMenu.tsx | 3 +- .../NavBar/Navbar.SocialMediaKit.tsx | 3 +- src/components/Podcasts/PodcastShowCard.tsx | 8 ++- src/components/Podcasts/Podcasts.Lists.tsx | 15 ++--- .../PostCard/PostCard.ShowDetails.tsx | 9 +-- src/components/PostList/PostList.tsx | 3 +- .../RelatedArticles/RelatedArticles.tsx | 3 +- .../TableOfContents/TableOfContents.tsx | 3 +- src/containers/ArticleContainer.tsx | 9 ++- src/layouts/SearchLayout/Search.layout.tsx | 3 +- src/utils/lsd.utils.ts | 55 ++++++++++++++++--- 31 files changed, 137 insertions(+), 78 deletions(-) diff --git a/src/components/Article/Article.Body.tsx b/src/components/Article/Article.Body.tsx index 1646144..e9f11a0 100644 --- a/src/components/Article/Article.Body.tsx +++ b/src/components/Article/Article.Body.tsx @@ -26,7 +26,4 @@ const ArticleContainer = styled.article` gap: 16px; max-width: 700px; padding-bottom: 80px; - - @media (min-width: 768px) and (max-width: 1200px) { - } ` diff --git a/src/components/Article/Article.Heading.tsx b/src/components/Article/Article.Heading.tsx index 30e223d..9796264 100644 --- a/src/components/Article/Article.Heading.tsx +++ b/src/components/Article/Article.Heading.tsx @@ -8,6 +8,7 @@ import { Typography, TypographyProps } from '@acid-info/lsd-react' import styled from '@emotion/styled' import { PropsWithChildren } from 'react' import { LPE } from '../../types/lpe.types' +import { lsdUtils } from '../../utils/lsd.utils' type Props = PropsWithChildren<{ block: LPE.Article.TextBlock @@ -50,7 +51,7 @@ const Headline = styled(Typography)` white-space: pre-wrap; margin-top: 16px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { &.title { font-size: var(--lsd-h4-fontSize); line-height: var(--lsd-h4-lineHeight); diff --git a/src/components/Article/Footer/Article.Footer.tsx b/src/components/Article/Footer/Article.Footer.tsx index d759a89..fd0291d 100644 --- a/src/components/Article/Footer/Article.Footer.tsx +++ b/src/components/Article/Footer/Article.Footer.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled' import { useMemo } from 'react' import { LPE } from '../../../types/lpe.types' +import { lsdUtils } from '../../../utils/lsd.utils' import ArticleFootnotes from './Article.Footnotes' import FromSameAuthorsArticles from './Article.FromSameAuthorsArticles' import ArticleRelatedArticles from './Article.RelatedArticles' @@ -32,7 +33,7 @@ const ArticleFooterContainer = styled.div` border-top: none; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 72px; } ` diff --git a/src/components/Article/Header/Article.Header.tsx b/src/components/Article/Header/Article.Header.tsx index 3057ef2..a4f3e66 100644 --- a/src/components/Article/Header/Article.Header.tsx +++ b/src/components/Article/Header/Article.Header.tsx @@ -7,6 +7,7 @@ import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' import { ArticleBlocksOrders } from '../../../configs/data.configs' import { LPE } from '../../../types/lpe.types' +import { lsdUtils } from '../../../utils/lsd.utils' import { ArticleImageBlockWrapper } from '../Article.ImageBlockWrapper' import ArticleStats from '../Article.Stats' import ArticleSummary from './Article.Summary' @@ -78,7 +79,7 @@ const ArticleHeaderContainer = styled.header` display: block; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { .mobileSummary { display: block; p { @@ -105,7 +106,7 @@ const CustomTypography = styled(Typography)` const ArticleTitle = styled(ArticleHeading)` margin-bottom: 16px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-bottom: 8px; } ` @@ -113,7 +114,7 @@ const ArticleTitle = styled(ArticleHeading)` const ArticleSubtitle = styled(CustomTypography)` margin-bottom: 16px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { font-size: var(--lsd-subtitle1-fontSize); } ` @@ -123,7 +124,7 @@ const AuthorsContainer = styled.div` margin-top: 24px; margin-bottom: 32px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 16px; margin-bottom: 24px; diff --git a/src/components/Episode/Episode.Body.tsx b/src/components/Episode/Episode.Body.tsx index f946b6c..97d995f 100644 --- a/src/components/Episode/Episode.Body.tsx +++ b/src/components/Episode/Episode.Body.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled' import { useHookstate } from '@hookstate/core' import { LPE } from '../../types/lpe.types' +import { lsdUtils } from '../../utils/lsd.utils' import { playerState } from '../GlobalAudioPlayer/globalAudioPlayer.state' import EpisodeTranscript from './Episode.Transcript' import EpisodeFooter from './Footer/Episode.Footer' @@ -41,7 +42,7 @@ const EpisodeContainer = styled.article` flex-direction: column; max-width: 696px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 32px; } ` diff --git a/src/components/Episode/Episode.Stats.tsx b/src/components/Episode/Episode.Stats.tsx index 1c0f8de..f9bf790 100644 --- a/src/components/Episode/Episode.Stats.tsx +++ b/src/components/Episode/Episode.Stats.tsx @@ -1,5 +1,6 @@ import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' +import { lsdUtils } from '../../utils/lsd.utils' const EpisodeStats = ({ date, @@ -32,7 +33,7 @@ const Row = styled.div` margin-bottom: 12px; margin-top: 32px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 24px; } ` diff --git a/src/components/Episode/Footer/Episode.Footer.tsx b/src/components/Episode/Footer/Episode.Footer.tsx index e368ac3..b0acc5e 100644 --- a/src/components/Episode/Footer/Episode.Footer.tsx +++ b/src/components/Episode/Footer/Episode.Footer.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled' import { useMemo } from 'react' import { LPE } from '../../../types/lpe.types' +import { lsdUtils } from '../../../utils/lsd.utils' import EpisodeCredits from './Episode.Credits' import EpisodeFootnotes from './Episode.Footnotes' import RelatedEpisodes from './Episode.RelatedEpisodes' @@ -43,7 +44,7 @@ const EpisodeFooterContainer = styled.div` border-top: none; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 72px; } ` diff --git a/src/components/Episode/Header/Episode.Channels.tsx b/src/components/Episode/Header/Episode.Channels.tsx index 7654040..49e32c2 100644 --- a/src/components/Episode/Header/Episode.Channels.tsx +++ b/src/components/Episode/Header/Episode.Channels.tsx @@ -5,6 +5,7 @@ import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' import Link from 'next/link' import { LPE } from '../../../types/lpe.types' +import { lsdUtils } from '../../../utils/lsd.utils' export type EpisodeChannelProps = { channels: LPE.Podcast.Channel[] @@ -53,7 +54,7 @@ const EpisodeChannelContainer = styled.div` margin-top: 32px; margin-bottom: 32px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 24px; } ` @@ -66,7 +67,7 @@ const Channel = styled(Link)` ` const ChannelName = styled(Typography)` - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { font-size: var(--lsd-body3-fontSize) !important; line-height: var(--lsd-body3-lineHeight) !important; } diff --git a/src/components/Footer/Footer.BuPanel.tsx b/src/components/Footer/Footer.BuPanel.tsx index da463ad..f35360d 100644 --- a/src/components/Footer/Footer.BuPanel.tsx +++ b/src/components/Footer/Footer.BuPanel.tsx @@ -3,6 +3,7 @@ import { FooterSection } from '@/components/Footer/Footer.Section' import { FooterLinksItems } from '@/configs/data.configs' import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' +import { lsdUtils } from '../../utils/lsd.utils' export const FooterBuPanel = () => { return ( @@ -68,14 +69,14 @@ const BusinessUnits = styled.div` display: flex; align-items: baseline; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { flex-direction: column; margin-top: 72px; } ` const BUInfo = styled(FooterSection)` - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-bottom: 76px; } ` @@ -85,7 +86,7 @@ const BUs = styled(FooterSection)` flex-direction: row; gap: 8px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { flex-direction: column; } ` @@ -103,7 +104,7 @@ const BusinessUnitItemGroup = styled.div` grid-area: 1 / 1 / 2 / 2; } - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { grid-template-columns: repeat(1, 1fr); padding-bottom: 24px; } @@ -115,7 +116,7 @@ const LinkGroup = styled.div` margin-bottom: 34px; gap: 4px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-bottom: 24px; } ` diff --git a/src/components/Footer/Footer.Copyright.tsx b/src/components/Footer/Footer.Copyright.tsx index c9ab04d..ddcd43d 100644 --- a/src/components/Footer/Footer.Copyright.tsx +++ b/src/components/Footer/Footer.Copyright.tsx @@ -2,6 +2,7 @@ import { FooterSection } from '@/components/Footer/Footer.Section' import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' import { siteConfigs } from '../../configs/site.configs' +import { lsdUtils } from '../../utils/lsd.utils' export const FooterCopyright = () => ( @@ -15,7 +16,7 @@ export const FooterCopyright = () => ( ) const OrgInfo = styled(FooterSection)` - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-bottom: 72px; } ` diff --git a/src/components/Footer/Footer.OrgPanel.tsx b/src/components/Footer/Footer.OrgPanel.tsx index 33dee59..468a853 100644 --- a/src/components/Footer/Footer.OrgPanel.tsx +++ b/src/components/Footer/Footer.OrgPanel.tsx @@ -3,6 +3,7 @@ import { FooterLink } from '@/components/Footer/Footer.Link' import { FooterSection } from '@/components/Footer/Footer.Section' import { FooterLinksItems } from '@/configs/data.configs' import styled from '@emotion/styled' +import { lsdUtils } from '../../utils/lsd.utils' export const FooterOrgPanel = () => { return ( @@ -35,7 +36,7 @@ const Wrapper = styled.div` border-top: 1px solid rgb(var(--lsd-theme-primary)); padding-top: 16px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { flex-direction: column; } ` diff --git a/src/components/Footer/Footer.Section.tsx b/src/components/Footer/Footer.Section.tsx index b0ae6de..c8925dd 100644 --- a/src/components/Footer/Footer.Section.tsx +++ b/src/components/Footer/Footer.Section.tsx @@ -1,5 +1,6 @@ import { uiConfigs } from '@/configs/ui.configs' import styled from '@emotion/styled' +import { lsdUtils } from '../../utils/lsd.utils' export const FooterSection = styled.div` display: flex; @@ -7,7 +8,7 @@ export const FooterSection = styled.div` flex-wrap: wrap; width: 50%; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { width: 100%; } ` diff --git a/src/components/GlobalAudioPlayer/GlobalAudioPlayer.tsx b/src/components/GlobalAudioPlayer/GlobalAudioPlayer.tsx index 2cf24cc..4172e90 100644 --- a/src/components/GlobalAudioPlayer/GlobalAudioPlayer.tsx +++ b/src/components/GlobalAudioPlayer/GlobalAudioPlayer.tsx @@ -6,6 +6,7 @@ import Image from 'next/image' import Link from 'next/link' import React, { useEffect, useRef } from 'react' import ReactPlayer from 'react-player' +import { lsdUtils } from '../../utils/lsd.utils' import { PlayerType } from '../LpePlayer/Controls/Controls' import { episodeState } from './episode.state' import { playerState } from './globalAudioPlayer.state' @@ -208,13 +209,13 @@ const Container = styled.div<{ visible: boolean }>` > :first-child { width: 60%; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { overflow: hidden; white-space: nowrap; } } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { padding: 10px 16px; > :first-child { @@ -229,7 +230,7 @@ const RightMenu = styled.div` justify-content: flex-end; margin-left: 32px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { width: fit-content; margin-left: auto; } @@ -247,7 +248,7 @@ const EpisodeData = styled(Link)` white-space: nowrap; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none !important; } ` @@ -255,7 +256,7 @@ const EpisodeData = styled(Link)` const Thumbnail = styled(Image)` margin-right: 16px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none !important; } ` @@ -263,7 +264,7 @@ const Thumbnail = styled(Image)` const CloseIconContainer = styled.div` margin-left: 43px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-left: 16px; } ` diff --git a/src/components/Grid/Grid.tsx b/src/components/Grid/Grid.tsx index 06646cb..44092e3 100644 --- a/src/components/Grid/Grid.tsx +++ b/src/components/Grid/Grid.tsx @@ -84,7 +84,7 @@ export const GridItem = styled.div` grid-column: span 16; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { grid-column: span 16 !important; } diff --git a/src/components/Hero/Hero.tags.tsx b/src/components/Hero/Hero.tags.tsx index 261f0eb..bbda3cf 100644 --- a/src/components/Hero/Hero.tags.tsx +++ b/src/components/Hero/Hero.tags.tsx @@ -25,9 +25,6 @@ const Container = styled.div` text-align: center; display: flex; overflow: hidden; - - @media (max-width: 768px) { - } ` const Tags = styled.div` diff --git a/src/components/Hero/Hero.tsx b/src/components/Hero/Hero.tsx index 0ea4a43..6745371 100644 --- a/src/components/Hero/Hero.tsx +++ b/src/components/Hero/Hero.tsx @@ -6,6 +6,7 @@ import { useEffect, useRef } from 'react' import { useWindowScroll } from 'react-use' import { uiConfigs } from '../../configs/ui.configs' import { useNavbarState } from '../../states/navbarState' +import { lsdUtils } from '../../utils/lsd.utils' export type HeroProps = Partial> & { tags?: string[] @@ -53,7 +54,7 @@ const Container = styled.div` position: relative; padding: 24px 16px 40px 16px; - @media (max-width: ${(props) => props.theme.breakpoints.md.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'down')} { padding: 8px 0 16px 0; } ` @@ -62,7 +63,8 @@ const Title = styled(Typography)` text-align: center; text-transform: uppercase; padding: 0 var(--main-content-padding); - @media (max-width: ${(props) => props.theme.breakpoints.md.width}px) { + + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'down')} { font-size: var(--lsd-h4-fontSize) !important; font-weight: var(--lsd-h4-fontWeight) !important; line-height: var(--lsd-h4-lineHeight) !important; @@ -75,7 +77,7 @@ const Description = styled(Typography)` text-transform: capitalize; padding: 0 var(--main-content-padding); - @media (max-width: ${(props) => props.theme.breakpoints.md.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'down')} { font-size: 12px !important; font-weight: 400 !important; line-height: 16px !important; diff --git a/src/components/LpePlayer/Controls/Controls.tsx b/src/components/LpePlayer/Controls/Controls.tsx index e8ea4ce..fcbc825 100644 --- a/src/components/LpePlayer/Controls/Controls.tsx +++ b/src/components/LpePlayer/Controls/Controls.tsx @@ -10,6 +10,7 @@ import { import { convertSecToMinAndSec } from '@/utils/string.utils' import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' +import { lsdUtils } from '../../../utils/lsd.utils' export enum PlayerType { GLOBAL = 'global', @@ -148,7 +149,7 @@ const TimeContainer = styled(Row)<{ color: string; isHidden: boolean }>` color: ${({ color }) => color || 'black'}; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: ${({ isHidden }) => (isHidden ? 'none' : 'flex')}; } ` @@ -165,7 +166,7 @@ const Metadata = styled.div` overflow: hidden; text-overflow: ellipsis; - @media (min-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none; } ` @@ -181,7 +182,7 @@ const Podcast = styled(Typography)` ` const Volume = styled(Row)<{ isHidden: boolean }>` - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: ${({ isHidden }) => (isHidden ? 'none' : 'flex')}; } ` diff --git a/src/components/Main/Main.tsx b/src/components/Main/Main.tsx index 429a049..862c025 100644 --- a/src/components/Main/Main.tsx +++ b/src/components/Main/Main.tsx @@ -1,5 +1,6 @@ import { uiConfigs } from '@/configs/ui.configs' import styled from '@emotion/styled' +import { lsdUtils } from '../../utils/lsd.utils' export type MainProps = Partial> & {} @@ -35,7 +36,7 @@ const Container = styled.main<{ ${(props) => (props.contentPadding ? `var(--main-content-padding)` : '0')}; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { --main-margin-top: ${({ spacing }) => spacing ? uiConfigs.postSectionMobileMargin diff --git a/src/components/NavBar/NavBar.tsx b/src/components/NavBar/NavBar.tsx index 7e91e51..84387f1 100644 --- a/src/components/NavBar/NavBar.tsx +++ b/src/components/NavBar/NavBar.tsx @@ -116,7 +116,7 @@ const PressLogoType = styled(Typography)<{ display: boolean }>` ` const SocialMediaKitContainer = styled.div` - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none; } ` @@ -198,7 +198,7 @@ const NavLinksContainer = styled.div` flex: 1; justify-content: center; - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none !important; } ` @@ -210,7 +210,7 @@ const LeftContainer = styled(Link)` left: 0; display: flex; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { position: relative; } ` @@ -230,7 +230,7 @@ const ControlsContainer = styled.div` display: none; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { .theme-switch { // hide theme switch display: none; diff --git a/src/components/NavBar/Navbar.Links.tsx b/src/components/NavBar/Navbar.Links.tsx index 76ee0f4..57bf4dc 100644 --- a/src/components/NavBar/Navbar.Links.tsx +++ b/src/components/NavBar/Navbar.Links.tsx @@ -2,6 +2,7 @@ import { Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' import Link from 'next/link' import { useRouter } from 'next/router' +import { lsdUtils } from '../../utils/lsd.utils' interface Props { links: { href: string; label: string }[] @@ -56,7 +57,7 @@ const Container = styled.div` margin: 0 20px; } - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { flex-direction: column; align-items: flex-start; justify-content: flex-start; @@ -76,7 +77,7 @@ const Container = styled.div` ` const LinkText = styled(Typography)` - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { font-size: 20px; // LSD doesn't have this font size line-height: 28px; // LSD doesn't have this line height } diff --git a/src/components/NavBar/Navbar.MobileMenu.tsx b/src/components/NavBar/Navbar.MobileMenu.tsx index e371fa7..2ad1d50 100644 --- a/src/components/NavBar/Navbar.MobileMenu.tsx +++ b/src/components/NavBar/Navbar.MobileMenu.tsx @@ -6,6 +6,7 @@ import { uiConfigs } from '@/configs/ui.configs' import { useThemeState } from '@/states/themeState' import styled from '@emotion/styled' import { useEffect } from 'react' +import { lsdUtils } from '../../utils/lsd.utils' import { SocialMediaKit } from './Navbar.SocialMediaKit' interface Props {} @@ -48,7 +49,7 @@ const NavbarMobileMenuContainer = styled.div` background: rgb(var(--lsd-surface-primary)); overflow-y: auto; - @media (min-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'up')} { display: none; } ` diff --git a/src/components/NavBar/Navbar.SocialMediaKit.tsx b/src/components/NavBar/Navbar.SocialMediaKit.tsx index eafce92..1e5cbc8 100644 --- a/src/components/NavBar/Navbar.SocialMediaKit.tsx +++ b/src/components/NavBar/Navbar.SocialMediaKit.tsx @@ -5,6 +5,7 @@ import { FooterLinksItems } from '@/configs/data.configs' import { LPEFooterGroup } from '@/types/ui.types' import styled from '@emotion/styled' import Link from 'next/link' +import { lsdUtils } from '../../utils/lsd.utils' const socialLinks = FooterLinksItems.about.find( (item) => item.key === 'social', @@ -59,7 +60,7 @@ const Container = styled.div` ` const LinkContainer = styled.div` - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { width: fit-content; display: flex; diff --git a/src/components/Podcasts/PodcastShowCard.tsx b/src/components/Podcasts/PodcastShowCard.tsx index 8d3d565..3db3e6d 100644 --- a/src/components/Podcasts/PodcastShowCard.tsx +++ b/src/components/Podcasts/PodcastShowCard.tsx @@ -67,11 +67,15 @@ const ShowData = styled.div` const Description = styled(Typography)` margin-top: 16px; - @media (min-width: 768px) and (max-width: 1200px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'exact')} { margin-top: 12px; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'md', 'exact')} { + margin-top: 12px; + } + + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { text-align: center; margin-top: 8px; } diff --git a/src/components/Podcasts/Podcasts.Lists.tsx b/src/components/Podcasts/Podcasts.Lists.tsx index c5723da..380c432 100644 --- a/src/components/Podcasts/Podcasts.Lists.tsx +++ b/src/components/Podcasts/Podcasts.Lists.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled' import Image from 'next/image' import Link from 'next/link' import { LPE } from '../../types/lpe.types' +import { lsdUtils } from '../../utils/lsd.utils' import { getPostLink } from '../../utils/route.utils' import { Grid, GridItem } from '../Grid/Grid' import PodcastHost from './Podcast.Host' @@ -66,7 +67,7 @@ export default function PodcastsLists({ shows }: Props) { const PodcastListsContainer = styled(Grid)` gap: 16px; - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { flex-direction: column; gap: 24px 16px; } @@ -88,11 +89,11 @@ const ShowCard = styled(Link)<{ isEven: boolean }>` ? 'rgb(var(--lsd-surface-secondary))' : 'rgb(var(--lsd-surface-primary))'}; - @media (max-width: ${({ theme }) => theme.breakpoints.md.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'down')} { height: 420px; } - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { height: 374px; } ` @@ -101,7 +102,7 @@ const ShowInfoContainer = styled.div` display: flex; gap: 16px; - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { gap: 8px; } ` @@ -135,7 +136,7 @@ const ShowData = styled.div<{ isEven: boolean }>` : 'rgb(var(--lsd-text-primary))'}; } - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { margin-top: 57px; } ` @@ -151,7 +152,7 @@ const Description = styled(Typography)` font-size: var(--lsd-h4-fontSize); line-height: var(--lsd-h4-lineHeight); - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { font-size: var(--lsd-h6-fontSize); line-height: var(--lsd-h6-lineHeight); } @@ -181,7 +182,7 @@ const ShowButton = styled(Button)<{ isEven: boolean }>` transform: rotate(-90deg); } - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { padding: 7px; } ` diff --git a/src/components/PostCard/PostCard.ShowDetails.tsx b/src/components/PostCard/PostCard.ShowDetails.tsx index 07f6cfe..acc70e4 100644 --- a/src/components/PostCard/PostCard.ShowDetails.tsx +++ b/src/components/PostCard/PostCard.ShowDetails.tsx @@ -5,6 +5,7 @@ import styled from '@emotion/styled' import clsx from 'clsx' import Image from 'next/image' import Link from 'next/link' +import { lsdUtils } from '../../utils/lsd.utils' import { getPostLink } from '../../utils/route.utils' type Size = 'small' | 'medium' | 'large' @@ -145,28 +146,28 @@ const CustomLink = styled(Link)` } &.show-details { - @media (max-width: ${({ theme }) => theme.breakpoints.sm.width - 1}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { ${(props) => props.xsSize && props.applySizeStyles && PostCardShowDetails.styles[props.xsSize](props.theme)} } - @media (min-width: ${({ theme }) => theme.breakpoints.sm.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'up')} { ${(props) => props.smSize && props.applySizeStyles && PostCardShowDetails.styles[props.smSize](props.theme)} } - @media (min-width: ${({ theme }) => theme.breakpoints.md.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'md', 'up')} { ${(props) => props.mdSize && props.applySizeStyles && PostCardShowDetails.styles[props.mdSize](props.theme)} } - @media (min-width: ${({ theme }) => theme.breakpoints.lg.width}px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'lg', 'up')} { ${(props) => props.lgSize && props.applySizeStyles && diff --git a/src/components/PostList/PostList.tsx b/src/components/PostList/PostList.tsx index 8969958..e030f53 100644 --- a/src/components/PostList/PostList.tsx +++ b/src/components/PostList/PostList.tsx @@ -4,6 +4,7 @@ import { Button, Typography } from '@acid-info/lsd-react' import styled from '@emotion/styled' import { useEffect, useState } from 'react' import { LPE } from '../../types/lpe.types' +import { lsdUtils } from '../../utils/lsd.utils' import { Grid, GridItem } from '../Grid/Grid' import PostTypes = LPE.PostTypes @@ -90,7 +91,7 @@ export const PostsList = (props: Props) => { const CustomGrid = styled(Grid)` min-height: 500px; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { gap: 8px; min-height: auto; } diff --git a/src/components/RelatedArticles/RelatedArticles.tsx b/src/components/RelatedArticles/RelatedArticles.tsx index af4f326..a12bf57 100644 --- a/src/components/RelatedArticles/RelatedArticles.tsx +++ b/src/components/RelatedArticles/RelatedArticles.tsx @@ -2,6 +2,7 @@ import { SearchResultsSection } from '@/components/SearchResultsSection/SearchRe import { SearchHook } from '@/types/data.types' import styled from '@emotion/styled' import { LPE } from '../../types/lpe.types' +import { lsdUtils } from '../../utils/lsd.utils' import { PostsList } from '../PostList/PostList' type Props = { @@ -36,7 +37,7 @@ const Container = styled.div` flex-direction: column; align-items: center; - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { align-items: flex-start; } ` diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index 64da99b..8b4ff8f 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -7,6 +7,7 @@ import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect } from 'react' import { LPE } from '../../types/lpe.types' +import { lsdUtils } from '../../utils/lsd.utils' type Props = { contents?: LPE.Article.TocItem[] @@ -79,7 +80,7 @@ const Container = styled.aside<{ dy: number; height: number }>` opacity: 0; } - @media (max-width: 776px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none; } ` diff --git a/src/containers/ArticleContainer.tsx b/src/containers/ArticleContainer.tsx index a221eba..5ef5650 100644 --- a/src/containers/ArticleContainer.tsx +++ b/src/containers/ArticleContainer.tsx @@ -5,6 +5,7 @@ import { ArticleContainerContext } from '@/containers/ArticleContainer.Context' import styled from '@emotion/styled' import { useState } from 'react' import { LPE } from '../types/lpe.types' +import { lsdUtils } from '../utils/lsd.utils' interface Props { data: LPE.Article.Document @@ -30,25 +31,23 @@ const ArticleContainer = (props: Props) => { } const ArticleBodyContainer = styled(GridItem)` - @media (min-width: 768px) and (max-width: 1200px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'between', 'lg')} { grid-column: span 10 !important; } ` const ArticleTocContainer = styled(GridItem)` - @media (min-width: 768px) and (max-width: 1200px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'sm', 'between', 'lg')} { grid-column: span 4 !important; } ` const ArticleGrid = styled(Grid)` width: 100%; - @media (min-width: 768px) and (max-width: 1200px) { - } ` const Gap = styled(GridItem)` - @media (max-width: 550px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { display: none; } ` diff --git a/src/layouts/SearchLayout/Search.layout.tsx b/src/layouts/SearchLayout/Search.layout.tsx index a2567df..7a30d98 100644 --- a/src/layouts/SearchLayout/Search.layout.tsx +++ b/src/layouts/SearchLayout/Search.layout.tsx @@ -4,6 +4,7 @@ import { uiConfigs } from '@/configs/ui.configs' import styled from '@emotion/styled' import { PropsWithChildren } from 'react' import { AppBar } from '../../components/NavBar' +import { lsdUtils } from '../../utils/lsd.utils' import styles from './Search.layout.module.css' export default function SearchLayout(props: PropsWithChildren) { @@ -23,7 +24,7 @@ const MainContainer = styled(Main)` // margin-top: ${uiConfigs.postSectionMargin}px; } - @media (max-width: 768px) { + ${(props) => lsdUtils.breakpoint(props.theme, 'xs', 'down')} { &.search_page { margin-top: ${uiConfigs.postSectionMobileMargin * 3}px; } diff --git a/src/utils/lsd.utils.ts b/src/utils/lsd.utils.ts index d4c0261..72c22ed 100644 --- a/src/utils/lsd.utils.ts +++ b/src/utils/lsd.utils.ts @@ -1,12 +1,47 @@ import { Breakpoints, - THEME_BREAKPOINTS, Theme, + THEME_BREAKPOINTS, TypographyVariants, } from '@acid-info/lsd-react' -import { SerializedStyles, css } from '@emotion/react' +import { css, SerializedStyles } from '@emotion/react' export class LsdUtils { + private _breakpoints: Record< + string, + Record + > = {} + + private getBreakpoints = (theme: Theme) => { + if (this._breakpoints[theme.name]) { + return this._breakpoints[theme.name] + } + + const breakpoints: (typeof this._breakpoints)[string] = {} + for (let i = 0; i < THEME_BREAKPOINTS.length; i++) { + const name = THEME_BREAKPOINTS[i] + const breakpoint = theme.breakpoints[name] + const next = theme.breakpoints[THEME_BREAKPOINTS[i + 1]] + + const min = breakpoint.width + const max = next ? next.width - 1 : Number.MAX_SAFE_INTEGER + + breakpoints[name] = { + min, + max, + } + } + + this._breakpoints[theme.name] = breakpoints + + return breakpoints + } + + private getBreakpoint = (theme: Theme, breakpoint: Breakpoints) => { + const breakpoints = this.getBreakpoints(theme) + return breakpoints[breakpoint] + } + breakpoints = (exclude: Breakpoints[] = []) => THEME_BREAKPOINTS.filter((b) => !exclude.find((b2) => b2 === b)) @@ -30,20 +65,22 @@ export class LsdUtils { breakpoint = ( theme: Theme, breakpoint: Breakpoints, - func: 'exact' | 'up' | 'down' = 'up', + func: 'exact' | 'up' | 'down' | 'between' = 'up', + next?: Breakpoints, ) => { - const width = theme.breakpoints[breakpoint].width - const idx = THEME_BREAKPOINTS.findIndex((b) => b === breakpoint) - const next = theme.breakpoints[THEME_BREAKPOINTS[idx + 1]] - const min = width - const max = next?.width ? next.width - 1 : Number.MAX_SAFE_INTEGER + const { min, max } = this.getBreakpoint(theme, breakpoint) let media = `@media ` if (func === 'up') { media += `(min-width: ${min}px)` } else if (func === 'down') media += `(max-width: ${max}px)` - else media += `(min-width: ${min}px) and (max-width: ${max}px)` + else if (func === 'between' && !!next) { + const nextBreakpoint = this.getBreakpoint(theme, next) + media += `(min-width: ${min}px) and (max-width: ${ + nextBreakpoint.min - 1 + }px)` + } else media += `(min-width: ${min}px) and (max-width: ${max}px)` return `${media}` }