lightview 1.8.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codacy/cli.sh +149 -0
- package/.codacy/codacy.yaml +15 -0
- package/.github/instructions/codacy.instructions.md +72 -0
- package/.wranglerignore +21 -0
- package/README.md +1330 -19
- package/_headers +4 -0
- package/build.js +70 -0
- package/components/actions/button.js +151 -0
- package/components/actions/dropdown.js +120 -0
- package/components/actions/modal.js +146 -0
- package/components/actions/swap.js +118 -0
- package/components/daisyui.js +288 -0
- package/components/data-display/accordion.js +128 -0
- package/components/data-display/alert.js +112 -0
- package/components/data-display/avatar.js +170 -0
- package/components/data-display/badge.js +82 -0
- package/components/data-display/card.js +151 -0
- package/components/data-display/carousel.js +94 -0
- package/components/data-display/chart.js +220 -0
- package/components/data-display/chat.js +128 -0
- package/components/data-display/collapse.js +103 -0
- package/components/data-display/countdown.js +69 -0
- package/components/data-display/diff.js +111 -0
- package/components/data-display/kbd.js +65 -0
- package/components/data-display/loading.js +75 -0
- package/components/data-display/progress.js +79 -0
- package/components/data-display/radial-progress.js +88 -0
- package/components/data-display/skeleton.js +66 -0
- package/components/data-display/stats.js +159 -0
- package/components/data-display/table.js +146 -0
- package/components/data-display/timeline.js +146 -0
- package/components/data-display/toast.js +72 -0
- package/components/data-display/tooltip.js +74 -0
- package/components/data-input/checkbox.js +253 -0
- package/components/data-input/file-input.js +224 -0
- package/components/data-input/input.js +264 -0
- package/components/data-input/radio.js +338 -0
- package/components/data-input/range.js +204 -0
- package/components/data-input/rating.js +219 -0
- package/components/data-input/select.js +287 -0
- package/components/data-input/textarea.js +287 -0
- package/components/data-input/toggle.js +201 -0
- package/components/index.js +137 -0
- package/components/layout/divider.js +72 -0
- package/components/layout/drawer.js +142 -0
- package/components/layout/footer.js +100 -0
- package/components/layout/hero.js +109 -0
- package/components/layout/indicator.js +90 -0
- package/components/layout/join.js +78 -0
- package/components/layout/navbar.js +110 -0
- package/components/navigation/breadcrumbs.js +91 -0
- package/components/navigation/dock.js +103 -0
- package/components/navigation/menu.js +126 -0
- package/components/navigation/pagination.js +105 -0
- package/components/navigation/steps.js +89 -0
- package/components/navigation/tabs.css +177 -0
- package/components/navigation/tabs.js +123 -0
- package/components/theme/theme-switch.css +65 -0
- package/components/theme/theme-switch.js +177 -0
- package/docs/about.html +164 -0
- package/docs/api/computed.html +184 -0
- package/docs/api/effects.html +173 -0
- package/docs/api/elements.html +180 -0
- package/docs/api/enhance.html +225 -0
- package/docs/api/hypermedia.html +165 -0
- package/docs/api/index.html +178 -0
- package/docs/api/nav.html +18 -0
- package/docs/api/signals.html +136 -0
- package/docs/api/state.html +217 -0
- package/docs/assets/images/logo-favicon.svg +42 -0
- package/docs/assets/images/logo-static.svg +40 -0
- package/docs/assets/images/logo.svg +66 -0
- package/docs/assets/js/examplify.js +395 -0
- package/docs/assets/styles/site.css +1102 -0
- package/docs/assets/styles/themes.css +236 -0
- package/docs/components/accordion.html +439 -0
- package/docs/components/alert.html +528 -0
- package/docs/components/avatar.html +586 -0
- package/docs/components/badge.html +531 -0
- package/docs/components/breadcrumbs.html +278 -0
- package/docs/components/button.html +579 -0
- package/docs/components/card.html +561 -0
- package/docs/components/carousel.html +286 -0
- package/docs/components/chart-area.html +702 -0
- package/docs/components/chart-bar.html +782 -0
- package/docs/components/chart-column.html +735 -0
- package/docs/components/chart-line.html +794 -0
- package/docs/components/chart-pie.html +823 -0
- package/docs/components/chart.html +610 -15
- package/docs/components/chat.html +547 -0
- package/docs/components/checkbox.html +641 -0
- package/docs/components/collapse.html +536 -0
- package/docs/components/component-nav.html +53 -0
- package/docs/components/countdown.html +470 -0
- package/docs/components/diff.html +245 -0
- package/docs/components/divider.html +240 -0
- package/docs/components/dock.html +277 -0
- package/docs/components/drawer.html +515 -0
- package/docs/components/dropdown.html +479 -0
- package/docs/components/file-input.html +591 -0
- package/docs/components/footer.html +301 -0
- package/docs/components/gallery.html +504 -0
- package/docs/components/hero.html +264 -0
- package/docs/components/index.css +840 -0
- package/docs/components/index.html +735 -0
- package/docs/components/indicator.html +342 -0
- package/docs/components/input.html +644 -0
- package/docs/components/join.html +285 -0
- package/docs/components/kbd.html +322 -0
- package/docs/components/loading.html +521 -0
- package/docs/components/menu.html +461 -0
- package/docs/components/modal.html +639 -0
- package/docs/components/navbar.html +321 -0
- package/docs/components/pagination.html +279 -0
- package/docs/components/progress.html +514 -0
- package/docs/components/radial-progress.html +434 -0
- package/docs/components/radio.html +655 -0
- package/docs/components/range.html +611 -0
- package/docs/components/rating.html +642 -0
- package/docs/components/select.html +696 -0
- package/docs/components/sidebar-setup.js +93 -0
- package/docs/components/skeleton.html +447 -0
- package/docs/components/spinner.html +68 -0
- package/docs/components/stats.html +486 -0
- package/docs/components/steps.html +356 -0
- package/docs/components/swap.html +517 -0
- package/docs/components/switch.html +68 -0
- package/docs/components/table.html +668 -0
- package/docs/components/tabs.html +506 -0
- package/docs/components/text-input.html +68 -0
- package/docs/components/textarea.html +603 -0
- package/docs/components/timeline.html +485 -42
- package/docs/components/toast.html +474 -0
- package/docs/components/toggle.html +564 -0
- package/docs/components/tooltip.html +423 -0
- package/docs/examples/getting-started-example.html +40 -0
- package/docs/examples/index.html +93 -0
- package/docs/getting-started/index.html +739 -0
- package/docs/getting-started/reviews.html +23 -0
- package/docs/getting-started/reviews.odom +108 -0
- package/docs/getting-started/reviews.vdom +84 -0
- package/docs/index.html +132 -42
- package/docs/playground.html +416 -0
- package/docs/router.html +285 -0
- package/docs/styles/index.html +190 -0
- package/functions/_middleware.js +32 -0
- package/index.html +309 -0
- package/lightview-router.js +364 -0
- package/lightview-x.js +1577 -0
- package/lightview.js +659 -1200
- package/middleware/locale.js +25 -0
- package/middleware/markdown.js +44 -0
- package/middleware/notFound.js +37 -0
- package/package.json +27 -41
- package/watch.js +92 -0
- package/wrangler.toml +12 -0
- package/.idea/lightview.iml +0 -12
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/LICENSE +0 -21
- package/codepen-no-tabs-embed.css +0 -2
- package/docs/CNAME +0 -1
- package/docs/api.html +0 -674
- package/docs/blank.html +0 -10
- package/docs/comparedto.html +0 -89
- package/docs/components/chart-repl.html +0 -69
- package/docs/components/components.js +0 -113
- package/docs/components/contents.html +0 -17
- package/docs/components/gantt-repl.html +0 -61
- package/docs/components/gantt.html +0 -42
- package/docs/components/gauge-repl.html +0 -66
- package/docs/components/gauge.html +0 -20
- package/docs/components/orgchart-repl.html +0 -64
- package/docs/components/orgchart.html +0 -41
- package/docs/components/repl-as-src.html +0 -17
- package/docs/components/repl-repl.html +0 -95
- package/docs/components/repl.html +0 -527
- package/docs/components/timeline-repl.html +0 -72
- package/docs/components.html +0 -14
- package/docs/css/highlightjs.min.css +0 -9
- package/docs/css/tutorial.css +0 -35
- package/docs/examples/anchor.html +0 -11
- package/docs/examples/chart.html +0 -34
- package/docs/examples/counter.html +0 -26
- package/docs/examples/counter.test.mjs +0 -47
- package/docs/examples/counter2.html +0 -26
- package/docs/examples/directives.html +0 -79
- package/docs/examples/foreign.html +0 -50
- package/docs/examples/forgeinform.html +0 -98
- package/docs/examples/form.html +0 -61
- package/docs/examples/gauge.html +0 -18
- package/docs/examples/invalid-template-literals.html +0 -44
- package/docs/examples/medium/remote.html +0 -60
- package/docs/examples/message.html +0 -18
- package/docs/examples/nested.html +0 -11
- package/docs/examples/object-bound-form.html +0 -34
- package/docs/examples/remote-server.js +0 -51
- package/docs/examples/remote.html +0 -34
- package/docs/examples/remote.json +0 -1
- package/docs/examples/scratch.html +0 -69
- package/docs/examples/sensors/index.html +0 -44
- package/docs/examples/sensors/sensor-server.js +0 -30
- package/docs/examples/shared.html +0 -41
- package/docs/examples/template.html +0 -33
- package/docs/examples/timeline.html +0 -21
- package/docs/examples/todo.html +0 -40
- package/docs/examples/top.html +0 -10
- package/docs/examples/types.html +0 -94
- package/docs/examples/xor.html +0 -62
- package/docs/examples.html +0 -25
- package/docs/javascript/codejar.min.js +0 -8
- package/docs/javascript/highlightjs.min.js +0 -1173
- package/docs/javascript/isomorphic-git.js +0 -9
- package/docs/javascript/json5.min.js +0 -1
- package/docs/javascript/lightning-fs.js +0 -1
- package/docs/javascript/lightview.js +0 -1285
- package/docs/javascript/marked.min.js +0 -6
- package/docs/javascript/peerjs.min.js +0 -70
- package/docs/javascript/turndown.js +0 -973
- package/docs/javascript/types.js +0 -606
- package/docs/javascript/utils.js +0 -45
- package/docs/lightview.html +0 -63
- package/docs/old_index.html +0 -965
- package/docs/old_index.md +0 -1132
- package/docs/slidein.html +0 -51
- package/docs/tutorial/0-getting-started.html +0 -67
- package/docs/tutorial/1-intro-to-variables.html +0 -103
- package/docs/tutorial/10-template-components.html +0 -80
- package/docs/tutorial/11-linked-components.html +0 -76
- package/docs/tutorial/12-imported-components.html +0 -67
- package/docs/tutorial/13-input-binding.html +0 -94
- package/docs/tutorial/14-automatic-variable-creation.html +0 -74
- package/docs/tutorial/15-form-binding.html +0 -110
- package/docs/tutorial/16-if-directive.html +0 -60
- package/docs/tutorial/17-loop-directives.html +0 -83
- package/docs/tutorial/18-sanitizing-and-escaping-input.html +0 -79
- package/docs/tutorial/2-imported-and-exported-variables.html +0 -80
- package/docs/tutorial/3-data-types.html +0 -89
- package/docs/tutorial/4-extended-data-types.html +0 -83
- package/docs/tutorial/5-extended-functional-types.html +0 -96
- package/docs/tutorial/5.1-extended-functional-types.html +0 -79
- package/docs/tutorial/5.2-extended-functional-types.html +0 -70
- package/docs/tutorial/6-conventional-javascript.html +0 -75
- package/docs/tutorial/7-monitoring-with-observers.html +0 -107
- package/docs/tutorial/8-event-listeners.html +0 -65
- package/docs/tutorial/9-intro-to-components.html +0 -91
- package/docs/tutorial/contents.html +0 -32
- package/docs/tutorial/my-component.html +0 -29
- package/docs/tutorial/remote-value.json +0 -4
- package/docs/websiterepl.html +0 -46
- package/jest-puppeteer.config.js +0 -5
- package/jest.config.json +0 -12
- package/lightview.min.js +0 -1
- package/lightview_good.js +0 -1267
- package/lightview_optimized.js +0 -1274
- package/repl_hold.html +0 -320
- package/test/basic.html +0 -104
- package/test/basic.test.mjs +0 -315
- package/test/extended.html +0 -29
- package/test/extended.test.mjs +0 -448
- package/types.js +0 -607
- package/unsplash.key +0 -1
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightview Components - Textarea
|
|
3
|
+
* A multi-line text input component using DaisyUI 5 styling with validation support
|
|
4
|
+
* @see https://daisyui.com/components/textarea/
|
|
5
|
+
*
|
|
6
|
+
* Uses DaisyUI's fieldset pattern:
|
|
7
|
+
* <fieldset class="fieldset">
|
|
8
|
+
* <legend class="fieldset-legend">Label</legend>
|
|
9
|
+
* <textarea class="textarea" />
|
|
10
|
+
* <p class="label">Helper text</p>
|
|
11
|
+
* </fieldset>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import '../daisyui.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Textarea Component
|
|
18
|
+
* @param {Object} props - Textarea properties
|
|
19
|
+
* @param {string|Signal} props.value - Textarea value (controlled)
|
|
20
|
+
* @param {string} props.defaultValue - Default value (uncontrolled)
|
|
21
|
+
* @param {string} props.placeholder - Placeholder text
|
|
22
|
+
* @param {string} props.size - 'xs' | 'sm' | 'md' | 'lg' (default: 'md')
|
|
23
|
+
* @param {string} props.color - 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'
|
|
24
|
+
* @param {boolean} props.ghost - Ghost style (no background)
|
|
25
|
+
* @param {boolean} props.disabled - Disable textarea
|
|
26
|
+
* @param {boolean} props.required - Required field
|
|
27
|
+
* @param {boolean} props.readOnly - Make read-only
|
|
28
|
+
* @param {string} props.label - Label text (rendered as fieldset legend)
|
|
29
|
+
* @param {string} props.helper - Helper text (rendered below textarea)
|
|
30
|
+
* @param {string|Function} props.error - Error message (string or validation function)
|
|
31
|
+
* @param {Function} props.validate - Validation function (value) => errorMessage | null
|
|
32
|
+
* @param {number} props.rows - Number of visible rows (default: 3)
|
|
33
|
+
* @param {number} props.maxLength - Maximum character length
|
|
34
|
+
* @param {boolean} props.showCount - Show character count
|
|
35
|
+
* @param {Function} props.onChange - Change handler
|
|
36
|
+
* @param {Function} props.onBlur - Blur handler
|
|
37
|
+
* @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
|
|
38
|
+
*/
|
|
39
|
+
const Textarea = (props = {}) => {
|
|
40
|
+
const { tags, signal } = window.Lightview || {};
|
|
41
|
+
const LVX = window.LightviewX || {};
|
|
42
|
+
|
|
43
|
+
if (!tags) {
|
|
44
|
+
console.error('Lightview not found');
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { div, textarea, fieldset, legend, p, span, shadowDOM } = tags;
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
value,
|
|
52
|
+
defaultValue = '',
|
|
53
|
+
placeholder,
|
|
54
|
+
size = 'md',
|
|
55
|
+
color,
|
|
56
|
+
ghost = false,
|
|
57
|
+
disabled = false,
|
|
58
|
+
readOnly = false,
|
|
59
|
+
required = false,
|
|
60
|
+
label: labelText,
|
|
61
|
+
helper,
|
|
62
|
+
error,
|
|
63
|
+
validate,
|
|
64
|
+
rows = 3,
|
|
65
|
+
maxLength,
|
|
66
|
+
showCount = false,
|
|
67
|
+
onChange,
|
|
68
|
+
onBlur,
|
|
69
|
+
onInput,
|
|
70
|
+
name,
|
|
71
|
+
id,
|
|
72
|
+
class: className = '',
|
|
73
|
+
useShadow,
|
|
74
|
+
...rest
|
|
75
|
+
} = props;
|
|
76
|
+
|
|
77
|
+
// Generate unique ID if not provided
|
|
78
|
+
const textareaId = id || `textarea-${Math.random().toString(36).slice(2, 9)}`;
|
|
79
|
+
const textareaName = name || textareaId;
|
|
80
|
+
|
|
81
|
+
// Internal state
|
|
82
|
+
const internalValue = signal ? signal(defaultValue) : { value: defaultValue };
|
|
83
|
+
const internalError = signal ? signal(null) : { value: null };
|
|
84
|
+
const touched = signal ? signal(false) : { value: false };
|
|
85
|
+
|
|
86
|
+
const isControlled = value !== undefined;
|
|
87
|
+
|
|
88
|
+
const getValue = () => {
|
|
89
|
+
if (isControlled) {
|
|
90
|
+
return typeof value === 'function' ? value() :
|
|
91
|
+
(value && typeof value.value !== 'undefined') ? value.value : value;
|
|
92
|
+
}
|
|
93
|
+
return internalValue.value;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const getError = () => {
|
|
97
|
+
// External error takes priority
|
|
98
|
+
if (error) {
|
|
99
|
+
const err = typeof error === 'function' ? error() : error;
|
|
100
|
+
if (err) return err;
|
|
101
|
+
}
|
|
102
|
+
// Then internal validation error
|
|
103
|
+
return internalError.value;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const runValidation = (val) => {
|
|
107
|
+
if (!validate) return null;
|
|
108
|
+
const result = validate(val);
|
|
109
|
+
internalError.value = result;
|
|
110
|
+
return result;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const handleInput = (e) => {
|
|
114
|
+
const newValue = e.target.value;
|
|
115
|
+
|
|
116
|
+
if (!isControlled) {
|
|
117
|
+
internalValue.value = newValue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (isControlled && value && typeof value.value !== 'undefined') {
|
|
121
|
+
value.value = newValue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Validate on input if already touched
|
|
125
|
+
if (touched.value && validate) {
|
|
126
|
+
runValidation(newValue);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (onInput) onInput(e);
|
|
130
|
+
if (onChange) onChange(newValue, e);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const handleBlur = (e) => {
|
|
134
|
+
touched.value = true;
|
|
135
|
+
runValidation(e.target.value);
|
|
136
|
+
if (onBlur) onBlur(e);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Build DaisyUI textarea classes
|
|
140
|
+
const getTextareaClass = () => {
|
|
141
|
+
const classes = ['textarea', 'w-full'];
|
|
142
|
+
|
|
143
|
+
// Ghost style
|
|
144
|
+
if (ghost) {
|
|
145
|
+
classes.push('textarea-ghost');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Size
|
|
149
|
+
if (size && size !== 'md') {
|
|
150
|
+
classes.push(`textarea-${size}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Color
|
|
154
|
+
if (color) {
|
|
155
|
+
classes.push(`textarea-${color}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Error state
|
|
159
|
+
const currentError = getError();
|
|
160
|
+
if (currentError) {
|
|
161
|
+
classes.push('textarea-error');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return classes.join(' ');
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const getCharCount = () => {
|
|
168
|
+
const val = getValue() || '';
|
|
169
|
+
return val.length;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Build textarea attributes
|
|
173
|
+
const textareaAttrs = {
|
|
174
|
+
class: validate || error ? () => getTextareaClass() : getTextareaClass(),
|
|
175
|
+
value: isControlled
|
|
176
|
+
? (typeof value === 'function' ? value : () => getValue())
|
|
177
|
+
: () => internalValue.value,
|
|
178
|
+
disabled: typeof disabled === 'function' ? disabled : disabled,
|
|
179
|
+
readonly: readOnly,
|
|
180
|
+
required,
|
|
181
|
+
rows,
|
|
182
|
+
name: textareaName,
|
|
183
|
+
id: textareaId,
|
|
184
|
+
oninput: handleInput,
|
|
185
|
+
onblur: handleBlur,
|
|
186
|
+
'aria-invalid': () => !!getError(),
|
|
187
|
+
...rest
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Only add placeholder if defined
|
|
191
|
+
if (placeholder !== undefined) {
|
|
192
|
+
textareaAttrs.placeholder = placeholder;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Only add maxlength if defined
|
|
196
|
+
if (maxLength !== undefined) {
|
|
197
|
+
textareaAttrs.maxlength = maxLength;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const textareaEl = textarea(textareaAttrs);
|
|
201
|
+
|
|
202
|
+
// Build the component using DaisyUI fieldset pattern
|
|
203
|
+
const fieldsetContent = [];
|
|
204
|
+
|
|
205
|
+
// Legend/Label (DaisyUI fieldset-legend)
|
|
206
|
+
if (labelText) {
|
|
207
|
+
fieldsetContent.push(
|
|
208
|
+
legend({ class: 'fieldset-legend' },
|
|
209
|
+
labelText,
|
|
210
|
+
required ? span({ class: 'text-error' }, ' *') : null
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Textarea element
|
|
216
|
+
fieldsetContent.push(textareaEl);
|
|
217
|
+
|
|
218
|
+
// Footer with helper/error and character count
|
|
219
|
+
const hasFooter = helper || validate || error || showCount || maxLength;
|
|
220
|
+
if (hasFooter) {
|
|
221
|
+
fieldsetContent.push(
|
|
222
|
+
div({ class: 'flex justify-between items-center' },
|
|
223
|
+
() => {
|
|
224
|
+
const currentError = getError();
|
|
225
|
+
if (currentError) {
|
|
226
|
+
return p({
|
|
227
|
+
class: 'label text-error flex-1',
|
|
228
|
+
role: 'alert'
|
|
229
|
+
}, currentError);
|
|
230
|
+
}
|
|
231
|
+
if (helper) {
|
|
232
|
+
return p({
|
|
233
|
+
class: 'label flex-1'
|
|
234
|
+
}, helper);
|
|
235
|
+
}
|
|
236
|
+
return span({ class: 'flex-1' });
|
|
237
|
+
},
|
|
238
|
+
(showCount || maxLength) ? span({
|
|
239
|
+
class: () => {
|
|
240
|
+
const count = getCharCount();
|
|
241
|
+
let classes = 'label text-xs';
|
|
242
|
+
if (maxLength) {
|
|
243
|
+
if (count > maxLength) classes += ' text-error';
|
|
244
|
+
else if (count > maxLength * 0.9) classes += ' text-warning';
|
|
245
|
+
}
|
|
246
|
+
return classes;
|
|
247
|
+
}
|
|
248
|
+
}, () => maxLength ? `${getCharCount()}/${maxLength}` : getCharCount()) : null
|
|
249
|
+
)
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Wrapper with DaisyUI fieldset class
|
|
254
|
+
const wrapperEl = fieldset({
|
|
255
|
+
class: `fieldset ${className}`.trim()
|
|
256
|
+
}, ...fieldsetContent);
|
|
257
|
+
|
|
258
|
+
// Check if we should use shadow DOM
|
|
259
|
+
let usesShadow = false;
|
|
260
|
+
if (LVX.shouldUseShadow) {
|
|
261
|
+
usesShadow = LVX.shouldUseShadow(useShadow);
|
|
262
|
+
} else {
|
|
263
|
+
usesShadow = useShadow === true;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (usesShadow) {
|
|
267
|
+
const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
|
|
268
|
+
|
|
269
|
+
// Get current theme from document
|
|
270
|
+
const themeValue = LVX.themeSignal ? () => LVX.themeSignal.value : 'light';
|
|
271
|
+
|
|
272
|
+
return div({ class: 'content', style: 'display: inline-block' },
|
|
273
|
+
shadowDOM({ mode: 'open', adoptedStyleSheets },
|
|
274
|
+
div({ 'data-theme': themeValue },
|
|
275
|
+
wrapperEl
|
|
276
|
+
)
|
|
277
|
+
)
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return wrapperEl;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// Auto-register
|
|
285
|
+
window.Lightview.tags.Textarea = Textarea;
|
|
286
|
+
|
|
287
|
+
export default Textarea;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightview Components - Toggle
|
|
3
|
+
* A toggle switch component using DaisyUI 5 styling
|
|
4
|
+
* @see https://daisyui.com/components/toggle/
|
|
5
|
+
*
|
|
6
|
+
* Uses DaisyUI's form-control pattern:
|
|
7
|
+
* <div class="form-control">
|
|
8
|
+
* <label class="label cursor-pointer">
|
|
9
|
+
* <span class="label-text">Label</span>
|
|
10
|
+
* <input type="checkbox" class="toggle" />
|
|
11
|
+
* </label>
|
|
12
|
+
* </div>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import '../daisyui.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Toggle Component
|
|
19
|
+
* @param {Object} props - Toggle properties
|
|
20
|
+
* @param {boolean|Signal} props.checked - Controlled checked state
|
|
21
|
+
* @param {boolean} props.defaultChecked - Initial checked state (uncontrolled)
|
|
22
|
+
* @param {string} props.size - 'xs' | 'sm' | 'md' | 'lg' (default: 'md')
|
|
23
|
+
* @param {string} props.color - 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'
|
|
24
|
+
* @param {boolean} props.disabled - Disable toggle
|
|
25
|
+
* @param {string} props.label - Label text
|
|
26
|
+
* @param {string} props.labelPosition - 'left' | 'right' (default: 'left')
|
|
27
|
+
* @param {string} props.description - Description text below label
|
|
28
|
+
* @param {Function} props.onChange - Change handler
|
|
29
|
+
* @param {boolean} props.useShadow - Render in Shadow DOM
|
|
30
|
+
*/
|
|
31
|
+
const Toggle = (props = {}) => {
|
|
32
|
+
const { tags, signal } = window.Lightview || {};
|
|
33
|
+
const LVX = window.LightviewX || {};
|
|
34
|
+
|
|
35
|
+
if (!tags) {
|
|
36
|
+
console.error('Lightview not found');
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { div, input, label, span, shadowDOM } = tags;
|
|
41
|
+
|
|
42
|
+
const {
|
|
43
|
+
checked,
|
|
44
|
+
defaultChecked = false,
|
|
45
|
+
size = 'md',
|
|
46
|
+
color,
|
|
47
|
+
disabled = false,
|
|
48
|
+
label: labelText,
|
|
49
|
+
labelPosition = 'left',
|
|
50
|
+
description,
|
|
51
|
+
onChange,
|
|
52
|
+
name,
|
|
53
|
+
id,
|
|
54
|
+
class: className = '',
|
|
55
|
+
useShadow,
|
|
56
|
+
theme, // Explicit theme override
|
|
57
|
+
...rest
|
|
58
|
+
} = props;
|
|
59
|
+
|
|
60
|
+
const toggleId = id || `toggle-${Math.random().toString(36).slice(2, 9)}`;
|
|
61
|
+
|
|
62
|
+
// Internal state for uncontrolled mode
|
|
63
|
+
const internalChecked = signal ? signal(defaultChecked) : { value: defaultChecked };
|
|
64
|
+
|
|
65
|
+
const isControlled = checked !== undefined;
|
|
66
|
+
|
|
67
|
+
const getChecked = () => {
|
|
68
|
+
if (isControlled) {
|
|
69
|
+
return typeof checked === 'function' ? checked() :
|
|
70
|
+
(checked && typeof checked.value !== 'undefined') ? checked.value : checked;
|
|
71
|
+
}
|
|
72
|
+
return internalChecked.value;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const handleChange = (e) => {
|
|
76
|
+
const newValue = e.target.checked;
|
|
77
|
+
|
|
78
|
+
if (!isControlled) {
|
|
79
|
+
internalChecked.value = newValue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// If controlled with a signal, update it
|
|
83
|
+
if (isControlled && checked && typeof checked.value !== 'undefined') {
|
|
84
|
+
checked.value = newValue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (onChange) onChange(newValue, e);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Build DaisyUI toggle classes
|
|
91
|
+
const getToggleClass = () => {
|
|
92
|
+
const classes = ['toggle'];
|
|
93
|
+
|
|
94
|
+
if (size && size !== 'md') {
|
|
95
|
+
classes.push(`toggle-${size}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (color) {
|
|
99
|
+
classes.push(`toggle-${color}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return classes.join(' ');
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const toggleInput = input({
|
|
106
|
+
type: 'checkbox',
|
|
107
|
+
class: getToggleClass(),
|
|
108
|
+
checked: isControlled
|
|
109
|
+
? (typeof checked === 'function' ? checked : () => getChecked())
|
|
110
|
+
: () => internalChecked.value,
|
|
111
|
+
disabled: typeof disabled === 'function' ? disabled : disabled,
|
|
112
|
+
name,
|
|
113
|
+
id: toggleId,
|
|
114
|
+
onchange: handleChange,
|
|
115
|
+
role: 'switch',
|
|
116
|
+
'aria-checked': isControlled
|
|
117
|
+
? (typeof checked === 'function' ? checked : () => getChecked())
|
|
118
|
+
: () => internalChecked.value,
|
|
119
|
+
...rest
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// If no label, return just the toggle
|
|
123
|
+
if (!labelText) {
|
|
124
|
+
// Check if we should use shadow DOM
|
|
125
|
+
let usesShadow = false;
|
|
126
|
+
if (LVX.shouldUseShadow) {
|
|
127
|
+
usesShadow = LVX.shouldUseShadow(useShadow);
|
|
128
|
+
} else {
|
|
129
|
+
usesShadow = useShadow === true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (usesShadow) {
|
|
133
|
+
const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
|
|
134
|
+
// Use reactive theme signal if available, otherwise fallback to explicit 'theme' prop or default
|
|
135
|
+
const themeValue = theme || (LVX.themeSignal ? () => LVX.themeSignal.value : 'light');
|
|
136
|
+
|
|
137
|
+
return div({ class: 'content', style: 'display: inline-block' },
|
|
138
|
+
shadowDOM({ mode: 'open', adoptedStyleSheets },
|
|
139
|
+
div({ 'data-theme': themeValue }, toggleInput)
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return toggleInput;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Build label content
|
|
148
|
+
const labelContent = div({ style: 'display: flex; flex-direction: column;' },
|
|
149
|
+
span({ class: 'label-text' }, labelText),
|
|
150
|
+
description ? span({ class: 'label-text-alt', style: 'opacity: 0.7;' }, description) : null
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// Arrange based on label position
|
|
154
|
+
const labelChildren = labelPosition === 'right'
|
|
155
|
+
? [toggleInput, labelContent]
|
|
156
|
+
: [labelContent, toggleInput];
|
|
157
|
+
|
|
158
|
+
const formControl = div({
|
|
159
|
+
class: `form-control ${className}`.trim()
|
|
160
|
+
},
|
|
161
|
+
label({ class: 'label cursor-pointer', style: 'justify-content: flex-start; gap: 0.75rem;' },
|
|
162
|
+
...labelChildren
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Check if we should use shadow DOM
|
|
167
|
+
let usesShadow = false;
|
|
168
|
+
if (LVX.shouldUseShadow) {
|
|
169
|
+
usesShadow = LVX.shouldUseShadow(useShadow);
|
|
170
|
+
} else {
|
|
171
|
+
usesShadow = useShadow === true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (usesShadow) {
|
|
175
|
+
const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
|
|
176
|
+
|
|
177
|
+
// Use reactive theme signal if available, otherwise fallback to explicit 'theme' prop or default
|
|
178
|
+
const themeValue = theme || (LVX.themeSignal ? () => LVX.themeSignal.value : 'light');
|
|
179
|
+
|
|
180
|
+
return span({ style: 'margin-right: 0.5rem' },
|
|
181
|
+
shadowDOM({ mode: 'open', adoptedStyleSheets },
|
|
182
|
+
div({ 'data-theme': themeValue, style: 'display: inline-block' }, formControl)
|
|
183
|
+
)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return formControl;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// Auto-register
|
|
191
|
+
window.Lightview.tags.Toggle = Toggle;
|
|
192
|
+
|
|
193
|
+
// Register as Custom Element
|
|
194
|
+
if (window.LightviewX?.createCustomElement) {
|
|
195
|
+
const ToggleElement = window.LightviewX.createCustomElement(Toggle);
|
|
196
|
+
if (!customElements.get('lv-toggle')) {
|
|
197
|
+
customElements.define('lv-toggle', ToggleElement);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export default Toggle;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightview Components - DaisyUI Edition
|
|
3
|
+
* Main export file for all components
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// DaisyUI utilities
|
|
7
|
+
export * from './daisyui.js';
|
|
8
|
+
export { default as DaisyUI } from './daisyui.js';
|
|
9
|
+
|
|
10
|
+
// Actions
|
|
11
|
+
export { default as Button } from './actions/button.js';
|
|
12
|
+
export { default as Dropdown } from './actions/dropdown.js';
|
|
13
|
+
export { default as Modal } from './actions/modal.js';
|
|
14
|
+
export { default as Swap } from './actions/swap.js';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
// Data Display
|
|
18
|
+
export { default as Accordion } from './data-display/accordion.js';
|
|
19
|
+
export { default as Alert } from './data-display/alert.js';
|
|
20
|
+
export { default as Avatar } from './data-display/avatar.js';
|
|
21
|
+
export { default as Badge } from './data-display/badge.js';
|
|
22
|
+
export { default as Card } from './data-display/card.js';
|
|
23
|
+
export { default as Chart } from './data-display/chart.js';
|
|
24
|
+
export { default as Carousel } from './data-display/carousel.js';
|
|
25
|
+
export { default as Chat } from './data-display/chat.js';
|
|
26
|
+
export { default as Collapse } from './data-display/collapse.js';
|
|
27
|
+
export { default as Countdown } from './data-display/countdown.js';
|
|
28
|
+
export { default as Diff } from './data-display/diff.js';
|
|
29
|
+
export { default as Kbd } from './data-display/kbd.js';
|
|
30
|
+
export { default as Loading } from './data-display/loading.js';
|
|
31
|
+
export { default as Progress } from './data-display/progress.js';
|
|
32
|
+
export { default as RadialProgress } from './data-display/radial-progress.js';
|
|
33
|
+
export { default as Skeleton } from './data-display/skeleton.js';
|
|
34
|
+
export { default as Stats } from './data-display/stats.js';
|
|
35
|
+
export { default as Table } from './data-display/table.js';
|
|
36
|
+
export { default as Timeline } from './data-display/timeline.js';
|
|
37
|
+
export { default as Toast } from './data-display/toast.js';
|
|
38
|
+
export { default as Tooltip } from './data-display/tooltip.js';
|
|
39
|
+
|
|
40
|
+
// Data Input
|
|
41
|
+
export { default as Checkbox } from './data-input/checkbox.js';
|
|
42
|
+
export { default as FileInput } from './data-input/file-input.js';
|
|
43
|
+
export { default as Radio } from './data-input/radio.js';
|
|
44
|
+
export { default as Range } from './data-input/range.js';
|
|
45
|
+
export { default as Rating } from './data-input/rating.js';
|
|
46
|
+
export { default as Select } from './data-input/select.js';
|
|
47
|
+
export { default as Input } from './data-input/input.js';
|
|
48
|
+
export { default as Textarea } from './data-input/textarea.js';
|
|
49
|
+
export { default as Toggle } from './data-input/toggle.js';
|
|
50
|
+
|
|
51
|
+
// Layout
|
|
52
|
+
export { default as Divider } from './layout/divider.js';
|
|
53
|
+
export { default as Drawer } from './layout/drawer.js';
|
|
54
|
+
export { default as Footer } from './layout/footer.js';
|
|
55
|
+
export { default as Hero } from './layout/hero.js';
|
|
56
|
+
export { default as Indicator } from './layout/indicator.js';
|
|
57
|
+
export { default as Join } from './layout/join.js';
|
|
58
|
+
export { default as Navbar } from './layout/navbar.js';
|
|
59
|
+
|
|
60
|
+
// Navigation
|
|
61
|
+
export { default as Breadcrumbs } from './navigation/breadcrumbs.js';
|
|
62
|
+
export { default as Dock } from './navigation/dock.js';
|
|
63
|
+
export { default as Menu } from './navigation/menu.js';
|
|
64
|
+
export { default as Pagination } from './navigation/pagination.js';
|
|
65
|
+
export { default as Steps } from './navigation/steps.js';
|
|
66
|
+
export { default as Tabs } from './navigation/tabs.js';
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Component manifest for documentation/tooling
|
|
70
|
+
*/
|
|
71
|
+
export const componentManifest = {
|
|
72
|
+
actions: [
|
|
73
|
+
{ name: 'Button', description: 'Versatile button with variants, colors, and loading states' },
|
|
74
|
+
{ name: 'Dropdown', description: 'Dropdown menu that opens on click or hover' },
|
|
75
|
+
{ name: 'Modal', description: 'Dialog overlay for important content' },
|
|
76
|
+
{ name: 'Swap', description: 'Toggle between two elements with animation' },
|
|
77
|
+
|
|
78
|
+
],
|
|
79
|
+
dataDisplay: [
|
|
80
|
+
{ name: 'Accordion', description: 'Collapsible content sections' },
|
|
81
|
+
{ name: 'Alert', description: 'Inline messages and notifications' },
|
|
82
|
+
{ name: 'Avatar', description: 'User avatar with image/initials fallback' },
|
|
83
|
+
{ name: 'Badge', description: 'Small label for status or counts' },
|
|
84
|
+
{ name: 'Card', description: 'Container for grouping content' },
|
|
85
|
+
{ name: 'Chart', description: 'Charts and graphs powered by charts.css' },
|
|
86
|
+
{ name: 'Carousel', description: 'Scrollable image/content gallery' },
|
|
87
|
+
{ name: 'Chat', description: 'Chat bubble messages' },
|
|
88
|
+
{ name: 'Collapse', description: 'Show/hide content sections' },
|
|
89
|
+
{ name: 'Countdown', description: 'Animated countdown number' },
|
|
90
|
+
{ name: 'Diff', description: 'Side-by-side comparison' },
|
|
91
|
+
{ name: 'Kbd', description: 'Keyboard shortcut indicator' },
|
|
92
|
+
{ name: 'Loading', description: 'Loading spinner animations' },
|
|
93
|
+
{ name: 'Progress', description: 'Linear progress bar' },
|
|
94
|
+
{ name: 'RadialProgress', description: 'Circular progress indicator' },
|
|
95
|
+
{ name: 'Skeleton', description: 'Loading placeholder' },
|
|
96
|
+
{ name: 'Stats', description: 'Statistics display blocks' },
|
|
97
|
+
{ name: 'Table', description: 'Data table with styling' },
|
|
98
|
+
{ name: 'Timeline', description: 'Chronological event list' },
|
|
99
|
+
{ name: 'Toast', description: 'Positioned notification container' },
|
|
100
|
+
{ name: 'Tooltip', description: 'Hover tooltip' }
|
|
101
|
+
],
|
|
102
|
+
dataInput: [
|
|
103
|
+
{ name: 'Checkbox', description: 'Checkbox input' },
|
|
104
|
+
{ name: 'FileInput', description: 'File upload input' },
|
|
105
|
+
{ name: 'Radio', description: 'Radio button' },
|
|
106
|
+
{ name: 'Range', description: 'Slider input' },
|
|
107
|
+
{ name: 'Rating', description: 'Star rating input' },
|
|
108
|
+
{ name: 'Select', description: 'Dropdown select' },
|
|
109
|
+
{ name: 'Input', description: 'Text input field' },
|
|
110
|
+
{ name: 'Textarea', description: 'Multi-line text input' },
|
|
111
|
+
{ name: 'Toggle', description: 'Switch toggle' }
|
|
112
|
+
],
|
|
113
|
+
layout: [
|
|
114
|
+
{ name: 'Divider', description: 'Content separator' },
|
|
115
|
+
{ name: 'Drawer', description: 'Slide-out sidebar' },
|
|
116
|
+
{ name: 'Footer', description: 'Page footer' },
|
|
117
|
+
{ name: 'Hero', description: 'Large banner section' },
|
|
118
|
+
{ name: 'Indicator', description: 'Position badges on corners' },
|
|
119
|
+
{ name: 'Join', description: 'Group items with shared borders' },
|
|
120
|
+
{ name: 'Navbar', description: 'Navigation bar' }
|
|
121
|
+
],
|
|
122
|
+
navigation: [
|
|
123
|
+
{ name: 'Breadcrumbs', description: 'Navigation breadcrumb trail' },
|
|
124
|
+
{ name: 'Dock', description: 'Bottom navigation bar' },
|
|
125
|
+
{ name: 'Menu', description: 'Navigation menu list' },
|
|
126
|
+
{ name: 'Pagination', description: 'Page navigation' },
|
|
127
|
+
{ name: 'Steps', description: 'Step progress indicator' },
|
|
128
|
+
{ name: 'Tabs', description: 'Tabbed navigation' }
|
|
129
|
+
]
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Initialize all components
|
|
134
|
+
*/
|
|
135
|
+
export const initComponents = () => {
|
|
136
|
+
console.log('Lightview Components (DaisyUI) initialized');
|
|
137
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightview Divider Component (DaisyUI)
|
|
3
|
+
* @see https://daisyui.com/components/divider/
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import '../daisyui.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Divider Component
|
|
10
|
+
* @param {Object} props
|
|
11
|
+
* @param {boolean} props.horizontal - Horizontal divider (default is vertical in flex row)
|
|
12
|
+
* @param {boolean} props.vertical - Vertical divider (explicit)
|
|
13
|
+
* @param {string} props.position - 'start' | 'end' for text position
|
|
14
|
+
* @param {string} props.color - 'neutral' | 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'info' | 'error'
|
|
15
|
+
* @param {boolean} props.useShadow - Render in Shadow DOM with isolated DaisyUI styles
|
|
16
|
+
*/
|
|
17
|
+
const Divider = (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
|
+
horizontal = false,
|
|
27
|
+
vertical = false,
|
|
28
|
+
position,
|
|
29
|
+
color,
|
|
30
|
+
useShadow,
|
|
31
|
+
class: className = '',
|
|
32
|
+
...rest
|
|
33
|
+
} = props;
|
|
34
|
+
|
|
35
|
+
const classes = ['divider'];
|
|
36
|
+
if (horizontal) classes.push('divider-horizontal');
|
|
37
|
+
if (vertical) classes.push('divider-vertical');
|
|
38
|
+
if (position === 'start') classes.push('divider-start');
|
|
39
|
+
else if (position === 'end') classes.push('divider-end');
|
|
40
|
+
if (color) classes.push(`divider-${color}`);
|
|
41
|
+
if (className) classes.push(className);
|
|
42
|
+
|
|
43
|
+
const dividerEl = div({ class: classes.join(' '), ...rest }, ...children);
|
|
44
|
+
|
|
45
|
+
// Check if we should use shadow DOM
|
|
46
|
+
let usesShadow = false;
|
|
47
|
+
if (LVX.shouldUseShadow) {
|
|
48
|
+
usesShadow = LVX.shouldUseShadow(useShadow);
|
|
49
|
+
} else {
|
|
50
|
+
usesShadow = useShadow === true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (usesShadow) {
|
|
54
|
+
const adoptedStyleSheets = LVX.getAdoptedStyleSheets ? LVX.getAdoptedStyleSheets() : [];
|
|
55
|
+
|
|
56
|
+
const themeValue = LVX.themeSignal ? () => LVX.themeSignal.value : 'light';
|
|
57
|
+
|
|
58
|
+
return div({ class: 'contents' },
|
|
59
|
+
shadowDOM({ mode: 'open', adoptedStyleSheets },
|
|
60
|
+
div({ 'data-theme': themeValue },
|
|
61
|
+
dividerEl
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return dividerEl;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
window.Lightview.tags.Divider = Divider;
|
|
71
|
+
|
|
72
|
+
export default Divider;
|