金額入力
stimeo--currency-input
桁区切りを自動付与しつつ、送信用には正規化済みの数値を保持する金額入力。
stimeo--currency-input コントローラは、入力中に桁区切り(カンマ)を自動付与し、blur 時に指定の小数桁へ丸めます(整形は Intl.NumberFormat と指定ロケールを利用)。桁区切り付きの文字列は表示用の入力欄に保持し、区切りなしの正規化済み数値は送信用の隠し input に保持します。隠し input は支援技術に露出しないため、正規化済みの実値は aria-describedby から参照する視覚的に隠したテキストにも反映します。ライブラリは挙動のみを提供し、見た目やバリデーションは持ちません。
実行中
円
<%# Markup for the currency-input demo.
stimeo--currency-input formats thousands separators (while typing / on blur) and
rounds decimals, keeping the normalized number in a submit hidden input. It
separates the formatted display from the machine-readable value, and has assistive
tech announce the normalized actual value (srValue) via aria-describedby. %>
<div
class="currency-input"
data-controller="stimeo--currency-input"
data-stimeo--currency-input-locale-value="<%= t("components.currency_input.demo.locale") %>"
data-stimeo--currency-input-currency-value="<%= t("components.currency_input.demo.currency") %>"
data-stimeo--currency-input-precision-value="<%= t(
"components.currency_input.demo.precision"
) %>">
<label class="currency-input__label" for="currency-amount">
<%= t("components.currency_input.demo.label") %>
</label>
<div class="currency-input__field">
<span class="currency-input__symbol" aria-hidden="true">
<%= t("components.currency_input.demo.symbol") %>
</span>
<input
id="currency-amount"
class="currency-input__input"
type="text"
inputmode="decimal"
value="1234.5"
aria-describedby="currency-amount-unit currency-amount-sr"
data-stimeo--currency-input-target="display"
data-action="input->stimeo--currency-input#onInput
blur->stimeo--currency-input#format" />
<span id="currency-amount-unit" class="currency-input__unit">
<%= t("components.currency_input.demo.unit") %>
</span>
</div>
<%# Channel that conveys the normalized actual value to assistive tech (visually hidden). %>
<span id="currency-amount-sr" class="visually-hidden"
data-stimeo--currency-input-target="srValue"></span>
<input type="hidden" name="amount" data-stimeo--currency-input-target="field" />
</div>
/*
* Presentation-only styles for the currency-input demo.
* The library handles the formatting logic; the input and currency-symbol look are
* defined here.
*/
.currency-input {
width: min(20rem, 100%);
}
.currency-input__label {
display: block;
margin-bottom: 0.375rem;
font-weight: 600;
}
.currency-input__field {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0 0.75rem;
border: 1px solid var(--border);
border-radius: 0.5rem;
background: var(--surface, var(--surface-card));
}
.currency-input__field:focus-within {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
.currency-input__symbol,
.currency-input__unit {
color: var(--text-muted, var(--color-text-muted));
}
.currency-input__input {
flex: 1 1 auto;
min-width: 0;
padding: 0.5rem 0;
border: 0;
background: transparent;
font: inherit;
text-align: right;
font-variant-numeric: tabular-nums;
}
.currency-input__input:focus {
outline: none;
}
// Demo that subscribes to the currency-input change event to inspect the normalized
// number that gets submitted. The display uses thousands separators, while the hidden
// input holds the unseparated number.
document.querySelectorAll('[data-controller~="stimeo--currency-input"]').forEach((root) => {
root.addEventListener('stimeo--currency-input:change', (e) => {
// In real use, e.detail.value (the number) feeds form submission or aggregation.
console.log('currency value:', e.detail.value, 'formatted:', e.detail.formatted);
});
});
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。 共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--currency-input"
ターゲット
| 名前 | 説明 | 属性 |
|---|---|---|
display
必須
|
桁区切りした金額を表示する可視テキスト input。唯一の Tab 停止位置。 | data-stimeo--currency-input-target="display" |
field
必須
|
フォーム送信用に機械可読な正規化済み数値を保持する隠し input。 | data-stimeo--currency-input-target="field" |
srValue
|
支援技術へ正規化金額を読み上げる視覚的非表示の span(aria-describedby で参照)。 |
data-stimeo--currency-input-target="srValue" |
値(Values)
| 名前 | 説明 | 属性 |
|---|---|---|
locale
|
桁区切りと小数点に用いる BCP 47 ロケール(既定 en-US)。 |
data-stimeo--currency-input-locale-value |
currency
|
ISO 4217 通貨コード。指定時は SR テキストを通貨表記にする(既定は空)。 | data-stimeo--currency-input-currency-value |
precision
|
blur 時の固定精度丸めに使う小数桁数(既定 2)。 | data-stimeo--currency-input-precision-value |
アクション
| 名前 | 説明 | アクション |
|---|---|---|
format
|
blur 時に固定精度の丸めを適用する。 | stimeo--currency-input#format |
onInput
|
入力中にキャレット位置を保ちつつ桁区切りを再適用する。 | stimeo--currency-input#onInput |
イベント
| 名前 | 説明 | イベント |
|---|---|---|
change
|
確定値が変化したときに発火。detail は { value, formatted }。 |
stimeo--currency-input:change |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
value |
表示用 input | 桁区切り付きの表示文字列。 |
value |
隠し input | 送信用の正規化済み数値(区切りなし)。 |
テキスト |
srValue span | aria-describedby 経由で AT に読み上げさせる正規化済みの実値。 |
data-stimeo--currency-input-empty |
ルート要素 | 値が空のときに付与される手掛かり。 |