lightview 2.0.9 → 2.2.1

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 (115) hide show
  1. package/build-bundles.mjs +105 -0
  2. package/build.js +236 -46
  3. package/components/actions/button.js +16 -3
  4. package/components/actions/swap.js +26 -3
  5. package/components/daisyui.js +1 -1
  6. package/components/data-display/alert.js +13 -3
  7. package/components/data-display/avatar.js +25 -1
  8. package/components/data-display/badge.js +11 -3
  9. package/components/data-display/chart.js +22 -5
  10. package/components/data-display/countdown.js +3 -2
  11. package/components/data-display/kbd.js +9 -3
  12. package/components/data-display/loading.js +11 -3
  13. package/components/data-display/progress.js +11 -3
  14. package/components/data-display/radial-progress.js +12 -3
  15. package/components/data-display/tooltip.js +17 -0
  16. package/components/data-input/checkbox.js +23 -1
  17. package/components/data-input/input.js +24 -1
  18. package/components/data-input/radio.js +37 -2
  19. package/components/data-input/select.js +24 -1
  20. package/components/data-input/toggle.js +21 -1
  21. package/components/layout/divider.js +21 -1
  22. package/components/layout/indicator.js +14 -0
  23. package/components/navigation/breadcrumbs.js +42 -2
  24. package/components/navigation/tabs.js +291 -16
  25. package/docs/api/elements.html +125 -49
  26. package/docs/api/hypermedia.html +29 -2
  27. package/docs/api/index.html +6 -2
  28. package/docs/api/nav.html +18 -4
  29. package/docs/assets/js/examplify.js +1 -1
  30. package/docs/cdom-nav.html +55 -0
  31. package/docs/cdom.html +792 -0
  32. package/docs/components/alert.html +8 -8
  33. package/docs/components/avatar.html +24 -54
  34. package/docs/components/badge.html +69 -14
  35. package/docs/components/breadcrumbs.html +95 -29
  36. package/docs/components/button.html +78 -92
  37. package/docs/components/chart-area.html +3 -3
  38. package/docs/components/chart-bar.html +4 -181
  39. package/docs/components/chart-column.html +4 -189
  40. package/docs/components/chart-line.html +3 -3
  41. package/docs/components/chart-pie.html +112 -166
  42. package/docs/components/chart.html +11 -13
  43. package/docs/components/checkbox.html +48 -28
  44. package/docs/components/collapse.html +6 -6
  45. package/docs/components/component-nav.html +1 -1
  46. package/docs/components/countdown.html +12 -12
  47. package/docs/components/divider.html +65 -21
  48. package/docs/components/dropdown.html +1 -1
  49. package/docs/components/file-input.html +4 -4
  50. package/docs/components/footer.html +11 -11
  51. package/docs/components/indicator.html +85 -31
  52. package/docs/components/input.html +45 -29
  53. package/docs/components/join.html +4 -4
  54. package/docs/components/kbd.html +67 -28
  55. package/docs/components/loading.html +96 -92
  56. package/docs/components/pagination.html +4 -4
  57. package/docs/components/progress.html +50 -7
  58. package/docs/components/radial-progress.html +32 -12
  59. package/docs/components/radio.html +42 -31
  60. package/docs/components/select.html +48 -59
  61. package/docs/components/swap.html +183 -100
  62. package/docs/components/tabs.html +146 -278
  63. package/docs/components/toggle.html +44 -25
  64. package/docs/components/tooltip.html +71 -31
  65. package/docs/getting-started/index.html +8 -6
  66. package/docs/index.html +1 -1
  67. package/docs/syntax-nav.html +10 -0
  68. package/docs/syntax.html +8 -6
  69. package/index.html +2 -2
  70. package/jprx/LICENSE +21 -0
  71. package/jprx/README.md +130 -0
  72. package/jprx/helpers/array.js +75 -0
  73. package/jprx/helpers/compare.js +26 -0
  74. package/jprx/helpers/conditional.js +34 -0
  75. package/jprx/helpers/datetime.js +54 -0
  76. package/jprx/helpers/format.js +20 -0
  77. package/jprx/helpers/logic.js +24 -0
  78. package/jprx/helpers/lookup.js +25 -0
  79. package/jprx/helpers/math.js +34 -0
  80. package/jprx/helpers/network.js +41 -0
  81. package/jprx/helpers/state.js +80 -0
  82. package/jprx/helpers/stats.js +39 -0
  83. package/jprx/helpers/string.js +49 -0
  84. package/jprx/index.js +69 -0
  85. package/jprx/package.json +24 -0
  86. package/jprx/parser.js +1517 -0
  87. package/lightview-all.js +3785 -0
  88. package/lightview-cdom.js +2128 -0
  89. package/lightview-router.js +179 -208
  90. package/lightview-x.js +1435 -1608
  91. package/lightview.js +613 -766
  92. package/lightview.js.bak +1 -0
  93. package/package.json +10 -3
  94. package/src/lightview-all.js +10 -0
  95. package/src/lightview-cdom.js +457 -0
  96. package/src/lightview-router.js +210 -0
  97. package/src/lightview-x.js +1630 -0
  98. package/src/lightview.js +705 -0
  99. package/src/reactivity/signal.js +133 -0
  100. package/src/reactivity/state.js +217 -0
  101. package/{watch.js → start-dev.js} +2 -1
  102. package/tests/cdom/fixtures/helpers.cdomc +62 -0
  103. package/tests/cdom/fixtures/user.cdom +14 -0
  104. package/tests/cdom/fixtures/user.cdomc +12 -0
  105. package/tests/cdom/fixtures/user.odom +18 -0
  106. package/tests/cdom/fixtures/user.vdom +11 -0
  107. package/tests/cdom/helpers.test.js +121 -0
  108. package/tests/cdom/loader.test.js +125 -0
  109. package/tests/cdom/parser.test.js +179 -0
  110. package/tests/cdom/reactivity.test.js +186 -0
  111. package/tests/text-tag.test.js +77 -0
  112. package/vite.config.mjs +52 -0
  113. package/wrangler.toml +0 -3
  114. package/components/data-display/skeleton.js +0 -66
  115. package/docs/components/skeleton.html +0 -447
@@ -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
  }
@@ -20,7 +20,7 @@
20
20
  'Divider', 'Dock', 'Drawer', 'Dropdown', 'File Input', 'Footer', 'Hero',
21
21
  'Indicator', 'Input', 'Join', 'Kbd', 'Loading', 'Menu', 'Modal', 'Navbar',
22
22
  'Pagination', 'Progress', 'Radial Progress', 'Radio', 'Range', 'Rating',
23
- 'Select', 'Skeleton', 'Stats', 'Steps', 'Swap', 'Table', 'Tabs', 'Textarea',
23
+ 'Select', 'Stats', 'Steps', 'Swap', 'Table', 'Tabs', 'Textarea',
24
24
  'Timeline', 'Toast', 'Toggle', 'Tooltip'
25
25
  ].sort(); // Sort alphabetically
26
26
 
@@ -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>
@@ -71,7 +71,7 @@
71
71
  <!-- Tabs -->
72
72
  <script>
73
73
  globalThis.switchSyntaxTab = (tabId) => {
74
- const tabs = ['tagged', 'vdom', 'object'];
74
+ const tabs = ['tagged', 'vdom', 'object', 'html'];
75
75
  tabs.forEach(t => {
76
76
  const tabEl = document.getElementById(`tab-btn-${t}`);
77
77
  const contentEl = document.getElementById(`syntax-${t}`);
@@ -93,6 +93,8 @@
93
93
  <button id="tab-btn-object" role="tab" class="syntax-tab"
94
94
  onclick="switchSyntaxTab('object')">Object
95
95
  DOM</button>
96
+ <button id="tab-btn-html" role="tab" class="syntax-tab"
97
+ onclick="switchSyntaxTab('html')">HTML</button>
96
98
  </div>
97
99
 
98
100
  <!-- Tagged Syntax -->
@@ -167,17 +169,39 @@ const demo = {
167
169
  div: {
168
170
  class: 'flex flex-col w-full',
169
171
  children: [
170
- { div: { class: 'card bg-base-300 p-4 rounded-box', text: 'Content above' } },
171
- { Divider: { text: 'OR' } },
172
- { div: { class: 'card bg-base-300 p-4 rounded-box', text: 'Content below' } },
173
- { Divider: { color: 'primary', text: 'Primary' } },
174
- { div: { class: 'card bg-base-300 p-4 rounded-box', text: 'More content' } }
172
+ { div: { class: 'card bg-base-300 p-4 rounded-box', children: ['Content above'] } },
173
+ { Divider: { children: ['OR'] } },
174
+ { div: { class: 'card bg-base-300 p-4 rounded-box', children: ['Content below'] } },
175
+ { Divider: { color: 'primary', children: ['Primary'] } },
176
+ { div: { class: 'card bg-base-300 p-4 rounded-box', children: ['More content'] } }
175
177
  ]
176
178
  }
177
179
  };
178
180
 
179
181
  $('#example').content(demo);</code></pre>
180
182
  </div>
183
+
184
+ <!-- HTML Syntax -->
185
+ <div id="syntax-html" style="display: none;">
186
+ <pre><script>
187
+ examplify(document.currentScript.nextElementSibling, {
188
+ at: document.currentScript.parentElement,
189
+ scripts: ['/lightview.js', '/lightview-x.js'],
190
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
191
+ type: 'module',
192
+ language: 'html',
193
+ minHeight: 240
194
+ });
195
+ </script><code contenteditable="true" class="language-html">&lt;script type="module" src="/components/layout/divider.js"&gt;&lt;/script&gt;
196
+
197
+ &lt;div class="flex flex-col w-full"&gt;
198
+ &lt;div class="card bg-base-300 p-4 rounded-box"&gt;Content above&lt;/div&gt;
199
+ &lt;lv-divider&gt;OR&lt;/lv-divider&gt;
200
+ &lt;div class="card bg-base-300 p-4 rounded-box"&gt;Content below&lt;/div&gt;
201
+ &lt;lv-divider color="primary"&gt;Primary&lt;/lv-divider&gt;
202
+ &lt;div class="card bg-base-300 p-4 rounded-box"&gt;More content&lt;/div&gt;
203
+ &lt;/div&gt;</code></pre>
204
+ </div>
181
205
  </div>
182
206
  </div>
183
207
 
@@ -210,29 +234,49 @@ $('#example').content(demo);</code></pre>
210
234
  </table>
211
235
  </div>
212
236
 
213
- <!-- Static Examples -->
214
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Without Text</h2>
237
+ <!-- Divider Gallery -->
238
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Divider Gallery</h2>
239
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1.5rem;">
240
+ Live examples using <code>&lt;lv-divider&gt;</code> custom elements.
241
+ </p>
242
+
243
+ <script type="module" src="/components/layout/divider.js"></script>
244
+
245
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Basic Divider</h3>
215
246
  <div style="display: flex; width: 100%; flex-direction: column; margin-bottom: 2rem;">
216
247
  <div class="card bg-base-300 rounded-box p-4">Content</div>
217
- <div class="divider"></div>
248
+ <lv-divider></lv-divider>
218
249
  <div class="card bg-base-300 rounded-box p-4">Content</div>
219
250
  </div>
220
251
 
221
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Vertical</h2>
222
- <div style="display: flex; width: 100%; margin-bottom: 2rem;">
223
- <div class="card bg-base-300 rounded-box p-4 flex-grow">Left</div>
224
- <div class="divider divider-horizontal">OR</div>
225
- <div class="card bg-base-300 rounded-box p-4 flex-grow">Right</div>
252
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">With Text</h3>
253
+ <div style="display: flex; width: 100%; flex-direction: column; margin-bottom: 2rem;">
254
+ <div class="card bg-base-300 rounded-box p-4">Login</div>
255
+ <lv-divider>OR</lv-divider>
256
+ <div class="card bg-base-300 rounded-box p-4">Sign Up</div>
257
+ </div>
258
+
259
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Horizontal (Manual)</h3>
260
+ <div style="display: flex; width: 100%; margin-bottom: 2rem; height: 100px;">
261
+ <div class="card bg-base-300 rounded-box p-4 flex-grow place-items-center">Left</div>
262
+ <lv-divider horizontal>OR</lv-divider>
263
+ <div class="card bg-base-300 rounded-box p-4 flex-grow place-items-center">Right</div>
264
+ </div>
265
+
266
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Colors</h3>
267
+ <div style="display: flex; width: 100%; flex-direction: column; gap: 0.5rem; margin-bottom: 2rem;">
268
+ <lv-divider color="primary">Primary</lv-divider>
269
+ <lv-divider color="secondary">Secondary</lv-divider>
270
+ <lv-divider color="accent">Accent</lv-divider>
271
+ <lv-divider color="success">Success</lv-divider>
272
+ <lv-divider color="warning">Warning</lv-divider>
273
+ <lv-divider color="error">Error</lv-divider>
226
274
  </div>
227
275
 
228
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Colors</h2>
276
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Text Position</h3>
229
277
  <div style="display: flex; width: 100%; flex-direction: column; gap: 0.5rem; margin-bottom: 2rem;">
230
- <div class="divider divider-primary">Primary</div>
231
- <div class="divider divider-secondary">Secondary</div>
232
- <div class="divider divider-accent">Accent</div>
233
- <div class="divider divider-success">Success</div>
234
- <div class="divider divider-warning">Warning</div>
235
- <div class="divider divider-error">Error</div>
278
+ <lv-divider position="start">Start</lv-divider>
279
+ <lv-divider position="end">End</lv-divider>
236
280
  </div>
237
281
  </div>
238
282
  </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
  }
@@ -71,7 +71,7 @@
71
71
  <!-- Tabs -->
72
72
  <script>
73
73
  globalThis.switchSyntaxTab = (tabId) => {
74
- const tabs = ['tagged', 'vdom', 'object'];
74
+ const tabs = ['tagged', 'vdom', 'object', 'html'];
75
75
  tabs.forEach(t => {
76
76
  const tabEl = document.getElementById(`tab-btn-${t}`);
77
77
  const contentEl = document.getElementById(`syntax-${t}`);
@@ -93,6 +93,8 @@
93
93
  <button id="tab-btn-object" role="tab" class="syntax-tab"
94
94
  onclick="switchSyntaxTab('object')">Object
95
95
  DOM</button>
96
+ <button id="tab-btn-html" role="tab" class="syntax-tab"
97
+ onclick="switchSyntaxTab('html')">HTML</button>
96
98
  </div>
97
99
 
98
100
  <!-- Tagged Syntax -->
@@ -228,13 +230,13 @@ const demo = {
228
230
  children: [
229
231
  {
230
232
  'Indicator.Item': {
231
- children: [{ Badge: { color: 'primary', text: () => count.value } }]
233
+ children: [{ Badge: { color: 'primary', children: [() => count.value] } }]
232
234
  }
233
235
  },
234
236
  {
235
237
  Button: {
236
238
  onclick: () => { count.value++; },
237
- text: 'Messages'
239
+ children: ['Messages']
238
240
  }
239
241
  }
240
242
  ]
@@ -271,6 +273,38 @@ const demo = {
271
273
 
272
274
  $('#example').content(demo);</code></pre>
273
275
  </div>
276
+
277
+ <!-- HTML Syntax -->
278
+ <div id="syntax-html" style="display: none;">
279
+ <pre><script>
280
+ examplify(document.currentScript.nextElementSibling, {
281
+ at: document.currentScript.parentElement,
282
+ scripts: ['/lightview.js', '/lightview-x.js'],
283
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
284
+ type: 'module',
285
+ language: 'html',
286
+ minHeight: 100
287
+ });
288
+ </script><code contenteditable="true" class="language-html">&lt;script type="module" src="/components/layout/indicator.js"&gt;&lt;/script&gt;
289
+ &lt;script type="module" src="/components/data-display/badge.js"&gt;&lt;/script&gt;
290
+ &lt;script type="module" src="/components/actions/button.js"&gt;&lt;/script&gt;
291
+
292
+ &lt;div style="display: flex; gap: 2rem"&gt;
293
+ &lt;lv-indicator&gt;
294
+ &lt;item class="badge badge-primary"&gt;3&lt;/item&gt;
295
+ &lt;lv-button&gt;Messages&lt;/lv-button&gt;
296
+ &lt;/lv-indicator&gt;
297
+
298
+ &lt;lv-indicator&gt;
299
+ &lt;item position="bottom-end" class="badge badge-success badge-xs"&gt;&lt;/item&gt;
300
+ &lt;div class="avatar"&gt;
301
+ &lt;div class="w-12 rounded-full"&gt;
302
+ &lt;img src="https://i.pravatar.cc/100?img=5" /&gt;
303
+ &lt;/div&gt;
304
+ &lt;/div&gt;
305
+ &lt;/lv-indicator&gt;
306
+ &lt;/div&gt;</code></pre>
307
+ </div>
274
308
  </div>
275
309
  </div>
276
310
 
@@ -299,42 +333,62 @@ $('#example').content(demo);</code></pre>
299
333
  </table>
300
334
  </div>
301
335
 
302
- <!-- Positions -->
303
- <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Positions</h2>
304
- <div class="example-flex" style="margin-bottom: 2rem;">
305
- <div class="indicator">
306
- <span
307
- class="indicator-item indicator-top indicator-start badge badge-secondary">top-start</span>
336
+ <!-- Indicator Gallery -->
337
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Indicator Gallery</h2>
338
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1.5rem;">
339
+ Live examples using <code>&lt;lv-indicator&gt;</code> custom elements.
340
+ </p>
341
+
342
+ <script type="module" src="/components/layout/indicator.js"></script>
343
+ <script type="module" src="/components/data-display/badge.js"></script>
344
+
345
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Top Positions</h3>
346
+ <div style="display: flex; gap: 2rem; margin-bottom: 2rem; flex-wrap: wrap;">
347
+ <lv-indicator>
348
+ <item position="top-start" class="badge badge-secondary">top-start</item>
308
349
  <div class="bg-base-300 p-6 rounded-box">content</div>
309
- </div>
310
- <div class="indicator">
311
- <span
312
- class="indicator-item indicator-top indicator-center badge badge-secondary">top-center</span>
350
+ </lv-indicator>
351
+ <lv-indicator>
352
+ <item position="top-center" class="badge badge-secondary">top-center</item>
313
353
  <div class="bg-base-300 p-6 rounded-box">content</div>
314
- </div>
315
- <div class="indicator">
316
- <span
317
- class="indicator-item indicator-top indicator-end badge badge-secondary">top-end</span>
354
+ </lv-indicator>
355
+ <lv-indicator>
356
+ <item position="top-end" class="badge badge-secondary">top-end</item>
318
357
  <div class="bg-base-300 p-6 rounded-box">content</div>
319
- </div>
358
+ </lv-indicator>
320
359
  </div>
321
360
 
322
- <div class="example-flex" style="margin-bottom: 2rem;">
323
- <div class="indicator">
324
- <span
325
- class="indicator-item indicator-bottom indicator-start badge badge-secondary">bottom-start</span>
361
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Bottom Positions</h3>
362
+ <div style="display: flex; gap: 2rem; margin-bottom: 2rem; flex-wrap: wrap;">
363
+ <lv-indicator>
364
+ <item position="bottom-start" class="badge badge-secondary">bottom-start</item>
326
365
  <div class="bg-base-300 p-6 rounded-box">content</div>
327
- </div>
328
- <div class="indicator">
329
- <span
330
- class="indicator-item indicator-bottom indicator-center badge badge-secondary">bottom-center</span>
366
+ </lv-indicator>
367
+ <lv-indicator>
368
+ <item position="bottom-center" class="badge badge-secondary">bottom-center</item>
331
369
  <div class="bg-base-300 p-6 rounded-box">content</div>
332
- </div>
333
- <div class="indicator">
334
- <span
335
- class="indicator-item indicator-bottom indicator-end badge badge-secondary">bottom-end</span>
370
+ </lv-indicator>
371
+ <lv-indicator>
372
+ <item position="bottom-end" class="badge badge-secondary">bottom-end</item>
336
373
  <div class="bg-base-300 p-6 rounded-box">content</div>
337
- </div>
374
+ </lv-indicator>
375
+ </div>
376
+
377
+ <h3 class="text-lg font-semibold" style="margin-bottom: 0.75rem;">Common Use Cases</h3>
378
+ <div style="display: flex; gap: 3rem; margin-bottom: 2rem; align-items: center;">
379
+ <lv-indicator>
380
+ <item class="badge badge-primary">99+</item>
381
+ <lv-button>Inbox</lv-button>
382
+ </lv-indicator>
383
+
384
+ <lv-indicator>
385
+ <item position="bottom-end" class="badge badge-success badge-xs"></item>
386
+ <div class="avatar">
387
+ <div class="w-12 rounded-full">
388
+ <img src="https://i.pravatar.cc/100?img=8" />
389
+ </div>
390
+ </div>
391
+ </lv-indicator>
338
392
  </div>
339
393
  </div>
340
394
  </div>