diff --git a/packages/pxweb2/src/app/components/NavigationDrawer/Drawers/DrawerHelp.tsx b/packages/pxweb2/src/app/components/NavigationDrawer/Drawers/DrawerHelp.tsx index f0c3e5100..1e692f7da 100644 --- a/packages/pxweb2/src/app/components/NavigationDrawer/Drawers/DrawerHelp.tsx +++ b/packages/pxweb2/src/app/components/NavigationDrawer/Drawers/DrawerHelp.tsx @@ -7,6 +7,7 @@ import type { LocaleContent, HelpSection as HelpSectionType, } from '../../../util/config/localeContentTypes'; +import React from 'react'; export function DrawerHelp() { const { i18n } = useTranslation(); @@ -14,6 +15,14 @@ export function DrawerHelp() { const helpSectionContent: HelpSectionType | undefined = localeContent?.tableViewer?.helpSection; + React.useEffect(() => { + // Fire a custom event after mount to signal that HelpSection is rendered + const timeout = setTimeout(() => { + globalThis.dispatchEvent(new CustomEvent('drawer-help-rendered')); + }, 0); + return () => clearTimeout(timeout); + }, [helpSectionContent]); + if (!helpSectionContent) { return null; } diff --git a/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.module.scss b/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.module.scss index a9ca749e5..6efba6ec7 100644 --- a/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.module.scss +++ b/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.module.scss @@ -67,18 +67,11 @@ border-end-end-radius: var(--px-border-radius-xlarge); border-end-start-radius: var(--px-border-radius-none); - // Not from Figma position: absolute; - inset-inline-start: 120px; // Instead of "left" to handle rtl languages + inset-inline-start: 120px; z-index: 999; - - // Position NavigationDrawer below the header - top: fixed.$spacing-22; - - &.skipToMainContentVisible { - // Calculate position of NavigationDrawer below the header and SkipToMainContent - top: calc(fixed.$spacing-22 + var(--skip-to-main-content-height)); - } + top: 88px; + order: 0; } // xlarge and xxlarge @@ -86,6 +79,10 @@ width: 396px; padding: 0px fixed.$spacing-8 fixed.$spacing-8 0px; border-radius: var(--px-border-radius-none); + + // Participate in flex layout within mainContainer + position: static; + order: 0; } } diff --git a/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.spec.tsx b/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.spec.tsx new file mode 100644 index 000000000..4071b5c11 --- /dev/null +++ b/packages/pxweb2/src/app/components/NavigationDrawer/NavigationDrawer.spec.tsx @@ -0,0 +1,240 @@ +import React from 'react'; +import '@testing-library/jest-dom'; +import { + render, + screen, + fireEvent, + within, + waitFor, +} from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { vi, afterEach } from 'vitest'; +import NavigationDrawer from './NavigationDrawer'; + +// Mocks +vi.mock('../../context/useAccessibility', () => ({ + __esModule: true, + default: () => ({ + addModal: vi.fn(), + removeModal: vi.fn(), + }), +})); + +vi.mock('react-i18next', () => ({ + useTranslation: () => ({ t: (k: string) => k }), +})); + +vi.mock('@pxweb2/pxweb2-ui', () => ({ + Heading: (props: React.ComponentProps<'h2'>) =>
, + Icon: () => , + Label: (props: React.ComponentProps<'span'>) => , + getIconDirection: (dir: string, ltr: string, rtl: string) => + dir === 'rtl' ? rtl : ltr, +})); + +vi.mock('i18next', () => ({ + __esModule: true, + default: { dir: () => 'ltr' }, +})); + +// useApp mock (hook default export) +import useApp from '../../context/useApp'; +vi.mock('../../context/useApp', () => ({ + __esModule: true, + default: vi.fn(), +})); + +function setSmallScreen(isSmall: boolean) { + (useApp as any).mockReturnValue({ + skipToMainFocused: false, + isMobile: false, + isTablet: false, + isXLargeDesktop: !isSmall, + isXXLargeDesktop: !isSmall, + }); + Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation((query: string) => ({ + matches: isSmall && query === '(max-width: 1199px)', + media: query, + addListener: vi.fn(), + removeListener: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); +} + +afterEach(() => { + // Cleanup custom drawer root if created + const root = document.querySelector('[data-drawer-root]'); + root?.parentElement?.removeChild(root); + vi.clearAllMocks(); +}); + +function renderDrawer(options?: { + view?: 'selection' | 'view' | 'edit' | 'save' | 'help'; + heading?: string; + openedWithKeyboard?: boolean; + smallScreen?: boolean; + useDrawerRoot?: boolean; + onClose?: ReturnType