@ticatec/uniface-element 0.2.3 → 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/DialogBoard.svelte +1 -1
- 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/ticatec-uniface-web.css +1 -0
- 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,787 @@
|
|
|
1
|
+
# FlexRowForm (FormContainer)
|
|
2
|
+
|
|
3
|
+
A structured row-based form layout system that provides explicit row and cell organization for precise form layouts with 12-column grid support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Explicit Row Structure**: Manual row definition for precise layout control
|
|
8
|
+
- **12-Column Grid System**: Cell spanning from 1-12 columns with percentage-based widths
|
|
9
|
+
- **Layout Modes**: Supports vertical and horizontal field layouts
|
|
10
|
+
- **Structured Organization**: Clear separation between rows and cells
|
|
11
|
+
- **FormField Integration**: Works seamlessly with FormField components
|
|
12
|
+
- **Responsive Design**: Flexible grid system that adapts to different screen sizes
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @ticatec/uniface-element
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Usage
|
|
23
|
+
|
|
24
|
+
```svelte
|
|
25
|
+
<script>
|
|
26
|
+
import FormContainer, { Row, Cell } from '@ticatec/uniface-element/flex-row-form';
|
|
27
|
+
import FormField from '@ticatec/uniface-element/form-field';
|
|
28
|
+
import TextEditor from '@ticatec/uniface-element/text-editor';
|
|
29
|
+
|
|
30
|
+
let formData = {};
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<FormContainer>
|
|
34
|
+
<Row>
|
|
35
|
+
<Cell span={6}>
|
|
36
|
+
<FormField label="First Name" required>
|
|
37
|
+
<TextEditor bind:value={formData.firstName} variant="filled" />
|
|
38
|
+
</FormField>
|
|
39
|
+
</Cell>
|
|
40
|
+
|
|
41
|
+
<Cell span={6}>
|
|
42
|
+
<FormField label="Last Name" required>
|
|
43
|
+
<TextEditor bind:value={formData.lastName} variant="filled" />
|
|
44
|
+
</FormField>
|
|
45
|
+
</Cell>
|
|
46
|
+
</Row>
|
|
47
|
+
|
|
48
|
+
<Row>
|
|
49
|
+
<Cell span={12}>
|
|
50
|
+
<FormField label="Email Address">
|
|
51
|
+
<TextEditor bind:value={formData.email} variant="filled" />
|
|
52
|
+
</FormField>
|
|
53
|
+
</Cell>
|
|
54
|
+
</Row>
|
|
55
|
+
</FormContainer>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Complete Form Example
|
|
59
|
+
|
|
60
|
+
```svelte
|
|
61
|
+
<script>
|
|
62
|
+
import FormContainer, { Row, Cell } from '@ticatec/uniface-element/flex-row-form';
|
|
63
|
+
import FormField from '@ticatec/uniface-element/form-field';
|
|
64
|
+
import TextEditor from '@ticatec/uniface-element/text-editor';
|
|
65
|
+
import DatePicker from '@ticatec/uniface-element/date-picker';
|
|
66
|
+
import OptionsSelect from '@ticatec/uniface-element/options-select';
|
|
67
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
68
|
+
|
|
69
|
+
let formData = {};
|
|
70
|
+
let errors = {};
|
|
71
|
+
|
|
72
|
+
const genderOptions = [
|
|
73
|
+
{ code: 'F', text: 'Female' },
|
|
74
|
+
{ code: 'M', text: 'Male' }
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
const countries = [
|
|
78
|
+
{ code: 'AU', text: 'Australia' },
|
|
79
|
+
{ code: 'NZ', text: 'New Zealand' },
|
|
80
|
+
{ code: 'US', text: 'United States' }
|
|
81
|
+
];
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<FormContainer style="max-width: 800px; margin: 0 auto; border: 1px solid #e1e1e1; padding: 20px;">
|
|
85
|
+
<Row>
|
|
86
|
+
<Cell span={4}>
|
|
87
|
+
<FormField label="Full Name" required error={errors.name}>
|
|
88
|
+
<TextEditor
|
|
89
|
+
bind:value={formData.name}
|
|
90
|
+
variant="filled"
|
|
91
|
+
placeholder="Enter full name"
|
|
92
|
+
input$maxLength={50}
|
|
93
|
+
/>
|
|
94
|
+
</FormField>
|
|
95
|
+
</Cell>
|
|
96
|
+
|
|
97
|
+
<Cell span={4}>
|
|
98
|
+
<FormField label="Date of Birth" required error={errors.dob}>
|
|
99
|
+
<DatePicker
|
|
100
|
+
bind:value={formData.dob}
|
|
101
|
+
variant="filled"
|
|
102
|
+
max={new Date()}
|
|
103
|
+
/>
|
|
104
|
+
</FormField>
|
|
105
|
+
</Cell>
|
|
106
|
+
|
|
107
|
+
<Cell span={4}>
|
|
108
|
+
<FormField label="Gender" required error={errors.gender}>
|
|
109
|
+
<OptionsSelect
|
|
110
|
+
bind:value={formData.gender}
|
|
111
|
+
variant="filled"
|
|
112
|
+
options={genderOptions}
|
|
113
|
+
/>
|
|
114
|
+
</FormField>
|
|
115
|
+
</Cell>
|
|
116
|
+
</Row>
|
|
117
|
+
|
|
118
|
+
<Row>
|
|
119
|
+
<Cell span={6}>
|
|
120
|
+
<FormField label="Nationality" error={errors.nationality}>
|
|
121
|
+
<OptionsSelect
|
|
122
|
+
bind:value={formData.nationality}
|
|
123
|
+
variant="filled"
|
|
124
|
+
options={countries}
|
|
125
|
+
/>
|
|
126
|
+
</FormField>
|
|
127
|
+
</Cell>
|
|
128
|
+
|
|
129
|
+
<Cell span={6}>
|
|
130
|
+
<FormField label="Phone Number" error={errors.phone}>
|
|
131
|
+
<TextEditor
|
|
132
|
+
bind:value={formData.phone}
|
|
133
|
+
variant="filled"
|
|
134
|
+
placeholder="Enter phone number"
|
|
135
|
+
/>
|
|
136
|
+
</FormField>
|
|
137
|
+
</Cell>
|
|
138
|
+
</Row>
|
|
139
|
+
|
|
140
|
+
<Row>
|
|
141
|
+
<Cell span={12}>
|
|
142
|
+
<FormField label="Additional Notes" error={errors.notes}>
|
|
143
|
+
<MemoEditor
|
|
144
|
+
bind:value={formData.notes}
|
|
145
|
+
variant="filled"
|
|
146
|
+
input$rows={4}
|
|
147
|
+
input$maxLength={300}
|
|
148
|
+
showIndicator
|
|
149
|
+
/>
|
|
150
|
+
</FormField>
|
|
151
|
+
</Cell>
|
|
152
|
+
</Row>
|
|
153
|
+
</FormContainer>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Horizontal Layout
|
|
157
|
+
|
|
158
|
+
```svelte
|
|
159
|
+
<FormContainer fieldLayout="horizontal">
|
|
160
|
+
<Row>
|
|
161
|
+
<Cell span={6}>
|
|
162
|
+
<FormField label="Start Date">
|
|
163
|
+
<DatePicker bind:value={startDate} variant="filled" />
|
|
164
|
+
</FormField>
|
|
165
|
+
</Cell>
|
|
166
|
+
|
|
167
|
+
<Cell span={6}>
|
|
168
|
+
<FormField label="End Date">
|
|
169
|
+
<DatePicker bind:value={endDate} variant="filled" />
|
|
170
|
+
</FormField>
|
|
171
|
+
</Cell>
|
|
172
|
+
</Row>
|
|
173
|
+
|
|
174
|
+
<Row>
|
|
175
|
+
<Cell span={12}>
|
|
176
|
+
<FormField label="Description" label$alignment="top">
|
|
177
|
+
<MemoEditor bind:value={description} variant="filled" />
|
|
178
|
+
</FormField>
|
|
179
|
+
</Cell>
|
|
180
|
+
</Row>
|
|
181
|
+
</FormContainer>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## API Reference
|
|
185
|
+
|
|
186
|
+
### FormContainer
|
|
187
|
+
|
|
188
|
+
Main container component for structured row-based form layout.
|
|
189
|
+
|
|
190
|
+
#### Props
|
|
191
|
+
|
|
192
|
+
| Prop | Type | Default | Description |
|
|
193
|
+
|------|------|---------|-------------|
|
|
194
|
+
| `style` | `string` | `''` | Custom CSS styles for the form container |
|
|
195
|
+
| `fieldLayout` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout mode for form fields |
|
|
196
|
+
| `class` | `string` | `''` | Additional CSS classes for the container |
|
|
197
|
+
|
|
198
|
+
#### Slots
|
|
199
|
+
|
|
200
|
+
| Slot | Description |
|
|
201
|
+
|------|-------------|
|
|
202
|
+
| default | Form content containing Row components |
|
|
203
|
+
|
|
204
|
+
### Row
|
|
205
|
+
|
|
206
|
+
Container component for organizing cells in horizontal rows.
|
|
207
|
+
|
|
208
|
+
#### Props
|
|
209
|
+
|
|
210
|
+
| Prop | Type | Default | Description |
|
|
211
|
+
|------|------|---------|-------------|
|
|
212
|
+
| `style` | `string` | `''` | Custom CSS styles for the row |
|
|
213
|
+
| `class` | `string` | `''` | Additional CSS classes for the row |
|
|
214
|
+
|
|
215
|
+
#### Slots
|
|
216
|
+
|
|
217
|
+
| Slot | Description |
|
|
218
|
+
|------|-------------|
|
|
219
|
+
| default | Cell components and content for the row |
|
|
220
|
+
|
|
221
|
+
### Cell
|
|
222
|
+
|
|
223
|
+
Grid cell component that spans specified columns within a row.
|
|
224
|
+
|
|
225
|
+
#### Props
|
|
226
|
+
|
|
227
|
+
| Prop | Type | Default | Description |
|
|
228
|
+
|------|------|---------|-------------|
|
|
229
|
+
| `span` | `number` | `1` | Number of columns to span (1-12) |
|
|
230
|
+
| `style` | `string` | `''` | Custom CSS styles for the cell |
|
|
231
|
+
| `class` | `string` | `''` | Additional CSS classes for the cell |
|
|
232
|
+
|
|
233
|
+
#### Slots
|
|
234
|
+
|
|
235
|
+
| Slot | Description |
|
|
236
|
+
|------|-------------|
|
|
237
|
+
| default | Content for the cell (typically FormField components) |
|
|
238
|
+
|
|
239
|
+
## Grid System
|
|
240
|
+
|
|
241
|
+
The FlexRowForm uses a 12-column grid system where each Cell can span 1-12 columns:
|
|
242
|
+
|
|
243
|
+
- **span={1}**: 8.33% width (1/12)
|
|
244
|
+
- **span={2}**: 16.67% width (2/12)
|
|
245
|
+
- **span={3}**: 25% width (3/12)
|
|
246
|
+
- **span={4}**: 33.33% width (4/12)
|
|
247
|
+
- **span={6}**: 50% width (6/12)
|
|
248
|
+
- **span={8}**: 66.67% width (8/12)
|
|
249
|
+
- **span={12}**: 100% width (12/12)
|
|
250
|
+
|
|
251
|
+
## Layout Examples
|
|
252
|
+
|
|
253
|
+
### Multi-Row Complex Form
|
|
254
|
+
|
|
255
|
+
```svelte
|
|
256
|
+
<FormContainer>
|
|
257
|
+
<!-- Header Row -->
|
|
258
|
+
<Row>
|
|
259
|
+
<Cell span={12}>
|
|
260
|
+
<FormField label="Project Title" required>
|
|
261
|
+
<TextEditor bind:value={project.title} variant="filled" />
|
|
262
|
+
</FormField>
|
|
263
|
+
</Cell>
|
|
264
|
+
</Row>
|
|
265
|
+
|
|
266
|
+
<!-- Details Row -->
|
|
267
|
+
<Row>
|
|
268
|
+
<Cell span={4}>
|
|
269
|
+
<FormField label="Start Date" required>
|
|
270
|
+
<DatePicker bind:value={project.startDate} variant="filled" />
|
|
271
|
+
</FormField>
|
|
272
|
+
</Cell>
|
|
273
|
+
|
|
274
|
+
<Cell span={4}>
|
|
275
|
+
<FormField label="End Date">
|
|
276
|
+
<DatePicker bind:value={project.endDate} variant="filled" />
|
|
277
|
+
</FormField>
|
|
278
|
+
</Cell>
|
|
279
|
+
|
|
280
|
+
<Cell span={4}>
|
|
281
|
+
<FormField label="Priority">
|
|
282
|
+
<OptionsSelect bind:value={project.priority} options={priorities} />
|
|
283
|
+
</FormField>
|
|
284
|
+
</Cell>
|
|
285
|
+
</Row>
|
|
286
|
+
|
|
287
|
+
<!-- Contact Row -->
|
|
288
|
+
<Row>
|
|
289
|
+
<Cell span={6}>
|
|
290
|
+
<FormField label="Project Manager">
|
|
291
|
+
<TextEditor bind:value={project.manager} variant="filled" />
|
|
292
|
+
</FormField>
|
|
293
|
+
</Cell>
|
|
294
|
+
|
|
295
|
+
<Cell span={6}>
|
|
296
|
+
<FormField label="Contact Email">
|
|
297
|
+
<TextEditor bind:value={project.email} variant="filled" />
|
|
298
|
+
</FormField>
|
|
299
|
+
</Cell>
|
|
300
|
+
</Row>
|
|
301
|
+
|
|
302
|
+
<!-- Description Row -->
|
|
303
|
+
<Row>
|
|
304
|
+
<Cell span={12}>
|
|
305
|
+
<FormField label="Project Description" label$alignment="top">
|
|
306
|
+
<MemoEditor bind:value={project.description} variant="filled" />
|
|
307
|
+
</FormField>
|
|
308
|
+
</Cell>
|
|
309
|
+
</Row>
|
|
310
|
+
</FormContainer>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Asymmetric Layout
|
|
314
|
+
|
|
315
|
+
```svelte
|
|
316
|
+
<FormContainer>
|
|
317
|
+
<Row>
|
|
318
|
+
<Cell span={8}>
|
|
319
|
+
<FormField label="Main Information">
|
|
320
|
+
<TextEditor bind:value={mainInfo} variant="filled" />
|
|
321
|
+
</FormField>
|
|
322
|
+
</Cell>
|
|
323
|
+
|
|
324
|
+
<Cell span={4}>
|
|
325
|
+
<FormField label="Code">
|
|
326
|
+
<TextEditor bind:value={code} variant="filled" />
|
|
327
|
+
</FormField>
|
|
328
|
+
</Cell>
|
|
329
|
+
</Row>
|
|
330
|
+
|
|
331
|
+
<Row>
|
|
332
|
+
<Cell span={3}>
|
|
333
|
+
<FormField label="Type">
|
|
334
|
+
<OptionsSelect bind:value={type} options={typeOptions} />
|
|
335
|
+
</FormField>
|
|
336
|
+
</Cell>
|
|
337
|
+
|
|
338
|
+
<Cell span={3}>
|
|
339
|
+
<FormField label="Status">
|
|
340
|
+
<OptionsSelect bind:value={status} options={statusOptions} />
|
|
341
|
+
</FormField>
|
|
342
|
+
</Cell>
|
|
343
|
+
|
|
344
|
+
<Cell span={6}>
|
|
345
|
+
<FormField label="Reference">
|
|
346
|
+
<TextEditor bind:value={reference} variant="filled" />
|
|
347
|
+
</FormField>
|
|
348
|
+
</Cell>
|
|
349
|
+
</Row>
|
|
350
|
+
</FormContainer>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Form Sections
|
|
354
|
+
|
|
355
|
+
```svelte
|
|
356
|
+
<FormContainer>
|
|
357
|
+
<!-- Personal Information Section -->
|
|
358
|
+
<Row>
|
|
359
|
+
<Cell span={12}>
|
|
360
|
+
<h3>Personal Information</h3>
|
|
361
|
+
</Cell>
|
|
362
|
+
</Row>
|
|
363
|
+
|
|
364
|
+
<Row>
|
|
365
|
+
<Cell span={6}>
|
|
366
|
+
<FormField label="First Name" required>
|
|
367
|
+
<TextEditor bind:value={personal.firstName} variant="filled" />
|
|
368
|
+
</FormField>
|
|
369
|
+
</Cell>
|
|
370
|
+
|
|
371
|
+
<Cell span={6}>
|
|
372
|
+
<FormField label="Last Name" required>
|
|
373
|
+
<TextEditor bind:value={personal.lastName} variant="filled" />
|
|
374
|
+
</FormField>
|
|
375
|
+
</Cell>
|
|
376
|
+
</Row>
|
|
377
|
+
|
|
378
|
+
<!-- Contact Information Section -->
|
|
379
|
+
<Row>
|
|
380
|
+
<Cell span={12}>
|
|
381
|
+
<h3>Contact Information</h3>
|
|
382
|
+
</Cell>
|
|
383
|
+
</Row>
|
|
384
|
+
|
|
385
|
+
<Row>
|
|
386
|
+
<Cell span={8}>
|
|
387
|
+
<FormField label="Email Address" required>
|
|
388
|
+
<TextEditor bind:value={contact.email} variant="filled" />
|
|
389
|
+
</FormField>
|
|
390
|
+
</Cell>
|
|
391
|
+
|
|
392
|
+
<Cell span={4}>
|
|
393
|
+
<FormField label="Phone">
|
|
394
|
+
<TextEditor bind:value={contact.phone} variant="filled" />
|
|
395
|
+
</FormField>
|
|
396
|
+
</Cell>
|
|
397
|
+
</Row>
|
|
398
|
+
</FormContainer>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Validation and Error Handling
|
|
402
|
+
|
|
403
|
+
```svelte
|
|
404
|
+
<script>
|
|
405
|
+
let formData = {
|
|
406
|
+
name: '',
|
|
407
|
+
email: '',
|
|
408
|
+
phone: '',
|
|
409
|
+
notes: ''
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
let errors = {};
|
|
413
|
+
|
|
414
|
+
function validateForm() {
|
|
415
|
+
errors = {};
|
|
416
|
+
|
|
417
|
+
if (!formData.name?.trim()) {
|
|
418
|
+
errors.name = 'Name is required';
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (!formData.email?.trim()) {
|
|
422
|
+
errors.email = 'Email is required';
|
|
423
|
+
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
|
|
424
|
+
errors.email = 'Please enter a valid email address';
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (formData.phone && !/^\+?[\d\s\-()]+$/.test(formData.phone)) {
|
|
428
|
+
errors.phone = 'Please enter a valid phone number';
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return Object.keys(errors).length === 0;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function handleSubmit() {
|
|
435
|
+
if (validateForm()) {
|
|
436
|
+
console.log('Form submitted:', formData);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
</script>
|
|
440
|
+
|
|
441
|
+
<FormContainer>
|
|
442
|
+
<Row>
|
|
443
|
+
<Cell span={6}>
|
|
444
|
+
<FormField label="Full Name" required error={errors.name}>
|
|
445
|
+
<TextEditor
|
|
446
|
+
bind:value={formData.name}
|
|
447
|
+
variant="filled"
|
|
448
|
+
placeholder="Enter your full name"
|
|
449
|
+
/>
|
|
450
|
+
</FormField>
|
|
451
|
+
</Cell>
|
|
452
|
+
|
|
453
|
+
<Cell span={6}>
|
|
454
|
+
<FormField label="Phone Number" error={errors.phone}>
|
|
455
|
+
<TextEditor
|
|
456
|
+
bind:value={formData.phone}
|
|
457
|
+
variant="filled"
|
|
458
|
+
placeholder="Enter phone number"
|
|
459
|
+
/>
|
|
460
|
+
</FormField>
|
|
461
|
+
</Cell>
|
|
462
|
+
</Row>
|
|
463
|
+
|
|
464
|
+
<Row>
|
|
465
|
+
<Cell span={12}>
|
|
466
|
+
<FormField label="Email Address" required error={errors.email}>
|
|
467
|
+
<TextEditor
|
|
468
|
+
bind:value={formData.email}
|
|
469
|
+
variant="filled"
|
|
470
|
+
placeholder="Enter email address"
|
|
471
|
+
/>
|
|
472
|
+
</FormField>
|
|
473
|
+
</Cell>
|
|
474
|
+
</Row>
|
|
475
|
+
|
|
476
|
+
<Row>
|
|
477
|
+
<Cell span={12}>
|
|
478
|
+
<FormField label="Additional Notes">
|
|
479
|
+
<MemoEditor
|
|
480
|
+
bind:value={formData.notes}
|
|
481
|
+
variant="filled"
|
|
482
|
+
placeholder="Enter any additional notes..."
|
|
483
|
+
/>
|
|
484
|
+
</FormField>
|
|
485
|
+
</Cell>
|
|
486
|
+
</Row>
|
|
487
|
+
|
|
488
|
+
<Row>
|
|
489
|
+
<Cell span={12} style="text-align: right; margin-top: 20px;">
|
|
490
|
+
<button type="button" on:click={handleSubmit}>
|
|
491
|
+
Submit Form
|
|
492
|
+
</button>
|
|
493
|
+
</Cell>
|
|
494
|
+
</Row>
|
|
495
|
+
</FormContainer>
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## Styling
|
|
499
|
+
|
|
500
|
+
### Custom Form Styling
|
|
501
|
+
|
|
502
|
+
```svelte
|
|
503
|
+
<FormContainer
|
|
504
|
+
style="
|
|
505
|
+
max-width: 900px;
|
|
506
|
+
margin: 2rem auto;
|
|
507
|
+
padding: 2rem;
|
|
508
|
+
border: 1px solid #e2e8f0;
|
|
509
|
+
border-radius: 8px;
|
|
510
|
+
background: #ffffff;
|
|
511
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
512
|
+
"
|
|
513
|
+
>
|
|
514
|
+
<Row style="margin-bottom: 1.5rem;">
|
|
515
|
+
<Cell span={12}>
|
|
516
|
+
<h2 style="margin: 0; color: #2d3748;">Form Title</h2>
|
|
517
|
+
</Cell>
|
|
518
|
+
</Row>
|
|
519
|
+
|
|
520
|
+
<!-- Form content here -->
|
|
521
|
+
</FormContainer>
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### CSS Classes
|
|
525
|
+
|
|
526
|
+
```css
|
|
527
|
+
.custom-form-container {
|
|
528
|
+
max-width: 800px;
|
|
529
|
+
margin: 0 auto;
|
|
530
|
+
padding: 2rem;
|
|
531
|
+
background: white;
|
|
532
|
+
border-radius: 8px;
|
|
533
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.custom-form-container .form-row {
|
|
537
|
+
margin-bottom: 1.5rem;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.custom-form-container .form-row:last-child {
|
|
541
|
+
margin-bottom: 0;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.custom-form-container .form-cell {
|
|
545
|
+
padding: 0 0.5rem;
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
## Responsive Design
|
|
550
|
+
|
|
551
|
+
```svelte
|
|
552
|
+
<FormContainer class="responsive-form">
|
|
553
|
+
<Row>
|
|
554
|
+
<Cell span={4}>
|
|
555
|
+
<FormField label="Field 1">
|
|
556
|
+
<TextEditor bind:value={field1} />
|
|
557
|
+
</FormField>
|
|
558
|
+
</Cell>
|
|
559
|
+
|
|
560
|
+
<Cell span={4}>
|
|
561
|
+
<FormField label="Field 2">
|
|
562
|
+
<TextEditor bind:value={field2} />
|
|
563
|
+
</FormField>
|
|
564
|
+
</Cell>
|
|
565
|
+
|
|
566
|
+
<Cell span={4}>
|
|
567
|
+
<FormField label="Field 3">
|
|
568
|
+
<TextEditor bind:value={field3} />
|
|
569
|
+
</FormField>
|
|
570
|
+
</Cell>
|
|
571
|
+
</Row>
|
|
572
|
+
</FormContainer>
|
|
573
|
+
|
|
574
|
+
<style>
|
|
575
|
+
@media (max-width: 768px) {
|
|
576
|
+
:global(.responsive-form .form-cell) {
|
|
577
|
+
width: 100% !important;
|
|
578
|
+
margin-bottom: 1rem;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
@media (max-width: 480px) {
|
|
583
|
+
:global(.responsive-form) {
|
|
584
|
+
padding: 1rem;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
</style>
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
## Best Practices
|
|
591
|
+
|
|
592
|
+
### 1. Logical Row Organization
|
|
593
|
+
|
|
594
|
+
Group related fields in the same row:
|
|
595
|
+
|
|
596
|
+
```svelte
|
|
597
|
+
<FormContainer>
|
|
598
|
+
<!-- Personal details in one row -->
|
|
599
|
+
<Row>
|
|
600
|
+
<Cell span={4}>
|
|
601
|
+
<FormField label="First Name" required>
|
|
602
|
+
<TextEditor bind:value={firstName} />
|
|
603
|
+
</FormField>
|
|
604
|
+
</Cell>
|
|
605
|
+
|
|
606
|
+
<Cell span={4}>
|
|
607
|
+
<FormField label="Last Name" required>
|
|
608
|
+
<TextEditor bind:value={lastName} />
|
|
609
|
+
</FormField>
|
|
610
|
+
</Cell>
|
|
611
|
+
|
|
612
|
+
<Cell span={4}>
|
|
613
|
+
<FormField label="Date of Birth">
|
|
614
|
+
<DatePicker bind:value={dateOfBirth} />
|
|
615
|
+
</FormField>
|
|
616
|
+
</Cell>
|
|
617
|
+
</Row>
|
|
618
|
+
|
|
619
|
+
<!-- Contact details in another row -->
|
|
620
|
+
<Row>
|
|
621
|
+
<Cell span={8}>
|
|
622
|
+
<FormField label="Email Address" required>
|
|
623
|
+
<TextEditor bind:value={email} />
|
|
624
|
+
</FormField>
|
|
625
|
+
</Cell>
|
|
626
|
+
|
|
627
|
+
<Cell span={4}>
|
|
628
|
+
<FormField label="Phone">
|
|
629
|
+
<TextEditor bind:value={phone} />
|
|
630
|
+
</FormField>
|
|
631
|
+
</Cell>
|
|
632
|
+
</Row>
|
|
633
|
+
</FormContainer>
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
### 2. Consistent Spacing
|
|
637
|
+
|
|
638
|
+
Use consistent cell spans for similar field types:
|
|
639
|
+
|
|
640
|
+
```svelte
|
|
641
|
+
<FormContainer>
|
|
642
|
+
<Row>
|
|
643
|
+
<!-- Standard text fields: 6 columns each -->
|
|
644
|
+
<Cell span={6}>
|
|
645
|
+
<FormField label="Username" required>
|
|
646
|
+
<TextEditor bind:value={username} />
|
|
647
|
+
</FormField>
|
|
648
|
+
</Cell>
|
|
649
|
+
|
|
650
|
+
<Cell span={6}>
|
|
651
|
+
<FormField label="Department">
|
|
652
|
+
<TextEditor bind:value={department} />
|
|
653
|
+
</FormField>
|
|
654
|
+
</Cell>
|
|
655
|
+
</Row>
|
|
656
|
+
|
|
657
|
+
<Row>
|
|
658
|
+
<!-- Important fields: full width -->
|
|
659
|
+
<Cell span={12}>
|
|
660
|
+
<FormField label="Description">
|
|
661
|
+
<MemoEditor bind:value={description} />
|
|
662
|
+
</FormField>
|
|
663
|
+
</Cell>
|
|
664
|
+
</Row>
|
|
665
|
+
</FormContainer>
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### 3. Form Sections
|
|
669
|
+
|
|
670
|
+
Use rows to create clear form sections:
|
|
671
|
+
|
|
672
|
+
```svelte
|
|
673
|
+
<FormContainer>
|
|
674
|
+
<!-- Section Header -->
|
|
675
|
+
<Row>
|
|
676
|
+
<Cell span={12}>
|
|
677
|
+
<h3 style="border-bottom: 1px solid #e2e8f0; padding-bottom: 0.5rem;">
|
|
678
|
+
Account Information
|
|
679
|
+
</h3>
|
|
680
|
+
</Cell>
|
|
681
|
+
</Row>
|
|
682
|
+
|
|
683
|
+
<!-- Section Fields -->
|
|
684
|
+
<Row>
|
|
685
|
+
<Cell span={6}>
|
|
686
|
+
<FormField label="Username" required>
|
|
687
|
+
<TextEditor bind:value={username} />
|
|
688
|
+
</FormField>
|
|
689
|
+
</Cell>
|
|
690
|
+
|
|
691
|
+
<Cell span={6}>
|
|
692
|
+
<FormField label="Email" required>
|
|
693
|
+
<TextEditor bind:value={email} />
|
|
694
|
+
</FormField>
|
|
695
|
+
</Cell>
|
|
696
|
+
</Row>
|
|
697
|
+
</FormContainer>
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
## Comparison with FlexForm
|
|
701
|
+
|
|
702
|
+
| Feature | FlexRowForm | FlexForm |
|
|
703
|
+
|---------|-------------|----------|
|
|
704
|
+
| Structure | Explicit rows and cells | Automatic wrapping |
|
|
705
|
+
| Layout Control | High precision | Automatic flow |
|
|
706
|
+
| Row Management | Manual row breaks | Automatic wrapping |
|
|
707
|
+
| Use Case | Complex structured forms | Simple flowing forms |
|
|
708
|
+
| Complexity | Higher | Lower |
|
|
709
|
+
|
|
710
|
+
## Integration with Other Components
|
|
711
|
+
|
|
712
|
+
### With Dynamic Content
|
|
713
|
+
|
|
714
|
+
```svelte
|
|
715
|
+
<script>
|
|
716
|
+
let items = [
|
|
717
|
+
{ id: 1, name: '', value: '' },
|
|
718
|
+
{ id: 2, name: '', value: '' }
|
|
719
|
+
];
|
|
720
|
+
|
|
721
|
+
function addItem() {
|
|
722
|
+
items = [...items, { id: Date.now(), name: '', value: '' }];
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
function removeItem(id) {
|
|
726
|
+
items = items.filter(item => item.id !== id);
|
|
727
|
+
}
|
|
728
|
+
</script>
|
|
729
|
+
|
|
730
|
+
<FormContainer>
|
|
731
|
+
{#each items as item, index}
|
|
732
|
+
<Row>
|
|
733
|
+
<Cell span={5}>
|
|
734
|
+
<FormField label="Name">
|
|
735
|
+
<TextEditor bind:value={item.name} variant="filled" />
|
|
736
|
+
</FormField>
|
|
737
|
+
</Cell>
|
|
738
|
+
|
|
739
|
+
<Cell span={5}>
|
|
740
|
+
<FormField label="Value">
|
|
741
|
+
<TextEditor bind:value={item.value} variant="filled" />
|
|
742
|
+
</FormField>
|
|
743
|
+
</Cell>
|
|
744
|
+
|
|
745
|
+
<Cell span={2} style="display: flex; align-items: end;">
|
|
746
|
+
<button type="button" on:click={() => removeItem(item.id)}>
|
|
747
|
+
Remove
|
|
748
|
+
</button>
|
|
749
|
+
</Cell>
|
|
750
|
+
</Row>
|
|
751
|
+
{/each}
|
|
752
|
+
|
|
753
|
+
<Row>
|
|
754
|
+
<Cell span={12} style="text-align: center; margin-top: 1rem;">
|
|
755
|
+
<button type="button" on:click={addItem}>
|
|
756
|
+
Add Item
|
|
757
|
+
</button>
|
|
758
|
+
</Cell>
|
|
759
|
+
</Row>
|
|
760
|
+
</FormContainer>
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
## Accessibility Features
|
|
764
|
+
|
|
765
|
+
- **Semantic Structure**: Proper form organization with logical tab order
|
|
766
|
+
- **Keyboard Navigation**: Standard form navigation patterns
|
|
767
|
+
- **Screen Reader Support**: Clear row and cell structure
|
|
768
|
+
- **Error Association**: Proper error message association with fields
|
|
769
|
+
- **Focus Management**: Logical focus flow through rows and cells
|
|
770
|
+
|
|
771
|
+
## Browser Support
|
|
772
|
+
|
|
773
|
+
- **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest versions)
|
|
774
|
+
- **Mobile Browsers**: iOS Safari, Chrome Mobile, Firefox Mobile
|
|
775
|
+
- **CSS Flexbox**: Required for layout functionality
|
|
776
|
+
|
|
777
|
+
## Related Components
|
|
778
|
+
|
|
779
|
+
- **FormField**: Form field wrapper with labels and validation
|
|
780
|
+
- **FlexForm**: Alternative automatic-wrapping form layout
|
|
781
|
+
- **TextEditor**: Single-line text input component
|
|
782
|
+
- **DatePicker**: Date selection component
|
|
783
|
+
- **OptionsSelect**: Dropdown selection component
|
|
784
|
+
|
|
785
|
+
## License
|
|
786
|
+
|
|
787
|
+
MIT License - see LICENSE file for details.
|