@kubex/zinc 1.0.24 → 1.0.98
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/.claude/project.md +556 -0
- package/.github/workflows/js_build_and_deploy.yaml +9 -10
- package/dist/custom-elements.json +13431 -8728
- package/dist/vscode.html-custom-data.json +571 -37
- package/dist/web-types.json +1439 -181
- package/dist/zn.d.ts +1642 -661
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +1407 -887
- package/docs/_utilities/code-previews.cjs +10 -1
- package/docs/assets/scripts/docs.js +42 -18
- package/docs/data/data-table.json +229 -66
- package/docs/data/empty.json +6 -0
- package/docs/data/products-table.json +41 -193
- package/docs/pages/components/action-bar.md +121 -6
- package/docs/pages/components/alert.md +118 -15
- package/docs/pages/components/animated-button.md +299 -0
- package/docs/pages/components/audio-select.md +534 -0
- package/docs/pages/components/bulk-actions.md +79 -5
- package/docs/pages/components/button-group.md +235 -27
- package/docs/pages/components/button.md +139 -1
- package/docs/pages/components/chart.md +365 -9
- package/docs/pages/components/checkbox.md +387 -58
- package/docs/pages/components/chip.md +253 -33
- package/docs/pages/components/collapsible.md +393 -46
- package/docs/pages/components/cols.md +152 -30
- package/docs/pages/components/confirm.md +182 -16
- package/docs/pages/components/copy-button.md +169 -6
- package/docs/pages/components/data-select.md +194 -15
- package/docs/pages/components/data-table-filter.md +96 -5
- package/docs/pages/components/data-table-search.md +451 -0
- package/docs/pages/components/data-table-sort.md +66 -5
- package/docs/pages/components/data-table.md +727 -66
- package/docs/pages/components/datepicker.md +402 -7
- package/docs/pages/components/defined-label.md +120 -5
- package/docs/pages/components/dialog.md +339 -59
- package/docs/pages/components/dropdown.md +366 -11
- package/docs/pages/components/editor.md +604 -7
- package/docs/pages/components/empty-state.md +315 -16
- package/docs/pages/components/expanding-action.md +212 -28
- package/docs/pages/components/file.md +421 -12
- package/docs/pages/components/filter-container.md +158 -5
- package/docs/pages/components/filter-wrapper.md +167 -6
- package/docs/pages/components/form-group.md +383 -6
- package/docs/pages/components/hover-container.md +237 -6
- package/docs/pages/components/icon-picker.md +121 -0
- package/docs/pages/components/icon.md +454 -48
- package/docs/pages/components/inline-edit.md +787 -19
- package/docs/pages/components/input-group.md +207 -13
- package/docs/pages/components/input.md +194 -0
- package/docs/pages/components/key-container.md +115 -0
- package/docs/pages/components/key.md +101 -0
- package/docs/pages/components/menu.md +512 -6
- package/docs/pages/components/note.md +239 -36
- package/docs/pages/components/opt-group.md +107 -0
- package/docs/pages/components/pagination.md +332 -6
- package/docs/pages/components/pane.md +222 -6
- package/docs/pages/components/panel.md +213 -26
- package/docs/pages/components/popup.md +1354 -6
- package/docs/pages/components/priority-list.md +233 -0
- package/docs/pages/components/progress-bar.md +387 -6
- package/docs/pages/components/radio-group.md +242 -5
- package/docs/pages/components/radio.md +474 -6
- package/docs/pages/components/rating.md +331 -7
- package/docs/pages/components/reveal.md +524 -6
- package/docs/pages/components/scroll-container.md +552 -6
- package/docs/pages/components/select.md +762 -160
- package/docs/pages/components/skeleton.md +473 -30
- package/docs/pages/components/slideout.md +261 -5
- package/docs/pages/components/sp.md +99 -41
- package/docs/pages/components/split-button.md +347 -9
- package/docs/pages/components/split-pane.md +445 -6
- package/docs/pages/components/stat.md +549 -9
- package/docs/pages/components/status-indicator.md +230 -1
- package/docs/pages/components/stepper.md +563 -6
- package/docs/pages/components/tabs.md +439 -13
- package/docs/pages/components/textarea.md +415 -17
- package/docs/pages/components/tile.md +385 -26
- package/docs/pages/components/toggle.md +424 -6
- package/docs/pages/components/tooltip.md +367 -0
- package/docs/pages/components/translation-group.md +210 -0
- package/docs/pages/components/translations.md +319 -18
- package/docs/pages/components/vertical-stepper.md +401 -8
- package/docs/pages/components/well.md +300 -3
- package/docs/pages/getting-started/form-controls.md +162 -0
- package/docs/pages/index.md +116 -15
- package/package.json +5 -6
- package/scss/_global-spacing.scss +4 -0
- package/scss/_root.scss +2 -2
- package/scss/boot.scss +19 -0
- package/scss/shared/layout.scss +5 -0
- package/scss/themes/_light.scss +3 -3
- package/src/components/alert/alert.scss +1 -0
- package/src/components/animated-button/README.md +306 -0
- package/src/components/animated-button/animated-button.component.ts +229 -0
- package/src/components/animated-button/animated-button.scss +228 -0
- package/src/components/animated-button/animated-button.test.ts +143 -0
- package/src/components/animated-button/index.ts +12 -0
- package/src/components/button/button.component.ts +5 -0
- package/src/components/button-group/button-group.component.ts +25 -13
- package/src/components/button-group/button-group.scss +6 -0
- package/src/components/checkbox/checkbox.component.ts +4 -0
- package/src/components/checkbox/checkbox.scss +7 -4
- package/src/components/checkbox-group/checkbox-group.scss +7 -0
- package/src/components/chip/chip.component.ts +7 -2
- package/src/components/chip/chip.scss +16 -2
- package/src/components/collapsible/collapsible.component.ts +27 -20
- package/src/components/cols/cols.component.ts +14 -2
- package/src/components/cols/cols.scss +6 -12
- package/src/components/confirm/confirm.component.ts +7 -0
- package/src/components/copy-button/copy-button.component.ts +12 -11
- package/src/components/data-select/data-select.component.ts +215 -44
- package/src/components/data-select/data-select.scss +66 -6
- package/src/components/data-select/providers/currency-data-provider.ts +20 -6
- package/src/components/data-select/providers/provider.ts +1 -0
- package/src/components/data-select/providers/us-state-data-provider.ts +68 -0
- package/src/components/data-table/data-table.component.ts +82 -23
- package/src/components/data-table-search/data-table-search.component.ts +184 -0
- package/src/components/data-table-search/data-table-search.scss +17 -0
- package/src/components/data-table-search/data-table-search.test.ts +11 -0
- package/src/components/data-table-search/index.ts +12 -0
- package/src/components/datepicker/datepicker.component.ts +347 -13
- package/src/components/dialog/dialog.component.ts +1 -1
- package/src/components/empty-state/empty-state.scss +6 -1
- package/src/components/header/header.scss +3 -3
- package/src/components/icon/icon.component.ts +23 -1
- package/src/components/icon/icon.scss +23 -0
- package/src/components/icon-picker/brand-icons.ts +24 -0
- package/src/components/icon-picker/icon-picker.component.ts +407 -0
- package/src/components/icon-picker/icon-picker.scss +205 -0
- package/src/components/icon-picker/index.ts +12 -0
- package/src/components/icon-picker/line-icons.ts +612 -0
- package/src/components/icon-picker/material-icons.ts +14543 -0
- package/src/components/inline-edit/inline-edit.component.ts +190 -46
- package/src/components/inline-edit/inline-edit.scss +29 -0
- package/src/components/inline-edit/inline-edit.test.ts +314 -1
- package/src/components/input/input.component.ts +328 -5
- package/src/components/input/input.scss +100 -4
- package/src/components/input-group/input-group.component.ts +28 -7
- package/src/components/input-group/input-group.scss +48 -10
- package/src/components/item/item.component.ts +11 -2
- package/src/components/item/item.scss +7 -0
- package/src/components/key/index.ts +12 -0
- package/src/components/key/key.component.ts +47 -0
- package/src/components/key/key.scss +38 -0
- package/src/components/key-container/index.ts +12 -0
- package/src/components/key-container/key-container.component.ts +142 -0
- package/src/components/key-container/key-container.scss +33 -0
- package/src/components/menu-item/menu-item.component.ts +20 -0
- package/src/components/menu-item/menu-item.scss +69 -2
- package/src/components/navbar/navbar.component.ts +103 -8
- package/src/components/navbar/navbar.scss +6 -1
- package/src/components/opt-group/index.ts +12 -0
- package/src/components/opt-group/opt-group.component.ts +74 -0
- package/src/components/opt-group/opt-group.scss +37 -0
- package/src/components/opt-group/opt-group.test.ts +27 -0
- package/src/components/option/option.component.ts +1 -16
- package/src/components/option/option.scss +4 -0
- package/src/components/panel/panel.component.ts +10 -8
- package/src/components/panel/panel.scss +20 -0
- package/src/components/priority-list/index.ts +12 -0
- package/src/components/priority-list/priority-list.component.ts +611 -0
- package/src/components/priority-list/priority-list.scss +185 -0
- package/src/components/priority-list/priority-list.test.ts +139 -0
- package/src/components/progress-bar/progress-bar.component.ts +22 -16
- package/src/components/radio/radio.scss +10 -3
- package/src/components/select/select.component.ts +812 -72
- package/src/components/select/select.scss +108 -2
- package/src/components/select/select.test.ts +147 -2
- package/src/components/settings-container/settings-container.component.ts +44 -19
- package/src/components/settings-container/settings-container.scss +1 -1
- package/src/components/skeleton/skeleton.component.ts +6 -1
- package/src/components/slideout/slideout.scss +8 -3
- package/src/components/sp/sp.component.ts +3 -1
- package/src/components/sp/sp.scss +19 -0
- package/src/components/stepper/stepper.component.ts +16 -10
- package/src/components/textarea/textarea.scss +0 -4
- package/src/components/tile/tile.component.ts +12 -3
- package/src/components/tile/tile.scss +1 -1
- package/src/components/timer/timer.component.ts +15 -2
- package/src/components/toggle/toggle.component.ts +29 -26
- package/src/components/toggle/toggle.scss +13 -1
- package/src/components/translation-group/index.ts +12 -0
- package/src/components/translation-group/translation-group.component.ts +207 -0
- package/src/components/translation-group/translation-group.scss +8 -0
- package/src/components/translations/translations.component.ts +90 -42
- package/src/components/translations/translations.scss +5 -1
- package/src/components/vertical-stepper/vertical-stepper.component.ts +14 -9
- package/src/events/events.ts +12 -7
- package/src/events/zn-language-change.ts +7 -0
- package/src/events/zn-purchase.ts +11 -0
- package/src/events/zn-redirect.ts +7 -0
- package/src/events/zn-reorder.ts +7 -0
- package/src/events/zn-search-change.ts +11 -0
- package/src/events/zn-submit.ts +1 -1
- package/src/form-control.scss +4 -0
- package/src/internal/form-navigation.ts +510 -0
- package/src/internal/form.ts +6 -0
- package/src/zinc.ts +91 -83
|
@@ -7,6 +7,10 @@ unusedProperties: |
|
|
|
7
7
|
- Sizes `small`, `large`
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
```html:preview
|
|
11
|
+
<zn-textarea label="Comments" placeholder="Enter your feedback here..."></zn-textarea>
|
|
12
|
+
```
|
|
13
|
+
|
|
10
14
|
## Examples
|
|
11
15
|
|
|
12
16
|
### Basic Textarea with Label
|
|
@@ -22,13 +26,30 @@ This component works with standard `<form>` elements. Please refer to the sectio
|
|
|
22
26
|
on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
|
23
27
|
:::
|
|
24
28
|
|
|
29
|
+
### With Value
|
|
30
|
+
|
|
31
|
+
Set the initial value using the `value` attribute.
|
|
32
|
+
|
|
33
|
+
```html:preview
|
|
34
|
+
<zn-textarea label="Description" value="This is some initial text content."></zn-textarea>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
You can also set the value using text content inside the element.
|
|
38
|
+
|
|
39
|
+
```html:preview
|
|
40
|
+
<zn-textarea label="Notes">
|
|
41
|
+
This is the initial content set via text content.
|
|
42
|
+
It can span multiple lines.
|
|
43
|
+
</zn-textarea>
|
|
44
|
+
```
|
|
45
|
+
|
|
25
46
|
### Help Text
|
|
26
47
|
|
|
27
48
|
Add descriptive help text to a textarea with the `help-text` attribute. For help text that contains HTML, use the
|
|
28
49
|
`help-text` slot instead.
|
|
29
50
|
|
|
30
51
|
```html:preview
|
|
31
|
-
<zn-textarea
|
|
52
|
+
<zn-textarea label="Month in review" help-text="Tell us the highlights. Be sure to include details about any financial performance anomalies."></zn-textarea>
|
|
32
53
|
<br />
|
|
33
54
|
<zn-textarea label="Month in review">
|
|
34
55
|
<div slot="help-text">Tell us the highlights. Be sure to include details about any financial performance <strong>anomalies</strong>.</div>
|
|
@@ -65,10 +86,18 @@ without errors.
|
|
|
65
86
|
<zn-textarea label="Month in review" help-text="Tell us the highlights. Be sure to include details about any financial performance anomalies." context-note="Data synced 1 hr ago"></zn-textarea>
|
|
66
87
|
```
|
|
67
88
|
|
|
89
|
+
### Placeholders
|
|
90
|
+
|
|
91
|
+
Use the `placeholder` attribute to add a placeholder.
|
|
92
|
+
|
|
93
|
+
```html:preview
|
|
94
|
+
<zn-textarea label="Feedback" placeholder="Type something"></zn-textarea>
|
|
95
|
+
```
|
|
96
|
+
|
|
68
97
|
### Rows
|
|
69
98
|
|
|
70
99
|
Use the `rows` attribute to change the number of text rows that the textarea shows before the text starts to overflow
|
|
71
|
-
and the textarea scrolls.
|
|
100
|
+
and the textarea scrolls. The default is 4 rows.
|
|
72
101
|
|
|
73
102
|
```html:preview
|
|
74
103
|
<zn-textarea label="Textarea with 2 rows" rows="2"></zn-textarea>
|
|
@@ -78,35 +107,39 @@ and the textarea scrolls.
|
|
|
78
107
|
<zn-textarea label="Textarea with 6 rows" rows="6"></zn-textarea>
|
|
79
108
|
```
|
|
80
109
|
|
|
81
|
-
###
|
|
110
|
+
### Sizes
|
|
82
111
|
|
|
83
|
-
Use the `
|
|
112
|
+
Use the `size` attribute to change a textarea's size. Available sizes are `small`, `medium` (default), and `large`.
|
|
84
113
|
|
|
85
114
|
```html:preview
|
|
86
|
-
<zn-textarea
|
|
115
|
+
<zn-textarea label="Small textarea" size="small"></zn-textarea>
|
|
116
|
+
<br />
|
|
117
|
+
<zn-textarea label="Medium textarea" size="medium"></zn-textarea>
|
|
118
|
+
<br />
|
|
119
|
+
<zn-textarea label="Large textarea" size="large"></zn-textarea>
|
|
87
120
|
```
|
|
88
121
|
|
|
89
|
-
###
|
|
122
|
+
### Resize Options
|
|
90
123
|
|
|
91
|
-
|
|
124
|
+
Control how the textarea can be resized using the `resize` attribute. Options are `vertical` (default), `none`, and `auto`.
|
|
125
|
+
|
|
126
|
+
#### Vertical Resize (Default)
|
|
127
|
+
|
|
128
|
+
By default, textareas can be resized vertically by the user.
|
|
92
129
|
|
|
93
130
|
```html:preview
|
|
94
|
-
<zn-textarea
|
|
95
|
-
<br />
|
|
96
|
-
<zn-textarea placeholder="Medium" size="medium"></zn-textarea>
|
|
97
|
-
<br />
|
|
98
|
-
<zn-textarea placeholder="Large" size="large"></zn-textarea>
|
|
131
|
+
<zn-textarea label="Vertically resizable" resize="vertical"></zn-textarea>
|
|
99
132
|
```
|
|
100
133
|
|
|
101
|
-
|
|
134
|
+
#### Prevent Resizing
|
|
102
135
|
|
|
103
|
-
|
|
136
|
+
To prevent resizing, set the `resize` attribute to `none`.
|
|
104
137
|
|
|
105
138
|
```html:preview
|
|
106
|
-
<zn-textarea label="
|
|
139
|
+
<zn-textarea label="No resizing allowed" resize="none"></zn-textarea>
|
|
107
140
|
```
|
|
108
141
|
|
|
109
|
-
|
|
142
|
+
#### Auto-Resize
|
|
110
143
|
|
|
111
144
|
Textareas will automatically resize to expand to fit their content when `resize` is set to `auto`.
|
|
112
145
|
|
|
@@ -116,5 +149,370 @@ Textareas will automatically resize to expand to fit their content when `resize`
|
|
|
116
149
|
:::
|
|
117
150
|
|
|
118
151
|
```html:preview
|
|
119
|
-
<zn-textarea label="Expanding textarea" resize="auto" value="Someone
|
|
152
|
+
<zn-textarea label="Expanding textarea" resize="auto" value="Someone's sitting in the shade today because someone planted a tree a long time ago..." rows="2"></zn-textarea>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Try typing multiple lines in the textarea above to see it automatically expand.
|
|
156
|
+
|
|
157
|
+
### Character Limits
|
|
158
|
+
|
|
159
|
+
Use the `maxlength` attribute to limit the number of characters that can be entered. The `minlength` attribute sets a minimum character requirement.
|
|
160
|
+
|
|
161
|
+
```html:preview
|
|
162
|
+
<zn-textarea label="Tweet" maxlength="280" help-text="Maximum 280 characters"></zn-textarea>
|
|
163
|
+
<br />
|
|
164
|
+
<zn-textarea label="Review" minlength="20" maxlength="500" help-text="Must be between 20 and 500 characters"></zn-textarea>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Disabled
|
|
168
|
+
|
|
169
|
+
Use the `disabled` attribute to disable a textarea.
|
|
170
|
+
|
|
171
|
+
```html:preview
|
|
172
|
+
<zn-textarea label="Disabled textarea" disabled value="This textarea cannot be edited"></zn-textarea>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Readonly
|
|
176
|
+
|
|
177
|
+
Use the `readonly` attribute to make a textarea read-only. Unlike disabled textareas, readonly textareas can still receive focus and their values are submitted with forms.
|
|
178
|
+
|
|
179
|
+
```html:preview
|
|
180
|
+
<zn-textarea label="Readonly textarea" readonly value="This textarea is read-only but can be focused"></zn-textarea>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Required
|
|
184
|
+
|
|
185
|
+
Use the `required` attribute to make a textarea required for form submission.
|
|
186
|
+
|
|
187
|
+
```html:preview
|
|
188
|
+
<form class="textarea-required-form">
|
|
189
|
+
<zn-textarea name="feedback" label="Feedback" required help-text="This field is required"></zn-textarea>
|
|
190
|
+
<br />
|
|
191
|
+
<zn-button type="submit" color="success">Submit</zn-button>
|
|
192
|
+
</form>
|
|
193
|
+
|
|
194
|
+
<script type="module">
|
|
195
|
+
const form = document.querySelector('.textarea-required-form');
|
|
196
|
+
|
|
197
|
+
await customElements.whenDefined('zn-button');
|
|
198
|
+
await customElements.whenDefined('zn-textarea');
|
|
199
|
+
|
|
200
|
+
form.addEventListener('submit', (e) => {
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
alert('Form submitted successfully!');
|
|
203
|
+
});
|
|
204
|
+
</script>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Transparent Style
|
|
208
|
+
|
|
209
|
+
Use the `transparent` attribute to create a transparent textarea without a visible border.
|
|
210
|
+
|
|
211
|
+
```html:preview
|
|
212
|
+
<zn-textarea label="Transparent textarea" transparent placeholder="Type here..."></zn-textarea>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Flush Style
|
|
216
|
+
|
|
217
|
+
Use the `flush` attribute to remove padding from the textarea container.
|
|
218
|
+
|
|
219
|
+
```html:preview
|
|
220
|
+
<zn-textarea label="Flush textarea" flush></zn-textarea>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Text Input Options
|
|
224
|
+
|
|
225
|
+
#### Autocapitalize
|
|
226
|
+
|
|
227
|
+
Control automatic capitalization using the `autocapitalize` attribute.
|
|
228
|
+
|
|
229
|
+
```html:preview
|
|
230
|
+
<zn-textarea label="Sentences" autocapitalize="sentences" placeholder="First letter of each sentence capitalized"></zn-textarea>
|
|
231
|
+
<br />
|
|
232
|
+
<zn-textarea label="Words" autocapitalize="words" placeholder="First letter of each word capitalized"></zn-textarea>
|
|
233
|
+
<br />
|
|
234
|
+
<zn-textarea label="Characters" autocapitalize="characters" placeholder="All letters capitalized"></zn-textarea>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### Spellcheck
|
|
238
|
+
|
|
239
|
+
Control spell checking with the `spellcheck` attribute. It's enabled by default.
|
|
240
|
+
|
|
241
|
+
```html:preview
|
|
242
|
+
<zn-textarea label="Spellcheck enabled (default)" spellcheck="true" value="This haz a speling eror"></zn-textarea>
|
|
243
|
+
<br />
|
|
244
|
+
<zn-textarea label="Spellcheck disabled" spellcheck="false" value="This haz a speling eror"></zn-textarea>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### Autocorrect
|
|
248
|
+
|
|
249
|
+
Use the `autocorrect` attribute to control autocorrection on mobile devices.
|
|
250
|
+
|
|
251
|
+
```html:preview
|
|
252
|
+
<zn-textarea label="With autocorrect" autocorrect="on"></zn-textarea>
|
|
253
|
+
<br />
|
|
254
|
+
<zn-textarea label="Without autocorrect" autocorrect="off"></zn-textarea>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### Input Mode
|
|
258
|
+
|
|
259
|
+
Use the `inputmode` attribute to control the type of virtual keyboard displayed on mobile devices.
|
|
260
|
+
|
|
261
|
+
```html:preview
|
|
262
|
+
<zn-textarea label="Email" inputmode="email" placeholder="user@example.com"></zn-textarea>
|
|
263
|
+
<br />
|
|
264
|
+
<zn-textarea label="URL" inputmode="url" placeholder="https://example.com"></zn-textarea>
|
|
265
|
+
<br />
|
|
266
|
+
<zn-textarea label="Numeric" inputmode="numeric" placeholder="123456"></zn-textarea>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### Enter Key Hint
|
|
270
|
+
|
|
271
|
+
Use the `enterkeyhint` attribute to customize the label or icon of the Enter key on virtual keyboards.
|
|
272
|
+
|
|
273
|
+
```html:preview
|
|
274
|
+
<zn-textarea label="Search" enterkeyhint="search"></zn-textarea>
|
|
275
|
+
<br />
|
|
276
|
+
<zn-textarea label="Message" enterkeyhint="send"></zn-textarea>
|
|
277
|
+
<br />
|
|
278
|
+
<zn-textarea label="Step" enterkeyhint="next"></zn-textarea>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Form Integration
|
|
282
|
+
|
|
283
|
+
Textareas can be used in forms with various form-related attributes.
|
|
284
|
+
|
|
285
|
+
```html:preview
|
|
286
|
+
<form class="textarea-form">
|
|
287
|
+
<zn-textarea name="comments" label="Comments" required minlength="10"></zn-textarea>
|
|
288
|
+
<br />
|
|
289
|
+
<zn-button type="submit" color="success">Submit</zn-button>
|
|
290
|
+
<zn-button type="reset" color="secondary">Reset</zn-button>
|
|
291
|
+
</form>
|
|
292
|
+
|
|
293
|
+
<script type="module">
|
|
294
|
+
const form = document.querySelector('.textarea-form');
|
|
295
|
+
|
|
296
|
+
await customElements.whenDefined('zn-button');
|
|
297
|
+
await customElements.whenDefined('zn-textarea');
|
|
298
|
+
|
|
299
|
+
form.addEventListener('submit', (e) => {
|
|
300
|
+
e.preventDefault();
|
|
301
|
+
const formData = new FormData(form);
|
|
302
|
+
const data = Object.fromEntries(formData);
|
|
303
|
+
alert('Form submitted!\n\n' + JSON.stringify(data, null, 2));
|
|
304
|
+
});
|
|
305
|
+
</script>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Custom Validation
|
|
309
|
+
|
|
310
|
+
Use the `setCustomValidity()` method to set custom validation messages.
|
|
311
|
+
|
|
312
|
+
```html:preview
|
|
313
|
+
<form class="textarea-validation-form">
|
|
314
|
+
<zn-textarea id="validation-textarea" name="review" label="Product Review" help-text="Must contain the word 'product'"></zn-textarea>
|
|
315
|
+
<br />
|
|
316
|
+
<zn-button type="submit" color="success">Submit</zn-button>
|
|
317
|
+
</form>
|
|
318
|
+
|
|
319
|
+
<script type="module">
|
|
320
|
+
const form = document.querySelector('.textarea-validation-form');
|
|
321
|
+
const textarea = document.getElementById('validation-textarea');
|
|
322
|
+
|
|
323
|
+
await customElements.whenDefined('zn-button');
|
|
324
|
+
await customElements.whenDefined('zn-textarea');
|
|
325
|
+
|
|
326
|
+
textarea.addEventListener('zn-input', () => {
|
|
327
|
+
if (textarea.value && !textarea.value.toLowerCase().includes('product')) {
|
|
328
|
+
textarea.setCustomValidity('Your review must mention the product');
|
|
329
|
+
} else {
|
|
330
|
+
textarea.setCustomValidity('');
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
form.addEventListener('submit', (e) => {
|
|
335
|
+
e.preventDefault();
|
|
336
|
+
if (form.checkValidity()) {
|
|
337
|
+
alert('Form submitted successfully!');
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
</script>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Character Count Display
|
|
344
|
+
|
|
345
|
+
Create a character counter using the `zn-input` event and `maxlength` attribute.
|
|
346
|
+
|
|
347
|
+
```html:preview
|
|
348
|
+
<div class="textarea-counter-container">
|
|
349
|
+
<zn-textarea
|
|
350
|
+
id="counter-textarea"
|
|
351
|
+
label="Description"
|
|
352
|
+
maxlength="200"
|
|
353
|
+
help-text="Maximum 200 characters"
|
|
354
|
+
></zn-textarea>
|
|
355
|
+
<div id="char-count" style="text-align: right; margin-top: 0.5rem; font-size: 0.875rem; color: var(--zn-color-neutral-600);">
|
|
356
|
+
0 / 200
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<script type="module">
|
|
361
|
+
const textarea = document.getElementById('counter-textarea');
|
|
362
|
+
const counter = document.getElementById('char-count');
|
|
363
|
+
|
|
364
|
+
await customElements.whenDefined('zn-textarea');
|
|
365
|
+
|
|
366
|
+
textarea.addEventListener('zn-input', () => {
|
|
367
|
+
const length = textarea.value.length;
|
|
368
|
+
const max = textarea.maxlength;
|
|
369
|
+
counter.textContent = `${length} / ${max}`;
|
|
370
|
+
|
|
371
|
+
if (length > max * 0.9) {
|
|
372
|
+
counter.style.color = 'var(--zn-color-error-600)';
|
|
373
|
+
} else if (length > max * 0.75) {
|
|
374
|
+
counter.style.color = 'var(--zn-color-warning-600)';
|
|
375
|
+
} else {
|
|
376
|
+
counter.style.color = 'var(--zn-color-neutral-600)';
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
</script>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Programmatic Control
|
|
383
|
+
|
|
384
|
+
Use methods to programmatically control the textarea.
|
|
385
|
+
|
|
386
|
+
```html:preview
|
|
387
|
+
<zn-textarea id="control-textarea" label="Controlled Textarea" value="Initial text content"></zn-textarea>
|
|
388
|
+
<br />
|
|
389
|
+
<zn-button id="focus-btn">Focus</zn-button>
|
|
390
|
+
<zn-button id="blur-btn">Blur</zn-button>
|
|
391
|
+
<zn-button id="select-btn">Select All</zn-button>
|
|
392
|
+
<zn-button id="clear-btn" color="error">Clear</zn-button>
|
|
393
|
+
|
|
394
|
+
<script type="module">
|
|
395
|
+
const textarea = document.getElementById('control-textarea');
|
|
396
|
+
const focusBtn = document.getElementById('focus-btn');
|
|
397
|
+
const blurBtn = document.getElementById('blur-btn');
|
|
398
|
+
const selectBtn = document.getElementById('select-btn');
|
|
399
|
+
const clearBtn = document.getElementById('clear-btn');
|
|
400
|
+
|
|
401
|
+
await customElements.whenDefined('zn-button');
|
|
402
|
+
await customElements.whenDefined('zn-textarea');
|
|
403
|
+
|
|
404
|
+
focusBtn.addEventListener('click', () => textarea.focus());
|
|
405
|
+
blurBtn.addEventListener('click', () => textarea.blur());
|
|
406
|
+
selectBtn.addEventListener('click', () => textarea.select());
|
|
407
|
+
clearBtn.addEventListener('click', () => textarea.value = '');
|
|
408
|
+
</script>
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Selection and Range Methods
|
|
412
|
+
|
|
413
|
+
Use `setSelectionRange()` and `setRangeText()` methods to work with text selections.
|
|
414
|
+
|
|
415
|
+
```html:preview
|
|
416
|
+
<zn-textarea id="selection-textarea" label="Text Selection Demo" value="The quick brown fox jumps over the lazy dog"></zn-textarea>
|
|
417
|
+
<br />
|
|
418
|
+
<zn-button id="select-word-btn">Select "brown"</zn-button>
|
|
419
|
+
<zn-button id="replace-word-btn">Replace "fox" with "cat"</zn-button>
|
|
420
|
+
<zn-button id="insert-text-btn">Insert at cursor</zn-button>
|
|
421
|
+
|
|
422
|
+
<script type="module">
|
|
423
|
+
const textarea = document.getElementById('selection-textarea');
|
|
424
|
+
const selectWordBtn = document.getElementById('select-word-btn');
|
|
425
|
+
const replaceWordBtn = document.getElementById('replace-word-btn');
|
|
426
|
+
const insertTextBtn = document.getElementById('insert-text-btn');
|
|
427
|
+
|
|
428
|
+
await customElements.whenDefined('zn-button');
|
|
429
|
+
await customElements.whenDefined('zn-textarea');
|
|
430
|
+
|
|
431
|
+
selectWordBtn.addEventListener('click', () => {
|
|
432
|
+
const text = textarea.value;
|
|
433
|
+
const start = text.indexOf('brown');
|
|
434
|
+
const end = start + 5;
|
|
435
|
+
textarea.setSelectionRange(start, end);
|
|
436
|
+
textarea.focus();
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
replaceWordBtn.addEventListener('click', () => {
|
|
440
|
+
const text = textarea.value;
|
|
441
|
+
const start = text.indexOf('fox');
|
|
442
|
+
const end = start + 3;
|
|
443
|
+
textarea.setRangeText('cat', start, end, 'select');
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
insertTextBtn.addEventListener('click', () => {
|
|
447
|
+
textarea.setRangeText(' [INSERTED]');
|
|
448
|
+
textarea.focus();
|
|
449
|
+
});
|
|
450
|
+
</script>
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Events
|
|
454
|
+
|
|
455
|
+
Listen to textarea events to respond to user interactions.
|
|
456
|
+
|
|
457
|
+
```html:preview
|
|
458
|
+
<zn-textarea id="event-textarea" label="Event Demo" placeholder="Type or interact with this textarea"></zn-textarea>
|
|
459
|
+
<div id="event-log" style="margin-top: 1rem; padding: 1rem; background: var(--zn-color-neutral-100); border-radius: 4px; font-family: monospace; font-size: 0.875rem; max-height: 200px; overflow-y: auto;">
|
|
460
|
+
Events will appear here...
|
|
461
|
+
</div>
|
|
462
|
+
|
|
463
|
+
<script type="module">
|
|
464
|
+
const textarea = document.getElementById('event-textarea');
|
|
465
|
+
const eventLog = document.getElementById('event-log');
|
|
466
|
+
|
|
467
|
+
await customElements.whenDefined('zn-textarea');
|
|
468
|
+
|
|
469
|
+
function logEvent(eventName, detail = '') {
|
|
470
|
+
const time = new Date().toLocaleTimeString();
|
|
471
|
+
const message = `[${time}] ${eventName}${detail ? ': ' + detail : ''}`;
|
|
472
|
+
eventLog.innerHTML = message + '<br>' + eventLog.innerHTML;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
textarea.addEventListener('zn-focus', () => logEvent('zn-focus'));
|
|
476
|
+
textarea.addEventListener('zn-blur', () => logEvent('zn-blur'));
|
|
477
|
+
textarea.addEventListener('zn-input', (e) => logEvent('zn-input', `value="${e.target.value}"`));
|
|
478
|
+
textarea.addEventListener('zn-change', (e) => logEvent('zn-change', `value="${e.target.value}"`));
|
|
479
|
+
textarea.addEventListener('zn-invalid', () => logEvent('zn-invalid'));
|
|
480
|
+
</script>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Customizing Label Position
|
|
484
|
+
|
|
485
|
+
Use [CSS parts](#css-parts) to customize the way form controls are drawn. This example uses CSS grid to position the
|
|
486
|
+
label to the left of the control.
|
|
487
|
+
|
|
488
|
+
```html:preview
|
|
489
|
+
<zn-textarea class="label-on-left" label="Bio" help-text="Tell us about yourself"></zn-textarea>
|
|
490
|
+
<zn-textarea class="label-on-left" label="Notes" help-text="Additional notes"></zn-textarea>
|
|
491
|
+
|
|
492
|
+
<style>
|
|
493
|
+
.label-on-left {
|
|
494
|
+
--label-width: 3.75rem;
|
|
495
|
+
--gap-width: 1rem;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.label-on-left + .label-on-left {
|
|
499
|
+
margin-top: var(--zn-spacing-medium);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.label-on-left::part(form-control) {
|
|
503
|
+
display: grid;
|
|
504
|
+
grid: auto / var(--label-width) 1fr;
|
|
505
|
+
gap: var(--zn-spacing-3x-small) var(--gap-width);
|
|
506
|
+
align-items: start;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.label-on-left::part(form-control-label) {
|
|
510
|
+
text-align: right;
|
|
511
|
+
padding-top: var(--zn-spacing-small);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.label-on-left::part(form-control-help-text) {
|
|
515
|
+
grid-column-start: 2;
|
|
516
|
+
}
|
|
517
|
+
</style>
|
|
120
518
|
```
|