@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,831 @@
1
+ # RadioGroup
2
+
3
+ ## Description
4
+
5
+ A group container component for radio button options that manages selection state and provides coordinated behavior between radio button children. Supports both horizontal and vertical layouts, form integration, controlled and uncontrolled modes, and accessibility features for creating option selectors, preference settings, and choice-based inputs.
6
+
7
+ ## Aliases
8
+
9
+ - RadioGroup
10
+ - RadioButtonGroup
11
+ - OptionGroup
12
+ - ChoiceGroup
13
+ - SelectionGroup
14
+ - RadioSet
15
+
16
+ ## Props Breakdown
17
+
18
+ **Extends:** ControlledFormComponentProps<string | number>
19
+
20
+ | Prop | Type | Default | Required | Description |
21
+ |------|------|---------|----------|-------------|
22
+ | `children` | `ReactElement<RadioButtonProps> \| ReactElement<RadioButtonProps>[]` | - | Yes | The radio buttons to render in the group |
23
+ | `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | No | Layout orientation of the radio group |
24
+ | `value` | `string \| number` | - | No | Current selected value (controlled mode) |
25
+ | `onValueChange` | `(value: string \| number) => void` | - | No | Callback when selection changes |
26
+ | `disabled` | `boolean` | `false` | No | Whether the entire group is disabled |
27
+ | `required` | `boolean` | `false` | No | Whether a selection is required |
28
+ | `invalid` | `boolean` | `false` | No | Whether the current selection is invalid |
29
+ | `className` | `string` | - | No | Additional CSS class names |
30
+
31
+ ## Examples
32
+
33
+ ### Basic Usage
34
+ ```tsx
35
+ import { RadioGroup, RadioButton } from '@delightui/components';
36
+
37
+ function BasicExample() {
38
+ const [selectedSize, setSelectedSize] = useState('medium');
39
+
40
+ return (
41
+ <div className="size-selector">
42
+ <Text type="Heading6">Select Size</Text>
43
+
44
+ <RadioGroup
45
+ value={selectedSize}
46
+ onValueChange={setSelectedSize}
47
+ >
48
+ <RadioButton value="small" label="Small" />
49
+ <RadioButton value="medium" label="Medium" />
50
+ <RadioButton value="large" label="Large" />
51
+ <RadioButton value="xlarge" label="Extra Large" />
52
+ </RadioGroup>
53
+
54
+ <Text type="BodySmall">
55
+ Selected: {selectedSize}
56
+ </Text>
57
+ </div>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ### Horizontal Layout
63
+ ```tsx
64
+ function HorizontalLayoutExample() {
65
+ const [paymentMethod, setPaymentMethod] = useState('credit');
66
+
67
+ return (
68
+ <div className="payment-options">
69
+ <Text type="Heading6">Payment Method</Text>
70
+
71
+ <RadioGroup
72
+ value={paymentMethod}
73
+ onValueChange={setPaymentMethod}
74
+ orientation="horizontal"
75
+ className="payment-radio-group"
76
+ >
77
+ <RadioButton
78
+ value="credit"
79
+ label="Credit Card"
80
+ />
81
+ <RadioButton
82
+ value="debit"
83
+ label="Debit Card"
84
+ />
85
+ <RadioButton
86
+ value="paypal"
87
+ label="PayPal"
88
+ />
89
+ <RadioButton
90
+ value="bank"
91
+ label="Bank Transfer"
92
+ />
93
+ </RadioGroup>
94
+
95
+ <div className="payment-info">
96
+ <Text type="BodySmall">
97
+ You selected: {paymentMethod.replace(/^\w/, c => c.toUpperCase())}
98
+ </Text>
99
+ </div>
100
+ </div>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ### Form Integration
106
+ ```tsx
107
+ function FormIntegrationExample() {
108
+ const handleSubmit = (values, setError) => {
109
+ if (!values.priority) {
110
+ setError('priority', 'Please select a priority level');
111
+ return;
112
+ }
113
+
114
+ console.log('Form submitted:', values);
115
+ };
116
+
117
+ return (
118
+ <Form onSubmit={handleSubmit}>
119
+ <FormField
120
+ name="title"
121
+ label="Issue Title"
122
+ required
123
+ >
124
+ <Input placeholder="Describe the issue" />
125
+ </FormField>
126
+
127
+ <FormField
128
+ name="priority"
129
+ label="Priority Level"
130
+ required
131
+ >
132
+ <RadioGroup>
133
+ <RadioButton
134
+ value="low"
135
+ label="Low Priority"
136
+ description="Minor issues, can wait"
137
+ />
138
+ <RadioButton
139
+ value="medium"
140
+ label="Medium Priority"
141
+ description="Important but not urgent"
142
+ />
143
+ <RadioButton
144
+ value="high"
145
+ label="High Priority"
146
+ description="Needs immediate attention"
147
+ />
148
+ <RadioButton
149
+ value="critical"
150
+ label="Critical"
151
+ description="System down or major issue"
152
+ />
153
+ </RadioGroup>
154
+ </FormField>
155
+
156
+ <FormField name="description" label="Description">
157
+ <TextArea
158
+ placeholder="Additional details..."
159
+ rows={3}
160
+ />
161
+ </FormField>
162
+
163
+ <Button actionType="submit">
164
+ Submit Issue
165
+ </Button>
166
+ </Form>
167
+ );
168
+ }
169
+ ```
170
+
171
+ ### Product Selection
172
+ ```tsx
173
+ function ProductSelectionExample() {
174
+ const [selectedPlan, setSelectedPlan] = useState('');
175
+
176
+ const plans = [
177
+ {
178
+ id: 'basic',
179
+ name: 'Basic Plan',
180
+ price: '$9.99/month',
181
+ features: ['5 Projects', '10GB Storage', 'Email Support'],
182
+ recommended: false
183
+ },
184
+ {
185
+ id: 'pro',
186
+ name: 'Pro Plan',
187
+ price: '$19.99/month',
188
+ features: ['Unlimited Projects', '100GB Storage', 'Priority Support', 'Advanced Analytics'],
189
+ recommended: true
190
+ },
191
+ {
192
+ id: 'enterprise',
193
+ name: 'Enterprise Plan',
194
+ price: '$49.99/month',
195
+ features: ['Everything in Pro', 'Custom Integrations', 'Dedicated Manager', 'SLA Guarantee'],
196
+ recommended: false
197
+ }
198
+ ];
199
+
200
+ return (
201
+ <div className="plan-selector">
202
+ <Text type="Heading5">Choose Your Plan</Text>
203
+
204
+ <RadioGroup
205
+ value={selectedPlan}
206
+ onValueChange={setSelectedPlan}
207
+ className="plan-radio-group"
208
+ >
209
+ <List
210
+ data={plans}
211
+ component={({ id, name, price, features, recommended }) => {
212
+ const FeatureComponent = ({ feature }) => (
213
+ <div className="feature-item">
214
+ <Icon icon="Check" className="feature-icon" />
215
+ <Text type="BodySmall">{feature}</Text>
216
+ </div>
217
+ );
218
+
219
+ return (
220
+ <div className="plan-option">
221
+ <div className="plan-header">
222
+ <RadioButton
223
+ value={id}
224
+ label={
225
+ <div className="plan-title">
226
+ <Text type="Heading6">{name}</Text>
227
+ {recommended && (
228
+ <Chip size="Small" style="Primary">
229
+ Recommended
230
+ </Chip>
231
+ )}
232
+ </div>
233
+ }
234
+ />
235
+ <Text type="Heading6" className="plan-price">
236
+ {price}
237
+ </Text>
238
+ </div>
239
+
240
+ <div className="plan-features">
241
+ <List
242
+ data={features.map(feature => ({ feature }))}
243
+ component={FeatureComponent}
244
+ keyExtractor={(item) => item.feature}
245
+ />
246
+ </div>
247
+ </div>
248
+ );
249
+ }}
250
+ keyExtractor={(plan) => plan.id}
251
+ />
252
+ </RadioGroup>
253
+
254
+ <div className="plan-actions">
255
+ <Button
256
+ disabled={!selectedPlan}
257
+ onClick={() => console.log('Selected plan:', selectedPlan)}
258
+ >
259
+ Continue with {plans.find(p => p.id === selectedPlan)?.name || 'Selected Plan'}
260
+ </Button>
261
+ </div>
262
+ </div>
263
+ );
264
+ }
265
+ ```
266
+
267
+ ### Settings Configuration
268
+ ```tsx
269
+ function SettingsConfigExample() {
270
+ const [settings, setSettings] = useState({
271
+ theme: 'light',
272
+ notifications: 'email',
273
+ privacy: 'friends',
274
+ language: 'en'
275
+ });
276
+
277
+ const updateSetting = (key, value) => {
278
+ setSettings(prev => ({ ...prev, [key]: value }));
279
+ };
280
+
281
+ return (
282
+ <div className="settings-panel">
283
+ <Text type="Heading5">Preferences</Text>
284
+
285
+ <div className="settings-section">
286
+ <Text type="Heading6">Theme</Text>
287
+ <RadioGroup
288
+ value={settings.theme}
289
+ onValueChange={(value) => updateSetting('theme', value)}
290
+ orientation="horizontal"
291
+ >
292
+ <RadioButton
293
+ value="light"
294
+ label="Light"
295
+ />
296
+ <RadioButton
297
+ value="dark"
298
+ label="Dark"
299
+ />
300
+ <RadioButton
301
+ value="auto"
302
+ label="Auto"
303
+ />
304
+ </RadioGroup>
305
+ </div>
306
+
307
+ <div className="settings-section">
308
+ <Text type="Heading6">Notifications</Text>
309
+ <RadioGroup
310
+ value={settings.notifications}
311
+ onValueChange={(value) => updateSetting('notifications', value)}
312
+ >
313
+ <RadioButton
314
+ value="all"
315
+ label="All Notifications"
316
+ description="Receive all notifications via email and push"
317
+ />
318
+ <RadioButton
319
+ value="email"
320
+ label="Email Only"
321
+ description="Only receive email notifications"
322
+ />
323
+ <RadioButton
324
+ value="push"
325
+ label="Push Only"
326
+ description="Only receive push notifications"
327
+ />
328
+ <RadioButton
329
+ value="none"
330
+ label="None"
331
+ description="Disable all notifications"
332
+ />
333
+ </RadioGroup>
334
+ </div>
335
+
336
+ <div className="settings-section">
337
+ <Text type="Heading6">Privacy</Text>
338
+ <RadioGroup
339
+ value={settings.privacy}
340
+ onValueChange={(value) => updateSetting('privacy', value)}
341
+ >
342
+ <RadioButton
343
+ value="public"
344
+ label="Public"
345
+ description="Anyone can see your profile"
346
+ />
347
+ <RadioButton
348
+ value="friends"
349
+ label="Friends Only"
350
+ description="Only friends can see your profile"
351
+ />
352
+ <RadioButton
353
+ value="private"
354
+ label="Private"
355
+ description="Only you can see your profile"
356
+ />
357
+ </RadioGroup>
358
+ </div>
359
+
360
+ <div className="settings-actions">
361
+ <Button type="Outlined">
362
+ Reset to Defaults
363
+ </Button>
364
+ <Button>
365
+ Save Settings
366
+ </Button>
367
+ </div>
368
+ </div>
369
+ );
370
+ }
371
+ ```
372
+
373
+ ### Survey Question
374
+ ```tsx
375
+ function SurveyQuestionExample() {
376
+ const [answers, setAnswers] = useState({});
377
+ const [currentQuestion, setCurrentQuestion] = useState(0);
378
+
379
+ const questions = [
380
+ {
381
+ id: 'satisfaction',
382
+ question: 'How satisfied are you with our service?',
383
+ options: [
384
+ { value: 'very-satisfied', label: 'Very Satisfied', emoji: '😍' },
385
+ { value: 'satisfied', label: 'Satisfied', emoji: '😊' },
386
+ { value: 'neutral', label: 'Neutral', emoji: '😐' },
387
+ { value: 'dissatisfied', label: 'Dissatisfied', emoji: '😞' },
388
+ { value: 'very-dissatisfied', label: 'Very Dissatisfied', emoji: '😤' }
389
+ ]
390
+ },
391
+ {
392
+ id: 'recommend',
393
+ question: 'How likely are you to recommend us to others?',
394
+ options: [
395
+ { value: '10', label: 'Extremely Likely (10)' },
396
+ { value: '9', label: 'Very Likely (9)' },
397
+ { value: '8', label: 'Likely (8)' },
398
+ { value: '7', label: 'Somewhat Likely (7)' },
399
+ { value: '6', label: 'Neutral (6)' },
400
+ { value: '5', label: 'Somewhat Unlikely (5)' },
401
+ { value: '4', label: 'Unlikely (4)' },
402
+ { value: '3', label: 'Very Unlikely (3)' },
403
+ { value: '2', label: 'Extremely Unlikely (2)' },
404
+ { value: '1', label: 'Not at All Likely (1)' }
405
+ ]
406
+ }
407
+ ];
408
+
409
+ const currentQ = questions[currentQuestion];
410
+
411
+ const nextQuestion = () => {
412
+ if (currentQuestion < questions.length - 1) {
413
+ setCurrentQuestion(prev => prev + 1);
414
+ }
415
+ };
416
+
417
+ const prevQuestion = () => {
418
+ if (currentQuestion > 0) {
419
+ setCurrentQuestion(prev => prev - 1);
420
+ }
421
+ };
422
+
423
+ const updateAnswer = (questionId, value) => {
424
+ setAnswers(prev => ({ ...prev, [questionId]: value }));
425
+ };
426
+
427
+ return (
428
+ <div className="survey-form">
429
+ <div className="survey-header">
430
+ <Text type="Heading5">Customer Feedback Survey</Text>
431
+ <Text type="BodySmall">
432
+ Question {currentQuestion + 1} of {questions.length}
433
+ </Text>
434
+ </div>
435
+
436
+ <ProgressBar
437
+ value={((currentQuestion + 1) / questions.length) * 100}
438
+ showLabel="Text"
439
+ label={`${currentQuestion + 1} of ${questions.length} completed`}
440
+ />
441
+
442
+ <div className="survey-question">
443
+ <Text type="Heading6">{currentQ.question}</Text>
444
+
445
+ <RadioGroup
446
+ value={answers[currentQ.id] || ''}
447
+ onValueChange={(value) => updateAnswer(currentQ.id, value)}
448
+ className="survey-options"
449
+ >
450
+ {currentQ.options.map(option => (
451
+ <RadioButton
452
+ key={option.value}
453
+ value={option.value}
454
+ label={
455
+ <div className="survey-option">
456
+ {option.emoji && (
457
+ <span className="option-emoji">{option.emoji}</span>
458
+ )}
459
+ <Text>{option.label}</Text>
460
+ </div>
461
+ }
462
+ />
463
+ ))}
464
+ </RadioGroup>
465
+ </div>
466
+
467
+ <div className="survey-navigation">
468
+ <Button
469
+ type="Outlined"
470
+ onClick={prevQuestion}
471
+ disabled={currentQuestion === 0}
472
+ >
473
+ Previous
474
+ </Button>
475
+
476
+ <div className="survey-progress">
477
+ {questions.map((_, index) => (
478
+ <div
479
+ key={index}
480
+ className={`progress-dot ${
481
+ index === currentQuestion ? 'current' :
482
+ answers[questions[index].id] ? 'completed' : 'pending'
483
+ }`}
484
+ />
485
+ ))}
486
+ </div>
487
+
488
+ <Button
489
+ onClick={nextQuestion}
490
+ disabled={!answers[currentQ.id] || currentQuestion === questions.length - 1}
491
+ >
492
+ {currentQuestion === questions.length - 1 ? 'Submit' : 'Next'}
493
+ </Button>
494
+ </div>
495
+ </div>
496
+ );
497
+ }
498
+ ```
499
+
500
+ ### Shipping Options
501
+ ```tsx
502
+ function ShippingOptionsExample() {
503
+ const [selectedShipping, setSelectedShipping] = useState('');
504
+
505
+ const shippingOptions = [
506
+ {
507
+ id: 'standard',
508
+ name: 'Standard Shipping',
509
+ price: 'Free',
510
+ duration: '5-7 business days',
511
+ description: 'Free standard delivery'
512
+ },
513
+ {
514
+ id: 'express',
515
+ name: 'Express Shipping',
516
+ price: '$9.99',
517
+ duration: '2-3 business days',
518
+ description: 'Faster delivery for urgent orders'
519
+ },
520
+ {
521
+ id: 'overnight',
522
+ name: 'Overnight Delivery',
523
+ price: '$24.99',
524
+ duration: '1 business day',
525
+ description: 'Next business day delivery'
526
+ },
527
+ {
528
+ id: 'weekend',
529
+ name: 'Weekend Delivery',
530
+ price: '$19.99',
531
+ duration: 'Saturday delivery',
532
+ description: 'Delivered on Saturday'
533
+ }
534
+ ];
535
+
536
+ const selectedOption = shippingOptions.find(opt => opt.id === selectedShipping);
537
+
538
+ return (
539
+ <div className="shipping-selector">
540
+ <Text type="Heading6">Choose Shipping Method</Text>
541
+
542
+ <RadioGroup
543
+ value={selectedShipping}
544
+ onValueChange={setSelectedShipping}
545
+ required
546
+ className="shipping-options"
547
+ >
548
+ {shippingOptions.map(option => (
549
+ <div key={option.id} className="shipping-option">
550
+ <RadioButton
551
+ value={option.id}
552
+ label={
553
+ <div className="shipping-details">
554
+ <div className="shipping-header">
555
+ <Text type="BodyMedium">{option.name}</Text>
556
+ <Text type="BodyMedium" className="shipping-price">
557
+ {option.price}
558
+ </Text>
559
+ </div>
560
+
561
+ <div className="shipping-info">
562
+ <Text type="BodySmall" className="delivery-time">
563
+ <Icon icon="Clock" size="Small" />
564
+ {option.duration}
565
+ </Text>
566
+ <Text type="BodySmall" className="shipping-desc">
567
+ {option.description}
568
+ </Text>
569
+ </div>
570
+ </div>
571
+ }
572
+ />
573
+ </div>
574
+ ))}
575
+ </RadioGroup>
576
+
577
+ {selectedOption && (
578
+ <div className="shipping-summary">
579
+ <Text type="BodySmall">
580
+ Selected: {selectedOption.name} - {selectedOption.price}
581
+ </Text>
582
+ <Text type="BodySmall">
583
+ Estimated delivery: {selectedOption.duration}
584
+ </Text>
585
+ </div>
586
+ )}
587
+ </div>
588
+ );
589
+ }
590
+ ```
591
+
592
+ ### Quiz Question
593
+ ```tsx
594
+ function QuizQuestionExample() {
595
+ const [selectedAnswer, setSelectedAnswer] = useState('');
596
+ const [showResult, setShowResult] = useState(false);
597
+
598
+ const question = {
599
+ question: 'What is the capital of France?',
600
+ options: [
601
+ { id: 'a', text: 'London', correct: false },
602
+ { id: 'b', text: 'Berlin', correct: false },
603
+ { id: 'c', text: 'Paris', correct: true },
604
+ { id: 'd', text: 'Madrid', correct: false }
605
+ ]
606
+ };
607
+
608
+ const submitAnswer = () => {
609
+ setShowResult(true);
610
+ };
611
+
612
+ const resetQuestion = () => {
613
+ setSelectedAnswer('');
614
+ setShowResult(false);
615
+ };
616
+
617
+ const correctAnswer = question.options.find(opt => opt.correct);
618
+ const selectedOption = question.options.find(opt => opt.id === selectedAnswer);
619
+ const isCorrect = selectedOption?.correct || false;
620
+
621
+ return (
622
+ <div className="quiz-question">
623
+ <Text type="Heading6">Quiz Question</Text>
624
+
625
+ <div className="question-text">
626
+ <Text type="BodyMedium">{question.question}</Text>
627
+ </div>
628
+
629
+ <RadioGroup
630
+ value={selectedAnswer}
631
+ onValueChange={setSelectedAnswer}
632
+ disabled={showResult}
633
+ className="quiz-options"
634
+ >
635
+ {question.options.map(option => (
636
+ <div
637
+ key={option.id}
638
+ className={`quiz-option ${
639
+ showResult ? (
640
+ option.correct ? 'correct' :
641
+ option.id === selectedAnswer && !option.correct ? 'incorrect' :
642
+ 'neutral'
643
+ ) : ''
644
+ }`}
645
+ >
646
+ <RadioButton
647
+ value={option.id}
648
+ label={
649
+ <div className="option-content">
650
+ <Text>{option.id.toUpperCase()}. {option.text}</Text>
651
+ {showResult && option.correct && (
652
+ <Icon icon="CheckCircle" className="correct-icon" />
653
+ )}
654
+ {showResult && option.id === selectedAnswer && !option.correct && (
655
+ <Icon icon="XCircle" className="incorrect-icon" />
656
+ )}
657
+ </div>
658
+ }
659
+ />
660
+ </div>
661
+ ))}
662
+ </RadioGroup>
663
+
664
+ {!showResult ? (
665
+ <Button
666
+ onClick={submitAnswer}
667
+ disabled={!selectedAnswer}
668
+ >
669
+ Submit Answer
670
+ </Button>
671
+ ) : (
672
+ <div className="quiz-result">
673
+ <div className={`result-message ${isCorrect ? 'correct' : 'incorrect'}`}>
674
+ <Icon
675
+ icon={isCorrect ? 'CheckCircle' : 'XCircle'}
676
+ className="result-icon"
677
+ />
678
+ <Text type="BodyMedium">
679
+ {isCorrect ? 'Correct!' : 'Incorrect'}
680
+ </Text>
681
+ </div>
682
+
683
+ {!isCorrect && (
684
+ <Text type="BodySmall">
685
+ The correct answer is: {correctAnswer.text}
686
+ </Text>
687
+ )}
688
+
689
+ <Button type="Outlined" onClick={resetQuestion}>
690
+ Try Again
691
+ </Button>
692
+ </div>
693
+ )}
694
+ </div>
695
+ );
696
+ }
697
+ ```
698
+
699
+ ### Accessibility Enhanced RadioGroup
700
+ ```tsx
701
+ function AccessibilityExample() {
702
+ const [accessibility, setAccessibility] = useState({
703
+ fontSize: 'medium',
704
+ contrast: 'normal',
705
+ motionPreference: 'normal'
706
+ });
707
+
708
+ const updateAccessibility = (key, value) => {
709
+ setAccessibility(prev => ({ ...prev, [key]: value }));
710
+ };
711
+
712
+ return (
713
+ <div className="accessibility-settings">
714
+ <Text type="Heading5">Accessibility Preferences</Text>
715
+
716
+ <div className="accessibility-section">
717
+ <Text type="Heading6">Font Size</Text>
718
+ <Text type="BodySmall">
719
+ Choose a comfortable reading size
720
+ </Text>
721
+
722
+ <RadioGroup
723
+ value={accessibility.fontSize}
724
+ onValueChange={(value) => updateAccessibility('fontSize', value)}
725
+ orientation="horizontal"
726
+ className="font-size-options"
727
+ >
728
+ <RadioButton
729
+ value="small"
730
+ label="Small"
731
+ aria-describedby="font-small-desc"
732
+ />
733
+ <RadioButton
734
+ value="medium"
735
+ label="Medium"
736
+ aria-describedby="font-medium-desc"
737
+ />
738
+ <RadioButton
739
+ value="large"
740
+ label="Large"
741
+ aria-describedby="font-large-desc"
742
+ />
743
+ <RadioButton
744
+ value="xlarge"
745
+ label="Extra Large"
746
+ aria-describedby="font-xlarge-desc"
747
+ />
748
+ </RadioGroup>
749
+ </div>
750
+
751
+ <div className="accessibility-section">
752
+ <Text type="Heading6">Color Contrast</Text>
753
+ <Text type="BodySmall">
754
+ Adjust contrast for better visibility
755
+ </Text>
756
+
757
+ <RadioGroup
758
+ value={accessibility.contrast}
759
+ onValueChange={(value) => updateAccessibility('contrast', value)}
760
+ >
761
+ <RadioButton
762
+ value="normal"
763
+ label="Normal Contrast"
764
+ description="Standard color scheme"
765
+ />
766
+ <RadioButton
767
+ value="high"
768
+ label="High Contrast"
769
+ description="Enhanced contrast for better readability"
770
+ />
771
+ <RadioButton
772
+ value="dark"
773
+ label="Dark Mode"
774
+ description="Dark background with light text"
775
+ />
776
+ </RadioGroup>
777
+ </div>
778
+
779
+ <div className="accessibility-section">
780
+ <Text type="Heading6">Motion Preference</Text>
781
+ <Text type="BodySmall">
782
+ Control animations and transitions
783
+ </Text>
784
+
785
+ <RadioGroup
786
+ value={accessibility.motionPreference}
787
+ onValueChange={(value) => updateAccessibility('motionPreference', value)}
788
+ >
789
+ <RadioButton
790
+ value="normal"
791
+ label="Normal Motion"
792
+ description="Standard animations and transitions"
793
+ />
794
+ <RadioButton
795
+ value="reduced"
796
+ label="Reduced Motion"
797
+ description="Minimal animations for sensitivity"
798
+ />
799
+ <RadioButton
800
+ value="none"
801
+ label="No Motion"
802
+ description="Disable all animations"
803
+ />
804
+ </RadioGroup>
805
+ </div>
806
+
807
+ <div className="preview-section">
808
+ <Text type="Heading6">Preview</Text>
809
+ <div
810
+ className={`preview-area
811
+ font-${accessibility.fontSize}
812
+ contrast-${accessibility.contrast}
813
+ motion-${accessibility.motionPreference}`}
814
+ >
815
+ <Text>This is how your settings will look.</Text>
816
+ <Button size="Small">Sample Button</Button>
817
+ </div>
818
+ </div>
819
+
820
+ <div className="accessibility-actions">
821
+ <Button type="Outlined">
822
+ Reset Defaults
823
+ </Button>
824
+ <Button>
825
+ Apply Settings
826
+ </Button>
827
+ </div>
828
+ </div>
829
+ );
830
+ }
831
+ ```