@hlw-uni-mp/use 1.1.6 → 1.1.9

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/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import * as vue from 'vue';
2
- import { App, Ref } from 'vue';
3
1
  import * as pinia from 'pinia';
2
+ import * as vue from 'vue';
3
+ import { Ref } from 'vue';
4
4
 
5
5
  declare module "pinia" {
6
6
  interface DefineStoreOptionsBase<S, Store> {
@@ -33,13 +33,13 @@ interface InitThemeOptions {
33
33
  }
34
34
  /** 字体大小预设项 */
35
35
  interface FontSizePreset {
36
- id: string;
36
+ id: FontSize;
37
37
  name: string;
38
38
  class: string;
39
39
  }
40
40
  /** 字体样式预设项 */
41
41
  interface FontFamilyPreset {
42
- id: string;
42
+ id: FontFamily;
43
43
  name: string;
44
44
  class: string;
45
45
  }
@@ -52,13 +52,21 @@ declare const fontSizePresets: FontSizePreset[];
52
52
  /** 字体样式预设表 */
53
53
  declare const fontFamilyPresets: FontFamilyPreset[];
54
54
  /** 主题状态 Store */
55
- declare const useThemeStore: pinia.StoreDefinition<"theme", ThemeState, {}, {}>;
55
+ declare const useThemeStore: pinia.StoreDefinition<"theme", ThemeState, {}, {
56
+ setMode(targetMode: ThemeMode): void;
57
+ setColor(hexColor: string): void;
58
+ setFontSize(targetSize: string): void;
59
+ setFontFamily(targetFont: string): void;
60
+ resetTheme(): void;
61
+ applyTheme(themeState: Partial<ThemeState>): void;
62
+ }>;
63
+
56
64
  /** 获取存储配置 */
57
65
  declare function getTheme(): ThemeState;
58
66
  /** 应用主题状态 */
59
67
  declare function applyTheme(themeState: Partial<ThemeState>): void;
60
68
  /** 初始化主题系统 */
61
- declare function initTheme(app: App, options?: InitThemeOptions): void;
69
+ declare function initTheme(app: any, options?: InitThemeOptions): void;
62
70
  /** 主题组合式函数 */
63
71
  declare function useTheme(): {
64
72
  mode: vue.Ref<ThemeMode, ThemeMode>;
@@ -78,7 +86,14 @@ declare function useTheme(): {
78
86
  applyTheme: typeof applyTheme;
79
87
  getTheme: typeof getTheme;
80
88
  initTheme: typeof initTheme;
81
- store: pinia.Store<"theme", ThemeState, {}, {}>;
89
+ store: pinia.Store<"theme", ThemeState, {}, {
90
+ setMode(targetMode: ThemeMode): void;
91
+ setColor(hexColor: string): void;
92
+ setFontSize(targetSize: string): void;
93
+ setFontFamily(targetFont: string): void;
94
+ resetTheme(): void;
95
+ applyTheme(themeState: Partial<ThemeState>): void;
96
+ }>;
82
97
  };
83
98
 
84
99
  /**
@@ -113,4 +128,77 @@ interface UseRefsReturn<T = unknown> {
113
128
  */
114
129
  declare function useRefs<T = unknown>(): UseRefsReturn<T>;
115
130
 
116
- export { DEFAULT_THEME, type FontFamily, type FontFamilyPreset, type FontSize, type FontSizePreset, type InitThemeOptions, THEME_COLORS, type ThemeColor, type ThemeMode, type ThemeState, type UseRefsReturn, applyTheme, fontFamilyPresets, fontSizePresets, getTheme, initTheme, useRefs, useTheme, useThemeStore };
131
+ /**
132
+ * 分享信息配置
133
+ */
134
+ interface ShareInfo {
135
+ /** 转发标题 */
136
+ title?: string;
137
+ /** 转发页面路径(可带 query 参数) */
138
+ path?: string;
139
+ /** 自定义分享封面图 URL 或本地路径 */
140
+ imageUrl?: string;
141
+ /** 分享到朋友圈的 query 参数(默认自动从 path 中提取) */
142
+ query?: string;
143
+ }
144
+ /** 分享配置解析器(支持对象或返回对象的函数) */
145
+ type ShareResolver = ShareInfo | (() => ShareInfo);
146
+ /**
147
+ * 通用小程序分享 Hook
148
+ * 自动激活小程序转发与朋友圈菜单,并统一接管分享标题与路径生成
149
+ *
150
+ * @param resolver 静态分享配置或动态计算函数
151
+ * @param onTrigger 触发分享时的动作回调(如打点统计,入参 from 代表触发源:menu 或 button)
152
+ */
153
+ declare function useShare(resolver?: ShareResolver, onTrigger?: (from: string) => void): {
154
+ onShareAppMessage: (custom?: ShareInfo) => void;
155
+ onShareTimeline: (custom?: ShareInfo) => void;
156
+ };
157
+
158
+ /**
159
+ * 分页数据接口返回格式
160
+ */
161
+ type PagingResult<T> = {
162
+ list: T[];
163
+ total?: number;
164
+ } | T[];
165
+ /**
166
+ * 分页请求函数
167
+ */
168
+ type PagingFetcher<T> = (page: number, limit: number) => Promise<PagingResult<T>>;
169
+ /**
170
+ * 分页配置选项
171
+ */
172
+ interface PagingOptions {
173
+ /** 每页条数(默认 20) */
174
+ limit?: number;
175
+ /** 组件挂载时是否立即发起首次请求(默认 true) */
176
+ immediate?: boolean;
177
+ /** 是否自动接管页面级下拉刷新与触底加载(默认 true) */
178
+ autoLifecycle?: boolean;
179
+ }
180
+ /**
181
+ * 分页返回值接口
182
+ */
183
+ interface UsePagingReturn<T> {
184
+ list: Ref<T[]>;
185
+ page: Ref<number>;
186
+ limit: Ref<number>;
187
+ total: Ref<number>;
188
+ loading: Ref<boolean>;
189
+ loadingMore: Ref<boolean>;
190
+ hasMore: Ref<boolean>;
191
+ refresh: () => Promise<void>;
192
+ loadMore: () => Promise<void>;
193
+ reset: () => void;
194
+ }
195
+ /**
196
+ * 通用分页数据流 Hook
197
+ * 自动接管分页页码递增、下拉刷新、触底加载与加载状态维护
198
+ *
199
+ * @param fetcher 数据请求函数
200
+ * @param options 配置参数
201
+ */
202
+ declare function usePaging<T>(fetcher: PagingFetcher<T>, options?: PagingOptions): UsePagingReturn<T>;
203
+
204
+ export { DEFAULT_THEME, type FontFamily, type FontFamilyPreset, type FontSize, type FontSizePreset, type InitThemeOptions, type PagingFetcher, type PagingOptions, type PagingResult, type ShareInfo, type ShareResolver, THEME_COLORS, type ThemeColor, type ThemeMode, type ThemeState, type UsePagingReturn, type UseRefsReturn, applyTheme, fontFamilyPresets, fontSizePresets, getTheme, initTheme, usePaging, useRefs, useShare, useTheme, useThemeStore };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import * as vue from 'vue';
2
- import { App, Ref } from 'vue';
3
1
  import * as pinia from 'pinia';
2
+ import * as vue from 'vue';
3
+ import { Ref } from 'vue';
4
4
 
5
5
  declare module "pinia" {
6
6
  interface DefineStoreOptionsBase<S, Store> {
@@ -33,13 +33,13 @@ interface InitThemeOptions {
33
33
  }
34
34
  /** 字体大小预设项 */
35
35
  interface FontSizePreset {
36
- id: string;
36
+ id: FontSize;
37
37
  name: string;
38
38
  class: string;
39
39
  }
40
40
  /** 字体样式预设项 */
41
41
  interface FontFamilyPreset {
42
- id: string;
42
+ id: FontFamily;
43
43
  name: string;
44
44
  class: string;
45
45
  }
@@ -52,13 +52,21 @@ declare const fontSizePresets: FontSizePreset[];
52
52
  /** 字体样式预设表 */
53
53
  declare const fontFamilyPresets: FontFamilyPreset[];
54
54
  /** 主题状态 Store */
55
- declare const useThemeStore: pinia.StoreDefinition<"theme", ThemeState, {}, {}>;
55
+ declare const useThemeStore: pinia.StoreDefinition<"theme", ThemeState, {}, {
56
+ setMode(targetMode: ThemeMode): void;
57
+ setColor(hexColor: string): void;
58
+ setFontSize(targetSize: string): void;
59
+ setFontFamily(targetFont: string): void;
60
+ resetTheme(): void;
61
+ applyTheme(themeState: Partial<ThemeState>): void;
62
+ }>;
63
+
56
64
  /** 获取存储配置 */
57
65
  declare function getTheme(): ThemeState;
58
66
  /** 应用主题状态 */
59
67
  declare function applyTheme(themeState: Partial<ThemeState>): void;
60
68
  /** 初始化主题系统 */
61
- declare function initTheme(app: App, options?: InitThemeOptions): void;
69
+ declare function initTheme(app: any, options?: InitThemeOptions): void;
62
70
  /** 主题组合式函数 */
63
71
  declare function useTheme(): {
64
72
  mode: vue.Ref<ThemeMode, ThemeMode>;
@@ -78,7 +86,14 @@ declare function useTheme(): {
78
86
  applyTheme: typeof applyTheme;
79
87
  getTheme: typeof getTheme;
80
88
  initTheme: typeof initTheme;
81
- store: pinia.Store<"theme", ThemeState, {}, {}>;
89
+ store: pinia.Store<"theme", ThemeState, {}, {
90
+ setMode(targetMode: ThemeMode): void;
91
+ setColor(hexColor: string): void;
92
+ setFontSize(targetSize: string): void;
93
+ setFontFamily(targetFont: string): void;
94
+ resetTheme(): void;
95
+ applyTheme(themeState: Partial<ThemeState>): void;
96
+ }>;
82
97
  };
83
98
 
84
99
  /**
@@ -113,4 +128,77 @@ interface UseRefsReturn<T = unknown> {
113
128
  */
114
129
  declare function useRefs<T = unknown>(): UseRefsReturn<T>;
115
130
 
116
- export { DEFAULT_THEME, type FontFamily, type FontFamilyPreset, type FontSize, type FontSizePreset, type InitThemeOptions, THEME_COLORS, type ThemeColor, type ThemeMode, type ThemeState, type UseRefsReturn, applyTheme, fontFamilyPresets, fontSizePresets, getTheme, initTheme, useRefs, useTheme, useThemeStore };
131
+ /**
132
+ * 分享信息配置
133
+ */
134
+ interface ShareInfo {
135
+ /** 转发标题 */
136
+ title?: string;
137
+ /** 转发页面路径(可带 query 参数) */
138
+ path?: string;
139
+ /** 自定义分享封面图 URL 或本地路径 */
140
+ imageUrl?: string;
141
+ /** 分享到朋友圈的 query 参数(默认自动从 path 中提取) */
142
+ query?: string;
143
+ }
144
+ /** 分享配置解析器(支持对象或返回对象的函数) */
145
+ type ShareResolver = ShareInfo | (() => ShareInfo);
146
+ /**
147
+ * 通用小程序分享 Hook
148
+ * 自动激活小程序转发与朋友圈菜单,并统一接管分享标题与路径生成
149
+ *
150
+ * @param resolver 静态分享配置或动态计算函数
151
+ * @param onTrigger 触发分享时的动作回调(如打点统计,入参 from 代表触发源:menu 或 button)
152
+ */
153
+ declare function useShare(resolver?: ShareResolver, onTrigger?: (from: string) => void): {
154
+ onShareAppMessage: (custom?: ShareInfo) => void;
155
+ onShareTimeline: (custom?: ShareInfo) => void;
156
+ };
157
+
158
+ /**
159
+ * 分页数据接口返回格式
160
+ */
161
+ type PagingResult<T> = {
162
+ list: T[];
163
+ total?: number;
164
+ } | T[];
165
+ /**
166
+ * 分页请求函数
167
+ */
168
+ type PagingFetcher<T> = (page: number, limit: number) => Promise<PagingResult<T>>;
169
+ /**
170
+ * 分页配置选项
171
+ */
172
+ interface PagingOptions {
173
+ /** 每页条数(默认 20) */
174
+ limit?: number;
175
+ /** 组件挂载时是否立即发起首次请求(默认 true) */
176
+ immediate?: boolean;
177
+ /** 是否自动接管页面级下拉刷新与触底加载(默认 true) */
178
+ autoLifecycle?: boolean;
179
+ }
180
+ /**
181
+ * 分页返回值接口
182
+ */
183
+ interface UsePagingReturn<T> {
184
+ list: Ref<T[]>;
185
+ page: Ref<number>;
186
+ limit: Ref<number>;
187
+ total: Ref<number>;
188
+ loading: Ref<boolean>;
189
+ loadingMore: Ref<boolean>;
190
+ hasMore: Ref<boolean>;
191
+ refresh: () => Promise<void>;
192
+ loadMore: () => Promise<void>;
193
+ reset: () => void;
194
+ }
195
+ /**
196
+ * 通用分页数据流 Hook
197
+ * 自动接管分页页码递增、下拉刷新、触底加载与加载状态维护
198
+ *
199
+ * @param fetcher 数据请求函数
200
+ * @param options 配置参数
201
+ */
202
+ declare function usePaging<T>(fetcher: PagingFetcher<T>, options?: PagingOptions): UsePagingReturn<T>;
203
+
204
+ export { DEFAULT_THEME, type FontFamily, type FontFamilyPreset, type FontSize, type FontSizePreset, type InitThemeOptions, type PagingFetcher, type PagingOptions, type PagingResult, type ShareInfo, type ShareResolver, THEME_COLORS, type ThemeColor, type ThemeMode, type ThemeState, type UsePagingReturn, type UseRefsReturn, applyTheme, fontFamilyPresets, fontSizePresets, getTheme, initTheme, usePaging, useRefs, useShare, useTheme, useThemeStore };
package/dist/index.js CHANGED
@@ -27,7 +27,9 @@ __export(index_exports, {
27
27
  fontSizePresets: () => fontSizePresets,
28
28
  getTheme: () => getTheme,
29
29
  initTheme: () => initTheme,
30
+ usePaging: () => usePaging,
30
31
  useRefs: () => useRefs,
32
+ useShare: () => useShare,
31
33
  useTheme: () => useTheme,
32
34
  useThemeStore: () => useThemeStore
33
35
  });
@@ -35,6 +37,9 @@ module.exports = __toCommonJS(index_exports);
35
37
 
36
38
  // src/theme/index.ts
37
39
  var import_vue = require("vue");
40
+ var import_pinia2 = require("pinia");
41
+
42
+ // src/theme/store.ts
38
43
  var import_pinia = require("pinia");
39
44
  var DEFAULT_THEME = {
40
45
  mode: "light",
@@ -72,8 +77,45 @@ var useThemeStore = (0, import_pinia.defineStore)("theme", {
72
77
  fontSize: "standard",
73
78
  fontFamily: "system"
74
79
  }),
80
+ actions: {
81
+ setMode(targetMode) {
82
+ this.mode = targetMode;
83
+ },
84
+ setColor(hexColor) {
85
+ this.color = hexColor;
86
+ },
87
+ setFontSize(targetSize) {
88
+ if (["small", "standard", "large", "extra-large"].includes(targetSize)) {
89
+ this.fontSize = targetSize;
90
+ }
91
+ },
92
+ setFontFamily(targetFont) {
93
+ if (["system", "sans", "serif", "kaiti"].includes(targetFont)) {
94
+ this.fontFamily = targetFont;
95
+ }
96
+ },
97
+ resetTheme() {
98
+ Object.assign(this, DEFAULT_THEME);
99
+ },
100
+ applyTheme(themeState) {
101
+ if (themeState.mode) {
102
+ this.mode = themeState.mode;
103
+ }
104
+ if (themeState.color) {
105
+ this.color = themeState.color;
106
+ }
107
+ if (themeState.fontSize && ["small", "standard", "large", "extra-large"].includes(themeState.fontSize)) {
108
+ this.fontSize = themeState.fontSize;
109
+ }
110
+ if (themeState.fontFamily && ["system", "sans", "serif", "kaiti"].includes(themeState.fontFamily)) {
111
+ this.fontFamily = themeState.fontFamily;
112
+ }
113
+ }
114
+ },
75
115
  unistorage: true
76
116
  });
117
+
118
+ // src/theme/index.ts
77
119
  function getTheme() {
78
120
  const store = useThemeStore();
79
121
  return {
@@ -85,14 +127,7 @@ function getTheme() {
85
127
  }
86
128
  function applyTheme(themeState) {
87
129
  const store = useThemeStore();
88
- if (themeState.mode) store.mode = themeState.mode;
89
- if (themeState.color) store.color = themeState.color;
90
- if (themeState.fontSize && ["small", "standard", "large", "extra-large"].includes(themeState.fontSize)) {
91
- store.fontSize = themeState.fontSize;
92
- }
93
- if (themeState.fontFamily && ["system", "sans", "serif", "kaiti"].includes(themeState.fontFamily)) {
94
- store.fontFamily = themeState.fontFamily;
95
- }
130
+ store.applyTheme(themeState);
96
131
  }
97
132
  function initTheme(app, options = {}) {
98
133
  const { sync = true, defaultTheme } = options;
@@ -104,7 +139,7 @@ function initTheme(app, options = {}) {
104
139
  }
105
140
  function useTheme() {
106
141
  const store = useThemeStore();
107
- const { mode, color, fontSize, fontFamily } = (0, import_pinia.storeToRefs)(store);
142
+ const { mode, color, fontSize, fontFamily } = (0, import_pinia2.storeToRefs)(store);
108
143
  const fontSizeClass = (0, import_vue.computed)(() => {
109
144
  return fontSizePresets.find((item) => item.id === store.fontSize)?.class || "font-size-standard";
110
145
  });
@@ -121,25 +156,11 @@ function useTheme() {
121
156
  colors: THEME_COLORS,
122
157
  fontSizePresets,
123
158
  fontFamilyPresets,
124
- setMode: (targetMode) => {
125
- store.mode = targetMode;
126
- },
127
- setColor: (hexColor) => {
128
- store.color = hexColor;
129
- },
130
- setFontSize: (targetSize) => {
131
- if (["small", "standard", "large", "extra-large"].includes(targetSize)) {
132
- store.fontSize = targetSize;
133
- }
134
- },
135
- setFontFamily: (targetFont) => {
136
- if (["system", "sans", "serif", "kaiti"].includes(targetFont)) {
137
- store.fontFamily = targetFont;
138
- }
139
- },
140
- resetTheme: () => {
141
- Object.assign(store, DEFAULT_THEME);
142
- },
159
+ setMode: (targetMode) => store.setMode(targetMode),
160
+ setColor: (hexColor) => store.setColor(hexColor),
161
+ setFontSize: (targetSize) => store.setFontSize(targetSize),
162
+ setFontFamily: (targetFont) => store.setFontFamily(targetFont),
163
+ resetTheme: () => store.resetTheme(),
143
164
  applyTheme,
144
165
  getTheme,
145
166
  initTheme,
@@ -162,6 +183,144 @@ function useRefs() {
162
183
  };
163
184
  return { refs, setRefs };
164
185
  }
186
+
187
+ // src/share/index.ts
188
+ var import_uni_app = require("@dcloudio/uni-app");
189
+ function useShare(resolver, onTrigger) {
190
+ function resolveOptions(custom) {
191
+ const base = typeof resolver === "function" ? resolver() : resolver || {};
192
+ return {
193
+ title: custom?.title || base.title,
194
+ path: custom?.path || base.path,
195
+ imageUrl: custom?.imageUrl || base.imageUrl,
196
+ query: custom?.query || base.query
197
+ };
198
+ }
199
+ function shareApp(custom) {
200
+ (0, import_uni_app.onShareAppMessage)((res) => {
201
+ onTrigger?.(String(res?.from || "menu"));
202
+ const opts = resolveOptions(custom);
203
+ return {
204
+ ...opts.title ? { title: opts.title } : {},
205
+ ...opts.path ? { path: opts.path } : {},
206
+ ...opts.imageUrl ? { imageUrl: opts.imageUrl } : {}
207
+ };
208
+ });
209
+ }
210
+ function shareTime(custom) {
211
+ (0, import_uni_app.onShareTimeline)(() => {
212
+ const opts = resolveOptions(custom);
213
+ const queryFromPath = opts.path?.includes("?") ? opts.path.split("?")[1] : void 0;
214
+ return {
215
+ ...opts.title ? { title: opts.title } : {},
216
+ ...opts.imageUrl ? { imageUrl: opts.imageUrl } : {},
217
+ query: opts.query || queryFromPath
218
+ };
219
+ });
220
+ }
221
+ if (typeof uni !== "undefined" && typeof uni.showShareMenu === "function") {
222
+ uni.showShareMenu({
223
+ withShareTicket: true,
224
+ menus: ["shareAppMessage", "shareTimeline"]
225
+ });
226
+ }
227
+ return {
228
+ onShareAppMessage: shareApp,
229
+ onShareTimeline: shareTime
230
+ };
231
+ }
232
+
233
+ // src/paging/index.ts
234
+ var import_vue3 = require("vue");
235
+ var import_uni_app2 = require("@dcloudio/uni-app");
236
+ function usePaging(fetcher, options = {}) {
237
+ const limitNum = options.limit || 20;
238
+ const immediate = options.immediate !== false;
239
+ const autoLifecycle = options.autoLifecycle !== false;
240
+ const list = (0, import_vue3.ref)([]);
241
+ const page = (0, import_vue3.ref)(1);
242
+ const limit = (0, import_vue3.ref)(limitNum);
243
+ const total = (0, import_vue3.ref)(0);
244
+ const loading = (0, import_vue3.ref)(false);
245
+ const loadingMore = (0, import_vue3.ref)(false);
246
+ const hasMore = (0, import_vue3.ref)(true);
247
+ async function loadData(isInit = false) {
248
+ if (isInit) {
249
+ loading.value = true;
250
+ page.value = 1;
251
+ hasMore.value = true;
252
+ } else {
253
+ loadingMore.value = true;
254
+ }
255
+ try {
256
+ const res = await fetcher(page.value, limit.value);
257
+ const items = Array.isArray(res) ? res : res.list || [];
258
+ const resTotal = !Array.isArray(res) && typeof res.total === "number" ? res.total : 0;
259
+ if (isInit) {
260
+ list.value = items;
261
+ } else {
262
+ list.value = [...list.value, ...items];
263
+ }
264
+ total.value = resTotal || list.value.length;
265
+ hasMore.value = items.length >= limit.value;
266
+ } finally {
267
+ if (isInit) {
268
+ loading.value = false;
269
+ } else {
270
+ loadingMore.value = false;
271
+ }
272
+ }
273
+ }
274
+ async function refresh() {
275
+ await loadData(true);
276
+ }
277
+ async function loadMore() {
278
+ if (!hasMore.value || loading.value || loadingMore.value) {
279
+ return;
280
+ }
281
+ page.value += 1;
282
+ await loadData(false);
283
+ }
284
+ function reset() {
285
+ list.value = [];
286
+ page.value = 1;
287
+ total.value = 0;
288
+ loading.value = false;
289
+ loadingMore.value = false;
290
+ hasMore.value = true;
291
+ }
292
+ if (autoLifecycle) {
293
+ (0, import_uni_app2.onPullDownRefresh)(async () => {
294
+ try {
295
+ await refresh();
296
+ } finally {
297
+ if (typeof uni !== "undefined" && typeof uni.stopPullDownRefresh === "function") {
298
+ uni.stopPullDownRefresh();
299
+ }
300
+ }
301
+ });
302
+ (0, import_uni_app2.onReachBottom)(() => {
303
+ loadMore();
304
+ });
305
+ }
306
+ if (immediate) {
307
+ (0, import_vue3.onMounted)(() => {
308
+ loadData(true);
309
+ });
310
+ }
311
+ return {
312
+ list,
313
+ page,
314
+ limit,
315
+ total,
316
+ loading,
317
+ loadingMore,
318
+ hasMore,
319
+ refresh,
320
+ loadMore,
321
+ reset
322
+ };
323
+ }
165
324
  // Annotate the CommonJS export names for ESM import in node:
166
325
  0 && (module.exports = {
167
326
  DEFAULT_THEME,
@@ -171,7 +330,9 @@ function useRefs() {
171
330
  fontSizePresets,
172
331
  getTheme,
173
332
  initTheme,
333
+ usePaging,
174
334
  useRefs,
335
+ useShare,
175
336
  useTheme,
176
337
  useThemeStore
177
338
  });
package/dist/index.mjs CHANGED
@@ -1,6 +1,9 @@
1
1
  // src/theme/index.ts
2
2
  import { computed } from "vue";
3
- import { defineStore, storeToRefs } from "pinia";
3
+ import { storeToRefs } from "pinia";
4
+
5
+ // src/theme/store.ts
6
+ import { defineStore } from "pinia";
4
7
  var DEFAULT_THEME = {
5
8
  mode: "light",
6
9
  color: "#08c060",
@@ -37,8 +40,45 @@ var useThemeStore = defineStore("theme", {
37
40
  fontSize: "standard",
38
41
  fontFamily: "system"
39
42
  }),
43
+ actions: {
44
+ setMode(targetMode) {
45
+ this.mode = targetMode;
46
+ },
47
+ setColor(hexColor) {
48
+ this.color = hexColor;
49
+ },
50
+ setFontSize(targetSize) {
51
+ if (["small", "standard", "large", "extra-large"].includes(targetSize)) {
52
+ this.fontSize = targetSize;
53
+ }
54
+ },
55
+ setFontFamily(targetFont) {
56
+ if (["system", "sans", "serif", "kaiti"].includes(targetFont)) {
57
+ this.fontFamily = targetFont;
58
+ }
59
+ },
60
+ resetTheme() {
61
+ Object.assign(this, DEFAULT_THEME);
62
+ },
63
+ applyTheme(themeState) {
64
+ if (themeState.mode) {
65
+ this.mode = themeState.mode;
66
+ }
67
+ if (themeState.color) {
68
+ this.color = themeState.color;
69
+ }
70
+ if (themeState.fontSize && ["small", "standard", "large", "extra-large"].includes(themeState.fontSize)) {
71
+ this.fontSize = themeState.fontSize;
72
+ }
73
+ if (themeState.fontFamily && ["system", "sans", "serif", "kaiti"].includes(themeState.fontFamily)) {
74
+ this.fontFamily = themeState.fontFamily;
75
+ }
76
+ }
77
+ },
40
78
  unistorage: true
41
79
  });
80
+
81
+ // src/theme/index.ts
42
82
  function getTheme() {
43
83
  const store = useThemeStore();
44
84
  return {
@@ -50,14 +90,7 @@ function getTheme() {
50
90
  }
51
91
  function applyTheme(themeState) {
52
92
  const store = useThemeStore();
53
- if (themeState.mode) store.mode = themeState.mode;
54
- if (themeState.color) store.color = themeState.color;
55
- if (themeState.fontSize && ["small", "standard", "large", "extra-large"].includes(themeState.fontSize)) {
56
- store.fontSize = themeState.fontSize;
57
- }
58
- if (themeState.fontFamily && ["system", "sans", "serif", "kaiti"].includes(themeState.fontFamily)) {
59
- store.fontFamily = themeState.fontFamily;
60
- }
93
+ store.applyTheme(themeState);
61
94
  }
62
95
  function initTheme(app, options = {}) {
63
96
  const { sync = true, defaultTheme } = options;
@@ -86,25 +119,11 @@ function useTheme() {
86
119
  colors: THEME_COLORS,
87
120
  fontSizePresets,
88
121
  fontFamilyPresets,
89
- setMode: (targetMode) => {
90
- store.mode = targetMode;
91
- },
92
- setColor: (hexColor) => {
93
- store.color = hexColor;
94
- },
95
- setFontSize: (targetSize) => {
96
- if (["small", "standard", "large", "extra-large"].includes(targetSize)) {
97
- store.fontSize = targetSize;
98
- }
99
- },
100
- setFontFamily: (targetFont) => {
101
- if (["system", "sans", "serif", "kaiti"].includes(targetFont)) {
102
- store.fontFamily = targetFont;
103
- }
104
- },
105
- resetTheme: () => {
106
- Object.assign(store, DEFAULT_THEME);
107
- },
122
+ setMode: (targetMode) => store.setMode(targetMode),
123
+ setColor: (hexColor) => store.setColor(hexColor),
124
+ setFontSize: (targetSize) => store.setFontSize(targetSize),
125
+ setFontFamily: (targetFont) => store.setFontFamily(targetFont),
126
+ resetTheme: () => store.resetTheme(),
108
127
  applyTheme,
109
128
  getTheme,
110
129
  initTheme,
@@ -127,6 +146,144 @@ function useRefs() {
127
146
  };
128
147
  return { refs, setRefs };
129
148
  }
149
+
150
+ // src/share/index.ts
151
+ import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
152
+ function useShare(resolver, onTrigger) {
153
+ function resolveOptions(custom) {
154
+ const base = typeof resolver === "function" ? resolver() : resolver || {};
155
+ return {
156
+ title: custom?.title || base.title,
157
+ path: custom?.path || base.path,
158
+ imageUrl: custom?.imageUrl || base.imageUrl,
159
+ query: custom?.query || base.query
160
+ };
161
+ }
162
+ function shareApp(custom) {
163
+ onShareAppMessage((res) => {
164
+ onTrigger?.(String(res?.from || "menu"));
165
+ const opts = resolveOptions(custom);
166
+ return {
167
+ ...opts.title ? { title: opts.title } : {},
168
+ ...opts.path ? { path: opts.path } : {},
169
+ ...opts.imageUrl ? { imageUrl: opts.imageUrl } : {}
170
+ };
171
+ });
172
+ }
173
+ function shareTime(custom) {
174
+ onShareTimeline(() => {
175
+ const opts = resolveOptions(custom);
176
+ const queryFromPath = opts.path?.includes("?") ? opts.path.split("?")[1] : void 0;
177
+ return {
178
+ ...opts.title ? { title: opts.title } : {},
179
+ ...opts.imageUrl ? { imageUrl: opts.imageUrl } : {},
180
+ query: opts.query || queryFromPath
181
+ };
182
+ });
183
+ }
184
+ if (typeof uni !== "undefined" && typeof uni.showShareMenu === "function") {
185
+ uni.showShareMenu({
186
+ withShareTicket: true,
187
+ menus: ["shareAppMessage", "shareTimeline"]
188
+ });
189
+ }
190
+ return {
191
+ onShareAppMessage: shareApp,
192
+ onShareTimeline: shareTime
193
+ };
194
+ }
195
+
196
+ // src/paging/index.ts
197
+ import { ref as ref2, onMounted } from "vue";
198
+ import { onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
199
+ function usePaging(fetcher, options = {}) {
200
+ const limitNum = options.limit || 20;
201
+ const immediate = options.immediate !== false;
202
+ const autoLifecycle = options.autoLifecycle !== false;
203
+ const list = ref2([]);
204
+ const page = ref2(1);
205
+ const limit = ref2(limitNum);
206
+ const total = ref2(0);
207
+ const loading = ref2(false);
208
+ const loadingMore = ref2(false);
209
+ const hasMore = ref2(true);
210
+ async function loadData(isInit = false) {
211
+ if (isInit) {
212
+ loading.value = true;
213
+ page.value = 1;
214
+ hasMore.value = true;
215
+ } else {
216
+ loadingMore.value = true;
217
+ }
218
+ try {
219
+ const res = await fetcher(page.value, limit.value);
220
+ const items = Array.isArray(res) ? res : res.list || [];
221
+ const resTotal = !Array.isArray(res) && typeof res.total === "number" ? res.total : 0;
222
+ if (isInit) {
223
+ list.value = items;
224
+ } else {
225
+ list.value = [...list.value, ...items];
226
+ }
227
+ total.value = resTotal || list.value.length;
228
+ hasMore.value = items.length >= limit.value;
229
+ } finally {
230
+ if (isInit) {
231
+ loading.value = false;
232
+ } else {
233
+ loadingMore.value = false;
234
+ }
235
+ }
236
+ }
237
+ async function refresh() {
238
+ await loadData(true);
239
+ }
240
+ async function loadMore() {
241
+ if (!hasMore.value || loading.value || loadingMore.value) {
242
+ return;
243
+ }
244
+ page.value += 1;
245
+ await loadData(false);
246
+ }
247
+ function reset() {
248
+ list.value = [];
249
+ page.value = 1;
250
+ total.value = 0;
251
+ loading.value = false;
252
+ loadingMore.value = false;
253
+ hasMore.value = true;
254
+ }
255
+ if (autoLifecycle) {
256
+ onPullDownRefresh(async () => {
257
+ try {
258
+ await refresh();
259
+ } finally {
260
+ if (typeof uni !== "undefined" && typeof uni.stopPullDownRefresh === "function") {
261
+ uni.stopPullDownRefresh();
262
+ }
263
+ }
264
+ });
265
+ onReachBottom(() => {
266
+ loadMore();
267
+ });
268
+ }
269
+ if (immediate) {
270
+ onMounted(() => {
271
+ loadData(true);
272
+ });
273
+ }
274
+ return {
275
+ list,
276
+ page,
277
+ limit,
278
+ total,
279
+ loading,
280
+ loadingMore,
281
+ hasMore,
282
+ refresh,
283
+ loadMore,
284
+ reset
285
+ };
286
+ }
130
287
  export {
131
288
  DEFAULT_THEME,
132
289
  THEME_COLORS,
@@ -135,7 +292,9 @@ export {
135
292
  fontSizePresets,
136
293
  getTheme,
137
294
  initTheme,
295
+ usePaging,
138
296
  useRefs,
297
+ useShare,
139
298
  useTheme,
140
299
  useThemeStore
141
300
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hlw-uni-mp/use",
3
- "version": "1.1.6",
3
+ "version": "1.1.9",
4
4
  "description": "Universal Uni-App Vue 3 stateful composables library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -15,10 +15,6 @@
15
15
  "files": [
16
16
  "dist"
17
17
  ],
18
- "scripts": {
19
- "build": "tsup",
20
- "dev": "tsup --watch"
21
- },
22
18
  "publishConfig": {
23
19
  "access": "public"
24
20
  },
@@ -39,5 +35,9 @@
39
35
  "tsup": "^8.5.1",
40
36
  "typescript": "^5.9.3",
41
37
  "vue": "^3.5.34"
38
+ },
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch"
42
42
  }
43
- }
43
+ }