@delightui/components 0.1.105 → 0.1.107

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 (102) 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/index.d.ts +2 -0
  9. package/dist/cjs/library.css +19 -6
  10. package/dist/cjs/library.js +3 -3
  11. package/dist/cjs/library.js.map +1 -1
  12. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  13. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  14. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  15. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  16. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  17. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  18. package/dist/esm/components/molecules/index.d.ts +2 -0
  19. package/dist/esm/library.css +19 -6
  20. package/dist/esm/library.js +3 -3
  21. package/dist/esm/library.js.map +1 -1
  22. package/dist/index.d.ts +108 -2
  23. package/docs/README.md +264 -0
  24. package/docs/components/atoms/ActionImage.md +119 -0
  25. package/docs/components/atoms/Button.md +197 -0
  26. package/docs/components/atoms/Checkbox.md +299 -0
  27. package/docs/components/atoms/CheckboxItem.md +314 -0
  28. package/docs/components/atoms/Chip.md +380 -0
  29. package/docs/components/atoms/CustomToggle.md +270 -0
  30. package/docs/components/atoms/Icon.md +365 -0
  31. package/docs/components/atoms/IconButton.md +407 -0
  32. package/docs/components/atoms/Image.md +448 -0
  33. package/docs/components/atoms/Input.md +430 -0
  34. package/docs/components/atoms/ListItem.md +502 -0
  35. package/docs/components/atoms/Password.md +472 -0
  36. package/docs/components/atoms/RadioButton.md +614 -0
  37. package/docs/components/atoms/RadioButtonItem.md +588 -0
  38. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  39. package/docs/components/atoms/SelectListItem.md +609 -0
  40. package/docs/components/atoms/Slider.md +605 -0
  41. package/docs/components/atoms/Spinner.md +605 -0
  42. package/docs/components/atoms/Text.md +463 -0
  43. package/docs/components/atoms/TextArea.md +670 -0
  44. package/docs/components/atoms/ToastNotification.md +668 -0
  45. package/docs/components/atoms/Toggle.md +737 -0
  46. package/docs/components/atoms/ToggleButton.md +751 -0
  47. package/docs/components/atoms/Tooltip.md +391 -0
  48. package/docs/components/molecules/Accordion.md +440 -0
  49. package/docs/components/molecules/AccordionGroup.md +547 -0
  50. package/docs/components/molecules/ActionCard.md +546 -0
  51. package/docs/components/molecules/Breadcrumb.md +403 -0
  52. package/docs/components/molecules/Breadcrumbs.md +485 -0
  53. package/docs/components/molecules/ButtonGroup.md +383 -0
  54. package/docs/components/molecules/Card.md +298 -0
  55. package/docs/components/molecules/ChipInput.md +646 -0
  56. package/docs/components/molecules/ContextMenu.md +768 -0
  57. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  58. package/docs/components/molecules/DatePicker.md +516 -0
  59. package/docs/components/molecules/DateTimeSelector.md +166 -0
  60. package/docs/components/molecules/FormField.md +312 -0
  61. package/docs/components/molecules/Grid.md +577 -0
  62. package/docs/components/molecules/GridItem.md +834 -0
  63. package/docs/components/molecules/GridList.md +244 -0
  64. package/docs/components/molecules/List.md +485 -0
  65. package/docs/components/molecules/Modal.md +470 -0
  66. package/docs/components/molecules/ModalFooter.md +702 -0
  67. package/docs/components/molecules/ModalHeader.md +756 -0
  68. package/docs/components/molecules/ModalProvider.md +205 -0
  69. package/docs/components/molecules/Nav.md +530 -0
  70. package/docs/components/molecules/NavItem.md +572 -0
  71. package/docs/components/molecules/NavLink.md +499 -0
  72. package/docs/components/molecules/Option.md +521 -0
  73. package/docs/components/molecules/Pagination.md +592 -0
  74. package/docs/components/molecules/PaginationNumberField.md +722 -0
  75. package/docs/components/molecules/Popover.md +516 -0
  76. package/docs/components/molecules/ProgressBar.md +624 -0
  77. package/docs/components/molecules/RadioGroup.md +831 -0
  78. package/docs/components/molecules/RepeaterList.md +185 -0
  79. package/docs/components/molecules/Select.md +402 -0
  80. package/docs/components/molecules/SortableTrigger.md +82 -0
  81. package/docs/components/molecules/useModal.md +379 -0
  82. package/docs/components/organisms/Dropzone.md +346 -0
  83. package/docs/components/organisms/DropzoneClear.md +135 -0
  84. package/docs/components/organisms/DropzoneContent.md +216 -0
  85. package/docs/components/organisms/DropzoneFilename.md +191 -0
  86. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  87. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  88. package/docs/components/organisms/Form.md +533 -0
  89. package/docs/components/organisms/SlideOutPanel.md +662 -0
  90. package/docs/components/organisms/TabContent.md +902 -0
  91. package/docs/components/organisms/TabItem.md +1091 -0
  92. package/docs/components/organisms/Table.md +611 -0
  93. package/docs/components/organisms/TableBody.md +679 -0
  94. package/docs/components/organisms/TableCell.md +482 -0
  95. package/docs/components/organisms/TableHeader.md +513 -0
  96. package/docs/components/organisms/TableHeaderCell.md +661 -0
  97. package/docs/components/organisms/TableRow.md +715 -0
  98. package/docs/components/organisms/Tabs.md +1330 -0
  99. package/docs/components/utils/ConditionalView.md +568 -0
  100. package/docs/components/utils/RenderStateView.md +726 -0
  101. package/docs/components/utils/WrapTextNodes.md +614 -0
  102. package/package.json +3 -2
@@ -0,0 +1,614 @@
1
+ # RadioButton
2
+
3
+ A radio button component that allows users to select one option from a group of mutually exclusive choices. It provides flexible sizing, label positioning, and integrates seamlessly with form handling. RadioButton components are typically used in groups where only one selection is allowed.
4
+
5
+ ## Aliases
6
+
7
+ - RadioButton
8
+ - Radio
9
+ - OptionButton
10
+
11
+ ## Props Breakdown
12
+
13
+ **Extends:** `InputHTMLAttributes<HTMLInputElement>` (excluding `type`, `size`, `value`) + `ControlledFormComponentProps<string | number>`
14
+
15
+ | Prop | Type | Default | Required | Description |
16
+ |------|------|---------|----------|-------------|
17
+ | `children` | `ReactNode` | `undefined` | No | The label content of the radio button |
18
+ | `size` | `'Small' \| 'Medium' \| 'Large'` | `'Medium'` | No | The size of the radio button |
19
+ | `labelAlignment` | `'Left' \| 'Right'` | `'Right'` | No | Position of the label relative to the radio button |
20
+ | `initialValue` | `string \| number` | `undefined` | No | The initial value for the field |
21
+ | `checked` | `boolean` | `undefined` | No | Whether the radio button is checked |
22
+ | `value` | `string \| number` | `undefined` | No | The current value of the form field |
23
+ | `onValueChange` | `(value: string \| number) => void` | `undefined` | No | Callback function that is called when the field value changes |
24
+ | `disabled` | `boolean` | `false` | No | Whether the form field is disabled and cannot be interacted with |
25
+ | `required` | `boolean` | `false` | No | Whether the form field must have a value |
26
+ | `invalid` | `boolean` | `false` | No | Whether the form field's current value is invalid |
27
+ | `id` | `string` | `undefined` | No | Id for the form field |
28
+ | `name` | `string` | `undefined` | No | Name attribute for the radio button |
29
+
30
+ Plus all standard HTML input attributes (onChange, onFocus, onBlur, aria-*, data-*, etc.).
31
+
32
+ ## Examples
33
+
34
+ ### Basic Radio Button
35
+
36
+ ```tsx
37
+ import { RadioButton } from '@delightui/components';
38
+
39
+ function BasicRadioButtonExample() {
40
+ const [selectedOption, setSelectedOption] = useState('');
41
+
42
+ return (
43
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
44
+ <RadioButton
45
+ name="basicExample"
46
+ value="option1"
47
+ checked={selectedOption === 'option1'}
48
+ onValueChange={setSelectedOption}
49
+ >
50
+ Option 1
51
+ </RadioButton>
52
+
53
+ <RadioButton
54
+ name="basicExample"
55
+ value="option2"
56
+ checked={selectedOption === 'option2'}
57
+ onValueChange={setSelectedOption}
58
+ >
59
+ Option 2
60
+ </RadioButton>
61
+
62
+ <RadioButton
63
+ name="basicExample"
64
+ value="option3"
65
+ checked={selectedOption === 'option3'}
66
+ onValueChange={setSelectedOption}
67
+ >
68
+ Option 3
69
+ </RadioButton>
70
+ </div>
71
+ );
72
+ }
73
+ ```
74
+
75
+ ### Different Sizes
76
+
77
+ ```tsx
78
+ import { RadioButton } from '@delightui/components';
79
+
80
+ function SizedRadioButtonExample() {
81
+ const [selectedSize, setSelectedSize] = useState('medium');
82
+
83
+ return (
84
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
85
+ <RadioButton
86
+ name="sizeExample"
87
+ value="small"
88
+ size="Small"
89
+ checked={selectedSize === 'small'}
90
+ onValueChange={setSelectedSize}
91
+ >
92
+ Small Radio Button
93
+ </RadioButton>
94
+
95
+ <RadioButton
96
+ name="sizeExample"
97
+ value="medium"
98
+ size="Medium"
99
+ checked={selectedSize === 'medium'}
100
+ onValueChange={setSelectedSize}
101
+ >
102
+ Medium Radio Button
103
+ </RadioButton>
104
+
105
+ <RadioButton
106
+ name="sizeExample"
107
+ value="large"
108
+ size="Large"
109
+ checked={selectedSize === 'large'}
110
+ onValueChange={setSelectedSize}
111
+ >
112
+ Large Radio Button
113
+ </RadioButton>
114
+ </div>
115
+ );
116
+ }
117
+ ```
118
+
119
+ ### Label Alignment
120
+
121
+ ```tsx
122
+ import { RadioButton } from '@delightui/components';
123
+
124
+ function LabelAlignmentExample() {
125
+ const [selectedAlignment, setSelectedAlignment] = useState('right');
126
+
127
+ return (
128
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
129
+ <RadioButton
130
+ name="alignmentExample"
131
+ value="left"
132
+ labelAlignment="Left"
133
+ checked={selectedAlignment === 'left'}
134
+ onValueChange={setSelectedAlignment}
135
+ >
136
+ Label on Left
137
+ </RadioButton>
138
+
139
+ <RadioButton
140
+ name="alignmentExample"
141
+ value="right"
142
+ labelAlignment="Right"
143
+ checked={selectedAlignment === 'right'}
144
+ onValueChange={setSelectedAlignment}
145
+ >
146
+ Label on Right
147
+ </RadioButton>
148
+ </div>
149
+ );
150
+ }
151
+ ```
152
+
153
+ ### Form Integration
154
+
155
+ ```tsx
156
+ import { Form, FormField, RadioButton, Button } from '@delightui/components';
157
+
158
+ function RadioButtonFormExample() {
159
+ const handleSubmit = (data: any) => {
160
+ console.log('Form submitted:', data);
161
+ };
162
+
163
+ return (
164
+ <Form onSubmit={handleSubmit}>
165
+ <FormField
166
+ name="paymentMethod"
167
+ label="Payment Method"
168
+ required
169
+ >
170
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
171
+ <RadioButton name="paymentMethod" value="credit-card">
172
+ Credit Card
173
+ </RadioButton>
174
+ <RadioButton name="paymentMethod" value="paypal">
175
+ PayPal
176
+ </RadioButton>
177
+ <RadioButton name="paymentMethod" value="bank-transfer">
178
+ Bank Transfer
179
+ </RadioButton>
180
+ </div>
181
+ </FormField>
182
+
183
+ <FormField
184
+ name="deliverySpeed"
185
+ label="Delivery Speed"
186
+ required
187
+ >
188
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
189
+ <RadioButton name="deliverySpeed" value="standard">
190
+ Standard Delivery (5-7 days)
191
+ </RadioButton>
192
+ <RadioButton name="deliverySpeed" value="express">
193
+ Express Delivery (2-3 days)
194
+ </RadioButton>
195
+ <RadioButton name="deliverySpeed" value="overnight">
196
+ Overnight Delivery
197
+ </RadioButton>
198
+ </div>
199
+ </FormField>
200
+
201
+ <Button type="submit">
202
+ Complete Order
203
+ </Button>
204
+ </Form>
205
+ );
206
+ }
207
+ ```
208
+
209
+ ### Survey Example
210
+
211
+ ```tsx
212
+ import { Form, FormField, RadioButton, Button, Text } from '@delightui/components';
213
+
214
+ function SurveyExample() {
215
+ const handleSubmit = (data: any) => {
216
+ console.log('Survey submitted:', data);
217
+ };
218
+
219
+ return (
220
+ <Form onSubmit={handleSubmit}>
221
+ <FormField
222
+ name="satisfaction"
223
+ label="How satisfied are you with our service?"
224
+ required
225
+ >
226
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
227
+ <RadioButton name="satisfaction" value="very-satisfied">
228
+ Very Satisfied
229
+ </RadioButton>
230
+ <RadioButton name="satisfaction" value="satisfied">
231
+ Satisfied
232
+ </RadioButton>
233
+ <RadioButton name="satisfaction" value="neutral">
234
+ Neutral
235
+ </RadioButton>
236
+ <RadioButton name="satisfaction" value="dissatisfied">
237
+ Dissatisfied
238
+ </RadioButton>
239
+ <RadioButton name="satisfaction" value="very-dissatisfied">
240
+ Very Dissatisfied
241
+ </RadioButton>
242
+ </div>
243
+ </FormField>
244
+
245
+ <FormField
246
+ name="recommendation"
247
+ label="Would you recommend us to others?"
248
+ required
249
+ >
250
+ <div style={{ display: 'flex', gap: '24px' }}>
251
+ <RadioButton name="recommendation" value="yes">
252
+ Yes
253
+ </RadioButton>
254
+ <RadioButton name="recommendation" value="no">
255
+ No
256
+ </RadioButton>
257
+ <RadioButton name="recommendation" value="maybe">
258
+ Maybe
259
+ </RadioButton>
260
+ </div>
261
+ </FormField>
262
+
263
+ <Button type="submit">
264
+ Submit Survey
265
+ </Button>
266
+ </Form>
267
+ );
268
+ }
269
+ ```
270
+
271
+ ### Disabled States
272
+
273
+ ```tsx
274
+ import { RadioButton } from '@delightui/components';
275
+
276
+ function DisabledRadioButtonExample() {
277
+ return (
278
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
279
+ <RadioButton
280
+ name="disabledExample"
281
+ value="enabled"
282
+ checked={true}
283
+ >
284
+ Enabled and Selected
285
+ </RadioButton>
286
+
287
+ <RadioButton
288
+ name="disabledExample"
289
+ value="disabled-unchecked"
290
+ disabled
291
+ >
292
+ Disabled and Unchecked
293
+ </RadioButton>
294
+
295
+ <RadioButton
296
+ name="disabledExample"
297
+ value="disabled-checked"
298
+ disabled
299
+ checked={true}
300
+ >
301
+ Disabled and Checked
302
+ </RadioButton>
303
+ </div>
304
+ );
305
+ }
306
+ ```
307
+
308
+ ### Settings Configuration
309
+
310
+ ```tsx
311
+ import { Form, FormField, RadioButton, Button, Text } from '@delightui/components';
312
+
313
+ function SettingsConfigExample() {
314
+ const handleSubmit = (data: any) => {
315
+ console.log('Settings saved:', data);
316
+ };
317
+
318
+ return (
319
+ <Form onSubmit={handleSubmit}>
320
+ <FormField
321
+ name="theme"
322
+ label="Theme Preference"
323
+ >
324
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
325
+ <RadioButton name="theme" value="light">
326
+ Light Theme
327
+ </RadioButton>
328
+ <RadioButton name="theme" value="dark">
329
+ Dark Theme
330
+ </RadioButton>
331
+ <RadioButton name="theme" value="auto">
332
+ Auto (System Default)
333
+ </RadioButton>
334
+ </div>
335
+ </FormField>
336
+
337
+ <FormField
338
+ name="language"
339
+ label="Language"
340
+ >
341
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
342
+ <RadioButton name="language" value="en">
343
+ English
344
+ </RadioButton>
345
+ <RadioButton name="language" value="es">
346
+ Spanish
347
+ </RadioButton>
348
+ <RadioButton name="language" value="fr">
349
+ French
350
+ </RadioButton>
351
+ <RadioButton name="language" value="de">
352
+ German
353
+ </RadioButton>
354
+ </div>
355
+ </FormField>
356
+
357
+ <FormField
358
+ name="notifications"
359
+ label="Notification Frequency"
360
+ >
361
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
362
+ <RadioButton name="notifications" value="immediate">
363
+ Immediate
364
+ </RadioButton>
365
+ <RadioButton name="notifications" value="daily">
366
+ Daily Summary
367
+ </RadioButton>
368
+ <RadioButton name="notifications" value="weekly">
369
+ Weekly Summary
370
+ </RadioButton>
371
+ <RadioButton name="notifications" value="never">
372
+ Never
373
+ </RadioButton>
374
+ </div>
375
+ </FormField>
376
+
377
+ <Button type="submit">
378
+ Save Settings
379
+ </Button>
380
+ </Form>
381
+ );
382
+ }
383
+ ```
384
+
385
+ ### Quiz Application
386
+
387
+ ```tsx
388
+ import { Form, FormField, RadioButton, Button, Text } from '@delightui/components';
389
+
390
+ function QuizExample() {
391
+ const [currentQuestion, setCurrentQuestion] = useState(0);
392
+ const [answers, setAnswers] = useState<Record<string, string>>({});
393
+
394
+ const questions = [
395
+ {
396
+ id: 'q1',
397
+ question: 'What is the capital of France?',
398
+ options: [
399
+ { value: 'london', label: 'London' },
400
+ { value: 'berlin', label: 'Berlin' },
401
+ { value: 'paris', label: 'Paris' },
402
+ { value: 'madrid', label: 'Madrid' }
403
+ ]
404
+ },
405
+ {
406
+ id: 'q2',
407
+ question: 'Which planet is closest to the Sun?',
408
+ options: [
409
+ { value: 'venus', label: 'Venus' },
410
+ { value: 'mercury', label: 'Mercury' },
411
+ { value: 'earth', label: 'Earth' },
412
+ { value: 'mars', label: 'Mars' }
413
+ ]
414
+ }
415
+ ];
416
+
417
+ const handleNext = () => {
418
+ if (currentQuestion < questions.length - 1) {
419
+ setCurrentQuestion(currentQuestion + 1);
420
+ }
421
+ };
422
+
423
+ const handleSubmit = () => {
424
+ console.log('Quiz answers:', answers);
425
+ };
426
+
427
+ const question = questions[currentQuestion];
428
+
429
+ return (
430
+ <div style={{ maxWidth: '500px', margin: '0 auto' }}>
431
+ <Text weight="bold" size="large" style={{ marginBottom: '16px' }}>
432
+ Question {currentQuestion + 1} of {questions.length}
433
+ </Text>
434
+
435
+ <Text style={{ marginBottom: '20px' }}>
436
+ {question.question}
437
+ </Text>
438
+
439
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginBottom: '24px' }}>
440
+ {question.options.map((option) => (
441
+ <RadioButton
442
+ key={option.value}
443
+ name={question.id}
444
+ value={option.value}
445
+ checked={answers[question.id] === option.value}
446
+ onValueChange={(value) => setAnswers(prev => ({ ...prev, [question.id]: value as string }))}
447
+ >
448
+ {option.label}
449
+ </RadioButton>
450
+ ))}
451
+ </div>
452
+
453
+ <div style={{ display: 'flex', gap: '12px' }}>
454
+ {currentQuestion < questions.length - 1 ? (
455
+ <Button
456
+ onClick={handleNext}
457
+ disabled={!answers[question.id]}
458
+ >
459
+ Next Question
460
+ </Button>
461
+ ) : (
462
+ <Button
463
+ onClick={handleSubmit}
464
+ disabled={!answers[question.id]}
465
+ >
466
+ Submit Quiz
467
+ </Button>
468
+ )}
469
+ </div>
470
+ </div>
471
+ );
472
+ }
473
+ ```
474
+
475
+ ### Grouped Radio Buttons with Descriptions
476
+
477
+ ```tsx
478
+ import { RadioButton, Text } from '@delightui/components';
479
+
480
+ function GroupedRadioWithDescriptionExample() {
481
+ const [selectedPlan, setSelectedPlan] = useState('');
482
+
483
+ const plans = [
484
+ {
485
+ value: 'basic',
486
+ title: 'Basic Plan',
487
+ description: 'Perfect for individuals getting started',
488
+ price: '$9/month'
489
+ },
490
+ {
491
+ value: 'pro',
492
+ title: 'Pro Plan',
493
+ description: 'Best for growing businesses',
494
+ price: '$29/month'
495
+ },
496
+ {
497
+ value: 'enterprise',
498
+ title: 'Enterprise Plan',
499
+ description: 'Advanced features for large organizations',
500
+ price: '$99/month'
501
+ }
502
+ ];
503
+
504
+ return (
505
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
506
+ {plans.map((plan) => (
507
+ <div
508
+ key={plan.value}
509
+ style={{
510
+ border: selectedPlan === plan.value ? '2px solid #007bff' : '1px solid #ccc',
511
+ borderRadius: '8px',
512
+ padding: '16px',
513
+ cursor: 'pointer'
514
+ }}
515
+ onClick={() => setSelectedPlan(plan.value)}
516
+ >
517
+ <RadioButton
518
+ name="subscriptionPlan"
519
+ value={plan.value}
520
+ checked={selectedPlan === plan.value}
521
+ onValueChange={setSelectedPlan}
522
+ labelAlignment="Right"
523
+ >
524
+ <div style={{ marginLeft: '8px' }}>
525
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
526
+ <Text weight="bold">{plan.title}</Text>
527
+ <Text weight="bold" color="primary">{plan.price}</Text>
528
+ </div>
529
+ <Text size="small" color="secondary">
530
+ {plan.description}
531
+ </Text>
532
+ </div>
533
+ </RadioButton>
534
+ </div>
535
+ ))}
536
+ </div>
537
+ );
538
+ }
539
+ ```
540
+
541
+ ### Invalid State Example
542
+
543
+ ```tsx
544
+ import { Form, FormField, RadioButton, Button, Text } from '@delightui/components';
545
+
546
+ function InvalidRadioButtonExample() {
547
+ const [hasError, setHasError] = useState(false);
548
+ const [selectedValue, setSelectedValue] = useState('');
549
+
550
+ const handleSubmit = (data: any) => {
551
+ if (!data.priority) {
552
+ setHasError(true);
553
+ return;
554
+ }
555
+ setHasError(false);
556
+ console.log('Form submitted:', data);
557
+ };
558
+
559
+ return (
560
+ <Form onSubmit={handleSubmit}>
561
+ <FormField
562
+ name="priority"
563
+ label="Task Priority"
564
+ required
565
+ invalid={hasError}
566
+ message={hasError ? "Please select a priority level" : undefined}
567
+ >
568
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
569
+ <RadioButton
570
+ name="priority"
571
+ value="low"
572
+ invalid={hasError}
573
+ checked={selectedValue === 'low'}
574
+ onValueChange={(value) => {
575
+ setSelectedValue(value as string);
576
+ if (hasError) setHasError(false);
577
+ }}
578
+ >
579
+ Low Priority
580
+ </RadioButton>
581
+ <RadioButton
582
+ name="priority"
583
+ value="medium"
584
+ invalid={hasError}
585
+ checked={selectedValue === 'medium'}
586
+ onValueChange={(value) => {
587
+ setSelectedValue(value as string);
588
+ if (hasError) setHasError(false);
589
+ }}
590
+ >
591
+ Medium Priority
592
+ </RadioButton>
593
+ <RadioButton
594
+ name="priority"
595
+ value="high"
596
+ invalid={hasError}
597
+ checked={selectedValue === 'high'}
598
+ onValueChange={(value) => {
599
+ setSelectedValue(value as string);
600
+ if (hasError) setHasError(false);
601
+ }}
602
+ >
603
+ High Priority
604
+ </RadioButton>
605
+ </div>
606
+ </FormField>
607
+
608
+ <Button type="submit">
609
+ Create Task
610
+ </Button>
611
+ </Form>
612
+ );
613
+ }
614
+ ```