lightview 1.8.1-b → 2.0.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 (224) hide show
  1. package/.agent/workflows/daisyui-component-migration.md +155 -0
  2. package/.codacy/cli.sh +149 -0
  3. package/.codacy/codacy.yaml +15 -0
  4. package/.github/instructions/codacy.instructions.md +72 -0
  5. package/.wranglerignore +21 -0
  6. package/README.md +1331 -21
  7. package/_headers +4 -0
  8. package/build.js +70 -0
  9. package/components/actions/button.js +151 -0
  10. package/components/actions/dropdown.js +120 -0
  11. package/components/actions/modal.js +146 -0
  12. package/components/actions/swap.js +118 -0
  13. package/components/daisyui.js +288 -0
  14. package/components/data-display/accordion.js +128 -0
  15. package/components/data-display/alert.js +112 -0
  16. package/components/data-display/avatar.js +170 -0
  17. package/components/data-display/badge.js +82 -0
  18. package/components/data-display/card.js +151 -0
  19. package/components/data-display/carousel.js +94 -0
  20. package/components/data-display/chart.js +220 -0
  21. package/components/data-display/chat.js +128 -0
  22. package/components/data-display/collapse.js +103 -0
  23. package/components/data-display/countdown.js +69 -0
  24. package/components/data-display/diff.js +111 -0
  25. package/components/data-display/kbd.js +65 -0
  26. package/components/data-display/loading.js +75 -0
  27. package/components/data-display/progress.js +79 -0
  28. package/components/data-display/radial-progress.js +88 -0
  29. package/components/data-display/skeleton.js +66 -0
  30. package/components/data-display/stats.js +159 -0
  31. package/components/data-display/table.js +146 -0
  32. package/components/data-display/timeline.js +146 -0
  33. package/components/data-display/toast.js +72 -0
  34. package/components/data-display/tooltip.js +74 -0
  35. package/components/data-input/checkbox.js +253 -0
  36. package/components/data-input/file-input.js +224 -0
  37. package/components/data-input/input.js +264 -0
  38. package/components/data-input/radio.js +338 -0
  39. package/components/data-input/range.js +204 -0
  40. package/components/data-input/rating.js +219 -0
  41. package/components/data-input/select.js +287 -0
  42. package/components/data-input/textarea.js +287 -0
  43. package/components/data-input/toggle.js +201 -0
  44. package/components/index.js +137 -0
  45. package/components/layout/divider.js +72 -0
  46. package/components/layout/drawer.js +142 -0
  47. package/components/layout/footer.js +100 -0
  48. package/components/layout/hero.js +109 -0
  49. package/components/layout/indicator.js +90 -0
  50. package/components/layout/join.js +78 -0
  51. package/components/layout/navbar.js +110 -0
  52. package/components/navigation/breadcrumbs.js +91 -0
  53. package/components/navigation/dock.js +103 -0
  54. package/components/navigation/menu.js +126 -0
  55. package/components/navigation/pagination.js +105 -0
  56. package/components/navigation/steps.js +89 -0
  57. package/components/navigation/tabs.css +177 -0
  58. package/components/navigation/tabs.js +123 -0
  59. package/components/theme/theme-switch.css +65 -0
  60. package/components/theme/theme-switch.js +177 -0
  61. package/docs/about.html +164 -0
  62. package/docs/api/computed.html +184 -0
  63. package/docs/api/effects.html +173 -0
  64. package/docs/api/elements.html +180 -0
  65. package/docs/api/enhance.html +225 -0
  66. package/docs/api/hypermedia.html +165 -0
  67. package/docs/api/index.html +178 -0
  68. package/docs/api/nav.html +18 -0
  69. package/docs/api/signals.html +136 -0
  70. package/docs/api/state.html +217 -0
  71. package/docs/assets/images/logo-favicon.svg +42 -0
  72. package/docs/assets/images/logo-static.svg +40 -0
  73. package/docs/assets/images/logo.svg +66 -0
  74. package/docs/assets/js/examplify.js +395 -0
  75. package/docs/assets/styles/site.css +1102 -0
  76. package/docs/assets/styles/themes.css +236 -0
  77. package/docs/components/accordion.html +439 -0
  78. package/docs/components/alert.html +528 -0
  79. package/docs/components/avatar.html +586 -0
  80. package/docs/components/badge.html +531 -0
  81. package/docs/components/breadcrumbs.html +278 -0
  82. package/docs/components/button.html +579 -0
  83. package/docs/components/card.html +561 -0
  84. package/docs/components/carousel.html +286 -0
  85. package/docs/components/chart-area.html +702 -0
  86. package/docs/components/chart-bar.html +782 -0
  87. package/docs/components/chart-column.html +735 -0
  88. package/docs/components/chart-line.html +794 -0
  89. package/docs/components/chart-pie.html +823 -0
  90. package/docs/components/chart.html +612 -0
  91. package/docs/components/chat.html +547 -0
  92. package/docs/components/checkbox.html +641 -0
  93. package/docs/components/collapse.html +536 -0
  94. package/docs/components/component-nav.html +53 -0
  95. package/docs/components/countdown.html +470 -0
  96. package/docs/components/diff.html +245 -0
  97. package/docs/components/divider.html +240 -0
  98. package/docs/components/dock.html +277 -0
  99. package/docs/components/drawer.html +515 -0
  100. package/docs/components/dropdown.html +479 -0
  101. package/docs/components/file-input.html +591 -0
  102. package/docs/components/footer.html +301 -0
  103. package/docs/components/gallery.html +504 -0
  104. package/docs/components/hero.html +264 -0
  105. package/docs/components/index.css +840 -0
  106. package/docs/components/index.html +735 -0
  107. package/docs/components/indicator.html +342 -0
  108. package/docs/components/input.html +644 -0
  109. package/docs/components/join.html +285 -0
  110. package/docs/components/kbd.html +322 -0
  111. package/docs/components/loading.html +521 -0
  112. package/docs/components/menu.html +461 -0
  113. package/docs/components/modal.html +639 -0
  114. package/docs/components/navbar.html +321 -0
  115. package/docs/components/pagination.html +279 -0
  116. package/docs/components/progress.html +514 -0
  117. package/docs/components/radial-progress.html +434 -0
  118. package/docs/components/radio.html +655 -0
  119. package/docs/components/range.html +611 -0
  120. package/docs/components/rating.html +642 -0
  121. package/docs/components/select.html +696 -0
  122. package/docs/components/sidebar-setup.js +93 -0
  123. package/docs/components/skeleton.html +447 -0
  124. package/docs/components/spinner.html +68 -0
  125. package/docs/components/stats.html +486 -0
  126. package/docs/components/steps.html +356 -0
  127. package/docs/components/swap.html +517 -0
  128. package/docs/components/switch.html +68 -0
  129. package/docs/components/table.html +668 -0
  130. package/docs/components/tabs.html +506 -0
  131. package/docs/components/text-input.html +68 -0
  132. package/docs/components/textarea.html +603 -0
  133. package/docs/components/timeline.html +487 -0
  134. package/docs/components/toast.html +474 -0
  135. package/docs/components/toggle.html +564 -0
  136. package/docs/components/tooltip.html +423 -0
  137. package/docs/examples/getting-started-example.html +40 -0
  138. package/docs/examples/index.html +93 -0
  139. package/docs/getting-started/index.html +739 -0
  140. package/docs/getting-started/reviews.html +23 -0
  141. package/docs/getting-started/reviews.odom +108 -0
  142. package/docs/getting-started/reviews.vdom +84 -0
  143. package/docs/index.html +134 -0
  144. package/docs/playground.html +416 -0
  145. package/docs/router.html +285 -0
  146. package/docs/styles/index.html +190 -0
  147. package/functions/_middleware.js +32 -0
  148. package/index.html +309 -0
  149. package/lightview-router.js +364 -0
  150. package/lightview-x.js +1577 -0
  151. package/lightview.js +658 -1109
  152. package/lightview.js.backup +793 -0
  153. package/middleware/locale.js +25 -0
  154. package/middleware/markdown.js +44 -0
  155. package/middleware/notFound.js +37 -0
  156. package/package.json +27 -41
  157. package/watch.js +92 -0
  158. package/wrangler.toml +12 -0
  159. package/.idea/lightview.iml +0 -12
  160. package/.idea/modules.xml +0 -8
  161. package/.idea/vcs.xml +0 -6
  162. package/LICENSE +0 -21
  163. package/codepen-no-tabs-embed.css +0 -2
  164. package/components/chart/chart.html +0 -17
  165. package/components/chart/example.html +0 -32
  166. package/components/chart.html +0 -83
  167. package/components/components.js +0 -113
  168. package/components/gantt/example.html +0 -22
  169. package/components/gantt/gantt.html +0 -42
  170. package/components/gauge/example.html +0 -28
  171. package/components/gauge/gauge.html +0 -20
  172. package/components/gauge.html +0 -60
  173. package/components/orgchart/example.html +0 -25
  174. package/components/orgchart/orgchart.html +0 -41
  175. package/components/repl/code-editor.html +0 -64
  176. package/components/repl/editor.html +0 -37
  177. package/components/repl/editorjs-inline-tool/index.js +0 -3
  178. package/components/repl/editorjs-inline-tool/inline-tools.js +0 -28
  179. package/components/repl/editorjs-inline-tool/tool.js +0 -175
  180. package/components/repl/repl-with-wysiwyg.html +0 -355
  181. package/components/repl/repl.html +0 -345
  182. package/components/repl/sup.js +0 -44
  183. package/components/repl/wysiwyg-repl.html +0 -258
  184. package/components/timeline/example.html +0 -33
  185. package/components/timeline/timeline.html +0 -44
  186. package/components/timeline.html +0 -81
  187. package/examples/anchor.html +0 -11
  188. package/examples/chart.html +0 -34
  189. package/examples/counter.html +0 -26
  190. package/examples/counter.test.mjs +0 -47
  191. package/examples/counter2.html +0 -26
  192. package/examples/directives.html +0 -79
  193. package/examples/foreign.html +0 -50
  194. package/examples/forgeinform.html +0 -98
  195. package/examples/form.html +0 -61
  196. package/examples/gauge.html +0 -18
  197. package/examples/invalid-template-literals.html +0 -44
  198. package/examples/medium/remote.html +0 -60
  199. package/examples/message.html +0 -18
  200. package/examples/nested.html +0 -11
  201. package/examples/object-bound-form.html +0 -34
  202. package/examples/remote-server.js +0 -51
  203. package/examples/remote.html +0 -34
  204. package/examples/remote.json +0 -1
  205. package/examples/scratch.html +0 -69
  206. package/examples/sensors/index.html +0 -30
  207. package/examples/sensors/sensor-server.js +0 -30
  208. package/examples/shared.html +0 -41
  209. package/examples/template.html +0 -33
  210. package/examples/timeline.html +0 -21
  211. package/examples/todo.html +0 -38
  212. package/examples/top.html +0 -10
  213. package/examples/types.html +0 -94
  214. package/examples/xor.html +0 -62
  215. package/jest-puppeteer.config.js +0 -5
  216. package/jest.config.json +0 -12
  217. package/sites/client.html +0 -48
  218. package/sites/index.html +0 -247
  219. package/test/basic.html +0 -93
  220. package/test/basic.test.mjs +0 -315
  221. package/test/extended.html +0 -29
  222. package/test/extended.test.mjs +0 -448
  223. package/types.js +0 -534
  224. package/unsplash.key +0 -1
@@ -0,0 +1,474 @@
1
+ <!-- SEO-friendly SPA Shim -->
2
+ <script src="/lightview-router.js"></script>
3
+ <script>
4
+ if (window.LightviewRouter) {
5
+ LightviewRouter.base('/index.html');
6
+ }
7
+ </script>
8
+
9
+ <!-- Load the page-specific stylesheet -->
10
+ <link rel="stylesheet" href="./index.css">
11
+
12
+ <!-- Gallery Structure -->
13
+ <div class="gallery-page">
14
+ <div class="gallery-layout">
15
+ <!-- Sidebar Overlay -->
16
+ <div id="sidebar-overlay" class="sidebar-overlay"></div>
17
+
18
+ <!-- Sidebar -->
19
+ <div id="gallery-sidebar" class="gallery-sidebar" style="visibility: hidden" src="./component-nav.html"></div>
20
+
21
+ <!-- Main Content -->
22
+ <div id="gallery-main" class="gallery-main">
23
+ <!-- Header Container -->
24
+ <div
25
+ style="position: sticky; top: 0; z-index: 30; background: var(--gallery-surface); border-bottom: 1px solid var(--gallery-border); backdrop-filter: blur(8px);">
26
+ <!-- Breadcrumbs Row -->
27
+ <div style="padding: 0.75rem 1.5rem 0;">
28
+ <script>
29
+ (() => {
30
+ const { Breadcrumbs } = Lightview.tags;
31
+ const breadcrumbs = Breadcrumbs({
32
+ id: 'page-breadcrumbs',
33
+ items: [
34
+ { label: 'Components', href: '/docs/components' },
35
+ { label: 'Toast' }
36
+ ]
37
+ });
38
+ document.currentScript.replaceWith(breadcrumbs.domEl);
39
+ })();
40
+ </script>
41
+ </div>
42
+ <!-- Title Row -->
43
+ <div class="gallery-header"
44
+ style="border-bottom: none; height: auto; padding-top: 0.5rem; padding-bottom: 0.75rem;">
45
+ <button id="toggle-btn" class="toggle-btn" aria-label="Toggle Sidebar">
46
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="toggle-icon"
47
+ style="stroke: currentColor; stroke-width: 2;">
48
+ <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" />
49
+ <path stroke-linecap="round" stroke-linejoin="round" d="M11 19l-7-7 7-7" />
50
+ </svg>
51
+ </button>
52
+ <h1 class="gallery-title">Toast</h1>
53
+ </div>
54
+ </div>
55
+
56
+ <!-- Content -->
57
+ <div class="gallery-content">
58
+ <div class="section-content" style="max-width: 1000px;">
59
+ <p class="text-lg" style="opacity: 0.7; margin-bottom: 1.5rem;">
60
+ Toast is a wrapper to position alert components at the corner of the screen.
61
+ Perfect for notifications and temporary messages.
62
+ </p>
63
+
64
+ <!-- Basic Example with Examplify -->
65
+ <div class="card bg-base-200" style="margin-bottom: 2rem;">
66
+ <div class="card-body">
67
+ <h2 class="card-title">Basic Example</h2>
68
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;">Toast with alert at different
69
+ positions
70
+ </p>
71
+
72
+ <!-- Tabs -->
73
+ <script>
74
+ window.switchSyntaxTab = (tabId) => {
75
+ const tabs = ['tagged', 'vdom', 'object'];
76
+ tabs.forEach(t => {
77
+ const tabEl = document.getElementById(`tab-btn-${t}`);
78
+ const contentEl = document.getElementById(`syntax-${t}`);
79
+ if (t === tabId) {
80
+ tabEl.classList.add('syntax-tab-active');
81
+ contentEl.style.display = 'block';
82
+ } else {
83
+ tabEl.classList.remove('syntax-tab-active');
84
+ contentEl.style.display = 'none';
85
+ }
86
+ });
87
+ };
88
+ </script>
89
+ <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;">
90
+ <button id="tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active"
91
+ onclick="switchSyntaxTab('tagged')">Tagged</button>
92
+ <button id="tab-btn-vdom" role="tab" class="syntax-tab"
93
+ onclick="switchSyntaxTab('vdom')">vDOM</button>
94
+ <button id="tab-btn-object" role="tab" class="syntax-tab"
95
+ onclick="switchSyntaxTab('object')">Object
96
+ DOM</button>
97
+ </div>
98
+
99
+ <!-- Tagged Syntax -->
100
+ <div id="syntax-tagged">
101
+ <pre><script>
102
+ examplify(document.currentScript.nextElementSibling, {
103
+ at: document.currentScript.parentElement,
104
+ scripts: ['/lightview.js', '/lightview-x.js'],
105
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
106
+ type: 'module',
107
+ minHeight: 100,
108
+ autoRun: true,
109
+ html: '<div id="demo" style="height: 80px; position: relative;"></div>'
110
+ });
111
+ </script><code contenteditable="true">await import('/components/data-display/toast.js');
112
+ await import('/components/data-display/alert.js');
113
+
114
+ const { tags, $ } = Lightview;
115
+ const { span, Toast, Alert } = tags;
116
+
117
+ // Toast positioned at bottom-end (default)
118
+ const toast = Toast({ position: 'end', vertical: 'bottom' },
119
+ Alert({ color: 'success', icon: 'success' },
120
+ span({}, 'Message sent successfully!')
121
+ )
122
+ );
123
+
124
+ $('#demo').content(toast);</code></pre>
125
+ </div>
126
+
127
+ <!-- vDOM Syntax -->
128
+ <div id="syntax-vdom" style="display: none;">
129
+ <pre><script>
130
+ examplify(document.currentScript.nextElementSibling, {
131
+ at: document.currentScript.parentElement,
132
+ scripts: ['/lightview.js', '/lightview-x.js'],
133
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
134
+ type: 'module',
135
+ minHeight: 100,
136
+ html: '<div id="demo" style="height: 80px; position: relative;"></div>'
137
+ });
138
+ </script><code contenteditable="true">await import('/components/data-display/toast.js');
139
+ await import('/components/data-display/alert.js');
140
+ const { $, tags } = Lightview;
141
+ const { Toast, Alert, span } = tags;
142
+
143
+ const toast = {
144
+ tag: Toast,
145
+ attributes: { position: 'end', vertical: 'bottom' },
146
+ children: [
147
+ {
148
+ tag: Alert,
149
+ attributes: { color: 'success', icon: 'success' },
150
+ children: [{ tag: span, children: ['Message sent successfully!'] }]
151
+ }
152
+ ]
153
+ };
154
+
155
+ $('#demo').content(toast);</code></pre>
156
+ </div>
157
+
158
+ <!-- Object DOM Syntax -->
159
+ <div id="syntax-object" style="display: none;">
160
+ <pre><script>
161
+ examplify(document.currentScript.nextElementSibling, {
162
+ at: document.currentScript.parentElement,
163
+ scripts: ['/lightview.js', '/lightview-x.js'],
164
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
165
+ type: 'module',
166
+ minHeight: 100,
167
+ html: '<div id="demo" style="height: 80px; position: relative;"></div>'
168
+ });
169
+ </script><code contenteditable="true">await import('/components/data-display/toast.js');
170
+ await import('/components/data-display/alert.js');
171
+ const { $ } = Lightview;
172
+
173
+ const toast = {
174
+ Toast: {
175
+ position: 'end',
176
+ vertical: 'bottom',
177
+ children: [
178
+ {
179
+ Alert: {
180
+ color: 'success',
181
+ icon: 'success',
182
+ children: [
183
+ { span: { children: ['Message sent successfully!'] } }
184
+ ]
185
+ }
186
+ }
187
+ ]
188
+ }
189
+ };
190
+
191
+ $('#demo').content(toast);</code></pre>
192
+ </div>
193
+ </div>
194
+ </div>
195
+
196
+ <!-- Reactive Example with Examplify -->
197
+ <div class="card bg-base-200" style="margin-bottom: 2rem;">
198
+ <div class="card-body">
199
+ <h2 class="card-title">Notification System</h2>
200
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;">Dynamic toasts with
201
+ auto-dismiss</p>
202
+
203
+ <!-- Tabs -->
204
+ <script>
205
+ window.switchReactiveSyntaxTab = (tabId) => {
206
+ const tabs = ['tagged', 'vdom', 'object'];
207
+ tabs.forEach(t => {
208
+ const tabEl = document.getElementById(`reactive-tab-btn-${t}`);
209
+ const contentEl = document.getElementById(`reactive-syntax-${t}`);
210
+ if (t === tabId) {
211
+ tabEl.classList.add('syntax-tab-active');
212
+ contentEl.style.display = 'block';
213
+ } else {
214
+ tabEl.classList.remove('syntax-tab-active');
215
+ contentEl.style.display = 'none';
216
+ }
217
+ });
218
+ };
219
+ </script>
220
+ <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;">
221
+ <button id="reactive-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active"
222
+ onclick="switchReactiveSyntaxTab('tagged')">Tagged</button>
223
+ <button id="reactive-tab-btn-vdom" role="tab" class="syntax-tab"
224
+ onclick="switchReactiveSyntaxTab('vdom')">vDOM</button>
225
+ <button id="reactive-tab-btn-object" role="tab" class="syntax-tab"
226
+ onclick="switchReactiveSyntaxTab('object')">Object DOM</button>
227
+ </div>
228
+
229
+ <!-- Tagged Syntax -->
230
+ <div id="reactive-syntax-tagged">
231
+ <pre><script>
232
+ examplify(document.currentScript.nextElementSibling, {
233
+ at: document.currentScript.parentElement,
234
+ scripts: ['/lightview.js', '/lightview-x.js'],
235
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
236
+ type: 'module',
237
+ minHeight: 180,
238
+ html: '<div id="demo" style="height: 150px; position: relative;"></div>'
239
+ });
240
+ </script><code contenteditable="true">await import('/components/data-display/toast.js');
241
+ await import('/components/data-display/alert.js');
242
+ await import('/components/actions/button.js');
243
+
244
+ const { signal, tags, $ } = Lightview;
245
+ const { div, span, Toast, Alert, Button } = tags;
246
+
247
+ const notifications = signal([]);
248
+ let id = 0;
249
+
250
+ const addNotification = (type) => {
251
+ const messages = {
252
+ success: '✓ Action completed!',
253
+ info: 'ℹ️ New update available',
254
+ warning: '⚠️ Please review',
255
+ error: '✕ Something went wrong'
256
+ };
257
+ const newId = ++id;
258
+ notifications.value = [...notifications.value, { id: newId, type, msg: messages[type] }];
259
+ // Auto-remove after 3 seconds
260
+ setTimeout(() => {
261
+ notifications.value = notifications.value.filter(n => n.id !== newId);
262
+ }, 3000);
263
+ };
264
+
265
+ const demo = div({},
266
+ div({ style: 'display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem' },
267
+ Button({ color: 'success', size: 'sm', onclick: () => addNotification('success') }, 'Success'),
268
+ Button({ color: 'info', size: 'sm', onclick: () => addNotification('info') }, 'Info'),
269
+ Button({ color: 'warning', size: 'sm', onclick: () => addNotification('warning') }, 'Warning'),
270
+ Button({ color: 'error', size: 'sm', onclick: () => addNotification('error') }, 'Error')
271
+ ),
272
+ () => Toast({ position: 'end', vertical: 'top' },
273
+ ...notifications.value.map(n =>
274
+ Alert({ color: n.type, key: n.id }, span({}, n.msg))
275
+ )
276
+ )
277
+ );
278
+
279
+ $('#demo').content(demo);</code></pre>
280
+ </div>
281
+
282
+ <!-- vDOM Syntax -->
283
+ <div id="reactive-syntax-vdom" style="display: none;">
284
+ <pre><script>
285
+ examplify(document.currentScript.nextElementSibling, {
286
+ at: document.currentScript.parentElement,
287
+ scripts: ['/lightview.js', '/lightview-x.js'],
288
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
289
+ type: 'module',
290
+ minHeight: 180,
291
+ html: '<div id="demo" style="height: 150px; position: relative;"></div>'
292
+ });
293
+ </script><code contenteditable="true">await import('/components/data-display/toast.js');
294
+ await import('/components/data-display/alert.js');
295
+ await import('/components/actions/button.js');
296
+ const { signal, $, tags } = Lightview;
297
+ const { Toast, Alert, Button, div, span } = tags;
298
+
299
+ const notifications = signal([]);
300
+ let id = 0;
301
+
302
+ const addNotification = (type) => {
303
+ const messages = {
304
+ success: '✓ Action completed!',
305
+ info: 'ℹ️ New update available',
306
+ warning: '⚠️ Please review',
307
+ error: '✕ Something went wrong'
308
+ };
309
+ const newId = ++id;
310
+ notifications.value = [...notifications.value, { id: newId, type, msg: messages[type] }];
311
+ setTimeout(() => {
312
+ notifications.value = notifications.value.filter(n => n.id !== newId);
313
+ }, 3000);
314
+ };
315
+
316
+ const demo = {
317
+ tag: div,
318
+ children: [
319
+ {
320
+ tag: div,
321
+ attributes: { style: 'display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem' },
322
+ children: [
323
+ { tag: Button, attributes: { color: 'success', size: 'sm', onclick: () => addNotification('success') }, children: ['Success'] },
324
+ { tag: Button, attributes: { color: 'info', size: 'sm', onclick: () => addNotification('info') }, children: ['Info'] },
325
+ { tag: Button, attributes: { color: 'warning', size: 'sm', onclick: () => addNotification('warning') }, children: ['Warning'] },
326
+ { tag: Button, attributes: { color: 'error', size: 'sm', onclick: () => addNotification('error') }, children: ['Error'] }
327
+ ]
328
+ },
329
+ () => ({
330
+ tag: Toast,
331
+ attributes: { position: 'end', vertical: 'top' },
332
+ children: notifications.value.map(n => ({
333
+ tag: Alert,
334
+ attributes: { color: n.type, key: n.id },
335
+ children: [{ tag: span, children: [n.msg] }]
336
+ }))
337
+ })
338
+ ]
339
+ };
340
+
341
+ $('#demo').content(demo);</code></pre>
342
+ </div>
343
+
344
+ <!-- Object DOM Syntax -->
345
+ <div id="reactive-syntax-object" style="display: none;">
346
+ <pre><script>
347
+ examplify(document.currentScript.nextElementSibling, {
348
+ at: document.currentScript.parentElement,
349
+ scripts: ['/lightview.js', '/lightview-x.js'],
350
+ styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
351
+ type: 'module',
352
+ minHeight: 180,
353
+ html: '<div id="demo" style="height: 150px; position: relative;"></div>'
354
+ });
355
+ </script><code contenteditable="true">await import('/components/data-display/toast.js');
356
+ await import('/components/data-display/alert.js');
357
+ await import('/components/actions/button.js');
358
+ const { signal, $ } = Lightview;
359
+
360
+ const notifications = signal([]);
361
+ let id = 0;
362
+
363
+ const addNotification = (type) => {
364
+ const messages = {
365
+ success: '✓ Action completed!',
366
+ info: 'ℹ️ New update available',
367
+ warning: '⚠️ Please review',
368
+ error: '✕ Something went wrong'
369
+ };
370
+ const newId = ++id;
371
+ notifications.value = [...notifications.value, { id: newId, type, msg: messages[type] }];
372
+ setTimeout(() => {
373
+ notifications.value = notifications.value.filter(n => n.id !== newId);
374
+ }, 3000);
375
+ };
376
+
377
+ const demo = {
378
+ div: {
379
+ children: [
380
+ {
381
+ div: {
382
+ style: 'display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem',
383
+ children: [
384
+ { Button: { color: 'success', size: 'sm', onclick: () => addNotification('success'), children: ['Success'] } },
385
+ { Button: { color: 'info', size: 'sm', onclick: () => addNotification('info'), children: ['Info'] } },
386
+ { Button: { color: 'warning', size: 'sm', onclick: () => addNotification('warning'), children: ['Warning'] } },
387
+ { Button: { color: 'error', size: 'sm', onclick: () => addNotification('error'), children: ['Error'] } }
388
+ ]
389
+ }
390
+ },
391
+ () => ({
392
+ Toast: {
393
+ position: 'end',
394
+ vertical: 'top',
395
+ children: notifications.value.map(n => ({
396
+ Alert: {
397
+ color: n.type,
398
+ key: n.id,
399
+ children: [
400
+ { span: { children: [n.msg] } }
401
+ ]
402
+ }
403
+ }))
404
+ }
405
+ })
406
+ ]
407
+ }
408
+ };
409
+
410
+ $('#demo').content(demo);</code></pre>
411
+ </div>
412
+ </div>
413
+ </div>
414
+
415
+ <!-- Props Table -->
416
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Props</h2>
417
+ <div style="overflow-x: auto; margin-bottom: 2rem;">
418
+ <table class="table table-zebra">
419
+ <thead>
420
+ <tr>
421
+ <th>Prop</th>
422
+ <th>Type</th>
423
+ <th>Default</th>
424
+ <th>Description</th>
425
+ </tr>
426
+ </thead>
427
+ <tbody>
428
+ <tr>
429
+ <td><code>position</code></td>
430
+ <td>string</td>
431
+ <td>'end'</td>
432
+ <td>'start' | 'center' | 'end'</td>
433
+ </tr>
434
+ <tr>
435
+ <td><code>vertical</code></td>
436
+ <td>string</td>
437
+ <td>'bottom'</td>
438
+ <td>'top' | 'middle' | 'bottom'</td>
439
+ </tr>
440
+ </tbody>
441
+ </table>
442
+ </div>
443
+
444
+ <!-- Positions Demo -->
445
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Positions</h2>
446
+ <p style="opacity: 0.7; margin-bottom: 1rem;">Click to see toast position (shown for 3 seconds):</p>
447
+ <div class="example-flex" style="margin-bottom: 2rem;">
448
+ <button class="btn btn-sm" onclick="showToast('top', 'start')">Top Start</button>
449
+ <button class="btn btn-sm" onclick="showToast('top', 'center')">Top Center</button>
450
+ <button class="btn btn-sm" onclick="showToast('top', 'end')">Top End</button>
451
+ <button class="btn btn-sm" onclick="showToast('bottom', 'start')">Bottom Start</button>
452
+ <button class="btn btn-sm" onclick="showToast('bottom', 'center')">Bottom Center</button>
453
+ <button class="btn btn-sm" onclick="showToast('bottom', 'end')">Bottom End</button>
454
+ </div>
455
+
456
+ <div id="toast-container"></div>
457
+
458
+
459
+ </div>
460
+ </div>
461
+
462
+ <script>
463
+ function showToast(vertical, horizontal) {
464
+ const container = document.getElementById('toast-container');
465
+ container.innerHTML = `
466
+ <div class="toast toast-${vertical} toast-${horizontal}">
467
+ <div class="alert alert-success">
468
+ <span>Toast at ${vertical}-${horizontal}!</span>
469
+ </div>
470
+ </div>
471
+ `;
472
+ setTimeout(() => container.innerHTML = '', 3000);
473
+ }
474
+ </script>