@spaced-out/genesis-mcp 1.0.17 → 1.0.19

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "metadata": {
3
- "buildDate": "2026-03-06T11:13:06.404Z",
4
- "version": "0.6.1",
3
+ "buildDate": "2026-03-10T07:14:54.783Z",
4
+ "version": "0.6.2",
5
5
  "designSystemPath": "/home/runner/work/ui-design-system/ui-design-system"
6
6
  },
7
7
  "components": {
@@ -836,7 +836,7 @@
836
836
  },
837
837
  "story": {
838
838
  "path": "Dialog.stories.tsx",
839
- "content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport type {DialogProps} from 'src/components/Dialog/Dialog';\nimport {\n BasicDialog,\n Dialog,\n DIALOG_SEMANTIC,\n DialogBody,\n DialogFooter,\n DialogHeader,\n} from 'src/components/Dialog/Dialog';\nimport {BodyLarge, SubTitleLarge} from 'src/components/Text';\n\nimport css from 'src/components/Dialog/Dialog.stories.module.css';\n\n\nconst semanticOptions: Array<unknown> = [...Object.values(DIALOG_SEMANTIC)];\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Dialog',\n argTypes: {\n semantic: {\n options: semanticOptions,\n description: 'Semantic type of Dialog',\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: DIALOG_SEMANTIC.neutral},\n },\n },\n iconName: {\n description: 'Custom icon. This overrides the default semantic icon',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n customAnimation: {\n description: `\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n \\`customAnimation: UseTransitionStylesProps\\` prop for\n all your custom animation needs.\n It defines the following properties: \\n\\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\\n\\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed. This\nis the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Dialog component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Dialog, DialogBody, DialogHeader, DialogFooter } from \"@spaced-out/ui-design-system/lib/components/Dialog\";\n\\`\\`\\`\nA **dialog** is a particular kind of **<a href=\"../?path=/docs/components-modal--docs\">Modal</a>** window that appears in front of the app's content to offer important information or solicit input.\nWhen they appear, dialogues **turn off** all app functions. They stay on screen until they are acknowledged, dismissed, or a necessary action is made.\n\nDialogs should only be used occasionally because they are intended to be disruptive. Dialogs come in multiple variants as listed below.\n\nyou can either use a Basic Dialog or\nSemantically a Dialog component should be composed from \\`DialogHeader\\`, \\`DialogBody\\`, and \\`DialogFooter\\` components,\nthese are nothing but layout components which defines appropriate spacing for the children living in them.\nEach of these components also exposes a className\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Dialog/Dialog',\n },\n },\n};\n\nexport const DialogStory = (args: DialogProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Dialog</Button>\n <Dialog {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <DialogHeader>\n <SubTitleLarge> Dialog Title</SubTitleLarge>\n </DialogHeader>\n\n <DialogBody>\n <BodyLarge color=\"secondary\">\n Dialogs should only be used occasionally because they are intended\n to be disruptive. Dialogs come in multiple variants.\n </BodyLarge>\n </DialogBody>\n\n <DialogFooter>\n <Button type=\"tertiary\" isFluid onClick={() => setIsOpen(false)}>\n Close\n </Button>\n\n <Button type=\"primary\" isFluid onClick={() => setIsOpen(false)}>\n Confirm\n </Button>\n </DialogFooter>\n </Dialog>\n </div>\n );\n};\n\nDialogStory.args = {\n classNames: {container: ''},\n initialFocus: 1,\n semantic: 'neutral',\n testId: 'dialog-story',\n};\n\n/**\n * Basic Dialog supports these additional props <br><br>\n * `heading?: React.Node` <br>\n * `body?: React.Node` <br>\n * `confirmText?: string` <br>\n * `abortText?: string` <br>\n * `handleConfirm?: (event: SyntheticEvent<>) => mixed` <br>\n * `handleAbort?: (event: SyntheticEvent<>) => mixed`\n */\nexport const BasicDialogStory = (args: DialogProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Basic Dialog</Button>\n <BasicDialog\n {...args}\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n handleAbort={() => setIsOpen(false)}\n handleConfirm={() => setIsOpen(false)}\n />\n </div>\n );\n};\n\nBasicDialogStory.args = {\n semantic: 'danger',\n heading: 'Dialog Title',\n body: 'A basic dialog supports text props to prepare content. You don\\'t need to import semantic components to prepare the desired layout.',\n abortText: 'Close',\n confirmText: 'Confirm',\n testId: 'basic-dialog-story',\n};\nDialogStory.storyName = 'Dialog';\nBasicDialogStory.storyName = 'Basic Dialog';\n"
839
+ "content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport type {DialogProps} from 'src/components/Dialog/Dialog';\nimport {\n BasicDialog,\n Dialog,\n DIALOG_SEMANTIC,\n DialogBody,\n DialogFooter,\n DialogHeader,\n} from 'src/components/Dialog/Dialog';\nimport {BodyLarge, SubTitleLarge} from 'src/components/Text';\n\nimport css from 'src/components/Dialog/Dialog.stories.module.css';\n\n\nconst semanticOptions: Array<unknown> = [...Object.values(DIALOG_SEMANTIC)];\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Dialog',\n argTypes: {\n semantic: {\n options: semanticOptions,\n description: 'Semantic type of Dialog',\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: DIALOG_SEMANTIC.neutral},\n },\n },\n iconName: {\n description: 'Custom icon. This overrides the default semantic icon',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n customAnimation: {\n description: `\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n \\`customAnimation: UseTransitionStylesProps\\` prop for\n all your custom animation needs.\n It defines the following properties: \\n\\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\\n\\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed. This\nis the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Dialog component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Dialog, DialogBody, DialogHeader, DialogFooter } from \"@spaced-out/ui-design-system/lib/components/Dialog\";\n\\`\\`\\`\nA **dialog** is a particular kind of **<a href=\"../?path=/docs/components-modal--docs\">Modal</a>** window that appears in front of the app's content to offer important information or solicit input.\nWhen they appear, dialogues **turn off** all app functions. They stay on screen until they are acknowledged, dismissed, or a necessary action is made.\n\nDialogs should only be used occasionally because they are intended to be disruptive. Dialogs come in multiple variants as listed below.\n\nyou can either use a Basic Dialog or\nSemantically a Dialog component should be composed from \\`DialogHeader\\`, \\`DialogBody\\`, and \\`DialogFooter\\` components,\nthese are nothing but layout components which defines appropriate spacing for the children living in them.\nEach of these components also exposes a className\n\n---\n\n### Overlay Lifecycle Events\n\nDialog emits **strongly-typed window events** when it mounts and unmounts (see **<a href=\"../?path=/docs/components-modal--docs\">Modal docs</a>** for the full API reference, all event types, and advanced usage patterns).\n\nDialog-specific fields in the event payload:\n\n| Field | Value |\n|---|---|\n| \\`overlayType\\` | \\`'Dialog'\\` |\n| \\`semantic\\` | \\`'neutral' \\\\| 'success' \\\\| 'information' \\\\| 'warning' \\\\| 'danger'\\` (from the \\`semantic\\` prop) |\n| \\`hasBackdrop\\` | Derived from \\`hideBackdrop\\` (default \\`true\\` for Dialog) |\n| \\`tapOutsideToClose\\` | Default \\`false\\` for Dialog |\n\n**Listening for Dialog events:**\n\n\\`\\`\\`ts\nimport {\n OVERLAY_MOUNT_EVENT,\n OVERLAY_UNMOUNT_EVENT,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Dialog') {\n console.log(\\\\\\`Dialog opened: semantic=\\\\\\${e.detail.semantic}\\\\\\`);\n }\n});\n\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Dialog') {\n console.log(\\\\\\`Dialog closed: id=\\\\\\${e.detail.id}\\\\\\`);\n }\n});\n\\`\\`\\`\n\n**Filter by semantic type:**\n\n\\`\\`\\`ts\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Dialog' && e.detail.semantic === 'danger') {\n analytics.track('danger_dialog_shown', { testId: e.detail.testId });\n }\n});\n\\`\\`\\`\n\n**Example payload (Dialog, danger):**\n\n\\`\\`\\`json\n{\n \"id\": \"g7h8i9\",\n \"overlayType\": \"Dialog\",\n \"hasBackdrop\": true,\n \"tapOutsideToClose\": false,\n \"allowBackgroundInteraction\": false,\n \"semantic\": \"danger\",\n \"testId\": \"confirm-delete-dialog\"\n}\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Dialog/Dialog',\n },\n },\n};\n\nexport const DialogStory = (args: DialogProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Dialog</Button>\n <Dialog {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <DialogHeader>\n <SubTitleLarge> Dialog Title</SubTitleLarge>\n </DialogHeader>\n\n <DialogBody>\n <BodyLarge color=\"secondary\">\n Dialogs should only be used occasionally because they are intended\n to be disruptive. Dialogs come in multiple variants.\n </BodyLarge>\n </DialogBody>\n\n <DialogFooter>\n <Button type=\"tertiary\" isFluid onClick={() => setIsOpen(false)}>\n Close\n </Button>\n\n <Button type=\"primary\" isFluid onClick={() => setIsOpen(false)}>\n Confirm\n </Button>\n </DialogFooter>\n </Dialog>\n </div>\n );\n};\n\nDialogStory.args = {\n classNames: {container: ''},\n initialFocus: 1,\n semantic: 'neutral',\n testId: 'dialog-story',\n};\n\n/**\n * Basic Dialog supports these additional props <br><br>\n * `heading?: React.Node` <br>\n * `body?: React.Node` <br>\n * `confirmText?: string` <br>\n * `abortText?: string` <br>\n * `handleConfirm?: (event: SyntheticEvent<>) => mixed` <br>\n * `handleAbort?: (event: SyntheticEvent<>) => mixed`\n */\nexport const BasicDialogStory = (args: DialogProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Basic Dialog</Button>\n <BasicDialog\n {...args}\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n handleAbort={() => setIsOpen(false)}\n handleConfirm={() => setIsOpen(false)}\n />\n </div>\n );\n};\n\nBasicDialogStory.args = {\n semantic: 'danger',\n heading: 'Dialog Title',\n body: 'A basic dialog supports text props to prepare content. You don\\'t need to import semantic components to prepare the desired layout.',\n abortText: 'Close',\n confirmText: 'Confirm',\n testId: 'basic-dialog-story',\n};\nDialogStory.storyName = 'Dialog';\nBasicDialogStory.storyName = 'Basic Dialog';\n"
840
840
  },
841
841
  "css": {
842
842
  "path": "Dialog.module.css",
@@ -1585,11 +1585,11 @@
1585
1585
  "files": {
1586
1586
  "main": {
1587
1587
  "path": "Modal.d.ts",
1588
- "content": "import * as React from 'react';\nimport type { UseTransitionStylesProps } from '@floating-ui/react';\ntype ClassNames = Readonly<{\n container?: string;\n content?: string;\n backdrop?: string;\n}>;\ntype FooterClassNames = Readonly<{\n wrapper?: string;\n actions?: string;\n}>;\nexport interface ModalProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n isOpen?: boolean;\n onClose?: ((arg1: React.SyntheticEvent<HTMLElement>) => unknown) | null | undefined;\n hideBackdrop?: boolean;\n tapOutsideToClose?: boolean;\n allowBackgroundInteraction?: boolean;\n initialFocus?: number;\n customAnimation?: UseTransitionStylesProps;\n testId?: string;\n}\nexport type ModalSize = 'small' | 'medium' | 'large';\nexport interface BaseModalProps extends Omit<ModalProps, 'size'> {\n size?: ModalSize;\n}\nexport interface ModalHeaderProps {\n children?: React.ReactNode;\n hideCloseBtn?: boolean;\n onCloseButtonClick?: React.MouseEventHandler<HTMLButtonElement>;\n className?: string;\n testId?: string;\n}\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n classNames?: FooterClassNames;\n testId?: string;\n}\nexport interface ModalBodyProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport declare const ModalHeader: ({ children, hideCloseBtn, onCloseButtonClick, className, testId, }: ModalHeaderProps) => React.JSX.Element;\nexport declare const ModalBody: ({ children, className, testId }: ModalBodyProps) => React.JSX.Element;\nexport declare const ModalFooter: ({ children, classNames, testId, }: ModalFooterProps) => React.JSX.Element;\nexport declare const Modal: ({ classNames, children, isOpen, onClose, hideBackdrop, tapOutsideToClose, initialFocus, customAnimation, allowBackgroundInteraction, testId, size, }: BaseModalProps) => React.ReactPortal | null;\nexport declare const FullScreenModal: ({ classNames, testId, ...props }: ModalProps) => React.JSX.Element;\nexport {};\n//# sourceMappingURL=Modal.d.ts.map"
1588
+ "content": "import * as React from 'react';\nimport type { UseTransitionStylesProps } from '@floating-ui/react';\ntype ClassNames = Readonly<{\n container?: string;\n content?: string;\n backdrop?: string;\n}>;\ntype FooterClassNames = Readonly<{\n wrapper?: string;\n actions?: string;\n}>;\nexport interface ModalProps {\n classNames?: ClassNames;\n children?: React.ReactNode;\n isOpen?: boolean;\n onClose?: ((arg1: React.SyntheticEvent<HTMLElement>) => unknown) | null | undefined;\n hideBackdrop?: boolean;\n tapOutsideToClose?: boolean;\n allowBackgroundInteraction?: boolean;\n initialFocus?: number;\n customAnimation?: UseTransitionStylesProps;\n testId?: string;\n}\nexport type ModalSize = 'small' | 'medium' | 'large';\nexport type OverlayType = 'Modal' | 'Dialog' | 'Panel';\nexport type OverlaySize = 'small' | 'medium' | 'large' | 'fullscreen';\nexport type OverlayAnchor = 'left' | 'right';\nexport interface OverlayEventDetail {\n /** Stable identifier to correlate mount/unmount pairs */\n id: string;\n overlayType: OverlayType;\n size?: OverlaySize;\n anchor?: OverlayAnchor;\n /** Whether the overlay renders a visible backdrop */\n hasBackdrop: boolean;\n tapOutsideToClose: boolean;\n allowBackgroundInteraction: boolean;\n /** Dialog semantic (neutral, success, warning, danger, information) */\n semantic?: string;\n testId?: string;\n}\nexport declare const OVERLAY_MOUNT_EVENT: \"ds:overlay:mount\";\nexport declare const OVERLAY_UNMOUNT_EVENT: \"ds:overlay:unmount\";\nexport type OverlayMountEvent = CustomEvent<OverlayEventDetail>;\nexport type OverlayUnmountEvent = CustomEvent<OverlayEventDetail>;\ndeclare global {\n interface WindowEventMap {\n 'ds:overlay:mount': OverlayMountEvent;\n 'ds:overlay:unmount': OverlayUnmountEvent;\n }\n}\nexport interface BaseModalProps extends Omit<ModalProps, 'size'> {\n size?: ModalSize;\n /** @internal Used by Panel/Dialog to identify overlay type in lifecycle events */\n overlayType?: OverlayType;\n /** @internal Used by Panel/Dialog to report size in lifecycle events */\n overlaySize?: OverlaySize;\n /** @internal Used by Panel to report anchor in lifecycle events */\n overlayAnchor?: OverlayAnchor;\n /** @internal Used by Dialog to report semantic variant in lifecycle events */\n overlaySemantic?: string;\n}\nexport interface ModalHeaderProps {\n children?: React.ReactNode;\n hideCloseBtn?: boolean;\n onCloseButtonClick?: React.MouseEventHandler<HTMLButtonElement>;\n className?: string;\n testId?: string;\n}\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n classNames?: FooterClassNames;\n testId?: string;\n}\nexport interface ModalBodyProps {\n children?: React.ReactNode;\n className?: string;\n testId?: string;\n}\nexport declare const ModalHeader: ({ children, hideCloseBtn, onCloseButtonClick, className, testId, }: ModalHeaderProps) => React.JSX.Element;\nexport declare const ModalBody: ({ children, className, testId }: ModalBodyProps) => React.JSX.Element;\nexport declare const ModalFooter: ({ children, classNames, testId, }: ModalFooterProps) => React.JSX.Element;\nexport declare const Modal: ({ classNames, children, isOpen, onClose, hideBackdrop, tapOutsideToClose, initialFocus, customAnimation, allowBackgroundInteraction, testId, size, overlayType, overlaySize, overlayAnchor, overlaySemantic, }: BaseModalProps) => React.ReactPortal | null;\nexport declare const FullScreenModal: ({ classNames, testId, ...props }: ModalProps) => React.JSX.Element;\nexport {};\n//# sourceMappingURL=Modal.d.ts.map"
1589
1589
  },
1590
1590
  "story": {
1591
1591
  "path": "Modal.stories.tsx",
1592
- "content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport {SimpleDropdown} from 'src/components/Dropdown';\nimport {Input} from 'src/components/Input';\nimport type {MenuOption} from 'src/components/Menu';\nimport type {ModalProps} from 'src/components/Modal/Modal';\nimport {\n Modal,\n ModalBody,\n ModalFooter,\n ModalHeader,\n} from 'src/components/Modal/Modal';\nimport {SubTitleLarge} from 'src/components/Text';\nimport {Textarea} from 'src/components/Textarea';\nimport {Tooltip} from 'src/components/Tooltip';\n\n\nconst options: MenuOption[] = [\n {\n key: '1',\n label: 'Option one',\n iconLeft: 'coffee',\n },\n {key: '2', label: 'Option two', iconLeft: 'user'},\n {\n key: '4',\n label:\n 'Option three is a very long option that would truncate and keep going to make it even longer than before. You can hover over the label to see the full text. ShowLabelTooltip maxLines is used to define the number of lines to show in the tooltip.',\n iconLeft: 'face-party',\n },\n {\n key: '5',\n label: 'Option five(disabled)',\n disabled: true,\n iconLeft: 'flag',\n },\n];\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Modal',\n argTypes: {\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n size: {\n description: `\nModal supports only three size variants namely small, medium and large. \\`small\\` < \\`medium\\` < \\`large\\`.\nYou can always override the sizing by a className. The default value is currently not set to support backward compatibility\n `,\n options: ['small', 'medium', 'large'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: ''},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n customAnimation: {\n description: `\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n \\`customAnimation: UseTransitionStylesProps\\` prop for\n all your custom animation needs.\n It defines the following properties: \\n\\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\\n\\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed. This\nis the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Modal component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Modal, ModalBody, ModalHeader, ModalFooter } from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\\`\\`\\`\n**Modal** component provides the foundational base for creating elements which blocks interaction with the rest of the application.\nIt is used as base for Dialog and Panel components. A **Modal** component can be used in cases where you want to have a custom implementation.\nModal component renders its children on top of a backdrop spanning across the whole page. The backdrop in turn also blurs the background.\nSome features of the Modal components are listed below:\n\n\\`Modal implements Focus trapping where in the focus is trapped and rotated inside a modal element only.\\`\n\n\\`When the Modal is presented, page scrolling is disabled \\`\n\n\\`Manages stacking \\`\n\nModal is attached on the \\`body\\` using **React Portal**.\n\nSemantically a \\`Modal\\` component should be composed from \\`ModalHeader\\`, \\`ModalBody\\`, and \\`ModalFooter\\` components,\nthese are nothing but layout components which defines appropriate spacing for the children living in them.\n\\`ModalHeader\\` adds a **close icon** by default and provides a callback on click. You can pass a **prop to show/hide the close button** as well.\n\n**Styling: **\n\n\\`Modal\\` accepts a \\`classNames\\` object. You can style the modal(if required) using the **content className**. Most of the use\ncases of Modal sizing can be handled by \\`size\\` prop of Modal which accepts \\`small\\` \\`medium\\` \\`large\\` as value.\n\nIf you want to assign custom props the parent should set those props of the\nModal using the content className.\n\nEach of these components also exposes a className\n\n**Usage: **\n\n\\`\\`\\`jsx\n<Modal\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n classNames={{content: css.modalContent}}\n>\n <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n <SubTitleLarge>\n The quick brown fox jumps over the lazy dog is an English-language pangram—a sentence that contain\n </SubTitleLarge>\n </ModalHeader>\n <ModalBody>\n <BodyLarge color=\"secondary\">\n \"The quick brown fox jumps over the lazy dog\" is an English-language pangram—a sentence that contains all the letters of the alphabet.\n The phrase is commonly used for touch-typing practice, testing typewriters and computer keyboards, displaying examples of fonts,\n and other applications involving text where the use of all letters in the alphabet is desired.\n </BodyLarge>\n </ModalBody>\n <ModalFooter>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>Secondary Button</Button>\n <Button type=\"primary\" onClick={() => setIsOpen(false)}>Primary Button</Button>\n </ModalFooter>\n</Modal>\n\\`\\`\\`\n\\`\\`\\`css\n// You can style the modal(if required) using the **content className**. Most of the use\n// cases of Modal sizing can be handled by size prop of Modal which accepts small, medium and large as value.\n.modalContent {\n max-height: size720;\n}\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Modal/Modal',\n },\n },\n};\n\nexport const ModalStory = (args: ModalProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <>\n <Tooltip title=\"Open\">\n <Button onClick={() => setIsOpen(!isOpen)}>Open Modal</Button>\n </Tooltip>\n <Modal {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n <SubTitleLarge>Modal Title</SubTitleLarge>\n </ModalHeader>\n <ModalBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </ModalBody>\n <ModalFooter>\n <Tooltip title=\"Some text\" elevation=\"modal\">\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Cancel\n </Button>\n </Tooltip>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Action\n </Button>\n </ModalFooter>\n </Modal>\n </>\n );\n};\n\nModalStory.args = {\n hideBackdrop: false,\n tapOutsideToClose: true,\n initialFocus: 1,\n size: 'medium',\n testId: 'modal-story',\n};\n\nexport const ModalWithOverflowBodyStory = (args: ModalProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <>\n <Tooltip title=\"Open\">\n <Button onClick={() => setIsOpen(!isOpen)}>Open Modal</Button>\n </Tooltip>\n <Modal {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n <SubTitleLarge>Modal Title</SubTitleLarge>\n </ModalHeader>\n <ModalBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n showLabelTooltip={{maxLines: 6}}\n options={options}\n />\n </ModalBody>\n </Modal>\n </>\n );\n};\n\nModalWithOverflowBodyStory.args = {\n hideBackdrop: false,\n tapOutsideToClose: true,\n initialFocus: 1,\n size: 'medium',\n testId: 'modal-overflow-body-story',\n};\n\n// export const _FullScreenModal = (args: ModalProps): React.Node => {\n// const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n// React.useEffect(() => {\n// setIsOpen(args.isOpen);\n// }, [args.isOpen]);\n\n// return (\n// <div className={css.container}>\n// <Tooltip title=\"Open\">\n// <Button onClick={() => setIsOpen(!isOpen)}>Open Modal</Button>\n// </Tooltip>\n// <FullScreenModal\n// {...args}\n// isOpen={isOpen}\n// onClose={() => setIsOpen(false)}\n// >\n// <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n// <SubTitleLarge>Modal Title</SubTitleLarge>\n// </ModalHeader>\n// <ModalBody>\n// <Input\n// type=\"email\"\n// label=\"Email Address\"\n// placeholder=\"Enter your email address\"\n// />\n// <br />\n// <SimpleDropdown\n// label=\"Issue Type\"\n// placeholder=\"Select an issue type\"\n// options={[\n// {\n// iconLeft: 'bug',\n// iconLeftType: 'duotone',\n// key: '1',\n// label: 'Production Issue',\n// },\n// {\n// iconLeft: 'bug-slash',\n// iconLeftType: 'duotone',\n// key: '2',\n// label: 'Dev Issue',\n// },\n// {\n// iconLeft: 'ban-bug',\n// iconLeftType: 'duotone',\n// key: '4',\n// label: 'Product Issue',\n// },\n// ]}\n// />\n// <br />\n// <Textarea\n// label=\"Description\"\n// placeholder=\"Enter the issue description\"\n// />\n// </ModalBody>\n// <ModalFooter>\n// <Tooltip title=\"Some text\" elevation=\"modal\">\n// <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n// Cancel\n// </Button>\n// </Tooltip>\n// <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n// Action\n// </Button>\n// </ModalFooter>\n// </FullScreenModal>\n// </div>\n// );\n// };\n\n// _FullScreenModal.args = {\n// hideBackdrop: false,\n// tapOutsideToClose: true,\n// initialFocus: 1,\n// size: 'medium',\n// };\nModalStory.storyName = 'Modal';\nModalWithOverflowBodyStory.storyName = 'Modal With Overflow Body';\n"
1592
+ "content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport {SimpleDropdown} from 'src/components/Dropdown';\nimport {Input} from 'src/components/Input';\nimport type {MenuOption} from 'src/components/Menu';\nimport type {ModalProps} from 'src/components/Modal/Modal';\nimport {\n Modal,\n ModalBody,\n ModalFooter,\n ModalHeader,\n} from 'src/components/Modal/Modal';\nimport {SubTitleLarge} from 'src/components/Text';\nimport {Textarea} from 'src/components/Textarea';\nimport {Tooltip} from 'src/components/Tooltip';\n\n\nconst options: MenuOption[] = [\n {\n key: '1',\n label: 'Option one',\n iconLeft: 'coffee',\n },\n {key: '2', label: 'Option two', iconLeft: 'user'},\n {\n key: '4',\n label:\n 'Option three is a very long option that would truncate and keep going to make it even longer than before. You can hover over the label to see the full text. ShowLabelTooltip maxLines is used to define the number of lines to show in the tooltip.',\n iconLeft: 'face-party',\n },\n {\n key: '5',\n label: 'Option five(disabled)',\n disabled: true,\n iconLeft: 'flag',\n },\n];\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Modal',\n argTypes: {\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n size: {\n description: `\nModal supports only three size variants namely small, medium and large. \\`small\\` < \\`medium\\` < \\`large\\`.\nYou can always override the sizing by a className. The default value is currently not set to support backward compatibility\n `,\n options: ['small', 'medium', 'large'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: ''},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n customAnimation: {\n description: `\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n \\`customAnimation: UseTransitionStylesProps\\` prop for\n all your custom animation needs.\n It defines the following properties: \\n\\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\\n\\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed. This\nis the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Modal component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Modal, ModalBody, ModalHeader, ModalFooter } from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\\`\\`\\`\n**Modal** component provides the foundational base for creating elements which blocks interaction with the rest of the application.\nIt is used as base for Dialog and Panel components. A **Modal** component can be used in cases where you want to have a custom implementation.\nModal component renders its children on top of a backdrop spanning across the whole page. The backdrop in turn also blurs the background.\nSome features of the Modal components are listed below:\n\n\\`Modal implements Focus trapping where in the focus is trapped and rotated inside a modal element only.\\`\n\n\\`When the Modal is presented, page scrolling is disabled \\`\n\n\\`Manages stacking \\`\n\nModal is attached on the \\`body\\` using **React Portal**.\n\nSemantically a \\`Modal\\` component should be composed from \\`ModalHeader\\`, \\`ModalBody\\`, and \\`ModalFooter\\` components,\nthese are nothing but layout components which defines appropriate spacing for the children living in them.\n\\`ModalHeader\\` adds a **close icon** by default and provides a callback on click. You can pass a **prop to show/hide the close button** as well.\n\n**Styling: **\n\n\\`Modal\\` accepts a \\`classNames\\` object. You can style the modal(if required) using the **content className**. Most of the use\ncases of Modal sizing can be handled by \\`size\\` prop of Modal which accepts \\`small\\` \\`medium\\` \\`large\\` as value.\n\nIf you want to assign custom props the parent should set those props of the\nModal using the content className.\n\nEach of these components also exposes a className\n\n**Usage: **\n\n\\`\\`\\`jsx\n<Modal\n isOpen={isOpen}\n onClose={() => setIsOpen(false)}\n classNames={{content: css.modalContent}}\n>\n <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n <SubTitleLarge>\n The quick brown fox jumps over the lazy dog is an English-language pangram—a sentence that contain\n </SubTitleLarge>\n </ModalHeader>\n <ModalBody>\n <BodyLarge color=\"secondary\">\n \"The quick brown fox jumps over the lazy dog\" is an English-language pangram—a sentence that contains all the letters of the alphabet.\n The phrase is commonly used for touch-typing practice, testing typewriters and computer keyboards, displaying examples of fonts,\n and other applications involving text where the use of all letters in the alphabet is desired.\n </BodyLarge>\n </ModalBody>\n <ModalFooter>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>Secondary Button</Button>\n <Button type=\"primary\" onClick={() => setIsOpen(false)}>Primary Button</Button>\n </ModalFooter>\n</Modal>\n\\`\\`\\`\n\\`\\`\\`css\n// You can style the modal(if required) using the **content className**. Most of the use\n// cases of Modal sizing can be handled by size prop of Modal which accepts small, medium and large as value.\n.modalContent {\n max-height: size720;\n}\n\\`\\`\\`\n\n---\n\n### Overlay Lifecycle Events\n\n\\`Modal\\`, \\`Dialog\\`, and \\`Panel\\` all emit **strongly-typed window events** when they mount and unmount. Since Dialog and Panel internally use Modal,\nthe event system is centralized — every overlay that opens or closes dispatches a pair of events on \\`window\\`.\n\n**Event names (exported constants):**\n\n| Constant | Value |\n|---|---|\n| \\`OVERLAY_MOUNT_EVENT\\` | \\`'ds:overlay:mount'\\` |\n| \\`OVERLAY_UNMOUNT_EVENT\\` | \\`'ds:overlay:unmount'\\` |\n\n**Event payload (\\`OverlayEventDetail\\`):**\n\n| Field | Type | Description |\n|---|---|---|\n| \\`id\\` | \\`string\\` | Stable UUID per overlay instance — use to correlate mount/unmount pairs |\n| \\`overlayType\\` | \\`'Modal' \\\\| 'Dialog' \\\\| 'Panel'\\` | Which component emitted the event |\n| \\`size\\` | \\`'small' \\\\| 'medium' \\\\| 'large' \\\\| 'fullscreen'\\` | Size variant of the overlay |\n| \\`anchor\\` | \\`'left' \\\\| 'right'\\` | Anchor position (Panel only) |\n| \\`hasBackdrop\\` | \\`boolean\\` | Whether the overlay renders a visible backdrop |\n| \\`tapOutsideToClose\\` | \\`boolean\\` | Whether clicking the backdrop dismisses the overlay |\n| \\`allowBackgroundInteraction\\` | \\`boolean\\` | Whether the background remains interactive |\n| \\`semantic\\` | \\`string\\` | Dialog semantic variant — \\`neutral\\`, \\`success\\`, \\`warning\\`, \\`danger\\`, \\`information\\` |\n| \\`testId\\` | \\`string\\` | The \\`testId\\` prop passed to the component |\n\n**Import:**\n\n\\`\\`\\`ts\nimport {\n OVERLAY_MOUNT_EVENT,\n OVERLAY_UNMOUNT_EVENT,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\n// Types (if needed)\nimport type {\n OverlayEventDetail,\n OverlayMountEvent,\n OverlayUnmountEvent,\n OverlayType,\n OverlaySize,\n OverlayAnchor,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\\`\\`\\`\n\n**Basic usage — listen for mount/unmount:**\n\n\\`\\`\\`ts\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n // e is fully typed as CustomEvent<OverlayEventDetail>\n console.log('Opened:', e.detail.overlayType, e.detail.size);\n});\n\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n console.log('Closed:', e.detail.overlayType, e.detail.id);\n});\n\\`\\`\\`\n\n**Track all open overlays:**\n\n\\`\\`\\`ts\nconst openOverlays = new Map<string, OverlayEventDetail>();\n\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n openOverlays.set(e.detail.id, e.detail);\n});\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n openOverlays.delete(e.detail.id);\n});\n\\`\\`\\`\n\n**React hook pattern — \\`useOverlayLifecycle\\`:**\n\n\\`\\`\\`tsx\nimport { useEffect } from 'react';\nimport {\n OVERLAY_MOUNT_EVENT,\n OVERLAY_UNMOUNT_EVENT,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\nimport type { OverlayEventDetail } from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\nfunction useOverlayLifecycle(\n onMount?: (detail: OverlayEventDetail) => void,\n onUnmount?: (detail: OverlayEventDetail) => void,\n) {\n useEffect(() => {\n const handleMount = (e: CustomEvent<OverlayEventDetail>) => onMount?.(e.detail);\n const handleUnmount = (e: CustomEvent<OverlayEventDetail>) => onUnmount?.(e.detail);\n window.addEventListener(OVERLAY_MOUNT_EVENT, handleMount);\n window.addEventListener(OVERLAY_UNMOUNT_EVENT, handleUnmount);\n return () => {\n window.removeEventListener(OVERLAY_MOUNT_EVENT, handleMount);\n window.removeEventListener(OVERLAY_UNMOUNT_EVENT, handleUnmount);\n };\n }, [onMount, onUnmount]);\n}\n\\`\\`\\`\n\n**Correlating mount/unmount with \\`id\\`:**\n\nEach overlay instance gets a stable UUID. The same \\`id\\` appears in both the mount and unmount events,\nso you can measure how long an overlay stayed open:\n\n\\`\\`\\`ts\nconst timestamps = new Map<string, number>();\n\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n timestamps.set(e.detail.id, Date.now());\n});\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n const opened = timestamps.get(e.detail.id);\n if (opened) {\n const duration = Date.now() - opened;\n analytics.track('overlay_closed', { ...e.detail, durationMs: duration });\n timestamps.delete(e.detail.id);\n }\n});\n\\`\\`\\`\n\n**Example payloads by component:**\n\nModal (medium):\n\\`\\`\\`json\n{ \"id\": \"a1b2c3\", \"overlayType\": \"Modal\", \"size\": \"medium\", \"hasBackdrop\": true,\n \"tapOutsideToClose\": true, \"allowBackgroundInteraction\": false }\n\\`\\`\\`\n\nPanel (right, large):\n\\`\\`\\`json\n{ \"id\": \"d4e5f6\", \"overlayType\": \"Panel\", \"size\": \"large\", \"anchor\": \"right\",\n \"hasBackdrop\": false, \"tapOutsideToClose\": true, \"allowBackgroundInteraction\": false }\n\\`\\`\\`\n\nDialog (danger):\n\\`\\`\\`json\n{ \"id\": \"g7h8i9\", \"overlayType\": \"Dialog\", \"hasBackdrop\": true,\n \"tapOutsideToClose\": false, \"allowBackgroundInteraction\": false, \"semantic\": \"danger\" }\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Modal/Modal',\n },\n },\n};\n\nexport const ModalStory = (args: ModalProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <>\n <Tooltip title=\"Open\">\n <Button onClick={() => setIsOpen(!isOpen)}>Open Modal</Button>\n </Tooltip>\n <Modal {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n <SubTitleLarge>Modal Title</SubTitleLarge>\n </ModalHeader>\n <ModalBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </ModalBody>\n <ModalFooter>\n <Tooltip title=\"Some text\" elevation=\"modal\">\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Cancel\n </Button>\n </Tooltip>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Action\n </Button>\n </ModalFooter>\n </Modal>\n </>\n );\n};\n\nModalStory.args = {\n hideBackdrop: false,\n tapOutsideToClose: true,\n initialFocus: 1,\n size: 'medium',\n testId: 'modal-story',\n};\n\nexport const ModalWithOverflowBodyStory = (args: ModalProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <>\n <Tooltip title=\"Open\">\n <Button onClick={() => setIsOpen(!isOpen)}>Open Modal</Button>\n </Tooltip>\n <Modal {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n <SubTitleLarge>Modal Title</SubTitleLarge>\n </ModalHeader>\n <ModalBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n showLabelTooltip={{maxLines: 6}}\n options={options}\n />\n </ModalBody>\n </Modal>\n </>\n );\n};\n\nModalWithOverflowBodyStory.args = {\n hideBackdrop: false,\n tapOutsideToClose: true,\n initialFocus: 1,\n size: 'medium',\n testId: 'modal-overflow-body-story',\n};\n\n// export const _FullScreenModal = (args: ModalProps): React.Node => {\n// const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n// React.useEffect(() => {\n// setIsOpen(args.isOpen);\n// }, [args.isOpen]);\n\n// return (\n// <div className={css.container}>\n// <Tooltip title=\"Open\">\n// <Button onClick={() => setIsOpen(!isOpen)}>Open Modal</Button>\n// </Tooltip>\n// <FullScreenModal\n// {...args}\n// isOpen={isOpen}\n// onClose={() => setIsOpen(false)}\n// >\n// <ModalHeader onCloseButtonClick={() => setIsOpen(false)}>\n// <SubTitleLarge>Modal Title</SubTitleLarge>\n// </ModalHeader>\n// <ModalBody>\n// <Input\n// type=\"email\"\n// label=\"Email Address\"\n// placeholder=\"Enter your email address\"\n// />\n// <br />\n// <SimpleDropdown\n// label=\"Issue Type\"\n// placeholder=\"Select an issue type\"\n// options={[\n// {\n// iconLeft: 'bug',\n// iconLeftType: 'duotone',\n// key: '1',\n// label: 'Production Issue',\n// },\n// {\n// iconLeft: 'bug-slash',\n// iconLeftType: 'duotone',\n// key: '2',\n// label: 'Dev Issue',\n// },\n// {\n// iconLeft: 'ban-bug',\n// iconLeftType: 'duotone',\n// key: '4',\n// label: 'Product Issue',\n// },\n// ]}\n// />\n// <br />\n// <Textarea\n// label=\"Description\"\n// placeholder=\"Enter the issue description\"\n// />\n// </ModalBody>\n// <ModalFooter>\n// <Tooltip title=\"Some text\" elevation=\"modal\">\n// <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n// Cancel\n// </Button>\n// </Tooltip>\n// <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n// Action\n// </Button>\n// </ModalFooter>\n// </FullScreenModal>\n// </div>\n// );\n// };\n\n// _FullScreenModal.args = {\n// hideBackdrop: false,\n// tapOutsideToClose: true,\n// initialFocus: 1,\n// size: 'medium',\n// };\nModalStory.storyName = 'Modal';\nModalWithOverflowBodyStory.storyName = 'Modal With Overflow Body';\n"
1593
1593
  },
1594
1594
  "css": {
1595
1595
  "path": "Modal.module.css",
@@ -1597,7 +1597,7 @@
1597
1597
  },
1598
1598
  "index": {
1599
1599
  "path": "index.d.ts",
1600
- "content": "export type { BaseModalProps, ModalBodyProps, ModalFooterProps, ModalHeaderProps, ModalProps, } from '../../components/Modal/Modal';\nexport { FullScreenModal, Modal, ModalBody, ModalFooter, ModalHeader, } from '../../components/Modal/Modal';\n//# sourceMappingURL=index.d.ts.map"
1600
+ "content": "export type { BaseModalProps, ModalBodyProps, ModalFooterProps, ModalHeaderProps, ModalProps, OverlayAnchor, OverlayEventDetail, OverlayMountEvent, OverlaySize, OverlayType, OverlayUnmountEvent, } from '../../components/Modal/Modal';\nexport { FullScreenModal, Modal, ModalBody, ModalFooter, ModalHeader, OVERLAY_MOUNT_EVENT, OVERLAY_UNMOUNT_EVENT, } from '../../components/Modal/Modal';\n//# sourceMappingURL=index.d.ts.map"
1601
1601
  },
1602
1602
  "additional": {}
1603
1603
  },
@@ -1751,7 +1751,7 @@
1751
1751
  },
1752
1752
  "story": {
1753
1753
  "path": "Panel.stories.tsx",
1754
- "content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport {\n Dialog,\n DialogBody,\n DialogFooter,\n DialogHeader,\n} from 'src/components/Dialog';\nimport {SimpleDropdown} from 'src/components/Dropdown';\nimport {Input} from 'src/components/Input';\nimport type {PanelProps} from 'src/components/Panel/Panel';\nimport {\n Panel,\n PanelBody,\n PanelFooter,\n PanelHeader,\n} from 'src/components/Panel/Panel';\nimport {BodyLarge, SubTitleLarge} from 'src/components/Text';\nimport {Textarea} from 'src/components/Textarea';\nimport {Tooltip} from 'src/components/Tooltip';\n\nimport css from 'src/components/Panel/Panel.stories.module.css';\n\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Panel',\n argTypes: {\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n anchor: {\n options: ['left', 'right'],\n description: 'Position of Panel',\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'left'},\n },\n },\n allowBackgroundInteraction: {\n description:\n 'if **true**, allows interaction with the background content. This would remove the backdrop layer for the panel and set tapOutsideToClose to false',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n size: {\n description:\n 'Panel supports only three size variants namely small, medium and large. `small` < `medium` < `large`',\n options: ['small', 'medium', 'large'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'medium'},\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n customAnimation: {\n description: `\n\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n\\`customAnimation: UseTransitionStylesProps\\` prop for\nall your custom animation needs.\nIt defines the following properties:\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed.\n\nThis is the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Panel component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Panel, PanelBody, PanelHeader, PanelFooter } from \"@spaced-out/ui-design-system/lib/components/Panel\";\n\\`\\`\\`\nDestinations in the app are accessible through Panels. Panels are **side sheets**, which are attached to the left or\nright edge of the screen and are surfaces with extra content. Panels can either be permanently on-screen or controlled by an **action**.\n\nPanel is a variation of a **<a href=\"../?path=/docs/components-modal--docs\">Modal</a>** with additional animation, position and size overrides.\n\nSemantically a Panel component should be composed from \\`PanelHeader\\`, \\`PanelBody\\`, and \\`PanelFooter\\` **components**, these are nothing but layout components which defines\nappropriate spacing for the children living in them. \\`PanelHeader\\` adds a close icon by default and provides a callback on click. You can pass a prop to\nshow/hide the close button as well.\nEach of these components also exposes a className\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Panel/Panel',\n },\n },\n};\n\nexport const NormalStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nNormalStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-normal-story',\n};\n\nexport const WithNestedDialogStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState<boolean>(args.isOpen || false);\n const [isOpen2, setIsOpen2] = React.useState(false);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen || false);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>\n Open Panel With Nested Dialog\n </Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title(First Elevation)</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n <Dialog\n initialFocus={1}\n onClose={() => setIsOpen2(false)}\n semantic=\"neutral\"\n isOpen={isOpen2}\n >\n <DialogHeader>\n <SubTitleLarge> Dialog Title</SubTitleLarge>\n </DialogHeader>\n <DialogBody>\n <BodyLarge color=\"secondary\">\n Dialogs should only be used occasionally because they are\n intended to be disruptive. Dialogs come in multiple variants.\n </BodyLarge>\n </DialogBody>\n <DialogFooter>\n <Button isFluid onClick={() => setIsOpen2(false)} type=\"tertiary\">\n Close\n </Button>\n <Button\n isFluid\n onClick={() => setIsOpen2(false)}\n type=\"secondary\"\n >\n Confirm\n </Button>\n </DialogFooter>\n </Dialog>\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen2(true)}>\n Open Nested Dialog\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithNestedDialogStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-with-nested-dialog-story',\n};\n\nexport const WithInteractiveBackgroundStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <div className={css.interactionContainer}>\n <Tooltip\n body=\"When the panel opens, the background content is interactive\"\n bodyMaxLines={2}\n placement=\"top\"\n title=\"I am interactive tooltip\"\n >\n <Button iconLeftName=\"face-sunglasses\" type=\"tertiary\">\n Hover Me after opening the panel\n </Button>\n </Tooltip>\n </div>\n\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithInteractiveBackgroundStory.args = {\n anchor: 'right',\n size: 'medium',\n initialFocus: 1,\n allowBackgroundInteraction: true,\n testId: 'panel-with-interactive-background-story',\n};\nNormalStory.storyName = 'Normal';\nWithNestedDialogStory.storyName = 'With Nested Dialog';\nWithInteractiveBackgroundStory.storyName = 'With Interactive Background';\n"
1754
+ "content": "import * as React from 'react';\n\nimport {Button} from 'src/components/Button';\nimport {\n Dialog,\n DialogBody,\n DialogFooter,\n DialogHeader,\n} from 'src/components/Dialog';\nimport {SimpleDropdown} from 'src/components/Dropdown';\nimport {Input} from 'src/components/Input';\nimport type {PanelProps} from 'src/components/Panel/Panel';\nimport {\n Panel,\n PanelBody,\n PanelFooter,\n PanelHeader,\n} from 'src/components/Panel/Panel';\nimport {BodyLarge, SubTitleLarge} from 'src/components/Text';\nimport {Textarea} from 'src/components/Textarea';\nimport {Tooltip} from 'src/components/Tooltip';\n\nimport css from 'src/components/Panel/Panel.stories.module.css';\n\n\nexport default {\n tags: ['autodocs'],\n title: 'Components/Panel',\n argTypes: {\n isOpen: {\n description: 'if **true**, the modal is presented',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n classNames: {\n description: 'External classnames to be applied',\n control: {\n type: 'object',\n },\n table: {\n type: {\n summary: '{container?: string, content?: string, backdrop?: string}',\n },\n },\n },\n tapOutsideToClose: {\n description: 'if **true**, closes the modal on tap of backdrop',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n anchor: {\n options: ['left', 'right'],\n description: 'Position of Panel',\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'left'},\n },\n },\n allowBackgroundInteraction: {\n description:\n 'if **true**, allows interaction with the background content. This would remove the backdrop layer for the panel and set tapOutsideToClose to false',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'false'},\n },\n },\n size: {\n description:\n 'Panel supports only three size variants namely small, medium and large. `small` < `medium` < `large`',\n options: ['small', 'medium', 'large'],\n control: {\n type: 'select',\n },\n table: {\n type: {summary: 'enum'},\n defaultValue: {summary: 'medium'},\n },\n },\n children: {\n description: 'The children to rendered inside the Modal window',\n table: {\n type: {summary: 'React.Node'},\n },\n },\n onClose: {\n description: '**onClose** handler is triggered on backdrop click',\n action: 'clicked',\n table: {\n type: {summary: '(SyntheticEvent<HTMLElement>) => mixed'},\n },\n },\n customAnimation: {\n description: `\n\\`<Modal>\\` and its derivatives(\\`<Dialog>\\`, \\`<Panel>\\`) support\n\\`customAnimation: UseTransitionStylesProps\\` prop for\nall your custom animation needs.\nIt defines the following properties:\n\n- \\`duration\\` (optional): Specifies the duration of the animation in milliseconds.\nIt can be a single number to set the duration for both opening and closing animations,\nor an object with separate open and close properties to specify different durations\nfor opening and closing animations.\n- \\`initial\\` (optional): Represents the initial CSS styles for the modal component when\nit is first mounted. This property allows you to define the initial appearance of the\nmodal before any animations occur.\n- \\`open\\` (optional): Defines the CSS styles that should be applied when the modal is fully\nopened. This property specifies the appearance of the modal when it transitions from the\ninitial state to the fully open state.\n- \\`close\\` (optional): Specifies the CSS styles for the modal when it is being closed. This\nproperty determines the appearance of the modal when it transitions from the fully open\nstate to the closed state.\n- \\`common\\` (optional): Represents the CSS styles that are common to all states of the modal\ncomponent. These styles will be applied throughout the entire lifecycle of the modal,\nregardless of whether it is in the initial, open, or close state. You can use this property\nto define shared styles that should be present in all states.\n\nThe modal component follows a predefined order of states as it transitions through\nits lifecycle. It starts in the \\`unmounted\\` state, then moves to the \\`initial\\` state when mounted.\nFrom there, it can transition to the \\`open\\` state when fully opened, and then to the \\`close\\` state\nwhen being closed. Finally, it returns to the \\`unmounted\\` state when it is no longer needed.\n\nThis is the transition order: \\`unmounted\\` -> \\`initial\\` -> \\`open\\` -> \\`close\\` -> \\`unmounted\\`\nBy specifying the appropriate values for the \\`duration\\`, \\`initial\\`, \\`open\\`, \\`close\\`, and \\`common\\` properties,\nyou can control the animation and styling of the modal at each stage of its lifecycle.\n `,\n control: {\n type: 'object',\n },\n table: {\n type: {summary: 'UseTransitionStylesProps'},\n },\n },\n hideBackdrop: {\n description:\n 'if **true**, dark backdrop is removed and transparent backdrop is applied on the DOM',\n control: {\n type: 'boolean',\n },\n table: {\n type: {summary: 'boolean'},\n defaultValue: {summary: 'true'},\n },\n },\n initialFocus: {\n description:\n 'Which element to initially focus. Can be a number (tabbable index as specified by the order)',\n control: {\n type: 'number',\n },\n table: {\n type: {summary: 'number'},\n defaultValue: {summary: '-1'},\n },\n },\n testId: {\n description: 'Test ID for the component',\n control: {\n type: 'text',\n },\n table: {\n type: {summary: 'string'},\n },\n },\n },\n\n parameters: {\n docs: {\n subtitle: 'Generates a Panel component',\n description: {\n component: `\n\\`\\`\\`js\nimport { Panel, PanelBody, PanelHeader, PanelFooter } from \"@spaced-out/ui-design-system/lib/components/Panel\";\n\\`\\`\\`\nDestinations in the app are accessible through Panels. Panels are **side sheets**, which are attached to the left or\nright edge of the screen and are surfaces with extra content. Panels can either be permanently on-screen or controlled by an **action**.\n\nPanel is a variation of a **<a href=\"../?path=/docs/components-modal--docs\">Modal</a>** with additional animation, position and size overrides.\n\nSemantically a Panel component should be composed from \\`PanelHeader\\`, \\`PanelBody\\`, and \\`PanelFooter\\` **components**, these are nothing but layout components which defines\nappropriate spacing for the children living in them. \\`PanelHeader\\` adds a close icon by default and provides a callback on click. You can pass a prop to\nshow/hide the close button as well.\nEach of these components also exposes a className\n\n---\n\n### Overlay Lifecycle Events\n\nPanel emits **strongly-typed window events** when it mounts and unmounts (see **<a href=\"../?path=/docs/components-modal--docs\">Modal docs</a>** for the full API reference, all event types, and advanced usage patterns).\n\nPanel-specific fields in the event payload:\n\n| Field | Value |\n|---|---|\n| \\`overlayType\\` | \\`'Panel'\\` |\n| \\`size\\` | \\`'small' \\\\| 'medium' \\\\| 'large'\\` (from the \\`size\\` prop) |\n| \\`anchor\\` | \\`'left' \\\\| 'right'\\` (from the \\`anchor\\` prop) |\n| \\`hasBackdrop\\` | Derived from \\`hideBackdrop\\` (default \\`false\\` for Panel) |\n| \\`allowBackgroundInteraction\\` | From the \\`allowBackgroundInteraction\\` prop |\n\n**Listening for Panel events:**\n\n\\`\\`\\`ts\nimport {\n OVERLAY_MOUNT_EVENT,\n OVERLAY_UNMOUNT_EVENT,\n} from \"@spaced-out/ui-design-system/lib/components/Modal\";\n\nwindow.addEventListener(OVERLAY_MOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Panel') {\n console.log(\\\\\\`Panel opened: size=\\\\\\${e.detail.size}, anchor=\\\\\\${e.detail.anchor}\\\\\\`);\n }\n});\n\nwindow.addEventListener(OVERLAY_UNMOUNT_EVENT, (e) => {\n if (e.detail.overlayType === 'Panel') {\n console.log(\\\\\\`Panel closed: id=\\\\\\${e.detail.id}\\\\\\`);\n }\n});\n\\`\\`\\`\n\n**Example payload (Panel, right, medium):**\n\n\\`\\`\\`json\n{\n \"id\": \"d4e5f6\",\n \"overlayType\": \"Panel\",\n \"size\": \"medium\",\n \"anchor\": \"right\",\n \"hasBackdrop\": false,\n \"tapOutsideToClose\": true,\n \"allowBackgroundInteraction\": false,\n \"testId\": \"my-panel\"\n}\n\\`\\`\\`\n `,\n },\n },\n storySource: {\n componentPath: '/src/components/Panel/Panel',\n },\n },\n};\n\nexport const NormalStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nNormalStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-normal-story',\n};\n\nexport const WithNestedDialogStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState<boolean>(args.isOpen || false);\n const [isOpen2, setIsOpen2] = React.useState(false);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen || false);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>\n Open Panel With Nested Dialog\n </Button>\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title(First Elevation)</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n <Dialog\n initialFocus={1}\n onClose={() => setIsOpen2(false)}\n semantic=\"neutral\"\n isOpen={isOpen2}\n >\n <DialogHeader>\n <SubTitleLarge> Dialog Title</SubTitleLarge>\n </DialogHeader>\n <DialogBody>\n <BodyLarge color=\"secondary\">\n Dialogs should only be used occasionally because they are\n intended to be disruptive. Dialogs come in multiple variants.\n </BodyLarge>\n </DialogBody>\n <DialogFooter>\n <Button isFluid onClick={() => setIsOpen2(false)} type=\"tertiary\">\n Close\n </Button>\n <Button\n isFluid\n onClick={() => setIsOpen2(false)}\n type=\"secondary\"\n >\n Confirm\n </Button>\n </DialogFooter>\n </Dialog>\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen2(true)}>\n Open Nested Dialog\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithNestedDialogStory.args = {\n anchor: 'right',\n size: 'medium',\n tapOutsideToClose: true,\n initialFocus: 1,\n testId: 'panel-with-nested-dialog-story',\n};\n\nexport const WithInteractiveBackgroundStory = (args: PanelProps) => {\n const [isOpen, setIsOpen] = React.useState(args.isOpen);\n\n React.useEffect(() => {\n setIsOpen(args.isOpen);\n }, [args.isOpen]);\n\n return (\n <div className={css.container}>\n <Button onClick={() => setIsOpen(!isOpen)}>Open Panel</Button>\n <div className={css.interactionContainer}>\n <Tooltip\n body=\"When the panel opens, the background content is interactive\"\n bodyMaxLines={2}\n placement=\"top\"\n title=\"I am interactive tooltip\"\n >\n <Button iconLeftName=\"face-sunglasses\" type=\"tertiary\">\n Hover Me after opening the panel\n </Button>\n </Tooltip>\n </div>\n\n <Panel {...args} isOpen={isOpen} onClose={() => setIsOpen(false)}>\n <PanelHeader onCloseButtonClick={() => setIsOpen(false)} size=\"medium\">\n <SubTitleLarge>Panel Title</SubTitleLarge>\n </PanelHeader>\n\n <PanelBody>\n <Input\n type=\"email\"\n label=\"Email Address\"\n placeholder=\"Enter your email address\"\n />\n <br />\n <SimpleDropdown\n label=\"Issue Type\"\n placeholder=\"Select an issue type\"\n options={[\n {\n iconLeft: 'bug',\n iconLeftType: 'duotone',\n key: '1',\n label: 'Production Issue',\n },\n {\n iconLeft: 'bug-slash',\n iconLeftType: 'duotone',\n key: '2',\n label: 'Dev Issue',\n },\n {\n iconLeft: 'ban-bug',\n iconLeftType: 'duotone',\n key: '4',\n label: 'Product Issue',\n },\n ]}\n />\n <br />\n <Textarea\n label=\"Description\"\n placeholder=\"Enter the issue description\"\n />\n </PanelBody>\n\n <PanelFooter>\n <Button type=\"tertiary\" onClick={() => setIsOpen(false)}>\n Close\n </Button>\n <Button type=\"secondary\" onClick={() => setIsOpen(false)}>\n Save\n </Button>\n </PanelFooter>\n </Panel>\n </div>\n );\n};\n\nWithInteractiveBackgroundStory.args = {\n anchor: 'right',\n size: 'medium',\n initialFocus: 1,\n allowBackgroundInteraction: true,\n testId: 'panel-with-interactive-background-story',\n};\nNormalStory.storyName = 'Normal';\nWithNestedDialogStory.storyName = 'With Nested Dialog';\nWithInteractiveBackgroundStory.storyName = 'With Interactive Background';\n"
1755
1755
  },
1756
1756
  "css": {
1757
1757
  "path": "Panel.module.css",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/genesis-mcp",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "MCP server for Genesis UI Design System - provides AI assistants with access to components, hooks, and design tokens",
5
5
  "type": "module",
6
6
  "main": "index.js",