@motion-proto/live-tokens 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-plugin/index.cjs +80 -4
- package/dist-plugin/index.js +80 -4
- package/package.json +2 -2
- package/src/component-editor/scaffolding/ComponentFileManager.svelte +3 -1
- package/src/component-editor/scaffolding/SaveAsDialog.svelte +24 -7
- package/src/lib/ColumnsOverlay.svelte +1 -1
- package/src/lib/componentPersist.ts +65 -0
- package/src/lib/presetService.ts +121 -1
- package/src/lib/productionPulse.ts +32 -0
- package/src/pages/ComponentEditorPage.svelte +25 -0
- package/src/pages/EditorShell.svelte +25 -0
- package/src/ui/PresetFileManager.svelte +763 -216
- package/src/ui/ThemeFileManager.svelte +557 -307
- package/src/ui/UnsavedComponentsDialog.svelte +315 -0
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { componentRegistryEntries, validateRegistryAgainstServerScan } from '../component-editor/registry';
|
|
9
9
|
import { listComponents } from '../lib/componentConfigService';
|
|
10
10
|
import { selectedComponent } from '../lib/editorViewStore';
|
|
11
|
+
import { componentDirty } from '../lib/editorStore';
|
|
11
12
|
// Editor chrome + form controls + icon font must be JS imports (not @import
|
|
12
13
|
// inside the style block) so Vite resolves them via the module graph
|
|
13
14
|
// regardless of how the consumer compiles Svelte CSS (external ?lang.css vs
|
|
@@ -149,12 +150,16 @@
|
|
|
149
150
|
<button
|
|
150
151
|
class="nav-item"
|
|
151
152
|
class:active={$selectedComponent === item.id}
|
|
153
|
+
class:dirty={$componentDirty[item.id]}
|
|
152
154
|
onmouseenter={(e) => showHint(item.label, e.currentTarget)}
|
|
153
155
|
onmouseleave={hideHint}
|
|
154
156
|
onclick={() => selectComponent(item.id)}
|
|
155
157
|
>
|
|
156
158
|
<i class={item.icon}></i>
|
|
157
159
|
<span class="rail-label">{item.label}</span>
|
|
160
|
+
{#if $componentDirty[item.id]}
|
|
161
|
+
<span class="dirty-dot" aria-label="Unsaved changes" title="Unsaved changes"></span>
|
|
162
|
+
{/if}
|
|
158
163
|
</button>
|
|
159
164
|
{/each}
|
|
160
165
|
</div>
|
|
@@ -334,6 +339,7 @@
|
|
|
334
339
|
}
|
|
335
340
|
|
|
336
341
|
.nav-item {
|
|
342
|
+
position: relative;
|
|
337
343
|
display: grid;
|
|
338
344
|
grid-template-columns: 48px 1fr;
|
|
339
345
|
align-items: center;
|
|
@@ -369,6 +375,25 @@
|
|
|
369
375
|
opacity: 0.85;
|
|
370
376
|
}
|
|
371
377
|
|
|
378
|
+
/* Amber dot indicating unsaved changes. Anchored to the top-right of the
|
|
379
|
+
icon column so it stays visible whether the rail is collapsed (icon-only)
|
|
380
|
+
or expanded (icon + label). */
|
|
381
|
+
.dirty-dot {
|
|
382
|
+
position: absolute;
|
|
383
|
+
top: 8px;
|
|
384
|
+
left: 30px;
|
|
385
|
+
width: 7px;
|
|
386
|
+
height: 7px;
|
|
387
|
+
border-radius: 50%;
|
|
388
|
+
background: var(--ui-highlight);
|
|
389
|
+
box-shadow: 0 0 0 2px black;
|
|
390
|
+
pointer-events: none;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.nav-item.dirty {
|
|
394
|
+
color: var(--ui-text-secondary);
|
|
395
|
+
}
|
|
396
|
+
|
|
372
397
|
.content {
|
|
373
398
|
padding: 0 var(--ui-space-32);
|
|
374
399
|
background: black;
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { scrollSectionIntoView } from '../lib/scrollSection';
|
|
13
13
|
import { editorState } from '../lib/editorStore';
|
|
14
14
|
import { editorView, sidebarCondensed, selectedComponent } from '../lib/editorViewStore';
|
|
15
|
+
import { componentDirty } from '../lib/editorStore';
|
|
15
16
|
import { componentRegistryEntries, validateRegistryAgainstServerScan } from '../component-editor/registry';
|
|
16
17
|
import { listComponents } from '../lib/componentConfigService';
|
|
17
18
|
|
|
@@ -170,12 +171,16 @@
|
|
|
170
171
|
<button
|
|
171
172
|
class="nav-item"
|
|
172
173
|
class:active={$selectedComponent === item.id}
|
|
174
|
+
class:dirty={$componentDirty[item.id]}
|
|
173
175
|
onmouseenter={(e) => showHint(item.label, e.currentTarget)}
|
|
174
176
|
onmouseleave={hideHint}
|
|
175
177
|
onclick={() => selectComponent(item.id)}
|
|
176
178
|
>
|
|
177
179
|
<i class={item.icon}></i>
|
|
178
180
|
<span class="nav-label">{item.label}</span>
|
|
181
|
+
{#if $componentDirty[item.id]}
|
|
182
|
+
<span class="dirty-dot" aria-label="Unsaved changes" title="Unsaved changes"></span>
|
|
183
|
+
{/if}
|
|
179
184
|
</button>
|
|
180
185
|
{/each}
|
|
181
186
|
</div>
|
|
@@ -262,6 +267,7 @@
|
|
|
262
267
|
}
|
|
263
268
|
|
|
264
269
|
.nav-item {
|
|
270
|
+
position: relative;
|
|
265
271
|
display: grid;
|
|
266
272
|
grid-template-columns: 48px 1fr;
|
|
267
273
|
align-items: center;
|
|
@@ -286,6 +292,25 @@
|
|
|
286
292
|
opacity: 0.85;
|
|
287
293
|
}
|
|
288
294
|
|
|
295
|
+
/* Amber dot indicating unsaved changes. Anchored to the top-right of the
|
|
296
|
+
icon column so it stays visible whether the sidebar is condensed
|
|
297
|
+
(icon-only) or expanded (icon + label). */
|
|
298
|
+
.dirty-dot {
|
|
299
|
+
position: absolute;
|
|
300
|
+
top: 8px;
|
|
301
|
+
left: 30px;
|
|
302
|
+
width: 7px;
|
|
303
|
+
height: 7px;
|
|
304
|
+
border-radius: 50%;
|
|
305
|
+
background: var(--ui-highlight);
|
|
306
|
+
box-shadow: 0 0 0 2px black;
|
|
307
|
+
pointer-events: none;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.nav-item.dirty {
|
|
311
|
+
color: var(--ui-text-secondary);
|
|
312
|
+
}
|
|
313
|
+
|
|
289
314
|
.nav-label {
|
|
290
315
|
white-space: nowrap;
|
|
291
316
|
overflow: hidden;
|