# #031 TimeBox — 操作・HTML Functional Class

## 0. このDOCの前提

この説明は **UI-031 / BoneTimeBox v1.0.9** を対象にする。DOC Integration は既存Runtimeを置き換えない。時刻の入力・編集・確定・Validation・Security・OUT・WAIT/FIFO/BLOCKEDは #031 が保持し、時刻選択UIは、正式完了した #026 TimePicker DOC Integration v1.0.6 / BoneTimePicker v1.0.17へ委譲する。

`Runtime` はブラウザ上で実際に動く `BoneTimeBox` JavaScript本体、`root` は `BoneTimeBox.create(...)` が返すTimeBoxの実DOM要素、`commit` は編集中の値を確定値へ移す操作、`WAIT/FIFO/BLOCKED` は #002 Joint Delivery Channelの配送状態を意味する。

[[BF-TIMEBOX-SAMPLE:contract]]

上の **Runtime Contract** は、現在ロードされている `BoneTimeBox.defaults()` とfunction一覧を実Runtimeから取得する。DOC本文とRuntimeの差を隠すための固定リストではない。

## 1. 基本操作

1. TimeBoxをクリックまたはフォーカスして時刻を編集する。
2. 時刻アイコン／TimePickerを使用する場合、#026 TimePickerが候補を表示し、選択時刻を #031へRETURNする。
3. #031はRETURNされた値を自身のeditingValueへ反映し、自身のValidation/commit規則に従って確定する。
4. OUT接続済みなら確定値を#002 Delivery Channelへ渡す。Target BusyならWAITしてFIFO順に保持し、BLOCKEDなら配送しない。

[[BF-TIMEBOX-SAMPLE:basic]]

## 2. 時刻値

正式なPicker責務境界では、時は `00～23`、分はminute stepを適用、秒は `00～59`。HTML Functional Classでは空値、`HH:mm`、`HH:mm:ss` を受け付ける。範囲外の時分秒はFunctional Classの入口で拒否する。

[[BF-TIMEBOX-SAMPLE:seconds]]

### min / max

`min` は選択可能な最小時刻、`max` は最大時刻。`min <= max` の範囲で使う。#031は #026固有Property `showOutOfRangeHours` を重複実装せず、正式#026の既定値 `false` をそのまま使用する。例えば `min=08:00 / max=18:00` なら**時列**は `08`～`18` だけがDOMへ生成され、`00`～`07` と `19`～`23` は時候補DOMに存在しない。一方、**分列はminute stepだけで生成**されるため、境界時でもstep候補自体は削除しない。min/max外になる境界分は #026 Validationにより選択不可になる。秒表示時も秒列は `00`～`59` を維持し、境界秒は #026 Validationで選択不可になる。DOC Integrationは候補DOMをhidden/display/disabled等で後処理しない。Guide監査では #031 と #026 の `min / max / step`、#026の `showOutOfRangeHours=false`、実候補列を**読むだけ**で照合する。#026の候補Panelは`document.body`直下へPortalされるため、候補列は正式API `BoneTimePicker.getPanel(picker)` が返すPanelから取得する。取得不能なら `UNRESOLVED`、契約不一致なら `MISMATCH` とする。

[[BF-TIMEBOX-SAMPLE:minmax]]

### step

正式TimePicker連携のminute step候補は **1 / 5 / 10 / 15 / 30**。stepは**分列へ適用する分単位**で、min/maxによってstep候補をDOC側で削らない。秒は00～59の独立列として扱い、stepを秒へ適用しない。

HTML Functional Classでは **`data-step` を正式指定**として使用する。Guideの実Live Sampleはブラウザ標準 `input[type=time]` を使わない。`bf-timebox` はHTMLアンカーから正式 `BoneTimeBox v1.0.9` を生成し、時刻選択は **BoneTimeBox自身が所有する #026 TimePicker** だけを使用する。

5値を個別に確認できるLive Runtime。**Runtimeの `getOptions().step` が一致するだけではPASSにしない。TimeBox自身の時計アイコンから正式#026を開き、可視分候補まで一致することを確認する。DOC側は別Pickerを生成しない。**

- `step=1` → `00～59`（60候補）
- `step=5` → `00 / 05 / 10 / 15 / 20 / 25 / 30 / 35 / 40 / 45 / 50 / 55`
- `step=10` → `00 / 10 / 20 / 30 / 40 / 50`
- `step=15` → **`00 / 15 / 30 / 45`**
- `step=30` → `00 / 30`

各Live Sampleでは**TimeBox自身の時計アイコン**から正式#026を開く。DOC専用の開閉ボタンや別Pickerは作らない。正式#026を取得できない場合はFAILとして表示する。


[[BF-TIMEBOX-SAMPLE:step1]]
[[BF-TIMEBOX-SAMPLE:step5]]
[[BF-TIMEBOX-SAMPLE:step10]]
[[BF-TIMEBOX-SAMPLE:step15]]
[[BF-TIMEBOX-SAMPLE:step30]]

### PreviewとGuideのstep同期確認

Guideの通常Live Sampleは、完成済み#030と#031初期DOCと同じく、**各サンプルが明示したHTML Functional Class属性だけで独立生成する。** 基本・秒・min/max・step 1/5/10/15/30・required・disabled・readonly・theme・position・#026 RETURNは、元Previewが取得できなくても生成・操作できなければならない。Preview探索失敗を理由にこれらのLive Sampleを止めない。

Previewとの同期確認は `previewLinked` **1件だけ**が担当する。このサンプルだけ、元TimeBox Previewの `value / step / min / max / theme / backgroundColor / appearance / position / width / height / inputAlign / font / pickerVisual / Boolean系` など、Functional Classへ写せるPropertyを取得してGuide側へ反映し、全件比較する。Preview rootはRuntimeの `getOptions()` で実instanceとして読めるDOMから解決し、`isInstance()` が存在するRuntimeではそのAPIも利用する。特定CSS class名をPreview identityとして必須にはしない。

`previewLinked` ではstep値だけでなく、Guide側TimeBoxが所有する正式#026の**可視分候補**も読み取り監査する。Previewが `step=15` なら #031→#026 のstep受け渡しが一致し、正式#026分列が `00 / 15 / 30 / 45` でなければFAILとする。Guide内でユーザーが候補を選択した直後はPreview値へ強制再同期せず、選択後状態を保持して監査する。`document.body`直下の#026 Panel上のクリックも、そのGuide Live Sample自身の操作として扱う。

元Previewを取得できない場合、`previewLinked` だけは `TIMEBOX_DOC_PREVIEW_NOT_FOUND` を表示して同期を偽装しない。**他の独立Live Sampleにはこのエラーを波及させない。**

[[BF-TIMEBOX-SAMPLE:previewLinked]]

## 3. HTML Functional Class `bf-timebox`

通常利用では、既存HTML要素へ `bf-timebox` を付ける。

```html
<input class="bf-timebox" value="09:30">
```

Functional Classは元inputをアンカーとして保持し、BoneTimeBox v1.0.9を実DOMとして生成する。Runtimeのcommit/changeで確定値が変わった時は元inputのvalueへ同期する。

### Boolean

- `data-disabled="true|false"`: trueは操作不可、falseは操作可能。
- `data-readonly="true|false"`: trueは表示のみでユーザー編集を抑止する。
- `data-required="true|false"`: trueは空値をValidationエラー対象にする。
- `data-enter-commit="true|false"`: Runtimeに同名Propertyがある時だけ渡す。
- `data-blur-commit="true|false"`: Runtimeに同名Propertyがある時だけ渡す。
- `data-select-on-focus="true|false"`: Runtimeに同名Propertyがある時だけ渡す。
- `data-inherit-parent="true|false"`: true時は親要素追従をRuntimeへ要求する。
- `data-show-hour / data-show-minute / data-show-second`: Runtimeが同Propertyを持つ時だけ渡す。存在しないPropertyはFunctional Classが勝手に追加しない。

無効なBoolean文字列は `TIMEBOX_FUNCTIONAL_CLASS_BOOLEAN_INVALID`。時刻形式不正は `TIMEBOX_FUNCTIONAL_CLASS_VALUE_INVALID`。minute stepが `1 / 5 / 10 / 15 / 30` 以外なら `TIMEBOX_FUNCTIONAL_CLASS_STEP_INVALID`。

[[BF-TIMEBOX-SAMPLE:required]]
[[BF-TIMEBOX-SAMPLE:disabled]]
[[BF-TIMEBOX-SAMPLE:readonly]]

## 4. 表示Property

### theme / backgroundColor / appearance

これらはRuntime `defaults()` に同名Propertyが存在する場合だけFunctional Classから渡す。テーマの実列挙値・既定値は上部Runtime Contractが正本であり、DOC Integrationが別仕様を作らない。

[[BF-TIMEBOX-SAMPLE:themeDark]]

### position 9値

Bone Flowの正式9方向配置は次の意味で使用する。

- `top-left`: 左上 (`justify-self:start / align-self:start`)
- `top-center`: 上中央 (`center / start`)
- `top-right`: 右上 (`end / start`)
- `middle-left`: 左中央 (`start / center`)
- `center`: 中央 (`center / center`)
- `middle-right`: 右中央 (`end / center`)
- `bottom-left`: 左下 (`start / end`)
- `bottom-center`: 下中央 (`center / end`)
- `bottom-right`: 右下 (`end / end`)

`inheritParent=true` の場合は親追従がpositionより優先する。

[[BF-TIMEBOX-SAMPLE:position]]

### inputAlign

`auto / left / center / right` をRuntimeが持つ場合、そのままRuntimeへ渡す。どの値を既定とするかは `BoneTimeBox.defaults()` を確認する。DOC側で別のDefaultへ上書きしない。

### Font FIT

`fontSizeMode=fit` がRuntimeに存在する場合は利用可能領域に合わせて文字サイズを計算する。`fixed` が存在する場合は `fontSize` を使用する。許容範囲は実Runtimeのnormalizerが最終判定する。

### Active Border Effect

`activeBorderEffect / activeEffectColor / activeEffectDirection / activeEffectSpeed` がRuntimeに存在する場合、フォーカス中の枠Effectへ反映する。#022 Hover Border Effectの責務をDOC側へ複製しない。

> #031のmin/max可視契約: 正式#026 TimePicker v1.0.17をそのまま使用します。#031は候補DOMを加工しません。`showOutOfRangeHours=false` のとき min=08:00 / max=18:00 の**時列**は 08～18 のみDOM生成されます。**分列**はstepに従い、step=15なら常に 00 / 15 / 30 / 45 を生成し、境界でmin/max外になる分は #026 Validationが選択不可にします。秒列は表示時00～59です。

## 5. #026 TimePicker連携

#026は **Picker UI、候補生成・表示、候補Validation、選択時刻RETURN**を担当する。#031の入力値管理、commit、Security、OUT、WAIT/FIFO/BLOCKEDを#026へ移してはいけない。

[[BF-TIMEBOX-SAMPLE:picker]]

Pickerで候補を選んだ後は、#031側のeditingValue / committedValue / Validationを確認する。TimePickerが開いたことだけをPASS条件にしない。

## 6. Security

Securityは「不正な入力を安全に拒否し、既存の確定値を壊さない」ための境界。文字列化の副作用、getter/setter、Proxy trap、過大入力などの扱いは **BoneTimeBox v1.0.9 Runtimeの実装が正本**。Functional ClassはRuntime Securityを緩和しない。

不正入力時に確認する項目:

- エラーコード
- 拒否された経路（HTML、通常入力、Joint IN、API）
- committedValueが保持されたか
- OUTへ不正値が出ていないか
- BLOCKED表示とDelivery状態が一致するか

## 7. WAIT / FIFO / BLOCKED

- **WAIT**: Target Busyでも接続を維持し、値をQueueへ積む。Target Ready後にFIFO順で配送する。
- **FIFO**: 先にWAITへ入った確定値から先に配送する。
- **BLOCKED**: 接続は維持するが対象値を配送しない。理由/状態をUIとRuntime stateの両方で確認する。

WAIT/BLOCKEDは装飾ではなく、#002 Delivery Channelの実状態として検証する。

## 8. Public API

Public APIの正確なfunction一覧は上部Runtime Contractで実Runtimeから取得する。APIを呼ぶ前に対象rootが有効なBoneTimeBox instanceか確認する。

代表的な確認観点:

- `create`: TimeBox root生成。生成前はDOMなし、生成後は入力/Preview/Picker連携DOMが存在する。
- `getValue / getEditingValue / getCommittedValue`: 表示中・編集中・確定値を混同しない。
- `setValue`: APIから値を設定。emit/sourceの扱いは実Runtime契約に従う。
- `setOptions`: Property変更。無効値はRuntimeのErrorとして処理し、DOC側で握り潰さない。
- `validate / commit`: Validationと確定を分離して確認する。
- `applyJointInput`: Untrusted INの受理/拒否と既存値保持を確認する。
- `connectOutput / setTargetReady / clearOutputBlock`: WAIT/FIFO/BLOCKEDを#002と連動させる。
- `destroy`: DOM、Picker、listener、Delivery Channelの残骸を残さない。

API名が現在のv1.0.9に存在しない場合は、Runtime Contractの実一覧を優先する。

## 9. Error Code

このDOC Integration自身が追加するError Code:

- `TIMEBOX_FUNCTIONAL_CLASS_RUNTIME_MISSING`: BoneTimeBox v1.0.9が先にロードされていない。
- `TIMEBOX_FUNCTIONAL_CLASS_ANCHOR_INVALID`: `bf-timebox`をElement以外へ使った、またはClassがない。
- `TIMEBOX_FUNCTIONAL_CLASS_BOOLEAN_INVALID`: Boolean属性値がtrue/false系でない。
- `TIMEBOX_FUNCTIONAL_CLASS_VALUE_INVALID`: 空/HH:mm/HH:mm:ss以外、または範囲外。
- `TIMEBOX_FUNCTIONAL_CLASS_STEP_INVALID`: minute stepが1/5/10/15/30以外。既存Runtimeへ渡す前に拒否する。

BoneTimeBox Runtime本体のError Codeは実Runtimeが正本。DOC Integrationは `TIMEBOX_*` を推測追加しない。Runtimeで発生したErrorはコードとmessageをそのまま確認する。

## 10. 回帰確認

DOC Integration後も次を壊してはいけない。

- 元のTimeBox PreviewとProperty Editor
- PreviewとGuide `previewLinked` の全マップProperty一致
- stepのRuntime値だけでなく、#026 TimePicker可視分候補の完全一致（例: step=15 → 00 / 15 / 30 / 45）
- #026 TimePicker RETURN
- Security Test
- 接続イメージ
- OUT WAIT / FIFO / BLOCKED
- Smoke Test / Validation Report
- Runtime Console
- Completion
- JP / EN
- #022 Hover Border Effect等の既存依存

Shared DOC (`bone-doc-loader.js / bone-doc-guide.js / bone-doc-guide.css`) は#031都合で変更しない。Guideでブラウザ標準Pickerや#026模造DOMを作ることも禁止する。
