@rogieking/figui3 11.4.2 → 11.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,18 +2,18 @@
2
2
  name: fig-editor
3
3
  description: >-
4
4
  Guides FigUI3 editor bundle (`fig-editor.js` / `fig-editor.css`): fig-select,
5
- fig-select-options, fig-select-option, fig-fill-picker, fig-palette-editor,
6
- fig-reorder, and fig-interpolation-swatch,
5
+ fig-select-options, fig-select-option, fig-property, fig-input-point,
6
+ fig-fill-picker, fig-palette-editor, fig-gradient-editor, fig-reorder, and fig-interpolation-swatch,
7
7
  including React JSX usage. Use when building custom selects, grouped option lists,
8
- sticky separators, ghost selects, fill picker dialogs, reorderable lists, or
9
- interpolation swatches.
8
+ sticky separators, ghost selects, composable property rows, fill picker dialogs,
9
+ reorderable lists, or interpolation swatches.
10
10
  Requires fig.js.
11
11
  user-invocable: false
12
12
  ---
13
13
 
14
14
  # FigUI3 editor (`fig-editor.js`)
15
15
 
16
- Custom select and full fill-picker. Not in core `fig.js`.
16
+ Custom selects, property rows, point inputs, and full fill editing. Not in core `fig.js`.
17
17
 
18
18
  React: [../figui3/react.md](../figui3/react.md). Per-tag JSX: [components.md](components.md). Attrs: [reference.md](reference.md).
19
19
 
@@ -37,7 +37,10 @@ Registered tags:
37
37
  | `fig-select-options` | Scrollable panel (`slot="panel"`), overflow chevrons |
38
38
  | `fig-select-option` | Option (`value`, `label`, `selected`, `disabled`, `subtle`) |
39
39
  | `fig-fill-picker` | Full fill editor dialog (solid, gradient, image, video, webcam, custom modes) |
40
+ | `fig-property` | Composable property row with leading, input, and trailing slots |
41
+ | `fig-input-point` | Paired X/Y numeric point input |
40
42
  | `fig-palette-editor` | Ordered palette editor |
43
+ | `fig-gradient-editor` | Full gradient editor with reorderable stops |
41
44
  | `fig-reorder` | Pointer- and keyboard-reorderable direct-child list |
42
45
  | `fig-interpolation-swatch` | Gradient interpolation preview swatch |
43
46
 
@@ -55,7 +58,7 @@ Do not use `picker` or `picker-anchor` on `fig-input-color`. Forward picker chro
55
58
 
56
59
  ## Maintainer notes
57
60
 
58
- - Implementation: `fig-editor.js`, styles: `fig-editor.css`
61
+ - Implementation: `fig-editor.js` / `fig-editor.css`; property row: `fig-property.js` / `fig-property.css` (imported by the editor bundle)
59
62
  - Do not move fill-picker or select into `fig.js`
60
63
  - Nested overlay positioning: keep `popover="manual"` on the select popup
61
64
  - Tests: `tests/figui/component-contracts.spec.ts` (ghost variant, sticky separator vs overflow-start)
@@ -66,6 +66,91 @@ Data-driven (no authored options):
66
66
  - Attrs: `value` (falls back to trimmed `textContent`), `label` (closed-trigger text when content is rich), `selected`, `disabled`, `subtle` (secondary hover/focus fill)
67
67
  - `role="option"`, `aria-selected`, `aria-disabled`
68
68
 
69
+ ## `fig-input-point`
70
+
71
+ ```tsx
72
+ <fig-input-point
73
+ x={String(point.x)}
74
+ y={String(point.y)}
75
+ units="%"
76
+ full
77
+ onInput={onInput}
78
+ onChange={onChange}
79
+ />
80
+ ```
81
+
82
+ - Attrs: `x`, `y`, `units` (forwarded to both number inputs), `full`
83
+ - Renders two equally sized `fig-input-number` controls in a `fig-input-combo`.
84
+ - Events: `input` while editing and `change` on commit, with `{ x, y }`.
85
+
86
+ ## `fig-property`
87
+
88
+ Default playground example (`/figui3#property/default`):
89
+
90
+ ```html
91
+ <fig-property label="Size">
92
+ <fig-input-number
93
+ slot="input"
94
+ value="16"
95
+ units="px"
96
+ steppers="true"
97
+ full
98
+ ></fig-input-number>
99
+ </fig-property>
100
+ ```
101
+
102
+ Generated accessories:
103
+
104
+ ```html
105
+ <fig-property
106
+ label="Color"
107
+ leading="drag"
108
+ trailing="remove"
109
+ show-leading="hover"
110
+ show-trailing
111
+ >
112
+ <fig-input-color slot="input" value="#0D99FF" text="true" full></fig-input-color>
113
+ </fig-property>
114
+ ```
115
+
116
+ Authored trailing accessory (`/figui3#property/custom-accessory`):
117
+
118
+ ```html
119
+ <fig-property label="Opacity" show-trailing>
120
+ <fig-slider slot="input" value="75" min="0" max="100" units="%" text="true" full></fig-slider>
121
+ <fig-button slot="trailing" variant="ghost" icon aria-label="Reset opacity">
122
+ <fig-icon name="reset"></fig-icon>
123
+ </fig-button>
124
+ </fig-property>
125
+ ```
126
+
127
+ - Attrs: `label`, `leading` (`drag` | `chevron`), `trailing` (`remove` | `add` | `bind`), `show-leading`, `show-trailing`
128
+ - Slots: `input` (one direct primary control), `label`, `leading`, `trailing`
129
+ - Authored label markup overrides the `label` attribute.
130
+ - Authored accessory slots override generated shortcuts.
131
+ - Omitted or `"hover"` show attributes use hover visibility; `"false"` never shows the slot; an empty/present attribute always shows it.
132
+ - Generated trailing controls emit bubbling, composed `remove`, `add`, or `bind` events with the slotted control in `detail.input`.
133
+ - Child input events bubble unchanged.
134
+
135
+ ## `fig-popup-easing`
136
+
137
+ Reusable easing dialog with an internal
138
+ `<fig-easing-curve aspect-ratio="4/3">`.
139
+
140
+ ```html
141
+ <fig-button id="easing-trigger">Edit easing</fig-button>
142
+ <dialog
143
+ is="fig-popup-easing"
144
+ anchor="#easing-trigger"
145
+ value="0.42, 0, 0.58, 1"
146
+ open
147
+ ></dialog>
148
+ ```
149
+
150
+ - Attrs: `value`, `mode`, `precision`, `edit`, `presets`, `text`, plus inherited `fig-popup` attributes.
151
+ - Events: bubbling `input` / `change` forwarded from the easing curve.
152
+ - Create it as `<dialog is="fig-popup-easing">`, not `<fig-popup-easing>`.
153
+
69
154
  ## `fig-palette-editor`
70
155
 
71
156
  Reusable ordered palette editor used by `fig-input-palette edit="picker"`.
@@ -83,6 +168,63 @@ Reusable ordered palette editor used by `fig-input-palette edit="picker"`.
83
168
  - Events: `input` / `change` with the normalized ordered color array in `detail`
84
169
  - Uses `fig-reorder` for pointer and keyboard reordering.
85
170
 
171
+ ## `fig-gradient-editor`
172
+
173
+ Reusable full gradient editor used by the Gradient tab in `fig-fill-picker`.
174
+
175
+ ```tsx
176
+ <fig-gradient-editor
177
+ value='{"type":"linear","angle":90,"stops":[{"position":0,"color":"#0D99FF","opacity":100},{"position":100,"color":"#9747FF","opacity":100}]}'
178
+ onInput={onInput}
179
+ onChange={onChange}
180
+ />
181
+ ```
182
+
183
+ - Attrs: `value`, `color-space` (`srgb` | `display-p3`), `disabled`.
184
+ - Property: `value` is the normalized gradient config; `cssValue` is the rendered CSS gradient.
185
+ - Property: `pickerAnchor` accepts an element used to anchor nested stop color pickers.
186
+ - Events: `input` / `change` with `{ type: "gradient", gradient, css }`.
187
+ - Includes type, flip/rotate, stop bar, add/remove, and pointer/keyboard reorder controls.
188
+
189
+ ## `fig-popup-gradient`
190
+
191
+ Reusable popup containing one `fig-gradient-editor`. It is the picker opened by
192
+ `fig-input-gradient edit="picker"`.
193
+
194
+ ```html
195
+ <fig-button id="gradient-trigger">Edit gradient</fig-button>
196
+ <dialog
197
+ is="fig-popup-gradient"
198
+ anchor="#gradient-trigger"
199
+ value='{"type":"linear","angle":90,"stops":[{"position":0,"color":"#0D99FF","opacity":100},{"position":100,"color":"#9747FF","opacity":100}]}'
200
+ open
201
+ ></dialog>
202
+ ```
203
+
204
+ - Attrs: `value`, `color-space`, `disabled`, plus inherited `fig-popup` attributes.
205
+ - Events: bubbling `input` / `change` with `{ type: "gradient", gradient, css }`.
206
+ - Create it as `<dialog is="fig-popup-gradient">`.
207
+
208
+ ## `fig-popup-palette`
209
+
210
+ Reusable palette dialog used by `fig-input-palette edit="picker"`. It extends
211
+ `fig-popup` and owns its `fig-palette-editor`.
212
+
213
+ ```html
214
+ <fig-button id="palette-trigger">Edit palette</fig-button>
215
+ <dialog
216
+ is="fig-popup-palette"
217
+ anchor="#palette-trigger"
218
+ value='["#94BD00","#83AD00","#1A632A","#003905"]'
219
+ open
220
+ ></dialog>
221
+ ```
222
+
223
+ - Attrs: `value`, `min`, `max`, `fixed`, `disabled`, plus inherited `fig-popup` attributes.
224
+ - Property: `value` returns the normalized `{ color, alpha }[]`.
225
+ - Events: bubbling `input` / `change` with the normalized color array in `detail`.
226
+ - Create it as `<dialog is="fig-popup-palette">`, not `<fig-popup-palette>`.
227
+
86
228
  ## `fig-reorder`
87
229
 
88
230
  ```tsx
@@ -35,6 +35,40 @@ Position: omit to overlay the selected option on the trigger. Set to place the m
35
35
 
36
36
  Events: `input`, `change`, `optionhover`, `optionfocus`.
37
37
 
38
+ ## Input point
39
+
40
+ `fig-input-point` observes `x`, `y`, and `units`.
41
+
42
+ - Missing or invalid coordinates resolve to `0`.
43
+ - The generated X/Y `fig-input-number` controls stay synchronized with the host attributes.
44
+ - `units` is forwarded to both generated number inputs and removed from both when omitted.
45
+ - `input` and `change` events provide numeric `{ x, y }` in `detail`.
46
+ - `full` makes the host fill its parent.
47
+
48
+ ## Property
49
+
50
+ `fig-property` observes `label`, `leading`, `trailing`, `show-leading`, and `show-trailing`.
51
+
52
+ - Direct slots: `input`, `label`, `leading`, `trailing`
53
+ - Authored `slot="label"` markup takes precedence over the `label` attribute.
54
+ - `leading`: `drag` or `chevron`
55
+ - `trailing`: `remove`, `add`, or `bind`
56
+ - `show-leading` / `show-trailing`: omitted or `hover` reveals on hover, `false` hides, and an empty attribute always shows
57
+ - Authored accessory slots override generated shortcuts.
58
+ - `input` returns the direct `slot="input"` element.
59
+ - Generated labels associate to the input with `aria-labelledby` unless it already has an accessible name.
60
+ - Generated trailing events bubble across shadow roots with `detail: { input }`.
61
+ - Child control events are not normalized or re-emitted.
62
+
63
+ ## Easing popup
64
+
65
+ `dialog[is="fig-popup-easing"]` extends `fig-popup` and owns a
66
+ `fig-easing-curve` with `aspect-ratio="4/3"`.
67
+
68
+ - Observes and forwards `value`, `mode`, `precision`, `edit`, `presets`, and `text`.
69
+ - Forwards bubbling `input` / `change` events and reflects the current easing value.
70
+ - Defaults: `position="bottom left"`, `offset="0 8"`, `viewport-margin="8"`, and `popover="manual"`.
71
+
38
72
  ## Reorder
39
73
 
40
74
  `fig-reorder` observes `axis`, `handle`, `items`, `indicator`, and `disabled`.
@@ -53,6 +87,34 @@ Events: `input`, `change`, `optionhover`, `optionfocus`.
53
87
  - `value` property and `input` / `change` event `detail`: normalized ordered `{ color, alpha }[]`
54
88
  - Rows are direct `fig-reorder` items and support pointer or keyboard reordering.
55
89
 
90
+ ## Gradient editor
91
+
92
+ `fig-gradient-editor` observes `value`, `color-space`, and `disabled`.
93
+
94
+ - `value` accepts a gradient config or `{ type: "gradient", gradient }` and returns a normalized gradient config.
95
+ - `cssValue` returns the current CSS gradient.
96
+ - `pickerAnchor` anchors nested stop color pickers.
97
+ - Bubbling `input` / `change` detail is `{ type: "gradient", gradient, css }`.
98
+ - Interpolation remains locked to sRGB to match the fill picker’s current behavior.
99
+
100
+ ## Gradient popup
101
+
102
+ `dialog[is="fig-popup-gradient"]` extends `fig-popup`, owns a
103
+ `fig-gradient-editor`, and observes `value`, `color-space`, and `disabled`.
104
+
105
+ - Defaults: `position="bottom left"`, `offset="0 8"`, `viewport-margin="8"`, and `popover="manual"`.
106
+ - Bubbling `input` / `change` detail is `{ type: "gradient", gradient, css }`.
107
+
108
+ ## Palette popup
109
+
110
+ `dialog[is="fig-popup-palette"]` extends `fig-popup`, owns a
111
+ `fig-palette-editor`, and observes `value`, `min`, `max`, `fixed`, and
112
+ `disabled` in addition to inherited popup attributes.
113
+
114
+ - `value` property and bubbling `input` / `change` detail are normalized `{ color, alpha }[]`.
115
+ - Defaults: `position="bottom left"`, `offset="0 8"`, `viewport-margin="8"`, and `popover="manual"`.
116
+ - Import through `fig-editor.js`; create it with `document.createElement("dialog", { is: "fig-popup-palette" })` or matching HTML.
117
+
56
118
  ## Fill picker modes
57
119
 
58
120
  Built-in: `solid`, `gradient`, `image`, `video`, `webcam`.
@@ -170,7 +170,7 @@ Handlers below assume `onInput` / `onChange` / `onClick` from [react.md](react.m
170
170
 
171
171
  - Attrs: `preview`, `label`, `accepts`, `multiple`, `disabled`, `variant` (forwards `fig-button` variants; defaults to `property`)
172
172
  - Blank or omitted `label` defaults to `Upload audio`, `Upload image`, or `Upload file` based on the known file type. An explicit label overrides it.
173
- - `preview` renders supported image extensions in a full-width checkerboard `fig-image` at `4/3`, or turns known audio files into play/pause buttons with a waveform and filename tooltip.
173
+ - For known audio files, `preview` shows the audio icon and filename at rest, reveals play and waveform controls on hover/focus, and keeps pause plus waveform visible while playing.
174
174
  - `accepts` controls the native chooser filter; file icons and previews are detected independently.
175
175
  - Events: `change` / `input` with files on the host
176
176
 
@@ -321,6 +321,7 @@ Handlers below assume `onInput` / `onChange` / `onClick` from [react.md](react.m
321
321
  ```
322
322
 
323
323
  - Attrs: `value`, `edit`, `mode` (`handle` | `tip`), `disabled`
324
+ - `edit="picker"` opens `dialog[is="fig-popup-gradient"]` when `fig-editor.js` is loaded.
324
325
 
325
326
  ### `fig-swatch`
326
327
 
@@ -358,6 +359,7 @@ Handlers below assume `onInput` / `onChange` / `onClick` from [react.md](react.m
358
359
  ```
359
360
 
360
361
  - Attrs: `direction` (`horizontal` | `vertical`), `label`, `columns`
362
+ - Slots: `leading` for an accessory before the label; `trailing` for an end action.
361
363
  - Put control attrs on the control, not the field.
362
364
 
363
365
  ### `fig-stack`
@@ -712,6 +714,10 @@ toastRef.current?.showToast();
712
714
  Set `mode="bezier"` or `mode="spring"` to constrain the editor and preset list
713
715
  to one curve type.
714
716
 
717
+ With `edit="false"`, the compact preset control opens `fig-popup-easing` when
718
+ `fig-editor.js` is loaded; without the editor bundle it retains the preset
719
+ dropdown fallback.
720
+
715
721
  ### `fig-3d-rotate`
716
722
 
717
723
  ```tsx
@@ -80,8 +80,11 @@ type FigTag =
80
80
  | "fig-input-fill"
81
81
  | "fig-input-gradient"
82
82
  | "fig-input-number"
83
+ | "fig-input-point"
83
84
  | "fig-input-palette"
84
85
  | "fig-palette-editor"
86
+ | "fig-gradient-editor"
87
+ | "fig-property"
85
88
  | "fig-input-text"
86
89
  | "fig-input-wheel"
87
90
  | "fig-interpolation-swatch"
@@ -64,6 +64,8 @@ Public API: `README.md`. React recipes: [components.md](components.md).
64
64
 
65
65
  - `direction="horizontal|vertical"`
66
66
  - `label` or a child `<label>`
67
+ - `slot="leading"` places an accessory before the label
68
+ - `slot="trailing"` places an end action in the input area
67
69
 
68
70
  ## `fig-toolbelt`
69
71
 
package/CHANGELOG.md CHANGED
@@ -2,6 +2,43 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [11.6.0]
6
+
7
+ ### Added
8
+
9
+ - Added reusable `fig-gradient-editor`, `fig-popup-gradient`, `fig-popup-palette`, and `fig-popup-easing` editor components.
10
+ - Added package source files, playground examples, tests, manifests, typings, and skill documentation for the new editor components.
11
+
12
+ ### Changed
13
+
14
+ - Rebuilt the fill picker’s gradient tab with `fig-gradient-editor`.
15
+ - Routed gradient, palette, and compact easing picker modes through their dedicated reusable popups.
16
+ - Refined audio file previews to show the filename at rest, waveform controls on hover, and persistent playback state with focus styling.
17
+
18
+ ### Fixed
19
+
20
+ - Kept gradient and easing popup values, trigger previews, and selected preset labels synchronized while editing.
21
+
22
+ ## [11.5.0]
23
+
24
+ ### Added
25
+
26
+ - Added the composable `fig-property` editor row with generated leading/trailing accessories, visibility controls, accessible labels, and action events.
27
+ - Added `fig-input-point` for paired X/Y numeric values.
28
+ - Added standalone `fig-property.js` and `fig-property.css` package exports and editor skill guidance.
29
+
30
+ ### Changed
31
+
32
+ - Rebuilt palette editor rows and fill-picker gradient stop rows with `fig-property`.
33
+ - Expanded playground editor controls, property examples, event output, and direct hash loading.
34
+ - Updated easing preset artwork to use `fig-icon` prepend content and added the drag-handle icon token.
35
+ - Refined `fig-field` leading/trailing slot handling and property-row hover layout.
36
+
37
+ ### Fixed
38
+
39
+ - Kept hover-only trailing property actions from reserving space or shifting the input.
40
+ - Made generated property actions bubble across shadow roots with their slotted input in event detail.
41
+
5
42
  ## [11.4.2]
6
43
 
7
44
  ### Changed
package/README.md CHANGED
@@ -108,13 +108,18 @@ Minimal example:
108
108
  | [Input Wheel](#input-wheel) | `<fig-input-wheel>` | Standalone SVG tick-and-handle numeric scrubber |
109
109
  | [Text Input](#text-input) | `<fig-input-text>` | Styled text/textarea input |
110
110
  | [Number Input](#number-input) | `<fig-input-number>` | Numeric input with units |
111
+ | [Input Point](#input-point) | `<fig-input-point>` | Paired X/Y numeric input |
111
112
  | [File Input](#file-input) | `<fig-input-file>` | File upload with image previews and audio playback waveforms |
112
113
  | [Angle](#angle) | `<fig-angle>` | Instrument-style angle/rotation dial |
113
114
  | [Swatch](#swatch) | `<fig-swatch>` | Color/gradient/image swatch |
114
115
  | [Color Tip](#color-tip) | `<fig-color-tip>` | Compact color tip with picker |
115
116
  | [Color Input](#color-input) | `<fig-input-color>` | Color picker with hex/alpha |
116
117
  | [Input Palette](#input-palette) | `<fig-input-palette>` | Editable multi-color palette |
118
+ | [Property](#property) | `<fig-property>` | Composable editor property row |
117
119
  | [Palette Editor](#palette-editor) | `<fig-palette-editor>` | Reusable reorderable palette editor |
120
+ | [Gradient Editor](#gradient-editor) | `<fig-gradient-editor>` | Full gradient editor with reorderable stops |
121
+ | [Gradient Popup](#gradient-popup) | `<dialog is="fig-popup-gradient">` | Reusable full gradient editor popup |
122
+ | [Palette Popup](#palette-popup) | `<dialog is="fig-popup-palette">` | Reusable palette editor popup |
118
123
  | [Reorder](#reorder) | `<fig-reorder>` | Pointer- and keyboard-reorderable list |
119
124
  | [Gradient Input](#gradient-input) | `<fig-input-gradient>` | Gradient editor with stops |
120
125
  | [Fill Input](#fill-input) | `<fig-input-fill>` | Solid, gradient, image, video fill |
@@ -128,6 +133,7 @@ Minimal example:
128
133
  | [Joystick](#joystick) | `<fig-joystick>` | 2D position input |
129
134
  | [Origin Grid](#origin-grid) | `<fig-origin-grid>` | Transform-origin grid |
130
135
  | [Easing Curve](#easing-curve) | `<fig-easing-curve>` | Bezier/spring curve editor |
136
+ | [Easing Popup](#easing-popup) | `<dialog is="fig-popup-easing">` | Reusable easing editor popup |
131
137
  | [3D Rotate](#3d-rotate) | `<fig-3d-rotate>` | 3D cube rotation control |
132
138
  | [Handle](#handle) | `<fig-handle>` | Draggable handle on a surface |
133
139
  | [Canvas Control](#canvas-control) | `<fig-canvas-control>` | Point with optional radius, angle, or second point |
@@ -510,6 +516,27 @@ The `value`, `min`, `max`, and `step` properties mirror their attributes. `aria-
510
516
 
511
517
  ---
512
518
 
519
+ #### Input Point
520
+
521
+ `<fig-input-point>` — [demo](https://rog.ie/figui3/#input-point)
522
+
523
+ An editor-bundle point control that renders two equally sized `<fig-input-number>` controls inside `<fig-input-combo>`. User edits reflect to the `x` and `y` attributes, and `units` is forwarded to both fields. Its `input` and `change` events provide numeric `{ x, y }` in `detail`.
524
+
525
+ | Attribute | Type | Default | Description |
526
+ |---|---|---|---|
527
+ | `x` | number | `0` | Horizontal coordinate |
528
+ | `y` | number | `0` | Vertical coordinate |
529
+ | `units` | string | — | Unit string forwarded to both number inputs |
530
+ | `full` | boolean | `false` | Fill the parent width |
531
+
532
+ ```html
533
+ <fig-input-point x="24" y="16" units="%"></fig-input-point>
534
+ ```
535
+
536
+ Requires `fig-editor.js` and `fig-editor.css`.
537
+
538
+ ---
539
+
513
540
  #### File Input
514
541
 
515
542
  `<fig-input-file>` — [demo](https://rog.ie/figui3/#file-input)
@@ -523,7 +550,7 @@ The `value`, `min`, `max`, and `step` properties mirror their attributes. `aria-
523
550
  | `disabled` | boolean | `false` | Disabled state |
524
551
  | `variant` | string | `"property"` | Internal button variant |
525
552
 
526
- Known image and audio files use media-specific icons; unmatched files retain the upload icon. A present or `"true"` `preview` uses the compact image swatch, audio waveform playback, or video icon. `preview="large"` renders known images and videos as upload-enabled `fig-image` or `fig-video` previews; audio and other formats retain their compact preview behavior. `preview="false"` disables previews. Image preview supports `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg`, and `.avif`; audio playback supports `.mp3`, `.wav`, `.aac`, `.m4a`, `.ogg`, and `.flac`; video detection supports common formats including `.mp4`, `.webm`, `.mov`, `.m4v`, `.avi`, `.mkv`, `.ogv`, `.mpeg`, `.mpg`, and `.3gp`.
553
+ Known image and audio files use media-specific icons; unmatched files retain the upload icon. A present or `"true"` `preview` uses the compact image swatch, audio playback preview, or video icon. Audio previews show the audio icon and filename at rest, reveal play and waveform controls on hover or focus, and keep the pause control and waveform visible while playing. `preview="large"` renders known images and videos as upload-enabled `fig-image` or `fig-video` previews; audio and other formats retain their compact preview behavior. `preview="false"` disables previews. Image preview supports `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg`, and `.avif`; audio playback supports `.mp3`, `.wav`, `.aac`, `.m4a`, `.ogg`, and `.flac`; video detection supports common formats including `.mp4`, `.webm`, `.mov`, `.m4v`, `.avi`, `.mkv`, `.ogv`, `.mpeg`, `.mpg`, and `.3gp`.
527
554
 
528
555
  ```html
529
556
  <fig-input-file accepts="image/*"></fig-input-file>
@@ -684,6 +711,20 @@ An editable palette of solid colors, each rendered as a `<fig-input-color>` swat
684
711
 
685
712
  The editable palette is a single tab stop. Enter or Space expands inline mode or opens picker mode. `edit="false"` renders only the compact preview. Picker mode requires `fig-editor.js`.
686
713
 
714
+ #### Property
715
+
716
+ `<fig-property>`
717
+
718
+ An editor-bundle property row. Supply one control in `slot="input"` and optionally author `slot="label"`, `slot="leading"`, or `slot="trailing"` content. Authored label markup takes precedence over the `label` attribute. The `leading="drag|chevron"` and `trailing="remove|add|bind"` attributes generate common accessories; authored slot content takes precedence. Leading and trailing content appears on hover or focus by default. Set `show-leading="false"` or `show-trailing="false"` to hide it, or add an empty `show-leading` or `show-trailing` attribute to always show it. Generated trailing actions emit bubbling, composed events named `remove`, `add`, or `bind` with the slotted control in `detail.input`. Input events bubble directly from the supplied control.
719
+
720
+ ```html
721
+ <fig-property label="Size" leading="drag" trailing="remove">
722
+ <fig-input-number slot="input" value="16" units="px" full></fig-input-number>
723
+ </fig-property>
724
+ ```
725
+
726
+ Import `fig-property.js` and `fig-property.css` directly, or use the `fig-editor` bundle, which includes both.
727
+
687
728
  #### Palette Editor
688
729
 
689
730
  `<fig-palette-editor>`
@@ -694,6 +735,61 @@ A reusable editor-bundle component for ordered color arrays. It uses `<fig-reord
694
735
  <fig-palette-editor value='["#94BD00","#83AD00","#1A632A","#003905"]'></fig-palette-editor>
695
736
  ```
696
737
 
738
+ #### Gradient Editor
739
+
740
+ `<fig-gradient-editor>`
741
+
742
+ A reusable editor-bundle component for gradient type, direction, stop handles,
743
+ and reorderable stop rows. It supports `value`, `color-space`, and `disabled`;
744
+ its `value` property is the normalized gradient config. Bubbling `input` and
745
+ `change` events include `{ type, gradient, css }`.
746
+
747
+ ```html
748
+ <fig-gradient-editor
749
+ value='{"type":"linear","angle":90,"stops":[{"position":0,"color":"#0D99FF","opacity":100},{"position":100,"color":"#9747FF","opacity":100}]}'
750
+ ></fig-gradient-editor>
751
+ ```
752
+
753
+ `fig-fill-picker` uses this component for its Gradient tab.
754
+
755
+ #### Gradient Popup
756
+
757
+ `<dialog is="fig-popup-gradient">`
758
+
759
+ A reusable `fig-popup` subclass that owns a `<fig-gradient-editor>`. It
760
+ supports `value`, `color-space`, and `disabled`, plus inherited popup
761
+ positioning. Its bubbling `input` and `change` events include
762
+ `{ type, gradient, css }`.
763
+
764
+ ```html
765
+ <fig-button id="gradient-trigger">Edit gradient</fig-button>
766
+ <dialog
767
+ is="fig-popup-gradient"
768
+ anchor="#gradient-trigger"
769
+ value='{"type":"linear","angle":90,"stops":[{"position":0,"color":"#0D99FF","opacity":100},{"position":100,"color":"#9747FF","opacity":100}]}'
770
+ open
771
+ ></dialog>
772
+ ```
773
+
774
+ #### Palette Popup
775
+
776
+ `<dialog is="fig-popup-palette">`
777
+
778
+ A reusable `fig-popup` subclass that owns a `<fig-palette-editor>`. It supports
779
+ `value`, `min`, `max`, `fixed`, and `disabled`, plus the standard popup
780
+ positioning attributes. Its `value` property and bubbling `input` / `change`
781
+ events use normalized `{ color, alpha }[]` values.
782
+
783
+ ```html
784
+ <fig-button id="palette-trigger">Edit palette</fig-button>
785
+ <dialog
786
+ is="fig-popup-palette"
787
+ anchor="#palette-trigger"
788
+ value='["#94BD00","#83AD00","#1A632A","#003905"]'
789
+ open
790
+ ></dialog>
791
+ ```
792
+
697
793
  #### Reorder
698
794
 
699
795
  `<fig-reorder>`
@@ -715,7 +811,7 @@ Attributes: `axis`, `handle`, `items`, `indicator`, and `disabled`. The bubbling
715
811
 
716
812
  `<fig-input-gradient>`
717
813
 
718
- A gradient editor with draggable stops. With `edit="picker"` and the optional picker registered, it opens `<fig-fill-picker>` locked to gradient mode; otherwise it falls back to inline stop editing.
814
+ A gradient editor with draggable stops. With `edit="picker"` and the editor bundle registered, it opens the reusable `dialog[is="fig-popup-gradient"]`; otherwise it renders the gradient swatch without opening a picker.
719
815
 
720
816
  | Attribute | Type | Default | Description |
721
817
  |---|---|---|---|
@@ -1021,7 +1117,7 @@ An interactive bezier or spring easing curve editor with a preset dropdown and m
1021
1117
  | `mode` | string | — | Optional `"bezier"` or `"spring"` constraint; filters presets and rejects the other value type |
1022
1118
  | `precision` | number | `2` | Decimal places |
1023
1119
  | `aspect-ratio` | string | — | Editor aspect ratio |
1024
- | `edit` | boolean | `true` | Show the editor and custom bezier/spring options; set to `"false"` for preset-only |
1120
+ | `edit` | boolean | `true` | Show the inline editor; `"false"` uses the compact preset control and opens `fig-popup-easing` when `fig-editor.js` is loaded |
1025
1121
  | `presets` | boolean | `true` | Show the preset selector; set to `"false"` to hide it |
1026
1122
  | `text` | boolean | `true` | Show the bezier value or normalized spring bounce input; set to `"false"` to hide it |
1027
1123
 
@@ -1070,6 +1166,24 @@ In spring mode, the compact number input edits normalized bounce from `0` (criti
1070
1166
 
1071
1167
  Editable bezier and spring handles are keyboard operable. Bezier handles keep tab order aligned with the visual handle order.
1072
1168
 
1169
+ #### Easing Popup
1170
+
1171
+ `<dialog is="fig-popup-easing">`
1172
+
1173
+ A reusable `fig-popup` subclass containing a
1174
+ `<fig-easing-curve aspect-ratio="4/3">`. Easing attributes and events are
1175
+ forwarded through the popup.
1176
+
1177
+ ```html
1178
+ <fig-button id="easing-trigger">Edit easing</fig-button>
1179
+ <dialog
1180
+ is="fig-popup-easing"
1181
+ anchor="#easing-trigger"
1182
+ value="0.42, 0, 0.58, 1"
1183
+ open
1184
+ ></dialog>
1185
+ ```
1186
+
1073
1187
  ---
1074
1188
 
1075
1189
  #### 3D Rotate
@@ -1290,6 +1404,8 @@ Adjacent `fig-field` children in a horizontal stack share compact gutters.
1290
1404
 
1291
1405
  A form field wrapper with flexible layout. Automatically links `<label>` to the first `fig-*` child for accessibility.
1292
1406
 
1407
+ Use `slot="leading"` for an accessory before the label, such as a disclosure or drag handle. Use `slot="trailing"` for an action at the end of the input area, such as reset or remove.
1408
+
1293
1409
  | Attribute | Type | Default | Description |
1294
1410
  |---|---|---|---|
1295
1411
  | `direction` | string | `"column"` | `"column"`, `"row"`, `"horizontal"` |
@@ -1298,8 +1414,12 @@ A form field wrapper with flexible layout. Automatically links `<label>` to the
1298
1414
 
1299
1415
  ```html
1300
1416
  <fig-field direction="horizontal" columns="thirds">
1417
+ <fig-icon slot="leading" name="drag-handle" size="small"></fig-icon>
1301
1418
  <label>Opacity</label>
1302
1419
  <fig-slider value="50" units="%"></fig-slider>
1420
+ <fig-button slot="trailing" variant="ghost" icon aria-label="Reset">
1421
+ <fig-icon name="reset"></fig-icon>
1422
+ </fig-button>
1303
1423
  </fig-field>
1304
1424
  ```
1305
1425