@urbicon-ui/blocks 6.24.0 → 6.26.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 (73) hide show
  1. package/README.md +14 -0
  2. package/dist/components/Calendar/CalendarTimeGrid.svelte +2 -1
  3. package/dist/components/Calendar/calendar.variants.d.ts +63 -63
  4. package/dist/components/Calendar/calendar.variants.js +5 -3
  5. package/dist/components/CommandPalette/CommandPalette.svelte +32 -16
  6. package/dist/components/CommandPalette/CommandPalette.svelte.d.ts +1 -1
  7. package/dist/components/CommandPalette/commandPalette.variants.d.ts +10 -0
  8. package/dist/components/CommandPalette/commandPalette.variants.js +9 -7
  9. package/dist/components/CommandPalette/index.d.ts +19 -0
  10. package/dist/components/CompositionBar/CompositionBar.svelte +2 -2
  11. package/dist/components/CompositionBar/composition-bar.variants.js +1 -1
  12. package/dist/components/Planner/planner.variants.js +1 -1
  13. package/dist/components/Sankey/sankey.variants.js +1 -1
  14. package/dist/i18n/index.d.ts +378 -2
  15. package/dist/internal/charts/variants.js +2 -2
  16. package/dist/internal/date-grid/DateGridScaffold.svelte +9 -2
  17. package/dist/internal/date-grid/date-grid.svelte.d.ts +4 -2
  18. package/dist/internal/date-grid/date-grid.svelte.js +63 -7
  19. package/dist/primitives/Alert/alert.variants.d.ts +8 -8
  20. package/dist/primitives/Alert/alert.variants.js +1 -1
  21. package/dist/primitives/Avatar/Avatar.svelte +38 -24
  22. package/dist/primitives/Avatar/index.d.ts +1 -1
  23. package/dist/primitives/Badge/badge.variants.js +1 -1
  24. package/dist/primitives/Button/Button.svelte +12 -25
  25. package/dist/primitives/Button/button.variants.js +2 -2
  26. package/dist/primitives/ButtonGroup/ButtonGroup.svelte +5 -1
  27. package/dist/primitives/Checkbox/checkbox.variants.js +2 -2
  28. package/dist/primitives/Collapsible/Collapsible.svelte +10 -0
  29. package/dist/primitives/Collapsible/index.d.ts +13 -2
  30. package/dist/primitives/ConfirmDialog/ConfirmDialog.svelte +14 -0
  31. package/dist/primitives/ConfirmDialog/index.d.ts +13 -2
  32. package/dist/primitives/Dialog/Dialog.svelte +36 -8
  33. package/dist/primitives/Drawer/Drawer.svelte +34 -7
  34. package/dist/primitives/Input/Input.svelte +7 -1
  35. package/dist/primitives/JourneyTimeline/journey-timeline.variants.d.ts +22 -22
  36. package/dist/primitives/JourneyTimeline/journey-timeline.variants.js +3 -3
  37. package/dist/primitives/Menu/Menu.svelte +8 -0
  38. package/dist/primitives/Menu/index.d.ts +11 -13
  39. package/dist/primitives/Popover/Popover.svelte +107 -4
  40. package/dist/primitives/Popover/index.d.ts +15 -2
  41. package/dist/primitives/Popover/index.js +1 -1
  42. package/dist/primitives/Popover/popover.variants.d.ts +25 -0
  43. package/dist/primitives/Popover/popover.variants.js +35 -0
  44. package/dist/primitives/Progress/progress.variants.js +1 -1
  45. package/dist/primitives/RadioGroup/radioGroup.variants.js +2 -2
  46. package/dist/primitives/Select/index.d.ts +8 -1
  47. package/dist/primitives/Slider/Slider.svelte +32 -3
  48. package/dist/primitives/Spinner/spinner.variants.d.ts +16 -16
  49. package/dist/primitives/Stepper/stepper.variants.d.ts +11 -11
  50. package/dist/primitives/Stepper/stepper.variants.js +2 -2
  51. package/dist/primitives/Textarea/Textarea.svelte +5 -1
  52. package/dist/primitives/Toast/toast.variants.d.ts +12 -12
  53. package/dist/primitives/Tooltip/tooltip.variants.d.ts +3 -3
  54. package/dist/primitives/Tooltip/tooltip.variants.js +14 -3
  55. package/dist/style/foundation.css +41 -7
  56. package/dist/style/interaction.css +19 -2
  57. package/dist/style/semantic.css +84 -1
  58. package/dist/style/themes/forest.css +3 -1
  59. package/dist/style/themes/neutral.css +10 -1
  60. package/dist/style/themes/ocean.css +5 -1
  61. package/dist/style/themes/sunset.css +3 -1
  62. package/dist/utils/compose-handlers.d.ts +72 -0
  63. package/dist/utils/compose-handlers.js +65 -0
  64. package/dist/utils/figma-token-export.js +6 -2
  65. package/dist/utils/guide.svelte.js +92 -29
  66. package/dist/utils/index.d.ts +1 -1
  67. package/dist/utils/index.js +1 -1
  68. package/dist/utils/overlay-tokens.d.ts +17 -0
  69. package/dist/utils/overlay-tokens.js +30 -0
  70. package/dist/utils/overlay.js +24 -2
  71. package/dist/utils/use-floating-panel.svelte.js +9 -3
  72. package/dist/utils/variants.js +5 -1
  73. package/package.json +3 -3
@@ -114,7 +114,9 @@ export const calendarVariants = tv({
114
114
  'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50'
115
115
  ],
116
116
  allDayArea: ['border-b border-border-hairline'],
117
- currentTimeLine: 'absolute left-0 right-0 z-10 pointer-events-none border-t-2 border-red-500',
117
+ // `live` is the dedicated "now" accent (red by convention, themes via
118
+ // --color-live) — deliberately not `danger`, which signals errors.
119
+ currentTimeLine: 'absolute left-0 right-0 z-10 pointer-events-none border-t-2 border-live',
118
120
  // Week time grid mode (replaces weekGrid when showTimeGrid)
119
121
  weekTimeLayout: ['w-full flex flex-col', 'border-t border-border-hairline'],
120
122
  // Event popover
@@ -191,7 +193,7 @@ export const calendarVariants = tv({
191
193
  yearGrid: 'gap-1 p-1',
192
194
  yearMonth: 'p-1 gap-0.5',
193
195
  yearMonthTitle: 'text-xs mb-0.5',
194
- yearMiniDay: 'text-[9px] size-3',
196
+ yearMiniDay: 'text-3xs size-3',
195
197
  yearMiniDot: 'size-0.5',
196
198
  weekGrid: 'gap-px',
197
199
  weekColumn: 'min-h-16',
@@ -244,7 +246,7 @@ export const calendarVariants = tv({
244
246
  yearGrid: 'gap-2 p-2',
245
247
  yearMonth: 'p-2 gap-1',
246
248
  yearMonthTitle: 'text-sm mb-1',
247
- yearMiniDay: 'text-[10px] size-4',
249
+ yearMiniDay: 'text-3xs size-4',
248
250
  yearMiniDot: 'size-1',
249
251
  weekGrid: 'gap-px',
250
252
  weekColumn: 'min-h-24',
@@ -13,6 +13,7 @@
13
13
  emptyText: emptyTextProp,
14
14
  showFooter = true,
15
15
  open = $bindable(false),
16
+ query = $bindable(''),
16
17
  shortcut = 'mod+k',
17
18
  filter,
18
19
  onSelect,
@@ -32,7 +33,6 @@
32
33
  const blocksConfig = getBlocksConfig();
33
34
  const unstyled = $derived(unstyledProp || blocksConfig?.unstyled || false);
34
35
 
35
- let query = $state('');
36
36
  let selectedIndex = $state(0);
37
37
  let inputEl: HTMLInputElement | undefined = $state();
38
38
 
@@ -58,18 +58,25 @@
58
58
  return items.filter((item) => fn(item, query));
59
59
  });
60
60
 
61
+ /**
62
+ * Entries carry their index into `filtered` so the markup does not have to
63
+ * look it up per row — that was an `indexOf` per item, i.e. quadratic in the
64
+ * item count on every render.
65
+ */
66
+ type GroupEntry = { item: CommandPaletteItem; flatIdx: number };
67
+
61
68
  const grouped = $derived.by(() => {
62
- const groups: { category: string; items: CommandPaletteItem[] }[] = [];
63
- const seen: Record<string, CommandPaletteItem[]> = {};
64
- for (const item of filtered) {
69
+ const groups: { category: string; entries: GroupEntry[] }[] = [];
70
+ const seen: Record<string, GroupEntry[]> = {};
71
+ filtered.forEach((item, flatIdx) => {
65
72
  const cat = item.category ?? '';
66
73
  if (!seen[cat]) {
67
- const arr: CommandPaletteItem[] = [];
74
+ const arr: GroupEntry[] = [];
68
75
  seen[cat] = arr;
69
- groups.push({ category: cat, items: arr });
76
+ groups.push({ category: cat, entries: arr });
70
77
  }
71
- seen[cat].push(item);
72
- }
78
+ seen[cat].push({ item, flatIdx });
79
+ });
73
80
  return groups;
74
81
  });
75
82
 
@@ -129,10 +136,6 @@
129
136
  }
130
137
  }
131
138
 
132
- function getFlatIndex(item: CommandPaletteItem): number {
133
- return filtered.indexOf(item);
134
- }
135
-
136
139
  export function toggle() {
137
140
  setOpen(!open);
138
141
  }
@@ -251,8 +254,7 @@
251
254
  {group.category}
252
255
  </div>
253
256
  {/if}
254
- {#each group.items as item (item.id ?? item.label)}
255
- {@const flatIdx = getFlatIndex(item)}
257
+ {#each group.entries as { item, flatIdx } (item.id ?? item.label)}
256
258
  {@const isHighlighted = flatIdx === selectedIndex}
257
259
  {@const isDisabled = item.disabled ?? false}
258
260
  {#if customItem}
@@ -312,9 +314,23 @@
312
314
  {/if}
313
315
  <span
314
316
  class={unstyled
315
- ? (slotClasses?.itemLabel ?? '')
316
- : styles.itemLabel({ class: slotClasses?.itemLabel })}>{item.label}</span
317
+ ? (slotClasses?.itemText ?? '')
318
+ : styles.itemText({ class: slotClasses?.itemText })}
317
319
  >
320
+ <span
321
+ class={unstyled
322
+ ? (slotClasses?.itemLabel ?? '')
323
+ : styles.itemLabel({ class: slotClasses?.itemLabel })}>{item.label}</span
324
+ >
325
+ {#if item.excerpt}
326
+ <span
327
+ class={unstyled
328
+ ? (slotClasses?.itemExcerpt ?? '')
329
+ : styles.itemExcerpt({ class: slotClasses?.itemExcerpt })}
330
+ >{item.excerpt}</span
331
+ >
332
+ {/if}
333
+ </span>
318
334
  {#if item.shortcut}
319
335
  <kbd
320
336
  class={unstyled
@@ -3,6 +3,6 @@ declare const CommandPalette: import("svelte").Component<CommandPaletteProps, {
3
3
  toggle: () => void;
4
4
  show: () => void;
5
5
  hide: () => void;
6
- }, "open">;
6
+ }, "open" | "query">;
7
7
  type CommandPalette = ReturnType<typeof CommandPalette>;
8
8
  export default CommandPalette;
@@ -62,11 +62,21 @@ export declare const commandPaletteVariants: ((props?: {
62
62
  } & {
63
63
  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;
64
64
  }) | undefined) => string;
65
+ itemText: (props?: ({
66
+ size?: "sm" | "md" | "lg" | undefined;
67
+ } & {
68
+ 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;
69
+ }) | undefined) => string;
65
70
  itemLabel: (props?: ({
66
71
  size?: "sm" | "md" | "lg" | undefined;
67
72
  } & {
68
73
  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;
69
74
  }) | undefined) => string;
75
+ itemExcerpt: (props?: ({
76
+ size?: "sm" | "md" | "lg" | undefined;
77
+ } & {
78
+ 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;
79
+ }) | undefined) => string;
70
80
  itemShortcut: (props?: ({
71
81
  size?: "sm" | "md" | "lg" | undefined;
72
82
  } & {
@@ -16,9 +16,7 @@ export const commandPaletteVariants = tv({
16
16
  inputIcon: 'h-4 w-4 shrink-0 text-text-tertiary',
17
17
  clearButton: 'text-text-quaternary hover:text-text-secondary',
18
18
  list: 'max-h-72 overflow-y-auto p-1.5',
19
- groupLabel: [
20
- 'px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-text-quaternary'
21
- ],
19
+ groupLabel: ['px-2 py-1.5 text-2xs font-semibold uppercase tracking-wide text-text-quaternary'],
22
20
  // tier: modify — palette items are selectable actions.
23
21
  item: [
24
22
  'flex w-full items-center gap-3 rounded-modify px-3 py-2 text-sm',
@@ -28,20 +26,24 @@ export const commandPaletteVariants = tv({
28
26
  itemDefault: 'text-text-secondary hover:bg-surface-hover',
29
27
  itemDisabled: 'text-text-quaternary cursor-not-allowed opacity-50',
30
28
  itemIcon: 'h-4 w-4 shrink-0',
31
- itemLabel: 'flex-1 text-left',
29
+ itemText: 'flex min-w-0 flex-1 flex-col items-start gap-0.5',
30
+ itemLabel: 'text-left',
31
+ // One line only: excerpts are prose around a search match and would
32
+ // otherwise reflow every row to a different height.
33
+ itemExcerpt: 'w-full truncate text-left text-2xs text-text-tertiary',
32
34
  itemShortcut: [
33
35
  'rounded border border-border-subtle bg-surface-subtle',
34
- 'px-1.5 py-0.5 font-mono text-[10px] text-text-quaternary'
36
+ 'px-1.5 py-0.5 font-mono text-3xs text-text-quaternary'
35
37
  ],
36
38
  empty: 'py-8 text-center text-sm text-text-tertiary',
37
39
  footer: [
38
40
  'flex items-center gap-4 border-t border-border-hairline',
39
- 'px-4 py-2 text-[11px] text-text-quaternary'
41
+ 'px-4 py-2 text-2xs text-text-quaternary'
40
42
  ],
41
43
  footerHint: 'flex items-center gap-1',
42
44
  kbd: [
43
45
  'rounded border border-border-subtle bg-surface-subtle',
44
- 'px-1 py-0.5 font-mono text-[10px]'
46
+ 'px-1 py-0.5 font-mono text-3xs'
45
47
  ],
46
48
  separator: 'my-1'
47
49
  },
@@ -18,6 +18,12 @@ export interface CommandPaletteItem {
18
18
  id?: string;
19
19
  /** Display text shown in the list. */
20
20
  label: string;
21
+ /**
22
+ * Secondary line rendered under the label, truncated to one line. Use it for
23
+ * context the label cannot carry — a description, or an excerpt around a
24
+ * search match.
25
+ */
26
+ excerpt?: string;
21
27
  /** Group header this item belongs to. Items with the same category are grouped together. */
22
28
  category?: string;
23
29
  /** Optional keyboard shortcut displayed on the right side. */
@@ -38,6 +44,8 @@ export interface CommandPaletteItem {
38
44
  *
39
45
  * @tag action
40
46
  * @related Dialog
47
+ * @related Menu
48
+ * @related Combobox
41
49
  *
42
50
  * @example
43
51
  * ```svelte
@@ -76,6 +84,17 @@ export interface CommandPaletteProps {
76
84
  showFooter?: boolean;
77
85
  /** Controls visibility. Supports `bind:open`. @default false */
78
86
  open?: boolean;
87
+ /**
88
+ * Current search text. Supports `bind:query`. Reset to `''` whenever the
89
+ * palette opens.
90
+ *
91
+ * Bind it to source `items` asynchronously — derive your results from the
92
+ * query and pass them back in via `items`, with `filter={() => true}` so the
93
+ * built-in label match does not filter them a second time.
94
+ *
95
+ * @default ''
96
+ */
97
+ query?: string;
79
98
  /**
80
99
  * Register a global keyboard shortcut that toggles the palette.
81
100
  * Set to `false` to disable. @default 'mod+k' (Cmd+K / Ctrl+K)
@@ -147,7 +147,7 @@
147
147
  primary: 'text-text-on-primary',
148
148
  secondary: 'text-text-on-primary',
149
149
  success: 'text-text-on-primary',
150
- warning: 'text-text-on-surface',
150
+ warning: 'text-text-on-warning',
151
151
  danger: 'text-text-on-primary',
152
152
  neutral: 'text-text-on-primary'
153
153
  };
@@ -318,7 +318,7 @@
318
318
  <span
319
319
  aria-hidden="true"
320
320
  class={[
321
- 'pointer-events-none truncate px-1.5 text-[10px] font-medium tabular-nums',
321
+ 'pointer-events-none truncate px-1.5 text-3xs font-medium tabular-nums',
322
322
  !unstyled && getOnColorClass(item)
323
323
  ]
324
324
  .filter(Boolean)
@@ -71,7 +71,7 @@ export const compositionBarVariants = tv({
71
71
  sm: {
72
72
  legendItem: 'text-xs',
73
73
  legendDot: 'h-2 w-2',
74
- tooltip: 'text-[11px]'
74
+ tooltip: 'text-2xs'
75
75
  },
76
76
  md: {
77
77
  legendItem: 'text-sm',
@@ -67,7 +67,7 @@ export const plannerVariants = tv({
67
67
  headerTitle: 'text-sm',
68
68
  navButton: 'h-7 w-7',
69
69
  weekday: 'text-xs',
70
- weekNumber: 'text-[0.65rem]',
70
+ weekNumber: 'text-3xs',
71
71
  cellDate: 'text-xs h-5 min-w-5',
72
72
  cellWeekday: 'text-xs',
73
73
  cellItems: 'text-xs',
@@ -14,7 +14,7 @@ export const sankeyVariants = tv({
14
14
  'fill-text-primary text-xs font-medium',
15
15
  'transition-[opacity] duration-[var(--blocks-duration-fast)]'
16
16
  ],
17
- nodeValue: ['pointer-events-none select-none', 'fill-text-tertiary text-[10px] tabular-nums'],
17
+ nodeValue: ['pointer-events-none select-none', 'fill-text-tertiary text-3xs tabular-nums'],
18
18
  link: [
19
19
  'cursor-default fill-none',
20
20
  'transition-[opacity,stroke-opacity,stroke-width] duration-[var(--blocks-duration-fast)]',