{"version":3,"file":"TooltipPortal.cjs","sources":["../../../src/components/Tooltip/TooltipPortal.tsx"],"sourcesContent":["import { type FC, type ReactNode, useEffect, useMemo, useRef, useState } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useTheme } from '../../hooks/useTheme'\nimport { debounce } from '../../libs/debounce'\nimport { Balloon } from '../Balloon'\n\ntype Props = {\n  message: ReactNode\n  isVisible: boolean\n  parentRect: DOMRect | null\n  isIcon?: boolean\n}\n\nconst classNameGenerator = tv({\n  slots: {\n    container: 'smarthr-ui-Tooltip-popup shr-absolute shr-z-overlap aria-hidden:shr-hidden',\n    balloon: 'shr-max-w-full [&&&]:shr-whitespace-normal',\n    balloonText: 'shr-m-0 shr-px-1 shr-py-0.5',\n  },\n})\n\nconst OUTER_MARGIN = 10\nconst SPACING = 5\n\ntype HorizontalType = 'left' | 'center' | 'right'\ntype VerticalType = 'top' | 'middle' | 'bottom'\n\nexport const TooltipPortal: FC<Props> = ({ message, isVisible, parentRect, isIcon }) => {\n  const theme = useTheme()\n  const portalRef = useRef<HTMLDivElement>(null)\n  const [style, setStyle] = useState<{ [key: string]: undefined | string }>({})\n  const [actualHorizontal, setActualHorizontal] = useState<HorizontalType>('center')\n  const [actualVertical, setActualVertical] = useState<VerticalType>('bottom')\n\n  useEffect(() => {\n    if (!portalRef.current || !parentRect) {\n      return\n    }\n\n    const portal = portalRef.current\n\n    const action = () => {\n      const vertical = calculateVertical(portal.offsetHeight, parentRect)\n      const horizontal = calculateHorizontal(portal.offsetWidth, parentRect, theme)\n\n      setStyle({\n        insetBlockStart: vertical.insetBlockStart,\n        insetInlineStart: horizontal.insetInlineStart,\n        insetInlineEnd: horizontal.insetInlineEnd,\n        maxWidth: horizontal.maxWidth,\n        maxHeight: vertical.maxHeight,\n      })\n      setActualVertical(vertical.alignment)\n      setActualHorizontal(horizontal.alignment)\n    }\n    const debouncedAction = debounce(action, 100)\n\n    action()\n\n    window.addEventListener('resize', debouncedAction)\n\n    return () => {\n      window.removeEventListener('resize', debouncedAction)\n    }\n  }, [parentRect, theme])\n\n  const classNames = useMemo(() => {\n    const { container, balloon, balloonText } = classNameGenerator()\n\n    return {\n      container: container(),\n      balloon: balloon(),\n      balloonText: balloonText(),\n    }\n  }, [])\n\n  return (\n    <div\n      ref={portalRef}\n      role=\"tooltip\"\n      aria-hidden={!isVisible}\n      className={classNames.container}\n      style={style}\n    >\n      <Balloon\n        horizontal={actualHorizontal}\n        vertical={actualVertical}\n        triggerIcon={isIcon}\n        className={classNames.balloon}\n      >\n        <div className={classNames.balloonText}>{message}</div>\n      </Balloon>\n    </div>\n  )\n}\n\nconst calculateVertical = (\n  portalHeight: number,\n  parentRect: DOMRect,\n): { insetBlockStart: string; maxHeight: string | undefined; alignment: VerticalType } => {\n  // トリガの上側の領域に収まる場合\n  if (parentRect.top - portalHeight >= 0) {\n    return {\n      insetBlockStart: `${scrollY + parentRect.top - portalHeight - SPACING}px`,\n      maxHeight: undefined,\n      alignment: 'bottom',\n    }\n  }\n\n  // トリガの下側の領域に収まる場合\n  if (parentRect.bottom + portalHeight <= innerHeight) {\n    return {\n      insetBlockStart: `${scrollY + parentRect.bottom + SPACING}px`,\n      maxHeight: undefined,\n      alignment: 'top',\n    }\n  }\n\n  const triggerHeight = parentRect.bottom - parentRect.top\n\n  // 上側の領域のほうが広い場合\n  if (parentRect.top + triggerHeight / 2 >= innerHeight / 2) {\n    return {\n      insetBlockStart: `${scrollY + OUTER_MARGIN - SPACING}px`,\n      maxHeight: `${parentRect.top - OUTER_MARGIN}px`,\n      alignment: 'bottom',\n    }\n  }\n\n  // 下側の領域のほうが広い場合\n  return {\n    insetBlockStart: `${scrollY + parentRect.bottom + SPACING}px`,\n    maxHeight: `${innerHeight - parentRect.bottom - OUTER_MARGIN}px`,\n    alignment: 'top',\n  }\n}\n\ntype ReturnCalculateHorizontalType = {\n  insetInlineStart: string | undefined\n  insetInlineEnd: string | undefined\n  maxWidth: string\n  alignment: HorizontalType\n}\nconst calculateHorizontal = (\n  portalWidth: number,\n  parentRect: DOMRect,\n  theme: ReturnType<typeof useTheme>,\n): ReturnCalculateHorizontalType => {\n  const triggerAlignCenter = parentRect.left + parentRect.width / 2\n  const portalHalfWidth = portalWidth / 2\n  const edgeSpacing = theme.spacingByChar(0.5)\n\n  // トリガを中心に左右に十分な余白がある場合\n  if (\n    triggerAlignCenter - portalHalfWidth > SPACING &&\n    triggerAlignCenter + portalHalfWidth < document.body.clientWidth - SPACING\n  ) {\n    const insetInlineStart = `${triggerAlignCenter - portalHalfWidth}px`\n\n    return {\n      insetInlineStart,\n      insetInlineEnd: undefined,\n      maxWidth: `calc(100% - max(${insetInlineStart}, 0px) - ${edgeSpacing})`,\n      alignment: 'center',\n    }\n  }\n\n  // トリガが画面左寄りの場合\n  if (triggerAlignCenter <= document.body.clientWidth / 2) {\n    const insetInlineStart = `${scrollX + parentRect.left - SPACING}px`\n\n    return {\n      insetInlineStart,\n      insetInlineEnd: undefined,\n      maxWidth: `calc(100% - max(${insetInlineStart}, 0px) - ${edgeSpacing})`,\n      alignment: 'left',\n    }\n  }\n\n  // トリガが画面右寄りの場合\n  const insetInlineEnd = `${document.body.clientWidth - parentRect.right - scrollX - SPACING}px`\n\n  return {\n    insetInlineStart: undefined,\n    insetInlineEnd,\n    maxWidth: `calc(100% - ${edgeSpacing} - max(${insetInlineEnd}, 0px))`,\n    alignment: 'right',\n  }\n}\n"],"names":["tv","useTheme","useRef","useState","useEffect","debounce","useMemo","_jsx","Balloon"],"mappings":"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"}