lightview 1.8.2 → 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 (264) 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 +1330 -19
  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 +610 -15
  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 +485 -42
  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 +132 -42
  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 +659 -1200
  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/docs/CNAME +0 -1
  165. package/docs/api.html +0 -674
  166. package/docs/blank.html +0 -10
  167. package/docs/comparedto.html +0 -89
  168. package/docs/components/chart-repl.html +0 -69
  169. package/docs/components/components.js +0 -113
  170. package/docs/components/contents.html +0 -17
  171. package/docs/components/gantt-repl.html +0 -61
  172. package/docs/components/gantt.html +0 -42
  173. package/docs/components/gauge-repl.html +0 -66
  174. package/docs/components/gauge.html +0 -20
  175. package/docs/components/orgchart-repl.html +0 -64
  176. package/docs/components/orgchart.html +0 -41
  177. package/docs/components/repl-as-src.html +0 -17
  178. package/docs/components/repl-repl.html +0 -95
  179. package/docs/components/repl.html +0 -527
  180. package/docs/components/timeline-repl.html +0 -72
  181. package/docs/components.html +0 -14
  182. package/docs/css/highlightjs.min.css +0 -9
  183. package/docs/css/tutorial.css +0 -35
  184. package/docs/examples/anchor.html +0 -11
  185. package/docs/examples/chart.html +0 -34
  186. package/docs/examples/counter.html +0 -26
  187. package/docs/examples/counter.test.mjs +0 -47
  188. package/docs/examples/counter2.html +0 -26
  189. package/docs/examples/directives.html +0 -79
  190. package/docs/examples/foreign.html +0 -50
  191. package/docs/examples/forgeinform.html +0 -98
  192. package/docs/examples/form.html +0 -61
  193. package/docs/examples/gauge.html +0 -18
  194. package/docs/examples/invalid-template-literals.html +0 -44
  195. package/docs/examples/medium/remote.html +0 -60
  196. package/docs/examples/message.html +0 -18
  197. package/docs/examples/nested.html +0 -11
  198. package/docs/examples/object-bound-form.html +0 -34
  199. package/docs/examples/remote-server.js +0 -51
  200. package/docs/examples/remote.html +0 -34
  201. package/docs/examples/remote.json +0 -1
  202. package/docs/examples/scratch.html +0 -69
  203. package/docs/examples/sensors/index.html +0 -44
  204. package/docs/examples/sensors/sensor-server.js +0 -30
  205. package/docs/examples/shared.html +0 -41
  206. package/docs/examples/template.html +0 -33
  207. package/docs/examples/timeline.html +0 -21
  208. package/docs/examples/todo.html +0 -40
  209. package/docs/examples/top.html +0 -10
  210. package/docs/examples/types.html +0 -94
  211. package/docs/examples/xor.html +0 -62
  212. package/docs/examples.html +0 -25
  213. package/docs/javascript/codejar.min.js +0 -8
  214. package/docs/javascript/highlightjs.min.js +0 -1173
  215. package/docs/javascript/isomorphic-git.js +0 -9
  216. package/docs/javascript/json5.min.js +0 -1
  217. package/docs/javascript/lightning-fs.js +0 -1
  218. package/docs/javascript/lightview.js +0 -1285
  219. package/docs/javascript/marked.min.js +0 -6
  220. package/docs/javascript/peerjs.min.js +0 -70
  221. package/docs/javascript/turndown.js +0 -973
  222. package/docs/javascript/types.js +0 -606
  223. package/docs/javascript/utils.js +0 -45
  224. package/docs/lightview.html +0 -63
  225. package/docs/old_index.html +0 -965
  226. package/docs/old_index.md +0 -1132
  227. package/docs/slidein.html +0 -51
  228. package/docs/tutorial/0-getting-started.html +0 -67
  229. package/docs/tutorial/1-intro-to-variables.html +0 -103
  230. package/docs/tutorial/10-template-components.html +0 -80
  231. package/docs/tutorial/11-linked-components.html +0 -76
  232. package/docs/tutorial/12-imported-components.html +0 -67
  233. package/docs/tutorial/13-input-binding.html +0 -94
  234. package/docs/tutorial/14-automatic-variable-creation.html +0 -74
  235. package/docs/tutorial/15-form-binding.html +0 -110
  236. package/docs/tutorial/16-if-directive.html +0 -60
  237. package/docs/tutorial/17-loop-directives.html +0 -83
  238. package/docs/tutorial/18-sanitizing-and-escaping-input.html +0 -79
  239. package/docs/tutorial/2-imported-and-exported-variables.html +0 -80
  240. package/docs/tutorial/3-data-types.html +0 -89
  241. package/docs/tutorial/4-extended-data-types.html +0 -83
  242. package/docs/tutorial/5-extended-functional-types.html +0 -96
  243. package/docs/tutorial/5.1-extended-functional-types.html +0 -79
  244. package/docs/tutorial/5.2-extended-functional-types.html +0 -70
  245. package/docs/tutorial/6-conventional-javascript.html +0 -75
  246. package/docs/tutorial/7-monitoring-with-observers.html +0 -107
  247. package/docs/tutorial/8-event-listeners.html +0 -65
  248. package/docs/tutorial/9-intro-to-components.html +0 -91
  249. package/docs/tutorial/contents.html +0 -32
  250. package/docs/tutorial/my-component.html +0 -29
  251. package/docs/tutorial/remote-value.json +0 -4
  252. package/docs/websiterepl.html +0 -46
  253. package/jest-puppeteer.config.js +0 -5
  254. package/jest.config.json +0 -12
  255. package/lightview.min.js +0 -1
  256. package/lightview_good.js +0 -1267
  257. package/lightview_optimized.js +0 -1274
  258. package/repl_hold.html +0 -320
  259. package/test/basic.html +0 -104
  260. package/test/basic.test.mjs +0 -315
  261. package/test/extended.html +0 -29
  262. package/test/extended.test.mjs +0 -448
  263. package/types.js +0 -607
  264. package/unsplash.key +0 -1
@@ -0,0 +1,93 @@
1
+ /* eslint-env browser */
2
+ /* global Lightview */
3
+ /**
4
+ * Sidebar Setup Utility
5
+ * Initializes the slide-out drawer functionality for component documentation pages
6
+ */
7
+
8
+ /**
9
+ * Initialize the sidebar drawer functionality
10
+ * This should be called after the DOM is loaded and Lightview is available
11
+ *
12
+ * @example
13
+ * <script type="module">
14
+ * import { initSidebar } from './sidebar-setup.js';
15
+ * initSidebar();
16
+ * </script>
17
+ */
18
+ export function initSidebar() {
19
+ const { signal } = Lightview;
20
+
21
+ // Sidebar state
22
+ const sidebarOpen = signal(false);
23
+
24
+ // Get DOM elements
25
+ const sidebar = document.getElementById('gallery-sidebar');
26
+ const main = document.getElementById('gallery-main');
27
+ const overlay = document.getElementById('sidebar-overlay');
28
+ const toggleBtn = document.getElementById('toggle-btn');
29
+ const toggleIcon = toggleBtn?.querySelector('svg');
30
+
31
+ // Validate required elements exist
32
+ if (!sidebar || !main || !overlay || !toggleBtn || !toggleIcon) {
33
+ console.error('Sidebar elements not found. Required elements:', {
34
+ sidebar: !!sidebar,
35
+ main: !!main,
36
+ overlay: !!overlay,
37
+ toggleBtn: !!toggleBtn,
38
+ toggleIcon: !!toggleIcon
39
+ });
40
+ return;
41
+ }
42
+
43
+ /**
44
+ * Update the UI based on sidebar state
45
+ */
46
+ function updateSidebarUI() {
47
+ sidebar.className = `gallery-sidebar ${sidebarOpen.value ? 'open' : 'closed'}`;
48
+ main.className = `gallery-main ${sidebarOpen.value ? '' : 'sidebar-closed'}`;
49
+ overlay.className = `sidebar-overlay ${sidebarOpen.value ? 'active' : ''}`;
50
+ toggleIcon.setAttribute('class', `toggle-icon ${sidebarOpen.value ? '' : 'rotated'}`);
51
+ }
52
+
53
+ /**
54
+ * Toggle sidebar open/closed
55
+ */
56
+ function toggleSidebar() {
57
+ sidebar.style.visibility = ''; // Remove initial hidden state
58
+ sidebarOpen.value = !sidebarOpen.value;
59
+ updateSidebarUI();
60
+ }
61
+
62
+ /**
63
+ * Close sidebar
64
+ */
65
+ function closeSidebar() {
66
+ sidebarOpen.value = false;
67
+ updateSidebarUI();
68
+ }
69
+
70
+ // Attach event listeners
71
+ toggleBtn.onclick = toggleSidebar;
72
+ overlay.onclick = closeSidebar;
73
+
74
+ // Initial UI update
75
+ updateSidebarUI();
76
+
77
+ // Mark layout as ready - enables sidebar visibility after initial state is set
78
+ const galleryLayout = document.querySelector('.gallery-layout');
79
+ if (galleryLayout) {
80
+ galleryLayout.classList.add('js-ready');
81
+ }
82
+
83
+ // Return API for programmatic control if needed
84
+ return {
85
+ open: () => {
86
+ sidebarOpen.value = true;
87
+ updateSidebarUI();
88
+ },
89
+ close: closeSidebar,
90
+ toggle: toggleSidebar,
91
+ isOpen: () => sidebarOpen.value
92
+ };
93
+ }
@@ -0,0 +1,447 @@
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: 'Skeleton' }
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">Skeleton</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
+ Skeleton is used as placeholder while content is loading.
61
+ Provides visual feedback during data fetching.
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;">Card skeleton layout</p>
69
+
70
+ <!-- Tabs -->
71
+ <script>
72
+ window.switchSyntaxTab = (tabId) => {
73
+ const tabs = ['tagged', 'vdom', 'object'];
74
+ tabs.forEach(t => {
75
+ const tabEl = document.getElementById(`tab-btn-${t}`);
76
+ const contentEl = document.getElementById(`syntax-${t}`);
77
+ if (t === tabId) {
78
+ tabEl.classList.add('syntax-tab-active');
79
+ contentEl.style.display = 'block';
80
+ } else {
81
+ tabEl.classList.remove('syntax-tab-active');
82
+ contentEl.style.display = 'none';
83
+ }
84
+ });
85
+ };
86
+ </script>
87
+ <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;">
88
+ <button id="tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active"
89
+ onclick="switchSyntaxTab('tagged')">Tagged</button>
90
+ <button id="tab-btn-vdom" role="tab" class="syntax-tab"
91
+ onclick="switchSyntaxTab('vdom')">vDOM</button>
92
+ <button id="tab-btn-object" role="tab" class="syntax-tab"
93
+ onclick="switchSyntaxTab('object')">Object
94
+ DOM</button>
95
+ </div>
96
+
97
+ <!-- Tagged Syntax -->
98
+ <div id="syntax-tagged">
99
+ <pre><script>
100
+ examplify(document.currentScript.nextElementSibling, {
101
+ at: document.currentScript.parentElement,
102
+ scripts: ['/lightview.js', '/lightview-x.js'],
103
+ type: 'module',
104
+ minHeight: 200,
105
+ autoRun: true
106
+ });
107
+ </script><code contenteditable="true">const { default: Skeleton } = await import('/components/data-display/skeleton.js');
108
+ const { tags, $ } = Lightview;
109
+ const { div } = tags;
110
+
111
+ const cardSkeleton = div({ style: 'display: flex; flex-direction: column; gap: 1rem; width: 13rem' },
112
+ Skeleton({ class: 'h-32 w-full' }),
113
+ Skeleton({ class: 'h-4 w-28' }),
114
+ Skeleton({ class: 'h-4 w-full' }),
115
+ Skeleton({ class: 'h-4 w-full' })
116
+ );
117
+
118
+ $('#example').content(cardSkeleton);</code></pre>
119
+ </div>
120
+
121
+ <!-- vDOM Syntax -->
122
+ <div id="syntax-vdom" style="display: none;">
123
+ <pre><script>
124
+ examplify(document.currentScript.nextElementSibling, {
125
+ at: document.currentScript.parentElement,
126
+ scripts: ['/lightview.js', '/lightview-x.js'],
127
+ type: 'module',
128
+ minHeight: 200
129
+ });
130
+ </script><code contenteditable="true">const { default: Skeleton } = await import('/components/data-display/skeleton.js');
131
+ const { $ } = Lightview;
132
+
133
+ const cardSkeleton = {
134
+ tag: 'div',
135
+ attributes: { style: 'display: flex; flex-direction: column; gap: 1rem; width: 13rem' },
136
+ children: [
137
+ { tag: Skeleton, attributes: { class: 'h-32 w-full' } },
138
+ { tag: Skeleton, attributes: { class: 'h-4 w-28' } },
139
+ { tag: Skeleton, attributes: { class: 'h-4 w-full' } },
140
+ { tag: Skeleton, attributes: { class: 'h-4 w-full' } }
141
+ ]
142
+ };
143
+
144
+ $('#example').content(cardSkeleton);</code></pre>
145
+ </div>
146
+
147
+ <!-- Object DOM Syntax -->
148
+ <div id="syntax-object" style="display: none;">
149
+ <pre><script>
150
+ examplify(document.currentScript.nextElementSibling, {
151
+ at: document.currentScript.parentElement,
152
+ scripts: ['/lightview.js', '/lightview-x.js'],
153
+ type: 'module',
154
+ minHeight: 200
155
+ });
156
+ </script><code contenteditable="true">const { default: Skeleton } = await import('/components/data-display/skeleton.js');
157
+ const { tags, $ } = Lightview;
158
+ tags.Skeleton = Skeleton;
159
+
160
+ $('#example').content({
161
+ div: {
162
+ style: 'display: flex; flex-direction: column; gap: 1rem; width: 13rem',
163
+ children: [
164
+ { Skeleton: { class: 'h-32 w-full' } },
165
+ { Skeleton: { class: 'h-4 w-28' } },
166
+ { Skeleton: { class: 'h-4 w-full' } },
167
+ { Skeleton: { class: 'h-4 w-full' } }
168
+ ]
169
+ }
170
+ });</code></pre>
171
+ </div>
172
+ </div>
173
+ </div>
174
+
175
+ <!-- Reactive Example with Examplify -->
176
+ <div class="card bg-base-200" style="margin-bottom: 2rem;">
177
+ <div class="card-body">
178
+ <h2 class="card-title">Loading State</h2>
179
+ <p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;">Toggle between skeleton and
180
+ content</p>
181
+
182
+ <!-- Tabs -->
183
+ <script>
184
+ window.switchReactiveSyntaxTab = (tabId) => {
185
+ const tabs = ['tagged', 'vdom', 'object'];
186
+ tabs.forEach(t => {
187
+ const tabEl = document.getElementById(`reactive-tab-btn-${t}`);
188
+ const contentEl = document.getElementById(`reactive-syntax-${t}`);
189
+ if (t === tabId) {
190
+ tabEl.classList.add('syntax-tab-active');
191
+ contentEl.style.display = 'block';
192
+ } else {
193
+ tabEl.classList.remove('syntax-tab-active');
194
+ contentEl.style.display = 'none';
195
+ }
196
+ });
197
+ };
198
+ </script>
199
+ <div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;">
200
+ <button id="reactive-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active"
201
+ onclick="switchReactiveSyntaxTab('tagged')">Tagged</button>
202
+ <button id="reactive-tab-btn-vdom" role="tab" class="syntax-tab"
203
+ onclick="switchReactiveSyntaxTab('vdom')">vDOM</button>
204
+ <button id="reactive-tab-btn-object" role="tab" class="syntax-tab"
205
+ onclick="switchReactiveSyntaxTab('object')">Object DOM</button>
206
+ </div>
207
+
208
+ <!-- Tagged Syntax -->
209
+ <div id="reactive-syntax-tagged">
210
+ <pre><script>
211
+ examplify(document.currentScript.nextElementSibling, {
212
+ at: document.currentScript.parentElement,
213
+ scripts: ['/lightview.js', '/lightview-x.js'],
214
+ type: 'module',
215
+ minHeight: 380
216
+ });
217
+ </script><code contenteditable="true">const { default: Skeleton } = await import('/components/data-display/skeleton.js');
218
+ const { default: Button } = await import('/components/actions/button.js');
219
+ const { default: Card } = await import('/components/data-display/card.js');
220
+
221
+ const { signal, tags, $ } = Lightview;
222
+ const { div, p, h3, img } = tags;
223
+
224
+ const loading = signal(true);
225
+
226
+ // Simulate data loading
227
+ setTimeout(() => { loading.value = false; }, 2000);
228
+
229
+ const demo = div({ class: 'w-64' },
230
+ () => loading.value
231
+ ? div({ style: 'display: flex; flex-direction: column; gap: 1rem' },
232
+ Skeleton({ class: 'h-40 w-full rounded-lg' }),
233
+ Skeleton({ class: 'h-6 w-3/4' }),
234
+ Skeleton({ class: 'h-4 w-full' }),
235
+ Skeleton({ class: 'h-10 w-24' })
236
+ )
237
+ : Card({},
238
+ Card.Figure({
239
+ src: 'https://picsum.photos/300/200?random=20',
240
+ alt: 'Loaded content'
241
+ }),
242
+ Card.Body({},
243
+ Card.Title({}, 'Content Loaded'),
244
+ p({}, 'This is the actual content!'),
245
+ Button({ color: 'primary', size: 'sm' }, 'Action')
246
+ )
247
+ ),
248
+ Button({
249
+ class: 'mt-4',
250
+ size: 'sm',
251
+ onclick: () => { loading.value = true; setTimeout(() => { loading.value = false; }, 2000); }
252
+ }, 'Reload')
253
+ );
254
+
255
+ $('#example').content(demo);</code></pre>
256
+ </div>
257
+
258
+ <!-- vDOM Syntax -->
259
+ <div id="reactive-syntax-vdom" style="display: none;">
260
+ <pre><script>
261
+ examplify(document.currentScript.nextElementSibling, {
262
+ at: document.currentScript.parentElement,
263
+ scripts: ['/lightview.js', '/lightview-x.js'],
264
+ type: 'module',
265
+ minHeight: 380
266
+ });
267
+ </script><code contenteditable="true">const { default: Skeleton } = await import('/components/data-display/skeleton.js');
268
+ const { default: Button } = await import('/components/actions/button.js');
269
+ const { default: Card } = await import('/components/data-display/card.js');
270
+ const { signal, $ } = Lightview;
271
+
272
+ const loading = signal(true);
273
+
274
+ setTimeout(() => { loading.value = false; }, 2000);
275
+
276
+ const demo = {
277
+ tag: 'div',
278
+ attributes: { class: 'w-64' },
279
+ children: [
280
+ () => loading.value
281
+ ? {
282
+ tag: 'div',
283
+ attributes: { style: 'display: flex; flex-direction: column; gap: 1rem' },
284
+ children: [
285
+ { tag: Skeleton, attributes: { class: 'h-40 w-full rounded-lg' } },
286
+ { tag: Skeleton, attributes: { class: 'h-6 w-3/4' } },
287
+ { tag: Skeleton, attributes: { class: 'h-4 w-full' } },
288
+ { tag: Skeleton, attributes: { class: 'h-10 w-24' } }
289
+ ]
290
+ }
291
+ : {
292
+ tag: Card,
293
+ children: [
294
+ {
295
+ tag: Card.Figure,
296
+ attributes: {
297
+ src: 'https://picsum.photos/300/200?random=20',
298
+ alt: 'Loaded content'
299
+ }
300
+ },
301
+ {
302
+ tag: Card.Body,
303
+ children: [
304
+ { tag: Card.Title, children: ['Content Loaded'] },
305
+ { tag: 'p', children: ['This is the actual content!'] },
306
+ { tag: Button, attributes: { color: 'primary', size: 'sm' }, children: ['Action'] }
307
+ ]
308
+ }
309
+ ]
310
+ },
311
+ {
312
+ tag: Button,
313
+ attributes: {
314
+ class: 'mt-4',
315
+ size: 'sm',
316
+ onclick: () => { loading.value = true; setTimeout(() => { loading.value = false; }, 2000); }
317
+ },
318
+ children: ['Reload']
319
+ }
320
+ ]
321
+ };
322
+
323
+ $('#example').content(demo);</code></pre>
324
+ </div>
325
+
326
+ <!-- Object DOM Syntax -->
327
+ <div id="reactive-syntax-object" style="display: none;">
328
+ <pre><script>
329
+ examplify(document.currentScript.nextElementSibling, {
330
+ at: document.currentScript.parentElement,
331
+ scripts: ['/lightview.js', '/lightview-x.js'],
332
+ type: 'module',
333
+ minHeight: 380
334
+ });
335
+ </script><code contenteditable="true">const { default: Skeleton } = await import('/components/data-display/skeleton.js');
336
+ const { default: Button } = await import('/components/actions/button.js');
337
+ const { default: Card } = await import('/components/data-display/card.js');
338
+ const { signal, tags, $ } = Lightview;
339
+ tags.Skeleton = Skeleton;
340
+ tags.Button = Button;
341
+ tags.Card = Card;
342
+
343
+ const loading = signal(true);
344
+
345
+ setTimeout(() => { loading.value = false; }, 2000);
346
+
347
+ const demo = {
348
+ div: {
349
+ class: 'w-64',
350
+ children: [
351
+ () => loading.value
352
+ ? {
353
+ div: {
354
+ style: 'display: flex; flex-direction: column; gap: 1rem',
355
+ children: [
356
+ { Skeleton: { class: 'h-40 w-full rounded-lg' } },
357
+ { Skeleton: { class: 'h-6 w-3/4' } },
358
+ { Skeleton: { class: 'h-4 w-full' } },
359
+ { Skeleton: { class: 'h-10 w-24' } }
360
+ ]
361
+ }
362
+ }
363
+ : {
364
+ Card: {
365
+ children: [
366
+ {
367
+ 'Card.Figure': {
368
+ src: 'https://picsum.photos/300/200?random=20',
369
+ alt: 'Loaded content'
370
+ }
371
+ },
372
+ {
373
+ 'Card.Body': {
374
+ children: [
375
+ { 'Card.Title': { text: 'Content Loaded' } },
376
+ { p: { text: 'This is the actual content!' } },
377
+ { Button: { color: 'primary', size: 'sm', text: 'Action' } }
378
+ ]
379
+ }
380
+ }
381
+ ]
382
+ }
383
+ },
384
+ {
385
+ Button: {
386
+ class: 'mt-4',
387
+ size: 'sm',
388
+ onclick: () => { loading.value = true; setTimeout(() => { loading.value = false; }, 2000); },
389
+ text: 'Reload'
390
+ }
391
+ }
392
+ ]
393
+ }
394
+ };
395
+
396
+ $('#example').content(demo);</code></pre>
397
+ </div>
398
+ </div>
399
+ </div>
400
+
401
+ <!-- Props Table -->
402
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Props</h2>
403
+ <div style="overflow-x: auto; margin-bottom: 2rem;">
404
+ <table class="table table-zebra">
405
+ <thead>
406
+ <tr>
407
+ <th>Prop</th>
408
+ <th>Type</th>
409
+ <th>Default</th>
410
+ <th>Description</th>
411
+ </tr>
412
+ </thead>
413
+ <tbody>
414
+ <tr>
415
+ <td><code>class</code></td>
416
+ <td>string</td>
417
+ <td>-</td>
418
+ <td>Width/height classes (h-32 w-full, rounded-full, etc.)</td>
419
+ </tr>
420
+ </tbody>
421
+ </table>
422
+ </div>
423
+
424
+ <!-- Examples -->
425
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Card Skeleton</h2>
426
+ <div style="display: flex; width: 13rem; flex-direction: column; gap: 1rem; margin-bottom: 2rem;">
427
+ <div class="skeleton h-32 w-full"></div>
428
+ <div class="skeleton h-4 w-28"></div>
429
+ <div class="skeleton h-4 w-full"></div>
430
+ <div class="skeleton h-4 w-full"></div>
431
+ </div>
432
+
433
+ <h2 class="text-xl font-bold" style="margin-bottom: 1rem;">With Avatar</h2>
434
+ <div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 2rem;">
435
+ <div class="skeleton h-16 w-16 shrink-0 rounded-full"></div>
436
+ <div style="display: flex; flex-direction: column; gap: 1rem">
437
+ <div class="skeleton h-4 w-20"></div>
438
+ <div class="skeleton h-4 w-28"></div>
439
+ </div>
440
+ </div>
441
+ </div>
442
+ </div>
443
+ </div>
444
+ </div>
445
+ </div>
446
+ </div>
447
+ </div>
@@ -0,0 +1,68 @@
1
+ <!-- SEO-friendly SPA Shim -->
2
+ <script src="/lightview-router.js"></script>
3
+ <script>
4
+ if (window.LightviewRouter) {
5
+ window.location.replace('/docs/components/loading');
6
+ } else {
7
+ window.location.href = 'loading.html';
8
+ }
9
+ </script>
10
+
11
+ <!-- Load the page-specific stylesheet -->
12
+ <link rel="stylesheet" href="./index.css">
13
+
14
+ <!-- Gallery Structure -->
15
+ <div class="gallery-page">
16
+ <div class="gallery-layout">
17
+ <!-- Sidebar Overlay -->
18
+ <div id="sidebar-overlay" class="sidebar-overlay"></div>
19
+
20
+ <!-- Sidebar -->
21
+ <div id="gallery-sidebar" class="gallery-sidebar" style="visibility: hidden" src="./component-nav.html"></div>
22
+
23
+ <!-- Main Content -->
24
+ <div id="gallery-main" class="gallery-main">
25
+ <!-- Header Container -->
26
+ <div
27
+ style="position: sticky; top: 0; z-index: 30; background: var(--gallery-surface); border-bottom: 1px solid var(--gallery-border); backdrop-filter: blur(8px);">
28
+ <!-- Breadcrumbs Row -->
29
+ <div style="padding: 0.75rem 1.5rem 0;">
30
+ <script>
31
+ (() => {
32
+ const { Breadcrumbs } = Lightview.tags;
33
+ const breadcrumbs = Breadcrumbs({
34
+ id: 'page-breadcrumbs',
35
+ items: [
36
+ { label: 'Components', href: '/docs/components' },
37
+ { label: 'Spinner' }
38
+ ]
39
+ });
40
+ document.currentScript.replaceWith(breadcrumbs.domEl);
41
+ })();
42
+ </script>
43
+ </div>
44
+ <!-- Title Row -->
45
+ <div class="gallery-header"
46
+ style="border-bottom: none; height: auto; padding-top: 0.5rem; padding-bottom: 0.75rem;">
47
+ <button id="toggle-btn" class="toggle-btn" aria-label="Toggle Sidebar">
48
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="toggle-icon"
49
+ style="stroke: currentColor; stroke-width: 2;">
50
+ <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" />
51
+ <path stroke-linecap="round" stroke-linejoin="round" d="M11 19l-7-7 7-7" />
52
+ </svg>
53
+ </button>
54
+ <h1 class="gallery-title">Spinner</h1>
55
+ </div>
56
+ </div>
57
+
58
+ <!-- Content -->
59
+ <div class="gallery-content">
60
+ <div class="section-content" style="max-width: 1000px;">
61
+ <p class="text-lg" style="opacity: 0.7; margin-bottom: 1.5rem;">
62
+ Redirecting to <a href="/docs/components/loading">Loading</a>...
63
+ </p>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>