@zerodep-dev/vue-tsx-pro-mobile 0.0.0-stage → 0.4.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/LICENSE +21 -0
- package/README.md +29 -2
- package/dist/area/data.d.ts +10 -0
- package/dist/area/data.js +3899 -0
- package/dist/area/data.js.map +1 -0
- package/dist/area/index.d.ts +22 -0
- package/dist/area/index.js +41 -0
- package/dist/area/index.js.map +1 -0
- package/dist/base/Button.d.ts +170 -0
- package/dist/base/Button.js +537 -0
- package/dist/base/Button.js.map +1 -0
- package/dist/base/Icon.d.ts +38 -0
- package/dist/base/Icon.js +65 -0
- package/dist/base/Icon.js.map +1 -0
- package/dist/capability/PrivacyPrompt.d.ts +1 -0
- package/dist/capability/PrivacyPrompt.js +73 -0
- package/dist/capability/PrivacyPrompt.js.map +1 -0
- package/dist/capability/types.d.ts +92 -0
- package/dist/capability/usePermission.d.ts +23 -0
- package/dist/capability/usePermission.js +52 -0
- package/dist/capability/usePermission.js.map +1 -0
- package/dist/capability/useStorage.d.ts +8 -0
- package/dist/capability/useStorage.js +19 -0
- package/dist/capability/useStorage.js.map +1 -0
- package/dist/capability/web.d.ts +18 -0
- package/dist/capability/web.js +109 -0
- package/dist/capability/web.js.map +1 -0
- package/dist/capacitor/index.d.ts +9 -0
- package/dist/capacitor/index.js +143 -0
- package/dist/capacitor/index.js.map +1 -0
- package/dist/config/ConfigProvider.d.ts +37 -0
- package/dist/config/ConfigProvider.js +64 -0
- package/dist/config/ConfigProvider.js.map +1 -0
- package/dist/config/context.d.ts +16 -0
- package/dist/config/context.js +20 -0
- package/dist/config/context.js.map +1 -0
- package/dist/config/lang.d.ts +85 -0
- package/dist/config/lang.js +138 -0
- package/dist/config/lang.js.map +1 -0
- package/dist/display/Badge.d.ts +39 -0
- package/dist/display/Badge.js +108 -0
- package/dist/display/Badge.js.map +1 -0
- package/dist/display/Cell.d.ts +92 -0
- package/dist/display/Cell.js +204 -0
- package/dist/display/Cell.js.map +1 -0
- package/dist/display/Collapse.d.ts +47 -0
- package/dist/display/Collapse.js +173 -0
- package/dist/display/Collapse.js.map +1 -0
- package/dist/display/Empty.d.ts +42 -0
- package/dist/display/Empty.js +79 -0
- package/dist/display/Empty.js.map +1 -0
- package/dist/display/Grid.d.ts +49 -0
- package/dist/display/Grid.js +136 -0
- package/dist/display/Grid.js.map +1 -0
- package/dist/display/Image.d.ts +70 -0
- package/dist/display/Image.js +138 -0
- package/dist/display/Image.js.map +1 -0
- package/dist/display/IndexBar.d.ts +34 -0
- package/dist/display/IndexBar.js +158 -0
- package/dist/display/IndexBar.js.map +1 -0
- package/dist/display/List.d.ts +34 -0
- package/dist/display/List.js +105 -0
- package/dist/display/List.js.map +1 -0
- package/dist/display/NoticeBar.d.ts +57 -0
- package/dist/display/NoticeBar.js +172 -0
- package/dist/display/NoticeBar.js.map +1 -0
- package/dist/display/Steps.d.ts +59 -0
- package/dist/display/Steps.js +158 -0
- package/dist/display/Steps.js.map +1 -0
- package/dist/display/SwipeCell.d.ts +37 -0
- package/dist/display/SwipeCell.js +147 -0
- package/dist/display/SwipeCell.js.map +1 -0
- package/dist/display/Swiper.d.ts +47 -0
- package/dist/display/Swiper.js +173 -0
- package/dist/display/Swiper.js.map +1 -0
- package/dist/display/Tag.d.ts +99 -0
- package/dist/display/Tag.js +320 -0
- package/dist/display/Tag.js.map +1 -0
- package/dist/feedback/Dialog.d.ts +79 -0
- package/dist/feedback/Dialog.js +186 -0
- package/dist/feedback/Dialog.js.map +1 -0
- package/dist/feedback/FeedbackOutlet.d.ts +2 -0
- package/dist/feedback/FeedbackOutlet.js +31 -0
- package/dist/feedback/FeedbackOutlet.js.map +1 -0
- package/dist/feedback/Loading.d.ts +26 -0
- package/dist/feedback/Loading.js +68 -0
- package/dist/feedback/Loading.js.map +1 -0
- package/dist/feedback/Notify.d.ts +48 -0
- package/dist/feedback/Notify.js +116 -0
- package/dist/feedback/Notify.js.map +1 -0
- package/dist/feedback/PullRefresh.d.ts +58 -0
- package/dist/feedback/PullRefresh.js +178 -0
- package/dist/feedback/PullRefresh.js.map +1 -0
- package/dist/feedback/Skeleton.d.ts +56 -0
- package/dist/feedback/Skeleton.js +99 -0
- package/dist/feedback/Skeleton.js.map +1 -0
- package/dist/feedback/Toast.d.ts +89 -0
- package/dist/feedback/Toast.js +186 -0
- package/dist/feedback/Toast.js.map +1 -0
- package/dist/form/Checkbox.d.ts +52 -0
- package/dist/form/Checkbox.js +107 -0
- package/dist/form/Checkbox.js.map +1 -0
- package/dist/form/Field.d.ts +91 -0
- package/dist/form/Field.js +296 -0
- package/dist/form/Field.js.map +1 -0
- package/dist/form/Form.d.ts +50 -0
- package/dist/form/Form.js +96 -0
- package/dist/form/Form.js.map +1 -0
- package/dist/form/FormItem.d.ts +57 -0
- package/dist/form/FormItem.js +142 -0
- package/dist/form/FormItem.js.map +1 -0
- package/dist/form/Radio.d.ts +41 -0
- package/dist/form/Radio.js +85 -0
- package/dist/form/Radio.js.map +1 -0
- package/dist/form/Rate.d.ts +45 -0
- package/dist/form/Rate.js +162 -0
- package/dist/form/Rate.js.map +1 -0
- package/dist/form/Search.d.ts +50 -0
- package/dist/form/Search.js +152 -0
- package/dist/form/Search.js.map +1 -0
- package/dist/form/Slider.d.ts +43 -0
- package/dist/form/Slider.js +213 -0
- package/dist/form/Slider.js.map +1 -0
- package/dist/form/Stepper.d.ts +61 -0
- package/dist/form/Stepper.js +222 -0
- package/dist/form/Stepper.js.map +1 -0
- package/dist/form/Switch.d.ts +33 -0
- package/dist/form/Switch.js +116 -0
- package/dist/form/Switch.js.map +1 -0
- package/dist/form/Uploader.d.ts +67 -0
- package/dist/form/Uploader.js +207 -0
- package/dist/form/Uploader.js.map +1 -0
- package/dist/form/choice.d.ts +42 -0
- package/dist/form/choice.js +109 -0
- package/dist/form/choice.js.map +1 -0
- package/dist/form/context.d.ts +83 -0
- package/dist/form/context.js +89 -0
- package/dist/form/context.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +59 -0
- package/dist/layout/Divider.d.ts +34 -0
- package/dist/layout/Divider.js +55 -0
- package/dist/layout/Divider.js.map +1 -0
- package/dist/layout/Space.d.ts +66 -0
- package/dist/layout/Space.js +65 -0
- package/dist/layout/Space.js.map +1 -0
- package/dist/navigation/BackTop.d.ts +29 -0
- package/dist/navigation/BackTop.js +89 -0
- package/dist/navigation/BackTop.js.map +1 -0
- package/dist/navigation/NavBar.d.ts +46 -0
- package/dist/navigation/NavBar.js +141 -0
- package/dist/navigation/NavBar.js.map +1 -0
- package/dist/navigation/Sticky.d.ts +19 -0
- package/dist/navigation/Sticky.js +28 -0
- package/dist/navigation/Sticky.js.map +1 -0
- package/dist/navigation/TabBar.d.ts +54 -0
- package/dist/navigation/TabBar.js +138 -0
- package/dist/navigation/TabBar.js.map +1 -0
- package/dist/navigation/Tabs.d.ts +45 -0
- package/dist/navigation/Tabs.js +206 -0
- package/dist/navigation/Tabs.js.map +1 -0
- package/dist/overlay/ActionSheet.d.ts +80 -0
- package/dist/overlay/ActionSheet.js +164 -0
- package/dist/overlay/ActionSheet.js.map +1 -0
- package/dist/overlay/Overlay.d.ts +35 -0
- package/dist/overlay/Overlay.js +85 -0
- package/dist/overlay/Overlay.js.map +1 -0
- package/dist/overlay/Popup.d.ts +76 -0
- package/dist/overlay/Popup.js +191 -0
- package/dist/overlay/Popup.js.map +1 -0
- package/dist/picker/Calendar.d.ts +69 -0
- package/dist/picker/Calendar.js +213 -0
- package/dist/picker/Calendar.js.map +1 -0
- package/dist/picker/Cascader.d.ts +50 -0
- package/dist/picker/Cascader.js +199 -0
- package/dist/picker/Cascader.js.map +1 -0
- package/dist/picker/DatePicker.d.ts +52 -0
- package/dist/picker/DatePicker.js +135 -0
- package/dist/picker/DatePicker.js.map +1 -0
- package/dist/picker/DropdownMenu.d.ts +39 -0
- package/dist/picker/DropdownMenu.js +242 -0
- package/dist/picker/DropdownMenu.js.map +1 -0
- package/dist/picker/Picker.d.ts +67 -0
- package/dist/picker/Picker.js +185 -0
- package/dist/picker/Picker.js.map +1 -0
- package/dist/picker/PickerColumn.d.ts +36 -0
- package/dist/picker/PickerColumn.js +175 -0
- package/dist/picker/PickerColumn.js.map +1 -0
- package/dist/theme/dark.d.ts +121 -0
- package/dist/theme/dark.js +77 -0
- package/dist/theme/dark.js.map +1 -0
- package/dist/theme/divider.d.ts +6 -0
- package/dist/theme/divider.js +18 -0
- package/dist/theme/divider.js.map +1 -0
- package/dist/theme/token-names.d.ts +1389 -0
- package/dist/theme/tokens.d.ts +549 -0
- package/dist/theme/tokens.js +312 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/utils/host.d.ts +97 -0
- package/dist/utils/host.js +98 -0
- package/dist/utils/host.js.map +1 -0
- package/dist/utils/presence.d.ts +11 -0
- package/dist/utils/presence.js +34 -0
- package/dist/utils/presence.js.map +1 -0
- package/dist/utils/props.d.ts +38 -0
- package/dist/utils/props.js +115 -0
- package/dist/utils/props.js.map +1 -0
- package/dist/utils/scales.d.ts +48 -0
- package/package.json +106 -3
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { useConfig } from "../config/context.js";
|
|
2
|
+
import { hasContent, mergeAttrs, mergePartProps, mergeProps } from "../utils/props.js";
|
|
3
|
+
import { Button } from "../base/Button.js";
|
|
4
|
+
import { Popup } from "../overlay/Popup.js";
|
|
5
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
6
|
+
import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
7
|
+
import { createVNode, ref, shallowReactive } from "vue";
|
|
8
|
+
//#region src/feedback/Dialog.tsx
|
|
9
|
+
/** 关闭的原因 */
|
|
10
|
+
/** 对话框的选项(组件的 props 与 showDialog 的参数共用) */
|
|
11
|
+
/** 未声明的属性落到对话框的面板上 */
|
|
12
|
+
/** Dialog 的样式:panel、header、title、message、footer、action */
|
|
13
|
+
var dialogStyles = css.create({
|
|
14
|
+
panel: {
|
|
15
|
+
width: "20em",
|
|
16
|
+
maxWidth: "85vw",
|
|
17
|
+
overflow: "hidden"
|
|
18
|
+
},
|
|
19
|
+
header: {
|
|
20
|
+
paddingBlockStart: "1.6em",
|
|
21
|
+
paddingInline: "1.5em",
|
|
22
|
+
textAlign: "center"
|
|
23
|
+
},
|
|
24
|
+
title: {
|
|
25
|
+
fontSize: "_lg",
|
|
26
|
+
fontWeight: "_semibold",
|
|
27
|
+
lineHeight: "_tight",
|
|
28
|
+
color: "_text"
|
|
29
|
+
},
|
|
30
|
+
message: {
|
|
31
|
+
paddingInline: "1.5em",
|
|
32
|
+
paddingBlock: "0.75em 1.6em",
|
|
33
|
+
fontSize: "_md",
|
|
34
|
+
lineHeight: "1.6",
|
|
35
|
+
color: "_textMuted",
|
|
36
|
+
textAlign: "center",
|
|
37
|
+
whiteSpace: "pre-wrap",
|
|
38
|
+
overflowWrap: "anywhere"
|
|
39
|
+
},
|
|
40
|
+
titleOnly: { paddingBlockEnd: "1.6em" },
|
|
41
|
+
footer: {
|
|
42
|
+
display: "flex",
|
|
43
|
+
borderBlockStartWidth: "_hairline",
|
|
44
|
+
borderBlockStartStyle: "solid",
|
|
45
|
+
borderBlockStartColor: "_border"
|
|
46
|
+
},
|
|
47
|
+
action: {
|
|
48
|
+
flex: "1 1 0",
|
|
49
|
+
minHeight: "3.2em",
|
|
50
|
+
borderRadius: "_none",
|
|
51
|
+
borderInlineStartWidth: {
|
|
52
|
+
default: "_hairline",
|
|
53
|
+
":first-child": 0
|
|
54
|
+
},
|
|
55
|
+
borderInlineStartColor: "_border",
|
|
56
|
+
fontSize: "_lg"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
/** 对话框(弹出层 > 标题 + 说明 + 按钮) */
|
|
60
|
+
var Dialog = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
61
|
+
const open = bindable(_props, "_open", () => false, _ctx.emit);
|
|
62
|
+
const title = readonlyProp(_props, "title");
|
|
63
|
+
const message = readonlyProp(_props, "message");
|
|
64
|
+
const confirmText = readonlyProp(_props, "confirmText");
|
|
65
|
+
const cancelText = readonlyProp(_props, "cancelText");
|
|
66
|
+
const showCancel = readonlyProp(_props, "showCancel", false);
|
|
67
|
+
const confirmTone = readonlyProp(_props, "confirmTone", "accent");
|
|
68
|
+
const closeOnOverlay = readonlyProp(_props, "closeOnOverlay", false);
|
|
69
|
+
const onConfirm = readonlyProp(_props, "onConfirm");
|
|
70
|
+
const onCancel = readonlyProp(_props, "onCancel");
|
|
71
|
+
const onOpenChange = readonlyProp(_props, "onOpenChange");
|
|
72
|
+
const children = childrenProp(_props);
|
|
73
|
+
const footer = readonlyProp(_props, "footer");
|
|
74
|
+
const propsPopup = readonlyProp(_props, "propsPopup");
|
|
75
|
+
const propsConfirm = readonlyProp(_props, "propsConfirm");
|
|
76
|
+
const propsCancel = readonlyProp(_props, "propsCancel");
|
|
77
|
+
const rest = restProps(_props, _ctx, false);
|
|
78
|
+
const config = useConfig();
|
|
79
|
+
let confirming = ref(false);
|
|
80
|
+
const close = (reason) => {
|
|
81
|
+
open.value = false;
|
|
82
|
+
onOpenChange.value?.(false, { reason });
|
|
83
|
+
};
|
|
84
|
+
const confirm = async () => {
|
|
85
|
+
const pending = onConfirm.value?.();
|
|
86
|
+
if (!(pending instanceof Promise)) return close("confirm");
|
|
87
|
+
confirming.value = true;
|
|
88
|
+
try {
|
|
89
|
+
await pending;
|
|
90
|
+
close("confirm");
|
|
91
|
+
} finally {
|
|
92
|
+
confirming.value = false;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const cancel = (reason) => {
|
|
96
|
+
onCancel.value?.();
|
|
97
|
+
close(reason);
|
|
98
|
+
};
|
|
99
|
+
return () => {
|
|
100
|
+
const body = hasContent(message.value) ? message.value : children.value;
|
|
101
|
+
return createVNode(Popup, mergePartProps({
|
|
102
|
+
_open: open.value,
|
|
103
|
+
position: "center",
|
|
104
|
+
round: true,
|
|
105
|
+
closeOnOverlay: closeOnOverlay.value,
|
|
106
|
+
sx: dialogStyles.panel,
|
|
107
|
+
onOpenChange: (next, { reason }) => !next && reason === "overlay" && cancel("overlay")
|
|
108
|
+
}, mergeProps(rest, propsPopup.value)), { default: () => [
|
|
109
|
+
hasContent(title.value) && createVNode("div", mergeAttrs({ sx: [dialogStyles.header, !hasContent(body) && dialogStyles.titleOnly] }), [createVNode("div", mergeAttrs({ sx: dialogStyles.title }), [title.value])]),
|
|
110
|
+
hasContent(body) && createVNode("div", mergeAttrs({ sx: dialogStyles.message }), [body]),
|
|
111
|
+
hasContent(footer.value) ? footer.value : createVNode("div", mergeAttrs({ sx: dialogStyles.footer }), [showCancel.value && createVNode(Button, mergeJsxProps(mergePartProps({
|
|
112
|
+
variant: "ghost",
|
|
113
|
+
tone: "neutral",
|
|
114
|
+
sx: dialogStyles.action,
|
|
115
|
+
onClick: () => cancel("cancel")
|
|
116
|
+
}, propsCancel.value), { "key": "__site0" }), {
|
|
117
|
+
default: () => [cancelText.value ?? config.lang.cancel],
|
|
118
|
+
$stable: true
|
|
119
|
+
}), createVNode(Button, mergeJsxProps(mergePartProps({
|
|
120
|
+
variant: "ghost",
|
|
121
|
+
tone: confirmTone.value,
|
|
122
|
+
loading: confirming.value,
|
|
123
|
+
sx: dialogStyles.action,
|
|
124
|
+
onClick: () => void confirm()
|
|
125
|
+
}, propsConfirm.value), { "key": "__site1" }), {
|
|
126
|
+
default: () => [confirmText.value ?? config.lang.confirm],
|
|
127
|
+
$stable: true
|
|
128
|
+
})])
|
|
129
|
+
] });
|
|
130
|
+
};
|
|
131
|
+
}, {
|
|
132
|
+
name: "Dialog",
|
|
133
|
+
props: [
|
|
134
|
+
"_open",
|
|
135
|
+
"onUpdate:_open",
|
|
136
|
+
"title",
|
|
137
|
+
"message",
|
|
138
|
+
"confirmText",
|
|
139
|
+
"cancelText",
|
|
140
|
+
"showCancel",
|
|
141
|
+
"confirmTone",
|
|
142
|
+
"closeOnOverlay",
|
|
143
|
+
"onConfirm",
|
|
144
|
+
"onCancel",
|
|
145
|
+
"onOpenChange",
|
|
146
|
+
"footer",
|
|
147
|
+
"propsPopup",
|
|
148
|
+
"propsConfirm",
|
|
149
|
+
"propsCancel"
|
|
150
|
+
]
|
|
151
|
+
});
|
|
152
|
+
/** 命令式对话框:排队显示,前一个关了才显示下一个 */
|
|
153
|
+
/** 命令式对话框的状态:ConfigProvider 里的出口按它渲染 */
|
|
154
|
+
var dialogState = shallowReactive({
|
|
155
|
+
open: false,
|
|
156
|
+
queue: []
|
|
157
|
+
});
|
|
158
|
+
/** 显示一个对话框;确认时结果为 true,取消(或点遮罩关闭)时为 false */
|
|
159
|
+
function showDialog(options) {
|
|
160
|
+
return new Promise((resolve) => {
|
|
161
|
+
dialogState.queue = [...dialogState.queue, {
|
|
162
|
+
options,
|
|
163
|
+
resolve
|
|
164
|
+
}];
|
|
165
|
+
dialogState.open = true;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/** 带取消按钮的确认对话框 */
|
|
169
|
+
var showConfirmDialog = (options) => showDialog({
|
|
170
|
+
showCancel: true,
|
|
171
|
+
...options
|
|
172
|
+
});
|
|
173
|
+
/** 当前的命令式对话框关闭后:交出结果,过了离场动画再显示下一个 */
|
|
174
|
+
function settleDialog(confirmed) {
|
|
175
|
+
const [current, ...rest] = dialogState.queue;
|
|
176
|
+
current?.resolve(confirmed);
|
|
177
|
+
dialogState.open = false;
|
|
178
|
+
setTimeout(() => {
|
|
179
|
+
dialogState.queue = rest;
|
|
180
|
+
if (rest.length) dialogState.open = true;
|
|
181
|
+
}, 300);
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { Dialog, dialogState, dialogStyles, settleDialog, showConfirmDialog, showDialog };
|
|
185
|
+
|
|
186
|
+
//# sourceMappingURL=Dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/feedback/Dialog.tsx"],"sourcesContent":["/**\n * 对话框:屏幕中间的卡片,标题、说明、底部一排按钮(确认、取消)。用来确认操作、提示重要信息。\n *\n * await showDialog({ title: '提示', message: '提交成功' });\n * if (await showConfirmDialog({ title: '删除地址', message: '删除后不能恢复', confirmTone: 'danger' })) remove();\n * <Dialog _open={show} title=\"退出登录\" showCancel onConfirm={logout} />\n *\n * onConfirm 返回 Promise 时确认按钮转圈,完成后才关闭(抛错时不关闭)。命令式的写法渲染在 ConfigProvider 里。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { shallowReactive, type VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { useConfig } from '../config/context';\nimport { Popup, type PopupProps } from '../overlay/Popup';\nimport { hasContent, mergeAttrs, mergePartProps, mergeProps, type PartProps } from '../utils/props';\n\n/** 关闭的原因 */\nexport type DialogCloseReason = 'confirm' | 'cancel' | 'overlay';\n\n/** 对话框的选项(组件的 props 与 showDialog 的参数共用) */\nexport interface DialogOptions {\n /** 标题 */\n title?: VNodeChild;\n /** 说明 */\n message?: VNodeChild;\n /** 确认按钮的文字;不给时用语言包的\"确认\" */\n confirmText?: VNodeChild;\n /** 取消按钮的文字;不给时用语言包的\"取消\" */\n cancelText?: VNodeChild;\n /** 显示取消按钮 */\n showCancel?: boolean;\n /**\n * 确认按钮的色调:删除这类操作用 danger\n * @default 'accent'\n */\n confirmTone?: 'accent' | 'danger';\n /** 点遮罩关闭(等于取消) */\n closeOnOverlay?: boolean;\n /** 点了确认;返回 Promise 时按钮转圈,完成后才关闭 */\n onConfirm?: () => void | Promise<unknown>;\n /** 点了取消(或点遮罩关闭) */\n onCancel?: () => void;\n}\n\n/** 未声明的属性落到对话框的面板上 */\nexport interface DialogProps extends DialogOptions, Omit<PartProps<'div', 'role'>, 'title'> {\n /** 是否打开;双向绑定写 `_open={x}` */\n _open?: boolean;\n /** 关闭时带原因 */\n onOpenChange?: (open: boolean, details: { reason: DialogCloseReason }) => void;\n /** 说明(与 message 二选一),可以放任意内容 */\n children?: VNodeChild;\n /** 自定义底部(代替确认、取消按钮) */\n footer?: VNodeChild;\n /** 弹出层的部件属性 */\n propsPopup?: Partial<PopupProps>;\n /** 确认按钮的部件属性 */\n propsConfirm?: Partial<ButtonProps>;\n /** 取消按钮的部件属性 */\n propsCancel?: Partial<ButtonProps>;\n}\n\n/** Dialog 的样式:panel、header、title、message、footer、action */\nexport const dialogStyles = css.create({\n panel: { width: '20em', maxWidth: '85vw', overflow: 'hidden' },\n header: { paddingBlockStart: '1.6em', paddingInline: '1.5em', textAlign: 'center' },\n title: { fontSize: '_lg', fontWeight: '_semibold', lineHeight: '_tight', color: '_text' },\n message: {\n paddingInline: '1.5em',\n paddingBlock: '0.75em 1.6em',\n fontSize: '_md',\n lineHeight: '1.6',\n color: '_textMuted',\n textAlign: 'center',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'anywhere',\n },\n // 只有标题时,标题下面也留出同样的空\n titleOnly: { paddingBlockEnd: '1.6em' },\n footer: {\n display: 'flex',\n borderBlockStartWidth: '_hairline',\n borderBlockStartStyle: 'solid',\n borderBlockStartColor: '_border',\n },\n action: {\n flex: '1 1 0',\n minHeight: '3.2em',\n borderRadius: '_none',\n borderInlineStartWidth: { default: '_hairline', ':first-child': 0 },\n borderInlineStartColor: '_border',\n fontSize: '_lg',\n },\n});\n\n/** 对话框(弹出层 > 标题 + 说明 + 按钮) */\nexport const Dialog = _component(\n ({\n _open: open = _bindable(false),\n title,\n message,\n confirmText,\n cancelText,\n showCancel = false,\n confirmTone = 'accent',\n closeOnOverlay = false,\n onConfirm,\n onCancel,\n onOpenChange,\n children,\n footer,\n propsPopup,\n propsConfirm,\n propsCancel,\n ...rest\n }: DialogProps) => {\n const config = useConfig();\n let confirming = _state(false);\n const close = (reason: DialogCloseReason) => {\n open = false;\n onOpenChange?.(false, { reason });\n };\n const confirm = async () => {\n const pending = onConfirm?.();\n if (!(pending instanceof Promise)) return close('confirm');\n confirming = true;\n try {\n await pending;\n close('confirm');\n } finally {\n confirming = false;\n }\n };\n const cancel = (reason: 'cancel' | 'overlay') => {\n onCancel?.();\n close(reason);\n };\n return () => {\n const body = hasContent(message) ? message : children;\n return (\n <Popup\n {...mergePartProps<PopupProps>(\n {\n _open: open,\n position: 'center',\n round: true,\n closeOnOverlay,\n sx: dialogStyles.panel,\n onOpenChange: (next, { reason }) =>\n !next && reason === 'overlay' && cancel('overlay'),\n },\n // 对话框上未声明的属性与弹出层的部件属性都落到面板上\n mergeProps<PopupProps>(rest as Partial<PopupProps>, propsPopup) as Partial<PopupProps>,\n )}\n >\n {hasContent(title) && (\n <div\n {...mergeAttrs<'div'>({\n sx: [dialogStyles.header, !hasContent(body) && dialogStyles.titleOnly],\n })}\n >\n <div {...mergeAttrs<'div'>({ sx: dialogStyles.title })}>{title}</div>\n </div>\n )}\n {hasContent(body) && (\n <div {...mergeAttrs<'div'>({ sx: dialogStyles.message })}>{body}</div>\n )}\n {hasContent(footer) ? (\n footer\n ) : (\n <div {...mergeAttrs<'div'>({ sx: dialogStyles.footer })}>\n {showCancel && (\n <Button\n {...mergePartProps<ButtonProps>(\n {\n variant: 'ghost',\n tone: 'neutral',\n sx: dialogStyles.action,\n onClick: () => cancel('cancel'),\n },\n propsCancel,\n )}\n >\n {cancelText ?? config.lang.cancel}\n </Button>\n )}\n <Button\n {...mergePartProps<ButtonProps>(\n {\n variant: 'ghost',\n tone: confirmTone,\n loading: confirming,\n sx: dialogStyles.action,\n onClick: () => void confirm(),\n },\n propsConfirm,\n )}\n >\n {confirmText ?? config.lang.confirm}\n </Button>\n </div>\n )}\n </Popup>\n );\n };\n },\n);\n\n/** 命令式对话框:排队显示,前一个关了才显示下一个 */\ninterface DialogRequest {\n options: DialogOptions;\n resolve: (confirmed: boolean) => void;\n}\n\n/** 命令式对话框的状态:ConfigProvider 里的出口按它渲染 */\nexport const dialogState = shallowReactive<{ open: boolean; queue: DialogRequest[] }>({\n open: false,\n queue: [],\n});\n\n/** 显示一个对话框;确认时结果为 true,取消(或点遮罩关闭)时为 false */\nexport function showDialog(options: DialogOptions): Promise<boolean> {\n return new Promise((resolve) => {\n dialogState.queue = [...dialogState.queue, { options, resolve }];\n dialogState.open = true;\n });\n}\n\n/** 带取消按钮的确认对话框 */\nexport const showConfirmDialog = (options: DialogOptions) =>\n showDialog({ showCancel: true, ...options });\n\n/** 当前的命令式对话框关闭后:交出结果,过了离场动画再显示下一个 */\nexport function settleDialog(confirmed: boolean) {\n const [current, ...rest] = dialogState.queue;\n current?.resolve(confirmed);\n dialogState.open = false;\n setTimeout(() => {\n dialogState.queue = rest;\n if (rest.length) dialogState.open = true;\n }, 300);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PrivacyPrompt } from "../capability/PrivacyPrompt.js";
|
|
2
|
+
import { Dialog, dialogState, settleDialog } from "./Dialog.js";
|
|
3
|
+
import { Notify, notifyState } from "./Notify.js";
|
|
4
|
+
import { Toast, toastState } from "./Toast.js";
|
|
5
|
+
import { _component, mergeJsxProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
6
|
+
import { createVNode } from "vue";
|
|
7
|
+
//#region src/feedback/FeedbackOutlet.tsx
|
|
8
|
+
/** 命令式反馈的出口:轻提示、对话框、顶部通知、隐私协议 */
|
|
9
|
+
var FeedbackOutlet = /*#__PURE__*/ _component(() => () => {
|
|
10
|
+
const dialog = dialogState.queue[0];
|
|
11
|
+
return [
|
|
12
|
+
createVNode(Toast, mergeJsxProps(toastState.options, {
|
|
13
|
+
"_open": toastState.open,
|
|
14
|
+
"onUpdate:_open": ($event) => toastState.open = $event
|
|
15
|
+
}), null),
|
|
16
|
+
createVNode(Notify, mergeJsxProps(notifyState.options, {
|
|
17
|
+
"_open": notifyState.open,
|
|
18
|
+
"onUpdate:_open": ($event) => notifyState.open = $event
|
|
19
|
+
}), null),
|
|
20
|
+
dialog && createVNode(Dialog, mergeJsxProps(dialog.options, {
|
|
21
|
+
"_open": dialogState.open,
|
|
22
|
+
"onUpdate:_open": ($event) => dialogState.open = $event,
|
|
23
|
+
"onOpenChange": (_open, { reason }) => settleDialog(reason === "confirm")
|
|
24
|
+
}), null),
|
|
25
|
+
createVNode(PrivacyPrompt, null, null)
|
|
26
|
+
];
|
|
27
|
+
}, { name: "FeedbackOutlet" });
|
|
28
|
+
//#endregion
|
|
29
|
+
export { FeedbackOutlet };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=FeedbackOutlet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackOutlet.js","names":["_createVNode","_mergeProps"],"sources":["../../src/feedback/FeedbackOutlet.tsx"],"sourcesContent":["/**\n * 命令式反馈的出口:showToast、showDialog、showNotify 改的是模块里的状态,这里把它们渲染出来;\n * 平台要求同意隐私协议时的弹窗(PrivacyPrompt)也在这里。\n * ConfigProvider 自动渲染一个;小程序里每个页面都有自己的一个(页面栈里看不见的页面渲染了也看不到)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { PrivacyPrompt } from '../capability/PrivacyPrompt';\nimport { Dialog, dialogState, settleDialog } from './Dialog';\nimport { Notify, notifyState } from './Notify';\nimport { Toast, toastState } from './Toast';\n\n/** 命令式反馈的出口:轻提示、对话框、顶部通知、隐私协议 */\nexport const FeedbackOutlet = _component(() => () => {\n const dialog = dialogState.queue[0];\n return [\n // 对象属性的 _open 双向绑定:到时间自动关闭时写回状态\n <Toast {...toastState.options} _open={toastState.open} />,\n <Notify {...notifyState.options} _open={notifyState.open} />,\n dialog && (\n <Dialog\n {...dialog.options}\n _open={dialogState.open}\n onOpenChange={(_open, { reason }) => settleDialog(reason === 'confirm')}\n />\n ),\n <PrivacyPrompt />,\n ];\n});\n"],"mappings":";;;;;;;;AAYA,IAAa,iBAAiB,qCAAuB;CACnD,MAAM,SAAS,YAAY,MAAM;CACjC,OAAO;EACLA,YAAA,OAAAC,cACW,WAAW,SAAO;GAAA,SAAS,WAAW;GAAI,mBAAA,WAAf,WAAW,OAAI;EAAA,CAAA,GAAA,IAAA;EAAAD,YAAA,QAAAC,cACzC,YAAY,SAAO;GAAA,SAAS,YAAY;GAAI,mBAAA,WAAhB,YAAY,OAAI;EAAA,CAAA,GAAA,IAAA;EACxD,UAAMD,YAAA,QAAAC,cAEE,OAAO,SAAO;GAAA,SACX,YAAY;GAAI,mBAAA,WAAhB,YAAY,OAAI;GAAA,iBACR,OAAO,EAAE,aAAa,aAAa,WAAW,SAAS;EAAC,CAAA,GAAA,IAAA;EAE1ED,YAAA,eAAA,MAAA,IAAA;CAAA;AAGL,GAAC,EAAA,MAAA,iBAAA,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
2
|
+
import type { VNodeChild } from 'vue';
|
|
3
|
+
import { type IconProps } from '../base/Icon';
|
|
4
|
+
import { type PartProps } from '../utils/props';
|
|
5
|
+
/** 未声明的属性落到外层的 span 上 */
|
|
6
|
+
export interface LoadingProps extends PartProps<'span', 'role'> {
|
|
7
|
+
/** 图标大小(px);不写时为 1em */
|
|
8
|
+
size?: number;
|
|
9
|
+
/** 文字放在图标下面(整块的加载状态) */
|
|
10
|
+
vertical?: boolean;
|
|
11
|
+
/** 说明文字;有文字时 role="status" */
|
|
12
|
+
children?: VNodeChild;
|
|
13
|
+
/** 旋转图标的部件属性 */
|
|
14
|
+
propsIcon?: Partial<IconProps>;
|
|
15
|
+
/** 文字的部件属性 */
|
|
16
|
+
propsText?: PartProps<'span'>;
|
|
17
|
+
}
|
|
18
|
+
/** Loading 的样式:root、vertical、icon、text */
|
|
19
|
+
export declare const loadingStyles: Readonly<{
|
|
20
|
+
icon: css.CompiledStyles;
|
|
21
|
+
root: css.CompiledStyles;
|
|
22
|
+
text: css.CompiledStyles;
|
|
23
|
+
vertical: css.CompiledStyles;
|
|
24
|
+
}>;
|
|
25
|
+
/** 加载指示(span > 图标 + 文字) */
|
|
26
|
+
export declare const Loading: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<LoadingProps>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { hasContent, mergeAttrs, mergePartProps } from "../utils/props.js";
|
|
2
|
+
import { Icon } from "../base/Icon.js";
|
|
3
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
4
|
+
import { _component, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
5
|
+
import { createVNode } from "vue";
|
|
6
|
+
import { LoaderCircle } from "@lucide/icons";
|
|
7
|
+
//#region src/feedback/Loading.tsx
|
|
8
|
+
/**
|
|
9
|
+
* 加载指示:旋转的圆弧,可带文字。大小随所在文字(1em),颜色随文字;表示"一个操作正在进行"。
|
|
10
|
+
*
|
|
11
|
+
* <Loading /> 装饰性:旁边已经有说明
|
|
12
|
+
* <Loading>加载中…</Loading> 带文字:role="status",读屏会念出
|
|
13
|
+
* <Loading vertical size={24}>…</Loading>
|
|
14
|
+
*/
|
|
15
|
+
/** 未声明的属性落到外层的 span 上 */
|
|
16
|
+
var spin = css.keyframes({ to: { transform: "rotate(360deg)" } });
|
|
17
|
+
/** Loading 的样式:root、vertical、icon、text */
|
|
18
|
+
var loadingStyles = css.create({
|
|
19
|
+
root: {
|
|
20
|
+
display: "inline-flex",
|
|
21
|
+
alignItems: "center",
|
|
22
|
+
gap: "_sm",
|
|
23
|
+
verticalAlign: "middle"
|
|
24
|
+
},
|
|
25
|
+
vertical: {
|
|
26
|
+
flexDirection: "column",
|
|
27
|
+
gap: "_sm"
|
|
28
|
+
},
|
|
29
|
+
icon: {
|
|
30
|
+
animationName: spin,
|
|
31
|
+
animationDuration: {
|
|
32
|
+
default: "0.8s",
|
|
33
|
+
_reducedMotion: "1.6s"
|
|
34
|
+
},
|
|
35
|
+
animationTimingFunction: "linear",
|
|
36
|
+
animationIterationCount: "infinite"
|
|
37
|
+
},
|
|
38
|
+
text: { fontSize: "_sm" }
|
|
39
|
+
});
|
|
40
|
+
/** 加载指示(span > 图标 + 文字) */
|
|
41
|
+
var Loading = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
42
|
+
const size = readonlyProp(_props, "size");
|
|
43
|
+
const vertical = readonlyProp(_props, "vertical", false);
|
|
44
|
+
const children = childrenProp(_props);
|
|
45
|
+
const propsIcon = readonlyProp(_props, "propsIcon");
|
|
46
|
+
const propsText = readonlyProp(_props, "propsText");
|
|
47
|
+
const rest = restProps(_props, _ctx, false);
|
|
48
|
+
return () => {
|
|
49
|
+
const labelled = hasContent(children.value);
|
|
50
|
+
return createVNode("span", mergeAttrs({ sx: [loadingStyles.root, vertical.value && loadingStyles.vertical] }, rest, { role: labelled ? "status" : void 0 }), [createVNode(Icon, mergePartProps({
|
|
51
|
+
icon: LoaderCircle,
|
|
52
|
+
size: size.value,
|
|
53
|
+
sx: loadingStyles.icon
|
|
54
|
+
}, propsIcon.value), null), labelled && createVNode("span", mergeAttrs({ sx: loadingStyles.text }, propsText.value), [children.value])]);
|
|
55
|
+
};
|
|
56
|
+
}, {
|
|
57
|
+
name: "Loading",
|
|
58
|
+
props: [
|
|
59
|
+
"size",
|
|
60
|
+
"vertical",
|
|
61
|
+
"propsIcon",
|
|
62
|
+
"propsText"
|
|
63
|
+
]
|
|
64
|
+
});
|
|
65
|
+
//#endregion
|
|
66
|
+
export { Loading, loadingStyles };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=Loading.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Loading.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode"],"sources":["../../src/feedback/Loading.tsx"],"sourcesContent":["/**\n * 加载指示:旋转的圆弧,可带文字。大小随所在文字(1em),颜色随文字;表示\"一个操作正在进行\"。\n *\n * <Loading /> 装饰性:旁边已经有说明\n * <Loading>加载中…</Loading> 带文字:role=\"status\",读屏会念出\n * <Loading vertical size={24}>…</Loading>\n */\nimport { LoaderCircle } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { Icon, type IconProps } from '../base/Icon';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\n\n/** 未声明的属性落到外层的 span 上 */\nexport interface LoadingProps extends PartProps<'span', 'role'> {\n /** 图标大小(px);不写时为 1em */\n size?: number;\n /** 文字放在图标下面(整块的加载状态) */\n vertical?: boolean;\n /** 说明文字;有文字时 role=\"status\" */\n children?: VNodeChild;\n /** 旋转图标的部件属性 */\n propsIcon?: Partial<IconProps>;\n /** 文字的部件属性 */\n propsText?: PartProps<'span'>;\n}\n\nconst spin = css.keyframes({ to: { transform: 'rotate(360deg)' } });\n\n/** Loading 的样式:root、vertical、icon、text */\nexport const loadingStyles = css.create({\n root: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '_sm',\n // 颜色跟随所在文字:按钮里是按钮的字色,页面里由使用方的 sx 定\n verticalAlign: 'middle',\n },\n vertical: { flexDirection: 'column', gap: '_sm' },\n icon: {\n animationName: spin,\n // 旋转本身就是\"还在加载\"的信息,减少动态效果时转慢一些而不停\n animationDuration: { default: '0.8s', _reducedMotion: '1.6s' },\n animationTimingFunction: 'linear',\n animationIterationCount: 'infinite',\n },\n text: { fontSize: '_sm' },\n});\n\n/** 加载指示(span > 图标 + 文字) */\nexport const Loading = _component(\n ({ size, vertical = false, children, propsIcon, propsText, ...rest }: LoadingProps) =>\n () => {\n const labelled = hasContent(children);\n return (\n <span\n {...mergeAttrs<'span'>(\n { sx: [loadingStyles.root, vertical && loadingStyles.vertical] },\n rest,\n { role: labelled ? 'status' : undefined },\n )}\n >\n <Icon\n {...mergePartProps<IconProps>(\n { icon: LoaderCircle, size, sx: loadingStyles.icon },\n propsIcon,\n )}\n />\n {labelled && (\n <span {...mergeAttrs<'span'>({ sx: loadingStyles.text }, propsText)}>{children}</span>\n )}\n </span>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;AA4BA,IAAM,OAAO,IAAI,UAAU,EAAE,IAAI,EAAE,WAAW,iBAAiB,EAAE,CAAC;;AAGlE,IAAa,gBAAgB,IAAI,OAAO;CACtC,MAAM;EACJ,SAAS;EACT,YAAY;EACZ,KAAK;EAEL,eAAe;CACjB;CACA,UAAU;EAAE,eAAe;EAAU,KAAK;CAAM;CAChD,MAAM;EACJ,eAAe;EAEf,mBAAmB;GAAE,SAAS;GAAQ,gBAAgB;EAAO;EAC7D,yBAAyB;EACzB,yBAAyB;CAC3B;CACA,MAAM,EAAE,UAAU,MAAM;AAC1B,CAAC;;AAGD,IAAa,UAAU,0BACrB,QAAA,SAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,YAAoB,KAAK;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAAA,YAAAD,aAAA,QAAA,WAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAqC,OAAIE,UAAA,QAAA,MAAA,KAAA;CAAA,aAC1D;EACJ,MAAM,WAAW,WAAU,SAAA,KAAS;EACpC,OAAAC,YAAA,QAEQ,WACF,EAAE,IAAI,CAAC,cAAc,MAAM,SAAA,SAAY,cAAc,QAAQ,EAAE,GAC/D,MACA,EAAE,MAAM,WAAW,WAAW,KAAA,EAAU,CAC1C,GAAC,CAAAA,YAAA,MAGK,eACF;GAAE,MAAM;GAAc,MAAI,KAAA;GAAE,IAAI,cAAc;EAAK,GAAC,UAAA,KAEtD,GAAC,IAAA,GAEF,YAAQA,YAAA,QACG,WAAmB,EAAE,IAAI,cAAc,KAAK,GAAC,UAAA,KAAW,GAAC,CAAA,SAAA,KAAA,CAAA,CACpE,CAAA;CAGP;AAAC,GAAA;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACL"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
2
|
+
import { type VNodeChild } from 'vue';
|
|
3
|
+
import { type PartProps } from '../utils/props';
|
|
4
|
+
/** 通知的选项(组件的 props 与 showNotify 的参数共用) */
|
|
5
|
+
export interface NotifyOptions {
|
|
6
|
+
/** 文字 */
|
|
7
|
+
message?: VNodeChild;
|
|
8
|
+
/**
|
|
9
|
+
* 色调
|
|
10
|
+
* @default 'danger'
|
|
11
|
+
*/
|
|
12
|
+
tone?: 'danger' | 'success' | 'warning' | 'accent';
|
|
13
|
+
/**
|
|
14
|
+
* 显示多久(ms);0 表示不自动收起
|
|
15
|
+
* @default 3000
|
|
16
|
+
*/
|
|
17
|
+
duration?: number;
|
|
18
|
+
/** 点了通知 */
|
|
19
|
+
onClick?: (event: Event) => void;
|
|
20
|
+
/** 收起之后 */
|
|
21
|
+
onClose?: () => void;
|
|
22
|
+
}
|
|
23
|
+
/** 未声明的属性落到通知栏(div)上 */
|
|
24
|
+
export interface NotifyProps extends NotifyOptions, Omit<PartProps<'div', 'role'>, 'onClick'> {
|
|
25
|
+
/** 是否显示;双向绑定写 `_open={x}` */
|
|
26
|
+
_open?: boolean;
|
|
27
|
+
/** 文字(与 message 二选一) */
|
|
28
|
+
children?: VNodeChild;
|
|
29
|
+
}
|
|
30
|
+
/** Notify 的样式:root、各色调 */
|
|
31
|
+
export declare const notifyStyles: Readonly<{
|
|
32
|
+
accent: css.CompiledStyles;
|
|
33
|
+
danger: css.CompiledStyles;
|
|
34
|
+
root: css.CompiledStyles;
|
|
35
|
+
success: css.CompiledStyles;
|
|
36
|
+
warning: css.CompiledStyles;
|
|
37
|
+
}>;
|
|
38
|
+
/** 顶部通知(div[role=alert],渲染到浮层根) */
|
|
39
|
+
export declare const Notify: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<NotifyProps>;
|
|
40
|
+
/** 命令式通知的状态:ConfigProvider 里的出口按它渲染 */
|
|
41
|
+
export declare const notifyState: import("vue").ShallowReactive<{
|
|
42
|
+
open: boolean;
|
|
43
|
+
options: NotifyOptions;
|
|
44
|
+
}>;
|
|
45
|
+
/** 显示一条顶部通知;同一时间只有一条 */
|
|
46
|
+
export declare function showNotify(options: NotifyOptions | string): void;
|
|
47
|
+
/** 收起当前的顶部通知 */
|
|
48
|
+
export declare function closeNotify(): void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useConfig } from "../config/context.js";
|
|
2
|
+
import { dataAttrs, mergeAttrs } from "../utils/props.js";
|
|
3
|
+
import { useHost } from "../utils/host.js";
|
|
4
|
+
import { usePresence } from "../utils/presence.js";
|
|
5
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
6
|
+
import { _component, bindable, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
|
|
7
|
+
import { Teleport, createVNode, onBeforeUnmount, shallowReactive, watch } from "vue";
|
|
8
|
+
//#region src/feedback/Notify.tsx
|
|
9
|
+
/** 通知的选项(组件的 props 与 showNotify 的参数共用) */
|
|
10
|
+
/** 未声明的属性落到通知栏(div)上 */
|
|
11
|
+
/** Notify 的样式:root、各色调 */
|
|
12
|
+
var notifyStyles = css.create({
|
|
13
|
+
root: {
|
|
14
|
+
boxSizing: "border-box",
|
|
15
|
+
position: "fixed",
|
|
16
|
+
insetBlockStart: 0,
|
|
17
|
+
insetInline: 0,
|
|
18
|
+
zIndex: 3e3,
|
|
19
|
+
paddingBlock: "0.6em",
|
|
20
|
+
paddingInline: "_lg",
|
|
21
|
+
paddingBlockStart: `max(0.6em, env(safe-area-inset-top))`,
|
|
22
|
+
fontSize: "_md",
|
|
23
|
+
lineHeight: "1.5",
|
|
24
|
+
textAlign: "center",
|
|
25
|
+
overflowWrap: "anywhere",
|
|
26
|
+
transform: {
|
|
27
|
+
default: "translateY(-100%)",
|
|
28
|
+
"[data-state=\"open\"]": "none"
|
|
29
|
+
},
|
|
30
|
+
transitionProperty: "transform",
|
|
31
|
+
transitionDuration: "_md",
|
|
32
|
+
transitionTimingFunction: "_standard"
|
|
33
|
+
},
|
|
34
|
+
danger: {
|
|
35
|
+
color: "_dangerContrast",
|
|
36
|
+
backgroundColor: "_danger"
|
|
37
|
+
},
|
|
38
|
+
success: {
|
|
39
|
+
color: "_successContrast",
|
|
40
|
+
backgroundColor: "_success"
|
|
41
|
+
},
|
|
42
|
+
warning: {
|
|
43
|
+
color: "_warningContrast",
|
|
44
|
+
backgroundColor: "_warning"
|
|
45
|
+
},
|
|
46
|
+
accent: {
|
|
47
|
+
color: "_accentContrast",
|
|
48
|
+
backgroundColor: "_accent"
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
/** 顶部通知(div[role=alert],渲染到浮层根) */
|
|
52
|
+
var Notify = /*#__PURE__*/ _component((_props, _ctx) => {
|
|
53
|
+
const open = bindable(_props, "_open", () => false, _ctx.emit);
|
|
54
|
+
const message = readonlyProp(_props, "message");
|
|
55
|
+
const tone = readonlyProp(_props, "tone", "danger");
|
|
56
|
+
const duration = readonlyProp(_props, "duration", 3e3);
|
|
57
|
+
const onClick = readonlyProp(_props, "onClick");
|
|
58
|
+
const onClose = readonlyProp(_props, "onClose");
|
|
59
|
+
const children = childrenProp(_props);
|
|
60
|
+
const rest = restProps(_props, _ctx, false);
|
|
61
|
+
const host = useHost();
|
|
62
|
+
const config = useConfig();
|
|
63
|
+
const presence = usePresence(() => open.value, 240);
|
|
64
|
+
let timer;
|
|
65
|
+
watch(() => [
|
|
66
|
+
open.value,
|
|
67
|
+
message.value,
|
|
68
|
+
tone.value,
|
|
69
|
+
duration.value
|
|
70
|
+
], () => {
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
if (open.value && duration.value > 0) timer = setTimeout(() => {
|
|
73
|
+
open.value = false;
|
|
74
|
+
onClose.value?.();
|
|
75
|
+
}, duration.value);
|
|
76
|
+
}, { immediate: true });
|
|
77
|
+
onBeforeUnmount(() => clearTimeout(timer));
|
|
78
|
+
return () => presence.mounted && createVNode(Teleport, { "to": host.overlayRoot() }, { default: () => [createVNode("div", mergeAttrs({ sx: [
|
|
79
|
+
config.rootSx,
|
|
80
|
+
notifyStyles.root,
|
|
81
|
+
notifyStyles[tone.value]
|
|
82
|
+
] }, rest, {
|
|
83
|
+
role: "alert",
|
|
84
|
+
onClick: onClick.value,
|
|
85
|
+
...dataAttrs({ "data-state": presence.visible ? "open" : "closed" })
|
|
86
|
+
}), [message.value ?? children.value])] });
|
|
87
|
+
}, {
|
|
88
|
+
name: "Notify",
|
|
89
|
+
props: [
|
|
90
|
+
"_open",
|
|
91
|
+
"onUpdate:_open",
|
|
92
|
+
"message",
|
|
93
|
+
"tone",
|
|
94
|
+
"duration",
|
|
95
|
+
"onClick",
|
|
96
|
+
"onClose"
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
/** 命令式通知的状态:ConfigProvider 里的出口按它渲染 */
|
|
100
|
+
var notifyState = shallowReactive({
|
|
101
|
+
open: false,
|
|
102
|
+
options: {}
|
|
103
|
+
});
|
|
104
|
+
/** 显示一条顶部通知;同一时间只有一条 */
|
|
105
|
+
function showNotify(options) {
|
|
106
|
+
notifyState.options = typeof options === "string" ? { message: options } : options;
|
|
107
|
+
notifyState.open = true;
|
|
108
|
+
}
|
|
109
|
+
/** 收起当前的顶部通知 */
|
|
110
|
+
function closeNotify() {
|
|
111
|
+
notifyState.open = false;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { Notify, closeNotify, notifyState, notifyStyles, showNotify };
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=Notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Notify.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode"],"sources":["../../src/feedback/Notify.tsx"],"sourcesContent":["/**\n * 顶部通知:从页面顶部滑下的一条通知栏,过一会儿自己收起。用来提示操作结果、网络状态这类不打断操作的消息。\n *\n * showNotify('网络连接已断开');\n * showNotify({ message: '已保存', tone: 'success' });\n * <Notify _open={show} tone=\"warning\">余额不足</Notify>\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Teleport, onBeforeUnmount, shallowReactive, watch, type VNodeChild } from 'vue';\nimport { useConfig } from '../config/context';\nimport { useHost } from '../utils/host';\nimport { usePresence } from '../utils/presence';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\n\n/** 通知的选项(组件的 props 与 showNotify 的参数共用) */\nexport interface NotifyOptions {\n /** 文字 */\n message?: VNodeChild;\n /**\n * 色调\n * @default 'danger'\n */\n tone?: 'danger' | 'success' | 'warning' | 'accent';\n /**\n * 显示多久(ms);0 表示不自动收起\n * @default 3000\n */\n duration?: number;\n /** 点了通知 */\n onClick?: (event: Event) => void;\n /** 收起之后 */\n onClose?: () => void;\n}\n\n/** 未声明的属性落到通知栏(div)上 */\nexport interface NotifyProps extends NotifyOptions, Omit<PartProps<'div', 'role'>, 'onClick'> {\n /** 是否显示;双向绑定写 `_open={x}` */\n _open?: boolean;\n /** 文字(与 message 二选一) */\n children?: VNodeChild;\n}\n\n/** Notify 的样式:root、各色调 */\nexport const notifyStyles = css.create({\n root: {\n boxSizing: 'border-box',\n position: 'fixed',\n insetBlockStart: 0,\n insetInline: 0,\n zIndex: 3000,\n paddingBlock: '0.6em',\n paddingInline: '_lg',\n // 刘海屏顶部的安全区\n paddingBlockStart: `max(0.6em, env(safe-area-inset-top))`,\n fontSize: '_md',\n lineHeight: '1.5',\n textAlign: 'center',\n overflowWrap: 'anywhere',\n transform: { default: 'translateY(-100%)', '[data-state=\"open\"]': 'none' },\n transitionProperty: 'transform',\n transitionDuration: '_md',\n transitionTimingFunction: '_standard',\n },\n danger: { color: '_dangerContrast', backgroundColor: '_danger' },\n success: { color: '_successContrast', backgroundColor: '_success' },\n warning: { color: '_warningContrast', backgroundColor: '_warning' },\n accent: { color: '_accentContrast', backgroundColor: '_accent' },\n});\n\n/** 顶部通知(div[role=alert],渲染到浮层根) */\nexport const Notify = _component(\n ({\n _open: open = _bindable(false),\n message,\n tone = 'danger',\n duration = 3000,\n onClick,\n onClose,\n children,\n ...rest\n }: NotifyProps) => {\n const host = useHost();\n const config = useConfig();\n const presence = usePresence(() => open, 240);\n let timer: ReturnType<typeof setTimeout> | undefined;\n watch(\n () => [open, message, tone, duration],\n () => {\n clearTimeout(timer);\n if (open && duration > 0)\n timer = setTimeout(() => {\n open = false;\n onClose?.();\n }, duration);\n },\n { immediate: true },\n );\n onBeforeUnmount(() => clearTimeout(timer));\n return () =>\n presence.mounted && (\n <Teleport to={host.overlayRoot() as never}>\n <div\n {...mergeAttrs<'div'>(\n { sx: [config.rootSx, notifyStyles.root, notifyStyles[tone]] },\n rest,\n {\n role: 'alert',\n onClick,\n ...dataAttrs({ 'data-state': presence.visible ? 'open' : 'closed' }),\n },\n )}\n >\n {message ?? children}\n </div>\n </Teleport>\n );\n },\n);\n\n/** 命令式通知的状态:ConfigProvider 里的出口按它渲染 */\nexport const notifyState = shallowReactive<{ open: boolean; options: NotifyOptions }>({\n open: false,\n options: {},\n});\n\n/** 显示一条顶部通知;同一时间只有一条 */\nexport function showNotify(options: NotifyOptions | string) {\n notifyState.options = typeof options === 'string' ? { message: options } : options;\n notifyState.open = true;\n}\n\n/** 收起当前的顶部通知 */\nexport function closeNotify() {\n notifyState.open = false;\n}\n"],"mappings":";;;;;;;;;;;AA4CA,IAAa,eAAe,IAAI,OAAO;CACrC,MAAM;EACJ,WAAW;EACX,UAAU;EACV,iBAAiB;EACjB,aAAa;EACb,QAAQ;EACR,cAAc;EACd,eAAe;EAEf,mBAAmB;EACnB,UAAU;EACV,YAAY;EACZ,WAAW;EACX,cAAc;EACd,WAAW;GAAE,SAAS;GAAqB,yBAAuB;EAAO;EACzE,oBAAoB;EACpB,oBAAoB;EACpB,0BAA0B;CAC5B;CACA,QAAQ;EAAE,OAAO;EAAmB,iBAAiB;CAAU;CAC/D,SAAS;EAAE,OAAO;EAAoB,iBAAiB;CAAW;CAClE,SAAS;EAAE,OAAO;EAAoB,iBAAiB;CAAW;CAClE,QAAQ;EAAE,OAAO;EAAmB,iBAAiB;CAAU;AACjE,CAAC;;AAGD,IAAa,SAAS,0BACpB,QAAA,SASmB;CAAA,MAAA,OAAAA,SAAA,QAAA,eARO,OAAK,KAAA,IAAA;CAAA,MAAA,UAAAC,aAAA,QAAA,SAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,QAEtB,QAAQ;CAAA,MAAA,WAAAA,aAAA,QAAA,YACJ,GAAI;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAIZ,OAAIC,UAAA,QAAA,MAAA,KAAA;CAEP,MAAM,OAAO,QAAQ;CACrB,MAAM,SAAS,UAAU;CACzB,MAAM,WAAW,kBAAY,KAAA,OAAY,GAAG;CAC5C,IAAI;CACJ,YACQ;EAAA,KAAA;EAAA,QAAA;EAAA,KAAA;EAAA,SAAA;CAAA,SACA;EACJ,aAAa,KAAK;EAClB,IAAI,KAAA,SAAQ,SAAA,QAAW,GACrB,QAAQ,iBAAiB;GACvB,KAAA,QAAO;GACP,QAAA,QAAU;EACZ,GAAC,SAAA,KAAU;CACf,GACA,EAAE,WAAW,KAAK,CACpB;CACA,sBAAsB,aAAa,KAAK,CAAC;CACzC,aACE,SAAS,WAAOC,YAAA,UAAA,EAAA,MACA,KAAK,YAAY,EAAC,GAAA,EAAA,eAAA,CAAAA,YAAA,OAExB,WACF,EAAE,IAAI;EAAC,OAAO;EAAQ,aAAa;EAAM,aAAY,KAAA;CAAM,EAAE,GAC7D,MACA;EACE,MAAM;EACN,SAAO,QAAA;EACP,GAAG,UAAU,EAAE,cAAc,SAAS,UAAU,SAAS,SAAS,CAAC;CACrE,CACF,GAAC,CAEA,QAAA,SAAA,SAAA,KAAmB,CAAA,CAAA,EAAA,CAAA;AAI9B,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH;;AAGA,IAAa,cAAc,gBAA2D;CACpF,MAAM;CACN,SAAS,CAAC;AACZ,CAAC;;AAGD,SAAgB,WAAW,SAAiC;CAC1D,YAAY,UAAU,OAAO,YAAY,WAAW,EAAE,SAAS,QAAQ,IAAI;CAC3E,YAAY,OAAO;AACrB;;AAGA,SAAgB,cAAc;CAC5B,YAAY,OAAO;AACrB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
|
|
2
|
+
import { type VNodeChild } from 'vue';
|
|
3
|
+
import { type PartProps } from '../utils/props';
|
|
4
|
+
/** 下拉的阶段 */
|
|
5
|
+
export interface PullRefreshStatuses {
|
|
6
|
+
/** 没在拉 */
|
|
7
|
+
normal: unknown;
|
|
8
|
+
/** 拉了但还不够,松手会弹回 */
|
|
9
|
+
pulling: unknown;
|
|
10
|
+
/** 拉够了,松手就刷新 */
|
|
11
|
+
loosing: unknown;
|
|
12
|
+
/** 刷新中 */
|
|
13
|
+
loading: unknown;
|
|
14
|
+
/** 刷新完了,显示一会儿成功的提示 */
|
|
15
|
+
success: unknown;
|
|
16
|
+
}
|
|
17
|
+
/** 下拉的阶段 */
|
|
18
|
+
export type PullRefreshStatus = keyof PullRefreshStatuses;
|
|
19
|
+
/** 未声明的属性落到根元素(div)上 */
|
|
20
|
+
export interface PullRefreshProps extends PartProps<'div'> {
|
|
21
|
+
/** 是否在刷新;双向绑定写 `_refreshing={x}` */
|
|
22
|
+
_refreshing?: boolean;
|
|
23
|
+
/** 松手刷新;返回 Promise 时完成后自动收起 */
|
|
24
|
+
onRefresh?: () => void | Promise<unknown>;
|
|
25
|
+
/** 不能下拉 */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* 顶部提示区的高度(px),也是拉到多少算"拉够了"
|
|
29
|
+
* @default 50
|
|
30
|
+
*/
|
|
31
|
+
headHeight?: number;
|
|
32
|
+
/** 各阶段的提示文字;不给时用语言包 */
|
|
33
|
+
pullingText?: VNodeChild;
|
|
34
|
+
loosingText?: VNodeChild;
|
|
35
|
+
loadingText?: VNodeChild;
|
|
36
|
+
/** 刷新完显示的文字;不给时直接收起 */
|
|
37
|
+
successText?: VNodeChild;
|
|
38
|
+
/**
|
|
39
|
+
* 成功提示显示多久(ms)
|
|
40
|
+
* @default 500
|
|
41
|
+
*/
|
|
42
|
+
successDuration?: number;
|
|
43
|
+
/** 自定义提示区的内容(代替各阶段的文字) */
|
|
44
|
+
head?: (status: PullRefreshStatus, distance: number) => VNodeChild;
|
|
45
|
+
/** 内容 */
|
|
46
|
+
children?: VNodeChild;
|
|
47
|
+
/** 提示区的部件属性 */
|
|
48
|
+
propsHead?: PartProps<'div'>;
|
|
49
|
+
}
|
|
50
|
+
/** PullRefresh 的样式:root、track、dragging、head */
|
|
51
|
+
export declare const pullRefreshStyles: Readonly<{
|
|
52
|
+
dragging: css.CompiledStyles;
|
|
53
|
+
head: css.CompiledStyles;
|
|
54
|
+
root: css.CompiledStyles;
|
|
55
|
+
track: css.CompiledStyles;
|
|
56
|
+
}>;
|
|
57
|
+
/** 下拉刷新(div > 滑动层:提示区 + 内容) */
|
|
58
|
+
export declare const PullRefresh: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<PullRefreshProps>;
|