diff --git a/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts index f19f1909e..b6f4cb367 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts @@ -84,16 +84,13 @@ test.describe('Left panel desktop', () => { }); }); -test.describe('Left panel mobile', () => { - test.use({ viewport: { width: 500, height: 1200 } }); - - test.beforeEach(async ({ page }) => { - await page.goto('/'); - }); - - test('checks all the desktop elements are hidden and all mobile elements are visible', async ({ +test.describe('Left panel responsive', () => { + test('checks elements visibility on different screen sizes', async ({ page, }) => { + await page.setViewportSize({ width: 500, height: 1200 }); + await page.goto('/'); + await expect(page.getByTestId('left-panel-desktop')).toBeHidden(); await expect(page.getByTestId('left-panel-mobile')).not.toBeInViewport(); @@ -120,12 +117,27 @@ test.describe('Left panel mobile', () => { await expect(newDocButton).toBeInViewport(); await expect(languageButton).toBeInViewport(); await expect(logoutButton).toBeInViewport(); + + await header.getByLabel('Close the header menu').click(); + + // Tablet size - like in desktop, left panel should be visible + await page.setViewportSize({ width: 900, height: 1200 }); + await page.goto('/'); + + await expect(page.getByRole('link', { name: 'All docs' })).toBeInViewport(); + await expect(newDocButton).toBeInViewport(); + await expect(languageButton).toBeInViewport(); + await expect(logoutButton).toBeInViewport(); + await expect(header.getByLabel('Open the header menu')).toBeHidden(); }); test('checks panel closes when clicking on a subdoc', async ({ page, browserName, }) => { + await page.setViewportSize({ width: 500, height: 1200 }); + await page.goto('/'); + const [docTitle] = await createDoc( page, 'mobile-doc-test', @@ -162,12 +174,4 @@ test.describe('Left panel mobile', () => { await verifyDocName(page, docChild); await expect(page.getByTestId('left-panel-mobile')).not.toBeInViewport(); }); - - test('checks resize handle is not present on mobile', async ({ page }) => { - await page.goto('/'); - - // Verify the resize handle is NOT present on mobile - const resizeHandle = page.locator('[data-panel-resize-handle-id]'); - await expect(resizeHandle).toBeHidden(); - }); }); diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx index a7f238792..7a3ce2ea2 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx @@ -110,7 +110,7 @@ const DocTitleEmojiPicker = ({ doc }: DocTitleProps) => { }; const DocTitleInput = ({ doc }: DocTitleProps) => { - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); const { t } = useTranslation(); const { isTopRoot } = useDocUtils(doc); const { untitledDocument } = useTrans(); @@ -227,9 +227,9 @@ const DocTitleInput = ({ doc }: DocTitleProps) => { pointer-events: none; font-style: italic; } - font-size: ${isDesktop - ? css`var(--c--globals--font--sizes--h2)` - : css`var(--c--globals--font--sizes--sm)`}; + font-size: ${isLargeScreen + ? 'var(--c--globals--font--sizes--h2)' + : 'var(--c--globals--font--sizes--sm)'}; font-weight: 700; outline: none; `} diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/FloatingBar.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/FloatingBar.tsx index 45a94108e..bcd24d2c5 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/FloatingBar.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/FloatingBar.tsx @@ -16,7 +16,7 @@ import { useResponsiveStore } from '@/stores'; */ export const FloatingBar = () => { const { spacingsTokens } = useCunninghamTheme(); - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); const FLOATING_STYLES = useMemo(() => { const base = spacingsTokens['base']; @@ -69,7 +69,7 @@ export const FloatingBar = () => { $direction="row" $justify="space-between" > - {isDesktop ? : } + {isLargeScreen ? : } ); diff --git a/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx b/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx index 3f18134dd..e4dfebe5c 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-search/components/DocSearchModal.tsx @@ -4,6 +4,7 @@ import Image from 'next/image'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { createGlobalStyle } from 'styled-components'; import { useDebouncedCallback } from 'use-debounce'; import { Box, ButtonCloseModal, Text } from '@/components'; @@ -20,6 +21,12 @@ import EmptySearchIcon from '../assets/illustration-docs-empty.png'; import { DocSearchContent } from './DocSearchContent'; +const ModalStyle = createGlobalStyle` + .c__modal__scroller { + overflow: inherit ; + } +`; + type DocSearchModalGlobalProps = { onClose: () => void; isOpen: boolean; @@ -43,7 +50,7 @@ const DocSearchModalGlobal = ({ const [filters, setFilters] = useState( defaultFilters ?? {}, ); - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); const handleInputSearch = useDebouncedCallback(setSearch, 300); const handleSelect = (doc: Doc) => { @@ -60,10 +67,11 @@ const DocSearchModalGlobal = ({ + {search.length === 0 && ( diff --git a/src/frontend/apps/impress/src/features/header/components/Header.tsx b/src/frontend/apps/impress/src/features/header/components/Header.tsx index 0efc1072e..07d0678c8 100644 --- a/src/frontend/apps/impress/src/features/header/components/Header.tsx +++ b/src/frontend/apps/impress/src/features/header/components/Header.tsx @@ -19,7 +19,7 @@ export const Header = () => { const { t } = useTranslation(); const { data: config } = useConfig(); const { spacingsTokens } = useCunninghamTheme(); - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); const icon = config?.theme_customization?.header?.icon; @@ -46,7 +46,7 @@ export const Header = () => { var(--c--contextuals--border--surface--primary); `} > - {!isDesktop && } + {!isLargeScreen && } { /> - {!isDesktop ? ( + {!isLargeScreen ? ( diff --git a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanel.tsx b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanel.tsx index 6d6c8da53..1158ac4cd 100644 --- a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanel.tsx +++ b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanel.tsx @@ -24,8 +24,8 @@ const MobileLeftPanelStyle = createGlobalStyle` `; export const LeftPanel = () => { - const { isDesktop } = useResponsiveStore(); - if (isDesktop) { + const { isLargeScreen } = useResponsiveStore(); + if (isLargeScreen) { return ; } diff --git a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFavoriteItem.tsx b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFavoriteItem.tsx index b2d3cc7d7..bc68a7853 100644 --- a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFavoriteItem.tsx +++ b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFavoriteItem.tsx @@ -14,7 +14,7 @@ type LeftPanelFavoriteItemProps = { export const LeftPanelFavoriteItem = ({ doc }: LeftPanelFavoriteItemProps) => { const { colorsTokens, spacingsTokens } = useCunninghamTheme(); - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); return ( { padding: ${spacingsTokens['2xs']}; border-radius: 4px; .pinned-actions { - opacity: ${isDesktop ? 0 : 1}; + opacity: ${isLargeScreen ? 0 : 1}; } &:hover { background-color: var( diff --git a/src/frontend/apps/impress/src/features/left-panel/components/ResizableLeftPanel.tsx b/src/frontend/apps/impress/src/features/left-panel/components/ResizableLeftPanel.tsx index cf89f7fbb..8e558aff4 100644 --- a/src/frontend/apps/impress/src/features/left-panel/components/ResizableLeftPanel.tsx +++ b/src/frontend/apps/impress/src/features/left-panel/components/ResizableLeftPanel.tsx @@ -51,7 +51,7 @@ export const ResizableLeftPanel = ({ maxPanelSizePx = 450, }: ResizableLeftPanelProps) => { const { t } = useTranslation(); - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); const { isPanelOpen } = useLeftPanelStore(); const ref = useRef(null); const savedWidthPxRef = useRef(minPanelSizePx); @@ -89,7 +89,7 @@ export const ResizableLeftPanel = ({ * to either expand/collapse */ useEffect(() => { - if (!ref.current || !isDesktop) { + if (!ref.current || !isLargeScreen) { return; } if (isPanelOpen) { @@ -97,11 +97,11 @@ export const ResizableLeftPanel = ({ } else { ref.current.collapse(); } - }, [isPanelOpen, isDesktop]); + }, [isPanelOpen, isLargeScreen]); // Keep pixel width constant on window resize useEffect(() => { - if (!isDesktop) { + if (!isLargeScreen) { return; } @@ -117,7 +117,7 @@ export const ResizableLeftPanel = ({ return () => { window.removeEventListener('resize', handleResize); }; - }, [isDesktop]); + }, [isLargeScreen]); /** * Workaround: NVDA does not enter focus mode for role="separator" @@ -158,15 +158,15 @@ export const ResizableLeftPanel = ({ }} order={0} defaultSize={ - isDesktop + isLargeScreen ? Math.max( minPanelSizePercent, Math.min(panelSizePercent, maxPanelSizePercent), ) : 0 } - minSize={isDesktop ? minPanelSizePercent : 0} - maxSize={isDesktop ? maxPanelSizePercent : 0} + minSize={isLargeScreen ? minPanelSizePercent : 0} + maxSize={isLargeScreen ? maxPanelSizePercent : 0} onResize={handleResize} > {leftPanel} @@ -193,7 +193,7 @@ export const ResizableLeftPanel = ({ cursor: 'col-resize', }} onDragging={setIsDragging} - disabled={!isDesktop} + disabled={!isLargeScreen} /> )} {children} diff --git a/src/frontend/apps/impress/src/layouts/MainLayout.tsx b/src/frontend/apps/impress/src/layouts/MainLayout.tsx index 750408bf3..b3546cd31 100644 --- a/src/frontend/apps/impress/src/layouts/MainLayout.tsx +++ b/src/frontend/apps/impress/src/layouts/MainLayout.tsx @@ -52,7 +52,7 @@ export function MainLayoutContent({ backgroundColor, enableResizablePanel, }: PropsWithChildren) { - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); if (enableResizablePanel) { return ( @@ -71,7 +71,7 @@ export function MainLayoutContent({ ); } - if (!isDesktop) { + if (!isLargeScreen) { return ( <> diff --git a/src/frontend/apps/impress/src/layouts/PageLayout.tsx b/src/frontend/apps/impress/src/layouts/PageLayout.tsx index d92b28b6f..4969008a4 100644 --- a/src/frontend/apps/impress/src/layouts/PageLayout.tsx +++ b/src/frontend/apps/impress/src/layouts/PageLayout.tsx @@ -18,7 +18,7 @@ export function PageLayout({ children, withFooter = true, }: PropsWithChildren) { - const { isDesktop } = useResponsiveStore(); + const { isLargeScreen } = useResponsiveStore(); const { t } = useTranslation(); return ( - {!isDesktop && } + {!isLargeScreen && } {children} {withFooter &&