@hlw-uni/mp-vue 1.0.33 → 1.0.35
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/dist/composables/theme/font.d.ts +9 -0
- package/dist/composables/theme/index.d.ts +9 -0
- package/dist/composables/theme/palette.d.ts +8 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +204 -54
- package/dist/index.mjs +205 -53
- package/dist/stores/theme.d.ts +1 -0
- package/dist/style.css +87 -2
- package/package.json +9 -9
- package/src/composables/theme/font.ts +51 -0
- package/src/composables/theme/index.ts +33 -0
- package/src/composables/theme/palette.ts +36 -0
- package/src/index.ts +2 -2
- package/src/stores/theme.ts +2 -2
- package/dist/components/hlw-page/font-presets.d.ts +0 -54
- package/src/composables/theme-presets.ts +0 -109
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type FontScale = "small" | "normal" | "large" | "xlarge";
|
|
2
|
+
export interface FontPreset {
|
|
3
|
+
label: string;
|
|
4
|
+
vars: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export declare const FONT_SCALE_KEY = "hlw_font_scale";
|
|
7
|
+
export declare const FONT_PRESETS: Record<FontScale, FontPreset>;
|
|
8
|
+
export declare function getCurrentFontScale(): FontScale;
|
|
9
|
+
export declare function getCurrentFontVars(): Record<string, string>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const THEME_CHANGE_EVENT = "hlw:theme-change";
|
|
2
|
+
export declare function buildThemeStyle(): string;
|
|
3
|
+
export declare function useThemePageStyle(): {
|
|
4
|
+
themePageStyle: any;
|
|
5
|
+
};
|
|
6
|
+
export type { FontScale, FontPreset } from './font';
|
|
7
|
+
export { FONT_SCALE_KEY, FONT_PRESETS, getCurrentFontScale, getCurrentFontVars } from './font';
|
|
8
|
+
export type { ThemeColor } from './palette';
|
|
9
|
+
export { THEME_COLOR_KEY, DEFAULT_THEMES, getCurrentThemeColor, getCurrentThemeVars } from './palette';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ThemeColor {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const THEME_COLOR_KEY = "hlw_theme_color";
|
|
6
|
+
export declare const DEFAULT_THEMES: ThemeColor[];
|
|
7
|
+
export declare function getCurrentThemeColor(): string;
|
|
8
|
+
export declare function getCurrentThemeVars(): Record<string, string>;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,6 @@ export { default as HlwLoading } from './components/hlw-loading/index.vue';
|
|
|
10
10
|
export { default as HlwMenu } from './components/hlw-menu/index.vue';
|
|
11
11
|
export type { HlwMenuItem } from './components/hlw-menu/types';
|
|
12
12
|
export { default as HlwPage } from './components/hlw-page/index.vue';
|
|
13
|
-
export type { FontScale, FontPreset } from './
|
|
14
|
-
export { FONT_PRESETS, FONT_SCALE_KEY,
|
|
13
|
+
export type { FontScale, FontPreset, ThemeColor } from './composables/theme';
|
|
14
|
+
export { FONT_PRESETS, FONT_SCALE_KEY, DEFAULT_THEMES, THEME_COLOR_KEY, THEME_CHANGE_EVENT, getCurrentFontScale, getCurrentFontVars, getCurrentThemeColor, getCurrentThemeVars, buildThemeStyle, useThemePageStyle } from './composables/theme';
|
|
15
|
+
export { useThemeStore } from './stores/theme';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue")) : typeof define === "function" && define.amd ? define(["exports", "vue"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.HlwUniVue = {}, global.vue));
|
|
3
|
-
})(this, function(exports2, vue) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vue"), require("@hlw-uni/mp-core"), require("pinia")) : typeof define === "function" && define.amd ? define(["exports", "vue", "@hlw-uni/mp-core", "pinia"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.HlwUniVue = {}, global.vue, global.mpCore, global.pinia));
|
|
3
|
+
})(this, function(exports2, vue, mpCore, pinia) {
|
|
4
4
|
"use strict";
|
|
5
5
|
const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
|
|
6
6
|
...{ name: "HlwAd" },
|
|
@@ -79,67 +79,108 @@
|
|
|
79
79
|
return target;
|
|
80
80
|
};
|
|
81
81
|
const index$6 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-89dcbc96"]]);
|
|
82
|
-
const _hoisted_1$5 = {
|
|
83
|
-
const _hoisted_2$5 = {
|
|
82
|
+
const _hoisted_1$5 = {
|
|
84
83
|
key: 0,
|
|
85
84
|
class: "hlw-card-header"
|
|
86
85
|
};
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
86
|
+
const _hoisted_2$5 = { class: "hlw-card-header-inner" };
|
|
87
|
+
const _hoisted_3$3 = { class: "hlw-card-header-left" };
|
|
88
|
+
const _hoisted_4$2 = {
|
|
89
|
+
key: 0,
|
|
90
|
+
class: "hlw-card-title"
|
|
91
|
+
};
|
|
92
|
+
const _hoisted_5$1 = {
|
|
93
|
+
key: 0,
|
|
94
|
+
class: "hlw-card-header-right"
|
|
95
|
+
};
|
|
96
|
+
const _hoisted_6$1 = {
|
|
97
|
+
key: 0,
|
|
98
|
+
class: "hlw-card-extra"
|
|
99
|
+
};
|
|
91
100
|
const _hoisted_7$1 = {
|
|
101
|
+
key: 1,
|
|
102
|
+
class: "hlw-card-divider"
|
|
103
|
+
};
|
|
104
|
+
const _hoisted_8$1 = {
|
|
105
|
+
key: 2,
|
|
106
|
+
class: "hlw-card-footer"
|
|
107
|
+
};
|
|
108
|
+
const _hoisted_9$1 = { class: "hlw-card-footer-inner" };
|
|
109
|
+
const _hoisted_10$1 = { class: "hlw-card-footer-left" };
|
|
110
|
+
const _hoisted_11$1 = {
|
|
92
111
|
key: 0,
|
|
93
|
-
class: "
|
|
112
|
+
class: "hlw-card-footer-right"
|
|
94
113
|
};
|
|
95
|
-
const _hoisted_8$1 = { class: "hlw-card-body" };
|
|
96
114
|
const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
|
|
97
|
-
...{
|
|
98
|
-
options: {
|
|
99
|
-
styleIsolation: "shared",
|
|
100
|
-
virtualHost: true
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
115
|
__name: "index",
|
|
104
116
|
props: {
|
|
105
117
|
title: { default: "" },
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
extra: { default: "" },
|
|
119
|
+
border: { type: Boolean, default: true },
|
|
120
|
+
radius: { default: "xl" },
|
|
121
|
+
divider: { type: Boolean, default: void 0 },
|
|
122
|
+
padding: { type: Boolean, default: true }
|
|
109
123
|
},
|
|
110
124
|
setup(__props) {
|
|
125
|
+
const props = __props;
|
|
126
|
+
const slots = vue.useSlots();
|
|
127
|
+
const hasHeader = vue.computed(
|
|
128
|
+
() => !!(props.title || props.extra || slots.header || slots["header-left"] || slots["header-right"])
|
|
129
|
+
);
|
|
130
|
+
const hasFooter = vue.computed(
|
|
131
|
+
() => !!(slots.footer || slots["footer-left"] || slots["footer-right"])
|
|
132
|
+
);
|
|
133
|
+
const showDivider = vue.computed(() => {
|
|
134
|
+
if (props.divider !== void 0)
|
|
135
|
+
return props.divider;
|
|
136
|
+
return hasHeader.value;
|
|
137
|
+
});
|
|
111
138
|
return (_ctx, _cache) => {
|
|
112
|
-
return vue.openBlock(), vue.createElementBlock("view",
|
|
113
|
-
|
|
139
|
+
return vue.openBlock(), vue.createElementBlock("view", {
|
|
140
|
+
class: vue.normalizeClass(["hlw-card", [
|
|
141
|
+
`hlw-card--radius-${__props.radius}`,
|
|
142
|
+
__props.border ? "hlw-card--bordered" : ""
|
|
143
|
+
]])
|
|
144
|
+
}, [
|
|
145
|
+
hasHeader.value ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_1$5, [
|
|
114
146
|
vue.renderSlot(_ctx.$slots, "header", {}, () => [
|
|
115
|
-
vue.createElementVNode("view",
|
|
116
|
-
|
|
147
|
+
vue.createElementVNode("view", _hoisted_2$5, [
|
|
148
|
+
vue.createElementVNode("view", _hoisted_3$3, [
|
|
117
149
|
vue.renderSlot(_ctx.$slots, "header-left", {}, () => [
|
|
118
|
-
vue.
|
|
119
|
-
__props.icon ? (vue.openBlock(), vue.createElementBlock("text", {
|
|
120
|
-
key: 0,
|
|
121
|
-
class: vue.normalizeClass([__props.icon, __props.iconColor])
|
|
122
|
-
}, null, 2)) : vue.createCommentVNode("", true),
|
|
123
|
-
vue.createElementVNode("text", null, vue.toDisplayString(__props.title), 1)
|
|
124
|
-
])
|
|
150
|
+
__props.title ? (vue.openBlock(), vue.createElementBlock("text", _hoisted_4$2, vue.toDisplayString(__props.title), 1)) : vue.createCommentVNode("", true)
|
|
125
151
|
], true)
|
|
126
|
-
])
|
|
127
|
-
_ctx.$slots["header-right"] || __props.extra ? (vue.openBlock(), vue.createElementBlock("view",
|
|
152
|
+
]),
|
|
153
|
+
_ctx.$slots["header-right"] || __props.extra ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_5$1, [
|
|
128
154
|
vue.renderSlot(_ctx.$slots, "header-right", {}, () => [
|
|
129
|
-
__props.extra ? (vue.openBlock(), vue.createElementBlock("text",
|
|
155
|
+
__props.extra ? (vue.openBlock(), vue.createElementBlock("text", _hoisted_6$1, vue.toDisplayString(__props.extra), 1)) : vue.createCommentVNode("", true)
|
|
130
156
|
], true)
|
|
131
157
|
])) : vue.createCommentVNode("", true)
|
|
132
158
|
])
|
|
133
159
|
], true)
|
|
134
160
|
])) : vue.createCommentVNode("", true),
|
|
135
|
-
vue.
|
|
161
|
+
showDivider.value ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_7$1)) : vue.createCommentVNode("", true),
|
|
162
|
+
vue.createElementVNode("view", {
|
|
163
|
+
class: vue.normalizeClass(["hlw-card-body", { "hlw-card-body--padded": __props.padding }])
|
|
164
|
+
}, [
|
|
136
165
|
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
|
|
137
|
-
])
|
|
138
|
-
|
|
166
|
+
], 2),
|
|
167
|
+
hasFooter.value ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_8$1, [
|
|
168
|
+
vue.renderSlot(_ctx.$slots, "footer", {}, () => [
|
|
169
|
+
vue.createElementVNode("view", _hoisted_9$1, [
|
|
170
|
+
vue.createElementVNode("view", _hoisted_10$1, [
|
|
171
|
+
vue.renderSlot(_ctx.$slots, "footer-left", {}, void 0, true)
|
|
172
|
+
]),
|
|
173
|
+
_ctx.$slots["footer-right"] ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_11$1, [
|
|
174
|
+
vue.renderSlot(_ctx.$slots, "footer-right", {}, void 0, true)
|
|
175
|
+
])) : vue.createCommentVNode("", true)
|
|
176
|
+
])
|
|
177
|
+
], true)
|
|
178
|
+
])) : vue.createCommentVNode("", true)
|
|
179
|
+
], 2);
|
|
139
180
|
};
|
|
140
181
|
}
|
|
141
182
|
});
|
|
142
|
-
const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-
|
|
183
|
+
const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-cf55252e"]]);
|
|
143
184
|
const _hoisted_1$4 = { class: "hlw-empty" };
|
|
144
185
|
const _hoisted_2$4 = ["src"];
|
|
145
186
|
const _hoisted_3$2 = {
|
|
@@ -524,44 +565,147 @@
|
|
|
524
565
|
});
|
|
525
566
|
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d8833363"]]);
|
|
526
567
|
const FONT_SCALE_KEY = "hlw_font_scale";
|
|
527
|
-
const FONT_SCALE_EVENT = "hlw:font-scale-change";
|
|
528
568
|
const FONT_PRESETS = {
|
|
569
|
+
small: {
|
|
570
|
+
label: "小字体",
|
|
571
|
+
vars: {
|
|
572
|
+
"--font-xs": "16rpx",
|
|
573
|
+
"--font-sm": "20rpx",
|
|
574
|
+
"--font-base": "24rpx",
|
|
575
|
+
"--font-md": "28rpx",
|
|
576
|
+
"--font-lg": "32rpx",
|
|
577
|
+
"--font-xl": "36rpx"
|
|
578
|
+
}
|
|
579
|
+
},
|
|
529
580
|
normal: {
|
|
530
581
|
label: "标准",
|
|
531
|
-
|
|
582
|
+
vars: {
|
|
583
|
+
"--font-xs": "20rpx",
|
|
584
|
+
"--font-sm": "24rpx",
|
|
585
|
+
"--font-base": "28rpx",
|
|
586
|
+
"--font-md": "32rpx",
|
|
587
|
+
"--font-lg": "36rpx",
|
|
588
|
+
"--font-xl": "40rpx"
|
|
589
|
+
}
|
|
532
590
|
},
|
|
533
591
|
large: {
|
|
534
592
|
label: "大字体",
|
|
535
|
-
|
|
593
|
+
vars: {
|
|
594
|
+
"--font-xs": "24rpx",
|
|
595
|
+
"--font-sm": "30rpx",
|
|
596
|
+
"--font-base": "34rpx",
|
|
597
|
+
"--font-md": "40rpx",
|
|
598
|
+
"--font-lg": "46rpx",
|
|
599
|
+
"--font-xl": "52rpx"
|
|
600
|
+
}
|
|
536
601
|
},
|
|
537
602
|
xlarge: {
|
|
538
603
|
label: "超大字体",
|
|
539
|
-
|
|
604
|
+
vars: {
|
|
605
|
+
"--font-xs": "28rpx",
|
|
606
|
+
"--font-sm": "36rpx",
|
|
607
|
+
"--font-base": "42rpx",
|
|
608
|
+
"--font-md": "48rpx",
|
|
609
|
+
"--font-lg": "56rpx",
|
|
610
|
+
"--font-xl": "64rpx"
|
|
611
|
+
}
|
|
540
612
|
}
|
|
541
613
|
};
|
|
542
614
|
function getCurrentFontScale() {
|
|
543
615
|
try {
|
|
544
616
|
const v = uni.getStorageSync(FONT_SCALE_KEY);
|
|
545
|
-
if (v === "large" || v === "xlarge")
|
|
617
|
+
if (v === "small" || v === "large" || v === "xlarge")
|
|
546
618
|
return v;
|
|
547
619
|
} catch {
|
|
548
620
|
}
|
|
549
621
|
return "normal";
|
|
550
622
|
}
|
|
551
|
-
function
|
|
552
|
-
return FONT_PRESETS[getCurrentFontScale()].
|
|
623
|
+
function getCurrentFontVars() {
|
|
624
|
+
return FONT_PRESETS[getCurrentFontScale()].vars;
|
|
553
625
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
626
|
+
const { hexToRgba, darkenHex } = mpCore.useColor();
|
|
627
|
+
const THEME_COLOR_KEY = "hlw_theme_color";
|
|
628
|
+
const DEFAULT_THEMES = [
|
|
629
|
+
{ label: "默认蓝", value: "#3b82f6" },
|
|
630
|
+
{ label: "活力橙", value: "#f97316" },
|
|
631
|
+
{ label: "翡翠绿", value: "#10b981" },
|
|
632
|
+
{ label: "玫瑰红", value: "#f43f5e" },
|
|
633
|
+
{ label: "紫罗兰", value: "#8b5cf6" },
|
|
634
|
+
{ label: "青石灰", value: "#64748b" }
|
|
635
|
+
];
|
|
636
|
+
function getCurrentThemeColor() {
|
|
637
|
+
try {
|
|
638
|
+
const v = uni.getStorageSync(THEME_COLOR_KEY);
|
|
639
|
+
if (v && typeof v === "string")
|
|
640
|
+
return v;
|
|
641
|
+
} catch {
|
|
642
|
+
}
|
|
643
|
+
return DEFAULT_THEMES[0].value;
|
|
644
|
+
}
|
|
645
|
+
function getCurrentThemeVars() {
|
|
646
|
+
const color = getCurrentThemeColor();
|
|
647
|
+
return {
|
|
648
|
+
"--primary-color": color,
|
|
649
|
+
"--primary-light": hexToRgba(color, 0.12),
|
|
650
|
+
"--primary-dark": darkenHex(color)
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
const { varsToStyle } = mpCore.useColor();
|
|
654
|
+
const THEME_CHANGE_EVENT = "hlw:theme-change";
|
|
655
|
+
function buildThemeStyle() {
|
|
656
|
+
return varsToStyle({
|
|
657
|
+
...getCurrentFontVars(),
|
|
658
|
+
...getCurrentThemeVars()
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
function useThemePageStyle() {
|
|
662
|
+
const themePageStyle = vue.ref(buildThemeStyle());
|
|
663
|
+
const onThemeChange = () => {
|
|
664
|
+
themePageStyle.value = buildThemeStyle();
|
|
558
665
|
};
|
|
559
|
-
vue.onMounted(() => uni.$on(
|
|
560
|
-
vue.onUnmounted(() => uni.$off(
|
|
561
|
-
return {
|
|
666
|
+
vue.onMounted(() => uni.$on(THEME_CHANGE_EVENT, onThemeChange));
|
|
667
|
+
vue.onUnmounted(() => uni.$off(THEME_CHANGE_EVENT, onThemeChange));
|
|
668
|
+
return { themePageStyle };
|
|
562
669
|
}
|
|
670
|
+
const useThemeStore = pinia.defineStore(
|
|
671
|
+
"theme",
|
|
672
|
+
() => {
|
|
673
|
+
const scale = vue.ref("normal");
|
|
674
|
+
function setScale(s) {
|
|
675
|
+
scale.value = s;
|
|
676
|
+
uni.setStorageSync(FONT_SCALE_KEY, s);
|
|
677
|
+
uni.$emit(THEME_CHANGE_EVENT);
|
|
678
|
+
}
|
|
679
|
+
const fontOptions = Object.keys(FONT_PRESETS).map((key) => ({
|
|
680
|
+
value: key,
|
|
681
|
+
label: FONT_PRESETS[key].label
|
|
682
|
+
}));
|
|
683
|
+
const primaryColor = vue.ref(DEFAULT_THEMES[0].value);
|
|
684
|
+
const themes = DEFAULT_THEMES;
|
|
685
|
+
const activeTheme = vue.computed(
|
|
686
|
+
() => themes.find((t) => t.value === primaryColor.value) ?? { label: "自定义", value: primaryColor.value }
|
|
687
|
+
);
|
|
688
|
+
function setTheme(color) {
|
|
689
|
+
primaryColor.value = color;
|
|
690
|
+
uni.setStorageSync(THEME_COLOR_KEY, color);
|
|
691
|
+
uni.$emit(THEME_CHANGE_EVENT);
|
|
692
|
+
}
|
|
693
|
+
return {
|
|
694
|
+
// 字体
|
|
695
|
+
scale,
|
|
696
|
+
fontOptions,
|
|
697
|
+
setScale,
|
|
698
|
+
// 主题色
|
|
699
|
+
primaryColor,
|
|
700
|
+
themes,
|
|
701
|
+
activeTheme,
|
|
702
|
+
setTheme
|
|
703
|
+
};
|
|
704
|
+
},
|
|
705
|
+
{ unistorage: true }
|
|
706
|
+
);
|
|
707
|
+
exports2.DEFAULT_THEMES = DEFAULT_THEMES;
|
|
563
708
|
exports2.FONT_PRESETS = FONT_PRESETS;
|
|
564
|
-
exports2.FONT_SCALE_EVENT = FONT_SCALE_EVENT;
|
|
565
709
|
exports2.FONT_SCALE_KEY = FONT_SCALE_KEY;
|
|
566
710
|
exports2.HlwAd = _sfc_main$7;
|
|
567
711
|
exports2.HlwAvatar = index$6;
|
|
@@ -571,8 +715,14 @@
|
|
|
571
715
|
exports2.HlwLoading = index$2;
|
|
572
716
|
exports2.HlwMenu = index$1;
|
|
573
717
|
exports2.HlwPage = index;
|
|
718
|
+
exports2.THEME_CHANGE_EVENT = THEME_CHANGE_EVENT;
|
|
719
|
+
exports2.THEME_COLOR_KEY = THEME_COLOR_KEY;
|
|
720
|
+
exports2.buildThemeStyle = buildThemeStyle;
|
|
574
721
|
exports2.getCurrentFontScale = getCurrentFontScale;
|
|
575
|
-
exports2.
|
|
576
|
-
exports2.
|
|
722
|
+
exports2.getCurrentFontVars = getCurrentFontVars;
|
|
723
|
+
exports2.getCurrentThemeColor = getCurrentThemeColor;
|
|
724
|
+
exports2.getCurrentThemeVars = getCurrentThemeVars;
|
|
725
|
+
exports2.useThemePageStyle = useThemePageStyle;
|
|
726
|
+
exports2.useThemeStore = useThemeStore;
|
|
577
727
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
578
728
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { defineComponent, resolveComponent, openBlock, createBlock, ref, computed, createElementBlock, normalizeClass, createElementVNode, toDisplayString, renderSlot, createCommentVNode,
|
|
1
|
+
import { defineComponent, resolveComponent, openBlock, createBlock, ref, computed, createElementBlock, normalizeClass, createElementVNode, toDisplayString, useSlots, renderSlot, createCommentVNode, normalizeStyle, unref, Fragment, renderList, withCtx, createVNode, onMounted, onUnmounted } from "vue";
|
|
2
|
+
import { useColor } from "@hlw-uni/mp-core";
|
|
3
|
+
import { defineStore } from "pinia";
|
|
2
4
|
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
3
5
|
...{ name: "HlwAd" },
|
|
4
6
|
__name: "index",
|
|
@@ -76,67 +78,108 @@ const _export_sfc = (sfc, props) => {
|
|
|
76
78
|
return target;
|
|
77
79
|
};
|
|
78
80
|
const index$6 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-89dcbc96"]]);
|
|
79
|
-
const _hoisted_1$5 = {
|
|
80
|
-
const _hoisted_2$5 = {
|
|
81
|
+
const _hoisted_1$5 = {
|
|
81
82
|
key: 0,
|
|
82
83
|
class: "hlw-card-header"
|
|
83
84
|
};
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
85
|
+
const _hoisted_2$5 = { class: "hlw-card-header-inner" };
|
|
86
|
+
const _hoisted_3$3 = { class: "hlw-card-header-left" };
|
|
87
|
+
const _hoisted_4$2 = {
|
|
88
|
+
key: 0,
|
|
89
|
+
class: "hlw-card-title"
|
|
90
|
+
};
|
|
91
|
+
const _hoisted_5$1 = {
|
|
92
|
+
key: 0,
|
|
93
|
+
class: "hlw-card-header-right"
|
|
94
|
+
};
|
|
95
|
+
const _hoisted_6$1 = {
|
|
96
|
+
key: 0,
|
|
97
|
+
class: "hlw-card-extra"
|
|
98
|
+
};
|
|
88
99
|
const _hoisted_7$1 = {
|
|
100
|
+
key: 1,
|
|
101
|
+
class: "hlw-card-divider"
|
|
102
|
+
};
|
|
103
|
+
const _hoisted_8$1 = {
|
|
104
|
+
key: 2,
|
|
105
|
+
class: "hlw-card-footer"
|
|
106
|
+
};
|
|
107
|
+
const _hoisted_9$1 = { class: "hlw-card-footer-inner" };
|
|
108
|
+
const _hoisted_10$1 = { class: "hlw-card-footer-left" };
|
|
109
|
+
const _hoisted_11$1 = {
|
|
89
110
|
key: 0,
|
|
90
|
-
class: "
|
|
111
|
+
class: "hlw-card-footer-right"
|
|
91
112
|
};
|
|
92
|
-
const _hoisted_8$1 = { class: "hlw-card-body" };
|
|
93
113
|
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
94
|
-
...{
|
|
95
|
-
options: {
|
|
96
|
-
styleIsolation: "shared",
|
|
97
|
-
virtualHost: true
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
114
|
__name: "index",
|
|
101
115
|
props: {
|
|
102
116
|
title: { default: "" },
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
117
|
+
extra: { default: "" },
|
|
118
|
+
border: { type: Boolean, default: true },
|
|
119
|
+
radius: { default: "xl" },
|
|
120
|
+
divider: { type: Boolean, default: void 0 },
|
|
121
|
+
padding: { type: Boolean, default: true }
|
|
106
122
|
},
|
|
107
123
|
setup(__props) {
|
|
124
|
+
const props = __props;
|
|
125
|
+
const slots = useSlots();
|
|
126
|
+
const hasHeader = computed(
|
|
127
|
+
() => !!(props.title || props.extra || slots.header || slots["header-left"] || slots["header-right"])
|
|
128
|
+
);
|
|
129
|
+
const hasFooter = computed(
|
|
130
|
+
() => !!(slots.footer || slots["footer-left"] || slots["footer-right"])
|
|
131
|
+
);
|
|
132
|
+
const showDivider = computed(() => {
|
|
133
|
+
if (props.divider !== void 0)
|
|
134
|
+
return props.divider;
|
|
135
|
+
return hasHeader.value;
|
|
136
|
+
});
|
|
108
137
|
return (_ctx, _cache) => {
|
|
109
|
-
return openBlock(), createElementBlock("view",
|
|
110
|
-
|
|
138
|
+
return openBlock(), createElementBlock("view", {
|
|
139
|
+
class: normalizeClass(["hlw-card", [
|
|
140
|
+
`hlw-card--radius-${__props.radius}`,
|
|
141
|
+
__props.border ? "hlw-card--bordered" : ""
|
|
142
|
+
]])
|
|
143
|
+
}, [
|
|
144
|
+
hasHeader.value ? (openBlock(), createElementBlock("view", _hoisted_1$5, [
|
|
111
145
|
renderSlot(_ctx.$slots, "header", {}, () => [
|
|
112
|
-
createElementVNode("view",
|
|
113
|
-
|
|
146
|
+
createElementVNode("view", _hoisted_2$5, [
|
|
147
|
+
createElementVNode("view", _hoisted_3$3, [
|
|
114
148
|
renderSlot(_ctx.$slots, "header-left", {}, () => [
|
|
115
|
-
|
|
116
|
-
__props.icon ? (openBlock(), createElementBlock("text", {
|
|
117
|
-
key: 0,
|
|
118
|
-
class: normalizeClass([__props.icon, __props.iconColor])
|
|
119
|
-
}, null, 2)) : createCommentVNode("", true),
|
|
120
|
-
createElementVNode("text", null, toDisplayString(__props.title), 1)
|
|
121
|
-
])
|
|
149
|
+
__props.title ? (openBlock(), createElementBlock("text", _hoisted_4$2, toDisplayString(__props.title), 1)) : createCommentVNode("", true)
|
|
122
150
|
], true)
|
|
123
|
-
])
|
|
124
|
-
_ctx.$slots["header-right"] || __props.extra ? (openBlock(), createElementBlock("view",
|
|
151
|
+
]),
|
|
152
|
+
_ctx.$slots["header-right"] || __props.extra ? (openBlock(), createElementBlock("view", _hoisted_5$1, [
|
|
125
153
|
renderSlot(_ctx.$slots, "header-right", {}, () => [
|
|
126
|
-
__props.extra ? (openBlock(), createElementBlock("text",
|
|
154
|
+
__props.extra ? (openBlock(), createElementBlock("text", _hoisted_6$1, toDisplayString(__props.extra), 1)) : createCommentVNode("", true)
|
|
127
155
|
], true)
|
|
128
156
|
])) : createCommentVNode("", true)
|
|
129
157
|
])
|
|
130
158
|
], true)
|
|
131
159
|
])) : createCommentVNode("", true),
|
|
132
|
-
|
|
160
|
+
showDivider.value ? (openBlock(), createElementBlock("view", _hoisted_7$1)) : createCommentVNode("", true),
|
|
161
|
+
createElementVNode("view", {
|
|
162
|
+
class: normalizeClass(["hlw-card-body", { "hlw-card-body--padded": __props.padding }])
|
|
163
|
+
}, [
|
|
133
164
|
renderSlot(_ctx.$slots, "default", {}, void 0, true)
|
|
134
|
-
])
|
|
135
|
-
|
|
165
|
+
], 2),
|
|
166
|
+
hasFooter.value ? (openBlock(), createElementBlock("view", _hoisted_8$1, [
|
|
167
|
+
renderSlot(_ctx.$slots, "footer", {}, () => [
|
|
168
|
+
createElementVNode("view", _hoisted_9$1, [
|
|
169
|
+
createElementVNode("view", _hoisted_10$1, [
|
|
170
|
+
renderSlot(_ctx.$slots, "footer-left", {}, void 0, true)
|
|
171
|
+
]),
|
|
172
|
+
_ctx.$slots["footer-right"] ? (openBlock(), createElementBlock("view", _hoisted_11$1, [
|
|
173
|
+
renderSlot(_ctx.$slots, "footer-right", {}, void 0, true)
|
|
174
|
+
])) : createCommentVNode("", true)
|
|
175
|
+
])
|
|
176
|
+
], true)
|
|
177
|
+
])) : createCommentVNode("", true)
|
|
178
|
+
], 2);
|
|
136
179
|
};
|
|
137
180
|
}
|
|
138
181
|
});
|
|
139
|
-
const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-
|
|
182
|
+
const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-cf55252e"]]);
|
|
140
183
|
const _hoisted_1$4 = { class: "hlw-empty" };
|
|
141
184
|
const _hoisted_2$4 = ["src"];
|
|
142
185
|
const _hoisted_3$2 = {
|
|
@@ -521,45 +564,148 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
521
564
|
});
|
|
522
565
|
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d8833363"]]);
|
|
523
566
|
const FONT_SCALE_KEY = "hlw_font_scale";
|
|
524
|
-
const FONT_SCALE_EVENT = "hlw:font-scale-change";
|
|
525
567
|
const FONT_PRESETS = {
|
|
568
|
+
small: {
|
|
569
|
+
label: "小字体",
|
|
570
|
+
vars: {
|
|
571
|
+
"--font-xs": "16rpx",
|
|
572
|
+
"--font-sm": "20rpx",
|
|
573
|
+
"--font-base": "24rpx",
|
|
574
|
+
"--font-md": "28rpx",
|
|
575
|
+
"--font-lg": "32rpx",
|
|
576
|
+
"--font-xl": "36rpx"
|
|
577
|
+
}
|
|
578
|
+
},
|
|
526
579
|
normal: {
|
|
527
580
|
label: "标准",
|
|
528
|
-
|
|
581
|
+
vars: {
|
|
582
|
+
"--font-xs": "20rpx",
|
|
583
|
+
"--font-sm": "24rpx",
|
|
584
|
+
"--font-base": "28rpx",
|
|
585
|
+
"--font-md": "32rpx",
|
|
586
|
+
"--font-lg": "36rpx",
|
|
587
|
+
"--font-xl": "40rpx"
|
|
588
|
+
}
|
|
529
589
|
},
|
|
530
590
|
large: {
|
|
531
591
|
label: "大字体",
|
|
532
|
-
|
|
592
|
+
vars: {
|
|
593
|
+
"--font-xs": "24rpx",
|
|
594
|
+
"--font-sm": "30rpx",
|
|
595
|
+
"--font-base": "34rpx",
|
|
596
|
+
"--font-md": "40rpx",
|
|
597
|
+
"--font-lg": "46rpx",
|
|
598
|
+
"--font-xl": "52rpx"
|
|
599
|
+
}
|
|
533
600
|
},
|
|
534
601
|
xlarge: {
|
|
535
602
|
label: "超大字体",
|
|
536
|
-
|
|
603
|
+
vars: {
|
|
604
|
+
"--font-xs": "28rpx",
|
|
605
|
+
"--font-sm": "36rpx",
|
|
606
|
+
"--font-base": "42rpx",
|
|
607
|
+
"--font-md": "48rpx",
|
|
608
|
+
"--font-lg": "56rpx",
|
|
609
|
+
"--font-xl": "64rpx"
|
|
610
|
+
}
|
|
537
611
|
}
|
|
538
612
|
};
|
|
539
613
|
function getCurrentFontScale() {
|
|
540
614
|
try {
|
|
541
615
|
const v = uni.getStorageSync(FONT_SCALE_KEY);
|
|
542
|
-
if (v === "large" || v === "xlarge")
|
|
616
|
+
if (v === "small" || v === "large" || v === "xlarge")
|
|
543
617
|
return v;
|
|
544
618
|
} catch {
|
|
545
619
|
}
|
|
546
620
|
return "normal";
|
|
547
621
|
}
|
|
548
|
-
function
|
|
549
|
-
return FONT_PRESETS[getCurrentFontScale()].
|
|
622
|
+
function getCurrentFontVars() {
|
|
623
|
+
return FONT_PRESETS[getCurrentFontScale()].vars;
|
|
550
624
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
625
|
+
const { hexToRgba, darkenHex } = useColor();
|
|
626
|
+
const THEME_COLOR_KEY = "hlw_theme_color";
|
|
627
|
+
const DEFAULT_THEMES = [
|
|
628
|
+
{ label: "默认蓝", value: "#3b82f6" },
|
|
629
|
+
{ label: "活力橙", value: "#f97316" },
|
|
630
|
+
{ label: "翡翠绿", value: "#10b981" },
|
|
631
|
+
{ label: "玫瑰红", value: "#f43f5e" },
|
|
632
|
+
{ label: "紫罗兰", value: "#8b5cf6" },
|
|
633
|
+
{ label: "青石灰", value: "#64748b" }
|
|
634
|
+
];
|
|
635
|
+
function getCurrentThemeColor() {
|
|
636
|
+
try {
|
|
637
|
+
const v = uni.getStorageSync(THEME_COLOR_KEY);
|
|
638
|
+
if (v && typeof v === "string")
|
|
639
|
+
return v;
|
|
640
|
+
} catch {
|
|
641
|
+
}
|
|
642
|
+
return DEFAULT_THEMES[0].value;
|
|
643
|
+
}
|
|
644
|
+
function getCurrentThemeVars() {
|
|
645
|
+
const color = getCurrentThemeColor();
|
|
646
|
+
return {
|
|
647
|
+
"--primary-color": color,
|
|
648
|
+
"--primary-light": hexToRgba(color, 0.12),
|
|
649
|
+
"--primary-dark": darkenHex(color)
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
const { varsToStyle } = useColor();
|
|
653
|
+
const THEME_CHANGE_EVENT = "hlw:theme-change";
|
|
654
|
+
function buildThemeStyle() {
|
|
655
|
+
return varsToStyle({
|
|
656
|
+
...getCurrentFontVars(),
|
|
657
|
+
...getCurrentThemeVars()
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
function useThemePageStyle() {
|
|
661
|
+
const themePageStyle = ref(buildThemeStyle());
|
|
662
|
+
const onThemeChange = () => {
|
|
663
|
+
themePageStyle.value = buildThemeStyle();
|
|
555
664
|
};
|
|
556
|
-
onMounted(() => uni.$on(
|
|
557
|
-
onUnmounted(() => uni.$off(
|
|
558
|
-
return {
|
|
665
|
+
onMounted(() => uni.$on(THEME_CHANGE_EVENT, onThemeChange));
|
|
666
|
+
onUnmounted(() => uni.$off(THEME_CHANGE_EVENT, onThemeChange));
|
|
667
|
+
return { themePageStyle };
|
|
559
668
|
}
|
|
669
|
+
const useThemeStore = defineStore(
|
|
670
|
+
"theme",
|
|
671
|
+
() => {
|
|
672
|
+
const scale = ref("normal");
|
|
673
|
+
function setScale(s) {
|
|
674
|
+
scale.value = s;
|
|
675
|
+
uni.setStorageSync(FONT_SCALE_KEY, s);
|
|
676
|
+
uni.$emit(THEME_CHANGE_EVENT);
|
|
677
|
+
}
|
|
678
|
+
const fontOptions = Object.keys(FONT_PRESETS).map((key) => ({
|
|
679
|
+
value: key,
|
|
680
|
+
label: FONT_PRESETS[key].label
|
|
681
|
+
}));
|
|
682
|
+
const primaryColor = ref(DEFAULT_THEMES[0].value);
|
|
683
|
+
const themes = DEFAULT_THEMES;
|
|
684
|
+
const activeTheme = computed(
|
|
685
|
+
() => themes.find((t) => t.value === primaryColor.value) ?? { label: "自定义", value: primaryColor.value }
|
|
686
|
+
);
|
|
687
|
+
function setTheme(color) {
|
|
688
|
+
primaryColor.value = color;
|
|
689
|
+
uni.setStorageSync(THEME_COLOR_KEY, color);
|
|
690
|
+
uni.$emit(THEME_CHANGE_EVENT);
|
|
691
|
+
}
|
|
692
|
+
return {
|
|
693
|
+
// 字体
|
|
694
|
+
scale,
|
|
695
|
+
fontOptions,
|
|
696
|
+
setScale,
|
|
697
|
+
// 主题色
|
|
698
|
+
primaryColor,
|
|
699
|
+
themes,
|
|
700
|
+
activeTheme,
|
|
701
|
+
setTheme
|
|
702
|
+
};
|
|
703
|
+
},
|
|
704
|
+
{ unistorage: true }
|
|
705
|
+
);
|
|
560
706
|
export {
|
|
707
|
+
DEFAULT_THEMES,
|
|
561
708
|
FONT_PRESETS,
|
|
562
|
-
FONT_SCALE_EVENT,
|
|
563
709
|
FONT_SCALE_KEY,
|
|
564
710
|
_sfc_main$7 as HlwAd,
|
|
565
711
|
index$6 as HlwAvatar,
|
|
@@ -569,7 +715,13 @@ export {
|
|
|
569
715
|
index$2 as HlwLoading,
|
|
570
716
|
index$1 as HlwMenu,
|
|
571
717
|
index as HlwPage,
|
|
718
|
+
THEME_CHANGE_EVENT,
|
|
719
|
+
THEME_COLOR_KEY,
|
|
720
|
+
buildThemeStyle,
|
|
572
721
|
getCurrentFontScale,
|
|
573
|
-
|
|
574
|
-
|
|
722
|
+
getCurrentFontVars,
|
|
723
|
+
getCurrentThemeColor,
|
|
724
|
+
getCurrentThemeVars,
|
|
725
|
+
useThemePageStyle,
|
|
726
|
+
useThemeStore
|
|
575
727
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useThemeStore: any;
|
package/dist/style.css
CHANGED
|
@@ -33,10 +33,95 @@
|
|
|
33
33
|
.hlw-avatar--large .hlw-avatar__initial[data-v-89dcbc96] { font-size: var(--font-xl, 40rpx);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
.hlw-card[data-v-
|
|
37
|
-
|
|
36
|
+
.hlw-card[data-v-cf55252e] {
|
|
37
|
+
width: 100%;
|
|
38
|
+
background: #fff;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
/* 圆角档位 */
|
|
41
|
+
}
|
|
42
|
+
.hlw-card--radius-none[data-v-cf55252e] {
|
|
43
|
+
border-radius: 0;
|
|
44
|
+
}
|
|
45
|
+
.hlw-card--radius-sm[data-v-cf55252e] {
|
|
46
|
+
border-radius: var(--radius-sm, 8rpx);
|
|
47
|
+
}
|
|
48
|
+
.hlw-card--radius-md[data-v-cf55252e] {
|
|
49
|
+
border-radius: var(--radius-md, 16rpx);
|
|
50
|
+
}
|
|
51
|
+
.hlw-card--radius-lg[data-v-cf55252e] {
|
|
52
|
+
border-radius: var(--radius-lg, 24rpx);
|
|
53
|
+
}
|
|
54
|
+
.hlw-card--radius-xl[data-v-cf55252e] {
|
|
55
|
+
border-radius: var(--radius-xl, 32rpx);
|
|
56
|
+
}
|
|
57
|
+
.hlw-card[data-v-cf55252e] {
|
|
58
|
+
/* 边框 */
|
|
59
|
+
}
|
|
60
|
+
.hlw-card--bordered[data-v-cf55252e] {
|
|
61
|
+
border: 1rpx solid var(--border-color, #e2e8f0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* 头部 */
|
|
65
|
+
.hlw-card-header[data-v-cf55252e] {
|
|
66
|
+
width: 100%;
|
|
67
|
+
}
|
|
68
|
+
.hlw-card-header-inner[data-v-cf55252e] {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: space-between;
|
|
72
|
+
padding: 24rpx 28rpx;
|
|
73
|
+
}
|
|
74
|
+
.hlw-card-header-left[data-v-cf55252e] {
|
|
75
|
+
flex: 1;
|
|
76
|
+
min-width: 0;
|
|
77
|
+
}
|
|
78
|
+
.hlw-card-header-right[data-v-cf55252e] {
|
|
79
|
+
flex-shrink: 0;
|
|
80
|
+
margin-left: 16rpx;
|
|
81
|
+
}
|
|
82
|
+
.hlw-card-title[data-v-cf55252e] {
|
|
83
|
+
font-size: var(--font-sm, 24rpx);
|
|
84
|
+
font-weight: 700;
|
|
85
|
+
color: #1e293b;
|
|
86
|
+
letter-spacing: 0.02em;
|
|
87
|
+
}
|
|
88
|
+
.hlw-card-extra[data-v-cf55252e] {
|
|
89
|
+
font-size: var(--font-xs, 20rpx);
|
|
90
|
+
color: #94a3b8;
|
|
38
91
|
}
|
|
39
92
|
|
|
93
|
+
/* 虚线分隔 */
|
|
94
|
+
.hlw-card-divider[data-v-cf55252e] {
|
|
95
|
+
width: 100%;
|
|
96
|
+
border-bottom: 1rpx dashed var(--border-color, #e2e8f0);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* 内容区 */
|
|
100
|
+
.hlw-card-body[data-v-cf55252e] {
|
|
101
|
+
width: 100%;
|
|
102
|
+
}
|
|
103
|
+
.hlw-card-body--padded[data-v-cf55252e] {
|
|
104
|
+
padding: 24rpx 28rpx;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* 底部 */
|
|
108
|
+
.hlw-card-footer[data-v-cf55252e] {
|
|
109
|
+
width: 100%;
|
|
110
|
+
border-top: 1rpx solid var(--border-color-light, #f1f5f9);
|
|
111
|
+
}
|
|
112
|
+
.hlw-card-footer-inner[data-v-cf55252e] {
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
padding: 20rpx 28rpx;
|
|
116
|
+
}
|
|
117
|
+
.hlw-card-footer-left[data-v-cf55252e] {
|
|
118
|
+
flex: 1;
|
|
119
|
+
min-width: 0;
|
|
120
|
+
}
|
|
121
|
+
.hlw-card-footer-right[data-v-cf55252e] {
|
|
122
|
+
flex-shrink: 0;
|
|
123
|
+
margin-left: 16rpx;
|
|
124
|
+
}
|
|
40
125
|
.hlw-empty[data-v-08b8d8fe] {
|
|
41
126
|
display: flex;
|
|
42
127
|
flex-direction: column;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hlw-uni/mp-vue",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"description": "hlw-uni Vue 组件库 — 供小程序业务方使用的 UI 组件集合",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -26,19 +26,19 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"
|
|
30
|
-
"
|
|
29
|
+
"pinia": ">=2.0.0",
|
|
30
|
+
"vue": ">=3.4.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@dcloudio/types": "^3.4.
|
|
34
|
-
"@types/node": "^20.
|
|
35
|
-
"@vitejs/plugin-vue": "^5.
|
|
36
|
-
"typescript": "^4.9.
|
|
33
|
+
"@dcloudio/types": "^3.4.30",
|
|
34
|
+
"@types/node": "^20.19.39",
|
|
35
|
+
"@vitejs/plugin-vue": "^5.2.4",
|
|
36
|
+
"typescript": "^4.9.5",
|
|
37
37
|
"vite": "5.2.8",
|
|
38
38
|
"vite-plugin-dts": "^4.5.4",
|
|
39
|
-
"vue": "^3.
|
|
39
|
+
"vue": "^3.5.32"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@hlw-uni/mp-core": "^1.0.
|
|
42
|
+
"@hlw-uni/mp-core": "^1.0.28"
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export type FontScale = "small" | "normal" | "large" | "xlarge";
|
|
2
|
+
|
|
3
|
+
export interface FontPreset {
|
|
4
|
+
label: string;
|
|
5
|
+
vars: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const FONT_SCALE_KEY = "hlw_font_scale";
|
|
9
|
+
|
|
10
|
+
export const FONT_PRESETS: Record<FontScale, FontPreset> = {
|
|
11
|
+
small: {
|
|
12
|
+
label: "小字体",
|
|
13
|
+
vars: {
|
|
14
|
+
"--font-xs": "16rpx", "--font-sm": "20rpx", "--font-base": "24rpx",
|
|
15
|
+
"--font-md": "28rpx", "--font-lg": "32rpx", "--font-xl": "36rpx",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
normal: {
|
|
19
|
+
label: "标准",
|
|
20
|
+
vars: {
|
|
21
|
+
"--font-xs": "20rpx", "--font-sm": "24rpx", "--font-base": "28rpx",
|
|
22
|
+
"--font-md": "32rpx", "--font-lg": "36rpx", "--font-xl": "40rpx",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
large: {
|
|
26
|
+
label: "大字体",
|
|
27
|
+
vars: {
|
|
28
|
+
"--font-xs": "24rpx", "--font-sm": "30rpx", "--font-base": "34rpx",
|
|
29
|
+
"--font-md": "40rpx", "--font-lg": "46rpx", "--font-xl": "52rpx",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
xlarge: {
|
|
33
|
+
label: "超大字体",
|
|
34
|
+
vars: {
|
|
35
|
+
"--font-xs": "28rpx", "--font-sm": "36rpx", "--font-base": "42rpx",
|
|
36
|
+
"--font-md": "48rpx", "--font-lg": "56rpx", "--font-xl": "64rpx",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function getCurrentFontScale(): FontScale {
|
|
42
|
+
try {
|
|
43
|
+
const v = uni.getStorageSync(FONT_SCALE_KEY);
|
|
44
|
+
if (v === "small" || v === "large" || v === "xlarge") return v;
|
|
45
|
+
} catch {}
|
|
46
|
+
return "normal";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function getCurrentFontVars(): Record<string, string> {
|
|
50
|
+
return FONT_PRESETS[getCurrentFontScale()].vars;
|
|
51
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ref, onMounted, onUnmounted } from "vue";
|
|
2
|
+
import { useColor } from "@hlw-uni/mp-core";
|
|
3
|
+
|
|
4
|
+
const { varsToStyle } = useColor();
|
|
5
|
+
import { getCurrentFontVars } from "./font";
|
|
6
|
+
import { getCurrentThemeVars } from "./palette";
|
|
7
|
+
|
|
8
|
+
export const THEME_CHANGE_EVENT = "hlw:theme-change";
|
|
9
|
+
|
|
10
|
+
export function buildThemeStyle(): string {
|
|
11
|
+
return varsToStyle({
|
|
12
|
+
...getCurrentFontVars(),
|
|
13
|
+
...getCurrentThemeVars(),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useThemePageStyle() {
|
|
18
|
+
const themePageStyle = ref(buildThemeStyle());
|
|
19
|
+
|
|
20
|
+
const onThemeChange = () => {
|
|
21
|
+
themePageStyle.value = buildThemeStyle();
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
onMounted(() => uni.$on(THEME_CHANGE_EVENT, onThemeChange));
|
|
25
|
+
onUnmounted(() => uni.$off(THEME_CHANGE_EVENT, onThemeChange));
|
|
26
|
+
|
|
27
|
+
return { themePageStyle };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type { FontScale, FontPreset } from "./font";
|
|
31
|
+
export { FONT_SCALE_KEY, FONT_PRESETS, getCurrentFontScale, getCurrentFontVars } from "./font";
|
|
32
|
+
export type { ThemeColor } from "./palette";
|
|
33
|
+
export { THEME_COLOR_KEY, DEFAULT_THEMES, getCurrentThemeColor, getCurrentThemeVars } from "./palette";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useColor } from "@hlw-uni/mp-core";
|
|
2
|
+
|
|
3
|
+
const { hexToRgba, darkenHex } = useColor();
|
|
4
|
+
|
|
5
|
+
export interface ThemeColor {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const THEME_COLOR_KEY = "hlw_theme_color";
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_THEMES: ThemeColor[] = [
|
|
13
|
+
{ label: "默认蓝", value: "#3b82f6" },
|
|
14
|
+
{ label: "活力橙", value: "#f97316" },
|
|
15
|
+
{ label: "翡翠绿", value: "#10b981" },
|
|
16
|
+
{ label: "玫瑰红", value: "#f43f5e" },
|
|
17
|
+
{ label: "紫罗兰", value: "#8b5cf6" },
|
|
18
|
+
{ label: "青石灰", value: "#64748b" },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export function getCurrentThemeColor(): string {
|
|
22
|
+
try {
|
|
23
|
+
const v = uni.getStorageSync(THEME_COLOR_KEY);
|
|
24
|
+
if (v && typeof v === "string") return v;
|
|
25
|
+
} catch {}
|
|
26
|
+
return DEFAULT_THEMES[0].value;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getCurrentThemeVars(): Record<string, string> {
|
|
30
|
+
const color = getCurrentThemeColor();
|
|
31
|
+
return {
|
|
32
|
+
"--primary-color": color,
|
|
33
|
+
"--primary-light": hexToRgba(color, 0.12),
|
|
34
|
+
"--primary-dark": darkenHex(color),
|
|
35
|
+
};
|
|
36
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,6 @@ export { default as HlwLoading } from "./components/hlw-loading/index.vue";
|
|
|
11
11
|
export { default as HlwMenu } from "./components/hlw-menu/index.vue";
|
|
12
12
|
export type { HlwMenuItem } from "./components/hlw-menu/types";
|
|
13
13
|
export { default as HlwPage } from "./components/hlw-page/index.vue";
|
|
14
|
-
export type { FontScale, FontPreset, ThemeColor } from "./composables/theme
|
|
15
|
-
export { FONT_PRESETS, FONT_SCALE_KEY, DEFAULT_THEMES, THEME_COLOR_KEY, THEME_CHANGE_EVENT, getCurrentFontScale,
|
|
14
|
+
export type { FontScale, FontPreset, ThemeColor } from "./composables/theme";
|
|
15
|
+
export { FONT_PRESETS, FONT_SCALE_KEY, DEFAULT_THEMES, THEME_COLOR_KEY, THEME_CHANGE_EVENT, getCurrentFontScale, getCurrentFontVars, getCurrentThemeColor, getCurrentThemeVars, buildThemeStyle, useThemePageStyle } from "./composables/theme";
|
|
16
16
|
export { useThemeStore } from "./stores/theme";
|
package/src/stores/theme.ts
CHANGED
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
DEFAULT_THEMES,
|
|
11
11
|
THEME_COLOR_KEY,
|
|
12
12
|
THEME_CHANGE_EVENT,
|
|
13
|
-
} from "../composables/theme
|
|
14
|
-
import type { FontScale, ThemeColor } from "../composables/theme
|
|
13
|
+
} from "../composables/theme";
|
|
14
|
+
import type { FontScale, ThemeColor } from "../composables/theme";
|
|
15
15
|
|
|
16
16
|
export const useThemeStore = defineStore(
|
|
17
17
|
"theme",
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* hlw-page 字体档位预设
|
|
3
|
-
*
|
|
4
|
-
* 三档:标准 / 大字体 / 超大字体
|
|
5
|
-
* 通过 <page-meta page-style="..."> 注入到页面根节点,
|
|
6
|
-
* 覆盖 CSS 变量,所有使用 var(--font-*) 的组件自动跟随。
|
|
7
|
-
*/
|
|
8
|
-
export type FontScale = "normal" | "large" | "xlarge";
|
|
9
|
-
/** storage key,与 qz2 font store 保持一致 */
|
|
10
|
-
export declare const FONT_SCALE_KEY = "hlw_font_scale";
|
|
11
|
-
/** 全局事件名,store.setScale 触发后 hlw-page 实时响应 */
|
|
12
|
-
export declare const FONT_SCALE_EVENT = "hlw:font-scale-change";
|
|
13
|
-
export interface FontPreset {
|
|
14
|
-
/** 展示名称 */
|
|
15
|
-
label: string;
|
|
16
|
-
/** 注入到 page-meta 的 CSS 变量字符串 */
|
|
17
|
-
style: string;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* 三档字体预设
|
|
21
|
-
*
|
|
22
|
-
* 变量说明:
|
|
23
|
-
* --font-xs 极小文字(角标、辅助标注)
|
|
24
|
-
* --font-sm 小文字(次要说明、标签、grid-label)
|
|
25
|
-
* --font-base 正文(菜单项、内容主体)
|
|
26
|
-
* --font-md 中等(次级标题)
|
|
27
|
-
* --font-lg 大号(页面标题、导航标题)
|
|
28
|
-
* --font-xl 特大(数字展示)
|
|
29
|
-
*/
|
|
30
|
-
export declare const FONT_PRESETS: Record<FontScale, FontPreset>;
|
|
31
|
-
/** 读取当前档位(同步,从 storage 取) */
|
|
32
|
-
export declare function getCurrentFontScale(): FontScale;
|
|
33
|
-
/** 读取当前档位对应的 page-style 字符串 */
|
|
34
|
-
export declare function getCurrentFontStyle(): string;
|
|
35
|
-
/**
|
|
36
|
-
* 在页面根节点使用,配合 <page-meta :page-style="fontPageStyle"> 实现全局字体缩放。
|
|
37
|
-
*
|
|
38
|
-
* 注意:<page-meta> 必须作为页面 .vue 文件 template 的第一个根节点,不可放在子组件内。
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```vue
|
|
42
|
-
* <template>
|
|
43
|
-
* <page-meta :page-style="fontPageStyle" />
|
|
44
|
-
* <hlw-page title="xxx">...</hlw-page>
|
|
45
|
-
* </template>
|
|
46
|
-
* <script setup>
|
|
47
|
-
* import { useFontPageStyle } from '@hlw-uni/mp-vue';
|
|
48
|
-
* const { fontPageStyle } = useFontPageStyle();
|
|
49
|
-
* </script>
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
export declare function useFontPageStyle(): {
|
|
53
|
-
fontPageStyle: any;
|
|
54
|
-
};
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { ref, computed, onMounted, onUnmounted } from "vue";
|
|
2
|
-
|
|
3
|
-
// ─── 字体档位 ────────────────────────────────────────
|
|
4
|
-
|
|
5
|
-
export type FontScale = "small" | "normal" | "large" | "xlarge";
|
|
6
|
-
|
|
7
|
-
export const FONT_SCALE_KEY = "hlw_font_scale";
|
|
8
|
-
|
|
9
|
-
export interface FontPreset {
|
|
10
|
-
label: string;
|
|
11
|
-
style: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const FONT_PRESETS: Record<FontScale, FontPreset> = {
|
|
15
|
-
small: {
|
|
16
|
-
label: "小字体",
|
|
17
|
-
style: "--font-xs:16rpx;--font-sm:20rpx;--font-base:24rpx;--font-md:28rpx;--font-lg:32rpx;--font-xl:36rpx;",
|
|
18
|
-
},
|
|
19
|
-
normal: {
|
|
20
|
-
label: "标准",
|
|
21
|
-
style: "--font-xs:20rpx;--font-sm:24rpx;--font-base:28rpx;--font-md:32rpx;--font-lg:36rpx;--font-xl:40rpx;",
|
|
22
|
-
},
|
|
23
|
-
large: {
|
|
24
|
-
label: "大字体",
|
|
25
|
-
style: "--font-xs:24rpx;--font-sm:30rpx;--font-base:34rpx;--font-md:40rpx;--font-lg:46rpx;--font-xl:52rpx;",
|
|
26
|
-
},
|
|
27
|
-
xlarge: {
|
|
28
|
-
label: "超大字体",
|
|
29
|
-
style: "--font-xs:28rpx;--font-sm:36rpx;--font-base:42rpx;--font-md:48rpx;--font-lg:56rpx;--font-xl:64rpx;",
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export function getCurrentFontScale(): FontScale {
|
|
34
|
-
try {
|
|
35
|
-
const v = uni.getStorageSync(FONT_SCALE_KEY);
|
|
36
|
-
if (v === "small" || v === "large" || v === "xlarge") return v;
|
|
37
|
-
} catch {}
|
|
38
|
-
return "normal";
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function getCurrentFontStyle(): string {
|
|
42
|
-
return FONT_PRESETS[getCurrentFontScale()].style;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ─── 主题色 ──────────────────────────────────────────
|
|
46
|
-
|
|
47
|
-
export interface ThemeColor {
|
|
48
|
-
label: string;
|
|
49
|
-
value: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const THEME_COLOR_KEY = "hlw_theme_color";
|
|
53
|
-
|
|
54
|
-
/** 内置预设主题色 */
|
|
55
|
-
export const DEFAULT_THEMES: ThemeColor[] = [
|
|
56
|
-
{ label: "默认蓝", value: "#3b82f6" },
|
|
57
|
-
{ label: "活力橙", value: "#f97316" },
|
|
58
|
-
{ label: "翡翠绿", value: "#10b981" },
|
|
59
|
-
{ label: "玫瑰红", value: "#f43f5e" },
|
|
60
|
-
{ label: "紫罗兰", value: "#8b5cf6" },
|
|
61
|
-
{ label: "青石灰", value: "#64748b" },
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
export function getCurrentThemeColor(): string {
|
|
65
|
-
try {
|
|
66
|
-
const v = uni.getStorageSync(THEME_COLOR_KEY);
|
|
67
|
-
if (v && typeof v === "string") return v;
|
|
68
|
-
} catch {}
|
|
69
|
-
return DEFAULT_THEMES[0].value;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function getCurrentThemeStyle(): string {
|
|
73
|
-
return `--primary-color:${getCurrentThemeColor()};`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// ─── 统一事件 ────────────────────────────────────────
|
|
77
|
-
|
|
78
|
-
/** 字体 / 主题色变更时统一广播此事件 */
|
|
79
|
-
export const THEME_CHANGE_EVENT = "hlw:theme-change";
|
|
80
|
-
|
|
81
|
-
// ─── 组合式函数 ──────────────────────────────────────
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 在页面中使用,配合 <page-meta :page-style="themePageStyle"> 注入字体 + 主题色。
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```vue
|
|
88
|
-
* <template>
|
|
89
|
-
* <page-meta :page-style="themePageStyle" />
|
|
90
|
-
* <hlw-page title="xxx">...</hlw-page>
|
|
91
|
-
* </template>
|
|
92
|
-
* <script setup>
|
|
93
|
-
* import { useThemePageStyle } from '@hlw-uni/mp-vue';
|
|
94
|
-
* const { themePageStyle } = useThemePageStyle();
|
|
95
|
-
* </script>
|
|
96
|
-
* ```
|
|
97
|
-
*/
|
|
98
|
-
export function useThemePageStyle() {
|
|
99
|
-
const themePageStyle = ref(getCurrentFontStyle() + getCurrentThemeStyle());
|
|
100
|
-
|
|
101
|
-
const onThemeChange = () => {
|
|
102
|
-
themePageStyle.value = getCurrentFontStyle() + getCurrentThemeStyle();
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
onMounted(() => uni.$on(THEME_CHANGE_EVENT, onThemeChange));
|
|
106
|
-
onUnmounted(() => uni.$off(THEME_CHANGE_EVENT, onThemeChange));
|
|
107
|
-
|
|
108
|
-
return { themePageStyle };
|
|
109
|
-
}
|