{"version":3,"file":"LineClamp.cjs","sources":["../../../src/components/LineClamp/LineClamp.tsx"],"sourcesContent":["'use client'\n\nimport {\n  type ComponentPropsWithRef,\n  type FC,\n  type PropsWithChildren,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { Tooltip } from '../Tooltip'\n\ntype AbstractProps = PropsWithChildren<VariantProps<typeof classNameGenerator>>\ntype Props = AbstractProps & Omit<ComponentPropsWithRef<'span'>, keyof AbstractProps>\n\nconst classNameGenerator = tv({\n  slots: {\n    base: 'smarthr-ui-LineClamp shr-relative',\n    clampedLine: 'shr-max-w-full',\n    shadowElementWrapper:\n      'shr-invisible shr-absolute shr-left-0 shr-top-0 shr-h-full shr-max-w-full shr-overflow-hidden shr-whitespace-normal shr-opacity-0',\n    shadowElement: 'shr-absolute shr-left-0 shr-top-0 shr-max-w-full',\n  },\n  variants: {\n    maxLines: {\n      1: {\n        clampedLine:\n          'shr-inline-block shr-max-w-full shr-overflow-x-clip shr-overflow-ellipsis shr-whitespace-nowrap shr-align-middle',\n      },\n      2: {\n        clampedLine: 'shr-line-clamp-[2]',\n      },\n      3: {\n        clampedLine: 'shr-line-clamp-[3]',\n      },\n      4: {\n        clampedLine: 'shr-line-clamp-[4]',\n      },\n      5: {\n        clampedLine: 'shr-line-clamp-[5]',\n      },\n      6: {\n        clampedLine: 'shr-line-clamp-[6]',\n      },\n    },\n  },\n  compoundVariants: [\n    {\n      maxLines: [2, 3, 4, 5, 6],\n      className: {\n        // baseがdisplay:-webkit-boxでないと高さ取得用の要素が表示部分と同じ大きさで表示されないバグを回避するため\n        base: '[display:-webkit-box]',\n      },\n    },\n  ],\n})\n\nexport const LineClamp: FC<Props> = ({ maxLines = 3, children, className, ...rest }) => {\n  if (maxLines < 1 || maxLines > 6) {\n    throw new Error('\"maxLines\" は 1 ~ 6 の範囲で指定してください')\n  }\n\n  const [isTooltipVisible, setTooltipVisible] = useState(false)\n  const ref = useRef<HTMLSpanElement>(null)\n  const shadowRef = useRef<HTMLSpanElement>(null)\n\n  useEffect(() => {\n    const el = ref.current\n    const shadowEl = shadowRef.current\n\n    // -webkit-line-clamp を使った要素ではel.scrollHeightとel.clientHeightの比較だと\n    // フォントの高さの計算が期待と異なり適切な高さが取得できないためshadowElと比較している\n    // 参考: https://github.com/kufu/smarthr-ui/pull/4710\n    const isMultiLineOverflow =\n      el && shadowEl\n        ? shadowEl.clientWidth > el.clientWidth || shadowEl.clientHeight > el.clientHeight\n        : false\n\n    setTooltipVisible(isMultiLineOverflow)\n  }, [maxLines, children])\n\n  const classNames = useMemo(() => {\n    const { base, clampedLine, shadowElementWrapper, shadowElement } = classNameGenerator({\n      maxLines,\n    })\n\n    return {\n      base: base({ className }),\n      clampedLine: clampedLine(),\n      shadowElementWrapper: shadowElementWrapper(),\n      shadowElement: shadowElement(),\n    }\n  }, [maxLines, className])\n\n  const actualLineClamp = (\n    <span {...rest} className={classNames.base}>\n      <span ref={ref} className={classNames.clampedLine}>\n        {children}\n      </span>\n      {/* 切り取られていないテキストの高さを取得するための要素 */}\n      <span aria-hidden className={classNames.shadowElementWrapper}>\n        <span className={classNames.shadowElement} ref={shadowRef}>\n          {children}\n        </span>\n      </span>\n    </span>\n  )\n\n  return isTooltipVisible ? (\n    <Tooltip message={children}>{actualLineClamp}</Tooltip>\n  ) : (\n    actualLineClamp\n  )\n}\n"],"names":[],"mappings":";;;;;;;;AAkBA;AACE;AACE;AACA;AACA;AAEA;AACD;AACD;AACE;AACE;AACE;AAED;AACD;AACE;AACD;AACD;AACE;AACD;AACD;AACE;AACD;AACD;AACE;AACD;AACD;AACE;AACD;AACF;AACF;AACD;AACE;;AAEE;;AAEE;AACD;AACF;AACF;AACF;AAEM;;AAEH;;;AAIF;AACA;;AAGE;AACA;;;;AAKA;AAEI;;;AAIN;AAEA;;;AAGG;;AAGC;;;;;AAKJ;;;AAqBF;;"}