@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.
- package/README.md +320 -1
- package/README_CN.md +392 -0
- package/dist/accordion/Accordion.svelte +1 -1
- package/dist/action-bar/ActionBar.svelte +7 -1
- package/dist/attachment-files/FileRender.svelte +1 -1
- package/dist/attachment-files/FileUploadBar.svelte +7 -6
- package/dist/attachment-files/FileUploadPanel.svelte +2 -2
- package/dist/base-calendar/DateContext.js +5 -4
- package/dist/base-calendar/YearPickupPanel.svelte +4 -4
- package/dist/card/Card.svelte +1 -1
- package/dist/card/Card.svelte.d.ts +1 -1
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +2 -3
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +46 -1
- package/dist/cascade-options-select/CascadePanel.svelte +1 -1
- package/dist/checkbox/CheckBox.svelte +1 -1
- package/dist/color-picker/ColorPicker.svelte +9 -9
- package/dist/color-picker/ColorPicker.svelte.d.ts +0 -2
- package/dist/color-picker/ColorPickerPanel.svelte +11 -15
- package/dist/color-picker/ColorPickerPanel.svelte.d.ts +1 -1
- package/dist/common/CommonPicker.svelte +2 -2
- package/dist/common/CommonPicker.svelte.d.ts +1 -1
- package/dist/common/MouseClickHandler.d.ts +1 -1
- package/dist/common/Popover.svelte +28 -6
- package/dist/common/Popover.svelte.d.ts +9 -3
- package/dist/common/uniface-utils.js +6 -4
- package/dist/common-editor/CommonEditor.svelte +1 -1
- package/dist/common-editor/CommonEditor.svelte.d.ts +1 -1
- package/dist/common-editor/NumberInput.svelte +1 -1
- package/dist/common-editor/NumberInput.svelte.d.ts +1 -1
- package/dist/concise-data-table/ConciseListTable.svelte +7 -2
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +1 -0
- package/dist/concise-data-table/DataRow.svelte +1 -1
- package/dist/concise-data-table/TableOptions.d.ts +1 -1
- package/dist/data-table/DataTable.svelte +1 -1
- package/dist/data-table/parts/ActionsPanel.svelte +4 -3
- package/dist/data-table/parts/ActionsRow.svelte +3 -3
- package/dist/data-table/parts/ContentPanel.svelte +3 -2
- package/dist/data-table/parts/FixedColumnsPanel.svelte +0 -1
- package/dist/data-table/parts/FixedColumnsPanel.svelte.d.ts +1 -2
- package/dist/data-table/parts/FixedHeaderPanel.svelte +2 -2
- package/dist/data-table/parts/FixedRow.svelte +2 -1
- package/dist/data-table/parts/FixedRow.svelte.d.ts +1 -1
- package/dist/data-table/parts/HrefCell.svelte +23 -2
- package/dist/data-table/parts/PopupMenu.svelte +25 -2
- package/dist/data-table/parts/PopupMenu.svelte.d.ts +8 -1
- package/dist/date-picker/DatePicker.svelte +0 -1
- package/dist/date-picker/DateTimePicker.svelte +3 -3
- package/dist/date-picker/ScrollBar.svelte +4 -7
- package/dist/date-range/DateRangeEditor.svelte +1 -1
- package/dist/dialog/CommonDialog.svelte +8 -5
- package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
- package/dist/dialog/Dialog.svelte +37 -12
- 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/{common-editor/DateInput.svelte.d.ts → dialog/DialogWrapper.svelte.d.ts} +6 -13
- package/dist/dialog/Dialogs.js +1 -1
- package/dist/dialog/ModalResult.d.ts +5 -0
- package/dist/dialog/ModalResult.js +5 -0
- package/dist/drawer/Drawer.svelte +1 -1
- package/dist/form-field/FormField.svelte +2 -1
- package/dist/form-field/FormField.svelte.d.ts +1 -0
- package/dist/form-panel/flex-row-form/FormContainer.svelte +1 -1
- package/dist/form-panel/grid-form/EmptyCell.svelte +8 -7
- package/dist/form-panel/grid-form/EmptyCell.svelte.d.ts +2 -2
- package/dist/form-panel/grid-form/GridField.svelte +1 -1
- package/dist/i18nRes/i18nRes.d.ts +2 -0
- package/dist/i18nRes/i18nRes.js +44 -0
- package/dist/i18nRes/index.d.ts +2 -0
- package/dist/i18nRes/index.js +2 -0
- package/dist/image-files/ImageFilesField.svelte +1 -1
- package/dist/indicator/IndicatorBoard.svelte +1 -1
- package/dist/inline-cell-editor/InvalidEditor.svelte +1 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +6 -6
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +1 -1
- package/dist/layout/flex/FlexBlock.svelte +1 -1
- package/dist/lookup-editor/LookupEditor.svelte +1 -1
- package/dist/memo-editor/MemoEditor.svelte +2 -2
- package/dist/message-box/IMessageBox.d.ts +2 -4
- package/dist/message-box/IMessageBox.js +4 -6
- package/dist/message-box/MessageBoxBoard.svelte +1 -3
- package/dist/options-multi-select/OptionsMultiSelect.svelte +1 -1
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +2 -2
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +1 -1
- package/dist/property-editor/PropertyEditor.svelte +3 -3
- package/dist/text-editor/PasswordEditor.svelte +1 -1
- package/dist/transfer/Transfer.svelte +17 -12
- package/dist/transfer/Transfer.svelte.d.ts +0 -1
- package/dist/unit-number-editor/UnitNumberEditor.svelte +2 -2
- 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 +53 -13
- package/dist/common-editor/DateInput.svelte +0 -27
- package/dist/i18n_resources/index.d.ts +0 -3
- package/dist/i18n_resources/index.js +0 -3
- /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.d.ts +0 -0
- /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.js +0 -0
- /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.d.ts +0 -0
- /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.js +0 -0
|
@@ -0,0 +1,847 @@
|
|
|
1
|
+
# Form Components
|
|
2
|
+
|
|
3
|
+
The Uniface Element Form Components provide a comprehensive set of input controls for building rich forms and data entry interfaces in Svelte applications. These components are designed with consistent styling, validation support, and flexible configuration options.
|
|
4
|
+
|
|
5
|
+
> **Important Note**: Form components are typically used standalone and don't require labels. When labels and error handling are needed, use them in combination with `FormField` component for displaying labels and error messages. For advanced validation, integrate with [@ticatec/web-bean-validator](https://github.com/ticatec/web-bean-validator) for comprehensive form validation.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [FormField Integration](#formfield-integration)
|
|
10
|
+
- [Validation with Web Bean Validator](#validation-with-web-bean-validator)
|
|
11
|
+
- [Architecture Overview](#architecture-overview)
|
|
12
|
+
- [TextEditor Component](#texteditor-component)
|
|
13
|
+
- [NumberEditor Component](#numbereditor-component)
|
|
14
|
+
- [TimeEditor Component](#timeeditor-component)
|
|
15
|
+
- [UnitNumberEditor Component](#unitnumbereditor-component)
|
|
16
|
+
- [CheckBox Component](#checkbox-component)
|
|
17
|
+
- [RadioButton Component](#radiobutton-component)
|
|
18
|
+
- [OptionsSelect Component](#optionsselect-component)
|
|
19
|
+
- [OptionsMultiSelect Component](#optionsmultiselect-component)
|
|
20
|
+
- [PromptsTextEditor Component](#promptstexteditor-component)
|
|
21
|
+
- [Switch Component](#switch-component)
|
|
22
|
+
- [InputOptionsSelect Component](#inputoptionsselect-component)
|
|
23
|
+
- [LookupEditor Component](#lookupeditor-component)
|
|
24
|
+
- [DatePicker Component](#datepicker-component)
|
|
25
|
+
- [DateTimePicker Component](#datetimepicker-component)
|
|
26
|
+
- [CascadeOptionsSelect Component](#cascadeoptionsselect-component)
|
|
27
|
+
- [Common Properties](#common-properties)
|
|
28
|
+
- [Display Modes](#display-modes)
|
|
29
|
+
- [Styling and Theming](#styling-and-theming)
|
|
30
|
+
- [Validation and Events](#validation-and-events)
|
|
31
|
+
- [Best Practices](#best-practices)
|
|
32
|
+
- [Accessibility](#accessibility)
|
|
33
|
+
|
|
34
|
+
## FormField Integration
|
|
35
|
+
|
|
36
|
+
Form components work seamlessly with the `FormField` component to provide labels, error messages, and consistent form layouts:
|
|
37
|
+
|
|
38
|
+
```svelte
|
|
39
|
+
<script lang="ts">
|
|
40
|
+
import TextEditor, FormField from '@ticatec/uniface-element/TextEditor, FormField';
|
|
41
|
+
|
|
42
|
+
let userEmail = '';
|
|
43
|
+
let emailError = '';
|
|
44
|
+
|
|
45
|
+
const validateEmail = (value: string) => {
|
|
46
|
+
if (!value) {
|
|
47
|
+
emailError = 'Email is required';
|
|
48
|
+
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
|
|
49
|
+
emailError = 'Please enter a valid email address';
|
|
50
|
+
} else {
|
|
51
|
+
emailError = '';
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<FormField
|
|
57
|
+
label="Email Address"
|
|
58
|
+
error={emailError}
|
|
59
|
+
required={true}
|
|
60
|
+
>
|
|
61
|
+
<TextEditor
|
|
62
|
+
bind:value={userEmail}
|
|
63
|
+
placeholder="Enter your email"
|
|
64
|
+
onChange={validateEmail}
|
|
65
|
+
/>
|
|
66
|
+
</FormField>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Validation with Web Bean Validator
|
|
70
|
+
|
|
71
|
+
For advanced form validation, integrate with `@ticatec/web-bean-validator` for declarative, type-safe validation:
|
|
72
|
+
|
|
73
|
+
### Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm install @ticatec/web-bean-validator
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Basic Usage
|
|
80
|
+
|
|
81
|
+
```svelte
|
|
82
|
+
<script lang="ts">
|
|
83
|
+
import TextEditor, NumberEditor, FormField from '@ticatec/uniface-element/TextEditor, NumberEditor, FormField';
|
|
84
|
+
import beanValidator from '@ticatec/web-bean-validator';
|
|
85
|
+
import { StringValidator, NumberValidator } from '@ticatec/entity-validator';
|
|
86
|
+
|
|
87
|
+
let formData = {
|
|
88
|
+
name: '',
|
|
89
|
+
email: '',
|
|
90
|
+
age: null
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
let errors = {};
|
|
94
|
+
|
|
95
|
+
// Define validation rules
|
|
96
|
+
const validationRules = [
|
|
97
|
+
new StringValidator('name', { minLen: 2, required: true }),
|
|
98
|
+
new StringValidator('email', {
|
|
99
|
+
required: true,
|
|
100
|
+
format: {
|
|
101
|
+
regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
102
|
+
message: 'Invalid email format'
|
|
103
|
+
}
|
|
104
|
+
}),
|
|
105
|
+
new NumberValidator('age', { min: 18, max: 120, required: false })
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
const validateForm = () => {
|
|
109
|
+
const result = beanValidator.validate(formData, validationRules);
|
|
110
|
+
|
|
111
|
+
// Convert validation results to error object
|
|
112
|
+
errors = {};
|
|
113
|
+
if (result.errors) {
|
|
114
|
+
result.errors.forEach(error => {
|
|
115
|
+
errors[error.field] = error.message;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return result.isValid;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const handleSubmit = () => {
|
|
123
|
+
if (validateForm()) {
|
|
124
|
+
console.log('Form is valid:', formData);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<form class="validation-form">
|
|
130
|
+
<FormField label="Full Name" error={errors.name} required>
|
|
131
|
+
<TextEditor
|
|
132
|
+
bind:value={formData.name}
|
|
133
|
+
placeholder="Enter your full name"
|
|
134
|
+
on:blur={validateForm}
|
|
135
|
+
/>
|
|
136
|
+
</FormField>
|
|
137
|
+
|
|
138
|
+
<FormField label="Email" error={errors.email} required>
|
|
139
|
+
<TextEditor
|
|
140
|
+
bind:value={formData.email}
|
|
141
|
+
placeholder="Enter your email"
|
|
142
|
+
on:blur={validateForm}
|
|
143
|
+
/>
|
|
144
|
+
</FormField>
|
|
145
|
+
|
|
146
|
+
<FormField label="Age" error={errors.age}>
|
|
147
|
+
<NumberEditor
|
|
148
|
+
bind:value={formData.age}
|
|
149
|
+
placeholder="Enter your age"
|
|
150
|
+
min={18}
|
|
151
|
+
max={120}
|
|
152
|
+
precision={0}
|
|
153
|
+
on:blur={validateForm}
|
|
154
|
+
/>
|
|
155
|
+
</FormField>
|
|
156
|
+
|
|
157
|
+
<button type="button" on:click={handleSubmit}>
|
|
158
|
+
Submit Form
|
|
159
|
+
</button>
|
|
160
|
+
</form>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Advanced Validation Example
|
|
164
|
+
|
|
165
|
+
```svelte
|
|
166
|
+
<script lang="ts">
|
|
167
|
+
import DatePicker, FormField from '@ticatec/uniface-element/DatePicker, FormField';
|
|
168
|
+
import beanValidator from '@ticatec/web-bean-validator';
|
|
169
|
+
import { DateValidator } from '@ticatec/entity-validator';
|
|
170
|
+
|
|
171
|
+
let projectData = {
|
|
172
|
+
startDate: null,
|
|
173
|
+
endDate: null
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
let errors = {};
|
|
177
|
+
|
|
178
|
+
// Custom validation function
|
|
179
|
+
const validateDateRange = (value: any, data: any) => {
|
|
180
|
+
if (data.endDate && data.startDate && data.endDate < data.startDate) {
|
|
181
|
+
return "End date cannot be earlier than start date";
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const validationRules = [
|
|
186
|
+
new DateValidator('startDate', {
|
|
187
|
+
required: true,
|
|
188
|
+
minDaysAfter: 0 // Cannot be in the past
|
|
189
|
+
}),
|
|
190
|
+
new DateValidator('endDate', {
|
|
191
|
+
required: true,
|
|
192
|
+
customCheck: validateDateRange
|
|
193
|
+
})
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
const validateDates = () => {
|
|
197
|
+
const result = beanValidator.validate(projectData, validationRules);
|
|
198
|
+
|
|
199
|
+
errors = {};
|
|
200
|
+
if (result.errors) {
|
|
201
|
+
result.errors.forEach(error => {
|
|
202
|
+
errors[error.field] = error.message;
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
</script>
|
|
207
|
+
|
|
208
|
+
<div class="date-range-form">
|
|
209
|
+
<FormField label="Start Date" error={errors.startDate} required>
|
|
210
|
+
<DatePicker
|
|
211
|
+
bind:value={projectData.startDate}
|
|
212
|
+
onChange={validateDates}
|
|
213
|
+
/>
|
|
214
|
+
</FormField>
|
|
215
|
+
|
|
216
|
+
<FormField label="End Date" error={errors.endDate} required>
|
|
217
|
+
<DatePicker
|
|
218
|
+
bind:value={projectData.endDate}
|
|
219
|
+
onChange={validateDates}
|
|
220
|
+
/>
|
|
221
|
+
</FormField>
|
|
222
|
+
</div>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Architecture Overview
|
|
226
|
+
|
|
227
|
+
Form components in Uniface Element follow a consistent architecture:
|
|
228
|
+
|
|
229
|
+
- **CommonEditor**: Base wrapper providing consistent styling and behavior
|
|
230
|
+
- **CommonPicker**: Base for dropdown/picker components
|
|
231
|
+
- **DisplayMode**: Support for Edit/View/Display modes
|
|
232
|
+
- **Type Safety**: Full TypeScript support with proper type definitions
|
|
233
|
+
- **Event Handling**: Consistent onChange/onSelected event patterns
|
|
234
|
+
- **Icon Integration**: Uses `@ticatec/uniface-google-material-icons`
|
|
235
|
+
|
|
236
|
+
```mermaid
|
|
237
|
+
graph TD
|
|
238
|
+
A[Form Components] --> B[Text Inputs]
|
|
239
|
+
A --> C[Numeric Inputs]
|
|
240
|
+
A --> D[Selection Inputs]
|
|
241
|
+
A --> E[Date/Time Inputs]
|
|
242
|
+
A --> F[Boolean Inputs]
|
|
243
|
+
|
|
244
|
+
B --> B1[TextEditor]
|
|
245
|
+
B --> B2[PromptsTextEditor]
|
|
246
|
+
|
|
247
|
+
C --> C1[NumberEditor]
|
|
248
|
+
C --> C2[UnitNumberEditor]
|
|
249
|
+
C --> C3[TimeEditor]
|
|
250
|
+
|
|
251
|
+
D --> D1[OptionsSelect]
|
|
252
|
+
D --> D2[OptionsMultiSelect]
|
|
253
|
+
D --> D3[CascadeOptionsSelect]
|
|
254
|
+
D --> D4[InputOptionsSelect]
|
|
255
|
+
|
|
256
|
+
E --> E1[DatePicker]
|
|
257
|
+
E --> E2[DateTimePicker]
|
|
258
|
+
|
|
259
|
+
F --> F1[CheckBox]
|
|
260
|
+
F --> F2[RadioButton]
|
|
261
|
+
F --> F3[Switch]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## TextEditor Component
|
|
265
|
+
|
|
266
|
+
A versatile text input component with support for prefixes, suffixes, and various styling options.
|
|
267
|
+
|
|
268
|
+
### Basic Usage
|
|
269
|
+
|
|
270
|
+
```svelte
|
|
271
|
+
<script lang="ts">
|
|
272
|
+
import TextEditor from '@ticatec/uniface-element/TextEditor';
|
|
273
|
+
|
|
274
|
+
let userInput = '';
|
|
275
|
+
|
|
276
|
+
const handleChange = (value: string) => {
|
|
277
|
+
console.log('Text changed:', value);
|
|
278
|
+
};
|
|
279
|
+
</script>
|
|
280
|
+
|
|
281
|
+
<TextEditor
|
|
282
|
+
bind:value={userInput}
|
|
283
|
+
placeholder="Enter text here"
|
|
284
|
+
onChange={handleChange}
|
|
285
|
+
/>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Advanced Features
|
|
289
|
+
|
|
290
|
+
```svelte
|
|
291
|
+
<script lang="ts">
|
|
292
|
+
import TextEditor from '@ticatec/uniface-element/TextEditor';
|
|
293
|
+
|
|
294
|
+
let email = '';
|
|
295
|
+
let searchTerm = '';
|
|
296
|
+
|
|
297
|
+
const handleEmailChange = (value: string) => {
|
|
298
|
+
// Validate email format
|
|
299
|
+
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
300
|
+
console.log('Email valid:', isValid);
|
|
301
|
+
};
|
|
302
|
+
</script>
|
|
303
|
+
|
|
304
|
+
<!-- Email input with validation -->
|
|
305
|
+
<TextEditor
|
|
306
|
+
bind:value={email}
|
|
307
|
+
placeholder="Enter email address"
|
|
308
|
+
prefix="@"
|
|
309
|
+
variant="outlined"
|
|
310
|
+
onChange={handleEmailChange}
|
|
311
|
+
>
|
|
312
|
+
<i class="icon_google_email" slot="leading-icon"></i>
|
|
313
|
+
</TextEditor>
|
|
314
|
+
|
|
315
|
+
<!-- Search input with clear button -->
|
|
316
|
+
<TextEditor
|
|
317
|
+
bind:value={searchTerm}
|
|
318
|
+
placeholder="Search..."
|
|
319
|
+
removable={true}
|
|
320
|
+
compact={true}
|
|
321
|
+
>
|
|
322
|
+
<i class="icon_google_search" slot="leading-icon"></i>
|
|
323
|
+
</TextEditor>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### TextEditor Properties
|
|
327
|
+
|
|
328
|
+
| Property | Type | Default | Description |
|
|
329
|
+
|----------|------|---------|-------------|
|
|
330
|
+
| `value` | `string` | `''` | Input value |
|
|
331
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
332
|
+
| `disabled` | `boolean` | `false` | Disable input |
|
|
333
|
+
| `readonly` | `boolean` | `false` | Read-only mode |
|
|
334
|
+
| `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | Visual style variant |
|
|
335
|
+
| `compact` | `boolean` | `false` | Compact layout |
|
|
336
|
+
| `prefix` | `string` | `''` | Text prefix |
|
|
337
|
+
| `suffix` | `string` | `''` | Text suffix |
|
|
338
|
+
| `removable` | `boolean` | `true` | Show clear button |
|
|
339
|
+
| `displayMode` | `DisplayMode` | `DisplayMode.Edit` | Display mode |
|
|
340
|
+
| `onChange` | `(value: string) => void` | - | Change event handler |
|
|
341
|
+
| `setFocus` | `() => void` | - | Focus method |
|
|
342
|
+
|
|
343
|
+
## NumberEditor Component
|
|
344
|
+
|
|
345
|
+
Specialized numeric input with precision control, formatting, and validation.
|
|
346
|
+
|
|
347
|
+
### Basic Usage
|
|
348
|
+
|
|
349
|
+
```svelte
|
|
350
|
+
<script lang="ts">
|
|
351
|
+
import NumberEditor from '@ticatec/uniface-element/NumberEditor';
|
|
352
|
+
|
|
353
|
+
let amount = null;
|
|
354
|
+
let quantity = 1;
|
|
355
|
+
|
|
356
|
+
const handleAmountChange = (value: number | null) => {
|
|
357
|
+
console.log('Amount:', value);
|
|
358
|
+
};
|
|
359
|
+
</script>
|
|
360
|
+
|
|
361
|
+
<NumberEditor
|
|
362
|
+
bind:value={amount}
|
|
363
|
+
placeholder="Enter amount"
|
|
364
|
+
precision={2}
|
|
365
|
+
allowNegative={false}
|
|
366
|
+
onChange={handleAmountChange}
|
|
367
|
+
/>
|
|
368
|
+
|
|
369
|
+
<NumberEditor
|
|
370
|
+
bind:value={quantity}
|
|
371
|
+
min={1}
|
|
372
|
+
max={100}
|
|
373
|
+
precision={0}
|
|
374
|
+
prefix="Qty: "
|
|
375
|
+
/>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Currency and Formatting
|
|
379
|
+
|
|
380
|
+
```svelte
|
|
381
|
+
<script lang="ts">
|
|
382
|
+
let price = 99.99;
|
|
383
|
+
let percentage = 15.5;
|
|
384
|
+
let weight = 2.5;
|
|
385
|
+
</script>
|
|
386
|
+
|
|
387
|
+
<!-- Currency input -->
|
|
388
|
+
<NumberEditor
|
|
389
|
+
bind:value={price}
|
|
390
|
+
prefix="$"
|
|
391
|
+
precision={2}
|
|
392
|
+
allowNegative={false}
|
|
393
|
+
placeholder="0.00"
|
|
394
|
+
/>
|
|
395
|
+
|
|
396
|
+
<!-- Percentage input -->
|
|
397
|
+
<NumberEditor
|
|
398
|
+
bind:value={percentage}
|
|
399
|
+
suffix="%"
|
|
400
|
+
precision={1}
|
|
401
|
+
min={0}
|
|
402
|
+
max={100}
|
|
403
|
+
/>
|
|
404
|
+
|
|
405
|
+
<!-- Weight with unit -->
|
|
406
|
+
<NumberEditor
|
|
407
|
+
bind:value={weight}
|
|
408
|
+
suffix="kg"
|
|
409
|
+
precision={2}
|
|
410
|
+
allowNegative={false}
|
|
411
|
+
>
|
|
412
|
+
<i class="icon_google_scale" slot="leading-icon"></i>
|
|
413
|
+
</NumberEditor>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### NumberEditor Properties
|
|
417
|
+
|
|
418
|
+
| Property | Type | Default | Description |
|
|
419
|
+
|----------|------|---------|-------------|
|
|
420
|
+
| `value` | `number \| null` | `null` | Numeric value |
|
|
421
|
+
| `precision` | `number \| null` | `null` | Decimal places |
|
|
422
|
+
| `min` | `number \| null` | `null` | Minimum value |
|
|
423
|
+
| `max` | `number \| null` | `null` | Maximum value |
|
|
424
|
+
| `allowNegative` | `boolean` | `false` | Allow negative numbers |
|
|
425
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
426
|
+
| `prefix` | `string` | `''` | Text prefix |
|
|
427
|
+
| `suffix` | `string` | `''` | Text suffix |
|
|
428
|
+
| `removable` | `boolean` | `true` | Show clear button |
|
|
429
|
+
| `onChange` | `OnChangeHandler<number \| null>` | - | Change event handler |
|
|
430
|
+
|
|
431
|
+
## CheckBox Component
|
|
432
|
+
|
|
433
|
+
Boolean input component with support for indeterminate state.
|
|
434
|
+
|
|
435
|
+
### Basic Usage
|
|
436
|
+
|
|
437
|
+
```svelte
|
|
438
|
+
<script lang="ts">
|
|
439
|
+
import CheckBox from '@ticatec/uniface-element/CheckBox';
|
|
440
|
+
|
|
441
|
+
let agreedToTerms = false;
|
|
442
|
+
let enableNotifications = true;
|
|
443
|
+
|
|
444
|
+
const handleTermsChange = (checked: boolean) => {
|
|
445
|
+
console.log('Terms agreed:', checked);
|
|
446
|
+
};
|
|
447
|
+
</script>
|
|
448
|
+
|
|
449
|
+
<CheckBox
|
|
450
|
+
bind:value={agreedToTerms}
|
|
451
|
+
label="I agree to the terms and conditions"
|
|
452
|
+
onChange={handleTermsChange}
|
|
453
|
+
/>
|
|
454
|
+
|
|
455
|
+
<CheckBox
|
|
456
|
+
bind:value={enableNotifications}
|
|
457
|
+
label="Enable notifications"
|
|
458
|
+
compact={true}
|
|
459
|
+
/>
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Checkbox Groups
|
|
463
|
+
|
|
464
|
+
```svelte
|
|
465
|
+
<script lang="ts">
|
|
466
|
+
let selectedFeatures = {
|
|
467
|
+
darkMode: false,
|
|
468
|
+
notifications: true,
|
|
469
|
+
autoSave: true,
|
|
470
|
+
analytics: false
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
const features = [
|
|
474
|
+
{ key: 'darkMode', label: 'Dark Mode' },
|
|
475
|
+
{ key: 'notifications', label: 'Push Notifications' },
|
|
476
|
+
{ key: 'autoSave', label: 'Auto Save' },
|
|
477
|
+
{ key: 'analytics', label: 'Usage Analytics' }
|
|
478
|
+
];
|
|
479
|
+
|
|
480
|
+
const handleFeatureChange = (key: string) => (checked: boolean) => {
|
|
481
|
+
selectedFeatures[key] = checked;
|
|
482
|
+
selectedFeatures = { ...selectedFeatures };
|
|
483
|
+
};
|
|
484
|
+
</script>
|
|
485
|
+
|
|
486
|
+
<div class="checkbox-group">
|
|
487
|
+
<h3>Application Settings</h3>
|
|
488
|
+
{#each features as feature}
|
|
489
|
+
<CheckBox
|
|
490
|
+
value={selectedFeatures[feature.key]}
|
|
491
|
+
label={feature.label}
|
|
492
|
+
onChange={handleFeatureChange(feature.key)}
|
|
493
|
+
/>
|
|
494
|
+
{/each}
|
|
495
|
+
</div>
|
|
496
|
+
|
|
497
|
+
<style>
|
|
498
|
+
.checkbox-group {
|
|
499
|
+
display: flex;
|
|
500
|
+
flex-direction: column;
|
|
501
|
+
gap: 12px;
|
|
502
|
+
}
|
|
503
|
+
</style>
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### CheckBox Properties
|
|
507
|
+
|
|
508
|
+
| Property | Type | Default | Description |
|
|
509
|
+
|----------|------|---------|-------------|
|
|
510
|
+
| `value` | `boolean` | `false` | Checkbox state |
|
|
511
|
+
| `label` | `string \| null` | `null` | Checkbox label |
|
|
512
|
+
| `indeterminate` | `boolean` | `false` | Indeterminate state |
|
|
513
|
+
| `disabled` | `boolean` | `false` | Disable checkbox |
|
|
514
|
+
| `readonly` | `boolean` | `false` | Read-only mode |
|
|
515
|
+
| `compact` | `boolean` | `false` | Compact layout |
|
|
516
|
+
| `autoFocus` | `boolean` | `false` | Auto focus on mount |
|
|
517
|
+
| `onChange` | `OnChangeHandler<boolean>` | - | Change event handler |
|
|
518
|
+
| `onClick` | `(event: MouseEvent) => void` | - | Click event handler |
|
|
519
|
+
| `setFocus` | `() => void` | - | Focus method |
|
|
520
|
+
|
|
521
|
+
## OptionsSelect Component
|
|
522
|
+
|
|
523
|
+
Dropdown selection component with search and filtering capabilities.
|
|
524
|
+
|
|
525
|
+
### Basic Usage
|
|
526
|
+
|
|
527
|
+
```svelte
|
|
528
|
+
<script lang="ts">
|
|
529
|
+
import OptionsSelect from '@ticatec/uniface-element/OptionsSelect';
|
|
530
|
+
|
|
531
|
+
let selectedCountry = null;
|
|
532
|
+
let selectedCategory = 'electronics';
|
|
533
|
+
|
|
534
|
+
const countries = [
|
|
535
|
+
{ code: 'US', text: 'United States' },
|
|
536
|
+
{ code: 'UK', text: 'United Kingdom' },
|
|
537
|
+
{ code: 'CA', text: 'Canada' },
|
|
538
|
+
{ code: 'AU', text: 'Australia' }
|
|
539
|
+
];
|
|
540
|
+
|
|
541
|
+
const categories = [
|
|
542
|
+
{ code: 'electronics', text: 'Electronics' },
|
|
543
|
+
{ code: 'clothing', text: 'Clothing' },
|
|
544
|
+
{ code: 'books', text: 'Books' },
|
|
545
|
+
{ code: 'home', text: 'Home & Garden' }
|
|
546
|
+
];
|
|
547
|
+
|
|
548
|
+
const handleCountryChange = (value: any) => {
|
|
549
|
+
console.log('Selected country:', value);
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
const handleCountrySelected = (item: any) => {
|
|
553
|
+
console.log('Selected country object:', item);
|
|
554
|
+
};
|
|
555
|
+
</script>
|
|
556
|
+
|
|
557
|
+
<OptionsSelect
|
|
558
|
+
bind:value={selectedCountry}
|
|
559
|
+
options={countries}
|
|
560
|
+
keyField="code"
|
|
561
|
+
textField="text"
|
|
562
|
+
placeholder="Select a country"
|
|
563
|
+
onChange={handleCountryChange}
|
|
564
|
+
onSelected={handleCountrySelected}
|
|
565
|
+
/>
|
|
566
|
+
|
|
567
|
+
<OptionsSelect
|
|
568
|
+
bind:value={selectedCategory}
|
|
569
|
+
options={categories}
|
|
570
|
+
keyField="code"
|
|
571
|
+
textField="text"
|
|
572
|
+
mandatory={true}
|
|
573
|
+
/>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### OptionsSelect Properties
|
|
577
|
+
|
|
578
|
+
| Property | Type | Default | Description |
|
|
579
|
+
|----------|------|---------|-------------|
|
|
580
|
+
| `value` | `any` | `null` | Selected value |
|
|
581
|
+
| `options` | `Array<any>` | - | Available options |
|
|
582
|
+
| `keyField` | `string` | `'code'` | Key field name |
|
|
583
|
+
| `textField` | `string` | `'text'` | Display text field |
|
|
584
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
585
|
+
| `emptyText` | `string` | - | Text for null value |
|
|
586
|
+
| `mandatory` | `boolean` | `false` | Require selection |
|
|
587
|
+
| `disableOptions` | `string[]` | `[]` | Disabled option keys |
|
|
588
|
+
| `hideOptions` | `string[]` | `[]` | Hidden option keys |
|
|
589
|
+
| `itemRender` | `any` | `null` | Custom item renderer |
|
|
590
|
+
| `menu$height` | `number` | `0` | Menu height (px) |
|
|
591
|
+
| `onChange` | `OnChangeHandler<any>` | - | Change event handler |
|
|
592
|
+
| `onSelected` | `OnSelectedHandler` | - | Selection event handler |
|
|
593
|
+
| `setFocus` | `() => void` | - | Focus method |
|
|
594
|
+
|
|
595
|
+
## Common Properties
|
|
596
|
+
|
|
597
|
+
Most form components share these common properties:
|
|
598
|
+
|
|
599
|
+
### Styling Properties
|
|
600
|
+
|
|
601
|
+
| Property | Type | Default | Description |
|
|
602
|
+
|----------|------|---------|-------------|
|
|
603
|
+
| `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | Visual style variant |
|
|
604
|
+
| `compact` | `boolean` | `false` | Compact layout mode |
|
|
605
|
+
| `style` | `string` | `''` | Custom CSS styles |
|
|
606
|
+
| `class` | `string` | `''` | CSS class name |
|
|
607
|
+
|
|
608
|
+
### State Properties
|
|
609
|
+
|
|
610
|
+
| Property | Type | Default | Description |
|
|
611
|
+
|----------|------|---------|-------------|
|
|
612
|
+
| `disabled` | `boolean` | `false` | Disable component |
|
|
613
|
+
| `readonly` | `boolean` | `false` | Read-only mode |
|
|
614
|
+
| `mandatory` | `boolean` | `false` | Required field |
|
|
615
|
+
|
|
616
|
+
### Behavioral Properties
|
|
617
|
+
|
|
618
|
+
| Property | Type | Default | Description |
|
|
619
|
+
|----------|------|---------|-------------|
|
|
620
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
621
|
+
| `displayMode` | `DisplayMode` | `DisplayMode.Edit` | Display mode |
|
|
622
|
+
|
|
623
|
+
## Display Modes
|
|
624
|
+
|
|
625
|
+
Components support different display modes:
|
|
626
|
+
|
|
627
|
+
```typescript
|
|
628
|
+
enum DisplayMode {
|
|
629
|
+
Edit = 'edit', // Full editing capabilities
|
|
630
|
+
View = 'view', // Read-only display
|
|
631
|
+
Display = 'display' // Minimal display mode
|
|
632
|
+
}
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Usage Example
|
|
636
|
+
|
|
637
|
+
```svelte
|
|
638
|
+
<script lang="ts">
|
|
639
|
+
import DisplayMode from '@ticatec/uniface-element/DisplayMode';
|
|
640
|
+
|
|
641
|
+
let currentMode = DisplayMode.Edit;
|
|
642
|
+
let userInput = 'Sample text';
|
|
643
|
+
</script>
|
|
644
|
+
|
|
645
|
+
<!-- Edit mode - fully interactive -->
|
|
646
|
+
<TextEditor
|
|
647
|
+
bind:value={userInput}
|
|
648
|
+
displayMode={DisplayMode.Edit}
|
|
649
|
+
placeholder="Edit me"
|
|
650
|
+
/>
|
|
651
|
+
|
|
652
|
+
<!-- View mode - read-only display -->
|
|
653
|
+
<TextEditor
|
|
654
|
+
value={userInput}
|
|
655
|
+
displayMode={DisplayMode.View}
|
|
656
|
+
/>
|
|
657
|
+
|
|
658
|
+
<!-- Display mode - minimal presentation -->
|
|
659
|
+
<TextEditor
|
|
660
|
+
value={userInput}
|
|
661
|
+
displayMode={DisplayMode.Display}
|
|
662
|
+
/>
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
## Styling and Theming
|
|
666
|
+
|
|
667
|
+
### CSS Custom Properties
|
|
668
|
+
|
|
669
|
+
Form components use CSS custom properties for theming:
|
|
670
|
+
|
|
671
|
+
```css
|
|
672
|
+
:root {
|
|
673
|
+
--uniface-primary-color: #007bff;
|
|
674
|
+
--uniface-border-color: #ddd;
|
|
675
|
+
--uniface-background-color: #fff;
|
|
676
|
+
--uniface-text-color: #333;
|
|
677
|
+
--uniface-disabled-color: #999;
|
|
678
|
+
--uniface-focus-color: #0056b3;
|
|
679
|
+
}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
### Variant Styles
|
|
683
|
+
|
|
684
|
+
```svelte
|
|
685
|
+
<!-- Default styling -->
|
|
686
|
+
<TextEditor value="Default style" />
|
|
687
|
+
|
|
688
|
+
<!-- Plain variant - minimal borders -->
|
|
689
|
+
<TextEditor value="Plain style" variant="plain" />
|
|
690
|
+
|
|
691
|
+
<!-- Outlined variant - prominent borders -->
|
|
692
|
+
<TextEditor value="Outlined style" variant="outlined" />
|
|
693
|
+
|
|
694
|
+
<!-- Filled variant - background fill -->
|
|
695
|
+
<TextEditor value="Filled style" variant="filled" />
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
## Event Handling
|
|
699
|
+
|
|
700
|
+
Form components provide consistent event handling patterns for responding to user interactions and data changes.
|
|
701
|
+
|
|
702
|
+
## Best Practices
|
|
703
|
+
|
|
704
|
+
### 1. Use FormField for Labels and Error Handling
|
|
705
|
+
|
|
706
|
+
Always use `FormField` when you need labels, error messages, or form structure:
|
|
707
|
+
|
|
708
|
+
```svelte
|
|
709
|
+
<!-- Recommended: With FormField -->
|
|
710
|
+
<FormField label="User Name" error={nameError} required>
|
|
711
|
+
<TextEditor bind:value={userName} placeholder="Enter name" />
|
|
712
|
+
</FormField>
|
|
713
|
+
|
|
714
|
+
<!-- Standalone: Only when no label/error is needed -->
|
|
715
|
+
<TextEditor bind:value={searchQuery} placeholder="Search..." />
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### 2. Integrate Web Bean Validator for Complex Forms
|
|
719
|
+
|
|
720
|
+
For forms with multiple validation rules, use `@ticatec/web-bean-validator`:
|
|
721
|
+
|
|
722
|
+
```svelte
|
|
723
|
+
<script lang="ts">
|
|
724
|
+
import beanValidator from '@ticatec/web-bean-validator';
|
|
725
|
+
import { StringValidator, NumberValidator } from '@ticatec/entity-validator';
|
|
726
|
+
|
|
727
|
+
const rules = [
|
|
728
|
+
new StringValidator('email', { required: true, format: emailRegex }),
|
|
729
|
+
new NumberValidator('age', { min: 18, max: 120 })
|
|
730
|
+
];
|
|
731
|
+
|
|
732
|
+
const validateForm = () => beanValidator.validate(formData, rules);
|
|
733
|
+
</script>
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
### 3. Use Appropriate Input Types
|
|
737
|
+
|
|
738
|
+
Choose the right component for your data type:
|
|
739
|
+
|
|
740
|
+
```svelte
|
|
741
|
+
<!-- Text data with FormField -->
|
|
742
|
+
<FormField label="Name" error={errors.name}>
|
|
743
|
+
<TextEditor bind:value={userName} />
|
|
744
|
+
</FormField>
|
|
745
|
+
|
|
746
|
+
<!-- Numeric data -->
|
|
747
|
+
<FormField label="Price" error={errors.price}>
|
|
748
|
+
<NumberEditor bind:value={price} precision={2} />
|
|
749
|
+
</FormField>
|
|
750
|
+
|
|
751
|
+
<!-- Boolean data -->
|
|
752
|
+
<CheckBox bind:value={isEnabled} label="Enable notifications" />
|
|
753
|
+
|
|
754
|
+
<!-- Selection components -->
|
|
755
|
+
<FormField label="Category" error={errors.category}>
|
|
756
|
+
<OptionsSelect bind:value={selectedCategory} options={categories} />
|
|
757
|
+
</FormField>
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### 4. Provide Clear Labels and Placeholders
|
|
761
|
+
|
|
762
|
+
```svelte
|
|
763
|
+
<!-- Use FormField instead of manual label setup -->
|
|
764
|
+
<FormField label="Email Address" required error={emailError}>
|
|
765
|
+
<TextEditor
|
|
766
|
+
bind:value={email}
|
|
767
|
+
placeholder="Enter your email address"
|
|
768
|
+
variant="outlined"
|
|
769
|
+
/>
|
|
770
|
+
</FormField>
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
### 5. Handle Loading States
|
|
774
|
+
|
|
775
|
+
```svelte
|
|
776
|
+
<script lang="ts">
|
|
777
|
+
let isSubmitting = false;
|
|
778
|
+
|
|
779
|
+
const handleSubmit = async () => {
|
|
780
|
+
isSubmitting = true;
|
|
781
|
+
try {
|
|
782
|
+
await submitForm();
|
|
783
|
+
} finally {
|
|
784
|
+
isSubmitting = false;
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
</script>
|
|
788
|
+
|
|
789
|
+
<TextEditor
|
|
790
|
+
bind:value={formData.field}
|
|
791
|
+
disabled={isSubmitting}
|
|
792
|
+
placeholder={isSubmitting ? "Submitting..." : "Enter value"}
|
|
793
|
+
/>
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
## Accessibility
|
|
797
|
+
|
|
798
|
+
### Current Accessibility Features
|
|
799
|
+
|
|
800
|
+
Form components include basic accessibility features:
|
|
801
|
+
|
|
802
|
+
- Semantic HTML structure where possible
|
|
803
|
+
- Label association support
|
|
804
|
+
- Keyboard navigation for some components
|
|
805
|
+
- Screen reader compatible content
|
|
806
|
+
|
|
807
|
+
### Accessibility Improvements
|
|
808
|
+
|
|
809
|
+
For better accessibility, consider these enhancements:
|
|
810
|
+
|
|
811
|
+
```svelte
|
|
812
|
+
<!-- Proper labeling -->
|
|
813
|
+
<label for="user-name">Full Name *</label>
|
|
814
|
+
<TextEditor
|
|
815
|
+
id="user-name"
|
|
816
|
+
bind:value={userName}
|
|
817
|
+
required
|
|
818
|
+
aria-describedby="name-help"
|
|
819
|
+
/>
|
|
820
|
+
<div id="name-help">Enter your first and last name</div>
|
|
821
|
+
|
|
822
|
+
<!-- Error announcements -->
|
|
823
|
+
<TextEditor
|
|
824
|
+
bind:value={email}
|
|
825
|
+
aria-invalid={emailError ? 'true' : 'false'}
|
|
826
|
+
aria-describedby={emailError ? 'email-error' : undefined}
|
|
827
|
+
/>
|
|
828
|
+
{#if emailError}
|
|
829
|
+
<div id="email-error" role="alert">{emailError}</div>
|
|
830
|
+
{/if}
|
|
831
|
+
|
|
832
|
+
<!-- Fieldset grouping -->
|
|
833
|
+
<fieldset>
|
|
834
|
+
<legend>Contact Preferences</legend>
|
|
835
|
+
<CheckBox value={emailNotifications} label="Email notifications" />
|
|
836
|
+
<CheckBox value={smsNotifications} label="SMS notifications" />
|
|
837
|
+
</fieldset>
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
## Browser Support
|
|
841
|
+
|
|
842
|
+
- Modern browsers with ES2020+ support
|
|
843
|
+
- CSS Grid and Flexbox support for layouts
|
|
844
|
+
- Form validation APIs for enhanced validation
|
|
845
|
+
- Event handling for user interactions
|
|
846
|
+
|
|
847
|
+
This comprehensive guide covers the major form components in the Uniface Element library, providing examples, best practices, and implementation details for building robust form interfaces.
|