@ticatec/uniface-element 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) 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/README.md +596 -0
  70. package/dist/dialog/README_CN.md +596 -0
  71. package/dist/drawer/README.md +679 -1
  72. package/dist/drawer/README_CN.md +679 -0
  73. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  75. package/dist/group-box/group-check-box/README.md +749 -0
  76. package/dist/group-box/group-check-box/README_CN.md +750 -0
  77. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  79. package/dist/group-box/group-radio-box/README.md +920 -0
  80. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  81. package/dist/image-files/README.md +1346 -0
  82. package/dist/image-files/README_CN.md +1346 -0
  83. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  84. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  85. package/dist/lib/forwardAllEvents.d.ts +3 -0
  86. package/dist/lib/forwardAllEvents.js +24 -0
  87. package/dist/list-box/README.md +579 -0
  88. package/dist/list-box/README_CN.md +682 -0
  89. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  90. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  91. package/dist/lookup-editor/README.md +684 -0
  92. package/dist/lookup-editor/README_CN.md +684 -0
  93. package/dist/memo-editor/MemoEditor.svelte +77 -27
  94. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  95. package/dist/memo-editor/README.md +819 -0
  96. package/dist/memo-editor/README_CN.md +819 -0
  97. package/dist/message-box/README.md +398 -0
  98. package/dist/message-box/README_CN.md +398 -0
  99. package/dist/number-editor/NumberEditor.svelte +2 -2
  100. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  101. package/dist/number-editor/README.md +353 -22
  102. package/dist/number-editor/README_CN.md +357 -0
  103. package/dist/number-range/README.md +443 -0
  104. package/dist/number-range/README_CN.md +443 -0
  105. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  107. package/dist/options-multi-select/README.md +480 -0
  108. package/dist/options-multi-select/README_CN.md +480 -0
  109. package/dist/options-select/OptionsSelect.svelte +36 -5
  110. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  111. package/dist/options-select/README.md +632 -0
  112. package/dist/options-select/README_CN.md +632 -0
  113. package/dist/page/README.md +605 -0
  114. package/dist/page/README_CN.md +605 -0
  115. package/dist/pagination/README.md +946 -0
  116. package/dist/pagination/README_CN.md +946 -0
  117. package/dist/pagination-panel/README.md +1075 -0
  118. package/dist/pagination-panel/README_CN.md +1075 -0
  119. package/dist/popup-hint/README.md +841 -0
  120. package/dist/popup-hint/README_CN.md +840 -0
  121. package/dist/progress-bar/README.md +242 -0
  122. package/dist/progress-bar/README_CN.md +242 -0
  123. package/dist/progress-step-bar/README.md +316 -0
  124. package/dist/progress-step-bar/README_CN.md +316 -0
  125. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  127. package/dist/prompts-text-editor/README.md +329 -0
  128. package/dist/prompts-text-editor/README_CN.md +329 -0
  129. package/dist/property-editor/README.md +969 -0
  130. package/dist/property-editor/README_CN.md +969 -0
  131. package/dist/radio-button/README.md +372 -0
  132. package/dist/radio-button/README_CN.md +372 -0
  133. package/dist/radio-button/RadioButton.svelte +32 -3
  134. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  135. package/dist/search-box/README.md +425 -0
  136. package/dist/search-box/README_CN.md +424 -0
  137. package/dist/search-box/SearchBox.svelte +22 -6
  138. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  139. package/dist/tabs/README.md +919 -0
  140. package/dist/tabs/README_CN.md +920 -0
  141. package/dist/tag/README.md +922 -0
  142. package/dist/tag/README_CN.md +922 -0
  143. package/dist/text-editor/PasswordEditor.svelte +17 -2
  144. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  145. package/dist/text-editor/PasswordEditor_README.md +551 -0
  146. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  147. package/dist/text-editor/README.md +466 -0
  148. package/dist/text-editor/README_CN.md +466 -0
  149. package/dist/text-editor/TextEditor.svelte +51 -19
  150. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  151. package/dist/time-editor/README.md +498 -24
  152. package/dist/time-editor/README_CN.md +498 -0
  153. package/dist/time-editor/TimeEditor.svelte +7 -3
  154. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  155. package/dist/toast/README.md +667 -0
  156. package/dist/toast/README_CN.md +667 -0
  157. package/dist/transfer/README.md +795 -0
  158. package/dist/transfer/Transfer.svelte +6 -4
  159. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  160. package/dist/tree-view/README.md +761 -0
  161. package/dist/tree-view/README_CN.md +761 -0
  162. package/dist/tree-view/TreeView.svelte +5 -3
  163. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  164. package/dist/unit-number-editor/README.md +546 -20
  165. package/dist/unit-number-editor/README_CN.md +525 -0
  166. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  167. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  168. package/docs/form-field/cn/README_CN.md +364 -0
  169. package/docs/form-field/en/README.md +364 -0
  170. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  171. package/docs/form-panel/flex-form/en/README.md +586 -0
  172. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  173. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  174. package/docs/form-panel/grid-form/en/README.md +744 -0
  175. package/package.json +1 -1
  176. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,969 @@
1
+ # PropertyEditor
2
+
3
+ A dynamic property editor component that renders form fields based on metadata configuration. Features include multiple field types, nested object support, automatic component selection, and internationalization. Perfect for admin panels, form builders, and configuration interfaces.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ticatec/uniface-element
9
+ ```
10
+
11
+ ## Import
12
+
13
+ ```typescript
14
+ import PropertyEditor from "@ticatec/uniface-element/PropertyEditor";
15
+ import { MetaEditorType, type PropertyField } from "@ticatec/uniface-element/PropertyEditor";
16
+ ```
17
+
18
+ ## Basic Usage
19
+
20
+ ```svelte
21
+ <script>
22
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
23
+
24
+ let userData = {
25
+ name: "John Doe",
26
+ age: 30,
27
+ email: "john@example.com",
28
+ isActive: true
29
+ };
30
+
31
+ const userFields = [
32
+ {
33
+ name: "name",
34
+ label: "Full Name",
35
+ type: MetaEditorType.Text,
36
+ attrs: {
37
+ placeholder: "Enter full name",
38
+ maxLength: 50
39
+ }
40
+ },
41
+ {
42
+ name: "age",
43
+ label: "Age",
44
+ type: MetaEditorType.Number,
45
+ attrs: {
46
+ min: 0,
47
+ max: 120
48
+ }
49
+ },
50
+ {
51
+ name: "email",
52
+ label: "Email Address",
53
+ type: MetaEditorType.Text,
54
+ attrs: {
55
+ placeholder: "Enter email",
56
+ type: "email"
57
+ }
58
+ },
59
+ {
60
+ name: "isActive",
61
+ label: "Active Status",
62
+ type: MetaEditorType.Boolean
63
+ }
64
+ ];
65
+ </script>
66
+
67
+ <PropertyEditor fields={userFields} bind:data={userData} />
68
+ ```
69
+
70
+ ## Props
71
+
72
+ | Prop | Type | Default | Description |
73
+ |------|------|---------|-------------|
74
+ | `fields` | `Array<PropertyField>` | Required | Array of field definitions |
75
+ | `data` | `any` | Required | Data object to edit |
76
+
77
+ ## Type Definitions
78
+
79
+ ### PropertyField
80
+ ```typescript
81
+ interface PropertyField {
82
+ name: string; // Field name (supports nested with dot notation)
83
+ label: string; // Display label for the field
84
+ type: MetaEditorType; // Editor type
85
+ attrs?: any; // Additional attributes for the editor component
86
+ }
87
+ ```
88
+
89
+ ### MetaEditorType
90
+ ```typescript
91
+ enum MetaEditorType {
92
+ Text = 'Text', // Text input
93
+ CommonText = 'CommonText', // Text input with suggestions
94
+ Number = 'Number', // Number input
95
+ Date = 'Date', // Date picker
96
+ DateTime = 'DateTime', // Date and time picker
97
+ Options = 'Options', // Select dropdown
98
+ Boolean = 'Boolean' // Boolean (true/false)
99
+ }
100
+ ```
101
+
102
+ ## Field Types
103
+
104
+ ### Text Fields
105
+
106
+ ```svelte
107
+ <script>
108
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
109
+
110
+ let textData = {
111
+ title: "",
112
+ description: "",
113
+ keywords: ""
114
+ };
115
+
116
+ const textFields = [
117
+ {
118
+ name: "title",
119
+ label: "Title",
120
+ type: MetaEditorType.Text,
121
+ attrs: {
122
+ placeholder: "Enter title",
123
+ maxLength: 100
124
+ }
125
+ },
126
+ {
127
+ name: "description",
128
+ label: "Description",
129
+ type: MetaEditorType.Text,
130
+ attrs: {
131
+ placeholder: "Enter description",
132
+ rows: 3
133
+ }
134
+ },
135
+ {
136
+ name: "keywords",
137
+ label: "Keywords",
138
+ type: MetaEditorType.CommonText,
139
+ attrs: {
140
+ words: ["javascript", "svelte", "typescript", "frontend"],
141
+ placeholder: "Enter keywords"
142
+ }
143
+ }
144
+ ];
145
+ </script>
146
+
147
+ <div class="text-editor-demo">
148
+ <h3>Text Field Examples</h3>
149
+ <PropertyEditor fields={textFields} bind:data={textData} />
150
+
151
+ <div class="output">
152
+ <h4>Current Values:</h4>
153
+ <pre>{JSON.stringify(textData, null, 2)}</pre>
154
+ </div>
155
+ </div>
156
+
157
+ <style>
158
+ .text-editor-demo {
159
+ max-width: 600px;
160
+ margin: 20px auto;
161
+ padding: 20px;
162
+ border: 1px solid #ddd;
163
+ border-radius: 8px;
164
+ }
165
+
166
+ .output {
167
+ margin-top: 20px;
168
+ padding: 16px;
169
+ background: #f8f9fa;
170
+ border-radius: 4px;
171
+ }
172
+
173
+ .output pre {
174
+ margin: 8px 0 0 0;
175
+ font-size: 12px;
176
+ overflow-x: auto;
177
+ }
178
+ </style>
179
+ ```
180
+
181
+ ### Number Fields
182
+
183
+ ```svelte
184
+ <script>
185
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
186
+
187
+ let productData = {
188
+ price: 99.99,
189
+ quantity: 10,
190
+ weight: 0,
191
+ rating: 5
192
+ };
193
+
194
+ const numberFields = [
195
+ {
196
+ name: "price",
197
+ label: "Price ($)",
198
+ type: MetaEditorType.Number,
199
+ attrs: {
200
+ min: 0,
201
+ precision: 2,
202
+ step: 0.01
203
+ }
204
+ },
205
+ {
206
+ name: "quantity",
207
+ label: "Quantity",
208
+ type: MetaEditorType.Number,
209
+ attrs: {
210
+ min: 0,
211
+ precision: 0,
212
+ step: 1
213
+ }
214
+ },
215
+ {
216
+ name: "weight",
217
+ label: "Weight (kg)",
218
+ type: MetaEditorType.Number,
219
+ attrs: {
220
+ min: 0,
221
+ precision: 3,
222
+ step: 0.001
223
+ }
224
+ },
225
+ {
226
+ name: "rating",
227
+ label: "Rating",
228
+ type: MetaEditorType.Number,
229
+ attrs: {
230
+ min: 1,
231
+ max: 5,
232
+ precision: 0
233
+ }
234
+ }
235
+ ];
236
+ </script>
237
+
238
+ <div class="number-editor-demo">
239
+ <h3>Number Field Examples</h3>
240
+ <PropertyEditor fields={numberFields} bind:data={productData} />
241
+
242
+ <div class="summary">
243
+ <h4>Product Summary</h4>
244
+ <p>Price: ${productData.price}</p>
245
+ <p>Quantity: {productData.quantity} items</p>
246
+ <p>Weight: {productData.weight} kg</p>
247
+ <p>Rating: {productData.rating}/5 stars</p>
248
+ </div>
249
+ </div>
250
+
251
+ <style>
252
+ .number-editor-demo {
253
+ max-width: 600px;
254
+ margin: 20px auto;
255
+ padding: 20px;
256
+ border: 1px solid #ddd;
257
+ border-radius: 8px;
258
+ }
259
+
260
+ .summary {
261
+ margin-top: 20px;
262
+ padding: 16px;
263
+ background: #f8f9fa;
264
+ border-radius: 4px;
265
+ }
266
+
267
+ .summary h4 {
268
+ margin: 0 0 12px 0;
269
+ }
270
+
271
+ .summary p {
272
+ margin: 4px 0;
273
+ font-weight: 500;
274
+ }
275
+ </style>
276
+ ```
277
+
278
+ ### Date and DateTime Fields
279
+
280
+ ```svelte
281
+ <script>
282
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
283
+
284
+ let eventData = {
285
+ startDate: null,
286
+ endDate: null,
287
+ registrationDeadline: null,
288
+ createdAt: new Date().toISOString()
289
+ };
290
+
291
+ const dateFields = [
292
+ {
293
+ name: "startDate",
294
+ label: "Start Date",
295
+ type: MetaEditorType.Date,
296
+ attrs: {
297
+ placeholder: "Select start date"
298
+ }
299
+ },
300
+ {
301
+ name: "endDate",
302
+ label: "End Date",
303
+ type: MetaEditorType.Date,
304
+ attrs: {
305
+ placeholder: "Select end date"
306
+ }
307
+ },
308
+ {
309
+ name: "registrationDeadline",
310
+ label: "Registration Deadline",
311
+ type: MetaEditorType.DateTime,
312
+ attrs: {
313
+ placeholder: "Select deadline"
314
+ }
315
+ },
316
+ {
317
+ name: "createdAt",
318
+ label: "Created At",
319
+ type: MetaEditorType.DateTime,
320
+ attrs: {
321
+ readonly: true
322
+ }
323
+ }
324
+ ];
325
+ </script>
326
+
327
+ <div class="date-editor-demo">
328
+ <h3>Date Field Examples</h3>
329
+ <PropertyEditor fields={dateFields} bind:data={eventData} />
330
+
331
+ <div class="event-info">
332
+ <h4>Event Information</h4>
333
+ {#if eventData.startDate && eventData.endDate}
334
+ <p>Duration: {eventData.startDate} to {eventData.endDate}</p>
335
+ {/if}
336
+ {#if eventData.registrationDeadline}
337
+ <p>Registration closes: {eventData.registrationDeadline}</p>
338
+ {/if}
339
+ <p>Created: {new Date(eventData.createdAt).toLocaleDateString()}</p>
340
+ </div>
341
+ </div>
342
+
343
+ <style>
344
+ .date-editor-demo {
345
+ max-width: 600px;
346
+ margin: 20px auto;
347
+ padding: 20px;
348
+ border: 1px solid #ddd;
349
+ border-radius: 8px;
350
+ }
351
+
352
+ .event-info {
353
+ margin-top: 20px;
354
+ padding: 16px;
355
+ background: #f8f9fa;
356
+ border-radius: 4px;
357
+ }
358
+
359
+ .event-info h4 {
360
+ margin: 0 0 12px 0;
361
+ }
362
+
363
+ .event-info p {
364
+ margin: 4px 0;
365
+ }
366
+ </style>
367
+ ```
368
+
369
+ ### Options and Boolean Fields
370
+
371
+ ```svelte
372
+ <script>
373
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
374
+
375
+ let settingsData = {
376
+ theme: "light",
377
+ language: "en",
378
+ notifications: true,
379
+ autoSave: false,
380
+ privacy: "public"
381
+ };
382
+
383
+ const settingsFields = [
384
+ {
385
+ name: "theme",
386
+ label: "Theme",
387
+ type: MetaEditorType.Options,
388
+ attrs: {
389
+ options: [
390
+ { code: "light", text: "Light Theme" },
391
+ { code: "dark", text: "Dark Theme" },
392
+ { code: "auto", text: "Auto (System)" }
393
+ ]
394
+ }
395
+ },
396
+ {
397
+ name: "language",
398
+ label: "Language",
399
+ type: MetaEditorType.Options,
400
+ attrs: {
401
+ options: [
402
+ { code: "en", text: "English" },
403
+ { code: "zh", text: "中文" },
404
+ { code: "es", text: "Español" },
405
+ { code: "fr", text: "Français" }
406
+ ]
407
+ }
408
+ },
409
+ {
410
+ name: "notifications",
411
+ label: "Email Notifications",
412
+ type: MetaEditorType.Boolean
413
+ },
414
+ {
415
+ name: "autoSave",
416
+ label: "Auto Save",
417
+ type: MetaEditorType.Boolean
418
+ },
419
+ {
420
+ name: "privacy",
421
+ label: "Profile Visibility",
422
+ type: MetaEditorType.Options,
423
+ attrs: {
424
+ options: [
425
+ { code: "public", text: "Public" },
426
+ { code: "friends", text: "Friends Only" },
427
+ { code: "private", text: "Private" }
428
+ ]
429
+ }
430
+ }
431
+ ];
432
+ </script>
433
+
434
+ <div class="settings-editor-demo">
435
+ <h3>Options and Boolean Fields</h3>
436
+ <PropertyEditor fields={settingsFields} bind:data={settingsData} />
437
+
438
+ <div class="settings-preview">
439
+ <h4>Current Settings</h4>
440
+ <ul>
441
+ <li>Theme: {settingsData.theme}</li>
442
+ <li>Language: {settingsData.language}</li>
443
+ <li>Email Notifications: {settingsData.notifications ? 'Enabled' : 'Disabled'}</li>
444
+ <li>Auto Save: {settingsData.autoSave ? 'Enabled' : 'Disabled'}</li>
445
+ <li>Profile: {settingsData.privacy}</li>
446
+ </ul>
447
+ </div>
448
+ </div>
449
+
450
+ <style>
451
+ .settings-editor-demo {
452
+ max-width: 600px;
453
+ margin: 20px auto;
454
+ padding: 20px;
455
+ border: 1px solid #ddd;
456
+ border-radius: 8px;
457
+ }
458
+
459
+ .settings-preview {
460
+ margin-top: 20px;
461
+ padding: 16px;
462
+ background: #f8f9fa;
463
+ border-radius: 4px;
464
+ }
465
+
466
+ .settings-preview h4 {
467
+ margin: 0 0 12px 0;
468
+ }
469
+
470
+ .settings-preview ul {
471
+ margin: 0;
472
+ padding-left: 20px;
473
+ }
474
+
475
+ .settings-preview li {
476
+ margin: 6px 0;
477
+ }
478
+ </style>
479
+ ```
480
+
481
+ ### Nested Object Support
482
+
483
+ ```svelte
484
+ <script>
485
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
486
+
487
+ let profileData = {
488
+ personal: {
489
+ firstName: "John",
490
+ lastName: "Doe",
491
+ birthDate: null
492
+ },
493
+ contact: {
494
+ email: "john@example.com",
495
+ phone: "",
496
+ address: {
497
+ street: "",
498
+ city: "",
499
+ country: "US"
500
+ }
501
+ },
502
+ preferences: {
503
+ newsletter: true,
504
+ theme: "light"
505
+ }
506
+ };
507
+
508
+ const nestedFields = [
509
+ {
510
+ name: "personal.firstName",
511
+ label: "First Name",
512
+ type: MetaEditorType.Text,
513
+ attrs: { placeholder: "Enter first name" }
514
+ },
515
+ {
516
+ name: "personal.lastName",
517
+ label: "Last Name",
518
+ type: MetaEditorType.Text,
519
+ attrs: { placeholder: "Enter last name" }
520
+ },
521
+ {
522
+ name: "personal.birthDate",
523
+ label: "Birth Date",
524
+ type: MetaEditorType.Date
525
+ },
526
+ {
527
+ name: "contact.email",
528
+ label: "Email",
529
+ type: MetaEditorType.Text,
530
+ attrs: { type: "email", placeholder: "Enter email" }
531
+ },
532
+ {
533
+ name: "contact.phone",
534
+ label: "Phone",
535
+ type: MetaEditorType.Text,
536
+ attrs: { placeholder: "Enter phone number" }
537
+ },
538
+ {
539
+ name: "contact.address.street",
540
+ label: "Street Address",
541
+ type: MetaEditorType.Text,
542
+ attrs: { placeholder: "Enter street address" }
543
+ },
544
+ {
545
+ name: "contact.address.city",
546
+ label: "City",
547
+ type: MetaEditorType.Text,
548
+ attrs: { placeholder: "Enter city" }
549
+ },
550
+ {
551
+ name: "contact.address.country",
552
+ label: "Country",
553
+ type: MetaEditorType.Options,
554
+ attrs: {
555
+ options: [
556
+ { code: "US", text: "United States" },
557
+ { code: "CA", text: "Canada" },
558
+ { code: "UK", text: "United Kingdom" },
559
+ { code: "DE", text: "Germany" },
560
+ { code: "FR", text: "France" }
561
+ ]
562
+ }
563
+ },
564
+ {
565
+ name: "preferences.newsletter",
566
+ label: "Subscribe to Newsletter",
567
+ type: MetaEditorType.Boolean
568
+ },
569
+ {
570
+ name: "preferences.theme",
571
+ label: "Preferred Theme",
572
+ type: MetaEditorType.Options,
573
+ attrs: {
574
+ options: [
575
+ { code: "light", text: "Light" },
576
+ { code: "dark", text: "Dark" }
577
+ ]
578
+ }
579
+ }
580
+ ];
581
+ </script>
582
+
583
+ <div class="nested-editor-demo">
584
+ <h3>Nested Object Editor</h3>
585
+ <PropertyEditor fields={nestedFields} bind:data={profileData} />
586
+
587
+ <div class="profile-summary">
588
+ <h4>Profile Summary</h4>
589
+ <div class="section">
590
+ <h5>Personal Information</h5>
591
+ <p>Name: {profileData.personal.firstName} {profileData.personal.lastName}</p>
592
+ {#if profileData.personal.birthDate}
593
+ <p>Birth Date: {profileData.personal.birthDate}</p>
594
+ {/if}
595
+ </div>
596
+
597
+ <div class="section">
598
+ <h5>Contact Information</h5>
599
+ <p>Email: {profileData.contact.email}</p>
600
+ {#if profileData.contact.phone}
601
+ <p>Phone: {profileData.contact.phone}</p>
602
+ {/if}
603
+ <p>Address: {profileData.contact.address.street}, {profileData.contact.address.city}, {profileData.contact.address.country}</p>
604
+ </div>
605
+
606
+ <div class="section">
607
+ <h5>Preferences</h5>
608
+ <p>Newsletter: {profileData.preferences.newsletter ? 'Subscribed' : 'Not subscribed'}</p>
609
+ <p>Theme: {profileData.preferences.theme}</p>
610
+ </div>
611
+ </div>
612
+ </div>
613
+
614
+ <style>
615
+ .nested-editor-demo {
616
+ max-width: 700px;
617
+ margin: 20px auto;
618
+ padding: 20px;
619
+ border: 1px solid #ddd;
620
+ border-radius: 8px;
621
+ }
622
+
623
+ .profile-summary {
624
+ margin-top: 20px;
625
+ padding: 16px;
626
+ background: #f8f9fa;
627
+ border-radius: 4px;
628
+ }
629
+
630
+ .profile-summary h4 {
631
+ margin: 0 0 16px 0;
632
+ }
633
+
634
+ .section {
635
+ margin-bottom: 16px;
636
+ padding-bottom: 12px;
637
+ border-bottom: 1px solid #dee2e6;
638
+ }
639
+
640
+ .section:last-child {
641
+ border-bottom: none;
642
+ margin-bottom: 0;
643
+ }
644
+
645
+ .section h5 {
646
+ margin: 0 0 8px 0;
647
+ color: #495057;
648
+ font-size: 14px;
649
+ font-weight: 600;
650
+ text-transform: uppercase;
651
+ }
652
+
653
+ .section p {
654
+ margin: 4px 0;
655
+ font-size: 14px;
656
+ }
657
+ </style>
658
+ ```
659
+
660
+ ### Dynamic Form Builder
661
+
662
+ ```svelte
663
+ <script>
664
+ import PropertyEditor, { MetaEditorType } from "@ticatec/uniface-element/PropertyEditor";
665
+
666
+ let formData = {};
667
+ let formFields = [
668
+ {
669
+ name: "name",
670
+ label: "Name",
671
+ type: MetaEditorType.Text,
672
+ attrs: { placeholder: "Enter your name" }
673
+ }
674
+ ];
675
+
676
+ const availableFieldTypes = [
677
+ { type: MetaEditorType.Text, label: "Text Input" },
678
+ { type: MetaEditorType.Number, label: "Number Input" },
679
+ { type: MetaEditorType.Date, label: "Date Picker" },
680
+ { type: MetaEditorType.Boolean, label: "Boolean (Yes/No)" },
681
+ { type: MetaEditorType.Options, label: "Dropdown List" }
682
+ ];
683
+
684
+ function addField() {
685
+ const fieldName = prompt("Enter field name:");
686
+ if (!fieldName) return;
687
+
688
+ const fieldLabel = prompt("Enter field label:");
689
+ if (!fieldLabel) return;
690
+
691
+ const fieldType = prompt(`Enter field type (${availableFieldTypes.map(t => t.type).join(', ')}):`);
692
+ const selectedType = availableFieldTypes.find(t => t.type === fieldType);
693
+
694
+ if (!selectedType) {
695
+ alert("Invalid field type");
696
+ return;
697
+ }
698
+
699
+ const newField = {
700
+ name: fieldName,
701
+ label: fieldLabel,
702
+ type: selectedType.type,
703
+ attrs: {}
704
+ };
705
+
706
+ // Add default options for Options type
707
+ if (selectedType.type === MetaEditorType.Options) {
708
+ newField.attrs.options = [
709
+ { code: "option1", text: "Option 1" },
710
+ { code: "option2", text: "Option 2" }
711
+ ];
712
+ }
713
+
714
+ formFields = [...formFields, newField];
715
+ }
716
+
717
+ function removeField(index) {
718
+ formFields = formFields.filter((_, i) => i !== index);
719
+ }
720
+
721
+ function exportFormData() {
722
+ const exportData = {
723
+ fields: formFields,
724
+ data: formData
725
+ };
726
+
727
+ const blob = new Blob([JSON.stringify(exportData, null, 2)], {
728
+ type: 'application/json'
729
+ });
730
+
731
+ const url = URL.createObjectURL(blob);
732
+ const a = document.createElement('a');
733
+ a.href = url;
734
+ a.download = 'form-data.json';
735
+ a.click();
736
+ URL.revokeObjectURL(url);
737
+ }
738
+ </script>
739
+
740
+ <div class="form-builder-demo">
741
+ <div class="builder-header">
742
+ <h3>Dynamic Form Builder</h3>
743
+ <div class="builder-actions">
744
+ <button on:click={addField}>Add Field</button>
745
+ <button on:click={exportFormData}>Export Data</button>
746
+ </div>
747
+ </div>
748
+
749
+ <div class="builder-content">
750
+ <div class="field-list">
751
+ <h4>Form Fields</h4>
752
+ {#each formFields as field, index}
753
+ <div class="field-item">
754
+ <span>{field.label} ({field.type})</span>
755
+ <button on:click={() => removeField(index)}>Remove</button>
756
+ </div>
757
+ {/each}
758
+ </div>
759
+
760
+ <div class="form-preview">
761
+ <h4>Form Preview</h4>
762
+ <PropertyEditor fields={formFields} bind:data={formData} />
763
+ </div>
764
+ </div>
765
+
766
+ <div class="form-data">
767
+ <h4>Form Data</h4>
768
+ <pre>{JSON.stringify(formData, null, 2)}</pre>
769
+ </div>
770
+ </div>
771
+
772
+ <style>
773
+ .form-builder-demo {
774
+ max-width: 900px;
775
+ margin: 20px auto;
776
+ padding: 20px;
777
+ border: 1px solid #ddd;
778
+ border-radius: 8px;
779
+ }
780
+
781
+ .builder-header {
782
+ display: flex;
783
+ justify-content: space-between;
784
+ align-items: center;
785
+ margin-bottom: 20px;
786
+ padding-bottom: 12px;
787
+ border-bottom: 1px solid #eee;
788
+ }
789
+
790
+ .builder-header h3 {
791
+ margin: 0;
792
+ }
793
+
794
+ .builder-actions {
795
+ display: flex;
796
+ gap: 8px;
797
+ }
798
+
799
+ .builder-actions button {
800
+ padding: 8px 16px;
801
+ border: 1px solid #007bff;
802
+ background: white;
803
+ color: #007bff;
804
+ border-radius: 4px;
805
+ cursor: pointer;
806
+ }
807
+
808
+ .builder-actions button:hover {
809
+ background: #007bff;
810
+ color: white;
811
+ }
812
+
813
+ .builder-content {
814
+ display: grid;
815
+ grid-template-columns: 1fr 2fr;
816
+ gap: 20px;
817
+ margin-bottom: 20px;
818
+ }
819
+
820
+ .field-list h4,
821
+ .form-preview h4 {
822
+ margin: 0 0 12px 0;
823
+ font-size: 16px;
824
+ }
825
+
826
+ .field-item {
827
+ display: flex;
828
+ justify-content: space-between;
829
+ align-items: center;
830
+ padding: 8px 12px;
831
+ background: #f8f9fa;
832
+ border-radius: 4px;
833
+ margin-bottom: 8px;
834
+ }
835
+
836
+ .field-item button {
837
+ padding: 4px 8px;
838
+ background: #dc3545;
839
+ color: white;
840
+ border: none;
841
+ border-radius: 4px;
842
+ cursor: pointer;
843
+ font-size: 12px;
844
+ }
845
+
846
+ .form-preview {
847
+ padding: 16px;
848
+ background: #f8f9fa;
849
+ border-radius: 4px;
850
+ }
851
+
852
+ .form-data {
853
+ padding: 16px;
854
+ background: #f8f9fa;
855
+ border-radius: 4px;
856
+ }
857
+
858
+ .form-data h4 {
859
+ margin: 0 0 12px 0;
860
+ }
861
+
862
+ .form-data pre {
863
+ margin: 0;
864
+ font-size: 12px;
865
+ overflow-x: auto;
866
+ max-height: 200px;
867
+ overflow-y: auto;
868
+ }
869
+ </style>
870
+ ```
871
+
872
+ ## Features
873
+
874
+ - **Multiple Field Types**: Text, Number, Date, DateTime, Options, Boolean, and CommonText
875
+ - **Nested Object Support**: Use dot notation for deep object property editing
876
+ - **Dynamic Component Selection**: Automatic component selection based on field type
877
+ - **Flexible Attributes**: Pass custom attributes to underlying editor components
878
+ - **Two-way Data Binding**: Real-time synchronization with data object
879
+ - **Internationalization**: Built-in i18n support for labels
880
+ - **Extensible**: Easy to add new field types and components
881
+
882
+ ## Field Type Details
883
+
884
+ ### Text Fields
885
+ - **Type**: `MetaEditorType.Text`
886
+ - **Component**: TextEditor
887
+ - **Attributes**: placeholder, maxLength, type, etc.
888
+
889
+ ### CommonText Fields
890
+ - **Type**: `MetaEditorType.CommonText`
891
+ - **Component**: PromptsTextEditor
892
+ - **Attributes**: words (array of suggestions), placeholder
893
+
894
+ ### Number Fields
895
+ - **Type**: `MetaEditorType.Number`
896
+ - **Component**: NumberEditor
897
+ - **Attributes**: min, max, precision, step
898
+
899
+ ### Date Fields
900
+ - **Type**: `MetaEditorType.Date`
901
+ - **Component**: DatePicker
902
+ - **Attributes**: format, placeholder, readonly
903
+
904
+ ### DateTime Fields
905
+ - **Type**: `MetaEditorType.DateTime`
906
+ - **Component**: DateTimePicker
907
+ - **Attributes**: format, placeholder, readonly
908
+
909
+ ### Options Fields
910
+ - **Type**: `MetaEditorType.Options`
911
+ - **Component**: OptionsSelector
912
+ - **Attributes**: options (array of {code, text} objects)
913
+
914
+ ### Boolean Fields
915
+ - **Type**: `MetaEditorType.Boolean`
916
+ - **Component**: OptionsSelector (with true/false options)
917
+ - **Attributes**: Automatically configured with boolean options
918
+
919
+ ## Styling
920
+
921
+ The PropertyEditor component uses a table-like layout:
922
+
923
+ ```css
924
+ /* Property editor container */
925
+ .uniface-property-editor {
926
+ /* Your custom styles */
927
+ }
928
+
929
+ /* Header styling */
930
+ .table-header {
931
+ display: grid;
932
+ grid-template-columns: 1fr 2fr;
933
+ /* Header styles */
934
+ }
935
+
936
+ /* Content area */
937
+ .table-content {
938
+ /* Content styles */
939
+ }
940
+
941
+ /* Individual property rows */
942
+ .property_label,
943
+ .property_control {
944
+ /* Property row styles */
945
+ }
946
+ ```
947
+
948
+ ## Best Practices
949
+
950
+ 1. **Field Definition**: Keep field definitions in separate constants for reusability
951
+ 2. **Validation**: Implement validation logic in parent components
952
+ 3. **Nested Objects**: Use dot notation consistently for nested properties
953
+ 4. **Type Safety**: Use TypeScript for better type checking
954
+ 5. **Performance**: Consider memoization for large field arrays
955
+ 6. **Accessibility**: Ensure proper labels and ARIA attributes
956
+
957
+ ## Browser Support
958
+
959
+ - Modern browsers with full event support
960
+ - Compatible with Svelte 5+
961
+ - Grid layout support
962
+ - Full TypeScript support
963
+
964
+ ## Related Components
965
+
966
+ - `TextEditor` - Text input component
967
+ - `NumberEditor` - Number input component
968
+ - `DatePicker` - Date selection component
969
+ - `OptionsSelect` - Dropdown selection component