# Bone Flow #039 FilePicker Specification v1.0

Status: Development  
Component: #039 FilePicker  
Version: 1.0.2  
Development Order: `000-Development-Order_v1.1.1.md`

## 1. Responsibility

#039 FilePicker is an Input UI that uses the browser native `input[type=file]` and Drag & Drop to let the user select local files.

Its responsibility is limited to file selection and the selected File metadata contract.

Out of scope:

- OS FileSystem access
- Upload / transfer implementation
- File Manager
- File content Preview
- Editor
- Reading file contents automatically
- Exposing a real local path

## 2. Bone

```text
id   : string
type : FILEPICKER
value: FileMetadata[]
```

`FileMetadata` is serializable data only:

```text
name         : string
size         : finite number >= 0
type         : string
lastModified : finite number >= 0
```

The browser `File` object itself is not stored in Bone.value.
Runtime File references are held only in the component instance and are obtained with `getFiles()`.

## 3. Native input

The actual selection control is `input[type=file]`.

Formal FilePicker properties:

- accept
- multiple
- required
- disabled
- changeCommit
- showSelectionList
- showClearButton
- emptyText
- dropPosition: top / bottom / left / right

The component does not fabricate or restore a native File selection from metadata.
`setValue()` is metadata-state application only; `runtimeFileCount` therefore remains 0 unless the user has selected real files through the browser input.

## 4. Drag & Drop

The FilePicker exposes a dedicated drop zone. Dropped files are processed by the same metadata normalization, `accept`, `multiple`, Security and commit path as native file selection.

- `dragenter` / `dragover` activate the drop visual state.
- `drop` reads only `DataTransfer.files`.
- Dropping does not read file contents, expose a local path or upload automatically.
- `disabled=true` disables drop acceptance.
- Drop source is recorded as `drop` in change / commit events.
- `dropPosition` selects the drop-zone display position: `top` / `bottom` / `left` / `right`.
- The component root and file control are constrained to the Preview/parent width so the selected position does not cause horizontal overflow.

## 5. Common Input UI properties

Preserve the existing Input UI common responsibility:

- Japanese / English Property display
- Theme: default / dark / light / neon
- Background: theme / transparent / explicit #RRGGBB
- Appearance: normal / flat / borderless
- Parent dependency
- width / height
- 9-direction position
- FIT
- input alignment
- #020 Label
- #022 Hover Border Effect
- Security Test
- Connection image
- OUT WAIT / BLOCKED through #002 Bone Joint
- Smoke Test / Validation Report
- JSON / MD Runtime Report
- Completion management

## 6. accept

`accept` follows the browser style token list and supports validation for:

- extension token, e.g. `.txt`
- exact MIME, e.g. `application/pdf`
- wildcard MIME, e.g. `image/*`

An empty accept string means no FilePicker-side type filter.

## 7. multiple

`multiple=false` permits zero or one selected file.
`multiple=true` permits multiple metadata entries.

## 8. Security boundary

The component:

- does not use FileReader
- does not read file contents
- does not expose a real local path
- does not upload automatically
- rejects metadata accessors / unsafe descriptors
- rejects ASCII control characters in filename/type
- rejects non-finite or negative size / lastModified
- preserves the previous state when a browser selection is rejected

Security Sandbox is independent from normal Preview.

The formal Security panel uses the same three-stage Joint image as completed Input UI components: Source / Joint IN → Security Gate → #039 Security Sandbox. `applyJointInput()` actually applies ACCEPTED metadata to the Security Sandbox and preserves its previous value on BLOCKED input. Normal Preview is compared before/after and must remain unchanged.

## 9. OUT

`buildOutput()` returns at least:

```text
componentId
componentName
version
type
source
value
fileCount
runtimeFileCount
runtimeFilesAvailable
accept
multiple
bone
validation
```

OUT delivery is delegated to #002 Bone Joint v1.1.36 `createDeliveryChannel()`.
WAIT / BLOCKED are delivery states and do not change FilePicker responsibility.

Connection image uses #002 Bone Joint actual evaluation/drawing for five cases: normal IN/OUT, IN Target Field missing, OUT Target Field missing, IN type mismatch, OUT type mismatch. WAIT/BLOCK uses the #002 Joint renderer, including WAIT and BLOCK foreground markers while connection remains established.

## 10. QA isolation

Normal Preview, Security Sandbox, WAIT/BLOCK sandbox, Smoke Test and Validation must not share mutable state.
Smoke / Validation are not automatically executed at boot.
Initial state is `NOT RUN`.

## 11. Completion

Completion requires:

1. Smoke Test executed
2. Validation executed
3. Browser Runtime ALL PASS
4. WAIT visual confirmation
5. BLOCK visual confirmation
6. user presses the Completion button

Until the user confirms localhost Browser Runtime and Completion, status remains Development / not frozen.
