@urbicon-ui/blocks 6.30.1 → 6.31.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.
Files changed (39) hide show
  1. package/dist/components/Calendar/Calendar.svelte +17 -21
  2. package/dist/components/Calendar/CalendarAgendaView.svelte +9 -3
  3. package/dist/components/Calendar/CalendarDayView.svelte +9 -3
  4. package/dist/components/Calendar/CalendarGrid.svelte +9 -3
  5. package/dist/components/Calendar/CalendarWeekGrid.svelte +9 -3
  6. package/dist/components/Calendar/CalendarYearGrid.svelte +12 -3
  7. package/dist/components/Calendar/calendar.variants.d.ts +63 -63
  8. package/dist/components/CommandPalette/commandPalette.variants.js +9 -4
  9. package/dist/i18n/index.d.ts +2 -378
  10. package/dist/primitives/Accordion/accordion.variants.d.ts +7 -7
  11. package/dist/primitives/Accordion/accordion.variants.js +4 -4
  12. package/dist/primitives/Accordion/index.d.ts +2 -2
  13. package/dist/primitives/Alert/alert.variants.d.ts +8 -8
  14. package/dist/primitives/Button/Button.svelte +23 -7
  15. package/dist/primitives/Combobox/Combobox.svelte +11 -3
  16. package/dist/primitives/Combobox/combobox.variants.d.ts +9 -0
  17. package/dist/primitives/Combobox/combobox.variants.js +22 -4
  18. package/dist/primitives/Combobox/index.d.ts +2 -2
  19. package/dist/primitives/JourneyTimeline/journey-timeline.variants.d.ts +22 -22
  20. package/dist/primitives/Menu/menu.variants.js +13 -5
  21. package/dist/primitives/SegmentGroup/SegmentGroup.svelte +4 -4
  22. package/dist/primitives/SegmentGroup/SegmentItem.svelte +1 -1
  23. package/dist/primitives/SegmentGroup/index.d.ts +1 -1
  24. package/dist/primitives/SegmentGroup/segmentgroup.variants.d.ts +4 -4
  25. package/dist/primitives/SegmentGroup/segmentgroup.variants.js +15 -15
  26. package/dist/primitives/Select/select.variants.js +21 -7
  27. package/dist/primitives/Slider/Slider.svelte +2 -2
  28. package/dist/primitives/Slider/slider.variants.d.ts +14 -14
  29. package/dist/primitives/Slider/slider.variants.js +13 -13
  30. package/dist/primitives/Spinner/spinner.variants.d.ts +16 -16
  31. package/dist/primitives/Stepper/stepper.variants.d.ts +11 -11
  32. package/dist/primitives/Toast/toast.variants.d.ts +12 -12
  33. package/dist/primitives/Toggle/Toggle.svelte +2 -2
  34. package/dist/primitives/Toggle/index.d.ts +1 -1
  35. package/dist/primitives/Toggle/toggle.variants.d.ts +7 -7
  36. package/dist/primitives/Toggle/toggle.variants.js +32 -32
  37. package/dist/primitives/Tooltip/tooltip.variants.d.ts +3 -3
  38. package/docs/MIGRATION-v5.md +7 -5
  39. package/package.json +3 -3
@@ -105,6 +105,15 @@ export declare const comboboxVariants: ((props?: {
105
105
  } & {
106
106
  class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
107
107
  }) | undefined) => string;
108
+ optionCheck: (props?: ({
109
+ tier?: "commit" | "modify" | undefined;
110
+ variant?: "ghost" | "filled" | "outlined" | "underline" | undefined;
111
+ size?: "sm" | "md" | "lg" | "xs" | "xl" | undefined;
112
+ open?: boolean | undefined;
113
+ disabled?: boolean | undefined;
114
+ } & {
115
+ class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
116
+ }) | undefined) => string;
108
117
  group: (props?: ({
109
118
  tier?: "commit" | "modify" | undefined;
110
119
  variant?: "ghost" | "filled" | "outlined" | "underline" | undefined;
@@ -34,13 +34,21 @@ export const comboboxVariants = tv({
34
34
  'flex w-full items-center gap-2 rounded-modify px-3 py-2 text-left',
35
35
  'text-text-primary cursor-pointer select-none',
36
36
  'transition-colors duration-[var(--blocks-duration-fast)]',
37
- 'focus-visible:outline-none'
37
+ 'focus-visible:outline-none',
38
+ 'disabled:opacity-50 disabled:cursor-not-allowed'
38
39
  ],
39
40
  optionActive: 'bg-surface-hover',
40
41
  optionSelected: 'bg-surface-selected font-medium',
41
- // Grouped options (parity with Select). `group` is a bare container; the
42
- // label is a quiet, uppercase section header.
43
- group: '',
42
+ // Trailing selected-check (parity with Select `optionCheck`): always
43
+ // rendered with reserved space, fades in via opacity — no layout shift
44
+ // when a row becomes selected. Sized one step with the option per size.
45
+ optionCheck: [
46
+ 'shrink-0 text-primary opacity-0 transition-opacity duration-[var(--blocks-duration-fast)]'
47
+ ],
48
+ // Grouped options (parity with Select). `group` carries the same
49
+ // item-to-item rhythm as the flat listbox (`space-y-0.5` there lives on
50
+ // the `listbox` slot); the label is a quiet, uppercase section header.
51
+ group: 'space-y-0.5',
44
52
  groupLabel: 'px-3 py-1.5 text-xs font-medium text-text-tertiary uppercase tracking-wider',
45
53
  noResults: 'px-3 py-4 text-center text-sm text-text-tertiary',
46
54
  // Async-search in-flight message (queryFn). Mirrors noResults so both listbox
@@ -137,11 +145,15 @@ export const comboboxVariants = tv({
137
145
  // The multi-mode tokenizer (`control`/`search`/`tag`) tracks the same
138
146
  // ladder: `control` uses `min-h-*` (not `h-*`) so it grows as tags wrap,
139
147
  // and reserves right padding (`pr-*`) for the absolute chevron/clear.
148
+ // Option rows follow the shared listbox item rhythm (XC-9); the group
149
+ // label always shares the option's horizontal inset.
140
150
  xs: {
141
151
  // `pointer-coarse:text-base` floors the input to 16px on touch-primary
142
152
  // devices so iOS Safari doesn't auto-zoom (and never un-zoom) on focus.
143
153
  input: 'h-7 px-2 pr-7 text-xs pointer-coarse:text-base',
144
154
  option: 'px-2 py-1 text-xs min-h-[1.75rem]',
155
+ optionCheck: 'w-3 h-3',
156
+ groupLabel: 'px-2',
145
157
  control: 'min-h-7 gap-1 px-1.5 py-1 pr-7',
146
158
  search: 'text-xs pointer-coarse:text-base',
147
159
  tag: 'text-xs px-1.5 py-0.5',
@@ -151,6 +163,8 @@ export const comboboxVariants = tv({
151
163
  // See `xs` — floor to 16px on touch to avoid iOS Safari focus-zoom.
152
164
  input: 'h-8 px-3 pr-8 text-sm pointer-coarse:text-base',
153
165
  option: 'px-2 py-1.5 text-sm min-h-[2rem]',
166
+ optionCheck: 'w-3.5 h-3.5',
167
+ groupLabel: 'px-2',
154
168
  control: 'min-h-8 gap-1 px-2 py-1 pr-8',
155
169
  search: 'text-sm pointer-coarse:text-base',
156
170
  tag: 'text-xs px-2 py-0.5',
@@ -159,6 +173,7 @@ export const comboboxVariants = tv({
159
173
  md: {
160
174
  input: 'h-10 px-3 pr-8 text-base',
161
175
  option: 'px-3 py-2 text-sm min-h-[2.5rem]',
176
+ optionCheck: 'w-4 h-4',
162
177
  control: 'min-h-10 gap-1.5 px-2 py-1.5 pr-8',
163
178
  search: 'text-base',
164
179
  tag: 'text-sm px-2 py-0.5',
@@ -167,6 +182,7 @@ export const comboboxVariants = tv({
167
182
  lg: {
168
183
  input: 'h-12 px-4 pr-10 text-lg',
169
184
  option: 'px-3 py-2.5 text-base min-h-[3rem]',
185
+ optionCheck: 'w-5 h-5',
170
186
  control: 'min-h-12 gap-2 px-3 py-2 pr-10',
171
187
  search: 'text-lg',
172
188
  tag: 'text-base px-2.5 py-1',
@@ -175,6 +191,8 @@ export const comboboxVariants = tv({
175
191
  xl: {
176
192
  input: 'h-14 px-6 pr-12 text-xl',
177
193
  option: 'px-4 py-3 text-lg min-h-[3.5rem]',
194
+ optionCheck: 'w-6 h-6',
195
+ groupLabel: 'px-4',
178
196
  control: 'min-h-14 gap-2 px-4 py-2.5 pr-12',
179
197
  search: 'text-xl',
180
198
  tag: 'text-lg px-3 py-1',
@@ -138,8 +138,8 @@ interface ComboboxBaseProps<T extends SelectValue = string> extends ComboboxVari
138
138
  unstyled?: boolean;
139
139
  /** Per-slot class overrides merged with tv() styles. Slots: base | label | requiredMark |
140
140
  * inputWrapper | input | message | helper | listbox | option | optionActive | optionSelected |
141
- * group | groupLabel | loading | noResults | clear | chevron | control | search | tag |
142
- * tagLabel | tagRemove */
141
+ * optionCheck | group | groupLabel | loading | noResults | clear | chevron | control | search |
142
+ * tag | tagLabel | tagRemove */
143
143
  slotClasses?: Partial<Record<ComboboxSlots, string>>;
144
144
  /**
145
145
  * Apply a named preset registered via `<BlocksProvider presets={{ Combobox: {...} }}>`.
@@ -2,7 +2,7 @@ import { type SlotNames, type VariantProps } from '../../utils/variants.js';
2
2
  export declare const journeyTimelineVariants: ((props?: {
3
3
  orientation?: "horizontal" | "vertical" | undefined;
4
4
  size?: "sm" | "md" | "lg" | undefined;
5
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
5
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
6
6
  focused?: boolean | undefined;
7
7
  interactive?: boolean | undefined;
8
8
  travelled?: boolean | undefined;
@@ -13,7 +13,7 @@ export declare const journeyTimelineVariants: ((props?: {
13
13
  base: (props?: ({
14
14
  orientation?: "horizontal" | "vertical" | undefined;
15
15
  size?: "sm" | "md" | "lg" | undefined;
16
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
16
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
17
17
  focused?: boolean | undefined;
18
18
  interactive?: boolean | undefined;
19
19
  travelled?: boolean | undefined;
@@ -26,7 +26,7 @@ export declare const journeyTimelineVariants: ((props?: {
26
26
  rail: (props?: ({
27
27
  orientation?: "horizontal" | "vertical" | undefined;
28
28
  size?: "sm" | "md" | "lg" | undefined;
29
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
29
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
30
30
  focused?: boolean | undefined;
31
31
  interactive?: boolean | undefined;
32
32
  travelled?: boolean | undefined;
@@ -39,7 +39,7 @@ export declare const journeyTimelineVariants: ((props?: {
39
39
  node: (props?: ({
40
40
  orientation?: "horizontal" | "vertical" | undefined;
41
41
  size?: "sm" | "md" | "lg" | undefined;
42
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
42
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
43
43
  focused?: boolean | undefined;
44
44
  interactive?: boolean | undefined;
45
45
  travelled?: boolean | undefined;
@@ -52,7 +52,7 @@ export declare const journeyTimelineVariants: ((props?: {
52
52
  metaColumn: (props?: ({
53
53
  orientation?: "horizontal" | "vertical" | undefined;
54
54
  size?: "sm" | "md" | "lg" | undefined;
55
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
55
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
56
56
  focused?: boolean | undefined;
57
57
  interactive?: boolean | undefined;
58
58
  travelled?: boolean | undefined;
@@ -65,7 +65,7 @@ export declare const journeyTimelineVariants: ((props?: {
65
65
  meta: (props?: ({
66
66
  orientation?: "horizontal" | "vertical" | undefined;
67
67
  size?: "sm" | "md" | "lg" | undefined;
68
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
68
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
69
69
  focused?: boolean | undefined;
70
70
  interactive?: boolean | undefined;
71
71
  travelled?: boolean | undefined;
@@ -78,7 +78,7 @@ export declare const journeyTimelineVariants: ((props?: {
78
78
  markerColumn: (props?: ({
79
79
  orientation?: "horizontal" | "vertical" | undefined;
80
80
  size?: "sm" | "md" | "lg" | undefined;
81
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
81
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
82
82
  focused?: boolean | undefined;
83
83
  interactive?: boolean | undefined;
84
84
  travelled?: boolean | undefined;
@@ -91,7 +91,7 @@ export declare const journeyTimelineVariants: ((props?: {
91
91
  marker: (props?: ({
92
92
  orientation?: "horizontal" | "vertical" | undefined;
93
93
  size?: "sm" | "md" | "lg" | undefined;
94
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
94
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
95
95
  focused?: boolean | undefined;
96
96
  interactive?: boolean | undefined;
97
97
  travelled?: boolean | undefined;
@@ -104,7 +104,7 @@ export declare const journeyTimelineVariants: ((props?: {
104
104
  connector: (props?: ({
105
105
  orientation?: "horizontal" | "vertical" | undefined;
106
106
  size?: "sm" | "md" | "lg" | undefined;
107
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
107
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
108
108
  focused?: boolean | undefined;
109
109
  interactive?: boolean | undefined;
110
110
  travelled?: boolean | undefined;
@@ -117,7 +117,7 @@ export declare const journeyTimelineVariants: ((props?: {
117
117
  content: (props?: ({
118
118
  orientation?: "horizontal" | "vertical" | undefined;
119
119
  size?: "sm" | "md" | "lg" | undefined;
120
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
120
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
121
121
  focused?: boolean | undefined;
122
122
  interactive?: boolean | undefined;
123
123
  travelled?: boolean | undefined;
@@ -130,7 +130,7 @@ export declare const journeyTimelineVariants: ((props?: {
130
130
  card: (props?: ({
131
131
  orientation?: "horizontal" | "vertical" | undefined;
132
132
  size?: "sm" | "md" | "lg" | undefined;
133
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
133
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
134
134
  focused?: boolean | undefined;
135
135
  interactive?: boolean | undefined;
136
136
  travelled?: boolean | undefined;
@@ -143,7 +143,7 @@ export declare const journeyTimelineVariants: ((props?: {
143
143
  header: (props?: ({
144
144
  orientation?: "horizontal" | "vertical" | undefined;
145
145
  size?: "sm" | "md" | "lg" | undefined;
146
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
146
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
147
147
  focused?: boolean | undefined;
148
148
  interactive?: boolean | undefined;
149
149
  travelled?: boolean | undefined;
@@ -156,7 +156,7 @@ export declare const journeyTimelineVariants: ((props?: {
156
156
  trigger: (props?: ({
157
157
  orientation?: "horizontal" | "vertical" | undefined;
158
158
  size?: "sm" | "md" | "lg" | undefined;
159
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
159
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
160
160
  focused?: boolean | undefined;
161
161
  interactive?: boolean | undefined;
162
162
  travelled?: boolean | undefined;
@@ -169,7 +169,7 @@ export declare const journeyTimelineVariants: ((props?: {
169
169
  trailing: (props?: ({
170
170
  orientation?: "horizontal" | "vertical" | undefined;
171
171
  size?: "sm" | "md" | "lg" | undefined;
172
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
172
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
173
173
  focused?: boolean | undefined;
174
174
  interactive?: boolean | undefined;
175
175
  travelled?: boolean | undefined;
@@ -182,7 +182,7 @@ export declare const journeyTimelineVariants: ((props?: {
182
182
  labelGroup: (props?: ({
183
183
  orientation?: "horizontal" | "vertical" | undefined;
184
184
  size?: "sm" | "md" | "lg" | undefined;
185
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
185
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
186
186
  focused?: boolean | undefined;
187
187
  interactive?: boolean | undefined;
188
188
  travelled?: boolean | undefined;
@@ -195,7 +195,7 @@ export declare const journeyTimelineVariants: ((props?: {
195
195
  title: (props?: ({
196
196
  orientation?: "horizontal" | "vertical" | undefined;
197
197
  size?: "sm" | "md" | "lg" | undefined;
198
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
198
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
199
199
  focused?: boolean | undefined;
200
200
  interactive?: boolean | undefined;
201
201
  travelled?: boolean | undefined;
@@ -208,7 +208,7 @@ export declare const journeyTimelineVariants: ((props?: {
208
208
  subtitle: (props?: ({
209
209
  orientation?: "horizontal" | "vertical" | undefined;
210
210
  size?: "sm" | "md" | "lg" | undefined;
211
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
211
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
212
212
  focused?: boolean | undefined;
213
213
  interactive?: boolean | undefined;
214
214
  travelled?: boolean | undefined;
@@ -221,7 +221,7 @@ export declare const journeyTimelineVariants: ((props?: {
221
221
  segment: (props?: ({
222
222
  orientation?: "horizontal" | "vertical" | undefined;
223
223
  size?: "sm" | "md" | "lg" | undefined;
224
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
224
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
225
225
  focused?: boolean | undefined;
226
226
  interactive?: boolean | undefined;
227
227
  travelled?: boolean | undefined;
@@ -234,7 +234,7 @@ export declare const journeyTimelineVariants: ((props?: {
234
234
  detail: (props?: ({
235
235
  orientation?: "horizontal" | "vertical" | undefined;
236
236
  size?: "sm" | "md" | "lg" | undefined;
237
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
237
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
238
238
  focused?: boolean | undefined;
239
239
  interactive?: boolean | undefined;
240
240
  travelled?: boolean | undefined;
@@ -247,7 +247,7 @@ export declare const journeyTimelineVariants: ((props?: {
247
247
  detailInner: (props?: ({
248
248
  orientation?: "horizontal" | "vertical" | undefined;
249
249
  size?: "sm" | "md" | "lg" | undefined;
250
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
250
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
251
251
  focused?: boolean | undefined;
252
252
  interactive?: boolean | undefined;
253
253
  travelled?: boolean | undefined;
@@ -260,7 +260,7 @@ export declare const journeyTimelineVariants: ((props?: {
260
260
  detailContent: (props?: ({
261
261
  orientation?: "horizontal" | "vertical" | undefined;
262
262
  size?: "sm" | "md" | "lg" | undefined;
263
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
263
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
264
264
  focused?: boolean | undefined;
265
265
  interactive?: boolean | undefined;
266
266
  travelled?: boolean | undefined;
@@ -273,7 +273,7 @@ export declare const journeyTimelineVariants: ((props?: {
273
273
  panel: (props?: ({
274
274
  orientation?: "horizontal" | "vertical" | undefined;
275
275
  size?: "sm" | "md" | "lg" | undefined;
276
- status?: "complete" | "active" | "pending" | "attention" | "blocked" | "skipped" | undefined;
276
+ status?: "active" | "blocked" | "attention" | "complete" | "pending" | "skipped" | undefined;
277
277
  focused?: boolean | undefined;
278
278
  interactive?: boolean | undefined;
279
279
  travelled?: boolean | undefined;
@@ -27,7 +27,9 @@ export const menuVariants = tv({
27
27
  header: ['sticky top-0 z-10 bg-surface-elevated', 'px-2 py-1 border-b border-border-hairline'],
28
28
  section: ['px-3 py-1.5 text-xs font-medium text-text-tertiary'],
29
29
  divider: ['my-1 h-px bg-border-hairline'],
30
- items: ['py-1 space-y-0.5'],
30
+ // No extra `py` — the `content` slot's `p-1` is the single edge inset
31
+ // (symmetric 4px, same rhythm as the Select/Combobox listboxes, XC-9).
32
+ items: ['space-y-0.5'],
31
33
  // tier: modify — menu items are momentary affordances inside the contain panel.
32
34
  item: [
33
35
  'flex w-full items-center gap-2 rounded-modify text-left',
@@ -35,7 +37,9 @@ export const menuVariants = tv({
35
37
  'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-primary/50',
36
38
  'cursor-pointer select-none'
37
39
  ],
38
- indicator: ['mr-2 inline-flex items-center self-center'],
40
+ // No `mr-*` — the item's `gap-2` owns the icon↔label distance (8px, the
41
+ // same gap every listbox row in the library uses).
42
+ indicator: ['inline-flex items-center self-center'],
39
43
  submenu: ['ml-4 mt-2 border-l border-border-hairline pl-2'],
40
44
  footer: [
41
45
  'sticky bottom-0 z-10 bg-surface-elevated',
@@ -57,11 +61,15 @@ export const menuVariants = tv({
57
61
  content: 'min-w-48'
58
62
  }
59
63
  },
60
- // Size for menu items
64
+ // Size for menu items. Typo tracks the Button ladder (text-sm/base/lg —
65
+ // Action-family items read like the Button that opened them); py/min-h
66
+ // sit on the shared listbox baseline (2 / 2.5 / 3 rem, XC-9). The section
67
+ // header always shares the item's horizontal inset (px-3 lives on the
68
+ // `section` slot base for md).
61
69
  itemSize: {
62
- sm: { item: 'px-2 py-1.5 text-sm min-h-[2rem]' },
70
+ sm: { item: 'px-2 py-1.5 text-sm min-h-[2rem]', section: 'px-2' },
63
71
  md: { item: 'px-3 py-2 text-base min-h-[2.5rem]' },
64
- lg: { item: 'px-4 py-2.5 text-lg min-h-[3rem]' }
72
+ lg: { item: 'px-4 py-2.5 text-lg min-h-[3rem]', section: 'px-4' }
65
73
  },
66
74
  disabled: {
67
75
  true: {
@@ -12,7 +12,7 @@
12
12
  value = $bindable(),
13
13
  onValueChange,
14
14
  size = 'md',
15
- appearance = 'default',
15
+ variant = 'default',
16
16
  tier,
17
17
  fullWidth = false,
18
18
  disabled = false,
@@ -52,7 +52,7 @@
52
52
 
53
53
  const variantProps: SegmentGroupVariants = $derived({
54
54
  size,
55
- appearance,
55
+ variant,
56
56
  tier: effectiveTier,
57
57
  fullWidth,
58
58
  disabled
@@ -111,8 +111,8 @@
111
111
  get size() {
112
112
  return size;
113
113
  },
114
- get appearance() {
115
- return appearance;
114
+ get variant() {
115
+ return variant;
116
116
  },
117
117
  get tier() {
118
118
  return effectiveTier;
@@ -28,7 +28,7 @@
28
28
 
29
29
  const variantProps: SegmentGroupVariants = $derived({
30
30
  size: ctx.size,
31
- appearance: ctx.appearance,
31
+ variant: ctx.variant,
32
32
  tier: ctx.tier
33
33
  });
34
34
 
@@ -11,7 +11,7 @@ export interface SegmentGroupContext {
11
11
  selectItem: (value: string) => void;
12
12
  isActive: (value: string) => boolean;
13
13
  readonly size: NonNullable<SegmentGroupVariants['size']>;
14
- readonly appearance: NonNullable<SegmentGroupVariants['appearance']>;
14
+ readonly variant: NonNullable<SegmentGroupVariants['variant']>;
15
15
  readonly tier: InteractiveTier;
16
16
  readonly disabled: boolean;
17
17
  readonly unstyled: boolean;
@@ -1,14 +1,14 @@
1
1
  import { type SlotNames, type VariantProps } from '../../utils/variants.js';
2
2
  export declare const segmentGroupVariants: ((props?: {
3
3
  tier?: "commit" | "modify" | undefined;
4
- appearance?: "text" | "default" | undefined;
4
+ variant?: "text" | "default" | undefined;
5
5
  size?: "sm" | "md" | "lg" | undefined;
6
6
  fullWidth?: boolean | undefined;
7
7
  disabled?: boolean | undefined;
8
8
  } | undefined) => {
9
9
  base: (props?: ({
10
10
  tier?: "commit" | "modify" | undefined;
11
- appearance?: "text" | "default" | undefined;
11
+ variant?: "text" | "default" | undefined;
12
12
  size?: "sm" | "md" | "lg" | undefined;
13
13
  fullWidth?: boolean | undefined;
14
14
  disabled?: boolean | undefined;
@@ -17,7 +17,7 @@ export declare const segmentGroupVariants: ((props?: {
17
17
  }) | undefined) => string;
18
18
  indicator: (props?: ({
19
19
  tier?: "commit" | "modify" | undefined;
20
- appearance?: "text" | "default" | undefined;
20
+ variant?: "text" | "default" | undefined;
21
21
  size?: "sm" | "md" | "lg" | undefined;
22
22
  fullWidth?: boolean | undefined;
23
23
  disabled?: boolean | undefined;
@@ -26,7 +26,7 @@ export declare const segmentGroupVariants: ((props?: {
26
26
  }) | undefined) => string;
27
27
  item: (props?: ({
28
28
  tier?: "commit" | "modify" | undefined;
29
- appearance?: "text" | "default" | undefined;
29
+ variant?: "text" | "default" | undefined;
30
30
  size?: "sm" | "md" | "lg" | undefined;
31
31
  fullWidth?: boolean | undefined;
32
32
  disabled?: boolean | undefined;
@@ -33,12 +33,12 @@ export const segmentGroupVariants = tv({
33
33
  'group-data-[collapsed]:w-full group-data-[collapsed]:justify-start',
34
34
  'font-medium whitespace-nowrap cursor-pointer select-none',
35
35
  // `border-0` (not `border-none`) — keeps `border-style: solid` so the
36
- // text-appearance can add `border-b-[1.5px]` without a style conflict.
36
+ // text-variant can add `border-b-[1.5px]` without a style conflict.
37
37
  'border-0 bg-transparent',
38
38
  // Note: weight is intentionally not transitioned and not bumped on
39
39
  // active. Changing font weight on selection caused horizontal
40
40
  // reflow of sibling items (knob-strips wrapping mid-row). The
41
- // indicator (default appearance) / underline (text appearance)
41
+ // indicator (default variant) / underline (text variant)
42
42
  // already signal active state — the colour shift below adds the
43
43
  // semantic emphasis without altering layout.
44
44
  'transition-colors duration-[var(--blocks-duration-fast)] ease-out',
@@ -49,7 +49,7 @@ export const segmentGroupVariants = tv({
49
49
  'data-[state=active]:text-text-primary'
50
50
  ]
51
51
  },
52
- // Appearance contract (see docs/ARCHITECTURE.md §Component Styling
52
+ // Variant contract (see docs/ARCHITECTURE.md §Component Styling
53
53
  // for the surface-token hierarchy and docs/COMPONENT-FAMILIES.md §Navigation):
54
54
  // default → classic pill-track look with an animated indicator
55
55
  // text → no box frame; items are bare buttons, the active one
@@ -61,8 +61,8 @@ export const segmentGroupVariants = tv({
61
61
  // canonical pill-track surface in the 3-tier vocabulary. `modify`
62
62
  // produces a soft-rectangle track + indicator + item for compact
63
63
  // inline-toolbar contexts (usually inherited from a wrapping
64
- // `<Toolbar tier="modify">` via TierContext). When `appearance="text"`
65
- // the tier is moot — the appearance override flattens the track to
64
+ // `<Toolbar tier="modify">` via TierContext). When `variant="text"`
65
+ // the tier is moot — the variant override flattens the track to
66
66
  // `rounded-none` and the items wear their underline instead.
67
67
  tier: {
68
68
  commit: {
@@ -76,7 +76,7 @@ export const segmentGroupVariants = tv({
76
76
  item: 'rounded-modify'
77
77
  }
78
78
  },
79
- appearance: {
79
+ variant: {
80
80
  default: {},
81
81
  text: {
82
82
  // Radius flattening (`rounded-none`) and track-padding reset (`p-0`)
@@ -89,7 +89,7 @@ export const segmentGroupVariants = tv({
89
89
  'border-b-[1.5px] border-b-transparent',
90
90
  'data-[state=active]:border-b-primary',
91
91
  'data-[state=active]:bg-transparent data-[state=active]:shadow-none',
92
- // text-appearance overrides the base `font-medium` so SegmentGroup
92
+ // text-variant overrides the base `font-medium` so SegmentGroup
93
93
  // text sits at the same weight as adjacent Select/Input values in
94
94
  // editorial knob-strip contexts. Active state remains distinct via
95
95
  // border-b-primary + text-text-primary — no need for weight to
@@ -125,22 +125,22 @@ export const segmentGroupVariants = tv({
125
125
  }
126
126
  },
127
127
  compoundVariants: [
128
- // Text-appearance flattens the corner radius (regardless of tier) and
128
+ // Text-variant flattens the corner radius (regardless of tier) and
129
129
  // zeroes the track padding (regardless of size). Compounds resolve after
130
130
  // every variant axis, so these deterministically replace the tier-stage
131
131
  // `rounded-{commit|modify}` and the size-stage `p-*`.
132
- { appearance: 'text', class: { base: 'rounded-none p-0', item: 'rounded-none' } },
133
- // Text-appearance sizing: padding/sizing more compact than the pill-track,
132
+ { variant: 'text', class: { base: 'rounded-none p-0', item: 'rounded-none' } },
133
+ // Text-variant sizing: padding/sizing more compact than the pill-track,
134
134
  // but still WCAG 2.5.5 AA (≥ 24px tap height). For touch-first contexts
135
- // the `default` appearance should be used — text is primarily intended
135
+ // the `default` variant should be used — text is primarily intended
136
136
  // for cursor-driven toolbar/knob-strip contexts.
137
- { appearance: 'text', size: 'sm', class: { item: 'px-2 py-1.5 text-xs' } },
138
- { appearance: 'text', size: 'md', class: { item: 'px-2.5 py-2 text-sm' } },
139
- { appearance: 'text', size: 'lg', class: { item: 'px-3 py-2.5 text-base' } }
137
+ { variant: 'text', size: 'sm', class: { item: 'px-2 py-1.5 text-xs' } },
138
+ { variant: 'text', size: 'md', class: { item: 'px-2.5 py-2 text-sm' } },
139
+ { variant: 'text', size: 'lg', class: { item: 'px-3 py-2.5 text-base' } }
140
140
  ],
141
141
  defaultVariants: {
142
142
  tier: 'commit',
143
- appearance: 'default',
143
+ variant: 'default',
144
144
  size: 'md',
145
145
  fullWidth: false,
146
146
  disabled: false
@@ -55,7 +55,10 @@ export const selectVariants = tv({
55
55
  'bg-surface-base transition-colors duration-[var(--blocks-duration-fast)]',
56
56
  '[&_svg]:opacity-0 [&_svg]:transition-opacity [&_svg]:duration-[var(--blocks-duration-fast)]'
57
57
  ],
58
- group: [],
58
+ // `space-y-0.5` keeps grouped options on the same item-to-item rhythm as
59
+ // the flat listbox (whose spacing lives on the `listbox` slot) — without
60
+ // it, adjacent selected-highlights inside a group touch (XC-9).
61
+ group: ['space-y-0.5'],
59
62
  groupLabel: ['px-3 py-1.5 text-xs font-medium text-text-tertiary uppercase tracking-wider'],
60
63
  label: ['block font-medium text-text-secondary text-sm'],
61
64
  message: ['text-xs']
@@ -84,21 +87,26 @@ export const selectVariants = tv({
84
87
  size: {
85
88
  // Full xs–xl scale, mirroring Input's h-7…h-14 ladder (form-family
86
89
  // symmetry: a dense form should not pair an xs Input with an sm Select).
90
+ // Option inset (`px`) and the group label track the shared listbox item
91
+ // rhythm (XC-9): px-2 below md, px-3 at md/lg (slot base), px-4 at xl —
92
+ // the group header always shares the item's horizontal inset.
87
93
  xs: {
88
94
  trigger: 'h-7 pl-2 pr-7 text-xs gap-1.5',
89
95
  chevron: 'w-3 h-3',
90
96
  clear: 'right-1.5 p-0.5 [&_svg]:w-3 [&_svg]:h-3',
91
- option: 'py-1 text-xs min-h-[1.75rem]',
97
+ option: 'px-2 py-1 text-xs min-h-[1.75rem]',
92
98
  optionCheck: 'w-3 h-3',
93
- optionCheckbox: 'w-3 h-3 [&_svg]:w-2 [&_svg]:h-2'
99
+ optionCheckbox: 'w-3 h-3 [&_svg]:w-2 [&_svg]:h-2',
100
+ groupLabel: 'px-2'
94
101
  },
95
102
  sm: {
96
103
  trigger: 'h-8 pl-3 pr-8 text-sm gap-2',
97
104
  chevron: 'w-3.5 h-3.5',
98
105
  clear: 'right-2 p-0.5 [&_svg]:w-3.5 [&_svg]:h-3.5',
99
- option: 'py-1.5 text-sm min-h-[2rem]',
106
+ option: 'px-2 py-1.5 text-sm min-h-[2rem]',
100
107
  optionCheck: 'w-3.5 h-3.5',
101
- optionCheckbox: 'w-3.5 h-3.5 [&_svg]:w-2.5 [&_svg]:h-2.5'
108
+ optionCheckbox: 'w-3.5 h-3.5 [&_svg]:w-2.5 [&_svg]:h-2.5',
109
+ groupLabel: 'px-2'
102
110
  },
103
111
  md: {
104
112
  trigger: 'h-10 pl-4 pr-10 text-base gap-2',
@@ -120,9 +128,10 @@ export const selectVariants = tv({
120
128
  trigger: 'h-14 pl-6 pr-14 text-xl gap-3',
121
129
  chevron: 'w-6 h-6',
122
130
  clear: 'right-5 p-1 [&_svg]:w-6 [&_svg]:h-6',
123
- option: 'py-3 text-lg min-h-[3.5rem]',
131
+ option: 'px-4 py-3 text-lg min-h-[3.5rem]',
124
132
  optionCheck: 'w-6 h-6',
125
- optionCheckbox: 'w-5 h-5 [&_svg]:w-4 [&_svg]:h-4'
133
+ optionCheckbox: 'w-5 h-5 [&_svg]:w-4 [&_svg]:h-4',
134
+ groupLabel: 'px-4'
126
135
  }
127
136
  },
128
137
  open: {
@@ -153,6 +162,11 @@ export const selectVariants = tv({
153
162
  },
154
163
  selected: {
155
164
  true: {
165
+ // Form-family selected signature (parity with Combobox `optionSelected`):
166
+ // persistent value marking = `bg-surface-selected font-medium` + primary
167
+ // check. The keyboard/hover cursor (`bg-surface-hover`, call-site class)
168
+ // still wins the bg bucket, so the cursor stays visible on selected rows.
169
+ option: 'bg-surface-selected font-medium',
156
170
  optionCheck: 'opacity-100',
157
171
  optionCheckbox: 'border-primary bg-primary text-text-on-primary [&_svg]:opacity-100'
158
172
  }
@@ -21,7 +21,7 @@
21
21
  helper,
22
22
  intent = 'primary',
23
23
  size = 'md',
24
- appearance = 'default',
24
+ variant = 'default',
25
25
  disabled = false,
26
26
  name,
27
27
  validRange,
@@ -231,7 +231,7 @@
231
231
  const variantProps: SliderVariants = $derived({
232
232
  intent,
233
233
  size,
234
- appearance,
234
+ variant,
235
235
  disabled: disabled || undefined,
236
236
  error: !!error || undefined,
237
237
  messageType: error ? 'error' : 'helper',