@delightui/components 0.1.104 → 0.1.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +104 -1
  2. package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
  3. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  4. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  5. package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  6. package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  7. package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
  8. package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  9. package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
  10. package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
  11. package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
  12. package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
  13. package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
  14. package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
  15. package/dist/cjs/components/molecules/index.d.ts +2 -0
  16. package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
  17. package/dist/cjs/components/utils/index.d.ts +2 -0
  18. package/dist/cjs/library.css +13 -0
  19. package/dist/cjs/library.js +2 -2
  20. package/dist/cjs/library.js.map +1 -1
  21. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  22. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  23. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  24. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  25. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  26. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  27. package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  28. package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
  29. package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
  30. package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
  31. package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
  32. package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
  33. package/dist/esm/components/molecules/Select/index.d.ts +2 -9
  34. package/dist/esm/components/molecules/index.d.ts +2 -0
  35. package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
  36. package/dist/esm/components/utils/index.d.ts +2 -0
  37. package/dist/esm/library.css +13 -0
  38. package/dist/esm/library.js +3 -3
  39. package/dist/esm/library.js.map +1 -1
  40. package/dist/index.d.ts +156 -12
  41. package/docs/README.md +264 -0
  42. package/docs/components/atoms/ActionImage.md +119 -0
  43. package/docs/components/atoms/Button.md +197 -0
  44. package/docs/components/atoms/Checkbox.md +299 -0
  45. package/docs/components/atoms/CheckboxItem.md +314 -0
  46. package/docs/components/atoms/Chip.md +380 -0
  47. package/docs/components/atoms/CustomToggle.md +270 -0
  48. package/docs/components/atoms/Icon.md +365 -0
  49. package/docs/components/atoms/IconButton.md +407 -0
  50. package/docs/components/atoms/Image.md +448 -0
  51. package/docs/components/atoms/Input.md +430 -0
  52. package/docs/components/atoms/ListItem.md +502 -0
  53. package/docs/components/atoms/Password.md +472 -0
  54. package/docs/components/atoms/RadioButton.md +614 -0
  55. package/docs/components/atoms/RadioButtonItem.md +588 -0
  56. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  57. package/docs/components/atoms/SelectListItem.md +609 -0
  58. package/docs/components/atoms/Slider.md +605 -0
  59. package/docs/components/atoms/Spinner.md +605 -0
  60. package/docs/components/atoms/Text.md +463 -0
  61. package/docs/components/atoms/TextArea.md +670 -0
  62. package/docs/components/atoms/ToastNotification.md +668 -0
  63. package/docs/components/atoms/Toggle.md +737 -0
  64. package/docs/components/atoms/ToggleButton.md +751 -0
  65. package/docs/components/atoms/Tooltip.md +391 -0
  66. package/docs/components/molecules/Accordion.md +440 -0
  67. package/docs/components/molecules/AccordionGroup.md +547 -0
  68. package/docs/components/molecules/ActionCard.md +546 -0
  69. package/docs/components/molecules/Breadcrumb.md +403 -0
  70. package/docs/components/molecules/Breadcrumbs.md +485 -0
  71. package/docs/components/molecules/ButtonGroup.md +383 -0
  72. package/docs/components/molecules/Card.md +298 -0
  73. package/docs/components/molecules/ChipInput.md +646 -0
  74. package/docs/components/molecules/ContextMenu.md +768 -0
  75. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  76. package/docs/components/molecules/DatePicker.md +516 -0
  77. package/docs/components/molecules/DateTimeSelector.md +166 -0
  78. package/docs/components/molecules/FormField.md +312 -0
  79. package/docs/components/molecules/Grid.md +577 -0
  80. package/docs/components/molecules/GridItem.md +834 -0
  81. package/docs/components/molecules/GridList.md +244 -0
  82. package/docs/components/molecules/List.md +485 -0
  83. package/docs/components/molecules/Modal.md +470 -0
  84. package/docs/components/molecules/ModalFooter.md +702 -0
  85. package/docs/components/molecules/ModalHeader.md +756 -0
  86. package/docs/components/molecules/ModalProvider.md +205 -0
  87. package/docs/components/molecules/Nav.md +530 -0
  88. package/docs/components/molecules/NavItem.md +572 -0
  89. package/docs/components/molecules/NavLink.md +499 -0
  90. package/docs/components/molecules/Option.md +521 -0
  91. package/docs/components/molecules/Pagination.md +592 -0
  92. package/docs/components/molecules/PaginationNumberField.md +722 -0
  93. package/docs/components/molecules/Popover.md +516 -0
  94. package/docs/components/molecules/ProgressBar.md +624 -0
  95. package/docs/components/molecules/RadioGroup.md +831 -0
  96. package/docs/components/molecules/RepeaterList.md +185 -0
  97. package/docs/components/molecules/Select.md +402 -0
  98. package/docs/components/molecules/SortableTrigger.md +82 -0
  99. package/docs/components/molecules/useModal.md +379 -0
  100. package/docs/components/organisms/Dropzone.md +346 -0
  101. package/docs/components/organisms/DropzoneClear.md +135 -0
  102. package/docs/components/organisms/DropzoneContent.md +216 -0
  103. package/docs/components/organisms/DropzoneFilename.md +191 -0
  104. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  105. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  106. package/docs/components/organisms/Form.md +533 -0
  107. package/docs/components/organisms/SlideOutPanel.md +662 -0
  108. package/docs/components/organisms/TabContent.md +902 -0
  109. package/docs/components/organisms/TabItem.md +1091 -0
  110. package/docs/components/organisms/Table.md +611 -0
  111. package/docs/components/organisms/TableBody.md +679 -0
  112. package/docs/components/organisms/TableCell.md +482 -0
  113. package/docs/components/organisms/TableHeader.md +513 -0
  114. package/docs/components/organisms/TableHeaderCell.md +661 -0
  115. package/docs/components/organisms/TableRow.md +715 -0
  116. package/docs/components/organisms/Tabs.md +1330 -0
  117. package/docs/components/utils/ConditionalView.md +568 -0
  118. package/docs/components/utils/RenderStateView.md +726 -0
  119. package/docs/components/utils/WrapTextNodes.md +614 -0
  120. package/package.json +3 -2
@@ -0,0 +1,670 @@
1
+ # TextArea
2
+
3
+ A multi-line text input component that extends the standard HTML textarea with enhanced form integration capabilities. It provides a consistent interface for collecting longer text inputs from users, with full support for controlled and uncontrolled usage patterns, validation, and accessibility features.
4
+
5
+ ## Aliases
6
+
7
+ - TextArea
8
+ - MultilineInput
9
+ - TextBox
10
+
11
+ ## Props Breakdown
12
+
13
+ **Extends:** `TextareaHTMLAttributes<HTMLTextAreaElement>` (excluding `value`) + `ControlledFormComponentProps<string>`
14
+
15
+ | Prop | Type | Default | Required | Description |
16
+ |------|------|---------|----------|-------------|
17
+ | `initialValue` | `string` | `undefined` | No | The initial value for the field |
18
+ | `checked` | `boolean` | `undefined` | No | The initial value for the field |
19
+ | `value` | `string` | `undefined` | No | The current value of the form field |
20
+ | `onValueChange` | `(value: string) => void` | `undefined` | No | Callback function that is called when the field value changes |
21
+ | `disabled` | `boolean` | `false` | No | Whether the form field is disabled and cannot be interacted with |
22
+ | `required` | `boolean` | `false` | No | Whether the form field must have a value |
23
+ | `invalid` | `boolean` | `false` | No | Whether the form field's current value is invalid |
24
+ | `id` | `string` | `undefined` | No | Id for the form field |
25
+ | `placeholder` | `string` | `undefined` | No | Placeholder text for the textarea |
26
+ | `rows` | `number` | `undefined` | No | Number of visible text lines for the control |
27
+ | `cols` | `number` | `undefined` | No | Visible width of the text control |
28
+ | `maxLength` | `number` | `undefined` | No | Maximum length of the input value |
29
+ | `minLength` | `number` | `undefined` | No | Minimum length of the input value |
30
+ | `readOnly` | `boolean` | `false` | No | Whether the textarea is read-only |
31
+ | `autoFocus` | `boolean` | `false` | No | Whether the textarea should be focused on mount |
32
+ | `wrap` | `string` | `undefined` | No | How the text in the textarea is to be wrapped when submitted |
33
+ | `resize` | `string` | `undefined` | No | CSS resize property |
34
+
35
+ Plus all standard HTML textarea attributes (name, form, autoComplete, spellCheck, etc.) except `value`.
36
+
37
+ ## Examples
38
+
39
+ ### Basic TextArea
40
+
41
+ ```tsx
42
+ import { TextArea } from '@delightui/components';
43
+
44
+ function BasicTextAreaExample() {
45
+ const [message, setMessage] = useState('');
46
+
47
+ return (
48
+ <div>
49
+ <p>Character count: {message.length}</p>
50
+ <TextArea
51
+ value={message}
52
+ onValueChange={setMessage}
53
+ placeholder="Enter your message here..."
54
+ rows={4}
55
+ />
56
+ </div>
57
+ );
58
+ }
59
+ ```
60
+
61
+ ### Form Integration
62
+
63
+ ```tsx
64
+ import { Form, FormField, TextArea, Button } from '@delightui/components';
65
+
66
+ function TextAreaFormExample() {
67
+ const handleSubmit = (data: any) => {
68
+ console.log('Form submitted:', data);
69
+ };
70
+
71
+ return (
72
+ <Form onSubmit={handleSubmit}>
73
+ <FormField
74
+ name="description"
75
+ label="Description"
76
+ required
77
+ >
78
+ <TextArea
79
+ placeholder="Please provide a detailed description..."
80
+ rows={6}
81
+ maxLength={500}
82
+ />
83
+ </FormField>
84
+
85
+ <FormField
86
+ name="comments"
87
+ label="Additional Comments"
88
+ >
89
+ <TextArea
90
+ placeholder="Any additional comments or feedback..."
91
+ rows={4}
92
+ />
93
+ </FormField>
94
+
95
+ <Button type="submit">
96
+ Submit
97
+ </Button>
98
+ </Form>
99
+ );
100
+ }
101
+ ```
102
+
103
+ ### TextArea with Character Counter
104
+
105
+ ```tsx
106
+ import { TextArea, Text } from '@delightui/components';
107
+
108
+ function TextAreaWithCounterExample() {
109
+ const [content, setContent] = useState('');
110
+ const maxLength = 200;
111
+
112
+ const remainingChars = maxLength - content.length;
113
+ const isNearLimit = remainingChars <= 20;
114
+ const isOverLimit = remainingChars < 0;
115
+
116
+ return (
117
+ <div>
118
+ <TextArea
119
+ value={content}
120
+ onValueChange={setContent}
121
+ placeholder="Write your review..."
122
+ rows={6}
123
+ maxLength={maxLength}
124
+ invalid={isOverLimit}
125
+ />
126
+
127
+ <div style={{
128
+ display: 'flex',
129
+ justifyContent: 'space-between',
130
+ alignItems: 'center',
131
+ marginTop: '8px'
132
+ }}>
133
+ <Text
134
+ size="small"
135
+ color={isOverLimit ? 'error' : isNearLimit ? 'warning' : 'secondary'}
136
+ >
137
+ {content.length} / {maxLength} characters
138
+ </Text>
139
+
140
+ {isOverLimit && (
141
+ <Text size="small" color="error">
142
+ {Math.abs(remainingChars)} characters over limit
143
+ </Text>
144
+ )}
145
+ </div>
146
+ </div>
147
+ );
148
+ }
149
+ ```
150
+
151
+ ### Resizable TextArea
152
+
153
+ ```tsx
154
+ import { TextArea } from '@delightui/components';
155
+
156
+ function ResizableTextAreaExample() {
157
+ const [content, setContent] = useState('');
158
+
159
+ return (
160
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
161
+ <div>
162
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
163
+ Resizable (Default)
164
+ </Text>
165
+ <TextArea
166
+ value={content}
167
+ onValueChange={setContent}
168
+ placeholder="This textarea can be resized..."
169
+ rows={4}
170
+ />
171
+ </div>
172
+
173
+ <div>
174
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
175
+ Vertical Resize Only
176
+ </Text>
177
+ <TextArea
178
+ value={content}
179
+ onValueChange={setContent}
180
+ placeholder="This textarea can only be resized vertically..."
181
+ rows={4}
182
+ style={{ resize: 'vertical' }}
183
+ />
184
+ </div>
185
+
186
+ <div>
187
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
188
+ No Resize
189
+ </Text>
190
+ <TextArea
191
+ value={content}
192
+ onValueChange={setContent}
193
+ placeholder="This textarea cannot be resized..."
194
+ rows={4}
195
+ style={{ resize: 'none' }}
196
+ />
197
+ </div>
198
+ </div>
199
+ );
200
+ }
201
+ ```
202
+
203
+ ### Auto-growing TextArea
204
+
205
+ ```tsx
206
+ import { TextArea } from '@delightui/components';
207
+
208
+ function AutoGrowingTextAreaExample() {
209
+ const [content, setContent] = useState('');
210
+
211
+ // Calculate rows based on content
212
+ const calculateRows = (text: string) => {
213
+ const lines = text.split('\n').length;
214
+ const minRows = 3;
215
+ const maxRows = 10;
216
+ return Math.min(Math.max(lines, minRows), maxRows);
217
+ };
218
+
219
+ return (
220
+ <div>
221
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
222
+ Auto-growing TextArea
223
+ </Text>
224
+ <Text size="small" color="secondary" style={{ marginBottom: '12px' }}>
225
+ This textarea grows as you type (min 3 rows, max 10 rows)
226
+ </Text>
227
+
228
+ <TextArea
229
+ value={content}
230
+ onValueChange={setContent}
231
+ placeholder="Start typing and watch the textarea grow..."
232
+ rows={calculateRows(content)}
233
+ style={{ resize: 'none' }}
234
+ />
235
+ </div>
236
+ );
237
+ }
238
+ ```
239
+
240
+ ### Comment System Example
241
+
242
+ ```tsx
243
+ import { TextArea, Button, Text } from '@delightui/components';
244
+
245
+ function CommentSystemExample() {
246
+ const [comment, setComment] = useState('');
247
+ const [comments, setComments] = useState([
248
+ { id: 1, author: 'John Doe', content: 'Great article! Very informative.', time: '2 hours ago' },
249
+ { id: 2, author: 'Jane Smith', content: 'I learned a lot from this. Thank you for sharing.', time: '1 hour ago' }
250
+ ]);
251
+
252
+ const handleSubmit = () => {
253
+ if (comment.trim()) {
254
+ const newComment = {
255
+ id: comments.length + 1,
256
+ author: 'You',
257
+ content: comment,
258
+ time: 'Just now'
259
+ };
260
+ setComments([...comments, newComment]);
261
+ setComment('');
262
+ }
263
+ };
264
+
265
+ return (
266
+ <div style={{ maxWidth: '600px' }}>
267
+ <Text weight="bold" style={{ marginBottom: '16px' }}>
268
+ Comments ({comments.length})
269
+ </Text>
270
+
271
+ {/* Existing Comments */}
272
+ <div style={{ marginBottom: '24px' }}>
273
+ {comments.map((c) => (
274
+ <div key={c.id} style={{
275
+ border: '1px solid #eee',
276
+ borderRadius: '8px',
277
+ padding: '16px',
278
+ marginBottom: '12px'
279
+ }}>
280
+ <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '8px' }}>
281
+ <Text weight="bold">{c.author}</Text>
282
+ <Text size="small" color="secondary">{c.time}</Text>
283
+ </div>
284
+ <Text>{c.content}</Text>
285
+ </div>
286
+ ))}
287
+ </div>
288
+
289
+ {/* Add Comment */}
290
+ <div style={{
291
+ border: '1px solid #ccc',
292
+ borderRadius: '8px',
293
+ padding: '16px',
294
+ backgroundColor: '#f9f9fa'
295
+ }}>
296
+ <Text weight="bold" style={{ marginBottom: '12px' }}>
297
+ Add a comment
298
+ </Text>
299
+
300
+ <TextArea
301
+ value={comment}
302
+ onValueChange={setComment}
303
+ placeholder="What are your thoughts?"
304
+ rows={4}
305
+ style={{ marginBottom: '12px' }}
306
+ />
307
+
308
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
309
+ <Text size="small" color="secondary">
310
+ {comment.length} characters
311
+ </Text>
312
+ <Button
313
+ onClick={handleSubmit}
314
+ disabled={!comment.trim()}
315
+ size="Small"
316
+ >
317
+ Post Comment
318
+ </Button>
319
+ </div>
320
+ </div>
321
+ </div>
322
+ );
323
+ }
324
+ ```
325
+
326
+ ### Feedback Form
327
+
328
+ ```tsx
329
+ import { Form, FormField, TextArea, Button, RadioButton, Text } from '@delightui/components';
330
+
331
+ function FeedbackFormExample() {
332
+ const [formData, setFormData] = useState({
333
+ rating: '',
334
+ feedback: '',
335
+ suggestions: ''
336
+ });
337
+
338
+ const handleSubmit = (data: any) => {
339
+ console.log('Feedback submitted:', data);
340
+ };
341
+
342
+ return (
343
+ <Form onSubmit={handleSubmit}>
344
+ <Text weight="bold" size="large" style={{ marginBottom: '20px' }}>
345
+ We'd love your feedback!
346
+ </Text>
347
+
348
+ <FormField
349
+ name="rating"
350
+ label="How would you rate your experience?"
351
+ required
352
+ >
353
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
354
+ <RadioButton name="rating" value="excellent">Excellent</RadioButton>
355
+ <RadioButton name="rating" value="good">Good</RadioButton>
356
+ <RadioButton name="rating" value="average">Average</RadioButton>
357
+ <RadioButton name="rating" value="poor">Poor</RadioButton>
358
+ </div>
359
+ </FormField>
360
+
361
+ <FormField
362
+ name="feedback"
363
+ label="Tell us about your experience"
364
+ required
365
+ >
366
+ <TextArea
367
+ placeholder="Please share your thoughts about our service..."
368
+ rows={5}
369
+ maxLength={1000}
370
+ />
371
+ </FormField>
372
+
373
+ <FormField
374
+ name="suggestions"
375
+ label="Any suggestions for improvement?"
376
+ >
377
+ <TextArea
378
+ placeholder="How can we make your experience better?"
379
+ rows={4}
380
+ maxLength={500}
381
+ />
382
+ </FormField>
383
+
384
+ <Button type="submit">
385
+ Submit Feedback
386
+ </Button>
387
+ </Form>
388
+ );
389
+ }
390
+ ```
391
+
392
+ ### Code Input TextArea
393
+
394
+ ```tsx
395
+ import { TextArea, Button, Text } from '@delightui/components';
396
+
397
+ function CodeInputExample() {
398
+ const [code, setCode] = useState(`function greet(name) {
399
+ return \`Hello, \${name}!\`;
400
+ }
401
+
402
+ console.log(greet('World'));`);
403
+
404
+ const lineCount = code.split('\n').length;
405
+
406
+ return (
407
+ <div style={{ maxWidth: '600px' }}>
408
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
409
+ Code Editor
410
+ </Text>
411
+
412
+ <div style={{ position: 'relative' }}>
413
+ <TextArea
414
+ value={code}
415
+ onValueChange={setCode}
416
+ rows={12}
417
+ style={{
418
+ fontFamily: 'monospace',
419
+ fontSize: '14px',
420
+ resize: 'none',
421
+ paddingLeft: '50px'
422
+ }}
423
+ />
424
+
425
+ {/* Line numbers */}
426
+ <div style={{
427
+ position: 'absolute',
428
+ left: '8px',
429
+ top: '8px',
430
+ fontFamily: 'monospace',
431
+ fontSize: '14px',
432
+ color: '#666',
433
+ lineHeight: '1.5',
434
+ pointerEvents: 'none'
435
+ }}>
436
+ {Array.from({ length: lineCount }, (_, i) => (
437
+ <div key={i}>{i + 1}</div>
438
+ ))}
439
+ </div>
440
+ </div>
441
+
442
+ <div style={{
443
+ display: 'flex',
444
+ justifyContent: 'space-between',
445
+ alignItems: 'center',
446
+ marginTop: '8px'
447
+ }}>
448
+ <Text size="small" color="secondary">
449
+ Lines: {lineCount} | Characters: {code.length}
450
+ </Text>
451
+
452
+ <div style={{ display: 'flex', gap: '8px' }}>
453
+ <Button size="Small" type="Outlined" onClick={() => setCode('')}>
454
+ Clear
455
+ </Button>
456
+ <Button size="Small" onClick={() => console.log('Code executed:', code)}>
457
+ Run
458
+ </Button>
459
+ </div>
460
+ </div>
461
+ </div>
462
+ );
463
+ }
464
+ ```
465
+
466
+ ### Disabled and Read-only States
467
+
468
+ ```tsx
469
+ import { TextArea, Text } from '@delightui/components';
470
+
471
+ function DisabledReadOnlyExample() {
472
+ const sampleText = "This is some sample content that demonstrates different states of the TextArea component.";
473
+
474
+ return (
475
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
476
+ <div>
477
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
478
+ Normal TextArea
479
+ </Text>
480
+ <TextArea
481
+ value={sampleText}
482
+ placeholder="Type here..."
483
+ rows={3}
484
+ />
485
+ </div>
486
+
487
+ <div>
488
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
489
+ Disabled TextArea
490
+ </Text>
491
+ <TextArea
492
+ value={sampleText}
493
+ disabled
494
+ rows={3}
495
+ />
496
+ </div>
497
+
498
+ <div>
499
+ <Text weight="bold" style={{ marginBottom: '8px' }}>
500
+ Read-only TextArea
501
+ </Text>
502
+ <TextArea
503
+ value={sampleText}
504
+ readOnly
505
+ rows={3}
506
+ />
507
+ </div>
508
+ </div>
509
+ );
510
+ }
511
+ ```
512
+
513
+ ### Template System
514
+
515
+ ```tsx
516
+ import { TextArea, Button, Text } from '@delightui/components';
517
+
518
+ function TemplateSystemExample() {
519
+ const [message, setMessage] = useState('');
520
+
521
+ const templates = [
522
+ {
523
+ name: 'Thank You',
524
+ content: 'Thank you for your interest in our services. We appreciate your business and look forward to working with you.'
525
+ },
526
+ {
527
+ name: 'Follow Up',
528
+ content: 'I wanted to follow up on our previous conversation. Please let me know if you have any questions or if there\'s anything else I can help you with.'
529
+ },
530
+ {
531
+ name: 'Apology',
532
+ content: 'I apologize for any inconvenience this may have caused. We are working to resolve the issue and will keep you updated on our progress.'
533
+ }
534
+ ];
535
+
536
+ const useTemplate = (template: string) => {
537
+ setMessage(template);
538
+ };
539
+
540
+ return (
541
+ <div style={{ maxWidth: '600px' }}>
542
+ <Text weight="bold" style={{ marginBottom: '12px' }}>
543
+ Message Templates
544
+ </Text>
545
+
546
+ <div style={{ display: 'flex', gap: '8px', marginBottom: '16px', flexWrap: 'wrap' }}>
547
+ {templates.map((template, index) => (
548
+ <Button
549
+ key={index}
550
+ size="Small"
551
+ type="Outlined"
552
+ onClick={() => useTemplate(template.content)}
553
+ >
554
+ {template.name}
555
+ </Button>
556
+ ))}
557
+ </div>
558
+
559
+ <TextArea
560
+ value={message}
561
+ onValueChange={setMessage}
562
+ placeholder="Type your message or select a template above..."
563
+ rows={6}
564
+ />
565
+
566
+ <div style={{
567
+ display: 'flex',
568
+ justifyContent: 'space-between',
569
+ alignItems: 'center',
570
+ marginTop: '12px'
571
+ }}>
572
+ <Text size="small" color="secondary">
573
+ {message.length} characters
574
+ </Text>
575
+
576
+ <div style={{ display: 'flex', gap: '8px' }}>
577
+ <Button
578
+ size="Small"
579
+ type="Outlined"
580
+ onClick={() => setMessage('')}
581
+ disabled={!message}
582
+ >
583
+ Clear
584
+ </Button>
585
+ <Button
586
+ size="Small"
587
+ disabled={!message.trim()}
588
+ >
589
+ Send
590
+ </Button>
591
+ </div>
592
+ </div>
593
+ </div>
594
+ );
595
+ }
596
+ ```
597
+
598
+ ### Validation Example
599
+
600
+ ```tsx
601
+ import { Form, FormField, TextArea, Button, Text } from '@delightui/components';
602
+
603
+ function ValidationExample() {
604
+ const [content, setContent] = useState('');
605
+ const [error, setError] = useState('');
606
+
607
+ const minLength = 50;
608
+ const maxLength = 500;
609
+
610
+ const validateContent = (value: string) => {
611
+ if (value.length < minLength) {
612
+ setError(`Content must be at least ${minLength} characters long`);
613
+ return false;
614
+ }
615
+ if (value.length > maxLength) {
616
+ setError(`Content must not exceed ${maxLength} characters`);
617
+ return false;
618
+ }
619
+ setError('');
620
+ return true;
621
+ };
622
+
623
+ const handleSubmit = (data: any) => {
624
+ if (validateContent(content)) {
625
+ console.log('Valid submission:', data);
626
+ }
627
+ };
628
+
629
+ return (
630
+ <Form onSubmit={handleSubmit}>
631
+ <FormField
632
+ name="content"
633
+ label="Content"
634
+ required
635
+ invalid={!!error}
636
+ message={error}
637
+ >
638
+ <TextArea
639
+ value={content}
640
+ onValueChange={(value) => {
641
+ setContent(value);
642
+ validateContent(value);
643
+ }}
644
+ placeholder={`Write your content here (${minLength}-${maxLength} characters)...`}
645
+ rows={6}
646
+ invalid={!!error}
647
+ />
648
+ </FormField>
649
+
650
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '8px' }}>
651
+ <Text
652
+ size="small"
653
+ color={error ? 'error' : content.length < minLength ? 'warning' : 'success'}
654
+ >
655
+ {content.length} / {maxLength} characters
656
+ {content.length < minLength && ` (${minLength - content.length} more needed)`}
657
+ </Text>
658
+ </div>
659
+
660
+ <Button
661
+ type="submit"
662
+ disabled={!!error || content.length < minLength}
663
+ style={{ marginTop: '16px' }}
664
+ >
665
+ Submit
666
+ </Button>
667
+ </Form>
668
+ );
669
+ }
670
+ ```