Vercel の UI SDK 0.1.0-beta.2 上に構築。API は変わる可能性があります。
Number input
Vercel の UI SDK で作る数値欄。押し続けると繰り返すボタン、あらゆるロケールの通貨・パーセント・単位の書式、ドラッグで値を変えるハンドルを備えます。
- フォームのコンポーネント
- 8 個のパーツ
- 13 個の例
@tabler/icons-react@ui-sdk/core@ui-sdk/reactclass-variance-authority
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-number-input.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @ui-sdk/react@0.1.0-beta.2 @ui-sdk/core@0.1.0-beta.2 @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/ui-sdk-number-input.tsx インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
UI SDK は ui-sdk というカスケードレイヤーに少しだけ独自の CSS を追加します。自分のクラスが優先されるよう、グローバルスタイルシートの先頭、Tailwind の import より上でこのレイヤーを宣言してください。
値は数値で、欄が空のときは null です。欄には書式付きで表示されます。入力した文字が有効な数値になった時点で値が更新されます。Enter を押すか欄を離れると確定し、文字を読み取って min と max の範囲に収め、ステップに合わせて書式を付け直します。
ボタンは上限・下限で無効になります。範囲外の値を入力しても、確定すると範囲内に戻ります。
step が通常の増分です。Shift、Page Up、Page Down は largeStep ずつ、Alt または Option と矢印キーは smallStep ずつ変えます。ボタンを押し続けると繰り返します。
format は Intl.NumberFormat のオプションを受け取ります。同じ書式で入力でき、パーセントは割合なので 15% は 0.15 です。variant="stacked" のグループは末尾に小さな矢印を置きます。
locale は表示と入力の区切り文字、記号、桁区切りを決めます。指定しない場合、操作できるようになった時点でページの言語に従い、サーバーは英語で描画します。
デザインツールのように NumberInputScrubArea を横にドラッグして値を変えます。ブラウザーがポインターロックを許可する環境では画面の端を越えてドラッグでき、カーソルは NumberInputScrubAreaCursor が描きます。
wheel を付けると、フォーカス中の欄の上でスクロールして値を変えられます。既定ではオフなので、ページをスクロールしても値は変わりません。
onValueChange は有効な変更のたびに、onValueCommit は操作の終わりに呼ばれ、保存にはこちらを使います。コントローラーを使えば任意のボタンから値を変えたり設定したりできます。
name を付けると、数値は 1250 のように書式なしでそのまま送信されます。required は空欄を防ぎ、フォームをリセットすると既定値に戻ります。
invalid は欄に印を付け、入力に aria-invalid を設定します。在庫などの独自チェックに使います。
読み取り専用の欄はフォーカスでき送信もされますが、ボタン、ドラッグ、入力では変わりません。
ボタンの左右が入れ替わり、数字と通貨はロケールで決まります。
| キー | アクション |
|---|---|
| ↑↓ | 値を step ずつ変えます。 |
| ShiftPageUpPageDown | largeStep ずつ変えます。既定は 10 ステップです。Shift は矢印キー、ボタン、ホイール、ドラッグで使えます。 |
| Alt | 矢印キーと一緒に押すと smallStep ずつ変えます。既定は 1 ステップの 10 分の 1 です。 |
| HomeEnd | 設定されていれば最小値または最大値に移動します。 |
| Enter | 入力を確定して書式を付けます。 |
この欄はネイティブのテキスト入力に WAI-ARIA の spinbutton パターンのキー操作を載せたものなので、通常の文字編集もそのまま使えます。ラベルか aria-label で名前を付けてください。ボタンの既定名は「Increase」と「Decrease」で、入力欄を指し、矢印キーで同じ操作ができるためタブ順には入りません。
小数を扱う欄はスマートフォンで小数用のキーパッドを出し、ボタンはタッチ画面で大きくなります。押したときに縮むのは動きが許可されているときだけです。
各パーツは同名の UI SDK パーツをラップし、render やパーツの状態を受け取る関数にもできる className を含むすべての props を受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
value | number | null | – |
defaultValue | number | null | – |
onValueChange | (value: number | null, details) => void | – |
onValueCommit操作が終わったときに一度呼ばれます。保存向けです。 | (value: number | null, details) => void | – |
min | number | – |
max | number | – |
step | number | 1 |
largeStep | number | step × 10 |
smallStep | number | step ÷ 10 |
format | Intl.NumberFormatOptions | – |
locale既定はページの言語です。 | string | – |
wheel | boolean | false |
invalid | boolean | false |
disabled | boolean | false |
readOnly | boolean | false |
required | boolean | false |
name | string | – |
form | string | – |
controllercreateNumberInputController() で作ります。 | NumberInputController | – |
| 属性 | 説明 |
|---|---|
data-slot="number-input" | CSS で数値欄を指定するためのものです。 |
data-scrubbing | ドラッグで値を変えている間に付きます。 |
data-invalid | 無効なときに付きます。 |
data-disabled | 無効のときに存在します。 |
data-readonly | 読み取り専用のときに付与されます。 |
data-required | 必須のときに付与されます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
variant両側にボタン、末尾に縦並びの矢印、またはドラッグ用ハンドルのためにボタンなし。 | "split" | "stacked" | "plain" | "split" |
render | ReactElement | (props, state) => ReactElement | – |
| 属性 | 説明 |
|---|---|
data-slot="number-input-group" | CSS で欄の枠を指定するためのものです。 |
data-variant | バリアント。split、stacked、plain のいずれかです。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
id | string | – |
placeholder | string | – |
render | ReactElement | (props, state) => ReactElement | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
aria-label | string | "Increase" |
disabledこのボタンだけを無効にします。 | boolean | – |
children既定はプラス記号で、stacked バリアントでは矢印です。 | ReactNode | (state) => ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| 属性 | 説明 |
|---|---|
data-slot="number-input-increment" | CSS でボタンを指定します。 |
data-at-bound | 値が max のときに付きます。 |
data-disabled | ボタンで値を変えられないときに付きます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
aria-label | string | "Decrease" |
disabledこのボタンだけを無効にします。 | boolean | – |
render | ReactElement | (props, state) => ReactElement | – |
| 属性 | 説明 |
|---|---|
data-slot="number-input-decrement" | CSS でボタンを指定します。 |
data-at-bound | 値が min のときに付きます。 |
stacked グループの末尾で、増やすボタンを減らすボタンの上に重ねます。
| プロパティ | 型 | デフォルト |
|---|---|---|
orientation右と上で値が増えます。 | "horizontal" | "vertical" | "horizontal" |
pixelsPerStep1 ステップに必要なポインターの移動量です。 | number | – |
controllerツールバーのアイコンのように、数値欄の外にあるドラッグ領域をつなぎます。 | NumberInputController | – |
| 属性 | 説明 |
|---|---|
data-slot="number-input-scrub-area" | CSS でドラッグ領域を指定するためのものです。 |
data-orientation | horizontal または vertical。 |
data-scrubbing | ドラッグで値が変わっている間に付きます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
children既定はポインターの中心に置かれた横向きの矢印です。 | ReactNode | – |
- Calendar単一、範囲、複数選択に対応する日付グリッドです。月のスライド、範囲のプレビュー、タッチしやすいサイズの日付セルを備えています。
- Checkboxチェックが描かれるように表示されるチェックボックスです。中間状態の親、グループ、ホバーを共有するラベルに対応します。
- Comboboxチップ、グループ、非同期の結果に対応した、絞り込み可能なセレクトです。入力に合わせてポップアップのサイズが変わります。
- Date picker押すとポップオーバーでカレンダーを開くボタンです。スマートフォンではボトムシートになり、単一の日付も範囲も選べます。
- Fieldコントロールに紐付いたラベル、説明、エラーです。バリデーション状態とフォーム向けのレイアウトを備えています。
- Input3つのサイズ、無効状態と読み取り専用状態、ネイティブのバリデーションスタイル、スマートフォンでズームされない16pxのタッチ用フォントを備えたテキスト入力です。