{"version":3,"file":"atoms.mjs","names":[],"sources":["../../../src/base-ui/Modal/atoms.tsx"],"sourcesContent":["'use client';\n\nimport { Dialog } from '@base-ui/react/dialog';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { cx } from 'antd-style';\nimport { X } from 'lucide-react';\nimport { AnimatePresence } from 'motion/react';\nimport type React from 'react';\nimport {\n  cloneElement,\n  createContext,\n  isValidElement,\n  use,\n  useCallback,\n  useEffect,\n  useMemo,\n  useState,\n} from 'react';\nimport { mergeRefs } from 'react-merge-refs';\n\nimport { useNativeButton } from '@/hooks/useNativeButton';\nimport { useMotionComponent } from '@/MotionProvider';\nimport { useAppElement } from '@/ThemeProvider';\n\nimport { backdropTransition, modalMotionConfig } from './constants';\nimport { styles } from './style';\n\nconst mergeStateClassName = <TState,>(\n  base: string,\n  className: string | ((state: TState) => string | undefined) | undefined,\n) => {\n  if (typeof className === 'function') return (state: TState) => cx(base, className(state));\n  return cx(base, className);\n};\n\n// --- Animation Contexts (granular to minimize re-renders) ---\n\n// State: open boolean, null = non-animated mode\nconst ModalOpenContext = createContext<boolean | null>(null);\n\n// Actions: stable callbacks, null = non-animated mode\ninterface ModalAnimationActions {\n  onExitComplete: () => void;\n}\nconst ModalActionsContext = createContext<ModalAnimationActions | null>(null);\n\nexport const useModalOpen = () => use(ModalOpenContext);\nexport const useModalActions = () => use(ModalActionsContext);\n\n// --- Root ---\nexport type ModalRootProps = Dialog.Root.Props & {\n  onExitComplete?: () => void;\n};\n\nconst AnimatedModalRoot = ({\n  open,\n  children,\n  onExitComplete: onExitCompleteProp,\n  ...rest\n}: Omit<ModalRootProps, 'open'> & { open: boolean }) => {\n  const [isPresent, setIsPresent] = useState(!!open);\n\n  useEffect(() => {\n    if (open) setIsPresent(true);\n  }, [open]);\n\n  const handleExitComplete = useCallback(() => {\n    setIsPresent(false);\n    onExitCompleteProp?.();\n  }, [onExitCompleteProp]);\n\n  const actions = useMemo(() => ({ onExitComplete: handleExitComplete }), [handleExitComplete]);\n\n  if (!isPresent) return null;\n\n  return (\n    <ModalOpenContext value={open}>\n      <ModalActionsContext value={actions}>\n        <Dialog.Root modal open {...rest}>\n          {children}\n        </Dialog.Root>\n      </ModalActionsContext>\n    </ModalOpenContext>\n  );\n};\n\nexport const ModalRoot = ({ open, onExitComplete, ...rest }: ModalRootProps) => {\n  if (open !== undefined) {\n    return <AnimatedModalRoot open={open} onExitComplete={onExitComplete} {...rest} />;\n  }\n  return <Dialog.Root modal {...rest} />;\n};\n\n// --- Portal ---\nexport type ModalPortalProps = React.ComponentProps<typeof Dialog.Portal> & {\n  container?: HTMLElement | null;\n};\nexport const ModalPortal = ({ container, ...rest }: ModalPortalProps) => {\n  const appElement = useAppElement();\n  return <Dialog.Portal container={container ?? appElement ?? undefined} {...rest} />;\n};\n\n// --- Viewport ---\nexport type ModalViewportProps = React.ComponentProps<typeof Dialog.Viewport>;\nexport const ModalViewport = ({ className, ...rest }: ModalViewportProps) => (\n  <Dialog.Viewport\n    {...rest}\n    className={mergeStateClassName(styles.viewport, className as any) as any}\n  />\n);\n\n// --- Backdrop ---\nexport type ModalBackdropProps = React.ComponentProps<typeof Dialog.Backdrop>;\nexport const ModalBackdrop = ({ className, style, ...rest }: ModalBackdropProps) => {\n  const open = useModalOpen();\n  const Motion = useMotionComponent();\n\n  if (open !== null) {\n    return (\n      <Dialog.Backdrop\n        {...rest}\n        className={cx(styles.backdrop, className as string)}\n        style={{ ...style, transition: 'none' }}\n        render={\n          <Motion.div\n            animate={{ opacity: open ? 1 : 0 }}\n            initial={{ opacity: 0 }}\n            transition={backdropTransition}\n          />\n        }\n      />\n    );\n  }\n\n  return (\n    <Dialog.Backdrop\n      {...rest}\n      className={mergeStateClassName(styles.backdrop, className as any) as any}\n      style={style}\n    />\n  );\n};\n\n// --- Popup ---\nexport type ModalPopupProps = React.ComponentProps<typeof Dialog.Popup> & {\n  motionProps?: Record<string, any>;\n  panelClassName?: string;\n  popupStyle?: React.CSSProperties;\n  width?: number | string;\n};\nexport const ModalPopup = ({\n  className,\n  children,\n  width,\n  style,\n  motionProps,\n  panelClassName,\n  popupStyle,\n  ...rest\n}: ModalPopupProps) => {\n  const open = useModalOpen();\n  const actions = useModalActions();\n  const Motion = useMotionComponent();\n\n  if (open !== null && actions) {\n    return (\n      <Dialog.Popup {...rest} className={cx(styles.popup, className as string)} style={popupStyle}>\n        <AnimatePresence onExitComplete={actions.onExitComplete}>\n          {open ? (\n            <Motion.div\n              {...modalMotionConfig}\n              {...motionProps}\n              className={cx(styles.popupInner, panelClassName)}\n              key=\"modal-popup-panel\"\n              style={{ maxWidth: width ?? undefined, transition: 'none', ...style }}\n            >\n              {children}\n            </Motion.div>\n          ) : null}\n        </AnimatePresence>\n      </Dialog.Popup>\n    );\n  }\n\n  return (\n    <Dialog.Popup\n      {...rest}\n      className={mergeStateClassName(styles.popup, className as any) as any}\n      style={popupStyle}\n    >\n      <div\n        className={cx(styles.popupInner, panelClassName)}\n        style={{ maxWidth: width ?? undefined, ...style }}\n      >\n        {children}\n      </div>\n    </Dialog.Popup>\n  );\n};\n\n// --- Header ---\nexport type ModalHeaderProps = React.HTMLAttributes<HTMLDivElement> & {\n  ref?: React.Ref<HTMLDivElement>;\n};\nexport const ModalHeader = ({ className, ...rest }: ModalHeaderProps) => (\n  <div {...rest} className={cx(styles.header, className)} />\n);\n\n// --- Title ---\nexport type ModalTitleProps = React.ComponentProps<typeof Dialog.Title>;\nexport const ModalTitle = ({ className, ...rest }: ModalTitleProps) => (\n  <Dialog.Title {...rest} className={mergeStateClassName(styles.title, className as any) as any} />\n);\n\n// --- Description ---\nexport type ModalDescriptionProps = React.ComponentProps<typeof Dialog.Description>;\nexport const ModalDescription: React.FC<ModalDescriptionProps> = Dialog.Description;\n\n// --- Content ---\nexport type ModalContentProps = React.HTMLAttributes<HTMLDivElement> & {\n  ref?: React.Ref<HTMLDivElement>;\n};\nexport const ModalContent = ({ className, ...rest }: ModalContentProps) => (\n  <div {...rest} className={cx(styles.content, className)} />\n);\n\n// --- Footer ---\nexport type ModalFooterProps = React.HTMLAttributes<HTMLDivElement> & {\n  ref?: React.Ref<HTMLDivElement>;\n};\nexport const ModalFooter = ({ className, ...rest }: ModalFooterProps) => (\n  <div {...rest} className={cx(styles.footer, className)} />\n);\n\n// --- Close ---\nexport type ModalCloseProps = React.ComponentProps<typeof Dialog.Close>;\nexport const ModalClose = ({ className, children, ...rest }: ModalCloseProps) => (\n  <Dialog.Close {...rest} className={mergeStateClassName(styles.close, className as any) as any}>\n    {children ?? <X size={18} />}\n  </Dialog.Close>\n);\n\n// --- Trigger ---\nexport type ModalTriggerProps = Omit<\n  React.ComponentPropsWithRef<typeof Dialog.Trigger>,\n  'children' | 'render'\n> & {\n  children?: React.ReactNode;\n  nativeButton?: boolean;\n};\n\nexport const ModalTrigger = ({\n  children,\n  className,\n  nativeButton,\n  ref: refProp,\n  ...rest\n}: ModalTriggerProps) => {\n  const { isNativeButtonTriggerElement, resolvedNativeButton } = useNativeButton({\n    children,\n    nativeButton,\n  });\n\n  const renderer = (props: any) => {\n    const resolvedProps = (() => {\n      if (isNativeButtonTriggerElement) return props as any;\n      // eslint-disable-next-line unused-imports/no-unused-vars\n      const { type, ...restProps } = props as any;\n      return restProps;\n    })();\n\n    const mergedProps = mergeProps((children as any).props, resolvedProps);\n    return cloneElement(children as any, {\n      ...mergedProps,\n      ref: mergeRefs([(children as any).ref, (props as any).ref, refProp]),\n    });\n  };\n\n  if (isValidElement(children)) {\n    return (\n      <Dialog.Trigger\n        {...rest}\n        className={className}\n        nativeButton={resolvedNativeButton}\n        render={renderer as any}\n      />\n    );\n  }\n\n  return (\n    <Dialog.Trigger\n      {...rest}\n      className={className}\n      nativeButton={resolvedNativeButton}\n      ref={refProp as any}\n    >\n      {children}\n    </Dialog.Trigger>\n  );\n};\n"],"mappings":";;;;;;;;;;;;;;;AA2BA,MAAM,uBACJ,MACA,cACG;AACH,KAAI,OAAO,cAAc,WAAY,SAAQ,UAAkB,GAAG,MAAM,UAAU,MAAM,CAAC;AACzF,QAAO,GAAG,MAAM,UAAU;;AAM5B,MAAM,mBAAmB,cAA8B,KAAK;AAM5D,MAAM,sBAAsB,cAA4C,KAAK;AAE7E,MAAa,qBAAqB,IAAI,iBAAiB;AACvD,MAAa,wBAAwB,IAAI,oBAAoB;AAO7D,MAAM,qBAAqB,EACzB,MACA,UACA,gBAAgB,oBAChB,GAAG,WACmD;CACtD,MAAM,CAAC,WAAW,gBAAgB,SAAS,CAAC,CAAC,KAAK;AAElD,iBAAgB;AACd,MAAI,KAAM,cAAa,KAAK;IAC3B,CAAC,KAAK,CAAC;CAEV,MAAM,qBAAqB,kBAAkB;AAC3C,eAAa,MAAM;AACnB,wBAAsB;IACrB,CAAC,mBAAmB,CAAC;CAExB,MAAM,UAAU,eAAe,EAAE,gBAAgB,oBAAoB,GAAG,CAAC,mBAAmB,CAAC;AAE7F,KAAI,CAAC,UAAW,QAAO;AAEvB,QACE,oBAAC,kBAAD;EAAkB,OAAO;YACvB,oBAAC,qBAAD;GAAqB,OAAO;aAC1B,oBAAC,OAAO,MAAR;IAAa,OAAA;IAAM,MAAA;IAAK,GAAI;IACzB;IACW,CAAA;GACM,CAAA;EACL,CAAA;;AAIvB,MAAa,aAAa,EAAE,MAAM,gBAAgB,GAAG,WAA2B;AAC9E,KAAI,SAAS,KAAA,EACX,QAAO,oBAAC,mBAAD;EAAyB;EAAsB;EAAgB,GAAI;EAAQ,CAAA;AAEpF,QAAO,oBAAC,OAAO,MAAR;EAAa,OAAA;EAAM,GAAI;EAAQ,CAAA;;AAOxC,MAAa,eAAe,EAAE,WAAW,GAAG,WAA6B;CACvE,MAAM,aAAa,eAAe;AAClC,QAAO,oBAAC,OAAO,QAAR;EAAe,WAAW,aAAa,cAAc,KAAA;EAAW,GAAI;EAAQ,CAAA;;AAKrF,MAAa,iBAAiB,EAAE,WAAW,GAAG,WAC5C,oBAAC,OAAO,UAAR;CACE,GAAI;CACJ,WAAW,oBAAoB,OAAO,UAAU,UAAiB;CACjE,CAAA;AAKJ,MAAa,iBAAiB,EAAE,WAAW,OAAO,GAAG,WAA+B;CAClF,MAAM,OAAO,cAAc;CAC3B,MAAM,SAAS,oBAAoB;AAEnC,KAAI,SAAS,KACX,QACE,oBAAC,OAAO,UAAR;EACE,GAAI;EACJ,WAAW,GAAG,OAAO,UAAU,UAAoB;EACnD,OAAO;GAAE,GAAG;GAAO,YAAY;GAAQ;EACvC,QACE,oBAAC,OAAO,KAAR;GACE,SAAS,EAAE,SAAS,OAAO,IAAI,GAAG;GAClC,SAAS,EAAE,SAAS,GAAG;GACvB,YAAY;GACZ,CAAA;EAEJ,CAAA;AAIN,QACE,oBAAC,OAAO,UAAR;EACE,GAAI;EACJ,WAAW,oBAAoB,OAAO,UAAU,UAAiB;EAC1D;EACP,CAAA;;AAWN,MAAa,cAAc,EACzB,WACA,UACA,OACA,OACA,aACA,gBACA,YACA,GAAG,WACkB;CACrB,MAAM,OAAO,cAAc;CAC3B,MAAM,UAAU,iBAAiB;CACjC,MAAM,SAAS,oBAAoB;AAEnC,KAAI,SAAS,QAAQ,QACnB,QACE,oBAAC,OAAO,OAAR;EAAc,GAAI;EAAM,WAAW,GAAG,OAAO,OAAO,UAAoB;EAAE,OAAO;YAC/E,oBAAC,iBAAD;GAAiB,gBAAgB,QAAQ;aACtC,OACC,8BAAC,OAAO,KAAR;IACE,GAAI;IACJ,GAAI;IACJ,WAAW,GAAG,OAAO,YAAY,eAAe;IAChD,KAAI;IACJ,OAAO;KAAE,UAAU,SAAS,KAAA;KAAW,YAAY;KAAQ,GAAG;KAAO;IAG1D,EADV,SACU,GACX;GACY,CAAA;EACL,CAAA;AAInB,QACE,oBAAC,OAAO,OAAR;EACE,GAAI;EACJ,WAAW,oBAAoB,OAAO,OAAO,UAAiB;EAC9D,OAAO;YAEP,oBAAC,OAAD;GACE,WAAW,GAAG,OAAO,YAAY,eAAe;GAChD,OAAO;IAAE,UAAU,SAAS,KAAA;IAAW,GAAG;IAAO;GAEhD;GACG,CAAA;EACO,CAAA;;AAQnB,MAAa,eAAe,EAAE,WAAW,GAAG,WAC1C,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,OAAO,QAAQ,UAAU;CAAI,CAAA;AAK5D,MAAa,cAAc,EAAE,WAAW,GAAG,WACzC,oBAAC,OAAO,OAAR;CAAc,GAAI;CAAM,WAAW,oBAAoB,OAAO,OAAO,UAAiB;CAAW,CAAA;AAKnG,MAAa,mBAAoD,OAAO;AAMxE,MAAa,gBAAgB,EAAE,WAAW,GAAG,WAC3C,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,OAAO,SAAS,UAAU;CAAI,CAAA;AAO7D,MAAa,eAAe,EAAE,WAAW,GAAG,WAC1C,oBAAC,OAAD;CAAK,GAAI;CAAM,WAAW,GAAG,OAAO,QAAQ,UAAU;CAAI,CAAA;AAK5D,MAAa,cAAc,EAAE,WAAW,UAAU,GAAG,WACnD,oBAAC,OAAO,OAAR;CAAc,GAAI;CAAM,WAAW,oBAAoB,OAAO,OAAO,UAAiB;WACnF,YAAY,oBAAC,GAAD,EAAG,MAAM,IAAM,CAAA;CACf,CAAA;AAYjB,MAAa,gBAAgB,EAC3B,UACA,WACA,cACA,KAAK,SACL,GAAG,WACoB;CACvB,MAAM,EAAE,8BAA8B,yBAAyB,gBAAgB;EAC7E;EACA;EACD,CAAC;CAEF,MAAM,YAAY,UAAe;EAC/B,MAAM,uBAAuB;AAC3B,OAAI,6BAA8B,QAAO;GAEzC,MAAM,EAAE,MAAM,GAAG,cAAc;AAC/B,UAAO;MACL;AAGJ,SAAO,aAAa,UAAiB;GACnC,GAFkB,WAAY,SAAiB,OAAO,cAAc;GAGpE,KAAK,UAAU;IAAE,SAAiB;IAAM,MAAc;IAAK;IAAQ,CAAC;GACrE,CAAC;;AAGJ,KAAI,eAAe,SAAS,CAC1B,QACE,oBAAC,OAAO,SAAR;EACE,GAAI;EACO;EACX,cAAc;EACd,QAAQ;EACR,CAAA;AAIN,QACE,oBAAC,OAAO,SAAR;EACE,GAAI;EACO;EACX,cAAc;EACd,KAAK;EAEJ;EACc,CAAA"}