{"version":3,"file":"DialogContentInner.cjs","sources":["../../../src/components/Dialog/DialogContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n  type ComponentProps,\n  type FC,\n  type PropsWithChildren,\n  type RefObject,\n  memo,\n  useMemo,\n  useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useHandleEscape } from '../../hooks/useHandleEscape'\nimport { dialogSize } from '../../tailwind'\n\nimport { DialogOverlap } from './DialogOverlap'\nimport { FocusTrap, type FocusTrapRef } from './FocusTrap'\nimport { useBodyScrollLock } from './useBodyScrollLock'\n\nimport type { DialogSize } from './types'\n\nexport type DialogContentInnerProps = PropsWithChildren<{\n  /**\n   * オーバーレイをクリックした時に発火するコールバック関数\n   */\n  onClickOverlay?: () => void\n  /**\n   * エスケープキーを押下した時に発火するコールバック関数\n   */\n  onPressEscape?: () => void\n  /**\n   * ダイアログを開いているかどうか\n   */\n  isOpen: boolean\n  /**\n   * @deprecated ダイアログの幅を指定する場合は、`width` ではなく `size` を使用してください。\n   * ダイアログの幅\n   */\n  width?: string | number\n  /**\n   * ダイアログの大きさ\n   */\n  size?: DialogSize\n  /**\n   * ダイアログの `id`\n   * TODO 使われてなさそうなので確認\n   */\n  id?: string\n  /**\n   * ダイアログを開いた時にフォーカスする対象\n   */\n  firstFocusTarget?: RefObject<HTMLElement>\n  /**\n   * ダイアログの `aria-label`\n   */\n  ariaLabel?: string\n  /**\n   * ダイアログの `aria-labelledby`\n   */\n  ariaLabelledby?: string\n  /**\n   * ダイアログトップのフォーカストラップへの ref\n   */\n  focusTrapRef?: RefObject<FocusTrapRef>\n}>\ntype Props = DialogContentInnerProps & Omit<ComponentProps<'div'>, keyof DialogContentInnerProps>\n\nconst classNameGenerator = tv({\n  slots: {\n    layout: ['smarthr-ui-Dialog-wrapper', 'shr-max-w-[calc(100dvw-theme(spacing.1))]'],\n    inner: [\n      'smarthr-ui-Dialog',\n      'shr-border-shorthand shr-relative shr-z-1 shr-rounded-m shr-bg-white shr-shadow-layer-3',\n      'contrast-more:shr-border-high-contrast',\n    ],\n    background: ['smarthr-ui-Dialog-background', 'shr-absolute shr-inset-0 shr-bg-scrim'],\n  },\n  variants: {\n    size: {\n      XS: { layout: dialogSize.XS },\n      S: { layout: dialogSize.S },\n      M: { layout: dialogSize.M },\n      L: { layout: dialogSize.L },\n      XL: { layout: dialogSize.XL },\n      XXL: { layout: dialogSize.XXL },\n      FULL: { layout: dialogSize.FULL },\n    },\n  },\n})\n\nexport const DialogContentInner: FC<Props> = ({\n  onClickOverlay,\n  onPressEscape,\n  isOpen,\n  id,\n  width,\n  size,\n  firstFocusTarget,\n  ariaLabel,\n  ariaLabelledby,\n  children,\n  className,\n  focusTrapRef,\n  ...rest\n}) => {\n  const classNames = useMemo(() => {\n    const { layout, inner, background } = classNameGenerator()\n\n    return {\n      layout: layout({ size }),\n      inner: inner({ className }),\n      background: background(),\n    }\n  }, [size, className])\n  const style = useMemo(() => {\n    // width は deprecated なので、size が指定されている場合は width を無視する\n    const actualWidth = size ? undefined : typeof width === 'number' ? `${width}px` : width\n\n    return actualWidth ? { width: actualWidth } : undefined\n  }, [width, size])\n\n  const innerRef = useRef<HTMLDivElement>(null)\n\n  useHandleEscape(\n    useMemo(() => (onPressEscape && isOpen ? onPressEscape : undefined), [isOpen, onPressEscape]),\n  )\n\n  useBodyScrollLock(isOpen)\n\n  return (\n    <DialogOverlap isOpen={isOpen}>\n      <div id={id} className={classNames.layout} style={style}>\n        <Overlay\n          isOpen={isOpen}\n          onClickOverlay={onClickOverlay}\n          className={classNames.background}\n        />\n        <div\n          {...rest}\n          ref={innerRef}\n          role=\"dialog\"\n          aria-label={ariaLabel}\n          aria-labelledby={ariaLabelledby}\n          aria-modal=\"true\"\n          className={classNames.inner}\n        >\n          <FocusTrap firstFocusTarget={firstFocusTarget} ref={focusTrapRef}>\n            {children}\n          </FocusTrap>\n        </div>\n      </div>\n    </DialogOverlap>\n  )\n}\n\nconst Overlay = memo<Pick<Props, 'onClickOverlay' | 'isOpen'> & { className: string }>(\n  ({ onClickOverlay, isOpen, className }) => {\n    const onClick = useMemo(\n      () => (onClickOverlay && isOpen ? onClickOverlay : undefined),\n      [isOpen, onClickOverlay],\n    )\n\n    // eslint-disable-next-line smarthr/best-practice-for-interactive-element\n    return <div onClick={onClick} className={className} role=\"presentation\" />\n  },\n)\n"],"names":[],"mappings":";;;;;;;;;;;;AAoEA;AACE;AACE;AACA;;;;AAIC;AACD;AACD;AACD;AACE;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACD;AACF;AACF;AAEM;AAeL;;;AAII;AACA;;;AAGJ;AACA;;;AAIE;AACF;AAEA;;;AAQA;AAwBF;AAEA;;;AAQI;AACF;;"}