@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.
- package/dist/accordion/README.md +169 -0
- package/dist/accordion/README_CN.md +176 -0
- package/dist/action-bar/README.md +275 -0
- package/dist/action-bar/README_CN.md +285 -0
- package/dist/app-layout/README.md +374 -0
- package/dist/app-layout/README_CN.md +381 -0
- package/dist/app-top-bar/README.md +357 -0
- package/dist/app-top-bar/README_CN.md +365 -0
- package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
- package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
- package/dist/base-calendar/CalendarBase.svelte +0 -3
- package/dist/box/README.md +385 -0
- package/dist/box/README_CN.md +393 -0
- package/dist/breadcrumbs/README.md +442 -0
- package/dist/breadcrumbs/README_CN.md +442 -0
- package/dist/button/Button.svelte +27 -7
- package/dist/button/Button.svelte.d.ts +3 -1
- package/dist/button/IconButton.svelte +26 -6
- package/dist/button/IconButton.svelte.d.ts +3 -1
- package/dist/button/IconButton_README.md +513 -0
- package/dist/button/IconButton_README_CN.md +513 -0
- package/dist/button/README.md +428 -0
- package/dist/button/README_CN.md +428 -0
- package/dist/button/TextButton.svelte +26 -6
- package/dist/button/TextButton.svelte.d.ts +3 -1
- package/dist/button/TextButton_README.md +571 -0
- package/dist/button/TextButton_README_CN.md +571 -0
- package/dist/card/README.md +666 -0
- package/dist/card/README_CN.md +666 -0
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
- package/dist/cascade-options-select/README.md +663 -2
- package/dist/cascade-options-select/README_CN.md +664 -0
- package/dist/checkbox/CheckBox.svelte +20 -6
- package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
- package/dist/checkbox/README.md +562 -0
- package/dist/checkbox/README_CN.md +727 -0
- package/dist/common-editor/NumberInput.svelte +39 -26
- package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
- package/dist/concise-data-table/ConciseListTable.svelte +133 -36
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
- package/dist/concise-data-table/DataCell.svelte +5 -6
- package/dist/concise-data-table/DataRow.svelte +22 -2
- package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
- package/dist/concise-data-table/README.md +606 -0
- package/dist/concise-data-table/README_CN.md +611 -0
- package/dist/context-menu/ContextMenu.svelte +138 -21
- package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
- package/dist/context-menu/ContextMenuItem.d.ts +20 -4
- package/dist/context-menu/README.md +551 -0
- package/dist/context-menu/README_CN.md +551 -0
- package/dist/criteria-field/CriteriaField.svelte +3 -5
- package/dist/criteria-field/README.md +532 -0
- package/dist/criteria-field/README_CN.md +532 -0
- package/dist/data-table/README.md +712 -0
- package/dist/data-table/README_CN.md +712 -0
- package/dist/date-picker/DatePicker.svelte +44 -7
- package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
- package/dist/date-picker/DateTimePicker.svelte +32 -8
- package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
- package/dist/date-picker/README.md +326 -0
- package/dist/date-picker/README_CN.md +316 -0
- package/dist/date-picker/ScrollBar.svelte +18 -8
- package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
- package/dist/date-picker/TimePanel.svelte +5 -5
- package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
- package/dist/date-range/README.md +374 -0
- package/dist/date-range/README_CN.md +374 -0
- package/dist/dialog/README.md +596 -0
- package/dist/dialog/README_CN.md +596 -0
- package/dist/drawer/README.md +679 -1
- package/dist/drawer/README_CN.md +679 -0
- package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
- package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
- package/dist/group-box/group-check-box/README.md +749 -0
- package/dist/group-box/group-check-box/README_CN.md +750 -0
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
- package/dist/group-box/group-radio-box/README.md +920 -0
- package/dist/group-box/group-radio-box/README_CN.md +920 -0
- package/dist/image-files/README.md +1346 -0
- package/dist/image-files/README_CN.md +1346 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
- package/dist/lib/forwardAllEvents.d.ts +3 -0
- package/dist/lib/forwardAllEvents.js +24 -0
- package/dist/list-box/README.md +579 -0
- package/dist/list-box/README_CN.md +682 -0
- package/dist/lookup-editor/LookupEditor.svelte +15 -3
- package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
- package/dist/lookup-editor/README.md +684 -0
- package/dist/lookup-editor/README_CN.md +684 -0
- package/dist/memo-editor/MemoEditor.svelte +77 -27
- package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
- package/dist/memo-editor/README.md +819 -0
- package/dist/memo-editor/README_CN.md +819 -0
- package/dist/message-box/README.md +398 -0
- package/dist/message-box/README_CN.md +398 -0
- package/dist/number-editor/NumberEditor.svelte +2 -2
- package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
- package/dist/number-editor/README.md +353 -22
- package/dist/number-editor/README_CN.md +357 -0
- package/dist/number-range/README.md +443 -0
- package/dist/number-range/README_CN.md +443 -0
- package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
- package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
- package/dist/options-multi-select/README.md +480 -0
- package/dist/options-multi-select/README_CN.md +480 -0
- package/dist/options-select/OptionsSelect.svelte +36 -5
- package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
- package/dist/options-select/README.md +632 -0
- package/dist/options-select/README_CN.md +632 -0
- package/dist/page/README.md +605 -0
- package/dist/page/README_CN.md +605 -0
- package/dist/pagination/README.md +946 -0
- package/dist/pagination/README_CN.md +946 -0
- package/dist/pagination-panel/README.md +1075 -0
- package/dist/pagination-panel/README_CN.md +1075 -0
- package/dist/popup-hint/README.md +841 -0
- package/dist/popup-hint/README_CN.md +840 -0
- package/dist/progress-bar/README.md +242 -0
- package/dist/progress-bar/README_CN.md +242 -0
- package/dist/progress-step-bar/README.md +316 -0
- package/dist/progress-step-bar/README_CN.md +316 -0
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
- package/dist/prompts-text-editor/README.md +329 -0
- package/dist/prompts-text-editor/README_CN.md +329 -0
- package/dist/property-editor/README.md +969 -0
- package/dist/property-editor/README_CN.md +969 -0
- package/dist/radio-button/README.md +372 -0
- package/dist/radio-button/README_CN.md +372 -0
- package/dist/radio-button/RadioButton.svelte +32 -3
- package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
- package/dist/search-box/README.md +425 -0
- package/dist/search-box/README_CN.md +424 -0
- package/dist/search-box/SearchBox.svelte +22 -6
- package/dist/search-box/SearchBox.svelte.d.ts +4 -1
- package/dist/tabs/README.md +919 -0
- package/dist/tabs/README_CN.md +920 -0
- package/dist/tag/README.md +922 -0
- package/dist/tag/README_CN.md +922 -0
- package/dist/text-editor/PasswordEditor.svelte +17 -2
- package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
- package/dist/text-editor/PasswordEditor_README.md +551 -0
- package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
- package/dist/text-editor/README.md +466 -0
- package/dist/text-editor/README_CN.md +466 -0
- package/dist/text-editor/TextEditor.svelte +51 -19
- package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
- package/dist/time-editor/README.md +498 -24
- package/dist/time-editor/README_CN.md +498 -0
- package/dist/time-editor/TimeEditor.svelte +7 -3
- package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
- package/dist/toast/README.md +667 -0
- package/dist/toast/README_CN.md +667 -0
- package/dist/transfer/README.md +795 -0
- package/dist/transfer/Transfer.svelte +6 -4
- package/dist/transfer/Transfer.svelte.d.ts +3 -1
- package/dist/tree-view/README.md +761 -0
- package/dist/tree-view/README_CN.md +761 -0
- package/dist/tree-view/TreeView.svelte +5 -3
- package/dist/tree-view/TreeView.svelte.d.ts +3 -1
- package/dist/unit-number-editor/README.md +546 -20
- package/dist/unit-number-editor/README_CN.md +525 -0
- package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
- package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
- package/docs/form-field/cn/README_CN.md +364 -0
- package/docs/form-field/en/README.md +364 -0
- package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
- package/docs/form-panel/flex-form/en/README.md +586 -0
- package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
- package/docs/form-panel/flex-row-form/en/README.md +787 -0
- package/docs/form-panel/grid-form/en/README.md +744 -0
- package/package.json +1 -1
- 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
|