uview-ultra 4.5.48 → 4.5.71

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.
Files changed (40) hide show
  1. package/changelog.md +1650 -1435
  2. package/components/up-button/up-button.uvue +9 -8
  3. package/components/up-button/up-button.vue +4 -4
  4. package/components/up-cell/props.js +6 -0
  5. package/components/up-cell/up-cell.uvue +21 -8
  6. package/components/up-cell/up-cell.vue +9 -2
  7. package/components/up-cell-group/up-cell-group.uvue +7 -0
  8. package/components/up-checkbox/up-checkbox.uvue +4 -3
  9. package/components/up-empty/up-empty.uvue +4 -0
  10. package/components/up-empty/up-empty.vue +3 -0
  11. package/components/up-goods-sku/up-goods-sku.uvue +32 -3
  12. package/components/up-goods-sku/up-goods-sku.vue +19 -3
  13. package/components/up-icon/icons.uts +1 -1
  14. package/components/up-navbar/navbar.uts +2 -0
  15. package/components/up-navbar/up-navbar.uvue +199 -28
  16. package/components/up-navbar/up-navbar.vue +14 -1
  17. package/components/up-popup/props.js +10 -0
  18. package/components/up-popup/up-popup.uvue +89 -1
  19. package/components/up-popup/up-popup.vue +69 -1
  20. package/components/up-radio/up-radio.uvue +6 -4
  21. package/components/up-radio-group/radioGroup.js +1 -1
  22. package/components/up-radio-group/radioGroup.uts +1 -1
  23. package/components/up-root/props.js +28 -0
  24. package/components/up-root/props.uts +28 -0
  25. package/components/up-root/root.js +14 -0
  26. package/components/up-root/root.uts +14 -0
  27. package/components/up-root/up-root.uvue +57 -0
  28. package/components/up-root/up-root.vue +35 -0
  29. package/components/up-root-toast-host/up-root-toast-host.uvue +27 -0
  30. package/components/up-switch/switch.uts +2 -1
  31. package/components/up-tag/up-tag.uvue +1 -1
  32. package/components/up-tag/up-tag.vue +1 -1
  33. package/components/up-transition/up-transition.uvue +10 -0
  34. package/components/up-transition/up-transition.vue +7 -0
  35. package/components/up-transition/vue.ani-style.scss +39 -10
  36. package/index.uts +47 -0
  37. package/libs/root/rootState.uts +74 -0
  38. package/libs/theme/theme.js +12 -2
  39. package/libs/theme/theme.uts +578 -0
  40. package/package.json +1 -1
@@ -0,0 +1,28 @@
1
+ /*
2
+ * @Author : jry
3
+ * @Description : uview-ultra up-root component's props mixin file(uni-app Vue3 侧)
4
+ * @version : 4.0
5
+ */
6
+ import { defineMixin } from '../../libs/vue.js'
7
+ import defProps from './root.js'
8
+ let root = defProps['root']
9
+
10
+ export const propsRoot = defineMixin({
11
+ props: {
12
+ // 是否为根节点附加页面底色(--up-page-bg-color)
13
+ background: {
14
+ type: Boolean,
15
+ default: root['background']
16
+ },
17
+ // 是否内嵌全局 toast/notify 宿主
18
+ toastHost: {
19
+ type: Boolean,
20
+ default: root['toastHost']
21
+ },
22
+ // 自定义根节点样式(与主题变量合并,优先级更高)
23
+ customStyle: {
24
+ type: Object,
25
+ default: () => root['customStyle']
26
+ }
27
+ }
28
+ })
@@ -0,0 +1,28 @@
1
+ /*
2
+ * @Author : jry
3
+ * @Description : uview-ultra up-root component's props mixin file
4
+ * @version : 4.0
5
+ */
6
+ import { defineMixin } from '../../libs/vue.uts'
7
+ import defProps from './root.uts'
8
+ let root = defProps['root'] as UTSJSONObject
9
+
10
+ export const propsRoot = defineMixin({
11
+ props: {
12
+ // 是否为根节点附加页面底色(--up-page-bg-color)
13
+ background: {
14
+ type: Boolean,
15
+ default: root['background']
16
+ },
17
+ // 是否内嵌全局 toast/notify 宿主
18
+ toastHost: {
19
+ type: Boolean,
20
+ default: root['toastHost']
21
+ },
22
+ // 自定义根节点样式(与主题变量合并,优先级更高)
23
+ customStyle: {
24
+ type: Object,
25
+ default: () => root['customStyle']
26
+ }
27
+ }
28
+ })
@@ -0,0 +1,14 @@
1
+ /*
2
+ * @Author : jry
3
+ * @Description : up-root 组件默认值(uni-app Vue3 侧,与 root.uts 保持一致)
4
+ */
5
+ export default {
6
+ // root组件
7
+ root: {
8
+ // 是否为根节点附加页面底色(--up-page-bg-color)
9
+ background: true,
10
+ // 是否内嵌全局 toast/notify 宿主
11
+ toastHost: true,
12
+ customStyle: {}
13
+ }
14
+ } as UTSJSONObject
@@ -0,0 +1,14 @@
1
+ /*
2
+ * @Author : jry
3
+ * @Description : up-root 组件默认值
4
+ */
5
+ export default {
6
+ // root组件
7
+ root: {
8
+ // 是否为根节点附加页面底色(--up-page-bg-color)
9
+ background: true,
10
+ // 是否内嵌全局 toast/notify 宿主
11
+ toastHost: true,
12
+ customStyle: {}
13
+ }
14
+ } as UTSJSONObject
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <view class="up-root" :style="rootStyle">
3
+ <slot></slot>
4
+ <up-root-toast-host v-if="toastHost"></up-root-toast-host>
5
+ </view>
6
+ </template>
7
+
8
+ <script setup lang="uts">
9
+ /**
10
+ * up-root 页面级根组件(uni-app x 蒸汽模式)。
11
+ *
12
+ * uni-app x 的 App.uvue 不允许 template,无法像老工程那样在应用根注入
13
+ * 主题变量 —— 用 up-root 作为每个页面的根容器:把运行时主题系统的
14
+ * CSS 变量表(--up-* / --u-*)绑定到根节点 style,页面与子组件
15
+ * (styleIsolation: 'app-and-page')即可通过 var(--up-*) 消费,
16
+ * 切换暗黑时整页自动刷新。
17
+ */
18
+ defineOptions({
19
+ name: 'up-root',
20
+ styleIsolation: 'app-and-page'
21
+ })
22
+
23
+ import { computed } from 'vue'
24
+ import { propsRoot } from './props.uts'
25
+ import { upThemeVarsStyle, upThemeVar } from '../../libs/theme/theme.uts'
26
+
27
+ const props = defineProps(propsRoot)
28
+
29
+ const rootStyle = computed((): UTSJSONObject => {
30
+ const style = {} as UTSJSONObject
31
+ const vars = upThemeVarsStyle()
32
+ UTSJSONObject.keys(vars).forEach((key: string) => {
33
+ const value = vars[key]
34
+ if (typeof value === 'string') {
35
+ style[key] = value
36
+ }
37
+ })
38
+ if (props.background) {
39
+ style['backgroundColor'] = upThemeVar('--up-page-bg-color', '#f3f4f6')
40
+ style['color'] = upThemeVar('--up-main-color', '#303133')
41
+ }
42
+ const customStyle = props.customStyle
43
+ if (customStyle instanceof UTSJSONObject) {
44
+ const custom = customStyle as UTSJSONObject
45
+ UTSJSONObject.keys(custom).forEach((key: string) => {
46
+ style[key] = custom[key]
47
+ })
48
+ }
49
+ return style
50
+ })
51
+ </script>
52
+
53
+ <style>
54
+ .up-root {
55
+ flex: 1;
56
+ }
57
+ </style>
@@ -0,0 +1,35 @@
1
+ <template>
2
+ <view class="up-root" :style="[rootVars, backgroundStyle, customStyle]">
3
+ <slot></slot>
4
+ <RootToastHost v-if="toastHost"></RootToastHost>
5
+ </view>
6
+ </template>
7
+
8
+ <script setup>
9
+ /**
10
+ * up-root 页面级根组件(uni-app Vue3 侧)。
11
+ *
12
+ * Vue3 侧的主题变量由 index.js 安装的全局属性 helpers 提供
13
+ * (upThemeVars / upThemePageStyle),行为与 .uvue 版对齐。
14
+ */
15
+ defineOptions({
16
+ name: 'up-root',
17
+ styleIsolation: 'app-and-page'
18
+ })
19
+
20
+ import { computed, getCurrentInstance } from 'vue'
21
+ import { propsRoot } from './props.js'
22
+ import RootToastHost from '../up-root-toast-host/up-root-toast-host.vue'
23
+
24
+ const props = defineProps(propsRoot)
25
+ const { proxy } = getCurrentInstance() || {}
26
+
27
+ const rootVars = computed(() => proxy?.upThemeVars || {})
28
+ const backgroundStyle = computed(() => (props.background ? (proxy?.upThemePageStyle || {}) : {}))
29
+ </script>
30
+
31
+ <style scoped>
32
+ .up-root {
33
+ min-height: 100vh;
34
+ }
35
+ </style>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <up-toast ref="toastRef"></up-toast>
3
+ <up-notify ref="notifyRef"></up-notify>
4
+ </template>
5
+
6
+ <script setup lang="uts">
7
+ defineOptions({
8
+ name: 'up-root-toast-host',
9
+ styleIsolation: 'app-and-page'
10
+ })
11
+
12
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
13
+ import { setRootToastRef, setRootNotifyRef } from '../../libs/root/rootState.uts'
14
+
15
+ const toastRef = ref<ComponentPublicInstance | null>(null)
16
+ const notifyRef = ref<ComponentPublicInstance | null>(null)
17
+
18
+ onMounted(() => {
19
+ setRootToastRef(toastRef.value)
20
+ setRootNotifyRef(notifyRef.value)
21
+ })
22
+
23
+ onBeforeUnmount(() => {
24
+ setRootToastRef(null)
25
+ setRootNotifyRef(null)
26
+ })
27
+ </script>
@@ -15,7 +15,8 @@ export default {
15
15
  loading: false,
16
16
  disabled: false,
17
17
  size: 25,
18
- activeColor: '#2979ff',
18
+ // 与 switch.js 对齐:走主题变量(uvue 端 background 支持 var(),样式隔离 2.0 下变量可继承)
19
+ activeColor: 'var(--up-switch-active-color, var(--up-primary, #2979ff))',
19
20
  inactiveColor: '#ffffff',
20
21
  activeValue: true,
21
22
  inactiveValue: false,
@@ -275,7 +275,7 @@
275
275
  }
276
276
 
277
277
  &--square {
278
- border-radius: 3px;
278
+ border-radius: 8px;
279
279
  }
280
280
 
281
281
  &__icon {
@@ -183,7 +183,7 @@
183
183
  }
184
184
 
185
185
  &--square {
186
- border-radius: 3px;
186
+ border-radius: 8px;
187
187
  }
188
188
 
189
189
  &__icon {
@@ -142,6 +142,16 @@ const vueEnter = async (): Promise<void> => {
142
142
  emit('afterEnter')
143
143
  // 赋予组件enter-to类名
144
144
  classes.value = classNames['enter-to']!!.toString()
145
+ // 动画结束后清理 enter-active / enter-to。
146
+ // 不清理的话 transition-property 会常驻:进场的 CSS 过渡一旦被页面上任何一次
147
+ // 重渲染打断,computed transform 就冻结在起点(bottom 弹层 = translateY(100%),
148
+ // 整个弹层停在屏幕外),且之后再没有任何样式变化能触发新过渡把它拉回来。
149
+ // 清掉 active 类后 transition-property 消失,冻结值直接跳到最终态(归位)。
150
+ setTimeout(() => {
151
+ if (status.value === 'enter') {
152
+ classes.value = ''
153
+ }
154
+ }, parseInt(props.duration != null ? props.duration.toString() : "0") + 50)
145
155
  }
146
156
 
147
157
  // 动画离场处理
@@ -134,6 +134,13 @@ async function vueEnter() {
134
134
  emit('afterEnter')
135
135
  // 赋予组件enter-to类名
136
136
  classes.value = classNames['enter-to']
137
+ // 动画结束后清理 enter-active / enter-to(避免过渡被打断后 computed transform
138
+ // 冻结在起点,bottom 弹层停在屏幕外)
139
+ setTimeout(() => {
140
+ if (status.value === 'enter') {
141
+ classes.value = ''
142
+ }
143
+ }, parseInt(String(props.duration)) + 50)
137
144
  }
138
145
  }
139
146
 
@@ -25,13 +25,18 @@ $up-zoom-scale: scale(0.95);
25
25
  opacity: 0
26
26
  }
27
27
 
28
- .up-fade-zoom-enter,
28
+ .up-fade-enter-to {
29
+ opacity: 1;
30
+ }.up-fade-zoom-enter,
29
31
  .up-fade-zoom-leave-to {
30
32
  transform: $up-zoom-scale;
31
33
  opacity: 0;
32
34
  }
33
35
 
34
- .up-fade-zoom-enter-active,
36
+ .up-fade-zoom-enter-to {
37
+ transform: scale(1);
38
+ opacity: 1;
39
+ }.up-fade-zoom-enter-active,
35
40
  .up-fade-zoom-leave-active {
36
41
  transition-property: transform, opacity;
37
42
  }
@@ -53,25 +58,37 @@ $up-zoom-scale: scale(0.95);
53
58
  opacity: 0
54
59
  }
55
60
 
56
- .up-fade-down-enter,
61
+ .up-fade-up-enter-to {
62
+ transform: translateY(0);
63
+ opacity: 1;
64
+ }.up-fade-down-enter,
57
65
  .up-fade-down-leave-to {
58
66
  transform: translateY(-100%);
59
67
  opacity: 0
60
68
  }
61
69
 
62
- .up-fade-left-enter,
70
+ .up-fade-down-enter-to {
71
+ transform: translateY(0);
72
+ opacity: 1;
73
+ }.up-fade-left-enter,
63
74
  .up-fade-left-leave-to {
64
75
  transform: translateX(-100%);
65
76
  opacity: 0
66
77
  }
67
78
 
68
- .up-fade-right-enter,
79
+ .up-fade-left-enter-to {
80
+ transform: translateX(0);
81
+ opacity: 1;
82
+ }.up-fade-right-enter,
69
83
  .up-fade-right-leave-to {
70
84
  transform: translateX(100%);
71
85
  opacity: 0
72
86
  }
73
87
 
74
- .up-slide-down-enter-active,
88
+ .up-fade-right-enter-to {
89
+ transform: translateX(0);
90
+ opacity: 1;
91
+ }.up-slide-down-enter-active,
75
92
  .up-slide-down-leave-active,
76
93
  .up-slide-left-enter-active,
77
94
  .up-slide-left-leave-active,
@@ -87,22 +104,34 @@ $up-zoom-scale: scale(0.95);
87
104
  transform: translateY(100%)
88
105
  }
89
106
 
90
- .up-slide-down-enter,
107
+ .up-slide-up-enter-to {
108
+ transform: translateY(0);
109
+ opacity: 1;
110
+ }.up-slide-down-enter,
91
111
  .up-slide-down-leave-to {
92
112
  transform: translateY(-100%)
93
113
  }
94
114
 
95
- .up-slide-left-enter,
115
+ .up-slide-down-enter-to {
116
+ transform: translateY(0);
117
+ opacity: 1;
118
+ }.up-slide-left-enter,
96
119
  .up-slide-left-leave-to {
97
120
  transform: translateX(-100%)
98
121
  }
99
122
 
100
- .up-slide-right-enter,
123
+ .up-slide-left-enter-to {
124
+ transform: translateX(0);
125
+ opacity: 1;
126
+ }.up-slide-right-enter,
101
127
  .up-slide-right-leave-to {
102
128
  transform: translateX(100%)
103
129
  }
104
130
 
105
- .up-zoom-enter-active,
131
+ .up-slide-right-enter-to {
132
+ transform: translateX(0);
133
+ opacity: 1;
134
+ }.up-zoom-enter-active,
106
135
  .up-zoom-leave-active {
107
136
  transition-property: transform
108
137
  }
package/index.uts CHANGED
@@ -81,9 +81,56 @@ class UPUtils {
81
81
  }
82
82
  }
83
83
  const uputils = new UPUtils()
84
+
85
+ // 运行时主题系统(蒸汽模式暗黑支持)
86
+ import {
87
+ initThemeSystem,
88
+ setTheme,
89
+ setThemePreference,
90
+ getThemePreference,
91
+ getSystemTheme,
92
+ getThemeVars,
93
+ upThemeVar,
94
+ upThemeIsDark,
95
+ upThemeVarsStyle,
96
+ getThemePageStyle,
97
+ getThemeCardStyle,
98
+ getThemeTabBarStyle,
99
+ applyNativeThemeUI,
100
+ upThemeMode,
101
+ upThemePreference,
102
+ upThemeVersion,
103
+ upThemeVars
104
+ } from './libs/theme/theme.uts'
105
+ export {
106
+ initThemeSystem,
107
+ setTheme,
108
+ setThemePreference,
109
+ getThemePreference,
110
+ getSystemTheme,
111
+ getThemeVars,
112
+ upThemeVar,
113
+ upThemeIsDark,
114
+ upThemeVarsStyle,
115
+ getThemePageStyle,
116
+ getThemeCardStyle,
117
+ getThemeTabBarStyle,
118
+ applyNativeThemeUI
119
+ }
120
+
121
+ // 全局 root 宿主(up-root + 全局 toast/notify)
122
+ import {
123
+ rootToast,
124
+ rootNotify,
125
+ setRootToastRef,
126
+ setRootNotifyRef
127
+ } from './libs/root/rootState.uts'
128
+ export { rootToast, rootNotify, setRootToastRef, setRootNotifyRef }
129
+
84
130
  export const install = (app: VueApp): void => {
85
131
  app.config.globalProperties.$u = uputils
86
132
  app.config.globalProperties.$up = uputils
133
+ initThemeSystem()
87
134
  }
88
135
 
89
136
  export default {
@@ -0,0 +1,74 @@
1
+ /**
2
+ * uni-app x(蒸汽模式)全局 root 宿主状态。
3
+ *
4
+ * up-root-toast-host.uvue 挂载时把 up-toast / up-notify 的组件实例注册进来,
5
+ * 业务侧通过 rootToast() / rootNotify() 触发全局提示;没有宿主时降级
6
+ * uni.showToast。
7
+ */
8
+ import { ref } from 'vue'
9
+
10
+ export const rootToastRef = ref<ComponentPublicInstance | null>(null)
11
+ export const rootNotifyRef = ref<ComponentPublicInstance | null>(null)
12
+
13
+ export function setRootToastRef(instance: ComponentPublicInstance | null): void {
14
+ rootToastRef.value = instance
15
+ }
16
+
17
+ export function setRootNotifyRef(instance: ComponentPublicInstance | null): void {
18
+ rootNotifyRef.value = instance
19
+ }
20
+
21
+ function normalizeOptions(options: UTSJSONObject | string): UTSJSONObject {
22
+ if (options instanceof String) {
23
+ const obj = {} as UTSJSONObject
24
+ obj['message'] = options.toString()
25
+ return obj
26
+ }
27
+ const source = options as UTSJSONObject
28
+ const message = source['message']
29
+ if (message == null) {
30
+ const title = source['title']
31
+ if (title != null && typeof title === 'string') {
32
+ source['message'] = title
33
+ }
34
+ }
35
+ return source
36
+ }
37
+
38
+ export function rootToast(options: UTSJSONObject | string): void {
39
+ const toastOptions = normalizeOptions(options)
40
+ const instance = rootToastRef.value
41
+ if (instance != null) {
42
+ instance.$callMethod('show', toastOptions)
43
+ return
44
+ }
45
+ const message = toastOptions['message']
46
+ if (message == null || typeof message !== 'string') return
47
+ const durationValue = toastOptions['duration']
48
+ let duration = 2000
49
+ if (typeof durationValue === 'number') duration = Math.round(durationValue as number)
50
+ uni.showToast({
51
+ title: message as string,
52
+ icon: 'none',
53
+ duration
54
+ })
55
+ }
56
+
57
+ export function rootNotify(options: UTSJSONObject | string): void {
58
+ const notifyOptions = normalizeOptions(options)
59
+ const instance = rootNotifyRef.value
60
+ if (instance != null) {
61
+ instance.$callMethod('show', notifyOptions)
62
+ return
63
+ }
64
+ const message = notifyOptions['message']
65
+ if (message == null || typeof message !== 'string') return
66
+ const durationValue = notifyOptions['duration']
67
+ let duration = 3000
68
+ if (typeof durationValue === 'number') duration = Math.round(durationValue as number)
69
+ uni.showToast({
70
+ title: message as string,
71
+ icon: 'none',
72
+ duration
73
+ })
74
+ }
@@ -95,7 +95,8 @@ export const themeState = {
95
95
  vars: {}
96
96
  }
97
97
 
98
- const THEME_MODE_STORAGE_KEY = 'u-theme-mode'
98
+ const THEME_MODE_STORAGE_KEY = 'up-theme-mode'
99
+ const LEGACY_THEME_MODE_STORAGE_KEY = 'u-theme-mode'
99
100
  const THEME_MODE_SYSTEM = 'system'
100
101
  const THEME_MODE_MANUAL = ['light', 'dark']
101
102
  const LIGHT_THEME_TOKEN_FIELD_MAP = Object.freeze({
@@ -229,7 +230,16 @@ function getExplicitRuntimeColorValue(token, runtimeColorMap = {}) {
229
230
  function readThemePreferenceFromStorage() {
230
231
  try {
231
232
  if (typeof uni !== 'undefined' && typeof uni.getStorageSync === 'function') {
232
- const mode = uni.getStorageSync(THEME_MODE_STORAGE_KEY)
233
+ let mode = uni.getStorageSync(THEME_MODE_STORAGE_KEY)
234
+ // 旧 `u-theme-mode` 迁移(fork 时代 key)。
235
+ if (typeof mode !== 'string' || mode.length === 0) {
236
+ const legacy = uni.getStorageSync(LEGACY_THEME_MODE_STORAGE_KEY)
237
+ if (typeof legacy === 'string' && legacy.length > 0) {
238
+ mode = legacy
239
+ uni.setStorageSync(THEME_MODE_STORAGE_KEY, legacy)
240
+ uni.removeStorageSync(LEGACY_THEME_MODE_STORAGE_KEY)
241
+ }
242
+ }
233
243
  return normalizeThemePreference(mode)
234
244
  }
235
245
  } catch (e) {}