{"version":3,"sources":["../src/modal/modal.tsx"],"sourcesContent":["import { forwardRef, useEffect, useRef } from \"react\";\nimport { clsx } from \"@postenbring/hedwig-css/typed-classname\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { Box } from \"../box/box\";\nimport { useMergeRefs } from \"../utils/utils\";\n\ninterface ModalHeaderProps extends React.HTMLAttributes<HTMLHeadingElement> {\n  /**\n   * Change the default rendered element for the one passed as a child, merging their props and behavior.\n   *\n   * @default false\n   */\n  asChild?: boolean;\n}\nexport const ModalHeader = forwardRef<HTMLHeadingElement, ModalHeaderProps>(\n  ({ asChild, className, ...rest }, ref) => {\n    const Component = asChild ? Slot : \"h1\";\n    return (\n      <Component\n        className={clsx(\"hds-modal__header\", className as undefined)}\n        ref={ref}\n        {...rest}\n      />\n    );\n  },\n);\nModalHeader.displayName = \"Modal.Header\";\n\ninterface ModalContentProps extends React.HTMLAttributes<HTMLDivElement> {\n  /**\n   * Change the default rendered element for the one passed as a child, merging their props and behavior.\n   *\n   * @default false\n   */\n  asChild?: boolean;\n}\nexport const ModalContent = forwardRef<HTMLDivElement, ModalContentProps>(\n  ({ asChild, className, ...rest }, ref) => {\n    const Component = asChild ? Slot : \"div\";\n    return (\n      <Component\n        className={clsx(\"hds-modal__content\", className as undefined)}\n        ref={ref}\n        {...rest}\n      />\n    );\n  },\n);\nModalContent.displayName = \"Modal.Content\";\n\ninterface ModalFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n  /**\n   * Change the default rendered element for the one passed as a child, merging their props and behavior.\n   *\n   * @default false\n   */\n  asChild?: boolean;\n}\nexport const ModalFooter = forwardRef<HTMLDivElement, ModalFooterProps>(\n  ({ asChild, className, ...rest }, ref) => {\n    const Component = asChild ? Slot : \"footer\";\n    return (\n      <Component\n        className={clsx(\"hds-modal__footer\", className as undefined)}\n        ref={ref}\n        {...rest}\n      />\n    );\n  },\n);\nModalFooter.displayName = \"Modal.Footer\";\n\nexport interface ModalProps extends React.HTMLAttributes<HTMLDialogElement> {\n  children: React.ReactNode;\n\n  /**\n   * Controls the open state of the modal\n   */\n  open?: boolean;\n\n  /**\n   * Whether to close when clicking on the backdrop.\n   */\n  closeOnBackdropClick?: boolean;\n}\n\n/**\n * A modal dialog is a window that forces the user to interact with it before they can return to other parts of the application.\n *\n * Uses the native [`dialog`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) element.\n *\n * @example\n * ```tsx\n *   const modalRef = useRef<HTMLDialogElement>(null);\n *   const onClose = () => modalRef.current?.close();\n *\n *   return (\n *     <>\n *       <Button onClick={() => modalRef.current?.showModal()}>Open Modal</Button>\n *       <Modal ref={modalRef}>\n *         <Modal.Header>Dialog header</Modal.Header>\n *         <Modal.Content>\n *           <p>\n *             Dialog header Dialog description - a description of what is about to happen and maybe\n *             something about the consequences.\n *           </p>\n *         </Modal.Content>\n *         <Modal.Footer>\n *           <HStack gap=\"16\" wrap>\n *             <Button onClick={onMainAction}>Main action</Button>\n *             <Button variant=\"secondary\" onClick={onClose}>\n *               Cancel\n *             </Button>\n *           </HStack>\n *         </Modal.Footer>\n *       </Modal>\n *     </>\n *   );\n * ```\n */\nexport const Modal = forwardRef<HTMLDialogElement, ModalProps>(\n  ({ children, className, open, closeOnBackdropClick, onClick, ...rest }, ref) => {\n    const modalRef = useRef<HTMLDialogElement>(null);\n    const mergedRef = useMergeRefs([modalRef, ref]);\n\n    // The X close button that comes from the `Box` component\n    function onCloseButtonClick() {\n      modalRef.current?.close();\n      return false;\n    }\n\n    // No scroll when modal is open\n    useScrollLock(modalRef, \"hds-modal-scroll-lock\");\n\n    // `open` prop\n    useEffect(() => {\n      if (modalRef.current && open !== undefined) {\n        if (open && !modalRef.current.open) {\n          modalRef.current.showModal();\n        } else if (!open && modalRef.current.open) {\n          modalRef.current.close();\n        }\n      }\n    }, [modalRef, open]);\n\n    function onDialogClick(e: React.MouseEvent<HTMLElement>) {\n      if (closeOnBackdropClick && e.target === modalRef.current) {\n        modalRef.current.close();\n      }\n      onClick?.(e as React.MouseEvent<HTMLDialogElement>);\n    }\n\n    return (\n      <Box\n        asChild\n        className={clsx(\"hds-modal\", className as undefined)}\n        closeable\n        onClick={onDialogClick}\n        onClose={onCloseButtonClick}\n        variant=\"white\"\n      >\n        <dialog ref={mergedRef} {...rest}>\n          {children}\n        </dialog>\n      </Box>\n    );\n  },\n) as ModalType;\nModal.displayName = \"Modal\";\n\ntype ModalType = ReturnType<typeof forwardRef<HTMLDialogElement, ModalProps>> & {\n  Header: typeof ModalHeader;\n  Content: typeof ModalContent;\n  Footer: typeof ModalFooter;\n};\n\nModal.Header = ModalHeader;\nModal.Content = ModalContent;\nModal.Footer = ModalFooter;\n\nfunction useScrollLock(modalRef: React.RefObject<HTMLDialogElement>, bodyClass: string) {\n  useEffect(() => {\n    if (!modalRef.current) return;\n    if (modalRef.current.open) document.body.classList.add(bodyClass);\n\n    const observer = new MutationObserver(() => {\n      if (modalRef.current?.open) document.body.classList.add(bodyClass);\n      else document.body.classList.remove(bodyClass);\n    });\n    observer.observe(modalRef.current, {\n      attributes: true,\n      attributeFilter: [\"open\"],\n    });\n    return () => {\n      observer.disconnect();\n      document.body.classList.remove(bodyClass);\n    };\n  }, [bodyClass, modalRef]);\n}\n"],"mappings":"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","names":["_a"]}