@motion-proto/live-tokens 0.6.2 → 0.8.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 (232) hide show
  1. package/README.md +14 -13
  2. package/dist-plugin/index.cjs +854 -226
  3. package/dist-plugin/index.d.cts +2 -1
  4. package/dist-plugin/index.d.ts +2 -1
  5. package/dist-plugin/index.js +852 -225
  6. package/package.json +26 -40
  7. package/src/{styles → app}/site.css +1 -1
  8. package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
  9. package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
  10. package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
  11. package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +37 -30
  12. package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
  13. package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
  14. package/src/editor/component-editor/ImageEditor.svelte +30 -0
  15. package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
  16. package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
  17. package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +67 -38
  18. package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
  19. package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
  20. package/src/editor/component-editor/SectionDividerEditor.svelte +565 -0
  21. package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
  22. package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +29 -21
  23. package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
  24. package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
  25. package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
  26. package/src/editor/component-editor/editors.d.ts +10 -0
  27. package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
  28. package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +54 -15
  29. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
  30. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +151 -424
  31. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
  32. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
  33. package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
  34. package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
  35. package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
  36. package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -12
  37. package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
  38. package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
  39. package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
  40. package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +85 -0
  41. package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
  42. package/src/editor/component-editor/scaffolding/StateBlock.svelte +345 -0
  43. package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +17 -12
  44. package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +13 -1
  45. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +858 -0
  46. package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +1 -0
  47. package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
  48. package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
  49. package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +25 -0
  50. package/src/{lib → editor/core/components}/componentConfigKeys.ts +8 -0
  51. package/src/{lib → editor/core/components}/componentConfigService.ts +3 -3
  52. package/src/{lib → editor/core/components}/componentPersist.ts +11 -9
  53. package/src/editor/core/flashStatus.ts +30 -0
  54. package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
  55. package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
  56. package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
  57. package/src/editor/core/manifests/manifestService.ts +171 -0
  58. package/src/editor/core/palettes/familySwap.ts +99 -0
  59. package/src/{lib → editor/core/palettes}/paletteDerivation.ts +71 -2
  60. package/src/{lib → editor/core/palettes}/tokenRegistry.ts +9 -6
  61. package/src/editor/core/productionPulse.ts +37 -0
  62. package/src/{lib → editor/core/routing}/router.ts +1 -1
  63. package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
  64. package/src/{lib → editor/core/store}/editorCore.ts +24 -8
  65. package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
  66. package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
  67. package/src/{lib → editor/core/store}/editorStore.ts +222 -28
  68. package/src/{lib → editor/core/store}/editorTypes.ts +56 -13
  69. package/src/editor/core/store/gradientSource.ts +192 -0
  70. package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
  71. package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
  72. package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
  73. package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
  74. package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
  75. package/src/{lib → editor/core/themes}/migrations/index.ts +10 -0
  76. package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
  77. package/src/{lib → editor/core/themes}/slices/components.ts +20 -6
  78. package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
  79. package/src/{lib → editor/core/themes}/slices/gradients.ts +89 -14
  80. package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
  81. package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
  82. package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
  83. package/src/{lib → editor/core/themes}/themeInit.ts +8 -8
  84. package/src/{lib → editor/core/themes}/themeService.ts +6 -6
  85. package/src/{lib → editor/core/themes}/themeTypes.ts +67 -8
  86. package/src/editor/index.ts +69 -0
  87. package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -1
  88. package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +80 -129
  89. package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
  90. package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
  91. package/src/{pages → editor/pages}/Editor.svelte +4 -4
  92. package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
  93. package/src/{styles → editor/styles}/ui-editor.css +43 -22
  94. package/src/{styles → editor/styles}/ui-form-controls.css +23 -24
  95. package/src/{ui → editor/ui}/BezierCurveEditor.svelte +119 -68
  96. package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
  97. package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +7 -6
  98. package/src/editor/ui/FileLoadList.svelte +367 -0
  99. package/src/editor/ui/FilePill.svelte +80 -0
  100. package/src/editor/ui/FontStackEditor.svelte +499 -0
  101. package/src/editor/ui/GradientEditor.svelte +690 -0
  102. package/src/{ui → editor/ui}/GradientStopPicker.svelte +12 -4
  103. package/src/editor/ui/ManifestFileManager.svelte +438 -0
  104. package/src/{ui → editor/ui}/PaletteEditor.svelte +180 -673
  105. package/src/editor/ui/ProjectFontsSection.svelte +638 -0
  106. package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
  107. package/src/{ui → editor/ui}/TextTab.svelte +3 -3
  108. package/src/editor/ui/ThemeFileManager.svelte +783 -0
  109. package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
  110. package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -7
  111. package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +4 -1
  112. package/src/editor/ui/UIInfoPopover.svelte +243 -0
  113. package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
  114. package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
  115. package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
  116. package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
  117. package/src/{ui → editor/ui}/UIPaletteSelector.svelte +57 -30
  118. package/src/editor/ui/UIPillButton.svelte +168 -0
  119. package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
  120. package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
  121. package/src/editor/ui/UISegmentedControl.svelte +114 -0
  122. package/src/editor/ui/UISquareButton.svelte +172 -0
  123. package/src/{ui → editor/ui}/UITokenSelector.svelte +14 -11
  124. package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
  125. package/src/{ui → editor/ui}/VariablesTab.svelte +46 -17
  126. package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
  127. package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +24 -47
  128. package/src/{ui → editor/ui}/palette/PaletteBase.svelte +11 -8
  129. package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
  130. package/src/editor/ui/palette/paletteMath.ts +275 -0
  131. package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -18
  132. package/src/{ui → editor/ui}/sections/GradientsSection.svelte +8 -8
  133. package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +18 -18
  134. package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +23 -23
  135. package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
  136. package/src/{components → system/components}/Badge.svelte +0 -36
  137. package/src/{components → system/components}/Button.svelte +2 -2
  138. package/src/{components → system/components}/Card.svelte +34 -60
  139. package/src/{components → system/components}/CollapsibleSection.svelte +25 -2
  140. package/src/{components → system/components}/CornerBadge.svelte +8 -24
  141. package/src/{components → system/components}/Dialog.svelte +1 -1
  142. package/src/system/components/FloatingTokenTags.css +275 -0
  143. package/src/system/components/FloatingTokenTags.svelte +543 -0
  144. package/src/{components → system/components}/InlineEditActions.svelte +6 -4
  145. package/src/system/components/MenuSelect.svelte +229 -0
  146. package/src/{components → system/components}/Notification.svelte +8 -1
  147. package/src/{components → system/components}/ProgressBar.svelte +29 -11
  148. package/src/system/components/SectionDivider.svelte +560 -0
  149. package/src/{components → system/components}/SegmentedControl.svelte +49 -43
  150. package/src/{components → system/components}/TabBar.svelte +81 -65
  151. package/src/{components → system/components}/Table.svelte +17 -3
  152. package/src/{components → system/components}/Tooltip.svelte +6 -4
  153. package/src/system/styles/CONVENTIONS.md +178 -0
  154. package/src/system/styles/fonts.css +20 -0
  155. package/src/system/styles/tokens.css +601 -0
  156. package/src/system/styles/tokens.generated.css +544 -0
  157. package/src/component-editor/ImageEditor.svelte +0 -74
  158. package/src/component-editor/SectionDividerEditor.svelte +0 -265
  159. package/src/component-editor/scaffolding/DividerEditor.svelte +0 -94
  160. package/src/component-editor/scaffolding/GradientCard.svelte +0 -296
  161. package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
  162. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
  163. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
  164. package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
  165. package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
  166. package/src/components/SectionDivider.svelte +0 -483
  167. package/src/data/google-fonts.json +0 -75
  168. package/src/lib/index.ts +0 -68
  169. package/src/lib/presetService.ts +0 -214
  170. package/src/lib/productionPulse.ts +0 -32
  171. package/src/styles/fonts.css +0 -30
  172. package/src/styles/tokens.css +0 -1324
  173. package/src/ui/FontStackEditor.svelte +0 -361
  174. package/src/ui/GradientEditor.svelte +0 -470
  175. package/src/ui/PresetFileManager.svelte +0 -1116
  176. package/src/ui/ProjectFontsSection.svelte +0 -645
  177. package/src/ui/ThemeFileManager.svelte +0 -1020
  178. package/src/ui/UnsavedComponentsDialog.svelte +0 -315
  179. /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
  180. /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
  181. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
  182. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
  183. /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
  184. /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
  185. /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
  186. /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
  187. /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
  188. /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
  189. /package/src/{lib → editor/core/storage}/storage.ts +0 -0
  190. /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
  191. /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
  192. /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
  193. /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
  194. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
  195. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
  196. /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
  197. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
  198. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
  199. /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
  200. /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
  201. /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
  202. /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
  203. /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
  204. /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
  205. /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
  206. /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
  207. /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
  208. /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
  209. /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
  210. /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
  211. /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
  212. /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
  213. /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
  214. /package/src/{ui → editor/ui}/index.ts +0 -0
  215. /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
  216. /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
  217. /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
  218. /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
  219. /package/src/{ui → editor/ui}/variantScales.ts +0 -0
  220. /package/src/{assets → system/assets}/newspaper.webp +0 -0
  221. /package/src/{assets → system/assets}/offering.webp +0 -0
  222. /package/src/{components → system/components}/Callout.svelte +0 -0
  223. /package/src/{components → system/components}/Image.svelte +0 -0
  224. /package/src/{components → system/components}/RadioButton.svelte +0 -0
  225. /package/src/{components → system/components}/types.ts +0 -0
  226. /package/src/{styles → system/styles}/_padding.scss +0 -0
  227. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
  228. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
  229. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
  230. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
  231. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
  232. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
@@ -1,265 +0,0 @@
1
- <script module lang="ts">
2
- import { buildSiblings } from './scaffolding/siblings';
3
- import type { Token, TypeGroupConfig } from './scaffolding/types';
4
-
5
- export const component = 'sectiondivider';
6
-
7
- type Variant = 'canvas' | 'neutral' | 'alternate' | 'primary' | 'accent' | 'special';
8
- const variants: { key: Variant; title: string }[] = [
9
- { key: 'primary', title: 'Primary' },
10
- { key: 'accent', title: 'Accent' },
11
- { key: 'neutral', title: 'Neutral' },
12
- { key: 'special', title: 'Special' },
13
- { key: 'canvas', title: 'Canvas' },
14
- { key: 'alternate', title: 'Alternate' },
15
- ];
16
-
17
- /** Frame tokens for a variant. Gradient tokens are owned by GradientCard, and
18
- * outline thickness/color are rendered nested under the title TypeEditor;
19
- * both are emitted only for `allTokens` (reset/registry) — not for the
20
- * per-state token grid. */
21
- function frameTokens(v: Variant): Token[] {
22
- return [
23
- { label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `--sectiondivider-${v}-padding` },
24
- { label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: `--sectiondivider-${v}-radius` },
25
- { label: 'border color', canBeLinked: true, groupKey: 'border', variable: `--sectiondivider-${v}-border` },
26
- { label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: `--sectiondivider-${v}-border-width` },
27
- { label: 'drop shadow', canBeLinked: true, groupKey: 'shadow', variable: `--sectiondivider-${v}-shadow` },
28
- ];
29
- }
30
- /** Title outline tokens — rendered inside the title TypeEditor (not the
31
- * property grid) but registered here so reset/linkage still see them. */
32
- function titleOutlineTokens(v: Variant): Token[] {
33
- return [
34
- { label: 'outline thickness', canBeLinked: true, groupKey: 'title-border-width', variable: `--sectiondivider-${v}-title-border-width` },
35
- { label: 'outline color', canBeLinked: true, groupKey: 'title-stroke-color', variable: `--sectiondivider-${v}-title-stroke-color` },
36
- ];
37
- }
38
- function gradientTokens(v: Variant): Token[] {
39
- return [
40
- { label: 'gradient angle', groupKey: 'angle', variable: `--sectiondivider-${v}-gradient-angle` },
41
- { label: 'gradient stop 1 color', groupKey: 'color', variable: `--sectiondivider-${v}-gradient-stop-1-color` },
42
- { label: 'gradient stop 1 position', groupKey: 'position', variable: `--sectiondivider-${v}-gradient-stop-1-position` },
43
- { label: 'gradient stop 2 color', groupKey: 'color', variable: `--sectiondivider-${v}-gradient-stop-2-color` },
44
- { label: 'gradient stop 2 position', groupKey: 'position', variable: `--sectiondivider-${v}-gradient-stop-2-position` },
45
- { label: 'gradient stop 3 color', groupKey: 'color', variable: `--sectiondivider-${v}-gradient-stop-3-color` },
46
- { label: 'gradient stop 3 position', groupKey: 'position', variable: `--sectiondivider-${v}-gradient-stop-3-position` },
47
- ];
48
- }
49
- function variantTokens(v: Variant): Token[] {
50
- return [...frameTokens(v), ...titleOutlineTokens(v), ...gradientTokens(v)];
51
- }
52
-
53
- /** Two type groups per variant: title and description. The TypeEditor
54
- * fieldset visually groups each color with its font-shape props. The
55
- * title fieldset also nests the SVG-text outline width + color so those
56
- * controls sit with the typography that drives them. */
57
- function variantTypeGroups(v: Variant): TypeGroupConfig[] {
58
- return [
59
- {
60
- legend: 'title',
61
- colorVariable: `--sectiondivider-${v}-title`,
62
- familyVariable: `--sectiondivider-${v}-title-font-family`,
63
- sizeVariable: `--sectiondivider-${v}-title-font-size`,
64
- weightVariable: `--sectiondivider-${v}-title-font-weight`,
65
- lineHeightVariable: `--sectiondivider-${v}-title-line-height`,
66
- outlineWidthVariable: `--sectiondivider-${v}-title-border-width`,
67
- outlineColorVariable: `--sectiondivider-${v}-title-stroke-color`,
68
- },
69
- {
70
- legend: 'description',
71
- colorVariable: `--sectiondivider-${v}-description`,
72
- familyVariable: `--sectiondivider-${v}-description-font-family`,
73
- sizeVariable: `--sectiondivider-${v}-description-font-size`,
74
- weightVariable: `--sectiondivider-${v}-description-font-weight`,
75
- lineHeightVariable: `--sectiondivider-${v}-description-line-height`,
76
- },
77
- ];
78
- }
79
-
80
- /** Token registry entries for the type-group properties. Colors are emitted
81
- * with canBeLinked so the LinkedBlock keeps the cross-variant linkage they
82
- * ship with (title/description colors share the same theme defaults across
83
- * every variant). */
84
- function variantTypeGroupTokens(v: Variant): Token[] {
85
- return [
86
- { label: 'title color', canBeLinked: true, groupKey: 'title-color', variable: `--sectiondivider-${v}-title` },
87
- { label: 'title font family', canBeLinked: true, groupKey: 'title-font-family', variable: `--sectiondivider-${v}-title-font-family` },
88
- { label: 'title font size', canBeLinked: true, groupKey: 'title-font-size', variable: `--sectiondivider-${v}-title-font-size` },
89
- { label: 'title font weight', canBeLinked: true, groupKey: 'title-font-weight', variable: `--sectiondivider-${v}-title-font-weight` },
90
- { label: 'title line height', canBeLinked: true, groupKey: 'title-line-height', variable: `--sectiondivider-${v}-title-line-height` },
91
- { label: 'description color', canBeLinked: true, groupKey: 'description-color', variable: `--sectiondivider-${v}-description` },
92
- { label: 'description font family', canBeLinked: true, groupKey: 'description-font-family', variable: `--sectiondivider-${v}-description-font-family` },
93
- { label: 'description font size', canBeLinked: true, groupKey: 'description-font-size', variable: `--sectiondivider-${v}-description-font-size` },
94
- { label: 'description font weight', canBeLinked: true, groupKey: 'description-font-weight', variable: `--sectiondivider-${v}-description-font-weight` },
95
- { label: 'description line height', canBeLinked: true, groupKey: 'description-line-height', variable: `--sectiondivider-${v}-description-line-height` },
96
- ];
97
- }
98
-
99
- export const allTokens: Token[] = variants.flatMap((v) => [
100
- ...variantTokens(v.key),
101
- ...variantTypeGroupTokens(v.key),
102
- ]);
103
-
104
- // Linked block contexts: every linkable token registers under its variant name.
105
- // Gradient stops are intentionally absent — they're variant-defining and never link.
106
- const LINKED_GROUP_KEYS = [
107
- 'padding', 'radius',
108
- 'border', 'border-width', 'shadow',
109
- 'title-border-width', 'title-stroke-color',
110
- 'title-color', 'title-font-family', 'title-font-size', 'title-font-weight', 'title-line-height',
111
- 'description-color', 'description-font-family', 'description-font-size', 'description-font-weight', 'description-line-height',
112
- ] as const;
113
- const linkableContexts = new Map<string, string>(
114
- variants.flatMap((v) =>
115
- [...variantTokens(v.key), ...variantTypeGroupTokens(v.key)]
116
- .filter((t) => t.groupKey && (LINKED_GROUP_KEYS as readonly string[]).includes(t.groupKey))
117
- .map((t) => [t.variable, v.key] as const),
118
- ),
119
- );
120
-
121
- const variantOptions = variants.map((v) => ({ value: v.key, label: v.title }));
122
- </script>
123
-
124
- <script lang="ts">
125
- import { onMount } from 'svelte';
126
- import SectionDivider from '../components/SectionDivider.svelte';
127
- import VariantGroup from './scaffolding/VariantGroup.svelte';
128
- import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
129
- import GradientCard from './scaffolding/GradientCard.svelte';
130
- import ShadowBackdrop from './scaffolding/ShadowBackdrop.svelte';
131
- import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
132
- import { editorState } from '../lib/editorStore';
133
- import { setCssVar } from '../lib/cssVarSync';
134
- import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
135
-
136
- let testTitle = $state('Section Title');
137
- let showDescription = $state(true);
138
- let descriptionText = $state('This text is meant to provide additional context or meaning.');
139
-
140
- const bgVar = '--backdrop-sectiondivider-surface';
141
-
142
- onMount(() => {
143
- if (!document.documentElement.style.getPropertyValue(bgVar)) {
144
- setCssVar(bgVar, 'var(--surface-canvas)');
145
- }
146
- });
147
-
148
- let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
149
- // The gradient tokens are owned by GradientCard, so the property grid only
150
- // shows the frame tokens (padding/radius/outline). Gradient tokens still
151
- // live in `allTokens` so they participate in reset and the registry.
152
- let visibleVariantTokens = $derived((v: Variant) => withLinkedDisabled(frameTokens(v), linked.varSet));
153
- </script>
154
-
155
- <ComponentEditorBase {component} title="Section Divider" description="Full-width section banner with display font and palette variants. Import from <code>components/SectionDivider.svelte</code>" tokens={allTokens} {linked} variants={variantOptions}>
156
- {#snippet config()}
157
-
158
- <label class="text-field">
159
- <span>Test title</span>
160
- <input type="text" bind:value={testTitle} placeholder="Section Title" />
161
- </label>
162
- <label class="checkbox-field">
163
- <input type="checkbox" bind:checked={showDescription} />
164
- <span>Show description</span>
165
- </label>
166
- <label class="text-field text-field-wide">
167
- <span>Description text</span>
168
- <input type="text" bind:value={descriptionText} placeholder="Description text" />
169
- </label>
170
- <label class="backdrop-config">
171
- <span>Sample background</span>
172
- <div class="picker-slot">
173
- <UIPaletteSelector variable={bgVar} />
174
- </div>
175
- </label>
176
-
177
- {/snippet}
178
- {#each variants as v}
179
- <VariantGroup
180
- name={v.key}
181
- title={v.title}
182
- states={{ [v.key]: visibleVariantTokens(v.key) }}
183
- typeGroups={{ [v.key]: variantTypeGroups(v.key) }}
184
- {component}
185
- siblings={buildSiblings(
186
- variants.map((x) => x.key),
187
- v.key,
188
- (sv) => ({ [sv]: variantTokens(sv) }),
189
- (sv) => ({ [sv]: variantTypeGroups(sv) }),
190
- )}
191
- >
192
- <ShadowBackdrop mode="color" colorVariable={bgVar} padding="32px">
193
- <SectionDivider
194
- title={testTitle || v.title}
195
- variant={v.key}
196
- description={showDescription ? descriptionText : undefined}
197
- />
198
- </ShadowBackdrop>
199
- {#snippet compositeControls(_stateName)}
200
- <span class="gradient-section-label">Gradient</span>
201
- <GradientCard {component} prefix={`--sectiondivider-${v.key}`} />
202
- {/snippet}
203
- </VariantGroup>
204
- {/each}
205
- </ComponentEditorBase>
206
-
207
- <style>
208
- .text-field,
209
- .checkbox-field {
210
- display: inline-flex;
211
- align-items: center;
212
- gap: var(--ui-space-8);
213
- font-size: var(--ui-font-size-xs);
214
- color: var(--ui-text-secondary);
215
- }
216
-
217
- .checkbox-field {
218
- cursor: pointer;
219
- user-select: none;
220
- }
221
-
222
- .checkbox-field input {
223
- margin: 0;
224
- cursor: pointer;
225
- }
226
-
227
- .text-field input {
228
- padding: var(--ui-space-4) var(--ui-space-8);
229
- background: var(--ui-surface-input);
230
- color: var(--ui-text-primary);
231
- border: 1px solid var(--ui-border-subtle);
232
- border-radius: var(--ui-radius-sm);
233
- font-family: var(--ui-font-mono);
234
- font-size: var(--ui-font-size-xs);
235
- min-width: 16rem;
236
- }
237
-
238
- .text-field-wide input {
239
- min-width: 28rem;
240
- }
241
-
242
- .backdrop-config {
243
- display: inline-flex;
244
- align-items: center;
245
- gap: var(--ui-space-8);
246
- font-size: var(--ui-font-size-xs);
247
- color: var(--ui-text-secondary);
248
- }
249
-
250
- .picker-slot {
251
- min-width: 8rem;
252
- }
253
-
254
- .picker-slot :global(.ui-token-selector) {
255
- width: 100%;
256
- }
257
-
258
- .gradient-section-label {
259
- display: block;
260
- margin-top: var(--ui-space-8);
261
- font-size: var(--ui-font-size-md);
262
- font-weight: 500;
263
- color: var(--ui-text-primary);
264
- }
265
- </style>
@@ -1,94 +0,0 @@
1
- <script lang="ts">
2
- import { onMount, onDestroy } from 'svelte';
3
- import { CSS_VAR_CHANGE_EVENT } from '../../lib/cssVarSync';
4
- import UIPaletteSelector from '../../ui/UIPaletteSelector.svelte';
5
- import UIVariantSelector from '../../ui/UIVariantSelector.svelte';
6
- import { BORDER_WIDTH, DIVIDER_HEIGHT } from '../../ui/variantScales';
7
- import FieldsetWrapper from './FieldsetWrapper.svelte';
8
-
9
-
10
- interface Props {
11
- colorVariable?: string | undefined;
12
- colorLabel?: string | undefined;
13
- widthVariable?: string | undefined;
14
- widthLabel?: string | undefined;
15
- heightVariable?: string | undefined;
16
- heightLabel?: string | undefined;
17
- /** When set, writes persist through the editor store under this component. */
18
- component?: string | undefined;
19
- }
20
-
21
- let {
22
- colorVariable = undefined,
23
- colorLabel = undefined,
24
- widthVariable = undefined,
25
- widthLabel = undefined,
26
- heightVariable = undefined,
27
- heightLabel = undefined,
28
- component = undefined
29
- }: Props = $props();
30
-
31
- let heightResolved = $state('');
32
-
33
- function readHeight() {
34
- if (!heightVariable) {
35
- heightResolved = '';
36
- return;
37
- }
38
- heightResolved = getComputedStyle(document.documentElement)
39
- .getPropertyValue(heightVariable)
40
- .trim();
41
- }
42
-
43
- function handleVarChange(e: Event) {
44
- const detail = (e as CustomEvent<{ name: string }>).detail;
45
- if (detail?.name === heightVariable) readHeight();
46
- }
47
-
48
- onMount(() => {
49
- readHeight();
50
- document.addEventListener(CSS_VAR_CHANGE_EVENT, handleVarChange);
51
- });
52
-
53
- onDestroy(() => {
54
- document.removeEventListener(CSS_VAR_CHANGE_EVENT, handleVarChange);
55
- });
56
-
57
- let heightIsZero = $derived(/^0+(?:\.0+)?(px|rem|em|%)?$/.test(heightResolved));
58
- let siblingDisabled = $derived(heightIsZero);
59
- </script>
60
-
61
- <FieldsetWrapper legend="divider">
62
- {#if colorVariable}
63
- <div class="entry">
64
- <UIPaletteSelector variable={colorVariable} {component} disabled={siblingDisabled} onchange={readHeight} />
65
- <span class="label">{colorLabel ?? ''}</span>
66
- </div>
67
- {/if}
68
- {#if widthVariable}
69
- <div class="entry">
70
- <UIVariantSelector variable={widthVariable} {component} disabled={siblingDisabled} {...BORDER_WIDTH} onchange={readHeight} />
71
- <span class="label">{widthLabel ?? ''}</span>
72
- </div>
73
- {/if}
74
- {#if heightVariable}
75
- <div class="entry">
76
- <UIVariantSelector variable={heightVariable} {component} {...DIVIDER_HEIGHT} onchange={readHeight} />
77
- <span class="label">{heightLabel ?? ''}</span>
78
- </div>
79
- {/if}
80
- </FieldsetWrapper>
81
-
82
- <style>
83
- .entry {
84
- display: flex;
85
- flex-direction: column;
86
- gap: var(--ui-space-2);
87
- }
88
-
89
- .label {
90
- font-size: var(--ui-font-size-sm);
91
- color: var(--ui-text-secondary);
92
- padding-left: var(--ui-space-2);
93
- }
94
- </style>
@@ -1,296 +0,0 @@
1
- <script lang="ts">
2
- /**
3
- * Composite editor for a 3-stop linear gradient defined as flat per-variant
4
- * tokens (angle + 3× color + 3× position). Renders:
5
- * - a live gradient ribbon with diamond handles below each stop's position
6
- * - a UIPaletteSelector for the currently-selected stop's color
7
- * - an AngleDial bound to the angle token
8
- *
9
- * The component writes literals (`Ndeg`, `N%`) back through `setComponentAlias`
10
- * when the user drags; the picker writes its own token/literal ref via
11
- * UIPaletteSelector. Reads resolve through `tokenRegistry$` so values
12
- * authored as `var(--gradient-angle-diagonal)` show their resolved degrees.
13
- */
14
- import { setComponentAlias } from '../../lib/editorStore';
15
- import { tokenRegistry$ } from '../../lib/tokenRegistry';
16
- import UIPaletteSelector from '../../ui/UIPaletteSelector.svelte';
17
- import AngleDial from './AngleDial.svelte';
18
-
19
-
20
- interface Props {
21
- component: string;
22
- /** Prefix shared by all 7 token names — e.g. `--sectiondivider-canvas`. */
23
- prefix: string;
24
- }
25
-
26
- let { component, prefix }: Props = $props();
27
-
28
- type StopIndex = 1 | 2 | 3;
29
- const STOPS: readonly StopIndex[] = [1, 2, 3] as const;
30
-
31
- let angleVar = $derived(`${prefix}-gradient-angle`);
32
- function stopColorVar(i: StopIndex): string {
33
- return `${prefix}-gradient-stop-${i}-color`;
34
- }
35
- function stopPositionVar(i: StopIndex): string {
36
- return `${prefix}-gradient-stop-${i}-position`;
37
- }
38
-
39
- type Registry = typeof $tokenRegistry$;
40
-
41
- /** Walk the alias chain and read the terminal declared value as a literal.
42
- * The registry is passed in explicitly so the reactive expressions below
43
- * can see `$tokenRegistry$` as a dependency (Svelte's static analysis can't
44
- * peek into function bodies). */
45
- function resolveLiteralWith(reg: Registry, varName: string): string | null {
46
- const chain = reg.resolveAliasChain(varName);
47
- const terminal = chain[chain.length - 1];
48
- const decl = reg.getDeclaredValue(terminal);
49
- if (decl === null) return null;
50
- const m = decl.match(/^var\((--[a-z0-9-]+)\)$/i);
51
- return m ? reg.getDeclaredValue(m[1]) ?? null : decl.trim();
52
- }
53
-
54
- function parseNumberFromCss(raw: string | null, unit: 'deg' | '%'): number | null {
55
- if (!raw) return null;
56
- const m = raw.trim().match(new RegExp(`^(-?\\d+(?:\\.\\d+)?)\\s*${unit}$`));
57
- return m ? parseFloat(m[1]) : null;
58
- }
59
-
60
- let angleDeg = $derived(parseNumberFromCss(resolveLiteralWith($tokenRegistry$, angleVar), 'deg') ?? 135);
61
- let positions = $derived([
62
- parseNumberFromCss(resolveLiteralWith($tokenRegistry$, stopPositionVar(1)), '%') ?? 0,
63
- parseNumberFromCss(resolveLiteralWith($tokenRegistry$, stopPositionVar(2)), '%') ?? 50,
64
- parseNumberFromCss(resolveLiteralWith($tokenRegistry$, stopPositionVar(3)), '%') ?? 100,
65
- ] as [number, number, number]);
66
-
67
- // Reference the per-stop CSS var directly so the cascade fills in the
68
- // component's CSS defaults when the user hasn't overridden a stop. Reading
69
- // `aliases[...]` alone would miss defaults (no override → `#888`) even
70
- // though the component is rendering the color via its own `:root` block.
71
- let stopColors = $derived(([1, 2, 3] as StopIndex[]).map((i) => `var(${stopColorVar(i)})`) as [string, string, string]);
72
-
73
- // Build the live gradient string from current positions + colors so the
74
- // ribbon reflects edits even mid-drag (before the component re-renders via
75
- // its own CSS var consumption).
76
- let ribbonBg = $derived(`linear-gradient(90deg, ${stopColors
77
- .map((c, i) => `${c} ${positions[i]}%`)
78
- .join(', ')})`);
79
-
80
- let selected: StopIndex = $state(1);
81
-
82
- function setAngle(deg: number) {
83
- setComponentAlias(component, angleVar, { kind: 'literal', value: `${Math.round(deg)}deg` });
84
- }
85
-
86
- function setPosition(i: StopIndex, pct: number) {
87
- const clamped = Math.max(0, Math.min(100, Math.round(pct * 10) / 10));
88
- setComponentAlias(component, stopPositionVar(i), { kind: 'literal', value: `${clamped}%` });
89
- }
90
-
91
- // ── Position handle drag ────────────────────────────────────────────────
92
- let barEl: HTMLDivElement | undefined = $state();
93
- let dragIndex: StopIndex | null = $state(null);
94
-
95
- function pctFromEvent(e: PointerEvent): number {
96
- const rect = barEl!.getBoundingClientRect();
97
- const x = e.clientX - rect.left;
98
- return (x / rect.width) * 100;
99
- }
100
-
101
- function onHandleDown(e: PointerEvent, i: StopIndex) {
102
- selected = i;
103
- dragIndex = i;
104
- (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
105
- setPosition(i, pctFromEvent(e));
106
- }
107
- function onHandleMove(e: PointerEvent) {
108
- if (dragIndex === null) return;
109
- setPosition(dragIndex, pctFromEvent(e));
110
- }
111
- function onHandleUp(e: PointerEvent) {
112
- if (dragIndex === null) return;
113
- (e.currentTarget as HTMLElement).releasePointerCapture(e.pointerId);
114
- dragIndex = null;
115
- }
116
-
117
- function onPositionInput(i: StopIndex, e: Event) {
118
- const v = parseFloat((e.target as HTMLInputElement).value);
119
- if (Number.isFinite(v)) setPosition(i, v);
120
- }
121
- </script>
122
-
123
- <div class="gradient-card">
124
- <div class="ribbon-wrap">
125
- <div class="ribbon" bind:this={barEl} style="background: {ribbonBg};"></div>
126
- <div class="handles">
127
- {#each STOPS as i}
128
- <button
129
- type="button"
130
- class="handle"
131
- class:selected={selected === i}
132
- class:dragging={dragIndex === i}
133
- style="left: {positions[i - 1]}%; --stop-color: {stopColors[i - 1]};"
134
- onpointerdown={(e) => onHandleDown(e, i)}
135
- onpointermove={onHandleMove}
136
- onpointerup={onHandleUp}
137
- onpointercancel={onHandleUp}
138
- title="Stop {i} ({positions[i - 1]}%)"
139
- aria-label="Gradient stop {i}"
140
- >
141
- <span class="handle-diamond"></span>
142
- </button>
143
- {/each}
144
- </div>
145
- </div>
146
-
147
- <div class="stop-edit-row">
148
- <span class="row-label">Stop {selected}</span>
149
- <label class="pos-input">
150
- <input
151
- type="number"
152
- min="0"
153
- max="100"
154
- step="0.1"
155
- value={positions[selected - 1]}
156
- onchange={(e) => onPositionInput(selected, e)}
157
- />
158
- <span class="suffix">%</span>
159
- </label>
160
- <div class="picker-slot">
161
- <UIPaletteSelector variable={stopColorVar(selected)} {component} />
162
- </div>
163
- <div class="angle-slot">
164
- <AngleDial value={angleDeg} onchange={(d) => setAngle(d.value)} />
165
- </div>
166
- </div>
167
- </div>
168
-
169
- <style>
170
- .gradient-card {
171
- display: flex;
172
- flex-direction: column;
173
- gap: var(--ui-space-12);
174
- padding: var(--ui-space-12);
175
- background: var(--ui-surface-lowest);
176
- border: 1px solid var(--ui-border-faint);
177
- border-radius: var(--ui-radius-md);
178
- }
179
-
180
- .ribbon-wrap {
181
- display: flex;
182
- flex-direction: column;
183
- gap: var(--ui-space-8);
184
- }
185
-
186
- .ribbon {
187
- position: relative;
188
- height: 2.25rem;
189
- border-radius: var(--ui-radius-sm);
190
- border: 1px solid var(--ui-border-default);
191
- }
192
-
193
- .handles {
194
- position: relative;
195
- height: 1.25rem;
196
- }
197
-
198
- /* The button is a generous (1.25rem) transparent hit target so the diamond
199
- can stay visually small while remaining easy to grab/drag. The visible
200
- marker lives in `.handle-diamond` inside. */
201
- .handle {
202
- position: absolute;
203
- top: 0;
204
- width: 1.25rem;
205
- height: 1.25rem;
206
- margin-left: -0.625rem;
207
- padding: 0;
208
- background: transparent;
209
- border: none;
210
- cursor: ew-resize;
211
- touch-action: none;
212
- display: flex;
213
- align-items: center;
214
- justify-content: center;
215
- }
216
-
217
- .handle-diamond {
218
- width: 0.7rem;
219
- height: 0.7rem;
220
- background: var(--stop-color, var(--ui-surface-high));
221
- border: 1px solid var(--ui-border-default);
222
- transform: rotate(45deg);
223
- border-radius: 1px;
224
- transition: border-color var(--ui-transition-fast), box-shadow var(--ui-transition-fast);
225
- }
226
-
227
- .handle:hover .handle-diamond {
228
- border-color: var(--ui-text-secondary);
229
- }
230
-
231
- .handle.selected .handle-diamond {
232
- border-color: var(--ui-text-primary);
233
- box-shadow: 0 0 0 1px var(--ui-text-primary);
234
- }
235
-
236
- .handle.dragging {
237
- z-index: 2;
238
- }
239
- .handle.dragging .handle-diamond {
240
- border-color: var(--ui-text-primary);
241
- box-shadow: 0 0 0 2px var(--ui-text-primary);
242
- }
243
-
244
- /* Selected-stop row: label, position readout, color picker, then angle dial
245
- inline on the right. The selector width matches TokenLayout's
246
- `--token-selector-w` so this row aligns with the property grid below. */
247
- .stop-edit-row {
248
- display: flex;
249
- flex-wrap: wrap;
250
- align-items: center;
251
- gap: var(--ui-space-12);
252
- }
253
-
254
- .row-label {
255
- font-size: var(--ui-font-size-xs);
256
- color: var(--ui-text-secondary);
257
- white-space: nowrap;
258
- }
259
-
260
- .picker-slot {
261
- width: 8rem;
262
- min-width: 0;
263
- }
264
-
265
- .pos-input {
266
- display: inline-flex;
267
- align-items: center;
268
- gap: var(--ui-space-4);
269
- font-size: var(--ui-font-size-xs);
270
- color: var(--ui-text-secondary);
271
- }
272
-
273
- .pos-input input {
274
- width: 4rem;
275
- padding: var(--ui-space-2) var(--ui-space-6);
276
- background: var(--ui-surface-low);
277
- border: 1px solid var(--ui-border-faint);
278
- border-radius: var(--ui-radius-sm);
279
- color: var(--ui-text-primary);
280
- font-family: var(--ui-font-mono);
281
- font-size: var(--ui-font-size-sm);
282
- text-align: right;
283
- }
284
-
285
- .pos-input input::-webkit-outer-spin-button,
286
- .pos-input input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
287
-
288
- .suffix {
289
- font-size: var(--ui-font-size-xs);
290
- color: var(--ui-text-tertiary);
291
- }
292
-
293
- .angle-slot {
294
- margin-left: auto;
295
- }
296
- </style>