@motion-proto/live-tokens 0.23.0 → 0.24.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motion-proto/live-tokens",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "type": "module",
5
5
  "description": "Design token editor with live CSS variable editing. Svelte 5 + Vite 8.",
6
6
  "keywords": [
@@ -9,19 +9,20 @@
9
9
 
10
10
  function variantTokens(v: Variant): Token[] {
11
11
  return [
12
- { label: 'surface color', groupKey: 'surface', variable: `--callout-${v}-surface` },
13
- { label: 'border color', groupKey: 'border', variable: `--callout-${v}-border` },
14
- { label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: `--callout-${v}-border-width` },
15
- { label: 'accent edge width', canBeLinked: true, groupKey: 'accent-width', variable: `--callout-${v}-accent-width` },
16
- { label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: `--callout-${v}-radius` },
17
- { label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `--callout-${v}-padding` },
12
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: `--callout-${v}-surface` },
13
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: `--callout-${v}-border` },
14
+ { label: 'border width', element: 'frame', canBeLinked: true, groupKey: 'border-width', variable: `--callout-${v}-border-width` },
15
+ { label: 'accent edge width', element: 'frame', canBeLinked: true, groupKey: 'accent-width', variable: `--callout-${v}-accent-width` },
16
+ { label: 'corner radius', element: 'frame', canBeLinked: true, groupKey: 'radius', variable: `--callout-${v}-radius` },
17
+ { label: 'padding', element: 'frame', canBeLinked: true, groupKey: 'padding', variable: `--callout-${v}-padding` },
18
18
  ];
19
19
  }
20
20
  // Two type groups per variant: label (e.g. "Warning.") and message body.
21
21
  function variantTypeGroups(v: Variant): TypeGroupConfig[] {
22
22
  return [
23
23
  {
24
- legend: `${v} label`,
24
+ legend: '',
25
+ element: 'label',
25
26
  colorVariable: `--callout-${v}-label`,
26
27
  familyVariable: `--callout-${v}-label-font-family`,
27
28
  sizeVariable: `--callout-${v}-label-font-size`,
@@ -29,7 +30,8 @@
29
30
  lineHeightVariable: `--callout-${v}-label-line-height`,
30
31
  },
31
32
  {
32
- legend: `${v} message`,
33
+ legend: '',
34
+ element: 'message',
33
35
  colorVariable: `--callout-${v}-text`,
34
36
  familyVariable: `--callout-${v}-text-font-family`,
35
37
  sizeVariable: `--callout-${v}-text-font-size`,
@@ -3,23 +3,29 @@
3
3
 
4
4
  export const component = 'codesnippet';
5
5
 
6
- // Single variant. Default carries every container, code, and icon token;
7
- // hover layers a single icon-color override on top.
6
+ // `element` tags partition the panel into labeled groups (text / frame / icon /
7
+ // scrollbar) via StateBlock; labels drop the prefix the group heading carries.
8
+ // Order is permanent → impermanent. Hover overrides the icon color only.
8
9
  const states: Record<string, Token[]> = {
9
10
  default: [
10
- { label: 'surface', variable: '--codesnippet-surface' },
11
- { label: 'border', variable: '--codesnippet-border' },
12
- { label: 'border width', variable: '--codesnippet-border-width' },
13
- { label: 'corner radius', variable: '--codesnippet-radius' },
14
- { label: 'padding', variable: '--codesnippet-padding' },
15
- { label: 'gap', variable: '--codesnippet-gap' },
16
- { label: 'code text', variable: '--codesnippet-code-text' },
17
- { label: 'code font family', variable: '--codesnippet-code-font-family' },
18
- { label: 'code font size', variable: '--codesnippet-code-font-size' },
19
- { label: 'code font weight', variable: '--codesnippet-code-font-weight' },
20
- { label: 'code line height', variable: '--codesnippet-code-line-height' },
21
- { label: 'icon color', variable: '--codesnippet-icon' },
22
- { label: 'icon size', variable: '--codesnippet-icon-size' },
11
+ { label: 'color', element: 'text', variable: '--codesnippet-code-text' },
12
+ { label: 'font family', element: 'text', variable: '--codesnippet-code-font-family' },
13
+ { label: 'font size', element: 'text', variable: '--codesnippet-code-font-size' },
14
+ { label: 'font weight', element: 'text', variable: '--codesnippet-code-font-weight' },
15
+ { label: 'line height', element: 'text', variable: '--codesnippet-code-line-height' },
16
+
17
+ { label: 'surface', element: 'frame', variable: '--codesnippet-surface' },
18
+ { label: 'border', element: 'frame', variable: '--codesnippet-border' },
19
+ { label: 'border width', element: 'frame', variable: '--codesnippet-border-width' },
20
+ { label: 'corner radius', element: 'frame', variable: '--codesnippet-radius' },
21
+ { label: 'padding', element: 'frame', variable: '--codesnippet-padding' },
22
+ { label: 'gap', element: 'frame', variable: '--codesnippet-gap' },
23
+
24
+ { label: 'color', element: 'icon', variable: '--codesnippet-icon' },
25
+ { label: 'size', element: 'icon', variable: '--codesnippet-icon-size' },
26
+
27
+ { label: 'thumb', element: 'scrollbar', variable: '--codesnippet-scrollbar-thumb' },
28
+ { label: 'width', element: 'scrollbar', variable: '--codesnippet-scrollbar-border-width' },
23
29
  ],
24
30
  hover: [
25
31
  { label: 'icon color', variable: '--codesnippet-hover-icon' },
@@ -33,19 +39,30 @@
33
39
  import CodeSnippet from '../../system/components/CodeSnippet.svelte';
34
40
  import VariantGroup from './scaffolding/VariantGroup.svelte';
35
41
  import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
42
+
43
+ let previewCode = $state('npx @motion-proto/live-tokens setup-claude');
36
44
  </script>
37
45
 
38
46
  <ComponentEditorBase
39
47
  {component}
40
48
  title="Code Snippet"
41
- description="Single-line code display with a copy button. Shows a brief confirmation popover on copy."
49
+ description="Code display with a copy button. Long lines scroll horizontally; the copy button stays pinned top-right. Shows a brief confirmation popover on copy."
42
50
  tokens={allTokens}
43
51
  >
44
52
  <VariantGroup name="codesnippet" title="Code Snippet" {states} {component}>
45
53
  {#snippet children({ activeState })}
46
54
  <div class="codesnippet-preview">
55
+ <label class="preview-text">
56
+ <span>Preview text</span>
57
+ <textarea
58
+ bind:value={previewCode}
59
+ rows="2"
60
+ spellcheck="false"
61
+ placeholder="Paste a long command or block to preview scrolling"
62
+ ></textarea>
63
+ </label>
47
64
  <CodeSnippet
48
- code="npx @motion-proto/live-tokens setup-claude"
65
+ code={previewCode}
49
66
  class={activeState === 'hover' ? 'force-hover' : ''}
50
67
  />
51
68
  </div>
@@ -56,6 +73,35 @@
56
73
  <style>
57
74
  .codesnippet-preview {
58
75
  display: flex;
76
+ flex-direction: column;
77
+ gap: var(--ui-space-12);
59
78
  padding: var(--ui-space-16);
60
79
  }
80
+
81
+ /* Fixed width so pasted content overflows and demonstrates horizontal scroll. */
82
+ .codesnippet-preview :global(.codesnippet) {
83
+ width: 24rem;
84
+ max-width: 100%;
85
+ }
86
+
87
+ .preview-text {
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: var(--ui-space-4);
91
+ font-size: var(--ui-font-size-sm);
92
+ color: var(--ui-text-secondary);
93
+ }
94
+
95
+ .preview-text textarea {
96
+ width: 100%;
97
+ padding: var(--ui-space-8);
98
+ background: var(--ui-surface-lowest);
99
+ color: var(--ui-text-primary);
100
+ border: 1px solid var(--ui-border-low);
101
+ border-radius: var(--ui-radius-sm);
102
+ font-family: var(--ui-font-mono);
103
+ font-size: var(--ui-font-size-sm);
104
+ resize: vertical;
105
+ }
106
+ .preview-text textarea::placeholder { color: var(--ui-text-muted); opacity: 1; }
61
107
  </style>
@@ -12,13 +12,13 @@
12
12
  const variantOptions = buttons.map((b) => ({ value: b, label: b === 'save' ? 'Save button' : 'Cancel button' }));
13
13
  function buttonStateTokens(btn: Button, state: 'default' | 'hover'): Token[] {
14
14
  return [
15
- { label: 'surface color', groupKey: 'surface', variable: `--inlineeditactions-${btn}-${state}-surface` },
16
- { label: 'text color', groupKey: 'text', variable: `--inlineeditactions-${btn}-${state}-text` },
17
- { label: 'border color', groupKey: 'border', variable: `--inlineeditactions-${btn}-${state}-border` },
18
- { label: 'border width', canBeLinked: true, groupKey: `${btn}-border-width`, variable: `--inlineeditactions-${btn}-${state}-border-width` },
19
- { label: 'corner radius', canBeLinked: true, groupKey: `${btn}-radius`, variable: `--inlineeditactions-${btn}-${state}-radius` },
20
- { label: 'padding', canBeLinked: true, groupKey: `${btn}-padding`, variable: `--inlineeditactions-${btn}-${state}-padding` },
21
- { label: 'icon size', canBeLinked: true, groupKey: `${btn}-icon-size`, variable: `--inlineeditactions-${btn}-${state}-icon-size` },
15
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: `--inlineeditactions-${btn}-${state}-surface` },
16
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: `--inlineeditactions-${btn}-${state}-border` },
17
+ { label: 'border width', element: 'frame', canBeLinked: true, groupKey: `${btn}-border-width`, variable: `--inlineeditactions-${btn}-${state}-border-width` },
18
+ { label: 'corner radius', element: 'frame', canBeLinked: true, groupKey: `${btn}-radius`, variable: `--inlineeditactions-${btn}-${state}-radius` },
19
+ { label: 'padding', element: 'frame', canBeLinked: true, groupKey: `${btn}-padding`, variable: `--inlineeditactions-${btn}-${state}-padding` },
20
+ { label: 'color', element: 'text', groupKey: 'text', variable: `--inlineeditactions-${btn}-${state}-text` },
21
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: `${btn}-icon-size`, variable: `--inlineeditactions-${btn}-${state}-icon-size` },
22
22
  ];
23
23
  }
24
24
 
@@ -15,24 +15,24 @@
15
15
  { label: 'message gap', groupKey: 'gap', variable: '--input-gap' },
16
16
  ],
17
17
  default: [
18
- { label: 'surface color', groupKey: 'surface', variable: '--input-default-surface' },
19
- { label: 'border color', groupKey: 'border', variable: '--input-default-border' },
20
- { label: 'placeholder color', groupKey: 'placeholder', variable: '--input-default-placeholder' },
21
- { label: 'icon color', groupKey: 'icon', variable: '--input-default-icon' },
22
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--input-default-icon-size' },
18
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--input-default-surface' },
19
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: '--input-default-border' },
20
+ { label: 'placeholder color', element: 'frame', groupKey: 'placeholder', variable: '--input-default-placeholder' },
21
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--input-default-icon' },
22
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--input-default-icon-size' },
23
23
  ],
24
24
  focused: [
25
- { label: 'surface color', groupKey: 'surface', variable: '--input-focused-surface' },
26
- { label: 'border color', groupKey: 'border', variable: '--input-focused-border' },
27
- { label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: '--input-focused-border-width' },
28
- { label: 'icon color', groupKey: 'icon', variable: '--input-focused-icon' },
29
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--input-focused-icon-size' },
25
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--input-focused-surface' },
26
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: '--input-focused-border' },
27
+ { label: 'border width', element: 'frame', canBeLinked: true, groupKey: 'border-width', variable: '--input-focused-border-width' },
28
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--input-focused-icon' },
29
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--input-focused-icon-size' },
30
30
  ],
31
31
  disabled: [
32
- { label: 'surface color', groupKey: 'surface', variable: '--input-disabled-surface' },
33
- { label: 'border color', groupKey: 'border', variable: '--input-disabled-border' },
34
- { label: 'icon color', groupKey: 'icon', variable: '--input-disabled-icon' },
35
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--input-disabled-icon-size' },
32
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--input-disabled-surface' },
33
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: '--input-disabled-border' },
34
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--input-disabled-icon' },
35
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--input-disabled-icon-size' },
36
36
  ],
37
37
  label: [],
38
38
  hint: [],
@@ -46,7 +46,8 @@
46
46
  // Slot-prefixed groupKeys keep label/hint/error from collapsing into each other.
47
47
  const typeGroups: Record<string, TypeGroupConfig[]> = {
48
48
  default: [{
49
- legend: 'input text',
49
+ legend: '',
50
+ element: 'text',
50
51
  colorVariable: '--input-default-text',
51
52
  familyVariable: '--input-default-text-font-family',
52
53
  sizeVariable: '--input-default-text-font-size',
@@ -54,7 +55,8 @@
54
55
  lineHeightVariable: '--input-default-text-line-height',
55
56
  }],
56
57
  focused: [{
57
- legend: 'input text',
58
+ legend: '',
59
+ element: 'text',
58
60
  colorVariable: '--input-focused-text',
59
61
  familyVariable: '--input-focused-text-font-family',
60
62
  sizeVariable: '--input-focused-text-font-size',
@@ -62,7 +64,8 @@
62
64
  lineHeightVariable: '--input-focused-text-line-height',
63
65
  }],
64
66
  disabled: [{
65
- legend: 'input text',
67
+ legend: '',
68
+ element: 'text',
66
69
  colorVariable: '--input-disabled-text',
67
70
  familyVariable: '--input-disabled-text-font-family',
68
71
  sizeVariable: '--input-disabled-text-font-size',
@@ -7,43 +7,44 @@
7
7
  // Non-text tokens per state; text/font lives in typeGroups. Item-shape tokens sit under `menu` so they read as one decision across states.
8
8
  const states: Record<string, Token[]> = {
9
9
  menu: [
10
- { label: 'surface color', groupKey: 'surface', variable: '--menuselect-menu-surface' },
11
- { label: 'border color', groupKey: 'border', variable: '--menuselect-menu-border' },
12
- { label: 'border width', groupKey: 'width', variable: '--menuselect-menu-border-width' },
13
- { label: 'corner radius', groupKey: 'menu-radius', variable: '--menuselect-menu-radius' },
14
- { label: 'padding', variable: '--menuselect-menu-padding', groupKey: 'menu-padding' },
15
- { label: 'item gap', groupKey: 'gap', variable: '--menuselect-menu-gap' },
16
- { label: 'shadow', groupKey: 'shadow', variable: '--menuselect-menu-shadow' },
17
- { label: 'item radius', groupKey: 'item-radius', variable: '--menuselect-item-radius' },
18
- { label: 'item padding', variable: '--menuselect-item-padding', groupKey: 'item-padding' },
10
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--menuselect-menu-surface' },
11
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: '--menuselect-menu-border' },
12
+ { label: 'border width', element: 'frame', groupKey: 'width', variable: '--menuselect-menu-border-width' },
13
+ { label: 'corner radius', element: 'frame', groupKey: 'menu-radius', variable: '--menuselect-menu-radius' },
14
+ { label: 'padding', element: 'frame', variable: '--menuselect-menu-padding', groupKey: 'menu-padding' },
15
+ { label: 'item gap', element: 'frame', groupKey: 'gap', variable: '--menuselect-menu-gap' },
16
+ { label: 'shadow', element: 'frame', groupKey: 'shadow', variable: '--menuselect-menu-shadow' },
17
+ { label: 'radius', element: 'item', groupKey: 'item-radius', variable: '--menuselect-item-radius' },
18
+ { label: 'padding', element: 'item', variable: '--menuselect-item-padding', groupKey: 'item-padding' },
19
19
  ],
20
20
  'default item': [
21
- { label: 'surface color', groupKey: 'surface', variable: '--menuselect-default-surface' },
22
- { label: 'icon color', groupKey: 'icon', variable: '--menuselect-default-icon' },
23
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-default-icon-size' },
21
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--menuselect-default-surface' },
22
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--menuselect-default-icon' },
23
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-default-icon-size' },
24
24
  ],
25
25
  'hover item': [
26
- { label: 'surface color', groupKey: 'surface', variable: '--menuselect-hover-surface' },
27
- { label: 'icon color', groupKey: 'icon', variable: '--menuselect-hover-icon' },
28
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-hover-icon-size' },
26
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--menuselect-hover-surface' },
27
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--menuselect-hover-icon' },
28
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-hover-icon-size' },
29
29
  ],
30
30
  'selected item': [
31
- { label: 'surface color', groupKey: 'surface', variable: '--menuselect-selected-surface' },
32
- { label: 'icon color', groupKey: 'icon', variable: '--menuselect-selected-icon' },
33
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-selected-icon-size' },
34
- { label: 'indicator color', groupKey: 'indicator', variable: '--menuselect-selected-indicator' },
31
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--menuselect-selected-surface' },
32
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--menuselect-selected-icon' },
33
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-selected-icon-size' },
34
+ { label: 'color', element: 'indicator', groupKey: 'indicator', variable: '--menuselect-selected-indicator' },
35
35
  ],
36
36
  'disabled item': [
37
- { label: 'surface color', groupKey: 'surface', variable: '--menuselect-disabled-surface' },
38
- { label: 'icon color', groupKey: 'icon', variable: '--menuselect-disabled-icon' },
39
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-disabled-icon-size' },
37
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--menuselect-disabled-surface' },
38
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--menuselect-disabled-icon' },
39
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-disabled-icon-size' },
40
40
  ],
41
41
  };
42
42
 
43
43
  // Per-state item-label typography; linkable groupKeys let users collapse or diverge across states.
44
44
  const typeGroups: Record<string, TypeGroupConfig[]> = {
45
45
  'default item': [{
46
- legend: 'item label',
46
+ legend: '',
47
+ element: 'text',
47
48
  colorVariable: '--menuselect-default-text',
48
49
  familyVariable: '--menuselect-default-text-font-family',
49
50
  sizeVariable: '--menuselect-default-text-font-size',
@@ -51,7 +52,8 @@
51
52
  lineHeightVariable: '--menuselect-default-text-line-height',
52
53
  }],
53
54
  'hover item': [{
54
- legend: 'item label',
55
+ legend: '',
56
+ element: 'text',
55
57
  colorVariable: '--menuselect-hover-text',
56
58
  familyVariable: '--menuselect-hover-text-font-family',
57
59
  sizeVariable: '--menuselect-hover-text-font-size',
@@ -59,7 +61,8 @@
59
61
  lineHeightVariable: '--menuselect-hover-text-line-height',
60
62
  }],
61
63
  'selected item': [{
62
- legend: 'item label',
64
+ legend: '',
65
+ element: 'text',
63
66
  colorVariable: '--menuselect-selected-text',
64
67
  familyVariable: '--menuselect-selected-text-font-family',
65
68
  sizeVariable: '--menuselect-selected-text-font-size',
@@ -67,7 +70,8 @@
67
70
  lineHeightVariable: '--menuselect-selected-text-line-height',
68
71
  }],
69
72
  'disabled item': [{
70
- legend: 'item label',
73
+ legend: '',
74
+ element: 'text',
71
75
  colorVariable: '--menuselect-disabled-text',
72
76
  familyVariable: '--menuselect-disabled-text-font-family',
73
77
  sizeVariable: '--menuselect-disabled-text-font-size',
@@ -8,20 +8,21 @@
8
8
  // not a per-variant token namespace.
9
9
  const states: Record<string, Token[]> = {
10
10
  default: [
11
- { label: 'fill color', groupKey: 'fill', variable: '--progressbar-fill' },
12
- { label: 'track surface color', groupKey: 'surface', variable: '--progressbar-track-surface' },
13
- { label: 'track border color', groupKey: 'border', variable: '--progressbar-track-border' },
14
- { label: 'track border width', canBeLinked: true, groupKey: 'track-border-width', variable: '--progressbar-track-border-width' },
15
- { label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: '--progressbar-radius' },
16
- { label: 'track height', canBeLinked: true, groupKey: 'track-height', variable: '--progressbar-track-height' },
17
- { label: 'label gap', groupKey: 'label-gap', variable: '--progressbar-label-gap' },
11
+ { label: 'color', element: 'fill', groupKey: 'fill', variable: '--progressbar-fill' },
12
+ { label: 'surface', element: 'frame', groupKey: 'surface', variable: '--progressbar-track-surface' },
13
+ { label: 'border', element: 'frame', groupKey: 'border', variable: '--progressbar-track-border' },
14
+ { label: 'border width', element: 'frame', canBeLinked: true, groupKey: 'track-border-width', variable: '--progressbar-track-border-width' },
15
+ { label: 'corner radius', element: 'frame', canBeLinked: true, groupKey: 'radius', variable: '--progressbar-radius' },
16
+ { label: 'height', element: 'frame', canBeLinked: true, groupKey: 'track-height', variable: '--progressbar-track-height' },
17
+ { label: 'label gap', element: 'frame', groupKey: 'label-gap', variable: '--progressbar-label-gap' },
18
18
  ],
19
19
  };
20
20
 
21
21
  const typeGroups: Record<string, TypeGroupConfig[]> = {
22
22
  default: [
23
23
  {
24
- legend: 'label',
24
+ legend: '',
25
+ element: 'label',
25
26
  colorVariable: '--progressbar-label',
26
27
  familyVariable: '--progressbar-label-font-family',
27
28
  sizeVariable: '--progressbar-label-font-size',
@@ -29,7 +30,8 @@
29
30
  lineHeightVariable: '--progressbar-label-line-height',
30
31
  },
31
32
  {
32
- legend: 'value',
33
+ legend: '',
34
+ element: 'value',
33
35
  colorVariable: '--progressbar-value',
34
36
  familyVariable: '--progressbar-value-font-family',
35
37
  sizeVariable: '--progressbar-value-font-size',
@@ -10,15 +10,15 @@
10
10
  // they don't vary per state in the runtime.
11
11
  const defaultStates: Record<string, Token[]> = {
12
12
  'control bar': [
13
- { label: 'surface color', groupKey: 'surface', variable: '--segmentedcontrol-bar-surface' },
14
- { label: 'border color', groupKey: 'border', variable: '--segmentedcontrol-bar-border' },
15
- { label: 'border width', groupKey: 'width', variable: '--segmentedcontrol-bar-border-width' },
16
- { label: 'divider color', groupKey: 'color', variable: '--segmentedcontrol-divider-color' },
17
- { label: 'divider width', groupKey: 'thickness', variable: '--segmentedcontrol-divider-thickness' },
18
- { label: 'divider inset', groupKey: 'divider-inset', variable: '--segmentedcontrol-divider-inset' },
19
- { label: 'corner radius', groupKey: 'radius', variable: '--segmentedcontrol-bar-radius' },
20
- { label: 'option gap', groupKey: 'gap', variable: '--segmentedcontrol-bar-gap' },
21
- { label: 'padding', variable: '--segmentedcontrol-bar-padding', groupKey: 'bar-padding' },
13
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--segmentedcontrol-bar-surface' },
14
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: '--segmentedcontrol-bar-border' },
15
+ { label: 'border width', element: 'frame', groupKey: 'width', variable: '--segmentedcontrol-bar-border-width' },
16
+ { label: 'color', element: 'divider', groupKey: 'color', variable: '--segmentedcontrol-divider-color' },
17
+ { label: 'width', element: 'divider', groupKey: 'thickness', variable: '--segmentedcontrol-divider-thickness' },
18
+ { label: 'inset', element: 'divider', groupKey: 'divider-inset', variable: '--segmentedcontrol-divider-inset' },
19
+ { label: 'corner radius', element: 'frame', groupKey: 'radius', variable: '--segmentedcontrol-bar-radius' },
20
+ { label: 'option gap', element: 'frame', groupKey: 'gap', variable: '--segmentedcontrol-bar-gap' },
21
+ { label: 'padding', element: 'frame', variable: '--segmentedcontrol-bar-padding', groupKey: 'bar-padding' },
22
22
  ],
23
23
  'option base': [
24
24
  { label: 'padding', variable: '--segmentedcontrol-option-padding', groupKey: 'option-padding' },
@@ -29,11 +29,11 @@
29
29
  { label: 'icon color', groupKey: 'icon', variable: '--segmentedcontrol-option-icon' },
30
30
  ],
31
31
  'selected option': [
32
- { label: 'surface color', groupKey: 'surface', variable: '--segmentedcontrol-selected-surface' },
33
- { label: 'icon color', groupKey: 'icon', variable: '--segmentedcontrol-selected-icon' },
34
- { label: 'border color', groupKey: 'border', variable: '--segmentedcontrol-selected-border' },
35
- { label: 'border width', groupKey: 'width', variable: '--segmentedcontrol-selected-border-width' },
36
- { label: 'corner radius', groupKey: 'radius', variable: '--segmentedcontrol-selected-radius' },
32
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--segmentedcontrol-selected-surface' },
33
+ { label: 'color', element: 'icon', groupKey: 'icon', variable: '--segmentedcontrol-selected-icon' },
34
+ { label: 'border color', element: 'frame', groupKey: 'border', variable: '--segmentedcontrol-selected-border' },
35
+ { label: 'border width', element: 'frame', groupKey: 'width', variable: '--segmentedcontrol-selected-border-width' },
36
+ { label: 'corner radius', element: 'frame', groupKey: 'radius', variable: '--segmentedcontrol-selected-radius' },
37
37
  ],
38
38
  'hover option': [
39
39
  { label: 'surface color', groupKey: 'surface', variable: '--segmentedcontrol-option-hover-surface' },
@@ -52,10 +52,10 @@
52
52
  // since family/weight/color don't differ.
53
53
  const smallStates: Record<string, Token[]> = {
54
54
  'control bar': [
55
- { label: 'divider inset', groupKey: 'small-divider-inset', variable: '--segmentedcontrol-small-divider-inset' },
56
- { label: 'divider width', groupKey: 'small-divider-thickness', variable: '--segmentedcontrol-small-divider-thickness' },
57
- { label: 'corner radius', groupKey: 'small-radius', variable: '--segmentedcontrol-bar-small-radius' },
58
- { label: 'padding', variable: '--segmentedcontrol-bar-small-padding', groupKey: 'bar-small-padding' },
55
+ { label: 'corner radius', element: 'frame', groupKey: 'small-radius', variable: '--segmentedcontrol-bar-small-radius' },
56
+ { label: 'padding', element: 'frame', variable: '--segmentedcontrol-bar-small-padding', groupKey: 'bar-small-padding' },
57
+ { label: 'inset', element: 'divider', groupKey: 'small-divider-inset', variable: '--segmentedcontrol-small-divider-inset' },
58
+ { label: 'width', element: 'divider', groupKey: 'small-divider-thickness', variable: '--segmentedcontrol-small-divider-thickness' },
59
59
  ],
60
60
  'option base': [
61
61
  { label: 'icon size', groupKey: 'small-icon-size', variable: '--segmentedcontrol-option-small-icon-size' },
@@ -80,7 +80,8 @@
80
80
  lineHeightVariable: '--segmentedcontrol-option-text-line-height',
81
81
  }],
82
82
  'selected option': [{
83
- legend: 'option text',
83
+ legend: '',
84
+ element: 'text',
84
85
  colorVariable: '--segmentedcontrol-selected-text',
85
86
  familyVariable: '--segmentedcontrol-selected-text-font-family',
86
87
  sizeVariable: '--segmentedcontrol-selected-text-font-size',
@@ -7,21 +7,25 @@
7
7
  // The tab object — four states (default/hover/active/disabled) of the same tab button.
8
8
  const tabStateNames = ['default', 'hover', 'active', 'disabled'] as const;
9
9
  type TabState = typeof tabStateNames[number];
10
+ // `element` tags split each tab state into frame / icon / indicator / text.
11
+ // No elementOrder: it would force the flat `bar` state into grouped mode.
12
+ // Frame tokens lead so sections read frame → icon → indicator → text (typeGroup last).
10
13
  function tabStateTokens(s: TabState): Token[] {
11
14
  return [
12
- { label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: `--tabbar-${s}-icon-size` },
13
- { label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `--tabbar-${s}-padding` },
14
- { label: 'surface color', groupKey: 'surface', variable: `--tabbar-${s}-surface` },
15
- { label: 'top radius', canBeLinked: true, groupKey: 'tab-top-radius', variable: `--tabbar-${s}-tab-top-radius` },
16
- { label: 'bottom radius', canBeLinked: true, groupKey: 'tab-bottom-radius', variable: `--tabbar-${s}-tab-bottom-radius` },
17
- { label: 'border color', canBeLinked: true, groupKey: 'tab-border-color', variable: `--tabbar-${s}-tab-border-color` },
18
- { label: 'border width', canBeLinked: true, groupKey: 'tab-border-width', variable: `--tabbar-${s}-tab-border-width` },
19
- { label: 'indicator width', canBeLinked: true, groupKey: 'indicator-border-width', variable: `--tabbar-${s}-indicator-border-width` },
15
+ { label: 'surface color', element: 'frame', groupKey: 'surface', variable: `--tabbar-${s}-surface` },
16
+ { label: 'top radius', element: 'frame', canBeLinked: true, groupKey: 'tab-top-radius', variable: `--tabbar-${s}-tab-top-radius` },
17
+ { label: 'bottom radius', element: 'frame', canBeLinked: true, groupKey: 'tab-bottom-radius', variable: `--tabbar-${s}-tab-bottom-radius` },
18
+ { label: 'border color', element: 'frame', canBeLinked: true, groupKey: 'tab-border-color', variable: `--tabbar-${s}-tab-border-color` },
19
+ { label: 'border width', element: 'frame', canBeLinked: true, groupKey: 'tab-border-width', variable: `--tabbar-${s}-tab-border-width` },
20
+ { label: 'padding', element: 'frame', canBeLinked: true, groupKey: 'padding', variable: `--tabbar-${s}-padding` },
21
+ { label: 'size', element: 'icon', canBeLinked: true, groupKey: 'icon-size', variable: `--tabbar-${s}-icon-size` },
22
+ { label: 'width', element: 'indicator', canBeLinked: true, groupKey: 'indicator-border-width', variable: `--tabbar-${s}-indicator-border-width` },
20
23
  ];
21
24
  }
22
25
  function tabStateTypeGroups(s: TabState): TypeGroupConfig[] {
23
26
  return [{
24
- legend: 'tab text',
27
+ legend: '',
28
+ element: 'text',
25
29
  colorVariable: `--tabbar-${s}-text`,
26
30
  familyVariable: `--tabbar-${s}-text-font-family`,
27
31
  sizeVariable: `--tabbar-${s}-text-font-size`,
@@ -48,7 +52,7 @@
48
52
  };
49
53
  states['active tab'] = [
50
54
  ...states['active tab'],
51
- { label: 'indicator color', groupKey: 'indicator-color', variable: '--tabbar-active-border' },
55
+ { label: 'color', element: 'indicator', groupKey: 'indicator-color', variable: '--tabbar-active-border' },
52
56
  ];
53
57
  const typeGroups: Record<string, TypeGroupConfig[]> = Object.fromEntries(
54
58
  tabStateNames.map((s) => [`${s} tab`, tabStateTypeGroups(s)]),
@@ -8,29 +8,29 @@
8
8
  // on top of that baseline.
9
9
  const states: Record<string, Token[]> = {
10
10
  default: [
11
- { label: 'thumb size', variable: '--toggle-thumb-size' },
12
- { label: 'track padding', variable: '--toggle-track-padding' },
13
- { label: 'track radius', variable: '--toggle-track-radius' },
14
- { label: 'track border width',variable: '--toggle-track-border-width' },
15
- { label: 'track border', variable: '--toggle-track-border' },
16
- { label: 'track surface', variable: '--toggle-track-surface' },
17
- { label: 'thumb border', variable: '--toggle-thumb-border' },
18
- { label: 'thumb surface', variable: '--toggle-thumb-surface' },
19
- { label: 'label text', variable: '--toggle-label-text' },
20
- { label: 'label font family', variable: '--toggle-label-font-family' },
21
- { label: 'label font size', variable: '--toggle-label-font-size' },
22
- { label: 'label font weight', variable: '--toggle-label-font-weight' },
23
- { label: 'label gap', variable: '--toggle-gap' },
11
+ { label: 'surface', element: 'track', variable: '--toggle-track-surface' },
12
+ { label: 'border', element: 'track', variable: '--toggle-track-border' },
13
+ { label: 'border width', element: 'track', variable: '--toggle-track-border-width' },
14
+ { label: 'radius', element: 'track', variable: '--toggle-track-radius' },
15
+ { label: 'padding', element: 'track', variable: '--toggle-track-padding' },
16
+ { label: 'surface', element: 'thumb', variable: '--toggle-thumb-surface' },
17
+ { label: 'border', element: 'thumb', variable: '--toggle-thumb-border' },
18
+ { label: 'size', element: 'thumb', variable: '--toggle-thumb-size' },
19
+ { label: 'text', element: 'label', variable: '--toggle-label-text' },
20
+ { label: 'font family', element: 'label', variable: '--toggle-label-font-family' },
21
+ { label: 'font size', element: 'label', variable: '--toggle-label-font-size' },
22
+ { label: 'font weight', element: 'label', variable: '--toggle-label-font-weight' },
23
+ { label: 'gap', element: 'label', variable: '--toggle-gap' },
24
24
  ],
25
25
  hover: [
26
26
  { label: 'track surface', variable: '--toggle-hover-track-surface' },
27
27
  { label: 'thumb surface', variable: '--toggle-hover-thumb-surface' },
28
28
  ],
29
29
  on: [
30
- { label: 'track surface', variable: '--toggle-on-track-surface' },
31
- { label: 'track border', variable: '--toggle-on-track-border' },
32
- { label: 'thumb surface', variable: '--toggle-on-thumb-surface' },
33
- { label: 'thumb border', variable: '--toggle-on-thumb-border' },
30
+ { label: 'surface', element: 'track', variable: '--toggle-on-track-surface' },
31
+ { label: 'border', element: 'track', variable: '--toggle-on-track-border' },
32
+ { label: 'surface', element: 'thumb', variable: '--toggle-on-thumb-surface' },
33
+ { label: 'border', element: 'thumb', variable: '--toggle-on-thumb-border' },
34
34
  ],
35
35
  'on hover': [
36
36
  { label: 'track surface', variable: '--toggle-on-hover-track-surface' },
@@ -4,21 +4,22 @@
4
4
 
5
5
  export const component = 'tooltip';
6
6
 
7
- // Tooltip is a single object surface/border/padding/radius/shadow live together.
7
+ // Element tags split the panel into frame + text via StateBlock.
8
8
  const states: Record<string, Token[]> = {
9
9
  tooltip: [
10
- { label: 'surface color', variable: '--tooltip-surface' },
11
- { label: 'border color', variable: '--tooltip-border' },
12
- { label: 'border width', groupKey: 'width', variable: '--tooltip-border-width' },
13
- { label: 'corner radius', variable: '--tooltip-radius' },
14
- { label: 'padding', variable: '--tooltip-padding' },
15
- { label: 'tooltip shadow', variable: '--tooltip-shadow' },
10
+ { label: 'surface color', element: 'frame', variable: '--tooltip-surface' },
11
+ { label: 'border color', element: 'frame', variable: '--tooltip-border' },
12
+ { label: 'border width', element: 'frame', groupKey: 'width', variable: '--tooltip-border-width' },
13
+ { label: 'corner radius', element: 'frame', variable: '--tooltip-radius' },
14
+ { label: 'padding', element: 'frame', variable: '--tooltip-padding' },
15
+ { label: 'shadow', element: 'frame', variable: '--tooltip-shadow' },
16
16
  ],
17
17
  };
18
18
 
19
19
  const typeGroups: Record<string, TypeGroupConfig[]> = {
20
20
  tooltip: [{
21
- legend: 'tooltip text',
21
+ legend: '',
22
+ element: 'text',
22
23
  colorVariable: '--tooltip-text',
23
24
  familyVariable: '--tooltip-text-font-family',
24
25
  sizeVariable: '--tooltip-text-font-size',
@@ -1,6 +1,6 @@
1
1
  <!--
2
- CodeSnippet.svelte — single-line code display with a copy button. Click the
3
- button to copy `code` to the clipboard; a Tooltip-rendered confirmation
2
+ CodeSnippet.svelte — code display with a copy button pinned top-right. Click
3
+ the button to copy `code` to the clipboard; a Tooltip-rendered confirmation
4
4
  ("Copied") flashes briefly above the button.
5
5
  -->
6
6
  <script lang="ts">
@@ -71,11 +71,15 @@
71
71
  --codesnippet-icon: var(--text-secondary);
72
72
  --codesnippet-icon-size: var(--font-size-md);
73
73
  --codesnippet-hover-icon: var(--text-primary);
74
+
75
+ /* Horizontal-scroll scrollbar. */
76
+ --codesnippet-scrollbar-border-width: var(--border-width-6);
77
+ --codesnippet-scrollbar-thumb: var(--text-tertiary);
74
78
  }
75
79
 
76
80
  .codesnippet {
77
81
  display: inline-flex;
78
- align-items: center;
82
+ align-items: flex-start;
79
83
  gap: var(--codesnippet-gap);
80
84
  max-width: 100%;
81
85
  padding: var(--codesnippet-padding);
@@ -93,8 +97,22 @@
93
97
  font-weight: var(--codesnippet-code-font-weight);
94
98
  line-height: var(--codesnippet-code-line-height);
95
99
  white-space: pre;
96
- overflow: hidden;
97
- text-overflow: ellipsis;
100
+ overflow-x: auto;
101
+ scrollbar-width: thin;
102
+ scrollbar-color: var(--codesnippet-scrollbar-thumb) transparent;
103
+ }
104
+
105
+ .code::-webkit-scrollbar {
106
+ height: var(--codesnippet-scrollbar-border-width);
107
+ }
108
+
109
+ .code::-webkit-scrollbar-track {
110
+ background: transparent;
111
+ }
112
+
113
+ .code::-webkit-scrollbar-thumb {
114
+ background: var(--codesnippet-scrollbar-thumb);
115
+ border-radius: var(--radius-full);
98
116
  }
99
117
 
100
118
  .copy {