@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
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as t}from"react/jsx-runtime";import{ChevronUpIcon as i}from"@lifesg/react-icons/chevron-up";import{useSpring as a,animated as r}from"@react-spring/web";import n from"clsx";import{forwardRef as l,useRef as s,useContext as o,useState as d,useImperativeHandle as c,useEffect as m}from"react";import{useResizeDetector as p}from"../external/react-resize-detector/build/index.esm.js";import{inertValue as u}from"../shared/accessibility/index.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as f}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{AccordionContext as h}from"./accordion-context.js";import{container as x,containerExpanded as v,chevronIcon as j,iconContainer as g,iconContainerExpanded as b,expandCollapseButton as N,expandCollapseButtonExpanded as y,expandCollapseButtonCollapsible as $,expandable as C,contentContainer as D,title as I,titleSmall as S}from"./accordion-item.styles.js";const k=l((function({title:l,children:k,type:w="default",collapsible:z=!0,className:A,id:E,expanded:H,"data-testid":L="accordion-item"},O){var q;const B=s(null),{expandAll:F,itemHeadingLevel:G,onItemStateChange:J,itemState:K,onItemDeregister:M}=o(h),[P,Q]=d(!1),R=f(),T=`${R}-content`,{height:U,ref:V}=p(),W=null!==(q=K[R])&&void 0!==q?q:!z||(null!=H?H:F);c(O,(()=>Object.assign(B.current,{expand(){J(R,!0)},collapse(){J(R,!1)},isExpanded:()=>W})),[W]),m((()=>(Q(!0),()=>null==M?void 0:M(R))),[]),m((()=>{J(R,!z||(null!=H?H:F))}),[F,H,z]);const X=e=>{e.preventDefault(),J(R,!W)},Y=a({height:W?U:0});return e("div",{"data-testid":L,className:n(x,W&&v,A),id:E,ref:B,children:[t("h3",{"aria-level":G,children:e("button",{"data-testid":`${L}-expand-collapse-button`,onClick:z?X:void 0,className:n(N,W&&y,z&&$),"aria-controls":T,"aria-disabled":!z,"aria-expanded":W,children:["string"!=typeof l?l:t("span",{"data-testid":`${L}-title`,className:n(I,"small"===w&&S),children:l}),z&&t("span",{"data-testid":`${L}-expand-collapse-icon`,className:n(g,W&&b),children:t(i,{className:j})})]})}),t(r.div,{id:T,className:C,style:P?Y:void 0,"data-testid":`${L}-expandable-container`,inert:u(!W),children:t("div",{ref:V,className:D,"data-testid":"content-container",children:k})})]})}));export{k as AccordionItem};
1
+ import{jsxs as e,jsx as t}from"react/jsx-runtime";import{ChevronUpIcon as i}from"@lifesg/react-icons/chevron-up";import{useSpring as a,animated as n}from"@react-spring/web";import r from"clsx";import{forwardRef as l,useRef as s,useContext as o,useState as d,useImperativeHandle as c,useEffect as m}from"react";import{useResizeDetector as p}from"../external/react-resize-detector/build/index.esm.js";import{inertValue as u}from"../shared/accessibility/index.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as f}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{AccordionContext as h}from"./accordion-context.js";import{container as x,containerExpanded as v,chevronIcon as g,iconContainer as j,iconContainerExpanded as b,expandCollapseButton as N,expandCollapseButtonExpanded as y,expandCollapseButtonCollapsible as $,expandable as C,contentContainer as D,title as E,titleSmall as I}from"./accordion-item.styles.js";const S=l((function({title:l,children:S,type:k="default",collapsible:w=!0,className:z,id:A,expanded:H,onExpandChange:L,"data-testid":O="accordion-item"},q){var B;const F=s(null),{expandAll:G,itemHeadingLevel:J,onItemStateChange:K,itemState:M,onItemDeregister:P}=o(h),[Q,R]=d(!1),T=f(),U=`${T}-content`,{height:V,ref:W}=p(),X=void 0!==L,Y=X?!w||null!=H&&H:null!==(B=M[T])&&void 0!==B?B:!w||(null!=H?H:G);c(q,(()=>Object.assign(F.current,{expand(){X?null==L||L(!0):K(T,!0)},collapse(){X?null==L||L(!1):K(T,!1)},isExpanded:()=>Y})),[Y]),m((()=>(R(!0),()=>null==P?void 0:P(T))),[]),m((()=>{X&&K(T,!w||null!=H&&H)}),[H,w]),m((()=>{X||K(T,!w||(null!=H?H:G))}),[G,H,w]),m((()=>{if(!X||!Q)return;const e=!w||G;e!==H&&(null==L||L(e))}),[G]);const Z=e=>{e.preventDefault(),X?null==L||L(!Y):K(T,!Y)},_=a({height:Y?V:0});return e("div",{"data-testid":O,className:r(x,Y&&v,z),id:A,ref:F,children:[t("h3",{"aria-level":J,children:e("button",{"data-testid":`${O}-expand-collapse-button`,onClick:w?Z:void 0,className:r(N,Y&&y,w&&$),"aria-controls":U,"aria-disabled":!w,"aria-expanded":Y,children:["string"!=typeof l?l:t("span",{"data-testid":`${O}-title`,className:r(E,"small"===k&&I),children:l}),w&&t("span",{"data-testid":`${O}-expand-collapse-icon`,className:r(j,Y&&b),children:t(i,{className:g})})]})}),t(n.div,{id:U,className:C,style:Q?_:void 0,"data-testid":`${O}-expandable-container`,inert:u(!Y),children:t("div",{ref:W,className:D,"data-testid":"content-container",children:S})})]})}));export{S as AccordionItem};
2
2
  //# sourceMappingURL=accordion-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accordion-item.js","sources":["../../src/accordion/accordion-item.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { inertValue } from \"../shared/accessibility\";\nimport { useId } from \"../util\";\nimport { AccordionContext } from \"./accordion-context\";\nimport * as styles from \"./accordion-item.styles\";\nimport type {\n AccordionItemApi,\n AccordionItemHandle,\n AccordionItemProps,\n} from \"./types\";\n\nfunction Component(\n {\n title,\n children,\n type = \"default\",\n collapsible = true,\n className,\n id,\n expanded: expandedControlled,\n \"data-testid\": testId = \"accordion-item\",\n }: AccordionItemProps,\n ref: React.Ref<AccordionItemHandle>\n) {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const elementRef = useRef<HTMLDivElement>(null);\n const {\n expandAll,\n itemHeadingLevel,\n onItemStateChange,\n itemState,\n onItemDeregister,\n } = useContext(AccordionContext);\n const [hasFirstLoad, setHasFirstLoad] = useState<boolean>(false);\n const internalId = useId();\n const contentId = `${internalId}-content`;\n const { height, ref: resizeDetectorRef } = useResizeDetector();\n const expanded =\n itemState[internalId] ??\n (collapsible ? expandedControlled ?? expandAll : true); // the initial value\n\n useImperativeHandle(\n ref,\n () =>\n Object.assign<HTMLDivElement, AccordionItemApi>(\n elementRef.current!,\n {\n expand(): void {\n onItemStateChange(internalId, true);\n },\n collapse(): void {\n onItemStateChange(internalId, false);\n },\n isExpanded() {\n return expanded;\n },\n }\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [expanded]\n );\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setHasFirstLoad(true);\n\n return () => onItemDeregister?.(internalId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n onItemStateChange(\n internalId,\n collapsible ? expandedControlled ?? expandAll : true\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandAll, expandedControlled, collapsible]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n\n const handleExpandCollapseClick = (event: React.MouseEvent) => {\n event.preventDefault();\n onItemStateChange(internalId, !expanded);\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n // React spring animation configuration\n const resizeHeight = {\n height: expanded ? height : 0,\n };\n const expandableStyles = useSpring(resizeHeight);\n\n const renderContent = () => {\n return (\n <animated.div\n id={contentId}\n className={styles.expandable}\n style={hasFirstLoad ? expandableStyles : undefined}\n data-testid={`${testId}-expandable-container`}\n inert={inertValue(!expanded)}\n >\n <div\n ref={resizeDetectorRef}\n className={styles.contentContainer}\n data-testid=\"content-container\"\n >\n {children}\n </div>\n </animated.div>\n );\n };\n\n const renderTitleText = () => {\n if (typeof title !== \"string\") {\n return title;\n }\n\n return (\n <span\n data-testid={`${testId}-title`}\n className={clsx(\n styles.title,\n type === \"small\" && styles.titleSmall\n )}\n >\n {title}\n </span>\n );\n };\n\n const renderTitle = () => {\n return (\n <h3 aria-level={itemHeadingLevel}>\n <button\n data-testid={`${testId}-expand-collapse-button`}\n onClick={\n collapsible ? handleExpandCollapseClick : undefined\n }\n className={clsx(\n styles.expandCollapseButton,\n expanded && styles.expandCollapseButtonExpanded,\n collapsible && styles.expandCollapseButtonCollapsible\n )}\n aria-controls={contentId}\n aria-disabled={!collapsible} // remains focusable\n aria-expanded={expanded}\n >\n {renderTitleText()}\n {collapsible && (\n <span\n data-testid={`${testId}-expand-collapse-icon`}\n className={clsx(\n styles.iconContainer,\n expanded && styles.iconContainerExpanded\n )}\n >\n <ChevronUpIcon className={styles.chevronIcon} />\n </span>\n )}\n </button>\n </h3>\n );\n };\n\n return (\n <div\n data-testid={testId}\n className={clsx(\n styles.container,\n expanded && styles.containerExpanded,\n className\n )}\n id={id}\n ref={elementRef}\n >\n {renderTitle()}\n {renderContent()}\n </div>\n );\n}\n\nexport const AccordionItem = forwardRef<\n AccordionItemHandle,\n AccordionItemProps\n>(Component);\n"],"names":["AccordionItem","forwardRef","title","children","type","collapsible","className","id","expanded","expandedControlled","testId","ref","elementRef","useRef","expandAll","itemHeadingLevel","onItemStateChange","itemState","onItemDeregister","useContext","AccordionContext","hasFirstLoad","setHasFirstLoad","useState","internalId","useId","contentId","height","resizeDetectorRef","useResizeDetector","_a","useImperativeHandle","Object","assign","current","expand","collapse","isExpanded","useEffect","handleExpandCollapseClick","event","preventDefault","expandableStyles","useSpring","_jsxs","clsx","styles.container","styles.containerExpanded","_jsx","onClick","undefined","styles.expandCollapseButton","styles.expandCollapseButtonExpanded","styles.expandCollapseButtonCollapsible","styles.title","styles.titleSmall","styles.iconContainer","styles.iconContainerExpanded","ChevronUpIcon","styles.chevronIcon","animated","div","styles.expandable","style","inert","inertValue","styles.contentContainer"],"mappings":"igCA0MaA,EAAgBC,GAlL7B,UACIC,MACIA,EAAKC,SACLA,EAAQC,KACRA,EAAO,UAASC,YAChBA,GAAc,EAAIC,UAClBA,EAASC,GACTA,EACAC,SAAUC,EACV,cAAeC,EAAS,kBAE5BC,SAKA,MAAMC,EAAaC,EAAuB,OACpCC,UACFA,EAASC,iBACTA,EAAgBC,kBAChBA,EAAiBC,UACjBA,EAASC,iBACTA,GACAC,EAAWC,IACRC,EAAcC,GAAmBC,GAAkB,GACpDC,EAAaC,IACbC,EAAY,GAAGF,aACfG,OAAEA,EAAQhB,IAAKiB,GAAsBC,IACrCrB,EACmB,QAArBsB,EAAAb,EAAUO,UAAW,IAAAM,EAAAA,GACpBzB,IAAcI,QAAAA,EAAsBK,GAEzCiB,EACIpB,GACA,IACIqB,OAAOC,OACHrB,EAAWsB,QACX,CACI,MAAAC,GACInB,EAAkBQ,GAAY,EAClC,EACA,QAAAY,GACIpB,EAAkBQ,GAAY,EAClC,EACAa,WAAU,IACC7B,KAKvB,CAACA,IAML8B,GAAU,KACNhB,GAAgB,GAET,IAAMJ,aAAgB,EAAhBA,EAAmBM,KAEjC,IAEHc,GAAU,KACNtB,EACIQ,GACAnB,IAAcI,QAAAA,EAAsBK,GACvC,GAEF,CAACA,EAAWL,EAAoBJ,IAMnC,MAAMkC,EAA6BC,IAC/BA,EAAMC,iBACNzB,EAAkBQ,GAAahB,EAAS,EAUtCkC,EAAmBC,EAHJ,CACjBhB,OAAQnB,EAAWmB,EAAS,IA4EhC,OACIiB,EAAA,MAAA,CAAA,cACiBlC,EACbJ,UAAWuC,EACPC,EACAtC,GAAYuC,EACZzC,GAEJC,GAAIA,EACJI,IAAKC,EAAUT,SAAA,CAzCf6C,EAAA,KAAA,CAAA,aAAgBjC,WACZ6B,EAAA,SAAA,CAAA,cACiB,GAAGlC,2BAChBuC,QACI5C,EAAckC,OAA4BW,EAE9C5C,UAAWuC,EACPM,EACA3C,GAAY4C,EACZ/C,GAAegD,mBAEJ3B,EAAS,iBACRrB,kBACDG,EAAQL,SAAA,CAhCd,iBAAVD,EACAA,EAIP8C,EAAA,OAAA,CAAA,cACiB,GAAGtC,UAChBJ,UAAWuC,EACPS,EACS,UAATlD,GAAoBmD,GACvBpD,SAEAD,IAuBIG,GACG2C,wBACiB,GAAGtC,yBAChBJ,UAAWuC,EACPW,EACAhD,GAAYiD,GACftD,SAED6C,EAACU,EAAa,CAACpD,UAAWqD,WA9D1CX,EAACY,EAASC,IAAG,CACTtD,GAAImB,EACJpB,UAAWwD,EACXC,MAAO1C,EAAeqB,OAAmBQ,EAAS,cACrC,GAAGxC,yBAChBsD,MAAOC,GAAYzD,GAASL,SAE5B6C,EAAA,MAAA,CACIrC,IAAKiB,EACLtB,UAAW4D,EAAuB,cACtB,oBAAmB/D,SAE9BA,QAyErB"}
1
+ {"version":3,"file":"accordion-item.js","sources":["../../src/accordion/accordion-item.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { inertValue } from \"../shared/accessibility\";\nimport { useId } from \"../util\";\nimport { AccordionContext } from \"./accordion-context\";\nimport * as styles from \"./accordion-item.styles\";\nimport type {\n AccordionItemApi,\n AccordionItemHandle,\n AccordionItemProps,\n} from \"./types\";\n\nfunction Component(\n {\n title,\n children,\n type = \"default\",\n collapsible = true,\n className,\n id,\n expanded: expandedControlled,\n onExpandChange,\n \"data-testid\": testId = \"accordion-item\",\n }: AccordionItemProps,\n ref: React.Ref<AccordionItemHandle>\n) {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const elementRef = useRef<HTMLDivElement>(null);\n const {\n expandAll,\n itemHeadingLevel,\n onItemStateChange,\n itemState,\n onItemDeregister,\n } = useContext(AccordionContext);\n const [hasFirstLoad, setHasFirstLoad] = useState<boolean>(false);\n const internalId = useId();\n const contentId = `${internalId}-content`;\n const { height, ref: resizeDetectorRef } = useResizeDetector();\n const isControlled = onExpandChange !== undefined;\n const expanded = isControlled\n ? collapsible\n ? expandedControlled ?? false\n : true\n : itemState[internalId] ??\n (collapsible ? expandedControlled ?? expandAll : true);\n\n useImperativeHandle(\n ref,\n () =>\n Object.assign<HTMLDivElement, AccordionItemApi>(\n elementRef.current!,\n {\n expand(): void {\n if (isControlled) {\n onExpandChange?.(true);\n } else {\n onItemStateChange(internalId, true);\n }\n },\n collapse(): void {\n if (isControlled) {\n onExpandChange?.(false);\n } else {\n onItemStateChange(internalId, false);\n }\n },\n isExpanded() {\n return expanded;\n },\n }\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [expanded]\n );\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setHasFirstLoad(true);\n\n return () => onItemDeregister?.(internalId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Controlled mode: keep parent itemState in sync so \"Show all\"/\"Hide all\" label stays accurate\n useEffect(() => {\n if (isControlled) {\n onItemStateChange(\n internalId,\n collapsible ? expandedControlled ?? false : true\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandedControlled, collapsible]);\n\n // Uncontrolled mode: sync state when expandAll button or the hint prop changes\n useEffect(() => {\n if (!isControlled) {\n onItemStateChange(\n internalId,\n collapsible ? expandedControlled ?? expandAll : true\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandAll, expandedControlled, collapsible]);\n\n // Controlled mode: forward expandAll button changes to the caller\n useEffect(() => {\n if (!isControlled || !hasFirstLoad) return;\n const next = collapsible ? expandAll : true;\n if (next !== expandedControlled) {\n onExpandChange?.(next);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandAll]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n\n const handleExpandCollapseClick = (event: React.MouseEvent) => {\n event.preventDefault();\n if (isControlled) {\n onExpandChange?.(!expanded);\n } else {\n onItemStateChange(internalId, !expanded);\n }\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n // React spring animation configuration\n const resizeHeight = {\n height: expanded ? height : 0,\n };\n const expandableStyles = useSpring(resizeHeight);\n\n const renderContent = () => {\n return (\n <animated.div\n id={contentId}\n className={styles.expandable}\n style={hasFirstLoad ? expandableStyles : undefined}\n data-testid={`${testId}-expandable-container`}\n inert={inertValue(!expanded)}\n >\n <div\n ref={resizeDetectorRef}\n className={styles.contentContainer}\n data-testid=\"content-container\"\n >\n {children}\n </div>\n </animated.div>\n );\n };\n\n const renderTitleText = () => {\n if (typeof title !== \"string\") {\n return title;\n }\n\n return (\n <span\n data-testid={`${testId}-title`}\n className={clsx(\n styles.title,\n type === \"small\" && styles.titleSmall\n )}\n >\n {title}\n </span>\n );\n };\n\n const renderTitle = () => {\n return (\n <h3 aria-level={itemHeadingLevel}>\n <button\n data-testid={`${testId}-expand-collapse-button`}\n onClick={\n collapsible ? handleExpandCollapseClick : undefined\n }\n className={clsx(\n styles.expandCollapseButton,\n expanded && styles.expandCollapseButtonExpanded,\n collapsible && styles.expandCollapseButtonCollapsible\n )}\n aria-controls={contentId}\n aria-disabled={!collapsible} // remains focusable\n aria-expanded={expanded}\n >\n {renderTitleText()}\n {collapsible && (\n <span\n data-testid={`${testId}-expand-collapse-icon`}\n className={clsx(\n styles.iconContainer,\n expanded && styles.iconContainerExpanded\n )}\n >\n <ChevronUpIcon className={styles.chevronIcon} />\n </span>\n )}\n </button>\n </h3>\n );\n };\n\n return (\n <div\n data-testid={testId}\n className={clsx(\n styles.container,\n expanded && styles.containerExpanded,\n className\n )}\n id={id}\n ref={elementRef}\n >\n {renderTitle()}\n {renderContent()}\n </div>\n );\n}\n\nexport const AccordionItem = forwardRef<\n AccordionItemHandle,\n AccordionItemProps\n>(Component);\n"],"names":["AccordionItem","forwardRef","title","children","type","collapsible","className","id","expanded","expandedControlled","onExpandChange","testId","ref","elementRef","useRef","expandAll","itemHeadingLevel","onItemStateChange","itemState","onItemDeregister","useContext","AccordionContext","hasFirstLoad","setHasFirstLoad","useState","internalId","useId","contentId","height","resizeDetectorRef","useResizeDetector","isControlled","undefined","_a","useImperativeHandle","Object","assign","current","expand","collapse","isExpanded","useEffect","next","handleExpandCollapseClick","event","preventDefault","expandableStyles","useSpring","_jsxs","clsx","styles.container","styles.containerExpanded","_jsx","onClick","styles.expandCollapseButton","styles.expandCollapseButtonExpanded","styles.expandCollapseButtonCollapsible","styles.title","styles.titleSmall","styles.iconContainer","styles.iconContainerExpanded","ChevronUpIcon","styles.chevronIcon","animated","div","styles.expandable","style","inert","inertValue","styles.contentContainer"],"mappings":"igCAmPaA,EAAgBC,GA3N7B,UACIC,MACIA,EAAKC,SACLA,EAAQC,KACRA,EAAO,UAASC,YAChBA,GAAc,EAAIC,UAClBA,EAASC,GACTA,EACAC,SAAUC,EAAkBC,eAC5BA,EACA,cAAeC,EAAS,kBAE5BC,SAKA,MAAMC,EAAaC,EAAuB,OACpCC,UACFA,EAASC,iBACTA,EAAgBC,kBAChBA,EAAiBC,UACjBA,EAASC,iBACTA,GACAC,EAAWC,IACRC,EAAcC,GAAmBC,GAAkB,GACpDC,EAAaC,IACbC,EAAY,GAAGF,aACfG,OAAEA,EAAQhB,IAAKiB,GAAsBC,IACrCC,OAAkCC,IAAnBtB,EACfF,EAAWuB,GACX1B,GACII,SAAAA,EAEiB,QAArBwB,EAAAf,EAAUO,UAAW,IAAAQ,EAAAA,GACpB5B,IAAcI,QAAAA,EAAsBM,GAE3CmB,EACItB,GACA,IACIuB,OAAOC,OACHvB,EAAWwB,QACX,CACI,MAAAC,GACQP,EACArB,SAAAA,GAAiB,GAEjBO,EAAkBQ,GAAY,EAEtC,EACA,QAAAc,GACQR,EACArB,SAAAA,GAAiB,GAEjBO,EAAkBQ,GAAY,EAEtC,EACAe,WAAU,IACChC,KAKvB,CAACA,IAMLiC,GAAU,KACNlB,GAAgB,GAET,IAAMJ,aAAgB,EAAhBA,EAAmBM,KAEjC,IAGHgB,GAAU,KACFV,GACAd,EACIQ,GACApB,GAAcI,SAAAA,EAEtB,GAED,CAACA,EAAoBJ,IAGxBoC,GAAU,KACDV,GACDd,EACIQ,GACApB,IAAcI,QAAAA,EAAsBM,GAE5C,GAED,CAACA,EAAWN,EAAoBJ,IAGnCoC,GAAU,KACN,IAAKV,IAAiBT,EAAc,OACpC,MAAMoB,GAAOrC,GAAcU,EACvB2B,IAASjC,IACTC,SAAAA,EAAiBgC,GACrB,GAED,CAAC3B,IAMJ,MAAM4B,EAA6BC,IAC/BA,EAAMC,iBACFd,EACArB,SAAAA,GAAkBF,GAElBS,EAAkBQ,GAAajB,EACnC,EAUEsC,EAAmBC,EAHJ,CACjBnB,OAAQpB,EAAWoB,EAAS,IA4EhC,OACIoB,EAAA,MAAA,CAAA,cACiBrC,EACbL,UAAW2C,EACPC,EACA1C,GAAY2C,EACZ7C,GAEJC,GAAIA,EACJK,IAAKC,EAAUV,SAAA,CAzCfiD,EAAA,KAAA,CAAA,aAAgBpC,WACZgC,EAAA,SAAA,CAAA,cACiB,GAAGrC,2BAChB0C,QACIhD,EAAcsC,OAA4BX,EAE9C1B,UAAW2C,EACPK,EACA9C,GAAY+C,EACZlD,GAAemD,mBAEJ7B,EAAS,iBACRtB,kBACDG,EAAQL,SAAA,CAhCd,iBAAVD,EACAA,EAIPkD,EAAA,OAAA,CAAA,cACiB,GAAGzC,UAChBL,UAAW2C,EACPQ,EACS,UAATrD,GAAoBsD,GACvBvD,SAEAD,IAuBIG,GACG+C,wBACiB,GAAGzC,yBAChBL,UAAW2C,EACPU,EACAnD,GAAYoD,GACfzD,SAEDiD,EAACS,EAAa,CAACvD,UAAWwD,WA9D1CV,EAACW,EAASC,IAAG,CACTzD,GAAIoB,EACJrB,UAAW2D,EACXC,MAAO5C,EAAewB,OAAmBd,EAAS,cACrC,GAAGrB,yBAChBwD,MAAOC,GAAY5D,GAASL,SAE5BiD,EAAA,MAAA,CACIxC,IAAKiB,EACLvB,UAAW+D,EAAuB,cACtB,oBAAmBlE,SAE9BA,QAyErB"}
@@ -62,6 +62,13 @@ export interface AccordionItemProps {
62
62
  * @default true
63
63
  */
64
64
  collapsible?: boolean | undefined;
65
+ /**
66
+ * Called when the user toggles this item or the parent "Show all" / "Hide all"
67
+ * button fires. When provided, the item enters **controlled mode** — the caller
68
+ * must update the `expanded` prop in response. Without this prop, the item
69
+ * manages its own state internally (uncontrolled mode).
70
+ */
71
+ onExpandChange?: ((expanded: boolean) => void) | undefined;
65
72
  }
66
73
  /** Imperative API available on the `Accordion.Item` ref. */
67
74
  export interface AccordionItemApi {
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime"),t=require("@lifesg/react-icons/chevron-up"),a=require("@react-spring/web"),n=require("clsx"),i=require("react"),r=require("../external/react-resize-detector/build/index.esm.js"),s=require("../shared/accessibility/index.js");require("../util/calendar-helper.js"),require("../external/dayjs/dayjs.min.js");var l=require("../util/simple-id-generator.js");require("../util/string-helper.js"),require("@react-aria/live-announcer");var d=require("./accordion-context.js"),c=require("./accordion-item.styles.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=o(n);const p=i.forwardRef((function({title:n,children:o,type:p="default",collapsible:x=!0,className:f,id:m,expanded:j,"data-testid":h="accordion-item"},v){var q;const b=i.useRef(null),{expandAll:g,itemHeadingLevel:C,onItemStateChange:y,itemState:N,onItemDeregister:I}=i.useContext(d.AccordionContext),[E,S]=i.useState(!1),$=l.useId(),A=`${$}-content`,{height:B,ref:D}=r.useResizeDetector(),R=null!==(q=N[$])&&void 0!==q?q:!x||(null!=j?j:g);i.useImperativeHandle(v,(()=>Object.assign(b.current,{expand(){y($,!0)},collapse(){y($,!1)},isExpanded:()=>R})),[R]),i.useEffect((()=>(S(!0),()=>null==I?void 0:I($))),[]),i.useEffect((()=>{y($,!x||(null!=j?j:g))}),[g,j,x]);const w=e=>{e.preventDefault(),y($,!R)},z={height:R?B:0},H=a.useSpring(z);return e.jsxs("div",{"data-testid":h,className:u.default(c.container,R&&c.containerExpanded,f),id:m,ref:b,children:[e.jsx("h3",{"aria-level":C,children:e.jsxs("button",{"data-testid":`${h}-expand-collapse-button`,onClick:x?w:void 0,className:u.default(c.expandCollapseButton,R&&c.expandCollapseButtonExpanded,x&&c.expandCollapseButtonCollapsible),"aria-controls":A,"aria-disabled":!x,"aria-expanded":R,children:["string"!=typeof n?n:e.jsx("span",{"data-testid":`${h}-title`,className:u.default(c.title,"small"===p&&c.titleSmall),children:n}),x&&e.jsx("span",{"data-testid":`${h}-expand-collapse-icon`,className:u.default(c.iconContainer,R&&c.iconContainerExpanded),children:e.jsx(t.ChevronUpIcon,{className:c.chevronIcon})})]})}),e.jsx(a.animated.div,{id:A,className:c.expandable,style:E?H:void 0,"data-testid":`${h}-expandable-container`,inert:s.inertValue(!R),children:e.jsx("div",{ref:D,className:c.contentContainer,"data-testid":"content-container",children:o})})]})}));exports.AccordionItem=p;
1
+ "use strict";var e=require("react/jsx-runtime"),t=require("@lifesg/react-icons/chevron-up"),a=require("@react-spring/web"),n=require("clsx"),i=require("react"),r=require("../external/react-resize-detector/build/index.esm.js"),l=require("../shared/accessibility/index.js");require("../util/calendar-helper.js"),require("../external/dayjs/dayjs.min.js");var s=require("../util/simple-id-generator.js");require("../util/string-helper.js"),require("@react-aria/live-announcer");var d=require("./accordion-context.js"),c=require("./accordion-item.styles.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=o(n);const p=i.forwardRef((function({title:n,children:o,type:p="default",collapsible:x=!0,className:f,id:m,expanded:h,onExpandChange:j,"data-testid":v="accordion-item"},q){var g;const C=i.useRef(null),{expandAll:b,itemHeadingLevel:E,onItemStateChange:y,itemState:N,onItemDeregister:I}=i.useContext(d.AccordionContext),[S,$]=i.useState(!1),A=s.useId(),B=`${A}-content`,{height:D,ref:R}=r.useResizeDetector(),w=void 0!==j,z=w?!x||null!=h&&h:null!==(g=N[A])&&void 0!==g?g:!x||(null!=h?h:b);i.useImperativeHandle(q,(()=>Object.assign(C.current,{expand(){w?null==j||j(!0):y(A,!0)},collapse(){w?null==j||j(!1):y(A,!1)},isExpanded:()=>z})),[z]),i.useEffect((()=>($(!0),()=>null==I?void 0:I(A))),[]),i.useEffect((()=>{w&&y(A,!x||null!=h&&h)}),[h,x]),i.useEffect((()=>{w||y(A,!x||(null!=h?h:b))}),[b,h,x]),i.useEffect((()=>{if(!w||!S)return;const e=!x||b;e!==h&&(null==j||j(e))}),[b]);const H=e=>{e.preventDefault(),w?null==j||j(!z):y(A,!z)},k={height:z?D:0},L=a.useSpring(k);return e.jsxs("div",{"data-testid":v,className:u.default(c.container,z&&c.containerExpanded,f),id:m,ref:C,children:[e.jsx("h3",{"aria-level":E,children:e.jsxs("button",{"data-testid":`${v}-expand-collapse-button`,onClick:x?H:void 0,className:u.default(c.expandCollapseButton,z&&c.expandCollapseButtonExpanded,x&&c.expandCollapseButtonCollapsible),"aria-controls":B,"aria-disabled":!x,"aria-expanded":z,children:["string"!=typeof n?n:e.jsx("span",{"data-testid":`${v}-title`,className:u.default(c.title,"small"===p&&c.titleSmall),children:n}),x&&e.jsx("span",{"data-testid":`${v}-expand-collapse-icon`,className:u.default(c.iconContainer,z&&c.iconContainerExpanded),children:e.jsx(t.ChevronUpIcon,{className:c.chevronIcon})})]})}),e.jsx(a.animated.div,{id:B,className:c.expandable,style:S?L:void 0,"data-testid":`${v}-expandable-container`,inert:l.inertValue(!z),children:e.jsx("div",{ref:R,className:c.contentContainer,"data-testid":"content-container",children:o})})]})}));exports.AccordionItem=p;
2
2
  //# sourceMappingURL=accordion-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accordion-item.js","sources":["../../../src/accordion/accordion-item.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { inertValue } from \"../shared/accessibility\";\nimport { useId } from \"../util\";\nimport { AccordionContext } from \"./accordion-context\";\nimport * as styles from \"./accordion-item.styles\";\nimport type {\n AccordionItemApi,\n AccordionItemHandle,\n AccordionItemProps,\n} from \"./types\";\n\nfunction Component(\n {\n title,\n children,\n type = \"default\",\n collapsible = true,\n className,\n id,\n expanded: expandedControlled,\n \"data-testid\": testId = \"accordion-item\",\n }: AccordionItemProps,\n ref: React.Ref<AccordionItemHandle>\n) {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const elementRef = useRef<HTMLDivElement>(null);\n const {\n expandAll,\n itemHeadingLevel,\n onItemStateChange,\n itemState,\n onItemDeregister,\n } = useContext(AccordionContext);\n const [hasFirstLoad, setHasFirstLoad] = useState<boolean>(false);\n const internalId = useId();\n const contentId = `${internalId}-content`;\n const { height, ref: resizeDetectorRef } = useResizeDetector();\n const expanded =\n itemState[internalId] ??\n (collapsible ? expandedControlled ?? expandAll : true); // the initial value\n\n useImperativeHandle(\n ref,\n () =>\n Object.assign<HTMLDivElement, AccordionItemApi>(\n elementRef.current!,\n {\n expand(): void {\n onItemStateChange(internalId, true);\n },\n collapse(): void {\n onItemStateChange(internalId, false);\n },\n isExpanded() {\n return expanded;\n },\n }\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [expanded]\n );\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setHasFirstLoad(true);\n\n return () => onItemDeregister?.(internalId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n onItemStateChange(\n internalId,\n collapsible ? expandedControlled ?? expandAll : true\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandAll, expandedControlled, collapsible]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n\n const handleExpandCollapseClick = (event: React.MouseEvent) => {\n event.preventDefault();\n onItemStateChange(internalId, !expanded);\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n // React spring animation configuration\n const resizeHeight = {\n height: expanded ? height : 0,\n };\n const expandableStyles = useSpring(resizeHeight);\n\n const renderContent = () => {\n return (\n <animated.div\n id={contentId}\n className={styles.expandable}\n style={hasFirstLoad ? expandableStyles : undefined}\n data-testid={`${testId}-expandable-container`}\n inert={inertValue(!expanded)}\n >\n <div\n ref={resizeDetectorRef}\n className={styles.contentContainer}\n data-testid=\"content-container\"\n >\n {children}\n </div>\n </animated.div>\n );\n };\n\n const renderTitleText = () => {\n if (typeof title !== \"string\") {\n return title;\n }\n\n return (\n <span\n data-testid={`${testId}-title`}\n className={clsx(\n styles.title,\n type === \"small\" && styles.titleSmall\n )}\n >\n {title}\n </span>\n );\n };\n\n const renderTitle = () => {\n return (\n <h3 aria-level={itemHeadingLevel}>\n <button\n data-testid={`${testId}-expand-collapse-button`}\n onClick={\n collapsible ? handleExpandCollapseClick : undefined\n }\n className={clsx(\n styles.expandCollapseButton,\n expanded && styles.expandCollapseButtonExpanded,\n collapsible && styles.expandCollapseButtonCollapsible\n )}\n aria-controls={contentId}\n aria-disabled={!collapsible} // remains focusable\n aria-expanded={expanded}\n >\n {renderTitleText()}\n {collapsible && (\n <span\n data-testid={`${testId}-expand-collapse-icon`}\n className={clsx(\n styles.iconContainer,\n expanded && styles.iconContainerExpanded\n )}\n >\n <ChevronUpIcon className={styles.chevronIcon} />\n </span>\n )}\n </button>\n </h3>\n );\n };\n\n return (\n <div\n data-testid={testId}\n className={clsx(\n styles.container,\n expanded && styles.containerExpanded,\n className\n )}\n id={id}\n ref={elementRef}\n >\n {renderTitle()}\n {renderContent()}\n </div>\n );\n}\n\nexport const AccordionItem = forwardRef<\n AccordionItemHandle,\n AccordionItemProps\n>(Component);\n"],"names":["AccordionItem","forwardRef","title","children","type","collapsible","className","id","expanded","expandedControlled","testId","ref","elementRef","useRef","expandAll","itemHeadingLevel","onItemStateChange","itemState","onItemDeregister","useContext","AccordionContext","hasFirstLoad","setHasFirstLoad","useState","internalId","useId","contentId","height","resizeDetectorRef","useResizeDetector","_a","useImperativeHandle","Object","assign","current","expand","collapse","isExpanded","useEffect","handleExpandCollapseClick","event","preventDefault","resizeHeight","expandableStyles","useSpring","_jsxs","clsx","styles.container","styles.containerExpanded","_jsx","onClick","undefined","styles.expandCollapseButton","styles.expandCollapseButtonExpanded","styles.expandCollapseButtonCollapsible","styles.title","styles.titleSmall","styles.iconContainer","styles.iconContainerExpanded","ChevronUpIcon","styles.chevronIcon","animated","div","styles.expandable","style","inert","inertValue","styles.contentContainer"],"mappings":"moBA0MaA,EAAgBC,EAAAA,YAlL7B,UACIC,MACIA,EAAKC,SACLA,EAAQC,KACRA,EAAO,UAASC,YAChBA,GAAc,EAAIC,UAClBA,EAASC,GACTA,EACAC,SAAUC,EACV,cAAeC,EAAS,kBAE5BC,SAKA,MAAMC,EAAaC,EAAAA,OAAuB,OACpCC,UACFA,EAASC,iBACTA,EAAgBC,kBAChBA,EAAiBC,UACjBA,EAASC,iBACTA,GACAC,EAAAA,WAAWC,qBACRC,EAAcC,GAAmBC,EAAAA,UAAkB,GACpDC,EAAaC,EAAAA,QACbC,EAAY,GAAGF,aACfG,OAAEA,EAAQhB,IAAKiB,GAAsBC,EAAAA,oBACrCrB,EACmB,QAArBsB,EAAAb,EAAUO,UAAW,IAAAM,EAAAA,GACpBzB,IAAcI,QAAAA,EAAsBK,GAEzCiB,EAAAA,oBACIpB,GACA,IACIqB,OAAOC,OACHrB,EAAWsB,QACX,CACI,MAAAC,GACInB,EAAkBQ,GAAY,EAClC,EACA,QAAAY,GACIpB,EAAkBQ,GAAY,EAClC,EACAa,WAAU,IACC7B,KAKvB,CAACA,IAML8B,EAAAA,WAAU,KACNhB,GAAgB,GAET,IAAMJ,aAAgB,EAAhBA,EAAmBM,KAEjC,IAEHc,EAAAA,WAAU,KACNtB,EACIQ,GACAnB,IAAcI,QAAAA,EAAsBK,GACvC,GAEF,CAACA,EAAWL,EAAoBJ,IAMnC,MAAMkC,EAA6BC,IAC/BA,EAAMC,iBACNzB,EAAkBQ,GAAahB,EAAS,EAOtCkC,EAAe,CACjBf,OAAQnB,EAAWmB,EAAS,GAE1BgB,EAAmBC,EAAAA,UAAUF,GA0EnC,OACIG,EAAAA,KAAA,MAAA,CAAA,cACiBnC,EACbJ,UAAWwC,EAAAA,QACPC,YACAvC,GAAYwC,EAAAA,kBACZ1C,GAEJC,GAAIA,EACJI,IAAKC,EAAUT,SAAA,CAzCf8C,EAAAA,IAAA,KAAA,CAAA,aAAgBlC,WACZ8B,OAAA,SAAA,CAAA,cACiB,GAAGnC,2BAChBwC,QACI7C,EAAckC,OAA4BY,EAE9C7C,UAAWwC,EAAAA,QACPM,EAAAA,qBACA5C,GAAY6C,+BACZhD,GAAeiD,EAAAA,iDAEJ5B,EAAS,iBACRrB,kBACDG,EAAQL,SAAA,CAhCd,iBAAVD,EACAA,EAIP+C,EAAAA,IAAA,OAAA,CAAA,cACiB,GAAGvC,UAChBJ,UAAWwC,EAAAA,QACPS,EAAAA,MACS,UAATnD,GAAoBoD,EAAAA,YACvBrD,SAEAD,IAuBIG,GACG4C,EAAAA,0BACiB,GAAGvC,yBAChBJ,UAAWwC,UACPW,EAAAA,cACAjD,GAAYkD,EAAAA,uBACfvD,SAED8C,EAAAA,IAACU,EAAAA,cAAa,CAACrD,UAAWsD,EAAAA,qBA9D1CX,EAAAA,IAACY,EAAAA,SAASC,IAAG,CACTvD,GAAImB,EACJpB,UAAWyD,EAAAA,WACXC,MAAO3C,EAAesB,OAAmBQ,EAAS,cACrC,GAAGzC,yBAChBuD,MAAOC,EAAAA,YAAY1D,GAASL,SAE5B8C,EAAAA,IAAA,MAAA,CACItC,IAAKiB,EACLtB,UAAW6D,EAAAA,iBAAuB,cACtB,oBAAmBhE,SAE9BA,QAyErB"}
1
+ {"version":3,"file":"accordion-item.js","sources":["../../../src/accordion/accordion-item.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { inertValue } from \"../shared/accessibility\";\nimport { useId } from \"../util\";\nimport { AccordionContext } from \"./accordion-context\";\nimport * as styles from \"./accordion-item.styles\";\nimport type {\n AccordionItemApi,\n AccordionItemHandle,\n AccordionItemProps,\n} from \"./types\";\n\nfunction Component(\n {\n title,\n children,\n type = \"default\",\n collapsible = true,\n className,\n id,\n expanded: expandedControlled,\n onExpandChange,\n \"data-testid\": testId = \"accordion-item\",\n }: AccordionItemProps,\n ref: React.Ref<AccordionItemHandle>\n) {\n // =========================================================================\n // CONST, STATE, REF\n // =========================================================================\n const elementRef = useRef<HTMLDivElement>(null);\n const {\n expandAll,\n itemHeadingLevel,\n onItemStateChange,\n itemState,\n onItemDeregister,\n } = useContext(AccordionContext);\n const [hasFirstLoad, setHasFirstLoad] = useState<boolean>(false);\n const internalId = useId();\n const contentId = `${internalId}-content`;\n const { height, ref: resizeDetectorRef } = useResizeDetector();\n const isControlled = onExpandChange !== undefined;\n const expanded = isControlled\n ? collapsible\n ? expandedControlled ?? false\n : true\n : itemState[internalId] ??\n (collapsible ? expandedControlled ?? expandAll : true);\n\n useImperativeHandle(\n ref,\n () =>\n Object.assign<HTMLDivElement, AccordionItemApi>(\n elementRef.current!,\n {\n expand(): void {\n if (isControlled) {\n onExpandChange?.(true);\n } else {\n onItemStateChange(internalId, true);\n }\n },\n collapse(): void {\n if (isControlled) {\n onExpandChange?.(false);\n } else {\n onItemStateChange(internalId, false);\n }\n },\n isExpanded() {\n return expanded;\n },\n }\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [expanded]\n );\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setHasFirstLoad(true);\n\n return () => onItemDeregister?.(internalId);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Controlled mode: keep parent itemState in sync so \"Show all\"/\"Hide all\" label stays accurate\n useEffect(() => {\n if (isControlled) {\n onItemStateChange(\n internalId,\n collapsible ? expandedControlled ?? false : true\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandedControlled, collapsible]);\n\n // Uncontrolled mode: sync state when expandAll button or the hint prop changes\n useEffect(() => {\n if (!isControlled) {\n onItemStateChange(\n internalId,\n collapsible ? expandedControlled ?? expandAll : true\n );\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandAll, expandedControlled, collapsible]);\n\n // Controlled mode: forward expandAll button changes to the caller\n useEffect(() => {\n if (!isControlled || !hasFirstLoad) return;\n const next = collapsible ? expandAll : true;\n if (next !== expandedControlled) {\n onExpandChange?.(next);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [expandAll]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n\n const handleExpandCollapseClick = (event: React.MouseEvent) => {\n event.preventDefault();\n if (isControlled) {\n onExpandChange?.(!expanded);\n } else {\n onItemStateChange(internalId, !expanded);\n }\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n // React spring animation configuration\n const resizeHeight = {\n height: expanded ? height : 0,\n };\n const expandableStyles = useSpring(resizeHeight);\n\n const renderContent = () => {\n return (\n <animated.div\n id={contentId}\n className={styles.expandable}\n style={hasFirstLoad ? expandableStyles : undefined}\n data-testid={`${testId}-expandable-container`}\n inert={inertValue(!expanded)}\n >\n <div\n ref={resizeDetectorRef}\n className={styles.contentContainer}\n data-testid=\"content-container\"\n >\n {children}\n </div>\n </animated.div>\n );\n };\n\n const renderTitleText = () => {\n if (typeof title !== \"string\") {\n return title;\n }\n\n return (\n <span\n data-testid={`${testId}-title`}\n className={clsx(\n styles.title,\n type === \"small\" && styles.titleSmall\n )}\n >\n {title}\n </span>\n );\n };\n\n const renderTitle = () => {\n return (\n <h3 aria-level={itemHeadingLevel}>\n <button\n data-testid={`${testId}-expand-collapse-button`}\n onClick={\n collapsible ? handleExpandCollapseClick : undefined\n }\n className={clsx(\n styles.expandCollapseButton,\n expanded && styles.expandCollapseButtonExpanded,\n collapsible && styles.expandCollapseButtonCollapsible\n )}\n aria-controls={contentId}\n aria-disabled={!collapsible} // remains focusable\n aria-expanded={expanded}\n >\n {renderTitleText()}\n {collapsible && (\n <span\n data-testid={`${testId}-expand-collapse-icon`}\n className={clsx(\n styles.iconContainer,\n expanded && styles.iconContainerExpanded\n )}\n >\n <ChevronUpIcon className={styles.chevronIcon} />\n </span>\n )}\n </button>\n </h3>\n );\n };\n\n return (\n <div\n data-testid={testId}\n className={clsx(\n styles.container,\n expanded && styles.containerExpanded,\n className\n )}\n id={id}\n ref={elementRef}\n >\n {renderTitle()}\n {renderContent()}\n </div>\n );\n}\n\nexport const AccordionItem = forwardRef<\n AccordionItemHandle,\n AccordionItemProps\n>(Component);\n"],"names":["AccordionItem","forwardRef","title","children","type","collapsible","className","id","expanded","expandedControlled","onExpandChange","testId","ref","elementRef","useRef","expandAll","itemHeadingLevel","onItemStateChange","itemState","onItemDeregister","useContext","AccordionContext","hasFirstLoad","setHasFirstLoad","useState","internalId","useId","contentId","height","resizeDetectorRef","useResizeDetector","isControlled","undefined","_a","useImperativeHandle","Object","assign","current","expand","collapse","isExpanded","useEffect","next","handleExpandCollapseClick","event","preventDefault","resizeHeight","expandableStyles","useSpring","_jsxs","clsx","styles.container","styles.containerExpanded","_jsx","onClick","styles.expandCollapseButton","styles.expandCollapseButtonExpanded","styles.expandCollapseButtonCollapsible","styles.title","styles.titleSmall","styles.iconContainer","styles.iconContainerExpanded","ChevronUpIcon","styles.chevronIcon","animated","div","styles.expandable","style","inert","inertValue","styles.contentContainer"],"mappings":"moBAmPaA,EAAgBC,EAAAA,YA3N7B,UACIC,MACIA,EAAKC,SACLA,EAAQC,KACRA,EAAO,UAASC,YAChBA,GAAc,EAAIC,UAClBA,EAASC,GACTA,EACAC,SAAUC,EAAkBC,eAC5BA,EACA,cAAeC,EAAS,kBAE5BC,SAKA,MAAMC,EAAaC,EAAAA,OAAuB,OACpCC,UACFA,EAASC,iBACTA,EAAgBC,kBAChBA,EAAiBC,UACjBA,EAASC,iBACTA,GACAC,EAAAA,WAAWC,qBACRC,EAAcC,GAAmBC,EAAAA,UAAkB,GACpDC,EAAaC,EAAAA,QACbC,EAAY,GAAGF,aACfG,OAAEA,EAAQhB,IAAKiB,GAAsBC,EAAAA,oBACrCC,OAAkCC,IAAnBtB,EACfF,EAAWuB,GACX1B,GACII,SAAAA,EAEiB,QAArBwB,EAAAf,EAAUO,UAAW,IAAAQ,EAAAA,GACpB5B,IAAcI,QAAAA,EAAsBM,GAE3CmB,EAAAA,oBACItB,GACA,IACIuB,OAAOC,OACHvB,EAAWwB,QACX,CACI,MAAAC,GACQP,EACArB,SAAAA,GAAiB,GAEjBO,EAAkBQ,GAAY,EAEtC,EACA,QAAAc,GACQR,EACArB,SAAAA,GAAiB,GAEjBO,EAAkBQ,GAAY,EAEtC,EACAe,WAAU,IACChC,KAKvB,CAACA,IAMLiC,EAAAA,WAAU,KACNlB,GAAgB,GAET,IAAMJ,aAAgB,EAAhBA,EAAmBM,KAEjC,IAGHgB,EAAAA,WAAU,KACFV,GACAd,EACIQ,GACApB,GAAcI,SAAAA,EAEtB,GAED,CAACA,EAAoBJ,IAGxBoC,EAAAA,WAAU,KACDV,GACDd,EACIQ,GACApB,IAAcI,QAAAA,EAAsBM,GAE5C,GAED,CAACA,EAAWN,EAAoBJ,IAGnCoC,EAAAA,WAAU,KACN,IAAKV,IAAiBT,EAAc,OACpC,MAAMoB,GAAOrC,GAAcU,EACvB2B,IAASjC,IACTC,SAAAA,EAAiBgC,GACrB,GAED,CAAC3B,IAMJ,MAAM4B,EAA6BC,IAC/BA,EAAMC,iBACFd,EACArB,SAAAA,GAAkBF,GAElBS,EAAkBQ,GAAajB,EACnC,EAOEsC,EAAe,CACjBlB,OAAQpB,EAAWoB,EAAS,GAE1BmB,EAAmBC,EAAAA,UAAUF,GA0EnC,OACIG,EAAAA,KAAA,MAAA,CAAA,cACiBtC,EACbL,UAAW4C,EAAAA,QACPC,YACA3C,GAAY4C,EAAAA,kBACZ9C,GAEJC,GAAIA,EACJK,IAAKC,EAAUV,SAAA,CAzCfkD,EAAAA,IAAA,KAAA,CAAA,aAAgBrC,WACZiC,OAAA,SAAA,CAAA,cACiB,GAAGtC,2BAChB2C,QACIjD,EAAcsC,OAA4BX,EAE9C1B,UAAW4C,EAAAA,QACPK,EAAAA,qBACA/C,GAAYgD,+BACZnD,GAAeoD,EAAAA,iDAEJ9B,EAAS,iBACRtB,kBACDG,EAAQL,SAAA,CAhCd,iBAAVD,EACAA,EAIPmD,EAAAA,IAAA,OAAA,CAAA,cACiB,GAAG1C,UAChBL,UAAW4C,EAAAA,QACPQ,EAAAA,MACS,UAATtD,GAAoBuD,EAAAA,YACvBxD,SAEAD,IAuBIG,GACGgD,EAAAA,0BACiB,GAAG1C,yBAChBL,UAAW4C,UACPU,EAAAA,cACApD,GAAYqD,EAAAA,uBACf1D,SAEDkD,EAAAA,IAACS,EAAAA,cAAa,CAACxD,UAAWyD,EAAAA,qBA9D1CV,EAAAA,IAACW,EAAAA,SAASC,IAAG,CACT1D,GAAIoB,EACJrB,UAAW4D,EAAAA,WACXC,MAAO7C,EAAeyB,OAAmBf,EAAS,cACrC,GAAGrB,yBAChByD,MAAOC,EAAAA,YAAY7D,GAASL,SAE5BkD,EAAAA,IAAA,MAAA,CACIzC,IAAKiB,EACLvB,UAAWgE,EAAAA,iBAAuB,cACtB,oBAAmBnE,SAE9BA,QAyErB"}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime");require("./sgds-day.css"),require("./sgds-night.css");var t=require("clsx"),r=require("react");require("../theme/theme-provider/index.js");var s=require("../theme/theme-provider/hooks.js");require("../theme/tokens/border.js"),require("../theme/tokens/colour.js"),require("../theme/tokens/font.js"),require("../theme/tokens/media-query.js"),require("../util/calendar-helper.js"),require("../external/dayjs/dayjs.min.js"),require("../util/simple-id-generator.js"),require("../util/string-helper.js"),require("@react-aria/live-announcer"),require("../theme/utils/use-media-query.js");var d=require("./masthead.styles.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=n(t);const u=r.memo((({stretch:t=!1})=>{const{mode:n}=s.useTheme(),u="dark"===n;r.useEffect((()=>{c()||l()}),[]),r.useEffect((()=>{u?document.documentElement.classList.add(o):document.documentElement.classList.remove(o)}),[u]);const c=()=>document.getElementById(a),l=()=>{if(!document.getElementById(a)){const e=document.createElement("script");e.id=a,e.type="module",e.src=m,document.head.appendChild(e)}};return e.jsx("div",{className:i.default(d.wrapper,t&&d.wrapperStretch),dangerouslySetInnerHTML:{__html:"<sgds-masthead></sgds-masthead>"}})})),a="lifesg-ds-masthead-script",m="https://cdn.jsdelivr.net/npm/@govtechsg/sgds-web-component@3/components/Masthead/index.umd.js",o="sgds-night-theme";exports.Masthead=u;
1
+ "use strict";var e=require("react/jsx-runtime");require("./sgds-day.css"),require("./sgds-night.css");var r=require("clsx"),s=require("react");require("../theme/theme-provider/index.js");var t=require("../theme/theme-provider/hooks.js");require("../theme/tokens/border.js"),require("../theme/tokens/colour.js"),require("../theme/tokens/font.js"),require("../theme/tokens/media-query.js"),require("../util/calendar-helper.js"),require("../external/dayjs/dayjs.min.js"),require("../util/simple-id-generator.js"),require("../util/string-helper.js"),require("@react-aria/live-announcer"),require("../theme/utils/use-media-query.js");var i=require("./masthead.styles.js");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=u(r);const n=s.memo((({stretch:r=!1})=>{const{mode:u}=t.useTheme(),n="dark"===u;s.useEffect((()=>{import("@govtechsg/sgds-web-component/components/Masthead/index.js")}),[]),s.useEffect((()=>{n?document.documentElement.classList.add(d):document.documentElement.classList.remove(d)}),[n]);return e.jsx("div",{className:a.default(i.wrapper,r&&i.wrapperStretch),dangerouslySetInnerHTML:{__html:"<sgds-masthead></sgds-masthead>"}})})),d="sgds-night-theme";exports.Masthead=n;
2
2
  //# sourceMappingURL=masthead.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"masthead.js","sources":["../../../src/masthead/masthead.tsx"],"sourcesContent":["import \"@govtechsg/sgds-web-component/themes/day.css\";\nimport \"@govtechsg/sgds-web-component/themes/night.css\";\n\nimport clsx from \"clsx\";\nimport { memo, useEffect } from \"react\";\n\nimport { useTheme } from \"../theme\";\nimport * as styles from \"./masthead.styles\";\nimport type { MastheadProps } from \"./types\";\n\nconst MastheadComponent = ({ stretch = false }: MastheadProps): JSX.Element => {\n const { mode } = useTheme();\n const isDarkMode = mode === \"dark\";\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n if (!doAssetsExist()) {\n addAssets();\n }\n }, []);\n\n useEffect(() => {\n // SGDS dark mode only takes effect when this class is set on the :root element\n if (isDarkMode) {\n document.documentElement.classList.add(SGDS_THEME_NIGHT_CLASSNAME);\n } else {\n document.documentElement.classList.remove(\n SGDS_THEME_NIGHT_CLASSNAME\n );\n }\n }, [isDarkMode]);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const doAssetsExist = () => {\n return document.getElementById(SCRIPT_ID);\n };\n\n const addAssets = () => {\n if (!document.getElementById(SCRIPT_ID)) {\n const script = document.createElement(\"script\");\n script.id = SCRIPT_ID;\n script.type = \"module\";\n script.src = SCRIPT_SRC;\n\n document.head.appendChild(script);\n }\n };\n\n const createContent = () => {\n /**\n * Note: Had to use this method because we had to create a\n * custom type to handle Web Components (refer to this guide\n * https://blog.devgenius.io/how-to-use-web-components-in-react-54c951399bfd)\n * But we are having troubles exporting the custom type definition\n * via rollup\n */\n return { __html: \"<sgds-masthead></sgds-masthead>\" };\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n\n return (\n <div\n className={clsx(styles.wrapper, stretch && styles.wrapperStretch)}\n dangerouslySetInnerHTML={createContent()}\n />\n );\n};\n\n// @catalog\n/**\n * Displays the Singapore Government Design System (SGDS) masthead banner.\n *\n * Use `Masthead` at the top of government digital services to meet the SGDS\n * masthead requirement.\n * @keywords banner, branding, compliance, government, SGDS\n */\nexport const Masthead = memo(MastheadComponent);\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\nconst SCRIPT_ID = \"lifesg-ds-masthead-script\";\nconst SCRIPT_SRC =\n \"https://cdn.jsdelivr.net/npm/@govtechsg/sgds-web-component@3/components/Masthead/index.umd.js\";\nconst SGDS_THEME_NIGHT_CLASSNAME = \"sgds-night-theme\";\n"],"names":["Masthead","memo","stretch","mode","useTheme","isDarkMode","useEffect","doAssetsExist","addAssets","document","documentElement","classList","add","SGDS_THEME_NIGHT_CLASSNAME","remove","getElementById","SCRIPT_ID","script","createElement","id","type","src","SCRIPT_SRC","head","appendChild","_jsx","className","clsx","styles.wrapper","styles.wrapperStretch","dangerouslySetInnerHTML","__html"],"mappings":"4wBAUA,MAyEaA,EAAWC,EAAAA,MAzEE,EAAGC,WAAU,MACnC,MAAMC,KAAEA,GAASC,aACXC,EAAsB,SAATF,EAKnBG,EAAAA,WAAU,KACDC,KACDC,GACJ,GACD,IAEHF,EAAAA,WAAU,KAEFD,EACAI,SAASC,gBAAgBC,UAAUC,IAAIC,GAEvCJ,SAASC,gBAAgBC,UAAUG,OAC/BD,EAER,GACD,CAACR,IAKJ,MAAME,EAAgB,IACXE,SAASM,eAAeC,GAG7BR,EAAY,KACd,IAAKC,SAASM,eAAeC,GAAY,CACrC,MAAMC,EAASR,SAASS,cAAc,UACtCD,EAAOE,GAAKH,EACZC,EAAOG,KAAO,SACdH,EAAOI,IAAMC,EAEbb,SAASc,KAAKC,YAAYP,EAC9B,GAkBJ,OACIQ,aACIC,UAAWC,EAAAA,QAAKC,EAAAA,QAAgB1B,GAAW2B,kBAC3CC,wBAVG,CAAEC,OAAQ,oCAWf,IAiBJf,EAAY,4BACZM,EACF,gGACET,EAA6B"}
1
+ {"version":3,"file":"masthead.js","sources":["../../../src/masthead/masthead.tsx"],"sourcesContent":["import \"@govtechsg/sgds-web-component/themes/day.css\";\nimport \"@govtechsg/sgds-web-component/themes/night.css\";\n\nimport clsx from \"clsx\";\nimport { memo, useEffect } from \"react\";\n\nimport { useTheme } from \"../theme\";\nimport * as styles from \"./masthead.styles\";\nimport type { MastheadProps } from \"./types\";\n\nconst MastheadComponent = ({ stretch = false }: MastheadProps): JSX.Element => {\n const { mode } = useTheme();\n const isDarkMode = mode === \"dark\";\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n import(\"@govtechsg/sgds-web-component/components/Masthead/index.js\");\n }, []);\n\n useEffect(() => {\n // SGDS dark mode only takes effect when this class is set on the :root element\n if (isDarkMode) {\n document.documentElement.classList.add(SGDS_THEME_NIGHT_CLASSNAME);\n } else {\n document.documentElement.classList.remove(\n SGDS_THEME_NIGHT_CLASSNAME\n );\n }\n }, [isDarkMode]);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const createContent = () => {\n /**\n * Note: Had to use this method because we had to create a\n * custom type to handle Web Components (refer to this guide\n * https://blog.devgenius.io/how-to-use-web-components-in-react-54c951399bfd)\n * But we are having troubles exporting the custom type definition\n * via rollup\n */\n return { __html: \"<sgds-masthead></sgds-masthead>\" };\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n\n return (\n <div\n className={clsx(styles.wrapper, stretch && styles.wrapperStretch)}\n dangerouslySetInnerHTML={createContent()}\n />\n );\n};\n\n// @catalog\n/**\n * Displays the Singapore Government Design System (SGDS) masthead banner.\n *\n * Use `Masthead` at the top of government digital services to meet the SGDS\n * masthead requirement.\n * @keywords banner, branding, compliance, government, SGDS\n */\nexport const Masthead = memo(MastheadComponent);\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\nconst SGDS_THEME_NIGHT_CLASSNAME = \"sgds-night-theme\";\n"],"names":["Masthead","memo","stretch","mode","useTheme","isDarkMode","useEffect","import","document","documentElement","classList","add","SGDS_THEME_NIGHT_CLASSNAME","remove","_jsx","className","clsx","styles.wrapper","styles.wrapperStretch","dangerouslySetInnerHTML","__html"],"mappings":"4wBAUA,MAwDaA,EAAWC,EAAAA,MAxDE,EAAGC,WAAU,MACnC,MAAMC,KAAEA,GAASC,aACXC,EAAsB,SAATF,EAKnBG,EAAAA,WAAU,KACNC,OAAO,6DAA6D,GACrE,IAEHD,EAAAA,WAAU,KAEFD,EACAG,SAASC,gBAAgBC,UAAUC,IAAIC,GAEvCJ,SAASC,gBAAgBC,UAAUG,OAC/BD,EAER,GACD,CAACP,IAoBJ,OACIS,aACIC,UAAWC,EAAAA,QAAKC,EAAAA,QAAgBf,GAAWgB,kBAC3CC,wBAVG,CAAEC,OAAQ,oCAWf,IAiBJR,EAA6B"}