@ticatec/uniface-element 0.2.4 → 0.3.0
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/dist/accordion/README.md +169 -0
- package/dist/accordion/README_CN.md +176 -0
- package/dist/action-bar/README.md +275 -0
- package/dist/action-bar/README_CN.md +285 -0
- package/dist/app-layout/README.md +374 -0
- package/dist/app-layout/README_CN.md +381 -0
- package/dist/app-top-bar/README.md +357 -0
- package/dist/app-top-bar/README_CN.md +365 -0
- package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
- package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
- package/dist/base-calendar/CalendarBase.svelte +0 -3
- package/dist/box/README.md +385 -0
- package/dist/box/README_CN.md +393 -0
- package/dist/breadcrumbs/README.md +442 -0
- package/dist/breadcrumbs/README_CN.md +442 -0
- package/dist/button/Button.svelte +27 -7
- package/dist/button/Button.svelte.d.ts +3 -1
- package/dist/button/IconButton.svelte +26 -6
- package/dist/button/IconButton.svelte.d.ts +3 -1
- package/dist/button/IconButton_README.md +513 -0
- package/dist/button/IconButton_README_CN.md +513 -0
- package/dist/button/README.md +428 -0
- package/dist/button/README_CN.md +428 -0
- package/dist/button/TextButton.svelte +26 -6
- package/dist/button/TextButton.svelte.d.ts +3 -1
- package/dist/button/TextButton_README.md +571 -0
- package/dist/button/TextButton_README_CN.md +571 -0
- package/dist/card/README.md +666 -0
- package/dist/card/README_CN.md +666 -0
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
- package/dist/cascade-options-select/README.md +663 -2
- package/dist/cascade-options-select/README_CN.md +664 -0
- package/dist/checkbox/CheckBox.svelte +20 -6
- package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
- package/dist/checkbox/README.md +562 -0
- package/dist/checkbox/README_CN.md +727 -0
- package/dist/common-editor/NumberInput.svelte +39 -26
- package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
- package/dist/concise-data-table/ConciseListTable.svelte +133 -36
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
- package/dist/concise-data-table/DataCell.svelte +5 -6
- package/dist/concise-data-table/DataRow.svelte +22 -2
- package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
- package/dist/concise-data-table/README.md +606 -0
- package/dist/concise-data-table/README_CN.md +611 -0
- package/dist/context-menu/ContextMenu.svelte +138 -21
- package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
- package/dist/context-menu/ContextMenuItem.d.ts +20 -4
- package/dist/context-menu/README.md +551 -0
- package/dist/context-menu/README_CN.md +551 -0
- package/dist/criteria-field/CriteriaField.svelte +3 -5
- package/dist/criteria-field/README.md +532 -0
- package/dist/criteria-field/README_CN.md +532 -0
- package/dist/data-table/README.md +712 -0
- package/dist/data-table/README_CN.md +712 -0
- package/dist/date-picker/DatePicker.svelte +44 -7
- package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
- package/dist/date-picker/DateTimePicker.svelte +32 -8
- package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
- package/dist/date-picker/README.md +326 -0
- package/dist/date-picker/README_CN.md +316 -0
- package/dist/date-picker/ScrollBar.svelte +18 -8
- package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
- package/dist/date-picker/TimePanel.svelte +5 -5
- package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
- package/dist/date-range/README.md +374 -0
- package/dist/date-range/README_CN.md +374 -0
- package/dist/dialog/README.md +596 -0
- package/dist/dialog/README_CN.md +596 -0
- package/dist/drawer/README.md +679 -1
- package/dist/drawer/README_CN.md +679 -0
- package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
- package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
- package/dist/group-box/group-check-box/README.md +749 -0
- package/dist/group-box/group-check-box/README_CN.md +750 -0
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
- package/dist/group-box/group-radio-box/README.md +920 -0
- package/dist/group-box/group-radio-box/README_CN.md +920 -0
- package/dist/image-files/README.md +1346 -0
- package/dist/image-files/README_CN.md +1346 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
- package/dist/lib/forwardAllEvents.d.ts +3 -0
- package/dist/lib/forwardAllEvents.js +24 -0
- package/dist/list-box/README.md +579 -0
- package/dist/list-box/README_CN.md +682 -0
- package/dist/lookup-editor/LookupEditor.svelte +15 -3
- package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
- package/dist/lookup-editor/README.md +684 -0
- package/dist/lookup-editor/README_CN.md +684 -0
- package/dist/memo-editor/MemoEditor.svelte +77 -27
- package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
- package/dist/memo-editor/README.md +819 -0
- package/dist/memo-editor/README_CN.md +819 -0
- package/dist/message-box/README.md +398 -0
- package/dist/message-box/README_CN.md +398 -0
- package/dist/number-editor/NumberEditor.svelte +2 -2
- package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
- package/dist/number-editor/README.md +353 -22
- package/dist/number-editor/README_CN.md +357 -0
- package/dist/number-range/README.md +443 -0
- package/dist/number-range/README_CN.md +443 -0
- package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
- package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
- package/dist/options-multi-select/README.md +480 -0
- package/dist/options-multi-select/README_CN.md +480 -0
- package/dist/options-select/OptionsSelect.svelte +36 -5
- package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
- package/dist/options-select/README.md +632 -0
- package/dist/options-select/README_CN.md +632 -0
- package/dist/page/README.md +605 -0
- package/dist/page/README_CN.md +605 -0
- package/dist/pagination/README.md +946 -0
- package/dist/pagination/README_CN.md +946 -0
- package/dist/pagination-panel/README.md +1075 -0
- package/dist/pagination-panel/README_CN.md +1075 -0
- package/dist/popup-hint/README.md +841 -0
- package/dist/popup-hint/README_CN.md +840 -0
- package/dist/progress-bar/README.md +242 -0
- package/dist/progress-bar/README_CN.md +242 -0
- package/dist/progress-step-bar/README.md +316 -0
- package/dist/progress-step-bar/README_CN.md +316 -0
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
- package/dist/prompts-text-editor/README.md +329 -0
- package/dist/prompts-text-editor/README_CN.md +329 -0
- package/dist/property-editor/README.md +969 -0
- package/dist/property-editor/README_CN.md +969 -0
- package/dist/radio-button/README.md +372 -0
- package/dist/radio-button/README_CN.md +372 -0
- package/dist/radio-button/RadioButton.svelte +32 -3
- package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
- package/dist/search-box/README.md +425 -0
- package/dist/search-box/README_CN.md +424 -0
- package/dist/search-box/SearchBox.svelte +22 -6
- package/dist/search-box/SearchBox.svelte.d.ts +4 -1
- package/dist/tabs/README.md +919 -0
- package/dist/tabs/README_CN.md +920 -0
- package/dist/tag/README.md +922 -0
- package/dist/tag/README_CN.md +922 -0
- package/dist/text-editor/PasswordEditor.svelte +17 -2
- package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
- package/dist/text-editor/PasswordEditor_README.md +551 -0
- package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
- package/dist/text-editor/README.md +466 -0
- package/dist/text-editor/README_CN.md +466 -0
- package/dist/text-editor/TextEditor.svelte +51 -19
- package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
- package/dist/time-editor/README.md +498 -24
- package/dist/time-editor/README_CN.md +498 -0
- package/dist/time-editor/TimeEditor.svelte +7 -3
- package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
- package/dist/toast/README.md +667 -0
- package/dist/toast/README_CN.md +667 -0
- package/dist/transfer/README.md +795 -0
- package/dist/transfer/Transfer.svelte +6 -4
- package/dist/transfer/Transfer.svelte.d.ts +3 -1
- package/dist/tree-view/README.md +761 -0
- package/dist/tree-view/README_CN.md +761 -0
- package/dist/tree-view/TreeView.svelte +5 -3
- package/dist/tree-view/TreeView.svelte.d.ts +3 -1
- package/dist/unit-number-editor/README.md +546 -20
- package/dist/unit-number-editor/README_CN.md +525 -0
- package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
- package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
- package/docs/form-field/cn/README_CN.md +364 -0
- package/docs/form-field/en/README.md +364 -0
- package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
- package/docs/form-panel/flex-form/en/README.md +586 -0
- package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
- package/docs/form-panel/flex-row-form/en/README.md +787 -0
- package/docs/form-panel/grid-form/en/README.md +744 -0
- package/package.json +1 -1
- package/dist/drawer/README-CN.md +0 -1
|
@@ -0,0 +1,920 @@
|
|
|
1
|
+
# GroupRadioBox
|
|
2
|
+
|
|
3
|
+
A flexible group radio box component that allows users to select a single option from a predefined list. Features comprehensive state management, custom styling variants, and focus/blur event handling for seamless form integration.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ticatec/uniface-element
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Import
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
15
|
+
import { DisplayMode } from "@ticatec/uniface-element";
|
|
16
|
+
import type { OnChangeHandler } from "@ticatec/uniface-element";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Basic Usage
|
|
20
|
+
|
|
21
|
+
```svelte
|
|
22
|
+
<script>
|
|
23
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
24
|
+
|
|
25
|
+
const options = [
|
|
26
|
+
{ code: "sm", text: "Small" },
|
|
27
|
+
{ code: "md", text: "Medium" },
|
|
28
|
+
{ code: "lg", text: "Large" },
|
|
29
|
+
{ code: "xl", text: "Extra Large" }
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
let selectedSize = "md";
|
|
33
|
+
|
|
34
|
+
function handleChange(value) {
|
|
35
|
+
console.log('Selected size:', value);
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<GroupRadioBox
|
|
40
|
+
{options}
|
|
41
|
+
bind:value={selectedSize}
|
|
42
|
+
onchange={handleChange}
|
|
43
|
+
/>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Props
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
|------|------|---------|-------------|
|
|
50
|
+
| `value` | `any` | required | Selected value |
|
|
51
|
+
| `options` | `Array<any>` | required | Array of option objects |
|
|
52
|
+
| `keyField` | `string` | `"code"` | Field name for option keys/values |
|
|
53
|
+
| `textField` | `string` | `"text"` | Field name for option display text |
|
|
54
|
+
| `disabled` | `boolean` | `false` | Whether the component is disabled |
|
|
55
|
+
| `readonly` | `boolean` | `false` | Whether the component is read-only |
|
|
56
|
+
| `displayMode` | `DisplayMode` | `DisplayMode.Edit` | Display mode (Edit or View) |
|
|
57
|
+
| `variant` | `"" \| "plain" \| "outlined" \| "filled"` | `""` | Visual variant |
|
|
58
|
+
| `compact` | `boolean` | `false` | Whether to use compact spacing |
|
|
59
|
+
| `disabledOptions` | `Array<string>` | `[]` | Array of option keys to disable |
|
|
60
|
+
| `style` | `string` | `""` | Additional CSS styles |
|
|
61
|
+
| `item$style` | `string` | `""` | CSS styles for individual radio button items |
|
|
62
|
+
| `onchange` | `OnChangeHandler<any>` | `null` | Change event handler |
|
|
63
|
+
| `onfocus` | `(() => void) \| null` | `null` | Focus event handler |
|
|
64
|
+
| `onblur` | `(() => void) \| null` | `null` | Blur event handler |
|
|
65
|
+
|
|
66
|
+
## Methods
|
|
67
|
+
|
|
68
|
+
| Method | Description |
|
|
69
|
+
|--------|-------------|
|
|
70
|
+
| `setFocus()` | Programmatically focus the first enabled radio button |
|
|
71
|
+
|
|
72
|
+
## Examples
|
|
73
|
+
|
|
74
|
+
### Basic Selection
|
|
75
|
+
|
|
76
|
+
```svelte
|
|
77
|
+
<script>
|
|
78
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
79
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
80
|
+
|
|
81
|
+
const priorities = [
|
|
82
|
+
{ code: "low", text: "Low Priority" },
|
|
83
|
+
{ code: "medium", text: "Medium Priority" },
|
|
84
|
+
{ code: "high", text: "High Priority" },
|
|
85
|
+
{ code: "urgent", text: "Urgent" }
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
let taskPriority = "medium";
|
|
89
|
+
|
|
90
|
+
function handlePriorityChange(value) {
|
|
91
|
+
console.log('Priority changed to:', value);
|
|
92
|
+
|
|
93
|
+
// Handle priority-specific logic
|
|
94
|
+
if (value === 'urgent') {
|
|
95
|
+
console.log('Urgent task - notify team leads');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
</script>
|
|
99
|
+
|
|
100
|
+
<div class="demo-section">
|
|
101
|
+
<FormField label="Task Priority">
|
|
102
|
+
<GroupRadioBox
|
|
103
|
+
options={priorities}
|
|
104
|
+
bind:value={taskPriority}
|
|
105
|
+
onchange={handlePriorityChange}
|
|
106
|
+
onfocus={() => console.log('Priority field focused')}
|
|
107
|
+
onblur={() => console.log('Priority field blurred')}
|
|
108
|
+
/>
|
|
109
|
+
</FormField>
|
|
110
|
+
|
|
111
|
+
<div class="result">
|
|
112
|
+
<p><strong>Selected Priority:</strong> {taskPriority}</p>
|
|
113
|
+
<p><strong>Display Text:</strong> {priorities.find(p => p.code === taskPriority)?.text ?? 'None'}</p>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<style>
|
|
118
|
+
.demo-section {
|
|
119
|
+
margin: 20px;
|
|
120
|
+
padding: 20px;
|
|
121
|
+
border: 1px solid #e2e8f0;
|
|
122
|
+
border-radius: 8px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.result {
|
|
126
|
+
margin-top: 16px;
|
|
127
|
+
padding: 12px;
|
|
128
|
+
background: #f8fafc;
|
|
129
|
+
border-radius: 6px;
|
|
130
|
+
}
|
|
131
|
+
</style>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Different Visual Variants
|
|
135
|
+
|
|
136
|
+
```svelte
|
|
137
|
+
<script>
|
|
138
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
139
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
140
|
+
|
|
141
|
+
const themes = [
|
|
142
|
+
{ code: "light", text: "Light Theme" },
|
|
143
|
+
{ code: "dark", text: "Dark Theme" },
|
|
144
|
+
{ code: "auto", text: "Auto (System)" }
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
let selectedTheme = "auto";
|
|
148
|
+
</script>
|
|
149
|
+
|
|
150
|
+
<div class="variants-demo">
|
|
151
|
+
<div class="variant-section">
|
|
152
|
+
<h3>Default Variant</h3>
|
|
153
|
+
<FormField label="Theme Preference">
|
|
154
|
+
<GroupRadioBox options={themes} bind:value={selectedTheme} />
|
|
155
|
+
</FormField>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
<div class="variant-section">
|
|
159
|
+
<h3>Outlined Variant</h3>
|
|
160
|
+
<FormField label="Theme Preference">
|
|
161
|
+
<GroupRadioBox
|
|
162
|
+
options={themes}
|
|
163
|
+
variant="outlined"
|
|
164
|
+
bind:value={selectedTheme}
|
|
165
|
+
/>
|
|
166
|
+
</FormField>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<div class="variant-section">
|
|
170
|
+
<h3>Filled Variant</h3>
|
|
171
|
+
<FormField label="Theme Preference">
|
|
172
|
+
<GroupRadioBox
|
|
173
|
+
options={themes}
|
|
174
|
+
variant="filled"
|
|
175
|
+
bind:value={selectedTheme}
|
|
176
|
+
/>
|
|
177
|
+
</FormField>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<div class="variant-section">
|
|
181
|
+
<h3>Compact Variant</h3>
|
|
182
|
+
<FormField label="Theme Preference">
|
|
183
|
+
<GroupRadioBox
|
|
184
|
+
options={themes}
|
|
185
|
+
compact={true}
|
|
186
|
+
bind:value={selectedTheme}
|
|
187
|
+
/>
|
|
188
|
+
</FormField>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<style>
|
|
193
|
+
.variants-demo {
|
|
194
|
+
display: grid;
|
|
195
|
+
grid-template-columns: 1fr 1fr;
|
|
196
|
+
gap: 20px;
|
|
197
|
+
margin: 20px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.variant-section {
|
|
201
|
+
padding: 16px;
|
|
202
|
+
border: 1px solid #e2e8f0;
|
|
203
|
+
border-radius: 8px;
|
|
204
|
+
}
|
|
205
|
+
</style>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Conditional Options and Dynamic Behavior
|
|
209
|
+
|
|
210
|
+
```svelte
|
|
211
|
+
<script>
|
|
212
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
213
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
214
|
+
|
|
215
|
+
const paymentMethods = [
|
|
216
|
+
{ code: "card", text: "Credit Card" },
|
|
217
|
+
{ code: "paypal", text: "PayPal" },
|
|
218
|
+
{ code: "bank", text: "Bank Transfer" },
|
|
219
|
+
{ code: "crypto", text: "Cryptocurrency" },
|
|
220
|
+
{ code: "cash", text: "Cash on Delivery" }
|
|
221
|
+
];
|
|
222
|
+
|
|
223
|
+
let selectedPayment = "card";
|
|
224
|
+
let disabledOptions = [];
|
|
225
|
+
let orderTotal = 150.00;
|
|
226
|
+
let region = "domestic";
|
|
227
|
+
|
|
228
|
+
// Update available payment methods based on order conditions
|
|
229
|
+
$: {
|
|
230
|
+
disabledOptions = [];
|
|
231
|
+
|
|
232
|
+
// Disable crypto for small orders
|
|
233
|
+
if (orderTotal < 100) {
|
|
234
|
+
disabledOptions.push("crypto");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Disable cash on delivery for international orders
|
|
238
|
+
if (region === "international") {
|
|
239
|
+
disabledOptions.push("cash");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Auto-select available option if current selection becomes disabled
|
|
243
|
+
if (disabledOptions.includes(selectedPayment)) {
|
|
244
|
+
const availableOptions = paymentMethods.filter(method =>
|
|
245
|
+
!disabledOptions.includes(method.code)
|
|
246
|
+
);
|
|
247
|
+
if (availableOptions.length > 0) {
|
|
248
|
+
selectedPayment = availableOptions[0].code;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function handlePaymentChange(value) {
|
|
254
|
+
console.log('Payment method changed to:', value);
|
|
255
|
+
|
|
256
|
+
// Handle payment-specific logic
|
|
257
|
+
if (value === 'crypto') {
|
|
258
|
+
console.log('Crypto payment selected - show wallet options');
|
|
259
|
+
} else if (value === 'bank') {
|
|
260
|
+
console.log('Bank transfer selected - show bank details');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
</script>
|
|
264
|
+
|
|
265
|
+
<div class="conditional-demo">
|
|
266
|
+
<div class="controls">
|
|
267
|
+
<FormField label="Order Total">
|
|
268
|
+
<input
|
|
269
|
+
type="number"
|
|
270
|
+
bind:value={orderTotal}
|
|
271
|
+
min="10"
|
|
272
|
+
step="10"
|
|
273
|
+
class="number-input"
|
|
274
|
+
/>
|
|
275
|
+
</FormField>
|
|
276
|
+
|
|
277
|
+
<FormField label="Region">
|
|
278
|
+
<select bind:value={region} class="select-input">
|
|
279
|
+
<option value="domestic">Domestic</option>
|
|
280
|
+
<option value="international">International</option>
|
|
281
|
+
</select>
|
|
282
|
+
</FormField>
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
<FormField label="Payment Method">
|
|
286
|
+
<GroupRadioBox
|
|
287
|
+
options={paymentMethods}
|
|
288
|
+
bind:value={selectedPayment}
|
|
289
|
+
{disabledOptions}
|
|
290
|
+
onchange={handlePaymentChange}
|
|
291
|
+
variant="outlined"
|
|
292
|
+
/>
|
|
293
|
+
</FormField>
|
|
294
|
+
|
|
295
|
+
<div class="info-panel">
|
|
296
|
+
<p><strong>Selected:</strong> {selectedPayment}</p>
|
|
297
|
+
<p><strong>Order Total:</strong> ${orderTotal}</p>
|
|
298
|
+
<p><strong>Region:</strong> {region}</p>
|
|
299
|
+
<p><strong>Disabled Methods:</strong> {disabledOptions.join(', ') || 'None'}</p>
|
|
300
|
+
|
|
301
|
+
{#if disabledOptions.includes('crypto')}
|
|
302
|
+
<p class="info-note">💡 Cryptocurrency payments require minimum $100 order</p>
|
|
303
|
+
{/if}
|
|
304
|
+
|
|
305
|
+
{#if disabledOptions.includes('cash')}
|
|
306
|
+
<p class="info-note">💡 Cash on delivery not available for international orders</p>
|
|
307
|
+
{/if}
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
<style>
|
|
312
|
+
.conditional-demo {
|
|
313
|
+
margin: 20px;
|
|
314
|
+
padding: 20px;
|
|
315
|
+
border: 1px solid #e2e8f0;
|
|
316
|
+
border-radius: 8px;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.controls {
|
|
320
|
+
display: grid;
|
|
321
|
+
grid-template-columns: 1fr 1fr;
|
|
322
|
+
gap: 16px;
|
|
323
|
+
margin-bottom: 20px;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.number-input, .select-input {
|
|
327
|
+
width: 100%;
|
|
328
|
+
padding: 8px 12px;
|
|
329
|
+
border: 1px solid #d1d5db;
|
|
330
|
+
border-radius: 6px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.info-panel {
|
|
334
|
+
margin-top: 16px;
|
|
335
|
+
padding: 12px;
|
|
336
|
+
background: #f8fafc;
|
|
337
|
+
border-radius: 6px;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.info-note {
|
|
341
|
+
color: #6b7280;
|
|
342
|
+
font-style: italic;
|
|
343
|
+
margin-top: 8px;
|
|
344
|
+
}
|
|
345
|
+
</style>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Custom Field Configuration
|
|
349
|
+
|
|
350
|
+
```svelte
|
|
351
|
+
<script>
|
|
352
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
353
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
354
|
+
|
|
355
|
+
// Using custom field names
|
|
356
|
+
const departments = [
|
|
357
|
+
{ id: "eng", name: "Engineering", active: true },
|
|
358
|
+
{ id: "sales", name: "Sales & Marketing", active: true },
|
|
359
|
+
{ id: "hr", name: "Human Resources", active: false },
|
|
360
|
+
{ id: "finance", name: "Finance & Accounting", active: true }
|
|
361
|
+
];
|
|
362
|
+
|
|
363
|
+
let selectedDepartment = "eng";
|
|
364
|
+
|
|
365
|
+
function handleDepartmentChange(value) {
|
|
366
|
+
const selected = departments.find(dept => dept.id === value);
|
|
367
|
+
console.log('Department changed:', selected);
|
|
368
|
+
}
|
|
369
|
+
</script>
|
|
370
|
+
|
|
371
|
+
<div class="custom-demo">
|
|
372
|
+
<FormField label="Select Department">
|
|
373
|
+
<GroupRadioBox
|
|
374
|
+
options={departments}
|
|
375
|
+
keyField="id"
|
|
376
|
+
textField="name"
|
|
377
|
+
bind:value={selectedDepartment}
|
|
378
|
+
onchange={handleDepartmentChange}
|
|
379
|
+
variant="filled"
|
|
380
|
+
style="padding: 16px; background: linear-gradient(145deg, #f8fafc, #e2e8f0);"
|
|
381
|
+
item$style="margin: 8px 0; padding: 6px 12px; border-radius: 8px; background: white;"
|
|
382
|
+
/>
|
|
383
|
+
</FormField>
|
|
384
|
+
|
|
385
|
+
<div class="department-info">
|
|
386
|
+
{#each departments as dept}
|
|
387
|
+
{#if dept.id === selectedDepartment}
|
|
388
|
+
<div class="selected-dept">
|
|
389
|
+
<h4>{dept.name}</h4>
|
|
390
|
+
<p>Status: {dept.active ? '✅ Active' : '❌ Inactive'}</p>
|
|
391
|
+
<p>Department ID: {dept.id}</p>
|
|
392
|
+
</div>
|
|
393
|
+
{/if}
|
|
394
|
+
{/each}
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
|
|
398
|
+
<style>
|
|
399
|
+
.custom-demo {
|
|
400
|
+
margin: 20px;
|
|
401
|
+
padding: 20px;
|
|
402
|
+
border: 1px solid #e2e8f0;
|
|
403
|
+
border-radius: 8px;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.department-info {
|
|
407
|
+
margin-top: 16px;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.selected-dept {
|
|
411
|
+
padding: 16px;
|
|
412
|
+
background: #dbeafe;
|
|
413
|
+
border-radius: 8px;
|
|
414
|
+
border-left: 4px solid #3b82f6;
|
|
415
|
+
}
|
|
416
|
+
</style>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Read-Only and Display Modes
|
|
420
|
+
|
|
421
|
+
```svelte
|
|
422
|
+
<script>
|
|
423
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
424
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
425
|
+
import { DisplayMode } from "@ticatec/uniface-element";
|
|
426
|
+
|
|
427
|
+
const subscriptionPlans = [
|
|
428
|
+
{ code: "basic", text: "Basic Plan" },
|
|
429
|
+
{ code: "premium", text: "Premium Plan" },
|
|
430
|
+
{ code: "enterprise", text: "Enterprise Plan" }
|
|
431
|
+
];
|
|
432
|
+
|
|
433
|
+
let currentPlan = "premium"; // Pre-selected plan
|
|
434
|
+
</script>
|
|
435
|
+
|
|
436
|
+
<div class="readonly-demo">
|
|
437
|
+
<div class="mode-section">
|
|
438
|
+
<h3>Editable Mode</h3>
|
|
439
|
+
<FormField label="Change Subscription Plan">
|
|
440
|
+
<GroupRadioBox
|
|
441
|
+
options={subscriptionPlans}
|
|
442
|
+
bind:value={currentPlan}
|
|
443
|
+
/>
|
|
444
|
+
</FormField>
|
|
445
|
+
</div>
|
|
446
|
+
|
|
447
|
+
<div class="mode-section">
|
|
448
|
+
<h3>Read-Only Mode</h3>
|
|
449
|
+
<FormField label="Current Plan (Read-Only)">
|
|
450
|
+
<GroupRadioBox
|
|
451
|
+
options={subscriptionPlans}
|
|
452
|
+
value={currentPlan}
|
|
453
|
+
readonly={true}
|
|
454
|
+
/>
|
|
455
|
+
</FormField>
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
<div class="mode-section">
|
|
459
|
+
<h3>Disabled Mode</h3>
|
|
460
|
+
<FormField label="Plan Selection (Disabled)">
|
|
461
|
+
<GroupRadioBox
|
|
462
|
+
options={subscriptionPlans}
|
|
463
|
+
value={currentPlan}
|
|
464
|
+
disabled={true}
|
|
465
|
+
/>
|
|
466
|
+
</FormField>
|
|
467
|
+
</div>
|
|
468
|
+
|
|
469
|
+
<div class="mode-section">
|
|
470
|
+
<h3>Display-Only Mode</h3>
|
|
471
|
+
<FormField label="Active Plan">
|
|
472
|
+
<GroupRadioBox
|
|
473
|
+
options={subscriptionPlans}
|
|
474
|
+
value={currentPlan}
|
|
475
|
+
displayMode={DisplayMode.View}
|
|
476
|
+
/>
|
|
477
|
+
</FormField>
|
|
478
|
+
</div>
|
|
479
|
+
</div>
|
|
480
|
+
|
|
481
|
+
<style>
|
|
482
|
+
.readonly-demo {
|
|
483
|
+
display: grid;
|
|
484
|
+
grid-template-columns: 1fr 1fr;
|
|
485
|
+
gap: 20px;
|
|
486
|
+
margin: 20px;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.mode-section {
|
|
490
|
+
padding: 16px;
|
|
491
|
+
border: 1px solid #e2e8f0;
|
|
492
|
+
border-radius: 8px;
|
|
493
|
+
}
|
|
494
|
+
</style>
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Form Integration with Validation
|
|
498
|
+
|
|
499
|
+
```svelte
|
|
500
|
+
<script>
|
|
501
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
502
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
503
|
+
|
|
504
|
+
const shippingOptions = [
|
|
505
|
+
{ code: "standard", text: "Standard (5-7 days)" },
|
|
506
|
+
{ code: "express", text: "Express (2-3 days)" },
|
|
507
|
+
{ code: "overnight", text: "Overnight" }
|
|
508
|
+
];
|
|
509
|
+
|
|
510
|
+
const countries = [
|
|
511
|
+
{ code: "us", text: "United States" },
|
|
512
|
+
{ code: "ca", text: "Canada" },
|
|
513
|
+
{ code: "uk", text: "United Kingdom" },
|
|
514
|
+
{ code: "au", text: "Australia" }
|
|
515
|
+
];
|
|
516
|
+
|
|
517
|
+
let formData = {
|
|
518
|
+
name: '',
|
|
519
|
+
country: '',
|
|
520
|
+
shipping: ''
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
let errors = {};
|
|
524
|
+
let groupRadioBoxRef;
|
|
525
|
+
|
|
526
|
+
function validateForm() {
|
|
527
|
+
errors = {};
|
|
528
|
+
|
|
529
|
+
if (!formData.name.trim()) {
|
|
530
|
+
errors.name = 'Name is required';
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (!formData.country) {
|
|
534
|
+
errors.country = 'Please select a country';
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (!formData.shipping) {
|
|
538
|
+
errors.shipping = 'Please select a shipping option';
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return Object.keys(errors).length === 0;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function handleSubmit() {
|
|
545
|
+
if (validateForm()) {
|
|
546
|
+
console.log('Form submitted:', formData);
|
|
547
|
+
alert('Order placed successfully!');
|
|
548
|
+
} else {
|
|
549
|
+
console.log('Validation errors:', errors);
|
|
550
|
+
// Focus first error field
|
|
551
|
+
if (errors.shipping) {
|
|
552
|
+
groupRadioBoxRef.setFocus();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function handleShippingChange(value) {
|
|
558
|
+
formData.shipping = value;
|
|
559
|
+
// Clear error when user makes a selection
|
|
560
|
+
if (errors.shipping && value) {
|
|
561
|
+
delete errors.shipping;
|
|
562
|
+
errors = { ...errors };
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function handleCountryChange(value) {
|
|
567
|
+
formData.country = value;
|
|
568
|
+
// Clear shipping selection if changing country (different options might be available)
|
|
569
|
+
if (formData.shipping) {
|
|
570
|
+
formData.shipping = '';
|
|
571
|
+
}
|
|
572
|
+
// Clear error
|
|
573
|
+
if (errors.country && value) {
|
|
574
|
+
delete errors.country;
|
|
575
|
+
errors = { ...errors };
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
</script>
|
|
579
|
+
|
|
580
|
+
<div class="form-demo">
|
|
581
|
+
<form on:submit|preventDefault={handleSubmit}>
|
|
582
|
+
<FormField label="Full Name" error={errors.name}>
|
|
583
|
+
<input
|
|
584
|
+
type="text"
|
|
585
|
+
bind:value={formData.name}
|
|
586
|
+
class="form-input"
|
|
587
|
+
class:error={errors.name}
|
|
588
|
+
placeholder="Enter your full name"
|
|
589
|
+
/>
|
|
590
|
+
</FormField>
|
|
591
|
+
|
|
592
|
+
<FormField label="Country" error={errors.country}>
|
|
593
|
+
<GroupRadioBox
|
|
594
|
+
options={countries}
|
|
595
|
+
bind:value={formData.country}
|
|
596
|
+
onchange={handleCountryChange}
|
|
597
|
+
variant="outlined"
|
|
598
|
+
/>
|
|
599
|
+
</FormField>
|
|
600
|
+
|
|
601
|
+
<FormField label="Shipping Method" error={errors.shipping}>
|
|
602
|
+
<GroupRadioBox
|
|
603
|
+
bind:this={groupRadioBoxRef}
|
|
604
|
+
options={shippingOptions}
|
|
605
|
+
bind:value={formData.shipping}
|
|
606
|
+
onchange={handleShippingChange}
|
|
607
|
+
variant="outlined"
|
|
608
|
+
/>
|
|
609
|
+
<p class="field-hint">Shipping costs will be calculated based on your selection</p>
|
|
610
|
+
</FormField>
|
|
611
|
+
|
|
612
|
+
<div class="form-actions">
|
|
613
|
+
<button type="submit" class="submit-btn">Place Order</button>
|
|
614
|
+
<button type="button" on:click={() => console.log(formData)} class="preview-btn">
|
|
615
|
+
Preview Order
|
|
616
|
+
</button>
|
|
617
|
+
</div>
|
|
618
|
+
|
|
619
|
+
{#if formData.country && formData.shipping}
|
|
620
|
+
<div class="order-summary">
|
|
621
|
+
<h4>Order Summary</h4>
|
|
622
|
+
<p>Ship to: {countries.find(c => c.code === formData.country)?.text}</p>
|
|
623
|
+
<p>Shipping: {shippingOptions.find(s => s.code === formData.shipping)?.text}</p>
|
|
624
|
+
</div>
|
|
625
|
+
{/if}
|
|
626
|
+
</form>
|
|
627
|
+
</div>
|
|
628
|
+
|
|
629
|
+
<style>
|
|
630
|
+
.form-demo {
|
|
631
|
+
max-width: 500px;
|
|
632
|
+
margin: 20px;
|
|
633
|
+
padding: 24px;
|
|
634
|
+
border: 1px solid #e2e8f0;
|
|
635
|
+
border-radius: 8px;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
.form-input {
|
|
639
|
+
width: 100%;
|
|
640
|
+
padding: 8px 12px;
|
|
641
|
+
border: 1px solid #d1d5db;
|
|
642
|
+
border-radius: 6px;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.form-input.error {
|
|
646
|
+
border-color: #dc2626;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.field-hint {
|
|
650
|
+
margin-top: 4px;
|
|
651
|
+
font-size: 0.875rem;
|
|
652
|
+
color: #6b7280;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.form-actions {
|
|
656
|
+
display: flex;
|
|
657
|
+
gap: 12px;
|
|
658
|
+
margin-top: 20px;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.submit-btn, .preview-btn {
|
|
662
|
+
padding: 10px 20px;
|
|
663
|
+
border-radius: 6px;
|
|
664
|
+
border: none;
|
|
665
|
+
cursor: pointer;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.submit-btn {
|
|
669
|
+
background: #3b82f6;
|
|
670
|
+
color: white;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
.preview-btn {
|
|
674
|
+
background: #f3f4f6;
|
|
675
|
+
color: #374151;
|
|
676
|
+
border: 1px solid #d1d5db;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
.order-summary {
|
|
680
|
+
margin-top: 20px;
|
|
681
|
+
padding: 16px;
|
|
682
|
+
background: #f0f9ff;
|
|
683
|
+
border-radius: 8px;
|
|
684
|
+
border-left: 4px solid #3b82f6;
|
|
685
|
+
}
|
|
686
|
+
</style>
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### Survey and Rating Implementation
|
|
690
|
+
|
|
691
|
+
```svelte
|
|
692
|
+
<script>
|
|
693
|
+
import GroupRadioBox from "@ticatec/uniface-element/GroupRadioBox";
|
|
694
|
+
import FormField from "@ticatec/uniface-element/FormField";
|
|
695
|
+
|
|
696
|
+
const satisfactionLevels = [
|
|
697
|
+
{ code: "1", text: "Very Dissatisfied" },
|
|
698
|
+
{ code: "2", text: "Dissatisfied" },
|
|
699
|
+
{ code: "3", text: "Neutral" },
|
|
700
|
+
{ code: "4", text: "Satisfied" },
|
|
701
|
+
{ code: "5", text: "Very Satisfied" }
|
|
702
|
+
];
|
|
703
|
+
|
|
704
|
+
const frequencies = [
|
|
705
|
+
{ code: "daily", text: "Daily" },
|
|
706
|
+
{ code: "weekly", text: "Weekly" },
|
|
707
|
+
{ code: "monthly", text: "Monthly" },
|
|
708
|
+
{ code: "rarely", text: "Rarely" },
|
|
709
|
+
{ code: "never", text: "Never" }
|
|
710
|
+
];
|
|
711
|
+
|
|
712
|
+
let surveyData = {
|
|
713
|
+
satisfaction: '',
|
|
714
|
+
frequency: '',
|
|
715
|
+
recommendation: ''
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
let isCompleted = false;
|
|
719
|
+
|
|
720
|
+
$: isCompleted = surveyData.satisfaction && surveyData.frequency && surveyData.recommendation;
|
|
721
|
+
|
|
722
|
+
function handleSurveySubmit() {
|
|
723
|
+
if (isCompleted) {
|
|
724
|
+
console.log('Survey submitted:', surveyData);
|
|
725
|
+
alert('Thank you for your feedback!');
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
function getSatisfactionColor(level) {
|
|
730
|
+
const colors = {
|
|
731
|
+
'1': '#dc2626', '2': '#ea580c', '3': '#d97706',
|
|
732
|
+
'4': '#65a30d', '5': '#16a34a'
|
|
733
|
+
};
|
|
734
|
+
return colors[level] || '#6b7280';
|
|
735
|
+
}
|
|
736
|
+
</script>
|
|
737
|
+
|
|
738
|
+
<div class="survey-demo">
|
|
739
|
+
<h2>Customer Satisfaction Survey</h2>
|
|
740
|
+
|
|
741
|
+
<div class="survey-section">
|
|
742
|
+
<FormField label="How satisfied are you with our service?">
|
|
743
|
+
<GroupRadioBox
|
|
744
|
+
options={satisfactionLevels}
|
|
745
|
+
bind:value={surveyData.satisfaction}
|
|
746
|
+
variant="outlined"
|
|
747
|
+
item$style="padding: 12px; margin: 4px 0; border-radius: 8px;"
|
|
748
|
+
/>
|
|
749
|
+
</FormField>
|
|
750
|
+
|
|
751
|
+
{#if surveyData.satisfaction}
|
|
752
|
+
<div class="satisfaction-feedback" style="color: {getSatisfactionColor(surveyData.satisfaction)}">
|
|
753
|
+
<strong>You selected: {satisfactionLevels.find(s => s.code === surveyData.satisfaction)?.text}</strong>
|
|
754
|
+
</div>
|
|
755
|
+
{/if}
|
|
756
|
+
</div>
|
|
757
|
+
|
|
758
|
+
<div class="survey-section">
|
|
759
|
+
<FormField label="How often do you use our service?">
|
|
760
|
+
<GroupRadioBox
|
|
761
|
+
options={frequencies}
|
|
762
|
+
bind:value={surveyData.frequency}
|
|
763
|
+
variant="filled"
|
|
764
|
+
compact={true}
|
|
765
|
+
/>
|
|
766
|
+
</FormField>
|
|
767
|
+
</div>
|
|
768
|
+
|
|
769
|
+
<div class="survey-section">
|
|
770
|
+
<FormField label="Would you recommend us to others?">
|
|
771
|
+
<GroupRadioBox
|
|
772
|
+
options={[
|
|
773
|
+
{ code: "yes", text: "Yes, definitely" },
|
|
774
|
+
{ code: "maybe", text: "Maybe" },
|
|
775
|
+
{ code: "no", text: "No, I wouldn't" }
|
|
776
|
+
]}
|
|
777
|
+
bind:value={surveyData.recommendation}
|
|
778
|
+
variant="outlined"
|
|
779
|
+
/>
|
|
780
|
+
</FormField>
|
|
781
|
+
</div>
|
|
782
|
+
|
|
783
|
+
<div class="survey-progress">
|
|
784
|
+
<div class="progress-bar">
|
|
785
|
+
<div
|
|
786
|
+
class="progress-fill"
|
|
787
|
+
style="width: {(Object.values(surveyData).filter(v => v).length / 3) * 100}%"
|
|
788
|
+
></div>
|
|
789
|
+
</div>
|
|
790
|
+
<p>Progress: {Object.values(surveyData).filter(v => v).length}/3 questions completed</p>
|
|
791
|
+
</div>
|
|
792
|
+
|
|
793
|
+
<button
|
|
794
|
+
on:click={handleSurveySubmit}
|
|
795
|
+
disabled={!isCompleted}
|
|
796
|
+
class="submit-survey-btn"
|
|
797
|
+
class:disabled={!isCompleted}
|
|
798
|
+
>
|
|
799
|
+
Submit Survey
|
|
800
|
+
</button>
|
|
801
|
+
</div>
|
|
802
|
+
|
|
803
|
+
<style>
|
|
804
|
+
.survey-demo {
|
|
805
|
+
max-width: 600px;
|
|
806
|
+
margin: 20px;
|
|
807
|
+
padding: 24px;
|
|
808
|
+
border: 1px solid #e2e8f0;
|
|
809
|
+
border-radius: 8px;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
.survey-section {
|
|
813
|
+
margin-bottom: 24px;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
.satisfaction-feedback {
|
|
817
|
+
margin-top: 8px;
|
|
818
|
+
padding: 8px 12px;
|
|
819
|
+
background: #f0f9ff;
|
|
820
|
+
border-radius: 6px;
|
|
821
|
+
font-weight: 500;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
.survey-progress {
|
|
825
|
+
margin: 24px 0;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
.progress-bar {
|
|
829
|
+
height: 8px;
|
|
830
|
+
background: #e5e7eb;
|
|
831
|
+
border-radius: 4px;
|
|
832
|
+
overflow: hidden;
|
|
833
|
+
margin-bottom: 8px;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
.progress-fill {
|
|
837
|
+
height: 100%;
|
|
838
|
+
background: #3b82f6;
|
|
839
|
+
transition: width 0.3s ease;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
.submit-survey-btn {
|
|
843
|
+
width: 100%;
|
|
844
|
+
padding: 12px 24px;
|
|
845
|
+
background: #3b82f6;
|
|
846
|
+
color: white;
|
|
847
|
+
border: none;
|
|
848
|
+
border-radius: 8px;
|
|
849
|
+
font-size: 16px;
|
|
850
|
+
cursor: pointer;
|
|
851
|
+
transition: all 0.2s;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
.submit-survey-btn:hover:not(.disabled) {
|
|
855
|
+
background: #2563eb;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
.submit-survey-btn.disabled {
|
|
859
|
+
background: #d1d5db;
|
|
860
|
+
color: #9ca3af;
|
|
861
|
+
cursor: not-allowed;
|
|
862
|
+
}
|
|
863
|
+
</style>
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
## Styling
|
|
867
|
+
|
|
868
|
+
The GroupRadioBox component can be styled using CSS custom properties:
|
|
869
|
+
|
|
870
|
+
```css
|
|
871
|
+
.uniface-group-box {
|
|
872
|
+
--radio-spacing: 8px;
|
|
873
|
+
--radio-padding: 4px 8px;
|
|
874
|
+
--border-color: #e2e8f0;
|
|
875
|
+
--background-color: #ffffff;
|
|
876
|
+
--hover-background: #f9fafb;
|
|
877
|
+
--selected-color: #3b82f6;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/* Variant-specific styling */
|
|
881
|
+
.uniface-group-box.outlined {
|
|
882
|
+
border: 1px solid var(--border-color);
|
|
883
|
+
border-radius: 6px;
|
|
884
|
+
padding: 12px;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
.uniface-group-box.filled {
|
|
888
|
+
background-color: #f8fafc;
|
|
889
|
+
border-radius: 6px;
|
|
890
|
+
padding: 12px;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
.uniface-group-box.compact {
|
|
894
|
+
--radio-spacing: 4px;
|
|
895
|
+
--radio-padding: 2px 4px;
|
|
896
|
+
}
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
## Accessibility
|
|
900
|
+
|
|
901
|
+
The GroupRadioBox component includes several accessibility features:
|
|
902
|
+
|
|
903
|
+
- Keyboard navigation between radio buttons
|
|
904
|
+
- Focus management with `setFocus()` method
|
|
905
|
+
- ARIA labels and radio group semantics
|
|
906
|
+
- Screen reader announcements for selection changes
|
|
907
|
+
- Proper tab order management
|
|
908
|
+
|
|
909
|
+
## Best Practices
|
|
910
|
+
|
|
911
|
+
1. **Option Management**: Keep option arrays stable to prevent unnecessary re-renders
|
|
912
|
+
2. **Default Selection**: Always provide a sensible default value for better UX
|
|
913
|
+
3. **Validation**: Implement proper validation for required selections
|
|
914
|
+
4. **User Feedback**: Provide clear visual feedback for selection changes
|
|
915
|
+
5. **Accessibility**: Always provide meaningful labels and group descriptions
|
|
916
|
+
6. **State Management**: Handle focus/blur events appropriately for form validation
|
|
917
|
+
|
|
918
|
+
## License
|
|
919
|
+
|
|
920
|
+
MIT
|