lightview 2.1.0 → 2.2.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.
Files changed (71) hide show
  1. package/build-bundles.mjs +2 -6
  2. package/build.js +236 -46
  3. package/components/data-display/avatar.js +25 -1
  4. package/components/data-display/chart.js +22 -5
  5. package/components/data-display/countdown.js +3 -2
  6. package/components/data-input/checkbox.js +23 -1
  7. package/components/data-input/input.js +24 -1
  8. package/components/data-input/radio.js +37 -2
  9. package/components/data-input/select.js +24 -1
  10. package/components/data-input/toggle.js +21 -1
  11. package/components/navigation/breadcrumbs.js +42 -2
  12. package/docs/assets/js/examplify.js +1 -1
  13. package/docs/cdom-nav.html +32 -6
  14. package/docs/cdom.html +610 -180
  15. package/docs/components/avatar.html +24 -54
  16. package/docs/components/badge.html +14 -14
  17. package/docs/components/breadcrumbs.html +95 -29
  18. package/docs/components/chart-area.html +3 -3
  19. package/docs/components/chart-bar.html +4 -181
  20. package/docs/components/chart-column.html +4 -189
  21. package/docs/components/chart-line.html +3 -3
  22. package/docs/components/chart-pie.html +112 -166
  23. package/docs/components/chart.html +11 -13
  24. package/docs/components/checkbox.html +48 -28
  25. package/docs/components/collapse.html +6 -6
  26. package/docs/components/countdown.html +12 -12
  27. package/docs/components/dropdown.html +1 -1
  28. package/docs/components/file-input.html +4 -4
  29. package/docs/components/footer.html +11 -11
  30. package/docs/components/input.html +45 -29
  31. package/docs/components/join.html +4 -4
  32. package/docs/components/kbd.html +3 -3
  33. package/docs/components/loading.html +41 -53
  34. package/docs/components/pagination.html +4 -4
  35. package/docs/components/progress.html +6 -4
  36. package/docs/components/radio.html +42 -31
  37. package/docs/components/select.html +48 -59
  38. package/docs/components/toggle.html +44 -25
  39. package/docs/getting-started/index.html +4 -4
  40. package/jprx/LICENSE +21 -0
  41. package/jprx/README.md +130 -0
  42. package/{cdom → jprx}/helpers/array.js +9 -4
  43. package/{cdom → jprx}/helpers/state.js +6 -3
  44. package/jprx/index.js +69 -0
  45. package/jprx/package.json +24 -0
  46. package/jprx/parser.js +1517 -0
  47. package/lightview-all.js +3785 -1
  48. package/lightview-cdom.js +2128 -1
  49. package/lightview-router.js +179 -208
  50. package/lightview-x.js +1435 -1
  51. package/lightview.js +613 -1
  52. package/package.json +5 -2
  53. package/src/lightview-cdom.js +201 -49
  54. package/src/lightview-router.js +210 -0
  55. package/src/lightview-x.js +104 -55
  56. package/src/lightview.js +12 -1
  57. package/{watch.js → start-dev.js} +2 -1
  58. package/tests/cdom/parser.test.js +83 -12
  59. package/wrangler.toml +0 -3
  60. package/cdom/parser.js +0 -602
  61. package/test-text-tag.js +0 -6
  62. /package/{cdom → jprx}/helpers/compare.js +0 -0
  63. /package/{cdom → jprx}/helpers/conditional.js +0 -0
  64. /package/{cdom → jprx}/helpers/datetime.js +0 -0
  65. /package/{cdom → jprx}/helpers/format.js +0 -0
  66. /package/{cdom → jprx}/helpers/logic.js +0 -0
  67. /package/{cdom → jprx}/helpers/lookup.js +0 -0
  68. /package/{cdom → jprx}/helpers/math.js +0 -0
  69. /package/{cdom → jprx}/helpers/network.js +0 -0
  70. /package/{cdom → jprx}/helpers/stats.js +0 -0
  71. /package/{cdom → jprx}/helpers/string.js +0 -0
@@ -485,7 +485,7 @@ const reactiveDemo = {
485
485
  {
486
486
  p: {
487
487
  style: 'font-size: 0.875rem; font-family: monospace;',
488
- text: () => `Notifications: ${notifications.value}, Marketing: ${marketing.value}`
488
+ children: [() => `Notifications: ${notifications.value}, Marketing: ${marketing.value}`]
489
489
  }
490
490
  },
491
491
  {
@@ -493,7 +493,7 @@ const reactiveDemo = {
493
493
  class: 'btn btn-primary',
494
494
  style: () => `margin-top: 0.5rem; ${termsAccepted.value ? '' : 'opacity: 0.5; pointer-events: none;'}`,
495
495
  disabled: () => !termsAccepted.value,
496
- text: 'Submit'
496
+ children: ['Submit']
497
497
  }
498
498
  }
499
499
  ]
@@ -604,36 +604,56 @@ $('#example').content(reactiveDemo);</code></pre>
604
604
  </table>
605
605
  </div>
606
606
 
607
- <!-- Colors Example -->
608
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Colors</h2>
609
- <div style="display: flex; gap: 0.5rem; margin-bottom: 2rem;">
610
- <input type="checkbox" class="checkbox" checked />
611
- <input type="checkbox" class="checkbox checkbox-primary" checked />
612
- <input type="checkbox" class="checkbox checkbox-secondary" checked />
613
- <input type="checkbox" class="checkbox checkbox-accent" checked />
614
- <input type="checkbox" class="checkbox checkbox-success" checked />
615
- <input type="checkbox" class="checkbox checkbox-warning" checked />
616
- <input type="checkbox" class="checkbox checkbox-info" checked />
617
- <input type="checkbox" class="checkbox checkbox-error" checked />
607
+ <!-- Custom Element Gallery -->
608
+ <h2 class="text-xl font-bold" style="margin-top: 2rem; margin-bottom: 1rem;">Checkbox Gallery</h2>
609
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1.5rem;">
610
+ Live examples using <code>&lt;lv-checkbox&gt;</code> custom elements.
611
+ </p>
612
+
613
+ <script type="module" src="/components/data-input/checkbox.js"></script>
614
+
615
+ <!-- Colors -->
616
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Colors</h3>
617
+ <div style="display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 2rem;">
618
+ <lv-checkbox label="Default" checked></lv-checkbox>
619
+ <lv-checkbox label="Primary" color="primary" checked></lv-checkbox>
620
+ <lv-checkbox label="Secondary" color="secondary" checked></lv-checkbox>
621
+ <lv-checkbox label="Accent" color="accent" checked></lv-checkbox>
622
+ <lv-checkbox label="Info" color="info" checked></lv-checkbox>
623
+ <lv-checkbox label="Success" color="success" checked></lv-checkbox>
624
+ <lv-checkbox label="Warning" color="warning" checked></lv-checkbox>
625
+ <lv-checkbox label="Error" color="error" checked></lv-checkbox>
626
+ </div>
627
+
628
+ <!-- Sizes -->
629
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Sizes</h3>
630
+ <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 1.5rem; margin-bottom: 2rem;">
631
+ <lv-checkbox size="xs" label="Extra Small" checked></lv-checkbox>
632
+ <lv-checkbox size="sm" label="Small" checked></lv-checkbox>
633
+ <lv-checkbox size="md" label="Medium" checked></lv-checkbox>
634
+ <lv-checkbox size="lg" label="Large" checked></lv-checkbox>
618
635
  </div>
619
636
 
620
- <!-- Sizes Example -->
621
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Sizes</h2>
622
- <div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 2rem;">
623
- <input type="checkbox" class="checkbox checkbox-xs" checked />
624
- <input type="checkbox" class="checkbox checkbox-sm" checked />
625
- <input type="checkbox" class="checkbox checkbox-md" checked />
626
- <input type="checkbox" class="checkbox checkbox-lg" checked />
637
+ <!-- States -->
638
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">States</h3>
639
+ <div
640
+ style="display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem; max-width: 20rem;">
641
+ <lv-checkbox label="Disabled Unchecked" disabled></lv-checkbox>
642
+ <lv-checkbox label="Disabled Checked" checked disabled></lv-checkbox>
643
+ <lv-checkbox label="Required Field" required></lv-checkbox>
644
+ <lv-checkbox label="Indeterminate" indeterminate="true"></lv-checkbox>
627
645
  </div>
628
646
 
629
- <!-- With Label -->
630
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">With Label</h2>
631
- <div style="display: flex; flex-direction: column; width: 13rem; margin-bottom: 2rem;">
632
- <label
633
- style="display: flex; align-items: center; justify-content: space-between; cursor: pointer; padding: 0.5rem 0;">
634
- <span style="font-size: 0.875rem;">Remember me</span>
635
- <input type="checkbox" class="checkbox checkbox-primary" />
636
- </label>
647
+ <!-- Descriptions -->
648
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">With Descriptions</h3>
649
+ <div
650
+ style="display: flex; flex-direction: column; gap: 1.5rem; margin-bottom: 2rem; max-width: 28rem;">
651
+ <lv-checkbox label="Email Notifications"
652
+ description="Receive updates about your account activity." color="primary" checked>
653
+ </lv-checkbox>
654
+ <lv-checkbox label="Marketing" description="We'll send you occasional promotions and news."
655
+ color="secondary">
656
+ </lv-checkbox>
637
657
  </div>
638
658
  </div>
639
659
  </div>
@@ -203,8 +203,8 @@ const demo = {
203
203
  Collapse: {
204
204
  icon: 'arrow',
205
205
  children: [
206
- { 'Collapse.Title': { text: '📖 Description' } },
207
- { 'Collapse.Content': { children: [{ p: { text: 'This is a detailed product description that can be expanded.' } }] } }
206
+ { 'Collapse.Title': { children: ['📖 Description'] } },
207
+ { 'Collapse.Content': { children: [{ p: { children: ['This is a detailed product description that can be expanded.'] } }] } }
208
208
  ]
209
209
  }
210
210
  },
@@ -212,8 +212,8 @@ const demo = {
212
212
  Collapse: {
213
213
  icon: 'arrow',
214
214
  children: [
215
- { 'Collapse.Title': { text: '📦 Shipping Info' } },
216
- { 'Collapse.Content': { children: [{ p: { text: 'Free shipping on orders over $50. Delivery in 3-5 days.' } }] } }
215
+ { 'Collapse.Title': { children: ['📦 Shipping Info'] } },
216
+ { 'Collapse.Content': { children: [{ p: { children: ['Free shipping on orders over $50. Delivery in 3-5 days.'] } }] } }
217
217
  ]
218
218
  }
219
219
  },
@@ -221,8 +221,8 @@ const demo = {
221
221
  Collapse: {
222
222
  icon: 'arrow',
223
223
  children: [
224
- { 'Collapse.Title': { text: '🔄 Returns' } },
225
- { 'Collapse.Content': { children: [{ p: { text: '30-day return policy for unused items in original packaging.' } }] } }
224
+ { 'Collapse.Title': { children: ['🔄 Returns'] } },
225
+ { 'Collapse.Content': { children: [{ p: { children: ['30-day return policy for unused items in original packaging.'] } }] } }
226
226
  ]
227
227
  }
228
228
  }
@@ -167,9 +167,9 @@ const display = {
167
167
  style: 'display: flex; gap: 1.25rem',
168
168
  children: [
169
169
  { Countdown: { value: 15, class: 'font-mono text-4xl' } },
170
- { span: { class: 'text-4xl', text: ':' } },
170
+ { span: { class: 'text-4xl', children: [':'] } },
171
171
  { Countdown: { value: 30, class: 'font-mono text-4xl' } },
172
- { span: { class: 'text-4xl', text: ':' } },
172
+ { span: { class: 'text-4xl', children: [':'] } },
173
173
  { Countdown: { value: 45, class: 'font-mono text-4xl' } }
174
174
  ]
175
175
  }
@@ -389,8 +389,8 @@ const demo = {
389
389
  div: {
390
390
  style: 'display: flex; gap: 0.5rem',
391
391
  children: [
392
- { Button: { color: () => running.value ? 'error' : 'primary', onclick: toggle, text: () => running.value ? 'Pause' : 'Start' } },
393
- { Button: { onclick: reset, text: 'Reset' } }
392
+ { Button: { color: () => running.value ? 'error' : 'primary', onclick: toggle, children: [() => running.value ? 'Pause' : 'Start'] } },
393
+ { Button: { onclick: reset, children: ['Reset'] } }
394
394
  ]
395
395
  }
396
396
  }
@@ -432,26 +432,26 @@ $('#example').content(demo);</code></pre>
432
432
  style="display: grid; grid-auto-flow: column; grid-auto-columns: max-content; gap: 1.25rem; text-align: center; margin-bottom: 2rem;">
433
433
  <div style="display: flex; flex-direction: column; padding: 0.5rem;"
434
434
  class="bg-neutral rounded-box text-neutral-content">
435
- <span class="countdown font-mono text-5xl"><span id="cd-days"
436
- style="--value:15;"></span></span>
435
+ <span class="countdown font-mono text-5xl" style="line-height: 1.2em; height: 1.2em;"><span
436
+ id="cd-days" style="--value:15; height: 1.2em;"></span></span>
437
437
  days
438
438
  </div>
439
439
  <div style="display: flex; flex-direction: column; padding: 0.5rem;"
440
440
  class="bg-neutral rounded-box text-neutral-content">
441
- <span class="countdown font-mono text-5xl"><span id="cd-hours"
442
- style="--value:10;"></span></span>
441
+ <span class="countdown font-mono text-5xl" style="line-height: 1.2em; height: 1.2em;"><span
442
+ id="cd-hours" style="--value:10; height: 1.2em;"></span></span>
443
443
  hours
444
444
  </div>
445
445
  <div style="display: flex; flex-direction: column; padding: 0.5rem;"
446
446
  class="bg-neutral rounded-box text-neutral-content">
447
- <span class="countdown font-mono text-5xl"><span id="cd-min"
448
- style="--value:24;"></span></span>
447
+ <span class="countdown font-mono text-5xl" style="line-height: 1.2em; height: 1.2em;"><span
448
+ id="cd-min" style="--value:24; height: 1.2em;"></span></span>
449
449
  min
450
450
  </div>
451
451
  <div style="display: flex; flex-direction: column; padding: 0.5rem;"
452
452
  class="bg-neutral rounded-box text-neutral-content">
453
- <span class="countdown font-mono text-5xl"><span id="cd-sec"
454
- style="--value:59;"></span></span>
453
+ <span class="countdown font-mono text-5xl" style="line-height: 1.2em; height: 1.2em;"><span
454
+ id="cd-sec" style="--value:59; height: 1.2em;"></span></span>
455
455
  sec
456
456
  </div>
457
457
  </div>
@@ -357,7 +357,7 @@ const demo = {
357
357
  style: 'display: flex; gap: 1rem; align-items: center; height: 12rem;',
358
358
  children: [
359
359
  dropdown,
360
- { span: { style: 'font-size: 0.875rem; opacity: 0.7;', text: () => `Selected: ${selected.value}` } }
360
+ { span: { style: 'font-size: 0.875rem; opacity: 0.7;', children: [() => `Selected: ${selected.value}`] } }
361
361
  ]
362
362
  }
363
363
  };
@@ -414,20 +414,20 @@ const reactiveDemo = {
414
414
  () => {
415
415
  const files = selectedFiles.value;
416
416
  if (files.length === 0) {
417
- return { p: { class: 'text-sm opacity-50', text: 'No files selected' } };
417
+ return { p: { class: 'text-sm opacity-50', children: ['No files selected'] } };
418
418
  }
419
419
  return {
420
420
  div: {
421
421
  children: [
422
- { p: { class: 'text-sm font-semibold mb-2', text: `${files.length} file(s) selected:` } },
422
+ { p: { class: 'text-sm font-semibold mb-2', children: [`${files.length} file(s) selected:`] } },
423
423
  {
424
424
  ul: {
425
425
  class: 'text-xs font-mono', style: 'display: flex; flex-direction: column; gap: 0.25rem',
426
426
  children: files.map(f => ({
427
427
  li: {
428
428
  children: [
429
- { span: { class: 'text-primary', text: f.name } },
430
- { span: { class: 'opacity-50', text: ` (${(f.size / 1024).toFixed(1)} KB)` } }
429
+ { span: { class: 'text-primary', children: [f.name] } },
430
+ { span: { class: 'opacity-50', children: [` (${(f.size / 1024).toFixed(1)} KB)`] } }
431
431
  ]
432
432
  }
433
433
  }))
@@ -203,29 +203,29 @@ const footer = {
203
203
  {
204
204
  'Footer.Nav': {
205
205
  children: [
206
- { 'Footer.Title': { text: 'Services' } },
207
- { a: { class: 'link link-hover', text: 'Branding' } },
208
- { a: { class: 'link link-hover', text: 'Design' } },
209
- { a: { class: 'link link-hover', text: 'Marketing' } }
206
+ { 'Footer.Title': { children: ['Services'] } },
207
+ { a: { class: 'link link-hover', children: ['Branding'] } },
208
+ { a: { class: 'link link-hover', children: ['Design'] } },
209
+ { a: { class: 'link link-hover', children: ['Marketing'] } }
210
210
  ]
211
211
  }
212
212
  },
213
213
  {
214
214
  'Footer.Nav': {
215
215
  children: [
216
- { 'Footer.Title': { text: 'Company' } },
217
- { a: { class: 'link link-hover', text: 'About us' } },
218
- { a: { class: 'link link-hover', text: 'Contact' } },
219
- { a: { class: 'link link-hover', text: 'Jobs' } }
216
+ { 'Footer.Title': { children: ['Company'] } },
217
+ { a: { class: 'link link-hover', children: ['About us'] } },
218
+ { a: { class: 'link link-hover', children: ['Contact'] } },
219
+ { a: { class: 'link link-hover', children: ['Jobs'] } }
220
220
  ]
221
221
  }
222
222
  },
223
223
  {
224
224
  'Footer.Nav': {
225
225
  children: [
226
- { 'Footer.Title': { text: 'Legal' } },
227
- { a: { class: 'link link-hover', text: 'Terms of use' } },
228
- { a: { class: 'link link-hover', text: 'Privacy policy' } }
226
+ { 'Footer.Title': { children: ['Legal'] } },
227
+ { a: { class: 'link link-hover', children: ['Terms of use'] } },
228
+ { a: { class: 'link link-hover', children: ['Privacy policy'] } }
229
229
  ]
230
230
  }
231
231
  }
@@ -602,41 +602,57 @@ $('#example').content(reactiveDemo);</code></pre>
602
602
  </table>
603
603
  </div>
604
604
 
605
- <!-- Sizes Example -->
606
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Sizes</h2>
607
- <div style="display: flex; align-items: flex-end; gap: 0.5rem; margin-bottom: 2rem;">
608
- <input type="text" placeholder="Extra small" class="input input-xs" />
609
- <input type="text" placeholder="Small" class="input input-sm" />
610
- <input type="text" placeholder="Medium" class="input" />
611
- <input type="text" placeholder="Large" class="input input-lg" />
605
+ <!-- Custom Element Gallery -->
606
+ <h2 class="text-xl font-bold" style="margin-top: 2rem; margin-bottom: 1rem;">Input Gallery</h2>
607
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1.5rem;">
608
+ Live examples using <code>&lt;lv-input&gt;</code> custom elements.
609
+ </p>
610
+
611
+ <script type="module" src="/components/data-input/input.js"></script>
612
+
613
+ <!-- Sizes -->
614
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Sizes</h3>
615
+ <div style="display: flex; align-items: flex-end; flex-wrap: wrap; gap: 1rem; margin-bottom: 2rem;">
616
+ <lv-input size="xs" placeholder="Extra small"></lv-input>
617
+ <lv-input size="sm" placeholder="Small"></lv-input>
618
+ <lv-input placeholder="Medium (default)"></lv-input>
619
+ <lv-input size="lg" placeholder="Large"></lv-input>
612
620
  </div>
613
621
 
614
- <!-- Colors Example -->
615
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Colors</h2>
622
+ <!-- Colors -->
623
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Colors</h3>
616
624
  <div
617
625
  style="display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: 1rem; margin-bottom: 2rem;">
618
- <input type="text" placeholder="Primary" class="input input-primary" />
619
- <input type="text" placeholder="Secondary" class="input input-secondary" />
620
- <input type="text" placeholder="Accent" class="input input-accent" />
621
- <input type="text" placeholder="Info" class="input input-info" />
622
- <input type="text" placeholder="Success" class="input input-success" />
623
- <input type="text" placeholder="Warning" class="input input-warning" />
624
- <input type="text" placeholder="Error" class="input input-error" />
625
- <input type="text" placeholder="Ghost" class="input input-ghost" />
626
+ <lv-input color="primary" placeholder="Primary"></lv-input>
627
+ <lv-input color="secondary" placeholder="Secondary"></lv-input>
628
+ <lv-input color="accent" placeholder="Accent"></lv-input>
629
+ <lv-input color="info" placeholder="Info"></lv-input>
630
+ <lv-input color="success" placeholder="Success"></lv-input>
631
+ <lv-input color="warning" placeholder="Warning"></lv-input>
632
+ <lv-input color="error" placeholder="Error"></lv-input>
633
+ <lv-input ghost="true" placeholder="Ghost Style"></lv-input>
626
634
  </div>
627
635
 
628
- <!-- With Fieldset -->
629
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">With Label (Fieldset Pattern)</h2>
630
- <div style="max-width: 28rem; margin-bottom: 2rem;">
631
- <fieldset
632
- style="display: flex; flex-direction: column; gap: 0.5rem; border: none; padding: 0.5rem 0;">
633
- <legend
634
- style="font-size: 0.875rem; font-weight: 700; color: oklch(var(--bc)/0.8); padding: 0 0.5rem;">
635
- Email Address</legend>
636
- <input type="email" class="input" style="width: 100%;" placeholder="you@example.com" />
637
- <p style="font-size: 0.875rem; color: oklch(var(--bc)/0.6); padding: 0 0.5rem;">We'll never
638
- share your email.</p>
639
- </fieldset>
636
+ <!-- Labels and Helpers -->
637
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Labels & Assistance</h3>
638
+ <div
639
+ style="display: flex; flex-direction: column; gap: 1.5rem; margin-bottom: 2rem; max-width: 28rem;">
640
+ <lv-input label="Email Address" type="email" placeholder="you@example.com"
641
+ helper="We'll never share your email address.">
642
+ </lv-input>
643
+ <lv-input label="Password" type="password" placeholder="Enter your password" required="true">
644
+ </lv-input>
645
+ <lv-input label="Error State" placeholder="Invalid input"
646
+ error="This field has an error message.">
647
+ </lv-input>
648
+ </div>
649
+
650
+ <!-- States -->
651
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">States</h3>
652
+ <div
653
+ style="display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem; max-width: 28rem;">
654
+ <lv-input label="Disabled Input" value="Cannot edit this" disabled="true"></lv-input>
655
+ <lv-input label="Read Only (via value)" value="Static text" disabled="true"></lv-input>
640
656
  </div>
641
657
  </div>
642
658
  </div>
@@ -212,9 +212,9 @@ const demo = {
212
212
  {
213
213
  Join: {
214
214
  children: [
215
- { Button: { class: 'join-item', text: 'Previous' } },
216
- { Button: { class: 'join-item', color: 'primary', text: 'Current' } },
217
- { Button: { class: 'join-item', text: 'Next' } }
215
+ { Button: { class: 'join-item', children: ['Previous'] } },
216
+ { Button: { class: 'join-item', color: 'primary', children: ['Current'] } },
217
+ { Button: { class: 'join-item', children: ['Next'] } }
218
218
  ]
219
219
  }
220
220
  },
@@ -229,7 +229,7 @@ const demo = {
229
229
  oninput: (e) => { email.value = e.target.value; }
230
230
  }
231
231
  },
232
- { Button: { class: 'join-item', color: 'primary', text: 'Subscribe' } }
232
+ { Button: { class: 'join-item', color: 'primary', children: ['Subscribe'] } }
233
233
  ]
234
234
  }
235
235
  }
@@ -204,19 +204,19 @@ const shortcuts = {
204
204
  {
205
205
  div: {
206
206
  style: 'display: flex; gap: 0.5rem; align-items: center',
207
- children: [{ span: { text: 'Save: ' } }, { Kbd: { text: '⌘' } }, { Kbd: { text: 'S' } }]
207
+ children: [{ span: { children: ['Save: '] } }, { Kbd: { children: ['⌘'] } }, { Kbd: { children: ['S'] } }]
208
208
  }
209
209
  },
210
210
  {
211
211
  div: {
212
212
  style: 'display: flex; gap: 0.5rem; align-items: center',
213
- children: [{ span: { text: 'Undo: ' } }, { Kbd: { text: '⌘' } }, { Kbd: { text: 'Z' } }]
213
+ children: [{ span: { children: ['Undo: '] } }, { Kbd: { children: ['⌘'] } }, { Kbd: { children: ['Z'] } }]
214
214
  }
215
215
  },
216
216
  {
217
217
  div: {
218
218
  style: 'display: flex; gap: 0.5rem; align-items: center',
219
- children: [{ span: { text: 'Copy: ' } }, { Kbd: { text: '⌘' } }, { Kbd: { text: 'C' } }]
219
+ children: [{ span: { children: ['Copy: '] } }, { Kbd: { children: ['⌘'] } }, { Kbd: { children: ['C'] } }]
220
220
  }
221
221
  }
222
222
  ]
@@ -276,7 +276,8 @@ $('#example').content(loaders);</code></pre>
276
276
  scripts: ['/lightview.js', '/lightview-x.js'],
277
277
  styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
278
278
  type: 'module',
279
- minHeight: 80
279
+ minHeight: 80,
280
+ autoRun: true
280
281
  });
281
282
  </script><code contenteditable="true">await import('/components/data-display/loading.js');
282
283
  await import('/components/actions/button.js');
@@ -286,15 +287,6 @@ const { div, span, Loading, Button } = tags;
286
287
 
287
288
  const isLoading = signal(false);
288
289
 
289
- const handleClick = async () => {
290
- </script><code contenteditable="true">import { signal, tags, $ } from '/lightview.js';
291
- import { Loading } from '/components/data-display/loading.js';
292
- import { Button } from '/components/actions/button.js';
293
-
294
- const { div, span } = tags;
295
-
296
- const isLoading = signal(false);
297
-
298
290
  const handleClick = async () => {
299
291
  isLoading.value = true;
300
292
  await new Promise(r => setTimeout(r, 2000));
@@ -324,12 +316,13 @@ $('#example').content(demo);</code></pre>
324
316
  scripts: ['/lightview.js', '/lightview-x.js'],
325
317
  styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
326
318
  type: 'module',
327
- minHeight: 80
319
+ minHeight: 80,
320
+ autoRun: true
328
321
  });
329
- </script><code contenteditable="true">import { signal, $, tags } from '/lightview.js';
330
- import { Loading } from '/components/data-display/loading.js';
331
- import { Button } from '/components/actions/button.js';
332
- const { div, span } = tags;
322
+ </script><code contenteditable="true">await import('/components/data-display/loading.js');
323
+ await import('/components/actions/button.js');
324
+ const { signal, tags, $ } = Lightview;
325
+ const { div, span, Loading, Button } = tags;
333
326
 
334
327
  const isLoading = signal(false);
335
328
 
@@ -343,23 +336,20 @@ const demo = {
343
336
  tag: div,
344
337
  attributes: { style: 'display: flex; gap: 1rem; align-items: center;' },
345
338
  children: [
346
- {
347
- observable: isLoading,
348
- callback: (loading) => loading
349
- ? {
350
- tag: Button,
351
- attributes: { color: 'primary', disabled: true },
352
- children: [
353
- { tag: Loading, attributes: { type: 'spinner', size: 'sm' } },
354
- { tag: span, children: [' Processing...'] }
355
- ]
356
- }
357
- : {
358
- tag: Button,
359
- attributes: { color: 'primary', onclick: handleClick },
360
- children: ['Submit']
361
- }
362
- },
339
+ () => isLoading.value
340
+ ? {
341
+ tag: Button,
342
+ attributes: { color: 'primary', disabled: true },
343
+ children: [
344
+ { tag: Loading, attributes: { type: 'spinner', size: 'sm' } },
345
+ { tag: span, children: [' Processing...'] }
346
+ ]
347
+ }
348
+ : {
349
+ tag: Button,
350
+ attributes: { color: 'primary', onclick: handleClick },
351
+ children: ['Submit']
352
+ },
363
353
  {
364
354
  tag: span,
365
355
  attributes: { style: 'font-size: 0.875rem; opacity: 0.7;' },
@@ -379,11 +369,12 @@ $('#example').content(demo);</code></pre>
379
369
  scripts: ['/lightview.js', '/lightview-x.js'],
380
370
  styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
381
371
  type: 'module',
382
- minHeight: 80
372
+ minHeight: 80,
373
+ autoRun: true
383
374
  });
384
- </script><code contenteditable="true">import { signal, $ } from '/lightview.js';
385
- import { Loading } from '/components/data-display/loading.js';
386
- import { Button } from '/components/actions/button.js';
375
+ </script><code contenteditable="true">await import('/components/data-display/loading.js');
376
+ await import('/components/actions/button.js');
377
+ const { signal, $ } = Lightview;
387
378
 
388
379
  const isLoading = signal(false);
389
380
 
@@ -397,27 +388,24 @@ const demo = {
397
388
  div: {
398
389
  style: 'display: flex; gap: 1rem; align-items: center',
399
390
  children: [
400
- {
401
- observable: isLoading,
402
- callback: (loading) => loading
403
- ? {
404
- Button: {
405
- color: 'primary',
406
- disabled: true,
407
- children: [
408
- { Loading: { type: 'spinner', size: 'sm' } },
409
- { span: { text: ' Processing...' } }
410
- ]
411
- }
412
- }
413
- : {
414
- Button: { color: 'primary', onclick: handleClick, text: 'Submit' }
391
+ () => isLoading.value
392
+ ? {
393
+ Button: {
394
+ color: 'primary',
395
+ disabled: true,
396
+ children: [
397
+ { Loading: { type: 'spinner', size: 'sm' } },
398
+ { span: { children: [' Processing...'] } }
399
+ ]
415
400
  }
416
- },
401
+ }
402
+ : {
403
+ Button: { color: 'primary', onclick: handleClick, children: ['Submit'] }
404
+ },
417
405
  {
418
406
  span: {
419
407
  style: 'font-size: 0.875rem; opacity: 0.7;',
420
- text: () => isLoading.value ? 'Please wait...' : 'Click the button'
408
+ children: [() => isLoading.value ? 'Please wait...' : 'Click the button']
421
409
  }
422
410
  }
423
411
  ]
@@ -214,20 +214,20 @@ const demo = {
214
214
  {
215
215
  Join: {
216
216
  children: [
217
- { Button: { class: 'join-item', onclick: () => { if (page.value > 1) page.value--; }, text: '«' } },
217
+ { Button: { class: 'join-item', onclick: () => { if (page.value > 1) page.value--; }, children: ['«'] } },
218
218
  ...Array.from({ length: totalPages }, (_, i) => ({
219
219
  Button: {
220
220
  class: 'join-item',
221
221
  color: () => page.value === i + 1 ? 'primary' : undefined,
222
222
  onclick: () => { page.value = i + 1; },
223
- text: i + 1
223
+ children: [i + 1]
224
224
  }
225
225
  })),
226
- { Button: { class: 'join-item', onclick: () => { if (page.value < totalPages) page.value++; }, text: '»' } }
226
+ { Button: { class: 'join-item', onclick: () => { if (page.value < totalPages) page.value++; }, children: ['»'] } }
227
227
  ]
228
228
  }
229
229
  },
230
- { span: { class: 'text-sm opacity-70', text: () => `Page ${page.value} of ${totalPages}` } }
230
+ { span: { class: 'text-sm opacity-70', children: [() => `Page ${page.value} of ${totalPages}`] } }
231
231
  ]
232
232
  }
233
233
  };
@@ -425,9 +425,11 @@ const demo = {
425
425
  {
426
426
  p: {
427
427
  style: 'font-family: monospace; font-size: 0.875rem;',
428
- text: () => progress.value >= 100
429
- ? '✓ Complete!'
430
- : `Downloading: ${Math.round(progress.value)}%`
428
+ children: [
429
+ () => progress.value >= 100
430
+ ? '✓ Complete!'
431
+ : `Downloading: ${Math.round(progress.value)}%`
432
+ ]
431
433
  }
432
434
  },
433
435
  {
@@ -436,7 +438,7 @@ const demo = {
436
438
  size: 'sm',
437
439
  disabled: () => isRunning.value,
438
440
  onclick: startDownload,
439
- text: () => isRunning.value ? 'Downloading...' : 'Start Download'
441
+ children: [() => isRunning.value ? 'Downloading...' : 'Start Download']
440
442
  }
441
443
  }
442
444
  ]