@ticatec/uniface-element 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +273 -1
- package/README_CN.md +341 -0
- package/dist/common/MouseClickHandler.d.ts +1 -1
- package/dist/dialog/CommonDialog.svelte +6 -3
- package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
- package/dist/dialog/Dialog.svelte +36 -10
- package/dist/dialog/Dialog.svelte.d.ts +4 -3
- package/dist/dialog/DialogBoard.svelte +11 -8
- package/dist/dialog/DialogWrapper.svelte +10 -0
- package/dist/dialog/DialogWrapper.svelte.d.ts +22 -0
- package/dist/dialog/Dialogs.js +1 -1
- package/dist/dialog/ModalResult.d.ts +5 -0
- package/dist/dialog/ModalResult.js +5 -0
- package/docs/buttons/cn/ActionBar.md +459 -0
- package/docs/buttons/cn/Button.md +228 -0
- package/docs/buttons/cn/IconButton.md +294 -0
- package/docs/buttons/cn/README.md +600 -0
- package/docs/buttons/cn/TextButton.md +163 -0
- package/docs/buttons/en/ActionBar.md +459 -0
- package/docs/buttons/en/Button.md +228 -0
- package/docs/buttons/en/IconButton.md +294 -0
- package/docs/buttons/en/README.md +600 -0
- package/docs/buttons/en/TextButton.md +163 -0
- package/docs/containers/cn/accordion.md +622 -0
- package/docs/containers/cn/box.md +445 -0
- package/docs/containers/cn/card.md +404 -0
- package/docs/containers/cn/page.md +576 -0
- package/docs/containers/cn/tabs.md +686 -0
- package/docs/containers/en/accordion.md +622 -0
- package/docs/containers/en/box.md +445 -0
- package/docs/containers/en/card.md +404 -0
- package/docs/containers/en/page.md +576 -0
- package/docs/containers/en/tabs.md +686 -0
- package/docs/data-display/cn/concise-data-table.md +731 -0
- package/docs/data-display/cn/listbox.md +786 -0
- package/docs/data-display/cn/treeview.md +863 -0
- package/docs/data-display/en/concise-data-table.md +732 -0
- package/docs/data-display/en/listbox.md +786 -0
- package/docs/data-display/en/treeview.md +863 -0
- package/docs/data-table/cn/README.md +596 -0
- package/docs/data-table/en/README.md +596 -0
- package/docs/dialog/cn/README.md +767 -0
- package/docs/dialog/en/README.md +767 -0
- package/docs/form/cn/README.md +847 -0
- package/docs/form/en/README.md +847 -0
- package/docs/form-components/cn/README.md +495 -0
- package/docs/form-components/cn/attachmentfilesfield.md +757 -0
- package/docs/form-components/cn/cascade-options-select.md +374 -0
- package/docs/form-components/cn/checkbox.md +58 -0
- package/docs/form-components/cn/date-picker.md +138 -0
- package/docs/form-components/cn/datetime-picker.md +228 -0
- package/docs/form-components/cn/group-checkbox.md +405 -0
- package/docs/form-components/cn/group-radiobox.md +525 -0
- package/docs/form-components/cn/imagefilesfield.md +651 -0
- package/docs/form-components/cn/input-options-select.md +250 -0
- package/docs/form-components/cn/lookup-editor.md +406 -0
- package/docs/form-components/cn/memoeditor.md +409 -0
- package/docs/form-components/cn/number-editor.md +261 -0
- package/docs/form-components/cn/options-multi-select.md +177 -0
- package/docs/form-components/cn/options-select.md +83 -0
- package/docs/form-components/cn/passwordeditor.md +538 -0
- package/docs/form-components/cn/prompts-text-editor.md +241 -0
- package/docs/form-components/cn/radiobutton.md +84 -0
- package/docs/form-components/cn/switch.md +178 -0
- package/docs/form-components/cn/text-editor.md +142 -0
- package/docs/form-components/cn/time-editor.md +159 -0
- package/docs/form-components/cn/unit-number-editor.md +164 -0
- package/docs/form-components/en/README.md +463 -0
- package/docs/form-components/en/attachmentfilesfield.md +757 -0
- package/docs/form-components/en/cascade-options-select.md +358 -0
- package/docs/form-components/en/checkbox.md +59 -0
- package/docs/form-components/en/date-picker.md +138 -0
- package/docs/form-components/en/datetime-picker.md +228 -0
- package/docs/form-components/en/group-checkbox.md +395 -0
- package/docs/form-components/en/group-radiobox.md +498 -0
- package/docs/form-components/en/imagefilesfield.md +651 -0
- package/docs/form-components/en/input-options-select.md +239 -0
- package/docs/form-components/en/lookup-editor.md +389 -0
- package/docs/form-components/en/memoeditor.md +409 -0
- package/docs/form-components/en/number-editor.md +249 -0
- package/docs/form-components/en/options-multi-select.md +177 -0
- package/docs/form-components/en/options-select.md +83 -0
- package/docs/form-components/en/passwordeditor.md +538 -0
- package/docs/form-components/en/prompts-text-editor.md +241 -0
- package/docs/form-components/en/radiobutton.md +84 -0
- package/docs/form-components/en/switch.md +180 -0
- package/docs/form-components/en/text-editor.md +142 -0
- package/docs/form-components/en/time-editor.md +159 -0
- package/docs/form-components/en/unit-number-editor.md +164 -0
- package/docs/form-layout/cn/criteria-field.md +652 -0
- package/docs/form-layout/cn/flex-form.md +454 -0
- package/docs/form-layout/cn/flex-row-form.md +542 -0
- package/docs/form-layout/cn/form-field.md +923 -0
- package/docs/form-layout/cn/grid-form.md +676 -0
- package/docs/form-layout/en/criteria-field.md +652 -0
- package/docs/form-layout/en/flex-form.md +454 -0
- package/docs/form-layout/en/flex-row-form.md +542 -0
- package/docs/form-layout/en/form-field.md +923 -0
- package/docs/form-layout/en/grid-form.md +676 -0
- package/docs/global/cn/README.md +534 -0
- package/docs/global/en/README.md +534 -0
- package/docs/layout/cn/classiclayout.md +460 -0
- package/docs/layout/cn/headerlayout.md +524 -0
- package/docs/layout/cn/sidebarlayout.md +263 -0
- package/docs/layout/en/classiclayout.md +951 -0
- package/docs/layout/en/headerlayout.md +524 -0
- package/docs/layout/en/sidebarlayout.md +262 -0
- package/docs/misc/cn/README.md +1217 -0
- package/docs/misc/en/README.md +1217 -0
- package/docs/navigation/cn/breadcrumb.md +291 -0
- package/docs/navigation/cn/navigator.md +322 -0
- package/docs/navigation/cn/navigatormenu.md +512 -0
- package/docs/navigation/cn/progressbar.md +199 -0
- package/docs/navigation/cn/progressstepbar.md +299 -0
- package/docs/navigation/en/breadcrumb.md +291 -0
- package/docs/navigation/en/navigator.md +322 -0
- package/docs/navigation/en/navigatormenu.md +512 -0
- package/docs/navigation/en/progressbar.md +199 -0
- package/docs/navigation/en/progressstepbar.md +299 -0
- package/docs/search-filters/cn/daterange.md +1156 -0
- package/docs/search-filters/cn/numberrange.md +688 -0
- package/docs/search-filters/cn/searchbox.md +1582 -0
- package/docs/search-filters/en/daterange.md +1156 -0
- package/docs/search-filters/en/numberrange.md +688 -0
- package/docs/search-filters/en/searchbox.md +1582 -0
- package/package.json +38 -5
|
@@ -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
|
+
```
|