@rogieking/figui3 9.1.5 → 9.2.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.
@@ -17,6 +17,24 @@ Handlers below assume `onInput` / `onChange` / `onClick` from [react.md](react.m
17
17
  - Attrs: `variant` (`""` primary, `secondary`, `destructive`, `destructiveSecondary`, `destructiveGhost`, `destructiveLink`, `ghost`, `link`, `input`, `overlay`), `type` (`button`, `toggle`, `submit`, `select`, `upload`), `size` (`""`, `large`, `compact`), `align`, `selected`, `disabled`, `icon`, `close-dialog`
18
18
  - Events: `click`; toggle also reflects `selected`
19
19
 
20
+ ### `fig-property-button`
21
+
22
+ ```tsx
23
+ <fig-property-button
24
+ icon="settings"
25
+ aria-haspopup="dialog"
26
+ aria-controls="effects-editor"
27
+ onClick={onClick}
28
+ >
29
+ Effects
30
+ </fig-property-button>
31
+ ```
32
+
33
+ - Attrs: `icon` (required fig-icon name), `selected`, `disabled`, `aria-haspopup`, `aria-expanded`, `aria-controls`
34
+ - Fixed presentation: secondary, full width, start aligned, leading icon
35
+ - Trigger only: the consumer owns and positions the corresponding popup/dialog
36
+ - Events: `click`
37
+
20
38
  ### `fig-button-combo`
21
39
 
22
40
  ```tsx
@@ -301,6 +319,18 @@ Handlers below assume `onInput` / `onChange` / `onClick` from [react.md](react.m
301
319
  - Attrs: `direction` (`horizontal` | `vertical`), `label`, `columns`
302
320
  - Put control attrs on the control, not the field.
303
321
 
322
+ ### `fig-stack`
323
+
324
+ ```tsx
325
+ <fig-stack direction="vertical" gap="3">
326
+ <fig-stack justify="between" full>{children}</fig-stack>
327
+ <fig-stack direction="grid" columns="3">{children}</fig-stack>
328
+ </fig-stack>
329
+ ```
330
+
331
+ - Attrs: `direction` (`horizontal` default | `vertical` | `grid`), `gap` (spacer token or CSS length), `align`, `justify` (`start` | `center` | `end` | `between` | `around` | `stretch`), `wrap`, `full`, `columns` (grid), `min-width` (grid auto-fill)
332
+ - Use instead of the deprecated `hstack` / `vstack` tags.
333
+
304
334
  ### `fig-group`
305
335
 
306
336
  ```tsx
@@ -51,6 +51,7 @@ type FigTag =
51
51
  | "fig-attachments"
52
52
  | "fig-avatar"
53
53
  | "fig-button"
54
+ | "fig-property-button"
54
55
  | "fig-button-combo"
55
56
  | "fig-canvas-control"
56
57
  | "fig-card"
@@ -16,6 +16,14 @@ Public API: `README.md`. React recipes: [components.md](components.md).
16
16
  - `size`: `""`, `large`, `compact`
17
17
  - `selected`, `disabled`, `icon` (presence)
18
18
 
19
+ ## `fig-property-button`
20
+
21
+ - `icon`: required `fig-icon` name
22
+ - `selected`, `disabled`
23
+ - `aria-haspopup`, `aria-expanded`, `aria-controls`
24
+ - Fixed secondary, full-width, start-aligned presentation
25
+ - Trigger only; consumers manage the popup/dialog
26
+
19
27
  ## `fig-input-text`
20
28
 
21
29
  - `type`: `text`, `email`, `password`, `search`, `url`
package/README.md CHANGED
@@ -95,6 +95,7 @@ Minimal example:
95
95
  | Component | Tag | Description |
96
96
  |---|---|---|
97
97
  | [Button](#button) | `<fig-button>` | Buttons with variants, toggle, select, upload |
98
+ | [Property Button](#property-button) | `<fig-property-button>` | Full-width secondary trigger for property editors |
98
99
  | [Dropdown](#dropdown) | `<fig-dropdown>` | Native select wrapper with Figma styling |
99
100
  | [Select](#select) | `<fig-select>` | Custom listbox select (requires `fig-editor.js`) |
100
101
  | [Combo Input](#combo-input) | `<fig-combo-input>` | Text input with dropdown suggestions |
@@ -180,6 +181,45 @@ Minimal example:
180
181
 
181
182
  ---
182
183
 
184
+ #### Property Button
185
+
186
+ `<fig-property-button>` — [demo](https://rog.ie/figui3/#property-button)
187
+
188
+ A full-width secondary trigger for opening an effect editor, binding editor, preset picker, or other property-specific flyout. The component supplies the surface and generated leading icon but does not create or position a popup.
189
+
190
+ | Attribute | Type | Default | Description |
191
+ |---|---|---|---|
192
+ | `icon` | string | required | `fig-icon` name rendered in the prepend slot |
193
+ | `selected` | boolean | `false` | Selected styling, typically while the editor is open |
194
+ | `disabled` | boolean | `false` | Disabled state |
195
+ | `aria-haspopup` | string | — | Popup type exposed to assistive technology |
196
+ | `aria-expanded` | boolean | — | Whether the controlled flyout is open |
197
+ | `aria-controls` | string | — | ID of the controlled flyout |
198
+
199
+ ```html
200
+ <fig-property-button
201
+ id="effects-trigger"
202
+ icon="settings"
203
+ aria-haspopup="dialog"
204
+ aria-controls="effects-editor"
205
+ >
206
+ Effects
207
+ </fig-property-button>
208
+
209
+ <dialog
210
+ is="fig-popup"
211
+ id="effects-editor"
212
+ anchor="#effects-trigger"
213
+ position="bottom left"
214
+ >
215
+ <fig-content>Effect controls</fig-content>
216
+ </dialog>
217
+ ```
218
+
219
+ Wire click/open state in application code. `variant="secondary"`, `full`, and start alignment are enforced by the component.
220
+
221
+ ---
222
+
183
223
  #### Dropdown
184
224
 
185
225
  `<fig-dropdown>` — [demo](https://rog.ie/figui3/#dropdown)
@@ -1073,6 +1113,41 @@ timelines. Unsupported browsers retain ordinary scrolling without a fade.
1073
1113
 
1074
1114
  ---
1075
1115
 
1116
+ #### Stack
1117
+
1118
+ `<fig-stack>` — [demo](https://rog.ie/figui3/#stack)
1119
+
1120
+ A layout primitive for rows, columns, and grids. Replaces the deprecated `hstack` / `vstack` tags, which still render as aliases.
1121
+
1122
+ | Attribute | Type | Default | Description |
1123
+ |---|---|---|---|
1124
+ | `direction` | string | `"horizontal"` | `"horizontal"`, `"vertical"`, `"grid"` |
1125
+ | `gap` | string | `"2"` | Spacer token (`"0"`–`"6"`, `"2-5"`, `"half"`) or any CSS length |
1126
+ | `align` | string | `"center"` (horizontal), `"start"` (vertical), `"stretch"` (grid) | `"start"`, `"center"`, `"end"`, `"stretch"`, `"baseline"` |
1127
+ | `justify` | string | `"start"` | `"start"`, `"center"`, `"end"`, `"between"`, `"around"`, `"stretch"` |
1128
+ | `wrap` | boolean | `false` | Wrap items onto multiple lines |
1129
+ | `full` | boolean | `false` | Fill the parent's width |
1130
+ | `columns` | string | auto-fill | Grid only: column count (`"3"`) or a `grid-template-columns` value |
1131
+ | `min-width` | string | `"5rem"` | Grid only: minimum auto-fill column width |
1132
+
1133
+ Adjacent `fig-field` children in a horizontal stack share compact gutters.
1134
+
1135
+ ```html
1136
+ <fig-stack direction="vertical" gap="3">
1137
+ <fig-stack justify="between" full>
1138
+ <label>Layers</label>
1139
+ <fig-button variant="ghost" icon><fig-icon name="add"></fig-icon></fig-button>
1140
+ </fig-stack>
1141
+ <fig-stack direction="grid" columns="3">
1142
+ <fig-swatch value="#0D99FF"></fig-swatch>
1143
+ <fig-swatch value="#FFC700"></fig-swatch>
1144
+ <fig-swatch value="#14AE5C"></fig-swatch>
1145
+ </fig-stack>
1146
+ </fig-stack>
1147
+ ```
1148
+
1149
+ ---
1150
+
1076
1151
  #### Field
1077
1152
 
1078
1153
  `<fig-field>` — [demo](https://rog.ie/figui3/#field)
package/components.css CHANGED
@@ -804,7 +804,8 @@ select,
804
804
 
805
805
  /* Button */
806
806
  button,
807
- fig-button {
807
+ fig-button,
808
+ fig-property-button {
808
809
  --fig-button-content-alignment: center;
809
810
  --fig-button-text-alignment: center;
810
811
 
@@ -1149,6 +1150,16 @@ fig-button {
1149
1150
  }
1150
1151
  }
1151
1152
 
1153
+ fig-property-button[icon]:not([icon="false"]) {
1154
+ width: 100%;
1155
+ flex: 1 1 auto;
1156
+ padding: 0 calc(var(--spacer-2) - 1px) 0 0;
1157
+
1158
+ &[selected]:not([selected="false"]) {
1159
+ box-shadow: none;
1160
+ }
1161
+ }
1162
+
1152
1163
  /* Combo button */
1153
1164
  .fig-button-combo,
1154
1165
  fig-button-combo,
@@ -2510,6 +2521,7 @@ fig-origin-grid {
2510
2521
  mask-position: center;
2511
2522
  -webkit-mask-size: 24px 24px;
2512
2523
  mask-size: 24px 24px;
2524
+ background-color: var(--figma-color-icon-brand);
2513
2525
  --fig-handle-inner-bg: transparent !important;
2514
2526
  --fig-handle-outline-color: transparent !important;
2515
2527
  --fig-handle-inner-outline: none;
@@ -3624,6 +3636,7 @@ fig-preview {
3624
3636
 
3625
3637
  /* Web Components */
3626
3638
  fig-button,
3639
+ fig-property-button,
3627
3640
  fig-content,
3628
3641
  fig-slider,
3629
3642
  fig-switch,
@@ -3940,47 +3953,111 @@ fig-content{
3940
3953
  }
3941
3954
  }
3942
3955
 
3943
- vstack,
3944
- .vstack,
3945
- [vstack] {
3946
- display: flex;
3947
- flex-direction: column;
3948
- align-items: start;
3949
- gap: var(--spacer-2);
3950
- flex-wrap: wrap;
3951
- }
3952
-
3953
3956
  :root [hidden],
3954
3957
  [hidden] {
3955
3958
  display: none !important;
3956
3959
  }
3957
3960
 
3961
+ fig-stack,
3958
3962
  hstack,
3959
- .hstack{
3963
+ .hstack,
3964
+ vstack,
3965
+ .vstack,
3966
+ [vstack] {
3960
3967
  display: flex;
3961
- gap: var(--hstack-gap, var(--spacer-2));
3962
- align-items: var(--hstack-align, center);
3963
- justify-content: var(--hstack-justify, flex-start);
3964
- flex-wrap: var(--hstack-wrap, nowrap);
3968
+ flex-direction: row;
3969
+ gap: var(--fig-stack-gap, var(--hstack-gap, var(--spacer-2)));
3970
+ align-items: var(--fig-stack-align, var(--hstack-align, center));
3971
+ justify-content: var(--fig-stack-justify, var(--hstack-justify, flex-start));
3972
+ flex-wrap: var(--fig-stack-wrap, var(--hstack-wrap, nowrap));
3973
+ min-width: 0;
3974
+
3975
+ &:where(fig-stack[direction="vertical"], vstack, .vstack, [vstack]) {
3976
+ flex-direction: column;
3977
+ --fig-stack-align: flex-start;
3978
+ }
3979
+
3980
+ &:where(vstack, .vstack, [vstack]) {
3981
+ --fig-stack-wrap: wrap;
3982
+ }
3983
+
3984
+ &:where([direction="grid"]) {
3985
+ display: grid;
3986
+ grid-template-columns: var(
3987
+ --fig-stack-columns,
3988
+ repeat(auto-fill, minmax(min(var(--fig-stack-min-width, 5rem), 100%), 1fr))
3989
+ );
3990
+ --fig-stack-align: stretch;
3991
+ justify-items: var(--fig-stack-justify-items, stretch);
3992
+ }
3965
3993
 
3966
3994
  &[align="start"] {
3967
- --hstack-align: flex-start;
3995
+ --fig-stack-align: flex-start;
3996
+ }
3997
+
3998
+ &[align="center"] {
3999
+ --fig-stack-align: center;
3968
4000
  }
3969
4001
 
3970
4002
  &[align="end"] {
3971
- --hstack-align: flex-end;
4003
+ --fig-stack-align: flex-end;
3972
4004
  }
3973
4005
 
3974
4006
  &[align="stretch"] {
3975
- --hstack-align: stretch;
4007
+ --fig-stack-align: stretch;
4008
+ }
4009
+
4010
+ &[align="baseline"] {
4011
+ --fig-stack-align: baseline;
4012
+ }
4013
+
4014
+ &[justify="start"] {
4015
+ --fig-stack-justify: flex-start;
4016
+ --fig-stack-justify-items: start;
4017
+ }
4018
+
4019
+ &[justify="center"] {
4020
+ --fig-stack-justify: center;
4021
+ --fig-stack-justify-items: center;
4022
+ }
4023
+
4024
+ &[justify="end"] {
4025
+ --fig-stack-justify: flex-end;
4026
+ --fig-stack-justify-items: end;
4027
+ }
4028
+
4029
+ &[justify="between"] {
4030
+ --fig-stack-justify: space-between;
4031
+ }
4032
+
4033
+ &[justify="around"] {
4034
+ --fig-stack-justify: space-around;
4035
+ }
4036
+
4037
+ &[justify="stretch"] {
4038
+ --fig-stack-justify-items: stretch;
4039
+ }
4040
+
4041
+ &[wrap]:not([wrap="false"]) {
4042
+ --fig-stack-wrap: wrap;
3976
4043
  }
3977
4044
 
3978
- & > fig-field:has(+ fig-field) {
3979
- --fig-field-right-padding: var(--spacer-1);
4045
+ &[wrap="false"] {
4046
+ --fig-stack-wrap: nowrap;
3980
4047
  }
3981
4048
 
3982
- & > fig-field + fig-field {
3983
- --fig-field-left-padding: var(--spacer-1);
4049
+ &[full]:not([full="false"]) {
4050
+ width: 100%;
4051
+ }
4052
+
4053
+ &:is(fig-stack:not([direction]), fig-stack[direction="horizontal"], hstack, .hstack) {
4054
+ & > fig-field:has(+ fig-field) {
4055
+ --fig-field-right-padding: var(--spacer-1);
4056
+ }
4057
+
4058
+ & > fig-field + fig-field {
4059
+ --fig-field-left-padding: var(--spacer-1);
4060
+ }
3984
4061
  }
3985
4062
  }
3986
4063