@ticatec/uniface-element 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +320 -1
  2. package/README_CN.md +392 -0
  3. package/dist/accordion/Accordion.svelte +1 -1
  4. package/dist/action-bar/ActionBar.svelte +7 -1
  5. package/dist/attachment-files/FileRender.svelte +1 -1
  6. package/dist/attachment-files/FileUploadBar.svelte +7 -6
  7. package/dist/attachment-files/FileUploadPanel.svelte +2 -2
  8. package/dist/base-calendar/DateContext.js +5 -4
  9. package/dist/base-calendar/YearPickupPanel.svelte +4 -4
  10. package/dist/card/Card.svelte +1 -1
  11. package/dist/card/Card.svelte.d.ts +1 -1
  12. package/dist/cascade-options-select/CascadeOptionSelect.svelte +2 -3
  13. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +46 -1
  14. package/dist/cascade-options-select/CascadePanel.svelte +1 -1
  15. package/dist/checkbox/CheckBox.svelte +1 -1
  16. package/dist/color-picker/ColorPicker.svelte +9 -9
  17. package/dist/color-picker/ColorPicker.svelte.d.ts +0 -2
  18. package/dist/color-picker/ColorPickerPanel.svelte +11 -15
  19. package/dist/color-picker/ColorPickerPanel.svelte.d.ts +1 -1
  20. package/dist/common/CommonPicker.svelte +2 -2
  21. package/dist/common/CommonPicker.svelte.d.ts +1 -1
  22. package/dist/common/MouseClickHandler.d.ts +1 -1
  23. package/dist/common/Popover.svelte +28 -6
  24. package/dist/common/Popover.svelte.d.ts +9 -3
  25. package/dist/common/uniface-utils.js +6 -4
  26. package/dist/common-editor/CommonEditor.svelte +1 -1
  27. package/dist/common-editor/CommonEditor.svelte.d.ts +1 -1
  28. package/dist/common-editor/NumberInput.svelte +1 -1
  29. package/dist/common-editor/NumberInput.svelte.d.ts +1 -1
  30. package/dist/concise-data-table/ConciseListTable.svelte +7 -2
  31. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +1 -0
  32. package/dist/concise-data-table/DataRow.svelte +1 -1
  33. package/dist/concise-data-table/TableOptions.d.ts +1 -1
  34. package/dist/data-table/DataTable.svelte +1 -1
  35. package/dist/data-table/parts/ActionsPanel.svelte +4 -3
  36. package/dist/data-table/parts/ActionsRow.svelte +3 -3
  37. package/dist/data-table/parts/ContentPanel.svelte +3 -2
  38. package/dist/data-table/parts/FixedColumnsPanel.svelte +0 -1
  39. package/dist/data-table/parts/FixedColumnsPanel.svelte.d.ts +1 -2
  40. package/dist/data-table/parts/FixedHeaderPanel.svelte +2 -2
  41. package/dist/data-table/parts/FixedRow.svelte +2 -1
  42. package/dist/data-table/parts/FixedRow.svelte.d.ts +1 -1
  43. package/dist/data-table/parts/HrefCell.svelte +23 -2
  44. package/dist/data-table/parts/PopupMenu.svelte +25 -2
  45. package/dist/data-table/parts/PopupMenu.svelte.d.ts +8 -1
  46. package/dist/date-picker/DatePicker.svelte +0 -1
  47. package/dist/date-picker/DateTimePicker.svelte +3 -3
  48. package/dist/date-picker/ScrollBar.svelte +4 -7
  49. package/dist/date-range/DateRangeEditor.svelte +1 -1
  50. package/dist/dialog/CommonDialog.svelte +8 -5
  51. package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
  52. package/dist/dialog/Dialog.svelte +37 -12
  53. package/dist/dialog/Dialog.svelte.d.ts +4 -3
  54. package/dist/dialog/DialogBoard.svelte +11 -8
  55. package/dist/dialog/DialogWrapper.svelte +10 -0
  56. package/dist/{common-editor/DateInput.svelte.d.ts → dialog/DialogWrapper.svelte.d.ts} +6 -13
  57. package/dist/dialog/Dialogs.js +1 -1
  58. package/dist/dialog/ModalResult.d.ts +5 -0
  59. package/dist/dialog/ModalResult.js +5 -0
  60. package/dist/drawer/Drawer.svelte +1 -1
  61. package/dist/form-field/FormField.svelte +2 -1
  62. package/dist/form-field/FormField.svelte.d.ts +1 -0
  63. package/dist/form-panel/flex-row-form/FormContainer.svelte +1 -1
  64. package/dist/form-panel/grid-form/EmptyCell.svelte +8 -7
  65. package/dist/form-panel/grid-form/EmptyCell.svelte.d.ts +2 -2
  66. package/dist/form-panel/grid-form/GridField.svelte +1 -1
  67. package/dist/i18nRes/i18nRes.d.ts +2 -0
  68. package/dist/i18nRes/i18nRes.js +44 -0
  69. package/dist/i18nRes/index.d.ts +2 -0
  70. package/dist/i18nRes/index.js +2 -0
  71. package/dist/image-files/ImageFilesField.svelte +1 -1
  72. package/dist/indicator/IndicatorBoard.svelte +1 -1
  73. package/dist/inline-cell-editor/InvalidEditor.svelte +1 -0
  74. package/dist/input-options-select/InputOptionsSelect.svelte +6 -6
  75. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +1 -1
  76. package/dist/layout/flex/FlexBlock.svelte +1 -1
  77. package/dist/lookup-editor/LookupEditor.svelte +1 -1
  78. package/dist/memo-editor/MemoEditor.svelte +2 -2
  79. package/dist/message-box/IMessageBox.d.ts +2 -4
  80. package/dist/message-box/IMessageBox.js +4 -6
  81. package/dist/message-box/MessageBoxBoard.svelte +1 -3
  82. package/dist/options-multi-select/OptionsMultiSelect.svelte +1 -1
  83. package/dist/prompts-text-editor/PromptsTextEditor.svelte +2 -2
  84. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +1 -1
  85. package/dist/property-editor/PropertyEditor.svelte +3 -3
  86. package/dist/text-editor/PasswordEditor.svelte +1 -1
  87. package/dist/transfer/Transfer.svelte +17 -12
  88. package/dist/transfer/Transfer.svelte.d.ts +0 -1
  89. package/dist/unit-number-editor/UnitNumberEditor.svelte +2 -2
  90. package/docs/buttons/cn/ActionBar.md +459 -0
  91. package/docs/buttons/cn/Button.md +228 -0
  92. package/docs/buttons/cn/IconButton.md +294 -0
  93. package/docs/buttons/cn/README.md +600 -0
  94. package/docs/buttons/cn/TextButton.md +163 -0
  95. package/docs/buttons/en/ActionBar.md +459 -0
  96. package/docs/buttons/en/Button.md +228 -0
  97. package/docs/buttons/en/IconButton.md +294 -0
  98. package/docs/buttons/en/README.md +600 -0
  99. package/docs/buttons/en/TextButton.md +163 -0
  100. package/docs/containers/cn/accordion.md +622 -0
  101. package/docs/containers/cn/box.md +445 -0
  102. package/docs/containers/cn/card.md +404 -0
  103. package/docs/containers/cn/page.md +576 -0
  104. package/docs/containers/cn/tabs.md +686 -0
  105. package/docs/containers/en/accordion.md +622 -0
  106. package/docs/containers/en/box.md +445 -0
  107. package/docs/containers/en/card.md +404 -0
  108. package/docs/containers/en/page.md +576 -0
  109. package/docs/containers/en/tabs.md +686 -0
  110. package/docs/data-display/cn/concise-data-table.md +731 -0
  111. package/docs/data-display/cn/listbox.md +786 -0
  112. package/docs/data-display/cn/treeview.md +863 -0
  113. package/docs/data-display/en/concise-data-table.md +732 -0
  114. package/docs/data-display/en/listbox.md +786 -0
  115. package/docs/data-display/en/treeview.md +863 -0
  116. package/docs/data-table/cn/README.md +596 -0
  117. package/docs/data-table/en/README.md +596 -0
  118. package/docs/dialog/cn/README.md +767 -0
  119. package/docs/dialog/en/README.md +767 -0
  120. package/docs/form/cn/README.md +847 -0
  121. package/docs/form/en/README.md +847 -0
  122. package/docs/form-components/cn/README.md +495 -0
  123. package/docs/form-components/cn/attachmentfilesfield.md +757 -0
  124. package/docs/form-components/cn/cascade-options-select.md +374 -0
  125. package/docs/form-components/cn/checkbox.md +58 -0
  126. package/docs/form-components/cn/date-picker.md +138 -0
  127. package/docs/form-components/cn/datetime-picker.md +228 -0
  128. package/docs/form-components/cn/group-checkbox.md +405 -0
  129. package/docs/form-components/cn/group-radiobox.md +525 -0
  130. package/docs/form-components/cn/imagefilesfield.md +651 -0
  131. package/docs/form-components/cn/input-options-select.md +250 -0
  132. package/docs/form-components/cn/lookup-editor.md +406 -0
  133. package/docs/form-components/cn/memoeditor.md +409 -0
  134. package/docs/form-components/cn/number-editor.md +261 -0
  135. package/docs/form-components/cn/options-multi-select.md +177 -0
  136. package/docs/form-components/cn/options-select.md +83 -0
  137. package/docs/form-components/cn/passwordeditor.md +538 -0
  138. package/docs/form-components/cn/prompts-text-editor.md +241 -0
  139. package/docs/form-components/cn/radiobutton.md +84 -0
  140. package/docs/form-components/cn/switch.md +178 -0
  141. package/docs/form-components/cn/text-editor.md +142 -0
  142. package/docs/form-components/cn/time-editor.md +159 -0
  143. package/docs/form-components/cn/unit-number-editor.md +164 -0
  144. package/docs/form-components/en/README.md +463 -0
  145. package/docs/form-components/en/attachmentfilesfield.md +757 -0
  146. package/docs/form-components/en/cascade-options-select.md +358 -0
  147. package/docs/form-components/en/checkbox.md +59 -0
  148. package/docs/form-components/en/date-picker.md +138 -0
  149. package/docs/form-components/en/datetime-picker.md +228 -0
  150. package/docs/form-components/en/group-checkbox.md +395 -0
  151. package/docs/form-components/en/group-radiobox.md +498 -0
  152. package/docs/form-components/en/imagefilesfield.md +651 -0
  153. package/docs/form-components/en/input-options-select.md +239 -0
  154. package/docs/form-components/en/lookup-editor.md +389 -0
  155. package/docs/form-components/en/memoeditor.md +409 -0
  156. package/docs/form-components/en/number-editor.md +249 -0
  157. package/docs/form-components/en/options-multi-select.md +177 -0
  158. package/docs/form-components/en/options-select.md +83 -0
  159. package/docs/form-components/en/passwordeditor.md +538 -0
  160. package/docs/form-components/en/prompts-text-editor.md +241 -0
  161. package/docs/form-components/en/radiobutton.md +84 -0
  162. package/docs/form-components/en/switch.md +180 -0
  163. package/docs/form-components/en/text-editor.md +142 -0
  164. package/docs/form-components/en/time-editor.md +159 -0
  165. package/docs/form-components/en/unit-number-editor.md +164 -0
  166. package/docs/form-layout/cn/criteria-field.md +652 -0
  167. package/docs/form-layout/cn/flex-form.md +454 -0
  168. package/docs/form-layout/cn/flex-row-form.md +542 -0
  169. package/docs/form-layout/cn/form-field.md +923 -0
  170. package/docs/form-layout/cn/grid-form.md +676 -0
  171. package/docs/form-layout/en/criteria-field.md +652 -0
  172. package/docs/form-layout/en/flex-form.md +454 -0
  173. package/docs/form-layout/en/flex-row-form.md +542 -0
  174. package/docs/form-layout/en/form-field.md +923 -0
  175. package/docs/form-layout/en/grid-form.md +676 -0
  176. package/docs/global/cn/README.md +534 -0
  177. package/docs/global/en/README.md +534 -0
  178. package/docs/layout/cn/classiclayout.md +460 -0
  179. package/docs/layout/cn/headerlayout.md +524 -0
  180. package/docs/layout/cn/sidebarlayout.md +263 -0
  181. package/docs/layout/en/classiclayout.md +951 -0
  182. package/docs/layout/en/headerlayout.md +524 -0
  183. package/docs/layout/en/sidebarlayout.md +262 -0
  184. package/docs/misc/cn/README.md +1217 -0
  185. package/docs/misc/en/README.md +1217 -0
  186. package/docs/navigation/cn/breadcrumb.md +291 -0
  187. package/docs/navigation/cn/navigator.md +322 -0
  188. package/docs/navigation/cn/navigatormenu.md +512 -0
  189. package/docs/navigation/cn/progressbar.md +199 -0
  190. package/docs/navigation/cn/progressstepbar.md +299 -0
  191. package/docs/navigation/en/breadcrumb.md +291 -0
  192. package/docs/navigation/en/navigator.md +322 -0
  193. package/docs/navigation/en/navigatormenu.md +512 -0
  194. package/docs/navigation/en/progressbar.md +199 -0
  195. package/docs/navigation/en/progressstepbar.md +299 -0
  196. package/docs/search-filters/cn/daterange.md +1156 -0
  197. package/docs/search-filters/cn/numberrange.md +688 -0
  198. package/docs/search-filters/cn/searchbox.md +1582 -0
  199. package/docs/search-filters/en/daterange.md +1156 -0
  200. package/docs/search-filters/en/numberrange.md +688 -0
  201. package/docs/search-filters/en/searchbox.md +1582 -0
  202. package/package.json +53 -13
  203. package/dist/common-editor/DateInput.svelte +0 -27
  204. package/dist/i18n_resources/index.d.ts +0 -3
  205. package/dist/i18n_resources/index.js +0 -3
  206. /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.d.ts +0 -0
  207. /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.js +0 -0
  208. /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.d.ts +0 -0
  209. /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.js +0 -0
@@ -0,0 +1,767 @@
1
+ # Dialog System
2
+
3
+ The Uniface Element Dialog System provides a comprehensive modal dialog solution for Svelte applications. It includes global dialog management, built-in dialog components, and flexible customization options.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Architecture Overview](#architecture-overview)
8
+ - [DialogBoard - Global Dialog Manager](#dialogboard---global-dialog-manager)
9
+ - [Built-in Dialog Components](#built-in-dialog-components)
10
+ - [Creating Custom Dialogs](#creating-custom-dialogs)
11
+ - [API Reference](#api-reference)
12
+ - [Advanced Usage](#advanced-usage)
13
+ - [Best Practices](#best-practices)
14
+
15
+ ## Architecture Overview
16
+
17
+ The dialog system consists of several interconnected components:
18
+
19
+ - **DialogBoard**: Global dialog manager that handles dialog lifecycle
20
+ - **Dialog**: Base dialog component with standard UI elements
21
+ - **CommonDialog**: Pre-configured dialog for common use cases
22
+ - **IDialog**: TypeScript interface for global dialog access
23
+ - **Dialogs Store**: Svelte store managing dialog state
24
+
25
+ ```mermaid
26
+ graph TD
27
+ A[DialogBoard] --> B[Dialogs Store]
28
+ A --> C[Dialog Components]
29
+ C --> D[Dialog.svelte]
30
+ C --> E[CommonDialog.svelte]
31
+ F[Custom Components] --> A
32
+ G[window.Dialog.showModal] --> A
33
+ ```
34
+
35
+ ## DialogBoard - Global Dialog Manager
36
+
37
+ The `DialogBoard` component manages all modal dialogs in your application and provides global access through the `window.Dialog` API.
38
+
39
+ ### Setup
40
+
41
+ Include `DialogBoard` in your root layout:
42
+
43
+ ```svelte
44
+ <!-- +layout.svelte or app.html -->
45
+ <script lang="ts">
46
+ import { DialogBoard } from "@ticatec/uniface-element/DialogBoard";
47
+ </script>
48
+
49
+ <!-- Your application content -->
50
+ <main>
51
+ <slot />
52
+ </main>
53
+
54
+ <!-- Global dialog manager -->
55
+ <DialogBoard />
56
+ ```
57
+
58
+ ### Global API
59
+
60
+ Once `DialogBoard` is mounted, you can access the dialog system globally:
61
+
62
+ ```typescript
63
+ // Open any Svelte component as a modal dialog
64
+ window.Dialog.showModal(MyComponent, {
65
+ // Props to pass to the component
66
+ title: "My Dialog",
67
+ data: someData,
68
+ onSave: (result) => {
69
+ console.log("Saved:", result);
70
+ }
71
+ });
72
+ ```
73
+
74
+ ### TypeScript Support
75
+
76
+ Add global type declarations:
77
+
78
+ ```typescript
79
+ // src/app.d.ts
80
+ import type { IDialog } from '@ticatec/uniface-element';
81
+
82
+ declare global {
83
+ interface Window {
84
+ Dialog: IDialog;
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Built-in Dialog Components
90
+
91
+ ### Dialog Component
92
+
93
+ The base `Dialog` component provides standard dialog functionality:
94
+
95
+ ```svelte
96
+ <script lang="ts">
97
+ import Dialog from '@ticatec/uniface-element/Dialog';
98
+ import type { ButtonActions } from '@ticatec/uniface-element';
99
+
100
+ let modalResult = null;
101
+
102
+ const actions: ButtonActions = [
103
+ {
104
+ label: "Save",
105
+ type: "primary",
106
+ handler: async () => {
107
+ // Perform save operation
108
+ await saveData();
109
+ return true; // Return true to auto-close dialog
110
+ }
111
+ }
112
+ ];
113
+
114
+ const onClose = (result) => {
115
+ console.log("Dialog closed with result:", result);
116
+ };
117
+ </script>
118
+
119
+ <Dialog
120
+ title="My Dialog"
121
+ width="500px"
122
+ height="400px"
123
+ bind:modalResult
124
+ {actions}
125
+ {onClose}
126
+ >
127
+ <!-- Dialog content -->
128
+ <p>This is the dialog content.</p>
129
+ </Dialog>
130
+ ```
131
+
132
+ #### Dialog Properties
133
+
134
+ | Property | Type | Description |
135
+ |----------|------|-------------|
136
+ | `title` | `string` | Dialog title |
137
+ | `width` | `string` | Dialog width (CSS value) |
138
+ | `height` | `string` | Dialog height (CSS value) |
139
+ | `actions` | `ButtonActions` | Array of action buttons |
140
+ | `closeConfirm` | `DialogCloseConfirm` | Confirmation function for close |
141
+ | `content$style` | `string` | Custom styles for content area |
142
+ | `modalResult` | `ModalResult` | Result binding for programmatic close |
143
+ | `onClose` | `OnClose` | Callback when dialog closes |
144
+
145
+ ### CommonDialog Component
146
+
147
+ The `CommonDialog` is a pre-configured dialog for typical use cases:
148
+
149
+ ```svelte
150
+ <script lang="ts">
151
+ import CommonDialog, ModalResult from '@ticatec/uniface-element/CommonDialog, ModalResult';
152
+
153
+ export let user: any;
154
+ export let onSave: (user: any) => void;
155
+
156
+ let modalResult = null;
157
+ let enableConfirm = true;
158
+
159
+ const confirmHandler = async () => {
160
+ try {
161
+ await onSave(user);
162
+ return true; // Return true to auto-close
163
+ } catch (error) {
164
+ console.error("Save failed:", error);
165
+ return false; // Keep dialog open on error
166
+ }
167
+ };
168
+
169
+ const onClose = (result) => {
170
+ if (result === ModalResult.Ok) {
171
+ console.log("User saved successfully");
172
+ }
173
+ };
174
+ </script>
175
+
176
+ <CommonDialog
177
+ title="Edit User"
178
+ width="600px"
179
+ height="500px"
180
+ bind:modalResult
181
+ bind:enableConfirm
182
+ {confirmHandler}
183
+ confirmText="Save Changes"
184
+ {onClose}
185
+ >
186
+ <div class="form-content">
187
+ <label>
188
+ Name:
189
+ <input bind:value={user.name} />
190
+ </label>
191
+ <label>
192
+ Email:
193
+ <input bind:value={user.email} type="email" />
194
+ </label>
195
+ </div>
196
+ </CommonDialog>
197
+
198
+ <style>
199
+ .form-content {
200
+ display: flex;
201
+ flex-direction: column;
202
+ gap: 16px;
203
+ }
204
+
205
+ label {
206
+ display: flex;
207
+ flex-direction: column;
208
+ gap: 4px;
209
+ }
210
+
211
+ input {
212
+ padding: 8px;
213
+ border: 1px solid #ccc;
214
+ border-radius: 4px;
215
+ }
216
+ </style>
217
+ ```
218
+
219
+ #### CommonDialog Properties
220
+
221
+ | Property | Type | Description |
222
+ |----------|------|-------------|
223
+ | `title` | `string` | Dialog title |
224
+ | `width` | `string` | Dialog width |
225
+ | `height` | `string` | Dialog height |
226
+ | `closeConfirm` | `DialogCloseConfirm` | Close confirmation function |
227
+ | `content$style` | `string` | Content area custom styles |
228
+ | `modalResult` | `ModalResult` | Result binding |
229
+ | `enableConfirm` | `boolean` | Enable/disable confirm button |
230
+ | `confirmHandler` | `() => Promise<boolean>` | Confirm button handler |
231
+ | `confirmText` | `string` | Custom confirm button text |
232
+ | `onClose` | `OnClose` | Close callback |
233
+
234
+ ## Creating Custom Dialogs
235
+
236
+ ### Method 1: Using Global Dialog API
237
+
238
+ ```svelte
239
+ <!-- UserEditDialog.svelte -->
240
+ <script lang="ts">
241
+ import { getContext } from 'svelte';
242
+ import CommonDialog, ModalResult from '@ticatec/uniface-element/CommonDialog, ModalResult';
243
+
244
+ export let user: any;
245
+ export let onSave: (user: any) => Promise<void>;
246
+
247
+ // Get close function from context
248
+ const closeDialog = getContext('closeDialog');
249
+
250
+ let saving = false;
251
+ let formData = { ...user };
252
+ let enableConfirm = true;
253
+
254
+ const handleSave = async () => {
255
+ if (saving) return false;
256
+
257
+ saving = true;
258
+ try {
259
+ await onSave(formData);
260
+ return true; // Auto-close on success
261
+ } catch (error) {
262
+ console.error('Save failed:', error);
263
+ return false; // Keep open on error
264
+ } finally {
265
+ saving = false;
266
+ }
267
+ };
268
+ </script>
269
+
270
+ <CommonDialog
271
+ title="Edit User"
272
+ width="600px"
273
+ height="400px"
274
+ bind:enableConfirm
275
+ confirmHandler={handleSave}
276
+ confirmText={saving ? "Saving..." : "Save Changes"}
277
+ >
278
+ <form class="user-form">
279
+ <div class="field">
280
+ <label for="name">Name:</label>
281
+ <input id="name" bind:value={formData.name} required />
282
+ </div>
283
+
284
+ <div class="field">
285
+ <label for="email">Email:</label>
286
+ <input id="email" type="email" bind:value={formData.email} required />
287
+ </div>
288
+
289
+ <div class="field">
290
+ <label for="role">Role:</label>
291
+ <select id="role" bind:value={formData.role}>
292
+ <option value="user">User</option>
293
+ <option value="admin">Admin</option>
294
+ <option value="moderator">Moderator</option>
295
+ </select>
296
+ </div>
297
+ </form>
298
+ </CommonDialog>
299
+
300
+ <style>
301
+ .user-form {
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: 16px;
305
+ padding: 20px;
306
+ }
307
+
308
+ .field {
309
+ display: flex;
310
+ flex-direction: column;
311
+ gap: 4px;
312
+ }
313
+
314
+ label {
315
+ font-weight: 500;
316
+ color: #374151;
317
+ }
318
+
319
+ input, select {
320
+ padding: 8px 12px;
321
+ border: 1px solid #d1d5db;
322
+ border-radius: 6px;
323
+ font-size: 14px;
324
+ }
325
+
326
+ input:focus, select:focus {
327
+ outline: none;
328
+ border-color: #3b82f6;
329
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
330
+ }
331
+ </style>
332
+ ```
333
+
334
+ ### Method 2: Custom Modal Component
335
+
336
+ ```svelte
337
+ <!-- ConfirmationDialog.svelte -->
338
+ <script lang="ts">
339
+ import { createEventDispatcher } from 'svelte';
340
+ import Button from '@ticatec/uniface-element/Button';
341
+
342
+ export let title = "Confirm Action";
343
+ export let message = "Are you sure you want to continue?";
344
+ export let confirmText = "Confirm";
345
+ export let cancelText = "Cancel";
346
+ export let danger = false;
347
+
348
+ const dispatch = createEventDispatcher();
349
+
350
+ const handleConfirm = () => {
351
+ dispatch('confirm');
352
+ };
353
+
354
+ const handleCancel = () => {
355
+ dispatch('cancel');
356
+ };
357
+
358
+ // Handle backdrop click
359
+ const handleBackdrop = (e) => {
360
+ if (e.target === e.currentTarget) {
361
+ handleCancel();
362
+ }
363
+ };
364
+ </script>
365
+
366
+ <div class="modal-backdrop" on:click={handleBackdrop}>
367
+ <div class="confirmation-dialog" role="dialog" aria-labelledby="dialog-title">
368
+ <div class="dialog-header">
369
+ <h2 id="dialog-title">{title}</h2>
370
+ </div>
371
+
372
+ <div class="dialog-body">
373
+ <p>{message}</p>
374
+ </div>
375
+
376
+ <div class="dialog-footer">
377
+ <Button
378
+ label={cancelText}
379
+ type="secondary"
380
+ onClick={handleCancel}
381
+ />
382
+ <Button
383
+ label={confirmText}
384
+ type={danger ? "third" : "primary"}
385
+ onClick={handleConfirm}
386
+ />
387
+ </div>
388
+ </div>
389
+ </div>
390
+
391
+ <style>
392
+ .modal-backdrop {
393
+ position: fixed;
394
+ top: 0;
395
+ left: 0;
396
+ width: 100%;
397
+ height: 100%;
398
+ background: rgba(0, 0, 0, 0.5);
399
+ display: flex;
400
+ align-items: center;
401
+ justify-content: center;
402
+ z-index: 1000;
403
+ }
404
+
405
+ .confirmation-dialog {
406
+ background: white;
407
+ border-radius: 8px;
408
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
409
+ max-width: 400px;
410
+ width: 90%;
411
+ max-height: 90vh;
412
+ overflow: hidden;
413
+ }
414
+
415
+ .dialog-header {
416
+ padding: 20px 20px 0;
417
+ }
418
+
419
+ .dialog-header h2 {
420
+ margin: 0;
421
+ font-size: 1.25rem;
422
+ color: #374151;
423
+ }
424
+
425
+ .dialog-body {
426
+ padding: 16px 20px;
427
+ }
428
+
429
+ .dialog-body p {
430
+ margin: 0;
431
+ color: #6b7280;
432
+ line-height: 1.5;
433
+ }
434
+
435
+ .dialog-footer {
436
+ padding: 16px 20px 20px;
437
+ display: flex;
438
+ justify-content: flex-end;
439
+ gap: 12px;
440
+ }
441
+ </style>
442
+ ```
443
+
444
+ ## Advanced Usage
445
+
446
+ ### Dialog with Form Validation
447
+
448
+ ```svelte
449
+ <script lang="ts">
450
+ import CommonDialog from '@ticatec/uniface-element/CommonDialog';
451
+
452
+ export let product: any;
453
+ export let onSave: (product: any) => Promise<void>;
454
+
455
+ let formData = { ...product };
456
+ let errors = {};
457
+ let saving = false;
458
+
459
+ $: enableConfirm = isFormValid(formData) && !saving;
460
+
461
+ const isFormValid = (data) => {
462
+ const newErrors = {};
463
+
464
+ if (!data.name?.trim()) {
465
+ newErrors.name = "Product name is required";
466
+ }
467
+
468
+ if (!data.price || data.price <= 0) {
469
+ newErrors.price = "Price must be greater than 0";
470
+ }
471
+
472
+ if (!data.category) {
473
+ newErrors.category = "Category is required";
474
+ }
475
+
476
+ errors = newErrors;
477
+ return Object.keys(newErrors).length === 0;
478
+ };
479
+
480
+ const handleSave = async () => {
481
+ if (!isFormValid(formData) || saving) {
482
+ return false;
483
+ }
484
+
485
+ saving = true;
486
+ try {
487
+ await onSave(formData);
488
+ return true;
489
+ } catch (error) {
490
+ console.error('Save failed:', error);
491
+ return false;
492
+ } finally {
493
+ saving = false;
494
+ }
495
+ };
496
+ </script>
497
+
498
+ <CommonDialog
499
+ title="Edit Product"
500
+ width="700px"
501
+ height="600px"
502
+ bind:enableConfirm
503
+ confirmHandler={handleSave}
504
+ confirmText={saving ? "Saving..." : "Save Product"}
505
+ >
506
+ <form class="product-form">
507
+ <div class="field">
508
+ <label for="name">Product Name *</label>
509
+ <input
510
+ id="name"
511
+ bind:value={formData.name}
512
+ class:error={errors.name}
513
+ placeholder="Enter product name"
514
+ />
515
+ {#if errors.name}
516
+ <span class="error-text">{errors.name}</span>
517
+ {/if}
518
+ </div>
519
+
520
+ <div class="field">
521
+ <label for="price">Price *</label>
522
+ <input
523
+ id="price"
524
+ type="number"
525
+ min="0"
526
+ step="0.01"
527
+ bind:value={formData.price}
528
+ class:error={errors.price}
529
+ placeholder="0.00"
530
+ />
531
+ {#if errors.price}
532
+ <span class="error-text">{errors.price}</span>
533
+ {/if}
534
+ </div>
535
+
536
+ <div class="field">
537
+ <label for="category">Category *</label>
538
+ <select
539
+ id="category"
540
+ bind:value={formData.category}
541
+ class:error={errors.category}
542
+ >
543
+ <option value="">Select category</option>
544
+ <option value="electronics">Electronics</option>
545
+ <option value="clothing">Clothing</option>
546
+ <option value="books">Books</option>
547
+ <option value="home">Home & Garden</option>
548
+ </select>
549
+ {#if errors.category}
550
+ <span class="error-text">{errors.category}</span>
551
+ {/if}
552
+ </div>
553
+
554
+ <div class="field">
555
+ <label for="description">Description</label>
556
+ <textarea
557
+ id="description"
558
+ bind:value={formData.description}
559
+ placeholder="Product description (optional)"
560
+ rows="4"
561
+ ></textarea>
562
+ </div>
563
+ </form>
564
+ </CommonDialog>
565
+
566
+ <style>
567
+ .product-form {
568
+ padding: 20px;
569
+ display: flex;
570
+ flex-direction: column;
571
+ gap: 16px;
572
+ }
573
+
574
+ .field {
575
+ display: flex;
576
+ flex-direction: column;
577
+ gap: 4px;
578
+ }
579
+
580
+ label {
581
+ font-weight: 500;
582
+ color: #374151;
583
+ font-size: 14px;
584
+ }
585
+
586
+ input, select, textarea {
587
+ padding: 8px 12px;
588
+ border: 1px solid #d1d5db;
589
+ border-radius: 6px;
590
+ font-size: 14px;
591
+ transition: border-color 0.2s, box-shadow 0.2s;
592
+ }
593
+
594
+ input:focus, select:focus, textarea:focus {
595
+ outline: none;
596
+ border-color: #3b82f6;
597
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
598
+ }
599
+
600
+ input.error, select.error, textarea.error {
601
+ border-color: #ef4444;
602
+ }
603
+
604
+ .error-text {
605
+ color: #ef4444;
606
+ font-size: 12px;
607
+ margin-top: 2px;
608
+ }
609
+
610
+ textarea {
611
+ resize: vertical;
612
+ min-height: 80px;
613
+ }
614
+ </style>
615
+ ```
616
+
617
+ ## API Reference
618
+
619
+ ### Global Dialog Interface
620
+
621
+ ```typescript
622
+ interface IDialog {
623
+ showModal<T>(component: any, props?: T): void;
624
+ }
625
+ ```
626
+
627
+ ### ModalResult Enum
628
+
629
+ ```typescript
630
+ enum ModalResult {
631
+ None = 0,
632
+ Ok = 1,
633
+ Cancel = 2,
634
+ Abort = 3,
635
+ Retry = 4,
636
+ Ignore = 5,
637
+ Yes = 6,
638
+ No = 7
639
+ }
640
+ ```
641
+
642
+ ### Event Handlers
643
+
644
+ ```typescript
645
+ type OnClose = (result: ModalResult) => void;
646
+ type DialogCloseConfirm = () => Promise<boolean>;
647
+ type ConfirmHandler = () => Promise<boolean>;
648
+ ```
649
+
650
+ ## Best Practices
651
+
652
+ ### 1. Use Appropriate Dialog Sizes
653
+
654
+ ```svelte
655
+ <!-- Small confirmation dialogs -->
656
+ <CommonDialog width="400px" height="200px">
657
+
658
+ <!-- Form dialogs -->
659
+ <CommonDialog width="600px" height="500px">
660
+
661
+ <!-- Large content dialogs -->
662
+ <CommonDialog width="800px" height="700px">
663
+ ```
664
+
665
+ ### 2. Handle Loading States
666
+
667
+ ```svelte
668
+ <script>
669
+ let saving = false;
670
+ let enableConfirm = true;
671
+
672
+ const handleSave = async () => {
673
+ saving = true;
674
+ enableConfirm = false;
675
+
676
+ try {
677
+ await saveData();
678
+ return true; // Close dialog
679
+ } catch (error) {
680
+ // Handle error, keep dialog open
681
+ return false;
682
+ } finally {
683
+ saving = false;
684
+ enableConfirm = true;
685
+ }
686
+ };
687
+ </script>
688
+
689
+ <CommonDialog
690
+ bind:enableConfirm
691
+ confirmHandler={handleSave}
692
+ confirmText={saving ? "Saving..." : "Save"}
693
+ >
694
+ ```
695
+
696
+ ### 3. Implement Proper Validation
697
+
698
+ ```svelte
699
+ <script>
700
+ let formData = { name: '', email: '' };
701
+ let errors = {};
702
+
703
+ $: enableConfirm = isValid(formData);
704
+
705
+ const isValid = (data) => {
706
+ return data.name.trim() &&
707
+ data.email.trim() &&
708
+ data.email.includes('@');
709
+ };
710
+ </script>
711
+ ```
712
+
713
+ ### 4. Use Context for Complex Dialogs
714
+
715
+ ```svelte
716
+ <script>
717
+ import { setContext } from 'svelte';
718
+
719
+ // Provide helper functions to child components
720
+ setContext('showNotification', (message) => {
721
+ // Show notification
722
+ });
723
+
724
+ setContext('closeDialog', () => {
725
+ modalResult = ModalResult.Cancel;
726
+ });
727
+ </script>
728
+ ```
729
+
730
+ ### 5. Keyboard Navigation Support
731
+
732
+ ```svelte
733
+ <script>
734
+ import { onMount } from 'svelte';
735
+
736
+ onMount(() => {
737
+ const handleKeydown = (e) => {
738
+ if (e.key === 'Escape') {
739
+ handleCancel();
740
+ } else if (e.key === 'Enter' && e.ctrlKey) {
741
+ handleConfirm();
742
+ }
743
+ };
744
+
745
+ document.addEventListener('keydown', handleKeydown);
746
+
747
+ return () => {
748
+ document.removeEventListener('keydown', handleKeydown);
749
+ };
750
+ });
751
+ </script>
752
+ ```
753
+
754
+ ## Accessibility Considerations
755
+
756
+ - Always provide proper `aria-labelledby` and `role="dialog"` attributes
757
+ - Ensure keyboard navigation works (Tab, Enter, Escape)
758
+ - Focus management - focus should be trapped within the dialog
759
+ - Provide clear visual indicators for required fields
760
+ - Use semantic HTML elements within dialog content
761
+ - Ensure sufficient color contrast for all text and interactive elements
762
+
763
+ ## Browser Support
764
+
765
+ - Modern browsers with ES2020+ support
766
+ - CSS Grid and Flexbox support required for layout
767
+ - JavaScript Proxy support needed for reactive stores