Theme
SD MILIEU

2022-5-27

[React] HTMLタグの属性をそのままPropsとして使う場合の書き方

https://zenn.dev/takepepe/articles/atoms-type-definitions

基本はここに書いている内容が全てなんだけど、最近よく参考にしているSmartHR UIのソースコードを見ていたら ButtonHTMLAttributes なるものが出てきた

ComponentPropsと何が違うのか型定義を見た所、詳細は全然理解出来なかったけどComponentPropsは内部的に ~HTMLAttributes を使用しているみたい。

/*
 * ComponentPropsは JSX.IntrinsicElements を呼び出しており、 
 * JSX.IntrinsicElementsは以下のような定義で ~HTMLAttributesを呼び出している
 */
interface IntrinsicElements {
    // HTML
    a: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;
    abbr: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
    address: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
    area: React.DetailedHTMLProps<React.AreaHTMLAttributes<HTMLAreaElement>, HTMLAreaElement>;
    article: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
    aside: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
    audio: React.DetailedHTMLProps<React.AudioHTMLAttributes<HTMLAudioElement>, HTMLAudioElement>;
    b: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
    ~
}

なので(正直よく理解できていないが)ComponentPropsを使う形で進めようかと思う。

DaisyUIを使ったButtonコンポーネントなんかは例として以下のような感じ。

classNameの指定がされないようにclassNameもOmitするようにしている。

type SpecificProps = {
  shape?: Shape
}
type Props = SpecificProps & Omit<React.ComponentProps<'button'>, keyof SpecificProps | 'className'>
export const ButtonComponent = ({
  type = 'button',
  shape = 'md',
  children,
  ...props
}: Props) => {
  return (
    <button
      {...props}
      type={type}
      className={classNames(['btn', shapeToCSSClassName(shape)])}
    >
      {children}
    </button>
  )
}