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,603 @@
|
|
|
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: 'Textarea' }
|
|
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">Textarea</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
|
+
Textarea allows users to enter multi-line text.
|
|
61
|
+
Supports labels, validation, character count, and reactive state binding.
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
<!-- Basic Examples -->
|
|
65
|
+
<div class="card bg-base-200" style="margin-bottom: 2rem;">
|
|
66
|
+
<div class="card-body">
|
|
67
|
+
<h2 class="card-title">Basic Examples</h2>
|
|
68
|
+
<p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;">Simple textareas with various
|
|
69
|
+
configurations</p>
|
|
70
|
+
|
|
71
|
+
<!-- Tabs -->
|
|
72
|
+
<script>
|
|
73
|
+
window.switchSyntaxTab = (tabId) => {
|
|
74
|
+
const tabs = ['tagged', 'vdom', 'object'];
|
|
75
|
+
tabs.forEach(t => {
|
|
76
|
+
const tabEl = document.getElementById(`tab-btn-${t}`);
|
|
77
|
+
const contentEl = document.getElementById(`syntax-${t}`);
|
|
78
|
+
if (t === tabId) {
|
|
79
|
+
tabEl.classList.add('syntax-tab-active');
|
|
80
|
+
contentEl.style.display = 'block';
|
|
81
|
+
} else {
|
|
82
|
+
tabEl.classList.remove('syntax-tab-active');
|
|
83
|
+
contentEl.style.display = 'none';
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
</script>
|
|
88
|
+
<div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;">
|
|
89
|
+
<button id="tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active"
|
|
90
|
+
onclick="switchSyntaxTab('tagged')">Tagged</button>
|
|
91
|
+
<button id="tab-btn-vdom" role="tab" class="syntax-tab"
|
|
92
|
+
onclick="switchSyntaxTab('vdom')">vDOM</button>
|
|
93
|
+
<button id="tab-btn-object" role="tab" class="syntax-tab"
|
|
94
|
+
onclick="switchSyntaxTab('object')">Object
|
|
95
|
+
DOM</button>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<!-- Tagged Syntax -->
|
|
99
|
+
<div id="syntax-tagged">
|
|
100
|
+
<pre><script>
|
|
101
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
102
|
+
at: document.currentScript.parentElement,
|
|
103
|
+
scripts: ['/lightview.js', '/lightview-x.js'],
|
|
104
|
+
styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
|
|
105
|
+
type: 'module',
|
|
106
|
+
minHeight: 380,
|
|
107
|
+
autoRun: true
|
|
108
|
+
});
|
|
109
|
+
</script><code contenteditable="true">await import('/components/data-input/textarea.js');
|
|
110
|
+
const { tags, $ } = Lightview;
|
|
111
|
+
const { div, Textarea } = tags;
|
|
112
|
+
|
|
113
|
+
// 1. Basic textarea
|
|
114
|
+
const basic = Textarea({
|
|
115
|
+
placeholder: 'Enter your message...',
|
|
116
|
+
rows: 3
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// 2. Textarea with label and helper
|
|
120
|
+
const withLabel = Textarea({
|
|
121
|
+
label: 'Bio',
|
|
122
|
+
placeholder: 'Tell us about yourself...',
|
|
123
|
+
helper: 'Max 500 characters',
|
|
124
|
+
rows: 4
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// 3. Textarea with character count
|
|
128
|
+
const withCount = Textarea({
|
|
129
|
+
label: 'Description',
|
|
130
|
+
placeholder: 'Product description...',
|
|
131
|
+
maxLength: 200,
|
|
132
|
+
showCount: true,
|
|
133
|
+
rows: 3
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Insert all examples
|
|
137
|
+
$('#example').content(
|
|
138
|
+
div({ style: 'display: flex; flex-direction: column; gap: 1rem' }, basic, withLabel, withCount)
|
|
139
|
+
);</code></pre>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<!-- vDOM Syntax -->
|
|
143
|
+
<div id="syntax-vdom" style="display: none;">
|
|
144
|
+
<pre><script>
|
|
145
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
146
|
+
at: document.currentScript.parentElement,
|
|
147
|
+
scripts: ['/lightview.js', '/lightview-x.js'],
|
|
148
|
+
styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
|
|
149
|
+
type: 'module',
|
|
150
|
+
minHeight: 380
|
|
151
|
+
});
|
|
152
|
+
</script><code contenteditable="true">await import('/components/data-input/textarea.js');
|
|
153
|
+
const { $, tags } = Lightview;
|
|
154
|
+
const { Textarea, div } = tags;
|
|
155
|
+
|
|
156
|
+
const basic = {
|
|
157
|
+
tag: Textarea,
|
|
158
|
+
attributes: {
|
|
159
|
+
placeholder: 'Enter your message...',
|
|
160
|
+
rows: 3
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const withLabel = {
|
|
165
|
+
tag: Textarea,
|
|
166
|
+
attributes: {
|
|
167
|
+
label: 'Bio',
|
|
168
|
+
placeholder: 'Tell us about yourself...',
|
|
169
|
+
helper: 'Max 500 characters',
|
|
170
|
+
rows: 4
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const withCount = {
|
|
175
|
+
tag: Textarea,
|
|
176
|
+
attributes: {
|
|
177
|
+
label: 'Description',
|
|
178
|
+
placeholder: 'Product description...',
|
|
179
|
+
maxLength: 200,
|
|
180
|
+
showCount: true,
|
|
181
|
+
rows: 3
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
$('#example').content({
|
|
186
|
+
tag: div,
|
|
187
|
+
attributes: { style: 'display: flex; flex-direction: column; gap: 1rem' },
|
|
188
|
+
children: [basic, withLabel, withCount]
|
|
189
|
+
});</code></pre>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<!-- Object DOM Syntax -->
|
|
193
|
+
<div id="syntax-object" style="display: none;">
|
|
194
|
+
<pre><script>
|
|
195
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
196
|
+
at: document.currentScript.parentElement,
|
|
197
|
+
scripts: ['/lightview.js', '/lightview-x.js'],
|
|
198
|
+
styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
|
|
199
|
+
type: 'module',
|
|
200
|
+
minHeight: 380
|
|
201
|
+
});
|
|
202
|
+
</script><code contenteditable="true">await import('/components/data-input/textarea.js');
|
|
203
|
+
const { $ } = Lightview;
|
|
204
|
+
|
|
205
|
+
$('#example').content({
|
|
206
|
+
div: {
|
|
207
|
+
style: 'display: flex; flex-direction: column; gap: 1rem',
|
|
208
|
+
children: [
|
|
209
|
+
{
|
|
210
|
+
Textarea: {
|
|
211
|
+
placeholder: 'Enter your message...',
|
|
212
|
+
rows: 3
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
Textarea: {
|
|
217
|
+
label: 'Bio',
|
|
218
|
+
placeholder: 'Tell us about yourself...',
|
|
219
|
+
helper: 'Max 500 characters',
|
|
220
|
+
rows: 4
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
Textarea: {
|
|
225
|
+
label: 'Description',
|
|
226
|
+
placeholder: 'Product description...',
|
|
227
|
+
maxLength: 200,
|
|
228
|
+
showCount: true,
|
|
229
|
+
rows: 3
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
});</code></pre>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<!-- Reactive Example -->
|
|
240
|
+
<div class="card bg-base-200" style="margin-bottom: 2rem;">
|
|
241
|
+
<div class="card-body">
|
|
242
|
+
<h2 class="card-title">Reactive Example</h2>
|
|
243
|
+
<p class="text-sm" style="opacity: 0.7; margin-bottom: 1rem;">Two-way binding with signals
|
|
244
|
+
and live
|
|
245
|
+
validation</p>
|
|
246
|
+
|
|
247
|
+
<!-- Tabs -->
|
|
248
|
+
<script>
|
|
249
|
+
window.switchReactiveSyntaxTab = (tabId) => {
|
|
250
|
+
const tabs = ['tagged', 'vdom', 'object'];
|
|
251
|
+
tabs.forEach(t => {
|
|
252
|
+
const tabEl = document.getElementById(`reactive-tab-btn-${t}`);
|
|
253
|
+
const contentEl = document.getElementById(`reactive-syntax-${t}`);
|
|
254
|
+
if (t === tabId) {
|
|
255
|
+
tabEl.classList.add('syntax-tab-active');
|
|
256
|
+
contentEl.style.display = 'block';
|
|
257
|
+
} else {
|
|
258
|
+
tabEl.classList.remove('syntax-tab-active');
|
|
259
|
+
contentEl.style.display = 'none';
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
</script>
|
|
264
|
+
<div role="tablist" class="syntax-tabs" style="margin-bottom: 1rem;">
|
|
265
|
+
<button id="reactive-tab-btn-tagged" role="tab" class="syntax-tab syntax-tab-active"
|
|
266
|
+
onclick="switchReactiveSyntaxTab('tagged')">Tagged</button>
|
|
267
|
+
<button id="reactive-tab-btn-vdom" role="tab" class="syntax-tab"
|
|
268
|
+
onclick="switchReactiveSyntaxTab('vdom')">vDOM</button>
|
|
269
|
+
<button id="reactive-tab-btn-object" role="tab" class="syntax-tab"
|
|
270
|
+
onclick="switchReactiveSyntaxTab('object')">Object DOM</button>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<!-- Tagged Syntax -->
|
|
274
|
+
<div id="reactive-syntax-tagged">
|
|
275
|
+
<pre><script>
|
|
276
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
277
|
+
at: document.currentScript.parentElement,
|
|
278
|
+
scripts: ['/lightview.js', '/lightview-x.js'],
|
|
279
|
+
styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
|
|
280
|
+
type: 'module',
|
|
281
|
+
minHeight: 220
|
|
282
|
+
});
|
|
283
|
+
</script><code contenteditable="true">await import('/components/data-input/textarea.js');
|
|
284
|
+
const { signal, tags, $ } = Lightview;
|
|
285
|
+
const { div, p, span, Textarea } = tags;
|
|
286
|
+
|
|
287
|
+
// Signal for two-way binding
|
|
288
|
+
const feedback = signal('');
|
|
289
|
+
|
|
290
|
+
// Validation function
|
|
291
|
+
const validateFeedback = (val) => {
|
|
292
|
+
if (!val || val.trim().length === 0) return 'Feedback is required';
|
|
293
|
+
if (val.length < 20) return 'Please provide more detail (at least 20 characters)';
|
|
294
|
+
if (val.length > 500) return 'Feedback is too long (max 500 characters)';
|
|
295
|
+
return null;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// Reactive textarea with validation
|
|
299
|
+
const reactiveDemo = div({ style: 'display: flex; flex-direction: column; gap: 1rem' },
|
|
300
|
+
Textarea({
|
|
301
|
+
label: 'Your Feedback',
|
|
302
|
+
placeholder: 'Share your thoughts with us...',
|
|
303
|
+
value: feedback,
|
|
304
|
+
validate: validateFeedback,
|
|
305
|
+
showCount: true,
|
|
306
|
+
maxLength: 500,
|
|
307
|
+
required: true,
|
|
308
|
+
rows: 4
|
|
309
|
+
}),
|
|
310
|
+
p({ class: 'text-sm' },
|
|
311
|
+
() => {
|
|
312
|
+
const error = validateFeedback(feedback.value);
|
|
313
|
+
return error
|
|
314
|
+
? span({ class: 'text-error' }, '✗ ' + error)
|
|
315
|
+
: span({ class: 'text-success' }, '✓ Feedback is valid!');
|
|
316
|
+
}
|
|
317
|
+
)
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
$('#example').content(reactiveDemo);</code></pre>
|
|
321
|
+
</div>
|
|
322
|
+
|
|
323
|
+
<!-- vDOM Syntax -->
|
|
324
|
+
<div id="reactive-syntax-vdom" style="display: none;">
|
|
325
|
+
<pre><script>
|
|
326
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
327
|
+
at: document.currentScript.parentElement,
|
|
328
|
+
scripts: ['/lightview.js', '/lightview-x.js'],
|
|
329
|
+
styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
|
|
330
|
+
type: 'module',
|
|
331
|
+
minHeight: 220
|
|
332
|
+
});
|
|
333
|
+
</script><code contenteditable="true">await import('/components/data-input/textarea.js');
|
|
334
|
+
const { signal, $, tags } = Lightview;
|
|
335
|
+
const { Textarea, div, p, span } = tags;
|
|
336
|
+
|
|
337
|
+
const feedback = signal('');
|
|
338
|
+
|
|
339
|
+
const validateFeedback = (val) => {
|
|
340
|
+
if (!val || val.trim().length === 0) return 'Feedback is required';
|
|
341
|
+
if (val.length < 20) return 'Please provide more detail (at least 20 characters)';
|
|
342
|
+
if (val.length > 500) return 'Feedback is too long (max 500 characters)';
|
|
343
|
+
return null;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const reactiveDemo = {
|
|
347
|
+
tag: div,
|
|
348
|
+
attributes: { style: 'display: flex; flex-direction: column; gap: 1rem' },
|
|
349
|
+
children: [
|
|
350
|
+
{
|
|
351
|
+
tag: Textarea,
|
|
352
|
+
attributes: {
|
|
353
|
+
label: 'Your Feedback',
|
|
354
|
+
placeholder: 'Share your thoughts with us...',
|
|
355
|
+
value: feedback,
|
|
356
|
+
validate: validateFeedback,
|
|
357
|
+
showCount: true,
|
|
358
|
+
maxLength: 500,
|
|
359
|
+
required: true,
|
|
360
|
+
rows: 4
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
tag: p,
|
|
365
|
+
attributes: { class: 'text-sm' },
|
|
366
|
+
children: [
|
|
367
|
+
() => {
|
|
368
|
+
const error = validateFeedback(feedback.value);
|
|
369
|
+
return error
|
|
370
|
+
? { tag: span, attributes: { class: 'text-error' }, children: ['✗ ' + error] }
|
|
371
|
+
: { tag: span, attributes: { class: 'text-success' }, children: ['✓ Feedback is valid!'] };
|
|
372
|
+
}
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
$('#example').content(reactiveDemo);</code></pre>
|
|
379
|
+
</div>
|
|
380
|
+
|
|
381
|
+
<!-- Object DOM Syntax -->
|
|
382
|
+
<div id="reactive-syntax-object" style="display: none;">
|
|
383
|
+
<pre><script>
|
|
384
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
385
|
+
at: document.currentScript.parentElement,
|
|
386
|
+
scripts: ['/lightview.js', '/lightview-x.js'],
|
|
387
|
+
styles: ['https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.min.css'],
|
|
388
|
+
type: 'module',
|
|
389
|
+
minHeight: 220
|
|
390
|
+
});
|
|
391
|
+
</script><code contenteditable="true">await import('/components/data-input/textarea.js');
|
|
392
|
+
const { signal, $ } = Lightview;
|
|
393
|
+
|
|
394
|
+
const feedback = signal('');
|
|
395
|
+
|
|
396
|
+
const validateFeedback = (val) => {
|
|
397
|
+
if (!val || val.trim().length === 0) return 'Feedback is required';
|
|
398
|
+
if (val.length < 20) return 'Please provide more detail (at least 20 characters)';
|
|
399
|
+
if (val.length > 500) return 'Feedback is too long (max 500 characters)';
|
|
400
|
+
return null;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const reactiveDemo = {
|
|
404
|
+
div: {
|
|
405
|
+
style: 'display: flex; flex-direction: column; gap: 1rem',
|
|
406
|
+
children: [
|
|
407
|
+
{
|
|
408
|
+
Textarea: {
|
|
409
|
+
label: 'Your Feedback',
|
|
410
|
+
placeholder: 'Share your thoughts with us...',
|
|
411
|
+
value: feedback,
|
|
412
|
+
validate: validateFeedback,
|
|
413
|
+
showCount: true,
|
|
414
|
+
maxLength: 500,
|
|
415
|
+
required: true,
|
|
416
|
+
rows: 4
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
p: {
|
|
421
|
+
class: 'text-sm',
|
|
422
|
+
children: [
|
|
423
|
+
() => {
|
|
424
|
+
const error = validateFeedback(feedback.value);
|
|
425
|
+
return error
|
|
426
|
+
? { span: { class: 'text-error', children: ['✗ ' + error] } }
|
|
427
|
+
: { span: { class: 'text-success', children: ['✓ Feedback is valid!'] } };
|
|
428
|
+
}
|
|
429
|
+
]
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
$('#example').content(reactiveDemo);</code></pre>
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
|
|
441
|
+
<!-- Props Table -->
|
|
442
|
+
<h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Props</h2>
|
|
443
|
+
<div style="overflow-x: auto; margin-bottom: 2rem;">
|
|
444
|
+
<table class="table table-zebra">
|
|
445
|
+
<thead>
|
|
446
|
+
<tr>
|
|
447
|
+
<th>Prop</th>
|
|
448
|
+
<th>Type</th>
|
|
449
|
+
<th>Default</th>
|
|
450
|
+
<th>Description</th>
|
|
451
|
+
</tr>
|
|
452
|
+
</thead>
|
|
453
|
+
<tbody>
|
|
454
|
+
<tr>
|
|
455
|
+
<td><code>value</code></td>
|
|
456
|
+
<td>string | signal</td>
|
|
457
|
+
<td>-</td>
|
|
458
|
+
<td>Textarea value (reactive with signals)</td>
|
|
459
|
+
</tr>
|
|
460
|
+
<tr>
|
|
461
|
+
<td><code>defaultValue</code></td>
|
|
462
|
+
<td>string</td>
|
|
463
|
+
<td>''</td>
|
|
464
|
+
<td>Default value for uncontrolled mode</td>
|
|
465
|
+
</tr>
|
|
466
|
+
<tr>
|
|
467
|
+
<td><code>placeholder</code></td>
|
|
468
|
+
<td>string</td>
|
|
469
|
+
<td>-</td>
|
|
470
|
+
<td>Placeholder text</td>
|
|
471
|
+
</tr>
|
|
472
|
+
<tr>
|
|
473
|
+
<td><code>label</code></td>
|
|
474
|
+
<td>string</td>
|
|
475
|
+
<td>-</td>
|
|
476
|
+
<td>Label text displayed above textarea</td>
|
|
477
|
+
</tr>
|
|
478
|
+
<tr>
|
|
479
|
+
<td><code>helper</code></td>
|
|
480
|
+
<td>string</td>
|
|
481
|
+
<td>-</td>
|
|
482
|
+
<td>Helper text displayed below the textarea</td>
|
|
483
|
+
</tr>
|
|
484
|
+
<tr>
|
|
485
|
+
<td><code>error</code></td>
|
|
486
|
+
<td>string | function</td>
|
|
487
|
+
<td>-</td>
|
|
488
|
+
<td>Error message or reactive error function</td>
|
|
489
|
+
</tr>
|
|
490
|
+
<tr>
|
|
491
|
+
<td><code>validate</code></td>
|
|
492
|
+
<td>function</td>
|
|
493
|
+
<td>-</td>
|
|
494
|
+
<td>Validation function: <code>(value) => errorMessage | null</code></td>
|
|
495
|
+
</tr>
|
|
496
|
+
<tr>
|
|
497
|
+
<td><code>rows</code></td>
|
|
498
|
+
<td>number</td>
|
|
499
|
+
<td>3</td>
|
|
500
|
+
<td>Number of visible text lines</td>
|
|
501
|
+
</tr>
|
|
502
|
+
<tr>
|
|
503
|
+
<td><code>maxLength</code></td>
|
|
504
|
+
<td>number</td>
|
|
505
|
+
<td>-</td>
|
|
506
|
+
<td>Maximum character length</td>
|
|
507
|
+
</tr>
|
|
508
|
+
<tr>
|
|
509
|
+
<td><code>showCount</code></td>
|
|
510
|
+
<td>boolean</td>
|
|
511
|
+
<td>false</td>
|
|
512
|
+
<td>Show character count</td>
|
|
513
|
+
</tr>
|
|
514
|
+
<tr>
|
|
515
|
+
<td><code>color</code></td>
|
|
516
|
+
<td>string</td>
|
|
517
|
+
<td>-</td>
|
|
518
|
+
<td>'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'
|
|
519
|
+
</td>
|
|
520
|
+
</tr>
|
|
521
|
+
<tr>
|
|
522
|
+
<td><code>size</code></td>
|
|
523
|
+
<td>string</td>
|
|
524
|
+
<td>'md'</td>
|
|
525
|
+
<td>'xs' | 'sm' | 'md' | 'lg'</td>
|
|
526
|
+
</tr>
|
|
527
|
+
<tr>
|
|
528
|
+
<td><code>ghost</code></td>
|
|
529
|
+
<td>boolean</td>
|
|
530
|
+
<td>false</td>
|
|
531
|
+
<td>Ghost style (no background)</td>
|
|
532
|
+
</tr>
|
|
533
|
+
<tr>
|
|
534
|
+
<td><code>disabled</code></td>
|
|
535
|
+
<td>boolean</td>
|
|
536
|
+
<td>false</td>
|
|
537
|
+
<td>Disable the textarea</td>
|
|
538
|
+
</tr>
|
|
539
|
+
<tr>
|
|
540
|
+
<td><code>readOnly</code></td>
|
|
541
|
+
<td>boolean</td>
|
|
542
|
+
<td>false</td>
|
|
543
|
+
<td>Make textarea read-only</td>
|
|
544
|
+
</tr>
|
|
545
|
+
<tr>
|
|
546
|
+
<td><code>required</code></td>
|
|
547
|
+
<td>boolean</td>
|
|
548
|
+
<td>false</td>
|
|
549
|
+
<td>Mark as required field (shows asterisk)</td>
|
|
550
|
+
</tr>
|
|
551
|
+
<tr>
|
|
552
|
+
<td><code>onChange</code></td>
|
|
553
|
+
<td>function</td>
|
|
554
|
+
<td>-</td>
|
|
555
|
+
<td>Callback when value changes: <code>(value, event) => void</code></td>
|
|
556
|
+
</tr>
|
|
557
|
+
<tr>
|
|
558
|
+
<td><code>useShadow</code></td>
|
|
559
|
+
<td>boolean</td>
|
|
560
|
+
<td>*</td>
|
|
561
|
+
<td>Render in Shadow DOM. *Follows global <code>initComponents()</code> setting</td>
|
|
562
|
+
</tr>
|
|
563
|
+
</tbody>
|
|
564
|
+
</table>
|
|
565
|
+
</div>
|
|
566
|
+
|
|
567
|
+
<!-- Sizes Example -->
|
|
568
|
+
<h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Sizes</h2>
|
|
569
|
+
<div class="example-stack" style="margin-bottom: 2rem; max-width: 28rem;">
|
|
570
|
+
<textarea class="textarea textarea-xs" placeholder="Extra small"></textarea>
|
|
571
|
+
<textarea class="textarea textarea-sm" placeholder="Small"></textarea>
|
|
572
|
+
<textarea class="textarea" placeholder="Medium"></textarea>
|
|
573
|
+
<textarea class="textarea textarea-lg" placeholder="Large"></textarea>
|
|
574
|
+
</div>
|
|
575
|
+
|
|
576
|
+
<!-- Colors Example -->
|
|
577
|
+
<h2 class="text-xl font-bold" style="margin-bottom: 1rem;">Colors</h2>
|
|
578
|
+
<div class="grid grid-cols-1 md:grid-cols-2"
|
|
579
|
+
style="margin-bottom: 2rem; max-width: 42rem; gap: 1rem">
|
|
580
|
+
<textarea class="textarea textarea-primary" placeholder="Primary"></textarea>
|
|
581
|
+
<textarea class="textarea textarea-secondary" placeholder="Secondary"></textarea>
|
|
582
|
+
<textarea class="textarea textarea-accent" placeholder="Accent"></textarea>
|
|
583
|
+
<textarea class="textarea textarea-info" placeholder="Info"></textarea>
|
|
584
|
+
<textarea class="textarea textarea-success" placeholder="Success"></textarea>
|
|
585
|
+
<textarea class="textarea textarea-warning" placeholder="Warning"></textarea>
|
|
586
|
+
<textarea class="textarea textarea-error" placeholder="Error"></textarea>
|
|
587
|
+
<textarea class="textarea textarea-ghost" placeholder="Ghost"></textarea>
|
|
588
|
+
</div>
|
|
589
|
+
|
|
590
|
+
<!-- With Fieldset -->
|
|
591
|
+
<h2 class="text-xl font-bold" style="margin-bottom: 1rem;">With Label (Fieldset Pattern)</h2>
|
|
592
|
+
<div class="max-w-md" style="margin-bottom: 2rem;">
|
|
593
|
+
<fieldset class="fieldset">
|
|
594
|
+
<legend class="fieldset-legend">Bio</legend>
|
|
595
|
+
<textarea class="textarea w-full" rows="4"
|
|
596
|
+
placeholder="Tell us about yourself..."></textarea>
|
|
597
|
+
<p class="label">Max 500 characters.</p>
|
|
598
|
+
</fieldset>
|
|
599
|
+
</div>
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
</div>
|
|
603
|
+
</div>
|