@urbicon-ui/blocks 6.2.0 → 6.3.1

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 (147) hide show
  1. package/dist/components/AreaChart/AreaChart.svelte +2 -6
  2. package/dist/components/BarChart/BarChart.svelte +2 -6
  3. package/dist/components/Calendar/Calendar.svelte +12 -10
  4. package/dist/components/Calendar/calendar.variants.d.ts +2 -1
  5. package/dist/components/Calendar/index.d.ts +2 -2
  6. package/dist/components/CommandPalette/CommandPalette.svelte +106 -39
  7. package/dist/components/CommandPalette/commandPalette.variants.d.ts +3 -7
  8. package/dist/components/CommandPalette/commandPalette.variants.js +0 -1
  9. package/dist/components/CommandPalette/index.d.ts +2 -2
  10. package/dist/components/CompositionBar/CompositionBar.svelte +12 -15
  11. package/dist/components/CompositionBar/composition-bar.variants.d.ts +3 -1
  12. package/dist/components/CompositionBar/index.d.ts +2 -2
  13. package/dist/components/DonutChart/DonutChart.svelte +2 -6
  14. package/dist/components/EmptyState/EmptyState.svelte +8 -9
  15. package/dist/components/EmptyState/emptyState.variants.d.ts +3 -1
  16. package/dist/components/EmptyState/index.d.ts +3 -3
  17. package/dist/components/FileUpload/FileUpload.svelte +17 -17
  18. package/dist/components/FileUpload/fileUpload.variants.d.ts +3 -11
  19. package/dist/components/FileUpload/fileUpload.variants.js +0 -5
  20. package/dist/components/FileUpload/index.d.ts +4 -3
  21. package/dist/components/Guide/Guide.svelte +5 -8
  22. package/dist/components/Guide/GuideArticle.svelte +5 -8
  23. package/dist/components/Guide/GuideBeacon.svelte +5 -8
  24. package/dist/components/Guide/GuideHint.svelte +5 -8
  25. package/dist/components/Guide/GuideMarker.svelte +5 -8
  26. package/dist/components/Guide/GuideMention.svelte +5 -8
  27. package/dist/components/Guide/GuidePanel.svelte +5 -8
  28. package/dist/components/Guide/guide.variants.d.ts +9 -1
  29. package/dist/components/Guide/index.d.ts +12 -9
  30. package/dist/components/LineChart/LineChart.svelte +2 -6
  31. package/dist/components/Planner/Planner.svelte +7 -10
  32. package/dist/components/Planner/index.d.ts +4 -4
  33. package/dist/components/Planner/planner.variants.d.ts +3 -1
  34. package/dist/components/Sankey/Sankey.svelte +8 -9
  35. package/dist/components/Sankey/index.d.ts +2 -2
  36. package/dist/components/Sankey/sankey.variants.d.ts +3 -1
  37. package/dist/components/SidebarLayout/SidebarLayout.svelte +17 -17
  38. package/dist/components/SidebarLayout/index.d.ts +8 -2
  39. package/dist/components/SidebarLayout/sidebar-layout.variants.d.ts +3 -1
  40. package/dist/components/ThemeSwitcher/ThemeSwitcher.svelte +30 -38
  41. package/dist/components/ThemeSwitcher/index.d.ts +6 -4
  42. package/dist/components/ThemeSwitcher/themeSwitcher.variants.d.ts +3 -1
  43. package/dist/primitives/Accordion/Accordion.svelte +7 -9
  44. package/dist/primitives/Accordion/AccordionItem.svelte +8 -20
  45. package/dist/primitives/Accordion/accordion.variants.d.ts +3 -1
  46. package/dist/primitives/Accordion/index.d.ts +6 -6
  47. package/dist/primitives/Alert/Alert.svelte +7 -21
  48. package/dist/primitives/Alert/alert.variants.d.ts +3 -1
  49. package/dist/primitives/Alert/index.d.ts +3 -3
  50. package/dist/primitives/Avatar/Avatar.svelte +17 -20
  51. package/dist/primitives/Avatar/avatar.variants.d.ts +3 -1
  52. package/dist/primitives/Avatar/index.d.ts +3 -3
  53. package/dist/primitives/Badge/Badge.svelte +2 -2
  54. package/dist/primitives/Badge/badge.variants.d.ts +3 -1
  55. package/dist/primitives/Badge/index.d.ts +2 -2
  56. package/dist/primitives/Breadcrumb/Breadcrumb.svelte +30 -32
  57. package/dist/primitives/Breadcrumb/breadcrumb.variants.d.ts +3 -1
  58. package/dist/primitives/Breadcrumb/index.d.ts +2 -2
  59. package/dist/primitives/Button/Button.svelte +21 -21
  60. package/dist/primitives/Button/button.variants.d.ts +3 -1
  61. package/dist/primitives/Button/index.d.ts +3 -3
  62. package/dist/primitives/ButtonGroup/ButtonGroup.svelte +15 -14
  63. package/dist/primitives/ButtonGroup/buttongroup.variants.d.ts +3 -1
  64. package/dist/primitives/ButtonGroup/index.d.ts +3 -2
  65. package/dist/primitives/Card/Card.svelte +15 -18
  66. package/dist/primitives/Card/card.variants.d.ts +3 -1
  67. package/dist/primitives/Card/index.d.ts +3 -3
  68. package/dist/primitives/Checkbox/Checkbox.svelte +20 -20
  69. package/dist/primitives/Checkbox/checkbox.variants.d.ts +3 -1
  70. package/dist/primitives/Checkbox/index.d.ts +7 -3
  71. package/dist/primitives/Collapsible/Collapsible.svelte +30 -30
  72. package/dist/primitives/Collapsible/collapsible.variants.d.ts +3 -1
  73. package/dist/primitives/Collapsible/index.d.ts +3 -3
  74. package/dist/primitives/Combobox/Combobox.svelte +20 -31
  75. package/dist/primitives/Combobox/combobox.variants.d.ts +3 -1
  76. package/dist/primitives/Combobox/index.d.ts +5 -3
  77. package/dist/primitives/Dialog/Dialog.svelte +7 -10
  78. package/dist/primitives/Dialog/dialog.variants.d.ts +3 -1
  79. package/dist/primitives/Dialog/index.d.ts +2 -2
  80. package/dist/primitives/Drawer/Drawer.svelte +7 -10
  81. package/dist/primitives/Drawer/drawer.variants.d.ts +3 -1
  82. package/dist/primitives/Drawer/index.d.ts +2 -2
  83. package/dist/primitives/Input/Input.svelte +54 -30
  84. package/dist/primitives/Input/index.d.ts +7 -3
  85. package/dist/primitives/Input/input.variants.d.ts +3 -1
  86. package/dist/primitives/Menu/Menu.svelte +23 -23
  87. package/dist/primitives/Menu/index.d.ts +4 -1
  88. package/dist/primitives/Menu/menu.variants.d.ts +3 -1
  89. package/dist/primitives/Pagination/Pagination.svelte +18 -16
  90. package/dist/primitives/Pagination/index.d.ts +2 -2
  91. package/dist/primitives/Pagination/pagination.variants.d.ts +3 -1
  92. package/dist/primitives/Popover/Popover.svelte +2 -6
  93. package/dist/primitives/Progress/Progress.svelte +17 -17
  94. package/dist/primitives/Progress/index.d.ts +8 -3
  95. package/dist/primitives/Progress/progress.variants.d.ts +3 -1
  96. package/dist/primitives/RadioGroup/RadioGroup.svelte +16 -16
  97. package/dist/primitives/RadioGroup/RadioItem.svelte +19 -19
  98. package/dist/primitives/RadioGroup/index.d.ts +3 -3
  99. package/dist/primitives/RadioGroup/radioGroup.variants.d.ts +4 -1
  100. package/dist/primitives/SegmentGroup/SegmentGroup.svelte +14 -11
  101. package/dist/primitives/SegmentGroup/SegmentItem.svelte +12 -11
  102. package/dist/primitives/SegmentGroup/index.d.ts +3 -3
  103. package/dist/primitives/SegmentGroup/segmentgroup.variants.d.ts +3 -1
  104. package/dist/primitives/Select/Select.svelte +31 -22
  105. package/dist/primitives/Select/index.d.ts +8 -3
  106. package/dist/primitives/Select/select.variants.d.ts +3 -1
  107. package/dist/primitives/Separator/Separator.svelte +2 -6
  108. package/dist/primitives/Sidebar/Sidebar.svelte +6 -9
  109. package/dist/primitives/Sidebar/index.d.ts +2 -2
  110. package/dist/primitives/Sidebar/sidebar.variants.d.ts +3 -1
  111. package/dist/primitives/Skeleton/Skeleton.svelte +7 -9
  112. package/dist/primitives/Skeleton/index.d.ts +3 -3
  113. package/dist/primitives/Skeleton/skeleton.variants.d.ts +3 -1
  114. package/dist/primitives/Skeleton/skeleton.variants.js +5 -6
  115. package/dist/primitives/Slider/Slider.svelte +19 -19
  116. package/dist/primitives/Slider/index.d.ts +8 -3
  117. package/dist/primitives/Slider/slider.variants.d.ts +3 -1
  118. package/dist/primitives/Spinner/Spinner.svelte +7 -9
  119. package/dist/primitives/Spinner/index.d.ts +5 -3
  120. package/dist/primitives/Spinner/spinner.variants.d.ts +3 -1
  121. package/dist/primitives/Stepper/Stepper.svelte +13 -18
  122. package/dist/primitives/Stepper/StepperStep.svelte +18 -19
  123. package/dist/primitives/Stepper/index.d.ts +5 -5
  124. package/dist/primitives/Stepper/stepper.variants.d.ts +3 -1
  125. package/dist/primitives/Tab/Tab.svelte +14 -17
  126. package/dist/primitives/Tab/TabItem.svelte +18 -19
  127. package/dist/primitives/Tab/TabPanel.svelte +10 -13
  128. package/dist/primitives/Tab/index.d.ts +7 -7
  129. package/dist/primitives/Tab/tab.variants.d.ts +3 -1
  130. package/dist/primitives/Textarea/Textarea.svelte +23 -23
  131. package/dist/primitives/Textarea/index.d.ts +7 -3
  132. package/dist/primitives/Textarea/textarea.variants.d.ts +3 -1
  133. package/dist/primitives/Toast/Toaster.svelte +5 -6
  134. package/dist/primitives/Toast/index.d.ts +2 -2
  135. package/dist/primitives/Toast/toast.variants.d.ts +3 -1
  136. package/dist/primitives/Toggle/Toggle.svelte +19 -19
  137. package/dist/primitives/Toggle/index.d.ts +7 -3
  138. package/dist/primitives/Toggle/toggle.variants.d.ts +3 -1
  139. package/dist/primitives/Toolbar/Toolbar.svelte +7 -9
  140. package/dist/primitives/Toolbar/index.d.ts +4 -3
  141. package/dist/primitives/Toolbar/toolbar.variants.d.ts +3 -1
  142. package/dist/primitives/Tooltip/Tooltip.svelte +7 -9
  143. package/dist/primitives/Tooltip/index.d.ts +2 -2
  144. package/dist/primitives/Tooltip/tooltip.variants.d.ts +3 -1
  145. package/dist/style/semantic.css +5 -0
  146. package/dist/utils/variants.d.ts +17 -0
  147. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
2
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
3
3
  import type { AreaChartProps } from './index';
4
4
  import type { ChartSeries } from '../../internal/charts/types';
5
5
  import { chartSlotResolver } from '../../internal/charts/variants';
@@ -38,11 +38,7 @@
38
38
  const blocksConfig = getBlocksConfig();
39
39
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
40
40
  const slotClasses = $derived(
41
- mergeSlotClasses(
42
- blocksConfig?.defaults?.AreaChart?.slotClasses,
43
- resolvePresetSlotClasses(blocksConfig?.presets, 'AreaChart', preset),
44
- slotClassesProp
45
- )
41
+ resolveSlotClasses(blocksConfig, 'AreaChart', preset, {}, slotClassesProp)
46
42
  );
47
43
  const slot = $derived(chartSlotResolver(unstyled, slotClasses));
48
44
 
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
2
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
3
3
  import type { BarChartProps } from './index';
4
4
  import type { ChartSeries } from '../../internal/charts/types';
5
5
  import { chartSlotResolver } from '../../internal/charts/variants';
@@ -35,11 +35,7 @@
35
35
  const blocksConfig = getBlocksConfig();
36
36
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
37
37
  const slotClasses = $derived(
38
- mergeSlotClasses(
39
- blocksConfig?.defaults?.BarChart?.slotClasses,
40
- resolvePresetSlotClasses(blocksConfig?.presets, 'BarChart', preset),
41
- slotClassesProp
42
- )
38
+ resolveSlotClasses(blocksConfig, 'BarChart', preset, {}, slotClassesProp)
43
39
  );
44
40
  const slot = $derived(chartSlotResolver(unstyled, slotClasses));
45
41
 
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { SvelteMap, MediaQuery } from 'svelte/reactivity';
3
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
4
- import { calendarVariants } from './calendar.variants';
3
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
4
+ import { calendarVariants, type CalendarVariants } from './calendar.variants';
5
5
  import { setCalendarContext, type CalendarContext } from './calendar.context';
6
6
  import {
7
7
  getYearMonths,
@@ -114,17 +114,19 @@
114
114
  // --- BlocksConfig integration ---
115
115
  const blocksConfig = getBlocksConfig();
116
116
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
117
+
118
+ // --- Variant styles + slot-class cascade ---
119
+ // `variantProps` feeds both the tv() style computation and the slot-class
120
+ // cascade (so provider `overrides` can match the active variant/size).
121
+ // Annotation is mandatory: without it the string literals widen to `string`
122
+ // and tsc rejects the call. The root only drives `variant`/`size`; the
123
+ // per-cell `dayState`/`hasEvents` axes are applied by sub-components.
124
+ const variantProps: CalendarVariants = $derived({ variant, size });
125
+ const styles = $derived(calendarVariants(variantProps));
117
126
  const slotClasses = $derived(
118
- mergeSlotClasses(
119
- blocksConfig?.defaults?.Calendar?.slotClasses,
120
- resolvePresetSlotClasses(blocksConfig?.presets, 'Calendar', preset),
121
- slotClassesProp
122
- )
127
+ resolveSlotClasses(blocksConfig, 'Calendar', preset, variantProps, slotClassesProp)
123
128
  );
124
129
 
125
- // --- Variant styles ---
126
- const styles = $derived(calendarVariants({ variant, size }));
127
-
128
130
  // --- Animation state ---
129
131
  const reducedMotion = new MediaQuery('(prefers-reduced-motion: reduce)');
130
132
  const shouldAnimate = $derived(animated && !reducedMotion.current);
@@ -1,4 +1,4 @@
1
- import { type VariantProps } from '../../utils/variants';
1
+ import { type SlotNames, type VariantProps } from '../../utils/variants';
2
2
  export declare const calendarVariants: (props?: import("../../utils/variants").TVProps<{
3
3
  variant: {
4
4
  default: {};
@@ -804,3 +804,4 @@ export declare const calendarVariants: (props?: import("../../utils/variants").T
804
804
  }) | undefined) => string;
805
805
  };
806
806
  export type CalendarVariants = VariantProps<typeof calendarVariants>;
807
+ export type CalendarSlots = SlotNames<typeof calendarVariants>;
@@ -2,7 +2,7 @@ import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { MintProp } from '../../mint';
4
4
  import type { CalendarEvent, CalendarEventCategory, CalendarSelection, CalendarViewMode, DayCellContext, EventItemContext, HeaderContext } from './calendar.types';
5
- import type { CalendarVariants } from './calendar.variants';
5
+ import type { CalendarSlots, CalendarVariants } from './calendar.variants';
6
6
  export type CalendarSlotName = 'base' | 'header' | 'title' | 'nav' | 'navButton' | 'grid' | 'weekdayHeader' | 'weekday' | 'weekRow' | 'weekNumber' | 'day' | 'dayNumber' | 'dotContainer' | 'dot' | 'list' | 'dateHeader' | 'empty' | 'item' | 'colorBar' | 'eventTitle' | 'eventDescription' | 'eventHelper' | 'legend' | 'legendItem' | 'legendDot' | 'legendLabel' | 'yearGrid' | 'yearMonth' | 'yearMonthTitle' | 'yearMiniDay' | 'yearMiniDot' | 'weekGrid' | 'weekColumn' | 'weekColumnHeader' | 'weekColumnDayName' | 'weekColumnDayNumber' | 'weekEventList' | 'weekAllDayEvent' | 'multiDayBar' | 'multiDayBarContainer' | 'agendaView' | 'agendaDayGroup' | 'agendaDayHeader' | 'agendaEventList' | 'dayView' | 'dayViewHeader' | 'dayEventList' | 'timeGrid' | 'timeLabel' | 'timeSlotRow' | 'timeDayColumn' | 'timeEvent' | 'allDayArea' | 'currentTimeLine' | 'weekTimeLayout' | 'eventPopover' | 'eventPopoverItem' | 'miniCalendar' | 'miniCalendarHeader' | 'miniCalendarTitle' | 'miniCalendarNavButton' | 'miniCalendarWeekday' | 'miniCalendarDay';
7
7
  /**
8
8
  * @description Flexible calendar component with month, year, week, and day views.
@@ -165,7 +165,7 @@ export interface CalendarProps extends Omit<CalendarVariants, 'dayState' | 'hasE
165
165
  /** Strip all default tv() classes. */
166
166
  unstyled?: boolean;
167
167
  /** Per-slot class overrides. */
168
- slotClasses?: Partial<Record<CalendarSlotName, string>>;
168
+ slotClasses?: Partial<Record<CalendarSlots, string>>;
169
169
  /**
170
170
  * Apply a named preset registered via `<BlocksProvider presets={{ Calendar: {...} }}>`.
171
171
  * Prefer this over `class` overrides when the requested look falls outside the
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { useBlocksI18n } from '../..';
3
3
  import { Dialog, Separator } from '../../primitives';
4
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
4
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
5
5
  import type { CommandPaletteProps, CommandPaletteItem } from './index';
6
- import { commandPaletteVariants } from './commandPalette.variants';
6
+ import { commandPaletteVariants, type CommandPaletteVariants } from './commandPalette.variants';
7
7
 
8
8
  const bt = useBlocksI18n();
9
9
 
@@ -31,25 +31,18 @@
31
31
 
32
32
  const blocksConfig = getBlocksConfig();
33
33
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
34
- const slotClasses = $derived(
35
- mergeSlotClasses(
36
- blocksConfig?.defaults?.CommandPalette?.slotClasses,
37
- resolvePresetSlotClasses(blocksConfig?.presets, 'CommandPalette', preset),
38
- slotClassesProp
39
- )
40
- );
41
34
 
42
35
  let query = $state('');
43
36
  let selectedIndex = $state(0);
44
37
  let inputEl: HTMLInputElement | undefined = $state();
45
38
 
46
- const styles = $derived(unstyled ? undefined : commandPaletteVariants({ size }));
39
+ const variantProps: CommandPaletteVariants = $derived({ size });
47
40
 
48
- function slot(name: keyof NonNullable<typeof styles>) {
49
- const base = styles?.[name]?.() ?? '';
50
- const override = slotClasses?.[name as keyof typeof slotClasses] ?? '';
51
- return override ? `${base} ${override}` : base;
52
- }
41
+ const styles = $derived(commandPaletteVariants(variantProps));
42
+
43
+ const slotClasses = $derived(
44
+ resolveSlotClasses(blocksConfig, 'CommandPalette', preset, variantProps, slotClassesProp)
45
+ );
53
46
 
54
47
  const defaultFilter = (item: CommandPaletteItem, q: string) => {
55
48
  const lower = q.toLowerCase();
@@ -156,11 +149,21 @@
156
149
  <svelte:window onkeydown={handleGlobalKeydown} />
157
150
 
158
151
  <Dialog bind:open size="md" placement="top" class="mt-[15vh]" onClose={() => setOpen(false)}>
159
- <div class="{slot('wrapper')} {className}">
152
+ <div
153
+ class={unstyled
154
+ ? [slotClasses?.wrapper, className].filter(Boolean).join(' ')
155
+ : styles.wrapper({ class: [slotClasses?.wrapper, className] })}
156
+ >
160
157
  <!-- Search input -->
161
- <div class={slot('inputWrapper')}>
158
+ <div
159
+ class={unstyled
160
+ ? (slotClasses?.inputWrapper ?? '')
161
+ : styles.inputWrapper({ class: slotClasses?.inputWrapper })}
162
+ >
162
163
  <svg
163
- class={slot('inputIcon')}
164
+ class={unstyled
165
+ ? (slotClasses?.inputIcon ?? '')
166
+ : styles.inputIcon({ class: slotClasses?.inputIcon })}
164
167
  fill="none"
165
168
  viewBox="0 0 24 24"
166
169
  stroke="currentColor"
@@ -178,7 +181,7 @@
178
181
  bind:value={query}
179
182
  onkeydown={handleKeydown}
180
183
  {placeholder}
181
- class={slot('input')}
184
+ class={unstyled ? (slotClasses?.input ?? '') : styles.input({ class: slotClasses?.input })}
182
185
  role="combobox"
183
186
  aria-expanded={filtered.length > 0}
184
187
  aria-controls="command-palette-list"
@@ -189,7 +192,9 @@
189
192
  />
190
193
  {#if query}
191
194
  <button
192
- class={slot('clearButton')}
195
+ class={unstyled
196
+ ? (slotClasses?.clearButton ?? '')
197
+ : styles.clearButton({ class: slotClasses?.clearButton })}
193
198
  aria-label={bt('accessibility.clearSearch')}
194
199
  onclick={() => {
195
200
  query = '';
@@ -210,22 +215,39 @@
210
215
  </div>
211
216
 
212
217
  <!-- Results -->
213
- <div id="command-palette-list" role="listbox" class={slot('list')}>
218
+ <div
219
+ id="command-palette-list"
220
+ role="listbox"
221
+ class={unstyled ? (slotClasses?.list ?? '') : styles.list({ class: slotClasses?.list })}
222
+ >
214
223
  {#if filtered.length === 0}
215
224
  {#if customEmpty}
216
225
  {@render customEmpty(query)}
217
226
  {:else}
218
- <div class={slot('empty')}>
227
+ <div
228
+ class={unstyled
229
+ ? (slotClasses?.empty ?? '')
230
+ : styles.empty({ class: slotClasses?.empty })}
231
+ >
219
232
  {emptyText}{#if query}&nbsp;"{query}"{/if}
220
233
  </div>
221
234
  {/if}
222
235
  {:else}
223
236
  {#each grouped as group, groupIdx (group.category)}
224
237
  {#if groupIdx > 0}
225
- <Separator class={slot('separator')} />
238
+ <Separator
239
+ class={unstyled
240
+ ? (slotClasses?.separator ?? '')
241
+ : styles.separator({ class: slotClasses?.separator })}
242
+ />
226
243
  {/if}
227
244
  {#if group.category}
228
- <div class={slot('groupLabel')} role="presentation">
245
+ <div
246
+ class={unstyled
247
+ ? (slotClasses?.groupLabel ?? '')
248
+ : styles.groupLabel({ class: slotClasses?.groupLabel })}
249
+ role="presentation"
250
+ >
229
251
  {group.category}
230
252
  </div>
231
253
  {/if}
@@ -243,6 +265,17 @@
243
265
  (Enter/Space handled in handleKeydown) plus pointer clicks
244
266
  here. tabindex="-1" keeps the items out of the tab sequence.
245
267
  -->
268
+ {@const itemStateClass = isDisabled
269
+ ? unstyled
270
+ ? (slotClasses?.itemDisabled ?? '')
271
+ : styles.itemDisabled({ class: slotClasses?.itemDisabled })
272
+ : isHighlighted
273
+ ? unstyled
274
+ ? (slotClasses?.itemHighlighted ?? '')
275
+ : styles.itemHighlighted({ class: slotClasses?.itemHighlighted })
276
+ : unstyled
277
+ ? (slotClasses?.itemDefault ?? '')
278
+ : styles.itemDefault({ class: slotClasses?.itemDefault })}
246
279
  <!-- svelte-ignore a11y_click_events_have_key_events -->
247
280
  <div
248
281
  id="command-palette-item-{flatIdx}"
@@ -251,11 +284,12 @@
251
284
  aria-selected={isHighlighted}
252
285
  aria-disabled={isDisabled}
253
286
  data-command-palette-selected={isHighlighted}
254
- class="{slot('item')} {isDisabled
255
- ? slot('itemDisabled')
256
- : isHighlighted
257
- ? slot('itemHighlighted')
258
- : slot('itemDefault')}"
287
+ class={[
288
+ unstyled ? (slotClasses?.item ?? '') : styles.item({ class: slotClasses?.item }),
289
+ itemStateClass
290
+ ]
291
+ .filter(Boolean)
292
+ .join(' ')}
259
293
  onclick={() => {
260
294
  if (!isDisabled) selectItem(item);
261
295
  }}
@@ -265,7 +299,9 @@
265
299
  >
266
300
  {#if item.icon}
267
301
  <svg
268
- class={slot('itemIcon')}
302
+ class={unstyled
303
+ ? (slotClasses?.itemIcon ?? '')
304
+ : styles.itemIcon({ class: slotClasses?.itemIcon })}
269
305
  fill="none"
270
306
  viewBox="0 0 24 24"
271
307
  stroke="currentColor"
@@ -274,9 +310,18 @@
274
310
  <path stroke-linecap="round" stroke-linejoin="round" d={item.icon} />
275
311
  </svg>
276
312
  {/if}
277
- <span class={slot('itemLabel')}>{item.label}</span>
313
+ <span
314
+ class={unstyled
315
+ ? (slotClasses?.itemLabel ?? '')
316
+ : styles.itemLabel({ class: slotClasses?.itemLabel })}>{item.label}</span
317
+ >
278
318
  {#if item.shortcut}
279
- <kbd class={slot('itemShortcut')}>{item.shortcut}</kbd>
319
+ <kbd
320
+ class={unstyled
321
+ ? (slotClasses?.itemShortcut ?? '')
322
+ : styles.itemShortcut({ class: slotClasses?.itemShortcut })}
323
+ >{item.shortcut}</kbd
324
+ >
280
325
  {/if}
281
326
  </div>
282
327
  {/if}
@@ -287,17 +332,39 @@
287
332
 
288
333
  <!-- Footer -->
289
334
  {#if showFooter}
290
- <div class={slot('footer')}>
291
- <span class={slot('footerHint')}>
292
- <kbd class={slot('kbd')}>&#8593;&#8595;</kbd>
335
+ <div
336
+ class={unstyled
337
+ ? (slotClasses?.footer ?? '')
338
+ : styles.footer({ class: slotClasses?.footer })}
339
+ >
340
+ <span
341
+ class={unstyled
342
+ ? (slotClasses?.footerHint ?? '')
343
+ : styles.footerHint({ class: slotClasses?.footerHint })}
344
+ >
345
+ <kbd class={unstyled ? (slotClasses?.kbd ?? '') : styles.kbd({ class: slotClasses?.kbd })}
346
+ >&#8593;&#8595;</kbd
347
+ >
293
348
  {bt('commandPalette.hints.navigate', {})}
294
349
  </span>
295
- <span class={slot('footerHint')}>
296
- <kbd class={slot('kbd')}>&#8629;</kbd>
350
+ <span
351
+ class={unstyled
352
+ ? (slotClasses?.footerHint ?? '')
353
+ : styles.footerHint({ class: slotClasses?.footerHint })}
354
+ >
355
+ <kbd class={unstyled ? (slotClasses?.kbd ?? '') : styles.kbd({ class: slotClasses?.kbd })}
356
+ >&#8629;</kbd
357
+ >
297
358
  {bt('commandPalette.hints.select', {})}
298
359
  </span>
299
- <span class={slot('footerHint')}>
300
- <kbd class={slot('kbd')}>esc</kbd>
360
+ <span
361
+ class={unstyled
362
+ ? (slotClasses?.footerHint ?? '')
363
+ : styles.footerHint({ class: slotClasses?.footerHint })}
364
+ >
365
+ <kbd class={unstyled ? (slotClasses?.kbd ?? '') : styles.kbd({ class: slotClasses?.kbd })}
366
+ >esc</kbd
367
+ >
301
368
  {bt('commandPalette.hints.close', {})}
302
369
  </span>
303
370
  </div>
@@ -1,4 +1,4 @@
1
- import { type VariantProps } from '../../utils/variants';
1
+ import { type SlotNames, type VariantProps } from '../../utils/variants';
2
2
  export declare const commandPaletteVariants: (props?: import("../../utils/variants").TVProps<{
3
3
  size: {
4
4
  sm: {
@@ -48,12 +48,6 @@ export declare const commandPaletteVariants: (props?: import("../../utils/varian
48
48
  class?: string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | /*elided*/ any | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined;
49
49
  className?: string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | /*elided*/ any | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined;
50
50
  }) | undefined) => string;
51
- group: (props?: ({
52
- size?: "sm" | "md" | "lg" | undefined;
53
- } & {
54
- class?: string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | /*elided*/ any | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined;
55
- className?: string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | (string | false | /*elided*/ any | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined)[] | null | undefined;
56
- }) | undefined) => string;
57
51
  groupLabel: (props?: ({
58
52
  size?: "sm" | "md" | "lg" | undefined;
59
53
  } & {
@@ -134,3 +128,5 @@ export declare const commandPaletteVariants: (props?: import("../../utils/varian
134
128
  }) | undefined) => string;
135
129
  };
136
130
  export type CommandPaletteVariants = VariantProps<typeof commandPaletteVariants>;
131
+ /** Slot names derived from the `tv()` config above — single source of truth for `slotClasses`. */
132
+ export type CommandPaletteSlots = SlotNames<typeof commandPaletteVariants>;
@@ -14,7 +14,6 @@ export const commandPaletteVariants = tv({
14
14
  inputIcon: 'h-4 w-4 shrink-0 text-text-tertiary',
15
15
  clearButton: 'text-text-quaternary hover:text-text-secondary',
16
16
  list: 'max-h-72 overflow-y-auto p-1.5',
17
- group: '',
18
17
  groupLabel: [
19
18
  'px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-text-quaternary'
20
19
  ],
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { CommandPaletteVariants } from './commandPalette.variants';
2
+ import type { CommandPaletteSlots, CommandPaletteVariants } from './commandPalette.variants';
3
3
  /**
4
4
  * A single item in the command palette.
5
5
  *
@@ -102,7 +102,7 @@ export interface CommandPaletteProps {
102
102
  /** Strip all default styles. @default false */
103
103
  unstyled?: boolean;
104
104
  /** Per-slot class overrides. */
105
- slotClasses?: Partial<Record<'wrapper' | 'input' | 'inputIcon' | 'clearButton' | 'list' | 'group' | 'groupLabel' | 'item' | 'itemHighlighted' | 'itemDefault' | 'itemDisabled' | 'itemIcon' | 'itemLabel' | 'itemShortcut' | 'empty' | 'footer' | 'kbd', string>>;
105
+ slotClasses?: Partial<Record<CommandPaletteSlots, string>>;
106
106
  /**
107
107
  * Apply a named preset registered via `<BlocksProvider presets={{ CommandPalette: {...} }}>`.
108
108
  * Prefer this over `class` overrides when the requested look falls outside the
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { useBlocksI18n, mintRegistry } from '../..';
3
3
  import { useI18n } from '@urbicon-ui/i18n';
4
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
4
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
5
5
  import type { CompositionBarProps, CompositionBarIntent, CompositionItem } from './index';
6
- import { compositionBarVariants } from './composition-bar.variants';
6
+ import { compositionBarVariants, type CompositionBarVariants } from './composition-bar.variants';
7
7
 
8
8
  const bt = useBlocksI18n();
9
9
  const i18n = useI18n();
@@ -36,12 +36,17 @@
36
36
 
37
37
  const blocksConfig = getBlocksConfig();
38
38
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
39
+
40
+ const variantProps: CompositionBarVariants = $derived({
41
+ orientation,
42
+ size,
43
+ legendPlacement
44
+ });
45
+
46
+ const styles = $derived(compositionBarVariants(variantProps));
47
+
39
48
  const slotClasses = $derived(
40
- mergeSlotClasses(
41
- blocksConfig?.defaults?.CompositionBar?.slotClasses,
42
- resolvePresetSlotClasses(blocksConfig?.presets, 'CompositionBar', preset),
43
- slotClassesProp
44
- )
49
+ resolveSlotClasses(blocksConfig, 'CompositionBar', preset, variantProps, slotClassesProp)
45
50
  );
46
51
 
47
52
  let barRef = $state<HTMLDivElement>();
@@ -167,14 +172,6 @@
167
172
  return intentRingClass[item.intent ?? intent];
168
173
  }
169
174
 
170
- const styles = $derived(
171
- compositionBarVariants({
172
- orientation,
173
- size,
174
- legendPlacement
175
- })
176
- );
177
-
178
175
  $effect(() => {
179
176
  if (barRef && mint && mint !== 'none') {
180
177
  return mintRegistry.apply(barRef, mint);
@@ -1,4 +1,4 @@
1
- import { type VariantProps } from '../../utils/variants';
1
+ import { type SlotNames, type VariantProps } from '../../utils/variants';
2
2
  export declare const compositionBarVariants: (props?: import("../../utils/variants").TVProps<{
3
3
  orientation: {
4
4
  horizontal: {
@@ -190,3 +190,5 @@ export declare const compositionBarVariants: (props?: import("../../utils/varian
190
190
  }) | undefined) => string;
191
191
  };
192
192
  export type CompositionBarVariants = VariantProps<typeof compositionBarVariants>;
193
+ /** Slot names derived from the `tv()` config above — single source of truth for `slotClasses`. */
194
+ export type CompositionBarSlots = SlotNames<typeof compositionBarVariants>;
@@ -1,7 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { MintProp } from '../../mint';
4
- import type { CompositionBarVariants } from './composition-bar.variants';
4
+ import type { CompositionBarSlots, CompositionBarVariants } from './composition-bar.variants';
5
5
  export type CompositionBarIntent = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'neutral';
6
6
  /** A single share in the stacked bar. */
7
7
  export interface CompositionItem {
@@ -105,7 +105,7 @@ export interface CompositionBarProps extends Omit<CompositionBarVariants, 'isHov
105
105
  /** Remove all default classes; only the layout structure remains. */
106
106
  unstyled?: boolean;
107
107
  /** Per-slot class overrides. */
108
- slotClasses?: Partial<Record<'wrapper' | 'barWrapper' | 'bar' | 'segment' | 'segmentRest' | 'tooltip' | 'tooltipLabel' | 'tooltipDetail' | 'legend' | 'legendItem' | 'legendDot' | 'legendLabel' | 'legendValue' | 'total' | 'totalLabel', string>>;
108
+ slotClasses?: Partial<Record<CompositionBarSlots, string>>;
109
109
  /** Preset name (registered via `<BlocksProvider presets={{ CompositionBar: {...} }}>`). */
110
110
  preset?: string;
111
111
  /**
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
2
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
3
3
  import type { DonutChartProps } from './index';
4
4
  import { chartSlotResolver } from '../../internal/charts/variants';
5
5
  import { arcPath, seriesColor, numberFormatter } from '../../internal/charts/utils';
@@ -25,11 +25,7 @@
25
25
  const blocksConfig = getBlocksConfig();
26
26
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
27
27
  const slotClasses = $derived(
28
- mergeSlotClasses(
29
- blocksConfig?.defaults?.DonutChart?.slotClasses,
30
- resolvePresetSlotClasses(blocksConfig?.presets, 'DonutChart', preset),
31
- slotClassesProp
32
- )
28
+ resolveSlotClasses(blocksConfig, 'DonutChart', preset, {}, slotClassesProp)
33
29
  );
34
30
  const slot = $derived(chartSlotResolver(unstyled, slotClasses));
35
31
 
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
2
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
3
3
  import type { EmptyStateProps } from './index';
4
- import { emptyStateVariants } from './emptyState.variants';
4
+ import { emptyStateVariants, type EmptyStateVariants } from './emptyState.variants';
5
5
 
6
6
  let {
7
7
  icon: IconComponent,
@@ -19,16 +19,15 @@
19
19
 
20
20
  const blocksConfig = getBlocksConfig();
21
21
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
22
+
23
+ const variantProps: EmptyStateVariants = $derived({ density });
24
+
25
+ const styles = $derived(unstyled ? undefined : emptyStateVariants(variantProps));
26
+
22
27
  const slotClasses = $derived(
23
- mergeSlotClasses(
24
- blocksConfig?.defaults?.EmptyState?.slotClasses,
25
- resolvePresetSlotClasses(blocksConfig?.presets, 'EmptyState', preset),
26
- slotClassesProp
27
- )
28
+ resolveSlotClasses(blocksConfig, 'EmptyState', preset, variantProps, slotClassesProp)
28
29
  );
29
30
 
30
- const styles = $derived(unstyled ? undefined : emptyStateVariants({ density }));
31
-
32
31
  const iconSize = $derived(density === 'compact' ? 32 : 40);
33
32
 
34
33
  function slot(name: 'base' | 'iconWrapper' | 'title' | 'description' | 'children' | 'cta') {
@@ -1,4 +1,4 @@
1
- import { type VariantProps } from '../../utils/variants';
1
+ import { type SlotNames, type VariantProps } from '../../utils/variants';
2
2
  export declare const emptyStateVariants: (props?: import("../../utils/variants").TVProps<{
3
3
  density: {
4
4
  compact: {
@@ -52,3 +52,5 @@ export declare const emptyStateVariants: (props?: import("../../utils/variants")
52
52
  }) | undefined) => string;
53
53
  };
54
54
  export type EmptyStateVariants = VariantProps<typeof emptyStateVariants>;
55
+ /** Slot names derived from the tv() config — single source of truth for slotClasses. */
56
+ export type EmptyStateSlots = SlotNames<typeof emptyStateVariants>;
@@ -1,7 +1,7 @@
1
1
  import type { Component, Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { IconProps } from '../../icons';
4
- type EmptyStateSlot = 'base' | 'iconWrapper' | 'title' | 'description' | 'children' | 'cta';
4
+ import type { EmptyStateSlots } from './emptyState.variants';
5
5
  /**
6
6
  * @description Centered placeholder block for "no data yet" / "no results"
7
7
  * states. Pairs an optional icon with a heading, supporting text, and an
@@ -47,8 +47,8 @@ export interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'c
47
47
  class?: string;
48
48
  /** Remove all default tv classes. */
49
49
  unstyled?: boolean;
50
- /** Per-slot class overrides. */
51
- slotClasses?: Partial<Record<EmptyStateSlot, string>>;
50
+ /** Per-slot class overrides. Slots: base | iconWrapper | title | description | children | cta */
51
+ slotClasses?: Partial<Record<EmptyStateSlots, string>>;
52
52
  /**
53
53
  * Apply a named preset registered via `<BlocksProvider presets={{ EmptyState: {...} }}>`.
54
54
  * Prefer this over `class` overrides when the same look should be reused
@@ -7,8 +7,8 @@
7
7
  FileUploadError,
8
8
  FileUploadSlotName
9
9
  } from './index';
10
- import { fileUploadVariants } from './fileUpload.variants';
11
- import { getBlocksConfig, mergeSlotClasses, resolvePresetSlotClasses } from '../../provider';
10
+ import { fileUploadVariants, type FileUploadVariants } from './fileUpload.variants';
11
+ import { getBlocksConfig, resolveSlotClasses } from '../../provider';
12
12
  import { resolveIcon } from '../../icons';
13
13
  import UploadCloudIconDefault from '../../icons/UploadCloudIcon.svelte';
14
14
  import FileIconDefault from '../../icons/FileIcon.svelte';
@@ -68,13 +68,6 @@
68
68
 
69
69
  const blocksConfig = getBlocksConfig();
70
70
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
71
- const slotClasses = $derived(
72
- mergeSlotClasses(
73
- blocksConfig?.defaults?.FileUpload?.slotClasses,
74
- resolvePresetSlotClasses(blocksConfig?.presets, 'FileUpload', preset),
75
- slotClassesProp
76
- )
77
- );
78
71
 
79
72
  // ── State ──────────────────────────────────────────────────────────────────
80
73
 
@@ -90,14 +83,21 @@
90
83
  const effectiveMultiple = $derived(multiple || maxFiles > 1);
91
84
  const acceptString = $derived(Array.isArray(accept) ? accept.join(',') : (accept ?? ''));
92
85
 
93
- const styles = $derived(
94
- fileUploadVariants({
95
- size,
96
- intent,
97
- dragging,
98
- invalid: dragInvalid,
99
- disabled
100
- })
86
+ // Variant props feed both the tv() style computation and the slot-class
87
+ // cascade — extracted into one derived so `resolveSlotClasses` can match
88
+ // conditional `overrides` against the dropzone's active variants.
89
+ const variantProps: FileUploadVariants = $derived({
90
+ size,
91
+ intent,
92
+ dragging,
93
+ invalid: dragInvalid,
94
+ disabled
95
+ });
96
+
97
+ const styles = $derived(fileUploadVariants(variantProps));
98
+
99
+ const slotClasses = $derived(
100
+ resolveSlotClasses(blocksConfig, 'FileUpload', preset, variantProps, slotClassesProp)
101
101
  );
102
102
 
103
103
  const iconSize = $derived({ sm: 24, md: 32, lg: 40 }[size ?? 'md']);