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,82 @@
1
+ /**
2
+ * Lightview Badge Component (DaisyUI)
3
+ * @see https://daisyui.com/components/badge/
4
+ */
5
+
6
+ import '../daisyui.js';
7
+
8
+ /**
9
+ * Badge Component
10
+ * @param {Object} props
11
+ * @param {string} props.color - 'primary' | 'secondary' | 'accent' | 'neutral' | 'info' | 'success' | 'warning' | 'error' | 'ghost'
12
+ * @param {string} props.size - 'xs' | 'sm' | 'md' | 'lg'
13
+ * @param {string} props.variant - 'outline' | 'soft' | 'dash'
14
+ * @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
15
+ */
16
+ const Badge = (props = {}, ...children) => {
17
+ const { tags } = window.Lightview || {};
18
+ const LVX = window.LightviewX || {};
19
+
20
+ if (!tags) return null;
21
+
22
+ const { span, div, shadowDOM } = tags;
23
+
24
+ const {
25
+ color,
26
+ size,
27
+ variant,
28
+ useShadow,
29
+ theme, // Explicit theme override
30
+ class: className = '',
31
+ ...rest
32
+ } = props;
33
+
34
+ const classes = ['badge'];
35
+
36
+ if (color) classes.push(`badge-${color}`);
37
+ if (size) classes.push(`badge-${size}`);
38
+ if (variant === 'outline') classes.push('badge-outline');
39
+ else if (variant === 'soft') classes.push('badge-soft');
40
+ else if (variant === 'dash') classes.push('badge-dash');
41
+
42
+ if (className) classes.push(className);
43
+
44
+ const badgeEl = span({ class: classes.join(' '), ...rest }, ...children);
45
+
46
+ // Check if we should use shadow DOM
47
+ let usesShadow = false;
48
+ if (LVX.shouldUseShadow) {
49
+ usesShadow = LVX.shouldUseShadow(useShadow);
50
+ } else {
51
+ usesShadow = useShadow === true;
52
+ }
53
+
54
+ if (usesShadow) {
55
+ const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
56
+
57
+ // Use reactive theme signal if available, otherwise fallback to explicit 'theme' prop or default
58
+ const themeValue = theme || (LVX.themeSignal ? () => LVX.themeSignal.value : 'light');
59
+
60
+ return div({ class: 'content', style: 'display: inline-block' },
61
+ shadowDOM({ mode: 'open', adoptedStyleSheets },
62
+ div({ 'data-theme': themeValue },
63
+ badgeEl
64
+ )
65
+ )
66
+ );
67
+ }
68
+
69
+ return badgeEl;
70
+ };
71
+
72
+ window.Lightview.tags.Badge = Badge;
73
+
74
+ // Register as Custom Element
75
+ if (window.LightviewX?.createCustomElement) {
76
+ const BadgeElement = window.LightviewX.createCustomElement(Badge);
77
+ if (!customElements.get('lv-badge')) {
78
+ customElements.define('lv-badge', BadgeElement);
79
+ }
80
+ }
81
+
82
+ export default Badge;
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Lightview Card Component (DaisyUI)
3
+ * @see https://daisyui.com/components/card/
4
+ */
5
+
6
+ import '../daisyui.js';
7
+
8
+ /**
9
+ * Card Component
10
+ * @param {Object} props
11
+ * @param {string} props.variant - 'bordered' | 'dash' | 'side' | 'compact'
12
+ * @param {string} props.imageFull - Image fills width
13
+ * @param {string} props.bg - Background class (e.g., 'bg-base-100')
14
+ * @param {string} props.shadow - Shadow class (e.g., 'shadow-sm', 'shadow-xl')
15
+ * @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
16
+ */
17
+ const Card = (props = {}, ...children) => {
18
+ const { tags } = window.Lightview || {};
19
+ const LVX = window.LightviewX || {};
20
+
21
+ if (!tags) return null;
22
+
23
+ const { div, shadowDOM } = tags;
24
+
25
+ const {
26
+ variant,
27
+ imageFull = false,
28
+ bg = 'bg-base-100',
29
+ shadow = 'shadow-sm',
30
+ useShadow,
31
+ class: className = '',
32
+ ...rest
33
+ } = props;
34
+
35
+ const classes = ['card', bg, shadow];
36
+
37
+ if (variant === 'bordered') classes.push('card-bordered');
38
+ else if (variant === 'dash') classes.push('card-dash');
39
+ else if (variant === 'side') classes.push('card-side');
40
+ else if (variant === 'compact') classes.push('card-compact');
41
+
42
+ if (imageFull) classes.push('image-full');
43
+ if (className) classes.push(className);
44
+
45
+ const cardEl = div({ class: classes.join(' '), ...rest }, ...children);
46
+
47
+ // Check if we should use shadow DOM
48
+ let usesShadow = false;
49
+ if (LVX.shouldUseShadow) {
50
+ usesShadow = LVX.shouldUseShadow(useShadow);
51
+ } else {
52
+ usesShadow = useShadow === true;
53
+ }
54
+
55
+ if (usesShadow) {
56
+ const mixedSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets(null, props.styleSheets) : [];
57
+ const adoptedStyleSheets = mixedSheets.filter(s => s instanceof CSSStyleSheet);
58
+ const fallbackLinks = mixedSheets.filter(s => typeof s === 'string');
59
+
60
+ // Use reactive theme signal if available (matches Button pattern)
61
+ const themeValue = LVX.themeSignal ? () => LVX.themeSignal.value : 'light';
62
+
63
+ return div({ class: 'contents' },
64
+ shadowDOM({ mode: 'open', adoptedStyleSheets },
65
+ // Inject fallback links if any
66
+ ...fallbackLinks.map(url => tags.link({ rel: 'stylesheet', href: url })),
67
+ div({ 'data-theme': themeValue },
68
+ cardEl
69
+ )
70
+ )
71
+ );
72
+ }
73
+
74
+ return cardEl;
75
+ };
76
+
77
+ /**
78
+ * Card Body
79
+ */
80
+ Card.Body = (props = {}, ...children) => {
81
+ const { tags } = window.Lightview || {};
82
+ if (!tags) return null;
83
+
84
+ const { class: className = '', ...rest } = props;
85
+
86
+ return tags.div({
87
+ class: `card-body ${className}`.trim(),
88
+ ...rest
89
+ }, ...children);
90
+ };
91
+
92
+ /**
93
+ * Card Title
94
+ */
95
+ Card.Title = (props = {}, ...children) => {
96
+ const { tags } = window.Lightview || {};
97
+ if (!tags) return null;
98
+
99
+ const { class: className = '', ...rest } = props;
100
+
101
+ return tags.h2({
102
+ class: `card-title ${className}`.trim(),
103
+ ...rest
104
+ }, ...children);
105
+ };
106
+
107
+ /**
108
+ * Card Actions
109
+ */
110
+ Card.Actions = (props = {}, ...children) => {
111
+ const { tags } = window.Lightview || {};
112
+ if (!tags) return null;
113
+
114
+ const {
115
+ justify = 'end',
116
+ class: className = '',
117
+ ...rest
118
+ } = props;
119
+
120
+ return tags.div({
121
+ class: `card-actions justify-${justify} ${className}`.trim(),
122
+ ...rest
123
+ }, ...children);
124
+ };
125
+
126
+ /**
127
+ * Card Figure (for images)
128
+ */
129
+ Card.Figure = (props = {}, ...children) => {
130
+ const { tags } = window.Lightview || {};
131
+ if (!tags) return null;
132
+
133
+ const { src, alt = '', class: className = '', ...rest } = props;
134
+
135
+ if (src) {
136
+ return tags.figure({ class: className, ...rest },
137
+ tags.img({ src, alt })
138
+ );
139
+ }
140
+
141
+ return tags.figure({ class: className, ...rest }, ...children);
142
+ };
143
+
144
+ const tags = window.Lightview.tags;
145
+ tags.Card = Card;
146
+ tags['Card.Body'] = Card.Body;
147
+ tags['Card.Title'] = Card.Title;
148
+ tags['Card.Actions'] = Card.Actions;
149
+ tags['Card.Figure'] = Card.Figure;
150
+
151
+ export default Card;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Lightview Carousel Component (DaisyUI)
3
+ * @see https://daisyui.com/components/carousel/
4
+ */
5
+
6
+ import '../daisyui.js';
7
+
8
+ /**
9
+ * Carousel Component
10
+ * @param {Object} props
11
+ * @param {string} props.snap - 'start' | 'center' | 'end'
12
+ * @param {boolean} props.vertical - Vertical carousel
13
+ * @param {boolean} props.full - Full width items
14
+ * @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
15
+ */
16
+ const Carousel = (props = {}, ...children) => {
17
+ const { tags } = window.Lightview || {};
18
+ const LVX = window.LightviewX || {};
19
+
20
+ if (!tags) return null;
21
+
22
+ const { div, shadowDOM } = tags;
23
+
24
+ const {
25
+ snap = 'start',
26
+ vertical = false,
27
+ full = false,
28
+ useShadow,
29
+ class: className = '',
30
+ ...rest
31
+ } = props;
32
+
33
+ const classes = ['carousel'];
34
+
35
+ if (snap === 'center') classes.push('carousel-center');
36
+ else if (snap === 'end') classes.push('carousel-end');
37
+
38
+ if (vertical) classes.push('carousel-vertical');
39
+ if (full) classes.push('w-full');
40
+ if (className) classes.push(className);
41
+
42
+ const carouselEl = div({ class: classes.join(' '), ...rest }, ...children);
43
+
44
+ // Check if we should use shadow DOM
45
+ let usesShadow = false;
46
+ if (LVX.shouldUseShadow) {
47
+ usesShadow = LVX.shouldUseShadow(useShadow);
48
+ } else {
49
+ usesShadow = useShadow === true;
50
+ }
51
+
52
+ if (usesShadow) {
53
+ const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
54
+
55
+ const themeValue = LVX.themeSignal ? () => LVX.themeSignal.value : 'light';
56
+
57
+ return div({ class: 'contents' },
58
+ shadowDOM({ mode: 'open', adoptedStyleSheets },
59
+ div({ 'data-theme': themeValue },
60
+ carouselEl
61
+ )
62
+ )
63
+ );
64
+ }
65
+
66
+ return carouselEl;
67
+ };
68
+
69
+ /**
70
+ * Carousel Item
71
+ */
72
+ Carousel.Item = (props = {}, ...children) => {
73
+ const { tags } = window.Lightview || {};
74
+ if (!tags) return null;
75
+
76
+ const { id, src, alt = '', class: className = '', ...rest } = props;
77
+
78
+ const classes = ['carousel-item'];
79
+ if (className) classes.push(className);
80
+
81
+ if (src) {
82
+ return tags.div({ id, class: classes.join(' '), ...rest },
83
+ tags.img({ src, alt })
84
+ );
85
+ }
86
+
87
+ return tags.div({ id, class: classes.join(' '), ...rest }, ...children);
88
+ };
89
+
90
+ const tags = window.Lightview.tags;
91
+ tags.Carousel = Carousel;
92
+ tags['Carousel.Item'] = Carousel.Item;
93
+
94
+ export default Carousel;
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Lightview Chart Component
3
+ * Powered by charts.css
4
+ * @see https://chartscss.org/
5
+ */
6
+
7
+ import '../daisyui.js';
8
+
9
+ /**
10
+ * Chart Component
11
+ * @param {Object} props
12
+ * @param {string} props.type - 'bar' | 'column' | 'line' | 'area' | 'pie'
13
+ * @param {string} props.heading - Table caption / Chart heading
14
+ * @param {boolean} props.labels - Show labels (.show-labels)
15
+ * @param {boolean} props.dataOnHover - Show data on hover (.show-data-on-hover)
16
+ * @param {boolean} props.primaryAxis - Show primary axis (.show-primary-axis)
17
+ * @param {boolean|string} props.secondaryAxis - Show secondary axes (.show-10-secondary-axes or custom class)
18
+ * @param {number} props.spacing - Data spacing (1-20) (.data-spacing-X)
19
+ * @param {boolean} props.reverse - Reverse orientation (.reverse)
20
+ * @param {boolean} props.multiple - Enable multiple datasets (.multiple)
21
+ * @param {boolean} props.stacked - Enable stacked mode (.stacked)
22
+ * @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
23
+ * @param {string} props.class - Additional classes
24
+ */
25
+ const CHARTS_CSS_URL = 'https://cdn.jsdelivr.net/npm/charts.css/dist/charts.min.css';
26
+
27
+ // Auto-load charts.css for Global/Light DOM usage
28
+ if (typeof document !== 'undefined') {
29
+ if (!document.querySelector(`link[href^="https://cdn.jsdelivr.net/npm/charts.css"]`)) {
30
+ const link = document.createElement('link');
31
+ link.rel = 'stylesheet';
32
+ link.href = CHARTS_CSS_URL;
33
+ document.head.appendChild(link);
34
+ }
35
+ }
36
+
37
+ const Chart = (props = {}, ...children) => {
38
+ const { tags } = window.Lightview || {};
39
+ const LVX = window.LightviewX || {};
40
+
41
+ if (!tags) return null;
42
+
43
+ const { table, caption, div, shadowDOM } = tags;
44
+
45
+ const {
46
+ type = 'bar',
47
+ heading,
48
+ labels = false,
49
+ dataOnHover = false,
50
+ primaryAxis = false,
51
+ secondaryAxis = false,
52
+ spacing,
53
+ reverse = false,
54
+ multiple = false,
55
+ stacked = false,
56
+ useShadow,
57
+ class: className = '',
58
+ style = '',
59
+ ...rest
60
+ } = props;
61
+
62
+ const classes = ['charts-css', type];
63
+ if (labels) classes.push('show-labels');
64
+ if (dataOnHover) classes.push('show-data-on-hover');
65
+ if (heading) classes.push('show-heading');
66
+ if (primaryAxis) classes.push('show-primary-axis');
67
+
68
+ if (secondaryAxis === true) classes.push('show-10-secondary-axes');
69
+ else if (typeof secondaryAxis === 'string') classes.push(secondaryAxis);
70
+
71
+ if (spacing) classes.push(`data-spacing-${spacing}`);
72
+ if (reverse) classes.push('reverse');
73
+ if (multiple) classes.push('multiple');
74
+ if (stacked) classes.push('stacked');
75
+ if (className) classes.push(className);
76
+
77
+ const content = [];
78
+ if (heading) {
79
+ content.push(caption(heading));
80
+ }
81
+ content.push(...children);
82
+
83
+ const chartEl = table({ class: classes.join(' '), style, ...rest }, ...content);
84
+
85
+ // Check if we should use shadow DOM
86
+ let usesShadow = false;
87
+ if (LVX.shouldUseShadow) {
88
+ usesShadow = LVX.shouldUseShadow(useShadow);
89
+ } else {
90
+ usesShadow = useShadow === true;
91
+ }
92
+
93
+ if (usesShadow) {
94
+ const rawSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets(null, [CHARTS_CSS_URL]) : [];
95
+ // Separate CSSStyleSheet objects from URL string fallbacks
96
+ const adoptedStyleSheets = rawSheets.filter(s => typeof s !== 'string');
97
+ const styles = rawSheets.filter(s => typeof s === 'string');
98
+
99
+ const themeValue = LVX.themeSignal ? () => LVX.themeSignal.value : 'light';
100
+
101
+ return div({ class: 'contents' },
102
+ shadowDOM({ mode: 'open', adoptedStyleSheets, styles },
103
+ div({ 'data-theme': themeValue },
104
+ chartEl
105
+ )
106
+ )
107
+ );
108
+ }
109
+
110
+ return chartEl;
111
+ };
112
+
113
+
114
+ /**
115
+ * Chart Head (thead)
116
+ */
117
+ Chart.Head = (props = {}, ...children) => {
118
+ const { tags } = window.Lightview || {};
119
+ if (!tags) return null;
120
+ return tags.thead(props, ...children);
121
+ };
122
+
123
+ /**
124
+ * Chart Body (tbody)
125
+ */
126
+ Chart.Body = (props = {}, ...children) => {
127
+ const { tags } = window.Lightview || {};
128
+ if (!tags) return null;
129
+ return tags.tbody(props, ...children);
130
+ };
131
+
132
+ /**
133
+ * Chart Row (tr)
134
+ */
135
+ Chart.Row = (props = {}, ...children) => {
136
+ const { tags } = window.Lightview || {};
137
+ if (!tags) return null;
138
+ return tags.tr(props, ...children);
139
+ };
140
+
141
+ /**
142
+ * Chart Label (th scope="row")
143
+ */
144
+ Chart.Label = (props = {}, ...children) => {
145
+ const { tags } = window.Lightview || {};
146
+ if (!tags) return null;
147
+
148
+ const { scope = 'row', ...rest } = props;
149
+ return tags.th({ scope, ...rest }, ...children);
150
+ };
151
+
152
+ /**
153
+ * Chart Data (td)
154
+ * @param {Object} props
155
+ * @param {number} props.value - Value (0.0 - 1.0) -> --size (for bar/column/line/area charts)
156
+ * @param {number} props.start - Start value (0.0 - 1.0) -> --start (for range/waterfall and pie)
157
+ * @param {number} props.end - End value (0.0 - 1.0) -> --end (for pie charts - use instead of value)
158
+ * @param {string} props.color - CSS color -> --color
159
+ * @param {string} props.tooltip - Tooltip text
160
+ */
161
+ Chart.Data = (props = {}, ...children) => {
162
+ const { tags } = window.Lightview || {};
163
+ if (!tags) return null;
164
+
165
+ const {
166
+ value,
167
+ size, // alias for value
168
+ start,
169
+ end, // for pie charts
170
+ color,
171
+ tooltip,
172
+ class: className = '',
173
+ style: styleProp = '',
174
+ ...rest
175
+ } = props;
176
+
177
+ const styles = [];
178
+ const val = value !== undefined ? value : size;
179
+
180
+ // For bar/column/line/area charts: use --size
181
+ if (val !== undefined) styles.push(`--size: ${val};`);
182
+ if (start !== undefined) styles.push(`--start: ${start};`);
183
+
184
+ // For Pie charts: use --end directly if provided, otherwise calculate from start + value
185
+ if (end !== undefined) {
186
+ styles.push(`--end: ${end};`);
187
+ } else if (start !== undefined && val !== undefined) {
188
+ // Legacy: Calculate --end for backward compatibility
189
+ const calculatedEnd = parseFloat(start) + parseFloat(val);
190
+ styles.push(`--end: ${calculatedEnd};`);
191
+ }
192
+
193
+ if (color) styles.push(`--color: ${color};`);
194
+ if (styleProp) styles.push(styleProp);
195
+
196
+ const classes = [];
197
+ if (className) classes.push(className);
198
+
199
+ const content = [...children];
200
+ if (tooltip) {
201
+ content.push(tags.span({ class: 'tooltip' }, tooltip));
202
+ }
203
+
204
+ return tags.td({
205
+ class: classes.join(' ') || undefined,
206
+ style: styles.join(' ') || undefined,
207
+ ...rest
208
+ }, ...content);
209
+ };
210
+
211
+ const tags = window.Lightview.tags;
212
+
213
+ tags.Chart = Chart;
214
+ tags['Chart.Head'] = Chart.Head;
215
+ tags['Chart.Body'] = Chart.Body;
216
+ tags['Chart.Row'] = Chart.Row;
217
+ tags['Chart.Label'] = Chart.Label;
218
+ tags['Chart.Data'] = Chart.Data;
219
+
220
+ export default Chart;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Lightview Chat Component (DaisyUI)
3
+ * @see https://daisyui.com/components/chat/
4
+ */
5
+
6
+ import '../daisyui.js';
7
+
8
+ /**
9
+ * Chat Component - container for chat bubbles
10
+ * @param {Object} props
11
+ * @param {string} props.position - 'start' | 'end'
12
+ * @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
13
+ */
14
+ const Chat = (props = {}, ...children) => {
15
+ const { tags } = window.Lightview || {};
16
+ const LVX = window.LightviewX || {};
17
+
18
+ if (!tags) return null;
19
+
20
+ const { div, shadowDOM } = tags;
21
+
22
+ const {
23
+ position = 'start',
24
+ useShadow,
25
+ class: className = '',
26
+ ...rest
27
+ } = props;
28
+
29
+ const classes = ['chat', `chat-${position}`];
30
+ if (className) classes.push(className);
31
+
32
+ const chatEl = div({ class: classes.join(' '), ...rest }, ...children);
33
+
34
+ // Check if we should use shadow DOM
35
+ let usesShadow = false;
36
+ if (LVX.shouldUseShadow) {
37
+ usesShadow = LVX.shouldUseShadow(useShadow);
38
+ } else {
39
+ usesShadow = useShadow === true;
40
+ }
41
+
42
+ if (usesShadow) {
43
+ const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
44
+
45
+ const themeValue = LVX.themeSignal ? () => LVX.themeSignal.value : 'light';
46
+
47
+ return div({ class: 'contents' },
48
+ shadowDOM({ mode: 'open', adoptedStyleSheets },
49
+ div({ 'data-theme': themeValue },
50
+ chatEl
51
+ )
52
+ )
53
+ );
54
+ }
55
+
56
+ return chatEl;
57
+ };
58
+
59
+ /**
60
+ * Chat Image
61
+ */
62
+ Chat.Image = (props = {}) => {
63
+ const { tags } = window.Lightview || {};
64
+ if (!tags) return null;
65
+
66
+ const { src, alt = 'Avatar', class: className = '', ...rest } = props;
67
+
68
+ return tags.div({ class: `chat-image avatar ${className}`.trim(), ...rest },
69
+ tags.div({ class: 'w-10 rounded-full' },
70
+ tags.img({ src, alt })
71
+ )
72
+ );
73
+ };
74
+
75
+ /**
76
+ * Chat Header
77
+ */
78
+ Chat.Header = (props = {}, ...children) => {
79
+ const { tags } = window.Lightview || {};
80
+ if (!tags) return null;
81
+
82
+ const { class: className = '', ...rest } = props;
83
+
84
+ return tags.div({
85
+ class: `chat-header ${className}`.trim(),
86
+ ...rest
87
+ }, ...children);
88
+ };
89
+
90
+ /**
91
+ * Chat Bubble
92
+ */
93
+ Chat.Bubble = (props = {}, ...children) => {
94
+ const { tags } = window.Lightview || {};
95
+ if (!tags) return null;
96
+
97
+ const { color, class: className = '', ...rest } = props;
98
+
99
+ const classes = ['chat-bubble'];
100
+ if (color) classes.push(`chat-bubble-${color}`);
101
+ if (className) classes.push(className);
102
+
103
+ return tags.div({ class: classes.join(' '), ...rest }, ...children);
104
+ };
105
+
106
+ /**
107
+ * Chat Footer
108
+ */
109
+ Chat.Footer = (props = {}, ...children) => {
110
+ const { tags } = window.Lightview || {};
111
+ if (!tags) return null;
112
+
113
+ const { class: className = '', ...rest } = props;
114
+
115
+ return tags.div({
116
+ class: `chat-footer opacity-50 ${className}`.trim(),
117
+ ...rest
118
+ }, ...children);
119
+ };
120
+
121
+ const tags = window.Lightview.tags;
122
+ tags.Chat = Chat;
123
+ tags['Chat.Image'] = Chat.Image;
124
+ tags['Chat.Header'] = Chat.Header;
125
+ tags['Chat.Bubble'] = Chat.Bubble;
126
+ tags['Chat.Footer'] = Chat.Footer;
127
+
128
+ export default Chat;