Skip to content

🐛 asChild で button 専用 props(form 系 / name / value)が非 button 要素に転送される #315

Description

@touyou

事象

#312typeasChild かつ差し込み先が native <button> 以外のときに転送しないよう修正しましたが、ButtonProps / IconButtonPropsReact.ComponentProps<"button"> を継承しているため、他の button 専用 props は引き続き {...restProps} 経由で転送されます

<Button asChild form="my-form" name="action" value="save">
  <a href="/foo">Foo</a>
</Button>
// → <a form="my-form" name="action" value="save"> が出力される

対象になりうるもの: form / formAction / formEncType / formMethod / formNoValidate / formTarget / valuename<a> でも歴史的に有効なので扱いは要検討)。

影響

いずれもブラウザからは無視される属性なので実害は小さいですが、

  • 不正な HTML が出力される
  • 利用者から見ると「type は落ちるのに form は落ちる/落ちない」という一貫性の無さになる

対応方針

type と同じく、canUseButtonProps(差し込み先が native <button> か)で分岐して転送を止める。Button / IconButton の両方に入れる。

併せて検討したいもの

無効時のガードは click / auxclick / keydown のみで、onMouseDown / onPointerDown / onTouchStartrestProps 経由でそのまま要素に付きます。native <button> では disabled 属性がこれらを抑止していたため、asChild + 非 button では非対称になっています(これらは Button で deprecated 扱いの props でもあるため、優先度は低め)。

出所

#312 のセルフレビュー(code-reviewer / silent-failure-hunter エージェント)で検出。#312 のスコープ(#310 の同型欠陥の解消)から外れるため別 issue にしています。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions