@hlw-uni/mp-vue 1.2.2 → 1.2.22

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.
@@ -1,5 +1,12 @@
1
1
  import { Ref } from 'vue';
2
2
  export declare const THEME_CHANGE_EVENT = "hlw:theme-change";
3
+ /**
4
+ * 只注入会随主题变化的变量(字号档位、主题色、外观模式)。
5
+ *
6
+ * 语义排版 token(--text-title-size 等)是静态值、不随主题变化,
7
+ * 放在项目的全局 CSS(static/css/style.scss)里作为 page{} 默认值即可,
8
+ * 让业务侧可以自由 override,不被运行时注入覆盖。
9
+ */
3
10
  export declare function buildThemeStyle(): string;
4
11
  export declare function useThemePageStyle(): {
5
12
  themePageStyle: Ref<string, string>;
@@ -10,3 +17,5 @@ export type { ThemeColor } from './palette';
10
17
  export { THEME_COLOR_KEY, THEME_SEMANTIC_COLORS, DEFAULT_THEMES, getCurrentThemeColor, getCurrentThemeVars, } from './palette';
11
18
  export type { Appearance, AppearanceMode, AppearancePreset } from './appearance';
12
19
  export { APPEARANCE_KEY, APPEARANCE_PRESETS, APPEARANCE_VAR_MAP, getCurrentAppearance, getCurrentAppearanceMode, getCurrentAppearanceVars, resolveAppearance, } from './appearance';
20
+ export type { TypographyRole } from './typography';
21
+ export { TYPOGRAPHY_ROLES, getCurrentTypographyVars } from './typography';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 语义化排版 token — 把"字号 + 字重 + 行高 + 颜色"打包成角色,统一各页面文字样式。
3
+ *
4
+ * 使用指南:
5
+ * - 页面样式里用 `var(--text-title-size)` 等变量代替硬编码,自动响应字体档位/外观模式切换
6
+ * - 或通过全局 utility class(见 qz2 项目的 static/css/style.scss)直接加 class
7
+ *
8
+ * 6 个语义角色:
9
+ * - title-lg: 页面大标题 / hero
10
+ * - title: 卡片 / 分区主标题
11
+ * - subtitle: 次级标题
12
+ * - body: 正文
13
+ * - desc: 卡片描述 / 副文
14
+ * - caption: 角标 / 底部小字 / 时间戳
15
+ */
16
+ export interface TypographyRole {
17
+ /** 对应 `--text-{role}-size` 的值(通常引用字号档位 token) */
18
+ size: string;
19
+ /** 对应 `--text-{role}-weight` */
20
+ weight: string;
21
+ /** 对应 `--text-{role}-line-height` */
22
+ lineHeight: string;
23
+ /** 对应 `--text-{role}-color`(通常引用文字色 token) */
24
+ color: string;
25
+ }
26
+ export declare const TYPOGRAPHY_ROLES: Record<string, TypographyRole>;
27
+ /**
28
+ * 展开成 CSS 变量平铺 map,用于 buildThemeStyle 注入 page 元素。
29
+ *
30
+ * 每个角色产出 4 个变量:
31
+ * --text-{role}-size / -weight / -line-height / -color
32
+ */
33
+ export declare function getCurrentTypographyVars(): Record<string, string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hlw-uni/mp-vue",
3
- "version": "1.2.2",
3
+ "version": "1.2.22",
4
4
  "description": "hlw-uni Vue 组件库 — 供小程序业务方使用的 UI 组件集合",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -0,0 +1,123 @@
1
+ <template>
2
+ <image
3
+ class="hlw-image"
4
+ :src="src"
5
+ :mode="mode"
6
+ :lazy-load="lazyLoad"
7
+ :show-menu-by-longpress="showMenuByLongpress"
8
+ :webp="webp"
9
+ :fade-show="fadeShow"
10
+ :draggable="draggable"
11
+ @load="$emit('load', $event)"
12
+ @error="$emit('error', $event)"
13
+ @tap="handleTap"
14
+ />
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ /**
19
+ * HlwImage — 图片组件
20
+ *
21
+ * 默认继承原生 <image> 所有属性,额外支持点击大图预览(uni.previewImage)。
22
+ *
23
+ * @props
24
+ * src - 图片地址
25
+ * mode - 裁剪/缩放模式(同原生 image),默认 scaleToFill
26
+ * lazyLoad - 懒加载
27
+ * showMenuByLongpress - 长按弹出菜单(保存图片等)
28
+ * webp - 指定为 webp 格式
29
+ * fadeShow - 淡入效果
30
+ * draggable - H5 端可拖拽
31
+ * preview - 点击是否弹出大图预览(uni.previewImage)
32
+ * previewList - 预览组 URL 数组;传了则进入分组预览,current 定位 src
33
+ *
34
+ * @events
35
+ * load - 原生 load
36
+ * error - 原生 error
37
+ * tap - 原生点击(不论是否 preview 都触发)
38
+ *
39
+ * @example
40
+ * ```vue
41
+ * <!-- 简单点击预览 -->
42
+ * <hlw-image :src="url" preview />
43
+ *
44
+ * <!-- 分组预览:点击任一图进入,支持左右滑动切换 -->
45
+ * <hlw-image :src="photo" preview :preview-list="photos" />
46
+ * ```
47
+ */
48
+
49
+ interface Props {
50
+ /** 图片 URL(必填) */
51
+ src: string;
52
+ /** 裁剪/缩放模式;参见 uni 官方文档 */
53
+ mode?:
54
+ | "scaleToFill"
55
+ | "aspectFit"
56
+ | "aspectFill"
57
+ | "widthFix"
58
+ | "heightFix"
59
+ | "top"
60
+ | "bottom"
61
+ | "center"
62
+ | "left"
63
+ | "right"
64
+ | "top left"
65
+ | "top right"
66
+ | "bottom left"
67
+ | "bottom right";
68
+ /** 懒加载(仅小程序) */
69
+ lazyLoad?: boolean;
70
+ /** 长按弹出菜单(保存/转发等) */
71
+ showMenuByLongpress?: boolean;
72
+ /** 指定为 webp 格式 */
73
+ webp?: boolean;
74
+ /** 淡入显示 */
75
+ fadeShow?: boolean;
76
+ /** H5 端是否可拖拽 */
77
+ draggable?: boolean;
78
+ /** 点击是否弹出大图预览 */
79
+ preview?: boolean;
80
+ /** 预览组;传了则在预览里支持左右滑切换,current 自动定位 src */
81
+ previewList?: string[];
82
+ }
83
+
84
+ const props = withDefaults(defineProps<Props>(), {
85
+ mode: "scaleToFill",
86
+ lazyLoad: false,
87
+ showMenuByLongpress: false,
88
+ webp: false,
89
+ fadeShow: true,
90
+ draggable: true,
91
+ preview: false,
92
+ previewList: () => [],
93
+ });
94
+
95
+ const emit = defineEmits<{
96
+ (e: "tap", event: unknown): void;
97
+ (e: "load", event: unknown): void;
98
+ (e: "error", event: unknown): void;
99
+ }>();
100
+
101
+ const handleTap = (event: unknown) => {
102
+ emit("tap", event);
103
+ if (!props.preview || !props.src) return;
104
+ const urls = props.previewList.length > 0 ? props.previewList : [props.src];
105
+ uni.previewImage({
106
+ urls,
107
+ current: props.src,
108
+ });
109
+ };
110
+ </script>
111
+
112
+ <style lang="scss" scoped>
113
+ /**
114
+ * 内部 image 默认填满宿主元素所分配的空间。
115
+ * 父组件通过 class (如 .qr-img { width:360rpx; height:360rpx }) 只能控制 <hlw-image> host;
116
+ * 由于 scoped 样式不穿透自定义组件,这里必须给内部 image 也设 100%,否则 mode 生效不了。
117
+ */
118
+ .hlw-image {
119
+ display: block;
120
+ width: 100%;
121
+ height: 100%;
122
+ }
123
+ </style>
@@ -1,5 +1,11 @@
1
1
  <template>
2
- <view class="hlw-page" :style="themePageStyle">
2
+ <view class="hlw-page">
3
+ <!--
4
+ 字号 / 主题色 / 外观变量注入到 page 根元素,
5
+ 这样 scroll-view 内部的 slot 内容也能继承到 CSS 变量(小程序原生组件对 CSS 变量的继承不稳定,挂在内层 view 上部分场景失效)。
6
+ -->
7
+ <page-meta :page-style="themePageStyle" />
8
+
3
9
  <view class="hlw-page-header">
4
10
  <slot name="header">
5
11
  <hlw-header
@@ -11,47 +17,12 @@
11
17
  </slot>
12
18
  </view>
13
19
 
14
- <hlw-paging
15
- v-if="props.usePaging"
16
- ref="pagingRef"
17
- class="hlw-page-content hlw-page-content--paging"
18
- :model-value="props.modelValue"
19
- :fixed="false"
20
- :use-page-scroll="false"
21
- :height="'100%'"
22
- :refresher-enabled="props.refresherEnabled"
23
- :loading-more-enabled="props.loadingMoreEnabled"
24
- :default-page-size="props.defaultPageSize"
25
- :loading-text="props.loadingText"
26
- :empty-text="props.emptyText"
27
- :error-text="props.errorText"
28
- :empty-image="props.emptyImage"
29
- :use-default-loading="props.useDefaultLoading"
30
- :use-default-empty="props.useDefaultEmpty"
31
- @update:model-value="handleUpdateModelValue"
32
- @query="handleQuery"
33
- >
34
- <slot />
35
-
36
- <template v-if="$slots.loading" #loading="slotProps">
37
- <slot name="loading" :isLoadFailed="slotProps && slotProps.isLoadFailed" />
38
- </template>
39
- <template v-if="$slots.empty" #empty="slotProps">
40
- <slot name="empty" :isLoadFailed="slotProps && slotProps.isLoadFailed" />
41
- </template>
42
- <template v-if="$slots['empty-extra']" #empty-extra="slotProps">
43
- <slot name="empty-extra" :isLoadFailed="slotProps && slotProps.isLoadFailed" />
44
- </template>
45
- </hlw-paging>
46
-
47
20
  <scroll-view
48
- v-else
49
21
  class="hlw-page-content"
50
22
  :scroll-y="true"
51
23
  :enable-flex="true"
52
24
  :enhanced="true"
53
25
  :show-scrollbar="false"
54
- :style="themePageStyle"
55
26
  >
56
27
  <slot />
57
28
  </scroll-view>
@@ -63,8 +34,6 @@
63
34
  </template>
64
35
 
65
36
  <script setup lang="ts">
66
- import { ref } from "vue";
67
- import type { HlwPagingRef } from "../hlw-paging/types";
68
37
  import { useThemePageStyle } from "../../composables/theme";
69
38
 
70
39
  defineOptions({
@@ -76,108 +45,15 @@ interface Props {
76
45
  title?: string;
77
46
  isBack?: boolean;
78
47
  bgClass?: string;
79
- usePaging?: boolean;
80
- modelValue?: any[];
81
- refresherEnabled?: boolean;
82
- loadingMoreEnabled?: boolean;
83
- defaultPageSize?: number;
84
- loadingText?: string;
85
- emptyText?: string;
86
- errorText?: string;
87
- emptyImage?: string;
88
- useDefaultLoading?: boolean;
89
- useDefaultEmpty?: boolean;
90
48
  }
91
49
 
92
50
  const props = withDefaults(defineProps<Props>(), {
93
51
  title: "",
94
52
  isBack: false,
95
53
  bgClass: "",
96
- usePaging: false,
97
- modelValue: () => [],
98
- useDefaultLoading: true,
99
- useDefaultEmpty: true,
100
54
  });
101
55
 
102
- const emit = defineEmits<{
103
- "update:modelValue": [value: any[]];
104
- query: [pageNo: number, pageSize: number, ...args: any[]];
105
- }>();
106
-
107
- const pagingRef = ref<HlwPagingRef<any> | null>(null);
108
56
  const { themePageStyle } = useThemePageStyle();
109
-
110
- function handleUpdateModelValue(value: any[]) {
111
- emit("update:modelValue", value ?? []);
112
- }
113
-
114
- function handleQuery(pageNo: number, pageSize: number, ...args: any[]) {
115
- emit("query", pageNo, pageSize, ...args);
116
- }
117
-
118
- const getPagingRef = () => pagingRef.value;
119
-
120
- const pagingMethodNames = [
121
- "reload",
122
- "refresh",
123
- "refreshToPage",
124
- "complete",
125
- "completeByTotal",
126
- "completeByNoMore",
127
- "completeByError",
128
- "completeByKey",
129
- "clear",
130
- "addDataFromTop",
131
- "resetTotalData",
132
- "endRefresh",
133
- "updateCustomRefresherHeight",
134
- "goF2",
135
- "closeF2",
136
- "doLoadMore",
137
- "updatePageScrollTop",
138
- "updatePageScrollTopHeight",
139
- "updatePageScrollBottomHeight",
140
- "updateLeftAndRightWidth",
141
- "updateFixedLayout",
142
- "doInsertVirtualListItem",
143
- "didUpdateVirtualListCell",
144
- "didDeleteVirtualListCell",
145
- "updateVirtualListRender",
146
- "setLocalPaging",
147
- "doChatRecordLoadMore",
148
- "addChatRecordData",
149
- "addKeyboardHeightChangeListener",
150
- "scrollToTop",
151
- "scrollToBottom",
152
- "scrollIntoViewById",
153
- "scrollIntoViewByNodeTop",
154
- "scrollToY",
155
- "scrollToX",
156
- "scrollIntoViewByIndex",
157
- "scrollIntoViewByView",
158
- "setSpecialEffects",
159
- "setListSpecialEffects",
160
- "updateCache",
161
- "getVersion",
162
- ] as const;
163
-
164
- type PagingMethodName = (typeof pagingMethodNames)[number];
165
-
166
- const exposed = pagingMethodNames.reduce((result, methodName) => {
167
- result[methodName] = (...args: any[]) => {
168
- return pagingRef.value?.[methodName]?.(...args);
169
- };
170
-
171
- return result;
172
- }, {
173
- pagingRef,
174
- getPagingRef,
175
- } as Record<string, any>);
176
-
177
- defineExpose(exposed as {
178
- pagingRef: typeof pagingRef;
179
- getPagingRef: () => HlwPagingRef<any> | null;
180
- } & Record<PagingMethodName, (...args: any[]) => any>);
181
57
  </script>
182
58
 
183
59
  <style lang="scss" scoped>
@@ -201,10 +77,6 @@ defineExpose(exposed as {
201
77
  width: 100%;
202
78
  }
203
79
 
204
- .hlw-page-content--paging {
205
- min-height: 0;
206
- }
207
-
208
80
  .hlw-page-footer {
209
81
  flex-shrink: 0;
210
82
  }
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <view v-if="visible" class="hlw-sheet-root" :class="{ show: shown }">
3
3
  <view class="hlw-sheet-overlay" @tap="handleMaskTap" />
4
- <view class="hlw-sheet-panel" :style="{ height: maxHeight, maxHeight }" @tap.stop>
4
+ <view class="hlw-sheet-panel" :style="{ maxHeight }" @tap.stop>
5
5
  <view class="hlw-sheet-header">
6
6
  <view v-if="showHandle" class="hlw-sheet-handle" />
7
7
  <text v-if="title" class="hlw-sheet-title">{{ title }}</text>
@@ -265,9 +265,9 @@ onBeforeUnmount(() => {
265
265
  }
266
266
 
267
267
  .hlw-sheet-cta-text {
268
- font-size: var(--font-base, 28rpx);
269
- font-weight: 600;
268
+ font-size: var(--font-sm, 24rpx);
269
+ font-weight: 400;
270
270
  color: #ffffff;
271
- letter-spacing: 1rpx;
271
+ letter-spacing: 0.5rpx;
272
272
  }
273
273
  </style>
@@ -8,6 +8,13 @@ import { getCurrentAppearanceVars } from "./appearance";
8
8
 
9
9
  export const THEME_CHANGE_EVENT = "hlw:theme-change";
10
10
 
11
+ /**
12
+ * 只注入会随主题变化的变量(字号档位、主题色、外观模式)。
13
+ *
14
+ * 语义排版 token(--text-title-size 等)是静态值、不随主题变化,
15
+ * 放在项目的全局 CSS(static/css/style.scss)里作为 page{} 默认值即可,
16
+ * 让业务侧可以自由 override,不被运行时注入覆盖。
17
+ */
11
18
  export function buildThemeStyle(): string {
12
19
  return varsToStyle({
13
20
  ...getCurrentFontVars(),
@@ -49,3 +56,5 @@ export {
49
56
  getCurrentAppearanceVars,
50
57
  resolveAppearance,
51
58
  } from "./appearance";
59
+ export type { TypographyRole } from "./typography";
60
+ export { TYPOGRAPHY_ROLES, getCurrentTypographyVars } from "./typography";
@@ -0,0 +1,82 @@
1
+ /**
2
+ * 语义化排版 token — 把"字号 + 字重 + 行高 + 颜色"打包成角色,统一各页面文字样式。
3
+ *
4
+ * 使用指南:
5
+ * - 页面样式里用 `var(--text-title-size)` 等变量代替硬编码,自动响应字体档位/外观模式切换
6
+ * - 或通过全局 utility class(见 qz2 项目的 static/css/style.scss)直接加 class
7
+ *
8
+ * 6 个语义角色:
9
+ * - title-lg: 页面大标题 / hero
10
+ * - title: 卡片 / 分区主标题
11
+ * - subtitle: 次级标题
12
+ * - body: 正文
13
+ * - desc: 卡片描述 / 副文
14
+ * - caption: 角标 / 底部小字 / 时间戳
15
+ */
16
+
17
+ export interface TypographyRole {
18
+ /** 对应 `--text-{role}-size` 的值(通常引用字号档位 token) */
19
+ size: string;
20
+ /** 对应 `--text-{role}-weight` */
21
+ weight: string;
22
+ /** 对应 `--text-{role}-line-height` */
23
+ lineHeight: string;
24
+ /** 对应 `--text-{role}-color`(通常引用文字色 token) */
25
+ color: string;
26
+ }
27
+
28
+ export const TYPOGRAPHY_ROLES: Record<string, TypographyRole> = {
29
+ "title-lg": {
30
+ size: "var(--font-xl)",
31
+ weight: "600",
32
+ lineHeight: "1.2",
33
+ color: "var(--text-primary)",
34
+ },
35
+ "title": {
36
+ size: "var(--font-md)",
37
+ weight: "500",
38
+ lineHeight: "1.3",
39
+ color: "var(--text-primary)",
40
+ },
41
+ "subtitle": {
42
+ size: "var(--font-base)",
43
+ weight: "500",
44
+ lineHeight: "1.3",
45
+ color: "var(--text-secondary)",
46
+ },
47
+ "body": {
48
+ size: "var(--font-base)",
49
+ weight: "400",
50
+ lineHeight: "1.5",
51
+ color: "var(--text-secondary)",
52
+ },
53
+ "desc": {
54
+ size: "var(--font-sm)",
55
+ weight: "400",
56
+ lineHeight: "1.4",
57
+ color: "var(--text-subtle)",
58
+ },
59
+ "caption": {
60
+ size: "var(--font-xs)",
61
+ weight: "500",
62
+ lineHeight: "1.3",
63
+ color: "var(--text-muted)",
64
+ },
65
+ };
66
+
67
+ /**
68
+ * 展开成 CSS 变量平铺 map,用于 buildThemeStyle 注入 page 元素。
69
+ *
70
+ * 每个角色产出 4 个变量:
71
+ * --text-{role}-size / -weight / -line-height / -color
72
+ */
73
+ export function getCurrentTypographyVars(): Record<string, string> {
74
+ const vars: Record<string, string> = {};
75
+ for (const [role, cfg] of Object.entries(TYPOGRAPHY_ROLES)) {
76
+ vars[`--text-${role}-size`] = cfg.size;
77
+ vars[`--text-${role}-weight`] = cfg.weight;
78
+ vars[`--text-${role}-line-height`] = cfg.lineHeight;
79
+ vars[`--text-${role}-color`] = cfg.color;
80
+ }
81
+ return vars;
82
+ }