@ticatec/uniface-element 0.2.0 → 0.2.2

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 (209) hide show
  1. package/README.md +320 -1
  2. package/README_CN.md +392 -0
  3. package/dist/accordion/Accordion.svelte +1 -1
  4. package/dist/action-bar/ActionBar.svelte +7 -1
  5. package/dist/attachment-files/FileRender.svelte +1 -1
  6. package/dist/attachment-files/FileUploadBar.svelte +7 -6
  7. package/dist/attachment-files/FileUploadPanel.svelte +2 -2
  8. package/dist/base-calendar/DateContext.js +5 -4
  9. package/dist/base-calendar/YearPickupPanel.svelte +4 -4
  10. package/dist/card/Card.svelte +1 -1
  11. package/dist/card/Card.svelte.d.ts +1 -1
  12. package/dist/cascade-options-select/CascadeOptionSelect.svelte +2 -3
  13. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +46 -1
  14. package/dist/cascade-options-select/CascadePanel.svelte +1 -1
  15. package/dist/checkbox/CheckBox.svelte +1 -1
  16. package/dist/color-picker/ColorPicker.svelte +9 -9
  17. package/dist/color-picker/ColorPicker.svelte.d.ts +0 -2
  18. package/dist/color-picker/ColorPickerPanel.svelte +11 -15
  19. package/dist/color-picker/ColorPickerPanel.svelte.d.ts +1 -1
  20. package/dist/common/CommonPicker.svelte +2 -2
  21. package/dist/common/CommonPicker.svelte.d.ts +1 -1
  22. package/dist/common/MouseClickHandler.d.ts +1 -1
  23. package/dist/common/Popover.svelte +28 -6
  24. package/dist/common/Popover.svelte.d.ts +9 -3
  25. package/dist/common/uniface-utils.js +6 -4
  26. package/dist/common-editor/CommonEditor.svelte +1 -1
  27. package/dist/common-editor/CommonEditor.svelte.d.ts +1 -1
  28. package/dist/common-editor/NumberInput.svelte +1 -1
  29. package/dist/common-editor/NumberInput.svelte.d.ts +1 -1
  30. package/dist/concise-data-table/ConciseListTable.svelte +7 -2
  31. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +1 -0
  32. package/dist/concise-data-table/DataRow.svelte +1 -1
  33. package/dist/concise-data-table/TableOptions.d.ts +1 -1
  34. package/dist/data-table/DataTable.svelte +1 -1
  35. package/dist/data-table/parts/ActionsPanel.svelte +4 -3
  36. package/dist/data-table/parts/ActionsRow.svelte +3 -3
  37. package/dist/data-table/parts/ContentPanel.svelte +3 -2
  38. package/dist/data-table/parts/FixedColumnsPanel.svelte +0 -1
  39. package/dist/data-table/parts/FixedColumnsPanel.svelte.d.ts +1 -2
  40. package/dist/data-table/parts/FixedHeaderPanel.svelte +2 -2
  41. package/dist/data-table/parts/FixedRow.svelte +2 -1
  42. package/dist/data-table/parts/FixedRow.svelte.d.ts +1 -1
  43. package/dist/data-table/parts/HrefCell.svelte +23 -2
  44. package/dist/data-table/parts/PopupMenu.svelte +25 -2
  45. package/dist/data-table/parts/PopupMenu.svelte.d.ts +8 -1
  46. package/dist/date-picker/DatePicker.svelte +0 -1
  47. package/dist/date-picker/DateTimePicker.svelte +3 -3
  48. package/dist/date-picker/ScrollBar.svelte +4 -7
  49. package/dist/date-range/DateRangeEditor.svelte +1 -1
  50. package/dist/dialog/CommonDialog.svelte +8 -5
  51. package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
  52. package/dist/dialog/Dialog.svelte +37 -12
  53. package/dist/dialog/Dialog.svelte.d.ts +4 -3
  54. package/dist/dialog/DialogBoard.svelte +11 -8
  55. package/dist/dialog/DialogWrapper.svelte +10 -0
  56. package/dist/{common-editor/DateInput.svelte.d.ts → dialog/DialogWrapper.svelte.d.ts} +6 -13
  57. package/dist/dialog/Dialogs.js +1 -1
  58. package/dist/dialog/ModalResult.d.ts +5 -0
  59. package/dist/dialog/ModalResult.js +5 -0
  60. package/dist/drawer/Drawer.svelte +1 -1
  61. package/dist/form-field/FormField.svelte +2 -1
  62. package/dist/form-field/FormField.svelte.d.ts +1 -0
  63. package/dist/form-panel/flex-row-form/FormContainer.svelte +1 -1
  64. package/dist/form-panel/grid-form/EmptyCell.svelte +8 -7
  65. package/dist/form-panel/grid-form/EmptyCell.svelte.d.ts +2 -2
  66. package/dist/form-panel/grid-form/GridField.svelte +1 -1
  67. package/dist/i18nRes/i18nRes.d.ts +2 -0
  68. package/dist/i18nRes/i18nRes.js +44 -0
  69. package/dist/i18nRes/index.d.ts +2 -0
  70. package/dist/i18nRes/index.js +2 -0
  71. package/dist/image-files/ImageFilesField.svelte +1 -1
  72. package/dist/indicator/IndicatorBoard.svelte +1 -1
  73. package/dist/inline-cell-editor/InvalidEditor.svelte +1 -0
  74. package/dist/input-options-select/InputOptionsSelect.svelte +6 -6
  75. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +1 -1
  76. package/dist/layout/flex/FlexBlock.svelte +1 -1
  77. package/dist/lookup-editor/LookupEditor.svelte +1 -1
  78. package/dist/memo-editor/MemoEditor.svelte +2 -2
  79. package/dist/message-box/IMessageBox.d.ts +2 -4
  80. package/dist/message-box/IMessageBox.js +4 -6
  81. package/dist/message-box/MessageBoxBoard.svelte +1 -3
  82. package/dist/options-multi-select/OptionsMultiSelect.svelte +1 -1
  83. package/dist/prompts-text-editor/PromptsTextEditor.svelte +2 -2
  84. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +1 -1
  85. package/dist/property-editor/PropertyEditor.svelte +3 -3
  86. package/dist/text-editor/PasswordEditor.svelte +1 -1
  87. package/dist/transfer/Transfer.svelte +17 -12
  88. package/dist/transfer/Transfer.svelte.d.ts +0 -1
  89. package/dist/unit-number-editor/UnitNumberEditor.svelte +2 -2
  90. package/docs/buttons/cn/ActionBar.md +459 -0
  91. package/docs/buttons/cn/Button.md +228 -0
  92. package/docs/buttons/cn/IconButton.md +294 -0
  93. package/docs/buttons/cn/README.md +600 -0
  94. package/docs/buttons/cn/TextButton.md +163 -0
  95. package/docs/buttons/en/ActionBar.md +459 -0
  96. package/docs/buttons/en/Button.md +228 -0
  97. package/docs/buttons/en/IconButton.md +294 -0
  98. package/docs/buttons/en/README.md +600 -0
  99. package/docs/buttons/en/TextButton.md +163 -0
  100. package/docs/containers/cn/accordion.md +622 -0
  101. package/docs/containers/cn/box.md +445 -0
  102. package/docs/containers/cn/card.md +404 -0
  103. package/docs/containers/cn/page.md +576 -0
  104. package/docs/containers/cn/tabs.md +686 -0
  105. package/docs/containers/en/accordion.md +622 -0
  106. package/docs/containers/en/box.md +445 -0
  107. package/docs/containers/en/card.md +404 -0
  108. package/docs/containers/en/page.md +576 -0
  109. package/docs/containers/en/tabs.md +686 -0
  110. package/docs/data-display/cn/concise-data-table.md +731 -0
  111. package/docs/data-display/cn/listbox.md +786 -0
  112. package/docs/data-display/cn/treeview.md +863 -0
  113. package/docs/data-display/en/concise-data-table.md +732 -0
  114. package/docs/data-display/en/listbox.md +786 -0
  115. package/docs/data-display/en/treeview.md +863 -0
  116. package/docs/data-table/cn/README.md +596 -0
  117. package/docs/data-table/en/README.md +596 -0
  118. package/docs/dialog/cn/README.md +767 -0
  119. package/docs/dialog/en/README.md +767 -0
  120. package/docs/form/cn/README.md +847 -0
  121. package/docs/form/en/README.md +847 -0
  122. package/docs/form-components/cn/README.md +495 -0
  123. package/docs/form-components/cn/attachmentfilesfield.md +757 -0
  124. package/docs/form-components/cn/cascade-options-select.md +374 -0
  125. package/docs/form-components/cn/checkbox.md +58 -0
  126. package/docs/form-components/cn/date-picker.md +138 -0
  127. package/docs/form-components/cn/datetime-picker.md +228 -0
  128. package/docs/form-components/cn/group-checkbox.md +405 -0
  129. package/docs/form-components/cn/group-radiobox.md +525 -0
  130. package/docs/form-components/cn/imagefilesfield.md +651 -0
  131. package/docs/form-components/cn/input-options-select.md +250 -0
  132. package/docs/form-components/cn/lookup-editor.md +406 -0
  133. package/docs/form-components/cn/memoeditor.md +409 -0
  134. package/docs/form-components/cn/number-editor.md +261 -0
  135. package/docs/form-components/cn/options-multi-select.md +177 -0
  136. package/docs/form-components/cn/options-select.md +83 -0
  137. package/docs/form-components/cn/passwordeditor.md +538 -0
  138. package/docs/form-components/cn/prompts-text-editor.md +241 -0
  139. package/docs/form-components/cn/radiobutton.md +84 -0
  140. package/docs/form-components/cn/switch.md +178 -0
  141. package/docs/form-components/cn/text-editor.md +142 -0
  142. package/docs/form-components/cn/time-editor.md +159 -0
  143. package/docs/form-components/cn/unit-number-editor.md +164 -0
  144. package/docs/form-components/en/README.md +463 -0
  145. package/docs/form-components/en/attachmentfilesfield.md +757 -0
  146. package/docs/form-components/en/cascade-options-select.md +358 -0
  147. package/docs/form-components/en/checkbox.md +59 -0
  148. package/docs/form-components/en/date-picker.md +138 -0
  149. package/docs/form-components/en/datetime-picker.md +228 -0
  150. package/docs/form-components/en/group-checkbox.md +395 -0
  151. package/docs/form-components/en/group-radiobox.md +498 -0
  152. package/docs/form-components/en/imagefilesfield.md +651 -0
  153. package/docs/form-components/en/input-options-select.md +239 -0
  154. package/docs/form-components/en/lookup-editor.md +389 -0
  155. package/docs/form-components/en/memoeditor.md +409 -0
  156. package/docs/form-components/en/number-editor.md +249 -0
  157. package/docs/form-components/en/options-multi-select.md +177 -0
  158. package/docs/form-components/en/options-select.md +83 -0
  159. package/docs/form-components/en/passwordeditor.md +538 -0
  160. package/docs/form-components/en/prompts-text-editor.md +241 -0
  161. package/docs/form-components/en/radiobutton.md +84 -0
  162. package/docs/form-components/en/switch.md +180 -0
  163. package/docs/form-components/en/text-editor.md +142 -0
  164. package/docs/form-components/en/time-editor.md +159 -0
  165. package/docs/form-components/en/unit-number-editor.md +164 -0
  166. package/docs/form-layout/cn/criteria-field.md +652 -0
  167. package/docs/form-layout/cn/flex-form.md +454 -0
  168. package/docs/form-layout/cn/flex-row-form.md +542 -0
  169. package/docs/form-layout/cn/form-field.md +923 -0
  170. package/docs/form-layout/cn/grid-form.md +676 -0
  171. package/docs/form-layout/en/criteria-field.md +652 -0
  172. package/docs/form-layout/en/flex-form.md +454 -0
  173. package/docs/form-layout/en/flex-row-form.md +542 -0
  174. package/docs/form-layout/en/form-field.md +923 -0
  175. package/docs/form-layout/en/grid-form.md +676 -0
  176. package/docs/global/cn/README.md +534 -0
  177. package/docs/global/en/README.md +534 -0
  178. package/docs/layout/cn/classiclayout.md +460 -0
  179. package/docs/layout/cn/headerlayout.md +524 -0
  180. package/docs/layout/cn/sidebarlayout.md +263 -0
  181. package/docs/layout/en/classiclayout.md +951 -0
  182. package/docs/layout/en/headerlayout.md +524 -0
  183. package/docs/layout/en/sidebarlayout.md +262 -0
  184. package/docs/misc/cn/README.md +1217 -0
  185. package/docs/misc/en/README.md +1217 -0
  186. package/docs/navigation/cn/breadcrumb.md +291 -0
  187. package/docs/navigation/cn/navigator.md +322 -0
  188. package/docs/navigation/cn/navigatormenu.md +512 -0
  189. package/docs/navigation/cn/progressbar.md +199 -0
  190. package/docs/navigation/cn/progressstepbar.md +299 -0
  191. package/docs/navigation/en/breadcrumb.md +291 -0
  192. package/docs/navigation/en/navigator.md +322 -0
  193. package/docs/navigation/en/navigatormenu.md +512 -0
  194. package/docs/navigation/en/progressbar.md +199 -0
  195. package/docs/navigation/en/progressstepbar.md +299 -0
  196. package/docs/search-filters/cn/daterange.md +1156 -0
  197. package/docs/search-filters/cn/numberrange.md +688 -0
  198. package/docs/search-filters/cn/searchbox.md +1582 -0
  199. package/docs/search-filters/en/daterange.md +1156 -0
  200. package/docs/search-filters/en/numberrange.md +688 -0
  201. package/docs/search-filters/en/searchbox.md +1582 -0
  202. package/package.json +53 -13
  203. package/dist/common-editor/DateInput.svelte +0 -27
  204. package/dist/i18n_resources/index.d.ts +0 -3
  205. package/dist/i18n_resources/index.js +0 -3
  206. /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.d.ts +0 -0
  207. /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.js +0 -0
  208. /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.d.ts +0 -0
  209. /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.js +0 -0
@@ -0,0 +1,498 @@
1
+ # GroupRadioBox Component
2
+
3
+ Radio button group component that organizes multiple radio button options together, used for selecting one value from multiple options. More convenient and semantic than using multiple individual RadioButton components.
4
+
5
+ ## Properties
6
+
7
+ | Property | Type | Default | Description |
8
+ |----------|------|---------|-------------|
9
+ | `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | Appearance variant |
10
+ | `disabled` | `boolean` | `false` | Whether disabled |
11
+ | `readonly` | `boolean` | `false` | Whether read-only |
12
+ | `compact` | `boolean` | `false` | Whether compact mode |
13
+ | `value` | `any` | - | Selected value |
14
+ | `options` | `Array<any>` | - | Options array |
15
+ | `keyField` | `string` | `'code'` | Value field name |
16
+ | `textField` | `string` | `'text'` | Display field name |
17
+ | `displayMode` | `DisplayMode` | `DisplayMode.Edit` | Display mode |
18
+ | `item$style` | `string` | `''` | Style for individual radio button |
19
+ | `disabledOptions` | `Array<string>` | `[]` | Disabled option values |
20
+ | `style` | `string` | `''` | Custom styles |
21
+ | `onChange` | `OnChangeHandler<any>` | - | Value change callback |
22
+
23
+ ## Usage Examples
24
+
25
+ ```svelte
26
+ <script lang="ts">
27
+ import GroupRadioBox from '@ticatec/uniface-element/GroupRadioBox';
28
+
29
+ // Gender options
30
+ const genderOptions = [
31
+ { code: 'male', text: 'Male' },
32
+ { code: 'female', text: 'Female' },
33
+ { code: 'other', text: 'Other' }
34
+ ];
35
+
36
+ // User level options
37
+ const userLevels = [
38
+ { code: 'basic', text: 'Basic User' },
39
+ { code: 'premium', text: 'Premium User' },
40
+ { code: 'vip', text: 'VIP User' },
41
+ { code: 'enterprise', text: 'Enterprise User' }
42
+ ];
43
+
44
+ // Notification frequency options
45
+ const notificationFrequency = [
46
+ { code: 'realtime', text: 'Real-time Notifications' },
47
+ { code: 'daily', text: 'Daily Summary' },
48
+ { code: 'weekly', text: 'Weekly Summary' },
49
+ { code: 'never', text: 'Never Notify' }
50
+ ];
51
+
52
+ let selectedGender = 'male';
53
+ let userLevel = 'basic';
54
+ let notifyFreq = 'daily';
55
+
56
+ const handleGenderChange = (value: string) => {
57
+ selectedGender = value;
58
+ console.log('Selected gender:', value);
59
+ };
60
+
61
+ const handleLevelChange = (value: string) => {
62
+ userLevel = value;
63
+ console.log('User level:', value);
64
+ };
65
+
66
+ const handleNotificationChange = (value: string) => {
67
+ notifyFreq = value;
68
+ console.log('Notification frequency:', value);
69
+ };
70
+ </script>
71
+
72
+ <!-- Gender selection -->
73
+ <div class="form-group">
74
+ <label>Gender:</label>
75
+ <GroupRadioBox
76
+ options={genderOptions}
77
+ keyField="code"
78
+ textField="text"
79
+ bind:value={selectedGender}
80
+ onChange={handleGenderChange}
81
+ />
82
+ </div>
83
+
84
+ <!-- User level selection -->
85
+ <div class="form-group">
86
+ <label>User Level:</label>
87
+ <GroupRadioBox
88
+ options={userLevels}
89
+ keyField="code"
90
+ textField="text"
91
+ bind:value={userLevel}
92
+ onChange={handleLevelChange}
93
+ />
94
+ </div>
95
+
96
+ <!-- Notification frequency selection (compact mode) -->
97
+ <div class="form-group">
98
+ <label>Notification Frequency:</label>
99
+ <GroupRadioBox
100
+ options={notificationFrequency}
101
+ keyField="code"
102
+ textField="text"
103
+ compact={true}
104
+ item$style="margin-right: 16px;"
105
+ bind:value={notifyFreq}
106
+ onChange={handleNotificationChange}
107
+ />
108
+ </div>
109
+
110
+ <!-- Radio group with disabled options -->
111
+ <div class="form-group">
112
+ <label>Subscription Plan:</label>
113
+ <GroupRadioBox
114
+ options={[
115
+ { code: 'free', text: 'Free' },
116
+ { code: 'pro', text: 'Professional' },
117
+ { code: 'enterprise', text: 'Enterprise' },
118
+ { code: 'custom', text: 'Custom' }
119
+ ]}
120
+ keyField="code"
121
+ textField="text"
122
+ disabledOptions={['custom']}
123
+ bind:value={subscriptionPlan}
124
+ />
125
+ </div>
126
+ ```
127
+
128
+ ## Advanced Usage
129
+
130
+ ### Dynamic Options and Conditional Disabling
131
+ ```svelte
132
+ <script lang="ts">
133
+ import { onMount } from 'svelte';
134
+
135
+ const paymentMethods = [
136
+ { code: 'credit_card', text: 'Credit Card', available: true },
137
+ { code: 'paypal', text: 'PayPal', available: true },
138
+ { code: 'apple_pay', text: 'Apple Pay', available: true },
139
+ { code: 'google_pay', text: 'Google Pay', available: true },
140
+ { code: 'bitcoin', text: 'Bitcoin', available: false }
141
+ ];
142
+
143
+ let selectedPayment = 'credit_card';
144
+ let userLocation = 'US'; // User location
145
+
146
+ // Dynamically set available payment methods based on user location
147
+ $: availablePaymentMethods = paymentMethods.filter(method => {
148
+ if (userLocation === 'CN') {
149
+ // Chinese users can use credit card and Alipay
150
+ return ['credit_card', 'alipay'].includes(method.code);
151
+ } else if (userLocation === 'US') {
152
+ // US users can use credit card, PayPal, Apple Pay, Google Pay
153
+ return ['credit_card', 'paypal', 'apple_pay', 'google_pay'].includes(method.code);
154
+ }
155
+ return method.available;
156
+ });
157
+
158
+ // Dynamically set disabled options
159
+ $: disabledOptions = paymentMethods
160
+ .filter(method => !method.available)
161
+ .map(method => method.code);
162
+
163
+ const handlePaymentChange = (value: string) => {
164
+ selectedPayment = value;
165
+ // Show corresponding payment form based on payment method
166
+ showPaymentForm(value);
167
+ };
168
+
169
+ const showPaymentForm = (paymentMethod: string) => {
170
+ console.log(`Show ${paymentMethod} payment form`);
171
+ };
172
+ </script>
173
+
174
+ <div class="form-group">
175
+ <label>User Location:</label>
176
+ <select bind:value={userLocation}>
177
+ <option value="CN">China</option>
178
+ <option value="US">United States</option>
179
+ <option value="OTHER">Other</option>
180
+ </select>
181
+ </div>
182
+
183
+ <div class="form-group">
184
+ <label>Payment Method:</label>
185
+ <GroupRadioBox
186
+ options={availablePaymentMethods}
187
+ keyField="code"
188
+ textField="text"
189
+ {disabledOptions}
190
+ bind:value={selectedPayment}
191
+ onChange={handlePaymentChange}
192
+ />
193
+ </div>
194
+ ```
195
+
196
+ ### Options with Descriptions
197
+ ```svelte
198
+ <script lang="ts">
199
+ const subscriptionPlans = [
200
+ {
201
+ code: 'free',
202
+ text: 'Free',
203
+ description: 'Basic features, suitable for personal use',
204
+ price: '$0/month'
205
+ },
206
+ {
207
+ code: 'pro',
208
+ text: 'Professional',
209
+ description: 'Full features, suitable for small teams',
210
+ price: '$9/month'
211
+ },
212
+ {
213
+ code: 'enterprise',
214
+ text: 'Enterprise',
215
+ description: 'Advanced features, suitable for large teams',
216
+ price: '$29/month'
217
+ }
218
+ ];
219
+
220
+ let selectedPlan = 'free';
221
+
222
+ const handlePlanChange = (value: string) => {
223
+ selectedPlan = value;
224
+ const plan = subscriptionPlans.find(p => p.code === value);
225
+ console.log(`Selected ${plan?.text} plan`);
226
+ };
227
+ </script>
228
+
229
+ <div class="form-group">
230
+ <label>Choose Subscription Plan:</label>
231
+ <div class="plan-options">
232
+ <GroupRadioBox
233
+ options={subscriptionPlans}
234
+ keyField="code"
235
+ textField="text"
236
+ bind:value={selectedPlan}
237
+ onChange={handlePlanChange}
238
+ />
239
+ </div>
240
+
241
+ <!-- Display selected plan details -->
242
+ {#each subscriptionPlans as plan}
243
+ {#if plan.code === selectedPlan}
244
+ <div class="plan-details">
245
+ <h4>{plan.text}</h4>
246
+ <p>{plan.description}</p>
247
+ <div class="price">{plan.price}</div>
248
+ </div>
249
+ {/if}
250
+ {/each}
251
+ </div>
252
+ ```
253
+
254
+ ### Grouped Radio Buttons
255
+ ```svelte
256
+ <script lang="ts">
257
+ const themes = {
258
+ light: [
259
+ { code: 'default_light', text: 'Default Light' },
260
+ { code: 'blue_light', text: 'Blue Light' },
261
+ { code: 'green_light', text: 'Green Light' }
262
+ ],
263
+ dark: [
264
+ { code: 'default_dark', text: 'Default Dark' },
265
+ { code: 'blue_dark', text: 'Blue Dark' },
266
+ { code: 'green_dark', text: 'Green Dark' }
267
+ ]
268
+ };
269
+
270
+ let selectedTheme = 'default_light';
271
+
272
+ const handleThemeChange = (value: string) => {
273
+ selectedTheme = value;
274
+ applyTheme(value);
275
+ };
276
+
277
+ const applyTheme = (themeCode: string) => {
278
+ console.log(`Apply theme: ${themeCode}`);
279
+ // Theme application logic
280
+ };
281
+ </script>
282
+
283
+ <div class="theme-selector">
284
+ <div class="theme-group">
285
+ <h4>Light Themes</h4>
286
+ <GroupRadioBox
287
+ options={themes.light}
288
+ keyField="code"
289
+ textField="text"
290
+ compact={true}
291
+ bind:value={selectedTheme}
292
+ onChange={handleThemeChange}
293
+ />
294
+ </div>
295
+
296
+ <div class="theme-group">
297
+ <h4>Dark Themes</h4>
298
+ <GroupRadioBox
299
+ options={themes.dark}
300
+ keyField="code"
301
+ textField="text"
302
+ compact={true}
303
+ bind:value={selectedTheme}
304
+ onChange={handleThemeChange}
305
+ />
306
+ </div>
307
+ </div>
308
+ ```
309
+
310
+ ### Form Validation
311
+ ```svelte
312
+ <script lang="ts">
313
+ const satisfactionLevels = [
314
+ { code: 'very_unsatisfied', text: 'Very Unsatisfied' },
315
+ { code: 'unsatisfied', text: 'Unsatisfied' },
316
+ { code: 'neutral', text: 'Neutral' },
317
+ { code: 'satisfied', text: 'Satisfied' },
318
+ { code: 'very_satisfied', text: 'Very Satisfied' }
319
+ ];
320
+
321
+ let satisfaction: string | null = null;
322
+ let satisfactionError = '';
323
+
324
+ const validateSatisfaction = (value: string | null) => {
325
+ if (!value) {
326
+ satisfactionError = 'Please select your satisfaction level';
327
+ } else {
328
+ satisfactionError = '';
329
+ }
330
+ };
331
+
332
+ const handleSatisfactionChange = (value: string) => {
333
+ satisfaction = value;
334
+ validateSatisfaction(value);
335
+ };
336
+
337
+ const handleSubmit = () => {
338
+ validateSatisfaction(satisfaction);
339
+ if (!satisfactionError) {
340
+ console.log('Submit satisfaction survey:', satisfaction);
341
+ }
342
+ };
343
+ </script>
344
+
345
+ <div class="form-group">
346
+ <label>How satisfied are you with our service? *</label>
347
+ <GroupRadioBox
348
+ options={satisfactionLevels}
349
+ keyField="code"
350
+ textField="text"
351
+ bind:value={satisfaction}
352
+ onChange={handleSatisfactionChange}
353
+ />
354
+ {#if satisfactionError}
355
+ <div class="error-message">{satisfactionError}</div>
356
+ {/if}
357
+ </div>
358
+
359
+ <button on:click={handleSubmit} disabled={!!satisfactionError}>
360
+ Submit Survey
361
+ </button>
362
+ ```
363
+
364
+ ## Style Customization
365
+
366
+ ```css
367
+ .form-group {
368
+ margin-bottom: 24px;
369
+ }
370
+
371
+ .form-group label {
372
+ display: block;
373
+ margin-bottom: 12px;
374
+ font-weight: 600;
375
+ color: #333;
376
+ }
377
+
378
+ .plan-options {
379
+ margin-bottom: 16px;
380
+ }
381
+
382
+ .plan-details {
383
+ padding: 16px;
384
+ background: #f8f9fa;
385
+ border-radius: 8px;
386
+ border-left: 4px solid #007bff;
387
+ }
388
+
389
+ .plan-details h4 {
390
+ margin: 0 0 8px 0;
391
+ color: #007bff;
392
+ }
393
+
394
+ .plan-details p {
395
+ margin: 0 0 12px 0;
396
+ color: #6c757d;
397
+ }
398
+
399
+ .price {
400
+ font-size: 18px;
401
+ font-weight: 700;
402
+ color: #28a745;
403
+ }
404
+
405
+ .theme-selector {
406
+ display: grid;
407
+ grid-template-columns: 1fr 1fr;
408
+ gap: 24px;
409
+ }
410
+
411
+ .theme-group {
412
+ padding: 16px;
413
+ border: 1px solid #e1e5e9;
414
+ border-radius: 8px;
415
+ }
416
+
417
+ .theme-group h4 {
418
+ margin: 0 0 12px 0;
419
+ color: #495057;
420
+ }
421
+
422
+ .error-message {
423
+ color: #dc3545;
424
+ font-size: 14px;
425
+ margin-top: 6px;
426
+ }
427
+
428
+ /* Custom radio group styles */
429
+ .custom-radio-group {
430
+ display: flex;
431
+ flex-wrap: wrap;
432
+ gap: 12px;
433
+ }
434
+
435
+ .custom-radio-group .radio-option {
436
+ flex: 1;
437
+ min-width: 120px;
438
+ }
439
+ ```
440
+
441
+ ## Component Advantages
442
+
443
+ **Advantages over using individual RadioButton components:**
444
+
445
+ 1. **Unified Management**: All related options managed in a single component
446
+ 2. **Simplified Data Binding**: Only need to bind one value instead of multiple independent values
447
+ 3. **Style Consistency**: All options have unified styling and spacing
448
+ 4. **Dynamic Option Management**: Easy to show/hide, enable/disable specific options
449
+ 5. **Better Semantics**: Clearly expresses the mutually exclusive relationship between options
450
+ 6. **Easy Maintenance**: All option additions, deletions, and modifications handled in one place
451
+
452
+ ## Best Practices
453
+
454
+ ### 1. Provide Reasonable Default Values
455
+ ```svelte
456
+ <!-- Recommended: Set reasonable default value -->
457
+ <GroupRadioBox
458
+ options={genderOptions}
459
+ bind:value={selectedGender}
460
+ defaultValue="other"
461
+ />
462
+
463
+ <!-- Avoid: Making user selection mandatory -->
464
+ <GroupRadioBox
465
+ options={genderOptions}
466
+ bind:value={selectedGender}
467
+ />
468
+ ```
469
+
470
+ ### 2. Limit Number of Options
471
+ ```svelte
472
+ <!-- Recommended: Moderate number of options (3-7) -->
473
+ <GroupRadioBox options={satisfactionLevels} /> <!-- 5 options -->
474
+
475
+ <!-- Avoid: Too many options, use dropdown select instead -->
476
+ <OptionsSelect options={countryList} /> <!-- 200+ countries -->
477
+ ```
478
+
479
+ ### 3. Provide Clear Labels
480
+ ```svelte
481
+ <!-- Recommended: Clear description -->
482
+ <label>Please select your age group:</label>
483
+ <GroupRadioBox options={ageRanges} />
484
+
485
+ <!-- Avoid: Vague labels -->
486
+ <label>Select:</label>
487
+ <GroupRadioBox options={someOptions} />
488
+ ```
489
+
490
+ ### 4. Use Disabled State Appropriately
491
+ ```svelte
492
+ <!-- Recommended: Clear reasoning -->
493
+ <GroupRadioBox
494
+ options={premiumFeatures}
495
+ disabledOptions={nonPremiumUser ? ['advanced', 'pro'] : []}
496
+ />
497
+ <div class="help-text">Upgrade to premium to unlock more features</div>
498
+ ```