@ticatec/uniface-element 0.2.0 → 0.2.1
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/README.md +273 -1
- package/README_CN.md +341 -0
- package/dist/common/MouseClickHandler.d.ts +1 -1
- package/dist/dialog/CommonDialog.svelte +6 -3
- package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
- package/dist/dialog/Dialog.svelte +36 -10
- package/dist/dialog/Dialog.svelte.d.ts +4 -3
- package/dist/dialog/DialogBoard.svelte +11 -8
- package/dist/dialog/DialogWrapper.svelte +10 -0
- package/dist/dialog/DialogWrapper.svelte.d.ts +22 -0
- package/dist/dialog/Dialogs.js +1 -1
- package/dist/dialog/ModalResult.d.ts +5 -0
- package/dist/dialog/ModalResult.js +5 -0
- package/docs/buttons/cn/ActionBar.md +459 -0
- package/docs/buttons/cn/Button.md +228 -0
- package/docs/buttons/cn/IconButton.md +294 -0
- package/docs/buttons/cn/README.md +600 -0
- package/docs/buttons/cn/TextButton.md +163 -0
- package/docs/buttons/en/ActionBar.md +459 -0
- package/docs/buttons/en/Button.md +228 -0
- package/docs/buttons/en/IconButton.md +294 -0
- package/docs/buttons/en/README.md +600 -0
- package/docs/buttons/en/TextButton.md +163 -0
- package/docs/containers/cn/accordion.md +622 -0
- package/docs/containers/cn/box.md +445 -0
- package/docs/containers/cn/card.md +404 -0
- package/docs/containers/cn/page.md +576 -0
- package/docs/containers/cn/tabs.md +686 -0
- package/docs/containers/en/accordion.md +622 -0
- package/docs/containers/en/box.md +445 -0
- package/docs/containers/en/card.md +404 -0
- package/docs/containers/en/page.md +576 -0
- package/docs/containers/en/tabs.md +686 -0
- package/docs/data-display/cn/concise-data-table.md +731 -0
- package/docs/data-display/cn/listbox.md +786 -0
- package/docs/data-display/cn/treeview.md +863 -0
- package/docs/data-display/en/concise-data-table.md +732 -0
- package/docs/data-display/en/listbox.md +786 -0
- package/docs/data-display/en/treeview.md +863 -0
- package/docs/data-table/cn/README.md +596 -0
- package/docs/data-table/en/README.md +596 -0
- package/docs/dialog/cn/README.md +767 -0
- package/docs/dialog/en/README.md +767 -0
- package/docs/form/cn/README.md +847 -0
- package/docs/form/en/README.md +847 -0
- package/docs/form-components/cn/README.md +495 -0
- package/docs/form-components/cn/attachmentfilesfield.md +757 -0
- package/docs/form-components/cn/cascade-options-select.md +374 -0
- package/docs/form-components/cn/checkbox.md +58 -0
- package/docs/form-components/cn/date-picker.md +138 -0
- package/docs/form-components/cn/datetime-picker.md +228 -0
- package/docs/form-components/cn/group-checkbox.md +405 -0
- package/docs/form-components/cn/group-radiobox.md +525 -0
- package/docs/form-components/cn/imagefilesfield.md +651 -0
- package/docs/form-components/cn/input-options-select.md +250 -0
- package/docs/form-components/cn/lookup-editor.md +406 -0
- package/docs/form-components/cn/memoeditor.md +409 -0
- package/docs/form-components/cn/number-editor.md +261 -0
- package/docs/form-components/cn/options-multi-select.md +177 -0
- package/docs/form-components/cn/options-select.md +83 -0
- package/docs/form-components/cn/passwordeditor.md +538 -0
- package/docs/form-components/cn/prompts-text-editor.md +241 -0
- package/docs/form-components/cn/radiobutton.md +84 -0
- package/docs/form-components/cn/switch.md +178 -0
- package/docs/form-components/cn/text-editor.md +142 -0
- package/docs/form-components/cn/time-editor.md +159 -0
- package/docs/form-components/cn/unit-number-editor.md +164 -0
- package/docs/form-components/en/README.md +463 -0
- package/docs/form-components/en/attachmentfilesfield.md +757 -0
- package/docs/form-components/en/cascade-options-select.md +358 -0
- package/docs/form-components/en/checkbox.md +59 -0
- package/docs/form-components/en/date-picker.md +138 -0
- package/docs/form-components/en/datetime-picker.md +228 -0
- package/docs/form-components/en/group-checkbox.md +395 -0
- package/docs/form-components/en/group-radiobox.md +498 -0
- package/docs/form-components/en/imagefilesfield.md +651 -0
- package/docs/form-components/en/input-options-select.md +239 -0
- package/docs/form-components/en/lookup-editor.md +389 -0
- package/docs/form-components/en/memoeditor.md +409 -0
- package/docs/form-components/en/number-editor.md +249 -0
- package/docs/form-components/en/options-multi-select.md +177 -0
- package/docs/form-components/en/options-select.md +83 -0
- package/docs/form-components/en/passwordeditor.md +538 -0
- package/docs/form-components/en/prompts-text-editor.md +241 -0
- package/docs/form-components/en/radiobutton.md +84 -0
- package/docs/form-components/en/switch.md +180 -0
- package/docs/form-components/en/text-editor.md +142 -0
- package/docs/form-components/en/time-editor.md +159 -0
- package/docs/form-components/en/unit-number-editor.md +164 -0
- package/docs/form-layout/cn/criteria-field.md +652 -0
- package/docs/form-layout/cn/flex-form.md +454 -0
- package/docs/form-layout/cn/flex-row-form.md +542 -0
- package/docs/form-layout/cn/form-field.md +923 -0
- package/docs/form-layout/cn/grid-form.md +676 -0
- package/docs/form-layout/en/criteria-field.md +652 -0
- package/docs/form-layout/en/flex-form.md +454 -0
- package/docs/form-layout/en/flex-row-form.md +542 -0
- package/docs/form-layout/en/form-field.md +923 -0
- package/docs/form-layout/en/grid-form.md +676 -0
- package/docs/global/cn/README.md +534 -0
- package/docs/global/en/README.md +534 -0
- package/docs/layout/cn/classiclayout.md +460 -0
- package/docs/layout/cn/headerlayout.md +524 -0
- package/docs/layout/cn/sidebarlayout.md +263 -0
- package/docs/layout/en/classiclayout.md +951 -0
- package/docs/layout/en/headerlayout.md +524 -0
- package/docs/layout/en/sidebarlayout.md +262 -0
- package/docs/misc/cn/README.md +1217 -0
- package/docs/misc/en/README.md +1217 -0
- package/docs/navigation/cn/breadcrumb.md +291 -0
- package/docs/navigation/cn/navigator.md +322 -0
- package/docs/navigation/cn/navigatormenu.md +512 -0
- package/docs/navigation/cn/progressbar.md +199 -0
- package/docs/navigation/cn/progressstepbar.md +299 -0
- package/docs/navigation/en/breadcrumb.md +291 -0
- package/docs/navigation/en/navigator.md +322 -0
- package/docs/navigation/en/navigatormenu.md +512 -0
- package/docs/navigation/en/progressbar.md +199 -0
- package/docs/navigation/en/progressstepbar.md +299 -0
- package/docs/search-filters/cn/daterange.md +1156 -0
- package/docs/search-filters/cn/numberrange.md +688 -0
- package/docs/search-filters/cn/searchbox.md +1582 -0
- package/docs/search-filters/en/daterange.md +1156 -0
- package/docs/search-filters/en/numberrange.md +688 -0
- package/docs/search-filters/en/searchbox.md +1582 -0
- package/package.json +38 -5
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
2
|
import {fade} from "svelte/transition";
|
|
4
3
|
import type {DialogCloseConfirm} from "./DialogCloseConfirm";
|
|
5
4
|
import ActionBar, {type ButtonAction, type ButtonActions} from "../action-bar";
|
|
6
5
|
import i18n from "@ticatec/i18n";
|
|
7
|
-
import {onMount} from "svelte";
|
|
6
|
+
import {getContext, onMount} from "svelte";
|
|
7
|
+
import {ModalResult, type OnClose} from "./ModalResult";
|
|
8
8
|
|
|
9
9
|
export let title: string;
|
|
10
|
-
|
|
11
10
|
export let width: string = 'unset';
|
|
12
11
|
export let height: string = 'unset';
|
|
13
12
|
export let actions: ButtonActions | null = null;
|
|
14
13
|
export let closeConfirm: DialogCloseConfirm | null = null;
|
|
15
14
|
export let content$style: string = '';
|
|
16
|
-
|
|
15
|
+
|
|
17
16
|
export let closeAction: ButtonAction | null = null;
|
|
17
|
+
export let onClose: OnClose | null = null;
|
|
18
18
|
|
|
19
19
|
export let dialog$style: string = "";
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const closeDialog = getContext<() => void>('closeDialog');
|
|
22
|
+
|
|
23
|
+
export const close = async (result: ModalResult) => {
|
|
24
|
+
let confirm = closeConfirm && result == ModalResult.Cancel ? await closeConfirm() : true;
|
|
23
25
|
if (confirm) {
|
|
24
|
-
|
|
26
|
+
console.log('关闭窗口')
|
|
27
|
+
closeDialog();
|
|
28
|
+
onClose?.(result);
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
31
|
|
|
@@ -52,10 +56,32 @@
|
|
|
52
56
|
label: i18n.getText('uniface.btnClose', 'Close'),
|
|
53
57
|
type: 'secondary'
|
|
54
58
|
};
|
|
55
|
-
closeAction.handler = close;
|
|
59
|
+
closeAction.handler = () => close(ModalResult.Cancel);
|
|
56
60
|
})
|
|
57
61
|
|
|
58
|
-
|
|
62
|
+
const wrapActions = () => {
|
|
63
|
+
let wa: ButtonActions = [];
|
|
64
|
+
if (actions) {
|
|
65
|
+
actions.forEach(action => {
|
|
66
|
+
if (action == null) {
|
|
67
|
+
wa.push(null)
|
|
68
|
+
} else {
|
|
69
|
+
wa.push({
|
|
70
|
+
...action, handler: async (event: MouseEvent) => {
|
|
71
|
+
let result = await action.handler?.(event);
|
|
72
|
+
if (result) {
|
|
73
|
+
await close(ModalResult.Ok)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
wa.push(closeAction);
|
|
81
|
+
return wa;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$: dialogActions = actions ? wrapActions() : [closeAction];
|
|
59
85
|
|
|
60
86
|
|
|
61
87
|
</script>
|
|
@@ -67,7 +93,7 @@
|
|
|
67
93
|
<div class="title-bar" on:mousedown={handleMouseDown} on:mouseup={handleMouseUp} aria-hidden="true">
|
|
68
94
|
<div style="flex: 1 1 auto"><span>{title ?? 'New window'}</span></div>
|
|
69
95
|
<div style="flex: 0 0 auto; padding-left: 12px">
|
|
70
|
-
<i class="icon_google_clear dialog-action-button" aria-hidden="true" on:click={close}></i>
|
|
96
|
+
<i class="icon_google_clear dialog-action-button" aria-hidden="true" on:click={()=>close(ModalResult.Cancel)}></i>
|
|
71
97
|
</div>
|
|
72
98
|
</div>
|
|
73
99
|
<div class="dialog-content" style={content$style}>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DialogCloseConfirm } from "./DialogCloseConfirm";
|
|
2
2
|
import { type ButtonAction, type ButtonActions } from "../action-bar";
|
|
3
|
+
import { ModalResult, type OnClose } from "./ModalResult";
|
|
3
4
|
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
4
5
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
6
|
$$bindings?: Bindings;
|
|
@@ -25,10 +26,10 @@ declare const Dialog: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWit
|
|
|
25
26
|
actions?: ButtonActions | null;
|
|
26
27
|
closeConfirm?: DialogCloseConfirm | null;
|
|
27
28
|
content$style?: string;
|
|
28
|
-
closeHandler: () => void;
|
|
29
29
|
closeAction?: ButtonAction | null;
|
|
30
|
+
onClose?: OnClose | null;
|
|
30
31
|
dialog$style?: string;
|
|
31
|
-
close?: () => Promise<void>;
|
|
32
|
+
close?: (result: ModalResult) => Promise<void>;
|
|
32
33
|
}, {
|
|
33
34
|
default: {};
|
|
34
35
|
}>, {
|
|
@@ -36,7 +37,7 @@ declare const Dialog: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWit
|
|
|
36
37
|
}, {
|
|
37
38
|
default: {};
|
|
38
39
|
}, {
|
|
39
|
-
close: () => Promise<void>;
|
|
40
|
+
close: (result: ModalResult) => Promise<void>;
|
|
40
41
|
}, string>;
|
|
41
42
|
type Dialog = InstanceType<typeof Dialog>;
|
|
42
43
|
export default Dialog;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
import {onDestroy, onMount} from "svelte";
|
|
5
4
|
import {initialize} from "./IDialog";
|
|
6
5
|
|
|
7
6
|
import {dialogs} from "./Dialogs";
|
|
7
|
+
import DialogWrapper from "./DialogWrapper.svelte";
|
|
8
8
|
|
|
9
9
|
export const open = (component: any, params: any) => {
|
|
10
|
-
let dialog = {id:
|
|
11
|
-
params.closeHandler = () => {
|
|
12
|
-
dialogs.removeDialog(dialog.id);
|
|
13
|
-
}
|
|
10
|
+
let dialog = {component, params, id: crypto.randomUUID()};
|
|
14
11
|
dialogs.showDialog(dialog);
|
|
15
12
|
}
|
|
16
13
|
|
|
@@ -28,13 +25,19 @@
|
|
|
28
25
|
board && board.remove();
|
|
29
26
|
});
|
|
30
27
|
|
|
31
|
-
|
|
32
28
|
</script>
|
|
33
29
|
|
|
34
30
|
<div bind:this={board} class="uniface-dialog-board" style="display: {$dialogs.length > 0 ? 'block' : 'none'}">
|
|
35
31
|
<div style="width: 100%; height: 100%; position: relative">
|
|
36
|
-
{#each $dialogs as dialog}
|
|
37
|
-
|
|
32
|
+
<!--{#each $dialogs as dialog (dialog)}-->
|
|
33
|
+
<!-- <svelte:component bind:this={dialog.instance} this={dialog.component} {...dialog.params}></svelte:component>-->
|
|
34
|
+
<!--{/each}-->
|
|
35
|
+
{#each $dialogs as dialog (dialog.id)}
|
|
36
|
+
<DialogWrapper
|
|
37
|
+
component={dialog.component}
|
|
38
|
+
params={dialog.params}
|
|
39
|
+
closeDialog={() => dialogs.removeDialog(dialog.id)}
|
|
40
|
+
/>
|
|
38
41
|
{/each}
|
|
39
42
|
</div>
|
|
40
43
|
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const DialogWrapper: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
component: any;
|
|
16
|
+
params: any;
|
|
17
|
+
closeDialog: any;
|
|
18
|
+
}, {
|
|
19
|
+
[evt: string]: CustomEvent<any>;
|
|
20
|
+
}, {}, {}, string>;
|
|
21
|
+
type DialogWrapper = InstanceType<typeof DialogWrapper>;
|
|
22
|
+
export default DialogWrapper;
|
package/dist/dialog/Dialogs.js
CHANGED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
# ActionBar 组件
|
|
2
|
+
|
|
3
|
+
`ActionBar` 组件提供了一个容器,用于组织多个按钮操作,确保一致的间距和布局。
|
|
4
|
+
|
|
5
|
+
## 基础用法
|
|
6
|
+
|
|
7
|
+
```svelte
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
10
|
+
import type { ButtonActions } from '@ticatec/uniface-element';
|
|
11
|
+
|
|
12
|
+
const actions: ButtonActions = [
|
|
13
|
+
{
|
|
14
|
+
label: "保存",
|
|
15
|
+
type: "primary",
|
|
16
|
+
icon: "icon_google_save",
|
|
17
|
+
handler: async () => {
|
|
18
|
+
await saveChanges();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: "取消",
|
|
23
|
+
type: "secondary",
|
|
24
|
+
handler: async () => {
|
|
25
|
+
closeDialog();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<ActionBar buttons={actions} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 高级用法
|
|
35
|
+
|
|
36
|
+
```svelte
|
|
37
|
+
<script lang="ts">
|
|
38
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
39
|
+
import type { ButtonActions } from '@ticatec/uniface-element';
|
|
40
|
+
|
|
41
|
+
let isProcessing = false;
|
|
42
|
+
|
|
43
|
+
const formActions: ButtonActions = [
|
|
44
|
+
{
|
|
45
|
+
label: "重置",
|
|
46
|
+
type: "default",
|
|
47
|
+
icon: "icon_google_undo",
|
|
48
|
+
handler: async () => {
|
|
49
|
+
resetForm();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
null, // 分隔符
|
|
53
|
+
{
|
|
54
|
+
label: "预览",
|
|
55
|
+
type: "secondary",
|
|
56
|
+
icon: "icon_google_visibility",
|
|
57
|
+
handler: async () => {
|
|
58
|
+
showPreview();
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: isProcessing ? "处理中..." : "提交",
|
|
63
|
+
type: "primary",
|
|
64
|
+
icon: "icon_google_send",
|
|
65
|
+
disabled: isProcessing,
|
|
66
|
+
handler: async () => {
|
|
67
|
+
isProcessing = true;
|
|
68
|
+
try {
|
|
69
|
+
await submitForm();
|
|
70
|
+
} finally {
|
|
71
|
+
isProcessing = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
];
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<ActionBar
|
|
79
|
+
buttons={formActions}
|
|
80
|
+
gap={12}
|
|
81
|
+
style="padding: 16px; justify-content: flex-end;"
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 带自定义内容的 ActionBar
|
|
86
|
+
|
|
87
|
+
```svelte
|
|
88
|
+
<script lang="ts">
|
|
89
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
90
|
+
import Button from '@ticatec/uniface-element/Button';
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<!-- 当没有提供 buttons 属性时,使用插槽内容 -->
|
|
94
|
+
<ActionBar gap={16} style="padding: 20px;">
|
|
95
|
+
<Button label="自定义操作 1" type="primary" onClick={action1} />
|
|
96
|
+
<Button label="自定义操作 2" type="secondary" onClick={action2} />
|
|
97
|
+
<Button label="自定义操作 3" type="default" onClick={action3} />
|
|
98
|
+
</ActionBar>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 属性
|
|
102
|
+
|
|
103
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
104
|
+
|------|------|--------|------|
|
|
105
|
+
| `buttons` | `ButtonActions` | `[]` | 按钮配置数组 |
|
|
106
|
+
| `style` | `string` | `''` | 自定义 CSS 样式 |
|
|
107
|
+
| `gap` | `number` | `8` | 按钮间距,单位像素 |
|
|
108
|
+
|
|
109
|
+
## API 参考
|
|
110
|
+
|
|
111
|
+
### ButtonAction 接口
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface ButtonAction {
|
|
115
|
+
/** 按钮标签文本 */
|
|
116
|
+
label: string;
|
|
117
|
+
|
|
118
|
+
/** 按钮是否禁用 */
|
|
119
|
+
disabled?: boolean;
|
|
120
|
+
|
|
121
|
+
/** 图标类(如 Google Material Icons) */
|
|
122
|
+
icon?: string;
|
|
123
|
+
|
|
124
|
+
/** 按钮类型用于样式设置 */
|
|
125
|
+
type?: ButtonType;
|
|
126
|
+
|
|
127
|
+
/** 点击事件处理器 */
|
|
128
|
+
handler?: MouseClickHandler;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type ButtonActions = Array<ButtonAction | null>;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### MouseClickHandler 类型
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
type MouseClickHandler = (event: MouseEvent) => Promise<void>;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 使用示例
|
|
141
|
+
|
|
142
|
+
### 对话框操作
|
|
143
|
+
|
|
144
|
+
```svelte
|
|
145
|
+
<script lang="ts">
|
|
146
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
147
|
+
import type { ButtonActions } from '@ticatec/uniface-element';
|
|
148
|
+
|
|
149
|
+
export let onSave: () => Promise<void>;
|
|
150
|
+
export let onCancel: () => void;
|
|
151
|
+
|
|
152
|
+
const dialogActions: ButtonActions = [
|
|
153
|
+
{
|
|
154
|
+
label: "取消",
|
|
155
|
+
type: "secondary",
|
|
156
|
+
handler: async () => {
|
|
157
|
+
onCancel();
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
label: "保存更改",
|
|
162
|
+
type: "primary",
|
|
163
|
+
icon: "icon_google_save",
|
|
164
|
+
handler: async () => {
|
|
165
|
+
await onSave();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
];
|
|
169
|
+
</script>
|
|
170
|
+
|
|
171
|
+
<div class="dialog-footer">
|
|
172
|
+
<ActionBar buttons={dialogActions} style="justify-content: flex-end;" />
|
|
173
|
+
</div>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 表单操作栏
|
|
177
|
+
|
|
178
|
+
```svelte
|
|
179
|
+
<script lang="ts">
|
|
180
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
181
|
+
import type { ButtonActions } from '@ticatec/uniface-element';
|
|
182
|
+
|
|
183
|
+
let formData = {};
|
|
184
|
+
let isSubmitting = false;
|
|
185
|
+
let isDraft = false;
|
|
186
|
+
|
|
187
|
+
const formActions: ButtonActions = [
|
|
188
|
+
{
|
|
189
|
+
label: "重置",
|
|
190
|
+
type: "default",
|
|
191
|
+
handler: async () => {
|
|
192
|
+
formData = {};
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
null, // 分隔符
|
|
196
|
+
{
|
|
197
|
+
label: isDraft ? "保存中..." : "保存草稿",
|
|
198
|
+
type: "secondary",
|
|
199
|
+
icon: "icon_google_save",
|
|
200
|
+
disabled: isDraft,
|
|
201
|
+
handler: async () => {
|
|
202
|
+
isDraft = true;
|
|
203
|
+
try {
|
|
204
|
+
await saveDraft(formData);
|
|
205
|
+
} finally {
|
|
206
|
+
isDraft = false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
label: isSubmitting ? "提交中..." : "提交",
|
|
212
|
+
type: "primary",
|
|
213
|
+
icon: "icon_google_send",
|
|
214
|
+
disabled: isSubmitting,
|
|
215
|
+
handler: async () => {
|
|
216
|
+
isSubmitting = true;
|
|
217
|
+
try {
|
|
218
|
+
await submitForm(formData);
|
|
219
|
+
} finally {
|
|
220
|
+
isSubmitting = false;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
];
|
|
225
|
+
</script>
|
|
226
|
+
|
|
227
|
+
<form>
|
|
228
|
+
<!-- 表单字段在此 -->
|
|
229
|
+
|
|
230
|
+
<div class="form-footer">
|
|
231
|
+
<ActionBar
|
|
232
|
+
buttons={formActions}
|
|
233
|
+
gap={12}
|
|
234
|
+
style="justify-content: flex-end; margin-top: 24px;"
|
|
235
|
+
/>
|
|
236
|
+
</div>
|
|
237
|
+
</form>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 工具栏实现
|
|
241
|
+
|
|
242
|
+
```svelte
|
|
243
|
+
<script lang="ts">
|
|
244
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
245
|
+
import type { ButtonActions } from '@ticatec/uniface-element';
|
|
246
|
+
|
|
247
|
+
let selectedItems = [];
|
|
248
|
+
|
|
249
|
+
const toolbarActions: ButtonActions = [
|
|
250
|
+
{
|
|
251
|
+
label: "全选",
|
|
252
|
+
icon: "icon_google_check_box",
|
|
253
|
+
type: "default",
|
|
254
|
+
handler: async () => {
|
|
255
|
+
selectAll();
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
null, // 分隔符
|
|
259
|
+
{
|
|
260
|
+
label: "导出",
|
|
261
|
+
icon: "icon_google_download",
|
|
262
|
+
type: "secondary",
|
|
263
|
+
disabled: selectedItems.length === 0,
|
|
264
|
+
handler: async () => {
|
|
265
|
+
await exportItems(selectedItems);
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
label: "删除选中",
|
|
270
|
+
icon: "icon_google_delete",
|
|
271
|
+
type: "third",
|
|
272
|
+
disabled: selectedItems.length === 0,
|
|
273
|
+
handler: async () => {
|
|
274
|
+
if (confirm(`删除 ${selectedItems.length} 个项目?`)) {
|
|
275
|
+
await deleteItems(selectedItems);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
];
|
|
280
|
+
</script>
|
|
281
|
+
|
|
282
|
+
<div class="toolbar">
|
|
283
|
+
<div class="toolbar-info">
|
|
284
|
+
已选择 {selectedItems.length} 个项目
|
|
285
|
+
</div>
|
|
286
|
+
<ActionBar buttons={toolbarActions} />
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
<style>
|
|
290
|
+
.toolbar {
|
|
291
|
+
display: flex;
|
|
292
|
+
justify-content: space-between;
|
|
293
|
+
align-items: center;
|
|
294
|
+
padding: 12px;
|
|
295
|
+
border-bottom: 1px solid #eee;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.toolbar-info {
|
|
299
|
+
color: #666;
|
|
300
|
+
font-size: 14px;
|
|
301
|
+
}
|
|
302
|
+
</style>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### 卡片操作栏
|
|
306
|
+
|
|
307
|
+
```svelte
|
|
308
|
+
<script lang="ts">
|
|
309
|
+
import ActionBar from '@ticatec/uniface-element/ActionBar';
|
|
310
|
+
import type { ButtonActions } from '@ticatec/uniface-element';
|
|
311
|
+
|
|
312
|
+
export let item: any;
|
|
313
|
+
export let onEdit: (item: any) => Promise<void>;
|
|
314
|
+
export let onShare: (item: any) => Promise<void>;
|
|
315
|
+
export let onDelete: (item: any) => Promise<void>;
|
|
316
|
+
|
|
317
|
+
const cardActions: ButtonActions = [
|
|
318
|
+
{
|
|
319
|
+
label: "编辑",
|
|
320
|
+
icon: "icon_google_edit",
|
|
321
|
+
type: "primary",
|
|
322
|
+
handler: async () => {
|
|
323
|
+
await onEdit(item);
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
label: "分享",
|
|
328
|
+
icon: "icon_google_share",
|
|
329
|
+
type: "secondary",
|
|
330
|
+
handler: async () => {
|
|
331
|
+
await onShare(item);
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
label: "删除",
|
|
336
|
+
icon: "icon_google_delete",
|
|
337
|
+
type: "third",
|
|
338
|
+
handler: async () => {
|
|
339
|
+
if (confirm("确定要删除此项目吗?")) {
|
|
340
|
+
await onDelete(item);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
];
|
|
345
|
+
</script>
|
|
346
|
+
|
|
347
|
+
<div class="card">
|
|
348
|
+
<div class="card-content">
|
|
349
|
+
<!-- 卡片内容 -->
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<div class="card-actions">
|
|
353
|
+
<ActionBar buttons={cardActions} gap={8} />
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
|
|
357
|
+
<style>
|
|
358
|
+
.card {
|
|
359
|
+
border: 1px solid #e0e0e0;
|
|
360
|
+
border-radius: 8px;
|
|
361
|
+
overflow: hidden;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.card-content {
|
|
365
|
+
padding: 16px;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.card-actions {
|
|
369
|
+
padding: 12px 16px;
|
|
370
|
+
background: #f8f9fa;
|
|
371
|
+
border-top: 1px solid #e0e0e0;
|
|
372
|
+
}
|
|
373
|
+
</style>
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## 最佳实践
|
|
377
|
+
|
|
378
|
+
### 使用分隔符组织操作
|
|
379
|
+
|
|
380
|
+
使用 `null` 值作为分隔符来组织相关操作:
|
|
381
|
+
|
|
382
|
+
```svelte
|
|
383
|
+
<script lang="ts">
|
|
384
|
+
const editorActions: ButtonActions = [
|
|
385
|
+
// 文件操作组
|
|
386
|
+
{ label: "新建", icon: "icon_google_add", handler: newFile },
|
|
387
|
+
{ label: "打开", icon: "icon_google_folder_open", handler: openFile },
|
|
388
|
+
{ label: "保存", icon: "icon_google_save", handler: saveFile },
|
|
389
|
+
|
|
390
|
+
null, // 分隔符
|
|
391
|
+
|
|
392
|
+
// 编辑操作组
|
|
393
|
+
{ label: "撤销", icon: "icon_google_undo", handler: undo },
|
|
394
|
+
{ label: "重做", icon: "icon_google_redo", handler: redo },
|
|
395
|
+
|
|
396
|
+
null, // 分隔符
|
|
397
|
+
|
|
398
|
+
// 主要操作
|
|
399
|
+
{ label: "发布", type: "primary", icon: "icon_google_publish", handler: publish }
|
|
400
|
+
];
|
|
401
|
+
</script>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### 使用合适的间距
|
|
405
|
+
|
|
406
|
+
根据界面密度调整按钮间距:
|
|
407
|
+
|
|
408
|
+
```svelte
|
|
409
|
+
<!-- 紧凑界面 -->
|
|
410
|
+
<ActionBar buttons={actions} gap={4} />
|
|
411
|
+
|
|
412
|
+
<!-- 标准界面 -->
|
|
413
|
+
<ActionBar buttons={actions} gap={8} />
|
|
414
|
+
|
|
415
|
+
<!-- 宽松界面 -->
|
|
416
|
+
<ActionBar buttons={actions} gap={16} />
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### 响应式设计
|
|
420
|
+
|
|
421
|
+
考虑在小屏幕上隐藏或简化操作:
|
|
422
|
+
|
|
423
|
+
```svelte
|
|
424
|
+
<script lang="ts">
|
|
425
|
+
import { onMount } from 'svelte';
|
|
426
|
+
|
|
427
|
+
let isMobile = false;
|
|
428
|
+
|
|
429
|
+
onMount(() => {
|
|
430
|
+
const checkMobile = () => {
|
|
431
|
+
isMobile = window.innerWidth < 768;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
checkMobile();
|
|
435
|
+
window.addEventListener('resize', checkMobile);
|
|
436
|
+
|
|
437
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
$: responsiveActions = isMobile
|
|
441
|
+
? [
|
|
442
|
+
{ label: "保存", type: "primary", handler: save },
|
|
443
|
+
{ label: "取消", type: "secondary", handler: cancel }
|
|
444
|
+
]
|
|
445
|
+
: [
|
|
446
|
+
{ label: "重置", type: "default", handler: reset },
|
|
447
|
+
null,
|
|
448
|
+
{ label: "预览", type: "secondary", handler: preview },
|
|
449
|
+
{ label: "保存", type: "primary", handler: save },
|
|
450
|
+
{ label: "取消", type: "secondary", handler: cancel }
|
|
451
|
+
];
|
|
452
|
+
</script>
|
|
453
|
+
|
|
454
|
+
<ActionBar buttons={responsiveActions} />
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## 点击节流
|
|
458
|
+
|
|
459
|
+
ActionBar 中的所有按钮都实现了自动点击节流,具有 500ms 冷却时间,以防止意外的双击并确保正确的异步操作处理。
|