@zerodep-dev/vue-tsx-pro-mobile 0.0.0-stage → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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,312 @@
|
|
|
1
|
+
import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
|
|
2
|
+
//#region src/theme/tokens.ts
|
|
3
|
+
/**
|
|
4
|
+
* 移动端主题 tokens:组件里的颜色、字体、间距、圆角、阴影、动效都只从这里取,不写裸值。
|
|
5
|
+
* 每组一个 defineVars,变量名是 `--vtm-组名-token`;这里的取值即亮色主题,暗色主题见 dark.ts。
|
|
6
|
+
*
|
|
7
|
+
* 用法同桌面组件库:值整个就是一个 token 时写字符串 '_md'、'_space.md',文件末尾的 defineTokens 登记各组;
|
|
8
|
+
* 值里夹着 token(计算、多值)时在模板字符串里用 `t`:`` transition: `opacity ${t.durations.md} ${t.easings.standard}` ``。
|
|
9
|
+
*
|
|
10
|
+
* 取舍:
|
|
11
|
+
* - 配色取自 Radix Colors(与桌面组件库同一套色板,风格一致):slate 中性色、indigo 品牌色、red 危险、green 成功、amber 警告、blue 信息;
|
|
12
|
+
* 移动端的页面底色比表面深一档(分组列表、卡片浮在灰底上,同 iOS 的分组背景)
|
|
13
|
+
* - 尺寸、间距、圆角用 em,随组件字号等比缩放;边框宽度用 px(含 0.5px 的细线)
|
|
14
|
+
* - 字号按 375 宽的设计稿:正文 14、标题 16–18;控件高度由组件按档位给(按钮 24 / 32 / 44 / 50)
|
|
15
|
+
* - 组名与桌面组件库相同,样式里的短写写法一致;token 短写是全局登记的,同一页面里不要混用两套组件库(MOBILE.md)
|
|
16
|
+
*/
|
|
17
|
+
/** 颜色:slate 中性色、indigo 品牌色、red 危险、green 成功、amber 警告、blue 信息 */
|
|
18
|
+
var colors = css.defineVars("vtm-colors", {
|
|
19
|
+
/** 页面底色:分组列表、卡片下面的灰底。slate 3:亮色 `#f0f0f3`,暗色 slate 1 `#111113` */
|
|
20
|
+
background: "#f0f0f3",
|
|
21
|
+
/** 单元格、卡片、弹出层的表面。亮色白色,暗色 slate 2 `#18191b` */
|
|
22
|
+
surface: "#ffffff",
|
|
23
|
+
/** 表面里再分一层:搜索框、步进器、标签的底。slate 2:亮色 `#f9f9fb`,暗色 slate 3 `#212225` */
|
|
24
|
+
surfaceMuted: "#f9f9fb",
|
|
25
|
+
/** 填充:弱按钮、开关关闭态、骨架。slate 3:亮色 `#f0f0f3`,暗色 slate 4 `#272a2d` */
|
|
26
|
+
fill: "#f0f0f3",
|
|
27
|
+
/** 按下时的底色:单元格、菜单项按住。slate 4:亮色 `#e8e8ec`,暗色 slate 5 `#2e3135` */
|
|
28
|
+
fillActive: "#e8e8ec",
|
|
29
|
+
/** 主要文字。slate 12:亮色 `#1c2024`,暗色 `#edeef0` */
|
|
30
|
+
text: "#1c2024",
|
|
31
|
+
/** 次要文字、说明、图标。slate 11:亮色 `#60646c`,暗色 `#b0b4ba` */
|
|
32
|
+
textMuted: "#60646c",
|
|
33
|
+
/** 占位文字。slate 10:亮色 `#80838d`,暗色 `#777b84` */
|
|
34
|
+
textPlaceholder: "#80838d",
|
|
35
|
+
/** 不可用的文字。slate 8:亮色 `#b9bbc6`,暗色 `#5a6169` */
|
|
36
|
+
textDisabled: "#b9bbc6",
|
|
37
|
+
/** 分隔线、单元格之间的细线。slate 6:亮色 `#d9d9e0`,暗色 `#363a3f` */
|
|
38
|
+
border: "#d9d9e0",
|
|
39
|
+
/** 输入框、描边按钮的边框。slate 7:亮色 `#cdced6`,暗色 `#43484e` */
|
|
40
|
+
borderStrong: "#cdced6",
|
|
41
|
+
/** 品牌色:主要按钮、选中、开关打开。indigo 9 `#3e63dd` */
|
|
42
|
+
accent: "#3e63dd",
|
|
43
|
+
/** 品牌色按下。indigo 10:亮色 `#3358d4`,暗色 `#3758d4` */
|
|
44
|
+
accentActive: "#3358d4",
|
|
45
|
+
/** 品牌色上的文字。白色 */
|
|
46
|
+
accentContrast: "#ffffff",
|
|
47
|
+
/** 品牌色的文字(链接、浅色按钮的字)。indigo 11:亮色 `#3a5bc7`,暗色 `#9eb1ff` */
|
|
48
|
+
accentText: "#3a5bc7",
|
|
49
|
+
/** 品牌色的浅底。indigo 3:亮色 `#edf2fe`,暗色 `#182449` */
|
|
50
|
+
accentSoft: "#edf2fe",
|
|
51
|
+
/** 品牌色的浅底按下。indigo 4:亮色 `#e1e9ff`,暗色 `#1d2e62` */
|
|
52
|
+
accentSoftActive: "#e1e9ff",
|
|
53
|
+
/** 品牌色的边框。indigo 7:亮色 `#abbdf9`,暗色 `#3a4f97` */
|
|
54
|
+
accentBorder: "#abbdf9",
|
|
55
|
+
/** 危险:删除、错误。red 9:亮色 `#ce2c31`,暗色 `#b54548` */
|
|
56
|
+
danger: "#ce2c31",
|
|
57
|
+
/** 危险按下。red 10:亮色 `#b8272c`,暗色 `#a33b3e` */
|
|
58
|
+
dangerActive: "#b8272c",
|
|
59
|
+
/** 危险色上的文字。白色 */
|
|
60
|
+
dangerContrast: "#ffffff",
|
|
61
|
+
/** 危险的文字。red 11:亮色 `#b8272c`,暗色 `#ff9592` */
|
|
62
|
+
dangerText: "#b8272c",
|
|
63
|
+
/** 危险的浅底。red 3:亮色 `#feebec`,暗色 `#3b1219` */
|
|
64
|
+
dangerSoft: "#feebec",
|
|
65
|
+
/** 危险的浅底按下。red 4:亮色 `#ffdbdc`,暗色 `#500f1c` */
|
|
66
|
+
dangerSoftActive: "#ffdbdc",
|
|
67
|
+
/** 危险的边框。red 7:亮色 `#f4a9aa`,暗色 `#8c333a` */
|
|
68
|
+
dangerBorder: "#f4a9aa",
|
|
69
|
+
/** 成功。green 9:亮色 `#008751`,暗色 `#30a46c` */
|
|
70
|
+
success: "#008751",
|
|
71
|
+
/** 成功按下。亮色 `#007143`,暗色 `#52af7d` */
|
|
72
|
+
successActive: "#007143",
|
|
73
|
+
/** 成功色上的文字。亮色白色,暗色 slate 1 */
|
|
74
|
+
successContrast: "#ffffff",
|
|
75
|
+
/** 成功的文字。green 11:亮色 `#193b2d`,暗色 `#3dd68c` */
|
|
76
|
+
successText: "#193b2d",
|
|
77
|
+
/** 成功的浅底。green 3:亮色 `#e6f6eb`,暗色 `#132d21` */
|
|
78
|
+
successSoft: "#e6f6eb",
|
|
79
|
+
/** 成功的浅底按下。green 4:亮色 `#d6f1df`,暗色 `#113b29` */
|
|
80
|
+
successSoftActive: "#d6f1df",
|
|
81
|
+
/** 成功的边框。green 7:亮色 `#8eceaa`,暗色 `#28684a` */
|
|
82
|
+
successBorder: "#8eceaa",
|
|
83
|
+
/** 警告。amber 9 `#ffc53d` */
|
|
84
|
+
warning: "#ffc53d",
|
|
85
|
+
/** 警告按下。amber 10 `#ffcd5f` */
|
|
86
|
+
warningActive: "#ffcd5f",
|
|
87
|
+
/** 警告色上的文字(深色)。亮色 `#4f3422`,暗色 slate 1 */
|
|
88
|
+
warningContrast: "#4f3422",
|
|
89
|
+
/** 警告的文字。amber 11:亮色 `#4f3422`,暗色 `#ffca16` */
|
|
90
|
+
warningText: "#4f3422",
|
|
91
|
+
/** 警告的浅底。amber 3:亮色 `#fff7c2`,暗色 `#302008` */
|
|
92
|
+
warningSoft: "#fff7c2",
|
|
93
|
+
/** 警告的浅底按下。amber 4:亮色 `#ffee9c`,暗色 `#3f2700` */
|
|
94
|
+
warningSoftActive: "#ffee9c",
|
|
95
|
+
/** 警告的边框。amber 7:亮色 `#e9c162`,暗色 `#714f19` */
|
|
96
|
+
warningBorder: "#e9c162",
|
|
97
|
+
/** 信息。blue 9:亮色 `#0073e0`,暗色 `#0090ff` */
|
|
98
|
+
info: "#0073e0",
|
|
99
|
+
/** 信息按下。亮色 `#0060bd`,暗色 `#3d9fff` */
|
|
100
|
+
infoActive: "#0060bd",
|
|
101
|
+
/** 信息色上的文字。亮色白色,暗色 slate 1 */
|
|
102
|
+
infoContrast: "#ffffff",
|
|
103
|
+
/** 信息的文字。blue 11:亮色 `#113264`,暗色 `#70b8ff` */
|
|
104
|
+
infoText: "#113264",
|
|
105
|
+
/** 信息的浅底。blue 3:亮色 `#e6f4fe`,暗色 `#0d2847` */
|
|
106
|
+
infoSoft: "#e6f4fe",
|
|
107
|
+
/** 信息的浅底按下。blue 4:亮色 `#d5efff`,暗色 `#003362` */
|
|
108
|
+
infoSoftActive: "#d5efff",
|
|
109
|
+
/** 信息的边框。blue 7:亮色 `#8ec8f6`,暗色 `#205d9e` */
|
|
110
|
+
infoBorder: "#8ec8f6",
|
|
111
|
+
/** 反色表面:轻提示(Toast)、气泡。亮色 slate 12 `#1c2024`,暗色 slate 12 `#edeef0` */
|
|
112
|
+
inverseSurface: "#1c2024",
|
|
113
|
+
/** 反色表面上的文字 */
|
|
114
|
+
inverseText: "#fcfcfd",
|
|
115
|
+
/** 遮罩:弹出层、对话框下面的半透明黑。亮色 0.5,暗色 0.7 */
|
|
116
|
+
overlay: "rgba(0, 0, 0, 0.5)",
|
|
117
|
+
/** 焦点环(H5 的键盘焦点) */
|
|
118
|
+
focusRing: "#3e63dd"
|
|
119
|
+
});
|
|
120
|
+
/** 字体族:系统字体优先,数字用等宽数字(组件里 fontVariantNumeric: 'tabular-nums') */
|
|
121
|
+
var fonts = css.defineVars("vtm-fonts", {
|
|
122
|
+
/** 正文与标题 */
|
|
123
|
+
sans: "system-ui, -apple-system, \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Noto Sans SC\", sans-serif",
|
|
124
|
+
/** 代码、验证码这类等宽内容 */
|
|
125
|
+
mono: "ui-monospace, \"SFMono-Regular\", Menlo, Consolas, monospace"
|
|
126
|
+
});
|
|
127
|
+
/** 字号(375 宽的设计稿):组件根元素的字号决定内部尺寸(em) */
|
|
128
|
+
var fontSizes = css.defineVars("vtm-font-sizes", {
|
|
129
|
+
/** 辅助说明、标签、角标 `12px` */
|
|
130
|
+
xs: "12px",
|
|
131
|
+
/** 次要正文、小按钮 `13px` */
|
|
132
|
+
sm: "13px",
|
|
133
|
+
/** 正文、单元格 `14px` */
|
|
134
|
+
md: "14px",
|
|
135
|
+
/** 按钮、导航栏标题、强调正文 `16px` */
|
|
136
|
+
lg: "16px",
|
|
137
|
+
/** 弹窗标题 `18px` */
|
|
138
|
+
xl: "18px",
|
|
139
|
+
/** 页面标题 `20px` */
|
|
140
|
+
xxl: "20px",
|
|
141
|
+
/** 数值、结果页标题 `24px` */
|
|
142
|
+
xxxl: "24px"
|
|
143
|
+
});
|
|
144
|
+
/** 字重 */
|
|
145
|
+
var fontWeights = css.defineVars("vtm-font-weights", {
|
|
146
|
+
/** 常规 `400` */
|
|
147
|
+
normal: "400",
|
|
148
|
+
/** 中等:按钮、标签页 `500` */
|
|
149
|
+
medium: "500",
|
|
150
|
+
/** 半粗:标题 `600` */
|
|
151
|
+
semibold: "600",
|
|
152
|
+
/** 粗:数值 `700` */
|
|
153
|
+
bold: "700"
|
|
154
|
+
});
|
|
155
|
+
/** 行高(不带单位) */
|
|
156
|
+
var lineHeights = css.defineVars("vtm-line-heights", {
|
|
157
|
+
/** 单行控件 `1` */
|
|
158
|
+
none: "1",
|
|
159
|
+
/** 标题 `1.25` */
|
|
160
|
+
tight: "1.25",
|
|
161
|
+
/** 正文 `1.5` */
|
|
162
|
+
normal: "1.5",
|
|
163
|
+
/** 长段落 `1.75` */
|
|
164
|
+
relaxed: "1.75"
|
|
165
|
+
});
|
|
166
|
+
/** 字距 */
|
|
167
|
+
var letterSpacings = css.defineVars("vtm-letter-spacings", {
|
|
168
|
+
/** 默认 `0` */
|
|
169
|
+
normal: "0",
|
|
170
|
+
/** 大号数字、标题略收 `-0.01em` */
|
|
171
|
+
tight: "-0.01em",
|
|
172
|
+
/** 全大写的小字略放 `0.02em` */
|
|
173
|
+
wide: "0.02em"
|
|
174
|
+
});
|
|
175
|
+
/** 间距(em,随字号缩放) */
|
|
176
|
+
var space = css.defineVars("vtm-space", {
|
|
177
|
+
/** 没有间距 `0` */
|
|
178
|
+
none: "0",
|
|
179
|
+
/** 极小:图标与文字之间 `0.25em` */
|
|
180
|
+
xs: "0.25em",
|
|
181
|
+
/** 小:紧凑的内边距 `0.5em` */
|
|
182
|
+
sm: "0.5em",
|
|
183
|
+
/** 中:常用的间隔 `0.75em` */
|
|
184
|
+
md: "0.75em",
|
|
185
|
+
/** 大:单元格的左右内边距 `1em` */
|
|
186
|
+
lg: "1em",
|
|
187
|
+
/** 很大:分组之间 `1.5em` */
|
|
188
|
+
xl: "1.5em",
|
|
189
|
+
/** 特大:页面区块之间 `2em` */
|
|
190
|
+
xxl: "2em"
|
|
191
|
+
});
|
|
192
|
+
/** 尺寸 */
|
|
193
|
+
var sizes = css.defineVars("vtm-sizes", {
|
|
194
|
+
/** 单行控件(输入框、单元格)的最小高度 `2.75em`(14px 字号时 38.5px,16px 时 44px) */
|
|
195
|
+
control: "2.75em",
|
|
196
|
+
/** 触控目标的最小尺寸 `44px`(iOS 人机界面指南) */
|
|
197
|
+
touchTarget: "44px",
|
|
198
|
+
/** 占满容器 `100%` */
|
|
199
|
+
full: "100%"
|
|
200
|
+
});
|
|
201
|
+
/** 圆角(em) */
|
|
202
|
+
var radii = css.defineVars("vtm-radii", {
|
|
203
|
+
/** 直角 `0` */
|
|
204
|
+
none: "0",
|
|
205
|
+
/** 极小:角标、复选框 `0.125em` */
|
|
206
|
+
xs: "0.125em",
|
|
207
|
+
/** 小:标签、小按钮 `0.25em` */
|
|
208
|
+
sm: "0.25em",
|
|
209
|
+
/** 中:按钮、输入框 `0.5em` */
|
|
210
|
+
md: "0.5em",
|
|
211
|
+
/** 大:卡片、分组 `0.75em` */
|
|
212
|
+
lg: "0.75em",
|
|
213
|
+
/** 很大:弹出层、对话框 `1em` */
|
|
214
|
+
xl: "1em",
|
|
215
|
+
/** 全圆:胶囊按钮、头像 `9999px` */
|
|
216
|
+
full: "9999px"
|
|
217
|
+
});
|
|
218
|
+
/** 边框宽度(px) */
|
|
219
|
+
var borderWidths = css.defineVars("vtm-border-widths", {
|
|
220
|
+
/** 没有边框 `0` */
|
|
221
|
+
none: "0",
|
|
222
|
+
/** 细线:单元格分隔线(高分屏上的半像素) `0.5px` */
|
|
223
|
+
hairline: "0.5px",
|
|
224
|
+
/** 常规边框 `1px` */
|
|
225
|
+
xs: "1px",
|
|
226
|
+
/** 焦点环、选中描边 `2px` */
|
|
227
|
+
sm: "2px"
|
|
228
|
+
});
|
|
229
|
+
/** 阴影:亮色主题用,暗色主题靠表面的层级区分 */
|
|
230
|
+
var shadows = css.defineVars("vtm-shadows", {
|
|
231
|
+
/** 没有阴影 */
|
|
232
|
+
none: "none",
|
|
233
|
+
/** 卡片 */
|
|
234
|
+
sm: "0 1px 2px rgba(0, 0, 0, 0.06), 0 2px 8px -2px rgba(0, 0, 0, 0.08)",
|
|
235
|
+
/** 悬浮按钮、吸顶的栏 */
|
|
236
|
+
md: "0 4px 16px -4px rgba(0, 0, 0, 0.12), 0 2px 6px -2px rgba(0, 0, 0, 0.08)",
|
|
237
|
+
/** 弹出层、对话框 */
|
|
238
|
+
lg: "0 12px 40px -8px rgba(0, 0, 0, 0.2), 0 4px 12px -4px rgba(0, 0, 0, 0.1)"
|
|
239
|
+
});
|
|
240
|
+
var reduce = "@media (prefers-reduced-motion: reduce)";
|
|
241
|
+
/** 动效时长;系统开了"减少动态效果"时为 0 */
|
|
242
|
+
var durations = css.defineVars("vtm-durations", {
|
|
243
|
+
/** 没有过渡 `0ms` */
|
|
244
|
+
none: "0ms",
|
|
245
|
+
/** 按压反馈 `100ms` */
|
|
246
|
+
xs: {
|
|
247
|
+
default: "100ms",
|
|
248
|
+
[reduce]: "0ms"
|
|
249
|
+
},
|
|
250
|
+
/** 颜色、开关 `160ms` */
|
|
251
|
+
sm: {
|
|
252
|
+
default: "160ms",
|
|
253
|
+
[reduce]: "0ms"
|
|
254
|
+
},
|
|
255
|
+
/** 展开收起、提示进出 `240ms` */
|
|
256
|
+
md: {
|
|
257
|
+
default: "240ms",
|
|
258
|
+
[reduce]: "0ms"
|
|
259
|
+
},
|
|
260
|
+
/** 弹出层滑入滑出 `300ms` */
|
|
261
|
+
lg: {
|
|
262
|
+
default: "300ms",
|
|
263
|
+
[reduce]: "0ms"
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
/** 缓动 */
|
|
267
|
+
var easings = css.defineVars("vtm-easings", {
|
|
268
|
+
/** 一般的过渡 */
|
|
269
|
+
standard: "cubic-bezier(0.2, 0, 0, 1)",
|
|
270
|
+
/** 进场:快出慢停 */
|
|
271
|
+
enter: "cubic-bezier(0.05, 0.7, 0.1, 1)",
|
|
272
|
+
/** 离场:慢起快走 */
|
|
273
|
+
exit: "cubic-bezier(0.3, 0, 0.8, 0.15)"
|
|
274
|
+
});
|
|
275
|
+
/** 不透明度 */
|
|
276
|
+
var opacities = css.defineVars("vtm-opacities", {
|
|
277
|
+
/** 不可用 `0.5` */
|
|
278
|
+
disabled: "0.5",
|
|
279
|
+
/** 按下时叠在内容上的暗层(实底按钮) `0.1` */
|
|
280
|
+
pressed: "0.1"
|
|
281
|
+
});
|
|
282
|
+
/** SVG 描边宽度(图标) */
|
|
283
|
+
var strokeWidths = css.defineVars("vtm-stroke-widths", {
|
|
284
|
+
/** 细 `1.5` */
|
|
285
|
+
sm: "1.5",
|
|
286
|
+
/** 常规 `2` */
|
|
287
|
+
md: "2",
|
|
288
|
+
/** 粗 `2.5` */
|
|
289
|
+
lg: "2.5"
|
|
290
|
+
});
|
|
291
|
+
/** 各组 token 的变量引用,用在模板字符串里:`` `max(${t.sizes.control}, ${t.sizes.touchTarget})` `` */
|
|
292
|
+
var t = css.defineTokens({
|
|
293
|
+
colors,
|
|
294
|
+
fonts,
|
|
295
|
+
fontSizes,
|
|
296
|
+
fontWeights,
|
|
297
|
+
lineHeights,
|
|
298
|
+
letterSpacings,
|
|
299
|
+
space,
|
|
300
|
+
sizes,
|
|
301
|
+
radii,
|
|
302
|
+
borderWidths,
|
|
303
|
+
shadows,
|
|
304
|
+
durations,
|
|
305
|
+
easings,
|
|
306
|
+
opacities,
|
|
307
|
+
strokeWidths
|
|
308
|
+
});
|
|
309
|
+
//#endregion
|
|
310
|
+
export { borderWidths, colors, durations, easings, fontSizes, fontWeights, fonts, letterSpacings, lineHeights, opacities, radii, shadows, sizes, space, strokeWidths, t };
|
|
311
|
+
|
|
312
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","names":[],"sources":["../../src/theme/tokens.ts"],"sourcesContent":["/**\n * 移动端主题 tokens:组件里的颜色、字体、间距、圆角、阴影、动效都只从这里取,不写裸值。\n * 每组一个 defineVars,变量名是 `--vtm-组名-token`;这里的取值即亮色主题,暗色主题见 dark.ts。\n *\n * 用法同桌面组件库:值整个就是一个 token 时写字符串 '_md'、'_space.md',文件末尾的 defineTokens 登记各组;\n * 值里夹着 token(计算、多值)时在模板字符串里用 `t`:`` transition: `opacity ${t.durations.md} ${t.easings.standard}` ``。\n *\n * 取舍:\n * - 配色取自 Radix Colors(与桌面组件库同一套色板,风格一致):slate 中性色、indigo 品牌色、red 危险、green 成功、amber 警告、blue 信息;\n * 移动端的页面底色比表面深一档(分组列表、卡片浮在灰底上,同 iOS 的分组背景)\n * - 尺寸、间距、圆角用 em,随组件字号等比缩放;边框宽度用 px(含 0.5px 的细线)\n * - 字号按 375 宽的设计稿:正文 14、标题 16–18;控件高度由组件按档位给(按钮 24 / 32 / 44 / 50)\n * - 组名与桌面组件库相同,样式里的短写写法一致;token 短写是全局登记的,同一页面里不要混用两套组件库(MOBILE.md)\n */\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\n\n/** 颜色:slate 中性色、indigo 品牌色、red 危险、green 成功、amber 警告、blue 信息 */\nexport const colors = css.defineVars('vtm-colors', {\n // ───────── 背景与表面 ─────────\n\n /** 页面底色:分组列表、卡片下面的灰底。slate 3:亮色 `#f0f0f3`,暗色 slate 1 `#111113` */\n background: '#f0f0f3',\n /** 单元格、卡片、弹出层的表面。亮色白色,暗色 slate 2 `#18191b` */\n surface: '#ffffff',\n /** 表面里再分一层:搜索框、步进器、标签的底。slate 2:亮色 `#f9f9fb`,暗色 slate 3 `#212225` */\n surfaceMuted: '#f9f9fb',\n\n // ───────── 中性填充 ─────────\n\n /** 填充:弱按钮、开关关闭态、骨架。slate 3:亮色 `#f0f0f3`,暗色 slate 4 `#272a2d` */\n fill: '#f0f0f3',\n /** 按下时的底色:单元格、菜单项按住。slate 4:亮色 `#e8e8ec`,暗色 slate 5 `#2e3135` */\n fillActive: '#e8e8ec',\n\n // ───────── 文字 ─────────\n\n /** 主要文字。slate 12:亮色 `#1c2024`,暗色 `#edeef0` */\n text: '#1c2024',\n /** 次要文字、说明、图标。slate 11:亮色 `#60646c`,暗色 `#b0b4ba` */\n textMuted: '#60646c',\n /** 占位文字。slate 10:亮色 `#80838d`,暗色 `#777b84` */\n textPlaceholder: '#80838d',\n /** 不可用的文字。slate 8:亮色 `#b9bbc6`,暗色 `#5a6169` */\n textDisabled: '#b9bbc6',\n\n // ───────── 边框 ─────────\n\n /** 分隔线、单元格之间的细线。slate 6:亮色 `#d9d9e0`,暗色 `#363a3f` */\n border: '#d9d9e0',\n /** 输入框、描边按钮的边框。slate 7:亮色 `#cdced6`,暗色 `#43484e` */\n borderStrong: '#cdced6',\n\n // ───────── 品牌色 ─────────\n\n /** 品牌色:主要按钮、选中、开关打开。indigo 9 `#3e63dd` */\n accent: '#3e63dd',\n /** 品牌色按下。indigo 10:亮色 `#3358d4`,暗色 `#3758d4` */\n accentActive: '#3358d4',\n /** 品牌色上的文字。白色 */\n accentContrast: '#ffffff',\n /** 品牌色的文字(链接、浅色按钮的字)。indigo 11:亮色 `#3a5bc7`,暗色 `#9eb1ff` */\n accentText: '#3a5bc7',\n /** 品牌色的浅底。indigo 3:亮色 `#edf2fe`,暗色 `#182449` */\n accentSoft: '#edf2fe',\n /** 品牌色的浅底按下。indigo 4:亮色 `#e1e9ff`,暗色 `#1d2e62` */\n accentSoftActive: '#e1e9ff',\n /** 品牌色的边框。indigo 7:亮色 `#abbdf9`,暗色 `#3a4f97` */\n accentBorder: '#abbdf9',\n\n // ───────── 状态色:危险 ─────────\n\n /** 危险:删除、错误。red 9:亮色 `#ce2c31`,暗色 `#b54548` */\n danger: '#ce2c31',\n /** 危险按下。red 10:亮色 `#b8272c`,暗色 `#a33b3e` */\n dangerActive: '#b8272c',\n /** 危险色上的文字。白色 */\n dangerContrast: '#ffffff',\n /** 危险的文字。red 11:亮色 `#b8272c`,暗色 `#ff9592` */\n dangerText: '#b8272c',\n /** 危险的浅底。red 3:亮色 `#feebec`,暗色 `#3b1219` */\n dangerSoft: '#feebec',\n /** 危险的浅底按下。red 4:亮色 `#ffdbdc`,暗色 `#500f1c` */\n dangerSoftActive: '#ffdbdc',\n /** 危险的边框。red 7:亮色 `#f4a9aa`,暗色 `#8c333a` */\n dangerBorder: '#f4a9aa',\n\n // ───────── 状态色:成功 ─────────\n\n /** 成功。green 9:亮色 `#008751`,暗色 `#30a46c` */\n success: '#008751',\n /** 成功按下。亮色 `#007143`,暗色 `#52af7d` */\n successActive: '#007143',\n /** 成功色上的文字。亮色白色,暗色 slate 1 */\n successContrast: '#ffffff',\n /** 成功的文字。green 11:亮色 `#193b2d`,暗色 `#3dd68c` */\n successText: '#193b2d',\n /** 成功的浅底。green 3:亮色 `#e6f6eb`,暗色 `#132d21` */\n successSoft: '#e6f6eb',\n /** 成功的浅底按下。green 4:亮色 `#d6f1df`,暗色 `#113b29` */\n successSoftActive: '#d6f1df',\n /** 成功的边框。green 7:亮色 `#8eceaa`,暗色 `#28684a` */\n successBorder: '#8eceaa',\n\n // ───────── 状态色:警告 ─────────\n\n /** 警告。amber 9 `#ffc53d` */\n warning: '#ffc53d',\n /** 警告按下。amber 10 `#ffcd5f` */\n warningActive: '#ffcd5f',\n /** 警告色上的文字(深色)。亮色 `#4f3422`,暗色 slate 1 */\n warningContrast: '#4f3422',\n /** 警告的文字。amber 11:亮色 `#4f3422`,暗色 `#ffca16` */\n warningText: '#4f3422',\n /** 警告的浅底。amber 3:亮色 `#fff7c2`,暗色 `#302008` */\n warningSoft: '#fff7c2',\n /** 警告的浅底按下。amber 4:亮色 `#ffee9c`,暗色 `#3f2700` */\n warningSoftActive: '#ffee9c',\n /** 警告的边框。amber 7:亮色 `#e9c162`,暗色 `#714f19` */\n warningBorder: '#e9c162',\n\n // ───────── 状态色:信息 ─────────\n\n /** 信息。blue 9:亮色 `#0073e0`,暗色 `#0090ff` */\n info: '#0073e0',\n /** 信息按下。亮色 `#0060bd`,暗色 `#3d9fff` */\n infoActive: '#0060bd',\n /** 信息色上的文字。亮色白色,暗色 slate 1 */\n infoContrast: '#ffffff',\n /** 信息的文字。blue 11:亮色 `#113264`,暗色 `#70b8ff` */\n infoText: '#113264',\n /** 信息的浅底。blue 3:亮色 `#e6f4fe`,暗色 `#0d2847` */\n infoSoft: '#e6f4fe',\n /** 信息的浅底按下。blue 4:亮色 `#d5efff`,暗色 `#003362` */\n infoSoftActive: '#d5efff',\n /** 信息的边框。blue 7:亮色 `#8ec8f6`,暗色 `#205d9e` */\n infoBorder: '#8ec8f6',\n\n // ───────── 其他 ─────────\n\n /** 反色表面:轻提示(Toast)、气泡。亮色 slate 12 `#1c2024`,暗色 slate 12 `#edeef0` */\n inverseSurface: '#1c2024',\n /** 反色表面上的文字 */\n inverseText: '#fcfcfd',\n /** 遮罩:弹出层、对话框下面的半透明黑。亮色 0.5,暗色 0.7 */\n overlay: 'rgba(0, 0, 0, 0.5)',\n /** 焦点环(H5 的键盘焦点) */\n focusRing: '#3e63dd',\n});\n\n/** 字体族:系统字体优先,数字用等宽数字(组件里 fontVariantNumeric: 'tabular-nums') */\nexport const fonts = css.defineVars('vtm-fonts', {\n /** 正文与标题 */\n sans: 'system-ui, -apple-system, \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Noto Sans SC\", sans-serif',\n /** 代码、验证码这类等宽内容 */\n mono: 'ui-monospace, \"SFMono-Regular\", Menlo, Consolas, monospace',\n});\n\n/** 字号(375 宽的设计稿):组件根元素的字号决定内部尺寸(em) */\nexport const fontSizes = css.defineVars('vtm-font-sizes', {\n /** 辅助说明、标签、角标 `12px` */\n xs: '12px',\n /** 次要正文、小按钮 `13px` */\n sm: '13px',\n /** 正文、单元格 `14px` */\n md: '14px',\n /** 按钮、导航栏标题、强调正文 `16px` */\n lg: '16px',\n /** 弹窗标题 `18px` */\n xl: '18px',\n /** 页面标题 `20px` */\n xxl: '20px',\n /** 数值、结果页标题 `24px` */\n xxxl: '24px',\n});\n\n/** 字重 */\nexport const fontWeights = css.defineVars('vtm-font-weights', {\n /** 常规 `400` */\n normal: '400',\n /** 中等:按钮、标签页 `500` */\n medium: '500',\n /** 半粗:标题 `600` */\n semibold: '600',\n /** 粗:数值 `700` */\n bold: '700',\n});\n\n/** 行高(不带单位) */\nexport const lineHeights = css.defineVars('vtm-line-heights', {\n /** 单行控件 `1` */\n none: '1',\n /** 标题 `1.25` */\n tight: '1.25',\n /** 正文 `1.5` */\n normal: '1.5',\n /** 长段落 `1.75` */\n relaxed: '1.75',\n});\n\n/** 字距 */\nexport const letterSpacings = css.defineVars('vtm-letter-spacings', {\n /** 默认 `0` */\n normal: '0',\n /** 大号数字、标题略收 `-0.01em` */\n tight: '-0.01em',\n /** 全大写的小字略放 `0.02em` */\n wide: '0.02em',\n});\n\n/** 间距(em,随字号缩放) */\nexport const space = css.defineVars('vtm-space', {\n /** 没有间距 `0` */\n none: '0',\n /** 极小:图标与文字之间 `0.25em` */\n xs: '0.25em',\n /** 小:紧凑的内边距 `0.5em` */\n sm: '0.5em',\n /** 中:常用的间隔 `0.75em` */\n md: '0.75em',\n /** 大:单元格的左右内边距 `1em` */\n lg: '1em',\n /** 很大:分组之间 `1.5em` */\n xl: '1.5em',\n /** 特大:页面区块之间 `2em` */\n xxl: '2em',\n});\n\n/** 尺寸 */\nexport const sizes = css.defineVars('vtm-sizes', {\n /** 单行控件(输入框、单元格)的最小高度 `2.75em`(14px 字号时 38.5px,16px 时 44px) */\n control: '2.75em',\n /** 触控目标的最小尺寸 `44px`(iOS 人机界面指南) */\n touchTarget: '44px',\n /** 占满容器 `100%` */\n full: '100%',\n});\n\n/** 圆角(em) */\nexport const radii = css.defineVars('vtm-radii', {\n /** 直角 `0` */\n none: '0',\n /** 极小:角标、复选框 `0.125em` */\n xs: '0.125em',\n /** 小:标签、小按钮 `0.25em` */\n sm: '0.25em',\n /** 中:按钮、输入框 `0.5em` */\n md: '0.5em',\n /** 大:卡片、分组 `0.75em` */\n lg: '0.75em',\n /** 很大:弹出层、对话框 `1em` */\n xl: '1em',\n /** 全圆:胶囊按钮、头像 `9999px` */\n full: '9999px',\n});\n\n/** 边框宽度(px) */\nexport const borderWidths = css.defineVars('vtm-border-widths', {\n /** 没有边框 `0` */\n none: '0',\n /** 细线:单元格分隔线(高分屏上的半像素) `0.5px` */\n hairline: '0.5px',\n /** 常规边框 `1px` */\n xs: '1px',\n /** 焦点环、选中描边 `2px` */\n sm: '2px',\n});\n\n/** 阴影:亮色主题用,暗色主题靠表面的层级区分 */\nexport const shadows = css.defineVars('vtm-shadows', {\n /** 没有阴影 */\n none: 'none',\n /** 卡片 */\n sm: '0 1px 2px rgba(0, 0, 0, 0.06), 0 2px 8px -2px rgba(0, 0, 0, 0.08)',\n /** 悬浮按钮、吸顶的栏 */\n md: '0 4px 16px -4px rgba(0, 0, 0, 0.12), 0 2px 6px -2px rgba(0, 0, 0, 0.08)',\n /** 弹出层、对话框 */\n lg: '0 12px 40px -8px rgba(0, 0, 0, 0.2), 0 4px 12px -4px rgba(0, 0, 0, 0.1)',\n});\n\nconst reduce = '@media (prefers-reduced-motion: reduce)';\n\n/** 动效时长;系统开了\"减少动态效果\"时为 0 */\nexport const durations = css.defineVars('vtm-durations', {\n /** 没有过渡 `0ms` */\n none: '0ms',\n /** 按压反馈 `100ms` */\n xs: { default: '100ms', [reduce]: '0ms' },\n /** 颜色、开关 `160ms` */\n sm: { default: '160ms', [reduce]: '0ms' },\n /** 展开收起、提示进出 `240ms` */\n md: { default: '240ms', [reduce]: '0ms' },\n /** 弹出层滑入滑出 `300ms` */\n lg: { default: '300ms', [reduce]: '0ms' },\n});\n\n/** 缓动 */\nexport const easings = css.defineVars('vtm-easings', {\n /** 一般的过渡 */\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n /** 进场:快出慢停 */\n enter: 'cubic-bezier(0.05, 0.7, 0.1, 1)',\n /** 离场:慢起快走 */\n exit: 'cubic-bezier(0.3, 0, 0.8, 0.15)',\n});\n\n/** 不透明度 */\nexport const opacities = css.defineVars('vtm-opacities', {\n /** 不可用 `0.5` */\n disabled: '0.5',\n /** 按下时叠在内容上的暗层(实底按钮) `0.1` */\n pressed: '0.1',\n});\n\n/** SVG 描边宽度(图标) */\nexport const strokeWidths = css.defineVars('vtm-stroke-widths', {\n /** 细 `1.5` */\n sm: '1.5',\n /** 常规 `2` */\n md: '2',\n /** 粗 `2.5` */\n lg: '2.5',\n});\n\n/** 各组 token 的变量引用,用在模板字符串里:`` `max(${t.sizes.control}, ${t.sizes.touchTarget})` `` */\nexport const t = css.defineTokens({\n colors,\n fonts,\n fontSizes,\n fontWeights,\n lineHeights,\n letterSpacings,\n space,\n sizes,\n radii,\n borderWidths,\n shadows,\n durations,\n easings,\n opacities,\n strokeWidths,\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 宿主约定(MOBILE.md §5):组件要用的平台能力都从这里取,不直接碰 DOM 与 window——
|
|
3
|
+
* H5 用这里的 Web 实现;小程序由渲染运行时(@zerodep-dev/vue-tsx-pro-mini)在每个页面的应用上 provide 自己的实现。
|
|
4
|
+
* 两边约定同一个全局 Symbol,互不导入。
|
|
5
|
+
*
|
|
6
|
+
* const host = useHost();
|
|
7
|
+
* const rect = await host.measure(element);
|
|
8
|
+
* const unlock = host.lockScroll();
|
|
9
|
+
*/
|
|
10
|
+
import { type InjectionKey } from 'vue';
|
|
11
|
+
import type { HostPermissions, HostStorage, LoginOptions, LoginResult, PaymentOrder, PaymentResult, PhoneNumberResult, PrivacyReply, SubscribeState } from '../capability/types';
|
|
12
|
+
/** 元素的位置与大小(视口坐标,px) */
|
|
13
|
+
export interface HostRect {
|
|
14
|
+
top: number;
|
|
15
|
+
left: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}
|
|
19
|
+
/** 窗口信息 */
|
|
20
|
+
export interface HostWindow {
|
|
21
|
+
/** 可用宽度(px) */
|
|
22
|
+
width: number;
|
|
23
|
+
/** 可用高度(px) */
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
/** 选到的图片 */
|
|
27
|
+
export interface ChosenImage {
|
|
28
|
+
/** 能直接作为 img src 的地址(H5 是 blob: 地址,小程序是临时文件路径) */
|
|
29
|
+
url: string;
|
|
30
|
+
/** 字节数 */
|
|
31
|
+
size: number;
|
|
32
|
+
/** H5 里的 File,上传时用;小程序里没有 */
|
|
33
|
+
file?: File;
|
|
34
|
+
}
|
|
35
|
+
/** 平台能力 */
|
|
36
|
+
export interface Host {
|
|
37
|
+
/** 平台:web 是浏览器,app 是原生应用里的 WebView(Capacitor,见 capacitor/),wx 是微信小程序,my 是支付宝小程序 */
|
|
38
|
+
readonly platform: 'web' | 'app' | 'wx' | 'my';
|
|
39
|
+
/** 量元素(模板 ref 拿到的节点)的位置大小;量不到时 null。小程序里只能异步取 */
|
|
40
|
+
measure(element: unknown): Promise<HostRect | null>;
|
|
41
|
+
/** 窗口的宽高 */
|
|
42
|
+
window(): HostWindow;
|
|
43
|
+
/** 页面滚动到某个位置 */
|
|
44
|
+
scrollTo(top: number, options?: {
|
|
45
|
+
smooth?: boolean;
|
|
46
|
+
}): void;
|
|
47
|
+
/** 页面当前的滚动位置(px) */
|
|
48
|
+
scrollTop(): number;
|
|
49
|
+
/** 监听页面滚动,返回取消函数 */
|
|
50
|
+
onScroll(listener: (top: number) => void): () => void;
|
|
51
|
+
/**
|
|
52
|
+
* 等这一轮的改动画到屏幕上再回调,返回取消函数。进场动画要先画出关闭的样子,再换成打开的样子,过渡才会播。
|
|
53
|
+
* H5 是两次 requestAnimationFrame;小程序是这一轮 setData 生效之后(逻辑层没有屏幕刷新的回调)
|
|
54
|
+
*/
|
|
55
|
+
nextFrame(callback: () => void): () => void;
|
|
56
|
+
/** 锁住页面滚动(弹出层打开时),返回解锁函数;可叠加,最后一个解锁时恢复 */
|
|
57
|
+
lockScroll(): () => void;
|
|
58
|
+
/** 浮层根:弹出层、轻提示 Teleport 到这里 */
|
|
59
|
+
overlayRoot(): unknown;
|
|
60
|
+
/** 短震动反馈;不支持时什么也不做 */
|
|
61
|
+
vibrate(): void;
|
|
62
|
+
/** 写剪贴板 */
|
|
63
|
+
copy(text: string): Promise<void>;
|
|
64
|
+
/** 选图片 */
|
|
65
|
+
chooseImages(options: {
|
|
66
|
+
count: number;
|
|
67
|
+
}): Promise<ChosenImage[]>;
|
|
68
|
+
/** 设备权限:位置、相机、麦克风、相册、蓝牙(组件里用 usePermission) */
|
|
69
|
+
readonly permissions: HostPermissions;
|
|
70
|
+
/** 本地存储(组件里用 useStorage) */
|
|
71
|
+
readonly storage: HostStorage;
|
|
72
|
+
/** 登录凭证,交给后端换会话;H5 没有平台登录,由应用经 ConfigProvider 的 host 给出实现 */
|
|
73
|
+
login(options?: LoginOptions): Promise<LoginResult>;
|
|
74
|
+
/** 调起收银台;参数是后端下单的结果 */
|
|
75
|
+
pay(order: PaymentOrder): Promise<PaymentResult>;
|
|
76
|
+
/** 订阅消息:一次最多 3 个模板,要在用户点按的回调里调用 */
|
|
77
|
+
subscribe(templateIds: string[]): Promise<Record<string, SubscribeState>>;
|
|
78
|
+
/** 手机号按钮(Button 的 openType)的结果换成交给后端的凭证 */
|
|
79
|
+
phoneNumber(detail: unknown): Promise<PhoneNumberResult>;
|
|
80
|
+
/** 平台要求用户先同意隐私协议时通知(只有微信),返回取消函数;回复后平台才继续执行被拦下的接口 */
|
|
81
|
+
onPrivacyRequest(listener: (reply: PrivacyReply) => void): () => void;
|
|
82
|
+
/** 打开小程序的隐私协议页 */
|
|
83
|
+
openPrivacyContract(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* 页面的主题变了(最外层 ConfigProvider 通知):原生应用里状态栏的文字颜色跟着换。
|
|
86
|
+
* H5 与小程序不用做什么(小程序的导航栏颜色写在 app.json),可以不实现
|
|
87
|
+
*/
|
|
88
|
+
themeChanged?(theme: 'light' | 'dark' | 'system'): void;
|
|
89
|
+
}
|
|
90
|
+
/** 注入键:全局 Symbol,小程序运行时用同一个键 provide,不必导入这个模块 */
|
|
91
|
+
export declare const HOST_KEY: InjectionKey<Host>;
|
|
92
|
+
/** 浏览器里的实现 */
|
|
93
|
+
export declare const webHost: Host;
|
|
94
|
+
/** 小程序(没有 DOM,节点画在模板里);H5 与原生应用的 WebView 都是浏览器环境 */
|
|
95
|
+
export declare const isMiniProgram: (host: Host) => boolean;
|
|
96
|
+
/** 当前应用的平台能力:小程序页面里是运行时 provide 的,其余是浏览器的实现 */
|
|
97
|
+
export declare function useHost(): Host;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { webCapabilities } from "../capability/web.js";
|
|
2
|
+
import { inject } from "vue";
|
|
3
|
+
//#region src/utils/host.ts
|
|
4
|
+
/**
|
|
5
|
+
* 宿主约定(MOBILE.md §5):组件要用的平台能力都从这里取,不直接碰 DOM 与 window——
|
|
6
|
+
* H5 用这里的 Web 实现;小程序由渲染运行时(@zerodep-dev/vue-tsx-pro-mini)在每个页面的应用上 provide 自己的实现。
|
|
7
|
+
* 两边约定同一个全局 Symbol,互不导入。
|
|
8
|
+
*
|
|
9
|
+
* const host = useHost();
|
|
10
|
+
* const rect = await host.measure(element);
|
|
11
|
+
* const unlock = host.lockScroll();
|
|
12
|
+
*/
|
|
13
|
+
/** 注入键:全局 Symbol,小程序运行时用同一个键 provide,不必导入这个模块 */
|
|
14
|
+
var HOST_KEY = Symbol.for("vue-tsx-pro.host");
|
|
15
|
+
var locks = 0;
|
|
16
|
+
var restoreOverflow = "";
|
|
17
|
+
/** 浏览器里的实现 */
|
|
18
|
+
var webHost = {
|
|
19
|
+
platform: "web",
|
|
20
|
+
async measure(element) {
|
|
21
|
+
if (!(element instanceof Element)) return null;
|
|
22
|
+
const { top, left, width, height } = element.getBoundingClientRect();
|
|
23
|
+
return {
|
|
24
|
+
top,
|
|
25
|
+
left,
|
|
26
|
+
width,
|
|
27
|
+
height
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
window: () => ({
|
|
31
|
+
width: window.innerWidth,
|
|
32
|
+
height: window.innerHeight
|
|
33
|
+
}),
|
|
34
|
+
scrollTo(top, options) {
|
|
35
|
+
window.scrollTo({
|
|
36
|
+
top,
|
|
37
|
+
behavior: options?.smooth ? "smooth" : "auto"
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
scrollTop: () => window.scrollY,
|
|
41
|
+
onScroll(listener) {
|
|
42
|
+
const handle = () => listener(window.scrollY);
|
|
43
|
+
window.addEventListener("scroll", handle, { passive: true });
|
|
44
|
+
return () => window.removeEventListener("scroll", handle);
|
|
45
|
+
},
|
|
46
|
+
nextFrame(callback) {
|
|
47
|
+
let inner = 0;
|
|
48
|
+
const outer = requestAnimationFrame(() => inner = requestAnimationFrame(callback));
|
|
49
|
+
return () => {
|
|
50
|
+
cancelAnimationFrame(outer);
|
|
51
|
+
cancelAnimationFrame(inner);
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
lockScroll() {
|
|
55
|
+
if (locks++ === 0) {
|
|
56
|
+
restoreOverflow = document.body.style.overflow;
|
|
57
|
+
document.body.style.overflow = "hidden";
|
|
58
|
+
}
|
|
59
|
+
let released = false;
|
|
60
|
+
return () => {
|
|
61
|
+
if (released) return;
|
|
62
|
+
released = true;
|
|
63
|
+
if (--locks === 0) document.body.style.overflow = restoreOverflow;
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
overlayRoot: () => document.body,
|
|
67
|
+
vibrate() {
|
|
68
|
+
navigator.vibrate?.(10);
|
|
69
|
+
},
|
|
70
|
+
copy: (text) => navigator.clipboard.writeText(text),
|
|
71
|
+
chooseImages({ count }) {
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
const input = document.createElement("input");
|
|
74
|
+
input.type = "file";
|
|
75
|
+
input.accept = "image/*";
|
|
76
|
+
input.multiple = count > 1;
|
|
77
|
+
input.onchange = () => {
|
|
78
|
+
resolve([...input.files ?? []].slice(0, count).map((file) => ({
|
|
79
|
+
url: URL.createObjectURL(file),
|
|
80
|
+
size: file.size,
|
|
81
|
+
file
|
|
82
|
+
})));
|
|
83
|
+
};
|
|
84
|
+
input.click();
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
...webCapabilities
|
|
88
|
+
};
|
|
89
|
+
/** 小程序(没有 DOM,节点画在模板里);H5 与原生应用的 WebView 都是浏览器环境 */
|
|
90
|
+
var isMiniProgram = (host) => host.platform === "wx" || host.platform === "my";
|
|
91
|
+
/** 当前应用的平台能力:小程序页面里是运行时 provide 的,其余是浏览器的实现 */
|
|
92
|
+
function useHost() {
|
|
93
|
+
return inject(HOST_KEY, webHost);
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
export { HOST_KEY, isMiniProgram, useHost, webHost };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","names":[],"sources":["../../src/utils/host.ts"],"sourcesContent":["/**\n * 宿主约定(MOBILE.md §5):组件要用的平台能力都从这里取,不直接碰 DOM 与 window——\n * H5 用这里的 Web 实现;小程序由渲染运行时(@zerodep-dev/vue-tsx-pro-mini)在每个页面的应用上 provide 自己的实现。\n * 两边约定同一个全局 Symbol,互不导入。\n *\n * const host = useHost();\n * const rect = await host.measure(element);\n * const unlock = host.lockScroll();\n */\nimport { inject, type InjectionKey } from 'vue';\nimport type {\n HostPermissions,\n HostStorage,\n LoginOptions,\n LoginResult,\n PaymentOrder,\n PaymentResult,\n PhoneNumberResult,\n PrivacyReply,\n SubscribeState,\n} from '../capability/types';\nimport { webCapabilities } from '../capability/web';\n\n/** 元素的位置与大小(视口坐标,px) */\nexport interface HostRect {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\n/** 窗口信息 */\nexport interface HostWindow {\n /** 可用宽度(px) */\n width: number;\n /** 可用高度(px) */\n height: number;\n}\n\n/** 选到的图片 */\nexport interface ChosenImage {\n /** 能直接作为 img src 的地址(H5 是 blob: 地址,小程序是临时文件路径) */\n url: string;\n /** 字节数 */\n size: number;\n /** H5 里的 File,上传时用;小程序里没有 */\n file?: File;\n}\n\n/** 平台能力 */\nexport interface Host {\n /** 平台:web 是浏览器,app 是原生应用里的 WebView(Capacitor,见 capacitor/),wx 是微信小程序,my 是支付宝小程序 */\n readonly platform: 'web' | 'app' | 'wx' | 'my';\n /** 量元素(模板 ref 拿到的节点)的位置大小;量不到时 null。小程序里只能异步取 */\n measure(element: unknown): Promise<HostRect | null>;\n /** 窗口的宽高 */\n window(): HostWindow;\n /** 页面滚动到某个位置 */\n scrollTo(top: number, options?: { smooth?: boolean }): void;\n /** 页面当前的滚动位置(px) */\n scrollTop(): number;\n /** 监听页面滚动,返回取消函数 */\n onScroll(listener: (top: number) => void): () => void;\n /**\n * 等这一轮的改动画到屏幕上再回调,返回取消函数。进场动画要先画出关闭的样子,再换成打开的样子,过渡才会播。\n * H5 是两次 requestAnimationFrame;小程序是这一轮 setData 生效之后(逻辑层没有屏幕刷新的回调)\n */\n nextFrame(callback: () => void): () => void;\n /** 锁住页面滚动(弹出层打开时),返回解锁函数;可叠加,最后一个解锁时恢复 */\n lockScroll(): () => void;\n /** 浮层根:弹出层、轻提示 Teleport 到这里 */\n overlayRoot(): unknown;\n /** 短震动反馈;不支持时什么也不做 */\n vibrate(): void;\n /** 写剪贴板 */\n copy(text: string): Promise<void>;\n /** 选图片 */\n chooseImages(options: { count: number }): Promise<ChosenImage[]>;\n /** 设备权限:位置、相机、麦克风、相册、蓝牙(组件里用 usePermission) */\n readonly permissions: HostPermissions;\n /** 本地存储(组件里用 useStorage) */\n readonly storage: HostStorage;\n /** 登录凭证,交给后端换会话;H5 没有平台登录,由应用经 ConfigProvider 的 host 给出实现 */\n login(options?: LoginOptions): Promise<LoginResult>;\n /** 调起收银台;参数是后端下单的结果 */\n pay(order: PaymentOrder): Promise<PaymentResult>;\n /** 订阅消息:一次最多 3 个模板,要在用户点按的回调里调用 */\n subscribe(templateIds: string[]): Promise<Record<string, SubscribeState>>;\n /** 手机号按钮(Button 的 openType)的结果换成交给后端的凭证 */\n phoneNumber(detail: unknown): Promise<PhoneNumberResult>;\n /** 平台要求用户先同意隐私协议时通知(只有微信),返回取消函数;回复后平台才继续执行被拦下的接口 */\n onPrivacyRequest(listener: (reply: PrivacyReply) => void): () => void;\n /** 打开小程序的隐私协议页 */\n openPrivacyContract(): Promise<void>;\n /**\n * 页面的主题变了(最外层 ConfigProvider 通知):原生应用里状态栏的文字颜色跟着换。\n * H5 与小程序不用做什么(小程序的导航栏颜色写在 app.json),可以不实现\n */\n themeChanged?(theme: 'light' | 'dark' | 'system'): void;\n}\n\n/** 注入键:全局 Symbol,小程序运行时用同一个键 provide,不必导入这个模块 */\nexport const HOST_KEY: InjectionKey<Host> = Symbol.for('vue-tsx-pro.host') as InjectionKey<Host>;\n\nlet locks = 0;\nlet restoreOverflow = '';\n\n/** 浏览器里的实现 */\nexport const webHost: Host = {\n platform: 'web',\n async measure(element) {\n if (!(element instanceof Element)) return null;\n const { top, left, width, height } = element.getBoundingClientRect();\n return { top, left, width, height };\n },\n window: () => ({ width: window.innerWidth, height: window.innerHeight }),\n scrollTo(top, options) {\n window.scrollTo({ top, behavior: options?.smooth ? 'smooth' : 'auto' });\n },\n scrollTop: () => window.scrollY,\n onScroll(listener) {\n const handle = () => listener(window.scrollY);\n window.addEventListener('scroll', handle, { passive: true });\n return () => window.removeEventListener('scroll', handle);\n },\n nextFrame(callback) {\n // 第一次在绘制前,第二次时上一帧已经画好\n let inner = 0;\n const outer = requestAnimationFrame(() => (inner = requestAnimationFrame(callback)));\n return () => {\n cancelAnimationFrame(outer);\n cancelAnimationFrame(inner);\n };\n },\n lockScroll() {\n if (locks++ === 0) {\n restoreOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n let released = false;\n return () => {\n if (released) return;\n released = true;\n if (--locks === 0) document.body.style.overflow = restoreOverflow;\n };\n },\n overlayRoot: () => document.body,\n vibrate() {\n navigator.vibrate?.(10);\n },\n copy: (text) => navigator.clipboard.writeText(text),\n chooseImages({ count }) {\n return new Promise((resolve) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = 'image/*';\n input.multiple = count > 1;\n input.onchange = () => {\n const files = [...(input.files ?? [])].slice(0, count);\n resolve(files.map((file) => ({ url: URL.createObjectURL(file), size: file.size, file })));\n };\n input.click();\n });\n },\n ...webCapabilities,\n};\n\n/** 小程序(没有 DOM,节点画在模板里);H5 与原生应用的 WebView 都是浏览器环境 */\nexport const isMiniProgram = (host: Host): boolean =>\n host.platform === 'wx' || host.platform === 'my';\n\n/** 当前应用的平台能力:小程序页面里是运行时 provide 的,其余是浏览器的实现 */\nexport function useHost(): Host {\n return inject(HOST_KEY, webHost);\n}\n"],"mappings":";;;;;;;;;;;;;AAsGA,IAAa,WAA+B,OAAO,IAAI,kBAAkB;AAEzE,IAAI,QAAQ;AACZ,IAAI,kBAAkB;;AAGtB,IAAa,UAAgB;CAC3B,UAAU;CACV,MAAM,QAAQ,SAAS;EACrB,IAAI,EAAE,mBAAmB,UAAU,OAAO;EAC1C,MAAM,EAAE,KAAK,MAAM,OAAO,WAAW,QAAQ,sBAAsB;EACnE,OAAO;GAAE;GAAK;GAAM;GAAO;EAAO;CACpC;CACA,eAAe;EAAE,OAAO,OAAO;EAAY,QAAQ,OAAO;CAAY;CACtE,SAAS,KAAK,SAAS;EACrB,OAAO,SAAS;GAAE;GAAK,UAAU,SAAS,SAAS,WAAW;EAAO,CAAC;CACxE;CACA,iBAAiB,OAAO;CACxB,SAAS,UAAU;EACjB,MAAM,eAAe,SAAS,OAAO,OAAO;EAC5C,OAAO,iBAAiB,UAAU,QAAQ,EAAE,SAAS,KAAK,CAAC;EAC3D,aAAa,OAAO,oBAAoB,UAAU,MAAM;CAC1D;CACA,UAAU,UAAU;EAElB,IAAI,QAAQ;EACZ,MAAM,QAAQ,4BAA6B,QAAQ,sBAAsB,QAAQ,CAAE;EACnF,aAAa;GACX,qBAAqB,KAAK;GAC1B,qBAAqB,KAAK;EAC5B;CACF;CACA,aAAa;EACX,IAAI,YAAY,GAAG;GACjB,kBAAkB,SAAS,KAAK,MAAM;GACtC,SAAS,KAAK,MAAM,WAAW;EACjC;EACA,IAAI,WAAW;EACf,aAAa;GACX,IAAI,UAAU;GACd,WAAW;GACX,IAAI,EAAE,UAAU,GAAG,SAAS,KAAK,MAAM,WAAW;EACpD;CACF;CACA,mBAAmB,SAAS;CAC5B,UAAU;EACR,UAAU,UAAU,EAAE;CACxB;CACA,OAAO,SAAS,UAAU,UAAU,UAAU,IAAI;CAClD,aAAa,EAAE,SAAS;EACtB,OAAO,IAAI,SAAS,YAAY;GAC9B,MAAM,QAAQ,SAAS,cAAc,OAAO;GAC5C,MAAM,OAAO;GACb,MAAM,SAAS;GACf,MAAM,WAAW,QAAQ;GACzB,MAAM,iBAAiB;IAErB,QADc,CAAC,GAAI,MAAM,SAAS,CAAC,CAAE,CAAC,CAAC,MAAM,GAAG,KACxC,CAAA,CAAM,KAAK,UAAU;KAAE,KAAK,IAAI,gBAAgB,IAAI;KAAG,MAAM,KAAK;KAAM;IAAK,EAAE,CAAC;GAC1F;GACA,MAAM,MAAM;EACd,CAAC;CACH;CACA,GAAG;AACL;;AAGA,IAAa,iBAAiB,SAC5B,KAAK,aAAa,QAAQ,KAAK,aAAa;;AAG9C,SAAgB,UAAgB;CAC9B,OAAO,OAAO,UAAU,OAAO;AACjC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** 弹层的过渡时长(ms),与 token 的 durations.lg 一致 */
|
|
2
|
+
export declare const OVERLAY_DURATION = 300;
|
|
3
|
+
/** 进出场的状态 */
|
|
4
|
+
export interface Presence {
|
|
5
|
+
/** 要不要渲染:关闭后等过渡播完才变成 false */
|
|
6
|
+
readonly mounted: boolean;
|
|
7
|
+
/** 是不是打开的样子:挂上并画出来之后才变成 true */
|
|
8
|
+
readonly visible: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** 跟着 open 安排挂载与显示;duration 是离场过渡的时长(ms) */
|
|
11
|
+
export declare function usePresence(open: () => boolean, duration?: number): Presence;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useHost } from "./host.js";
|
|
2
|
+
import { onBeforeUnmount, shallowRef, watch } from "vue";
|
|
3
|
+
/** 跟着 open 安排挂载与显示;duration 是离场过渡的时长(ms) */
|
|
4
|
+
function usePresence(open, duration = 300) {
|
|
5
|
+
const host = useHost();
|
|
6
|
+
const mounted = shallowRef(false);
|
|
7
|
+
const visible = shallowRef(false);
|
|
8
|
+
let cancel = () => {};
|
|
9
|
+
const update = (next) => {
|
|
10
|
+
cancel();
|
|
11
|
+
if (next) {
|
|
12
|
+
mounted.value = true;
|
|
13
|
+
cancel = host.nextFrame(() => visible.value = true);
|
|
14
|
+
} else {
|
|
15
|
+
visible.value = false;
|
|
16
|
+
const timer = setTimeout(() => mounted.value = false, duration);
|
|
17
|
+
cancel = () => clearTimeout(timer);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
watch(open, update, { immediate: true });
|
|
21
|
+
onBeforeUnmount(() => cancel());
|
|
22
|
+
return {
|
|
23
|
+
get mounted() {
|
|
24
|
+
return mounted.value;
|
|
25
|
+
},
|
|
26
|
+
get visible() {
|
|
27
|
+
return visible.value;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { usePresence };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=presence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presence.js","names":[],"sources":["../../src/utils/presence.ts"],"sourcesContent":["/**\n * 进出场:弹层先以关闭的样子挂上,等它画到屏幕上(宿主的 nextFrame)再换成打开的样子,样式里的过渡(transition)就会播;\n * 关闭时先换回关闭的样子,等过渡播完再卸载。不用 Vue 的 <Transition>:它在运行时 DOM 里,小程序的渲染器用不了。\n *\n * const presence = usePresence(() => open, DURATION);\n * return () => presence.mounted && <div data-state={presence.visible ? 'open' : 'closed'} …/>;\n */\nimport { onBeforeUnmount, shallowRef, watch } from 'vue';\nimport { useHost } from './host';\n\n/** 弹层的过渡时长(ms),与 token 的 durations.lg 一致 */\nexport const OVERLAY_DURATION = 300;\n\n/** 进出场的状态 */\nexport interface Presence {\n /** 要不要渲染:关闭后等过渡播完才变成 false */\n readonly mounted: boolean;\n /** 是不是打开的样子:挂上并画出来之后才变成 true */\n readonly visible: boolean;\n}\n\n/** 跟着 open 安排挂载与显示;duration 是离场过渡的时长(ms) */\nexport function usePresence(open: () => boolean, duration = OVERLAY_DURATION): Presence {\n const host = useHost();\n const mounted = shallowRef(false);\n const visible = shallowRef(false);\n let cancel = () => {};\n const update = (next: boolean) => {\n cancel();\n if (next) {\n mounted.value = true;\n cancel = host.nextFrame(() => (visible.value = true));\n } else {\n visible.value = false;\n const timer = setTimeout(() => (mounted.value = false), duration);\n cancel = () => clearTimeout(timer);\n }\n };\n watch(open, update, { immediate: true });\n onBeforeUnmount(() => cancel());\n return {\n get mounted() {\n return mounted.value;\n },\n get visible() {\n return visible.value;\n },\n };\n}\n"],"mappings":";;;AAsBA,SAAgB,YAAY,MAAqB,WAAA,KAAuC;CACtF,MAAM,OAAO,QAAQ;CACrB,MAAM,UAAU,WAAW,KAAK;CAChC,MAAM,UAAU,WAAW,KAAK;CAChC,IAAI,eAAe,CAAC;CACpB,MAAM,UAAU,SAAkB;EAChC,OAAO;EACP,IAAI,MAAM;GACR,QAAQ,QAAQ;GAChB,SAAS,KAAK,gBAAiB,QAAQ,QAAQ,IAAK;EACtD,OAAO;GACL,QAAQ,QAAQ;GAChB,MAAM,QAAQ,iBAAkB,QAAQ,QAAQ,OAAQ,QAAQ;GAChE,eAAe,aAAa,KAAK;EACnC;CACF;CACA,MAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;CACvC,sBAAsB,OAAO,CAAC;CAC9B,OAAO;EACL,IAAI,UAAU;GACZ,OAAO,QAAQ;EACjB;EACA,IAAI,UAAU;GACZ,OAAO,QAAQ;EACjB;CACF;AACF"}
|