@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
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# TextButton 组件
|
|
2
|
+
|
|
3
|
+
`TextButton` 组件针对纯文本按钮进行了优化,采用最小化样式。
|
|
4
|
+
|
|
5
|
+
## 基础用法
|
|
6
|
+
|
|
7
|
+
```svelte
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import TextButton from '@ticatec/uniface-element/TextButton';
|
|
10
|
+
|
|
11
|
+
const handleCancel = async (event: MouseEvent) => {
|
|
12
|
+
// 处理取消操作
|
|
13
|
+
};
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<TextButton
|
|
17
|
+
label="取消"
|
|
18
|
+
type="secondary"
|
|
19
|
+
onClick={handleCancel}
|
|
20
|
+
/>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 使用示例
|
|
24
|
+
|
|
25
|
+
```svelte
|
|
26
|
+
<script lang="ts">
|
|
27
|
+
import TextButton from '@ticatec/uniface-element/TextButton';
|
|
28
|
+
|
|
29
|
+
const actions = {
|
|
30
|
+
save: async () => { /* 保存逻辑 */ },
|
|
31
|
+
delete: async () => { /* 删除逻辑 */ },
|
|
32
|
+
cancel: async () => { /* 取消逻辑 */ }
|
|
33
|
+
};
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<!-- 不同按钮类型 -->
|
|
37
|
+
<TextButton label="主要操作" type="primary" onClick={actions.save} />
|
|
38
|
+
<TextButton label="次要操作" type="secondary" onClick={actions.cancel} />
|
|
39
|
+
<TextButton label="危险操作" type="third" onClick={actions.delete} />
|
|
40
|
+
|
|
41
|
+
<!-- 不同大小 -->
|
|
42
|
+
<TextButton label="大号" size="big" onClick={actions.save} />
|
|
43
|
+
<TextButton label="普通" size="medium" onClick={actions.save} />
|
|
44
|
+
<TextButton label="小号" size="mini" onClick={actions.save} />
|
|
45
|
+
|
|
46
|
+
<!-- 带自定义内容 -->
|
|
47
|
+
<TextButton type="primary" onClick={actions.save}>
|
|
48
|
+
<i class="icon_google_check"></i> 确认更改
|
|
49
|
+
</TextButton>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 属性
|
|
53
|
+
|
|
54
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
55
|
+
|------|------|--------|------|
|
|
56
|
+
| `label` | `string` | `''` | 按钮文本标签 |
|
|
57
|
+
| `type` | `ButtonType` | `'default'` | 视觉样式变体 |
|
|
58
|
+
| `size` | `'big' \| 'medium' \| 'mini'` | `'medium'` | 按钮大小 |
|
|
59
|
+
| `disabled` | `boolean` | `false` | 禁用按钮交互 |
|
|
60
|
+
| `style` | `string` | `''` | 自定义 CSS 样式 |
|
|
61
|
+
| `onClick` | `MouseClickHandler` | - | 异步点击事件处理器 |
|
|
62
|
+
|
|
63
|
+
## 样式变体
|
|
64
|
+
|
|
65
|
+
### ButtonType 选项
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
type ButtonType = 'default' | 'primary' | 'secondary' | 'third' | 'forth';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 视觉外观
|
|
72
|
+
|
|
73
|
+
- **default**: 标准中性按钮外观
|
|
74
|
+
- **primary**: 强调主要操作的按钮(通常为蓝色)
|
|
75
|
+
- **secondary**: 次要操作按钮(通常为灰色)
|
|
76
|
+
- **third**: 替代样式(通常用于警告/注意)
|
|
77
|
+
- **forth**: 附加样式变体
|
|
78
|
+
|
|
79
|
+
### 大小变体
|
|
80
|
+
|
|
81
|
+
- **big**: 大按钮尺寸,用于突出操作
|
|
82
|
+
- **medium**: 标准按钮尺寸,适用于大多数使用场景
|
|
83
|
+
- **mini**: 小按钮尺寸,用于紧凑界面
|
|
84
|
+
|
|
85
|
+
## 使用场景
|
|
86
|
+
|
|
87
|
+
TextButton 组件特别适合以下场景:
|
|
88
|
+
|
|
89
|
+
- 对话框中的取消/确认操作
|
|
90
|
+
- 导航链接样式的按钮
|
|
91
|
+
- 内联操作按钮
|
|
92
|
+
- 表单中的辅助操作
|
|
93
|
+
|
|
94
|
+
## 最佳实践
|
|
95
|
+
|
|
96
|
+
### 在对话框中使用
|
|
97
|
+
|
|
98
|
+
```svelte
|
|
99
|
+
<script lang="ts">
|
|
100
|
+
import TextButton from '@ticatec/uniface-element/TextButton';
|
|
101
|
+
|
|
102
|
+
const handleCancel = async () => {
|
|
103
|
+
closeDialog();
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const handleConfirm = async () => {
|
|
107
|
+
await saveChanges();
|
|
108
|
+
closeDialog();
|
|
109
|
+
};
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
<div class="dialog-actions">
|
|
113
|
+
<TextButton label="取消" type="secondary" onClick={handleCancel} />
|
|
114
|
+
<TextButton label="确认" type="primary" onClick={handleConfirm} />
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<style>
|
|
118
|
+
.dialog-actions {
|
|
119
|
+
display: flex;
|
|
120
|
+
gap: 12px;
|
|
121
|
+
justify-content: flex-end;
|
|
122
|
+
margin-top: 16px;
|
|
123
|
+
}
|
|
124
|
+
</style>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 作为内联操作
|
|
128
|
+
|
|
129
|
+
```svelte
|
|
130
|
+
<div class="content-item">
|
|
131
|
+
<span class="item-text">项目名称</span>
|
|
132
|
+
<div class="item-actions">
|
|
133
|
+
<TextButton label="编辑" type="primary" size="mini" onClick={editItem} />
|
|
134
|
+
<TextButton label="删除" type="third" size="mini" onClick={deleteItem} />
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<style>
|
|
139
|
+
.content-item {
|
|
140
|
+
display: flex;
|
|
141
|
+
justify-content: space-between;
|
|
142
|
+
align-items: center;
|
|
143
|
+
padding: 8px 0;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.item-actions {
|
|
147
|
+
display: flex;
|
|
148
|
+
gap: 8px;
|
|
149
|
+
}
|
|
150
|
+
</style>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## API 参考
|
|
154
|
+
|
|
155
|
+
### MouseClickHandler 类型
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
type MouseClickHandler = (event: MouseEvent) => Promise<void>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 点击节流
|
|
162
|
+
|
|
163
|
+
TextButton 组件实现了自动点击节流,具有 500ms 冷却时间,以防止意外的双击并确保正确的异步操作处理。
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
# ActionBar Component
|
|
2
|
+
|
|
3
|
+
The `ActionBar` component provides a container for organizing multiple button actions with consistent spacing and layout.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
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: "Save",
|
|
15
|
+
type: "primary",
|
|
16
|
+
icon: "icon_google_save",
|
|
17
|
+
handler: async () => {
|
|
18
|
+
await saveChanges();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: "Cancel",
|
|
23
|
+
type: "secondary",
|
|
24
|
+
handler: async () => {
|
|
25
|
+
closeDialog();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<ActionBar buttons={actions} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Advanced Usage
|
|
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: "Reset",
|
|
46
|
+
type: "default",
|
|
47
|
+
icon: "icon_google_undo",
|
|
48
|
+
handler: async () => {
|
|
49
|
+
resetForm();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
null, // Separator
|
|
53
|
+
{
|
|
54
|
+
label: "Preview",
|
|
55
|
+
type: "secondary",
|
|
56
|
+
icon: "icon_google_visibility",
|
|
57
|
+
handler: async () => {
|
|
58
|
+
showPreview();
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: isProcessing ? "Processing..." : "Submit",
|
|
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 with Custom Content
|
|
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
|
+
<!-- When no buttons prop is provided, slot content is used -->
|
|
94
|
+
<ActionBar gap={16} style="padding: 20px;">
|
|
95
|
+
<Button label="Custom Action 1" type="primary" onClick={action1} />
|
|
96
|
+
<Button label="Custom Action 2" type="secondary" onClick={action2} />
|
|
97
|
+
<Button label="Custom Action 3" type="default" onClick={action3} />
|
|
98
|
+
</ActionBar>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Properties
|
|
102
|
+
|
|
103
|
+
| Property | Type | Default | Description |
|
|
104
|
+
|----------|------|---------|-------------|
|
|
105
|
+
| `buttons` | `ButtonActions` | `[]` | Array of button configurations |
|
|
106
|
+
| `style` | `string` | `''` | Custom CSS styles |
|
|
107
|
+
| `gap` | `number` | `8` | Button spacing in pixels |
|
|
108
|
+
|
|
109
|
+
## API Reference
|
|
110
|
+
|
|
111
|
+
### ButtonAction Interface
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface ButtonAction {
|
|
115
|
+
/** Button label text */
|
|
116
|
+
label: string;
|
|
117
|
+
|
|
118
|
+
/** Whether button is disabled */
|
|
119
|
+
disabled?: boolean;
|
|
120
|
+
|
|
121
|
+
/** Icon class (e.g., Google Material Icons) */
|
|
122
|
+
icon?: string;
|
|
123
|
+
|
|
124
|
+
/** Button type for styling */
|
|
125
|
+
type?: ButtonType;
|
|
126
|
+
|
|
127
|
+
/** Click event handler */
|
|
128
|
+
handler?: MouseClickHandler;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type ButtonActions = Array<ButtonAction | null>;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### MouseClickHandler Type
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
type MouseClickHandler = (event: MouseEvent) => Promise<void>;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Usage Examples
|
|
141
|
+
|
|
142
|
+
### Dialog Actions
|
|
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: "Cancel",
|
|
155
|
+
type: "secondary",
|
|
156
|
+
handler: async () => {
|
|
157
|
+
onCancel();
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
label: "Save Changes",
|
|
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
|
+
### Form Action Bar
|
|
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: "Reset",
|
|
190
|
+
type: "default",
|
|
191
|
+
handler: async () => {
|
|
192
|
+
formData = {};
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
null, // Separator
|
|
196
|
+
{
|
|
197
|
+
label: isDraft ? "Saving..." : "Save Draft",
|
|
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 ? "Submitting..." : "Submit",
|
|
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
|
+
<!-- Form fields here -->
|
|
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
|
+
### Toolbar Implementation
|
|
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: "Select All",
|
|
252
|
+
icon: "icon_google_check_box",
|
|
253
|
+
type: "default",
|
|
254
|
+
handler: async () => {
|
|
255
|
+
selectAll();
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
null, // Separator
|
|
259
|
+
{
|
|
260
|
+
label: "Export",
|
|
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: "Delete Selected",
|
|
270
|
+
icon: "icon_google_delete",
|
|
271
|
+
type: "third",
|
|
272
|
+
disabled: selectedItems.length === 0,
|
|
273
|
+
handler: async () => {
|
|
274
|
+
if (confirm(`Delete ${selectedItems.length} items?`)) {
|
|
275
|
+
await deleteItems(selectedItems);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
];
|
|
280
|
+
</script>
|
|
281
|
+
|
|
282
|
+
<div class="toolbar">
|
|
283
|
+
<div class="toolbar-info">
|
|
284
|
+
{selectedItems.length} items selected
|
|
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
|
+
### Card Action Bar
|
|
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: "Edit",
|
|
320
|
+
icon: "icon_google_edit",
|
|
321
|
+
type: "primary",
|
|
322
|
+
handler: async () => {
|
|
323
|
+
await onEdit(item);
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
label: "Share",
|
|
328
|
+
icon: "icon_google_share",
|
|
329
|
+
type: "secondary",
|
|
330
|
+
handler: async () => {
|
|
331
|
+
await onShare(item);
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
label: "Delete",
|
|
336
|
+
icon: "icon_google_delete",
|
|
337
|
+
type: "third",
|
|
338
|
+
handler: async () => {
|
|
339
|
+
if (confirm("Are you sure you want to delete this item?")) {
|
|
340
|
+
await onDelete(item);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
];
|
|
345
|
+
</script>
|
|
346
|
+
|
|
347
|
+
<div class="card">
|
|
348
|
+
<div class="card-content">
|
|
349
|
+
<!-- Card content -->
|
|
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
|
+
## Best Practices
|
|
377
|
+
|
|
378
|
+
### Use Separators to Group Actions
|
|
379
|
+
|
|
380
|
+
Use `null` values as separators to organize related actions:
|
|
381
|
+
|
|
382
|
+
```svelte
|
|
383
|
+
<script lang="ts">
|
|
384
|
+
const editorActions: ButtonActions = [
|
|
385
|
+
// File operations group
|
|
386
|
+
{ label: "New", icon: "icon_google_add", handler: newFile },
|
|
387
|
+
{ label: "Open", icon: "icon_google_folder_open", handler: openFile },
|
|
388
|
+
{ label: "Save", icon: "icon_google_save", handler: saveFile },
|
|
389
|
+
|
|
390
|
+
null, // Separator
|
|
391
|
+
|
|
392
|
+
// Edit operations group
|
|
393
|
+
{ label: "Undo", icon: "icon_google_undo", handler: undo },
|
|
394
|
+
{ label: "Redo", icon: "icon_google_redo", handler: redo },
|
|
395
|
+
|
|
396
|
+
null, // Separator
|
|
397
|
+
|
|
398
|
+
// Primary action
|
|
399
|
+
{ label: "Publish", type: "primary", icon: "icon_google_publish", handler: publish }
|
|
400
|
+
];
|
|
401
|
+
</script>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Use Appropriate Spacing
|
|
405
|
+
|
|
406
|
+
Adjust button spacing based on interface density:
|
|
407
|
+
|
|
408
|
+
```svelte
|
|
409
|
+
<!-- Compact interface -->
|
|
410
|
+
<ActionBar buttons={actions} gap={4} />
|
|
411
|
+
|
|
412
|
+
<!-- Standard interface -->
|
|
413
|
+
<ActionBar buttons={actions} gap={8} />
|
|
414
|
+
|
|
415
|
+
<!-- Spacious interface -->
|
|
416
|
+
<ActionBar buttons={actions} gap={16} />
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Responsive Design
|
|
420
|
+
|
|
421
|
+
Consider hiding or simplifying actions on small screens:
|
|
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: "Save", type: "primary", handler: save },
|
|
443
|
+
{ label: "Cancel", type: "secondary", handler: cancel }
|
|
444
|
+
]
|
|
445
|
+
: [
|
|
446
|
+
{ label: "Reset", type: "default", handler: reset },
|
|
447
|
+
null,
|
|
448
|
+
{ label: "Preview", type: "secondary", handler: preview },
|
|
449
|
+
{ label: "Save", type: "primary", handler: save },
|
|
450
|
+
{ label: "Cancel", type: "secondary", handler: cancel }
|
|
451
|
+
];
|
|
452
|
+
</script>
|
|
453
|
+
|
|
454
|
+
<ActionBar buttons={responsiveActions} />
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Click Throttling
|
|
458
|
+
|
|
459
|
+
All buttons in ActionBar implement automatic click throttling with a 500ms cooldown to prevent accidental double-clicks and ensure proper async operation handling.
|