@svgrid/ui 0.3.2 → 0.3.3

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 (3) hide show
  1. package/README.md +5 -3
  2. package/index.mjs +44 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,9 +30,11 @@ npx @svgrid/ui add button --preview
30
30
  ```
31
31
 
32
32
  `try` needs no project - it caches a tiny Vite + Svelte sandbox under your temp
33
- dir (so repeat runs are instant) and opens the browser. `--preview` drops a
34
- `src/routes/preview/<id>` page (plus a `/preview` index) into an existing
35
- SvelteKit app so it renders in your running dev server.
33
+ dir (so repeat runs are instant) and opens the browser, with a **theme picker
34
+ (all 19 presets) and a light/dark toggle** so you can see the component in your
35
+ target theme. `--preview` drops a `src/routes/preview/<id>` page (plus a
36
+ `/preview` index) into an existing SvelteKit app so it renders in your running
37
+ dev server.
36
38
 
37
39
  ## Usage
38
40
 
package/index.mjs CHANGED
@@ -471,23 +471,58 @@ async function cmdTry(registry, tokens) {
471
471
  await writeFile(
472
472
  join(src, 'App.svelte'),
473
473
  `<script lang="ts">
474
+ import { themePresets, resolveThemeTokens } from '@svgrid/grid/themes'
474
475
  ${imports.join('\n')}
476
+
477
+ let themeId = $state(themePresets[0].id)
478
+ let mode = $state<'light' | 'dark'>('light')
479
+ const preset = $derived(themePresets.find((p) => p.id === themeId) ?? themePresets[0])
480
+
481
+ // Apply the chosen preset + light/dark as --sg-* tokens on :root, the same way
482
+ // the shipped themes/<id>.css files do (light in :root, dark under data-theme),
483
+ // so both the components and this page follow the picker.
484
+ $effect(() => {
485
+ const tokens = resolveThemeTokens(preset, mode)
486
+ const root = document.documentElement
487
+ for (const [k, v] of Object.entries(tokens)) root.style.setProperty(k, v)
488
+ root.setAttribute('data-theme', mode)
489
+ root.style.colorScheme = mode
490
+ })
475
491
  </script>
476
492
 
493
+ <header class="svui-try__bar">
494
+ <strong class="svui-try__brand">@svgrid/ui preview</strong>
495
+ <div class="svui-try__controls">
496
+ <label class="svui-try__field">
497
+ Theme
498
+ <select bind:value={themeId}>
499
+ {#each themePresets as p (p.id)}<option value={p.id}>{p.name}</option>{/each}
500
+ </select>
501
+ </label>
502
+ <button type="button" class="svui-try__toggle" onclick={() => (mode = mode === 'light' ? 'dark' : 'light')}>
503
+ {mode === 'light' ? 'Dark' : 'Light'} mode
504
+ </button>
505
+ </div>
506
+ </header>
507
+
477
508
  <main class="svui-try">
478
- <header class="svui-try__head">
479
- <strong>@svgrid/ui preview</strong>
480
- <span>${esc(items.map((i) => i.id).join(', '))}</span>
481
- </header>
509
+ <p class="svui-try__sub">${esc(items.map((i) => i.id).join(', '))}</p>
482
510
  ${sections.join('\n')}
483
511
  </main>
484
512
 
485
513
  <style>
486
- :global(body) { margin: 0; background: #f8fafc; }
487
- .svui-try { max-width: 960px; margin: 0 auto; padding: 32px 24px; font-family: system-ui, sans-serif; }
488
- .svui-try__head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 24px; color: #64748b; }
489
- .svui-try__item { padding: 28px; border: 1px solid #e2e8f0; border-radius: 12px; background: #fff; margin-bottom: 16px; }
490
- .svui-try__item h2 { margin: 0 0 16px; font-size: 15px; color: #334155; }
514
+ :global(body) { margin: 0; background: var(--sg-bg, #f8fafc); color: var(--sg-fg, #0f172a); transition: background 0.15s, color 0.15s; }
515
+ .svui-try__bar { position: sticky; top: 0; z-index: 10; display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 12px 24px; background: var(--sg-header-bg, #fff); border-bottom: 1px solid var(--sg-border, #e2e8f0); }
516
+ .svui-try__brand { font-size: 13px; color: var(--sg-muted, #64748b); }
517
+ .svui-try__controls { display: flex; align-items: center; gap: 12px; }
518
+ .svui-try__field { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--sg-muted, #64748b); }
519
+ .svui-try__field select { font: inherit; padding: 5px 8px; border-radius: 8px; border: 1px solid var(--sg-border, #cbd5e1); background: var(--sg-bg, #fff); color: var(--sg-fg, #0f172a); }
520
+ .svui-try__toggle { font: inherit; font-size: 12px; padding: 6px 12px; border-radius: 8px; cursor: pointer; border: 1px solid var(--sg-border, #cbd5e1); background: var(--sg-bg, #fff); color: var(--sg-fg, #0f172a); }
521
+ .svui-try__toggle:hover { border-color: var(--sg-accent, #6366f1); }
522
+ .svui-try { max-width: 960px; margin: 0 auto; padding: 24px; font-family: system-ui, sans-serif; }
523
+ .svui-try__sub { margin: 0 0 20px; font-size: 12px; color: var(--sg-muted, #64748b); }
524
+ .svui-try__item { padding: 28px; border: 1px solid var(--sg-border, #e2e8f0); border-radius: 12px; background: var(--sg-bg, #fff); margin-bottom: 16px; }
525
+ .svui-try__item h2 { margin: 0 0 16px; font-size: 15px; color: var(--sg-muted, #334155); }
491
526
  </style>
492
527
  `,
493
528
  )
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "commercial",
5
5
  "url": "https://svgrid.com/pricing"
6
6
  },
7
- "version": "0.3.2",
7
+ "version": "0.3.3",
8
8
  "description": "Add and preview SvGrid UI components in one command: npx @svgrid/ui try calendar",
9
9
  "type": "module",
10
10
  "license": "MIT",