@motion-proto/live-tokens 0.3.7 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/package.json +11 -9
  3. package/src/component-editor/BadgeEditor.svelte +24 -22
  4. package/src/component-editor/CalloutEditor.svelte +3 -3
  5. package/src/component-editor/CardEditor.svelte +25 -21
  6. package/src/component-editor/CollapsibleSectionEditor.svelte +27 -25
  7. package/src/component-editor/CornerBadgeEditor.svelte +37 -35
  8. package/src/component-editor/DialogEditor.svelte +26 -24
  9. package/src/component-editor/ImageEditor.svelte +11 -9
  10. package/src/component-editor/InlineEditActionsEditor.svelte +17 -15
  11. package/src/component-editor/NotificationEditor.svelte +32 -30
  12. package/src/component-editor/ProgressBarEditor.svelte +3 -3
  13. package/src/component-editor/RadioButtonEditor.svelte +31 -29
  14. package/src/component-editor/SectionDividerEditor.svelte +30 -28
  15. package/src/component-editor/SegmentedControlEditor.svelte +29 -25
  16. package/src/component-editor/StandardButtonsEditor.svelte +42 -38
  17. package/src/component-editor/TabBarEditor.svelte +20 -18
  18. package/src/component-editor/TableEditor.svelte +4 -4
  19. package/src/component-editor/TooltipEditor.svelte +11 -9
  20. package/src/component-editor/registry.ts +2 -2
  21. package/src/component-editor/scaffolding/AngleDial.svelte +20 -19
  22. package/src/component-editor/scaffolding/ComponentEditorBase.svelte +44 -20
  23. package/src/component-editor/scaffolding/ComponentFileManager.svelte +260 -37
  24. package/src/component-editor/scaffolding/ComponentFileMenu.svelte +41 -29
  25. package/src/component-editor/scaffolding/ComponentsTab.svelte +7 -3
  26. package/src/component-editor/scaffolding/CopyFromMenu.svelte +21 -12
  27. package/src/component-editor/scaffolding/DemoHeader.svelte +13 -4
  28. package/src/component-editor/scaffolding/DividerEditor.svelte +27 -14
  29. package/src/component-editor/scaffolding/FieldsetWrapper.svelte +10 -4
  30. package/src/component-editor/scaffolding/GradientCard.svelte +25 -20
  31. package/src/component-editor/scaffolding/LinkageChart.svelte +43 -34
  32. package/src/component-editor/scaffolding/LinkedBlock.svelte +24 -21
  33. package/src/component-editor/scaffolding/NonStylableConfig.svelte +6 -1
  34. package/src/component-editor/scaffolding/SaveAsDialog.svelte +39 -35
  35. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +21 -9
  36. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +8 -3
  37. package/src/component-editor/scaffolding/StateBlock.svelte +30 -13
  38. package/src/component-editor/scaffolding/TokenLayout.svelte +46 -30
  39. package/src/component-editor/scaffolding/TypeEditor.svelte +52 -26
  40. package/src/component-editor/scaffolding/VariantGroup.svelte +81 -48
  41. package/src/component-editor/scaffolding/componentSectionType.ts +2 -2
  42. package/src/components/Badge.svelte +45 -26
  43. package/src/components/Button.svelte +44 -21
  44. package/src/components/Callout.svelte +17 -12
  45. package/src/components/Card.svelte +23 -11
  46. package/src/components/CollapsibleSection.svelte +56 -27
  47. package/src/components/CornerBadge.svelte +32 -18
  48. package/src/components/Dialog.svelte +55 -31
  49. package/src/components/Image.svelte +14 -5
  50. package/src/components/InlineEditActions.svelte +22 -10
  51. package/src/components/Notification.svelte +39 -19
  52. package/src/components/ProgressBar.svelte +27 -17
  53. package/src/components/RadioButton.svelte +27 -10
  54. package/src/components/SectionDivider.svelte +34 -26
  55. package/src/components/SegmentedControl.svelte +23 -9
  56. package/src/components/TabBar.svelte +23 -10
  57. package/src/components/Table.svelte +8 -3
  58. package/src/components/Tooltip.svelte +15 -5
  59. package/src/lib/ColumnsOverlay.svelte +3 -3
  60. package/src/lib/LiveEditorOverlay.svelte +73 -36
  61. package/src/pages/ComponentEditorPage.svelte +17 -13
  62. package/src/pages/EditorShell.svelte +24 -20
  63. package/src/styles/form-controls.css +2 -2
  64. package/src/styles/tokens.css +59 -81
  65. package/src/ui/BezierCurveEditor.svelte +59 -43
  66. package/src/ui/ColorEditPanel.svelte +71 -44
  67. package/src/ui/EditorViewSwitcher.svelte +9 -5
  68. package/src/ui/FontStackEditor.svelte +16 -15
  69. package/src/ui/GradientEditor.svelte +42 -33
  70. package/src/ui/GradientStopPicker.svelte +18 -29
  71. package/src/ui/PaletteEditor.svelte +238 -212
  72. package/src/ui/PresetFileManager.svelte +20 -18
  73. package/src/ui/ProjectFontsSection.svelte +30 -30
  74. package/src/ui/SurfacesTab.svelte +3 -3
  75. package/src/ui/TextTab.svelte +2 -2
  76. package/src/ui/ThemeFileManager.svelte +38 -35
  77. package/src/ui/Toggle.svelte +11 -9
  78. package/src/ui/UICopyPopover.svelte +19 -15
  79. package/src/ui/UIDialog.svelte +48 -30
  80. package/src/ui/UIFontFamilySelector.svelte +104 -78
  81. package/src/ui/UIFontSizeSelector.svelte +38 -20
  82. package/src/ui/UIFontWeightSelector.svelte +33 -13
  83. package/src/ui/UILineHeightSelector.svelte +33 -13
  84. package/src/ui/UILinkToggle.svelte +7 -6
  85. package/src/ui/UIOptionItem.svelte +21 -7
  86. package/src/ui/UIOptionList.svelte +9 -3
  87. package/src/ui/UIPaddingSelector.svelte +108 -82
  88. package/src/ui/UIPaletteSelector.svelte +186 -161
  89. package/src/ui/UIRadio.svelte +23 -8
  90. package/src/ui/UIRadioGroup.svelte +9 -8
  91. package/src/ui/UIRelinkConfirmPopover.svelte +26 -16
  92. package/src/ui/UITokenSelector.svelte +112 -68
  93. package/src/ui/UIVariantSelector.svelte +79 -57
  94. package/src/ui/VariablesTab.svelte +15 -15
  95. package/src/ui/palette/GradientStopEditor.svelte +45 -26
  96. package/src/ui/palette/OverridesPanel.svelte +85 -49
  97. package/src/ui/palette/PaletteBase.svelte +60 -32
  98. package/src/ui/palette/ScaleCurveEditor.svelte +25 -10
  99. package/src/ui/sections/ColumnsSection.svelte +13 -13
  100. package/src/ui/sections/GradientsSection.svelte +12 -9
  101. package/src/ui/sections/OverlaysSection.svelte +50 -47
  102. package/src/ui/sections/ShadowsSection.svelte +110 -104
  103. package/src/ui/sections/TokenScaleTable.svelte +38 -22
  104. package/src/ui/sections/tokenScales.ts +2 -2
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { writable } from 'svelte/store';
3
+ import type { Snippet } from 'svelte';
3
4
  import TokenLayout from './TokenLayout.svelte';
4
5
  import StateBlock from './StateBlock.svelte';
5
6
  import CopyFromMenu from './CopyFromMenu.svelte';
@@ -8,36 +9,62 @@
8
9
  import type { Token, TypeGroupConfig } from './types';
9
10
  import type { Sibling } from './siblings';
10
11
 
11
- export let name: string;
12
- export let title: string;
13
- export let tokens: Token[] = [];
14
- export let states: Record<string, Token[]> | null = null;
15
- /** Per-state type groups; rendered as TypeEditor blocks alongside the state's TokenLayout. */
16
- export let typeGroups: Record<string, TypeGroupConfig[]> = {};
17
- /** When set, overrides are read from and cleared through the editor store. */
18
- export let component: string | undefined = undefined;
19
- /** Sibling variants of this component (excludes self). When non-empty,
20
- a "Copy from" menu is rendered that lets the user pull token values from
21
- a sibling's same-state into the current state. */
22
- export let siblings: Sibling[] = [];
23
- /** Forwarded to StateBlock → TokenLayout. >1 lays out the property grid
24
- across multiple visual columns (column-major flow). Useful for
25
- single-text components like Button whose 8-10 properties stretch the
26
- panel vertically when stacked single-column. */
27
- export let columns: number = 1;
28
- /** Label rendered above the state-tab selector strip. Defaults to "Element"
29
- because most strips mix structural parts (e.g. bar, frame) with
30
- component states; "States" would mislabel the parts. Editors can override
31
- when every tab on the strip really is a state. */
32
- export let selectorLabel: string = 'Element';
12
+ interface Props {
13
+ name: string;
14
+ title: string;
15
+ tokens?: Token[];
16
+ states?: Record<string, Token[]> | null;
17
+ /** Per-state type groups; rendered as TypeEditor blocks alongside the state's TokenLayout. */
18
+ typeGroups?: Record<string, TypeGroupConfig[]>;
19
+ /** When set, overrides are read from and cleared through the editor store. */
20
+ component?: string | undefined;
21
+ /** Sibling variants of this component (excludes self). When non-empty,
22
+ a "Copy from" menu is rendered that lets the user pull token values from
23
+ a sibling's same-state into the current state. */
24
+ siblings?: Sibling[];
25
+ /** Forwarded to StateBlock TokenLayout. >1 lays out the property grid
26
+ across multiple visual columns (column-major flow). Useful for
27
+ single-text components like Button whose 8-10 properties stretch the
28
+ panel vertically when stacked single-column. */
29
+ columns?: number;
30
+ /** Label rendered above the state-tab selector strip. Defaults to "Element"
31
+ because most strips mix structural parts (e.g. bar, frame) with
32
+ component states; "States" would mislabel the parts. Editors can override
33
+ when every tab on the strip really is a state. */
34
+ selectorLabel?: string;
35
+ /** Forwarded to StateBlock — fires when a token is mutated. */
36
+ onchange?: () => void;
37
+ /** Default snippet: receives the active state name; renders the live preview. */
38
+ children?: Snippet<[{ activeState: string }]>;
39
+ /** Right-aligned controls in the state-tabs strip (e.g. per-state toggles). */
40
+ stateActions?: Snippet<[string]>;
41
+ /** Rendered above the property grid when a state is active. */
42
+ compositeControls?: Snippet<[string]>;
43
+ }
44
+
45
+ let {
46
+ name,
47
+ title,
48
+ tokens = [],
49
+ states = null,
50
+ typeGroups = {},
51
+ component = undefined,
52
+ siblings = [],
53
+ columns = 1,
54
+ selectorLabel = 'Element',
55
+ onchange,
56
+ children,
57
+ stateActions,
58
+ compositeControls,
59
+ }: Props = $props();
33
60
 
34
61
  const editorCtx = getEditorContext();
35
62
  const linkedOrderStore = editorCtx?.linkedOrder ?? writable<Map<string, number> | null>(null);
36
63
  const focusedVariantStore = editorCtx?.focusedVariant ?? writable<string | null>(null);
37
64
  const focusedStateStore = editorCtx?.focusedState ?? writable<string | null>(null);
38
- $: linkedOrder = $linkedOrderStore ?? undefined;
65
+ let linkedOrder = $derived($linkedOrderStore ?? undefined);
39
66
 
40
- let activeTab: string = '';
67
+ let activeTab: string = $state('');
41
68
 
42
69
  const TYPE_PROPS = ['colorVariable', 'familyVariable', 'sizeVariable', 'weightVariable', 'lineHeightVariable', 'outlineWidthVariable', 'outlineColorVariable'] as const;
43
70
 
@@ -73,7 +100,7 @@
73
100
  });
74
101
  }
75
102
 
76
- $: copySources = (() => {
103
+ let copySources = $derived.by(() => {
77
104
  const fromSiblings = siblings.map((s) => ({
78
105
  name: s.name,
79
106
  label: s.label,
@@ -84,27 +111,33 @@
84
111
  return [{ name, label: title, states: ownStates }, ...fromSiblings];
85
112
  }
86
113
  return fromSiblings;
87
- })();
114
+ });
88
115
 
89
- $: stateNames = states ? Object.keys(states) : [];
90
- $: tabsStripVisible = stateNames.length >= 2;
91
- $: if (stateNames.length > 0 && !stateNames.includes(activeTab)) {
92
- activeTab = stateNames[0];
93
- }
116
+ let stateNames = $derived(states ? Object.keys(states) : []);
117
+ let tabsStripVisible = $derived(stateNames.length >= 2);
118
+ $effect(() => {
119
+ if (stateNames.length > 0 && !stateNames.includes(activeTab)) {
120
+ activeTab = stateNames[0];
121
+ }
122
+ });
94
123
  // Cross-group hint from chart row clicks: adopt it if it names one of our states.
95
- $: if ($focusedStateStore && stateNames.includes($focusedStateStore) && activeTab !== $focusedStateStore) {
96
- activeTab = $focusedStateStore;
97
- }
124
+ $effect(() => {
125
+ if ($focusedStateStore && stateNames.includes($focusedStateStore) && activeTab !== $focusedStateStore) {
126
+ activeTab = $focusedStateStore;
127
+ }
128
+ });
98
129
 
99
- $: inFocusMode = siblings.length > 0;
100
- $: amIFocused = $focusedVariantStore === name;
101
- $: shouldRender = !inFocusMode || amIFocused;
130
+ let inFocusMode = $derived(siblings.length > 0);
131
+ let amIFocused = $derived($focusedVariantStore === name);
132
+ let shouldRender = $derived(!inFocusMode || amIFocused);
102
133
  // Mirror this group's active state back to the shared store when this is the
103
134
  // focused variant, so the linked-block row + chart selection track the user's
104
135
  // state-tab clicks (not just chart-row clicks).
105
- $: if (amIFocused && activeTab && stateNames.includes(activeTab) && $focusedStateStore !== activeTab) {
106
- focusedStateStore.set(activeTab);
107
- }
136
+ $effect(() => {
137
+ if (amIFocused && activeTab && stateNames.includes(activeTab) && $focusedStateStore !== activeTab) {
138
+ focusedStateStore.set(activeTab);
139
+ }
140
+ });
108
141
 
109
142
  </script>
110
143
 
@@ -120,7 +153,7 @@
120
153
  <!-- Preview at top, then state tabs + Copy from, then properties for active tab. -->
121
154
  <div class="tabs-preview">
122
155
  <span class="section-label">Preview</span>
123
- <slot activeState={activeTab} />
156
+ {@render children?.({ activeState: activeTab })}
124
157
  </div>
125
158
 
126
159
  {#if tabsStripVisible || (copySources.length > 0 && activeTab)}
@@ -138,20 +171,20 @@
138
171
  class:active={activeTab === s}
139
172
  role="tab"
140
173
  aria-selected={activeTab === s}
141
- on:click={() => { activeTab = s; focusedStateStore.set(s); }}
174
+ onclick={() => { activeTab = s; focusedStateStore.set(s); }}
142
175
  >{s}</button>
143
176
  {/each}
144
177
  </div>
145
178
  {/if}
146
179
  {#if activeTab}
147
- <slot name="state-actions" stateName={activeTab} />
180
+ {@render stateActions?.(activeTab)}
148
181
  {/if}
149
182
  {#if copySources.length > 0 && activeTab}
150
183
  <CopyFromMenu
151
184
  toState={activeTab}
152
185
  variantName={name}
153
186
  {copySources}
154
- on:select={(e) => pickCopySource(activeTab, e.detail.fromVariant, e.detail.fromState)}
187
+ onselect={(d) => pickCopySource(activeTab, d.fromVariant, d.fromState)}
155
188
  />
156
189
  {/if}
157
190
  </div>
@@ -160,7 +193,7 @@
160
193
 
161
194
  {#if activeTab && states[activeTab]}
162
195
  {@const stateName = activeTab}
163
- <slot name="composite-controls" {stateName} />
196
+ {@render compositeControls?.(stateName)}
164
197
  <span class="section-label">Properties</span>
165
198
  <StateBlock
166
199
  tokens={states[stateName]}
@@ -168,17 +201,17 @@
168
201
  {component}
169
202
  {linkedOrder}
170
203
  {columns}
171
- on:change
204
+ {onchange}
172
205
  />
173
206
  {/if}
174
207
  {:else}
175
- <slot activeState="" />
208
+ {@render children?.({ activeState: '' })}
176
209
  <TokenLayout
177
210
  title={name}
178
211
  tokens={tokens}
179
212
  {component}
180
213
  {linkedOrder}
181
- on:change
214
+ {onchange}
182
215
  />
183
216
  {/if}
184
217
 
@@ -1,8 +1,8 @@
1
- import type { ComponentType } from 'svelte';
1
+ import type { Component } from 'svelte';
2
2
 
3
3
  export type ComponentSection = {
4
4
  id: string;
5
5
  label: string;
6
- component: ComponentType;
6
+ component: Component<any, any, any>;
7
7
  props?: Record<string, unknown>;
8
8
  };
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  export const badgeVariants = [
3
3
  'primary',
4
4
  'accent',
@@ -15,17 +15,36 @@
15
15
  </script>
16
16
 
17
17
  <script lang="ts">
18
- export let variant: BadgeVariant = 'info';
19
- export let size: 'default' | 'small' = 'default';
20
- export let icon: string | undefined = undefined;
21
- /** When true, badge is absolutely positioned. Requires the parent to be position: relative. */
22
- export let floating: boolean = false;
23
- /** Corner of the positioned parent to attach to when floating. */
24
- export let anchor: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' = 'bottom-right';
25
- /** CSS length to offset from the anchor edges. Defaults to --space-12 (or --space-8 when size='small'). */
26
- export let offset: string | undefined = undefined;
27
- /** When true, badge sits flush in the anchor corner: zero offset and squared corners. */
28
- export let flush: boolean = false;
18
+ import type { Snippet } from 'svelte';
19
+
20
+ interface Props {
21
+ variant?: BadgeVariant;
22
+ size?: 'default' | 'small';
23
+ icon?: string | undefined;
24
+ /** When true, badge is absolutely positioned. Requires the parent to be position: relative. */
25
+ floating?: boolean;
26
+ /** Corner of the positioned parent to attach to when floating. */
27
+ anchor?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
28
+ /** CSS length to offset from the anchor edges. Defaults to --space-12 (or --space-8 when size='small'). */
29
+ offset?: string | undefined;
30
+ /** When true, badge sits flush in the anchor corner: zero offset and squared corners. */
31
+ flush?: boolean;
32
+ /** Custom icon content. Falls back to `icon` prop's font-icon class. Renamed from `slot="icon"` in 0.5.0. */
33
+ iconSlot?: Snippet;
34
+ children?: Snippet;
35
+ }
36
+
37
+ let {
38
+ variant = 'info',
39
+ size = 'default',
40
+ icon = undefined,
41
+ floating = false,
42
+ anchor = 'bottom-right',
43
+ offset = undefined,
44
+ flush = false,
45
+ iconSlot,
46
+ children,
47
+ }: Props = $props();
29
48
  </script>
30
49
 
31
50
  <span
@@ -38,10 +57,10 @@
38
57
  >
39
58
  {#if icon}
40
59
  <span class="icon"><i class={icon}></i></span>
41
- {:else}
42
- <span class="icon"><slot name="icon" /></span>
60
+ {:else if iconSlot}
61
+ <span class="icon">{@render iconSlot()}</span>
43
62
  {/if}
44
- <slot />
63
+ {@render children?.()}
45
64
  </span>
46
65
 
47
66
  <style lang="scss">
@@ -64,7 +83,7 @@
64
83
  --badge-primary-text-font-family: var(--font-sans);
65
84
  --badge-primary-text-font-size: var(--font-size-sm);
66
85
  --badge-primary-text-font-weight: var(--font-weight-light);
67
- --badge-primary-text-line-height: var(--line-height-tight);
86
+ --badge-primary-text-line-height: var(--line-height-xs);
68
87
  --badge-primary-border-width: var(--border-width-1);
69
88
  --badge-primary-radius: var(--radius-full);
70
89
  --badge-primary-padding: var(--space-6);
@@ -79,7 +98,7 @@
79
98
  --badge-accent-text-font-family: var(--font-sans);
80
99
  --badge-accent-text-font-size: var(--font-size-sm);
81
100
  --badge-accent-text-font-weight: var(--font-weight-light);
82
- --badge-accent-text-line-height: var(--line-height-tight);
101
+ --badge-accent-text-line-height: var(--line-height-xs);
83
102
  --badge-accent-border-width: var(--border-width-1);
84
103
  --badge-accent-radius: var(--radius-full);
85
104
  --badge-accent-padding: var(--space-6);
@@ -94,7 +113,7 @@
94
113
  --badge-neutral-text-font-family: var(--font-sans);
95
114
  --badge-neutral-text-font-size: var(--font-size-sm);
96
115
  --badge-neutral-text-font-weight: var(--font-weight-light);
97
- --badge-neutral-text-line-height: var(--line-height-tight);
116
+ --badge-neutral-text-line-height: var(--line-height-xs);
98
117
  --badge-neutral-border-width: var(--border-width-1);
99
118
  --badge-neutral-radius: var(--radius-full);
100
119
  --badge-neutral-padding: var(--space-6);
@@ -109,7 +128,7 @@
109
128
  --badge-alternate-text-font-family: var(--font-sans);
110
129
  --badge-alternate-text-font-size: var(--font-size-sm);
111
130
  --badge-alternate-text-font-weight: var(--font-weight-light);
112
- --badge-alternate-text-line-height: var(--line-height-tight);
131
+ --badge-alternate-text-line-height: var(--line-height-xs);
113
132
  --badge-alternate-border-width: var(--border-width-1);
114
133
  --badge-alternate-radius: var(--radius-full);
115
134
  --badge-alternate-padding: var(--space-6);
@@ -124,7 +143,7 @@
124
143
  --badge-canvas-text-font-family: var(--font-sans);
125
144
  --badge-canvas-text-font-size: var(--font-size-sm);
126
145
  --badge-canvas-text-font-weight: var(--font-weight-light);
127
- --badge-canvas-text-line-height: var(--line-height-tight);
146
+ --badge-canvas-text-line-height: var(--line-height-xs);
128
147
  --badge-canvas-border-width: var(--border-width-1);
129
148
  --badge-canvas-radius: var(--radius-full);
130
149
  --badge-canvas-padding: var(--space-6);
@@ -139,7 +158,7 @@
139
158
  --badge-special-text-font-family: var(--font-sans);
140
159
  --badge-special-text-font-size: var(--font-size-sm);
141
160
  --badge-special-text-font-weight: var(--font-weight-light);
142
- --badge-special-text-line-height: var(--line-height-tight);
161
+ --badge-special-text-line-height: var(--line-height-xs);
143
162
  --badge-special-border-width: var(--border-width-1);
144
163
  --badge-special-radius: var(--radius-full);
145
164
  --badge-special-padding: var(--space-6);
@@ -154,7 +173,7 @@
154
173
  --badge-success-text-font-family: var(--font-sans);
155
174
  --badge-success-text-font-size: var(--font-size-sm);
156
175
  --badge-success-text-font-weight: var(--font-weight-light);
157
- --badge-success-text-line-height: var(--line-height-tight);
176
+ --badge-success-text-line-height: var(--line-height-xs);
158
177
  --badge-success-border-width: var(--border-width-1);
159
178
  --badge-success-radius: var(--radius-full);
160
179
  --badge-success-padding: var(--space-6);
@@ -169,7 +188,7 @@
169
188
  --badge-warning-text-font-family: var(--font-sans);
170
189
  --badge-warning-text-font-size: var(--font-size-sm);
171
190
  --badge-warning-text-font-weight: var(--font-weight-light);
172
- --badge-warning-text-line-height: var(--line-height-tight);
191
+ --badge-warning-text-line-height: var(--line-height-xs);
173
192
  --badge-warning-border-width: var(--border-width-1);
174
193
  --badge-warning-radius: var(--radius-full);
175
194
  --badge-warning-padding: var(--space-6);
@@ -184,7 +203,7 @@
184
203
  --badge-danger-text-font-family: var(--font-sans);
185
204
  --badge-danger-text-font-size: var(--font-size-sm);
186
205
  --badge-danger-text-font-weight: var(--font-weight-light);
187
- --badge-danger-text-line-height: var(--line-height-tight);
206
+ --badge-danger-text-line-height: var(--line-height-xs);
188
207
  --badge-danger-border-width: var(--border-width-1);
189
208
  --badge-danger-radius: var(--radius-full);
190
209
  --badge-danger-padding: var(--space-6);
@@ -199,7 +218,7 @@
199
218
  --badge-info-text-font-family: var(--font-sans);
200
219
  --badge-info-text-font-size: var(--font-size-sm);
201
220
  --badge-info-text-font-weight: var(--font-weight-light);
202
- --badge-info-text-line-height: var(--line-height-tight);
221
+ --badge-info-text-line-height: var(--line-height-xs);
203
222
  --badge-info-border-width: var(--border-width-1);
204
223
  --badge-info-radius: var(--radius-full);
205
224
  --badge-info-padding: var(--space-6);
@@ -213,7 +232,7 @@
213
232
  display: inline-flex;
214
233
  align-items: center;
215
234
  gap: var(--space-6);
216
- line-height: var(--line-height-tight);
235
+ line-height: var(--line-height-xs);
217
236
  white-space: nowrap;
218
237
  backdrop-filter: blur(var(--badge-blur, 0));
219
238
  -webkit-backdrop-filter: blur(var(--badge-blur, 0));
@@ -1,23 +1,46 @@
1
1
  <script lang="ts">
2
2
  import { createEventDispatcher } from 'svelte';
3
3
 
4
- export let disabled: boolean = false;
5
- export let type: 'button' | 'submit' | 'reset' = 'button';
6
- export let variant: 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning' = 'primary';
7
- export let size: 'default' | 'small' = 'default';
8
- export let ariaLabel: string | undefined = undefined;
9
- export let tooltip: string | undefined = undefined;
10
- export let icon: string | undefined = undefined;
11
- export let iconPosition: 'left' | 'right' = 'left';
12
- export let fullWidth: boolean = false;
13
- export let buttonRef: HTMLButtonElement | undefined = undefined;
14
- let className: string = '';
15
- export { className as class };
4
+ interface Props {
5
+ disabled?: boolean;
6
+ type?: 'button' | 'submit' | 'reset';
7
+ variant?: 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning';
8
+ size?: 'default' | 'small';
9
+ ariaLabel?: string | undefined;
10
+ tooltip?: string | undefined;
11
+ icon?: string | undefined;
12
+ iconPosition?: 'left' | 'right';
13
+ fullWidth?: boolean;
14
+ buttonRef?: HTMLButtonElement | undefined;
15
+ class?: string;
16
+ /** Click callback. Preferred over `on:click` from 0.5.0 onward. */
17
+ onclick?: (event: MouseEvent) => void;
18
+ children?: import('svelte').Snippet;
19
+ }
16
20
 
21
+ let {
22
+ disabled = false,
23
+ type = 'button',
24
+ variant = 'primary',
25
+ size = 'default',
26
+ ariaLabel = undefined,
27
+ tooltip = undefined,
28
+ icon = undefined,
29
+ iconPosition = 'left',
30
+ fullWidth = false,
31
+ buttonRef = $bindable(undefined),
32
+ class: className = '',
33
+ onclick,
34
+ children
35
+ }: Props = $props();
36
+
37
+ // Dual-fire bridge: keeps Svelte-4-style `<Button on:click={fn}>` consumers
38
+ // working until 0.6.0. Remove the dispatcher and this comment in 0.6.0.
17
39
  const dispatch = createEventDispatcher();
18
40
 
19
41
  function handleClick(event: MouseEvent) {
20
42
  if (!disabled) {
43
+ onclick?.(event);
21
44
  dispatch('click', event);
22
45
  }
23
46
  }
@@ -32,12 +55,12 @@
32
55
  {disabled}
33
56
  aria-label={ariaLabel}
34
57
  data-tooltip={tooltip}
35
- on:click={handleClick}
58
+ onclick={handleClick}
36
59
  >
37
60
  {#if icon && iconPosition === 'left'}
38
61
  <i class={icon}></i>
39
62
  {/if}
40
- <slot />
63
+ {@render children?.()}
41
64
  {#if icon && iconPosition === 'right'}
42
65
  <i class={icon}></i>
43
66
  {/if}
@@ -56,7 +79,7 @@
56
79
  --button-primary-text-font-family: var(--font-sans);
57
80
  --button-primary-text-font-size: var(--font-size-sm);
58
81
  --button-primary-text-font-weight: var(--font-weight-light);
59
- --button-primary-text-line-height: var(--line-height-snug);
82
+ --button-primary-text-line-height: var(--line-height-sm);
60
83
  --button-primary-border: var(--border-brand);
61
84
  --button-primary-border-width: var(--border-width-1);
62
85
  --button-primary-radius: var(--radius-md);
@@ -81,7 +104,7 @@
81
104
  --button-secondary-text-font-family: var(--font-sans);
82
105
  --button-secondary-text-font-size: var(--font-size-sm);
83
106
  --button-secondary-text-font-weight: var(--font-weight-light);
84
- --button-secondary-text-line-height: var(--line-height-snug);
107
+ --button-secondary-text-line-height: var(--line-height-sm);
85
108
  --button-secondary-border: var(--border-neutral);
86
109
  --button-secondary-border-width: var(--border-width-1);
87
110
  --button-secondary-radius: var(--radius-md);
@@ -106,7 +129,7 @@
106
129
  --button-outline-text-font-family: var(--font-sans);
107
130
  --button-outline-text-font-size: var(--font-size-sm);
108
131
  --button-outline-text-font-weight: var(--font-weight-light);
109
- --button-outline-text-line-height: var(--line-height-snug);
132
+ --button-outline-text-line-height: var(--line-height-sm);
110
133
  --button-outline-border: var(--border-neutral);
111
134
  --button-outline-border-width: var(--border-width-1);
112
135
  --button-outline-radius: var(--radius-md);
@@ -131,7 +154,7 @@
131
154
  --button-success-text-font-family: var(--font-sans);
132
155
  --button-success-text-font-size: var(--font-size-sm);
133
156
  --button-success-text-font-weight: var(--font-weight-light);
134
- --button-success-text-line-height: var(--line-height-snug);
157
+ --button-success-text-line-height: var(--line-height-sm);
135
158
  --button-success-border: var(--border-success);
136
159
  --button-success-border-width: var(--border-width-2);
137
160
  --button-success-radius: var(--radius-md);
@@ -156,7 +179,7 @@
156
179
  --button-danger-text-font-family: var(--font-sans);
157
180
  --button-danger-text-font-size: var(--font-size-sm);
158
181
  --button-danger-text-font-weight: var(--font-weight-light);
159
- --button-danger-text-line-height: var(--line-height-snug);
182
+ --button-danger-text-line-height: var(--line-height-sm);
160
183
  --button-danger-border: var(--border-danger);
161
184
  --button-danger-border-width: var(--border-width-2);
162
185
  --button-danger-radius: var(--radius-md);
@@ -181,7 +204,7 @@
181
204
  --button-warning-text-font-family: var(--font-sans);
182
205
  --button-warning-text-font-size: var(--font-size-sm);
183
206
  --button-warning-text-font-weight: var(--font-weight-light);
184
- --button-warning-text-line-height: var(--line-height-snug);
207
+ --button-warning-text-line-height: var(--line-height-sm);
185
208
  --button-warning-border: var(--border-warning);
186
209
  --button-warning-border-width: var(--border-width-2);
187
210
  --button-warning-radius: var(--radius-md);
@@ -499,7 +522,7 @@
499
522
  padding: var(--space-6) var(--space-12);
500
523
  font-size: var(--font-size-xs);
501
524
  font-weight: var(--font-weight-normal);
502
- line-height: var(--line-height-snug);
525
+ line-height: var(--line-height-sm);
503
526
  }
504
527
 
505
528
  &.small :global(i) {
@@ -1,15 +1,20 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  export const calloutVariants = ['info', 'success', 'warning', 'danger'] as const;
3
3
  export type CalloutVariant = typeof calloutVariants[number];
4
4
  </script>
5
5
 
6
6
  <script lang="ts">
7
- export let variant: CalloutVariant = 'info';
8
- export let label: string = '';
7
+ interface Props {
8
+ variant?: CalloutVariant;
9
+ label?: string;
10
+ children?: import('svelte').Snippet;
11
+ }
12
+
13
+ let { variant = 'info', label = '', children }: Props = $props();
9
14
  </script>
10
15
 
11
16
  <div class="callout callout-{variant}">
12
- {#if label}<strong class="callout-label">{label}</strong>{' '}{/if}<span class="callout-message"><slot /></span>
17
+ {#if label}<strong class="callout-label">{label}</strong>{' '}{/if}<span class="callout-message">{@render children?.()}</span>
13
18
  </div>
14
19
 
15
20
  <style lang="scss">
@@ -31,12 +36,12 @@
31
36
  --callout-info-label-font-family: var(--font-serif);
32
37
  --callout-info-label-font-size: var(--font-size-md);
33
38
  --callout-info-label-font-weight: var(--font-weight-bold);
34
- --callout-info-label-line-height: var(--line-height-relaxed);
39
+ --callout-info-label-line-height: var(--line-height-md);
35
40
  --callout-info-text: var(--text-info);
36
41
  --callout-info-text-font-family: var(--font-serif);
37
42
  --callout-info-text-font-size: var(--font-size-md);
38
43
  --callout-info-text-font-weight: var(--font-weight-normal);
39
- --callout-info-text-line-height: var(--line-height-relaxed);
44
+ --callout-info-text-line-height: var(--line-height-md);
40
45
 
41
46
  /* Success */
42
47
  --callout-success-surface: var(--surface-success-lowest);
@@ -49,12 +54,12 @@
49
54
  --callout-success-label-font-family: var(--font-serif);
50
55
  --callout-success-label-font-size: var(--font-size-md);
51
56
  --callout-success-label-font-weight: var(--font-weight-bold);
52
- --callout-success-label-line-height: var(--line-height-relaxed);
57
+ --callout-success-label-line-height: var(--line-height-md);
53
58
  --callout-success-text: var(--text-success);
54
59
  --callout-success-text-font-family: var(--font-serif);
55
60
  --callout-success-text-font-size: var(--font-size-md);
56
61
  --callout-success-text-font-weight: var(--font-weight-normal);
57
- --callout-success-text-line-height: var(--line-height-relaxed);
62
+ --callout-success-text-line-height: var(--line-height-md);
58
63
 
59
64
  /* Warning */
60
65
  --callout-warning-surface: var(--surface-warning-lowest);
@@ -67,12 +72,12 @@
67
72
  --callout-warning-label-font-family: var(--font-serif);
68
73
  --callout-warning-label-font-size: var(--font-size-md);
69
74
  --callout-warning-label-font-weight: var(--font-weight-bold);
70
- --callout-warning-label-line-height: var(--line-height-relaxed);
75
+ --callout-warning-label-line-height: var(--line-height-md);
71
76
  --callout-warning-text: var(--text-warning);
72
77
  --callout-warning-text-font-family: var(--font-serif);
73
78
  --callout-warning-text-font-size: var(--font-size-md);
74
79
  --callout-warning-text-font-weight: var(--font-weight-normal);
75
- --callout-warning-text-line-height: var(--line-height-relaxed);
80
+ --callout-warning-text-line-height: var(--line-height-md);
76
81
 
77
82
  /* Danger */
78
83
  --callout-danger-surface: var(--surface-danger-lowest);
@@ -85,12 +90,12 @@
85
90
  --callout-danger-label-font-family: var(--font-serif);
86
91
  --callout-danger-label-font-size: var(--font-size-md);
87
92
  --callout-danger-label-font-weight: var(--font-weight-bold);
88
- --callout-danger-label-line-height: var(--line-height-relaxed);
93
+ --callout-danger-label-line-height: var(--line-height-md);
89
94
  --callout-danger-text: var(--text-danger);
90
95
  --callout-danger-text-font-family: var(--font-serif);
91
96
  --callout-danger-text-font-size: var(--font-size-md);
92
97
  --callout-danger-text-font-weight: var(--font-weight-normal);
93
- --callout-danger-text-line-height: var(--line-height-relaxed);
98
+ --callout-danger-text-line-height: var(--line-height-md);
94
99
  }
95
100
 
96
101
  .callout {