@motion-proto/live-tokens 0.7.1 → 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 (85) hide show
  1. package/dist-plugin/index.cjs +707 -90
  2. package/dist-plugin/index.d.cts +1 -0
  3. package/dist-plugin/index.d.ts +1 -0
  4. package/dist-plugin/index.js +707 -90
  5. package/package.json +2 -1
  6. package/src/app/site.css +1 -1
  7. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +34 -27
  8. package/src/editor/component-editor/DialogEditor.svelte +4 -4
  9. package/src/editor/component-editor/NotificationEditor.svelte +3 -1
  10. package/src/editor/component-editor/SectionDividerEditor.svelte +439 -112
  11. package/src/editor/component-editor/StandardButtonsEditor.svelte +13 -1
  12. package/src/editor/component-editor/editors.d.ts +10 -0
  13. package/src/editor/component-editor/scaffolding/AngleDial.svelte +52 -13
  14. package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +10 -11
  15. package/src/editor/component-editor/scaffolding/LinkedBlock.svelte +0 -1
  16. package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
  17. package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +15 -2
  18. package/src/editor/component-editor/scaffolding/StateBlock.svelte +103 -15
  19. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +9 -6
  20. package/src/editor/component-editor/scaffolding/TypeEditor.svelte +13 -1
  21. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +239 -25
  22. package/src/editor/component-editor/scaffolding/buildTypeGroupTokens.ts +1 -0
  23. package/src/editor/component-editor/scaffolding/types.ts +11 -0
  24. package/src/editor/core/components/componentConfigKeys.ts +8 -0
  25. package/src/editor/core/components/componentConfigService.ts +2 -2
  26. package/src/editor/core/components/componentPersist.ts +7 -5
  27. package/src/editor/core/manifests/manifestService.ts +58 -3
  28. package/src/editor/core/palettes/familySwap.ts +99 -0
  29. package/src/editor/core/palettes/paletteDerivation.ts +69 -0
  30. package/src/editor/core/palettes/tokenRegistry.ts +4 -1
  31. package/src/editor/core/store/editorStore.ts +206 -12
  32. package/src/editor/core/store/editorTypes.ts +55 -12
  33. package/src/editor/core/store/gradientSource.ts +192 -0
  34. package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
  35. package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
  36. package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
  37. package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
  38. package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
  39. package/src/editor/core/themes/migrations/index.ts +10 -0
  40. package/src/editor/core/themes/slices/components.ts +18 -4
  41. package/src/editor/core/themes/slices/gradients.ts +88 -13
  42. package/src/editor/core/themes/themeInit.ts +2 -2
  43. package/src/editor/core/themes/themeTypes.ts +56 -1
  44. package/src/editor/overlay/ColumnsOverlay.svelte +0 -1
  45. package/src/editor/overlay/LiveEditorOverlay.svelte +1 -4
  46. package/src/editor/styles/ui-editor.css +1 -0
  47. package/src/editor/styles/ui-form-controls.css +19 -20
  48. package/src/editor/ui/BezierCurveEditor.svelte +114 -63
  49. package/src/editor/ui/EditorViewSwitcher.svelte +0 -1
  50. package/src/editor/ui/FileLoadList.svelte +22 -5
  51. package/src/editor/ui/FontStackEditor.svelte +214 -76
  52. package/src/editor/ui/GradientEditor.svelte +435 -215
  53. package/src/editor/ui/GradientStopPicker.svelte +11 -3
  54. package/src/editor/ui/ManifestFileManager.svelte +71 -4
  55. package/src/editor/ui/PaletteEditor.svelte +52 -79
  56. package/src/editor/ui/ProjectFontsSection.svelte +328 -293
  57. package/src/editor/ui/ThemeFileManager.svelte +0 -4
  58. package/src/editor/ui/UIFontFamilySelector.svelte +0 -1
  59. package/src/editor/ui/UIFontSizeSelector.svelte +3 -0
  60. package/src/editor/ui/UIInfoPopover.svelte +0 -1
  61. package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
  62. package/src/editor/ui/UIPaletteSelector.svelte +31 -4
  63. package/src/editor/ui/UIPillButton.svelte +33 -3
  64. package/src/editor/ui/UISegmentedControl.svelte +114 -0
  65. package/src/editor/ui/UITokenSelector.svelte +4 -1
  66. package/src/editor/ui/VariablesTab.svelte +41 -35
  67. package/src/editor/ui/palette/OverridesPanel.svelte +14 -37
  68. package/src/editor/ui/palette/PaletteBase.svelte +3 -3
  69. package/src/editor/ui/sections/ColumnsSection.svelte +1 -2
  70. package/src/editor/ui/sections/GradientsSection.svelte +1 -1
  71. package/src/editor/ui/sections/OverlaysSection.svelte +1 -1
  72. package/src/editor/ui/sections/ShadowsSection.svelte +1 -1
  73. package/src/system/components/Button.svelte +2 -2
  74. package/src/system/components/Card.svelte +29 -1
  75. package/src/system/components/CollapsibleSection.svelte +25 -2
  76. package/src/system/components/FloatingTokenTags.css +43 -24
  77. package/src/system/components/FloatingTokenTags.svelte +88 -137
  78. package/src/system/components/Notification.svelte +8 -1
  79. package/src/system/components/SectionDivider.svelte +456 -379
  80. package/src/system/styles/CONVENTIONS.md +1 -1
  81. package/src/system/styles/fonts.css +3 -16
  82. package/src/system/styles/tokens.css +356 -1199
  83. package/src/system/styles/tokens.generated.css +544 -0
  84. package/src/editor/component-editor/scaffolding/DividerEditor.svelte +0 -94
  85. package/src/editor/component-editor/scaffolding/GradientCard.svelte +0 -296
@@ -59,11 +59,12 @@
59
59
  .ui-form-select {
60
60
  /* No vertical padding - let min-height and line-height center text naturally */
61
61
  padding: 0 var(--ui-space-16);
62
+ padding-right: var(--ui-space-32);
62
63
  min-height: 2.375rem; /* ~38px to match button height */
63
- background: var(--ui-surface-lowest) !important;
64
- border: 1px solid var(--ui-border) !important;
64
+ background-color: var(--ui-surface-lowest);
65
+ border: 1px solid var(--ui-border);
65
66
  border-radius: var(--ui-radius-md);
66
- color: var(--ui-text-primary) !important;
67
+ color: var(--ui-text-primary);
67
68
  font-family: var(--ui-font-sans);
68
69
  font-size: var(--ui-font-size-md);
69
70
  font-weight: var(--ui-font-weight-normal);
@@ -71,28 +72,26 @@
71
72
  vertical-align: middle;
72
73
  cursor: pointer;
73
74
  transition: all var(--ui-transition-fast);
74
- /* Prevent clipping */
75
- overflow: visible !important;
76
- box-sizing: border-box !important;
75
+ overflow: visible;
76
+ box-sizing: border-box;
77
77
  /* Reset browser defaults */
78
78
  -webkit-appearance: none;
79
79
  -moz-appearance: none;
80
80
  appearance: none;
81
81
  /* Custom dropdown arrow */
82
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M6 8L1 3h10z'/%3E%3C/svg%3E") !important;
83
- background-repeat: no-repeat !important;
84
- background-position: right var(--ui-space-12) center !important;
85
- padding-right: var(--ui-space-32) !important;
82
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
83
+ background-repeat: no-repeat;
84
+ background-position: right var(--ui-space-12) center;
86
85
  }
87
86
 
88
87
  .ui-form-select:hover:not(:disabled) {
89
- background-color: var(--ui-surface-low) !important;
90
- border-color: var(--ui-border-high) !important;
88
+ background-color: var(--ui-surface-low);
89
+ border-color: var(--ui-border-high);
91
90
  }
92
91
 
93
92
  .ui-form-select:focus {
94
93
  outline: none;
95
- border-color: var(--ui-border-higher) !important;
94
+ border-color: var(--ui-border-higher);
96
95
  box-shadow: 0 0 0 2px hsla(0, 58%, 50%, 0.2);
97
96
  }
98
97
 
@@ -102,13 +101,13 @@
102
101
  }
103
102
 
104
103
  .ui-form-select:active:not(:disabled) {
105
- background-color: var(--ui-surface) !important;
104
+ background-color: var(--ui-surface);
106
105
  }
107
106
 
108
107
  .ui-form-select:disabled {
109
- background-color: var(--ui-surface-lowest) !important;
110
- border-color: var(--ui-border-low) !important;
111
- color: var(--ui-text-disabled) !important;
108
+ background-color: var(--ui-surface-lowest);
109
+ border-color: var(--ui-border-low);
110
+ color: var(--ui-text-disabled);
112
111
  cursor: not-allowed;
113
112
  }
114
113
 
@@ -116,8 +115,8 @@
116
115
  /* Note: Most option styling is controlled by browser/OS and cannot be fully overridden */
117
116
  /* These styles apply where browsers allow (limited support in Chrome/Firefox) */
118
117
  .ui-form-select option {
119
- background-color: var(--ui-surface-lowest) !important;
120
- color: var(--ui-text-primary) !important;
118
+ background-color: var(--ui-surface-lowest);
119
+ color: var(--ui-text-primary);
121
120
  padding: var(--ui-space-8) var(--ui-space-12);
122
121
  min-height: 2rem;
123
122
  font-size: var(--ui-font-size-md);
@@ -127,7 +126,7 @@
127
126
 
128
127
  /* Disabled options */
129
128
  .ui-form-select option:disabled {
130
- color: var(--ui-text-disabled) !important;
129
+ color: var(--ui-text-disabled);
131
130
  }
132
131
 
133
132
  /* Input Field Styling */
@@ -8,6 +8,7 @@
8
8
  evalBezier, buildCurvePath, curveTemplates,
9
9
  serializeCurve, deserializeCurve,
10
10
  } from './curveEngine';
11
+ import UIPillButton from './UIPillButton.svelte';
11
12
 
12
13
  interface Props {
13
14
  anchors: CurveAnchor[];
@@ -257,8 +258,31 @@
257
258
  <div class="curve-panel">
258
259
  <div class="curve-panel-header">
259
260
  <span class="curve-panel-label">{cfg.label}</span>
261
+ <div class="curve-help">
262
+ <button class="curve-help-badge" type="button" aria-label="Curve editor help">
263
+ <i class="fas fa-circle-info" aria-hidden="true"></i>
264
+ </button>
265
+ <div class="curve-help-popover" role="tooltip">
266
+ <div><strong>Click</strong> path to add a point</div>
267
+ <div><strong>&#x2325; Click</strong> a point to remove</div>
268
+ <div><strong>Double-click</strong> a point to toggle smooth/corner</div>
269
+ </div>
270
+ </div>
260
271
  </div>
261
- <div class="curve-container" style="padding-inline: calc(50% / {stepCount})">
272
+ <div class="curve-container">
273
+ <div class="curve-chart-overlay">
274
+ <UIPillButton
275
+ size="compact"
276
+ variant={shiftActive ? 'default' : 'outline'}
277
+ title="Vertical offset"
278
+ onclick={() => shiftActive = !shiftActive}
279
+ >
280
+ <svg viewBox="0 0 12 20" class="curve-tool-icon">
281
+ <path d="M6,2 L10,7 L7,7 L7,13 L10,13 L6,18 L2,13 L5,13 L5,7 L2,7 Z" />
282
+ </svg>
283
+ <span>Offset{offset !== 0 ? ` ${offset > 0 ? '+' : ''}${offset}` : ''}</span>
284
+ </UIPillButton>
285
+ </div>
262
286
  <svg
263
287
  bind:this={svgEl}
264
288
  class="curve-svg"
@@ -383,22 +407,9 @@
383
407
  </svg>
384
408
  </div>
385
409
  <div class="curve-toolbar">
386
- <div class="curve-toolbar-left">
387
- <button
388
- class="curve-tool-btn"
389
- class:active={shiftActive}
390
- type="button"
391
- title="Vertical offset"
392
- onclick={() => shiftActive = !shiftActive}
393
- >
394
- <svg viewBox="0 0 12 20" class="curve-tool-icon">
395
- <path d="M6,2 L10,7 L7,7 L7,13 L10,13 L6,18 L2,13 L5,13 L5,7 L2,7 Z" />
396
- </svg>
397
- <span>Offset{offset !== 0 ? ` ${offset > 0 ? '+' : ''}${offset}` : ''}</span>
398
- </button>
399
- <span class="curve-hint">&x2325;-click to remove point</span>
400
- <button class="curve-tool-btn" type="button" title="Copy curve" onclick={copyToClipboard}>Copy</button>
401
- <button class="curve-tool-btn" type="button" title="Paste curve" onclick={pasteFromClipboard}>Paste</button>
410
+ <div class="curve-toolbar-group">
411
+ <UIPillButton size="compact" variant="outline" title="Copy curve" onclick={copyToClipboard}>Copy</UIPillButton>
412
+ <UIPillButton size="compact" variant="outline" title="Paste curve" onclick={pasteFromClipboard}>Paste</UIPillButton>
402
413
  </div>
403
414
  <div class="curve-templates">
404
415
  {#each curveTemplates as tpl}
@@ -413,13 +424,12 @@
413
424
  </svg>
414
425
  </button>
415
426
  {/each}
427
+ </div>
428
+ <div class="curve-toolbar-group">
416
429
  {#if defaultAnchors}
417
- <button
418
- class="curve-tool-btn"
419
- type="button"
420
- title="Reset to default"
421
- onclick={resetToDefault}
422
- >Reset</button>
430
+ <UIPillButton size="compact" variant="outline" title="Reset to default" onclick={resetToDefault}>
431
+ Reset
432
+ </UIPillButton>
423
433
  {/if}
424
434
  </div>
425
435
  </div>
@@ -435,7 +445,7 @@
435
445
  .curve-panel-header {
436
446
  display: flex;
437
447
  align-items: center;
438
- justify-content: space-between;
448
+ gap: var(--ui-space-6);
439
449
  }
440
450
 
441
451
  .curve-panel-label {
@@ -445,11 +455,89 @@
445
455
  }
446
456
 
447
457
  .curve-container {
458
+ position: relative;
448
459
  width: 100%;
449
460
  height: 250px;
450
461
  box-sizing: border-box;
451
462
  }
452
463
 
464
+ .curve-chart-overlay {
465
+ position: absolute;
466
+ inset: var(--ui-space-8);
467
+ display: flex;
468
+ align-items: flex-end;
469
+ pointer-events: none;
470
+ }
471
+
472
+ .curve-chart-overlay > :global(*) {
473
+ pointer-events: auto;
474
+ }
475
+
476
+ .curve-help {
477
+ position: relative;
478
+ margin-left: auto;
479
+ }
480
+
481
+ .curve-help-badge {
482
+ display: inline-flex;
483
+ align-items: center;
484
+ justify-content: center;
485
+ width: 1.25rem;
486
+ height: 1.25rem;
487
+ padding: 0;
488
+ border: none;
489
+ background: transparent;
490
+ color: var(--ui-text-muted);
491
+ cursor: help;
492
+ border-radius: var(--ui-radius-full);
493
+ transition: color var(--ui-transition-fast, 120ms ease);
494
+ }
495
+
496
+ .curve-help-badge:hover,
497
+ .curve-help-badge:focus-visible {
498
+ color: var(--ui-text-primary);
499
+ outline: none;
500
+ }
501
+
502
+ .curve-help-badge i {
503
+ font-size: var(--ui-font-size-md);
504
+ }
505
+
506
+ .curve-help-popover {
507
+ position: absolute;
508
+ top: calc(100% + var(--ui-space-4));
509
+ right: 0;
510
+ display: grid;
511
+ gap: var(--ui-space-4);
512
+ min-width: 14rem;
513
+ padding: var(--ui-space-8) var(--ui-space-12);
514
+ background: var(--ui-surface-highest);
515
+ border: 1px solid var(--ui-border-low);
516
+ border-radius: var(--ui-radius-sm);
517
+ color: var(--ui-text-secondary);
518
+ font-size: var(--ui-font-size-sm);
519
+ line-height: 1.4;
520
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
521
+ opacity: 0;
522
+ transform: translateY(-2px);
523
+ pointer-events: none;
524
+ transition:
525
+ opacity var(--ui-transition-fast, 120ms ease),
526
+ transform var(--ui-transition-fast, 120ms ease);
527
+ z-index: 2;
528
+ }
529
+
530
+ .curve-help-popover strong {
531
+ color: var(--ui-text-primary);
532
+ font-weight: var(--ui-font-weight-medium);
533
+ }
534
+
535
+ .curve-help:hover .curve-help-popover,
536
+ .curve-help:focus-within .curve-help-popover {
537
+ opacity: 1;
538
+ transform: translateY(0);
539
+ }
540
+
453
541
  .curve-svg {
454
542
  width: 100%;
455
543
  height: 100%;
@@ -565,48 +653,17 @@
565
653
  align-items: center;
566
654
  justify-content: space-between;
567
655
  flex-wrap: wrap;
568
- gap: var(--ui-space-2);
656
+ gap: var(--ui-space-8);
569
657
  padding-top: var(--ui-space-2);
570
658
  }
571
659
 
572
- .curve-toolbar-left {
660
+ .curve-toolbar-group {
573
661
  display: flex;
574
662
  align-items: center;
575
663
  gap: var(--ui-space-4);
576
664
  flex-wrap: wrap;
577
665
  }
578
666
 
579
- .curve-tool-btn {
580
- display: flex;
581
- align-items: center;
582
- gap: var(--ui-space-4);
583
- padding: var(--ui-space-2) var(--ui-space-6);
584
- border: 1px solid var(--ui-border-low);
585
- border-radius: var(--ui-radius-sm);
586
- background: var(--ui-surface-lowest);
587
- cursor: pointer;
588
- color: var(--ui-text-muted);
589
- font-size: var(--ui-font-size-md);
590
- }
591
-
592
- .curve-tool-btn:hover {
593
- border-color: var(--ui-border-high);
594
- color: var(--ui-text-secondary);
595
- background: var(--ui-surface-high);
596
- }
597
-
598
- .curve-tool-btn.active {
599
- border-color: var(--ui-border-high);
600
- background: var(--ui-surface-highest);
601
- color: var(--ui-text-primary);
602
- }
603
-
604
- .curve-tool-btn:disabled {
605
- opacity: 0.35;
606
- cursor: default;
607
- pointer-events: none;
608
- }
609
-
610
667
  .curve-tool-icon {
611
668
  width: 0.625rem;
612
669
  height: 1rem;
@@ -616,12 +673,6 @@
616
673
  fill: currentColor;
617
674
  }
618
675
 
619
- .curve-hint {
620
- font-size: var(--ui-font-size-md);
621
- color: var(--ui-text-muted);
622
- opacity: 0.6;
623
- }
624
-
625
676
  .curve-templates {
626
677
  display: flex;
627
678
  gap: var(--ui-space-2);
@@ -77,7 +77,6 @@
77
77
  .seg-label {
78
78
  font-size: 10px;
79
79
  font-weight: var(--ui-font-weight-semibold);
80
- letter-spacing: 0.04em;
81
80
  text-transform: uppercase;
82
81
  color: #fff;
83
82
  padding-left: var(--ui-space-2);
@@ -22,6 +22,11 @@
22
22
  width?: string;
23
23
  onload: (file: F) => void;
24
24
  ondelete?: (file: F) => void;
25
+ /** Optional per-row export action — e.g. download a manifest bundle.
26
+ * When omitted, no export button renders. */
27
+ onexport?: (file: F) => void;
28
+ /** Tooltip for the per-row export button. Falls back to "Export {name}". */
29
+ exportTitle?: (file: F) => string;
25
30
  }
26
31
 
27
32
  let {
@@ -38,6 +43,8 @@
38
43
  width = '420px',
39
44
  onload,
40
45
  ondelete,
46
+ onexport,
47
+ exportTitle,
41
48
  }: Props = $props();
42
49
 
43
50
  type SortKey = 'name' | 'updatedAt';
@@ -147,6 +154,15 @@
147
154
  {#if file.fileName === activeFileName}
148
155
  <span class="active-badge">active</span>
149
156
  {/if}
157
+ {#if onexport}
158
+ <button
159
+ class="file-action-btn"
160
+ onclick={stopPropagation(() => onexport!(file))}
161
+ title={exportTitle ? exportTitle(file) : `Export ${file.name}`}
162
+ >
163
+ <i class="fas fa-download"></i>
164
+ </button>
165
+ {/if}
150
166
  {#if shouldShowDelete(file)}
151
167
  <button
152
168
  class="file-delete-btn"
@@ -195,7 +211,6 @@
195
211
  font-size: 11px;
196
212
  font-weight: 600;
197
213
  text-transform: uppercase;
198
- letter-spacing: 0.04em;
199
214
  cursor: pointer;
200
215
  text-align: left;
201
216
  }
@@ -304,7 +319,6 @@
304
319
  border: 1px solid #3a3a3a;
305
320
  color: #888;
306
321
  text-transform: uppercase;
307
- letter-spacing: 0.04em;
308
322
  }
309
323
 
310
324
  .updated-at {
@@ -324,7 +338,8 @@
324
338
  color: #ccc;
325
339
  }
326
340
 
327
- .file-delete-btn {
341
+ .file-delete-btn,
342
+ .file-action-btn {
328
343
  flex-shrink: 0;
329
344
  display: flex;
330
345
  align-items: center;
@@ -340,11 +355,13 @@
340
355
  opacity: 0;
341
356
  }
342
357
 
343
- .load-item:hover .file-delete-btn {
358
+ .load-item:hover .file-delete-btn,
359
+ .load-item:hover .file-action-btn {
344
360
  opacity: 1;
345
361
  }
346
362
 
347
- .file-delete-btn:hover {
363
+ .file-delete-btn:hover,
364
+ .file-action-btn:hover {
348
365
  color: #ccc;
349
366
  }
350
367
  </style>