@rogieking/figui3 11.4.1 → 11.5.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-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,6 +37,8 @@ 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 |
41
43
  | `fig-reorder` | Pointer- and keyboard-reorderable direct-child list |
42
44
  | `fig-interpolation-swatch` | Gradient interpolation preview swatch |
@@ -55,7 +57,7 @@ Do not use `picker` or `picker-anchor` on `fig-input-color`. Forward picker chro
55
57
 
56
58
  ## Maintainer notes
57
59
 
58
- - Implementation: `fig-editor.js`, styles: `fig-editor.css`
60
+ - Implementation: `fig-editor.js` / `fig-editor.css`; property row: `fig-property.js` / `fig-property.css` (imported by the editor bundle)
59
61
  - Do not move fill-picker or select into `fig.js`
60
62
  - Nested overlay positioning: keep `popover="manual"` on the select popup
61
63
  - Tests: `tests/figui/component-contracts.spec.ts` (ghost variant, sticky separator vs overflow-start)
@@ -66,6 +66,61 @@ 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
+ - Attrs: `label`, `leading` (`drag` | `chevron`), `trailing` (`remove` | `add` | `bind`), `show-leading`, `show-trailing`
117
+ - Slots: `input` (one direct primary control), `label`, `leading`, `trailing`
118
+ - Authored label markup overrides the `label` attribute.
119
+ - Authored accessory slots override generated shortcuts.
120
+ - Omitted or `"hover"` show attributes use hover visibility; `"false"` never shows the slot; an empty/present attribute always shows it.
121
+ - Generated trailing controls emit bubbling, composed `remove`, `add`, or `bind` events with the slotted control in `detail.input`.
122
+ - Child input events bubble unchanged.
123
+
69
124
  ## `fig-palette-editor`
70
125
 
71
126
  Reusable ordered palette editor used by `fig-input-palette edit="picker"`.
@@ -35,6 +35,31 @@ 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
+
38
63
  ## Reorder
39
64
 
40
65
  `fig-reorder` observes `axis`, `handle`, `items`, `indicator`, and `disabled`.
@@ -358,6 +358,7 @@ Handlers below assume `onInput` / `onChange` / `onClick` from [react.md](react.m
358
358
  ```
359
359
 
360
360
  - Attrs: `direction` (`horizontal` | `vertical`), `label`, `columns`
361
+ - Slots: `leading` for an accessory before the label; `trailing` for an end action.
361
362
  - Put control attrs on the control, not the field.
362
363
 
363
364
  ### `fig-stack`
@@ -80,8 +80,10 @@ 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-property"
85
87
  | "fig-input-text"
86
88
  | "fig-input-wheel"
87
89
  | "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,33 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [11.5.0]
6
+
7
+ ### Added
8
+
9
+ - Added the composable `fig-property` editor row with generated leading/trailing accessories, visibility controls, accessible labels, and action events.
10
+ - Added `fig-input-point` for paired X/Y numeric values.
11
+ - Added standalone `fig-property.js` and `fig-property.css` package exports and editor skill guidance.
12
+
13
+ ### Changed
14
+
15
+ - Rebuilt palette editor rows and fill-picker gradient stop rows with `fig-property`.
16
+ - Expanded playground editor controls, property examples, event output, and direct hash loading.
17
+ - Updated easing preset artwork to use `fig-icon` prepend content and added the drag-handle icon token.
18
+ - Refined `fig-field` leading/trailing slot handling and property-row hover layout.
19
+
20
+ ### Fixed
21
+
22
+ - Kept hover-only trailing property actions from reserving space or shifting the input.
23
+ - Made generated property actions bubble across shadow roots with their slotted input in event detail.
24
+
25
+ ## [11.4.2]
26
+
27
+ ### Changed
28
+
29
+ - Simplified character prepend icons in number inputs to use direct text content.
30
+ - Refined prepend icon color inheritance and number-input secondary coloring.
31
+
5
32
  ## [11.4.1]
6
33
 
7
34
  ### Changed
package/README.md CHANGED
@@ -108,12 +108,14 @@ 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 |
118
120
  | [Reorder](#reorder) | `<fig-reorder>` | Pointer- and keyboard-reorderable list |
119
121
  | [Gradient Input](#gradient-input) | `<fig-input-gradient>` | Gradient editor with stops |
@@ -510,6 +512,27 @@ The `value`, `min`, `max`, and `step` properties mirror their attributes. `aria-
510
512
 
511
513
  ---
512
514
 
515
+ #### Input Point
516
+
517
+ `<fig-input-point>` — [demo](https://rog.ie/figui3/#input-point)
518
+
519
+ 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`.
520
+
521
+ | Attribute | Type | Default | Description |
522
+ |---|---|---|---|
523
+ | `x` | number | `0` | Horizontal coordinate |
524
+ | `y` | number | `0` | Vertical coordinate |
525
+ | `units` | string | — | Unit string forwarded to both number inputs |
526
+ | `full` | boolean | `false` | Fill the parent width |
527
+
528
+ ```html
529
+ <fig-input-point x="24" y="16" units="%"></fig-input-point>
530
+ ```
531
+
532
+ Requires `fig-editor.js` and `fig-editor.css`.
533
+
534
+ ---
535
+
513
536
  #### File Input
514
537
 
515
538
  `<fig-input-file>` — [demo](https://rog.ie/figui3/#file-input)
@@ -684,6 +707,20 @@ An editable palette of solid colors, each rendered as a `<fig-input-color>` swat
684
707
 
685
708
  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
709
 
710
+ #### Property
711
+
712
+ `<fig-property>`
713
+
714
+ 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.
715
+
716
+ ```html
717
+ <fig-property label="Size" leading="drag" trailing="remove">
718
+ <fig-input-number slot="input" value="16" units="px" full></fig-input-number>
719
+ </fig-property>
720
+ ```
721
+
722
+ Import `fig-property.js` and `fig-property.css` directly, or use the `fig-editor` bundle, which includes both.
723
+
687
724
  #### Palette Editor
688
725
 
689
726
  `<fig-palette-editor>`
@@ -1290,6 +1327,8 @@ Adjacent `fig-field` children in a horizontal stack share compact gutters.
1290
1327
 
1291
1328
  A form field wrapper with flexible layout. Automatically links `<label>` to the first `fig-*` child for accessibility.
1292
1329
 
1330
+ 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.
1331
+
1293
1332
  | Attribute | Type | Default | Description |
1294
1333
  |---|---|---|---|
1295
1334
  | `direction` | string | `"column"` | `"column"`, `"row"`, `"horizontal"` |
@@ -1298,8 +1337,12 @@ A form field wrapper with flexible layout. Automatically links `<label>` to the
1298
1337
 
1299
1338
  ```html
1300
1339
  <fig-field direction="horizontal" columns="thirds">
1340
+ <fig-icon slot="leading" name="drag-handle" size="small"></fig-icon>
1301
1341
  <label>Opacity</label>
1302
1342
  <fig-slider value="50" units="%"></fig-slider>
1343
+ <fig-button slot="trailing" variant="ghost" icon aria-label="Reset">
1344
+ <fig-icon name="reset"></fig-icon>
1345
+ </fig-button>
1303
1346
  </fig-field>
1304
1347
  ```
1305
1348
 
package/components.css CHANGED
@@ -433,6 +433,7 @@
433
433
  --icon-24-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M7.5 6C6.67157 6 6 6.67157 6 7.5V16.5C6 17.3284 6.67157 18 7.5 18H16.5C17.3284 18 18 17.3284 18 16.5V7.5C18 6.67157 17.3284 6 16.5 6H7.5ZM7 7.5C7 7.22386 7.22386 7 7.5 7H16.5C16.7761 7 17 7.22386 17 7.5V14.793L14.3536 12.1464C14.1583 11.9512 13.8417 11.9512 13.6464 12.1464L12 13.7929L9.85355 11.6464C9.65829 11.4512 9.34171 11.4512 9.14645 11.6464L7 13.7929V7.5ZM7 15.2071V16.5C7 16.7761 7.22386 17 7.5 17H16.5C16.7761 17 17 16.7761 17 16.5V16.2071L14 13.2071L12.3536 14.8536C12.1583 15.0488 11.8417 15.0488 11.6464 14.8536L9.5 12.7071L7 15.2071ZM13.5 8C14.3284 8 15 8.67157 15 9.5C15 10.3284 14.3284 11 13.5 11C12.6716 11 12 10.3284 12 9.5C12 8.67157 12.6716 8 13.5 8ZM13.5 9C13.2239 9 13 9.22386 13 9.5C13 9.77614 13.2239 10 13.5 10C13.7761 10 14 9.77614 14 9.5C14 9.22386 13.7761 9 13.5 9Z' fill='black' fill-opacity='0.9'/%3E%3C/svg%3E");
434
434
  --icon-24-video: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16 6C17.1046 6 18 6.89543 18 8V16C18 17.1046 17.1046 18 16 18H8C6.89543 18 6 17.1046 6 16V8C6 6.89543 6.89543 6 8 6H16ZM8 7C7.44772 7 7 7.44772 7 8V16C7 16.5523 7.44772 17 8 17H16C16.5523 17 17 16.5523 17 16V8C17 7.44772 16.5523 7 16 7H8ZM9.99805 9.13477C10.3063 8.95591 10.6866 8.955 10.9961 9.13184L14.4961 11.1318C14.8077 11.3099 15 11.6411 15 12C15 12.3589 14.8077 12.6901 14.4961 12.8682L10.9961 14.8682C10.6866 15.045 10.3063 15.0441 9.99805 14.8652C9.68973 14.6863 9.5 14.3565 9.5 14V10C9.5 9.64353 9.68973 9.31369 9.99805 9.13477ZM10.5 14L14 12L10.5 10V14Z' fill='black' fill-opacity='0.9'/%3E%3C/svg%3E");
435
435
  --icon-16-video: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.5 3C12.3284 3 13 3.67157 13 4.5V11.5C13 12.3284 12.3284 13 11.5 13H4.5L4.34668 12.9922C3.59028 12.9154 3 12.2767 3 11.5V4.5C3 3.67157 3.67157 3 4.5 3H11.5ZM4.5 4C4.22386 4 4 4.22386 4 4.5V11.5C4 11.7761 4.22386 12 4.5 12H11.5C11.7761 12 12 11.7761 12 11.5V4.5C12 4.22386 11.7761 4 11.5 4H4.5ZM6.50684 5.62988C6.82034 5.45238 7.20572 5.45722 7.51465 5.64258L10.0146 7.14258C10.3158 7.32332 10.5 7.64879 10.5 8C10.5 8.35121 10.3158 8.67668 10.0146 8.85742L7.51465 10.3574C7.20572 10.5428 6.82034 10.5476 6.50684 10.3701C6.19356 10.1926 6 9.86012 6 9.5V6.5C6 6.13988 6.19356 5.80744 6.50684 5.62988ZM7 9.5L9.5 8L7 6.5V9.5Z' fill='black' fill-opacity='0.9'/%3E%3C/svg%3E");
436
+ --icon-16-drag-handle: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 11.5C11 11.7761 10.7761 12 10.5 12H5.5C5.22386 12 5 11.7761 5 11.5C5 11.2239 5.22386 11 5.5 11H10.5C10.7761 11 11 11.2239 11 11.5ZM11 8C11 8.27614 10.7761 8.5 10.5 8.5H5.5C5.22386 8.5 5 8.27614 5 8C5 7.72386 5.22386 7.5 5.5 7.5H10.5C10.7761 7.5 11 7.72386 11 8ZM11 4.5C11 4.77614 10.7761 5 10.5 5H5.5C5.22386 5 5 4.77614 5 4.5C5 4.22386 5.22386 4 5.5 4H10.5C10.7761 4 11 4.22386 11 4.5Z' fill='black' fill-opacity='0.5'/%3E%3C/svg%3E");
436
437
  --tip-pointer: path("M8 6L2 0H14L8 6Z");
437
438
 
438
439
 
@@ -4341,6 +4342,7 @@ fig-input-number {
4341
4342
  & [slot="prepend"] {
4342
4343
  order: 0;
4343
4344
  padding-right: 0;
4345
+ color: var(--figma-color-text-secondary);
4344
4346
  margin-right: calc(var(--spacer-2) * -1);
4345
4347
  }
4346
4348
 
@@ -4889,32 +4891,32 @@ fig-field {
4889
4891
  grid-template-columns:
4890
4892
  var(--fig-field-left-padding) minmax(0, var(--fig-field-label-ratio))
4891
4893
  minmax(0, var(--fig-field-input-ratio)) var(--fig-field-right-padding);
4892
- grid-template-areas: "chevron label input pad";
4894
+ grid-template-areas: "leading label input pad";
4893
4895
  margin: 0;
4894
4896
  padding: var(--fig-field-top-padding) 0 var(--fig-field-bottom-padding) 0;
4895
4897
  gap: 0;
4896
4898
  align-items: start;
4897
4899
 
4898
4900
  &:not([direction="vertical"]):has(> label):has(
4899
- > :not(label):not(.fig-field-chevron):not(
4901
+ > :not(label):not([slot="leading"]):not([slot="trailing"]):not(
4900
4902
  fig-button[icon]:not([icon="false"])
4901
4903
  )
4902
4904
  + fig-button[icon]:not([icon="false"])
4903
4905
  ) {
4904
- & > :not(label):not(.fig-field-chevron):not(
4906
+ & > :not(label):not([slot="leading"]):not([slot="trailing"]):not(
4905
4907
  fig-button[icon]:not([icon="false"])
4906
4908
  ):has(+ fig-button[icon]:not([icon="false"])) {
4907
4909
  justify-self: start;
4908
4910
  width: calc(100% - var(--spacer-4) - var(--spacer-1));
4909
4911
  }
4910
4912
 
4911
- & > :not(label):not(.fig-field-chevron):not(
4913
+ & > :not(label):not([slot="leading"]):not([slot="trailing"]):not(
4912
4914
  fig-button[icon]:not([icon="false"])
4913
4915
  ):has(+ fig-button[icon]:not([icon="false"])[variant="ghost"]) {
4914
4916
  width: calc(100% - var(--spacer-4));
4915
4917
  }
4916
4918
 
4917
- & > :not(label):not(.fig-field-chevron):not(
4919
+ & > :not(label):not([slot="leading"]):not([slot="trailing"]):not(
4918
4920
  fig-button[icon]:not([icon="false"])
4919
4921
  )
4920
4922
  + fig-button[icon]:not([icon="false"]) {
@@ -4923,7 +4925,7 @@ fig-field {
4923
4925
  z-index: 1;
4924
4926
  }
4925
4927
 
4926
- & > :not(label):not(.fig-field-chevron):not(
4928
+ & > :not(label):not([slot="leading"]):not([slot="trailing"]):not(
4927
4929
  fig-button[icon]:not([icon="false"])
4928
4930
  )
4929
4931
  + fig-button[icon]:not([icon="false"])[variant="ghost"] {
@@ -4931,6 +4933,18 @@ fig-field {
4931
4933
  }
4932
4934
  }
4933
4935
 
4936
+ &:has(> label):has(> [slot="trailing"]) {
4937
+ & > :not(label):not([slot="leading"]):not([slot="trailing"]) {
4938
+ justify-self: start;
4939
+ width: calc(100% - var(--spacer-4) - var(--spacer-1));
4940
+ }
4941
+
4942
+ &:has(> [slot="trailing"][variant="ghost"])
4943
+ > :not(label):not([slot="leading"]):not([slot="trailing"]) {
4944
+ width: calc(100% - var(--spacer-4));
4945
+ }
4946
+ }
4947
+
4934
4948
 
4935
4949
  &[columns="half"] {
4936
4950
  --fig-field-label-ratio: 2fr;
@@ -4971,10 +4985,34 @@ fig-field {
4971
4985
  padding-block: 0;
4972
4986
  }
4973
4987
 
4974
- & > *:not(.fig-field-chevron):not(label) {
4988
+ & > *:not([slot="leading"]):not([slot="trailing"]):not(label) {
4975
4989
  grid-area: input;
4976
4990
  }
4977
4991
 
4992
+ & > [slot="leading"] {
4993
+ grid-area: leading;
4994
+ &[size="small"]{
4995
+ margin-top: var(--spacer-1);
4996
+ }
4997
+
4998
+ &[name="drag-handle"]{
4999
+ visibility: hidden;
5000
+ }
5001
+ }
5002
+ &:hover > [slot="leading"][name="drag-handle"]{
5003
+ visibility: visible;
5004
+ }
5005
+
5006
+ & > [slot="trailing"] {
5007
+ grid-area: input;
5008
+ justify-self: end;
5009
+ z-index: 1;
5010
+
5011
+ &[variant="ghost"] {
5012
+ margin-right: calc(var(--spacer-1) * -1);
5013
+ }
5014
+ }
5015
+
4978
5016
  & > progress {
4979
5017
  align-self: center;
4980
5018
  }
@@ -4987,7 +5025,6 @@ fig-field {
4987
5025
  transition: transform var(--transition-duration)
4988
5026
  var(--transition-timing-function);
4989
5027
  flex-shrink: 0;
4990
- grid-area: chevron;
4991
5028
  margin-top: var(--spacer-1);
4992
5029
  }
4993
5030
 
@@ -5005,10 +5042,19 @@ fig-field {
5005
5042
  padding-inline: var(--fig-field-left-padding) calc(var(--fig-field-right-padding) * 0.5);
5006
5043
  }
5007
5044
 
5008
- & > *:not(fig-button):not(.fig-field-chevron) {
5045
+ & > *:not(fig-button):not([slot="leading"]):not([slot="trailing"]) {
5009
5046
  flex: 1 1 0;
5010
5047
  min-width: 0;
5011
5048
  }
5049
+
5050
+ & > [slot="leading"] {
5051
+ order: -1;
5052
+ }
5053
+
5054
+ & > [slot="trailing"] {
5055
+ order: 1;
5056
+ margin-left: auto;
5057
+ }
5012
5058
  }
5013
5059
 
5014
5060
  &[direction="vertical"] {
@@ -5017,7 +5063,7 @@ fig-field {
5017
5063
  );
5018
5064
  grid-template-rows: auto auto;
5019
5065
  grid-template-areas:
5020
- "chevron label pad"
5066
+ "leading label pad"
5021
5067
  ". input pad";
5022
5068
 
5023
5069
  & > label {
@@ -6489,6 +6535,7 @@ fig-toolbelt {
6489
6535
  fig-icon {
6490
6536
  --size: var(--spacer-4);
6491
6537
  --icon: none;
6538
+ color: var(--icon-color, inherit);
6492
6539
 
6493
6540
  &[size="small"] {
6494
6541
  --size: var(--spacer-3);
@@ -6516,7 +6563,7 @@ fig-icon {
6516
6563
  &:has(> *),
6517
6564
  &:not([name]) {
6518
6565
  background: transparent !important;
6519
- color: var(--icon-color, inherit);
6566
+
6520
6567
  -webkit-mask-image: none;
6521
6568
  mask-image: none;
6522
6569
  }
@@ -6524,6 +6571,7 @@ fig-icon {
6524
6571
  &:not([name]) {
6525
6572
  align-items: center;
6526
6573
  justify-content: center;
6574
+ line-height: 1;
6527
6575
  }
6528
6576
 
6529
6577
  & > label {
@@ -7282,6 +7330,7 @@ fig-menu::part(listbox) {
7282
7330
  display: flex;
7283
7331
  flex-shrink: 0;
7284
7332
  align-items: center;
7333
+ text-align: left;
7285
7334
  gap: 0;
7286
7335
  width: 100%;
7287
7336
  padding: var(--fig-menu-item-padding);