# Bone Flow #046 SplitButton Specification v1.0

Component: #046 SplitButton  
Runtime: `bone-splitbutton.js`  
Implementation version: 1.0.16  
Status: Development

## 1. Authority / reference

#046 is an Action UI component placed after #045 in `000-Development-Order_v1.1.1.md`.
The completed reference is **#042 Button v1.0.12**. #046 must preserve #042's Button rendering/property responsibilities and add only SplitButton-specific behavior.

## 2. Responsibility

A SplitButton is one Action UI with two adjacent interaction regions:

- Primary region: executes the #042 Button action/command semantics.
- Split menu trigger: opens/closes the related action menu without executing the primary action.
- Menu selection: returns the selected menu item through #046 OUT.

The primary region and menu trigger are rendered by the formal #042 `BoneButton` runtime. #046 does not copy #042 Button rendering, #022 effects, #019 image/icon rendering, #039 image selection, or #040 ColorPicker internals.

## 3. Dependencies

- #042 Button v1.0.12: primary/toggle Button rendering and Button state/command semantics.
- #002 Bone Joint v1.1.36: WAIT / FIFO / BLOCKED delivery.
- #017 Bone Text v1.0.34: display responsibility reference inherited from #042.
- #019 Bone Image v1.0.72: image/icon responsibility inherited from #042.
- #039 FilePicker v1.0.2: button image selection inherited from #042.
- #020 Bone Label v1.0.61: common UI / QA / Completion reference inherited from #042.
- #022 Hover Border Effect v1.0.10: Active/focus and mouse-over effects through #042.
- #040 ColorPicker v1.0.15: formal Caller API used by the Property page exactly as #042 does.
- #118 Transition v1.0.3: menu ENTER / EXIT visual interpolation only. #046 owns open/closed semantic state.

## 4. Bone contract

`{ id: string, type: "SPLIT_BUTTON", value: string }`

`value` is the primary Button label. ASCII control characters are rejected.

## 5. Menu item contract

`menuItems` is an array of plain objects. Each item supports:

- `id: string` — unique item id.
- `label: string` — visible label.
- `visible: boolean` — per-item display / hidden state.
- `height: number` — per-item height, normalized by #042 Button.
- `commandId` / `command` — click processing through #042 Command semantics.
- `icon` / `iconPosition` — #019 Image value rendered through #042.
- Active / Mouse Over Effect properties — delegated through #042 to #022.

Getter/accessor properties, duplicate ids, ASCII control characters, and more than 100 items are blocked. Menu selection returns the selected item id through #046 OUT and includes the #042 command result as `menuActionResult` when a menu command executes.

## 6. #042 Button visual / property contract

The primary region keeps #042 v1.0.12 properties and behavior:

- `mode`: normal / command.
- `shape`: normal / square / raised / image.
- `normalColor`: #040 solid + GRADIENT_V1.
- `pressedTextColor`: #040 solid + GRADIENT_V1.
- `normalImage` / `pressedImage`: #039 selection, #019 rendering.
- `icon` / `iconPosition`: #019 Image value, top / bottom / left / right.
- `pressedLabel`, `tooltip`.
- theme / appearance / variant / size.
- Parent inheritance / FIT / 9-direction placement / alignment.
- Active/focus and mouse-over effects via #022.

The split trigger uses the same #042 visual state family and is not implemented with an independent custom Button renderer.


## 6.1 Menu Transition (#118)

#046 owns menu semantic state and #118 owns only the one-shot visual interpolation between states.

- `openMenu()`: #046 sets the menu to displayable/open state, then invokes #118 ENTER.
- `closeMenu()`: #046 sets semantic `menuOpen=false`, invokes #118 EXIT, and only after EXIT completes returns the menu to `hidden`.
- A later ENTER, including after changing the Transition pattern, must redisplay the menu without residual opacity/transform/filter/clip state.

Property contract:

- `menuTransition` — one of the canonical #118 Transition names.
- `menuTransitionDirection` — `up | down | left | right`.
- `menuTransitionSpeed` — `slow | normal | fast`.
- `menuTransitionRespectReducedMotion` — reduced-motion handling delegated to #118.

#046 must not implement its own CSS animation or duplicate #117 Animation / #118 Transition runtime behavior.

## 7. ColorPicker

The test Property page preserves #042's six formal color sources as hidden values with #040 Caller triggers.

- Normal color: solid + gradient.
- Pressed text color: solid + gradient.
- Parent background / text: solid only.
- Active Effect / Mouse Over Effect: solid only.

No #046-owned native `input[type=color]`, HEX picker, palette copy, or #040 internal DOM manipulation is allowed.

## 8. Primary / menu OUT

Primary action OUT:

- `action: "primary"`
- result is the #042 normal/command execution result.

Menu selection OUT:

- `action: "menu"`
- selected item is included as `item`.
- selected item `id` is included as result.

Both are delivered by #046's #002 Delivery Channel.

## 9. Security

`inspectUntrustedInput()` / `applyJointInput()` accept only a safe string in `payload.value`. BLOCKED input preserves the previous primary label.
The Security Test uses a dedicated #046 instance and must not alter the normal Preview or Delivery instance.

## 10. Connection image

The test page keeps the five formal #002 evaluated connection cases from #042:

- normal IN / OUT
- IN Target Field missing
- OUT Target Field missing
- IN type mismatch
- OUT type mismatch

The visual must use #002 `evaluate()` / formal line rendering, not hand-written arrows. Every diagnostic card must keep its line/marker within card bounds and visibly show the connection error code for error cases.

## 11. WAIT / BLOCKED

#046 owns no queue implementation. `connectOutput()` delegates to #002 `createDeliveryChannel()`.

- Target Busy -> WAIT queue.
- Target READY -> FIFO delivery.
- guard reject -> BLOCKED while connection remains visible and Target receives nothing.

Manual WAIT/BLOCK confirmation is independent from Smoke/Validation.

## 12. QA / Completion

Smoke and Validation start NOT RUN. Smoke alone is INCOMPLETE, not ALL PASS.
Completion requires:

- Smoke ALL PASS
- Validation ALL PASS
- Menu item visibility / height / click processing / Icon / Effect checks
- #118 menu ENTER / EXIT and EXIT -> different Transition -> ENTER redisplay check
- Connection Image bounds and visible error-code checks
- WAIT visual confirmation
- BLOCK visual confirmation

Completion UI follows the formal #042 flow and stores #046 state separately under `boneflow.completion.046`.
User localhost confirmation is required before Completed / Specification Frozen.

## 13. HTML Functional Class

Marker: `bone-html-class-use`.
#046 publishes functional classes for all public APIs under `bone-splitbutton-*`. The Guide must execute against dedicated #046 instances and must not mix normal Preview/Security/Delivery state.
