@motion-proto/live-tokens 0.1.1 → 0.3.2

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 (224) hide show
  1. package/README.md +168 -21
  2. package/dist-plugin/index.cjs +823 -336
  3. package/dist-plugin/index.d.cts +9 -7
  4. package/dist-plugin/index.d.ts +9 -7
  5. package/dist-plugin/index.js +822 -335
  6. package/package.json +46 -20
  7. package/src/assets/newspaper.webp +0 -0
  8. package/src/assets/offering.webp +0 -0
  9. package/src/component-editor/BadgeEditor.svelte +170 -0
  10. package/src/component-editor/CalloutEditor.svelte +103 -0
  11. package/src/component-editor/CardEditor.svelte +184 -0
  12. package/src/component-editor/CollapsibleSectionEditor.svelte +167 -0
  13. package/src/component-editor/CornerBadgeEditor.svelte +207 -0
  14. package/src/component-editor/DialogEditor.svelte +172 -0
  15. package/src/component-editor/ImageEditor.svelte +72 -0
  16. package/src/component-editor/InlineEditActionsEditor.svelte +83 -0
  17. package/src/component-editor/NotificationEditor.svelte +160 -0
  18. package/src/component-editor/ProgressBarEditor.svelte +124 -0
  19. package/src/component-editor/RadioButtonEditor.svelte +140 -0
  20. package/src/component-editor/SectionDividerEditor.svelte +263 -0
  21. package/src/component-editor/SegmentedControlEditor.svelte +154 -0
  22. package/src/component-editor/StandardButtonsEditor.svelte +178 -0
  23. package/src/component-editor/TabBarEditor.svelte +137 -0
  24. package/src/component-editor/TableEditor.svelte +128 -0
  25. package/src/component-editor/TooltipEditor.svelte +122 -0
  26. package/src/component-editor/editorTokens.test.ts +93 -0
  27. package/src/component-editor/groupKeySlots.test.ts +67 -0
  28. package/src/component-editor/groupKeySnapshot.test.ts +52 -0
  29. package/src/component-editor/index.ts +5 -0
  30. package/src/component-editor/registry.ts +246 -0
  31. package/src/component-editor/scaffolding/AngleDial.svelte +185 -0
  32. package/src/component-editor/scaffolding/ComponentEditorBase.svelte +96 -0
  33. package/src/component-editor/scaffolding/ComponentFileManager.svelte +682 -0
  34. package/src/component-editor/scaffolding/ComponentFileMenu.svelte +312 -0
  35. package/src/component-editor/scaffolding/ComponentsTab.svelte +69 -0
  36. package/src/component-editor/scaffolding/CopyFromMenu.svelte +246 -0
  37. package/src/component-editor/scaffolding/DemoHeader.svelte +21 -0
  38. package/src/component-editor/scaffolding/DividerEditor.svelte +81 -0
  39. package/src/component-editor/scaffolding/FieldsetWrapper.svelte +46 -0
  40. package/src/component-editor/scaffolding/GradientCard.svelte +291 -0
  41. package/src/component-editor/scaffolding/LinkageChart.svelte +297 -0
  42. package/src/component-editor/scaffolding/LinkedBlock.svelte +418 -0
  43. package/src/component-editor/scaffolding/NonStylableConfig.svelte +57 -0
  44. package/src/component-editor/scaffolding/SaveAsDialog.svelte +177 -0
  45. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +25 -0
  46. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +56 -0
  47. package/src/component-editor/scaffolding/StateBlock.svelte +115 -0
  48. package/src/component-editor/scaffolding/TokenLayout.svelte +511 -0
  49. package/src/component-editor/scaffolding/TypeEditor.svelte +82 -0
  50. package/src/component-editor/scaffolding/VariantGroup.svelte +277 -0
  51. package/src/component-editor/scaffolding/buildTypeGroupTokens.ts +97 -0
  52. package/src/component-editor/scaffolding/componentSectionType.ts +8 -0
  53. package/src/component-editor/scaffolding/componentSources.ts +9 -0
  54. package/src/component-editor/scaffolding/defaultSections.ts +16 -0
  55. package/src/component-editor/scaffolding/editorContext.ts +44 -0
  56. package/src/component-editor/scaffolding/linkedBlock.ts +226 -0
  57. package/src/component-editor/scaffolding/siblings.ts +33 -0
  58. package/src/component-editor/scaffolding/types.ts +39 -0
  59. package/src/components/Badge.svelte +231 -42
  60. package/src/components/Button.svelte +324 -124
  61. package/src/components/Callout.svelte +145 -0
  62. package/src/components/Card.svelte +123 -25
  63. package/src/components/CollapsibleSection.svelte +213 -35
  64. package/src/components/CornerBadge.svelte +224 -0
  65. package/src/components/Dialog.svelte +137 -114
  66. package/src/components/Image.svelte +43 -0
  67. package/src/components/InlineEditActions.svelte +74 -14
  68. package/src/components/Notification.svelte +184 -163
  69. package/src/components/ProgressBar.svelte +216 -22
  70. package/src/components/RadioButton.svelte +110 -40
  71. package/src/components/SectionDivider.svelte +428 -74
  72. package/src/components/SegmentedControl.svelte +203 -0
  73. package/src/components/TabBar.svelte +146 -21
  74. package/src/components/Table.svelte +102 -0
  75. package/src/components/Tooltip.svelte +45 -19
  76. package/src/components/types.ts +51 -0
  77. package/src/data/google-fonts.json +75 -0
  78. package/src/lib/ColumnsOverlay.svelte +20 -7
  79. package/src/lib/LiveEditorOverlay.svelte +257 -78
  80. package/src/lib/columnsOverlay.ts +21 -17
  81. package/src/lib/componentConfig.test.ts +204 -0
  82. package/src/lib/componentConfigKeys.ts +19 -0
  83. package/src/lib/componentConfigService.ts +88 -0
  84. package/src/lib/copyPopover.ts +30 -0
  85. package/src/lib/cssVarSync.ts +59 -7
  86. package/src/lib/editorConfigStore.ts +0 -10
  87. package/src/lib/editorCore.ts +402 -0
  88. package/src/lib/editorKeybindings.ts +52 -0
  89. package/src/lib/editorPersistence.ts +106 -0
  90. package/src/lib/editorRenderer.ts +74 -0
  91. package/src/lib/editorStore.test.ts +328 -0
  92. package/src/lib/editorStore.ts +412 -0
  93. package/src/lib/editorTypes.ts +100 -0
  94. package/src/lib/editorViewStore.ts +55 -0
  95. package/src/lib/files/versionedFileResource.ts +140 -0
  96. package/src/lib/fontLoader.ts +130 -0
  97. package/src/lib/fontMigration.ts +140 -0
  98. package/src/lib/fontParse.ts +168 -0
  99. package/src/lib/index.ts +48 -30
  100. package/src/lib/lazyConfig.test.ts +54 -0
  101. package/src/lib/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +64 -0
  102. package/src/lib/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +71 -0
  103. package/src/lib/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +43 -0
  104. package/src/lib/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +68 -0
  105. package/src/lib/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +35 -0
  106. package/src/lib/migrations/2026-05-10-sectiondivider-gradient-stops.ts +50 -0
  107. package/src/lib/migrations/2026-05-13-primary-to-brand.ts +90 -0
  108. package/src/lib/migrations/index.ts +93 -0
  109. package/src/lib/migrations/migrations.test.ts +341 -0
  110. package/src/lib/navLinkTypes.ts +1 -0
  111. package/src/lib/overlayState.ts +3 -0
  112. package/src/lib/paletteDerivation.ts +300 -0
  113. package/src/lib/parentRouteStore.ts +42 -0
  114. package/src/lib/parsers/globalRootBlock.ts +32 -0
  115. package/src/lib/presetService.ts +94 -0
  116. package/src/lib/router.ts +42 -10
  117. package/src/lib/scrollSection.ts +45 -0
  118. package/src/lib/slices/columns.ts +59 -0
  119. package/src/lib/slices/components.ts +362 -0
  120. package/src/lib/slices/domainVars.ts +15 -0
  121. package/src/lib/slices/fonts.ts +30 -0
  122. package/src/lib/slices/gradients.ts +153 -0
  123. package/src/lib/slices/overlays.ts +132 -0
  124. package/src/lib/slices/palettes.ts +26 -0
  125. package/src/lib/slices/shadows.ts +123 -0
  126. package/src/lib/storage.ts +88 -0
  127. package/src/lib/themeInit.ts +74 -0
  128. package/src/lib/themeService.ts +101 -0
  129. package/src/lib/themeTypes.ts +146 -0
  130. package/src/lib/tokenRegistry.ts +148 -0
  131. package/src/pages/ComponentEditorPage.svelte +384 -0
  132. package/src/pages/ComponentEditorPage.svelte.d.ts +2 -0
  133. package/src/pages/Editor.svelte +98 -0
  134. package/src/pages/Editor.svelte.d.ts +2 -0
  135. package/src/pages/EditorShell.svelte +348 -0
  136. package/src/styles/_padding.scss +34 -0
  137. package/src/styles/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
  138. package/src/styles/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
  139. package/src/styles/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
  140. package/src/styles/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
  141. package/src/styles/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
  142. package/src/styles/fonts/Manrope/Manrope-latin.woff2 +0 -0
  143. package/src/styles/fonts.css +22 -10
  144. package/src/styles/form-controls.css +14 -16
  145. package/src/styles/tokens.css +1322 -0
  146. package/src/styles/ui-editor.css +126 -0
  147. package/src/{showcase → ui}/BezierCurveEditor.svelte +14 -14
  148. package/src/{showcase → ui}/ColorEditPanel.svelte +42 -36
  149. package/src/ui/EditorViewSwitcher.svelte +180 -0
  150. package/src/ui/FontStackEditor.svelte +360 -0
  151. package/src/ui/GradientEditor.svelte +461 -0
  152. package/src/ui/GradientStopPicker.svelte +74 -0
  153. package/src/ui/PaletteEditor.svelte +1590 -0
  154. package/src/ui/PaletteEditor.test.ts +108 -0
  155. package/src/ui/PresetFileManager.svelte +567 -0
  156. package/src/ui/ProjectFontsSection.svelte +645 -0
  157. package/src/{showcase → ui}/SurfacesTab.svelte +39 -39
  158. package/src/{showcase → ui}/TextTab.svelte +27 -27
  159. package/src/{showcase/TokenFileManager.svelte → ui/ThemeFileManager.svelte} +196 -112
  160. package/src/ui/Toggle.svelte +108 -0
  161. package/src/ui/UICopyPopover.svelte +78 -0
  162. package/src/{showcase/EditorDialog.svelte → ui/UIDialog.svelte} +66 -25
  163. package/src/ui/UIFontFamilySelector.svelte +309 -0
  164. package/src/ui/UIFontSizeSelector.svelte +165 -0
  165. package/src/ui/UIFontWeightSelector.svelte +52 -0
  166. package/src/ui/UILineHeightSelector.svelte +47 -0
  167. package/src/ui/UILinkToggle.svelte +60 -0
  168. package/src/ui/UIOptionItem.svelte +74 -0
  169. package/src/ui/UIOptionList.svelte +27 -0
  170. package/src/ui/UIPaddingSelector.svelte +661 -0
  171. package/src/ui/UIPaletteSelector.svelte +1084 -0
  172. package/src/ui/UIRadio.svelte +72 -0
  173. package/src/ui/UIRadioGroup.svelte +59 -0
  174. package/src/ui/UIRelinkConfirmPopover.svelte +235 -0
  175. package/src/ui/UITokenSelector.svelte +509 -0
  176. package/src/ui/UIVariantSelector.svelte +145 -0
  177. package/src/ui/VariablesTab.svelte +252 -0
  178. package/src/ui/index.ts +31 -0
  179. package/src/ui/keepInViewport.ts +84 -0
  180. package/src/ui/palette/GradientStopEditor.svelte +482 -0
  181. package/src/ui/palette/OverridesPanel.svelte +526 -0
  182. package/src/ui/palette/PaletteBase.svelte +165 -0
  183. package/src/ui/palette/ScaleCurveEditor.svelte +38 -0
  184. package/src/ui/palette/paletteEditorState.ts +89 -0
  185. package/src/ui/sections/ColumnsSection.svelte +273 -0
  186. package/src/ui/sections/GradientsSection.svelte +147 -0
  187. package/src/ui/sections/OverlaysSection.svelte +670 -0
  188. package/src/ui/sections/ShadowsSection.svelte +1250 -0
  189. package/src/ui/sections/TokenScaleTable.svelte +332 -0
  190. package/src/ui/sections/tokenScales.ts +81 -0
  191. package/src/ui/variantScales.ts +108 -0
  192. package/src/components/DetailNav.svelte +0 -78
  193. package/src/components/Toggle.svelte +0 -86
  194. package/src/lib/tokenInit.ts +0 -29
  195. package/src/lib/tokenService.ts +0 -144
  196. package/src/lib/tokenTypes.ts +0 -45
  197. package/src/pages/Admin.svelte +0 -100
  198. package/src/pages/ShowcasePage.svelte +0 -144
  199. package/src/showcase/BackupBrowser.svelte +0 -617
  200. package/src/showcase/ComponentsTab.svelte +0 -105
  201. package/src/showcase/PaletteEditor.svelte +0 -2579
  202. package/src/showcase/PaletteSelector.svelte +0 -627
  203. package/src/showcase/TokenMap.svelte +0 -54
  204. package/src/showcase/VariablesTab.svelte +0 -2655
  205. package/src/showcase/VisualsTab.svelte +0 -231
  206. package/src/showcase/demos/BadgeDemo.svelte +0 -56
  207. package/src/showcase/demos/CardDemo.svelte +0 -50
  208. package/src/showcase/demos/ChoiceButtonsDemo.svelte +0 -192
  209. package/src/showcase/demos/CollapsibleSectionDemo.svelte +0 -54
  210. package/src/showcase/demos/DialogDemo.svelte +0 -42
  211. package/src/showcase/demos/InlineEditActionsDemo.svelte +0 -25
  212. package/src/showcase/demos/NotificationDemo.svelte +0 -147
  213. package/src/showcase/demos/ProgressBarDemo.svelte +0 -54
  214. package/src/showcase/demos/RadioButtonDemo.svelte +0 -56
  215. package/src/showcase/demos/SectionDividerDemo.svelte +0 -77
  216. package/src/showcase/demos/StandardButtonsDemo.svelte +0 -455
  217. package/src/showcase/demos/TabBarDemo.svelte +0 -58
  218. package/src/showcase/demos/TooltipDemo.svelte +0 -52
  219. package/src/showcase/editor.css +0 -93
  220. package/src/showcase/index.ts +0 -17
  221. package/src/styles/fonts/Domine/Domine-VariableFont_wght.ttf +0 -0
  222. package/src/styles/fonts/Domine/OFL.txt +0 -97
  223. package/src/styles/fonts/Domine/README.txt +0 -66
  224. /package/src/{showcase → ui}/curveEngine.ts +0 -0
@@ -0,0 +1,203 @@
1
+ <script lang="ts">
2
+ import { createEventDispatcher } from 'svelte';
3
+
4
+ type Segment = {
5
+ value: string;
6
+ label: string;
7
+ icon?: string;
8
+ disabled?: boolean;
9
+ };
10
+
11
+ export let segments: Segment[] = [];
12
+ export let value: string = '';
13
+ export let disabled: boolean = false;
14
+ export let forceHoverValue: string | null = null;
15
+
16
+ const dispatch = createEventDispatcher<{ change: string }>();
17
+
18
+ function select(v: string) {
19
+ value = v;
20
+ dispatch('change', v);
21
+ }
22
+ </script>
23
+
24
+ <div class="segmented-control" class:is-disabled={disabled} role="radiogroup">
25
+ {#each segments as seg, i (seg.value)}
26
+ {#if i > 0}
27
+ <span class="segment-divider" aria-hidden="true"></span>
28
+ {/if}
29
+ <button
30
+ type="button"
31
+ class="segment"
32
+ class:selected={value === seg.value}
33
+ class:force-hover={forceHoverValue === seg.value}
34
+ disabled={disabled || seg.disabled}
35
+ role="radio"
36
+ aria-checked={value === seg.value}
37
+ on:click={() => select(seg.value)}
38
+ >
39
+ {#if seg.icon}<i class={seg.icon}></i>{/if}
40
+ <span>{seg.label}</span>
41
+ </button>
42
+ {/each}
43
+ </div>
44
+
45
+ <style lang="scss">
46
+ @use '../styles/padding' as *;
47
+
48
+ :global(:root) {
49
+ /* Bar (outer wrapper) */
50
+ --segmentedcontrol-bar-surface: var(--surface-neutral-high);
51
+ --segmentedcontrol-bar-border: var(--border-neutral);
52
+ --segmentedcontrol-bar-border-width: var(--border-width-1);
53
+ --segmentedcontrol-bar-radius: var(--radius-lg);
54
+ --segmentedcontrol-bar-padding: var(--space-4);
55
+ --segmentedcontrol-bar-gap: var(--space-8);
56
+
57
+ /* Divider (line between non-selected options) */
58
+ --segmentedcontrol-divider-color: var(--border-neutral);
59
+ --segmentedcontrol-divider-thickness: var(--border-width-1);
60
+ --segmentedcontrol-divider-height: var(--space-12);
61
+
62
+ /* Option — default */
63
+ --segmentedcontrol-option-text: var(--text-primary);
64
+ --segmentedcontrol-option-text-font-family: var(--font-sans);
65
+ --segmentedcontrol-option-text-font-size: var(--font-size-md);
66
+ --segmentedcontrol-option-text-font-weight: var(--font-weight-normal);
67
+ --segmentedcontrol-option-text-line-height: var(--line-height-normal);
68
+ --segmentedcontrol-option-icon: var(--text-secondary);
69
+ --segmentedcontrol-option-icon-size: var(--icon-size-md);
70
+
71
+ /* Option — hover */
72
+ --segmentedcontrol-option-hover-surface: var(--surface-neutral-higher);
73
+ --segmentedcontrol-option-hover-text: var(--text-primary);
74
+ --segmentedcontrol-option-hover-text-font-family: var(--font-sans);
75
+ --segmentedcontrol-option-hover-text-font-size: var(--font-size-md);
76
+ --segmentedcontrol-option-hover-text-font-weight: var(--font-weight-normal);
77
+ --segmentedcontrol-option-hover-text-line-height: var(--line-height-normal);
78
+ --segmentedcontrol-option-hover-icon: var(--text-secondary);
79
+ --segmentedcontrol-option-hover-icon-size: var(--icon-size-md);
80
+
81
+ /* Selected (inner pill) — looks the same hovered or not */
82
+ --segmentedcontrol-selected-surface: var(--surface-success-high);
83
+ --segmentedcontrol-selected-text: var(--text-primary);
84
+ --segmentedcontrol-selected-text-font-family: var(--font-sans);
85
+ --segmentedcontrol-selected-text-font-size: var(--font-size-md);
86
+ --segmentedcontrol-selected-text-font-weight: var(--font-weight-semibold);
87
+ --segmentedcontrol-selected-text-line-height: var(--line-height-normal);
88
+ --segmentedcontrol-selected-icon: var(--text-secondary);
89
+ --segmentedcontrol-selected-icon-size: var(--icon-size-md);
90
+ --segmentedcontrol-selected-border: var(--border-success);
91
+ --segmentedcontrol-selected-border-width: var(--border-width-1);
92
+ --segmentedcontrol-selected-radius: var(--radius-md);
93
+
94
+ /* Disabled (whole component state — overrides both option and selected styling) */
95
+ --segmentedcontrol-disabled-surface: var(--surface-neutral-high);
96
+ --segmentedcontrol-disabled-text: var(--text-tertiary);
97
+ --segmentedcontrol-disabled-text-font-family: var(--font-sans);
98
+ --segmentedcontrol-disabled-text-font-size: var(--font-size-md);
99
+ --segmentedcontrol-disabled-text-font-weight: var(--font-weight-light);
100
+ --segmentedcontrol-disabled-text-line-height: var(--line-height-normal);
101
+ --segmentedcontrol-disabled-icon: var(--text-tertiary);
102
+ --segmentedcontrol-disabled-icon-size: var(--icon-size-md);
103
+ }
104
+
105
+ .segmented-control {
106
+ display: inline-flex;
107
+ align-items: stretch;
108
+ gap: var(--segmentedcontrol-bar-gap);
109
+ @include themed-padding(--segmentedcontrol-bar-padding);
110
+ background: var(--segmentedcontrol-bar-surface);
111
+ border: var(--segmentedcontrol-bar-border-width) solid var(--segmentedcontrol-bar-border);
112
+ border-radius: var(--segmentedcontrol-bar-radius);
113
+ }
114
+
115
+ .segment {
116
+ display: inline-flex;
117
+ align-items: center;
118
+ gap: var(--space-8);
119
+ padding: var(--space-6) var(--space-16);
120
+ background: transparent;
121
+ border: 0;
122
+ border-radius: var(--segmentedcontrol-selected-radius);
123
+ color: var(--segmentedcontrol-option-text);
124
+ font-family: var(--segmentedcontrol-option-text-font-family);
125
+ font-size: var(--segmentedcontrol-option-text-font-size);
126
+ font-weight: var(--segmentedcontrol-option-text-font-weight);
127
+ line-height: var(--segmentedcontrol-option-text-line-height);
128
+ cursor: pointer;
129
+ transition: background var(--duration-150), color var(--duration-150);
130
+ position: relative;
131
+ }
132
+
133
+ .segment i {
134
+ font-size: var(--segmentedcontrol-option-icon-size);
135
+ color: var(--segmentedcontrol-option-icon);
136
+ transition: color var(--duration-150);
137
+ }
138
+
139
+ /* Short centered divider between adjacent segments. Negative margins absorb
140
+ the surrounding flex gap so seg-to-seg distance stays var(--bar-gap). */
141
+ .segment-divider {
142
+ align-self: center;
143
+ flex-shrink: 0;
144
+ width: var(--segmentedcontrol-divider-thickness);
145
+ height: var(--segmentedcontrol-divider-height);
146
+ margin-inline: calc(
147
+ var(--segmentedcontrol-bar-gap) * -0.5 - var(--segmentedcontrol-divider-thickness) * 0.5
148
+ );
149
+ background: var(--segmentedcontrol-divider-color);
150
+ pointer-events: none;
151
+ }
152
+
153
+ .segment:hover:not(:disabled):not(.selected),
154
+ .segment.force-hover:not(:disabled):not(.selected) {
155
+ background: var(--segmentedcontrol-option-hover-surface);
156
+ color: var(--segmentedcontrol-option-hover-text);
157
+ font-family: var(--segmentedcontrol-option-hover-text-font-family);
158
+ font-size: var(--segmentedcontrol-option-hover-text-font-size);
159
+ font-weight: var(--segmentedcontrol-option-hover-text-font-weight);
160
+ line-height: var(--segmentedcontrol-option-hover-text-line-height);
161
+ }
162
+
163
+ .segment:hover:not(:disabled):not(.selected) i,
164
+ .segment.force-hover:not(:disabled):not(.selected) i {
165
+ color: var(--segmentedcontrol-option-hover-icon);
166
+ font-size: var(--segmentedcontrol-option-hover-icon-size);
167
+ }
168
+
169
+ .segment.selected {
170
+ background: var(--segmentedcontrol-selected-surface);
171
+ border: var(--segmentedcontrol-selected-border-width) solid var(--segmentedcontrol-selected-border);
172
+ border-radius: var(--segmentedcontrol-selected-radius);
173
+ color: var(--segmentedcontrol-selected-text);
174
+ font-family: var(--segmentedcontrol-selected-text-font-family);
175
+ font-size: var(--segmentedcontrol-selected-text-font-size);
176
+ font-weight: var(--segmentedcontrol-selected-text-font-weight);
177
+ line-height: var(--segmentedcontrol-selected-text-line-height);
178
+ /* Account for border so the pill doesn't shift adjacent segments */
179
+ padding: calc(var(--space-6) - var(--segmentedcontrol-selected-border-width))
180
+ calc(var(--space-16) - var(--segmentedcontrol-selected-border-width));
181
+ }
182
+
183
+ .segment.selected i {
184
+ color: var(--segmentedcontrol-selected-icon);
185
+ font-size: var(--segmentedcontrol-selected-icon-size);
186
+ }
187
+
188
+ .segment:disabled {
189
+ background: var(--segmentedcontrol-disabled-surface);
190
+ color: var(--segmentedcontrol-disabled-text);
191
+ font-family: var(--segmentedcontrol-disabled-text-font-family);
192
+ font-size: var(--segmentedcontrol-disabled-text-font-size);
193
+ font-weight: var(--segmentedcontrol-disabled-text-font-weight);
194
+ line-height: var(--segmentedcontrol-disabled-text-line-height);
195
+ opacity: 0.4;
196
+ cursor: not-allowed;
197
+ }
198
+
199
+ .segment:disabled i {
200
+ color: var(--segmentedcontrol-disabled-icon);
201
+ font-size: var(--segmentedcontrol-disabled-icon-size);
202
+ }
203
+ </style>
@@ -11,6 +11,8 @@
11
11
  export let tabs: Tab[] = [];
12
12
  export let selectedTab: string = '';
13
13
  export let iconOnly: boolean = false;
14
+ let className: string = '';
15
+ export { className as class };
14
16
 
15
17
  const dispatch = createEventDispatcher<{
16
18
  tabChange: string;
@@ -23,7 +25,7 @@
23
25
  }
24
26
  </script>
25
27
 
26
- <div class="tab-bar">
28
+ <div class="tab-bar {className}">
27
29
  {#each tabs as tab}
28
30
  <button
29
31
  class="tab"
@@ -42,43 +44,153 @@
42
44
  {/each}
43
45
  </div>
44
46
 
45
- <style>
47
+ <style lang="scss">
48
+ @use '../styles/padding' as *;
49
+
50
+ :global(:root) {
51
+ /* Bar */
52
+ --tabbar-bar-divider: var(--border-neutral-subtle);
53
+ --tabbar-bar-divider-thickness: var(--border-width-1);
54
+ --tabbar-bar-indicator-thickness: var(--border-width-2);
55
+ --tabbar-bar-top-margin: var(--space-0);
56
+ --tabbar-bar-bottom-padding: var(--space-0);
57
+ --tabbar-bar-bottom-margin: var(--space-0);
58
+ --tabbar-tab-gap: var(--space-2);
59
+
60
+ /* Default tab */
61
+ --tabbar-default-text: var(--text-tertiary);
62
+ --tabbar-default-text-font-family: var(--font-sans);
63
+ --tabbar-default-text-font-size: var(--font-size-md);
64
+ --tabbar-default-text-font-weight: var(--font-weight-light);
65
+ --tabbar-default-text-line-height: var(--line-height-normal);
66
+ --tabbar-default-icon-size: var(--icon-size-md);
67
+ --tabbar-default-padding: var(--space-8);
68
+ --tabbar-default-border: var(--color-transparent);
69
+ --tabbar-default-surface: var(--color-transparent);
70
+ --tabbar-default-tab-border-color: var(--color-transparent);
71
+ --tabbar-default-tab-border-width: var(--border-width-0);
72
+ --tabbar-default-tab-top-radius: var(--radius-none);
73
+ --tabbar-default-tab-bottom-radius: var(--radius-none);
74
+
75
+ /* Hover tab */
76
+ --tabbar-hover-text: var(--text-secondary);
77
+ --tabbar-hover-surface: var(--surface-neutral-lower);
78
+ --tabbar-hover-text-font-family: var(--font-sans);
79
+ --tabbar-hover-text-font-size: var(--font-size-md);
80
+ --tabbar-hover-text-font-weight: var(--font-weight-light);
81
+ --tabbar-hover-text-line-height: var(--line-height-normal);
82
+ --tabbar-hover-icon-size: var(--icon-size-md);
83
+ --tabbar-hover-padding: var(--space-8);
84
+ --tabbar-hover-border: var(--color-transparent);
85
+ --tabbar-hover-tab-border-color: var(--color-transparent);
86
+ --tabbar-hover-tab-border-width: var(--border-width-0);
87
+ --tabbar-hover-tab-top-radius: var(--radius-none);
88
+ --tabbar-hover-tab-bottom-radius: var(--radius-none);
89
+
90
+ /* Active tab */
91
+ --tabbar-active-text: var(--text-primary);
92
+ --tabbar-active-border: var(--color-brand-500);
93
+ --tabbar-active-surface: var(--overlay-lowest);
94
+ --tabbar-active-text-font-family: var(--font-sans);
95
+ --tabbar-active-text-font-size: var(--font-size-md);
96
+ --tabbar-active-text-font-weight: var(--font-weight-light);
97
+ --tabbar-active-text-line-height: var(--line-height-normal);
98
+ --tabbar-active-icon-size: var(--icon-size-md);
99
+ --tabbar-active-padding: var(--space-8);
100
+ --tabbar-active-tab-border-color: var(--color-transparent);
101
+ --tabbar-active-tab-border-width: var(--border-width-0);
102
+ --tabbar-active-tab-top-radius: var(--radius-none);
103
+ --tabbar-active-tab-bottom-radius: var(--radius-none);
104
+
105
+ /* Disabled tab */
106
+ --tabbar-disabled-text: var(--text-disabled);
107
+ --tabbar-disabled-text-font-family: var(--font-sans);
108
+ --tabbar-disabled-text-font-size: var(--font-size-md);
109
+ --tabbar-disabled-text-font-weight: var(--font-weight-light);
110
+ --tabbar-disabled-text-line-height: var(--line-height-normal);
111
+ --tabbar-disabled-icon-size: var(--icon-size-md);
112
+ --tabbar-disabled-padding: var(--space-8);
113
+ --tabbar-disabled-border: var(--color-transparent);
114
+ --tabbar-disabled-surface: var(--color-transparent);
115
+ --tabbar-disabled-tab-border-color: var(--color-transparent);
116
+ --tabbar-disabled-tab-border-width: var(--border-width-0);
117
+ --tabbar-disabled-tab-top-radius: var(--radius-none);
118
+ --tabbar-disabled-tab-bottom-radius: var(--radius-none);
119
+ }
120
+
46
121
  .tab-bar {
47
122
  display: flex;
48
- gap: var(--space-2);
49
- border-bottom: 1px solid var(--border-neutral-subtle);
50
- padding: 0 var(--space-8);
123
+ gap: var(--tabbar-tab-gap);
124
+ border-bottom: var(--tabbar-bar-divider-thickness) solid var(--tabbar-bar-divider);
125
+ margin-top: var(--tabbar-bar-top-margin);
126
+ padding-bottom: var(--tabbar-bar-bottom-padding);
127
+ margin-bottom: var(--tabbar-bar-bottom-margin);
51
128
  }
52
129
 
53
130
  .tab {
54
131
  display: inline-flex;
55
132
  align-items: center;
56
133
  gap: var(--space-6);
57
- padding: var(--space-8) var(--space-16);
58
- background: transparent;
59
- border: none;
60
- border-bottom: 2px solid transparent;
61
- color: var(--text-tertiary);
62
- font-size: var(--font-md);
63
- font-weight: var(--font-weight-medium);
134
+ @include themed-padding(--tabbar-default-padding, $h: 2);
135
+ background: var(--tabbar-default-surface);
136
+ border: var(--tabbar-default-tab-border-width) solid var(--tabbar-default-tab-border-color);
137
+ /* indicator accent — owns the bottom edge */
138
+ border-bottom: var(--tabbar-bar-indicator-thickness) solid var(--tabbar-default-border);
139
+ border-radius: var(--tabbar-default-tab-top-radius) var(--tabbar-default-tab-top-radius) var(--tabbar-default-tab-bottom-radius) var(--tabbar-default-tab-bottom-radius);
140
+ color: var(--tabbar-default-text);
141
+ font-family: var(--tabbar-default-text-font-family);
142
+ font-size: var(--tabbar-default-text-font-size);
143
+ font-weight: var(--tabbar-default-text-font-weight);
144
+ line-height: var(--tabbar-default-text-line-height);
64
145
  cursor: pointer;
65
- transition: all var(--transition-fast);
146
+ transition: all var(--duration-150);
66
147
  position: relative;
67
148
  }
68
149
 
69
- .tab:hover:not(:disabled):not(.active) {
70
- color: var(--text-secondary);
71
- background: var(--hover-low);
150
+ .tab:hover:not(:disabled):not(.active),
151
+ .tab-bar.force-hover .tab:not(:disabled):not(.active) {
152
+ color: var(--tabbar-hover-text);
153
+ background: var(--tabbar-hover-surface);
154
+ border-color: var(--tabbar-hover-tab-border-color);
155
+ border-width: var(--tabbar-hover-tab-border-width);
156
+ /* indicator accent owns the bottom edge */
157
+ border-bottom: var(--tabbar-bar-indicator-thickness) solid var(--tabbar-hover-border);
158
+ border-radius: var(--tabbar-hover-tab-top-radius) var(--tabbar-hover-tab-top-radius) var(--tabbar-hover-tab-bottom-radius) var(--tabbar-hover-tab-bottom-radius);
159
+ font-family: var(--tabbar-hover-text-font-family);
160
+ font-size: var(--tabbar-hover-text-font-size);
161
+ font-weight: var(--tabbar-hover-text-font-weight);
162
+ line-height: var(--tabbar-hover-text-line-height);
163
+ @include themed-padding(--tabbar-hover-padding, $h: 2);
72
164
  }
73
165
 
74
166
  .tab.active {
75
- color: var(--text-primary);
76
- border-bottom-color: var(--color-primary-500);
77
- background: linear-gradient(to bottom, transparent, var(--overlay-lowest));
167
+ color: var(--tabbar-active-text);
168
+ background: var(--tabbar-active-surface);
169
+ border-color: var(--tabbar-active-tab-border-color);
170
+ border-width: var(--tabbar-active-tab-border-width);
171
+ /* indicator accent owns the bottom edge */
172
+ border-bottom: var(--tabbar-bar-indicator-thickness) solid var(--tabbar-active-border);
173
+ border-radius: var(--tabbar-active-tab-top-radius) var(--tabbar-active-tab-top-radius) var(--tabbar-active-tab-bottom-radius) var(--tabbar-active-tab-bottom-radius);
174
+ font-family: var(--tabbar-active-text-font-family);
175
+ font-size: var(--tabbar-active-text-font-size);
176
+ font-weight: var(--tabbar-active-text-font-weight);
177
+ line-height: var(--tabbar-active-text-line-height);
178
+ @include themed-padding(--tabbar-active-padding, $h: 2);
78
179
  }
79
180
 
80
181
  .tab:disabled {
81
- opacity: var(--opacity-disabled);
182
+ color: var(--tabbar-disabled-text);
183
+ background: var(--tabbar-disabled-surface);
184
+ border-color: var(--tabbar-disabled-tab-border-color);
185
+ border-width: var(--tabbar-disabled-tab-border-width);
186
+ /* indicator accent owns the bottom edge */
187
+ border-bottom: var(--tabbar-bar-indicator-thickness) solid var(--tabbar-disabled-border);
188
+ border-radius: var(--tabbar-disabled-tab-top-radius) var(--tabbar-disabled-tab-top-radius) var(--tabbar-disabled-tab-bottom-radius) var(--tabbar-disabled-tab-bottom-radius);
189
+ font-family: var(--tabbar-disabled-text-font-family);
190
+ font-size: var(--tabbar-disabled-text-font-size);
191
+ font-weight: var(--tabbar-disabled-text-font-weight);
192
+ line-height: var(--tabbar-disabled-text-line-height);
193
+ @include themed-padding(--tabbar-disabled-padding, $h: 2);
82
194
  cursor: not-allowed;
83
195
  }
84
196
 
@@ -86,7 +198,20 @@
86
198
  padding: var(--space-8) var(--space-12);
87
199
  }
88
200
 
201
+ .tab:hover:not(:disabled):not(.active) i,
202
+ .tab-bar.force-hover .tab:not(:disabled):not(.active) i {
203
+ font-size: var(--tabbar-hover-icon-size);
204
+ }
205
+
206
+ .tab.active i {
207
+ font-size: var(--tabbar-active-icon-size);
208
+ }
209
+
210
+ .tab:disabled i {
211
+ font-size: var(--tabbar-disabled-icon-size);
212
+ }
213
+
89
214
  .tab i {
90
- font-size: var(--font-md);
215
+ font-size: var(--tabbar-default-icon-size);
91
216
  }
92
217
  </style>
@@ -0,0 +1,102 @@
1
+ <script lang="ts">
2
+ </script>
3
+
4
+ <div class="table-wrapper">
5
+ <slot />
6
+ </div>
7
+
8
+ <style lang="scss">
9
+ :global(:root) {
10
+ /* Wrapper */
11
+ --table-default-radius: var(--radius-md);
12
+ --table-default-border: var(--border-canvas-subtle);
13
+ --table-default-border-width: var(--border-width-1);
14
+ --table-default-shadow: var(--shadow-md);
15
+
16
+ /* Header */
17
+ --table-default-header-surface: var(--surface-canvas-low);
18
+ --table-default-header-text: var(--text-primary);
19
+ --table-default-header-font-family: var(--font-sans);
20
+ --table-default-header-font-size: var(--font-size-sm);
21
+ --table-default-header-font-weight: var(--font-weight-normal);
22
+ --table-default-header-line-height: var(--line-height-tight);
23
+ --table-default-header-padding: var(--space-12);
24
+ --table-default-header-border: var(--border-canvas-subtle);
25
+ --table-default-header-border-width: var(--border-width-1);
26
+
27
+ /* Cell */
28
+ --table-default-cell-text: var(--text-secondary);
29
+ --table-default-cell-font-family: var(--font-sans);
30
+ --table-default-cell-font-size: var(--font-size-sm);
31
+ --table-default-cell-font-weight: var(--font-weight-normal);
32
+ --table-default-cell-line-height: var(--line-height-normal);
33
+ --table-default-cell-padding: var(--space-8);
34
+
35
+ /* Row */
36
+ --table-default-row-divider: var(--border-canvas-faint);
37
+ --table-default-row-divider-width: var(--border-width-1);
38
+ --table-default-row-stripe-surface: var(--surface-canvas-lower);
39
+
40
+ /* Column */
41
+ --table-default-column-divider: var(--border-canvas-faint);
42
+ --table-default-column-divider-width: var(--border-width-0);
43
+ }
44
+
45
+ .table-wrapper {
46
+ overflow-x: auto;
47
+ margin: var(--space-12) 0;
48
+ -webkit-overflow-scrolling: touch;
49
+ border: var(--table-default-border-width) solid var(--table-default-border);
50
+ border-radius: var(--table-default-radius);
51
+ box-shadow: var(--table-default-shadow);
52
+ }
53
+
54
+ .table-wrapper :global(table) {
55
+ width: 100%;
56
+ border-collapse: collapse;
57
+ min-width: 400px;
58
+ margin: 0;
59
+ }
60
+
61
+ .table-wrapper :global(th) {
62
+ background: var(--table-default-header-surface);
63
+ color: var(--table-default-header-text);
64
+ font-family: var(--table-default-header-font-family);
65
+ font-size: var(--table-default-header-font-size);
66
+ font-weight: var(--table-default-header-font-weight);
67
+ line-height: var(--table-default-header-line-height);
68
+ padding: var(--table-default-header-padding);
69
+ text-align: left;
70
+ border-bottom: var(--table-default-header-border-width) solid var(--table-default-header-border);
71
+ border-right: var(--table-default-column-divider-width) solid var(--table-default-column-divider);
72
+ white-space: nowrap;
73
+ }
74
+
75
+ .table-wrapper :global(td) {
76
+ color: var(--table-default-cell-text);
77
+ font-family: var(--table-default-cell-font-family);
78
+ font-size: var(--table-default-cell-font-size);
79
+ font-weight: var(--table-default-cell-font-weight);
80
+ line-height: var(--table-default-cell-line-height);
81
+ padding:
82
+ var(--table-default-cell-padding-top, var(--table-default-cell-padding))
83
+ var(--table-default-cell-padding-right, calc(var(--table-default-cell-padding) * 1.5))
84
+ var(--table-default-cell-padding-bottom, var(--table-default-cell-padding))
85
+ var(--table-default-cell-padding-left, calc(var(--table-default-cell-padding) * 1.5));
86
+ border-bottom: var(--table-default-row-divider-width) solid var(--table-default-row-divider);
87
+ border-right: var(--table-default-column-divider-width) solid var(--table-default-column-divider);
88
+ }
89
+
90
+ .table-wrapper :global(th:last-child),
91
+ .table-wrapper :global(td:last-child) {
92
+ border-right: none;
93
+ }
94
+
95
+ .table-wrapper :global(tr:nth-child(even) td) {
96
+ background: var(--table-default-row-stripe-surface);
97
+ }
98
+
99
+ .table-wrapper :global(tr:last-child td) {
100
+ border-bottom: none;
101
+ }
102
+ </style>
@@ -1,9 +1,10 @@
1
1
  <script lang="ts">
2
2
  export let text: string = '';
3
3
  export let position: 'top' | 'bottom' = 'top';
4
+ export let open: boolean = false;
4
5
  </script>
5
6
 
6
- <div class="tooltip-wrapper">
7
+ <div class="tooltip-wrapper" class:open>
7
8
  <slot />
8
9
  {#if text}
9
10
  <div class="tooltip" class:bottom={position === 'bottom'}>
@@ -13,6 +14,20 @@
13
14
  </div>
14
15
 
15
16
  <style>
17
+ :global(:root) {
18
+ --tooltip-surface: var(--surface-neutral-highest);
19
+ --tooltip-text: var(--text-primary);
20
+ --tooltip-text-font-family: var(--font-sans);
21
+ --tooltip-text-font-size: var(--font-size-sm);
22
+ --tooltip-text-font-weight: var(--font-weight-normal);
23
+ --tooltip-text-line-height: var(--line-height-normal);
24
+ --tooltip-border: var(--border-neutral);
25
+ --tooltip-border-width: var(--border-width-0);
26
+ --tooltip-radius: var(--radius-md);
27
+ --tooltip-padding: var(--space-6);
28
+ --tooltip-shadow: var(--shadow-md);
29
+ }
30
+
16
31
  .tooltip-wrapper {
17
32
  position: relative;
18
33
  display: inline-block;
@@ -20,45 +35,56 @@
20
35
 
21
36
  .tooltip {
22
37
  position: absolute;
23
- bottom: calc(100% + 8px);
38
+ bottom: calc(100% + var(--space-8));
24
39
  left: 50%;
25
40
  transform: translateX(-50%);
26
- background: var(--surface-neutral-highest);
27
- color: var(--text-primary);
28
- padding: var(--space-6) var(--space-12);
29
- border-radius: var(--radius-md);
30
- font-size: var(--font-sm);
41
+ background: var(--tooltip-surface);
42
+ color: var(--tooltip-text);
43
+ padding: var(--tooltip-padding) calc(var(--tooltip-padding) * 2);
44
+ border: var(--tooltip-border-width) solid var(--tooltip-border);
45
+ border-radius: var(--tooltip-radius);
46
+ font-family: var(--tooltip-text-font-family);
47
+ font-size: var(--tooltip-text-font-size);
48
+ font-weight: var(--tooltip-text-font-weight);
49
+ line-height: var(--tooltip-text-line-height);
31
50
  white-space: nowrap;
32
51
  pointer-events: none;
33
52
  opacity: 0;
34
- transition: opacity var(--transition-fast);
53
+ transition: opacity var(--duration-150);
35
54
  z-index: var(--z-tooltip);
36
- box-shadow: var(--shadow-md);
55
+ box-shadow: var(--tooltip-shadow);
37
56
  }
38
57
 
39
58
  .tooltip::after {
40
59
  content: '';
41
60
  position: absolute;
42
- top: 100%;
61
+ bottom: calc(-4px - var(--tooltip-border-width) * 1px);
43
62
  left: 50%;
44
- transform: translateX(-50%);
45
- border: 5px solid transparent;
46
- border-top-color: var(--surface-neutral-highest);
63
+ width: 8px;
64
+ height: 8px;
65
+ transform: translateX(-50%) rotate(45deg);
66
+ background: var(--tooltip-surface);
67
+ border-right: var(--tooltip-border-width) solid var(--tooltip-border);
68
+ border-bottom: var(--tooltip-border-width) solid var(--tooltip-border);
69
+ z-index: -1;
47
70
  }
48
71
 
49
72
  .tooltip.bottom {
50
73
  bottom: auto;
51
- top: calc(100% + 8px);
74
+ top: calc(100% + var(--space-8));
52
75
  }
53
76
 
54
77
  .tooltip.bottom::after {
55
- top: auto;
56
- bottom: 100%;
57
- border-top-color: transparent;
58
- border-bottom-color: var(--surface-neutral-highest);
78
+ bottom: auto;
79
+ top: calc(-4px - var(--tooltip-border-width) * 1px);
80
+ border-right: none;
81
+ border-bottom: none;
82
+ border-left: var(--tooltip-border-width) solid var(--tooltip-border);
83
+ border-top: var(--tooltip-border-width) solid var(--tooltip-border);
59
84
  }
60
85
 
61
- .tooltip-wrapper:hover .tooltip {
86
+ .tooltip-wrapper:hover .tooltip,
87
+ .tooltip-wrapper.open .tooltip {
62
88
  opacity: 1;
63
89
  }
64
90
  </style>
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Shared component-API types.
3
+ *
4
+ * These shapes back the public props of multi-action components (Notification,
5
+ * Dialog) so that the prop list stays small as positions are added.
6
+ */
7
+
8
+ export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning';
9
+
10
+ /**
11
+ * A clickable action surfaced inside a component's chrome.
12
+ * Position-specific defaults (e.g. footer-right defaulting to 'primary')
13
+ * live in the consuming component's render block, not on this type.
14
+ */
15
+ export interface ActionSpec {
16
+ /** Visible text. Optional when an icon-only rendering is desired. */
17
+ label?: string;
18
+ /** Font Awesome icon class (e.g. 'fas fa-check'). */
19
+ icon?: string;
20
+ /** Click handler. The component does not dispatch — caller wires the handler directly. */
21
+ onClick: () => void;
22
+ /** Visual style. Position-default applies when omitted. */
23
+ variant?: ButtonVariant;
24
+ /** Render disabled-but-visible. */
25
+ disabled?: boolean;
26
+ }
27
+
28
+ /**
29
+ * Notification's four action positions. Each is independent; any subset may be present.
30
+ * - `header`: top-right pill inside the header row
31
+ * - `inline`: beside the message text on a single row (replaces the description block)
32
+ * - `left` / `right`: footer body-row buttons
33
+ */
34
+ export interface NotificationActions {
35
+ header?: ActionSpec;
36
+ inline?: ActionSpec;
37
+ left?: ActionSpec;
38
+ right?: ActionSpec;
39
+ }
40
+
41
+ /**
42
+ * Dialog footer button spec. Confirm and cancel are symmetric; either may be undefined to hide.
43
+ * `--dialog-confirm-variant` / `--dialog-cancel-variant` config still drives the visual variant
44
+ * when `variant` is unset.
45
+ */
46
+ export interface DialogButtonSpec {
47
+ label: string;
48
+ variant?: ButtonVariant;
49
+ disabled?: boolean;
50
+ onClick: () => void;
51
+ }