スキャン入力ScanInputExperimental
Barcode / QR scan field: a scan gun (or hand entry) types a code then Enter; it fires `onScan`, announces the result, auto-clears and re-focuses for the next scan, and keeps an optional running feed. For POS, stocktake, returns and goods-receiving — scan → match → tick up.
プレビュー
Props
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| onScan | (code: string) => ScanResult | void | - | Fires when a code is committed (scan gun types then Enter, or manual Enter). Return { ok, message } to drive the announcement, tone and feed. |
| label | ReactNode | - | Accessible label rendered above the field. |
| description | ReactNode | - | Helper text rendered under the field. |
| retainFocus | boolean | - | Re-focus the field after each scan so a scan gun fires continuously. Default true. |
| clearOnScan | boolean | - | Clear the field after each scan. Default true. |
| lockMs | number | - | Ignore repeat commits within this many ms (scan guns can double-fire). Default 150. |
| showFeed | boolean | - | Render a running feed of recent scans (newest first). Default false. |
| feedLimit | number | - | Max feed entries retained. Default 8. |
| icon | ReactNode | - | Leading adornment. Defaults to a barcode icon; pass null to hide. |
| assertive | boolean | - | Announce results assertively (role="alert" + aria-live="assertive") instead of politely — for safety-critical scanning where a mismatch must interrupt. Default false. |
| className | string | - | Additional CSS class names on the field wrapper. |
Usage
import { ScanInput, type ScanResult } from "@gunjo/ui"
export function Example() {
function handleScan(code: string): ScanResult {
const line = lines.find((l) => l.jan === code)
if (!line) return { ok: false, message: `発注に無い商品です(${code})` }
increment(line) // your state update
return { ok: true, message: `${line.name} を1点 検品` }
}
return (
<ScanInput
label="バーコード / JAN をスキャン"
placeholder="コードを入力して Enter"
inputMode="numeric"
onScan={handleScan}
showFeed
/>
)
}