@lifesg/react-design-system 4.0.0-alpha.10 → 4.0.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/accordion/accordion-item.js +1 -1
  2. package/accordion/accordion-item.js.map +1 -1
  3. package/accordion/types.d.ts +7 -0
  4. package/cjs/accordion/accordion-item.js +1 -1
  5. package/cjs/accordion/accordion-item.js.map +1 -1
  6. package/cjs/masthead/masthead.js +1 -1
  7. package/cjs/masthead/masthead.js.map +1 -1
  8. package/cjs/masthead/sgds-day.css +520 -59
  9. package/cjs/masthead/sgds-night.css +514 -53
  10. package/cjs/modal-v2/modal-v2.js.map +1 -1
  11. package/cjs/modal-v2/slots/card.js +1 -1
  12. package/cjs/modal-v2/slots/card.js.map +1 -1
  13. package/cjs/modal-v2/slots/slot-styles.js +1 -1
  14. package/cjs/modal-v2/slots/slot-styles.js.map +1 -1
  15. package/cjs/modal-v2/slots/slot-styles_ayb9il.css +33 -0
  16. package/cjs/navbar/menu.js +1 -1
  17. package/cjs/navbar/menu.js.map +1 -1
  18. package/cjs/navbar/menu.styles.js +1 -1
  19. package/cjs/navbar/menu.styles.js.map +1 -1
  20. package/{navbar/menu.styles_gdpqc.css → cjs/navbar/menu.styles_zkjexa.css} +1 -1
  21. package/cjs/navbar/navbar-items.js +1 -1
  22. package/cjs/navbar/navbar-items.js.map +1 -1
  23. package/cjs/navbar/navbar-items.styles.js +1 -1
  24. package/cjs/navbar/navbar-items.styles.js.map +1 -1
  25. package/{navbar/navbar-items.styles_1b1zx.css → cjs/navbar/navbar-items.styles_1klnd8i.css} +3 -3
  26. package/cjs/theme/theme-provider/breakpoint.js +1 -1
  27. package/cjs/theme/theme-provider/breakpoint.js.map +1 -1
  28. package/cjs/theme/theme-provider/hooks.js +1 -1
  29. package/cjs/theme/theme-provider/hooks.js.map +1 -1
  30. package/cjs/theme/theme-provider/index.js +1 -1
  31. package/cjs/theme/theme-provider/index.js.map +1 -1
  32. package/cjs/theme/types.js +1 -1
  33. package/cjs/theme/types.js.map +1 -1
  34. package/docs/component-catalog.json +1 -1
  35. package/masthead/masthead.js +1 -1
  36. package/masthead/masthead.js.map +1 -1
  37. package/masthead/sgds-day.css +520 -59
  38. package/masthead/sgds-night.css +514 -53
  39. package/modal-v2/modal-v2.d.ts +2 -2
  40. package/modal-v2/modal-v2.js.map +1 -1
  41. package/modal-v2/slots/card.js +1 -1
  42. package/modal-v2/slots/card.js.map +1 -1
  43. package/modal-v2/slots/slot-styles.d.ts +4 -0
  44. package/modal-v2/slots/slot-styles.js +1 -1
  45. package/modal-v2/slots/slot-styles.js.map +1 -1
  46. package/modal-v2/slots/slot-styles_ayb9il.css +33 -0
  47. package/modal-v2/types.d.ts +5 -0
  48. package/navbar/menu.d.ts +2 -1
  49. package/navbar/menu.js +1 -1
  50. package/navbar/menu.js.map +1 -1
  51. package/navbar/menu.styles.js +1 -1
  52. package/navbar/menu.styles.js.map +1 -1
  53. package/{cjs/navbar/menu.styles_gdpqc.css → navbar/menu.styles_zkjexa.css} +1 -1
  54. package/navbar/navbar-items.js +1 -1
  55. package/navbar/navbar-items.js.map +1 -1
  56. package/navbar/navbar-items.styles.js +1 -1
  57. package/navbar/navbar-items.styles.js.map +1 -1
  58. package/{cjs/navbar/navbar-items.styles_1b1zx.css → navbar/navbar-items.styles_1klnd8i.css} +3 -3
  59. package/package.json +2 -1
  60. package/theme/styles/vica.css +840 -0
  61. package/theme/styles/websg.css +840 -0
  62. package/theme/styles/wise.css +840 -0
  63. package/theme/styles/wogaa.css +840 -0
  64. package/theme/theme-provider/breakpoint.js +1 -1
  65. package/theme/theme-provider/breakpoint.js.map +1 -1
  66. package/theme/theme-provider/hooks.d.ts +1 -0
  67. package/theme/theme-provider/hooks.js +1 -1
  68. package/theme/theme-provider/hooks.js.map +1 -1
  69. package/theme/theme-provider/index.js +1 -1
  70. package/theme/theme-provider/index.js.map +1 -1
  71. package/theme/theme-provider/types.d.ts +8 -1
  72. package/theme/types.d.ts +3 -1
  73. package/theme/types.js +1 -1
  74. package/theme/types.js.map +1 -1
  75. package/cjs/modal-v2/slots/slot-styles_10ut1v7.css +0 -30
  76. package/modal-v2/slots/slot-styles_10ut1v7.css +0 -30
@@ -7,14 +7,14 @@ import type { ModalV2Props } from "./types";
7
7
  * content slots.
8
8
  *
9
9
  * Sub-components:
10
- * - `ModalV2.Card` — wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout.
10
+ * - `ModalV2.Card` — wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout. Supports a `fullscreen` prop that makes the card fill the viewport.
11
11
  * - `ModalV2.CloseButton` — renders an accessible close button that invokes the modal's `onClose` callback.
12
12
  * - `ModalV2.Content` — container for the body content of the modal card.
13
13
  * - `ModalV2.Footer` — footer area for primary and secondary action buttons.
14
14
  * @keywords dialog, overlay, popup
15
15
  */
16
16
  export declare const ModalV2: (({ id, show, onClose, animationFrom, children, enableOverlayClick, rootComponentId, zIndex, onOverlayClick, dismissKeyboardOnShow, "data-testid": testId, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, disableInitialFocus, className, ...otherProps }: ModalV2Props) => JSX.Element) & {
17
- /** Wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout. */
17
+ /** Wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout. Supports a `fullscreen` prop. */
18
18
  Card: (props: import("./types").ModalCardProps & React.RefAttributes<HTMLDivElement>) => React.ReactElement | null;
19
19
  /** Renders an accessible close button that invokes the modal's `onClose` callback. */
20
20
  CloseButton: {
@@ -1 +1 @@
1
- {"version":3,"file":"modal-v2.js","sources":["../../src/modal-v2/modal-v2.tsx"],"sourcesContent":["import {\n FloatingFocusManager,\n useDismiss,\n useFloating,\n useInteractions,\n useTransitionStatus,\n} from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport React, { useRef } from \"react\";\n\nimport { Overlay } from \"../overlay/overlay\";\nimport { useViewport } from \"../shared/hooks\";\nimport { useApplyStyle } from \"../theme\";\nimport { useEvent } from \"../util\";\nimport { ModalContext } from \"./modal-context\";\nimport * as styles from \"./modal-v2.styles\";\nimport { Card, CloseButton, Content, Footer, Header } from \"./slots\";\nimport type { ModalV2Props } from \"./types\";\n\nconst Base = ({\n id,\n show,\n onClose,\n animationFrom = \"bottom\",\n children,\n enableOverlayClick = true,\n rootComponentId,\n zIndex,\n onOverlayClick,\n dismissKeyboardOnShow = true,\n \"data-testid\": testId = \"modal\",\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n disableInitialFocus = false,\n className,\n ...otherProps\n}: ModalV2Props): JSX.Element => {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const dismissKeyboard = useEvent(() => {\n if (dismissKeyboardOnShow) {\n (document.activeElement as HTMLElement)?.blur?.();\n }\n });\n const { verticalHeight } = useViewport({\n enabled: show,\n onBeforeStart: dismissKeyboard,\n });\n const childRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const childWithRef =\n children && React.cloneElement(children, { ref: childRef });\n\n useApplyStyle(containerRef, {\n [styles.tokens.container.verticalHeight]:\n verticalHeight == null ? null : `${verticalHeight}px`,\n });\n\n // =========================================================================\n // FLOATING UI CONFIG\n // =========================================================================\n const { refs, context } = useFloating({\n open: show,\n onOpenChange: (isOpen) => {\n if (!isOpen) {\n onClose?.();\n }\n },\n });\n const { isMounted, status } = useTransitionStatus(context, {\n duration: 300,\n });\n const dismiss = useDismiss(context, {\n /* handled by overlayclick */\n outsidePress: false,\n enabled: !!onClose,\n });\n const { getFloatingProps } = useInteractions([dismiss]);\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n return (\n <Overlay\n data-testid={`${testId}-overlay`}\n show={show}\n enableOverlayClick={enableOverlayClick}\n onOverlayClick={onOverlayClick}\n id={id}\n rootId={rootComponentId}\n containerRef={childRef}\n zIndex={zIndex}\n >\n <div\n ref={containerRef}\n data-testid={testId}\n data-status={status}\n data-animation-from={animationFrom}\n {...otherProps}\n className={clsx(styles.container, className)}\n >\n <ModalContext.Provider value={{ onClose }}>\n {isMounted && (\n <FloatingFocusManager\n context={context}\n initialFocus={\n disableInitialFocus ? -1 : refs.floating\n }\n >\n <div className={styles.scrollContainer}>\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n className={styles.modalContainer}\n >\n {childWithRef}\n </div>\n </div>\n </FloatingFocusManager>\n )}\n </ModalContext.Provider>\n </div>\n </Overlay>\n );\n};\n\n// @catalog\n/**\n * A composable modal dialog with slot-based content layout.\n *\n * Use `ModalV2` when you need a controlled overlay dialog with structured\n * content slots.\n *\n * Sub-components:\n * - `ModalV2.Card` — wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout.\n * - `ModalV2.CloseButton` — renders an accessible close button that invokes the modal's `onClose` callback.\n * - `ModalV2.Content` — container for the body content of the modal card.\n * - `ModalV2.Footer` — footer area for primary and secondary action buttons.\n * @keywords dialog, overlay, popup\n */\nexport const ModalV2 = Object.assign(Base, {\n /** Wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout. */\n Card,\n /** Renders an accessible close button that invokes the modal's `onClose` callback. */\n CloseButton,\n /** Container for the body content of the modal card. */\n Content,\n /** Footer area for primary and secondary action buttons. */\n Footer,\n /** Header bar with a close button and optional title. Use instead of `CloseButton` when a heading is needed. */\n Header,\n});\n"],"names":["ModalV2","Object","assign","_a","id","show","onClose","animationFrom","children","enableOverlayClick","rootComponentId","zIndex","onOverlayClick","dismissKeyboardOnShow","testId","ariaLabel","ariaLabelledBy","ariaDescribedBy","disableInitialFocus","className","otherProps","__rest","dismissKeyboard","useEvent","_b","document","activeElement","blur","verticalHeight","useViewport","enabled","onBeforeStart","childRef","useRef","containerRef","childWithRef","React","cloneElement","ref","useApplyStyle","styles.tokens","container","refs","context","useFloating","open","onOpenChange","isOpen","isMounted","status","useTransitionStatus","duration","dismiss","useDismiss","outsidePress","getFloatingProps","useInteractions","_jsx","Overlay","rootId","clsx","styles.container","ModalContext","Provider","value","FloatingFocusManager","initialFocus","floating","styles.scrollContainer","setFloating","role","styles.modalContainer","Card","CloseButton","Content","Footer","Header"],"mappings":"4yCAmBA,MA+HaA,EAAUC,OAAOC,QA/HhBC,QAAAC,GACVA,EAAEC,KACFA,EAAIC,QACJA,EAAOC,cACPA,EAAgB,SAAQC,SACxBA,EAAQC,mBACRA,GAAqB,EAAIC,gBACzBA,EAAeC,OACfA,EAAMC,eACNA,EAAcC,sBACdA,GAAwB,EACxB,cAAeC,EAAS,QACxB,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EAAeC,oBACnCA,GAAsB,EAAKC,UAC3BA,GAAShB,EACNiB,EAAUC,EAAAlB,EAjBH,CAAA,KAAA,OAAA,UAAA,gBAAA,WAAA,qBAAA,kBAAA,SAAA,iBAAA,wBAAA,cAAA,aAAA,kBAAA,mBAAA,sBAAA,cAsBV,MAAMmB,EAAkBC,GAAS,aACzBV,YACAW,EAAuC,UAAtCC,SAASC,qBAA6B,IAAAvB,OAAA,EAAAA,EAAEwB,6BAC7C,KAEEC,eAAEA,GAAmBC,EAAY,CACnCC,QAASzB,EACT0B,cAAeT,IAEbU,EAAWC,EAAuB,MAClCC,EAAeD,EAAuB,MACtCE,EACF3B,GAAY4B,EAAMC,aAAa7B,EAAU,CAAE8B,IAAKN,IAEpDO,EAAcL,EAAc,CACxB,CAACM,EAAcC,UAAUb,gBACH,MAAlBA,EAAyB,KAAO,GAAGA,QAM3C,MAAMc,KAAEA,EAAIC,QAAEA,GAAYC,EAAY,CAClCC,KAAMxC,EACNyC,aAAeC,IACNA,GACDzC,SAAAA,GACJ,KAGF0C,UAAEA,EAASC,OAAEA,GAAWC,EAAoBP,EAAS,CACvDQ,SAAU,MAERC,EAAUC,EAAWV,EAAS,CAEhCW,cAAc,EACdxB,UAAWxB,KAETiD,iBAAEA,GAAqBC,EAAgB,CAACJ,IAK9C,OACIK,EAACC,EAAO,CAAA,cACS,GAAG5C,YAChBT,KAAMA,EACNI,mBAAoBA,EACpBG,eAAgBA,EAChBR,GAAIA,EACJuD,OAAQjD,EACRwB,aAAcF,EACdrB,OAAQA,EAAMH,SAEdiD,EAAA,MAAAxD,OAAAC,OAAA,CACIoC,IAAKJ,EAAY,cACJpB,EAAM,cACNmC,EAAM,sBACE1C,GACjBa,GACJD,UAAWyC,EAAKC,EAAkB1C,GAAUX,SAE5CiD,EAACK,EAAaC,SAAQ,CAACC,MAAO,CAAE1D,WAASE,SACpCwC,GACGS,EAACQ,EAAoB,CACjBtB,QAASA,EACTuB,aACIhD,GAAsB,EAAKwB,EAAKyB,SAAQ3D,SAG5CiD,EAAA,MAAA,CAAKtC,UAAWiD,EAAsB5D,SAClCiD,EAAA,MAAAxD,OAAAC,OAAA,CACIoC,IAAKI,EAAK2B,aACNd,IAAkB,CACtBe,KAAK,SAAQ,aACDvD,EAAS,kBACJC,EAAc,mBACbC,EAClBE,UAAWoD,WAEVpC,eAOnB,GAkByB,CAEvCqC,OAEAC,cAEAC,UAEAC,SAEAC"}
1
+ {"version":3,"file":"modal-v2.js","sources":["../../src/modal-v2/modal-v2.tsx"],"sourcesContent":["import {\n FloatingFocusManager,\n useDismiss,\n useFloating,\n useInteractions,\n useTransitionStatus,\n} from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport React, { useRef } from \"react\";\n\nimport { Overlay } from \"../overlay/overlay\";\nimport { useViewport } from \"../shared/hooks\";\nimport { useApplyStyle } from \"../theme\";\nimport { useEvent } from \"../util\";\nimport { ModalContext } from \"./modal-context\";\nimport * as styles from \"./modal-v2.styles\";\nimport { Card, CloseButton, Content, Footer, Header } from \"./slots\";\nimport type { ModalV2Props } from \"./types\";\n\nconst Base = ({\n id,\n show,\n onClose,\n animationFrom = \"bottom\",\n children,\n enableOverlayClick = true,\n rootComponentId,\n zIndex,\n onOverlayClick,\n dismissKeyboardOnShow = true,\n \"data-testid\": testId = \"modal\",\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n disableInitialFocus = false,\n className,\n ...otherProps\n}: ModalV2Props): JSX.Element => {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const dismissKeyboard = useEvent(() => {\n if (dismissKeyboardOnShow) {\n (document.activeElement as HTMLElement)?.blur?.();\n }\n });\n const { verticalHeight } = useViewport({\n enabled: show,\n onBeforeStart: dismissKeyboard,\n });\n const childRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const childWithRef =\n children && React.cloneElement(children, { ref: childRef });\n\n useApplyStyle(containerRef, {\n [styles.tokens.container.verticalHeight]:\n verticalHeight == null ? null : `${verticalHeight}px`,\n });\n\n // =========================================================================\n // FLOATING UI CONFIG\n // =========================================================================\n const { refs, context } = useFloating({\n open: show,\n onOpenChange: (isOpen) => {\n if (!isOpen) {\n onClose?.();\n }\n },\n });\n const { isMounted, status } = useTransitionStatus(context, {\n duration: 300,\n });\n const dismiss = useDismiss(context, {\n /* handled by overlayclick */\n outsidePress: false,\n enabled: !!onClose,\n });\n const { getFloatingProps } = useInteractions([dismiss]);\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n return (\n <Overlay\n data-testid={`${testId}-overlay`}\n show={show}\n enableOverlayClick={enableOverlayClick}\n onOverlayClick={onOverlayClick}\n id={id}\n rootId={rootComponentId}\n containerRef={childRef}\n zIndex={zIndex}\n >\n <div\n ref={containerRef}\n data-testid={testId}\n data-status={status}\n data-animation-from={animationFrom}\n {...otherProps}\n className={clsx(styles.container, className)}\n >\n <ModalContext.Provider value={{ onClose }}>\n {isMounted && (\n <FloatingFocusManager\n context={context}\n initialFocus={\n disableInitialFocus ? -1 : refs.floating\n }\n >\n <div className={styles.scrollContainer}>\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n className={styles.modalContainer}\n >\n {childWithRef}\n </div>\n </div>\n </FloatingFocusManager>\n )}\n </ModalContext.Provider>\n </div>\n </Overlay>\n );\n};\n\n// @catalog\n/**\n * A composable modal dialog with slot-based content layout.\n *\n * Use `ModalV2` when you need a controlled overlay dialog with structured\n * content slots.\n *\n * Sub-components:\n * - `ModalV2.Card` — wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout. Supports a `fullscreen` prop that makes the card fill the viewport.\n * - `ModalV2.CloseButton` — renders an accessible close button that invokes the modal's `onClose` callback.\n * - `ModalV2.Content` — container for the body content of the modal card.\n * - `ModalV2.Footer` — footer area for primary and secondary action buttons.\n * @keywords dialog, overlay, popup\n */\nexport const ModalV2 = Object.assign(Base, {\n /** Wraps modal content and arranges `Content`, `Footer`, and `CloseButton` slots in the correct layout. Supports a `fullscreen` prop. */\n Card,\n /** Renders an accessible close button that invokes the modal's `onClose` callback. */\n CloseButton,\n /** Container for the body content of the modal card. */\n Content,\n /** Footer area for primary and secondary action buttons. */\n Footer,\n /** Header bar with a close button and optional title. Use instead of `CloseButton` when a heading is needed. */\n Header,\n});\n"],"names":["ModalV2","Object","assign","_a","id","show","onClose","animationFrom","children","enableOverlayClick","rootComponentId","zIndex","onOverlayClick","dismissKeyboardOnShow","testId","ariaLabel","ariaLabelledBy","ariaDescribedBy","disableInitialFocus","className","otherProps","__rest","dismissKeyboard","useEvent","_b","document","activeElement","blur","verticalHeight","useViewport","enabled","onBeforeStart","childRef","useRef","containerRef","childWithRef","React","cloneElement","ref","useApplyStyle","styles.tokens","container","refs","context","useFloating","open","onOpenChange","isOpen","isMounted","status","useTransitionStatus","duration","dismiss","useDismiss","outsidePress","getFloatingProps","useInteractions","_jsx","Overlay","rootId","clsx","styles.container","ModalContext","Provider","value","FloatingFocusManager","initialFocus","floating","styles.scrollContainer","setFloating","role","styles.modalContainer","Card","CloseButton","Content","Footer","Header"],"mappings":"4yCAmBA,MA+HaA,EAAUC,OAAOC,QA/HhBC,QAAAC,GACVA,EAAEC,KACFA,EAAIC,QACJA,EAAOC,cACPA,EAAgB,SAAQC,SACxBA,EAAQC,mBACRA,GAAqB,EAAIC,gBACzBA,EAAeC,OACfA,EAAMC,eACNA,EAAcC,sBACdA,GAAwB,EACxB,cAAeC,EAAS,QACxB,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EAAeC,oBACnCA,GAAsB,EAAKC,UAC3BA,GAAShB,EACNiB,EAAUC,EAAAlB,EAjBH,CAAA,KAAA,OAAA,UAAA,gBAAA,WAAA,qBAAA,kBAAA,SAAA,iBAAA,wBAAA,cAAA,aAAA,kBAAA,mBAAA,sBAAA,cAsBV,MAAMmB,EAAkBC,GAAS,aACzBV,YACAW,EAAuC,UAAtCC,SAASC,qBAA6B,IAAAvB,OAAA,EAAAA,EAAEwB,6BAC7C,KAEEC,eAAEA,GAAmBC,EAAY,CACnCC,QAASzB,EACT0B,cAAeT,IAEbU,EAAWC,EAAuB,MAClCC,EAAeD,EAAuB,MACtCE,EACF3B,GAAY4B,EAAMC,aAAa7B,EAAU,CAAE8B,IAAKN,IAEpDO,EAAcL,EAAc,CACxB,CAACM,EAAcC,UAAUb,gBACH,MAAlBA,EAAyB,KAAO,GAAGA,QAM3C,MAAMc,KAAEA,EAAIC,QAAEA,GAAYC,EAAY,CAClCC,KAAMxC,EACNyC,aAAeC,IACNA,GACDzC,SAAAA,GACJ,KAGF0C,UAAEA,EAASC,OAAEA,GAAWC,EAAoBP,EAAS,CACvDQ,SAAU,MAERC,EAAUC,EAAWV,EAAS,CAEhCW,cAAc,EACdxB,UAAWxB,KAETiD,iBAAEA,GAAqBC,EAAgB,CAACJ,IAK9C,OACIK,EAACC,EAAO,CAAA,cACS,GAAG5C,YAChBT,KAAMA,EACNI,mBAAoBA,EACpBG,eAAgBA,EAChBR,GAAIA,EACJuD,OAAQjD,EACRwB,aAAcF,EACdrB,OAAQA,EAAMH,SAEdiD,EAAA,MAAAxD,OAAAC,OAAA,CACIoC,IAAKJ,EAAY,cACJpB,EAAM,cACNmC,EAAM,sBACE1C,GACjBa,GACJD,UAAWyC,EAAKC,EAAkB1C,GAAUX,SAE5CiD,EAACK,EAAaC,SAAQ,CAACC,MAAO,CAAE1D,WAASE,SACpCwC,GACGS,EAACQ,EAAoB,CACjBtB,QAASA,EACTuB,aACIhD,GAAsB,EAAKwB,EAAKyB,SAAQ3D,SAG5CiD,EAAA,MAAA,CAAKtC,UAAWiD,EAAsB5D,SAClCiD,EAAA,MAAAxD,OAAAC,OAAA,CACIoC,IAAKI,EAAK2B,aACNd,IAAkB,CACtBe,KAAK,SAAQ,aACDvD,EAAS,kBACJC,EAAc,mBACbC,EAClBE,UAAWoD,WAEVpC,eAOnB,GAkByB,CAEvCqC,OAEAC,cAEAC,UAEAC,SAEAC"}
@@ -1,2 +1,2 @@
1
- import{__rest as t}from"../../_virtual/_tslib.js";import{jsxs as r}from"react/jsx-runtime";import e from"clsx";import o from"react";import"../../util/calendar-helper.js";import"../../external/dayjs/dayjs.min.js";import{mergeRefs as i}from"../../util/merge-refs.js";import"../../util/simple-id-generator.js";import"../../util/string-helper.js";import"@react-aria/live-announcer";import s from"../../util/is-styled-components.js";import{CloseButton as a}from"./close-button.js";import{Content as m}from"./content.js";import{Footer as l}from"./footer.js";import{Header as n}from"./header.js";import{slotSpacer as d,modalCard as p}from"./slot-styles.js";const c=o.forwardRef((function(c,f){var{id:j,"data-testid":u="modal-card",children:h,className:y,elementRef:g}=c,v=t(c,["id","data-testid","children","className","elementRef"]);const N=t=>o.Children.toArray(h).find((r=>((t,r)=>s(t.type)?t.type.target===r:t.type===r)(r,t))),b=N(a),x=N(m),C=N(l),R=N(n),_=!!b||!!R;return r("div",Object.assign({ref:i(f,g),id:j,"data-testid":u},v,{onClick:t=>{t.stopPropagation()},className:e(p,y),children:[r("div",{"data-has-close-button":!!_,className:e(d),children:[x,C]}),_&&(R||b)]}))}));c.displayName="ModalV2.Card";export{c as Card};
1
+ import{__rest as t}from"../../_virtual/_tslib.js";import{jsxs as r}from"react/jsx-runtime";import e from"clsx";import o from"react";import"../../util/calendar-helper.js";import"../../external/dayjs/dayjs.min.js";import{mergeRefs as i}from"../../util/merge-refs.js";import"../../util/simple-id-generator.js";import"../../util/string-helper.js";import"@react-aria/live-announcer";import s from"../../util/is-styled-components.js";import{CloseButton as a}from"./close-button.js";import{Content as m}from"./content.js";import{Footer as l}from"./footer.js";import{Header as n}from"./header.js";import{slotSpacer as d,fullscreenSlotSpacer as p,cardBase as c,fullscreenModalCard as f,modalCard as j}from"./slot-styles.js";const u=o.forwardRef((function(u,h){var{id:y,"data-testid":g="modal-card",children:v,className:N,elementRef:b,fullscreen:x}=u,C=t(u,["id","data-testid","children","className","elementRef","fullscreen"]);const R=t=>o.Children.toArray(v).find((r=>((t,r)=>s(t.type)?t.type.target===r:t.type===r)(r,t))),_=R(a),k=R(m),w=R(l),A=R(n),M=!!_||!!A;return r("div",Object.assign({ref:i(h,b),id:y,"data-testid":g},C,{onClick:t=>{t.stopPropagation()},className:e(c,x?f:j,N),children:[r("div",{"data-has-close-button":!!M,className:e(d,x&&p),children:[k,w]}),M&&(A||_)]}))}));u.displayName="ModalV2.Card";export{u as Card};
2
2
  //# sourceMappingURL=card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","sources":["../../../src/modal-v2/slots/card.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { NamedExoticComponent } from \"react\";\nimport React from \"react\";\n\nimport { mergeRefs } from \"../../util\";\nimport isStyledComponent from \"../../util/is-styled-components\";\nimport type { ModalCardProps } from \"../types\";\nimport { CloseButton } from \"./close-button\";\nimport { Content } from \"./content\";\nimport { Footer } from \"./footer\";\nimport { Header } from \"./header\";\nimport * as styles from \"./slot-styles\";\n\nfunction CardInner(\n {\n id,\n \"data-testid\": testId = \"modal-card\",\n children,\n className,\n elementRef,\n ...otherProps\n }: ModalCardProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n };\n\n // =========================================================================\n // HELPERS\n // =========================================================================\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isComponentType = (child: React.ReactPortal, type: any) =>\n isStyledComponent(child.type)\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (child.type as unknown as { target: any }).target === type\n : child.type === type;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const findComponentOfType = (type: any) => {\n return React.Children.toArray(children).find((child) =>\n isComponentType(child as React.ReactPortal, type)\n );\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const CloseButtonSlot = findComponentOfType(CloseButton);\n const ContentSlot = findComponentOfType(Content);\n const FooterSlot = findComponentOfType(Footer);\n const HeaderSlot = findComponentOfType(Header);\n\n const hasHeader = !!CloseButtonSlot || !!HeaderSlot;\n\n return (\n <div\n ref={mergeRefs(ref, elementRef)}\n id={id}\n data-testid={testId}\n {...otherProps}\n onClick={handleOnClick}\n className={clsx(styles.modalCard, className)}\n >\n <div\n data-has-close-button={!!hasHeader}\n className={clsx(styles.slotSpacer)}\n >\n {ContentSlot}\n {FooterSlot}\n </div>\n {hasHeader && (HeaderSlot || CloseButtonSlot)}\n </div>\n );\n}\n\nexport const Card = React.forwardRef<HTMLDivElement, ModalCardProps>(CardInner);\n\n(Card as NamedExoticComponent).displayName = \"ModalV2.Card\";\n"],"names":["Card","React","forwardRef","_a","ref","id","testId","children","className","elementRef","otherProps","__rest","findComponentOfType","type","Children","toArray","find","child","isStyledComponent","target","isComponentType","CloseButtonSlot","CloseButton","ContentSlot","Content","FooterSlot","Footer","HeaderSlot","Header","hasHeader","_jsxs","Object","assign","mergeRefs","onClick","event","stopPropagation","clsx","styles.modalCard","styles.slotSpacer","displayName"],"mappings":"0oBA+EO,MAAMA,EAAOC,EAAMC,YAlE1B,SACIC,EAQAC,GARA,IAAAC,GACIA,EACA,cAAeC,EAAS,aAAYC,SACpCA,EAAQC,UACRA,EAASC,WACTA,GAAUN,EACPO,EAAUC,EAAAR,EANjB,0DAaA,MAeMS,EAAuBC,GAClBZ,EAAMa,SAASC,QAAQR,GAAUS,MAAMC,GAR1B,EAACA,EAA0BJ,IAC/CK,EAAkBD,EAAMJ,MAEjBI,EAAMJ,KAAoCM,SAAWN,EACtDI,EAAMJ,OAASA,EAKjBO,CAAgBH,EAA4BJ,KAO9CQ,EAAkBT,EAAoBU,GACtCC,EAAcX,EAAoBY,GAClCC,EAAab,EAAoBc,GACjCC,EAAaf,EAAoBgB,GAEjCC,IAAcR,KAAqBM,EAEzC,OACIG,EAAA,MAAAC,OAAAC,OAAA,CACI5B,IAAK6B,EAAU7B,EAAKK,GACpBJ,GAAIA,EAAE,cACOC,GACTI,EAAU,CACdwB,QArCeC,IACnBA,EAAMC,iBAAiB,EAqCnB5B,UAAW6B,EAAKC,EAAkB9B,GAAUD,SAAA,CAE5CuB,EAAA,MAAA,CAAA,0BAC6BD,EACzBrB,UAAW6B,EAAKE,GAAkBhC,SAAA,CAEjCgB,EACAE,KAEJI,IAAcF,GAAcN,MAGzC,IAICrB,EAA8BwC,YAAc"}
1
+ {"version":3,"file":"card.js","sources":["../../../src/modal-v2/slots/card.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { NamedExoticComponent } from \"react\";\nimport React from \"react\";\n\nimport { mergeRefs } from \"../../util\";\nimport isStyledComponent from \"../../util/is-styled-components\";\nimport type { ModalCardProps } from \"../types\";\nimport { CloseButton } from \"./close-button\";\nimport { Content } from \"./content\";\nimport { Footer } from \"./footer\";\nimport { Header } from \"./header\";\nimport * as styles from \"./slot-styles\";\n\nfunction CardInner(\n {\n id,\n \"data-testid\": testId = \"modal-card\",\n children,\n className,\n elementRef,\n fullscreen,\n ...otherProps\n }: ModalCardProps,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n };\n\n // =========================================================================\n // HELPERS\n // =========================================================================\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isComponentType = (child: React.ReactPortal, type: any) =>\n isStyledComponent(child.type)\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (child.type as unknown as { target: any }).target === type\n : child.type === type;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const findComponentOfType = (type: any) => {\n return React.Children.toArray(children).find((child) =>\n isComponentType(child as React.ReactPortal, type)\n );\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const CloseButtonSlot = findComponentOfType(CloseButton);\n const ContentSlot = findComponentOfType(Content);\n const FooterSlot = findComponentOfType(Footer);\n const HeaderSlot = findComponentOfType(Header);\n\n const hasHeader = !!CloseButtonSlot || !!HeaderSlot;\n\n return (\n <div\n ref={mergeRefs(ref, elementRef)}\n id={id}\n data-testid={testId}\n {...otherProps}\n onClick={handleOnClick}\n className={clsx(\n styles.cardBase,\n fullscreen ? styles.fullscreenModalCard : styles.modalCard,\n className\n )}\n >\n <div\n data-has-close-button={!!hasHeader}\n className={clsx(\n styles.slotSpacer,\n fullscreen && styles.fullscreenSlotSpacer\n )}\n >\n {ContentSlot}\n {FooterSlot}\n </div>\n {hasHeader && (HeaderSlot || CloseButtonSlot)}\n </div>\n );\n}\n\nexport const Card = React.forwardRef<HTMLDivElement, ModalCardProps>(CardInner);\n\n(Card as NamedExoticComponent).displayName = \"ModalV2.Card\";\n"],"names":["Card","React","forwardRef","_a","ref","id","testId","children","className","elementRef","fullscreen","otherProps","__rest","findComponentOfType","type","Children","toArray","find","child","isStyledComponent","target","isComponentType","CloseButtonSlot","CloseButton","ContentSlot","Content","FooterSlot","Footer","HeaderSlot","Header","hasHeader","_jsxs","Object","assign","mergeRefs","onClick","event","stopPropagation","clsx","styles.cardBase","styles.fullscreenModalCard","styles.modalCard","styles.slotSpacer","styles.fullscreenSlotSpacer","displayName"],"mappings":"2sBAuFO,MAAMA,EAAOC,EAAMC,YA1E1B,SACIC,EASAC,OATAC,GACIA,EACA,cAAeC,EAAS,aAAYC,SACpCA,EAAQC,UACRA,EAASC,WACTA,EAAUC,WACVA,GAAUP,EACPQ,EAAUC,EAAAT,EAPjB,uEAcA,MAeMU,EAAuBC,GAClBb,EAAMc,SAASC,QAAQT,GAAUU,MAAMC,GAR1B,EAACA,EAA0BJ,IAC/CK,EAAkBD,EAAMJ,MAEjBI,EAAMJ,KAAoCM,SAAWN,EACtDI,EAAMJ,OAASA,EAKjBO,CAAgBH,EAA4BJ,KAO9CQ,EAAkBT,EAAoBU,GACtCC,EAAcX,EAAoBY,GAClCC,EAAab,EAAoBc,GACjCC,EAAaf,EAAoBgB,GAEjCC,IAAcR,KAAqBM,EAEzC,OACIG,EAAA,MAAAC,OAAAC,OAAA,CACI7B,IAAK8B,EAAU9B,EAAKK,GACpBJ,GAAIA,EAAE,cACOC,GACTK,EAAU,CACdwB,QArCeC,IACnBA,EAAMC,iBAAiB,EAqCnB7B,UAAW8B,EACPC,EACA7B,EAAa8B,EAA6BC,EAC1CjC,GACHD,SAAA,CAEDwB,mCAC6BD,EACzBtB,UAAW8B,EACPI,EACAhC,GAAciC,aAGjBnB,EACAE,KAEJI,IAAcF,GAAcN,MAGzC,IAICtB,EAA8B4C,YAAc"}
@@ -6,12 +6,16 @@ export declare const slotSpacerTokens: {
6
6
  readonly footerNotFirstChildMarginTop: "--fds-internal-modalV2-slotSpacer-footerNotFirstChildMarginTop";
7
7
  readonly footerLastChildMarginBottom: "--fds-internal-modalV2-slotSpacer-footerLastChildMarginBottom";
8
8
  };
9
+ /** Shared by both the windowed (`modalCard`) and `fullscreenModalCard` variants. */
10
+ export declare const cardBase: import("@linaria/core").LinariaClassName;
9
11
  export declare const modalCard: import("@linaria/core").LinariaClassName;
12
+ export declare const fullscreenModalCard: import("@linaria/core").LinariaClassName;
10
13
  export declare const closeButtonContainer: import("@linaria/core").LinariaClassName;
11
14
  export declare const styledClickableIcon: import("@linaria/core").LinariaClassName;
12
15
  export declare const contentContainer: import("@linaria/core").LinariaClassName;
13
16
  export declare const footerContainer: import("@linaria/core").LinariaClassName;
14
17
  export declare const slotSpacer: import("@linaria/core").LinariaClassName;
18
+ export declare const fullscreenSlotSpacer: import("@linaria/core").LinariaClassName;
15
19
  export declare const headerContainer: import("@linaria/core").LinariaClassName;
16
20
  export declare const headerTitle: import("@linaria/core").LinariaClassName;
17
21
  export declare const headerCloseButton: import("@linaria/core").LinariaClassName;
@@ -1,2 +1,2 @@
1
- import"./slot-styles_10ut1v7.css";const s="metykyj",t="c1247joo",o="st53q25",h="c1ls09wh",l="f1s12qxk",a="s1vsayl1",m="h1adf5mq",c="hii7rdr",i="ha88pah",r="h3mtfiz";export{t as closeButtonContainer,h as contentContainer,l as footerContainer,i as headerCloseButton,m as headerContainer,r as headerSpacer,c as headerTitle,s as modalCard,a as slotSpacer,o as styledClickableIcon};
1
+ import"./slot-styles_ayb9il.css";const s="cetykyj",t="m1247joo",o="ft53q25",l="c1ls09wh",a="s1s12qxk",c="c1vsayl1",h="f1adf5mq",r="sii7rdr",e="fa88pah",f="h3mtfiz",i="h1evnebr",m="ht9zr8k",y="hjbud0c";export{s as cardBase,l as closeButtonContainer,c as contentContainer,h as footerContainer,o as fullscreenModalCard,e as fullscreenSlotSpacer,m as headerCloseButton,f as headerContainer,y as headerSpacer,i as headerTitle,t as modalCard,r as slotSpacer,a as styledClickableIcon};
2
2
  //# sourceMappingURL=slot-styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot-styles.js","sources":["../../../src/modal-v2/slots/slot-styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport {\n Breakpoint,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../../theme\";\n\n// =============================================================================\n// Tokens and attributes\n// =============================================================================\nexport const slotSpacerHasCloseButtonAttribute = \"data-has-close-button\";\nconst internalSlotSpacerTokens = {\n firstChildMarginTop:\n \"--fds-internal-modalV2-slotSpacer-firstChildMarginTop\",\n} as const;\n\nexport const slotSpacerTokens = {\n firstChildMarginTopWithCloseButton:\n \"--fds-internal-modalV2-slotSpacer-firstChildMarginTopWithCloseButton\",\n firstChildMarginTopNoCloseButton:\n \"--fds-internal-modalV2-slotSpacer-firstChildMarginTopNoCloseButton\",\n\n contentLastChildMarginBottom:\n \"--fds-internal-modalV2-slotSpacer-contentLastChildMarginBottom\",\n\n footerNotFirstChildMarginTop:\n \"--fds-internal-modalV2-slotSpacer-footerNotFirstChildMarginTop\",\n footerLastChildMarginBottom:\n \"--fds-internal-modalV2-slotSpacer-footerLastChildMarginBottom\",\n} as const;\n\n// =============================================================================\n// STYLING\n// =============================================================================\nexport const modalCard = css`\n width: 40rem;\n margin: ${Spacing[\"spacing-64\"]} auto;\n background: ${Colour.bg};\n box-shadow: ${Shadow[\"xs-strong\"]};\n border-radius: ${Radius[\"lg\"]};\n\n display: flex;\n flex-direction: column-reverse;\n\n max-width: calc(100% - ${Breakpoint[\"xxl-margin\"]} * 2);\n\n ${MediaQuery.MaxWidth.xl} {\n max-width: calc(100% - ${Breakpoint[\"xl-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.lg} {\n max-width: calc(100% - ${Breakpoint[\"lg-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.md} {\n max-width: calc(100% - ${Breakpoint[\"md-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.sm} {\n max-width: calc(100% - ${Breakpoint[\"sm-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.xs} {\n max-width: calc(100% - ${Breakpoint[\"xs-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.xxs} {\n max-width: calc(100% - ${Breakpoint[\"xxs-margin\"]} * 2);\n }\n`;\n\nexport const closeButtonContainer = css`\n margin-right: ${Spacing[\"spacing-16\"]};\n margin-left: auto;\n margin-top: ${Spacing[\"spacing-16\"]};\n margin-bottom: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const styledClickableIcon = css`\n padding: 0;\n color: ${Colour.icon};\n\n & svg {\n height: 2rem;\n width: 2rem;\n }\n`;\n\nexport const contentContainer = css`\n margin-right: ${Spacing[\"spacing-64\"]};\n margin-left: ${Spacing[\"spacing-64\"]};\n\n ${MediaQuery.MaxWidth.sm} {\n margin-right: ${Spacing[\"spacing-20\"]};\n margin-left: ${Spacing[\"spacing-20\"]};\n }\n`;\n\nexport const footerContainer = css`\n margin-right: ${Spacing[\"spacing-64\"]};\n margin-left: ${Spacing[\"spacing-64\"]};\n\n ${MediaQuery.MaxWidth.sm} {\n margin-right: ${Spacing[\"spacing-20\"]};\n margin-left: ${Spacing[\"spacing-20\"]};\n }\n\n display: flex;\n flex-direction: row-reverse; /* primary button on right */\n column-gap: ${Spacing[\"spacing-32\"]};\n row-gap: ${Spacing[\"spacing-16\"]};\n\n & > button {\n flex: 1;\n }\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n }\n`;\n\nexport const slotSpacer = css`\n ${slotSpacerTokens.contentLastChildMarginBottom}: initial;\n ${slotSpacerTokens.footerNotFirstChildMarginTop}: initial;\n ${slotSpacerTokens.footerLastChildMarginBottom}: initial;\n ${slotSpacerTokens.firstChildMarginTopWithCloseButton}: initial;\n ${slotSpacerTokens.firstChildMarginTopNoCloseButton}: initial;\n\n ${internalSlotSpacerTokens.firstChildMarginTop}: var(\n ${slotSpacerTokens.firstChildMarginTopNoCloseButton},\n ${Spacing[\"spacing-64\"]}\n );\n\n & > :where(.${contentContainer}:last-child) {\n margin-bottom: var(\n ${slotSpacerTokens.contentLastChildMarginBottom},\n ${Spacing[\"spacing-64\"]}\n );\n }\n\n & > :where(.${footerContainer}:not(:first-child)) {\n margin-top: var(\n ${slotSpacerTokens.footerNotFirstChildMarginTop},\n ${Spacing[\"spacing-32\"]}\n );\n }\n\n & > :where(.${footerContainer}:last-child) {\n margin-bottom: var(\n ${slotSpacerTokens.footerLastChildMarginBottom},\n ${Spacing[\"spacing-64\"]}\n );\n }\n\n &\n > :where(\n .${contentContainer}:first-child, .${footerContainer}:first-child\n ) {\n margin-top: var(${internalSlotSpacerTokens.firstChildMarginTop});\n }\n\n &[${slotSpacerHasCloseButtonAttribute}=\"true\"] {\n ${internalSlotSpacerTokens.firstChildMarginTop}: var(\n ${slotSpacerTokens.firstChildMarginTopWithCloseButton},\n 0\n );\n }\n\n &[${slotSpacerHasCloseButtonAttribute}=\"false\"] {\n ${internalSlotSpacerTokens.firstChildMarginTop}: var(\n ${slotSpacerTokens.firstChildMarginTopNoCloseButton},\n ${Spacing[\"spacing-64\"]}\n );\n }\n`;\n\nexport const headerContainer = css`\n display: flex;\n align-items: center;\n padding: ${Spacing[\"spacing-16\"]};\n\n &[data-close-button-position=\"right\"] {\n flex-direction: row-reverse;\n }\n`;\n\nexport const headerTitle = css`\n ${Font[\"heading-xs-semibold\"]}\n color: ${Colour.text};\n flex: 1;\n text-align: center;\n`;\n\nexport const headerCloseButton = css`\n padding: 0;\n color: ${Colour.icon};\n flex-shrink: 0;\n\n & svg {\n height: 2rem;\n width: 2rem;\n }\n`;\n\nexport const headerSpacer = css`\n width: 2rem;\n flex-shrink: 0;\n`;\n"],"names":["modalCard","closeButtonContainer","styledClickableIcon","contentContainer","footerContainer","slotSpacer","headerContainer","headerTitle","headerCloseButton","headerSpacer"],"mappings":"gEAuCO,MAAMA,EAAS,UAqCTC,EAAoB,WAOpBC,EAAmB,UAUnBC,EAAgB,WAUhBC,EAAe,WAuBfC,EAAU,WAuDVC,EAAe,WAUfC,EAAW,UAOXC,EAAiB,UAWjBC,EAAY"}
1
+ {"version":3,"file":"slot-styles.js","sources":["../../../src/modal-v2/slots/slot-styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport {\n Breakpoint,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../../theme\";\n\n// =============================================================================\n// Tokens and attributes\n// =============================================================================\nexport const slotSpacerHasCloseButtonAttribute = \"data-has-close-button\";\nconst internalSlotSpacerTokens = {\n firstChildMarginTop:\n \"--fds-internal-modalV2-slotSpacer-firstChildMarginTop\",\n} as const;\n\nexport const slotSpacerTokens = {\n firstChildMarginTopWithCloseButton:\n \"--fds-internal-modalV2-slotSpacer-firstChildMarginTopWithCloseButton\",\n firstChildMarginTopNoCloseButton:\n \"--fds-internal-modalV2-slotSpacer-firstChildMarginTopNoCloseButton\",\n\n contentLastChildMarginBottom:\n \"--fds-internal-modalV2-slotSpacer-contentLastChildMarginBottom\",\n\n footerNotFirstChildMarginTop:\n \"--fds-internal-modalV2-slotSpacer-footerNotFirstChildMarginTop\",\n footerLastChildMarginBottom:\n \"--fds-internal-modalV2-slotSpacer-footerLastChildMarginBottom\",\n} as const;\n\n// =============================================================================\n// STYLING\n// =============================================================================\n/** Shared by both the windowed (`modalCard`) and `fullscreenModalCard` variants. */\nexport const cardBase = css`\n background: ${Colour.bg};\n\n display: flex;\n flex-direction: column-reverse;\n`;\n\nexport const modalCard = css`\n width: 40rem;\n margin: ${Spacing[\"spacing-64\"]} auto;\n box-shadow: ${Shadow[\"xs-strong\"]};\n border-radius: ${Radius[\"lg\"]};\n\n max-width: calc(100% - ${Breakpoint[\"xxl-margin\"]} * 2);\n\n ${MediaQuery.MaxWidth.xl} {\n max-width: calc(100% - ${Breakpoint[\"xl-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.lg} {\n max-width: calc(100% - ${Breakpoint[\"lg-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.md} {\n max-width: calc(100% - ${Breakpoint[\"md-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.sm} {\n max-width: calc(100% - ${Breakpoint[\"sm-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.xs} {\n max-width: calc(100% - ${Breakpoint[\"xs-margin\"]} * 2);\n }\n\n ${MediaQuery.MaxWidth.xxs} {\n max-width: calc(100% - ${Breakpoint[\"xxs-margin\"]} * 2);\n }\n`;\n\nexport const fullscreenModalCard = css`\n width: 100%;\n height: 100vh;\n`;\n\nexport const closeButtonContainer = css`\n margin-right: ${Spacing[\"spacing-16\"]};\n margin-left: auto;\n margin-top: ${Spacing[\"spacing-16\"]};\n margin-bottom: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const styledClickableIcon = css`\n padding: 0;\n color: ${Colour.icon};\n\n & svg {\n height: 2rem;\n width: 2rem;\n }\n`;\n\nexport const contentContainer = css`\n margin-right: ${Spacing[\"spacing-64\"]};\n margin-left: ${Spacing[\"spacing-64\"]};\n\n ${MediaQuery.MaxWidth.sm} {\n margin-right: ${Spacing[\"spacing-20\"]};\n margin-left: ${Spacing[\"spacing-20\"]};\n }\n`;\n\nexport const footerContainer = css`\n margin-right: ${Spacing[\"spacing-64\"]};\n margin-left: ${Spacing[\"spacing-64\"]};\n\n ${MediaQuery.MaxWidth.sm} {\n margin-right: ${Spacing[\"spacing-20\"]};\n margin-left: ${Spacing[\"spacing-20\"]};\n }\n\n display: flex;\n flex-direction: row-reverse; /* primary button on right */\n column-gap: ${Spacing[\"spacing-32\"]};\n row-gap: ${Spacing[\"spacing-16\"]};\n\n & > button {\n flex: 1;\n }\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n }\n`;\n\nexport const slotSpacer = css`\n ${slotSpacerTokens.contentLastChildMarginBottom}: initial;\n ${slotSpacerTokens.footerNotFirstChildMarginTop}: initial;\n ${slotSpacerTokens.footerLastChildMarginBottom}: initial;\n ${slotSpacerTokens.firstChildMarginTopWithCloseButton}: initial;\n ${slotSpacerTokens.firstChildMarginTopNoCloseButton}: initial;\n\n ${internalSlotSpacerTokens.firstChildMarginTop}: var(\n ${slotSpacerTokens.firstChildMarginTopNoCloseButton},\n ${Spacing[\"spacing-64\"]}\n );\n\n & > :where(.${contentContainer}:last-child) {\n margin-bottom: var(\n ${slotSpacerTokens.contentLastChildMarginBottom},\n ${Spacing[\"spacing-64\"]}\n );\n }\n\n & > :where(.${footerContainer}:not(:first-child)) {\n margin-top: var(\n ${slotSpacerTokens.footerNotFirstChildMarginTop},\n ${Spacing[\"spacing-32\"]}\n );\n }\n\n & > :where(.${footerContainer}:last-child) {\n margin-bottom: var(\n ${slotSpacerTokens.footerLastChildMarginBottom},\n ${Spacing[\"spacing-64\"]}\n );\n }\n\n &\n > :where(\n .${contentContainer}:first-child, .${footerContainer}:first-child\n ) {\n margin-top: var(${internalSlotSpacerTokens.firstChildMarginTop});\n }\n\n &[${slotSpacerHasCloseButtonAttribute}=\"true\"] {\n ${internalSlotSpacerTokens.firstChildMarginTop}: var(\n ${slotSpacerTokens.firstChildMarginTopWithCloseButton},\n 0\n );\n }\n\n &[${slotSpacerHasCloseButtonAttribute}=\"false\"] {\n ${internalSlotSpacerTokens.firstChildMarginTop}: var(\n ${slotSpacerTokens.firstChildMarginTopNoCloseButton},\n ${Spacing[\"spacing-64\"]}\n );\n }\n`;\n\nexport const fullscreenSlotSpacer = css`\n flex-grow: 1;\n\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n`;\n\nexport const headerContainer = css`\n display: flex;\n align-items: center;\n padding: ${Spacing[\"spacing-16\"]};\n\n &[data-close-button-position=\"right\"] {\n flex-direction: row-reverse;\n }\n`;\n\nexport const headerTitle = css`\n ${Font[\"heading-xs-semibold\"]}\n color: ${Colour.text};\n flex: 1;\n text-align: center;\n`;\n\nexport const headerCloseButton = css`\n padding: 0;\n color: ${Colour.icon};\n flex-shrink: 0;\n\n & svg {\n height: 2rem;\n width: 2rem;\n }\n`;\n\nexport const headerSpacer = css`\n width: 2rem;\n flex-shrink: 0;\n`;\n"],"names":["cardBase","modalCard","fullscreenModalCard","closeButtonContainer","styledClickableIcon","contentContainer","footerContainer","slotSpacer","fullscreenSlotSpacer","headerContainer","headerTitle","headerCloseButton","headerSpacer"],"mappings":"+DAwCO,MAAMA,EAAQ,UAORC,EAAS,WAiCTC,EAAmB,UAKnBC,EAAoB,WAOpBC,EAAmB,WAUnBC,EAAgB,WAUhBC,EAAe,WAuBfC,EAAU,UAuDVC,EAAoB,UAQpBC,EAAe,UAUfC,EAAW,WAOXC,EAAiB,UAWjBC,EAAY"}
@@ -0,0 +1,33 @@
1
+ @layer fds{.cetykyj{background:var(--fds-colour-bg);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse;}
2
+ .m1247joo{width:40rem;margin:var(--fds-spacing-64) auto;box-shadow:var(--fds-shadow-xs-strong);border-radius:var(--fds-radius-lg);max-width:calc(100% - var(--fds-breakpoint-margin-xxl) * 2);}:where(body.fds-breakpoint-xl-max) .m1247joo{max-width:calc(100% - var(--fds-breakpoint-margin-xl) * 2);}:where(body.fds-breakpoint-lg-max) .m1247joo{max-width:calc(100% - var(--fds-breakpoint-margin-lg) * 2);}:where(body.fds-breakpoint-md-max) .m1247joo{max-width:calc(100% - var(--fds-breakpoint-margin-md) * 2);}:where(body.fds-breakpoint-sm-max) .m1247joo{max-width:calc(100% - var(--fds-breakpoint-margin-sm) * 2);}:where(body.fds-breakpoint-xs-max) .m1247joo{max-width:calc(100% - var(--fds-breakpoint-margin-xs) * 2);}:where(body.fds-breakpoint-xxs-max) .m1247joo{max-width:calc(100% - var(--fds-breakpoint-margin-xxs) * 2);}
3
+ .ft53q25{width:100%;height:100vh;}
4
+ .c1ls09wh{margin-right:var(--fds-spacing-16);margin-left:auto;margin-top:var(--fds-spacing-16);margin-bottom:var(--fds-spacing-16);}
5
+ .s1s12qxk{padding:0;color:var(--fds-colour-icon);}.s1s12qxk svg{height:2rem;width:2rem;}
6
+ .c1vsayl1{margin-right:var(--fds-spacing-64);margin-left:var(--fds-spacing-64);}:where(body.fds-breakpoint-sm-max) .c1vsayl1{margin-right:var(--fds-spacing-20);margin-left:var(--fds-spacing-20);}
7
+ .f1adf5mq{margin-right:var(--fds-spacing-64);margin-left:var(--fds-spacing-64);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-column-gap:var(--fds-spacing-32);column-gap:var(--fds-spacing-32);row-gap:var(--fds-spacing-16);}:where(body.fds-breakpoint-sm-max) .f1adf5mq{margin-right:var(--fds-spacing-20);margin-left:var(--fds-spacing-20);}.f1adf5mq>button{-webkit-flex:1;-ms-flex:1;flex:1;}:where(body.fds-breakpoint-md-max) .f1adf5mq{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}
8
+ .sii7rdr{--fds-internal-modalV2-slotSpacer-contentLastChildMarginBottom:initial;--fds-internal-modalV2-slotSpacer-footerNotFirstChildMarginTop:initial;--fds-internal-modalV2-slotSpacer-footerLastChildMarginBottom:initial;--fds-internal-modalV2-slotSpacer-firstChildMarginTopWithCloseButton:initial;--fds-internal-modalV2-slotSpacer-firstChildMarginTopNoCloseButton:initial;--fds-internal-modalV2-slotSpacer-firstChildMarginTop:var(
9
+ --fds-internal-modalV2-slotSpacer-firstChildMarginTopNoCloseButton,
10
+ var(--fds-spacing-64)
11
+ );}.sii7rdr>:where(.c1vsayl1:last-child){margin-bottom:var(
12
+ --fds-internal-modalV2-slotSpacer-contentLastChildMarginBottom,
13
+ var(--fds-spacing-64)
14
+ );}.sii7rdr>:where(.f1adf5mq:not(:first-child)){margin-top:var(
15
+ --fds-internal-modalV2-slotSpacer-footerNotFirstChildMarginTop,
16
+ var(--fds-spacing-32)
17
+ );}.sii7rdr>:where(.f1adf5mq:last-child){margin-bottom:var(
18
+ --fds-internal-modalV2-slotSpacer-footerLastChildMarginBottom,
19
+ var(--fds-spacing-64)
20
+ );}.sii7rdr>:where(
21
+ .c1vsayl1:first-child, .f1adf5mq:first-child
22
+ ){margin-top:var(--fds-internal-modalV2-slotSpacer-firstChildMarginTop);}.sii7rdr[data-has-close-button="true"]{--fds-internal-modalV2-slotSpacer-firstChildMarginTop:var(
23
+ --fds-internal-modalV2-slotSpacer-firstChildMarginTopWithCloseButton,
24
+ 0
25
+ );}.sii7rdr[data-has-close-button="false"]{--fds-internal-modalV2-slotSpacer-firstChildMarginTop:var(
26
+ --fds-internal-modalV2-slotSpacer-firstChildMarginTopNoCloseButton,
27
+ var(--fds-spacing-64)
28
+ );}
29
+ .fa88pah{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;}
30
+ .h3mtfiz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:var(--fds-spacing-16);}.h3mtfiz[data-close-button-position="right"]{-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;}
31
+ .h1evnebr{font-family:var(--fds-font-family-heading);font-variant:var(--fds-font-variant);font-size:var(--fds-font-heading-size-xs);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-heading-lh-xs);letter-spacing:var(--fds-font-heading-ls-xs);color:var(--fds-colour-text);-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;}
32
+ .ht9zr8k{padding:0;color:var(--fds-colour-icon);-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.ht9zr8k svg{height:2rem;width:2rem;}
33
+ .hjbud0c{width:2rem;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}}
@@ -15,6 +15,11 @@ export interface ModalCardProps extends React.HTMLAttributes<HTMLDivElement> {
15
15
  * Ref to the modal card DOM element. When used within `Modal`, the default `ref` is not available and you can specify this instead.
16
16
  */
17
17
  elementRef?: React.Ref<HTMLDivElement> | undefined;
18
+ /**
19
+ * When `true`, the card expands to fill the viewport with no border-radius,
20
+ * padding, or box-shadow.
21
+ */
22
+ fullscreen?: boolean | undefined;
18
23
  }
19
24
  /**
20
25
  * Props for the `ModalV2.CloseButton` slot.
package/navbar/menu.d.ts CHANGED
@@ -2,7 +2,8 @@ import type React from "react";
2
2
  import type { NavItemCommonProps } from "./types";
3
3
  interface Props<T> {
4
4
  items: NavItemCommonProps<T>[];
5
+ selectedId?: string | undefined;
5
6
  onItemClick: (event: React.MouseEvent<HTMLAnchorElement>, item: NavItemCommonProps<T>) => void;
6
7
  }
7
- export declare const Menu: <T>({ items, onItemClick }: Props<T>) => JSX.Element;
8
+ export declare const Menu: <T>({ items, selectedId, onItemClick, }: Props<T>) => JSX.Element;
8
9
  export {};
package/navbar/menu.js CHANGED
@@ -1,2 +1,2 @@
1
- import{__rest as t}from"../_virtual/_tslib.js";import{jsx as e,Fragment as n}from"react/jsx-runtime";import{Typography as i}from"../typography/index.js";import{mobileWrapper as o,menuItem as r,link as s}from"./menu.styles.js";const l=({items:l,onItemClick:m})=>{const a=t=>e=>{e.stopPropagation(),m(e,t)};return(null==l?void 0:l.length)?e("ul",{className:o,children:l.map(((n,o)=>{const{children:l,options:m}=n,c=t(n,["children","options"]),p=`menu__mobile-${o+1}`;return e("li",{className:r,children:e(i.LinkBL,Object.assign({className:s,"data-testid":p},c,m,{onClick:a(n),underlineStyle:"none",children:l}))},o)}))}):e(n,{})};export{l as Menu};
1
+ import{__rest as e}from"../_virtual/_tslib.js";import{jsx as t,Fragment as i}from"react/jsx-runtime";import{Typography as n}from"../typography/index.js";import{mobileWrapper as o,menuItem as r,link as s}from"./menu.styles.js";const l=({items:l,selectedId:a,onItemClick:m})=>{const c=e=>t=>{t.stopPropagation(),m(t,e)};return(null==l?void 0:l.length)?t("ul",{className:o,children:l.map(((i,o)=>{const{children:l,options:m,weight:d}=i,p=e(i,["children","options","weight"]),h=`menu__mobile-${o+1}`,u=i.id===a;return t("li",{className:r,children:t(n.LinkBL,Object.assign({className:s,"data-testid":h},p,m,{weight:u?"bold":d,"aria-current":u?"page":void 0,onClick:c(i),underlineStyle:"none",children:l}))},o)}))}):t(i,{})};export{l as Menu};
2
2
  //# sourceMappingURL=menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sources":["../../src/navbar/menu.tsx"],"sourcesContent":["import type React from \"react\";\n\nimport { Typography } from \"../typography\";\nimport * as styles from \"./menu.styles\";\nimport type { NavItemCommonProps } from \"./types\";\n\ninterface Props<T> {\n items: NavItemCommonProps<T>[];\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => void;\n}\n\nexport const Menu = <T,>({ items, onItemClick }: Props<T>): JSX.Element => {\n const handleLinkClick = (item: NavItemCommonProps<T>) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation(); // in mobile, this prevents the drawer from intercepting event\n onItemClick(event, item);\n };\n };\n\n if (!items?.length) return <></>;\n\n return (\n <ul className={styles.mobileWrapper}>\n {items.map((item, index) => {\n const { children, options, ...otherItemAttrs } = item;\n const testId = `menu__mobile-${index + 1}`;\n\n return (\n <li key={index} className={styles.menuItem}>\n <Typography.LinkBL\n className={styles.link}\n data-testid={testId}\n {...otherItemAttrs}\n {...options}\n onClick={handleLinkClick(item)}\n underlineStyle=\"none\"\n >\n {children}\n </Typography.LinkBL>\n </li>\n );\n })}\n </ul>\n );\n};\n"],"names":["Menu","items","onItemClick","handleLinkClick","item","event","stopPropagation","length","_jsx","className","styles.mobileWrapper","children","map","index","options","otherItemAttrs","__rest","testId","styles.menuItem","Typography","LinkBL","styles.link","onClick","underlineStyle"],"mappings":"kOAcO,MAAMA,EAAO,EAAOC,QAAOC,kBAC9B,MAAMC,EAAmBC,GACbC,IACJA,EAAMC,kBACNJ,EAAYG,EAAOD,EAAK,EAIhC,OAAKH,aAAK,EAALA,EAAOM,QAGRC,EAAA,KAAA,CAAIC,UAAWC,EAAoBC,SAC9BV,EAAMW,KAAI,CAACR,EAAMS,KACd,MAAMF,SAAEA,EAAQG,QAAEA,GAA+BV,EAAnBW,EAAcC,EAAKZ,EAA3C,CAAA,WAAA,YACAa,EAAS,gBAAgBJ,EAAQ,IAEvC,OACIL,EAAA,KAAA,CAAgBC,UAAWS,EAAeP,SACtCH,EAACW,EAAWC,sBACRX,UAAWY,gBACEJ,GACTF,EACAD,EAAO,CACXQ,QAASnB,EAAgBC,GACzBmB,eAAe,gBAEdZ,MATAE,EAWJ,MApBML,OAuBlB"}
1
+ {"version":3,"file":"menu.js","sources":["../../src/navbar/menu.tsx"],"sourcesContent":["import type React from \"react\";\n\nimport { Typography } from \"../typography\";\nimport * as styles from \"./menu.styles\";\nimport type { NavItemCommonProps } from \"./types\";\n\ninterface Props<T> {\n items: NavItemCommonProps<T>[];\n selectedId?: string | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => void;\n}\n\nexport const Menu = <T,>({\n items,\n selectedId,\n onItemClick,\n}: Props<T>): JSX.Element => {\n const handleLinkClick = (item: NavItemCommonProps<T>) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation(); // in mobile, this prevents the drawer from intercepting event\n onItemClick(event, item);\n };\n };\n\n if (!items?.length) return <></>;\n\n return (\n <ul className={styles.mobileWrapper}>\n {items.map((item, index) => {\n const { children, options, weight, ...otherItemAttrs } = item;\n const testId = `menu__mobile-${index + 1}`;\n const selected = item.id === selectedId;\n\n return (\n <li key={index} className={styles.menuItem}>\n <Typography.LinkBL\n className={styles.link}\n data-testid={testId}\n {...otherItemAttrs}\n {...options}\n weight={selected ? \"bold\" : weight}\n aria-current={selected ? \"page\" : undefined}\n onClick={handleLinkClick(item)}\n underlineStyle=\"none\"\n >\n {children}\n </Typography.LinkBL>\n </li>\n );\n })}\n </ul>\n );\n};\n"],"names":["Menu","items","selectedId","onItemClick","handleLinkClick","item","event","stopPropagation","length","_jsx","className","styles.mobileWrapper","children","map","index","options","weight","otherItemAttrs","__rest","testId","selected","id","styles.menuItem","Typography","LinkBL","styles.link","undefined","onClick","underlineStyle"],"mappings":"kOAeO,MAAMA,EAAO,EAChBC,QACAC,aACAC,kBAEA,MAAMC,EAAmBC,GACbC,IACJA,EAAMC,kBACNJ,EAAYG,EAAOD,EAAK,EAIhC,OAAKJ,aAAK,EAALA,EAAOO,QAGRC,EAAA,KAAA,CAAIC,UAAWC,EAAoBC,SAC9BX,EAAMY,KAAI,CAACR,EAAMS,KACd,MAAMF,SAAEA,EAAQG,QAAEA,EAAOC,OAAEA,GAA8BX,EAAnBY,EAAcC,EAAKb,EAAnD,CAAA,WAAA,UAAA,WACAc,EAAS,gBAAgBL,EAAQ,IACjCM,EAAWf,EAAKgB,KAAOnB,EAE7B,OACIO,EAAA,KAAA,CAAgBC,UAAWY,EAAeV,SACtCH,EAACc,EAAWC,sBACRd,UAAWe,EAAW,cACTN,GACTF,EACAF,EAAO,CACXC,OAAQI,EAAW,OAASJ,EAAM,eACpBI,EAAW,YAASM,EAClCC,QAASvB,EAAgBC,GACzBuB,eAAe,OAAMhB,SAEpBA,MAXAE,EAaJ,MAvBML,OA0BlB"}
@@ -1,2 +1,2 @@
1
- import"./menu.styles_gdpqc.css";const t="m1lq4qov",s="m6cy0t7",c="l1t9jy07";export{c as link,s as menuItem,t as mobileWrapper};
1
+ import"./menu.styles_zkjexa.css";const t="m1lq4qov",s="m6cy0t7",e="l1t9jy07";export{e as link,s as menuItem,t as mobileWrapper};
2
2
  //# sourceMappingURL=menu.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"menu.styles.js","sources":["../../src/navbar/menu.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { lineClampCss } from \"../shared/styles\";\nimport { Border, Colour, Radius, Spacing } from \"../theme\";\n\nexport const mobileWrapper = css`\n list-style: none;\n display: flex;\n flex-direction: column;\n\n margin: 0;\n padding: 0;\n\n border-left: ${Border[\"width-040\"]} solid ${Colour[\"border-selected\"]};\n`;\n\nexport const menuItem = css`\n width: 100%;\n display: flex;\n`;\n\nexport const link = css`\n width: 100%;\n text-align: left;\n color: ${Colour[\"text\"]};\n\n margin: 0 ${Spacing[\"spacing-8\"]};\n\n /* use border, as padding still shows an extra line after the ellipsis */\n border: ${Border[\"solid\"]} transparent;\n border-width: ${Spacing[\"spacing-12\"]} ${Spacing[\"spacing-8\"]};\n border-radius: ${Radius[\"md\"]};\n\n ${lineClampCss(2)}\n white-space: pre-wrap;\n\n &:hover,\n &:active,\n &:focus {\n background-color: ${Colour[\"bg-hover\"]};\n color: ${Colour[\"text\"]};\n }\n`;\n"],"names":["mobileWrapper","menuItem","link"],"mappings":"sDAKO,MAAMA,EAAa,WAWbC,EAAQ,UAKRC,EAAI"}
1
+ {"version":3,"file":"menu.styles.js","sources":["../../src/navbar/menu.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { lineClampCss } from \"../shared/styles\";\nimport { Border, Colour, Radius, Spacing } from \"../theme\";\n\nexport const mobileWrapper = css`\n list-style: none;\n display: flex;\n flex-direction: column;\n\n margin: 0;\n padding: 0;\n\n border-left: ${Border[\"width-040\"]} solid ${Colour[\"border-selected\"]};\n`;\n\nexport const menuItem = css`\n width: 100%;\n display: flex;\n`;\n\nexport const link = css`\n width: 100%;\n text-align: left;\n color: ${Colour[\"text\"]};\n\n margin: 0 ${Spacing[\"spacing-8\"]};\n\n /* use border, as padding still shows an extra line after the ellipsis */\n border: ${Border[\"solid\"]} transparent;\n border-width: 10px ${Spacing[\"spacing-16\"]} 10px ${Spacing[\"spacing-24\"]};\n border-radius: ${Radius[\"md\"]};\n\n ${lineClampCss(2)}\n white-space: pre-wrap;\n\n &:hover,\n &:active,\n &:focus {\n background-color: ${Colour[\"bg-hover\"]};\n color: ${Colour[\"text\"]};\n }\n`;\n"],"names":["mobileWrapper","menuItem","link"],"mappings":"uDAKO,MAAMA,EAAa,WAWbC,EAAQ,UAKRC,EAAI"}
@@ -1,3 +1,3 @@
1
1
  @layer fds{.m1lq4qov{list-style:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin:0;padding:0;border-left:var(--fds-border-width-040) solid var(--fds-colour-border-selected);}
2
2
  .m6cy0t7{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}
3
- .l1t9jy07{width:100%;text-align:left;color:var(--fds-colour-text);margin:0 var(--fds-spacing-8);border:var(--fds-border-style-solid) transparent;border-width:var(--fds-spacing-12) var(--fds-spacing-8);border-radius:var(--fds-radius-md);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;white-space:pre-wrap;}.l1t9jy07:hover,.l1t9jy07:active,.l1t9jy07:focus{background-color:var(--fds-colour-bg-hover);color:var(--fds-colour-text);}}
3
+ .l1t9jy07{width:100%;text-align:left;color:var(--fds-colour-text);margin:0 var(--fds-spacing-8);border:var(--fds-border-style-solid) transparent;border-width:10px var(--fds-spacing-16) 10px var(--fds-spacing-24);border-radius:var(--fds-radius-md);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;white-space:pre-wrap;}.l1t9jy07:hover,.l1t9jy07:active,.l1t9jy07:focus{background-color:var(--fds-colour-bg-hover);color:var(--fds-colour-text);}}
@@ -1,2 +1,2 @@
1
- import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as i,jsxs as r}from"react/jsx-runtime";import{ChevronUpIcon as t}from"@lifesg/react-icons/chevron-up";import a from"clsx";import{useState as l,useRef as s,useEffect as o}from"react";import{Menu as c}from"../menu/menu.js";import{ClickableIcon as d}from"../shared/clickable-icon/clickable-icon.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as m}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{Menu as u}from"./menu.js";import{mobileWrapper as p,wrapper as h,wrapperAlignLeft as b,link as v,linkSelected as f,linkItem as g,linkItemHiddenBranding as j,linkWeightRegular as N,linkWeightSemibold as k,linkWeightBold as x,linkLabel as $,linkButton as C,chevronIcon as M,chevronIconDesktop as I,chevronIconSelected as O,subMenuExpanded as _,linkIndicator as y,linkIndicatorSelected as L,linkIconContainer as P,expandCollapseButton as w}from"./navbar-items.styles.js";const E=({items:E,selectedId:D,mobile:A=!1,hideNavBranding:B,hideLinkIndicator:F=!1,onItemClick:H})=>{const[S,T]=l(-1),[q,z]=l(!1),[G,J]=l(null),K=s(null),Q=m();o((()=>{const e=e=>{K.current&&!K.current.contains(e.target)&&(z(!1),T(-1),J(null))};return document.addEventListener("click",e,!0),()=>{document.removeEventListener("click",e,!0)}}),[]);const R=(e,n)=>i=>{var r;if(i.stopPropagation(),A&&(null===(r=e.subMenu)||void 0===r?void 0:r.length)){const e=!(S===n&&q);T(n),z(e)}H(i,e)},U=(e,n)=>{e.stopPropagation(),H(e,n),z(!1),T(-1)},V=(e,i)=>n(c.Content,{id:i,children:n(c.Section,{showDivider:!1,children:e.map(((e,i)=>n(c.Link,{href:e.href,children:e.children},`${e.id}-${i}`)))})}),W=e=>n(u,{items:e,onItemClick:U}),X=(l,s)=>{const{children:o,options:m,subMenu:u}=l,p=e(l,["children","options","subMenu"]),h=!!(null==u?void 0:u.length),b=(e=>{var n;return e.id===D||!!(null===(n=e.subMenu)||void 0===n?void 0:n.length)&&!!e.subMenu.find((e=>e.id===D))})(l),H=!A&&h&&G===s,T=A&&h&&S===s&&q,z=H||T,K=null!==G?G===s:b,U=!F&&K,X=A?`link__mobile-${s+1}`:`link__${s+1}`,Y=()=>U?n("div",{"data-testid":`${X}-indicator`,className:a(y,K&&L)}):null,Z=a(v,(e=>{switch(e){case"bold":return x;case"semibold":return k;default:return N}})(K?A?"bold":"semibold":"regular"),K&&f);return n("li",{className:a(g,B&&j),children:h?(e=>{const v=`navbar-submenu-${Q}-${l.id}`;return A?r(i,{children:[r("a",Object.assign({"data-testid":X,className:Z},p,{"aria-current":b?"page":void 0,"aria-haspopup":"menu","aria-expanded":z,onClick:R(l,s)},m,{children:[n("div",{className:$,children:o}),Y(),A&&h?n("div",{className:P,children:n(d,{"data-testid":`${X}-expand-collapse-button`,className:a(w,T&&_),focusHighlight:!1,focusOutline:"browser","aria-label":T?"Collapse":"Expand",children:n(t,{className:a(M,K&&O)})})}):null]})),T&&W(u)]}):n(c,{position:e?"bottom-end":"bottom",customOffset:0,menuContent:V(u,v),triggerOnFocus:!0,isModal:!1,onPopoverAppear:()=>J(s),onPopoverDismiss:()=>{J((e=>e===s?null:e))},children:r("button",Object.assign({type:"button",tabIndex:0,"data-testid":X,className:a(Z,C),"aria-haspopup":"menu","aria-expanded":z},m,{children:[n("div",{className:$,children:o}),Y(),n(t,{className:a(M,I,K&&O,H&&_)})]}))})})(s===E.length-1):r("a",Object.assign({tabIndex:0,"data-testid":X,className:Z},p,{"aria-current":b?"page":void 0,onClick:R(l,s)},m,{children:[n("div",{className:$,children:o}),Y()]}))},s)},Y=()=>E.map(((e,i)=>{var r;return"component"===e.itemType?n("li",{children:null!==(r=e.children)&&void 0!==r?r:null},i):X(e,i)}));return E&&E.length>0?n("ul",A?{ref:K,className:p,children:Y()}:{ref:K,className:a(h,B&&b),children:Y()}):n(i,{})};export{E as NavbarItems};
1
+ import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as i,jsxs as r}from"react/jsx-runtime";import{ChevronUpIcon as t}from"@lifesg/react-icons/chevron-up";import l from"clsx";import{useState as a,useRef as s,useEffect as o}from"react";import{Menu as c}from"../menu/menu.js";import{ClickableIcon as d}from"../shared/clickable-icon/clickable-icon.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as m}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{Menu as u}from"./menu.js";import{mobileWrapper as p,wrapper as h,wrapperAlignLeft as b,link as v,linkSelected as f,linkItem as g,linkItemHiddenBranding as j,linkWeightRegular as N,linkWeightSemibold as k,linkWeightBold as x,linkLabel as I,linkButton as $,chevronIcon as C,chevronIconDesktop as y,chevronIconSelected as M,subMenuExpanded as O,linkIndicator as _,linkIndicatorSelected as L,linkIconContainer as P,expandCollapseButton as w}from"./navbar-items.styles.js";const E=({items:E,selectedId:D,mobile:T=!1,hideNavBranding:A,hideLinkIndicator:B=!1,onItemClick:F})=>{const[H,S]=a(null),q=s(null),z=m(),G=e=>{var n;return!!(null===(n=e.subMenu)||void 0===n?void 0:n.some((e=>e.id===D)))},J=T?E.findIndex((e=>"component"!==e.itemType&&G(e))):-1,K=J<0?null:J;o((()=>{T&&S(K)}),[T,K]),o((()=>{if(T)return;const e=e=>{q.current&&!q.current.contains(e.target)&&S(null)};return document.addEventListener("click",e,!0),()=>{document.removeEventListener("click",e,!0)}}),[T]);const Q=(e,n)=>i=>{i.stopPropagation(),T&&S((i=>{var r;return(null===(r=e.subMenu)||void 0===r?void 0:r.length)&&i!==n?n:null})),F(i,e)},R=(e,n)=>{e.stopPropagation(),F(e,n)},U=(e,i)=>n(c.Content,{id:i,children:n(c.Section,{showDivider:!1,children:e.map(((e,i)=>n(c.Link,{href:e.href,children:e.children},`${e.id}-${i}`)))})}),V=e=>n(u,{items:e,selectedId:D,onItemClick:R}),W=(a,s)=>{const{children:o,options:m,subMenu:u}=a,p=e(a,["children","options","subMenu"]),h=!!(null==u?void 0:u.length),b=(e=>e.id===D||G(e))(a),F=!T&&h&&H===s,q=T&&h&&H===s,J=F||q,K=T||null===H?b:H===s,R=!B&&K,W=T?`link__mobile-${s+1}`:`link__${s+1}`,X=()=>R?n("div",{"data-testid":`${W}-indicator`,className:l(_,K&&L)}):null,Y=l(v,(e=>{switch(e){case"bold":return x;case"semibold":return k;default:return N}})(K?T?"bold":"semibold":"regular"),K&&f);return n("li",{className:l(g,A&&j),children:h?(e=>{const v=`navbar-submenu-${z}-${a.id}`;return T?r(i,{children:[r("a",Object.assign({"data-testid":W,className:Y},p,{"aria-current":b?"page":void 0,"aria-haspopup":"menu","aria-expanded":J,onClick:Q(a,s)},m,{children:[n("div",{className:I,children:o}),X(),T&&h?n("div",{className:P,children:n(d,{"data-testid":`${W}-expand-collapse-button`,className:l(w,q&&O),focusHighlight:!1,focusOutline:"browser","aria-label":q?"Collapse":"Expand",children:n(t,{className:l(C,K&&M)})})}):null]})),q&&V(u)]}):n(c,{position:e?"bottom-end":"bottom",customOffset:0,menuContent:U(u,v),triggerOnFocus:!0,isModal:!1,onPopoverAppear:()=>{S(s)},onPopoverDismiss:()=>{S((e=>e===s?null:e))},children:r("button",Object.assign({type:"button",tabIndex:0,"data-testid":W,className:l(Y,$),"aria-haspopup":"menu","aria-expanded":J},m,{children:[n("div",{className:I,children:o}),X(),n(t,{className:l(C,y,K&&M,F&&O)})]}))})})(s===E.length-1):r("a",Object.assign({tabIndex:0,"data-testid":W,className:Y},p,{"aria-current":b?"page":void 0,onClick:Q(a,s)},m,{children:[n("div",{className:I,children:o}),X()]}))},s)},X=()=>E.map(((e,i)=>{var r;return"component"===e.itemType?n("li",{children:null!==(r=e.children)&&void 0!==r?r:null},i):W(e,i)}));return E&&E.length>0?n("ul",T?{ref:q,className:p,children:X()}:{ref:q,className:l(h,A&&b),children:X()}):n(i,{})};export{E as NavbarItems};
2
2
  //# sourceMappingURL=navbar-items.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navbar-items.js","sources":["../../src/navbar/navbar-items.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { Menu as DesktopMenu } from \"../menu\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport type { TypographyWeight } from \"../typography\";\nimport { useId } from \"../util\";\nimport { Menu as MobileMenu } from \"./menu\";\nimport * as styles from \"./navbar-items.styles\";\nimport type {\n NavItemCommonProps,\n NavItemLinkProps,\n NavItemProps,\n} from \"./types\";\n\nconst getLinkWeightClass = (weight: TypographyWeight) => {\n switch (weight) {\n case \"bold\":\n return styles.linkWeightBold;\n case \"semibold\":\n return styles.linkWeightSemibold;\n case \"regular\":\n default:\n return styles.linkWeightRegular;\n }\n};\n\ninterface Props<T> {\n items: NavItemProps<T>[];\n selectedId?: string | undefined;\n /** toggle for mobile or desktop view */\n mobile?: boolean | undefined;\n hideNavBranding?: boolean | undefined;\n /** hide the selected LinkIndicator */\n hideLinkIndicator?: boolean | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<T> | NavItemCommonProps<T>\n ) => void;\n}\n\nexport const NavbarItems = <T,>({\n items,\n selectedId,\n mobile = false,\n hideNavBranding,\n hideLinkIndicator = false,\n onItemClick,\n}: Props<T>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [selectedIndex, setSelectedIndex] = useState<number>(-1);\n const [showSubMenu, setShowSubMenu] = useState<boolean>(false);\n const [openSubMenuIndex, setOpenSubMenuIndex] = useState<number | null>(\n null\n );\n const listRef = useRef<HTMLUListElement>(null);\n const instanceId = useId();\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const resetAll = () => {\n setShowSubMenu(false);\n setSelectedIndex(-1);\n setOpenSubMenuIndex(null);\n };\n\n const closeMobileSubMenu = () => {\n setShowSubMenu(false);\n setSelectedIndex(-1);\n };\n\n const checkSelected = (item: NavItemLinkProps<T>): boolean => {\n if (item.id === selectedId) return true;\n if (item.subMenu?.length) {\n return !!item.subMenu.find((s) => s.id === selectedId);\n }\n return false;\n };\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n listRef.current &&\n !listRef.current.contains(event.target as Node)\n ) {\n resetAll();\n }\n };\n document.addEventListener(\"click\", handleClickOutside, true);\n return () => {\n document.removeEventListener(\"click\", handleClickOutside, true);\n };\n }, []);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleLinkClick = (item: NavItemLinkProps<T>, index: number) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n\n // mobile expands inline when link has submenu\n if (mobile && item.subMenu?.length) {\n const nextExpanded = !(selectedIndex === index && showSubMenu);\n setSelectedIndex(index);\n setShowSubMenu(nextExpanded);\n }\n\n onItemClick(event, item);\n };\n };\n\n const handleMobileSubLinkClick = (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => {\n event.stopPropagation();\n onItemClick(event, item);\n closeMobileSubMenu();\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderDesktopSubMenu = (\n subMenu: NavItemCommonProps<T>[],\n subMenuId: string\n ) => (\n <DesktopMenu.Content id={subMenuId}>\n <DesktopMenu.Section showDivider={false}>\n {subMenu.map((item, subIndex) => (\n <DesktopMenu.Link\n key={`${item.id}-${subIndex}`}\n href={item.href}\n >\n {item.children}\n </DesktopMenu.Link>\n ))}\n </DesktopMenu.Section>\n </DesktopMenu.Content>\n );\n\n const renderMobileSubMenu = (subMenu: NavItemCommonProps<T>[]) => (\n <MobileMenu items={subMenu} onItemClick={handleMobileSubLinkClick} />\n );\n\n const renderLinkItem = (item: NavItemLinkProps<T>, index: number) => {\n const { children, options, subMenu, ...otherItemAttrs } = item;\n\n const hasSubMenu = !!subMenu?.length;\n\n const isRouteSelected = checkSelected(item);\n\n // desktop popover open state\n const isDesktopExpanded =\n !mobile && hasSubMenu && openSubMenuIndex === index;\n\n // mobile inline expanded state\n const isMobileExpanded =\n mobile && hasSubMenu && selectedIndex === index && showSubMenu;\n\n const isExpanded = isDesktopExpanded || isMobileExpanded;\n\n const selected =\n openSubMenuIndex !== null\n ? openSubMenuIndex === index\n : isRouteSelected;\n\n const showIndicator = !hideLinkIndicator && selected;\n\n const textWeight: TypographyWeight = selected\n ? mobile\n ? \"bold\"\n : \"semibold\"\n : \"regular\";\n\n const testId = mobile\n ? `link__mobile-${index + 1}`\n : `link__${index + 1}`;\n\n const renderIndicator = () =>\n showIndicator ? (\n <div\n data-testid={`${testId}-indicator`}\n className={clsx(\n styles.linkIndicator,\n selected && styles.linkIndicatorSelected\n )}\n />\n ) : null;\n\n const renderMobileChevron = () =>\n mobile && hasSubMenu ? (\n <div className={styles.linkIconContainer}>\n <ClickableIcon\n data-testid={`${testId}-expand-collapse-button`}\n className={clsx(\n styles.expandCollapseButton,\n isMobileExpanded && styles.subMenuExpanded\n )}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={isMobileExpanded ? \"Collapse\" : \"Expand\"}\n >\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n selected && styles.chevronIconSelected\n )}\n />\n </ClickableIcon>\n </div>\n ) : null;\n\n const linkClassName = clsx(\n styles.link,\n getLinkWeightClass(textWeight),\n selected && styles.linkSelected\n );\n\n const renderLink = () => (\n <a\n tabIndex={0}\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n </a>\n );\n\n const renderLinkWithSubmenu = (isLastItem: boolean) => {\n const subMenuId = `navbar-submenu-${instanceId}-${item.id}`;\n\n if (mobile) {\n return (\n <>\n <a\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n {renderMobileChevron()}\n </a>\n\n {isMobileExpanded && renderMobileSubMenu(subMenu!)}\n </>\n );\n }\n\n return (\n <DesktopMenu\n position={isLastItem ? \"bottom-end\" : \"bottom\"}\n customOffset={0}\n menuContent={renderDesktopSubMenu(subMenu!, subMenuId)}\n triggerOnFocus\n isModal={false}\n onPopoverAppear={() => setOpenSubMenuIndex(index)}\n onPopoverDismiss={() => {\n setOpenSubMenuIndex((prev) =>\n prev === index ? null : prev\n );\n }}\n >\n <button\n type=\"button\"\n tabIndex={0}\n data-testid={testId}\n className={clsx(linkClassName, styles.linkButton)}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n styles.chevronIconDesktop,\n selected && styles.chevronIconSelected,\n isDesktopExpanded && styles.subMenuExpanded\n )}\n />\n </button>\n </DesktopMenu>\n );\n };\n\n return (\n <li\n key={index}\n className={clsx(\n styles.linkItem,\n hideNavBranding && styles.linkItemHiddenBranding\n )}\n >\n {hasSubMenu\n ? renderLinkWithSubmenu(index === items.length - 1)\n : renderLink()}\n </li>\n );\n };\n\n const renderItems = () =>\n items.map((item, index) => {\n switch (item.itemType) {\n case \"component\": {\n return <li key={index}>{item.children ?? null}</li>;\n }\n case \"link\":\n default: {\n return renderLinkItem(item as NavItemLinkProps<T>, index);\n }\n }\n });\n\n if (items && items.length > 0) {\n return mobile ? (\n <ul ref={listRef} className={styles.mobileWrapper}>\n {renderItems()}\n </ul>\n ) : (\n <ul\n ref={listRef}\n className={clsx(\n styles.wrapper,\n hideNavBranding && styles.wrapperAlignLeft\n )}\n >\n {renderItems()}\n </ul>\n );\n }\n\n return <></>;\n};\n"],"names":["NavbarItems","items","selectedId","mobile","hideNavBranding","hideLinkIndicator","onItemClick","selectedIndex","setSelectedIndex","useState","showSubMenu","setShowSubMenu","openSubMenuIndex","setOpenSubMenuIndex","listRef","useRef","instanceId","useId","useEffect","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","handleLinkClick","item","index","stopPropagation","_a","subMenu","length","nextExpanded","handleMobileSubLinkClick","renderDesktopSubMenu","subMenuId","_jsx","DesktopMenu","Content","id","children","Section","showDivider","map","subIndex","Link","href","renderMobileSubMenu","MobileMenu","renderLinkItem","options","otherItemAttrs","__rest","hasSubMenu","isRouteSelected","find","s","checkSelected","isDesktopExpanded","isMobileExpanded","isExpanded","selected","showIndicator","testId","renderIndicator","className","clsx","styles.linkIndicator","styles.linkIndicatorSelected","linkClassName","styles.link","weight","styles.linkWeightBold","styles.linkWeightSemibold","styles.linkWeightRegular","getLinkWeightClass","styles.linkSelected","styles.linkItem","styles.linkItemHiddenBranding","isLastItem","_jsxs","_Fragment","Object","assign","undefined","onClick","styles.linkLabel","styles.linkIconContainer","ClickableIcon","styles.expandCollapseButton","styles.subMenuExpanded","focusHighlight","focusOutline","ChevronUpIcon","styles.chevronIcon","styles.chevronIconSelected","position","customOffset","menuContent","triggerOnFocus","isModal","onPopoverAppear","onPopoverDismiss","prev","type","tabIndex","styles.linkButton","styles.chevronIconDesktop","renderLinkWithSubmenu","renderItems","itemType","ref","styles.mobileWrapper","styles.wrapper","styles.wrapperAlignLeft"],"mappings":"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"}
1
+ {"version":3,"file":"navbar-items.js","sources":["../../src/navbar/navbar-items.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { Menu as DesktopMenu } from \"../menu\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport type { TypographyWeight } from \"../typography\";\nimport { useId } from \"../util\";\nimport { Menu as MobileMenu } from \"./menu\";\nimport * as styles from \"./navbar-items.styles\";\nimport type {\n NavItemCommonProps,\n NavItemLinkProps,\n NavItemProps,\n} from \"./types\";\n\nconst getLinkWeightClass = (weight: TypographyWeight) => {\n switch (weight) {\n case \"bold\":\n return styles.linkWeightBold;\n case \"semibold\":\n return styles.linkWeightSemibold;\n case \"regular\":\n default:\n return styles.linkWeightRegular;\n }\n};\n\ninterface Props<T> {\n items: NavItemProps<T>[];\n selectedId?: string | undefined;\n /** toggle for mobile or desktop view */\n mobile?: boolean | undefined;\n hideNavBranding?: boolean | undefined;\n /** hide the selected LinkIndicator */\n hideLinkIndicator?: boolean | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<T> | NavItemCommonProps<T>\n ) => void;\n}\n\nexport const NavbarItems = <T,>({\n items,\n selectedId,\n mobile = false,\n hideNavBranding,\n hideLinkIndicator = false,\n onItemClick,\n}: Props<T>): JSX.Element => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n const listRef = useRef<HTMLUListElement>(null);\n const instanceId = useId();\n\n // =============================================================================\n // HELPERS\n // =============================================================================\n const hasSelectedSubMenuItem = (item: NavItemLinkProps<T>): boolean =>\n !!item.subMenu?.some((subItem) => subItem.id === selectedId);\n\n const checkSelected = (item: NavItemLinkProps<T>): boolean =>\n item.id === selectedId || hasSelectedSubMenuItem(item);\n\n const itemIndexWithSelectedSubItem = mobile\n ? items.findIndex(\n (item) =>\n item.itemType !== \"component\" &&\n hasSelectedSubMenuItem(item as NavItemLinkProps<T>)\n )\n : -1;\n const initialExpandedItemIndex =\n itemIndexWithSelectedSubItem < 0 ? null : itemIndexWithSelectedSubItem;\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n\n useEffect(() => {\n if (!mobile) return;\n\n setSelectedIndex(initialExpandedItemIndex);\n }, [mobile, initialExpandedItemIndex]);\n\n useEffect(() => {\n if (mobile) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (\n listRef.current &&\n !listRef.current.contains(event.target as Node)\n ) {\n setSelectedIndex(null);\n }\n };\n document.addEventListener(\"click\", handleClickOutside, true);\n return () => {\n document.removeEventListener(\"click\", handleClickOutside, true);\n };\n }, [mobile]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleLinkClick = (item: NavItemLinkProps<T>, index: number) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation();\n\n // mobile expands inline when link has submenu\n if (mobile) {\n setSelectedIndex((prev) =>\n item.subMenu?.length && prev !== index ? index : null\n );\n }\n\n onItemClick(event, item);\n };\n };\n\n const handleMobileSubLinkClick = (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => {\n event.stopPropagation();\n onItemClick(event, item);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderDesktopSubMenu = (\n subMenu: NavItemCommonProps<T>[],\n subMenuId: string\n ) => (\n <DesktopMenu.Content id={subMenuId}>\n <DesktopMenu.Section showDivider={false}>\n {subMenu.map((item, subIndex) => (\n <DesktopMenu.Link\n key={`${item.id}-${subIndex}`}\n href={item.href}\n >\n {item.children}\n </DesktopMenu.Link>\n ))}\n </DesktopMenu.Section>\n </DesktopMenu.Content>\n );\n\n const renderMobileSubMenu = (subMenu: NavItemCommonProps<T>[]) => (\n <MobileMenu\n items={subMenu}\n selectedId={selectedId}\n onItemClick={handleMobileSubLinkClick}\n />\n );\n\n const renderLinkItem = (item: NavItemLinkProps<T>, index: number) => {\n const { children, options, subMenu, ...otherItemAttrs } = item;\n\n const hasSubMenu = !!subMenu?.length;\n\n const isRouteSelected = checkSelected(item);\n\n // desktop popover open state\n const isDesktopExpanded =\n !mobile && hasSubMenu && selectedIndex === index;\n\n // mobile inline expanded state\n const isMobileExpanded =\n mobile && hasSubMenu && selectedIndex === index;\n\n const isExpanded = isDesktopExpanded || isMobileExpanded;\n\n const selected =\n !mobile && selectedIndex !== null\n ? selectedIndex === index\n : isRouteSelected;\n\n const showIndicator = !hideLinkIndicator && selected;\n\n const textWeight: TypographyWeight = selected\n ? mobile\n ? \"bold\"\n : \"semibold\"\n : \"regular\";\n\n const testId = mobile\n ? `link__mobile-${index + 1}`\n : `link__${index + 1}`;\n\n const renderIndicator = () =>\n showIndicator ? (\n <div\n data-testid={`${testId}-indicator`}\n className={clsx(\n styles.linkIndicator,\n selected && styles.linkIndicatorSelected\n )}\n />\n ) : null;\n\n const renderMobileChevron = () =>\n mobile && hasSubMenu ? (\n <div className={styles.linkIconContainer}>\n <ClickableIcon\n data-testid={`${testId}-expand-collapse-button`}\n className={clsx(\n styles.expandCollapseButton,\n isMobileExpanded && styles.subMenuExpanded\n )}\n focusHighlight={false}\n focusOutline=\"browser\"\n aria-label={isMobileExpanded ? \"Collapse\" : \"Expand\"}\n >\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n selected && styles.chevronIconSelected\n )}\n />\n </ClickableIcon>\n </div>\n ) : null;\n\n const linkClassName = clsx(\n styles.link,\n getLinkWeightClass(textWeight),\n selected && styles.linkSelected\n );\n\n const renderLink = () => (\n <a\n tabIndex={0}\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n </a>\n );\n\n const renderLinkWithSubmenu = (isLastItem: boolean) => {\n const subMenuId = `navbar-submenu-${instanceId}-${item.id}`;\n\n if (mobile) {\n return (\n <>\n <a\n data-testid={testId}\n className={linkClassName}\n {...otherItemAttrs}\n aria-current={isRouteSelected ? \"page\" : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n onClick={handleLinkClick(item, index)}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n {renderMobileChevron()}\n </a>\n\n {isMobileExpanded && renderMobileSubMenu(subMenu!)}\n </>\n );\n }\n\n return (\n <DesktopMenu\n position={isLastItem ? \"bottom-end\" : \"bottom\"}\n customOffset={0}\n menuContent={renderDesktopSubMenu(subMenu!, subMenuId)}\n triggerOnFocus\n isModal={false}\n onPopoverAppear={() => {\n setSelectedIndex(index);\n }}\n onPopoverDismiss={() => {\n setSelectedIndex((prev) =>\n prev === index ? null : prev\n );\n }}\n >\n <button\n type=\"button\"\n tabIndex={0}\n data-testid={testId}\n className={clsx(linkClassName, styles.linkButton)}\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n {...options}\n >\n <div className={styles.linkLabel}>{children}</div>\n {renderIndicator()}\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n styles.chevronIconDesktop,\n selected && styles.chevronIconSelected,\n isDesktopExpanded && styles.subMenuExpanded\n )}\n />\n </button>\n </DesktopMenu>\n );\n };\n\n return (\n <li\n key={index}\n className={clsx(\n styles.linkItem,\n hideNavBranding && styles.linkItemHiddenBranding\n )}\n >\n {hasSubMenu\n ? renderLinkWithSubmenu(index === items.length - 1)\n : renderLink()}\n </li>\n );\n };\n\n const renderItems = () =>\n items.map((item, index) => {\n switch (item.itemType) {\n case \"component\": {\n return <li key={index}>{item.children ?? null}</li>;\n }\n case \"link\":\n default: {\n return renderLinkItem(item as NavItemLinkProps<T>, index);\n }\n }\n });\n\n if (items && items.length > 0) {\n return mobile ? (\n <ul ref={listRef} className={styles.mobileWrapper}>\n {renderItems()}\n </ul>\n ) : (\n <ul\n ref={listRef}\n className={clsx(\n styles.wrapper,\n hideNavBranding && styles.wrapperAlignLeft\n )}\n >\n {renderItems()}\n </ul>\n );\n }\n\n return <></>;\n};\n"],"names":["NavbarItems","items","selectedId","mobile","hideNavBranding","hideLinkIndicator","onItemClick","selectedIndex","setSelectedIndex","useState","listRef","useRef","instanceId","useId","hasSelectedSubMenuItem","item","_a","subMenu","some","subItem","id","itemIndexWithSelectedSubItem","findIndex","itemType","initialExpandedItemIndex","useEffect","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","handleLinkClick","index","stopPropagation","prev","length","handleMobileSubLinkClick","renderDesktopSubMenu","subMenuId","_jsx","DesktopMenu","Content","children","Section","showDivider","map","subIndex","Link","href","renderMobileSubMenu","MobileMenu","renderLinkItem","options","otherItemAttrs","__rest","hasSubMenu","isRouteSelected","checkSelected","isDesktopExpanded","isMobileExpanded","isExpanded","selected","showIndicator","testId","renderIndicator","className","clsx","styles.linkIndicator","styles.linkIndicatorSelected","linkClassName","styles.link","weight","styles.linkWeightBold","styles.linkWeightSemibold","styles.linkWeightRegular","getLinkWeightClass","styles.linkSelected","styles.linkItem","styles.linkItemHiddenBranding","isLastItem","_jsxs","_Fragment","Object","assign","undefined","onClick","styles.linkLabel","styles.linkIconContainer","ClickableIcon","styles.expandCollapseButton","styles.subMenuExpanded","focusHighlight","focusOutline","ChevronUpIcon","styles.chevronIcon","styles.chevronIconSelected","position","customOffset","menuContent","triggerOnFocus","isModal","onPopoverAppear","onPopoverDismiss","type","tabIndex","styles.linkButton","styles.chevronIconDesktop","renderLinkWithSubmenu","renderItems","ref","styles.mobileWrapper","styles.wrapper","styles.wrapperAlignLeft"],"mappings":"ghCAiBA,MA0BaA,EAAc,EACvBC,QACAC,aACAC,UAAS,EACTC,kBACAC,qBAAoB,EACpBC,kBAKA,MAAOC,EAAeC,GAAoBC,EAAwB,MAC5DC,EAAUC,EAAyB,MACnCC,EAAaC,IAKbC,EAA0BC,IAAsC,IAAAC,EAClE,SAAc,QAAZA,EAAAD,EAAKE,eAAO,IAAAD,OAAA,EAAAA,EAAEE,MAAMC,GAAYA,EAAQC,KAAOlB,IAAW,EAK1DmB,EAA+BlB,EAC/BF,EAAMqB,WACDP,GACqB,cAAlBA,EAAKQ,UACLT,EAAuBC,MAE/B,EACAS,EACFH,EAA+B,EAAI,KAAOA,EAM9CI,GAAU,KACDtB,GAELK,EAAiBgB,EAAyB,GAC3C,CAACrB,EAAQqB,IAEZC,GAAU,KACN,GAAItB,EAAQ,OAEZ,MAAMuB,EAAsBC,IAEpBjB,EAAQkB,UACPlB,EAAQkB,QAAQC,SAASF,EAAMG,SAEhCtB,EAAiB,KACrB,EAGJ,OADAuB,SAASC,iBAAiB,QAASN,GAAoB,GAChD,KACHK,SAASE,oBAAoB,QAASP,GAAoB,EAAK,CAClE,GACF,CAACvB,IAKJ,MAAM+B,EAAkB,CAACnB,EAA2BoB,IACxCR,IACJA,EAAMS,kBAGFjC,GACAK,GAAkB6B,IAAQ,IAAArB,EACtB,OAAY,QAAZA,EAAAD,EAAKE,eAAO,IAAAD,OAAA,EAAAA,EAAEsB,SAAUD,IAASF,EAAQA,EAAQ,IAAI,IAI7D7B,EAAYqB,EAAOZ,EAAK,EAI1BwB,EAA2B,CAC7BZ,EACAZ,KAEAY,EAAMS,kBACN9B,EAAYqB,EAAOZ,EAAK,EAMtByB,EAAuB,CACzBvB,EACAwB,IAEAC,EAACC,EAAYC,QAAO,CAACxB,GAAIqB,EAASI,SAC9BH,EAACC,EAAYG,QAAO,CAACC,aAAa,EAAKF,SAClC5B,EAAQ+B,KAAI,CAACjC,EAAMkC,IAChBP,EAACC,EAAYO,KAAI,CAEbC,KAAMpC,EAAKoC,KAAIN,SAEd9B,EAAK8B,UAHD,GAAG9B,EAAKK,MAAM6B,WAUjCG,EAAuBnC,GACzByB,EAACW,EAAU,CACPpD,MAAOgB,EACPf,WAAYA,EACZI,YAAaiC,IAIfe,EAAiB,CAACvC,EAA2BoB,KAC/C,MAAMU,SAAEA,EAAQU,QAAEA,EAAOtC,QAAEA,GAA+BF,EAAnByC,EAAcC,EAAK1C,EAApD,CAAA,WAAA,UAAA,YAEA2C,KAAezC,aAAO,EAAPA,EAASqB,QAExBqB,EApGY,CAAC5C,GACnBA,EAAKK,KAAOlB,GAAcY,EAAuBC,GAmGzB6C,CAAc7C,GAGhC8C,GACD1D,GAAUuD,GAAcnD,IAAkB4B,EAGzC2B,EACF3D,GAAUuD,GAAcnD,IAAkB4B,EAExC4B,EAAaF,GAAqBC,EAElCE,EACD7D,GAA4B,OAAlBI,EAELoD,EADApD,IAAkB4B,EAGtB8B,GAAiB5D,GAAqB2D,EAQtCE,EAAS/D,EACT,gBAAgBgC,EAAQ,IACxB,SAASA,EAAQ,IAEjBgC,EAAkB,IACpBF,EACIvB,EAAA,MAAA,CAAA,cACiB,GAAGwB,cAChBE,UAAWC,EACPC,EACAN,GAAYO,KAGpB,KAyBFC,EAAgBH,EAClBI,EAnNe,CAACC,IACxB,OAAQA,GACJ,IAAK,OACD,OAAOC,EACX,IAAK,WACD,OAAOC,EAEX,QACI,OAAOC,IA4MPC,CA9CiCd,EAC/B7D,EACI,OACA,WACJ,WA2CF6D,GAAYe,GAoFhB,OACIrC,EAAA,KAAA,CAEI0B,UAAWC,EACPW,EACA5E,GAAmB6E,YAGtBvB,EA1EqB,CAACwB,IAC3B,MAAMzC,EAAY,kBAAkB7B,KAAcG,EAAKK,KAEvD,OAAIjB,EAEIgF,EAAAC,EAAA,CAAAvC,SAAA,CACIsC,EAAA,IAAAE,OAAAC,OAAA,CAAA,cACiBpB,EACbE,UAAWI,GACPhB,EAAc,CAAA,eACJG,EAAkB,YAAS4B,EAAS,gBACpC,OAAM,gBACLxB,EACfyB,QAAStD,EAAgBnB,EAAMoB,IAC3BoB,EAAO,CAAAV,SAAA,CAEXH,EAAA,MAAA,CAAK0B,UAAWqB,EAAgB5C,SAAGA,IAClCsB,IA5DjBhE,GAAUuD,EACNhB,EAAA,MAAA,CAAK0B,UAAWsB,EAAwB7C,SACpCH,EAACiD,EAAa,CAAA,cACG,GAAGzB,2BAChBE,UAAWC,EACPuB,EACA9B,GAAoB+B,GAExBC,gBAAgB,EAChBC,aAAa,UAAS,aACVjC,EAAmB,WAAa,kBAE5CpB,EAACsD,GACG5B,UAAWC,EACP4B,EACAjC,GAAYkC,SAK5B,SA4CSpC,GAAoBV,EAAoBnC,MAMjDyB,EAACC,EAAW,CACRwD,SAAUjB,EAAa,aAAe,SACtCkB,aAAc,EACdC,YAAa7D,EAAqBvB,EAAUwB,GAC5C6D,gBAAc,EACdC,SAAS,EACTC,gBAAiB,KACbhG,EAAiB2B,EAAM,EAE3BsE,iBAAkB,KACdjG,GAAkB6B,GACdA,IAASF,EAAQ,KAAOE,GAC3B,EACJQ,SAEDsC,EAAA,SAAAE,OAAAC,OAAA,CACIoB,KAAK,SACLC,SAAU,gBACGzC,EACbE,UAAWC,EAAKG,EAAeoC,GAAkB,gBACnC,OAAM,gBACL7C,GACXR,aAEJb,EAAA,MAAA,CAAK0B,UAAWqB,EAAgB5C,SAAGA,IAClCsB,IACDzB,EAACsD,EAAa,CACV5B,UAAWC,EACP4B,EACAY,EACA7C,GAAYkC,EACZrC,GAAqBgC,UAIvB,EAaRiB,CAAsB3E,IAAUlC,EAAMqC,OAAS,GAzFzD6C,EAAA,IAAAE,OAAAC,OAAA,CACIqB,SAAU,EAAC,cACEzC,EACbE,UAAWI,GACPhB,EAAc,CAAA,eACJG,EAAkB,YAAS4B,EACzCC,QAAStD,EAAgBnB,EAAMoB,IAC3BoB,EAAO,CAAAV,SAAA,CAEXH,EAAA,MAAA,CAAK0B,UAAWqB,EAAgB5C,SAAGA,IAClCsB,SAwEIhC,EASJ,EAIP4E,EAAc,IAChB9G,EAAM+C,KAAI,CAACjC,EAAMoB,WACb,MACS,cADDpB,EAAKQ,SAEEmB,EAAA,KAAA,CAAAG,iBAAiB7B,EAAAD,EAAK8B,wBAAY,MAAzBV,GAITmB,EAAevC,EAA6BoB,MAKnE,OAAIlC,GAASA,EAAMqC,OAAS,EAEpBI,EAAA,KADGvC,EACH,CAAI6G,IAAKtG,EAAS0D,UAAW6C,EAAoBpE,SAC5CkE,MAIDC,IAAKtG,EACL0D,UAAWC,EACP6C,EACA9G,GAAmB+G,YAGtBJ,MAKNrE,OAAK"}
@@ -1,2 +1,2 @@
1
- import"./navbar-items.styles_1b1zx.css";const s="w1ndf2sj",l="w177nfye",n="mw9gug8",c="l18t6f3m",e="lsn8o0d",o="l1o3p4yu",r="lkwvsmx",t="l1kp5n19",x="lqgrg2a",a="l1p7dxu8",f="l1xfqf3s",m="lsc0hr8",p="lnocj2s",u="l5qfat1",g="l1p9u80z",w="ej7h5do",d="c160mxwv",k="c1s8ur0k",v="s178e7hk",_="c1euxgs0";export{d as chevronIcon,k as chevronIconDesktop,_ as chevronIconSelected,w as expandCollapseButton,o as link,f as linkButton,g as linkIconContainer,p as linkIndicator,u as linkIndicatorSelected,c as linkItem,e as linkItemHiddenBranding,m as linkLabel,r as linkSelected,a as linkWeightBold,t as linkWeightRegular,x as linkWeightSemibold,n as mobileWrapper,v as subMenuExpanded,s as wrapper,l as wrapperAlignLeft};
1
+ import"./navbar-items.styles_1klnd8i.css";const s="w1ndf2sj",l="w177nfye",n="mw9gug8",c="l18t6f3m",e="lsn8o0d",o="l1o3p4yu",r="lkwvsmx",t="l1kp5n19",a="lqgrg2a",f="l1p7dxu8",m="l1xfqf3s",p="lsc0hr8",u="lnocj2s",x="l5qfat1",d="l1p9u80z",g="ej7h5do",k="c160mxwv",w="c1s8ur0k",v="s178e7hk",_="c1euxgs0";export{k as chevronIcon,w as chevronIconDesktop,_ as chevronIconSelected,g as expandCollapseButton,o as link,m as linkButton,d as linkIconContainer,u as linkIndicator,x as linkIndicatorSelected,c as linkItem,e as linkItemHiddenBranding,p as linkLabel,r as linkSelected,f as linkWeightBold,t as linkWeightRegular,a as linkWeightSemibold,n as mobileWrapper,v as subMenuExpanded,s as wrapper,l as wrapperAlignLeft};
2
2
  //# sourceMappingURL=navbar-items.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navbar-items.styles.js","sources":["../../src/navbar/navbar-items.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour, ComponentToken, Font, MediaQuery } from \"../theme\";\n\n// =============================================================================\n// WRAPPER\n// =============================================================================\n\nexport const wrapper = css`\n display: flex;\n list-style: none;\n position: relative;\n\n ${MediaQuery.MaxWidth.lg} {\n display: none;\n }\n`;\n\nexport const wrapperAlignLeft = css`\n margin-right: auto;\n`;\n\nexport const mobileWrapper = css`\n display: none;\n list-style: none;\n\n ${MediaQuery.MaxWidth.lg} {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n`;\n\n// =============================================================================\n// LINK ITEMS\n// =============================================================================\nexport const linkItem = css`\n display: flex;\n margin: 0 1rem;\n &:first-child {\n margin-left: 0;\n }\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n padding: 0.125rem 0;\n width: 100%;\n margin-left: 0rem;\n }\n`;\n\nexport const linkItemHiddenBranding = css`\n // negative margin to preserve touch target size for link\n &:first-child {\n margin-left: -0.5rem;\n }\n\n ${MediaQuery.MaxWidth.lg} {\n &:first-child {\n margin-left: 0rem;\n }\n }\n`;\n\nexport const link = css`\n display: flex;\n position: relative;\n align-items: center;\n text-align: center;\n color: ${ComponentToken.Navbar[\"link-colour-text\"]};\n height: 100%;\n gap: 0.5rem;\n\n &:active,\n &:hover,\n &:focus,\n &:focus-within {\n color: ${ComponentToken.Navbar[\"link-colour-text-hover\"]};\n }\n\n ${MediaQuery.MaxWidth.lg} {\n width: 100%;\n padding: 0.5rem 1rem;\n text-align: left;\n }\n`;\n\nexport const linkSelected = css`\n &:active,\n &:hover,\n &:focus {\n color: ${ComponentToken.Navbar[\"link-colour-text-selected-hover\"]};\n }\n`;\n\nexport const linkWeightRegular = css`\n ${Font[\"body-md-regular\"]}\n`;\n\nexport const linkWeightSemibold = css`\n ${Font[\"body-md-semibold\"]}\n`;\n\nexport const linkWeightBold = css`\n ${Font[\"body-md-bold\"]}\n`;\n\nexport const linkButton = css`\n background: none;\n border: 0;\n padding: 0;\n cursor: pointer;\n text-align: left;\n margin: 0;\n box-shadow: none;\n font: inherit;\n color: inherit;\n gap: 8px;\n`;\n\nexport const linkLabel = css`\n flex: 1;\n\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n white-space: pre-wrap;\n`;\n\nexport const linkIndicator = css`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 0.25rem;\n background-color: ${Colour[\"border-selected\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n left: 0;\n right: unset;\n top: 0;\n bottom: 0;\n height: 100%;\n width: 0.25rem;\n }\n`;\n\nexport const linkIndicatorSelected = css`\n .${link}:active &,\n .${link}:hover &,\n .${link}:focus & {\n background-color: ${Colour[\"border-selected-hover\"]};\n }\n`;\n\nexport const linkIconContainer = css`\n margin-right: -0.5rem;\n`;\n\nexport const expandCollapseButton = css`\n padding: 0.5rem;\n margin: auto 0.25rem auto 0;\n`;\n\nexport const chevronIcon = css`\n height: 1.25rem;\n width: 1.25rem;\n color: ${Colour.icon};\n transition: transform 300ms ease-in-out;\n transform: rotate(180deg);\n\n .${link}:active &,\n .${link}:hover &,\n .${link}:focus & {\n color: ${Colour[\"icon-hover\"]};\n }\n`;\n\nexport const chevronIconDesktop = css`\n height: 1.125rem;\n width: 1.125rem;\n`;\n\nexport const subMenuExpanded = css`\n transform: rotate(0deg);\n`;\n\nexport const chevronIconSelected = css`\n .${link}:active &,\n .${link}:hover &,\n .${link}:focus & {\n color: ${Colour[\"icon-selected-hover\"]};\n }\n`;\n"],"names":["wrapper","wrapperAlignLeft","mobileWrapper","linkItem","linkItemHiddenBranding","link","linkSelected","linkWeightRegular","linkWeightSemibold","linkWeightBold","linkButton","linkLabel","linkIndicator","linkIndicatorSelected","linkIconContainer","expandCollapseButton","chevronIcon","chevronIconDesktop","subMenuExpanded","chevronIconSelected"],"mappings":"8DAQO,MAAMA,EAAO,WAUPC,EAAgB,WAIhBC,EAAa,UAcbC,EAAQ,WAeRC,EAAsB,UAatBC,EAAI,WAuBJC,EAAY,UAQZC,EAAiB,WAIjBC,EAAkB,UAIlBC,EAAc,WAIdC,EAAU,WAaVC,EAAS,UAUTC,EAAa,UAkBbC,EAAqB,UAQrBC,EAAiB,WAIjBC,EAAoB,UAKpBC,EAAW,WAcXC,EAAkB,WAKlBC,EAAe,WAIfC,EAAmB"}
1
+ {"version":3,"file":"navbar-items.styles.js","sources":["../../src/navbar/navbar-items.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour, ComponentToken, Font, MediaQuery, Spacing } from \"../theme\";\n\n// =============================================================================\n// WRAPPER\n// =============================================================================\n\nexport const wrapper = css`\n display: flex;\n list-style: none;\n position: relative;\n\n ${MediaQuery.MaxWidth.lg} {\n display: none;\n }\n`;\n\nexport const wrapperAlignLeft = css`\n margin-right: auto;\n`;\n\nexport const mobileWrapper = css`\n display: none;\n list-style: none;\n\n ${MediaQuery.MaxWidth.lg} {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n`;\n\n// =============================================================================\n// LINK ITEMS\n// =============================================================================\nexport const linkItem = css`\n display: flex;\n margin: 0 1rem;\n &:first-child {\n margin-left: 0;\n }\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n width: 100%;\n margin-left: 0rem;\n }\n`;\n\nexport const linkItemHiddenBranding = css`\n // negative margin to preserve touch target size for link\n &:first-child {\n margin-left: -0.5rem;\n }\n\n ${MediaQuery.MaxWidth.lg} {\n &:first-child {\n margin-left: 0rem;\n }\n }\n`;\n\nexport const link = css`\n display: flex;\n position: relative;\n align-items: center;\n text-align: center;\n color: ${ComponentToken.Navbar[\"link-colour-text\"]};\n height: 100%;\n gap: ${Spacing[\"spacing-16\"]};\n\n &:active,\n &:hover,\n &:focus,\n &:focus-within {\n color: ${ComponentToken.Navbar[\"link-colour-text-hover\"]};\n }\n\n ${MediaQuery.MaxWidth.lg} {\n width: 100%;\n padding: 10px ${Spacing[\"spacing-24\"]};\n text-align: left;\n }\n`;\n\nexport const linkSelected = css`\n &:active,\n &:hover,\n &:focus {\n color: ${ComponentToken.Navbar[\"link-colour-text-selected-hover\"]};\n }\n`;\n\nexport const linkWeightRegular = css`\n ${Font[\"body-md-regular\"]}\n`;\n\nexport const linkWeightSemibold = css`\n ${Font[\"body-md-semibold\"]}\n`;\n\nexport const linkWeightBold = css`\n ${Font[\"body-md-bold\"]}\n`;\n\nexport const linkButton = css`\n background: none;\n border: 0;\n padding: 0;\n cursor: pointer;\n text-align: left;\n margin: 0;\n box-shadow: none;\n font: inherit;\n color: inherit;\n gap: 8px;\n`;\n\nexport const linkLabel = css`\n flex: 1;\n\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n white-space: pre-wrap;\n`;\n\nexport const linkIndicator = css`\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 0.25rem;\n background-color: ${Colour[\"border-selected\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n left: 0;\n right: unset;\n top: 0;\n bottom: 0;\n height: 100%;\n width: 0.25rem;\n }\n`;\n\nexport const linkIndicatorSelected = css`\n .${link}:active &,\n .${link}:hover &,\n .${link}:focus & {\n background-color: ${Colour[\"border-selected-hover\"]};\n }\n`;\n\nexport const linkIconContainer = css`\n margin-right: -0.5rem;\n`;\n\nexport const expandCollapseButton = css`\n padding: 0.5rem;\n margin: auto 0;\n`;\n\nexport const chevronIcon = css`\n height: 1.25rem;\n width: 1.25rem;\n color: ${Colour.icon};\n transition: transform 300ms ease-in-out;\n transform: rotate(180deg);\n\n .${link}:active &,\n .${link}:hover &,\n .${link}:focus & {\n color: ${Colour[\"icon-hover\"]};\n }\n`;\n\nexport const chevronIconDesktop = css`\n height: 1.125rem;\n width: 1.125rem;\n`;\n\nexport const subMenuExpanded = css`\n transform: rotate(0deg);\n`;\n\nexport const chevronIconSelected = css`\n .${link}:active &,\n .${link}:hover &,\n .${link}:focus & {\n color: ${Colour[\"icon-selected-hover\"]};\n }\n`;\n"],"names":["wrapper","wrapperAlignLeft","mobileWrapper","linkItem","linkItemHiddenBranding","link","linkSelected","linkWeightRegular","linkWeightSemibold","linkWeightBold","linkButton","linkLabel","linkIndicator","linkIndicatorSelected","linkIconContainer","expandCollapseButton","chevronIcon","chevronIconDesktop","subMenuExpanded","chevronIconSelected"],"mappings":"gEAQO,MAAMA,EAAO,WAUPC,EAAgB,WAIhBC,EAAa,UAcbC,EAAQ,WAcRC,EAAsB,UAatBC,EAAI,WAuBJC,EAAY,UAQZC,EAAiB,WAIjBC,EAAkB,UAIlBC,EAAc,WAIdC,EAAU,WAaVC,EAAS,UAUTC,EAAa,UAkBbC,EAAqB,UAQrBC,EAAiB,WAIjBC,EAAoB,UAKpBC,EAAW,WAcXC,EAAkB,WAKlBC,EAAe,WAIfC,EAAmB"}
@@ -1,9 +1,9 @@
1
1
  @layer fds{.w1ndf2sj{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;list-style:none;position:relative;}:where(body.fds-breakpoint-lg-max) .w1ndf2sj{display:none;}
2
2
  .w177nfye{margin-right:auto;}
3
3
  .mw9gug8{display:none;list-style:none;}:where(body.fds-breakpoint-lg-max) .mw9gug8{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:hidden;}
4
- .l18t6f3m{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0 1rem;}.l18t6f3m:first-child{margin-left:0;}:where(body.fds-breakpoint-lg-max) .l18t6f3m{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:0.125rem 0;width:100%;margin-left:0rem;}
4
+ .l18t6f3m{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0 1rem;}.l18t6f3m:first-child{margin-left:0;}:where(body.fds-breakpoint-lg-max) .l18t6f3m{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;margin-left:0rem;}
5
5
  .lsn8o0d:first-child{margin-left:-0.5rem;}:where(body.fds-breakpoint-lg-max) .lsn8o0d:first-child{margin-left:0rem;}
6
- .l1o3p4yu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-align:center;color:var(--fds-navbar-link-colour-text);height:100%;gap:0.5rem;}.l1o3p4yu:active,.l1o3p4yu:hover,.l1o3p4yu:focus,.l1o3p4yu:focus-within{color:var(--fds-navbar-link-colour-text-hover);}:where(body.fds-breakpoint-lg-max) .l1o3p4yu{width:100%;padding:0.5rem 1rem;text-align:left;}
6
+ .l1o3p4yu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-align:center;color:var(--fds-navbar-link-colour-text);height:100%;gap:var(--fds-spacing-16);}.l1o3p4yu:active,.l1o3p4yu:hover,.l1o3p4yu:focus,.l1o3p4yu:focus-within{color:var(--fds-navbar-link-colour-text-hover);}:where(body.fds-breakpoint-lg-max) .l1o3p4yu{width:100%;padding:10px var(--fds-spacing-24);text-align:left;}
7
7
  .lkwvsmx:active,.lkwvsmx:hover,.lkwvsmx:focus{color:var(--fds-navbar-link-colour-text-selected-hover);}
8
8
  .l1kp5n19{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-regular);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);}
9
9
  .lqgrg2a{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);}
@@ -13,7 +13,7 @@
13
13
  .lnocj2s{position:absolute;bottom:0;left:0;right:0;height:0.25rem;background-color:var(--fds-colour-border-selected);}:where(body.fds-breakpoint-lg-max) .lnocj2s{left:0;right:unset;top:0;bottom:0;height:100%;width:0.25rem;}
14
14
  .l1o3p4yu:active .l5qfat1,.l1o3p4yu:hover .l5qfat1,.l1o3p4yu:focus .l5qfat1{background-color:var(--fds-colour-border-selected-hover);}
15
15
  .l1p9u80z{margin-right:-0.5rem;}
16
- .ej7h5do{padding:0.5rem;margin:auto 0.25rem auto 0;}
16
+ .ej7h5do{padding:0.5rem;margin:auto 0;}
17
17
  .c160mxwv{height:1.25rem;width:1.25rem;color:var(--fds-colour-icon);-webkit-transition:-webkit-transform 300ms ease-in-out;transition:transform 300ms ease-in-out;-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg);}.l1o3p4yu:active .c160mxwv,.l1o3p4yu:hover .c160mxwv,.l1o3p4yu:focus .c160mxwv{color:var(--fds-colour-icon-hover);}
18
18
  .c1s8ur0k{height:1.125rem;width:1.125rem;}
19
19
  .s178e7hk{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifesg/react-design-system",
3
- "version": "4.0.0-alpha.10",
3
+ "version": "4.0.0-alpha.11",
4
4
  "description": "A component design system for LifeSG web apps",
5
5
  "keywords": [
6
6
  "design-system"
@@ -537,6 +537,7 @@
537
537
  }
538
538
  },
539
539
  "dependencies": {
540
+ "@govtechsg/sgds-web-component": "3.26.0",
540
541
  "@react-aria/live-announcer": "^3.4.4",
541
542
  "@react-spring/web": "^10.0.1",
542
543
  "clsx": "^2.1.1",