@rogieking/figui3 8.9.10 → 8.9.12
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.
- package/.cursor/skills/fig-editor/SKILL.md +184 -0
- package/.cursor/skills/fig-editor/reference.md +46 -0
- package/.cursor/skills/fig-lab/SKILL.md +159 -0
- package/.cursor/skills/fig-lab/reference.md +67 -0
- package/.cursor/skills/figui3/SKILL.md +160 -188
- package/.cursor/skills/figui3/reference.md +91 -0
- package/.cursor/skills/propkit/SKILL.md +66 -185
- package/README.md +66 -1
- package/components.css +109 -30
- package/dist/components.css +1 -1
- package/dist/fig-editor.css +1 -1
- package/dist/fig-editor.js +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +162 -3
- package/fig-editor.css +11 -91
- package/fig-editor.js +5 -0
- package/fig.js +525 -122
- package/package.json +1 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fig-editor
|
|
3
|
+
description: >-
|
|
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.
|
|
9
|
+
user-invocable: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# FigUI3 editor (`fig-editor.js`)
|
|
13
|
+
|
|
14
|
+
Custom select and full fill-picker. Not in core `fig.js`.
|
|
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`.
|
|
17
|
+
|
|
18
|
+
See also: `figui3` (core), `fig-lab` (`propskit-select` wraps this select).
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
import "@rogieking/figui3/fig.css";
|
|
24
|
+
import "@rogieking/figui3/fig.js";
|
|
25
|
+
import "@rogieking/figui3/fig-editor.css";
|
|
26
|
+
import "@rogieking/figui3/fig-editor.js";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`fig-editor.js` imports `fig.js` and `fig-lab.js`. Still import `fig-editor.css`. Import `fig-lab.css` if lab visuals are needed.
|
|
30
|
+
|
|
31
|
+
Registered tags:
|
|
32
|
+
|
|
33
|
+
| Tag | Role |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `fig-select` | Trigger + popup listbox |
|
|
36
|
+
| `fig-select-options` | Scrollable panel (`slot="panel"`), overflow chevrons |
|
|
37
|
+
| `fig-select-option` | Option (`value`, `label`, `selected`, `disabled`) |
|
|
38
|
+
| `fig-fill-picker` | Full fill editor dialog (solid, gradient, image, video, webcam, custom modes) |
|
|
39
|
+
| `fig-interpolation-swatch` | Gradient interpolation preview swatch |
|
|
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`
|
|
116
|
+
|
|
117
|
+
- `fig-dropdown` (core): native `<select>`.
|
|
118
|
+
- `fig-select` (this skill): custom listbox.
|
|
119
|
+
- `propskit-select` (lab): labeled `fig-field` wrapping `fig-select` (falls back if select is not registered).
|
|
120
|
+
|
|
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`.
|
|
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
|
+
|
|
140
|
+
Events: `input` / `change` with fill payload in `detail`.
|
|
141
|
+
|
|
142
|
+
Value shapes:
|
|
143
|
+
|
|
144
|
+
```txt
|
|
145
|
+
solid { type, colorSpace, color, alpha, hsv }
|
|
146
|
+
gradient { type, colorSpace, gradient, css }
|
|
147
|
+
image { type, colorSpace, image }
|
|
148
|
+
video { type, colorSpace, video }
|
|
149
|
+
webcam { type, colorSpace, image: { url: snapshot, scaleMode, scale } }
|
|
150
|
+
custom { type: <modeName>, ...payload }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`fig-input-color` expects solid data (`detail.color`, optional `detail.alpha`). Keep legacy `value` / `hex` / `rgba` on color input events.
|
|
154
|
+
|
|
155
|
+
Do not use `picker` or `picker-anchor` on `fig-input-color`. Forward picker chrome with `picker-*` (e.g. `picker-dialog-position`).
|
|
156
|
+
|
|
157
|
+
### Custom modes (vanilla)
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<fig-fill-picker mode="solid,tokens">
|
|
161
|
+
<fig-swatch></fig-swatch>
|
|
162
|
+
<div slot="mode-tokens" label="Tokens">Token UI</div>
|
|
163
|
+
</fig-fill-picker>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Child `slot="mode-<name>"` plus `<name>` in `mode`. Custom content must dispatch `input` / `change` with `detail` so the picker stores mode data.
|
|
167
|
+
|
|
168
|
+
### Custom modes (React)
|
|
169
|
+
|
|
170
|
+
1. Include the mode name in `mode`.
|
|
171
|
+
2. Listen for `modeready`; mount into `e.detail.container`.
|
|
172
|
+
3. Do not reparent React-owned DOM after render.
|
|
173
|
+
4. One React root per container; `unmount()` on host unmount; remove `modeready` listeners.
|
|
174
|
+
|
|
175
|
+
## `fig-interpolation-swatch`
|
|
176
|
+
|
|
177
|
+
Preview for gradient interpolation (linear or polar hue arc). Playground attrs: `size="small|large"`. Used inside the fill picker gradient UI; can be used standalone with a gradient `value`.
|
|
178
|
+
|
|
179
|
+
## Maintainer notes
|
|
180
|
+
|
|
181
|
+
- Implementation: `fig-editor.js`, styles: `fig-editor.css`
|
|
182
|
+
- Do not move fill-picker or select into `fig.js`
|
|
183
|
+
- Nested overlay positioning: keep `popover="manual"` on the select popup
|
|
184
|
+
- Tests: `tests/figui/component-contracts.spec.ts` (ghost variant, sticky separator vs overflow-start)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# FigUI3 editor API reference
|
|
2
|
+
|
|
3
|
+
Playground: `/figui3#select`, `/figui3#fill-picker` (Full editor on).
|
|
4
|
+
Rules: `playground/src/lib/attributeRules.ts`.
|
|
5
|
+
|
|
6
|
+
## `fig-select-option`
|
|
7
|
+
|
|
8
|
+
Observed: `value`, `disabled`, `selected`, `label`.
|
|
9
|
+
|
|
10
|
+
- `value` falls back to trimmed `textContent` if the attr is omitted
|
|
11
|
+
- `label` is the closed-trigger string when option content is rich
|
|
12
|
+
- `role="option"`, `aria-selected`, `aria-disabled`
|
|
13
|
+
|
|
14
|
+
## `fig-select-options`
|
|
15
|
+
|
|
16
|
+
- Auto `slot="panel"` if missing
|
|
17
|
+
- Unwraps a legacy nested `fig-chooser`
|
|
18
|
+
- First `fig-separator` child gets `borderless`
|
|
19
|
+
- Overflow nav buttons: `data-fig-select-nav`, classes `overflow-start` / `overflow-end`
|
|
20
|
+
- Methods: `syncOverflow()`, `scrollToOption(option, behavior)`
|
|
21
|
+
|
|
22
|
+
## `fig-select` observed
|
|
23
|
+
|
|
24
|
+
`value`, `disabled`, `label`, `options`, `position`, `offset`, `closedby`, `open`, `variant`
|
|
25
|
+
|
|
26
|
+
Position enum (playground):
|
|
27
|
+
|
|
28
|
+
- `bottom left`, `bottom right`, `top left`, `top right`, `bottom center`, `top center`
|
|
29
|
+
|
|
30
|
+
Events: `input`, `change`, `optionhover`.
|
|
31
|
+
|
|
32
|
+
## Fill picker modes
|
|
33
|
+
|
|
34
|
+
Built-in: `solid`, `gradient`, `image`, `video`, `webcam`.
|
|
35
|
+
|
|
36
|
+
Gradient spaces: `srgb`, `srgb-linear`, `display-p3`, `oklab`, `oklch`, `hsl`.
|
|
37
|
+
Hue interpolations (oklch/hsl): `shorter`, `longer`, `increasing`, `decreasing`.
|
|
38
|
+
|
|
39
|
+
`fig-interpolation-swatch` observed: `value` (gradient payload). Size via attr/CSS.
|
|
40
|
+
|
|
41
|
+
## Color input + picker
|
|
42
|
+
|
|
43
|
+
When picker is registered, `fig-input-color` / `fig-input-fill` open it on interaction.
|
|
44
|
+
|
|
45
|
+
- Do not emit `input` from programmatic `value` writes (React loop avoidance)
|
|
46
|
+
- Custom mode JSON: `type` = mode name, remaining keys in payload
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fig-lab
|
|
3
|
+
description: >-
|
|
4
|
+
Guides FigUI3 lab bundle (`fig-lab.js` / `fig-lab.css`): experimental propskit-*
|
|
5
|
+
property controls, fig-canvas-control, fig-input-angle, fig-reorder, and AI composer
|
|
6
|
+
components (fig-ai-prompt, fig-ai-context, fig-chat-message, fig-attachment). Use when
|
|
7
|
+
building labeled property panels, canvas handles, oscillators, reorder lists, or AI
|
|
8
|
+
chat UIs. Playground: /propskit/lab. APIs are unstable.
|
|
9
|
+
user-invocable: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# FigUI3 lab (`fig-lab.js`)
|
|
13
|
+
|
|
14
|
+
Experimental components. May change or be removed without notice.
|
|
15
|
+
|
|
16
|
+
Canonical examples: `/propskit/lab` (`playground/src/data/labSections.ts`).
|
|
17
|
+
Attrs: `playground/src/lib/attributeRules.ts`.
|
|
18
|
+
`/propskit` (raw `fig-field` rows) is the `propkit` skill, not this one.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
import "@rogieking/figui3/fig.css";
|
|
24
|
+
import "@rogieking/figui3/fig.js";
|
|
25
|
+
import "@rogieking/figui3/fig-lab.css";
|
|
26
|
+
import "@rogieking/figui3/fig-lab.js";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`propskit-select` prefers `fig-select` (import `fig-editor.js` + `fig-editor.css`). Without editor, it falls back.
|
|
30
|
+
|
|
31
|
+
`fig-editor.js` already imports `fig-lab.js`; lab **CSS** is still required for lab visuals.
|
|
32
|
+
|
|
33
|
+
## Catalog
|
|
34
|
+
|
|
35
|
+
Playground hashes: `/propskit/lab#{id}`.
|
|
36
|
+
|
|
37
|
+
### Propskit (labeled property controls)
|
|
38
|
+
|
|
39
|
+
Full-surface `fig-field` wrappers. Prefer these over hand-rolled label+control rows when building lab/property UIs.
|
|
40
|
+
|
|
41
|
+
Shared:
|
|
42
|
+
|
|
43
|
+
- `label`, `direction` (`horizontal` default for most), `size` (`""` | `large`), `disabled`
|
|
44
|
+
- `default` — reset target (may differ from initial `value`)
|
|
45
|
+
- Right-click **Reset** menu; `resetToDefault()`
|
|
46
|
+
- `propskit-slider` also double-click resets
|
|
47
|
+
- Forward remaining attrs to the inner control
|
|
48
|
+
|
|
49
|
+
| Tag | Playground | Inner control | Notes |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| `propskit-switch` | `#propskit-switch` | `fig-switch` | `checked`, `default` boolean |
|
|
52
|
+
| `propskit-color` | `#propskit-color` | `fig-input-color` | `alpha` default true |
|
|
53
|
+
| `propskit-gradient` | `#propskit-gradient` | `fig-input-gradient` | `edit`, `mode="handle\|tip"` |
|
|
54
|
+
| `propskit-select` | `#propskit-select` | `fig-select` | `options` or slotted `fig-select-options` |
|
|
55
|
+
| `propskit-text` | `#propskit-text` | `fig-input-text` | `type`, `readonly` |
|
|
56
|
+
| `propskit-number` | `#propskit-number` | `fig-input-number` | `min`, `max`, `step`, `precision`, `units`, `steppers` |
|
|
57
|
+
| `propskit-slider` | `#propskit-slider` | `fig-slider` | `type` range/hue/delta/stepper/opacity; `elastic` default true |
|
|
58
|
+
| `propskit-position` | `#propskit-position` | two numbers | `x`, `y`, `units="percent"` |
|
|
59
|
+
| `propskit-color-point` | `#propskit-color-point` | color + position | JSON `value`; `collapsible`, `open` |
|
|
60
|
+
| `propskit-point-radius` | `#propskit-point-radius` | position + radius | JSON `value` |
|
|
61
|
+
| `propskit-point-radius-angle` | `#propskit-point-radius-angle` | + angle | JSON `value` |
|
|
62
|
+
| `propskit-point-point` | `#propskit-point-point` | start/end | `{ x, y, x2, y2 }` |
|
|
63
|
+
| `propskit-group` | `#propskit-group` | group chrome | `name`, `open`, `show-reset` |
|
|
64
|
+
| `propskit-oscillator` | `#oscillator` | waveform editor | JSON `waves`; `edit`, `precision`, `aspect-ratio` |
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<propskit-slider
|
|
68
|
+
label="Opacity"
|
|
69
|
+
direction="horizontal"
|
|
70
|
+
type="opacity"
|
|
71
|
+
value="100"
|
|
72
|
+
default="100"
|
|
73
|
+
min="0"
|
|
74
|
+
max="100"
|
|
75
|
+
units="%"
|
|
76
|
+
></propskit-slider>
|
|
77
|
+
|
|
78
|
+
<propskit-select label="Blend" value="multiply" options="Normal,Multiply,Screen"></propskit-select>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Rich select (requires editor):
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<propskit-select label="Space" value="oklab">
|
|
85
|
+
<fig-select-options slot="panel">
|
|
86
|
+
<fig-select-option value="srgb" label="Classic">…</fig-select-option>
|
|
87
|
+
</fig-select-options>
|
|
88
|
+
</propskit-select>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Canvas and spatial
|
|
92
|
+
|
|
93
|
+
| Tag | Playground | Notes |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| `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` |
|
|
96
|
+
| `fig-input-angle` | `#angle` | Dial + optional text. `text`, `dial` default true, `rotations`, `min`/`max`/`units` |
|
|
97
|
+
| `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 }` |
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<div style="position:relative; aspect-ratio:1; width:100%">
|
|
101
|
+
<fig-canvas-control
|
|
102
|
+
type="point-radius-angle"
|
|
103
|
+
name="Position"
|
|
104
|
+
value='{"x":50,"y":50,"radius":60,"angle":45}'
|
|
105
|
+
snapping="modifier"
|
|
106
|
+
></fig-canvas-control>
|
|
107
|
+
</div>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Omit `handle` on `fig-reorder` to drag whole rows. Set `handle` when children contain sliders/handles so those stay interactive.
|
|
111
|
+
|
|
112
|
+
### AI composer (presentation)
|
|
113
|
+
|
|
114
|
+
These are layout shells. Wire behavior yourself.
|
|
115
|
+
|
|
116
|
+
| Tag | Playground | Notes |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `fig-ai-prompt` | `#ai-prompt` | Composer: slot `fig-input-text`, `fig-footer`, buttons, optional `fig-select` |
|
|
119
|
+
| `fig-ai-context` | (with prompt) | Open area above prompt for attachments/status |
|
|
120
|
+
| `fig-chat-message` | `#ai-chat-message` | `from="user\|agent"`. Optional `fig-avatar`, `fig-attachments` |
|
|
121
|
+
| `fig-attachments` / `fig-attachment` | `#ai-attachments` | `src`, `name`, `value`, `removable` default true |
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<fig-chat-message from="user">
|
|
125
|
+
Create a settings panel.
|
|
126
|
+
<fig-attachments aria-label="Message attachments">
|
|
127
|
+
<fig-attachment value="settings" name="settings.png" src="…" removable="false"></fig-attachment>
|
|
128
|
+
</fig-attachments>
|
|
129
|
+
<fig-avatar name="Rogie King"></fig-avatar>
|
|
130
|
+
</fig-chat-message>
|
|
131
|
+
<fig-chat-message from="agent">
|
|
132
|
+
<fig-shimmer><span>Thinking…</span></fig-shimmer>
|
|
133
|
+
</fig-chat-message>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Control choice
|
|
137
|
+
|
|
138
|
+
| Intent | Use |
|
|
139
|
+
|---|---|
|
|
140
|
+
| Labeled boolean | `propskit-switch` |
|
|
141
|
+
| Labeled continuous number | `propskit-slider` |
|
|
142
|
+
| Labeled exact number | `propskit-number` |
|
|
143
|
+
| Labeled text | `propskit-text` |
|
|
144
|
+
| Labeled discrete list | `propskit-select` (not `fig-dropdown`) |
|
|
145
|
+
| Labeled color / gradient | `propskit-color` / `propskit-gradient` |
|
|
146
|
+
| X/Y | `propskit-position` |
|
|
147
|
+
| Spatial on a canvas | `fig-canvas-control` |
|
|
148
|
+
| Angle | `fig-input-angle` |
|
|
149
|
+
| Section of props | `propskit-group` or core `fig-group` |
|
|
150
|
+
| Reorder rows | `fig-reorder` |
|
|
151
|
+
|
|
152
|
+
Raw `fig-field` + core control is still valid (see `propkit` skill / `/propskit`).
|
|
153
|
+
|
|
154
|
+
## Maintainer notes
|
|
155
|
+
|
|
156
|
+
- Implementation: `fig-lab.js`, styles: `fig-lab.css`
|
|
157
|
+
- Keep lab out of `fig.js`
|
|
158
|
+
- Playground loads lab only on `/propskit` and `/propskit/lab`
|
|
159
|
+
- Update `labSections.ts` + `attributeRules.ts` with API changes
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# FigUI3 lab API reference
|
|
2
|
+
|
|
3
|
+
Playground: `/propskit/lab#{id}`. Rules: `playground/src/lib/attributeRules.ts`.
|
|
4
|
+
|
|
5
|
+
## Propskit reset
|
|
6
|
+
|
|
7
|
+
- `default` attr stores the reset value
|
|
8
|
+
- `resetToDefault()` on the host
|
|
9
|
+
- Context menu item `reset-default`
|
|
10
|
+
- Slider: double-click also resets
|
|
11
|
+
- Equality helpers treat booleans and JSON objects
|
|
12
|
+
|
|
13
|
+
## `propskit-select`
|
|
14
|
+
|
|
15
|
+
Observed: `label`, `direction`, `aria-label`, `options`, `value`.
|
|
16
|
+
|
|
17
|
+
Uses `fig-select` when `fig-select`, `fig-select-options`, and `fig-select-option` are registered; otherwise a fallback control.
|
|
18
|
+
|
|
19
|
+
Options attr: JSON array, comma, or newline. Authored `fig-select-options slot="panel"` wins for rich menus.
|
|
20
|
+
|
|
21
|
+
## `propskit-slider`
|
|
22
|
+
|
|
23
|
+
Playground attrs: `type` (`range`, `hue`, `delta`, `stepper`, `opacity`), `color`, `label`, `default`, `units`, `elastic` (default true), `size`, `steppers`, `disabled`.
|
|
24
|
+
|
|
25
|
+
Inner `fig-slider` still needs `min` / `max` / `step` / `value` as forwarded attrs.
|
|
26
|
+
|
|
27
|
+
## Point JSON shapes
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{"x":50,"y":50}
|
|
31
|
+
{"x":50,"y":50,"radius":60}
|
|
32
|
+
{"x":50,"y":50,"radius":60,"angle":45}
|
|
33
|
+
{"x":10,"y":10,"x2":90,"y2":90}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Color-point combines a color payload with `x`/`y`.
|
|
37
|
+
|
|
38
|
+
Collapsible point groups: `collapsible` and `open` default true (string booleans).
|
|
39
|
+
|
|
40
|
+
## `fig-canvas-control`
|
|
41
|
+
|
|
42
|
+
Observed: `type`, `value`, `color`, `name`, `tooltips`, `disabled`, `drag-surface`, `snapping`.
|
|
43
|
+
|
|
44
|
+
Parent must be `position: relative` (or similar) so the control can fill it. Playground wraps in an aspect-ratio box.
|
|
45
|
+
|
|
46
|
+
Types: `point`, `color`, `point-radius`, `point-radius-angle`, `point-point`.
|
|
47
|
+
|
|
48
|
+
## `fig-input-angle`
|
|
49
|
+
|
|
50
|
+
Observed include `value`, `precision`, `text`, `min`, `max`, `units`, `dial`, plus `rotations`.
|
|
51
|
+
|
|
52
|
+
`dial` defaults true. `text="true"` shows the numeric field.
|
|
53
|
+
|
|
54
|
+
## `fig-reorder`
|
|
55
|
+
|
|
56
|
+
Observed: `axis`, `handle`, `disabled`.
|
|
57
|
+
|
|
58
|
+
Event `reorder`: `{ oldIndex, newIndex, item }`.
|
|
59
|
+
|
|
60
|
+
Nested drag is ignored for sliders, handles, canvas controls, and most propskit spatial controls so inner gestures still work. If a row is still stolen, set `handle` to a drag-affordance selector.
|
|
61
|
+
|
|
62
|
+
## AI shells
|
|
63
|
+
|
|
64
|
+
`fig-ai-prompt`, `fig-ai-context`, `fig-chat-message` are empty custom elements (presentation CSS only).
|
|
65
|
+
|
|
66
|
+
`fig-attachment` observed: `src`, `name`, `value`, `removable`, `disabled`.
|
|
67
|
+
`fig-chat-message`: `from="agent|user"`.
|