{"version":3,"file":"Input.cjs","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["'use client'\n\nimport {\n  type ComponentPropsWithRef,\n  type ReactNode,\n  type WheelEvent,\n  forwardRef,\n  useCallback,\n  useEffect,\n  useImperativeHandle,\n  useMemo,\n  useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useTheme } from '../../hooks/useTheme'\n\ntype AbstractProps = {\n  /** input 要素の `type` 値 */\n  type?: HTMLInputElement['type']\n  /** フォームにエラーがあるかどうか */\n  error?: boolean\n  /** コンポーネントの幅 */\n  width?: number | string\n  /** オートフォーカスを行うかどうか */\n  autoFocus?: boolean\n  /** コンポーネント内の先頭に表示する内容 */\n  prefix?: ReactNode\n  /** コンポーネント内の末尾に表示する内容 */\n  suffix?: ReactNode\n  /** 背景色。readOnly を下地の上に載せる場合に使う */\n  bgColor?: keyof typeof backgroundColor\n  /**\n   * @deprecated placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n   */\n  placeholder?: string\n}\ntype Props = AbstractProps & Omit<ComponentPropsWithRef<'input'>, keyof AbstractProps | 'onWheel'>\n\nexport const backgroundColor = {\n  BACKGROUND: 'background',\n  COLUMN: 'column',\n  BASE_GREY: 'base-grey',\n  OVER_BACKGROUND: 'over-background',\n  HEAD: 'head',\n  BORDER: 'border',\n  ACTION_BACKGROUND: 'action-background',\n} as const\n\nconst wrapperClassNameGenerator = tv({\n  base: [\n    'smarthr-ui-Input',\n    'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',\n    'contrast-more:shr-border-high-contrast',\n    'focus-within:shr-focus-indicator',\n    'has-[[aria-invalid]]:shr-border-danger',\n  ],\n  variants: {\n    disabled: {\n      true: 'shr-pointer-events-none shr-bg-white-darken [&&&]:shr-border-default/50',\n    },\n    readOnly: {\n      true: '[&&&]:shr-border-[theme(backgroundColor.column)] [&&&]:shr-bg-column',\n    },\n  },\n})\nconst innerClassNameGenerator = tv({\n  slots: {\n    input: [\n      'smarthr-ui-Input-input',\n      'shr-inline-block shr-w-full shr-grow shr-border-none shr-bg-transparent shr-py-0.75 shr-text-base shr-leading-none shr-text-black shr-outline-none shr-outline-0',\n      'placeholder:shr-text-grey',\n      'disabled:shr-text-disabled disabled:shr-opacity-100',\n      'shr-h-[theme(fontSize.base)]',\n      // HINT: 日付系inputがsafariなどで対応されていないため、input要素内が空白になりフォームが潰れる場合がある\n      // マジックナンバーになるが、ほかに適切なプロパティがないため、min-widthで最低幅を指定することで防ぐ\n      '[&[type=\"datetime-local\"]]:shr-min-w-[11em] [&[type=\"month\"]]:shr-min-w-[8em] [&[type=\"time\"]]:shr-min-w-[5em]',\n    ],\n    affix: 'shr-flex shr-shrink-0 shr-items-center shr-text-grey',\n  },\n  variants: {\n    disabled: {\n      true: {\n        affix: 'shr-text-disabled shr-opacity-100',\n      },\n    },\n  },\n})\n\nexport const Input = forwardRef<HTMLInputElement, Props>(\n  (\n    {\n      onFocus,\n      onBlur,\n      autoFocus,\n      prefix,\n      suffix,\n      className,\n      width,\n      disabled,\n      error,\n      readOnly,\n      bgColor,\n      type,\n      max,\n      ...rest\n    },\n    ref,\n  ) => {\n    const theme = useTheme()\n    const innerRef = useRef<HTMLInputElement>(null)\n\n    useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n      ref,\n      () => innerRef.current,\n    )\n\n    const attrsByType = useMemo(() => {\n      switch (type) {\n        case 'number':\n          return {\n            max,\n            onWheel: disableWheel,\n          }\n        // HINT: PC版ブラウザで年が6桁入力できる場合、コピー&ペーストが正常に動作しないなど、UI上の問題が発生する場合がある\n        // 回避のためmaxで年四桁を指定する\n        case 'date':\n          return {\n            max: max || '9999-12-31',\n          }\n        case 'datetime-local':\n          return {\n            max: max || '9999-12-31T23:59',\n          }\n        case 'month':\n          return {\n            max: max || '9999-12',\n          }\n      }\n\n      return { max }\n    }, [max, type])\n\n    const onDelegateClickFocus = useCallback(() => innerRef.current?.focus(), [])\n\n    useEffect(() => {\n      if (autoFocus && innerRef.current) {\n        innerRef.current.focus()\n      }\n    }, [autoFocus])\n\n    const wrapperClassName = useMemo(\n      () => wrapperClassNameGenerator({ disabled, readOnly, className }),\n      [disabled, readOnly, className],\n    )\n    const wrapperStyle = useMemo(() => {\n      const color = bgColor ? theme.backgroundColor[backgroundColor[bgColor]] : undefined\n      const maxWidth = typeof width === 'number' ? `${width}px` : width\n\n      return {\n        borderColor: color,\n        backgroundColor: color,\n        maxWidth,\n        width: maxWidth ? '100%' : undefined,\n      }\n    }, [width, bgColor, theme.backgroundColor])\n\n    const innerClassNames = useMemo(() => {\n      const { input, affix } = innerClassNameGenerator({ disabled })\n\n      return {\n        input: input(),\n        prefix: affix({ className: 'smarthr-ui-Input-prefix' }),\n        suffix: affix({ className: 'smarthr-ui-Input-suffix' }),\n      }\n    }, [disabled])\n\n    return (\n      <span\n        role=\"presentation\"\n        onClick={onDelegateClickFocus}\n        className={wrapperClassName}\n        style={wrapperStyle}\n      >\n        {prefix && <span className={innerClassNames.prefix}>{prefix}</span>}\n        <input\n          {...rest}\n          {...attrsByType}\n          type={type}\n          data-smarthr-ui-input=\"true\"\n          onFocus={onFocus}\n          onBlur={onBlur}\n          disabled={disabled}\n          readOnly={readOnly}\n          ref={innerRef}\n          aria-invalid={error || undefined}\n          className={innerClassNames.input}\n        />\n        {suffix && <span className={innerClassNames.suffix}>{suffix}</span>}\n      </span>\n    )\n  },\n)\n\nconst disableWheel = (e: WheelEvent) => {\n  // wheel イベントに preventDefault はないため\n  if (e.target) {\n    ;(e.target as HTMLInputElement).blur()\n  }\n}\n"],"names":[],"mappings":";;;;;;;;AAuCO;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAGF;AACE;;;;;;AAMC;AACD;AACE;AACE;AACD;AACD;AACE;AACD;AACF;AACF;AACD;AACE;AACE;;;;;;;;;AASC;AACD;AACD;AACD;AACE;AACE;AACE;AACD;AACF;AACF;AACF;AAEM;AAoBH;AACA;;AAOA;;AAEI;;;AAGI;;;;AAIJ;;;;AAIA;;;;AAIA;;;;;;AAOJ;AAEA;;AAGE;AACE;;AAEJ;;AAMA;AACE;AACA;;AAGE;AACA;;;;;AAMJ;AACE;;;;;;AAOF;AAEA;AAwBF;AAGF;;AAEE;AACI;;AAEN;;;"}