@rogieking/figui3 8.9.44 → 8.9.46

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,10 +2,10 @@
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, and fig-interpolation-swatch.
6
- Use when building custom selects, grouped option lists, sticky separators, ghost
7
- selects, fill picker dialogs, or interpolation swatches. Playground: /figui3#select
8
- and /figui3#fill-picker with the Full editor toggle. Requires fig.js.
5
+ fig-select-options, fig-select-option, fig-fill-picker, and fig-interpolation-swatch,
6
+ including React JSX usage. Use when building custom selects, grouped option lists,
7
+ sticky separators, ghost selects, fill picker dialogs, or interpolation swatches.
8
+ Requires fig.js.
9
9
  user-invocable: false
10
10
  ---
11
11
 
@@ -13,7 +13,7 @@ user-invocable: false
13
13
 
14
14
  Custom select and full fill-picker. Not in core `fig.js`.
15
15
 
16
- Canonical examples: `/figui3#select`, `/figui3#fill-picker` (enable **Full editor** in the playground theme menu). Markup: `playground/src/data/figui3Sections.ts`. Attrs: `playground/src/lib/attributeRules.ts`.
16
+ React: [../figui3/react.md](../figui3/react.md). Per-tag JSX: [components.md](components.md). Attrs: [reference.md](reference.md).
17
17
 
18
18
  See also: `figui3` (core), `fig-lab` (`propskit-select` wraps this select).
19
19
 
@@ -38,146 +38,19 @@ Registered tags:
38
38
  | `fig-fill-picker` | Full fill editor dialog (solid, gradient, image, video, webcam, custom modes) |
39
39
  | `fig-interpolation-swatch` | Gradient interpolation preview swatch |
40
40
 
41
- ## `fig-select`
42
-
43
- Use this instead of `fig-dropdown` for Figma-style menus (rich options, groups, overflow).
44
-
45
- ### Markup
46
-
47
- Author options in `fig-select-options`, or pass `options` (comma / newline / JSON — same as `fig-options`).
48
-
49
- ```html
50
- <fig-select value="center" label="Align">
51
- <fig-select-options>
52
- <fig-select-option value="left">Left</fig-select-option>
53
- <fig-select-option value="center">Center</fig-select-option>
54
- <fig-select-option value="right">Right</fig-select-option>
55
- </fig-select-options>
56
- </fig-select>
57
-
58
- <fig-select label="Align" value="Center" options="Left,Center,Right"></fig-select>
59
- ```
60
-
61
- Rich options: put extra content inside `fig-select-option` and set `label` for the closed trigger text. Use `slot="panel"` on `fig-select-options` when the panel is slotted (playground “verbose” / AI models examples).
62
-
63
- ```html
64
- <fig-select value="uuid" label="Version" full>
65
- <fig-select-options slot="panel">
66
- <fig-select-option value="uuid" label="Current (Version 6)">
67
- <strong>Current</strong>
68
- <span>Version 6</span>
69
- </fig-select-option>
70
- </fig-select-options>
71
- </fig-select>
72
- ```
73
-
74
- ### Attributes
75
-
76
- | Attr | Notes |
77
- |---|---|
78
- | `value` | Selected option value |
79
- | `label` | Closed-state / aria label |
80
- | `options` | Generated options if no authored `fig-select-option` |
81
- | `variant` | `ghost` — no border, hover `--figma-color-bg-secondary` |
82
- | `full` | Stretch width |
83
- | `disabled` | Presence |
84
- | `position` | `bottom left` (default), `bottom right`, `top left`, `top right`, `bottom center`, `top center` |
85
- | `offset`, `closedby`, `open` | Forwarded to internal `fig-popup` |
86
-
87
- Same `variant="ghost"` exists on core `fig-dropdown`.
88
-
89
- ### Groups and sticky separators
90
-
91
- ```html
92
- <fig-select-options>
93
- <fig-separator label="Darken" sticky></fig-separator>
94
- <fig-select-option value="multiply">Multiply</fig-select-option>
95
- <fig-separator label="Lighten" sticky></fig-separator>
96
- <fig-select-option value="screen">Screen</fig-select-option>
97
- </fig-select-options>
98
- ```
99
-
100
- - First separator in a panel is auto-`borderless`.
101
- - `sticky` on `fig-separator` pins the label while scrolling.
102
- - Overflow adds `.overflow-start` / `.overflow-end` on `fig-select-options`. Sticky `top` sits below the overflow chevron (`--fig-vertical-overflow-size`).
103
-
104
- Playground: `#select` examples `grouped`, `many-options`; AI models list in `figui3Sections.ts` (`aiModelSelectMarkup()`). Sticky toggle is a playground inspector concern (`?_sticky=1`), not a select host attr.
105
-
106
- ### Behavior
107
-
108
- - Internal popup uses `popover="manual"` (top layer) so the list positions correctly inside `fig-popup variant="popover"` (CSS `filter` containing block).
109
- - List `min-width` matches the trigger; `max-width` is `min(20rem, calc(100vw - 1rem))`.
110
- - Overflow: top/bottom chevron buttons, not a native scrollbar.
111
- - Keyboard: open, arrow, typeahead, Escape.
112
- - `optionhover` fires on pointer-over with the option value in `event.detail` without changing selection.
113
- - `input` / `change` on value commit. Do not `stopPropagation` on option click (React light-DOM handlers must run).
114
-
115
- ### `fig-select` vs `fig-dropdown` vs `propskit-select`
41
+ ## `fig-select` vs `fig-dropdown` vs `propskit-select`
116
42
 
117
43
  - `fig-dropdown` (core): native `<select>`.
118
- - `fig-select` (this skill): custom listbox.
44
+ - `fig-select` (this skill): custom listbox. Use this for Figma-style menus.
119
45
  - `propskit-select` (lab): labeled `fig-field` wrapping `fig-select` (falls back if select is not registered).
120
46
 
121
- ## `fig-fill-picker`
122
-
123
- Full fill editor. Core `fig-input-color` / `fig-input-fill` auto-open it when registered. Standalone:
124
-
125
- ```html
126
- <fig-fill-picker value='{"type":"solid","color":"#FF5733"}'>
127
- <fig-swatch></fig-swatch>
128
- </fig-fill-picker>
129
- ```
130
-
131
- Playground: `#fill-picker` — `all-modes`, `solid`, `gradient`, `image`, `video`, `webcam`, `shader` (custom `slot="mode-shader"`).
132
-
133
- | Attr | Notes |
134
- |---|---|
135
- | `value` | JSON fill object or string |
136
- | `alpha` | `"true"` default; hide alpha with `"false"` |
137
- | `mode` | Lock modes: `solid`, `gradient`, `image`, `video`, `webcam`, comma-separated, plus custom names |
138
- | `disabled` | Presence |
139
- | `webcam-mode` | `live` (default) or `snapshot`. Webcam tab starts the camera. Capture writes a still and switches to Image |
140
- | `default-video` | Sample clip URL when Video has no file |
141
-
142
- Events: `input` / `change` with fill payload in `detail`. `webcamstream` with `{ stream, deviceId }`. Live camera is `webcamStream` / `releaseWebcam()`, never JSON.
143
-
144
- Value shapes:
145
-
146
- ```txt
147
- solid { type, colorSpace, color, alpha, hsv }
148
- gradient { type, colorSpace, gradient, css }
149
- image { type, colorSpace, image: { url, scaleMode, scale } } // scaleMode includes tile
150
- video { type, colorSpace, video: { url, poster, scaleMode, scale, opacity } } // fill | fit | crop
151
- webcam { type, colorSpace, webcam: { live, snapshot, deviceId, scaleMode, scale, opacity } }
152
- custom { type: <modeName>, ...payload }
153
- ```
154
-
155
- Legacy `{ type: "webcam", image: { url } }` still parses as `webcam.snapshot` for one release. `fig-input-fill` uses the same `webcam` / `video.poster` shapes.
156
-
157
- `fig-input-color` expects solid data (`detail.color`, optional `detail.alpha`). Keep legacy `value` / `hex` / `rgba` on color input events.
158
-
159
- Do not use `picker` or `picker-anchor` on `fig-input-color`. Forward picker chrome with `picker-*` (e.g. `picker-dialog-position`).
160
-
161
- ### Custom modes (vanilla)
162
-
163
- ```html
164
- <fig-input-fill mode="solid,tokens" value='{"type":"tokens"}'>
165
- <div slot="mode-tokens" label="Tokens">Token UI</div>
166
- </fig-input-fill>
167
- ```
168
-
169
- Child `slot="mode-<name>"` plus `<name>` in `mode`. `fig-input-fill` forwards those slots to the inner picker and uses image-style chrome (type label + opacity). Custom content must dispatch `input` / `change` with `detail` so the picker stores mode data.
170
-
171
- ### Custom modes (React)
47
+ Author options as React children, or pass `options`. Do not `stopPropagation` on option click. `optionhover` is a native listener.
172
48
 
173
- 1. Include the mode name in `mode`.
174
- 2. Listen for `modeready`; mount into `e.detail.container`.
175
- 3. Do not reparent React-owned DOM after render.
176
- 4. One React root per container; `unmount()` on host unmount; remove `modeready` listeners.
49
+ ## Fill picker
177
50
 
178
- ## `fig-interpolation-swatch`
51
+ Core `fig-input-color` / `fig-input-fill` auto-open the picker when registered. Custom modes: `slot="mode-<name>"` on `fig-input-fill`, or React `modeready` → mount into `e.detail.container` (do not reparent).
179
52
 
180
- Preview for gradient interpolation (linear or polar hue arc). Playground attrs: `size="small|large"`. Can be used standalone with a gradient `value`. The fill picker interpolation row is hidden for now and locks to `srgb`.
53
+ Do not use `picker` or `picker-anchor` on `fig-input-color`. Forward picker chrome with `picker-*`.
181
54
 
182
55
  ## Maintainer notes
183
56
 
@@ -0,0 +1,134 @@
1
+ # FigUI3 editor components (`fig-editor.js`)
2
+
3
+ React contract: [../figui3/react.md](../figui3/react.md). Attrs: [reference.md](reference.md).
4
+
5
+ Install `fig-editor.css` + `fig-editor.js` (pulls in `fig.js` and `fig-lab.js`). Still import `fig-editor.css`. Import `fig-lab.css` if lab visuals are needed.
6
+
7
+ ## `fig-select`
8
+
9
+ Figma-style listbox. Prefer this over core `fig-dropdown`.
10
+
11
+ ```tsx
12
+ <fig-select value={align} label="Align" full onChange={onChange}>
13
+ <fig-select-options>
14
+ <fig-select-option value="left">Left</fig-select-option>
15
+ <fig-select-option value="center">Center</fig-select-option>
16
+ <fig-select-option value="right">Right</fig-select-option>
17
+ </fig-select-options>
18
+ </fig-select>
19
+ ```
20
+
21
+ Data-driven (no authored options):
22
+
23
+ ```tsx
24
+ <fig-select
25
+ label="Align"
26
+ value={align}
27
+ options="Left,Center,Right"
28
+ onChange={onChange}
29
+ />
30
+ ```
31
+
32
+ - Attrs: `value`, `label`, `options` (comma / newline / JSON), `variant` (`ghost`), `full`, `disabled`, `position` (`bottom left` default, also `bottom right`, `top left`, `top right`, `bottom center`, `top center`), `offset`, `closedby`, `open`
33
+ - Events: `input` / `change` on commit; `optionhover` with the option value in `detail` (does not change selection). Use a native listener for `optionhover`.
34
+ - Do not `stopPropagation` on option click — React light-DOM handlers must run.
35
+ - Internal popup uses `popover="manual"` so the list works inside `fig-popup variant="popover"`.
36
+ - List `min-width` matches the trigger; `max-width` is `min(20rem, calc(100vw - 1rem))`. Overflow: chevron buttons, not a native scrollbar.
37
+
38
+ `fig-dropdown` (core) is a native `<select>`. `propskit-select` (lab) wraps this select.
39
+
40
+ ## `fig-select-options`
41
+
42
+ ```tsx
43
+ <fig-select-options slot="panel">
44
+ <fig-separator label="Darken" sticky />
45
+ <fig-select-option value="multiply">Multiply</fig-select-option>
46
+ <fig-separator label="Lighten" sticky />
47
+ <fig-select-option value="screen">Screen</fig-select-option>
48
+ </fig-select-options>
49
+ ```
50
+
51
+ - Auto `slot="panel"` if missing. Use `slot="panel"` when the panel is slotted (rich / verbose options).
52
+ - First `fig-separator` child is auto-`borderless`. `sticky` pins the label while scrolling.
53
+ - Overflow adds `.overflow-start` / `.overflow-end`. Sticky `top` sits below the overflow chevron (`--fig-vertical-overflow-size`).
54
+ - Methods: `syncOverflow()`, `scrollToOption(option, behavior)`.
55
+ - Options stay in light DOM. Author them as React children.
56
+
57
+ ## `fig-select-option`
58
+
59
+ ```tsx
60
+ <fig-select-option value="uuid" label="Current (Version 6)">
61
+ <strong>Current</strong>
62
+ <span>Version 6</span>
63
+ </fig-select-option>
64
+ ```
65
+
66
+ - Attrs: `value` (falls back to trimmed `textContent`), `label` (closed-trigger text when content is rich), `selected`, `disabled`
67
+ - `role="option"`, `aria-selected`, `aria-disabled`
68
+
69
+ ## `fig-fill-picker`
70
+
71
+ Full fill editor. Core `fig-input-color` / `fig-input-fill` auto-open it when this tag is registered.
72
+
73
+ ```tsx
74
+ <fig-fill-picker
75
+ value='{"type":"solid","color":"#FF5733"}'
76
+ onInput={onInput}
77
+ onChange={onChange}
78
+ >
79
+ <fig-swatch />
80
+ </fig-fill-picker>
81
+ ```
82
+
83
+ - Attrs: `value` (JSON fill or string), `alpha` (`"true"` default; `"false"` hides), `mode` (`solid`, `gradient`, `image`, `video`, `webcam`, comma-separated, plus custom names), `disabled`, `webcam-mode` (`live` | `snapshot`), `default-video`
84
+ - Events: `input` / `change` with fill payload in `detail`; `webcamstream` with `{ stream, deviceId }`
85
+ - Live camera is `webcamStream` / `releaseWebcam()`, never JSON.
86
+
87
+ Value shapes:
88
+
89
+ ```txt
90
+ solid { type, colorSpace, color, alpha, hsv }
91
+ gradient { type, colorSpace, gradient, css }
92
+ image { type, colorSpace, image: { url, scaleMode, scale } }
93
+ video { type, colorSpace, video: { url, poster, scaleMode, scale, opacity } }
94
+ webcam { type, colorSpace, webcam: { live, snapshot, deviceId, scaleMode, scale, opacity } }
95
+ custom { type: <modeName>, ...payload }
96
+ ```
97
+
98
+ `fig-input-color` expects solid data (`detail.color`, optional `detail.alpha`). Keep legacy `value` / `hex` / `rgba` on color input events.
99
+
100
+ Do not use `picker` or `picker-anchor` on `fig-input-color`. Forward picker chrome with `picker-*` (e.g. `picker-dialog-position`).
101
+
102
+ ### Custom modes
103
+
104
+ On `fig-input-fill` (forwards `mode-*` slots to the inner picker, image-style chrome):
105
+
106
+ ```tsx
107
+ <fig-input-fill mode="solid,tokens" value='{"type":"tokens"}'>
108
+ <div slot="mode-tokens" label="Tokens">
109
+ Token UI
110
+ </div>
111
+ </fig-input-fill>
112
+ ```
113
+
114
+ Vanilla: child `slot="mode-<name>"` plus `<name>` in `mode`. Dispatch `input` / `change` with `detail` so the picker stores `{ type: "<name>", …detail }`.
115
+
116
+ React:
117
+
118
+ 1. Include the mode name in `mode`.
119
+ 2. Listen for `modeready`; mount into `e.detail.container`.
120
+ 3. Do not reparent React-owned DOM after render.
121
+ 4. One React root per container; `unmount()` on host unmount; remove `modeready` listeners.
122
+
123
+ ## `fig-interpolation-swatch`
124
+
125
+ ```tsx
126
+ <fig-interpolation-swatch
127
+ size="large"
128
+ value={gradientJson}
129
+ onInput={onInput}
130
+ />
131
+ ```
132
+
133
+ - Attrs: `value` (gradient payload), `size` (`small` | `large`)
134
+ - Standalone preview of linear or polar hue interpolation. The fill-picker interpolation row is hidden and locks to `srgb`.
@@ -1,7 +1,6 @@
1
1
  # FigUI3 editor API reference
2
2
 
3
- Playground: `/figui3#select`, `/figui3#fill-picker` (Full editor on).
4
- Rules: `playground/src/lib/attributeRules.ts`.
3
+ React recipes: [components.md](components.md).
5
4
 
6
5
  ## `fig-select-option`
7
6
 
@@ -23,7 +22,7 @@ Observed: `value`, `disabled`, `selected`, `label`.
23
22
 
24
23
  `value`, `disabled`, `label`, `options`, `position`, `offset`, `closedby`, `open`, `variant`
25
24
 
26
- Position enum (playground):
25
+ Position enum:
27
26
 
28
27
  - `bottom left`, `bottom right`, `top left`, `top right`, `bottom center`, `top center`
29
28
 
@@ -4,8 +4,8 @@ description: >-
4
4
  Guides FigUI3 lab bundle (`fig-lab.js` / `fig-lab.css`): experimental propskit-*
5
5
  property controls, fig-canvas-control, fig-input-angle, fig-input-wheel, fig-reorder,
6
6
  and AI composer components (fig-ai-prompt, fig-ai-context, fig-chat-message,
7
- fig-attachment). Use when building labeled property panels, canvas handles,
8
- oscillators, scrubbers, reorder lists, or AI chat UIs. Playground: /propskit/lab.
7
+ fig-attachment), including React JSX usage. Use when building labeled property
8
+ panels, canvas handles, oscillators, scrubbers, reorder lists, or AI chat UIs.
9
9
  APIs are unstable.
10
10
  user-invocable: false
11
11
  ---
@@ -14,9 +14,9 @@ user-invocable: false
14
14
 
15
15
  Experimental components. May change or be removed without notice.
16
16
 
17
- Canonical examples: `/propskit/lab` (`playground/src/data/labSections.ts`).
18
- Attrs: `playground/src/lib/attributeRules.ts`.
19
- `/propskit` (raw `fig-field` rows) is the `propkit` skill, not this one.
17
+ React: [../figui3/react.md](../figui3/react.md). Per-tag JSX: [components.md](components.md). Attrs: [reference.md](reference.md).
18
+
19
+ Raw `fig-field` rows are the `propkit` skill, not this one.
20
20
 
21
21
  ## Install
22
22
 
@@ -31,114 +31,16 @@ import "@rogieking/figui3/fig-lab.js";
31
31
 
32
32
  `fig-editor.js` already imports `fig-lab.js`; lab **CSS** is still required for lab visuals.
33
33
 
34
- ## Catalog
35
-
36
- Playground hashes: `/propskit/lab#{id}`.
37
-
38
- ### Propskit (labeled property controls)
34
+ ## Shared propskit
39
35
 
40
- Full-surface `fig-field` wrappers. Prefer these over hand-rolled label+control rows when building lab/property UIs.
41
-
42
- Shared:
43
-
44
- - `label`, `direction` (`horizontal` default for most), `size` (`""` | `small`; `large` remains an alias for the default), `disabled`
36
+ - `label`, `direction` (`horizontal` default), `size` (`""` | `small`; `large` remains an alias for the default), `disabled`
45
37
  - `variant="minimal"` — removes vertical row padding and reveals the field background on hover
46
38
  - `default` — reset target (may differ from initial `value`)
47
- - Right-click **Reset** menu; `resetToDefault()`
39
+ - Right-click **Reset** menu; `resetToDefault()` on a ref
48
40
  - `propskit-slider` also double-click resets
49
41
  - Forward remaining attrs to the inner control except where a component note says otherwise
50
42
  - Rows are large by default; `propskit-group size="small"` applies compact sizing to children without an authored size
51
43
 
52
- | Tag | Playground | Inner control | Notes |
53
- |---|---|---|---|
54
- | `propskit-switch` | `#propskit-switch` | `fig-switch` | `checked`, `default` boolean |
55
- | `propskit-color` | `#propskit-color` | `fig-fill-picker` + `fig-swatch` | Solid swatch, same size as gradient. Clicking the field opens the picker anchored to the host. Focus ring on the field, not the swatch. `alpha` default true |
56
- | `propskit-fill` | `#propskit-fill` | `fig-fill-picker` + `fig-swatch` | Same chrome as color. Clicking the field opens the picker anchored to the host. Focus ring on the field, not the swatch. Value may be fill JSON or a bare video URL. Forwards `mode-*` slots |
57
- | `propskit-gradient` | `#propskit-gradient` | `fig-input-gradient` | Default `edit="picker"`. Clicking the field opens the picker anchored to the host. Focus ring on the field, not the gradient. `mode="handle\|tip"` for inline edit |
58
- | `propskit-select` | `#propskit-select` | `fig-select` | `options` or slotted `fig-select-options` |
59
- | `propskit-text` | `#propskit-text` | `fig-input-text` | `type`, `readonly` |
60
- | `propskit-number` | `#propskit-number` | `fig-input-number` | `min`, `max`, `step`, `precision`, `units`, `steppers` |
61
- | `propskit-slider` | `#propskit-slider` | `fig-slider` | `type` range/hue/delta/stepper/opacity; `elastic` default true |
62
- | `propskit-wheel` | `#propskit-wheel` | `fig-input-wheel` + optional `fig-input-number` | Labeled scrubber with `label`, `text`, `spin`, `elastic` row stretch, `precision`, `units`, `default`/reset, `size`, and `variant`; units stay on the wrapper/number field and the effective step is applied to the wheel |
63
- | `propskit-position` | `#propskit-position` | two numbers | `x`, `y`, `units="percent"` |
64
- | `propskit-color-point` | `#propskit-color-point` | color + position | JSON `value`; `collapsible`, `open` |
65
- | `propskit-point-radius` | `#propskit-point-radius` | position + radius | JSON `value` |
66
- | `propskit-point-radius-angle` | `#propskit-point-radius-angle` | + angle | JSON `value` |
67
- | `propskit-point-point` | `#propskit-point-point` | start/end | `{ x, y, x2, y2 }` |
68
- | `propskit-group` | `#propskit-group` | group chrome | `name`, `open`, `show-reset` |
69
- | `propskit-oscillator` | `#oscillator` | waveform editor | JSON `waves`; `edit`, `precision`, `aspect-ratio` |
70
-
71
- ```html
72
- <propskit-slider
73
- label="Opacity"
74
- direction="horizontal"
75
- type="opacity"
76
- value="100"
77
- default="100"
78
- min="0"
79
- max="100"
80
- units="%"
81
- ></propskit-slider>
82
-
83
- <propskit-select label="Blend" value="multiply" options="Normal,Multiply,Screen"></propskit-select>
84
- ```
85
-
86
- Rich select (requires editor):
87
-
88
- ```html
89
- <propskit-select label="Space" value="oklab">
90
- <fig-select-options slot="panel">
91
- <fig-select-option value="srgb" label="Classic">…</fig-select-option>
92
- </fig-select-options>
93
- </propskit-select>
94
- ```
95
-
96
- ### Canvas and spatial
97
-
98
- | Tag | Playground | Notes |
99
- |---|---|---|
100
- | `fig-canvas-control` | `#canvas-control` | Overlay on a positioned parent. `type`: `point` (default), `color`, `point-radius`, `point-radius-angle`, `point-point`. `value` JSON `{x,y,radius?,angle?,x2?,y2?}`. `snapping="modifier\|true\|false"`, `name`, `tooltips`, `color` |
101
- | `fig-input-angle` | `#angle` | Dial + optional text. `text`, `dial` default true, `rotations`, `min`/`max`/`units` |
102
- | `fig-input-wheel` | `#input-wheel` | Standalone SVG tick + handle scrubber. Numeric `value`, optional `min`/`max`, `step` default 1, `spin` default true, `disabled` |
103
- | `fig-reorder` | `#reorder` | `display:contents` wrapper; drag-reorders **direct children**. `axis="vertical\|horizontal"`, `handle` CSS selector when rows contain nested controls. Event: `reorder` `{ oldIndex, newIndex, item }` |
104
-
105
- ```html
106
- <div style="position:relative; aspect-ratio:1; width:100%">
107
- <fig-canvas-control
108
- type="point-radius-angle"
109
- name="Position"
110
- value='{"x":50,"y":50,"radius":60,"angle":45}'
111
- snapping="modifier"
112
- ></fig-canvas-control>
113
- </div>
114
- ```
115
-
116
- Omit `handle` on `fig-reorder` to drag whole rows. Set `handle` when children contain sliders/handles so those stay interactive.
117
-
118
- ### AI composer (presentation)
119
-
120
- These are layout shells. Wire behavior yourself.
121
-
122
- | Tag | Playground | Notes |
123
- |---|---|---|
124
- | `fig-ai-prompt` | `#ai-prompt` | Composer: slot `fig-input-text`, `fig-footer`, buttons, optional `fig-select` |
125
- | `fig-ai-context` | (with prompt) | Open area above prompt for attachments/status |
126
- | `fig-chat-message` | `#ai-chat-message` | `from="user\|agent"`. Optional `fig-avatar`, `fig-attachments` |
127
- | `fig-attachments` / `fig-attachment` | `#ai-attachments` | `src`, `name`, `value`, `removable` default true |
128
-
129
- ```html
130
- <fig-chat-message from="user">
131
- Create a settings panel.
132
- <fig-attachments aria-label="Message attachments">
133
- <fig-attachment value="settings" name="settings.png" src="…" removable="false"></fig-attachment>
134
- </fig-attachments>
135
- <fig-avatar name="Rogie King"></fig-avatar>
136
- </fig-chat-message>
137
- <fig-chat-message from="agent">
138
- <fig-shimmer><span>Thinking…</span></fig-shimmer>
139
- </fig-chat-message>
140
- ```
141
-
142
44
  ## Control choice
143
45
 
144
46
  | Intent | Use |
@@ -157,11 +59,9 @@ These are layout shells. Wire behavior yourself.
157
59
  | Section of props | `propskit-group` or core `fig-group` |
158
60
  | Reorder rows | `fig-reorder` |
159
61
 
160
- Raw `fig-field` + core control is still valid (see `propkit` skill / `/propskit`).
62
+ Raw `fig-field` + core control is still valid (see `propkit` skill).
161
63
 
162
64
  ## Maintainer notes
163
65
 
164
66
  - Implementation: `fig-lab.js`, styles: `fig-lab.css`
165
67
  - Keep lab out of `fig.js`
166
- - Playground loads lab only on `/propskit` and `/propskit/lab`
167
- - Update `labSections.ts` + `attributeRules.ts` with API changes