@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,596 @@
1
+ # Dialog Components
2
+
3
+ A comprehensive dialog system built with Svelte, providing flexible modal dialogs with drag-and-drop functionality, action buttons, and advanced lifecycle management.
4
+
5
+ ## Features
6
+
7
+ - **Multiple Dialog Types**: Dialog, CommonDialog, and DialogBoard components
8
+ - **Drag & Drop**: Movable dialogs with title bar dragging
9
+ - **Action Buttons**: Configurable button actions with automatic result handling
10
+ - **Close Confirmation**: Optional confirmation dialogs before closing
11
+ - **Modal Management**: Stack-based dialog management with overlay
12
+ - **Responsive Design**: Automatic sizing and positioning
13
+ - **Accessibility**: ARIA support and keyboard navigation
14
+ - **Lifecycle Hooks**: onClose callbacks with result handling
15
+ - **Global Dialog API**: Window-level dialog management
16
+ - **Customizable Styling**: Flexible theming and sizing options
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @ticatec/uniface-element
22
+ ```
23
+
24
+ ```typescript
25
+ import Dialog, { CommonDialog, DialogBoard } from '@ticatec/uniface-element/Dialog';
26
+ ```
27
+
28
+ Or if using within the same project:
29
+ ```typescript
30
+ import Dialog, { CommonDialog, DialogBoard } from '$lib/dialog';
31
+ ```
32
+
33
+ ## Components Overview
34
+
35
+ ### Dialog
36
+ The base dialog component with full customization options.
37
+
38
+ ### CommonDialog
39
+ A simplified dialog with built-in confirm/cancel actions.
40
+
41
+ ### DialogBoard
42
+ The dialog container and management system.
43
+
44
+ ## Setup
45
+
46
+ ### 1. Add DialogBoard to Your App
47
+
48
+ First, add the DialogBoard component to your main app layout:
49
+
50
+ ```svelte
51
+ <!-- App.svelte or +layout.svelte -->
52
+ <script>
53
+ import { DialogBoard } from '$lib/dialog';
54
+ </script>
55
+
56
+ <!-- Your app content -->
57
+ <main>
58
+ <!-- Your routes and components -->
59
+ </main>
60
+
61
+ <!-- Dialog container (should be at the end) -->
62
+ <DialogBoard />
63
+ ```
64
+
65
+ ### 2. Initialize Global Dialog API
66
+
67
+ The DialogBoard automatically initializes the global `window.Dialog` API when mounted.
68
+
69
+ ## Dialog Component
70
+
71
+ ### Basic Usage
72
+
73
+ ```svelte
74
+ <script>
75
+ import Dialog from '$lib/dialog';
76
+ import { ModalResult } from '$lib/dialog/ModalResult';
77
+
78
+ let showDialog = false;
79
+
80
+ const actions = [
81
+ {
82
+ label: 'Save',
83
+ type: 'primary',
84
+ handler: async () => {
85
+ // Save logic here
86
+ console.log('Saving...');
87
+ return true; // Return true to close dialog
88
+ }
89
+ }
90
+ ];
91
+
92
+ function handleClose(result) {
93
+ console.log('Dialog closed with result:', result);
94
+ showDialog = false;
95
+ }
96
+ </script>
97
+
98
+ {#if showDialog}
99
+ <Dialog
100
+ title="My Dialog"
101
+ {actions}
102
+ onClose={handleClose}
103
+ width="500px"
104
+ height="300px"
105
+ >
106
+ <p>Dialog content goes here...</p>
107
+ </Dialog>
108
+ {/if}
109
+ ```
110
+
111
+ ### Props
112
+
113
+ | Prop | Type | Default | Description |
114
+ |------|------|---------|-------------|
115
+ | `title` | `string` | `''` | Dialog title displayed in title bar |
116
+ | `width` | `string` | `'unset'` | Dialog width (CSS value) |
117
+ | `height` | `string` | `'unset'` | Dialog height (CSS value) |
118
+ | `actions` | `ButtonActions \| null` | `null` | Array of action buttons |
119
+ | `closeConfirm` | `DialogCloseConfirm \| null` | `null` | Confirmation function before closing |
120
+ | `content$style` | `string` | `''` | Custom styles for content area |
121
+ | `closeAction` | `ButtonAction \| null` | `null` | Custom close button configuration |
122
+ | `onClose` | `OnClose \| null` | `null` | Callback when dialog closes |
123
+ | `dialog$style` | `string` | `''` | Custom styles for dialog container |
124
+
125
+ ### Methods
126
+
127
+ | Method | Description |
128
+ |--------|-------------|
129
+ | `close(result: ModalResult)` | Programmatically close the dialog with a result |
130
+
131
+ ## CommonDialog Component
132
+
133
+ A simplified dialog with built-in confirm/cancel pattern.
134
+
135
+ ### Basic Usage
136
+
137
+ ```svelte
138
+ <script>
139
+ import { CommonDialog } from '$lib/dialog';
140
+
141
+ let showDialog = false;
142
+
143
+ async function handleConfirm() {
144
+ // Your confirm logic
145
+ console.log('Confirmed!');
146
+ return true; // Return true to close dialog
147
+ }
148
+
149
+ function handleClose(result) {
150
+ console.log('Dialog result:', result);
151
+ showDialog = false;
152
+ }
153
+ </script>
154
+
155
+ {#if showDialog}
156
+ <CommonDialog
157
+ title="Confirm Action"
158
+ confirmHandler={handleConfirm}
159
+ onClose={handleClose}
160
+ width="400px"
161
+ >
162
+ <p>Are you sure you want to proceed?</p>
163
+ </CommonDialog>
164
+ {/if}
165
+ ```
166
+
167
+ ### Props
168
+
169
+ | Prop | Type | Default | Description |
170
+ |------|------|---------|-------------|
171
+ | `title` | `string` | `''` | Dialog title |
172
+ | `width` | `string` | `'unset'` | Dialog width |
173
+ | `height` | `string` | `'unset'` | Dialog height |
174
+ | `closeConfirm` | `DialogCloseConfirm \| null` | `null` | Close confirmation function |
175
+ | `content$style` | `string` | `''` | Content area styles |
176
+ | `enableConfirm` | `boolean` | `true` | Enable/disable confirm button |
177
+ | `confirmHandler` | `(() => Promise<any>) \| null` | `null` | Confirm button handler |
178
+ | `confirmText` | `string \| null` | `null` | Custom confirm button text |
179
+ | `onClose` | `OnClose \| null` | `null` | Close callback |
180
+
181
+ ## Global Dialog API
182
+
183
+ Use the global `window.Dialog` API to show dialogs from anywhere in your application.
184
+
185
+ ### Showing a Dialog
186
+
187
+ ```svelte
188
+ <script>
189
+ import MyDialogContent from './MyDialogContent.svelte';
190
+
191
+ function openDialog() {
192
+ window.Dialog.showModal(MyDialogContent, {
193
+ title: 'My Dialog',
194
+ data: { /* initial data */ },
195
+ onSave: (data) => console.log('Saved:', data)
196
+ });
197
+ }
198
+ </script>
199
+
200
+ <button on:click={openDialog}>Open Dialog</button>
201
+ ```
202
+
203
+ ### Creating Dialog Content Components
204
+
205
+ ```svelte
206
+ <!-- MyDialogContent.svelte -->
207
+ <script>
208
+ import Dialog from '$lib/dialog';
209
+ import { ModalResult } from '$lib/dialog/ModalResult';
210
+
211
+ // Props passed from showModal
212
+ export let title = 'Dialog';
213
+ export let data = {};
214
+ export let onSave = null;
215
+
216
+ const actions = [
217
+ {
218
+ label: 'Save',
219
+ type: 'primary',
220
+ handler: async () => {
221
+ // Validation logic
222
+ if (!data.name) {
223
+ alert('Name is required');
224
+ return false; // Don't close dialog
225
+ }
226
+
227
+ // Save logic
228
+ await onSave?.(data);
229
+ return true; // Close dialog
230
+ }
231
+ }
232
+ ];
233
+
234
+ const closeConfirm = async () => {
235
+ if (hasChanges) {
236
+ return await window.MessageBox.showConfirm(
237
+ 'You have unsaved changes. Are you sure?',
238
+ 'Confirm Close'
239
+ ) === ModalResult.Ok;
240
+ }
241
+ return true;
242
+ };
243
+ </script>
244
+
245
+ <Dialog {title} {actions} {closeConfirm} width="600px">
246
+ <!-- Your dialog content -->
247
+ <form>
248
+ <input bind:value={data.name} placeholder="Name" />
249
+ <!-- More form fields -->
250
+ </form>
251
+ </Dialog>
252
+ ```
253
+
254
+ ## Action Buttons
255
+
256
+ ### Button Configuration
257
+
258
+ ```typescript
259
+ type ButtonAction = {
260
+ label: string;
261
+ type?: 'primary' | 'secondary' | 'danger';
262
+ disabled?: boolean;
263
+ handler?: (event: MouseEvent) => Promise<boolean> | boolean;
264
+ };
265
+
266
+ type ButtonActions = (ButtonAction | null)[];
267
+ ```
268
+
269
+ ### Examples
270
+
271
+ ```svelte
272
+ <script>
273
+ const actions = [
274
+ {
275
+ label: 'Delete',
276
+ type: 'danger',
277
+ handler: async () => {
278
+ const confirmed = await confirmDelete();
279
+ if (confirmed) {
280
+ await deleteItem();
281
+ return true; // Close dialog
282
+ }
283
+ return false; // Keep dialog open
284
+ }
285
+ },
286
+ null, // Separator
287
+ {
288
+ label: 'Save',
289
+ type: 'primary',
290
+ disabled: !isValid,
291
+ handler: async () => {
292
+ await saveData();
293
+ return true;
294
+ }
295
+ }
296
+ ];
297
+ </script>
298
+ ```
299
+
300
+ ## Close Confirmation
301
+
302
+ Add confirmation before closing with unsaved changes:
303
+
304
+ ```svelte
305
+ <script>
306
+ let originalData = JSON.stringify(data);
307
+
308
+ const closeConfirm = async () => {
309
+ const hasChanges = JSON.stringify(data) !== originalData;
310
+ if (hasChanges) {
311
+ return await window.MessageBox.showConfirm(
312
+ 'You have unsaved changes. Close anyway?',
313
+ 'Confirm Close'
314
+ ) === ModalResult.Ok;
315
+ }
316
+ return true;
317
+ };
318
+ </script>
319
+
320
+ <Dialog {closeConfirm} {/* other props */}>
321
+ <!-- content -->
322
+ </Dialog>
323
+ ```
324
+
325
+ ## Modal Results
326
+
327
+ ```typescript
328
+ enum ModalResult {
329
+ Cancel = 0, // User cancelled or closed dialog
330
+ Ok = 1 // User confirmed or completed action
331
+ }
332
+ ```
333
+
334
+ ### Handling Results
335
+
336
+ ```svelte
337
+ <script>
338
+ function handleDialogClose(result) {
339
+ if (result === ModalResult.Ok) {
340
+ console.log('User confirmed');
341
+ } else {
342
+ console.log('User cancelled');
343
+ }
344
+ }
345
+ </script>
346
+ ```
347
+
348
+ ## Dialog Sizing and Positioning
349
+
350
+ ### Responsive Sizing
351
+
352
+ ```svelte
353
+ <!-- Fixed size -->
354
+ <Dialog width="500px" height="400px">
355
+
356
+ <!-- Responsive size -->
357
+ <Dialog width="90vw" height="80vh">
358
+
359
+ <!-- Auto size with max constraints -->
360
+ <Dialog
361
+ width="min(800px, 90vw)"
362
+ height="min(600px, 80vh)"
363
+ >
364
+ ```
365
+
366
+ ### Custom Styling
367
+
368
+ ```svelte
369
+ <Dialog
370
+ dialog$style="border-radius: 12px; box-shadow: 0 20px 40px rgba(0,0,0,0.3);"
371
+ content$style="padding: 2rem; background: #f9f9f9;"
372
+ >
373
+ ```
374
+
375
+ ## Advanced Examples
376
+
377
+ ### Form Dialog with Validation
378
+
379
+ ```svelte
380
+ <!-- UserFormDialog.svelte -->
381
+ <script>
382
+ import Dialog from '$lib/dialog';
383
+ import FormField from '$lib/form-field';
384
+ import TextEditor from '$lib/text-editor';
385
+
386
+ export let user = { name: '', email: '' };
387
+ export let onSave = null;
388
+
389
+ let errors = {};
390
+
391
+ function validate() {
392
+ errors = {};
393
+ if (!user.name) errors.name = 'Name is required';
394
+ if (!user.email) errors.email = 'Email is required';
395
+ if (user.email && !user.email.includes('@')) errors.email = 'Invalid email';
396
+ return Object.keys(errors).length === 0;
397
+ }
398
+
399
+ const actions = [
400
+ {
401
+ label: 'Save User',
402
+ type: 'primary',
403
+ handler: async () => {
404
+ if (!validate()) return false;
405
+
406
+ try {
407
+ await onSave?.(user);
408
+ return true;
409
+ } catch (error) {
410
+ console.error('Save failed:', error);
411
+ return false;
412
+ }
413
+ }
414
+ }
415
+ ];
416
+ </script>
417
+
418
+ <Dialog title="User Details" {actions} width="500px">
419
+ <div style="padding: 1rem;">
420
+ <FormField label="Name" error={errors.name}>
421
+ <TextEditor bind:value={user.name} />
422
+ </FormField>
423
+
424
+ <FormField label="Email" error={errors.email}>
425
+ <TextEditor bind:value={user.email} type="email" />
426
+ </FormField>
427
+ </div>
428
+ </Dialog>
429
+ ```
430
+
431
+ ### Master-Detail Dialog
432
+
433
+ ```svelte
434
+ <!-- ProjectDialog.svelte -->
435
+ <script>
436
+ import Dialog from '$lib/dialog';
437
+ import DataTable from '$lib/data-table';
438
+
439
+ export let project = { name: '', tasks: [] };
440
+
441
+ let selectedTask = null;
442
+
443
+ const actions = [
444
+ {
445
+ label: 'Add Task',
446
+ type: 'secondary',
447
+ handler: () => {
448
+ project.tasks = [...project.tasks, { name: 'New Task', status: 'pending' }];
449
+ return false; // Keep dialog open
450
+ }
451
+ },
452
+ {
453
+ label: 'Save Project',
454
+ type: 'primary',
455
+ handler: async () => {
456
+ await saveProject(project);
457
+ return true;
458
+ }
459
+ }
460
+ ];
461
+
462
+ const taskColumns = [
463
+ { title: 'Task Name', field: 'name' },
464
+ { title: 'Status', field: 'status' }
465
+ ];
466
+ </script>
467
+
468
+ <Dialog title="Project Details" {actions} width="800px" height="600px">
469
+ <div style="display: flex; height: 100%; gap: 1rem; padding: 1rem;">
470
+ <!-- Project Info -->
471
+ <div style="flex: 1;">
472
+ <h3>Project Information</h3>
473
+ <FormField label="Project Name">
474
+ <TextEditor bind:value={project.name} />
475
+ </FormField>
476
+ </div>
477
+
478
+ <!-- Tasks List -->
479
+ <div style="flex: 2;">
480
+ <h3>Tasks</h3>
481
+ <DataTable
482
+ list={project.tasks}
483
+ columns={taskColumns}
484
+ bind:selectedRow={selectedTask}
485
+ />
486
+ </div>
487
+ </div>
488
+ </Dialog>
489
+ ```
490
+
491
+ ## Styling
492
+
493
+ ### CSS Variables
494
+
495
+ ```css
496
+ .uniface-dialog {
497
+ --dialog-background: white;
498
+ --dialog-border-radius: 8px;
499
+ --dialog-shadow: 0 10px 30px rgba(0,0,0,0.2);
500
+ --title-bar-background: #f5f5f5;
501
+ --title-bar-color: #333;
502
+ }
503
+ ```
504
+
505
+ ### Custom Dialog Styles
506
+
507
+ ```scss
508
+ .custom-dialog {
509
+ .uniface-dialog-box {
510
+ border-radius: 12px;
511
+ overflow: hidden;
512
+
513
+ .title-bar {
514
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
515
+ color: white;
516
+ }
517
+
518
+ .dialog-content {
519
+ background: #fafafa;
520
+ }
521
+ }
522
+ }
523
+ ```
524
+
525
+ ## Accessibility
526
+
527
+ - **ARIA Labels**: Proper labeling for screen readers
528
+ - **Keyboard Navigation**: Tab through buttons and form elements
529
+ - **Focus Management**: Auto-focus on dialog open, restore on close
530
+ - **Escape Key**: Close dialog with Escape key
531
+ - **Modal Behavior**: Trap focus within dialog
532
+
533
+ ## Best Practices
534
+
535
+ ### 1. Dialog Size Guidelines
536
+ - Mobile: Use `width="95vw"` for mobile-friendly dialogs
537
+ - Desktop: Prefer fixed widths like `"500px"` or `"800px"`
538
+ - Content-driven: Use `"auto"` with max-width constraints
539
+
540
+ ### 2. Action Button Patterns
541
+ - Primary action on the right
542
+ - Destructive actions with `type="danger"`
543
+ - Use separators (`null`) to group related actions
544
+
545
+ ### 3. Form Validation
546
+ - Validate before allowing dialog to close
547
+ - Show field-level errors
548
+ - Disable submit button when form is invalid
549
+
550
+ ### 4. Data Management
551
+ - Use reactive statements to enable/disable buttons
552
+ - Implement close confirmation for forms with changes
553
+ - Pass callbacks for data persistence
554
+
555
+ ### 5. Error Handling
556
+ - Handle async errors in action handlers
557
+ - Show user-friendly error messages
558
+ - Keep dialog open on save failures
559
+
560
+ ## Type Definitions
561
+
562
+ ```typescript
563
+ interface DialogCloseConfirm {
564
+ (): Promise<boolean>;
565
+ }
566
+
567
+ interface ButtonAction {
568
+ label: string;
569
+ type?: 'primary' | 'secondary' | 'danger';
570
+ disabled?: boolean;
571
+ handler?: (event: MouseEvent) => Promise<boolean> | boolean;
572
+ }
573
+
574
+ type ButtonActions = (ButtonAction | null)[];
575
+
576
+ type OnClose = (result: ModalResult) => void;
577
+
578
+ interface IDialog {
579
+ showModal: (component: any, params: any) => void;
580
+ }
581
+ ```
582
+
583
+ ## Migration Guide
584
+
585
+ ### From v1.x to v2.x
586
+ - `DialogBoard` is now required in your app
587
+ - Global dialog API is automatically initialized
588
+ - Modal results are now enum-based instead of string-based
589
+
590
+ ## Notes
591
+
592
+ - Dialogs are automatically managed by the DialogBoard component
593
+ - Multiple dialogs can be open simultaneously (stacked)
594
+ - Drag and drop functionality is enabled by default on the title bar
595
+ - The dialog system uses Svelte transitions for smooth animations
596
+ - Action button handlers should return `true` to close the dialog, `false` to keep it open