useButtonFeedback
非同期のアクションを、読み込み中、成功、エラーの順に実行します。高速なリクエストではスピナーをスキップし、エラーは読み終えるまで保持します。
pnpm dlx shadcn@latest add https://hextaui.com/r/use-button-feedback.jsonフックと、その依存関係をプロジェクトに追加します。
次のコードをコピーしてプロジェクトに貼り付けてください。
hooks/use-button-feedback.ts インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
<Button feedback> は、onClick が promise を返すと、このフローを自動で実行します。フォームの onSubmit、キーボードショートカット、blur など、処理が別の場所で始まる場合にはこのフックを使います。ステータスがボタンではないものに属する場合にも使えます。
track() は promise、または promise を返す関数を受け取り、status を idle、loading、そして success または error と進め、idle に戻します。タイミングが、落ち着いた印象を生みます。
| ステップ | 説明 |
|---|---|
0–150ms | ステータスは idle のままです。この間に完了したリクエストは、スピナーなしで直接 success または error になります。 |
loading | 150msから表示されます。表示されたら最低400msは続くので、一瞬だけ表示されることはありません。 |
success | デフォルトでは2秒間保持され、その後 idle に戻ります。 |
error | デフォルトでは4秒間保持されます。ポインターがボタン上にある間、またはキーボードフォーカスがある間は、それらが離れてから600ms後までリセットを待ちます。 |
- リクエストの実行中に
track()を呼んでも無視されるため、ダブルクリックや Enter キーの押しっぱなしでリクエストが2回送信されることはありません。 track()に渡した関数が同期的に例外を投げた場合は、reject された promise と同じように扱われます。reset()はすぐに idle に戻ります。破棄されたリクエストがその後に行うことや、コンポーネントのアンマウント後に完了するものは無視されます。- エラーの保持は、実際のマウスのホバーとキーボードフォーカスだけを数えます。タッチにはホバーがなく、クリックによるフォーカスは
:focus-visibleではないため、どちらもエラーを固定しません。
フォーム
onSubmit から track() を呼び出し、送信ボタンに buttonProps を展開します。エラーを確認するには @ を取り除いてください。
ボタンのないステータス
status を読んで任意の UI を駆動します。このメモはフォーカスを失うと保存され、スクリーンリーダーが読み上げる role="status" の領域に、隣に結果を表示します。
resetAfter は両方の結果に対して1つの数値、または個別に設定するオブジェクトを受け取ります。error は最後の reject の理由を保持するので、Button のエラー詳細の例のように、ラベルに表示できます。
- 各ボタンに専用のフックを用意してください。1つの
buttonPropsを2つのボタンで共有すると、どちらも同じステータスを表示します。 onStatusChangeとonErrorは常に最後に渡した関数を呼ぶため、インライン関数でも問題ありません。track()の外側の処理を保護するには、isPending()を使います。ref を読むため、次のレンダリング前でも正確です。
| プロパティ | 型 | デフォルト |
|---|---|---|
resetAfter成功とエラーが idle に戻るまで残る時間。 | number | { success?: number; error?: number } | { success: 2000, error: 4000 } |
onStatusChangeステータスが変わるたびに呼ばれます。 | (status: ButtonStatus) => void | – |
onError拒否の理由とともに呼ばれます。 | (error: unknown) => void | – |
| プロパティ | 説明 |
|---|---|
track(action) | promise、または promise を返す関数を渡します。リクエストの実行中は無視されます。 |
buttonProps | status に加え、ポインターとフォーカスのハンドラー。<Button>、またはそれらのハンドラーを合成するものに展開します。 |
status | "idle" | "loading" | "success" | "error" |
error | 直近の拒否の理由。 |
reset() | すぐに idle に戻り、実行中のリクエストを無視します。 |
isPending() | リクエストが実行中かどうか。 |
feedback prop を通じた Button。