@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 对话框组件
2
+
3
+ 基于 Svelte 构建的全面对话框系统,提供具有拖拽功能、操作按钮和高级生命周期管理的灵活模态对话框。
4
+
5
+ ## 特性
6
+
7
+ - **多种对话框类型**:Dialog、CommonDialog 和 DialogBoard 组件
8
+ - **拖拽功能**:可通过标题栏拖拽移动的对话框
9
+ - **操作按钮**:可配置的按钮操作,自动处理结果
10
+ - **关闭确认**:关闭前的可选确认对话框
11
+ - **模态管理**:基于堆栈的对话框管理,带有遮罩层
12
+ - **响应式设计**:自动调整大小和定位
13
+ - **无障碍访问**:ARIA 支持和键盘导航
14
+ - **生命周期钩子**:带结果处理的 onClose 回调
15
+ - **全局对话框 API**:窗口级别的对话框管理
16
+ - **可定制样式**:灵活的主题和大小选项
17
+
18
+ ## 安装
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
+ 或者在同一项目中使用:
29
+ ```typescript
30
+ import Dialog, { CommonDialog, DialogBoard } from '$lib/dialog';
31
+ ```
32
+
33
+ ## 组件概览
34
+
35
+ ### Dialog
36
+ 具有完全自定义选项的基础对话框组件。
37
+
38
+ ### CommonDialog
39
+ 具有内置确认/取消操作的简化对话框。
40
+
41
+ ### DialogBoard
42
+ 对话框容器和管理系统。
43
+
44
+ ## 设置
45
+
46
+ ### 1. 将 DialogBoard 添加到您的应用
47
+
48
+ 首先,将 DialogBoard 组件添加到您的主应用布局中:
49
+
50
+ ```svelte
51
+ <!-- App.svelte 或 +layout.svelte -->
52
+ <script>
53
+ import { DialogBoard } from '$lib/dialog';
54
+ </script>
55
+
56
+ <!-- 您的应用内容 -->
57
+ <main>
58
+ <!-- 您的路由和组件 -->
59
+ </main>
60
+
61
+ <!-- 对话框容器(应放在最后) -->
62
+ <DialogBoard />
63
+ ```
64
+
65
+ ### 2. 初始化全局对话框 API
66
+
67
+ DialogBoard 在挂载时会自动初始化全局 `window.Dialog` API。
68
+
69
+ ## Dialog 组件
70
+
71
+ ### 基本用法
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: '保存',
83
+ type: 'primary',
84
+ handler: async () => {
85
+ // 保存逻辑
86
+ console.log('正在保存...');
87
+ return true; // 返回 true 关闭对话框
88
+ }
89
+ }
90
+ ];
91
+
92
+ function handleClose(result) {
93
+ console.log('对话框关闭,结果:', result);
94
+ showDialog = false;
95
+ }
96
+ </script>
97
+
98
+ {#if showDialog}
99
+ <Dialog
100
+ title="我的对话框"
101
+ {actions}
102
+ onClose={handleClose}
103
+ width="500px"
104
+ height="300px"
105
+ >
106
+ <p>对话框内容放在这里...</p>
107
+ </Dialog>
108
+ {/if}
109
+ ```
110
+
111
+ ### 属性
112
+
113
+ | 属性 | 类型 | 默认值 | 描述 |
114
+ |------|------|---------|-------------|
115
+ | `title` | `string` | `''` | 显示在标题栏的对话框标题 |
116
+ | `width` | `string` | `'unset'` | 对话框宽度(CSS 值) |
117
+ | `height` | `string` | `'unset'` | 对话框高度(CSS 值) |
118
+ | `actions` | `ButtonActions \| null` | `null` | 操作按钮数组 |
119
+ | `closeConfirm` | `DialogCloseConfirm \| null` | `null` | 关闭前的确认函数 |
120
+ | `content$style` | `string` | `''` | 内容区域的自定义样式 |
121
+ | `closeAction` | `ButtonAction \| null` | `null` | 自定义关闭按钮配置 |
122
+ | `onClose` | `OnClose \| null` | `null` | 对话框关闭时的回调 |
123
+ | `dialog$style` | `string` | `''` | 对话框容器的自定义样式 |
124
+
125
+ ### 方法
126
+
127
+ | 方法 | 描述 |
128
+ |--------|-------------|
129
+ | `close(result: ModalResult)` | 程序化关闭对话框并返回结果 |
130
+
131
+ ## CommonDialog 组件
132
+
133
+ 具有内置确认/取消模式的简化对话框。
134
+
135
+ ### 基本用法
136
+
137
+ ```svelte
138
+ <script>
139
+ import { CommonDialog } from '$lib/dialog';
140
+
141
+ let showDialog = false;
142
+
143
+ async function handleConfirm() {
144
+ // 您的确认逻辑
145
+ console.log('已确认!');
146
+ return true; // 返回 true 关闭对话框
147
+ }
148
+
149
+ function handleClose(result) {
150
+ console.log('对话框结果:', result);
151
+ showDialog = false;
152
+ }
153
+ </script>
154
+
155
+ {#if showDialog}
156
+ <CommonDialog
157
+ title="确认操作"
158
+ confirmHandler={handleConfirm}
159
+ onClose={handleClose}
160
+ width="400px"
161
+ >
162
+ <p>您确定要继续吗?</p>
163
+ </CommonDialog>
164
+ {/if}
165
+ ```
166
+
167
+ ### 属性
168
+
169
+ | 属性 | 类型 | 默认值 | 描述 |
170
+ |------|------|---------|-------------|
171
+ | `title` | `string` | `''` | 对话框标题 |
172
+ | `width` | `string` | `'unset'` | 对话框宽度 |
173
+ | `height` | `string` | `'unset'` | 对话框高度 |
174
+ | `closeConfirm` | `DialogCloseConfirm \| null` | `null` | 关闭确认函数 |
175
+ | `content$style` | `string` | `''` | 内容区域样式 |
176
+ | `enableConfirm` | `boolean` | `true` | 启用/禁用确认按钮 |
177
+ | `confirmHandler` | `(() => Promise<any>) \| null` | `null` | 确认按钮处理器 |
178
+ | `confirmText` | `string \| null` | `null` | 自定义确认按钮文本 |
179
+ | `onClose` | `OnClose \| null` | `null` | 关闭回调 |
180
+
181
+ ## 全局对话框 API
182
+
183
+ 使用全局 `window.Dialog` API 从应用的任何地方显示对话框。
184
+
185
+ ### 显示对话框
186
+
187
+ ```svelte
188
+ <script>
189
+ import MyDialogContent from './MyDialogContent.svelte';
190
+
191
+ function openDialog() {
192
+ window.Dialog.showModal(MyDialogContent, {
193
+ title: '我的对话框',
194
+ data: { /* 初始数据 */ },
195
+ onSave: (data) => console.log('已保存:', data)
196
+ });
197
+ }
198
+ </script>
199
+
200
+ <button on:click={openDialog}>打开对话框</button>
201
+ ```
202
+
203
+ ### 创建对话框内容组件
204
+
205
+ ```svelte
206
+ <!-- MyDialogContent.svelte -->
207
+ <script>
208
+ import Dialog from '$lib/dialog';
209
+ import { ModalResult } from '$lib/dialog/ModalResult';
210
+
211
+ // 从 showModal 传递的属性
212
+ export let title = '对话框';
213
+ export let data = {};
214
+ export let onSave = null;
215
+
216
+ const actions = [
217
+ {
218
+ label: '保存',
219
+ type: 'primary',
220
+ handler: async () => {
221
+ // 验证逻辑
222
+ if (!data.name) {
223
+ alert('姓名是必填的');
224
+ return false; // 不关闭对话框
225
+ }
226
+
227
+ // 保存逻辑
228
+ await onSave?.(data);
229
+ return true; // 关闭对话框
230
+ }
231
+ }
232
+ ];
233
+
234
+ const closeConfirm = async () => {
235
+ if (hasChanges) {
236
+ return await window.MessageBox.showConfirm(
237
+ '您有未保存的更改。确定要关闭吗?',
238
+ '确认关闭'
239
+ ) === ModalResult.Ok;
240
+ }
241
+ return true;
242
+ };
243
+ </script>
244
+
245
+ <Dialog {title} {actions} {closeConfirm} width="600px">
246
+ <!-- 您的对话框内容 -->
247
+ <form>
248
+ <input bind:value={data.name} placeholder="姓名" />
249
+ <!-- 更多表单字段 -->
250
+ </form>
251
+ </Dialog>
252
+ ```
253
+
254
+ ## 操作按钮
255
+
256
+ ### 按钮配置
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
+ ### 示例
270
+
271
+ ```svelte
272
+ <script>
273
+ const actions = [
274
+ {
275
+ label: '删除',
276
+ type: 'danger',
277
+ handler: async () => {
278
+ const confirmed = await confirmDelete();
279
+ if (confirmed) {
280
+ await deleteItem();
281
+ return true; // 关闭对话框
282
+ }
283
+ return false; // 保持对话框打开
284
+ }
285
+ },
286
+ null, // 分隔符
287
+ {
288
+ label: '保存',
289
+ type: 'primary',
290
+ disabled: !isValid,
291
+ handler: async () => {
292
+ await saveData();
293
+ return true;
294
+ }
295
+ }
296
+ ];
297
+ </script>
298
+ ```
299
+
300
+ ## 关闭确认
301
+
302
+ 为有未保存更改的情况添加关闭确认:
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
+ '您有未保存的更改。仍要关闭吗?',
313
+ '确认关闭'
314
+ ) === ModalResult.Ok;
315
+ }
316
+ return true;
317
+ };
318
+ </script>
319
+
320
+ <Dialog {closeConfirm} {/* 其他属性 */}>
321
+ <!-- 内容 -->
322
+ </Dialog>
323
+ ```
324
+
325
+ ## 模态结果
326
+
327
+ ```typescript
328
+ enum ModalResult {
329
+ Cancel = 0, // 用户取消或关闭对话框
330
+ Ok = 1 // 用户确认或完成操作
331
+ }
332
+ ```
333
+
334
+ ### 处理结果
335
+
336
+ ```svelte
337
+ <script>
338
+ function handleDialogClose(result) {
339
+ if (result === ModalResult.Ok) {
340
+ console.log('用户确认');
341
+ } else {
342
+ console.log('用户取消');
343
+ }
344
+ }
345
+ </script>
346
+ ```
347
+
348
+ ## 对话框大小和定位
349
+
350
+ ### 响应式大小
351
+
352
+ ```svelte
353
+ <!-- 固定大小 -->
354
+ <Dialog width="500px" height="400px">
355
+
356
+ <!-- 响应式大小 -->
357
+ <Dialog width="90vw" height="80vh">
358
+
359
+ <!-- 自动大小,带最大约束 -->
360
+ <Dialog
361
+ width="min(800px, 90vw)"
362
+ height="min(600px, 80vh)"
363
+ >
364
+ ```
365
+
366
+ ### 自定义样式
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
+ ## 高级示例
376
+
377
+ ### 带验证的表单对话框
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 = '姓名是必填的';
394
+ if (!user.email) errors.email = '邮箱是必填的';
395
+ if (user.email && !user.email.includes('@')) errors.email = '邮箱格式无效';
396
+ return Object.keys(errors).length === 0;
397
+ }
398
+
399
+ const actions = [
400
+ {
401
+ label: '保存用户',
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('保存失败:', error);
411
+ return false;
412
+ }
413
+ }
414
+ }
415
+ ];
416
+ </script>
417
+
418
+ <Dialog title="用户详情" {actions} width="500px">
419
+ <div style="padding: 1rem;">
420
+ <FormField label="姓名" error={errors.name}>
421
+ <TextEditor bind:value={user.name} />
422
+ </FormField>
423
+
424
+ <FormField label="邮箱" error={errors.email}>
425
+ <TextEditor bind:value={user.email} type="email" />
426
+ </FormField>
427
+ </div>
428
+ </Dialog>
429
+ ```
430
+
431
+ ### 主从详情对话框
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: '添加任务',
446
+ type: 'secondary',
447
+ handler: () => {
448
+ project.tasks = [...project.tasks, { name: '新任务', status: '待处理' }];
449
+ return false; // 保持对话框打开
450
+ }
451
+ },
452
+ {
453
+ label: '保存项目',
454
+ type: 'primary',
455
+ handler: async () => {
456
+ await saveProject(project);
457
+ return true;
458
+ }
459
+ }
460
+ ];
461
+
462
+ const taskColumns = [
463
+ { title: '任务名称', field: 'name' },
464
+ { title: '状态', field: 'status' }
465
+ ];
466
+ </script>
467
+
468
+ <Dialog title="项目详情" {actions} width="800px" height="600px">
469
+ <div style="display: flex; height: 100%; gap: 1rem; padding: 1rem;">
470
+ <!-- 项目信息 -->
471
+ <div style="flex: 1;">
472
+ <h3>项目信息</h3>
473
+ <FormField label="项目名称">
474
+ <TextEditor bind:value={project.name} />
475
+ </FormField>
476
+ </div>
477
+
478
+ <!-- 任务列表 -->
479
+ <div style="flex: 2;">
480
+ <h3>任务</h3>
481
+ <DataTable
482
+ list={project.tasks}
483
+ columns={taskColumns}
484
+ bind:selectedRow={selectedTask}
485
+ />
486
+ </div>
487
+ </div>
488
+ </Dialog>
489
+ ```
490
+
491
+ ## 样式定制
492
+
493
+ ### CSS 变量
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
+ ### 自定义对话框样式
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
+ ## 无障碍访问
526
+
527
+ - **ARIA 标签**:为屏幕阅读器提供适当的标签
528
+ - **键盘导航**:通过 Tab 在按钮和表单元素间切换
529
+ - **焦点管理**:对话框打开时自动聚焦,关闭时恢复焦点
530
+ - **Escape 键**:使用 Escape 键关闭对话框
531
+ - **模态行为**:将焦点限制在对话框内
532
+
533
+ ## 最佳实践
534
+
535
+ ### 1. 对话框大小指南
536
+ - 移动端:使用 `width="95vw"` 制作移动友好的对话框
537
+ - 桌面端:优先使用固定宽度如 `"500px"` 或 `"800px"`
538
+ - 内容驱动:使用 `"auto"` 并带有最大宽度约束
539
+
540
+ ### 2. 操作按钮模式
541
+ - 主要操作放在右侧
542
+ - 破坏性操作使用 `type="danger"`
543
+ - 使用分隔符(`null`)分组相关操作
544
+
545
+ ### 3. 表单验证
546
+ - 在允许对话框关闭前验证
547
+ - 显示字段级错误
548
+ - 表单无效时禁用提交按钮
549
+
550
+ ### 4. 数据管理
551
+ - 使用响应式语句启用/禁用按钮
552
+ - 为有更改的表单实现关闭确认
553
+ - 传递数据持久化的回调
554
+
555
+ ### 5. 错误处理
556
+ - 在操作处理器中处理异步错误
557
+ - 显示用户友好的错误消息
558
+ - 保存失败时保持对话框打开
559
+
560
+ ## 类型定义
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
+ ## 迁移指南
584
+
585
+ ### 从 v1.x 到 v2.x
586
+ - 您的应用现在需要 `DialogBoard`
587
+ - 全局对话框 API 会自动初始化
588
+ - 模态结果现在基于枚举而不是字符串
589
+
590
+ ## 注意事项
591
+
592
+ - 对话框由 DialogBoard 组件自动管理
593
+ - 可以同时打开多个对话框(堆叠)
594
+ - 标题栏默认启用拖拽功能
595
+ - 对话框系统使用 Svelte 过渡实现平滑动画
596
+ - 操作按钮处理器应返回 `true` 关闭对话框,返回 `false` 保持打开