@motion-proto/live-tokens 0.78.0 → 0.80.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 (172) hide show
  1. package/.claude/skills/live-tokens-check-compliance/SKILL.md +49 -38
  2. package/.claude/skills/live-tokens-create-component/SKILL.md +23 -28
  3. package/.claude/skills/live-tokens-create-component/references/contract-tests.md +61 -0
  4. package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +2 -2
  5. package/.claude/skills/live-tokens-create-component/references/token-naming.md +6 -15
  6. package/.claude/skills/live-tokens-create-page/SKILL.md +6 -4
  7. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
  8. package/.claude/skills/live-tokens-pick-component/SKILL.md +3 -3
  9. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +1 -1
  10. package/.claude/skills/live-tokens-set-geometry/SKILL.md +1 -1
  11. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +1 -1
  12. package/CHANGELOG.md +271 -0
  13. package/README.md +10 -16
  14. package/bin/check-component.mjs +154 -551
  15. package/bin/check-page.mjs +57 -541
  16. package/bin/cli.mjs +93 -16
  17. package/bin/contractRunner.mjs +37 -91
  18. package/bin/lib/buildChecks.mjs +32 -0
  19. package/bin/lib/catalogue.mjs +161 -34
  20. package/bin/lib/componentSource.mjs +152 -0
  21. package/bin/lib/cssValues.mjs +9 -0
  22. package/bin/lib/dataDir.mjs +126 -0
  23. package/bin/lib/findings.mjs +103 -12
  24. package/bin/lib/fixers.mjs +64 -0
  25. package/bin/lib/geometry.mjs +92 -0
  26. package/bin/lib/pageSource.mjs +230 -0
  27. package/bin/lib/report.mjs +57 -59
  28. package/bin/lib/tokenVocabulary.mjs +104 -34
  29. package/bin/migrate-build-script.mjs +66 -0
  30. package/bin/migrate.mjs +5 -0
  31. package/bin/rules/componentStructure.mjs +344 -0
  32. package/bin/rules/componentUse.mjs +313 -0
  33. package/bin/rules/importsAndRoutes.mjs +136 -0
  34. package/bin/rules/testRuns.mjs +122 -0
  35. package/bin/rules/tokens.mjs +426 -0
  36. package/bin/setup-claude.mjs +1 -2
  37. package/dist-plugin/{chunk-PDNL4NC5.js → chunk-D4WRIKEZ.js} +7 -2
  38. package/dist-plugin/{chunk-SWXRVZKT.js → chunk-REBHE3ZM.js} +414 -1
  39. package/dist-plugin/index.cjs +470 -19
  40. package/dist-plugin/index.d.cts +1 -0
  41. package/dist-plugin/index.d.ts +1 -0
  42. package/dist-plugin/index.js +87 -55
  43. package/dist-plugin/migrateData/index.cjs +422 -4
  44. package/dist-plugin/migrateData/index.js +2 -2
  45. package/dist-plugin/setColors/index.cjs +414 -1
  46. package/dist-plugin/setColors/index.d.cts +1 -1
  47. package/dist-plugin/setColors/index.d.ts +1 -1
  48. package/dist-plugin/setColors/index.js +1 -1
  49. package/dist-plugin/setGeometry/index.cjs +423 -13
  50. package/dist-plugin/setGeometry/index.d.cts +3 -3
  51. package/dist-plugin/setGeometry/index.d.ts +3 -3
  52. package/dist-plugin/setGeometry/index.js +10 -13
  53. package/dist-plugin/setType/index.d.cts +1 -1
  54. package/dist-plugin/setType/index.d.ts +1 -1
  55. package/dist-plugin/{themeTypes-BxRtuN5V.d.cts → themeTypes-B8_Idrp4.d.cts} +2 -2
  56. package/dist-plugin/{themeTypes-BxRtuN5V.d.ts → themeTypes-B8_Idrp4.d.ts} +2 -2
  57. package/package.json +2 -2
  58. package/src/editor/component-editor/CalloutEditor.svelte +2 -2
  59. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +14 -15
  60. package/src/editor/component-editor/CornerBadgeEditor.svelte +14 -14
  61. package/src/editor/component-editor/DialogEditor.svelte +5 -5
  62. package/src/editor/component-editor/InlineEditActionsEditor.svelte +2 -2
  63. package/src/editor/component-editor/RadioButtonEditor.svelte +21 -21
  64. package/src/editor/component-editor/SectionDividerEditor.svelte +7 -7
  65. package/src/editor/component-editor/SegmentedControlEditor.svelte +5 -5
  66. package/src/editor/component-editor/SideNavigationEditor.svelte +25 -25
  67. package/src/editor/component-editor/TabBarEditor.svelte +6 -6
  68. package/src/editor/component-editor/TableEditor.svelte +6 -6
  69. package/src/editor/component-editor/ToggleEditor.svelte +2 -2
  70. package/src/editor/component-editor/index.ts +3 -0
  71. package/src/editor/component-editor/registry.ts +57 -1
  72. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +14 -14
  73. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +3 -0
  74. package/src/editor/component-editor/scaffolding/types.ts +15 -0
  75. package/src/editor/core/components/adjustAliases.ts +4 -4
  76. package/src/editor/core/components/aliasKinds.ts +20 -19
  77. package/src/editor/core/sketch/sketchLayer.ts +3 -3
  78. package/src/editor/core/themes/migrateComponentConfig.ts +14 -6
  79. package/src/editor/core/themes/migrations/2026-09-13-badge-brand.ts +42 -0
  80. package/src/editor/core/themes/migrations/2026-09-13-collapsiblesection-open.ts +33 -0
  81. package/src/editor/core/themes/migrations/2026-09-13-cornerbadge-prefix.ts +70 -0
  82. package/src/editor/core/themes/migrations/2026-09-13-hairline.ts +92 -0
  83. package/src/editor/core/themes/migrations/2026-09-13-indicator.ts +54 -0
  84. package/src/editor/core/themes/migrations/2026-09-13-sectiondivider-surface.ts +36 -0
  85. package/src/editor/core/themes/migrations/2026-09-13-selected-state.ts +124 -0
  86. package/src/editor/core/themes/migrations/2026-09-13-toggle-label.ts +31 -0
  87. package/src/editor/core/themes/migrations/index.ts +16 -0
  88. package/src/editor/core/themes/themeService.ts +3 -3
  89. package/src/editor/core/themes/themeTypes.ts +13 -15
  90. package/src/editor/docs/Docs.svelte +1 -1
  91. package/src/editor/docs/content/light-and-dark.md +3 -3
  92. package/src/editor/docs/content.generated.ts +1 -1
  93. package/src/editor/index.ts +1 -0
  94. package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
  95. package/src/editor/skill-atlas/SkillAtlas.svelte +4 -4
  96. package/src/editor/skill-atlas/TreeNodeCard.svelte +4 -4
  97. package/src/editor/skill-atlas/skillSources.generated.ts +11 -14
  98. package/src/editor/skill-atlas/skillTrees.ts +1 -3
  99. package/src/editor/skill-atlas/trees/check-compliance.ts +37 -149
  100. package/src/editor/skill-atlas/trees/create-component.ts +62 -64
  101. package/src/editor/skill-atlas/trees/create-page.ts +38 -17
  102. package/src/editor/skill-atlas/trees/pick-component.ts +3 -3
  103. package/src/editor/skill-atlas/trees/set-geometry.ts +1 -1
  104. package/src/editor/ui/UIPaletteSelector.svelte +11 -15
  105. package/src/editor/ui/variantScales.ts +8 -8
  106. package/src/live-tokens/data/themes/autumn.json +188 -188
  107. package/src/live-tokens/data/themes/halloween.json +188 -188
  108. package/src/live-tokens/data/themes/midnight-study.json +245 -245
  109. package/src/live-tokens/data/themes/ocean.json +188 -188
  110. package/src/live-tokens/data/themes/royal-velvet.json +188 -188
  111. package/src/live-tokens/data/themes/sketchy.json +188 -188
  112. package/src/live-tokens/data/themes/spring-meadow.json +188 -188
  113. package/src/live-tokens/data/themes/sunset.json +188 -188
  114. package/src/system/components/Badge.svelte +27 -23
  115. package/src/system/components/Button.svelte +13 -7
  116. package/src/system/components/Callout.svelte +16 -11
  117. package/src/system/components/Card.svelte +22 -15
  118. package/src/system/components/CodeSnippet.svelte +10 -6
  119. package/src/system/components/CollapsibleSection.svelte +81 -76
  120. package/src/system/components/CornerBadge.svelte +78 -72
  121. package/src/system/components/Dialog.svelte +21 -18
  122. package/src/system/components/IconButton.svelte +13 -9
  123. package/src/system/components/Image.svelte +14 -8
  124. package/src/system/components/ImageLightbox.svelte +10 -6
  125. package/src/system/components/InlineEditActions.svelte +17 -14
  126. package/src/system/components/Input.svelte +13 -7
  127. package/src/system/components/MenuSelect.svelte +13 -7
  128. package/src/system/components/Notification.svelte +17 -11
  129. package/src/system/components/Panel.svelte +13 -6
  130. package/src/system/components/ProgressBar.svelte +10 -5
  131. package/src/system/components/RadioButton.svelte +33 -30
  132. package/src/system/components/SectionDivider.svelte +28 -21
  133. package/src/system/components/SegmentedControl.svelte +27 -23
  134. package/src/system/components/SideNavigation.svelte +175 -171
  135. package/src/system/components/Slider.svelte +11 -7
  136. package/src/system/components/TabBar.svelte +53 -49
  137. package/src/system/components/Table.svelte +20 -15
  138. package/src/system/components/Toggle.svelte +14 -10
  139. package/src/system/components/Tooltip.svelte +10 -6
  140. package/src/system/styles/CONVENTIONS.md +3 -4
  141. package/src/testing-js/chunk-3UKGXCDL.js +48 -0
  142. package/src/testing-js/chunk-3UKGXCDL.js.map +1 -0
  143. package/src/testing-js/{chunk-FAFOAWYL.js → chunk-Q3YIAAG3.js} +17 -3
  144. package/src/testing-js/chunk-Q3YIAAG3.js.map +1 -0
  145. package/src/testing-js/{chunk-GNIUPIU2.js → chunk-U7OJE5DU.js} +18 -18
  146. package/src/testing-js/chunk-U7OJE5DU.js.map +1 -0
  147. package/src/testing-js/{chunk-4JQX6WWL.js → chunk-ZMZQZ33J.js} +474 -166
  148. package/src/testing-js/chunk-ZMZQZ33J.js.map +1 -0
  149. package/src/testing-js/component-behavior.contract.js +155 -0
  150. package/src/testing-js/component-behavior.contract.js.map +1 -0
  151. package/src/testing-js/component-editor.contract.js +6 -4
  152. package/src/testing-js/component-editor.contract.js.map +1 -1
  153. package/src/testing-js/component-render.contract.js +14 -10
  154. package/src/testing-js/component-render.contract.js.map +1 -1
  155. package/src/testing-js/index.d.ts +44 -4
  156. package/src/testing-js/index.js +13 -7
  157. package/src/testing-js/index.js.map +1 -1
  158. package/src/testing-js/page-compliance.contract.js +48 -10
  159. package/src/testing-js/page-compliance.contract.js.map +1 -1
  160. package/src/testing-js/registry.contract.js +5 -3
  161. package/src/testing-js/registry.contract.js.map +1 -1
  162. package/src/testing-js/{vitest-C-wNWcoA.d.ts → vitest-BMLIbDs2.d.ts} +8 -2
  163. package/src/testing-js/vitest.d.ts +1 -1
  164. package/src/testing-js/vitest.js +2 -1
  165. package/template/package.json +1 -2
  166. package/template/vite.config.ts +3 -2
  167. package/.claude/skills/live-tokens-create-component/SKILL copy.md +0 -196
  168. package/.claude/skills/live-tokens-fix-findings/SKILL.md +0 -105
  169. package/src/editor/skill-atlas/trees/fix-findings.ts +0 -504
  170. package/src/testing-js/chunk-4JQX6WWL.js.map +0 -1
  171. package/src/testing-js/chunk-FAFOAWYL.js.map +0 -1
  172. package/src/testing-js/chunk-GNIUPIU2.js.map +0 -1
@@ -1,13 +1,17 @@
1
- <!--
2
- Badge.svelte. A short standing label on an element.
3
- Use for: status the reader takes at a glance, such as "Beta", "New", or a
4
- version.
5
- Not for: a marker that sits on a parent's corner (CornerBadge); feedback
6
- after an action (Notification).
7
- -->
8
1
  <script module lang="ts">
2
+ import type { CatalogueEntry } from '../../editor/component-editor/scaffolding/types';
3
+
4
+ export const catalogue = {
5
+ description: 'A short standing label on an element.',
6
+ useFor: 'status the reader takes at a glance, such as "Beta", "New", or a version.',
7
+ notFor: "a marker that sits on a parent's corner (CornerBadge); feedback after an action (Notification).",
8
+ props: {
9
+ variant: '`brand`, `accent`, `special`, `alternate`, `canvas`, and `neutral` paint a color family; `success`, `warning`, `danger`, and `info` carry a status.',
10
+ },
11
+ } satisfies CatalogueEntry;
12
+
9
13
  export const badgeVariants = [
10
- 'primary',
14
+ 'brand',
11
15
  'accent',
12
16
  'neutral',
13
17
  'alternate',
@@ -57,7 +61,7 @@
57
61
  <style lang="scss">
58
62
  @use '../styles/padding' as *;
59
63
 
60
- $variants: info, accent, primary, success, warning, danger, neutral, special, alternate, canvas;
64
+ $variants: info, accent, brand, success, warning, danger, neutral, special, alternate, canvas;
61
65
 
62
66
  // Per-variant token block kept flat (not collapsed via SCSS @each) so the
63
67
  // Layer-2 token-discovery parser (`extractGlobalRootBody` in
@@ -67,20 +71,20 @@
67
71
  // Notification.svelte. `--text-primary` is the neutral primary text (with
68
72
  // -secondary/-tertiary scale); `--text-brand` is the brand-family text.
69
73
  :global(:root) {
70
- /* Primary */
71
- --badge-primary-surface: var(--surface-brand);
72
- --badge-primary-text: var(--text-brand);
73
- --badge-primary-border: var(--border-brand);
74
- --badge-primary-text-font-family: var(--font-sans);
75
- --badge-primary-text-font-size: var(--font-size-md);
76
- --badge-primary-text-font-weight: var(--font-weight-normal);
77
- --badge-primary-text-line-height: var(--line-height-none);
78
- --badge-primary-border-width: var(--border-width-1);
79
- --badge-primary-radius: var(--radius-full);
80
- --badge-primary-padding: var(--space-6);
81
- --badge-primary-shadow: var(--shadow-none);
82
- --badge-primary-blur: var(--blur-none);
83
- --badge-primary-icon-size: var(--icon-size-sm);
74
+ /* Brand */
75
+ --badge-brand-surface: var(--surface-brand);
76
+ --badge-brand-text: var(--text-brand);
77
+ --badge-brand-border: var(--border-brand);
78
+ --badge-brand-text-font-family: var(--font-sans);
79
+ --badge-brand-text-font-size: var(--font-size-md);
80
+ --badge-brand-text-font-weight: var(--font-weight-normal);
81
+ --badge-brand-text-line-height: var(--line-height-none);
82
+ --badge-brand-border-width: var(--border-width-1);
83
+ --badge-brand-radius: var(--radius-full);
84
+ --badge-brand-padding: var(--space-6);
85
+ --badge-brand-shadow: var(--shadow-none);
86
+ --badge-brand-blur: var(--blur-none);
87
+ --badge-brand-icon-size: var(--icon-size-sm);
84
88
 
85
89
  /* Accent */
86
90
  --badge-accent-surface: var(--surface-accent);
@@ -1,10 +1,16 @@
1
- <!--
2
- Button.svelte. A labelled action.
3
- Use for: an action that needs a word to be unambiguous.
4
- Not for: an icon-only action (IconButton); a link to another page.
5
- Emphasis: one primary per page; secondary for the rest; outline for a
6
- tertiary action; danger for a destructive one.
7
- -->
1
+ <script module lang="ts">
2
+ import type { CatalogueEntry } from '../../editor/component-editor/scaffolding/types';
3
+
4
+ export const catalogue = {
5
+ description: 'A labelled action.',
6
+ useFor: 'an action that needs a word to be unambiguous.',
7
+ notFor: 'an icon-only action (IconButton); a link to another page.',
8
+ props: {
9
+ variant: 'one primary per page; secondary for the rest; outline for a tertiary action; danger for a destructive one.',
10
+ },
11
+ } satisfies CatalogueEntry;
12
+ </script>
13
+
8
14
  <script lang="ts">
9
15
  import { createEventDispatcher } from 'svelte';
10
16
 
@@ -1,10 +1,15 @@
1
- <!--
2
- Callout.svelte. A standing message that sits inside a section.
3
- Use for: something the reader must know about the content around it.
4
- Not for: feedback after an action (Notification); a hint that hangs off one
5
- element (Tooltip).
6
- -->
7
1
  <script module lang="ts">
2
+ import type { CatalogueEntry } from '../../editor/component-editor/scaffolding/types';
3
+
4
+ export const catalogue = {
5
+ description: 'A standing message that sits inside a section.',
6
+ useFor: 'something the reader must know about the content around it.',
7
+ notFor: 'feedback after an action (Notification); a note that hangs off one element (Tooltip).',
8
+ props: {
9
+ variant: '`info` notes, `success` confirms, `warning` cautions, `danger` flags harm.',
10
+ },
11
+ } satisfies CatalogueEntry;
12
+
8
13
  export const calloutVariants = ['info', 'success', 'warning', 'danger'] as const;
9
14
  export type CalloutVariant = typeof calloutVariants[number];
10
15
  </script>
@@ -35,7 +40,7 @@
35
40
  --callout-info-surface: var(--surface-info-lowest);
36
41
  --callout-info-border: var(--border-info-medium);
37
42
  --callout-info-border-width: var(--border-width-1);
38
- --callout-info-accent-width: var(--border-width-1);
43
+ --callout-info-indicator-width: var(--border-width-1);
39
44
  --callout-info-radius: var(--radius-lg);
40
45
  --callout-info-padding: var(--space-12);
41
46
  --callout-info-label: var(--text-primary);
@@ -53,7 +58,7 @@
53
58
  --callout-success-surface: var(--surface-success-lowest);
54
59
  --callout-success-border: var(--border-success-subtle);
55
60
  --callout-success-border-width: var(--border-width-1);
56
- --callout-success-accent-width: var(--border-width-1);
61
+ --callout-success-indicator-width: var(--border-width-1);
57
62
  --callout-success-radius: var(--radius-lg);
58
63
  --callout-success-padding: var(--space-12);
59
64
  --callout-success-label: var(--text-primary);
@@ -71,7 +76,7 @@
71
76
  --callout-warning-surface: var(--surface-warning-lowest);
72
77
  --callout-warning-border: var(--border-warning-subtle);
73
78
  --callout-warning-border-width: var(--border-width-1);
74
- --callout-warning-accent-width: var(--border-width-1);
79
+ --callout-warning-indicator-width: var(--border-width-1);
75
80
  --callout-warning-radius: var(--radius-lg);
76
81
  --callout-warning-padding: var(--space-12);
77
82
  --callout-warning-label: var(--text-primary);
@@ -89,7 +94,7 @@
89
94
  --callout-danger-surface: var(--surface-danger-lowest);
90
95
  --callout-danger-border: var(--border-danger-subtle);
91
96
  --callout-danger-border-width: var(--border-width-1);
92
- --callout-danger-accent-width: var(--border-width-1);
97
+ --callout-danger-indicator-width: var(--border-width-1);
93
98
  --callout-danger-radius: var(--radius-lg);
94
99
  --callout-danger-padding: var(--space-12);
95
100
  --callout-danger-label: var(--text-primary);
@@ -130,7 +135,7 @@
130
135
  .callout-#{$variant} {
131
136
  background: var(--callout-#{$variant}-surface);
132
137
  border: var(--callout-#{$variant}-border-width) solid var(--callout-#{$variant}-border);
133
- border-left-width: var(--callout-#{$variant}-accent-width);
138
+ border-left-width: var(--callout-#{$variant}-indicator-width);
134
139
  border-radius: var(--callout-#{$variant}-radius);
135
140
  @include themed-padding(--callout-#{$variant}-padding, $h: 1.33);
136
141
 
@@ -1,10 +1,17 @@
1
- <!--
2
- Card.svelte. One item with a title.
3
- Use for: an item on its own, or each item in a set: a product, a record, a
4
- plan the reader may act on.
5
- Not for: a section of the page's content (Panel); content the reader opens
6
- on demand (CollapsibleSection); a decision that blocks the page (Dialog).
7
- -->
1
+ <script module lang="ts">
2
+ import type { CatalogueEntry } from '../../editor/component-editor/scaffolding/types';
3
+
4
+ export const catalogue = {
5
+ description: 'One item with a title.',
6
+ useFor: 'an item on its own, or each item in a set: a product, a record, a plan the reader may act on.',
7
+ notFor:
8
+ "a section of the page's content (Panel); content the reader opens on demand (CollapsibleSection); a decision that blocks the page (Dialog).",
9
+ props: {
10
+ variant: '`bare` drops the header for content that carries its own title.',
11
+ },
12
+ } satisfies CatalogueEntry;
13
+ </script>
14
+
8
15
  <script lang="ts">
9
16
  interface Props {
10
17
  icon?: string;
@@ -13,7 +20,7 @@
13
20
  /** `bare` drops the header. The frame and body keep every token the default
14
21
  variant uses, so padding, stroke and fill stay editable. */
15
22
  variant?: 'default' | 'bare';
16
- size?: 'default' | 'compact';
23
+ size?: 'default' | 'small';
17
24
  /** false → the card stops pinning body typography so the consumer fully owns slotted content's styling. */
18
25
  prose?: boolean;
19
26
  /** true → the body drops its inset so slotted media runs to the card's edge.
@@ -62,7 +69,7 @@
62
69
  <div
63
70
  class="card {className}"
64
71
  class:bare={variant === 'bare'}
65
- class:compact={size === 'compact'}
72
+ class:small={size === 'small'}
66
73
  style:--card-color={iconColor}
67
74
  style:--card-hover-border-enabled={hoverBorder}
68
75
  style:--card-hover-shadow-enabled={hoverShadow}
@@ -175,8 +182,8 @@
175
182
  margin-left: auto;
176
183
  }
177
184
 
178
- .card.compact .card-header,
179
- .card.compact .card-body {
185
+ .card.small .card-header,
186
+ .card.small .card-body {
180
187
  padding: var(--space-8) var(--space-12);
181
188
  }
182
189
 
@@ -185,7 +192,7 @@
185
192
  color: var(--card-color, var(--card-default-title));
186
193
  }
187
194
 
188
- .card.compact .card-icon {
195
+ .card.small .card-icon {
189
196
  font-size: var(--icon-size-md);
190
197
  }
191
198
 
@@ -201,7 +208,7 @@
201
208
  text-overflow: ellipsis;
202
209
  }
203
210
 
204
- .card.compact .card-title {
211
+ .card.small .card-title {
205
212
  font-size: var(--font-size-md);
206
213
  }
207
214
 
@@ -216,11 +223,11 @@
216
223
  @include slot-prose;
217
224
  }
218
225
 
219
- .card.compact .card-body {
226
+ .card.small .card-body {
220
227
  font-size: var(--font-size-sm);
221
228
  }
222
229
 
223
- /* Last, and at the same weight as the compact override, so a flush card is
230
+ /* Last, and at the same weight as the small override, so a flush card is
224
231
  flush at either size. Full-bleed media has to reach the border the card
225
232
  already clips it against. */
226
233
  .card-body.flush {
@@ -1,9 +1,13 @@
1
- <!--
2
- CodeSnippet.svelte. A command or value with a copy button.
3
- Use for: text the reader is meant to run or paste somewhere else.
4
- Not for: prose the reader only reads (a paragraph in its Card or Panel); a
5
- value the reader edits (Input).
6
- -->
1
+ <script module lang="ts">
2
+ import type { CatalogueEntry } from '../../editor/component-editor/scaffolding/types';
3
+
4
+ export const catalogue = {
5
+ description: 'A command or value with a copy button.',
6
+ useFor: 'text the reader is meant to run or paste somewhere else.',
7
+ notFor: 'prose the reader only reads (a paragraph in its Card or Panel); a value the reader edits (Input).',
8
+ } satisfies CatalogueEntry;
9
+ </script>
10
+
7
11
  <script lang="ts">
8
12
  import Tooltip from './Tooltip.svelte';
9
13
 
@@ -1,19 +1,24 @@
1
- <!--
2
- CollapsibleSection.svelte. A section the reader opens and closes.
3
- Use for: secondary content that most readers skip.
4
- Not for: content every reader needs (Card); moving between pages
5
- (SideNavigation).
6
- Variant: `chromeless` sits inside other content, `divider` rules a line
7
- under the header, `container` frames the whole section.
8
- -->
1
+ <script module lang="ts">
2
+ import type { CatalogueEntry } from '../../editor/component-editor/scaffolding/types';
3
+
4
+ export const catalogue = {
5
+ description: 'A section the reader opens and closes.',
6
+ useFor: 'secondary content that most readers skip.',
7
+ notFor: 'content every reader needs (Card); moving between pages (SideNavigation).',
8
+ props: {
9
+ variant: '`chromeless` sits inside other content, `hairline` draws a line under the header, `container` frames the whole section.',
10
+ },
11
+ } satisfies CatalogueEntry;
12
+ </script>
13
+
9
14
  <script lang="ts">
10
15
  import { createEventDispatcher } from 'svelte';
11
16
 
12
17
  interface Props {
13
18
  label: string;
14
- expanded?: boolean;
19
+ open?: boolean;
15
20
  href?: string | undefined;
16
- variant?: 'chromeless' | 'divider' | 'container';
21
+ variant?: 'chromeless' | 'hairline' | 'container';
17
22
  /** false → the section stops pinning body typography so the consumer fully owns slotted content's styling. */
18
23
  prose?: boolean;
19
24
  class?: string;
@@ -25,7 +30,7 @@
25
30
 
26
31
  let {
27
32
  label,
28
- expanded = false,
33
+ open = false,
29
34
  href = undefined,
30
35
  variant = 'container',
31
36
  prose = true,
@@ -52,13 +57,13 @@
52
57
  section can still be collapsed even when the label is a link. Both
53
58
  live inside the same `.section-header` flex row so paint (hover,
54
59
  background, indicator) continues to land on the row as a whole. -->
55
- <div class="section-header section-header--linked" class:expanded>
60
+ <div class="section-header section-header--linked" class:open>
56
61
  <button
57
62
  type="button"
58
63
  class="section-toggle-button"
59
64
  onclick={fireToggle}
60
- aria-label={expanded ? 'Collapse section' : 'Expand section'}
61
- aria-expanded={expanded}
65
+ aria-label={open ? 'Collapse section' : 'Expand section'}
66
+ aria-expanded={open}
62
67
  >
63
68
  <i class="fas fa-chevron-right toggle-icon"></i>
64
69
  </button>
@@ -68,23 +73,20 @@
68
73
  {@render summary?.()}
69
74
  </div>
70
75
  {:else}
71
- <div class="section-header" class:expanded>
72
- <div class="section-toggle">
73
- <button
74
- type="button"
75
- class="section-toggle-button"
76
- onclick={fireToggle}
77
- aria-label={expanded ? 'Collapse section' : 'Expand section'}
78
- aria-expanded={expanded}
79
- >
80
- <i class="fas fa-chevron-right toggle-icon"></i>
81
- </button>
76
+ <div class="section-header" class:open>
77
+ <button
78
+ type="button"
79
+ class="section-toggle-button section-toggle"
80
+ onclick={fireToggle}
81
+ aria-expanded={open}
82
+ >
83
+ <i class="fas fa-chevron-right toggle-icon" aria-hidden="true"></i>
82
84
  <span class="section-label">{label}</span>
83
- </div>
85
+ </button>
84
86
  {@render summary?.()}
85
87
  </div>
86
88
  {/if}
87
- {#if expanded && children}
89
+ {#if open && children}
88
90
  <div class="section-content" class:prose>
89
91
  {@render children?.()}
90
92
  </div>
@@ -116,35 +118,35 @@
116
118
  --collapsiblesection-chromeless-hover-label-line-height: var(--line-height-normal);
117
119
  --collapsiblesection-chromeless-hover-icon: var(--text-primary);
118
120
  --collapsiblesection-chromeless-hover-icon-size: var(--icon-size-xs);
119
- /* Chromeless — expanded */
120
- --collapsiblesection-chromeless-expanded-padding: var(--space-4);
121
+ /* Chromeless — open */
122
+ --collapsiblesection-chromeless-open-padding: var(--space-4);
121
123
 
122
- /* Divider — default */
123
- --collapsiblesection-divider-default-surface: var(--color-transparent);
124
- --collapsiblesection-divider-default-hairline-color: var(--border-brand);
125
- --collapsiblesection-divider-default-hairline-thickness: var(--border-width-1);
126
- --collapsiblesection-divider-default-padding: var(--space-4);
127
- --collapsiblesection-divider-default-label: var(--text-primary);
128
- --collapsiblesection-divider-default-label-font-family: var(--font-sans);
129
- --collapsiblesection-divider-default-label-font-size: var(--font-size-md);
130
- --collapsiblesection-divider-default-label-font-weight: var(--font-weight-normal);
131
- --collapsiblesection-divider-default-label-line-height: var(--line-height-normal);
132
- --collapsiblesection-divider-default-icon: var(--text-primary);
133
- --collapsiblesection-divider-default-icon-size: var(--icon-size-xs);
134
- /* Divider — hover */
135
- --collapsiblesection-divider-hover-surface: var(--color-transparent);
136
- --collapsiblesection-divider-hover-hairline-color: var(--border-neutral);
137
- --collapsiblesection-divider-hover-hairline-thickness: var(--border-width-1);
138
- --collapsiblesection-divider-hover-padding: var(--space-4);
139
- --collapsiblesection-divider-hover-label: var(--text-primary);
140
- --collapsiblesection-divider-hover-label-font-family: var(--font-sans);
141
- --collapsiblesection-divider-hover-label-font-size: var(--font-size-md);
142
- --collapsiblesection-divider-hover-label-font-weight: var(--font-weight-normal);
143
- --collapsiblesection-divider-hover-label-line-height: var(--line-height-normal);
144
- --collapsiblesection-divider-hover-icon: var(--text-primary);
145
- --collapsiblesection-divider-hover-icon-size: var(--icon-size-xs);
146
- /* Divider — expanded */
147
- --collapsiblesection-divider-expanded-padding: var(--space-4);
124
+ /* Hairline — default */
125
+ --collapsiblesection-hairline-default-surface: var(--color-transparent);
126
+ --collapsiblesection-hairline-default-hairline-color: var(--border-brand);
127
+ --collapsiblesection-hairline-default-hairline-width: var(--border-width-1);
128
+ --collapsiblesection-hairline-default-padding: var(--space-4);
129
+ --collapsiblesection-hairline-default-label: var(--text-primary);
130
+ --collapsiblesection-hairline-default-label-font-family: var(--font-sans);
131
+ --collapsiblesection-hairline-default-label-font-size: var(--font-size-md);
132
+ --collapsiblesection-hairline-default-label-font-weight: var(--font-weight-normal);
133
+ --collapsiblesection-hairline-default-label-line-height: var(--line-height-normal);
134
+ --collapsiblesection-hairline-default-icon: var(--text-primary);
135
+ --collapsiblesection-hairline-default-icon-size: var(--icon-size-xs);
136
+ /* Hairline — hover */
137
+ --collapsiblesection-hairline-hover-surface: var(--color-transparent);
138
+ --collapsiblesection-hairline-hover-hairline-color: var(--border-neutral);
139
+ --collapsiblesection-hairline-hover-hairline-width: var(--border-width-1);
140
+ --collapsiblesection-hairline-hover-padding: var(--space-4);
141
+ --collapsiblesection-hairline-hover-label: var(--text-primary);
142
+ --collapsiblesection-hairline-hover-label-font-family: var(--font-sans);
143
+ --collapsiblesection-hairline-hover-label-font-size: var(--font-size-md);
144
+ --collapsiblesection-hairline-hover-label-font-weight: var(--font-weight-normal);
145
+ --collapsiblesection-hairline-hover-label-line-height: var(--line-height-normal);
146
+ --collapsiblesection-hairline-hover-icon: var(--text-primary);
147
+ --collapsiblesection-hairline-hover-icon-size: var(--icon-size-xs);
148
+ /* Hairline — open */
149
+ --collapsiblesection-hairline-open-padding: var(--space-4);
148
150
 
149
151
  /* Container — frame (always-on outer chrome) */
150
152
  --collapsiblesection-container-frame-border: var(--border-neutral);
@@ -170,9 +172,9 @@
170
172
  --collapsiblesection-container-hover-label-line-height: var(--line-height-normal);
171
173
  --collapsiblesection-container-hover-icon: var(--text-primary);
172
174
  --collapsiblesection-container-hover-icon-size: var(--icon-size-xs);
173
- /* Container — expanded content area */
174
- --collapsiblesection-container-expanded-surface: var(--surface-neutral-higher);
175
- --collapsiblesection-container-expanded-padding: var(--space-4);
175
+ /* Container — open content area */
176
+ --collapsiblesection-container-open-surface: var(--surface-neutral-higher);
177
+ --collapsiblesection-container-open-padding: var(--space-4);
176
178
  }
177
179
 
178
180
  .es-root {
@@ -189,16 +191,19 @@
189
191
  color: inherit;
190
192
  transition: all var(--duration-150);
191
193
 
192
- &.expanded .toggle-icon {
194
+ &.open .toggle-icon {
193
195
  transform: rotate(90deg);
194
196
  }
195
197
  }
196
198
 
197
- .section-toggle {
198
- display: flex;
199
- align-items: center;
199
+ /* The whole unlinked header toggles, so the button carries the label and
200
+ fills the row; a summary snippet still sits beside it. */
201
+ .section-toggle-button.section-toggle {
200
202
  gap: var(--space-8);
201
- flex-shrink: 0;
203
+ flex: 1 1 auto;
204
+ min-width: 0;
205
+ justify-content: flex-start;
206
+ text-align: start;
202
207
  }
203
208
 
204
209
  /* Linked header: chevron is a sibling button next to the label link, not a
@@ -251,8 +256,8 @@
251
256
  }
252
257
  }
253
258
 
254
- @mixin divider-bottom($state) {
255
- border-bottom: var(--collapsiblesection-divider-#{$state}-hairline-thickness) solid var(--collapsiblesection-divider-#{$state}-hairline-color);
259
+ @mixin hairline-bottom($state) {
260
+ border-bottom: var(--collapsiblesection-hairline-#{$state}-hairline-width) solid var(--collapsiblesection-hairline-#{$state}-hairline-color);
256
261
  }
257
262
 
258
263
  .es-root.variant-chromeless {
@@ -262,25 +267,25 @@
262
267
  }
263
268
  &.force-hover > .section-header { @include header-paint(chromeless, hover); }
264
269
  > .section-content {
265
- @include themed-padding(--collapsiblesection-chromeless-expanded-padding, $h: 2);
270
+ @include themed-padding(--collapsiblesection-chromeless-open-padding, $h: 2);
266
271
  }
267
272
  }
268
273
 
269
- .es-root.variant-divider {
274
+ .es-root.variant-hairline {
270
275
  > .section-header {
271
- @include header-paint(divider, default);
272
- @include divider-bottom(default);
276
+ @include header-paint(hairline, default);
277
+ @include hairline-bottom(default);
273
278
  &:hover {
274
- @include header-paint(divider, hover);
275
- @include divider-bottom(hover);
279
+ @include header-paint(hairline, hover);
280
+ @include hairline-bottom(hover);
276
281
  }
277
282
  }
278
283
  &.force-hover > .section-header {
279
- @include header-paint(divider, hover);
280
- @include divider-bottom(hover);
284
+ @include header-paint(hairline, hover);
285
+ @include hairline-bottom(hover);
281
286
  }
282
287
  > .section-content {
283
- @include themed-padding(--collapsiblesection-divider-expanded-padding, $h: 2);
288
+ @include themed-padding(--collapsiblesection-hairline-open-padding, $h: 2);
284
289
  }
285
290
  }
286
291
 
@@ -295,8 +300,8 @@
295
300
  }
296
301
  &.force-hover > .section-header { @include header-paint(container, hover); }
297
302
  > .section-content {
298
- background: var(--collapsiblesection-container-expanded-surface);
299
- @include themed-padding(--collapsiblesection-container-expanded-padding, $h: 2);
303
+ background: var(--collapsiblesection-container-open-surface);
304
+ @include themed-padding(--collapsiblesection-container-open-padding, $h: 2);
300
305
  }
301
306
  }
302
307