Skip to content
fandhe-frontendcore v0.4.3
GitHub

Signature Pad

fandhe-frontend-headless-ui の signature_pad mod が提供する手書き署名入力の unstyled 部品です。Root / Label(label 要素)/ Control / Segment(svg)/ SegmentPath / Guide / ClearTrigger / HiddenInput の 8 anatomy パーツを持ち、canvas を一切使わず、ストローク(座標列)を SVG path 文字列へ変換する決定的な純粋関数のみで描画します。ポインタイベントの収集自体は本部品の責務外です。

/themes/ 側の SignaturePad(Chakra ライクな variant/size を持つスタイル層)と異なり、CSS を一切持ちません。

root は disabled/empty(strokes が空か)に応じて data-disabled/data-empty を付与します。label/guide は data-disabled を反映します(label のタグはネイティブ <label> 要素です)。control は role="application"・aria-roledescription="signature pad" を常時付与し、disabled に応じて非 disabled 時のみ tabindex="0"、disabled 時のみ aria-disabled="true" を切り替えます。control のアクセシブルネーム(aria-label/aria-labelledby)は偽の説明文を捏造しない fail-closed 方針により本モジュールが自動生成することはなく、呼び出し側が attrs で渡す契約です。clear-trigger はネイティブ disabled + data-disabled を反映します。SignaturePad::control メソッド経由でのみ data-readonly が付与されます(自由関数 control にはこの属性はありません)。

キーボード操作

キー対象効果
TabControltabindex="0"(非 disabled 時のみ)によりフォーカスを移します。
Enter / SpaceClearTriggerフォーカスがネイティブ <button> 上にあるとき、ブラウザ既定の活性化操作で全ストロークを削除します。

参考サイト(ark-ui docs / zag.js signature-pad.connect.ts)に Keyboard Interactions 表・onKeyDown ハンドラは存在しません。描画自体はポインタ専用のままで、undo(直前ストロークの取り消し)を含むアクションに既定のキー割り当てはありません。

参考サイトとの差分

ark-ui docs(Anatomy / Data Attributes 表)と zag.js(signature-pad.connect.ts/signature-pad.anatomy.ts)を一次情報として突合し、label のタグ(div → label)・data-disabled(label/guide)・control の role/aria-roledescription/tabindex/aria-disabled を是正しました。一方、以下は意図的に合わせていません。

  • label の data-required・for(hidden input への関連付け): 本モジュールに「必須」概念が無く、for は呼び出し側 attrs に委ねます。
  • control のアクセシブルネーム自動生成: 偽の説明文を捏造しない fail-closed 方針により、呼び出し側が aria-label/aria-labelledby を渡す契約のままとします。
  • clear-trigger のネイティブ hidden(ストローク空 or 描画中): author CSS(display)との干渉を避けるため持ち込まず、root[data-empty] を使う自前 CSS(下記参照)で代替します。
  • data-empty(root)・data-readonly(control)・segment の role="img": 本フレームワーク固有の拡張として維持します。
  • hidden-input の type="hidden"(参照は type="text" hidden readOnly required): フォーム送信用途として type="hidden" のまま維持します。

スタイル済みの表示例は Signature Pad を参照してください。

関連 API: fandhe-frontend-headless-ui API

自前 CSS の最小例

Themes 版を使わず本部品を直接使う場合、[data-scope="signature-pad"][data-part="..."] セレクタでスタイルを当てます。以下は control の枠線とフォーカスリング、segment-path の線描画、guide のベースライン、root[data-empty] による clear-trigger の非表示(参照の hidden 相当)の最小例です。

CSS
[data-scope="signature-pad"][data-part="control"] {
  display: inline-block;
  border: 1px solid #ccc;
  border-radius: 6px;
}

[data-scope="signature-pad"][data-part="control"]:focus-visible {
  outline: 2px solid #06c;
  outline-offset: 2px;
}

[data-scope="signature-pad"][data-part="control"][data-disabled] {
  opacity: 0.5;
}

[data-scope="signature-pad"][data-part="segment-path"] {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

[data-scope="signature-pad"][data-part="guide"] {
  border-bottom: 1px dashed #999;
}

[data-scope="signature-pad"][data-part="root"][data-empty] [data-part="clear-trigger"] {
  display: none;
}

Demo

枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。

Features

  • Root / Label(label 要素)/ Control / Segment(svg)/ SegmentPath(ストロークごとの path)/ Guide / ClearTrigger / HiddenInput の 8 anatomy パーツを提供する。canvas を一切使わず、ストローク(座標列)を SVG path 文字列へ変換する決定的な純粋関数(stroke_path_d)が中核である。
  • stroke_path_d は同一座標列から常に同一の d 属性値を生成する(固定小数点 2 桁・round half away from zero・指数表記なし)。ポインタイベントの収集自体は本モジュールの責務外(fandhe-frontend-wasm-full が座標列を正規化して dispatch する)。
  • hidden_input は全ストロークの d 文字列を ; 結合した値をフォーム送信する。points 数・ストローク数には上限(MAX_POINTS_PER_STROKE/MAX_STROKES)があり、改ざんされた dispatch payload・hydration 属性による無制限メモリ確保を防ぐ。
  • 参照突合(イシュー #1620): control に role="application"・aria-roledescription="signature pad"・非 disabled 時 tabindex="0" を追加し zag.js の getControlProps と一致させた。呼び出し側 attrs からのこれら固定属性・data-disabled の偽装は fail-closed に除去する。

Anatomy

root
  label
  control
    guide
    segment
      segment-path
  clear-trigger
  hidden-input

API Reference

Arguments

NameTypeDefaultDescription
root(disabled)bool—data-disabled を反映する。
root(empty)bool—strokes が空かどうか。data-empty として反映する(本フレームワーク固有の拡張)。
label(disabled)bool—data-disabled を反映する。タグはネイティブ <label> 要素(イシュー #1620)。
control(disabled)bool—data-disabled・非 disabled 時 tabindex="0"・disabled 時 aria-disabled="true" を反映する。role="application"/aria-roledescription="signature pad" は常時固定。
segment(width, height)u32, u32—viewBox="0 0 {width} {height}" として描画領域寸法を出力する。
segment(aria_label_text)Option<&str>—Some のとき aria-label を付与する。未指定時は role="img" のみ(偽の説明文を捏造しない fail-closed 方針)。
segment_path(stroke)&Stroke—d 属性値は stroke_path_d(stroke) の内部生成文字列のみ(fill/stroke は付与せず headless 中立を保つ)。
guide(disabled)bool—data-disabled を反映する(イシュー #1620、ark docs Data Attributes 表の Guide 行と一致)。
clear_trigger(disabled)bool—ネイティブ disabled + data-disabled を反映する。
hidden_input(name, value)&str, &str—フォーム送信名と、全ストロークを ; 結合した値。

Data Attributes

PartAttributeObserved Values
clear-triggerdata-disabled(値なし)
controldata-disabled(値なし)
controldata-readonly(値なし)
guidedata-disabled(値なし)
hidden-inputdata-disabled(値なし)
labeldata-disabled(値なし)
rootdata-disabled(値なし)
rootdata-empty(値なし)

Examples

Empty, disabled

ストロークが 1 本もない無効化状態(root(empty: true, disabled: true))。guide のみが描画される。

Read-only

SignaturePad::new(strokes, false, true) の read-only 状態。data-readonly は SignaturePad::control メソッド経由でのみ付与される(自由関数 control にはこの属性はない)。

Custom CSS

headless-ui はスタイルレスです。data-scope/data-part/data-* をセレクタに使い、segment-path の fill/stroke・control の枠線と :focus-visible リング・guide のベースライン・root[data-empty] による clear-trigger の非表示を自前 CSS で当てられます。

headless-ui はスタイルレスです。data-scope/data-part/data-* をセレクタに使い、以下のような CSS を自前で当てられます。

CSS
[data-scope="signature-pad"][data-part="control"] {
  display: inline-block;
  border: 1px solid #ccc;
  border-radius: 6px;
}

[data-scope="signature-pad"][data-part="control"]:focus-visible {
  outline: 2px solid #06c;
  outline-offset: 2px;
}

[data-scope="signature-pad"][data-part="control"][data-disabled] {
  opacity: 0.5;
}

[data-scope="signature-pad"][data-part="segment-path"] {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

[data-scope="signature-pad"][data-part="guide"] {
  border-bottom: 1px dashed #999;
}

[data-scope="signature-pad"][data-part="root"][data-empty] [data-part="clear-trigger"] {
  display: none;
}

Accessibility

Keyboard Interactions

KeyDescription
Tabcontrol(tabindex="0"、非 disabled 時のみ)へフォーカスを移動する。参照(ark-ui docs / zag.js)に Keyboard Interactions 表は存在せず、描画自体はポインタ専用のまま(undo 等のアクションに既定キー割り当てはない)。
Enter / Spaceフォーカスが clear-trigger(ネイティブ <button>)上にあるとき、ブラウザ既定の活性化操作で全ストロークを削除する。

WAI-ARIA

AttributeDescription
role="application" (control)固定付与。zag.js getControlProps と一致(イシュー #1620)。
aria-roledescription="signature pad" (control)固定付与。
aria-disabled="true" (control)disabled が true のときのみ付与する(非 disabled 時は tabindex="0" を付与する)。
aria-label / aria-labelledby (control)偽の説明文を捏造しない fail-closed 方針により本モジュールは自動付与しない。呼び出し側が attrs 経由でアクセシブルネームを渡す契約。
role="img" (segment)aria_label_text が None のときのみ role="img" のみを出力し、偽の説明文を作らない(aria_label_text が Some のときは aria-label を併せて付与する)。