no-frills-ui 0.0.14-rc.0 → 0.0.14-rc.2

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 (60) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +389 -195
  3. package/dist/index.js.map +1 -1
  4. package/lib-esm/components/Accordion/Accordion.js +10 -1
  5. package/lib-esm/components/Accordion/Accordion.js.map +1 -1
  6. package/lib-esm/components/Accordion/AccordionStep.js +9 -9
  7. package/lib-esm/components/Accordion/AccordionStep.js.map +1 -1
  8. package/lib-esm/components/Card/Card.js +2 -2
  9. package/lib-esm/components/Card/Card.js.map +1 -1
  10. package/lib-esm/components/Chip/Chip.js +2 -2
  11. package/lib-esm/components/ChipInput/ChipInput.d.ts +1 -1
  12. package/lib-esm/components/ChipInput/ChipInput.js +14 -6
  13. package/lib-esm/components/ChipInput/ChipInput.js.map +1 -1
  14. package/lib-esm/components/DragAndDrop/DragAndDrop.js +2 -2
  15. package/lib-esm/components/DragAndDrop/DragItem.js +2 -2
  16. package/lib-esm/components/Drawer/Drawer.d.ts +1 -1
  17. package/lib-esm/components/Drawer/Drawer.js +2 -3
  18. package/lib-esm/components/Drawer/Drawer.js.map +1 -1
  19. package/lib-esm/components/Groups/Group.js +3 -3
  20. package/lib-esm/components/Groups/Group.js.map +1 -1
  21. package/lib-esm/components/Input/Checkbox.d.ts +2 -0
  22. package/lib-esm/components/Input/Checkbox.js +54 -23
  23. package/lib-esm/components/Input/Checkbox.js.map +1 -1
  24. package/lib-esm/components/Input/Dropdown.d.ts +2 -0
  25. package/lib-esm/components/Input/Dropdown.js +123 -59
  26. package/lib-esm/components/Input/Dropdown.js.map +1 -1
  27. package/lib-esm/components/Input/Input.js +17 -8
  28. package/lib-esm/components/Input/Input.js.map +1 -1
  29. package/lib-esm/components/Input/Radio.d.ts +2 -0
  30. package/lib-esm/components/Input/Radio.js +22 -10
  31. package/lib-esm/components/Input/Radio.js.map +1 -1
  32. package/lib-esm/components/Input/RadioButton.d.ts +2 -0
  33. package/lib-esm/components/Input/RadioButton.js +21 -9
  34. package/lib-esm/components/Input/RadioButton.js.map +1 -1
  35. package/lib-esm/components/Input/Select.js +21 -11
  36. package/lib-esm/components/Input/Select.js.map +1 -1
  37. package/lib-esm/components/Input/TextArea.js +17 -8
  38. package/lib-esm/components/Input/TextArea.js.map +1 -1
  39. package/lib-esm/components/Input/Toggle.d.ts +2 -0
  40. package/lib-esm/components/Input/Toggle.js +45 -15
  41. package/lib-esm/components/Input/Toggle.js.map +1 -1
  42. package/lib-esm/components/Input/index.d.ts +1 -0
  43. package/lib-esm/components/Menu/MenuItem.d.ts +1 -1
  44. package/lib-esm/components/Menu/MenuItem.js +1 -1
  45. package/lib-esm/components/Menu/MenuItem.js.map +1 -1
  46. package/lib-esm/components/Modal/Modal.d.ts +1 -1
  47. package/lib-esm/components/Modal/Modal.js +1 -2
  48. package/lib-esm/components/Modal/Modal.js.map +1 -1
  49. package/lib-esm/components/Popover/Popover.d.ts +1 -1
  50. package/lib-esm/components/Popover/Popover.js +3 -3
  51. package/lib-esm/components/Popover/Popover.js.map +1 -1
  52. package/lib-esm/components/Stepper/Stepper.js +14 -5
  53. package/lib-esm/components/Stepper/Stepper.js.map +1 -1
  54. package/lib-esm/index.js +1 -1
  55. package/lib-esm/shared/LayerManager.js +3 -15
  56. package/lib-esm/shared/LayerManager.js.map +1 -1
  57. package/lib-esm/shared/styles.d.ts +5 -1
  58. package/lib-esm/shared/styles.js +11 -7
  59. package/lib-esm/shared/styles.js.map +1 -1
  60. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"MenuItem.js","sources":["../../../src/components/Menu/MenuItem.tsx"],"sourcesContent":["import React, { SyntheticEvent, useContext } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\nimport Checkbox from '../Input/Checkbox';\nimport MenuContext, { MenuContextType } from './MenuContext';\n\ntype MenuItemProps<T> = {\n /** Value of the element */\n value: T;\n} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value'>;\n\nconst Container = styled.button<{ selected: boolean; multiselect?: boolean }>`\n font-weight: ${(props) => (props.selected ? 'bold' : 'normal')};\n padding: 8px;\n border: none;\n border-left: 4px solid\n ${(props) =>\n props.selected && !props.multiselect\n ? getThemeValue(THEME_NAME.TEXT_COLOR_DARK)\n : 'transparent'};\n background-color: transparent;\n font-size: 16px;\n border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n min-height: 41px;\n display: flex;\n align-items: center;\n cursor: pointer;\n position: relative;\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};\n\n &:hover,\n &:focus,\n &:focus-within {\n background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n }\n\n & > label {\n margin: 0 4px 0 0;\n }\n`;\n\n/**\n * MenuItem Component\n * @template T - The type of value in the menu item.\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLButtonElement\n */\nconst MenuItemInner = <T,>(props: MenuItemProps<T>, ref: React.Ref<HTMLButtonElement>) => {\n const context = useContext(MenuContext) as MenuContextType<T> | undefined;\n if (!context) {\n throw new Error('`MenuItem` must be used within a `Menu` provider');\n }\n const { value, children, ...rest } = props;\n const clickHandler = (e: SyntheticEvent) => {\n e.stopPropagation();\n context.updateValue(value as T);\n };\n\n let selected = false;\n if (context.multiSelect) {\n const arr = context.value as unknown as T[] | undefined;\n selected = Array.isArray(arr) && arr.includes(value as unknown as T);\n } else {\n selected = (context.value as unknown as T) === value;\n }\n\n return (\n <Container\n {...rest}\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={selected}\n selected={selected}\n onClick={clickHandler}\n multiselect={context.multiSelect ? true : undefined}\n >\n {context.multiSelect && (\n <Checkbox\n checked={selected}\n readOnly\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n />\n )}\n {children}\n </Container>\n );\n};\n\nconst MenuItem = React.forwardRef(MenuItemInner) as <T>(\n props: MenuItemProps<T> & { ref?: React.Ref<HTMLButtonElement> },\n) => ReturnType<typeof MenuItemInner>;\nexport default MenuItem;\n"],"names":["Container","styled","props","selected","multiselect","getThemeValue","THEME_NAME","TEXT_COLOR_DARK","BORDER_LIGHT_COLOR","MenuItemInner","ref","context","useContext","MenuContext","Error","value","children","rest","clickHandler","e","stopPropagation","updateValue","multiSelect","arr","Array","isArray","includes","_jsxs","type","role","aria-selected","onClick","undefined","_jsx","Checkbox","checked","readOnly","tabIndex","MenuItem","React","forwardRef"],"mappings":";;;;;;;AAWA,MAAMA,WAAAA,iBAAYC,MAAAA,CAAAA,QAAAA,EAAAA;;;AACC,CAAA,CAAA,CAAA,cAAA,EAAA,CAACC,KAAAA,GAAWA,KAAAA,CAAMC,QAAQ,GAAG,MAAA,GAAS,QAAA,EAAA,0DAAA,EAI/C,CAACD,KAAAA,GACCA,KAAAA,CAAMC,QAAQ,IAAI,CAACD,MAAME,WAAW,GAC9BC,aAAAA,CAAcC,UAAAA,CAAWC,eAAe,CAAA,GACxC,aAAA,EAAA,uEAAA,EAGaF,aAAAA,CAAcC,UAAAA,CAAWE,kBAAkB,CAAA,EAAA,0FAAA,EAM7DH,aAAAA,CAAcC,UAAAA,CAAWC,eAAe,CAAA,EAAA,mDAAA,EAKzBF,aAAAA,CAAcC,WAAWE,kBAAkB,CAAA,EAAA,gCAAA,CAAA;AAQvE;;;;;IAMA,MAAMC,aAAAA,GAAgB,CAAKP,KAAAA,EAAyBQ,GAAAA,GAAAA;AAChD,IAAA,MAAMC,UAAUC,UAAAA,CAAWC,WAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACF,OAAAA,EAAS;AACV,QAAA,MAAM,IAAIG,KAAAA,CAAM,kDAAA,CAAA;AACpB,IAAA;AACA,IAAA,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGC,MAAM,GAAGf,KAAAA;AACrC,IAAA,MAAMgB,eAAe,CAACC,CAAAA,GAAAA;AAClBA,QAAAA,CAAAA,CAAEC,eAAe,EAAA;AACjBT,QAAAA,OAAAA,CAAQU,WAAW,CAACN,KAAAA,CAAAA;AACxB,IAAA,CAAA;AAEA,IAAA,IAAIZ,QAAAA,GAAW,KAAA;IACf,IAAIQ,OAAAA,CAAQW,WAAW,EAAE;QACrB,MAAMC,GAAAA,GAAMZ,QAAQI,KAAK;AACzBZ,QAAAA,QAAAA,GAAWqB,MAAMC,OAAO,CAACF,GAAAA,CAAAA,IAAQA,GAAAA,CAAIG,QAAQ,CAACX,KAAAA,CAAAA;IAClD,CAAA,MAAO;QACHZ,QAAAA,GAAYQ,OAAAA,CAAQI,KAAK,KAAsBA,KAAAA;AACnD,IAAA;AAEA,IAAA,qBACIY,IAAA,CAAC3B,WAAAA,EAAAA;AACI,QAAA,GAAGiB,IAAI;QACRP,GAAAA,EAAKA,GAAAA;QACLkB,IAAAA,EAAK,QAAA;QACLC,IAAAA,EAAK,QAAA;QACLC,eAAAA,EAAe3B,QAAAA;QACfA,QAAAA,EAAUA,QAAAA;QACV4B,OAAAA,EAASb,YAAAA;QACTd,WAAAA,EAAaO,OAAAA,CAAQW,WAAW,GAAG,IAAA,GAAOU,SAAAA;;YAEzCrB,OAAAA,CAAQW,WAAW,kBAChBW,GAAA,CAACC,QAAAA,EAAAA;gBACGC,OAAAA,EAAShC,QAAAA;gBACTiC,QAAQ,EAAA,IAAA;AACRC,gBAAAA,QAAAA,EAAU,EAAC;gBACXN,OAAAA,EAAS,CAACZ,CAAAA,GAAMA,CAAAA,CAAEC,eAAe;;AAGxCJ,YAAAA;;;AAGb,CAAA;AAEA,MAAMsB,QAAAA,iBAAWC,KAAAA,CAAMC,UAAU,CAAC/B,aAAAA;;;;"}
1
+ {"version":3,"file":"MenuItem.js","sources":["../../../src/components/Menu/MenuItem.tsx"],"sourcesContent":["import React, { SyntheticEvent, useContext } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\nimport Checkbox from '../Input/Checkbox';\nimport MenuContext, { MenuContextType } from './MenuContext';\n\nexport type MenuItemProps<T> = {\n /** Value of the element */\n value: T;\n} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value'>;\n\nconst Container = styled.button<{ selected: boolean; multiselect?: boolean }>`\n font-weight: ${(props) => (props.selected ? 'bold' : 'normal')};\n padding: 8px;\n border: none;\n border-left: 4px solid\n ${(props) =>\n props.selected && !props.multiselect\n ? getThemeValue(THEME_NAME.TEXT_COLOR_DARK)\n : 'transparent'};\n background-color: transparent;\n font-size: 16px;\n border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n min-height: 41px;\n display: flex;\n align-items: center;\n cursor: pointer;\n position: relative;\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};\n\n &:hover,\n &:focus,\n &:focus-within {\n background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n }\n\n & > label {\n margin: 0 4px 0 0;\n }\n`;\n\n/**\n * MenuItem Component\n * @template T - The type of value in the menu item.\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLButtonElement\n */\nconst MenuItemInner = <T,>(props: MenuItemProps<T>, ref: React.Ref<HTMLButtonElement>) => {\n const context = useContext(MenuContext) as MenuContextType<T> | undefined;\n if (!context) {\n throw new Error('`MenuItem` must be used within a `Menu` provider');\n }\n const { value, children, ...rest } = props;\n const clickHandler = (e: SyntheticEvent) => {\n e.stopPropagation();\n context.updateValue(value as T);\n };\n\n let selected = false;\n if (context.multiSelect) {\n const arr = context.value as unknown as T[] | undefined;\n selected = Array.isArray(arr) && arr.includes(value as unknown as T);\n } else {\n selected = (context.value as unknown as T) === value;\n }\n\n return (\n <Container\n {...rest}\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={selected}\n selected={selected}\n onClick={clickHandler}\n multiselect={context.multiSelect ? true : undefined}\n >\n {context.multiSelect && (\n <Checkbox\n checked={selected}\n readOnly\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n />\n )}\n {children}\n </Container>\n );\n};\n\nconst MenuItem = React.forwardRef(MenuItemInner) as <T>(\n props: MenuItemProps<T> & { ref?: React.Ref<HTMLButtonElement> },\n) => ReturnType<typeof MenuItemInner>;\nexport default MenuItem;\n"],"names":["Container","styled","props","selected","multiselect","getThemeValue","THEME_NAME","TEXT_COLOR_DARK","BORDER_LIGHT_COLOR","MenuItemInner","ref","context","useContext","MenuContext","Error","value","children","rest","clickHandler","e","stopPropagation","updateValue","multiSelect","arr","Array","isArray","includes","_jsxs","type","role","aria-selected","onClick","undefined","_jsx","Checkbox","checked","readOnly","tabIndex","MenuItem","React","forwardRef"],"mappings":";;;;;;;AAWA,MAAMA,WAAAA,iBAAYC,MAAAA,CAAAA,QAAAA,EAAAA;;;AACC,CAAA,CAAA,CAAA,cAAA,EAAA,CAACC,KAAAA,GAAWA,KAAAA,CAAMC,QAAQ,GAAG,MAAA,GAAS,QAAA,EAAA,0DAAA,EAI/C,CAACD,KAAAA,GACCA,KAAAA,CAAMC,QAAQ,IAAI,CAACD,MAAME,WAAW,GAC9BC,aAAAA,CAAcC,UAAAA,CAAWC,eAAe,CAAA,GACxC,aAAA,EAAA,uEAAA,EAGaF,aAAAA,CAAcC,UAAAA,CAAWE,kBAAkB,CAAA,EAAA,0FAAA,EAM7DH,aAAAA,CAAcC,UAAAA,CAAWC,eAAe,CAAA,EAAA,mDAAA,EAKzBF,aAAAA,CAAcC,WAAWE,kBAAkB,CAAA,EAAA,gCAAA,CAAA;AAQvE;;;;;IAMA,MAAMC,aAAAA,GAAgB,CAAKP,KAAAA,EAAyBQ,GAAAA,GAAAA;AAChD,IAAA,MAAMC,UAAUC,UAAAA,CAAWC,WAAAA,CAAAA;AAC3B,IAAA,IAAI,CAACF,OAAAA,EAAS;AACV,QAAA,MAAM,IAAIG,KAAAA,CAAM,kDAAA,CAAA;AACpB,IAAA;AACA,IAAA,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGC,MAAM,GAAGf,KAAAA;AACrC,IAAA,MAAMgB,eAAe,CAACC,CAAAA,GAAAA;AAClBA,QAAAA,CAAAA,CAAEC,eAAe,EAAA;AACjBT,QAAAA,OAAAA,CAAQU,WAAW,CAACN,KAAAA,CAAAA;AACxB,IAAA,CAAA;AAEA,IAAA,IAAIZ,QAAAA,GAAW,KAAA;IACf,IAAIQ,OAAAA,CAAQW,WAAW,EAAE;QACrB,MAAMC,GAAAA,GAAMZ,QAAQI,KAAK;AACzBZ,QAAAA,QAAAA,GAAWqB,MAAMC,OAAO,CAACF,GAAAA,CAAAA,IAAQA,GAAAA,CAAIG,QAAQ,CAACX,KAAAA,CAAAA;IAClD,CAAA,MAAO;QACHZ,QAAAA,GAAYQ,OAAAA,CAAQI,KAAK,KAAsBA,KAAAA;AACnD,IAAA;AAEA,IAAA,qBACIY,IAAA,CAAC3B,WAAAA,EAAAA;AACI,QAAA,GAAGiB,IAAI;QACRP,GAAAA,EAAKA,GAAAA;QACLkB,IAAAA,EAAK,QAAA;QACLC,IAAAA,EAAK,QAAA;QACLC,eAAAA,EAAe3B,QAAAA;QACfA,QAAAA,EAAUA,QAAAA;QACV4B,OAAAA,EAASb,YAAAA;QACTd,WAAAA,EAAaO,OAAAA,CAAQW,WAAW,GAAG,IAAA,GAAOU,SAAAA;;YAEzCrB,OAAAA,CAAQW,WAAW,kBAChBW,GAAA,CAACC,QAAAA,EAAAA;gBACGC,OAAAA,EAAShC,QAAAA;gBACTiC,QAAQ,EAAA,IAAA;AACRC,gBAAAA,QAAAA,EAAU,EAAC;gBACXN,OAAAA,EAAS,CAACZ,CAAAA,GAAMA,CAAAA,CAAEC,eAAe;;AAGxCJ,YAAAA;;;AAGb,CAAA;AAEA,MAAMsB,QAAAA,iBAAWC,KAAAA,CAAMC,UAAU,CAAC/B,aAAAA;;;;"}
@@ -89,7 +89,7 @@ export default class Modal extends React.Component<React.PropsWithChildren<Modal
89
89
  * Lifecycle method to handle Modal updates.
90
90
  * Manages opening/closing logic via LayerManager and focus preservation.
91
91
  */
92
- getSnapshotBeforeUpdate(prevProps: ModalProps): null;
92
+ componentDidUpdate(prevProps: ModalProps): void;
93
93
  /**
94
94
  * Renders the Modal component via the LayerManager portal.
95
95
  */
@@ -39,7 +39,7 @@ class Modal extends React.Component {
39
39
  /**
40
40
  * Lifecycle method to handle Modal updates.
41
41
  * Manages opening/closing logic via LayerManager and focus preservation.
42
- */ getSnapshotBeforeUpdate(prevProps) {
42
+ */ componentDidUpdate(prevProps) {
43
43
  const { open } = this.props;
44
44
  if (prevProps.open && !open) {
45
45
  this.closeCallback?.();
@@ -50,7 +50,6 @@ class Modal extends React.Component {
50
50
  this.lastFocusedElement = document.activeElement;
51
51
  this.handleOpen();
52
52
  }
53
- return null;
54
53
  }
55
54
  /**
56
55
  * Renders the Modal component via the LayerManager portal.
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import React from 'react';\nimport LayerManager, { LAYER_POSITION } from '../../shared/LayerManager';\nexport {\n Header as ModalHeader,\n Body as ModalBody,\n Footer as ModalFooter,\n} from '../../shared/styles';\nimport { DialogContainer as ModalContainer } from '../Dialog/Dialog';\n\ntype ModalProps = {\n /** Opens the modal */\n open: boolean;\n /** Closes the modal on esc */\n closeOnEsc?: boolean;\n /** Closes the modal on overlay click */\n closeOnOverlayClick?: boolean;\n /** Call back function called when the modal closes. */\n onClose?: () => void;\n /** Ref forwarded to the underlying HTMLDivElement of the modal container */\n forwardRef?: React.Ref<HTMLDivElement>;\n} & React.HTMLAttributes<HTMLDivElement>;\n\ninterface ModalState {\n open: boolean;\n}\n\n/**\n * Modal component\n *\n * A dialog window that sits on top of the main application content.\n * It disrupts the user's workflow to demand attention for a critical task or decision.\n *\n * Accessibility:\n * - Implements ARIA `role=\"dialog\"` and `aria-modal=\"true\"`.\n * - Traps focus effectively within the modal while open.\n * - Restores focus to the triggering element upon closure.\n * - Supports closing via ESC key and overlay click.\n */\nexport default class Modal extends React.Component<\n React.PropsWithChildren<ModalProps>,\n ModalState\n> {\n state = {\n open: false,\n };\n\n static defaultProps = {\n closeOnEsc: true,\n closeOnOverlayClick: true,\n };\n\n /**\n * Syncs state with props.\n */\n static getDerivedStateFromProps(props: ModalProps) {\n if (props.open) {\n return {\n open: true,\n };\n }\n return null;\n }\n\n private layer?: ReturnType<typeof LayerManager.renderLayer>;\n\n private closeCallback?: (resp?: unknown) => void;\n\n /**\n * Internal close handler.\n * Restores focus and calls the external onClose callback.\n */\n private onClose = () => {\n this.restoreFocus();\n this.setState({\n open: false,\n });\n this.props.onClose?.();\n this.closeCallback = undefined;\n this.layer = undefined;\n };\n\n private lastFocusedElement: HTMLElement | null = null;\n private modalRef = React.createRef<HTMLDivElement>();\n\n /**\n * Retrieves all focusable elements within the modal.\n */\n private getFocusableElements = (): HTMLElement[] => {\n if (!this.modalRef.current) return [];\n return Array.from(\n this.modalRef.current.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n ),\n ) as HTMLElement[];\n };\n\n /**\n * Handles keydown events to implement the focus trap.\n * Traps Tab and Shift+Tab within the modal.\n */\n private handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Tab') {\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === firstElement) {\n lastElement.focus();\n e.preventDefault();\n }\n } else {\n if (document.activeElement === lastElement) {\n firstElement.focus();\n e.preventDefault();\n }\n }\n }\n };\n\n /**\n * Lifecycle method to save the currently focused element when the modal mounts while open.\n */\n componentDidMount() {\n if (this.props.open) {\n this.lastFocusedElement = document.activeElement as HTMLElement;\n // Handle initial open state\n this.handleOpen();\n }\n }\n\n /**\n * Handles opening the modal by creating the layer.\n */\n private handleOpen = () => {\n const { closeOnEsc, closeOnOverlayClick, children, ...rest } = this.props;\n\n this.layer = LayerManager.renderLayer({\n overlay: true,\n exitDelay: 300,\n position: LAYER_POSITION.DIALOG,\n closeCallback: this.onClose,\n closeOnEsc: closeOnEsc,\n closeOnOverlayClick: closeOnOverlayClick,\n component: (\n <ModalContainer\n {...rest}\n ref={this.setModalRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n onKeyDown={this.handleKeyDown}\n onClick={(e) => e.stopPropagation()}\n elevated\n >\n {children}\n </ModalContainer>\n ),\n });\n this.closeCallback = this.layer[1];\n this.forceUpdate();\n };\n\n /**\n * Lifecycle method to restore focus when the modal unmounts.\n */\n componentWillUnmount() {\n if (this.props.open) {\n this.restoreFocus();\n }\n // Clean up layer references\n if (this.closeCallback) {\n this.closeCallback();\n this.closeCallback = undefined;\n }\n this.layer = undefined;\n }\n\n /**\n * Restores focus to the element that was focused before the modal opened.\n */\n private restoreFocus = () => {\n if (this.lastFocusedElement) {\n // Check if the element is still in the document\n const elementToBeFocused = this.lastFocusedElement;\n this.lastFocusedElement = null;\n setTimeout(() => {\n if (document.body.contains(elementToBeFocused)) {\n elementToBeFocused.focus();\n }\n }, 100);\n }\n };\n\n /**\n * Callback ref to capture the Modal DOM element.\n * Triggers initial focus setting when the element mounts.\n */\n private setModalRef = (node: HTMLDivElement | null) => {\n // Update ref\n (this.modalRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n\n if (node) {\n // Set initial focus when the node is mounted\n this.setInitialFocus(node);\n }\n\n if (this.props.forwardRef) {\n (this.props.forwardRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n };\n\n /**\n * Sets initial focus within the modal.\n * Tries to focus the header (first child) first, then the first interactive element, or falls back to the container.\n */\n private setInitialFocus = (root: HTMLElement) => {\n // Try to find the header (assumed to be the first child)\n const firstChild = root.firstElementChild as HTMLElement;\n if (firstChild) {\n // Ensure it's focusable\n if (firstChild.getAttribute('tabindex') === null) {\n firstChild.setAttribute('tabindex', '-1');\n }\n firstChild.focus();\n return;\n }\n\n // Fallback to focusable elements\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n } else {\n // Fallback to container\n root.focus();\n }\n };\n\n /**\n * Lifecycle method to handle Modal updates.\n * Manages opening/closing logic via LayerManager and focus preservation.\n */\n getSnapshotBeforeUpdate(prevProps: ModalProps) {\n const { open } = this.props;\n\n if (prevProps.open && !open) {\n this.closeCallback?.();\n this.restoreFocus();\n }\n\n if (!prevProps.open && open) {\n // Save current focus\n this.lastFocusedElement = document.activeElement as HTMLElement;\n this.handleOpen();\n }\n\n return null;\n }\n\n /**\n * Renders the Modal component via the LayerManager portal.\n */\n render() {\n if (this.state.open && this.layer) {\n const [Component] = this.layer;\n return <Component />;\n }\n\n return null;\n }\n}\n"],"names":["Modal","React","Component","getDerivedStateFromProps","props","open","componentDidMount","lastFocusedElement","document","activeElement","handleOpen","componentWillUnmount","restoreFocus","closeCallback","undefined","layer","getSnapshotBeforeUpdate","prevProps","render","state","_jsx","onClose","setState","modalRef","createRef","getFocusableElements","current","Array","from","querySelectorAll","handleKeyDown","e","key","focusableElements","length","firstElement","lastElement","shiftKey","focus","preventDefault","closeOnEsc","closeOnOverlayClick","children","rest","LayerManager","renderLayer","overlay","exitDelay","position","LAYER_POSITION","DIALOG","component","ModalContainer","ref","setModalRef","role","aria-modal","tabIndex","onKeyDown","onClick","stopPropagation","elevated","forceUpdate","elementToBeFocused","setTimeout","body","contains","node","setInitialFocus","forwardRef","root","firstChild","firstElementChild","getAttribute","setAttribute","defaultProps"],"mappings":";;;;;AAsCe,MAAMA,KAAAA,SAAcC,MAAMC,SAAS,CAAA;AAa9C;;QAGA,OAAOC,wBAAAA,CAAyBC,KAAiB,EAAE;QAC/C,IAAIA,KAAAA,CAAMC,IAAI,EAAE;YACZ,OAAO;gBACHA,IAAAA,EAAM;AACV,aAAA;AACJ,QAAA;QACA,OAAO,IAAA;AACX,IAAA;AA6DA;;AAEC,QACDC,iBAAAA,GAAoB;AAChB,QAAA,IAAI,IAAI,CAACF,KAAK,CAACC,IAAI,EAAE;AACjB,YAAA,IAAI,CAACE,kBAAkB,GAAGC,QAAAA,CAASC,aAAa;;AAEhD,YAAA,IAAI,CAACC,UAAU,EAAA;AACnB,QAAA;AACJ,IAAA;AAkCA;;AAEC,QACDC,oBAAAA,GAAuB;AACnB,QAAA,IAAI,IAAI,CAACP,KAAK,CAACC,IAAI,EAAE;AACjB,YAAA,IAAI,CAACO,YAAY,EAAA;AACrB,QAAA;;QAEA,IAAI,IAAI,CAACC,aAAa,EAAE;AACpB,YAAA,IAAI,CAACA,aAAa,EAAA;YAClB,IAAI,CAACA,aAAa,GAAGC,SAAAA;AACzB,QAAA;QACA,IAAI,CAACC,KAAK,GAAGD,SAAAA;AACjB,IAAA;AA8DA;;;QAIAE,uBAAAA,CAAwBC,SAAqB,EAAE;AAC3C,QAAA,MAAM,EAAEZ,IAAI,EAAE,GAAG,IAAI,CAACD,KAAK;AAE3B,QAAA,IAAIa,SAAAA,CAAUZ,IAAI,IAAI,CAACA,IAAAA,EAAM;AACzB,YAAA,IAAI,CAACQ,aAAa,IAAA;AAClB,YAAA,IAAI,CAACD,YAAY,EAAA;AACrB,QAAA;AAEA,QAAA,IAAI,CAACK,SAAAA,CAAUZ,IAAI,IAAIA,IAAAA,EAAM;;AAEzB,YAAA,IAAI,CAACE,kBAAkB,GAAGC,QAAAA,CAASC,aAAa;AAChD,YAAA,IAAI,CAACC,UAAU,EAAA;AACnB,QAAA;QAEA,OAAO,IAAA;AACX,IAAA;AAEA;;AAEC,QACDQ,MAAAA,GAAS;QACL,IAAI,IAAI,CAACC,KAAK,CAACd,IAAI,IAAI,IAAI,CAACU,KAAK,EAAE;AAC/B,YAAA,MAAM,CAACb,SAAAA,CAAU,GAAG,IAAI,CAACa,KAAK;AAC9B,YAAA,qBAAOK,GAAA,CAAClB,SAAAA,EAAAA,EAAAA,CAAAA;AACZ,QAAA;QAEA,OAAO,IAAA;AACX,IAAA;;AAzOW,QAAA,KAAA,CAAA,GAAA,IAAA,CAAA,EAAA,IAAA,CAIXiB,KAAAA,GAAQ;YACJd,IAAAA,EAAM;SACV;;;AA0BC,QAAA,IAAA,CACOgB,OAAAA,GAAU,IAAA;AACd,YAAA,IAAI,CAACT,YAAY,EAAA;YACjB,IAAI,CAACU,QAAQ,CAAC;gBACVjB,IAAAA,EAAM;AACV,aAAA,CAAA;YACA,IAAI,CAACD,KAAK,CAACiB,OAAO,IAAA;YAClB,IAAI,CAACR,aAAa,GAAGC,SAAAA;YACrB,IAAI,CAACC,KAAK,GAAGD,SAAAA;AACjB,QAAA,CAAA,EAAA,IAAA,CAEQP,kBAAAA,GAAyC,IAAA,EAAA,IAAA,CACzCgB,QAAAA,iBAAWtB,KAAAA,CAAMuB,SAAS,EAAA;;AAIjC,QAAA,IAAA,CACOC,oBAAAA,GAAuB,IAAA;YAC3B,IAAI,CAAC,IAAI,CAACF,QAAQ,CAACG,OAAO,EAAE,OAAO,EAAE;YACrC,OAAOC,KAAAA,CAAMC,IAAI,CACb,IAAI,CAACL,QAAQ,CAACG,OAAO,CAACG,gBAAgB,CAClC,0EAAA,CAAA,CAAA;QAGZ,CAAA;;;AAKC,QAAA,IAAA,CACOC,gBAAgB,CAACC,CAAAA,GAAAA;YACrB,IAAIA,CAAAA,CAAEC,GAAG,KAAK,KAAA,EAAO;gBACjB,MAAMC,iBAAAA,GAAoB,IAAI,CAACR,oBAAoB,EAAA;gBACnD,IAAIQ,iBAAAA,CAAkBC,MAAM,KAAK,CAAA,EAAG;gBAEpC,MAAMC,YAAAA,GAAeF,iBAAiB,CAAC,CAAA,CAAE;AACzC,gBAAA,MAAMG,cAAcH,iBAAiB,CAACA,iBAAAA,CAAkBC,MAAM,GAAG,CAAA,CAAE;gBAEnE,IAAIH,CAAAA,CAAEM,QAAQ,EAAE;oBACZ,IAAI7B,QAAAA,CAASC,aAAa,KAAK0B,YAAAA,EAAc;AACzCC,wBAAAA,WAAAA,CAAYE,KAAK,EAAA;AACjBP,wBAAAA,CAAAA,CAAEQ,cAAc,EAAA;AACpB,oBAAA;gBACJ,CAAA,MAAO;oBACH,IAAI/B,QAAAA,CAASC,aAAa,KAAK2B,WAAAA,EAAa;AACxCD,wBAAAA,YAAAA,CAAaG,KAAK,EAAA;AAClBP,wBAAAA,CAAAA,CAAEQ,cAAc,EAAA;AACpB,oBAAA;AACJ,gBAAA;AACJ,YAAA;QACJ,CAAA;;AAeC,QAAA,IAAA,CACO7B,UAAAA,GAAa,IAAA;AACjB,YAAA,MAAM,EAAE8B,UAAU,EAAEC,mBAAmB,EAAEC,QAAQ,EAAE,GAAGC,IAAAA,EAAM,GAAG,IAAI,CAACvC,KAAK;AAEzE,YAAA,IAAI,CAACW,KAAK,GAAG6B,YAAAA,CAAaC,WAAW,CAAC;gBAClCC,OAAAA,EAAS,IAAA;gBACTC,SAAAA,EAAW,GAAA;AACXC,gBAAAA,QAAAA,EAAUC,eAAeC,MAAM;gBAC/BrC,aAAAA,EAAe,IAAI,CAACQ,OAAO;gBAC3BmB,UAAAA,EAAYA,UAAAA;gBACZC,mBAAAA,EAAqBA,mBAAAA;AACrBU,gBAAAA,SAAAA,gBACI/B,GAAA,CAACgC,eAAAA,EAAAA;AACI,oBAAA,GAAGT,IAAI;oBACRU,GAAAA,EAAK,IAAI,CAACC,WAAW;oBACrBC,IAAAA,EAAK,QAAA;oBACLC,YAAAA,EAAW,MAAA;AACXC,oBAAAA,QAAAA,EAAU,EAAC;oBACXC,SAAAA,EAAW,IAAI,CAAC5B,aAAa;oBAC7B6B,OAAAA,EAAS,CAAC5B,CAAAA,GAAMA,CAAAA,CAAE6B,eAAe,EAAA;oBACjCC,QAAQ,EAAA,IAAA;AAEPnB,oBAAAA,QAAAA,EAAAA;;AAGb,aAAA,CAAA;AACA,YAAA,IAAI,CAAC7B,aAAa,GAAG,IAAI,CAACE,KAAK,CAAC,CAAA,CAAE;AAClC,YAAA,IAAI,CAAC+C,WAAW,EAAA;QACpB,CAAA;;AAmBC,QAAA,IAAA,CACOlD,YAAAA,GAAe,IAAA;YACnB,IAAI,IAAI,CAACL,kBAAkB,EAAE;;gBAEzB,MAAMwD,kBAAAA,GAAqB,IAAI,CAACxD,kBAAkB;gBAClD,IAAI,CAACA,kBAAkB,GAAG,IAAA;gBAC1ByD,UAAAA,CAAW,IAAA;AACP,oBAAA,IAAIxD,QAAAA,CAASyD,IAAI,CAACC,QAAQ,CAACH,kBAAAA,CAAAA,EAAqB;AAC5CA,wBAAAA,kBAAAA,CAAmBzB,KAAK,EAAA;AAC5B,oBAAA;gBACJ,CAAA,EAAG,GAAA,CAAA;AACP,YAAA;QACJ,CAAA;;;AAKC,QAAA,IAAA,CACOgB,cAAc,CAACa,IAAAA,GAAAA;;AAElB,YAAA,IAAI,CAAC5C,QAAQ,CAAmDG,OAAO,GAAGyC,IAAAA;AAE3E,YAAA,IAAIA,IAAAA,EAAM;;gBAEN,IAAI,CAACC,eAAe,CAACD,IAAAA,CAAAA;AACzB,YAAA;AAEA,YAAA,IAAI,IAAI,CAAC/D,KAAK,CAACiE,UAAU,EAAE;AACtB,gBAAA,IAAI,CAACjE,KAAK,CAACiE,UAAU,CAAmD3C,OAAO,GAAGyC,IAAAA;AACvF,YAAA;QACJ,CAAA;;;AAKC,QAAA,IAAA,CACOC,kBAAkB,CAACE,IAAAA,GAAAA;;YAEvB,MAAMC,UAAAA,GAAaD,KAAKE,iBAAiB;AACzC,YAAA,IAAID,UAAAA,EAAY;;AAEZ,gBAAA,IAAIA,UAAAA,CAAWE,YAAY,CAAC,UAAA,CAAA,KAAgB,IAAA,EAAM;oBAC9CF,UAAAA,CAAWG,YAAY,CAAC,UAAA,EAAY,IAAA,CAAA;AACxC,gBAAA;AACAH,gBAAAA,UAAAA,CAAWjC,KAAK,EAAA;AAChB,gBAAA;AACJ,YAAA;;YAGA,MAAML,iBAAAA,GAAoB,IAAI,CAACR,oBAAoB,EAAA;YACnD,IAAIQ,iBAAAA,CAAkBC,MAAM,GAAG,CAAA,EAAG;gBAC9BD,iBAAiB,CAAC,CAAA,CAAE,CAACK,KAAK,EAAA;YAC9B,CAAA,MAAO;;AAEHgC,gBAAAA,IAAAA,CAAKhC,KAAK,EAAA;AACd,YAAA;AACJ,QAAA,CAAA;;AAkCJ;AA1OqBtC,KAAAA,CAQV2E,YAAAA,GAAe;IAClBnC,UAAAA,EAAY,IAAA;IACZC,mBAAAA,EAAqB;AACzB,CAAA;;;;"}
1
+ {"version":3,"file":"Modal.js","sources":["../../../src/components/Modal/Modal.tsx"],"sourcesContent":["import React from 'react';\nimport LayerManager, { LAYER_POSITION } from '../../shared/LayerManager';\nexport {\n Header as ModalHeader,\n Body as ModalBody,\n Footer as ModalFooter,\n} from '../../shared/styles';\nimport { DialogContainer as ModalContainer } from '../Dialog/Dialog';\n\ntype ModalProps = {\n /** Opens the modal */\n open: boolean;\n /** Closes the modal on esc */\n closeOnEsc?: boolean;\n /** Closes the modal on overlay click */\n closeOnOverlayClick?: boolean;\n /** Call back function called when the modal closes. */\n onClose?: () => void;\n /** Ref forwarded to the underlying HTMLDivElement of the modal container */\n forwardRef?: React.Ref<HTMLDivElement>;\n} & React.HTMLAttributes<HTMLDivElement>;\n\ninterface ModalState {\n open: boolean;\n}\n\n/**\n * Modal component\n *\n * A dialog window that sits on top of the main application content.\n * It disrupts the user's workflow to demand attention for a critical task or decision.\n *\n * Accessibility:\n * - Implements ARIA `role=\"dialog\"` and `aria-modal=\"true\"`.\n * - Traps focus effectively within the modal while open.\n * - Restores focus to the triggering element upon closure.\n * - Supports closing via ESC key and overlay click.\n */\nexport default class Modal extends React.Component<\n React.PropsWithChildren<ModalProps>,\n ModalState\n> {\n state = {\n open: false,\n };\n\n static defaultProps = {\n closeOnEsc: true,\n closeOnOverlayClick: true,\n };\n\n /**\n * Syncs state with props.\n */\n static getDerivedStateFromProps(props: ModalProps) {\n if (props.open) {\n return {\n open: true,\n };\n }\n return null;\n }\n\n private layer?: ReturnType<typeof LayerManager.renderLayer>;\n\n private closeCallback?: (resp?: unknown) => void;\n\n /**\n * Internal close handler.\n * Restores focus and calls the external onClose callback.\n */\n private onClose = () => {\n this.restoreFocus();\n this.setState({\n open: false,\n });\n this.props.onClose?.();\n this.closeCallback = undefined;\n this.layer = undefined;\n };\n\n private lastFocusedElement: HTMLElement | null = null;\n private modalRef = React.createRef<HTMLDivElement>();\n\n /**\n * Retrieves all focusable elements within the modal.\n */\n private getFocusableElements = (): HTMLElement[] => {\n if (!this.modalRef.current) return [];\n return Array.from(\n this.modalRef.current.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n ),\n ) as HTMLElement[];\n };\n\n /**\n * Handles keydown events to implement the focus trap.\n * Traps Tab and Shift+Tab within the modal.\n */\n private handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Tab') {\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === firstElement) {\n lastElement.focus();\n e.preventDefault();\n }\n } else {\n if (document.activeElement === lastElement) {\n firstElement.focus();\n e.preventDefault();\n }\n }\n }\n };\n\n /**\n * Lifecycle method to save the currently focused element when the modal mounts while open.\n */\n componentDidMount() {\n if (this.props.open) {\n this.lastFocusedElement = document.activeElement as HTMLElement;\n // Handle initial open state\n this.handleOpen();\n }\n }\n\n /**\n * Handles opening the modal by creating the layer.\n */\n private handleOpen = () => {\n const { closeOnEsc, closeOnOverlayClick, children, ...rest } = this.props;\n\n this.layer = LayerManager.renderLayer({\n overlay: true,\n exitDelay: 300,\n position: LAYER_POSITION.DIALOG,\n closeCallback: this.onClose,\n closeOnEsc: closeOnEsc,\n closeOnOverlayClick: closeOnOverlayClick,\n component: (\n <ModalContainer\n {...rest}\n ref={this.setModalRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n onKeyDown={this.handleKeyDown}\n onClick={(e) => e.stopPropagation()}\n elevated\n >\n {children}\n </ModalContainer>\n ),\n });\n this.closeCallback = this.layer[1];\n this.forceUpdate();\n };\n\n /**\n * Lifecycle method to restore focus when the modal unmounts.\n */\n componentWillUnmount() {\n if (this.props.open) {\n this.restoreFocus();\n }\n // Clean up layer references\n if (this.closeCallback) {\n this.closeCallback();\n this.closeCallback = undefined;\n }\n this.layer = undefined;\n }\n\n /**\n * Restores focus to the element that was focused before the modal opened.\n */\n private restoreFocus = () => {\n if (this.lastFocusedElement) {\n // Check if the element is still in the document\n const elementToBeFocused = this.lastFocusedElement;\n this.lastFocusedElement = null;\n setTimeout(() => {\n if (document.body.contains(elementToBeFocused)) {\n elementToBeFocused.focus();\n }\n }, 100);\n }\n };\n\n /**\n * Callback ref to capture the Modal DOM element.\n * Triggers initial focus setting when the element mounts.\n */\n private setModalRef = (node: HTMLDivElement | null) => {\n // Update ref\n (this.modalRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n\n if (node) {\n // Set initial focus when the node is mounted\n this.setInitialFocus(node);\n }\n\n if (this.props.forwardRef) {\n (this.props.forwardRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n };\n\n /**\n * Sets initial focus within the modal.\n * Tries to focus the header (first child) first, then the first interactive element, or falls back to the container.\n */\n private setInitialFocus = (root: HTMLElement) => {\n // Try to find the header (assumed to be the first child)\n const firstChild = root.firstElementChild as HTMLElement;\n if (firstChild) {\n // Ensure it's focusable\n if (firstChild.getAttribute('tabindex') === null) {\n firstChild.setAttribute('tabindex', '-1');\n }\n firstChild.focus();\n return;\n }\n\n // Fallback to focusable elements\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n } else {\n // Fallback to container\n root.focus();\n }\n };\n\n /**\n * Lifecycle method to handle Modal updates.\n * Manages opening/closing logic via LayerManager and focus preservation.\n */\n componentDidUpdate(prevProps: ModalProps) {\n const { open } = this.props;\n\n if (prevProps.open && !open) {\n this.closeCallback?.();\n this.restoreFocus();\n }\n\n if (!prevProps.open && open) {\n // Save current focus\n this.lastFocusedElement = document.activeElement as HTMLElement;\n this.handleOpen();\n }\n }\n\n /**\n * Renders the Modal component via the LayerManager portal.\n */\n render() {\n if (this.state.open && this.layer) {\n const [Component] = this.layer;\n return <Component />;\n }\n\n return null;\n }\n}\n"],"names":["Modal","React","Component","getDerivedStateFromProps","props","open","componentDidMount","lastFocusedElement","document","activeElement","handleOpen","componentWillUnmount","restoreFocus","closeCallback","undefined","layer","componentDidUpdate","prevProps","render","state","_jsx","onClose","setState","modalRef","createRef","getFocusableElements","current","Array","from","querySelectorAll","handleKeyDown","e","key","focusableElements","length","firstElement","lastElement","shiftKey","focus","preventDefault","closeOnEsc","closeOnOverlayClick","children","rest","LayerManager","renderLayer","overlay","exitDelay","position","LAYER_POSITION","DIALOG","component","ModalContainer","ref","setModalRef","role","aria-modal","tabIndex","onKeyDown","onClick","stopPropagation","elevated","forceUpdate","elementToBeFocused","setTimeout","body","contains","node","setInitialFocus","forwardRef","root","firstChild","firstElementChild","getAttribute","setAttribute","defaultProps"],"mappings":"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"}
@@ -9,7 +9,7 @@ type PopoverProps = {
9
9
  /** Opens the popover */
10
10
  open: boolean;
11
11
  /** Anchor element for the popover */
12
- element: React.ElementType;
12
+ element: React.ReactElement;
13
13
  /**
14
14
  * Position of the popover around anchor element
15
15
  * @default POPOVER_POSITION.BOTTOM_LEFT
@@ -29,11 +29,11 @@ const positionMap$2 = {
29
29
  `
30
30
  };
31
31
  const PopoverDiv = /*#__PURE__*/ styled("div", {
32
- target: "ejcb1ps0",
32
+ target: "e13swao70",
33
33
  label: "PopoverDiv"
34
34
  })("position:relative;display:inline-flex;");
35
35
  const Popper = /*#__PURE__*/ styled(Card, {
36
- target: "ejcb1ps1",
36
+ target: "e13swao71",
37
37
  label: "Popper"
38
38
  })("position:absolute;width:100%;min-width:200px;overflow:auto;animation:enter 0.3s linear;border-radius:3px;z-index:1;transform:translate(", (props)=>props.translateX, "px,", (props)=>props.translateY, "px);", (props)=>positionMap$2[props.position], " &.closing{animation:exit 0.3s linear;}@keyframes enter{from{max-height:0px;opacity:1;overflow:hidden;}to{max-height:300px;opacity:1;overflow:hidden;}}@keyframes exit{to{max-height:0px;opacity:1;overflow:hidden;}from{max-height:300px;opacity:1;overflow:hidden;}}");
39
39
  const KEY_CODES = {
@@ -212,7 +212,7 @@ const KEY_CODES = {
212
212
  ref: forwardRef,
213
213
  ...rest,
214
214
  children: [
215
- /*#__PURE__*/ React.createElement(element, {
215
+ /*#__PURE__*/ React.cloneElement(element, {
216
216
  ref: triggerRef,
217
217
  id: triggerId,
218
218
  'aria-expanded': open,
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport styled from '@emotion/styled';\nimport { Card } from '../Card';\n\nexport enum POPOVER_POSITION {\n TOP_LEFT = 'TOP_LEFT',\n TOP_RIGHT = 'TOP_RIGHT',\n BOTTOM_LEFT = 'BOTTOM_LEFT',\n BOTTOM_RIGHT = 'BOTTOM_RIGHT',\n}\n\ninterface Translate {\n x: number;\n y: number;\n}\n\nconst positionMap = {\n [POPOVER_POSITION.TOP_LEFT]: `\n bottom: calc(100% - 10px);\n left: 0;\n `,\n [POPOVER_POSITION.TOP_RIGHT]: `\n bottom: calc(100% - 10px);\n right: 0;\n `,\n [POPOVER_POSITION.BOTTOM_RIGHT]: `\n top: calc(100% - 10px);\n right: 0;\n `,\n [POPOVER_POSITION.BOTTOM_LEFT]: `\n top: calc(100% - 10px);\n left: 0;\n `,\n};\n\nconst PopoverDiv = styled.div`\n position: relative;\n display: inline-flex;\n`;\n\nconst Popper = styled(Card)<{ position: POPOVER_POSITION; translateX: number; translateY: number }>`\n position: absolute;\n width: 100%;\n min-width: 200px;\n overflow: auto;\n animation: enter 0.3s linear;\n border-radius: 3px;\n z-index: 1;\n transform: translate(${(props) => props.translateX}px, ${(props) => props.translateY}px);\n ${(props) => positionMap[props.position]}\n\n &.closing {\n /* max-height: 0px;\n opacity: 0;\n overflow: hidden; */\n animation: exit 0.3s linear;\n }\n\n @keyframes enter {\n from {\n max-height: 0px;\n opacity: 1;\n overflow: hidden;\n }\n to {\n max-height: 300px;\n opacity: 1;\n overflow: hidden;\n }\n }\n\n @keyframes exit {\n to {\n max-height: 0px;\n opacity: 1;\n overflow: hidden;\n }\n from {\n max-height: 300px;\n opacity: 1;\n overflow: hidden;\n }\n }\n`;\n\nconst KEY_CODES = {\n ESC: 27,\n};\n\ntype PopoverProps = {\n /** Opens the popover */\n open: boolean;\n /** Anchor element for the popover */\n element: React.ElementType;\n /**\n * Position of the popover around anchor element\n * @default POPOVER_POSITION.BOTTOM_LEFT\n */\n position?: POPOVER_POSITION;\n /**\n * If the popover should close on `esc` key press\n * @default true\n */\n closeOnEsc?: boolean;\n /** Popover close callback */\n onClose?: () => void;\n};\n\n/**\n * Popover Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLDivElement\n */\nfunction PopoverComponent(\n props: React.PropsWithChildren<PopoverProps>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const {\n open: propsOpen,\n element,\n position = POPOVER_POSITION.BOTTOM_LEFT,\n closeOnEsc = true,\n onClose,\n children,\n ...rest\n } = props;\n\n const [open, setOpen] = useState<boolean>(propsOpen);\n const [closing, setClosing] = useState<boolean>(false);\n const [translate, setTranslate] = useState<Translate>({ x: 0, y: 0 });\n const popperRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n const closeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const focusTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const popperId = useId();\n const triggerId = useId();\n\n const close = useCallback(() => {\n // Clear any existing timeouts first\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n }\n if (focusTimeoutRef.current) {\n clearTimeout(focusTimeoutRef.current);\n }\n\n setClosing(true);\n closeTimeoutRef.current = setTimeout(() => {\n setOpen(false);\n setTranslate({ x: 0, y: 0 });\n\n if (onClose) {\n onClose();\n }\n setClosing(false);\n\n // Restore focus to the trigger element after animation completes\n focusTimeoutRef.current = setTimeout(() => {\n if (triggerRef.current && document.body.contains(triggerRef.current)) {\n triggerRef.current.focus();\n }\n focusTimeoutRef.current = null;\n }, 50);\n closeTimeoutRef.current = null;\n }, 280);\n }, [onClose]);\n\n const keyupEventHandler = useCallback(\n (e: KeyboardEvent) => {\n if (closeOnEsc && e.keyCode === KEY_CODES.ESC) {\n close();\n }\n },\n [close, closeOnEsc],\n );\n\n const clickOutsideHandler = useCallback(\n (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n close();\n }\n },\n [close],\n );\n\n /**\n * Get called on popover mount.\n */\n useEffect(() => {\n document.addEventListener('keyup', keyupEventHandler);\n\n return () => {\n document.removeEventListener('keyup', keyupEventHandler);\n };\n }, [keyupEventHandler]);\n\n useEffect(() => {\n if (propsOpen) {\n setOpen(true);\n // Use requestAnimationFrame to add listener after current event loop\n const rafId = requestAnimationFrame(() => {\n document.addEventListener('click', clickOutsideHandler);\n });\n\n return () => {\n cancelAnimationFrame(rafId);\n document.removeEventListener('click', clickOutsideHandler);\n };\n } else {\n if (open) {\n close();\n }\n }\n }, [propsOpen, open, clickOutsideHandler, close]);\n\n useEffect(() => {\n if (open) {\n const {\n top = 0,\n left = 0,\n right = 0,\n } = popperRef.current?.getBoundingClientRect() ?? {};\n const height = popperRef.current?.scrollHeight ?? 0;\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n const translation = { x: 0, y: 0 };\n\n if (position === POPOVER_POSITION.BOTTOM_LEFT) {\n // overflow can happen at bottom and right\n if (viewportHeight - top - height < 0) {\n translation.y = -1 * (Math.abs(viewportHeight - top - height) + 5);\n }\n if (viewportWidth - right < 0) {\n translation.x = -1 * (Math.abs(viewportWidth - right) + 5);\n }\n } else if (position == POPOVER_POSITION.BOTTOM_RIGHT) {\n // overflow can happen at bottom and left\n if (viewportHeight - top - height < 0) {\n translation.y = -1 * (Math.abs(viewportHeight - top - height) + 5);\n }\n if (left < 0) {\n translation.x = Math.abs(left) + 5;\n }\n } else if (position === POPOVER_POSITION.TOP_LEFT) {\n // overflow can happen at top and right\n if (top - height < 0) {\n translation.y = Math.abs(top - height) + 5;\n }\n if (viewportWidth - right < 0) {\n translation.x = -1 * (Math.abs(viewportWidth - right) + 5);\n }\n } else {\n // overflow can happen at top and left\n if (top - height < 0) {\n translation.y = Math.abs(top - height) + 5;\n }\n if (left < 0) {\n translation.x = Math.abs(left) + 5;\n }\n }\n // Note it can still overflow, but in that case fitting popper inside the\n // window is not possible.\n setTranslate(translation);\n popperRef.current?.focus();\n }\n }, [open, position]);\n\n /**\n * Cleanup timeouts on unmount\n */\n useEffect(() => {\n return () => {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n }\n if (focusTimeoutRef.current) {\n clearTimeout(focusTimeoutRef.current);\n }\n };\n }, []);\n\n const forwardRef = (node: HTMLDivElement | null) => {\n containerRef.current = node;\n\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n };\n\n return (\n <PopoverDiv ref={forwardRef} {...rest}>\n {React.createElement(element, {\n ref: triggerRef,\n id: triggerId,\n 'aria-expanded': open,\n 'aria-haspopup': 'dialog',\n 'aria-controls': popperId,\n })}\n {open && (\n <Popper\n elevated\n tabIndex={0}\n role=\"dialog\"\n aria-labelledby={triggerId}\n id={popperId}\n position={position}\n translateX={translate.x}\n translateY={translate.y}\n className={closing ? 'closing' : ''}\n ref={popperRef}\n onClick={(e) => {\n e.stopPropagation();\n e.nativeEvent.stopImmediatePropagation();\n }}\n >\n {children}\n </Popper>\n )}\n </PopoverDiv>\n );\n}\n\nconst Popover = React.forwardRef(PopoverComponent);\nexport default Popover;\n"],"names":["POPOVER_POSITION","positionMap","PopoverDiv","styled","Popper","Card","props","translateX","translateY","position","KEY_CODES","ESC","PopoverComponent","ref","open","propsOpen","element","closeOnEsc","onClose","children","rest","setOpen","useState","closing","setClosing","translate","setTranslate","x","y","popperRef","useRef","containerRef","triggerRef","closeTimeoutRef","focusTimeoutRef","popperId","useId","triggerId","close","useCallback","current","clearTimeout","setTimeout","document","body","contains","focus","keyupEventHandler","e","keyCode","clickOutsideHandler","target","useEffect","addEventListener","removeEventListener","rafId","requestAnimationFrame","cancelAnimationFrame","top","left","right","getBoundingClientRect","height","scrollHeight","viewportWidth","documentElement","clientWidth","viewportHeight","clientHeight","translation","Math","abs","forwardRef","node","_jsxs","React","createElement","id","_jsx","elevated","tabIndex","role","aria-labelledby","className","onClick","stopPropagation","nativeEvent","stopImmediatePropagation","Popover"],"mappings":"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"}
1
+ {"version":3,"file":"Popover.js","sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport styled from '@emotion/styled';\nimport { Card } from '../Card';\n\nexport enum POPOVER_POSITION {\n TOP_LEFT = 'TOP_LEFT',\n TOP_RIGHT = 'TOP_RIGHT',\n BOTTOM_LEFT = 'BOTTOM_LEFT',\n BOTTOM_RIGHT = 'BOTTOM_RIGHT',\n}\n\ninterface Translate {\n x: number;\n y: number;\n}\n\nconst positionMap = {\n [POPOVER_POSITION.TOP_LEFT]: `\n bottom: calc(100% - 10px);\n left: 0;\n `,\n [POPOVER_POSITION.TOP_RIGHT]: `\n bottom: calc(100% - 10px);\n right: 0;\n `,\n [POPOVER_POSITION.BOTTOM_RIGHT]: `\n top: calc(100% - 10px);\n right: 0;\n `,\n [POPOVER_POSITION.BOTTOM_LEFT]: `\n top: calc(100% - 10px);\n left: 0;\n `,\n};\n\nconst PopoverDiv = styled.div`\n position: relative;\n display: inline-flex;\n`;\n\nconst Popper = styled(Card)<{ position: POPOVER_POSITION; translateX: number; translateY: number }>`\n position: absolute;\n width: 100%;\n min-width: 200px;\n overflow: auto;\n animation: enter 0.3s linear;\n border-radius: 3px;\n z-index: 1;\n transform: translate(${(props) => props.translateX}px, ${(props) => props.translateY}px);\n ${(props) => positionMap[props.position]}\n\n &.closing {\n /* max-height: 0px;\n opacity: 0;\n overflow: hidden; */\n animation: exit 0.3s linear;\n }\n\n @keyframes enter {\n from {\n max-height: 0px;\n opacity: 1;\n overflow: hidden;\n }\n to {\n max-height: 300px;\n opacity: 1;\n overflow: hidden;\n }\n }\n\n @keyframes exit {\n to {\n max-height: 0px;\n opacity: 1;\n overflow: hidden;\n }\n from {\n max-height: 300px;\n opacity: 1;\n overflow: hidden;\n }\n }\n`;\n\nconst KEY_CODES = {\n ESC: 27,\n};\n\ntype PopoverProps = {\n /** Opens the popover */\n open: boolean;\n /** Anchor element for the popover */\n element: React.ReactElement;\n /**\n * Position of the popover around anchor element\n * @default POPOVER_POSITION.BOTTOM_LEFT\n */\n position?: POPOVER_POSITION;\n /**\n * If the popover should close on `esc` key press\n * @default true\n */\n closeOnEsc?: boolean;\n /** Popover close callback */\n onClose?: () => void;\n};\n\n/**\n * Popover Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLDivElement\n */\nfunction PopoverComponent(\n props: React.PropsWithChildren<PopoverProps>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const {\n open: propsOpen,\n element,\n position = POPOVER_POSITION.BOTTOM_LEFT,\n closeOnEsc = true,\n onClose,\n children,\n ...rest\n } = props;\n\n const [open, setOpen] = useState<boolean>(propsOpen);\n const [closing, setClosing] = useState<boolean>(false);\n const [translate, setTranslate] = useState<Translate>({ x: 0, y: 0 });\n const popperRef = useRef<HTMLDivElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n const closeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const focusTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const popperId = useId();\n const triggerId = useId();\n\n const close = useCallback(() => {\n // Clear any existing timeouts first\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n }\n if (focusTimeoutRef.current) {\n clearTimeout(focusTimeoutRef.current);\n }\n\n setClosing(true);\n closeTimeoutRef.current = setTimeout(() => {\n setOpen(false);\n setTranslate({ x: 0, y: 0 });\n\n if (onClose) {\n onClose();\n }\n setClosing(false);\n\n // Restore focus to the trigger element after animation completes\n focusTimeoutRef.current = setTimeout(() => {\n if (triggerRef.current && document.body.contains(triggerRef.current)) {\n triggerRef.current.focus();\n }\n focusTimeoutRef.current = null;\n }, 50);\n closeTimeoutRef.current = null;\n }, 280);\n }, [onClose]);\n\n const keyupEventHandler = useCallback(\n (e: KeyboardEvent) => {\n if (closeOnEsc && e.keyCode === KEY_CODES.ESC) {\n close();\n }\n },\n [close, closeOnEsc],\n );\n\n const clickOutsideHandler = useCallback(\n (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n close();\n }\n },\n [close],\n );\n\n /**\n * Get called on popover mount.\n */\n useEffect(() => {\n document.addEventListener('keyup', keyupEventHandler);\n\n return () => {\n document.removeEventListener('keyup', keyupEventHandler);\n };\n }, [keyupEventHandler]);\n\n useEffect(() => {\n if (propsOpen) {\n setOpen(true);\n // Use requestAnimationFrame to add listener after current event loop\n const rafId = requestAnimationFrame(() => {\n document.addEventListener('click', clickOutsideHandler);\n });\n\n return () => {\n cancelAnimationFrame(rafId);\n document.removeEventListener('click', clickOutsideHandler);\n };\n } else {\n if (open) {\n close();\n }\n }\n }, [propsOpen, open, clickOutsideHandler, close]);\n\n useEffect(() => {\n if (open) {\n const {\n top = 0,\n left = 0,\n right = 0,\n } = popperRef.current?.getBoundingClientRect() ?? {};\n const height = popperRef.current?.scrollHeight ?? 0;\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n const translation = { x: 0, y: 0 };\n\n if (position === POPOVER_POSITION.BOTTOM_LEFT) {\n // overflow can happen at bottom and right\n if (viewportHeight - top - height < 0) {\n translation.y = -1 * (Math.abs(viewportHeight - top - height) + 5);\n }\n if (viewportWidth - right < 0) {\n translation.x = -1 * (Math.abs(viewportWidth - right) + 5);\n }\n } else if (position == POPOVER_POSITION.BOTTOM_RIGHT) {\n // overflow can happen at bottom and left\n if (viewportHeight - top - height < 0) {\n translation.y = -1 * (Math.abs(viewportHeight - top - height) + 5);\n }\n if (left < 0) {\n translation.x = Math.abs(left) + 5;\n }\n } else if (position === POPOVER_POSITION.TOP_LEFT) {\n // overflow can happen at top and right\n if (top - height < 0) {\n translation.y = Math.abs(top - height) + 5;\n }\n if (viewportWidth - right < 0) {\n translation.x = -1 * (Math.abs(viewportWidth - right) + 5);\n }\n } else {\n // overflow can happen at top and left\n if (top - height < 0) {\n translation.y = Math.abs(top - height) + 5;\n }\n if (left < 0) {\n translation.x = Math.abs(left) + 5;\n }\n }\n // Note it can still overflow, but in that case fitting popper inside the\n // window is not possible.\n setTranslate(translation);\n popperRef.current?.focus();\n }\n }, [open, position]);\n\n /**\n * Cleanup timeouts on unmount\n */\n useEffect(() => {\n return () => {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n }\n if (focusTimeoutRef.current) {\n clearTimeout(focusTimeoutRef.current);\n }\n };\n }, []);\n\n const forwardRef = (node: HTMLDivElement | null) => {\n containerRef.current = node;\n\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n }\n };\n\n return (\n <PopoverDiv ref={forwardRef} {...rest}>\n {React.cloneElement(element, {\n ref: triggerRef,\n id: triggerId,\n 'aria-expanded': open,\n 'aria-haspopup': 'dialog',\n 'aria-controls': popperId,\n } as React.Attributes)}\n {open && (\n <Popper\n elevated\n tabIndex={0}\n role=\"dialog\"\n aria-labelledby={triggerId}\n id={popperId}\n position={position}\n translateX={translate.x}\n translateY={translate.y}\n className={closing ? 'closing' : ''}\n ref={popperRef}\n onClick={(e) => {\n e.stopPropagation();\n e.nativeEvent.stopImmediatePropagation();\n }}\n >\n {children}\n </Popper>\n )}\n </PopoverDiv>\n );\n}\n\nconst Popover = React.forwardRef(PopoverComponent);\nexport default Popover;\n"],"names":["POPOVER_POSITION","positionMap","PopoverDiv","styled","Popper","Card","props","translateX","translateY","position","KEY_CODES","ESC","PopoverComponent","ref","open","propsOpen","element","closeOnEsc","onClose","children","rest","setOpen","useState","closing","setClosing","translate","setTranslate","x","y","popperRef","useRef","containerRef","triggerRef","closeTimeoutRef","focusTimeoutRef","popperId","useId","triggerId","close","useCallback","current","clearTimeout","setTimeout","document","body","contains","focus","keyupEventHandler","e","keyCode","clickOutsideHandler","target","useEffect","addEventListener","removeEventListener","rafId","requestAnimationFrame","cancelAnimationFrame","top","left","right","getBoundingClientRect","height","scrollHeight","viewportWidth","documentElement","clientWidth","viewportHeight","clientHeight","translation","Math","abs","forwardRef","node","_jsxs","React","cloneElement","id","_jsx","elevated","tabIndex","role","aria-labelledby","className","onClick","stopPropagation","nativeEvent","stopImmediatePropagation","Popover"],"mappings":"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"}
@@ -1,24 +1,24 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
- import React, { useState, Children, isValidElement } from 'react';
2
+ import React, { useState, Children, useRef, useEffect, isValidElement } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import { getThemeValue, THEME_NAME } from '../../shared/constants.js';
5
5
  import { Ellipsis } from '../../shared/styles.js';
6
6
  import Badge, { BADGE_TYPE } from '../Badge/Badge.js';
7
7
 
8
8
  const Container$1 = /*#__PURE__*/ styled("div", {
9
- target: "e14em2c80",
9
+ target: "er9cpfq0",
10
10
  label: "Container"
11
11
  })("flex:1;display:flex;flex-direction:column;min-height:400px;");
12
12
  const Header = /*#__PURE__*/ styled("div", {
13
- target: "e14em2c81",
13
+ target: "er9cpfq1",
14
14
  label: "Header"
15
15
  })("display:flex;flex-direction:row;justify-content:space-between;border-bottom:1px solid ", getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR), ";@media (min-width:601px){&::before{position:absolute;top:25px;left:0;right:0;height:2px;background-color:", getThemeValue(THEME_NAME.LIGHT_GREY), ";content:' ';z-index:0;}}& > *{z-index:1;}");
16
16
  const HeaderButton = /*#__PURE__*/ styled("button", {
17
- target: "e14em2c82",
17
+ target: "er9cpfq2",
18
18
  label: "HeaderButton"
19
19
  })("border:none;padding:16px 24px 16px 16px;font-size:16px;cursor:pointer;background-color:", (props)=>props.active ? getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR) : getThemeValue(THEME_NAME.BACKGROUND), ";font-weight:", (props)=>props.active ? 'bold' : 'normal', ";overflow:hidden;display:flex;align-items:center;color:", getThemeValue(THEME_NAME.TEXT_COLOR_DARK), ";&:disabled{cursor:not-allowed;background-color:", getThemeValue(THEME_NAME.DISABLED_BACKGROUND), ";}&:enabled:hover,&:focus{background-color:", getThemeValue(THEME_NAME.PRIMARY_LIGHTER), ";}@media (max-width:600px){&{display:none;}}");
20
20
  const MobileHeader = /*#__PURE__*/ styled("div", {
21
- target: "e14em2c83",
21
+ target: "er9cpfq3",
22
22
  label: "MobileHeader"
23
23
  })("padding:16px;font-size:16px;line-height:18px;align-items:center;font-weight:bold;flex:1;display:flex;flex-direction:row;justify-content:space-between;@media (min-width:601px){&{display:none;}}");
24
24
  /**
@@ -30,6 +30,15 @@ const MobileHeader = /*#__PURE__*/ styled("div", {
30
30
  const [active, setActive] = useState(propsActive);
31
31
  const childrenArray = Children.toArray(children);
32
32
  const stepRefs = [];
33
+ const prevActiveRef = useRef(null);
34
+ useEffect(()=>{
35
+ if (prevActiveRef.current !== propsActive) {
36
+ setActive(propsActive);
37
+ }
38
+ prevActiveRef.current = propsActive;
39
+ }, [
40
+ propsActive
41
+ ]);
33
42
  const stepClickHandler = (index)=>()=>{
34
43
  setActive(index);
35
44
  onStepClick?.(index);
@@ -1 +1 @@
1
- {"version":3,"file":"Stepper.js","sources":["../../../src/components/Stepper/Stepper.tsx"],"sourcesContent":["import React, { Children, PropsWithChildren, useState, isValidElement } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\nimport { Ellipsis } from '../../shared/styles';\nimport { Badge, BADGE_TYPE } from '../Badge';\n\nconst Container = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 400px;\n`;\n\nconst Header = styled.div`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n\n @media (min-width: 601px) {\n &::before {\n position: absolute;\n top: 25px;\n left: 0;\n right: 0;\n height: 2px;\n background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};\n content: ' ';\n z-index: 0;\n }\n }\n\n & > * {\n z-index: 1;\n }\n`;\n\nconst HeaderButton = styled.button<{ active: boolean }>`\n border: none;\n padding: 16px 24px 16px 16px;\n font-size: 16px;\n cursor: pointer;\n background-color: ${(props) =>\n props.active\n ? getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)\n : getThemeValue(THEME_NAME.BACKGROUND)};\n font-weight: ${(props) => (props.active ? 'bold' : 'normal')};\n overflow: hidden;\n display: flex;\n align-items: center;\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};\n\n &:disabled {\n cursor: not-allowed;\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};\n }\n\n &:enabled:hover,\n &:focus {\n background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHTER)};\n }\n\n @media (max-width: 600px) {\n & {\n display: none;\n }\n }\n`;\n\nconst MobileHeader = styled.div`\n padding: 16px;\n font-size: 16px;\n line-height: 18px;\n align-items: center;\n font-weight: bold;\n flex: 1;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n @media (min-width: 601px) {\n & {\n display: none;\n }\n }\n`;\n\ntype StepperProps = PropsWithChildren<{\n /**\n * Index of currently active step\n * @default 0\n */\n active?: number;\n /** Callback function for click event on a step */\n onStepClick?: (index: number) => void;\n}> &\n React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * Stepper Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLDivElement\n */\nfunction StepperComponent(props: StepperProps, ref: React.Ref<HTMLDivElement>) {\n const { active: propsActive = 0, onStepClick, children, ...rest } = props;\n\n const [active, setActive] = useState(propsActive);\n const childrenArray = Children.toArray(children);\n const stepRefs = [] as Array<HTMLButtonElement | null>;\n\n const stepClickHandler = (index: number) => () => {\n setActive(index);\n onStepClick?.(index);\n // Move focus to the active step\n stepRefs[index]?.focus();\n };\n\n const getBadgeType = (index: number, completed: boolean, disabled: boolean) => {\n if (disabled) {\n return BADGE_TYPE.DISABLED;\n } else if (index === active) {\n return BADGE_TYPE.PRIMARY;\n } else if (completed) {\n return BADGE_TYPE.SUCCESS;\n }\n return BADGE_TYPE.DISABLED;\n };\n\n // Keyboard navigation for step buttons\n const onStepKeyDown = (index: number) => (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault();\n const next = (index + 1) % childrenArray.length;\n stepRefs[next]?.focus();\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault();\n const prev = (index - 1 + childrenArray.length) % childrenArray.length;\n stepRefs[prev]?.focus();\n }\n };\n\n return (\n <Container ref={ref} {...rest}>\n <Header role=\"tablist\" aria-label=\"Stepper Steps\">\n {Children.map(children, (child, index) => {\n if (!isValidElement(child)) return null;\n const reactElement = child as React.ReactElement<{\n disabled?: boolean;\n completed?: boolean;\n name?: string;\n }>;\n return (\n <HeaderButton\n ref={(el) => {\n stepRefs[index] = el;\n }}\n active={index === active}\n type=\"button\"\n role=\"tab\"\n aria-selected={index === active}\n aria-disabled={!!reactElement.props.disabled}\n tabIndex={index === active ? 0 : -1}\n disabled={reactElement.props.disabled}\n onClick={stepClickHandler(index)}\n onKeyDown={onStepKeyDown(index)}\n >\n <Badge\n inline\n type={getBadgeType(\n index,\n reactElement.props.completed || false,\n reactElement.props.disabled || false,\n )}\n />\n <Ellipsis>{reactElement.props.name}</Ellipsis>\n </HeaderButton>\n );\n })}\n <MobileHeader>\n <span>\n {isValidElement(childrenArray[active])\n ? (childrenArray[active] as React.ReactElement<{ name?: string }>).props\n .name\n : ''}\n </span>\n <Badge inline type={BADGE_TYPE.PRIMARY}>\n {active + 1} of {Children.count(children)}\n </Badge>\n </MobileHeader>\n </Header>\n {childrenArray[active]}\n </Container>\n );\n}\n\nconst Stepper = React.forwardRef(StepperComponent);\nexport default Stepper;\n"],"names":["Container","styled","Header","getThemeValue","THEME_NAME","BORDER_LIGHT_COLOR","LIGHT_GREY","HeaderButton","props","active","BACKGROUND","TEXT_COLOR_DARK","DISABLED_BACKGROUND","PRIMARY_LIGHTER","MobileHeader","StepperComponent","ref","propsActive","onStepClick","children","rest","setActive","useState","childrenArray","Children","toArray","stepRefs","stepClickHandler","index","focus","getBadgeType","completed","disabled","BADGE_TYPE","DISABLED","PRIMARY","SUCCESS","onStepKeyDown","e","key","preventDefault","next","length","prev","_jsxs","role","aria-label","map","child","isValidElement","reactElement","el","type","aria-selected","aria-disabled","tabIndex","onClick","onKeyDown","_jsx","Badge","inline","Ellipsis","name","span","count","Stepper","React","forwardRef"],"mappings":"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"}
1
+ {"version":3,"file":"Stepper.js","sources":["../../../src/components/Stepper/Stepper.tsx"],"sourcesContent":["import React, {\n Children,\n PropsWithChildren,\n useState,\n isValidElement,\n useEffect,\n useRef,\n} from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\nimport { Ellipsis } from '../../shared/styles';\nimport { Badge, BADGE_TYPE } from '../Badge';\n\nconst Container = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 400px;\n`;\n\nconst Header = styled.div`\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n\n @media (min-width: 601px) {\n &::before {\n position: absolute;\n top: 25px;\n left: 0;\n right: 0;\n height: 2px;\n background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};\n content: ' ';\n z-index: 0;\n }\n }\n\n & > * {\n z-index: 1;\n }\n`;\n\nconst HeaderButton = styled.button<{ active: boolean }>`\n border: none;\n padding: 16px 24px 16px 16px;\n font-size: 16px;\n cursor: pointer;\n background-color: ${(props) =>\n props.active\n ? getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)\n : getThemeValue(THEME_NAME.BACKGROUND)};\n font-weight: ${(props) => (props.active ? 'bold' : 'normal')};\n overflow: hidden;\n display: flex;\n align-items: center;\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};\n\n &:disabled {\n cursor: not-allowed;\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};\n }\n\n &:enabled:hover,\n &:focus {\n background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHTER)};\n }\n\n @media (max-width: 600px) {\n & {\n display: none;\n }\n }\n`;\n\nconst MobileHeader = styled.div`\n padding: 16px;\n font-size: 16px;\n line-height: 18px;\n align-items: center;\n font-weight: bold;\n flex: 1;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n @media (min-width: 601px) {\n & {\n display: none;\n }\n }\n`;\n\ntype StepperProps = PropsWithChildren<{\n /**\n * Index of currently active step\n * @default 0\n */\n active?: number;\n /** Callback function for click event on a step */\n onStepClick?: (index: number) => void;\n}> &\n React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * Stepper Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLDivElement\n */\nfunction StepperComponent(props: StepperProps, ref: React.Ref<HTMLDivElement>) {\n const { active: propsActive = 0, onStepClick, children, ...rest } = props;\n\n const [active, setActive] = useState(propsActive);\n const childrenArray = Children.toArray(children);\n const stepRefs = [] as Array<HTMLButtonElement | null>;\n\n const prevActiveRef = useRef<number | null>(null);\n\n useEffect(() => {\n if (prevActiveRef.current !== propsActive) {\n setActive(propsActive);\n }\n prevActiveRef.current = propsActive;\n }, [propsActive]);\n\n const stepClickHandler = (index: number) => () => {\n setActive(index);\n onStepClick?.(index);\n // Move focus to the active step\n stepRefs[index]?.focus();\n };\n\n const getBadgeType = (index: number, completed: boolean, disabled: boolean) => {\n if (disabled) {\n return BADGE_TYPE.DISABLED;\n } else if (index === active) {\n return BADGE_TYPE.PRIMARY;\n } else if (completed) {\n return BADGE_TYPE.SUCCESS;\n }\n return BADGE_TYPE.DISABLED;\n };\n\n // Keyboard navigation for step buttons\n const onStepKeyDown = (index: number) => (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault();\n const next = (index + 1) % childrenArray.length;\n stepRefs[next]?.focus();\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault();\n const prev = (index - 1 + childrenArray.length) % childrenArray.length;\n stepRefs[prev]?.focus();\n }\n };\n\n return (\n <Container ref={ref} {...rest}>\n <Header role=\"tablist\" aria-label=\"Stepper Steps\">\n {Children.map(children, (child, index) => {\n if (!isValidElement(child)) return null;\n const reactElement = child as React.ReactElement<{\n disabled?: boolean;\n completed?: boolean;\n name?: string;\n }>;\n return (\n <HeaderButton\n ref={(el) => {\n stepRefs[index] = el;\n }}\n active={index === active}\n type=\"button\"\n role=\"tab\"\n aria-selected={index === active}\n aria-disabled={!!reactElement.props.disabled}\n tabIndex={index === active ? 0 : -1}\n disabled={reactElement.props.disabled}\n onClick={stepClickHandler(index)}\n onKeyDown={onStepKeyDown(index)}\n >\n <Badge\n inline\n type={getBadgeType(\n index,\n reactElement.props.completed || false,\n reactElement.props.disabled || false,\n )}\n />\n <Ellipsis>{reactElement.props.name}</Ellipsis>\n </HeaderButton>\n );\n })}\n <MobileHeader>\n <span>\n {isValidElement(childrenArray[active])\n ? (childrenArray[active] as React.ReactElement<{ name?: string }>).props\n .name\n : ''}\n </span>\n <Badge inline type={BADGE_TYPE.PRIMARY}>\n {active + 1} of {Children.count(children)}\n </Badge>\n </MobileHeader>\n </Header>\n {childrenArray[active]}\n </Container>\n );\n}\n\nconst Stepper = React.forwardRef(StepperComponent);\nexport default Stepper;\n"],"names":["Container","styled","Header","getThemeValue","THEME_NAME","BORDER_LIGHT_COLOR","LIGHT_GREY","HeaderButton","props","active","BACKGROUND","TEXT_COLOR_DARK","DISABLED_BACKGROUND","PRIMARY_LIGHTER","MobileHeader","StepperComponent","ref","propsActive","onStepClick","children","rest","setActive","useState","childrenArray","Children","toArray","stepRefs","prevActiveRef","useRef","useEffect","current","stepClickHandler","index","focus","getBadgeType","completed","disabled","BADGE_TYPE","DISABLED","PRIMARY","SUCCESS","onStepKeyDown","e","key","preventDefault","next","length","prev","_jsxs","role","aria-label","map","child","isValidElement","reactElement","el","type","aria-selected","aria-disabled","tabIndex","onClick","onKeyDown","_jsx","Badge","inline","Ellipsis","name","span","count","Stepper","React","forwardRef"],"mappings":"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"}
package/lib-esm/index.js CHANGED
@@ -29,7 +29,7 @@ export { default as Step } from './components/Stepper/Step.js';
29
29
  export { default as Tabs } from './components/Tabs/Tabs.js';
30
30
  export { default as Tab } from './components/Tabs/Tab.js';
31
31
  export { TOOLTIP_POSITION, default as Tooltip } from './components/Tooltip/Tooltip.js';
32
- export { Body as CardBody, Footer as CardFooter, Header as CardHeader, Body as DialogBody, Footer as DialogFooter, Header as DialogHeader, Body as DrawerBody, Footer as DrawerFooter, Header as DrawerHeader, Body as ModalBody, Footer as ModalFooter, Header as ModalHeader, Body as StepBody, Footer as StepFooter } from './shared/styles.js';
32
+ export { Body as CardBody, Footer as CardFooter, Header as CardHeader, Body as DialogBody, Footer as DialogFooter, Header as DialogHeader, Body as DrawerBody, Footer as DrawerFooter, Header as DrawerHeader, ErrorContainer, Body as ModalBody, Footer as ModalFooter, Header as ModalHeader, Body as StepBody, Footer as StepFooter } from './shared/styles.js';
33
33
  export { default as AlertDialog } from './components/Dialog/AlertDialog.js';
34
34
  export { default as ConfirmDialog } from './components/Dialog/ConfirmDialog.js';
35
35
  export { default as PromptDialog } from './components/Dialog/PromptDialog.js';
@@ -32,8 +32,8 @@ import { getThemeValue, THEME_NAME } from './constants.js';
32
32
  [5]: 'bottom: 0; right: 0; justify-content: flex-end;',
33
33
  [6]: 'top: 0; left: 0; justify-content: center; align-items: center;'
34
34
  };
35
- /** Layer container component. */ const Container$5 = /*#__PURE__*/ styled("div", {
36
- target: "erw6k0c0",
35
+ /** Layer container component. */ const Container$7 = /*#__PURE__*/ styled("div", {
36
+ target: "e1at2bda0",
37
37
  label: "Container"
38
38
  })("position:fixed;display:flex;opacity:0;transition:opacity 0.3s ease;", (props)=>POSITION_STYLE[props.position], " ", (props)=>props.overlay && `
39
39
  width: 100%;
@@ -197,9 +197,6 @@ import { getThemeValue, THEME_NAME } from './constants.js';
197
197
  // Track elements modified for accessibility
198
198
  const modifiedElements = [];
199
199
  let originalBodyOverflow = null;
200
- let originalBodyPosition = null;
201
- let originalBodyWidth = null;
202
- let originalBodyTop = null;
203
200
  let scrollY = 0;
204
201
  // Apply aria-hidden to siblings and body scroll lock for overlay modals
205
202
  if (layerConfig.overlay) {
@@ -223,13 +220,7 @@ import { getThemeValue, THEME_NAME } from './constants.js';
223
220
  // Prevent body scroll on iOS
224
221
  scrollY = window.scrollY;
225
222
  originalBodyOverflow = document.body.style.overflow;
226
- originalBodyPosition = document.body.style.position;
227
- originalBodyWidth = document.body.style.width;
228
- originalBodyTop = document.body.style.top;
229
223
  document.body.style.overflow = 'hidden';
230
- document.body.style.position = 'fixed';
231
- document.body.style.width = '100%';
232
- document.body.style.top = `-${scrollY}px`;
233
224
  }
234
225
  // Cleanup function - remove div when component unmounts
235
226
  return ()=>{
@@ -246,9 +237,6 @@ import { getThemeValue, THEME_NAME } from './constants.js';
246
237
  // Restore body scroll
247
238
  if (layerConfig.overlay) {
248
239
  document.body.style.overflow = originalBodyOverflow || '';
249
- document.body.style.position = originalBodyPosition || '';
250
- document.body.style.width = originalBodyWidth || '';
251
- document.body.style.top = originalBodyTop || '';
252
240
  window.scrollTo(0, scrollY);
253
241
  }
254
242
  if (document.body.contains(div)) {
@@ -264,7 +252,7 @@ import { getThemeValue, THEME_NAME } from './constants.js';
264
252
  if (!divElement) {
265
253
  return null;
266
254
  }
267
- return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx(Container$5, {
255
+ return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx(Container$7, {
268
256
  ...props,
269
257
  ref: ref,
270
258
  onClick: overlayClickHandler,
@@ -1 +1 @@
1
- {"version":3,"file":"LayerManager.js","sources":["../../src/shared/LayerManager.tsx"],"sourcesContent":["import React, { ForwardRefExoticComponent, RefAttributes, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from './constants';\n\n/** Enums for layer position on screen. */\nexport enum LAYER_POSITION {\n TOP_LEFT,\n TOP_CENTER,\n TOP_RIGHT,\n BOTTOM_LEFT,\n BOTTOM_CENTER,\n BOTTOM_RIGHT,\n DIALOG,\n}\n\ninterface LayerConfig {\n /** Show an overlay */\n overlay?: boolean;\n /** Element to render inside the layer. */\n component: React.JSX.Element | null;\n /** Position of the layer */\n position?: LAYER_POSITION;\n /** Delay for exit */\n exitDelay?: number;\n /** Close layer on `esc` key press. */\n closeOnEsc?: boolean;\n /** Close layer overlay is clicked. */\n closeOnOverlayClick?: boolean;\n /** Callback called when modal closes */\n closeCallback?: (resp?: unknown) => void;\n /** Layer is created with max z-index */\n alwaysOnTop?: boolean;\n}\n\n/** Default value of config */\nconst defaultConfig: LayerConfig = {\n closeOnEsc: true,\n overlay: false,\n position: LAYER_POSITION.TOP_LEFT,\n component: null,\n exitDelay: 0,\n closeOnOverlayClick: true,\n alwaysOnTop: false,\n};\n\n/** Metadata of each layer */\ninterface Layer {\n id: string;\n config: LayerConfig;\n element: HTMLDivElement;\n}\n\n/** Styles for each position */\nconst POSITION_STYLE: Record<LAYER_POSITION, string> = {\n [LAYER_POSITION.TOP_LEFT]: 'top: 0; left: 0;',\n [LAYER_POSITION.TOP_CENTER]: 'top: 0; left: 50%; justify-content: center;',\n [LAYER_POSITION.TOP_RIGHT]: 'top: 0; right: 0; justify-content: flex-end;',\n [LAYER_POSITION.BOTTOM_LEFT]: 'bottom: 0; left: 0;',\n [LAYER_POSITION.BOTTOM_CENTER]: 'bottom: 0; left: 50%; justify-content: center;',\n [LAYER_POSITION.BOTTOM_RIGHT]: 'bottom: 0; right: 0; justify-content: flex-end;',\n [LAYER_POSITION.DIALOG]: 'top: 0; left: 0; justify-content: center; align-items: center;',\n};\n\n/** Layer container component. */\nconst Container = styled.div<LayerConfig & { zIndex: number }>`\n position: fixed;\n display: flex;\n opacity: 0;\n transition: opacity 0.3s ease;\n ${(props) => POSITION_STYLE[props.position as LAYER_POSITION]}\n ${(props) =>\n props.overlay &&\n `\n width: 100%;\n height: 100vh;\n background-color: ${getThemeValue(THEME_NAME.BACKDROP_COLOR)};\n backdrop-filter: blur(0px);\n pointer-events: all;\n `}\n z-index: ${(props) => props.zIndex};\n\n .nf-layer-enter & {\n opacity: 1;\n ${(props) =>\n props.overlay &&\n `\n backdrop-filter: blur(3px);\n `}\n }\n`;\n\n/** Key code for different keys. */\nconst KEY_CODES = {\n ESC: 27,\n};\n\n/**\n * This is a shared helper class which manages the z-index of each layer.\n * If a component needs to be rendered in a different layer then this class\n * should be used. It internally maintains the stack of opened layer and each\n * `renderLayer` call will push a new layer in stack.\n *\n * This way we need not worry about the z-index and can freely keep on creating\n * new layers. The staring layer z-index is 10000. Leaving enough z-index for the\n * user if they desires so.\n *\n * @important Usage Pattern\n * To avoid creating duplicate layers (especially in React Strict Mode or Next.js),\n * always call `renderLayer` only once - either in a lifecycle method (like `componentDidUpdate`)\n * or in an imperative method (like `open()`).\n *\n * @example\n * // ❌ Don't call renderLayer in render() method\n * render() {\n * if (this.state.show) {\n * const [Component, closeFn] = LayerManager.renderLayer({ ... }); // Creates new layer on every render\n * return <Component />;\n * }\n * }\n *\n * @example\n * // ✅ Do call renderLayer once in a method and store the component\n * open() {\n * const [Component, closeFn] = LayerManager.renderLayer({ ... });\n * this.setState({ LayerComponent: Component });\n * }\n *\n * render() {\n * const { LayerComponent } = this.state;\n * return LayerComponent ? <LayerComponent /> : null;\n * }\n */\nclass LayerManager {\n /** Layer stack */\n private layers: Layer[] = [];\n /** z-index of the next layer */\n private nextIndex = 0;\n private keyupHandler!: (e: KeyboardEvent) => void;\n private timeoutIds = new Map<string, number>(); // Track timeouts\n\n /**\n * Constructor simply registers a event listener on body to\n * react to esc key press.\n */\n constructor() {\n if (typeof document !== 'undefined') {\n // Store handler reference for cleanup\n this.keyupHandler = (e) => {\n if (this.layers.length && e.keyCode === KEY_CODES.ESC) {\n const lastLayer = this.layers.slice(-1)[0];\n if (lastLayer.config.closeOnEsc !== false) {\n this.unmount(lastLayer);\n }\n }\n };\n document.body.addEventListener('keyup', this.keyupHandler);\n }\n }\n\n // Add cleanup method\n public destroy = () => {\n if (typeof document !== 'undefined' && this.keyupHandler) {\n document.body.removeEventListener('keyup', this.keyupHandler);\n }\n // Clear all pending timeouts\n this.timeoutIds.forEach((id) => clearTimeout(id));\n this.timeoutIds.clear();\n // Clean up remaining layers\n this.layers.forEach((layer) => {\n if (document.body.contains(layer.element)) {\n document.body.removeChild(layer.element);\n }\n });\n this.layers = [];\n };\n\n /**\n * Un-mounts a layer.\n *\n * It first adds a class 'nf-layer-exit' and then un-mounts the\n * layer after the `exitDelay` mentioned in the layer config.\n * This class will help component in triggering the entry animation.\n *\n * @param layer\n */\n private unmount = (layer: Layer, resp?: unknown) => {\n layer.element.setAttribute('class', 'nf-layer-exit');\n const index = this.layers.findIndex((item) => item === layer);\n if (index !== -1) {\n this.layers.splice(index, 1);\n }\n\n const timeoutId = window.setTimeout(() => {\n this.timeoutIds.delete(layer.id);\n try {\n layer.config.closeCallback?.(resp);\n } catch (err) {\n if (err instanceof Error) {\n console.warn(err.message);\n } else {\n console.warn(err);\n }\n }\n // Clear reference to help GC\n layer.config.component = null;\n }, layer.config.exitDelay);\n\n this.timeoutIds.set(layer.id, timeoutId);\n };\n\n private Empty = () => {\n return null;\n };\n\n /**\n * Renders a layer.\n * @param config\n */\n public renderLayer = (\n config: LayerConfig,\n ): [ForwardRefExoticComponent<RefAttributes<HTMLDivElement>>, (resp?: unknown) => void] => {\n // SSR guard\n if (typeof document === 'undefined') {\n return [React.forwardRef(this.Empty), () => {}];\n }\n\n // Merge default config with the provided config.\n const layerConfig = {\n ...defaultConfig,\n ...config,\n };\n\n // Get the z-index for the new layer\n const currentIndex = layerConfig.alwaysOnTop ? 2147483647 : 10000 + this.nextIndex;\n const className = layerConfig.alwaysOnTop ? 'nf-layer-manager-top' : 'nf-layer-manager';\n\n // Create a unique ID for tracking this layer\n const layerId = `${className}-${currentIndex + this.nextIndex}`;\n\n // Always increment for next layer\n this.nextIndex += 1;\n\n const overlayClickHandler = () => {\n const layer = this.layers.find((l) => l.id === layerId);\n if (layer && layer.config.closeOnOverlayClick !== false) {\n this.unmount(layer);\n }\n };\n\n const closeFn = (resp?: unknown) => {\n const layer = this.layers.find((l) => l.id === layerId);\n if (layer) {\n this.unmount(layer, resp);\n }\n };\n\n const LayerContainer = (\n props: React.HTMLAttributes<HTMLDivElement>,\n ref: React.Ref<HTMLDivElement>,\n ) => {\n const [divElement, setDivElement] = React.useState<HTMLDivElement | null>(null);\n\n useEffect(() => {\n // Create the div element only once when component mounts\n const div = document.createElement('div');\n div.setAttribute('class', className);\n div.setAttribute('id', layerId);\n document.body.appendChild(div);\n\n // Add layer to stack\n const currentLayer = {\n id: layerId,\n config: layerConfig,\n element: div,\n };\n this.layers.push(currentLayer);\n\n setDivElement(div);\n // Add entry animation class after a short delay\n setTimeout(() => {\n div.setAttribute('class', 'nf-layer-enter');\n }, 10);\n\n // Track elements modified for accessibility\n const modifiedElements: Array<{\n element: Element;\n hadAriaHidden: boolean;\n previousValue: string | null;\n }> = [];\n let originalBodyOverflow: string | null = null;\n let originalBodyPosition: string | null = null;\n let originalBodyWidth: string | null = null;\n let originalBodyTop: string | null = null;\n let scrollY = 0;\n\n // Apply aria-hidden to siblings and body scroll lock for overlay modals\n if (layerConfig.overlay) {\n // Hide all body children except this layer portal, scripts, and styles\n const bodyChildren = Array.from(document.body.children);\n bodyChildren.forEach((child) => {\n if (\n child !== div &&\n child.className !== 'nf-layer-manager-top' &&\n child.tagName !== 'SCRIPT' &&\n child.tagName !== 'STYLE'\n ) {\n const hadAriaHidden = child.hasAttribute('aria-hidden');\n const previousValue = child.getAttribute('aria-hidden');\n\n // Only set aria-hidden if not already hidden\n if (previousValue !== 'true') {\n child.setAttribute('aria-hidden', 'true');\n modifiedElements.push({\n element: child,\n hadAriaHidden,\n previousValue,\n });\n }\n }\n });\n\n // Prevent body scroll on iOS\n scrollY = window.scrollY;\n originalBodyOverflow = document.body.style.overflow;\n originalBodyPosition = document.body.style.position;\n originalBodyWidth = document.body.style.width;\n originalBodyTop = document.body.style.top;\n\n document.body.style.overflow = 'hidden';\n document.body.style.position = 'fixed';\n document.body.style.width = '100%';\n document.body.style.top = `-${scrollY}px`;\n }\n\n // Cleanup function - remove div when component unmounts\n return () => {\n // Restore aria-hidden attributes\n modifiedElements.forEach(({ element, hadAriaHidden, previousValue }) => {\n if (document.body.contains(element)) {\n if (hadAriaHidden && previousValue !== null) {\n element.setAttribute('aria-hidden', previousValue);\n } else {\n element.removeAttribute('aria-hidden');\n }\n }\n });\n\n // Restore body scroll\n if (layerConfig.overlay) {\n document.body.style.overflow = originalBodyOverflow || '';\n document.body.style.position = originalBodyPosition || '';\n document.body.style.width = originalBodyWidth || '';\n document.body.style.top = originalBodyTop || '';\n window.scrollTo(0, scrollY);\n }\n\n if (document.body.contains(div)) {\n document.body.removeChild(div);\n }\n // Remove from layers array\n const index = this.layers.findIndex((layer) => layer.id === layerId);\n if (index !== -1) {\n this.layers.splice(index, 1);\n }\n };\n }, []); // Empty dependency array - run only once\n\n if (!divElement) {\n return null;\n }\n\n return createPortal(\n <Container\n {...props}\n ref={ref}\n onClick={overlayClickHandler}\n zIndex={currentIndex}\n {...layerConfig}\n >\n {layerConfig.component}\n </Container>,\n divElement,\n );\n };\n\n // Return callback which will trigger the un-mount.\n return [\n React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(LayerContainer),\n closeFn,\n ];\n };\n}\n\n// Return the instance of the class to create a Singleton.\nexport default new LayerManager();\n"],"names":["LAYER_POSITION","defaultConfig","closeOnEsc","overlay","position","component","exitDelay","closeOnOverlayClick","alwaysOnTop","POSITION_STYLE","Container","styled","props","getThemeValue","THEME_NAME","BACKDROP_COLOR","zIndex","KEY_CODES","ESC","LayerManager","layers","nextIndex","timeoutIds","Map","destroy","document","keyupHandler","body","removeEventListener","forEach","id","clearTimeout","clear","layer","contains","element","removeChild","unmount","resp","setAttribute","index","findIndex","item","splice","timeoutId","window","setTimeout","delete","config","closeCallback","err","Error","console","warn","message","set","Empty","renderLayer","React","forwardRef","layerConfig","currentIndex","className","layerId","overlayClickHandler","find","l","closeFn","LayerContainer","ref","divElement","setDivElement","useState","useEffect","div","createElement","appendChild","currentLayer","push","modifiedElements","originalBodyOverflow","originalBodyPosition","originalBodyWidth","originalBodyTop","scrollY","bodyChildren","Array","from","children","child","tagName","hadAriaHidden","hasAttribute","previousValue","getAttribute","style","overflow","width","top","removeAttribute","scrollTo","createPortal","_jsx","onClick","e","length","keyCode","lastLayer","slice","addEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"LayerManager.js","sources":["../../src/shared/LayerManager.tsx"],"sourcesContent":["import React, { ForwardRefExoticComponent, RefAttributes, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from './constants';\n\n/** Enums for layer position on screen. */\nexport enum LAYER_POSITION {\n TOP_LEFT,\n TOP_CENTER,\n TOP_RIGHT,\n BOTTOM_LEFT,\n BOTTOM_CENTER,\n BOTTOM_RIGHT,\n DIALOG,\n}\n\ninterface LayerConfig {\n /** Show an overlay */\n overlay?: boolean;\n /** Element to render inside the layer. */\n component: React.JSX.Element | null;\n /** Position of the layer */\n position?: LAYER_POSITION;\n /** Delay for exit */\n exitDelay?: number;\n /** Close layer on `esc` key press. */\n closeOnEsc?: boolean;\n /** Close layer overlay is clicked. */\n closeOnOverlayClick?: boolean;\n /** Callback called when modal closes */\n closeCallback?: (resp?: unknown) => void;\n /** Layer is created with max z-index */\n alwaysOnTop?: boolean;\n}\n\n/** Default value of config */\nconst defaultConfig: LayerConfig = {\n closeOnEsc: true,\n overlay: false,\n position: LAYER_POSITION.TOP_LEFT,\n component: null,\n exitDelay: 0,\n closeOnOverlayClick: true,\n alwaysOnTop: false,\n};\n\n/** Metadata of each layer */\ninterface Layer {\n id: string;\n config: LayerConfig;\n element: HTMLDivElement;\n}\n\n/** Styles for each position */\nconst POSITION_STYLE: Record<LAYER_POSITION, string> = {\n [LAYER_POSITION.TOP_LEFT]: 'top: 0; left: 0;',\n [LAYER_POSITION.TOP_CENTER]: 'top: 0; left: 50%; justify-content: center;',\n [LAYER_POSITION.TOP_RIGHT]: 'top: 0; right: 0; justify-content: flex-end;',\n [LAYER_POSITION.BOTTOM_LEFT]: 'bottom: 0; left: 0;',\n [LAYER_POSITION.BOTTOM_CENTER]: 'bottom: 0; left: 50%; justify-content: center;',\n [LAYER_POSITION.BOTTOM_RIGHT]: 'bottom: 0; right: 0; justify-content: flex-end;',\n [LAYER_POSITION.DIALOG]: 'top: 0; left: 0; justify-content: center; align-items: center;',\n};\n\n/** Layer container component. */\nconst Container = styled.div<LayerConfig & { zIndex: number }>`\n position: fixed;\n display: flex;\n opacity: 0;\n transition: opacity 0.3s ease;\n ${(props) => POSITION_STYLE[props.position as LAYER_POSITION]}\n ${(props) =>\n props.overlay &&\n `\n width: 100%;\n height: 100vh;\n background-color: ${getThemeValue(THEME_NAME.BACKDROP_COLOR)};\n backdrop-filter: blur(0px);\n pointer-events: all;\n `}\n z-index: ${(props) => props.zIndex};\n\n .nf-layer-enter & {\n opacity: 1;\n ${(props) =>\n props.overlay &&\n `\n backdrop-filter: blur(3px);\n `}\n }\n`;\n\n/** Key code for different keys. */\nconst KEY_CODES = {\n ESC: 27,\n};\n\n/**\n * This is a shared helper class which manages the z-index of each layer.\n * If a component needs to be rendered in a different layer then this class\n * should be used. It internally maintains the stack of opened layer and each\n * `renderLayer` call will push a new layer in stack.\n *\n * This way we need not worry about the z-index and can freely keep on creating\n * new layers. The staring layer z-index is 10000. Leaving enough z-index for the\n * user if they desires so.\n *\n * @important Usage Pattern\n * To avoid creating duplicate layers (especially in React Strict Mode or Next.js),\n * always call `renderLayer` only once - either in a lifecycle method (like `componentDidUpdate`)\n * or in an imperative method (like `open()`).\n *\n * @example\n * // ❌ Don't call renderLayer in render() method\n * render() {\n * if (this.state.show) {\n * const [Component, closeFn] = LayerManager.renderLayer({ ... }); // Creates new layer on every render\n * return <Component />;\n * }\n * }\n *\n * @example\n * // ✅ Do call renderLayer once in a method and store the component\n * open() {\n * const [Component, closeFn] = LayerManager.renderLayer({ ... });\n * this.setState({ LayerComponent: Component });\n * }\n *\n * render() {\n * const { LayerComponent } = this.state;\n * return LayerComponent ? <LayerComponent /> : null;\n * }\n */\nclass LayerManager {\n /** Layer stack */\n private layers: Layer[] = [];\n /** z-index of the next layer */\n private nextIndex = 0;\n private keyupHandler!: (e: KeyboardEvent) => void;\n private timeoutIds = new Map<string, number>(); // Track timeouts\n\n /**\n * Constructor simply registers a event listener on body to\n * react to esc key press.\n */\n constructor() {\n if (typeof document !== 'undefined') {\n // Store handler reference for cleanup\n this.keyupHandler = (e) => {\n if (this.layers.length && e.keyCode === KEY_CODES.ESC) {\n const lastLayer = this.layers.slice(-1)[0];\n if (lastLayer.config.closeOnEsc !== false) {\n this.unmount(lastLayer);\n }\n }\n };\n document.body.addEventListener('keyup', this.keyupHandler);\n }\n }\n\n // Add cleanup method\n public destroy = () => {\n if (typeof document !== 'undefined' && this.keyupHandler) {\n document.body.removeEventListener('keyup', this.keyupHandler);\n }\n // Clear all pending timeouts\n this.timeoutIds.forEach((id) => clearTimeout(id));\n this.timeoutIds.clear();\n // Clean up remaining layers\n this.layers.forEach((layer) => {\n if (document.body.contains(layer.element)) {\n document.body.removeChild(layer.element);\n }\n });\n this.layers = [];\n };\n\n /**\n * Un-mounts a layer.\n *\n * It first adds a class 'nf-layer-exit' and then un-mounts the\n * layer after the `exitDelay` mentioned in the layer config.\n * This class will help component in triggering the entry animation.\n *\n * @param layer\n */\n private unmount = (layer: Layer, resp?: unknown) => {\n layer.element.setAttribute('class', 'nf-layer-exit');\n const index = this.layers.findIndex((item) => item === layer);\n if (index !== -1) {\n this.layers.splice(index, 1);\n }\n\n const timeoutId = window.setTimeout(() => {\n this.timeoutIds.delete(layer.id);\n try {\n layer.config.closeCallback?.(resp);\n } catch (err) {\n if (err instanceof Error) {\n console.warn(err.message);\n } else {\n console.warn(err);\n }\n }\n // Clear reference to help GC\n layer.config.component = null;\n }, layer.config.exitDelay);\n\n this.timeoutIds.set(layer.id, timeoutId);\n };\n\n private Empty = () => {\n return null;\n };\n\n /**\n * Renders a layer.\n * @param config\n */\n public renderLayer = (\n config: LayerConfig,\n ): [ForwardRefExoticComponent<RefAttributes<HTMLDivElement>>, (resp?: unknown) => void] => {\n // SSR guard\n if (typeof document === 'undefined') {\n return [React.forwardRef(this.Empty), () => {}];\n }\n\n // Merge default config with the provided config.\n const layerConfig = {\n ...defaultConfig,\n ...config,\n };\n\n // Get the z-index for the new layer\n const currentIndex = layerConfig.alwaysOnTop ? 2147483647 : 10000 + this.nextIndex;\n const className = layerConfig.alwaysOnTop ? 'nf-layer-manager-top' : 'nf-layer-manager';\n\n // Create a unique ID for tracking this layer\n const layerId = `${className}-${currentIndex + this.nextIndex}`;\n\n // Always increment for next layer\n this.nextIndex += 1;\n\n const overlayClickHandler = () => {\n const layer = this.layers.find((l) => l.id === layerId);\n if (layer && layer.config.closeOnOverlayClick !== false) {\n this.unmount(layer);\n }\n };\n\n const closeFn = (resp?: unknown) => {\n const layer = this.layers.find((l) => l.id === layerId);\n if (layer) {\n this.unmount(layer, resp);\n }\n };\n\n const LayerContainer = (\n props: React.HTMLAttributes<HTMLDivElement>,\n ref: React.Ref<HTMLDivElement>,\n ) => {\n const [divElement, setDivElement] = React.useState<HTMLDivElement | null>(null);\n\n useEffect(() => {\n // Create the div element only once when component mounts\n const div = document.createElement('div');\n div.setAttribute('class', className);\n div.setAttribute('id', layerId);\n document.body.appendChild(div);\n\n // Add layer to stack\n const currentLayer = {\n id: layerId,\n config: layerConfig,\n element: div,\n };\n this.layers.push(currentLayer);\n\n setDivElement(div);\n // Add entry animation class after a short delay\n setTimeout(() => {\n div.setAttribute('class', 'nf-layer-enter');\n }, 10);\n\n // Track elements modified for accessibility\n const modifiedElements: Array<{\n element: Element;\n hadAriaHidden: boolean;\n previousValue: string | null;\n }> = [];\n let originalBodyOverflow: string | null = null;\n let scrollY = 0;\n\n // Apply aria-hidden to siblings and body scroll lock for overlay modals\n if (layerConfig.overlay) {\n // Hide all body children except this layer portal, scripts, and styles\n const bodyChildren = Array.from(document.body.children);\n bodyChildren.forEach((child) => {\n if (\n child !== div &&\n child.className !== 'nf-layer-manager-top' &&\n child.tagName !== 'SCRIPT' &&\n child.tagName !== 'STYLE'\n ) {\n const hadAriaHidden = child.hasAttribute('aria-hidden');\n const previousValue = child.getAttribute('aria-hidden');\n\n // Only set aria-hidden if not already hidden\n if (previousValue !== 'true') {\n child.setAttribute('aria-hidden', 'true');\n modifiedElements.push({\n element: child,\n hadAriaHidden,\n previousValue,\n });\n }\n }\n });\n\n // Prevent body scroll on iOS\n scrollY = window.scrollY;\n originalBodyOverflow = document.body.style.overflow;\n\n document.body.style.overflow = 'hidden';\n }\n\n // Cleanup function - remove div when component unmounts\n return () => {\n // Restore aria-hidden attributes\n modifiedElements.forEach(({ element, hadAriaHidden, previousValue }) => {\n if (document.body.contains(element)) {\n if (hadAriaHidden && previousValue !== null) {\n element.setAttribute('aria-hidden', previousValue);\n } else {\n element.removeAttribute('aria-hidden');\n }\n }\n });\n\n // Restore body scroll\n if (layerConfig.overlay) {\n document.body.style.overflow = originalBodyOverflow || '';\n window.scrollTo(0, scrollY);\n }\n\n if (document.body.contains(div)) {\n document.body.removeChild(div);\n }\n // Remove from layers array\n const index = this.layers.findIndex((layer) => layer.id === layerId);\n if (index !== -1) {\n this.layers.splice(index, 1);\n }\n };\n }, []); // Empty dependency array - run only once\n\n if (!divElement) {\n return null;\n }\n\n return createPortal(\n <Container\n {...props}\n ref={ref}\n onClick={overlayClickHandler}\n zIndex={currentIndex}\n {...layerConfig}\n >\n {layerConfig.component}\n </Container>,\n divElement,\n );\n };\n\n // Return callback which will trigger the un-mount.\n return [\n React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(LayerContainer),\n closeFn,\n ];\n };\n}\n\n// Return the instance of the class to create a Singleton.\nexport default new LayerManager();\n"],"names":["LAYER_POSITION","defaultConfig","closeOnEsc","overlay","position","component","exitDelay","closeOnOverlayClick","alwaysOnTop","POSITION_STYLE","Container","styled","props","getThemeValue","THEME_NAME","BACKDROP_COLOR","zIndex","KEY_CODES","ESC","LayerManager","layers","nextIndex","timeoutIds","Map","destroy","document","keyupHandler","body","removeEventListener","forEach","id","clearTimeout","clear","layer","contains","element","removeChild","unmount","resp","setAttribute","index","findIndex","item","splice","timeoutId","window","setTimeout","delete","config","closeCallback","err","Error","console","warn","message","set","Empty","renderLayer","React","forwardRef","layerConfig","currentIndex","className","layerId","overlayClickHandler","find","l","closeFn","LayerContainer","ref","divElement","setDivElement","useState","useEffect","div","createElement","appendChild","currentLayer","push","modifiedElements","originalBodyOverflow","scrollY","bodyChildren","Array","from","children","child","tagName","hadAriaHidden","hasAttribute","previousValue","getAttribute","style","overflow","removeAttribute","scrollTo","createPortal","_jsx","onClick","e","length","keyCode","lastLayer","slice","addEventListener"],"mappings":"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"}
@@ -5,7 +5,7 @@ export declare const Ellipsis: import("@emotion/styled").StyledComponent<{
5
5
  export declare const Header: import("@emotion/styled").StyledComponent<{
6
6
  theme?: import("@emotion/react").Theme;
7
7
  as?: React.ElementType;
8
- }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, {}>;
8
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
9
9
  export declare const Body: import("@emotion/styled").StyledComponent<{
10
10
  theme?: import("@emotion/react").Theme;
11
11
  as?: React.ElementType;
@@ -14,3 +14,7 @@ export declare const Footer: import("@emotion/styled").StyledComponent<{
14
14
  theme?: import("@emotion/react").Theme;
15
15
  as?: React.ElementType;
16
16
  }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
17
+ export declare const ErrorContainer: import("@emotion/styled").StyledComponent<{
18
+ theme?: import("@emotion/react").Theme;
19
+ as?: React.ElementType;
20
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;