From b2c6c84dcae95bd161d91e0e7bec6509d5b4d372 Mon Sep 17 00:00:00 2001 From: Kanav Arora Date: Sat, 24 Feb 2024 17:59:15 +0530 Subject: [PATCH 1/2] MQ Facepaint introduced --- package.json | 2 + .../app/_components/ui/layout/Breadcrumbs.tsx | 65 +++++++++---------- .../src/app/_components/ui/theme/mq.ts | 7 ++ .../user-guide/UserGuideContent.tsx | 29 ++++----- .../_components/user-guide/UserGuideMain.tsx | 63 +++++++----------- .../user-guide/UserGuideSidebar.tsx | 28 ++++---- .../user-guide/UserGuideTableContents.tsx | 22 ++++--- packages/twenty-website/src/app/layout.css | 6 ++ .../src/app/user-guide/layout.tsx | 19 ++---- yarn.lock | 16 +++++ 10 files changed, 132 insertions(+), 125 deletions(-) create mode 100644 packages/twenty-website/src/app/_components/ui/theme/mq.ts diff --git a/package.json b/package.json index df96524779da..bc80e5285ce5 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@stoplight/elements": "^8.0.5", "@swc/jest": "^0.2.29", "@tabler/icons-react": "^2.44.0", + "@types/facepaint": "^1.2.5", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.merge": "^4.6.7", "@types/mailparser": "^3.4.4", @@ -79,6 +80,7 @@ "dotenv-cli": "^7.2.1", "drizzle-orm": "^0.29.3", "esbuild-plugin-svgr": "^2.1.0", + "facepaint": "^1.2.1", "file-type": "16.5.4", "framer-motion": "^10.12.17", "googleapis": "105", diff --git a/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx b/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx index 0b90803e48d9..830049c7a379 100644 --- a/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx +++ b/packages/twenty-website/src/app/_components/ui/layout/Breadcrumbs.tsx @@ -5,16 +5,15 @@ import styled from '@emotion/styled'; import { IconChevronLeft } from '@tabler/icons-react'; import Link from 'next/link'; -import { - DeviceType, - useDeviceType, -} from '@/app/_components/client-utils/useDeviceType'; +import mq from '@/app/_components/ui/theme/mq'; import { Theme } from '@/app/_components/ui/theme/theme'; const Container = styled.div` - display: flex; - gap: ${Theme.spacing(2)}; - color: #b3b3b3; + ${mq({ + display: ['none', 'flex', 'flex'], + gap: `${Theme.spacing(2)}`, + color: '#b3b3b3', + })}; `; const InternalLinkItem = styled(Link)` @@ -45,12 +44,14 @@ const StyledSection = styled.div` `; const StyledMobileContainer = styled.div` - display: flex; - flex-direction: row; - align-items: center; - gap: ${Theme.spacing(1)}; - color: ${Theme.text.color.quarternary}; - font-size: ${Theme.font.size.sm}; + ${mq({ + display: ['flex', 'none', 'none'], + flexDirection: 'row', + alignItems: 'center', + gap: `${Theme.spacing(1)}`, + color: `${Theme.text.color.quarternary}`, + fontSize: `${Theme.font.size.sm}`, + })}; `; interface BreadcrumbsProps { @@ -68,31 +69,29 @@ export const Breadcrumbs = ({ activePage, separator, }: BreadcrumbsProps) => { - const isMobile = useDeviceType() === DeviceType.MOBILE; - if (isMobile) { - const lastItem = items[items.length - 1]; - return ( + const lastItem = items[items.length - 1]; + + return ( +
{lastItem.label} - ); - } - return ( - - {items.map((item, index) => ( - - {item.isExternal ? ( - {item.label} - ) : ( - {item.label} - )} -
{separator}
-
- ))} - {activePage} -
+ + {items.map((item, index) => ( + + {item.isExternal ? ( + {item.label} + ) : ( + {item.label} + )} +
{separator}
+
+ ))} + {activePage} +
+
); }; diff --git a/packages/twenty-website/src/app/_components/ui/theme/mq.ts b/packages/twenty-website/src/app/_components/ui/theme/mq.ts new file mode 100644 index 000000000000..7aefe8ba84c4 --- /dev/null +++ b/packages/twenty-website/src/app/_components/ui/theme/mq.ts @@ -0,0 +1,7 @@ +import facepaint from 'facepaint'; + +const breakpoints = [810, 1200]; + +const mq = facepaint(breakpoints.map((bp) => `@media (min-width: ${bp}px)`)); + +export default mq; diff --git a/packages/twenty-website/src/app/_components/user-guide/UserGuideContent.tsx b/packages/twenty-website/src/app/_components/user-guide/UserGuideContent.tsx index c5c15d3605a3..bac56089fdff 100644 --- a/packages/twenty-website/src/app/_components/user-guide/UserGuideContent.tsx +++ b/packages/twenty-website/src/app/_components/user-guide/UserGuideContent.tsx @@ -2,26 +2,20 @@ import React from 'react'; import styled from '@emotion/styled'; -import { - DeviceType, - useDeviceType, -} from '@/app/_components/client-utils/useDeviceType'; import { Breadcrumbs } from '@/app/_components/ui/layout/Breadcrumbs'; +import mq from '@/app/_components/ui/theme/mq'; import { Theme } from '@/app/_components/ui/theme/theme'; import { FileContent } from '@/app/_server-utils/get-posts'; -const StyledContainer = styled.div<{ devicetype: string }>` - width: ${({ devicetype }) => - devicetype === DeviceType.TABLET - ? '70%' - : devicetype === DeviceType.DESKTOP - ? '60%' - : '100%'}; - display: flex; - flex-direction: row; - justify-content: center; - font-family: ${Theme.font.family}; - border-bottom: 1px solid ${Theme.background.transparent.medium}; +const StyledContainer = styled('div')` + ${mq({ + width: ['100%', '70%', '60%'], + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + borderBottom: `1px solid ${Theme.background.transparent.medium}`, + fontFamily: `${Theme.font.family}`, + })}; `; const StyledWrapper = styled.div` @@ -74,9 +68,8 @@ export default function UserGuideContent({ item }: { item: FileContent }) { label: 'User Guide', }, ]; - const deviceType = useDeviceType(); return ( - + ` - width: ${({ isMobile }) => (isMobile ? '100%' : '60%')}; - display: flex; - flex-direction: row; - justify-content: center; +const StyledContainer = styled.div` + ${mq({ + width: ['100%', '60%', '60%'], + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + })}; `; const StyledWrapper = styled.div` @@ -46,27 +45,21 @@ const StyledSubHeading = styled.h1` color: ${Theme.text.color.tertiary}; `; -const StyledContentGrid = styled.div` - width: 100%; - padding-top: ${Theme.spacing(6)}; - display: grid; - grid-template-rows: auto auto; - grid-template-columns: auto auto; - gap: ${Theme.spacing(6)}; -`; - -const StyledContentFlex = styled.div` - width: 100%; - padding-top: ${Theme.spacing(6)}; - display: flex; - flex-direction: column; - gap: ${Theme.spacing(6)}; +const StyledContent = styled.div` + ${mq({ + width: '100%', + paddingTop: `${Theme.spacing(6)}`, + display: ['flex', 'flex', 'grid'], + flexDirection: 'column', + gridTemplateRows: 'auto auto', + gridTemplateColumns: 'auto auto', + gap: `${Theme.spacing(6)}`, + })}; `; export default function UserGuideMain() { - const deviceType = useDeviceType(); return ( - + User Guide @@ -74,19 +67,11 @@ export default function UserGuideMain() { A brief guide to grasp the basics of Twenty - {deviceType === DeviceType.DESKTOP ? ( - - {UserGuideHomeCards.map((card) => { - return ; - })} - - ) : ( - - {UserGuideHomeCards.map((card) => { - return ; - })} - - )} + + {UserGuideHomeCards.map((card) => { + return ; + })} + ); diff --git a/packages/twenty-website/src/app/_components/user-guide/UserGuideSidebar.tsx b/packages/twenty-website/src/app/_components/user-guide/UserGuideSidebar.tsx index ddbdaa6ccecf..23ab69513c3d 100644 --- a/packages/twenty-website/src/app/_components/user-guide/UserGuideSidebar.tsx +++ b/packages/twenty-website/src/app/_components/user-guide/UserGuideSidebar.tsx @@ -3,24 +3,23 @@ import styled from '@emotion/styled'; import { useRouter } from 'next/navigation'; -import { - DeviceType, - useDeviceType, -} from '@/app/_components/client-utils/useDeviceType'; import { IconBook } from '@/app/_components/ui/icons'; +import mq from '@/app/_components/ui/theme/mq'; import { Theme } from '@/app/_components/ui/theme/theme'; import UserGuideSidebarSection from '@/app/_components/user-guide/UserGuideSidebarSection'; import { UserGuideIndex } from '@/content/user-guide/constants/UserGuideIndex'; -const StyledContainer = styled.div<{ isTablet: boolean }>` - width: ${({ isTablet }) => (isTablet ? '30%' : '20%')}; - background: ${Theme.background.secondary}; - display: flex; - flex-direction: column; - border-right: 1px solid ${Theme.background.transparent.medium}; - border-bottom: 1px solid ${Theme.background.transparent.medium}; - padding: ${Theme.spacing(10)} ${Theme.spacing(3)}; - gap: ${Theme.spacing(6)}; +const StyledContainer = styled.div` + ${mq({ + width: ['20%', '30%', '20%'], + display: ['none', 'flex', 'flex'], + flexDirection: 'column', + background: `${Theme.background.secondary}`, + borderRight: `1px solid ${Theme.background.transparent.medium}`, + borderBottom: `1px solid ${Theme.background.transparent.medium}`, + padding: `${Theme.spacing(10)} ${Theme.spacing(3)}`, + gap: `${Theme.spacing(6)}`, + })}; `; const StyledHeading = styled.div` @@ -55,9 +54,8 @@ const StyledHeadingText = styled.div` const UserGuideSidebar = () => { const router = useRouter(); - const isTablet = useDeviceType() === DeviceType.TABLET; return ( - + diff --git a/packages/twenty-website/src/app/_components/user-guide/UserGuideTableContents.tsx b/packages/twenty-website/src/app/_components/user-guide/UserGuideTableContents.tsx index a395285c4d3a..721ae4d11a7f 100644 --- a/packages/twenty-website/src/app/_components/user-guide/UserGuideTableContents.tsx +++ b/packages/twenty-website/src/app/_components/user-guide/UserGuideTableContents.tsx @@ -3,17 +3,23 @@ import styled from '@emotion/styled'; import { useRouter } from 'next/navigation'; +import mq from '@/app/_components/ui/theme/mq'; import { Theme } from '@/app/_components/ui/theme/theme'; const StyledContainer = styled.div` - width: 20%; - background: ${Theme.background.secondary}; - display: flex; - flex-direction: column; - border-left: 1px solid ${Theme.background.transparent.medium}; - border-bottom: 1px solid ${Theme.background.transparent.medium}; - padding: ${Theme.spacing(10)} ${Theme.spacing(6)}; - gap: ${Theme.spacing(6)}; + ${mq({ + width: '20%', + display: ['none', 'none', 'flex'], + flexDirection: 'column', + background: `${Theme.background.secondary}`, + borderLeft: `1px solid ${Theme.background.transparent.medium}`, + borderBottom: `1px solid ${Theme.background.transparent.medium}`, + padding: `${Theme.spacing(10)} ${Theme.spacing(6)}`, + gap: `${Theme.spacing(6)}`, + 'body nav': { + display: ['none', 'none', ''], + }, + })}; `; const StyledContent = styled.div` diff --git a/packages/twenty-website/src/app/layout.css b/packages/twenty-website/src/app/layout.css index 1e7c318abf95..b8370346b960 100644 --- a/packages/twenty-website/src/app/layout.css +++ b/packages/twenty-website/src/app/layout.css @@ -30,6 +30,12 @@ a { } } +@media (max-width: 1199px) { +nav { + display: none; + } +} + nav.toc { width: 20%; position: fixed; diff --git a/packages/twenty-website/src/app/user-guide/layout.tsx b/packages/twenty-website/src/app/user-guide/layout.tsx index c49fd5bb39ce..163e36385144 100644 --- a/packages/twenty-website/src/app/user-guide/layout.tsx +++ b/packages/twenty-website/src/app/user-guide/layout.tsx @@ -3,14 +3,10 @@ import { ReactNode } from 'react'; import styled from '@emotion/styled'; import { usePathname } from 'next/navigation'; -import { - DeviceType, - useDeviceType, -} from '@/app/_components/client-utils/useDeviceType'; +import mq from '@/app/_components/ui/theme/mq'; import { Theme } from '@/app/_components/ui/theme/theme'; import UserGuideSidebar from '@/app/_components/user-guide/UserGuideSidebar'; import UserGuideTableContents from '@/app/_components/user-guide/UserGuideTableContents'; - const StyledContainer = styled.div` width: 100%; display: flex; @@ -20,20 +16,19 @@ const StyledContainer = styled.div` `; const StyledEmptySideBar = styled.div` - width: 20%; + ${mq({ + width: '20%', + display: ['none', 'none', ''], + })}; `; export default function UserGuideLayout({ children }: { children: ReactNode }) { const pathname = usePathname(); - const deviceType = useDeviceType(); - return ( - {deviceType !== DeviceType.MOBILE && } + {children} - {deviceType !== DeviceType.DESKTOP ? ( - <> - ) : pathname === '/user-guide' ? ( + {pathname === '/user-guide' ? ( ) : ( diff --git a/yarn.lock b/yarn.lock index 11f6746a38b4..792aecab1a7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15247,6 +15247,13 @@ __metadata: languageName: node linkType: hard +"@types/facepaint@npm:^1.2.5": + version: 1.2.5 + resolution: "@types/facepaint@npm:1.2.5" + checksum: e759fef0858f2f691625c47d59124e35d745c33d7229b99607158361ac0346f012ffad5c24a7312b49d54c097862ca7fe66a3ca37dbf8074154edb093b9fa0fc + languageName: node + linkType: hard + "@types/filesystem@npm:*": version: 0.0.35 resolution: "@types/filesystem@npm:0.0.35" @@ -25327,6 +25334,13 @@ __metadata: languageName: node linkType: hard +"facepaint@npm:^1.2.1": + version: 1.2.1 + resolution: "facepaint@npm:1.2.1" + checksum: bc4e974f4db7e860afb86cfeaf25720f4058e100a0cc79d42e69b0518363a538643de18753f6ed0161cc9d7280ff49d9f07351dc1d614b5dc79a28837dd6cd50 + languageName: node + linkType: hard + "fast-decode-uri-component@npm:^1.0.1": version: 1.0.1 resolution: "fast-decode-uri-component@npm:1.0.1" @@ -44253,6 +44267,7 @@ __metadata: "@types/bytes": "npm:^3.1.1" "@types/deep-equal": "npm:^1.0.1" "@types/express": "npm:^4.17.13" + "@types/facepaint": "npm:^1.2.5" "@types/graphql-fields": "npm:^1.3.6" "@types/graphql-upload": "npm:^8.0.12" "@types/jest": "npm:^29.5.11" @@ -44323,6 +44338,7 @@ __metadata: eslint-plugin-simple-import-sort: "npm:^10.0.0" eslint-plugin-storybook: "npm:^0.6.15" eslint-plugin-unused-imports: "npm:^3.0.0" + facepaint: "npm:^1.2.1" file-type: "npm:16.5.4" framer-motion: "npm:^10.12.17" googleapis: "npm:105" From d7f93dd721a4bf034f175c779eb81c106cc7efdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Sat, 24 Feb 2024 21:34:17 +0100 Subject: [PATCH 2/2] Remove useDeviceType --- .../_components/client-utils/useDeviceType.ts | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 packages/twenty-website/src/app/_components/client-utils/useDeviceType.ts diff --git a/packages/twenty-website/src/app/_components/client-utils/useDeviceType.ts b/packages/twenty-website/src/app/_components/client-utils/useDeviceType.ts deleted file mode 100644 index d60821189671..000000000000 --- a/packages/twenty-website/src/app/_components/client-utils/useDeviceType.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useMediaQuery } from 'react-responsive'; - -export enum DeviceType { - DESKTOP = 'DESKTOP', - TABLET = 'TABLET', - MOBILE = 'MOBILE', -} - -export const useDeviceType = () => { - const isTablet = useMediaQuery({ - query: '(max-width: 1199px) and (min-width: 810px)', - }); - const isMobile = useMediaQuery({ query: '(max-width: 809px)' }); - - if (isMobile) { - return DeviceType.MOBILE; - } - if (isTablet) { - return DeviceType.TABLET; - } - return DeviceType.DESKTOP; -};