@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.
Files changed (178) hide show
  1. package/dist/accordion/README.md +169 -0
  2. package/dist/accordion/README_CN.md +176 -0
  3. package/dist/action-bar/README.md +275 -0
  4. package/dist/action-bar/README_CN.md +285 -0
  5. package/dist/app-layout/README.md +374 -0
  6. package/dist/app-layout/README_CN.md +381 -0
  7. package/dist/app-top-bar/README.md +357 -0
  8. package/dist/app-top-bar/README_CN.md +365 -0
  9. package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
  10. package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
  11. package/dist/base-calendar/CalendarBase.svelte +0 -3
  12. package/dist/box/README.md +385 -0
  13. package/dist/box/README_CN.md +393 -0
  14. package/dist/breadcrumbs/README.md +442 -0
  15. package/dist/breadcrumbs/README_CN.md +442 -0
  16. package/dist/button/Button.svelte +27 -7
  17. package/dist/button/Button.svelte.d.ts +3 -1
  18. package/dist/button/IconButton.svelte +26 -6
  19. package/dist/button/IconButton.svelte.d.ts +3 -1
  20. package/dist/button/IconButton_README.md +513 -0
  21. package/dist/button/IconButton_README_CN.md +513 -0
  22. package/dist/button/README.md +428 -0
  23. package/dist/button/README_CN.md +428 -0
  24. package/dist/button/TextButton.svelte +26 -6
  25. package/dist/button/TextButton.svelte.d.ts +3 -1
  26. package/dist/button/TextButton_README.md +571 -0
  27. package/dist/button/TextButton_README_CN.md +571 -0
  28. package/dist/card/README.md +666 -0
  29. package/dist/card/README_CN.md +666 -0
  30. package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
  31. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
  32. package/dist/cascade-options-select/README.md +663 -2
  33. package/dist/cascade-options-select/README_CN.md +664 -0
  34. package/dist/checkbox/CheckBox.svelte +20 -6
  35. package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
  36. package/dist/checkbox/README.md +562 -0
  37. package/dist/checkbox/README_CN.md +727 -0
  38. package/dist/common-editor/NumberInput.svelte +39 -26
  39. package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
  40. package/dist/concise-data-table/ConciseListTable.svelte +133 -36
  41. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
  42. package/dist/concise-data-table/DataCell.svelte +5 -6
  43. package/dist/concise-data-table/DataRow.svelte +22 -2
  44. package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
  45. package/dist/concise-data-table/README.md +606 -0
  46. package/dist/concise-data-table/README_CN.md +611 -0
  47. package/dist/context-menu/ContextMenu.svelte +138 -21
  48. package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
  49. package/dist/context-menu/ContextMenuItem.d.ts +20 -4
  50. package/dist/context-menu/README.md +551 -0
  51. package/dist/context-menu/README_CN.md +551 -0
  52. package/dist/criteria-field/CriteriaField.svelte +3 -5
  53. package/dist/criteria-field/README.md +532 -0
  54. package/dist/criteria-field/README_CN.md +532 -0
  55. package/dist/data-table/README.md +712 -0
  56. package/dist/data-table/README_CN.md +712 -0
  57. package/dist/date-picker/DatePicker.svelte +44 -7
  58. package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
  59. package/dist/date-picker/DateTimePicker.svelte +32 -8
  60. package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
  61. package/dist/date-picker/README.md +326 -0
  62. package/dist/date-picker/README_CN.md +316 -0
  63. package/dist/date-picker/ScrollBar.svelte +18 -8
  64. package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
  65. package/dist/date-picker/TimePanel.svelte +5 -5
  66. package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
  67. package/dist/date-range/README.md +374 -0
  68. package/dist/date-range/README_CN.md +374 -0
  69. package/dist/dialog/DialogBoard.svelte +1 -1
  70. package/dist/dialog/README.md +596 -0
  71. package/dist/dialog/README_CN.md +596 -0
  72. package/dist/drawer/README.md +679 -1
  73. package/dist/drawer/README_CN.md +679 -0
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  75. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  76. package/dist/group-box/group-check-box/README.md +749 -0
  77. package/dist/group-box/group-check-box/README_CN.md +750 -0
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  79. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  80. package/dist/group-box/group-radio-box/README.md +920 -0
  81. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  82. package/dist/image-files/README.md +1346 -0
  83. package/dist/image-files/README_CN.md +1346 -0
  84. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  85. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  86. package/dist/lib/forwardAllEvents.d.ts +3 -0
  87. package/dist/lib/forwardAllEvents.js +24 -0
  88. package/dist/list-box/README.md +579 -0
  89. package/dist/list-box/README_CN.md +682 -0
  90. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  91. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  92. package/dist/lookup-editor/README.md +684 -0
  93. package/dist/lookup-editor/README_CN.md +684 -0
  94. package/dist/memo-editor/MemoEditor.svelte +77 -27
  95. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  96. package/dist/memo-editor/README.md +819 -0
  97. package/dist/memo-editor/README_CN.md +819 -0
  98. package/dist/message-box/README.md +398 -0
  99. package/dist/message-box/README_CN.md +398 -0
  100. package/dist/number-editor/NumberEditor.svelte +2 -2
  101. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  102. package/dist/number-editor/README.md +353 -22
  103. package/dist/number-editor/README_CN.md +357 -0
  104. package/dist/number-range/README.md +443 -0
  105. package/dist/number-range/README_CN.md +443 -0
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  107. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  108. package/dist/options-multi-select/README.md +480 -0
  109. package/dist/options-multi-select/README_CN.md +480 -0
  110. package/dist/options-select/OptionsSelect.svelte +36 -5
  111. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  112. package/dist/options-select/README.md +632 -0
  113. package/dist/options-select/README_CN.md +632 -0
  114. package/dist/page/README.md +605 -0
  115. package/dist/page/README_CN.md +605 -0
  116. package/dist/pagination/README.md +946 -0
  117. package/dist/pagination/README_CN.md +946 -0
  118. package/dist/pagination-panel/README.md +1075 -0
  119. package/dist/pagination-panel/README_CN.md +1075 -0
  120. package/dist/popup-hint/README.md +841 -0
  121. package/dist/popup-hint/README_CN.md +840 -0
  122. package/dist/progress-bar/README.md +242 -0
  123. package/dist/progress-bar/README_CN.md +242 -0
  124. package/dist/progress-step-bar/README.md +316 -0
  125. package/dist/progress-step-bar/README_CN.md +316 -0
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  127. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  128. package/dist/prompts-text-editor/README.md +329 -0
  129. package/dist/prompts-text-editor/README_CN.md +329 -0
  130. package/dist/property-editor/README.md +969 -0
  131. package/dist/property-editor/README_CN.md +969 -0
  132. package/dist/radio-button/README.md +372 -0
  133. package/dist/radio-button/README_CN.md +372 -0
  134. package/dist/radio-button/RadioButton.svelte +32 -3
  135. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  136. package/dist/search-box/README.md +425 -0
  137. package/dist/search-box/README_CN.md +424 -0
  138. package/dist/search-box/SearchBox.svelte +22 -6
  139. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  140. package/dist/tabs/README.md +919 -0
  141. package/dist/tabs/README_CN.md +920 -0
  142. package/dist/tag/README.md +922 -0
  143. package/dist/tag/README_CN.md +922 -0
  144. package/dist/text-editor/PasswordEditor.svelte +17 -2
  145. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  146. package/dist/text-editor/PasswordEditor_README.md +551 -0
  147. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  148. package/dist/text-editor/README.md +466 -0
  149. package/dist/text-editor/README_CN.md +466 -0
  150. package/dist/text-editor/TextEditor.svelte +51 -19
  151. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  152. package/dist/ticatec-uniface-web.css +1 -0
  153. package/dist/time-editor/README.md +498 -24
  154. package/dist/time-editor/README_CN.md +498 -0
  155. package/dist/time-editor/TimeEditor.svelte +7 -3
  156. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  157. package/dist/toast/README.md +667 -0
  158. package/dist/toast/README_CN.md +667 -0
  159. package/dist/transfer/README.md +795 -0
  160. package/dist/transfer/Transfer.svelte +6 -4
  161. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  162. package/dist/tree-view/README.md +761 -0
  163. package/dist/tree-view/README_CN.md +761 -0
  164. package/dist/tree-view/TreeView.svelte +5 -3
  165. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  166. package/dist/unit-number-editor/README.md +546 -20
  167. package/dist/unit-number-editor/README_CN.md +525 -0
  168. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  169. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  170. package/docs/form-field/cn/README_CN.md +364 -0
  171. package/docs/form-field/en/README.md +364 -0
  172. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  173. package/docs/form-panel/flex-form/en/README.md +586 -0
  174. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  175. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  176. package/docs/form-panel/grid-form/en/README.md +744 -0
  177. package/package.json +1 -1
  178. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,744 @@
1
+ # GridForm
2
+
3
+ A flexible CSS Grid-based form layout system that provides precise control over field positioning, spanning, and complex layout arrangements.
4
+
5
+ ## Features
6
+
7
+ - **CSS Grid Layout**: True CSS Grid implementation for complex form layouts
8
+ - **Precise Positioning**: Explicit row and column positioning with `row` and `col` props
9
+ - **Row/Column Spanning**: Fields can span multiple rows and columns
10
+ - **Configurable Columns**: Set any number of columns (default 6)
11
+ - **Layout Modes**: Supports vertical and horizontal field layouts
12
+ - **FormField Integration**: Built-in FormField integration for labels and validation
13
+ - **Complex Layouts**: Perfect for forms with images, cards, and non-uniform layouts
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @ticatec/uniface-element
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ### Basic Usage
24
+
25
+ ```svelte
26
+ <script>
27
+ import GridForm, { GridField } from '@ticatec/uniface-element/grid-form';
28
+ import TextEditor from '@ticatec/uniface-element/text-editor';
29
+
30
+ let formData = {};
31
+ </script>
32
+
33
+ <GridForm columns={3}>
34
+ <GridField row={1} col={1} label="First Name" required>
35
+ <TextEditor bind:value={formData.firstName} variant="filled" />
36
+ </GridField>
37
+
38
+ <GridField row={1} col={2} label="Last Name" required>
39
+ <TextEditor bind:value={formData.lastName} variant="filled" />
40
+ </GridField>
41
+
42
+ <GridField row={1} col={3} label="Email">
43
+ <TextEditor bind:value={formData.email} variant="filled" />
44
+ </GridField>
45
+
46
+ <GridField row={2} col={1} colSpan={3} label="Address">
47
+ <TextEditor bind:value={formData.address} variant="filled" />
48
+ </GridField>
49
+ </GridForm>
50
+ ```
51
+
52
+ ### Complex Layout with Image
53
+
54
+ ```svelte
55
+ <script>
56
+ import GridForm, { GridField, EmptyCell } from '@ticatec/uniface-element/grid-form';
57
+ import TextEditor from '@ticatec/uniface-element/text-editor';
58
+ import DatePicker from '@ticatec/uniface-element/date-picker';
59
+ import OptionsSelect from '@ticatec/uniface-element/options-select';
60
+ import MemoEditor from '@ticatec/uniface-element/memo-editor';
61
+
62
+ let formData = {};
63
+ let errors = {};
64
+
65
+ const genderOptions = [
66
+ { code: 'F', text: 'Female' },
67
+ { code: 'M', text: 'Male' }
68
+ ];
69
+ </script>
70
+
71
+ <GridForm columns={3} style="border: 1px solid #e1e1e1; padding: 20px;">
72
+ <!-- Profile Image spanning 2 columns and 4 rows -->
73
+ <GridField
74
+ row={1}
75
+ col={1}
76
+ colSpan={2}
77
+ rowSpan={4}
78
+ label="Profile Photo"
79
+ required
80
+ error={errors.photo}
81
+ >
82
+ <div style="width: 100%; height: 180px; border: 2px dashed #ccc; display: flex; align-items: center; justify-content: center;">
83
+ <img
84
+ src={formData.photo || 'https://via.placeholder.com/200x180'}
85
+ alt="Profile"
86
+ style="width: 100%; height: 100%; object-fit: cover;"
87
+ />
88
+ </div>
89
+ </GridField>
90
+
91
+ <!-- Personal details in the right column -->
92
+ <GridField row={1} col={3} label="Full Name" required error={errors.name}>
93
+ <TextEditor
94
+ bind:value={formData.name}
95
+ variant="filled"
96
+ placeholder="Enter full name"
97
+ />
98
+ </GridField>
99
+
100
+ <GridField row={2} col={3} label="Date of Birth" required error={errors.dob}>
101
+ <DatePicker
102
+ bind:value={formData.dob}
103
+ variant="filled"
104
+ max={new Date()}
105
+ />
106
+ </GridField>
107
+
108
+ <GridField row={3} col={3} label="Gender" required error={errors.gender}>
109
+ <OptionsSelect
110
+ bind:value={formData.gender}
111
+ variant="filled"
112
+ options={genderOptions}
113
+ />
114
+ </GridField>
115
+
116
+ <GridField row={4} col={3} label="Phone Number" error={errors.phone}>
117
+ <TextEditor
118
+ bind:value={formData.phone}
119
+ variant="filled"
120
+ placeholder="Enter phone number"
121
+ />
122
+ </GridField>
123
+
124
+ <!-- Full-width notes field -->
125
+ <GridField row={5} col={1} colSpan={3} label="Additional Notes" error={errors.notes}>
126
+ <MemoEditor
127
+ bind:value={formData.notes}
128
+ variant="filled"
129
+ input$rows={4}
130
+ input$maxLength={300}
131
+ showIndicator
132
+ />
133
+ </GridField>
134
+ </GridForm>
135
+ ```
136
+
137
+ ### Card-Based Layout
138
+
139
+ ```svelte
140
+ <GridForm columns={4}>
141
+ <!-- Header spanning full width -->
142
+ <GridField row={1} col={1} colSpan={4} label="Project Information">
143
+ <h3 style="margin: 0; padding: 1rem; background: #f8f9fa; border-radius: 4px;">
144
+ Project Details
145
+ </h3>
146
+ </GridField>
147
+
148
+ <!-- Main content area -->
149
+ <GridField row={2} col={1} colSpan={3} rowSpan={2} label="Project Description">
150
+ <MemoEditor
151
+ bind:value={project.description}
152
+ variant="filled"
153
+ input$rows={6}
154
+ />
155
+ </GridField>
156
+
157
+ <!-- Sidebar information -->
158
+ <GridField row={2} col={4} label="Priority">
159
+ <OptionsSelect bind:value={project.priority} options={priorities} />
160
+ </GridField>
161
+
162
+ <GridField row={3} col={4} label="Status">
163
+ <OptionsSelect bind:value={project.status} options={statuses} />
164
+ </GridField>
165
+
166
+ <!-- Footer details -->
167
+ <GridField row={4} col={1} colSpan={2} label="Start Date">
168
+ <DatePicker bind:value={project.startDate} variant="filled" />
169
+ </GridField>
170
+
171
+ <GridField row={4} col={3} colSpan={2} label="End Date">
172
+ <DatePicker bind:value={project.endDate} variant="filled" />
173
+ </GridField>
174
+ </GridForm>
175
+ ```
176
+
177
+ ## API Reference
178
+
179
+ ### GridForm
180
+
181
+ Main container component for CSS Grid-based form layout.
182
+
183
+ #### Props
184
+
185
+ | Prop | Type | Default | Description |
186
+ |------|------|---------|-------------|
187
+ | `style` | `string` | `''` | Custom CSS styles for the form container |
188
+ | `columns` | `number` | `6` | Number of columns in the grid |
189
+ | `fieldLayout` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout mode for form fields |
190
+
191
+ #### Slots
192
+
193
+ | Slot | Description |
194
+ |------|-------------|
195
+ | default | Form content containing GridField and EmptyCell components |
196
+
197
+ ### GridField
198
+
199
+ A form field component that can be precisely positioned and span multiple grid cells.
200
+
201
+ #### Props
202
+
203
+ | Prop | Type | Default | Description |
204
+ |------|------|---------|-------------|
205
+ | `label` | `string` | `"Label:"` | Label text for the form field |
206
+ | `label$style` | `string` | `''` | Custom CSS styles for the label |
207
+ | `required` | `boolean` | `false` | Whether the field is required |
208
+ | `error` | `string \| null` | `null` | Error message to display |
209
+ | `arrangement` | `'vertical' \| 'horizontal'` | `'vertical'` | Field arrangement mode |
210
+ | `rowSpan` | `number` | `1` | Number of rows to span |
211
+ | `colSpan` | `number` | `1` | Number of columns to span |
212
+ | `row` | `number \| null` | `null` | Specific row position (1-based) |
213
+ | `col` | `number \| null` | `null` | Specific column position (1-based) |
214
+ | `height` | `string \| undefined` | `undefined` | Custom height for the field |
215
+ | `labelSuffix` | `string` | `':'` | Text to append to the label |
216
+
217
+ #### Slots
218
+
219
+ | Slot | Description |
220
+ |------|-------------|
221
+ | default | Form control content (input, select, etc.) |
222
+
223
+ ### EmptyCell
224
+
225
+ A placeholder cell for spacing and layout control.
226
+
227
+ #### Props
228
+
229
+ | Prop | Type | Default | Description |
230
+ |------|------|---------|-------------|
231
+ | `rowSpan` | `number` | `1` | Number of rows to span |
232
+ | `colSpan` | `number` | `1` | Number of columns to span |
233
+ | `row` | `number` | - | Specific row position (1-based) |
234
+ | `col` | `number` | - | Specific column position (1-based) |
235
+
236
+ ## Grid System
237
+
238
+ The GridForm uses CSS Grid with configurable columns:
239
+
240
+ - **columns={3}**: 3-column grid (33.33% each)
241
+ - **columns={4}**: 4-column grid (25% each)
242
+ - **columns={6}**: 6-column grid (16.67% each) - default
243
+ - **columns={12}**: 12-column grid (8.33% each)
244
+
245
+ ### Positioning
246
+
247
+ - **row/col**: 1-based positioning (row={1} col={1} is top-left)
248
+ - **rowSpan/colSpan**: Span multiple cells
249
+ - **Auto-placement**: Fields without explicit positioning flow naturally
250
+
251
+ ## Layout Examples
252
+
253
+ ### Dashboard-Style Form
254
+
255
+ ```svelte
256
+ <GridForm columns={4}>
257
+ <!-- Header -->
258
+ <GridField row={1} col={1} colSpan={4} label="Dashboard Title">
259
+ <h2 style="margin: 0;">System Configuration</h2>
260
+ </GridField>
261
+
262
+ <!-- Main settings panel -->
263
+ <GridField row={2} col={1} colSpan={2} rowSpan={3} label="Server Settings">
264
+ <div style="padding: 1rem; border: 1px solid #ddd; border-radius: 4px;">
265
+ <GridForm columns={2}>
266
+ <GridField label="Host">
267
+ <TextEditor bind:value={config.host} />
268
+ </GridField>
269
+ <GridField label="Port">
270
+ <TextEditor bind:value={config.port} />
271
+ </GridField>
272
+ <GridField colSpan={2} label="Database URL">
273
+ <TextEditor bind:value={config.dbUrl} />
274
+ </GridField>
275
+ </GridForm>
276
+ </div>
277
+ </GridField>
278
+
279
+ <!-- Side panels -->
280
+ <GridField row={2} col={3} colSpan={2} label="System Status">
281
+ <div style="padding: 1rem; background: #f0f9ff; border-radius: 4px;">
282
+ <p>System Online</p>
283
+ <p>Last Updated: {new Date().toLocaleString()}</p>
284
+ </div>
285
+ </GridField>
286
+
287
+ <GridField row={3} col={3} label="Environment">
288
+ <OptionsSelect bind:value={config.env} options={environments} />
289
+ </GridField>
290
+
291
+ <GridField row={3} col={4} label="Debug Mode">
292
+ <OptionsSelect bind:value={config.debug} options={[{code: true, text: 'On'}, {code: false, text: 'Off'}]} />
293
+ </GridField>
294
+
295
+ <GridField row={4} col={3} colSpan={2} label="Actions">
296
+ <div style="display: flex; gap: 1rem;">
297
+ <button>Save Config</button>
298
+ <button>Reset to Defaults</button>
299
+ </div>
300
+ </GridField>
301
+
302
+ <!-- Footer -->
303
+ <GridField row={5} col={1} colSpan={4} label="Additional Notes">
304
+ <MemoEditor bind:value={config.notes} variant="filled" />
305
+ </GridField>
306
+ </GridForm>
307
+ ```
308
+
309
+ ### Product Form with Image Gallery
310
+
311
+ ```svelte
312
+ <GridForm columns={5}>
313
+ <!-- Product images -->
314
+ <GridField row={1} col={1} colSpan={2} rowSpan={3} label="Product Images">
315
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem;">
316
+ {#each productImages as image, index}
317
+ <img
318
+ src={image}
319
+ alt="Product {index + 1}"
320
+ style="width: 100%; height: 80px; object-fit: cover; border-radius: 4px;"
321
+ />
322
+ {/each}
323
+ </div>
324
+ </GridField>
325
+
326
+ <!-- Product details -->
327
+ <GridField row={1} col={3} colSpan={3} label="Product Name" required>
328
+ <TextEditor bind:value={product.name} variant="filled" />
329
+ </GridField>
330
+
331
+ <GridField row={2} col={3} label="Price" required>
332
+ <TextEditor bind:value={product.price} variant="filled" />
333
+ </GridField>
334
+
335
+ <GridField row={2} col={4} label="Currency">
336
+ <OptionsSelect bind:value={product.currency} options={currencies} />
337
+ </GridField>
338
+
339
+ <GridField row={2} col={5} label="Stock">
340
+ <TextEditor bind:value={product.stock} variant="filled" />
341
+ </GridField>
342
+
343
+ <GridField row={3} col={3} colSpan={3} label="Category">
344
+ <OptionsSelect bind:value={product.category} options={categories} />
345
+ </GridField>
346
+
347
+ <!-- Full-width description -->
348
+ <GridField row={4} col={1} colSpan={5} label="Product Description">
349
+ <MemoEditor bind:value={product.description} variant="filled" />
350
+ </GridField>
351
+ </GridForm>
352
+ ```
353
+
354
+ ### Survey Form with Mixed Layouts
355
+
356
+ ```svelte
357
+ <GridForm columns={6}>
358
+ <!-- Question 1: Full width -->
359
+ <GridField row={1} col={1} colSpan={6} label="1. How would you rate our service?">
360
+ <OptionsSelect
361
+ bind:value={survey.rating}
362
+ options={ratingOptions}
363
+ variant="filled"
364
+ />
365
+ </GridField>
366
+
367
+ <!-- Question 2: Two columns -->
368
+ <GridField row={2} col={1} colSpan={3} label="2. Your age group">
369
+ <OptionsSelect bind:value={survey.ageGroup} options={ageGroups} />
370
+ </GridField>
371
+
372
+ <GridField row={2} col={4} colSpan={3} label="3. Your location">
373
+ <OptionsSelect bind:value={survey.location} options={locations} />
374
+ </GridField>
375
+
376
+ <!-- Question 4: Three columns -->
377
+ <GridField row={3} col={1} colSpan={2} label="4. Income level">
378
+ <OptionsSelect bind:value={survey.income} options={incomeRanges} />
379
+ </GridField>
380
+
381
+ <GridField row={3} col={3} colSpan={2} label="5. Education">
382
+ <OptionsSelect bind:value={survey.education} options={educationLevels} />
383
+ </GridField>
384
+
385
+ <GridField row={3} col={5} colSpan={2} label="6. Employment">
386
+ <OptionsSelect bind:value={survey.employment} options={employmentTypes} />
387
+ </GridField>
388
+
389
+ <!-- Open-ended question -->
390
+ <GridField row={4} col={1} colSpan={6} label="7. Additional comments" error={errors.comments}>
391
+ <MemoEditor
392
+ bind:value={survey.comments}
393
+ variant="filled"
394
+ input$rows={4}
395
+ placeholder="Please share any additional feedback..."
396
+ />
397
+ </GridField>
398
+ </GridForm>
399
+ ```
400
+
401
+ ## Validation and Error Handling
402
+
403
+ ```svelte
404
+ <script>
405
+ let formData = {
406
+ name: '',
407
+ email: '',
408
+ phone: '',
409
+ address: '',
410
+ notes: ''
411
+ };
412
+
413
+ let errors = {};
414
+
415
+ function validateForm() {
416
+ errors = {};
417
+
418
+ if (!formData.name?.trim()) {
419
+ errors.name = 'Name is required';
420
+ }
421
+
422
+ if (!formData.email?.trim()) {
423
+ errors.email = 'Email is required';
424
+ } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
425
+ errors.email = 'Please enter a valid email address';
426
+ }
427
+
428
+ if (!formData.address?.trim()) {
429
+ errors.address = 'Address is required';
430
+ }
431
+
432
+ return Object.keys(errors).length === 0;
433
+ }
434
+ </script>
435
+
436
+ <GridForm columns={4}>
437
+ <GridField row={1} col={1} colSpan={2} label="Full Name" required error={errors.name}>
438
+ <TextEditor
439
+ bind:value={formData.name}
440
+ variant="filled"
441
+ placeholder="Enter your full name"
442
+ />
443
+ </GridField>
444
+
445
+ <GridField row={1} col={3} colSpan={2} label="Email Address" required error={errors.email}>
446
+ <TextEditor
447
+ bind:value={formData.email}
448
+ variant="filled"
449
+ placeholder="Enter email address"
450
+ />
451
+ </GridField>
452
+
453
+ <GridField row={2} col={1} colSpan={3} label="Address" required error={errors.address}>
454
+ <TextEditor
455
+ bind:value={formData.address}
456
+ variant="filled"
457
+ placeholder="Enter your address"
458
+ />
459
+ </GridField>
460
+
461
+ <GridField row={2} col={4} label="Phone">
462
+ <TextEditor
463
+ bind:value={formData.phone}
464
+ variant="filled"
465
+ placeholder="Phone number"
466
+ />
467
+ </GridField>
468
+
469
+ <GridField row={3} col={1} colSpan={4} label="Additional Notes">
470
+ <MemoEditor
471
+ bind:value={formData.notes}
472
+ variant="filled"
473
+ placeholder="Any additional information..."
474
+ />
475
+ </GridField>
476
+
477
+ <GridField row={4} col={1} colSpan={4}>
478
+ <div style="text-align: right; margin-top: 1rem;">
479
+ <button type="button" on:click={validateForm}>
480
+ Validate & Submit
481
+ </button>
482
+ </div>
483
+ </GridField>
484
+ </GridForm>
485
+ ```
486
+
487
+ ## Styling
488
+
489
+ ### Custom Grid Styling
490
+
491
+ ```svelte
492
+ <GridForm
493
+ columns={3}
494
+ style="
495
+ max-width: 900px;
496
+ margin: 2rem auto;
497
+ padding: 2rem;
498
+ border: 1px solid #e2e8f0;
499
+ border-radius: 8px;
500
+ background: white;
501
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
502
+ gap: 1.5rem;
503
+ "
504
+ >
505
+ <!-- Grid content -->
506
+ </GridForm>
507
+ ```
508
+
509
+ ### CSS Classes
510
+
511
+ ```css
512
+ .custom-grid-form {
513
+ max-width: 1000px;
514
+ margin: 0 auto;
515
+ padding: 2rem;
516
+ background: #fafbfc;
517
+ border-radius: 8px;
518
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
519
+ }
520
+
521
+ .custom-grid-form .form-cell {
522
+ padding: 0.5rem;
523
+ border-radius: 4px;
524
+ background: white;
525
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
526
+ }
527
+
528
+ .custom-grid-form .form-cell.vertical {
529
+ /* Vertical layout specific styles */
530
+ }
531
+
532
+ .custom-grid-form .form-cell.horizontal {
533
+ /* Horizontal layout specific styles */
534
+ }
535
+ ```
536
+
537
+ ## Responsive Design
538
+
539
+ ```svelte
540
+ <GridForm columns={4} class="responsive-grid">
541
+ <GridField row={1} col={1} colSpan={2} label="Field 1">
542
+ <TextEditor bind:value={field1} />
543
+ </GridField>
544
+
545
+ <GridField row={1} col={3} colSpan={2} label="Field 2">
546
+ <TextEditor bind:value={field2} />
547
+ </GridField>
548
+
549
+ <GridField row={2} col={1} colSpan={4} label="Full Width Field">
550
+ <MemoEditor bind:value={field3} />
551
+ </GridField>
552
+ </GridForm>
553
+
554
+ <style>
555
+ @media (max-width: 768px) {
556
+ :global(.responsive-grid) {
557
+ grid-template-columns: 1fr !important;
558
+ }
559
+
560
+ :global(.responsive-grid .form-cell) {
561
+ grid-column: 1 !important;
562
+ grid-row: auto !important;
563
+ }
564
+ }
565
+ </style>
566
+ ```
567
+
568
+ ## Best Practices
569
+
570
+ ### 1. Plan Your Grid Layout
571
+
572
+ Sketch your form layout before implementing:
573
+
574
+ ```svelte
575
+ <!--
576
+ Grid Layout Plan (3 columns):
577
+ Row 1: [Image ] [Name ] [Phone ]
578
+ Row 2: [Image ] [Email ] [Country ]
579
+ Row 3: [Image ] [Address (spans 2 cols)]
580
+ Row 4: [Notes (spans all 3 columns) ]
581
+ -->
582
+
583
+ <GridForm columns={3}>
584
+ <GridField row={1} col={1} rowSpan={3} label="Photo">
585
+ <!-- Image upload component -->
586
+ </GridField>
587
+
588
+ <GridField row={1} col={2} label="Name">
589
+ <TextEditor bind:value={name} />
590
+ </GridField>
591
+
592
+ <GridField row={1} col={3} label="Phone">
593
+ <TextEditor bind:value={phone} />
594
+ </GridField>
595
+
596
+ <!-- Continue with planned layout -->
597
+ </GridForm>
598
+ ```
599
+
600
+ ### 2. Use Meaningful Grid Dimensions
601
+
602
+ Choose column counts that match your content:
603
+
604
+ ```svelte
605
+ <!-- For simple forms: 2-3 columns -->
606
+ <GridForm columns={3}>
607
+ <!-- Standard 3-column layout -->
608
+ </GridForm>
609
+
610
+ <!-- For complex forms: 4-6 columns -->
611
+ <GridForm columns={6}>
612
+ <!-- More flexibility for complex layouts -->
613
+ </GridForm>
614
+
615
+ <!-- For detailed forms: 12 columns (like Bootstrap) -->
616
+ <GridForm columns={12}>
617
+ <!-- Maximum flexibility -->
618
+ </GridForm>
619
+ ```
620
+
621
+ ### 3. Group Related Fields
622
+
623
+ Keep related fields visually connected:
624
+
625
+ ```svelte
626
+ <GridForm columns={4}>
627
+ <!-- Personal Information Section -->
628
+ <GridField row={1} col={1} colSpan={4} label="Personal Information">
629
+ <h3 style="margin: 0; padding: 0.5rem; background: #f8f9fa;">
630
+ Personal Details
631
+ </h3>
632
+ </GridField>
633
+
634
+ <GridField row={2} col={1} colSpan={2} label="First Name">
635
+ <TextEditor bind:value={firstName} />
636
+ </GridField>
637
+
638
+ <GridField row={2} col={3} colSpan={2} label="Last Name">
639
+ <TextEditor bind:value={lastName} />
640
+ </GridField>
641
+
642
+ <!-- Contact Information Section -->
643
+ <GridField row={3} col={1} colSpan={4} label="Contact Information">
644
+ <h3 style="margin: 0; padding: 0.5rem; background: #f8f9fa;">
645
+ Contact Details
646
+ </h3>
647
+ </GridField>
648
+
649
+ <!-- Contact fields -->
650
+ </GridForm>
651
+ ```
652
+
653
+ ### 4. Handle Empty Space
654
+
655
+ Use EmptyCell for intentional spacing:
656
+
657
+ ```svelte
658
+ <GridForm columns={5}>
659
+ <GridField row={1} col={1} colSpan={2} label="Important Field">
660
+ <TextEditor bind:value={important} />
661
+ </GridField>
662
+
663
+ <!-- Intentional empty space -->
664
+ <EmptyCell row={1} col={3} />
665
+
666
+ <GridField row={1} col={4} colSpan={2} label="Another Field">
667
+ <TextEditor bind:value={another} />
668
+ </GridField>
669
+ </GridForm>
670
+ ```
671
+
672
+ ## Advanced Patterns
673
+
674
+ ### Dynamic Grid Content
675
+
676
+ ```svelte
677
+ <script>
678
+ let sections = [
679
+ { id: 1, title: 'Section A', fields: ['field1', 'field2'] },
680
+ { id: 2, title: 'Section B', fields: ['field3', 'field4', 'field5'] }
681
+ ];
682
+
683
+ let currentRow = 1;
684
+ </script>
685
+
686
+ <GridForm columns={4}>
687
+ {#each sections as section}
688
+ <GridField row={currentRow} col={1} colSpan={4} label={section.title}>
689
+ <h3>{section.title}</h3>
690
+ </GridField>
691
+
692
+ {#each section.fields as field, index}
693
+ <GridField
694
+ row={currentRow + 1 + Math.floor(index / 2)}
695
+ col={1 + (index % 2) * 2}
696
+ colSpan={2}
697
+ label={field}
698
+ >
699
+ <TextEditor bind:value={formData[field]} />
700
+ </GridField>
701
+ {/each}
702
+
703
+ <!-- Update currentRow for next section -->
704
+ {currentRow = currentRow + 2 + Math.ceil(section.fields.length / 2)}
705
+ {/each}
706
+ </GridForm>
707
+ ```
708
+
709
+ ## Comparison with Other Form Layouts
710
+
711
+ | Feature | GridForm | FlexForm | FlexRowForm |
712
+ |---------|----------|----------|-------------|
713
+ | Layout Type | CSS Grid | Flexbox wrapping | Structured rows |
714
+ | Positioning | Explicit (row/col) | Auto-flow | Row-based |
715
+ | Spanning | Rows & columns | Columns only | Columns only |
716
+ | Complexity | Highest | Lowest | Medium |
717
+ | Use Case | Complex layouts | Simple forms | Structured forms |
718
+ | Learning Curve | Steeper | Gentle | Moderate |
719
+
720
+ ## Accessibility Features
721
+
722
+ - **Logical Tab Order**: Fields flow in logical reading order
723
+ - **Screen Reader Support**: Proper grid structure announced
724
+ - **Keyboard Navigation**: Standard form navigation patterns
725
+ - **Error Association**: Clear error message positioning
726
+ - **Focus Management**: Proper focus flow through grid cells
727
+
728
+ ## Browser Support
729
+
730
+ - **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest versions)
731
+ - **Mobile Browsers**: iOS Safari, Chrome Mobile, Firefox Mobile
732
+ - **CSS Grid**: Required for layout functionality (IE11+ with prefixes)
733
+
734
+ ## Related Components
735
+
736
+ - **FormField**: Base form field component with labels and validation
737
+ - **FlexForm**: Simpler automatic-wrapping form layout
738
+ - **FlexRowForm**: Structured row-based form layout
739
+ - **TextEditor**: Single-line text input component
740
+ - **DatePicker**: Date selection component
741
+
742
+ ## License
743
+
744
+ MIT License - see LICENSE file for details.