@hlw-uni/mp-vue 1.0.11 → 1.0.13

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.ts CHANGED
@@ -7,6 +7,8 @@ export { default as HlwCard } from './components/hlw-card/index.vue';
7
7
  export { default as HlwEmpty } from './components/hlw-empty/index.vue';
8
8
  export { default as HlwHeader } from './components/hlw-header/index.vue';
9
9
  export { default as HlwLoading } from './components/hlw-loading/index.vue';
10
+ export { default as HlwMenu } from './components/hlw-menu/index.vue';
11
+ export type { HlwMenuItem } from './components/hlw-menu/index.vue';
10
12
  export { default as HlwMenuList } from './components/hlw-menu-list/index.vue';
11
13
  export { default as HlwPage } from './components/hlw-page/index.vue';
12
14
  export type { MenuItem } from './components/hlw-menu-list/types';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
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
3
  })(this, function(exports2, vue) {
4
4
  "use strict";
5
- const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
5
+ const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
6
6
  ...{ name: "HlwAd" },
7
7
  __name: "index",
8
8
  props: {
@@ -33,13 +33,13 @@
33
33
  };
34
34
  }
35
35
  });
36
- const _hoisted_1$6 = ["src"];
37
- const _hoisted_2$6 = {
36
+ const _hoisted_1$7 = ["src"];
37
+ const _hoisted_2$7 = {
38
38
  key: 1,
39
39
  class: "hlw-avatar__placeholder"
40
40
  };
41
- const _hoisted_3$4 = { class: "hlw-avatar__initial" };
42
- const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
41
+ const _hoisted_3$5 = { class: "hlw-avatar__initial" };
42
+ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
43
43
  __name: "index",
44
44
  props: {
45
45
  src: {},
@@ -64,8 +64,8 @@
64
64
  src: __props.src,
65
65
  mode: "aspectFill",
66
66
  onError: _cache[0] || (_cache[0] = ($event) => loadError.value = true)
67
- }, null, 40, _hoisted_1$6)) : (vue.openBlock(), vue.createElementBlock("view", _hoisted_2$6, [
68
- vue.createElementVNode("text", _hoisted_3$4, vue.toDisplayString(initial.value), 1)
67
+ }, null, 40, _hoisted_1$7)) : (vue.openBlock(), vue.createElementBlock("view", _hoisted_2$7, [
68
+ vue.createElementVNode("text", _hoisted_3$5, vue.toDisplayString(initial.value), 1)
69
69
  ]))
70
70
  ], 2);
71
71
  };
@@ -78,13 +78,13 @@
78
78
  }
79
79
  return target;
80
80
  };
81
- const index$6 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-7e8f98a5"]]);
82
- const _hoisted_1$5 = { class: "hlw-card" };
83
- const _hoisted_2$5 = {
81
+ const index$7 = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-7e8f98a5"]]);
82
+ const _hoisted_1$6 = { class: "hlw-card" };
83
+ const _hoisted_2$6 = {
84
84
  key: 0,
85
85
  class: "hlw-card-header"
86
86
  };
87
- const _hoisted_3$3 = { class: "flex items-center justify-between px-5 py-4 border-0 border-b border-dashed border-slate-200 bg-slate-50/30" };
87
+ const _hoisted_3$4 = { class: "flex items-center justify-between px-5 py-4 border-0 border-b border-dashed border-slate-200 bg-slate-50/30" };
88
88
  const _hoisted_4$2 = { key: 0 };
89
89
  const _hoisted_5$1 = { class: "text-sm font-bold text-slate-800 flex items-center gap-2 tracking-wide" };
90
90
  const _hoisted_6$1 = { key: 1 };
@@ -93,7 +93,7 @@
93
93
  class: "text-[10px] text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100 tracking-wide"
94
94
  };
95
95
  const _hoisted_8 = { class: "hlw-card-body" };
96
- const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
96
+ const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
97
97
  ...{
98
98
  options: {
99
99
  styleIsolation: "shared",
@@ -109,10 +109,10 @@
109
109
  },
110
110
  setup(__props) {
111
111
  return (_ctx, _cache) => {
112
- return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$5, [
113
- _ctx.$slots.header || __props.title || __props.icon || _ctx.$slots["header-left"] || _ctx.$slots["header-right"] ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_2$5, [
112
+ return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$6, [
113
+ _ctx.$slots.header || __props.title || __props.icon || _ctx.$slots["header-left"] || _ctx.$slots["header-right"] ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_2$6, [
114
114
  vue.renderSlot(_ctx.$slots, "header", {}, () => [
115
- vue.createElementVNode("view", _hoisted_3$3, [
115
+ vue.createElementVNode("view", _hoisted_3$4, [
116
116
  _ctx.$slots["header-left"] || __props.title || __props.icon ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_4$2, [
117
117
  vue.renderSlot(_ctx.$slots, "header-left", {}, () => [
118
118
  vue.createElementVNode("view", _hoisted_5$1, [
@@ -139,15 +139,15 @@
139
139
  };
140
140
  }
141
141
  });
142
- const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-787fc3a7"]]);
143
- const _hoisted_1$4 = { class: "hlw-empty" };
144
- const _hoisted_2$4 = ["src"];
145
- const _hoisted_3$2 = {
142
+ const index$6 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-787fc3a7"]]);
143
+ const _hoisted_1$5 = { class: "hlw-empty" };
144
+ const _hoisted_2$5 = ["src"];
145
+ const _hoisted_3$3 = {
146
146
  key: 1,
147
147
  class: "hlw-empty__icon"
148
148
  };
149
149
  const _hoisted_4$1 = { class: "hlw-empty__text" };
150
- const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
150
+ const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
151
151
  __name: "index",
152
152
  props: {
153
153
  text: {},
@@ -155,29 +155,29 @@
155
155
  },
156
156
  setup(__props) {
157
157
  return (_ctx, _cache) => {
158
- return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$4, [
158
+ return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$5, [
159
159
  __props.image ? (vue.openBlock(), vue.createElementBlock("image", {
160
160
  key: 0,
161
161
  class: "hlw-empty__image",
162
162
  src: __props.image,
163
163
  mode: "aspectFit"
164
- }, null, 8, _hoisted_2$4)) : (vue.openBlock(), vue.createElementBlock("text", _hoisted_3$2, "📦")),
164
+ }, null, 8, _hoisted_2$5)) : (vue.openBlock(), vue.createElementBlock("text", _hoisted_3$3, "📦")),
165
165
  vue.createElementVNode("text", _hoisted_4$1, vue.toDisplayString(__props.text || "暂无数据"), 1),
166
166
  vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
167
167
  ]);
168
168
  };
169
169
  }
170
170
  });
171
- const index$4 = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-72364322"]]);
172
- const _hoisted_1$3 = {
171
+ const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-72364322"]]);
172
+ const _hoisted_1$4 = {
173
173
  key: 0,
174
174
  class: "header-placeholder"
175
175
  };
176
- const _hoisted_2$3 = {
176
+ const _hoisted_2$4 = {
177
177
  key: 0,
178
178
  class: "header-title header-title--center"
179
179
  };
180
- const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
180
+ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
181
181
  __name: "index",
182
182
  props: {
183
183
  extraHeight: { default: 0 },
@@ -264,9 +264,9 @@
264
264
  }, vue.toDisplayString(props.title), 5)
265
265
  ], true)
266
266
  ], 2),
267
- props.titleAlign === "center" ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_1$3)) : vue.createCommentVNode("", true)
267
+ props.titleAlign === "center" ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_1$4)) : vue.createCommentVNode("", true)
268
268
  ], 64)) : vue.renderSlot(_ctx.$slots, "default", { key: 1 }, () => [
269
- props.title ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_2$3, [
269
+ props.title ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_2$4, [
270
270
  vue.createElementVNode("text", {
271
271
  class: "header-title-text",
272
272
  style: vue.normalizeStyle(titleStyle.value)
@@ -278,27 +278,111 @@
278
278
  };
279
279
  }
280
280
  });
281
- const index$3 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-9a6c839c"]]);
282
- const _hoisted_1$2 = { class: "hlw-loading" };
283
- const _hoisted_2$2 = {
281
+ const index$4 = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-9a6c839c"]]);
282
+ const _hoisted_1$3 = { class: "hlw-loading" };
283
+ const _hoisted_2$3 = {
284
284
  key: 0,
285
285
  class: "hlw-loading__text"
286
286
  };
287
- const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
287
+ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
288
288
  __name: "index",
289
289
  props: {
290
290
  text: {}
291
291
  },
292
292
  setup(__props) {
293
293
  return (_ctx, _cache) => {
294
- return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$2, [
294
+ return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$3, [
295
295
  _cache[0] || (_cache[0] = vue.createElementVNode("view", { class: "hlw-loading__spinner" }, null, -1)),
296
- __props.text ? (vue.openBlock(), vue.createElementBlock("text", _hoisted_2$2, vue.toDisplayString(__props.text), 1)) : vue.createCommentVNode("", true)
296
+ __props.text ? (vue.openBlock(), vue.createElementBlock("text", _hoisted_2$3, vue.toDisplayString(__props.text), 1)) : vue.createCommentVNode("", true)
297
+ ]);
298
+ };
299
+ }
300
+ });
301
+ const index$3 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-14242381"]]);
302
+ const _hoisted_1$2 = { class: "hlw-menu" };
303
+ const _hoisted_2$2 = ["onClick"];
304
+ const _hoisted_3$2 = {
305
+ key: 2,
306
+ class: "hlw-menu-divider"
307
+ };
308
+ const HlwMenuItemContent = vue.defineComponent({
309
+ name: "HlwMenuItemContent",
310
+ props: {
311
+ item: { type: Object, required: true }
312
+ },
313
+ setup(props) {
314
+ return () => {
315
+ const item = props.item;
316
+ return vue.h("view", { class: "hlw-menu-item-inner" }, [
317
+ // 左侧
318
+ vue.h("view", { class: "hlw-menu-left" }, [
319
+ vue.h("view", { class: `hlw-menu-icon hlw-menu-icon--${item.iconTheme || "slate"}` }, [
320
+ vue.h("text", { class: item.icon })
321
+ ]),
322
+ vue.h("text", { class: "hlw-menu-label" }, item.label)
323
+ ]),
324
+ // 右侧
325
+ vue.h("view", { class: "hlw-menu-right" }, [
326
+ item.loading ? vue.h("text", { class: "i-fa6-solid-circle-notch hlw-menu-spin hlw-menu-muted" }) : null,
327
+ item.tag ? vue.h(
328
+ "text",
329
+ { class: `hlw-menu-tag hlw-menu-tag--${item.tagTheme || "rose"} ${item.tagPulse ? "hlw-menu-tag-pulse" : ""}` },
330
+ item.tag
331
+ ) : null,
332
+ vue.h("text", { class: "i-fa6-solid-chevron-right hlw-menu-arrow" })
333
+ ])
334
+ ]);
335
+ };
336
+ }
337
+ });
338
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
339
+ __name: "index",
340
+ props: {
341
+ items: {}
342
+ },
343
+ emits: ["click"],
344
+ setup(__props, { emit: __emit }) {
345
+ const props = __props;
346
+ const emit = __emit;
347
+ const visibleItems = vue.computed(() => props.items.filter((item) => item.visible !== false));
348
+ const handleClick = (item) => {
349
+ emit("click", item);
350
+ };
351
+ return (_ctx, _cache) => {
352
+ const _component_navigator = vue.resolveComponent("navigator");
353
+ return vue.openBlock(), vue.createElementBlock("view", _hoisted_1$2, [
354
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(visibleItems.value, (item, index2) => {
355
+ return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: index2 }, [
356
+ item.url ? (vue.openBlock(), vue.createBlock(_component_navigator, {
357
+ key: 0,
358
+ url: item.url,
359
+ class: "hlw-menu-item",
360
+ "hover-class": "hlw-menu-item--active"
361
+ }, {
362
+ default: vue.withCtx(() => [
363
+ vue.renderSlot(_ctx.$slots, "item", { item }, () => [
364
+ vue.createVNode(vue.unref(HlwMenuItemContent), { item }, null, 8, ["item"])
365
+ ], true)
366
+ ]),
367
+ _: 2
368
+ }, 1032, ["url"])) : (vue.openBlock(), vue.createElementBlock("view", {
369
+ key: 1,
370
+ class: "hlw-menu-item",
371
+ "hover-class": "hlw-menu-item--active",
372
+ onClick: ($event) => handleClick(item)
373
+ }, [
374
+ vue.renderSlot(_ctx.$slots, "item", { item }, () => [
375
+ vue.createVNode(vue.unref(HlwMenuItemContent), { item }, null, 8, ["item"])
376
+ ], true)
377
+ ], 8, _hoisted_2$2)),
378
+ index2 < visibleItems.value.length - 1 ? (vue.openBlock(), vue.createElementBlock("view", _hoisted_3$2)) : vue.createCommentVNode("", true)
379
+ ], 64);
380
+ }), 128))
297
381
  ]);
298
382
  };
299
383
  }
300
384
  });
301
- const index$2 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-14242381"]]);
385
+ const index$2 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-48deaf95"]]);
302
386
  const _hoisted_1$1 = { class: "hlw-menu-list" };
303
387
  const _hoisted_2$1 = ["onTap"];
304
388
  const _hoisted_3$1 = { class: "hlw-menu-list__left" };
@@ -396,12 +480,13 @@
396
480
  }
397
481
  });
398
482
  const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-155bc02a"]]);
399
- exports2.HlwAd = _sfc_main$7;
400
- exports2.HlwAvatar = index$6;
401
- exports2.HlwCard = index$5;
402
- exports2.HlwEmpty = index$4;
403
- exports2.HlwHeader = index$3;
404
- exports2.HlwLoading = index$2;
483
+ exports2.HlwAd = _sfc_main$8;
484
+ exports2.HlwAvatar = index$7;
485
+ exports2.HlwCard = index$6;
486
+ exports2.HlwEmpty = index$5;
487
+ exports2.HlwHeader = index$4;
488
+ exports2.HlwLoading = index$3;
489
+ exports2.HlwMenu = index$2;
405
490
  exports2.HlwMenuList = index$1;
406
491
  exports2.HlwPage = index;
407
492
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { defineComponent, resolveComponent, openBlock, createBlock, ref, computed, createElementBlock, normalizeClass, createElementVNode, toDisplayString, renderSlot, createCommentVNode, useSlots, normalizeStyle, unref, Fragment, renderList, createVNode, withCtx } from "vue";
2
- const _sfc_main$7 = /* @__PURE__ */ defineComponent({
1
+ import { defineComponent, resolveComponent, openBlock, createBlock, ref, computed, createElementBlock, normalizeClass, createElementVNode, toDisplayString, renderSlot, createCommentVNode, useSlots, normalizeStyle, unref, Fragment, h, renderList, withCtx, createVNode } from "vue";
2
+ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
3
3
  ...{ name: "HlwAd" },
4
4
  __name: "index",
5
5
  props: {
@@ -30,13 +30,13 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
30
30
  };
31
31
  }
32
32
  });
33
- const _hoisted_1$6 = ["src"];
34
- const _hoisted_2$6 = {
33
+ const _hoisted_1$7 = ["src"];
34
+ const _hoisted_2$7 = {
35
35
  key: 1,
36
36
  class: "hlw-avatar__placeholder"
37
37
  };
38
- const _hoisted_3$4 = { class: "hlw-avatar__initial" };
39
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
38
+ const _hoisted_3$5 = { class: "hlw-avatar__initial" };
39
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
40
40
  __name: "index",
41
41
  props: {
42
42
  src: {},
@@ -61,8 +61,8 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
61
61
  src: __props.src,
62
62
  mode: "aspectFill",
63
63
  onError: _cache[0] || (_cache[0] = ($event) => loadError.value = true)
64
- }, null, 40, _hoisted_1$6)) : (openBlock(), createElementBlock("view", _hoisted_2$6, [
65
- createElementVNode("text", _hoisted_3$4, toDisplayString(initial.value), 1)
64
+ }, null, 40, _hoisted_1$7)) : (openBlock(), createElementBlock("view", _hoisted_2$7, [
65
+ createElementVNode("text", _hoisted_3$5, toDisplayString(initial.value), 1)
66
66
  ]))
67
67
  ], 2);
68
68
  };
@@ -75,13 +75,13 @@ const _export_sfc = (sfc, props) => {
75
75
  }
76
76
  return target;
77
77
  };
78
- const index$6 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-7e8f98a5"]]);
79
- const _hoisted_1$5 = { class: "hlw-card" };
80
- const _hoisted_2$5 = {
78
+ const index$7 = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-7e8f98a5"]]);
79
+ const _hoisted_1$6 = { class: "hlw-card" };
80
+ const _hoisted_2$6 = {
81
81
  key: 0,
82
82
  class: "hlw-card-header"
83
83
  };
84
- const _hoisted_3$3 = { class: "flex items-center justify-between px-5 py-4 border-0 border-b border-dashed border-slate-200 bg-slate-50/30" };
84
+ const _hoisted_3$4 = { class: "flex items-center justify-between px-5 py-4 border-0 border-b border-dashed border-slate-200 bg-slate-50/30" };
85
85
  const _hoisted_4$2 = { key: 0 };
86
86
  const _hoisted_5$1 = { class: "text-sm font-bold text-slate-800 flex items-center gap-2 tracking-wide" };
87
87
  const _hoisted_6$1 = { key: 1 };
@@ -90,7 +90,7 @@ const _hoisted_7$1 = {
90
90
  class: "text-[10px] text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100 tracking-wide"
91
91
  };
92
92
  const _hoisted_8 = { class: "hlw-card-body" };
93
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
93
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
94
94
  ...{
95
95
  options: {
96
96
  styleIsolation: "shared",
@@ -106,10 +106,10 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
106
106
  },
107
107
  setup(__props) {
108
108
  return (_ctx, _cache) => {
109
- return openBlock(), createElementBlock("view", _hoisted_1$5, [
110
- _ctx.$slots.header || __props.title || __props.icon || _ctx.$slots["header-left"] || _ctx.$slots["header-right"] ? (openBlock(), createElementBlock("view", _hoisted_2$5, [
109
+ return openBlock(), createElementBlock("view", _hoisted_1$6, [
110
+ _ctx.$slots.header || __props.title || __props.icon || _ctx.$slots["header-left"] || _ctx.$slots["header-right"] ? (openBlock(), createElementBlock("view", _hoisted_2$6, [
111
111
  renderSlot(_ctx.$slots, "header", {}, () => [
112
- createElementVNode("view", _hoisted_3$3, [
112
+ createElementVNode("view", _hoisted_3$4, [
113
113
  _ctx.$slots["header-left"] || __props.title || __props.icon ? (openBlock(), createElementBlock("view", _hoisted_4$2, [
114
114
  renderSlot(_ctx.$slots, "header-left", {}, () => [
115
115
  createElementVNode("view", _hoisted_5$1, [
@@ -136,15 +136,15 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
136
136
  };
137
137
  }
138
138
  });
139
- const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-787fc3a7"]]);
140
- const _hoisted_1$4 = { class: "hlw-empty" };
141
- const _hoisted_2$4 = ["src"];
142
- const _hoisted_3$2 = {
139
+ const index$6 = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-787fc3a7"]]);
140
+ const _hoisted_1$5 = { class: "hlw-empty" };
141
+ const _hoisted_2$5 = ["src"];
142
+ const _hoisted_3$3 = {
143
143
  key: 1,
144
144
  class: "hlw-empty__icon"
145
145
  };
146
146
  const _hoisted_4$1 = { class: "hlw-empty__text" };
147
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
147
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
148
148
  __name: "index",
149
149
  props: {
150
150
  text: {},
@@ -152,29 +152,29 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
152
152
  },
153
153
  setup(__props) {
154
154
  return (_ctx, _cache) => {
155
- return openBlock(), createElementBlock("view", _hoisted_1$4, [
155
+ return openBlock(), createElementBlock("view", _hoisted_1$5, [
156
156
  __props.image ? (openBlock(), createElementBlock("image", {
157
157
  key: 0,
158
158
  class: "hlw-empty__image",
159
159
  src: __props.image,
160
160
  mode: "aspectFit"
161
- }, null, 8, _hoisted_2$4)) : (openBlock(), createElementBlock("text", _hoisted_3$2, "📦")),
161
+ }, null, 8, _hoisted_2$5)) : (openBlock(), createElementBlock("text", _hoisted_3$3, "📦")),
162
162
  createElementVNode("text", _hoisted_4$1, toDisplayString(__props.text || "暂无数据"), 1),
163
163
  renderSlot(_ctx.$slots, "default", {}, void 0, true)
164
164
  ]);
165
165
  };
166
166
  }
167
167
  });
168
- const index$4 = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-72364322"]]);
169
- const _hoisted_1$3 = {
168
+ const index$5 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-72364322"]]);
169
+ const _hoisted_1$4 = {
170
170
  key: 0,
171
171
  class: "header-placeholder"
172
172
  };
173
- const _hoisted_2$3 = {
173
+ const _hoisted_2$4 = {
174
174
  key: 0,
175
175
  class: "header-title header-title--center"
176
176
  };
177
- const _sfc_main$3 = /* @__PURE__ */ defineComponent({
177
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
178
178
  __name: "index",
179
179
  props: {
180
180
  extraHeight: { default: 0 },
@@ -261,9 +261,9 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
261
261
  }, toDisplayString(props.title), 5)
262
262
  ], true)
263
263
  ], 2),
264
- props.titleAlign === "center" ? (openBlock(), createElementBlock("view", _hoisted_1$3)) : createCommentVNode("", true)
264
+ props.titleAlign === "center" ? (openBlock(), createElementBlock("view", _hoisted_1$4)) : createCommentVNode("", true)
265
265
  ], 64)) : renderSlot(_ctx.$slots, "default", { key: 1 }, () => [
266
- props.title ? (openBlock(), createElementBlock("view", _hoisted_2$3, [
266
+ props.title ? (openBlock(), createElementBlock("view", _hoisted_2$4, [
267
267
  createElementVNode("text", {
268
268
  class: "header-title-text",
269
269
  style: normalizeStyle(titleStyle.value)
@@ -275,27 +275,111 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
275
275
  };
276
276
  }
277
277
  });
278
- const index$3 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-9a6c839c"]]);
279
- const _hoisted_1$2 = { class: "hlw-loading" };
280
- const _hoisted_2$2 = {
278
+ const index$4 = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-9a6c839c"]]);
279
+ const _hoisted_1$3 = { class: "hlw-loading" };
280
+ const _hoisted_2$3 = {
281
281
  key: 0,
282
282
  class: "hlw-loading__text"
283
283
  };
284
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
284
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
285
285
  __name: "index",
286
286
  props: {
287
287
  text: {}
288
288
  },
289
289
  setup(__props) {
290
290
  return (_ctx, _cache) => {
291
- return openBlock(), createElementBlock("view", _hoisted_1$2, [
291
+ return openBlock(), createElementBlock("view", _hoisted_1$3, [
292
292
  _cache[0] || (_cache[0] = createElementVNode("view", { class: "hlw-loading__spinner" }, null, -1)),
293
- __props.text ? (openBlock(), createElementBlock("text", _hoisted_2$2, toDisplayString(__props.text), 1)) : createCommentVNode("", true)
293
+ __props.text ? (openBlock(), createElementBlock("text", _hoisted_2$3, toDisplayString(__props.text), 1)) : createCommentVNode("", true)
294
+ ]);
295
+ };
296
+ }
297
+ });
298
+ const index$3 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-14242381"]]);
299
+ const _hoisted_1$2 = { class: "hlw-menu" };
300
+ const _hoisted_2$2 = ["onClick"];
301
+ const _hoisted_3$2 = {
302
+ key: 2,
303
+ class: "hlw-menu-divider"
304
+ };
305
+ const HlwMenuItemContent = defineComponent({
306
+ name: "HlwMenuItemContent",
307
+ props: {
308
+ item: { type: Object, required: true }
309
+ },
310
+ setup(props) {
311
+ return () => {
312
+ const item = props.item;
313
+ return h("view", { class: "hlw-menu-item-inner" }, [
314
+ // 左侧
315
+ h("view", { class: "hlw-menu-left" }, [
316
+ h("view", { class: `hlw-menu-icon hlw-menu-icon--${item.iconTheme || "slate"}` }, [
317
+ h("text", { class: item.icon })
318
+ ]),
319
+ h("text", { class: "hlw-menu-label" }, item.label)
320
+ ]),
321
+ // 右侧
322
+ h("view", { class: "hlw-menu-right" }, [
323
+ item.loading ? h("text", { class: "i-fa6-solid-circle-notch hlw-menu-spin hlw-menu-muted" }) : null,
324
+ item.tag ? h(
325
+ "text",
326
+ { class: `hlw-menu-tag hlw-menu-tag--${item.tagTheme || "rose"} ${item.tagPulse ? "hlw-menu-tag-pulse" : ""}` },
327
+ item.tag
328
+ ) : null,
329
+ h("text", { class: "i-fa6-solid-chevron-right hlw-menu-arrow" })
330
+ ])
331
+ ]);
332
+ };
333
+ }
334
+ });
335
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
336
+ __name: "index",
337
+ props: {
338
+ items: {}
339
+ },
340
+ emits: ["click"],
341
+ setup(__props, { emit: __emit }) {
342
+ const props = __props;
343
+ const emit = __emit;
344
+ const visibleItems = computed(() => props.items.filter((item) => item.visible !== false));
345
+ const handleClick = (item) => {
346
+ emit("click", item);
347
+ };
348
+ return (_ctx, _cache) => {
349
+ const _component_navigator = resolveComponent("navigator");
350
+ return openBlock(), createElementBlock("view", _hoisted_1$2, [
351
+ (openBlock(true), createElementBlock(Fragment, null, renderList(visibleItems.value, (item, index2) => {
352
+ return openBlock(), createElementBlock(Fragment, { key: index2 }, [
353
+ item.url ? (openBlock(), createBlock(_component_navigator, {
354
+ key: 0,
355
+ url: item.url,
356
+ class: "hlw-menu-item",
357
+ "hover-class": "hlw-menu-item--active"
358
+ }, {
359
+ default: withCtx(() => [
360
+ renderSlot(_ctx.$slots, "item", { item }, () => [
361
+ createVNode(unref(HlwMenuItemContent), { item }, null, 8, ["item"])
362
+ ], true)
363
+ ]),
364
+ _: 2
365
+ }, 1032, ["url"])) : (openBlock(), createElementBlock("view", {
366
+ key: 1,
367
+ class: "hlw-menu-item",
368
+ "hover-class": "hlw-menu-item--active",
369
+ onClick: ($event) => handleClick(item)
370
+ }, [
371
+ renderSlot(_ctx.$slots, "item", { item }, () => [
372
+ createVNode(unref(HlwMenuItemContent), { item }, null, 8, ["item"])
373
+ ], true)
374
+ ], 8, _hoisted_2$2)),
375
+ index2 < visibleItems.value.length - 1 ? (openBlock(), createElementBlock("view", _hoisted_3$2)) : createCommentVNode("", true)
376
+ ], 64);
377
+ }), 128))
294
378
  ]);
295
379
  };
296
380
  }
297
381
  });
298
- const index$2 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-14242381"]]);
382
+ const index$2 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-48deaf95"]]);
299
383
  const _hoisted_1$1 = { class: "hlw-menu-list" };
300
384
  const _hoisted_2$1 = ["onTap"];
301
385
  const _hoisted_3$1 = { class: "hlw-menu-list__left" };
@@ -394,12 +478,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
394
478
  });
395
479
  const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-155bc02a"]]);
396
480
  export {
397
- _sfc_main$7 as HlwAd,
398
- index$6 as HlwAvatar,
399
- index$5 as HlwCard,
400
- index$4 as HlwEmpty,
401
- index$3 as HlwHeader,
402
- index$2 as HlwLoading,
481
+ _sfc_main$8 as HlwAd,
482
+ index$7 as HlwAvatar,
483
+ index$6 as HlwCard,
484
+ index$5 as HlwEmpty,
485
+ index$4 as HlwHeader,
486
+ index$3 as HlwLoading,
487
+ index$2 as HlwMenu,
403
488
  index$1 as HlwMenuList,
404
489
  index as HlwPage
405
490
  };
package/dist/style.css CHANGED
@@ -1,4 +1,4 @@
1
-
1
+ @charset "UTF-8";
2
2
  .hlw-avatar[data-v-7e8f98a5] {
3
3
  border-radius: 50%;
4
4
  overflow: hidden;
@@ -145,6 +145,150 @@ to { transform: rotate(360deg);
145
145
  color: #999;
146
146
  }
147
147
 
148
+ .hlw-menu[data-v-48deaf95] {
149
+ background: #fff;
150
+ border-radius: var(--radius-lg, 24rpx);
151
+ border: 1rpx solid var(--border-color, #e2e8f0);
152
+ overflow: hidden;
153
+ width: 100%;
154
+ padding: 8rpx 0;
155
+ }
156
+ .hlw-menu-item[data-v-48deaf95] {
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: space-between;
160
+ padding: 16rpx 32rpx;
161
+ }
162
+ .hlw-menu-item--active[data-v-48deaf95] {
163
+ background: #f8fafc;
164
+ }
165
+ .hlw-menu-divider[data-v-48deaf95] {
166
+ margin: 8rpx 0;
167
+ height: 0;
168
+ border-bottom: 1rpx dashed var(--border-color, #e2e8f0);
169
+ }
170
+
171
+ /* 下面的样式供 HlwMenuItemContent 内部渲染用(非 scoped) */.hlw-menu-item-inner {
172
+ display: flex;
173
+ align-items: center;
174
+ justify-content: space-between;
175
+ width: 100%;
176
+ }
177
+ .hlw-menu-left {
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 24rpx;
181
+ }
182
+ .hlw-menu-right {
183
+ display: flex;
184
+ align-items: center;
185
+ gap: 16rpx;
186
+ }
187
+ .hlw-menu-icon {
188
+ width: 64rpx;
189
+ height: 64rpx;
190
+ border-radius: var(--radius-md, 16rpx);
191
+ display: flex;
192
+ align-items: center;
193
+ justify-content: center;
194
+ flex-shrink: 0;
195
+ }
196
+ .hlw-menu-icon text {
197
+ font-size: 20rpx;
198
+ }
199
+ .hlw-menu-icon--orange {
200
+ background: #fff7ed;
201
+ color: #f97316;
202
+ }
203
+ .hlw-menu-icon--purple {
204
+ background: #faf5ff;
205
+ color: #a855f7;
206
+ }
207
+ .hlw-menu-icon--wechat {
208
+ background: #f0fdf4;
209
+ color: #07C160;
210
+ }
211
+ .hlw-menu-icon--cyan {
212
+ background: #ecfeff;
213
+ color: #06b6d4;
214
+ }
215
+ .hlw-menu-icon--emerald {
216
+ background: #ecfdf5;
217
+ color: #10b981;
218
+ }
219
+ .hlw-menu-icon--slate {
220
+ background: #f1f5f9;
221
+ color: #64748b;
222
+ }
223
+ .hlw-menu-icon--rose {
224
+ background: #fff1f2;
225
+ color: #f43f5e;
226
+ }
227
+ .hlw-menu-icon--blue {
228
+ background: #eff6ff;
229
+ color: #3b82f6;
230
+ }
231
+ .hlw-menu-icon--red {
232
+ background: #fef2f2;
233
+ color: #ef4444;
234
+ }
235
+ .hlw-menu-label {
236
+ font-size: 28rpx;
237
+ font-weight: 500;
238
+ color: #334155;
239
+ }
240
+ .hlw-menu-tag {
241
+ font-size: 20rpx;
242
+ color: #fff;
243
+ padding: 2rpx 12rpx;
244
+ border-radius: 9999rpx;
245
+ box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
246
+ }
247
+ .hlw-menu-tag--orange {
248
+ background: #fb923c;
249
+ }
250
+ .hlw-menu-tag--red {
251
+ background: #ef4444;
252
+ }
253
+ .hlw-menu-tag--wechat {
254
+ background: #07C160;
255
+ }
256
+ .hlw-menu-tag--rose {
257
+ background: #f43f5e;
258
+ }
259
+ .hlw-menu-tag--blue {
260
+ background: #3b82f6;
261
+ }
262
+ .hlw-menu-tag-pulse {
263
+ animation: hlw-menu-tag-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
264
+ }
265
+ @keyframes hlw-menu-tag-pulse {
266
+ 0%, 100% {
267
+ opacity: 1;
268
+ }
269
+ 50% {
270
+ opacity: 0.5;
271
+ }
272
+ }
273
+ .hlw-menu-arrow {
274
+ color: #d1d5db;
275
+ font-size: 20rpx;
276
+ }
277
+ .hlw-menu-spin {
278
+ animation: hlw-menu-spin 1s linear infinite;
279
+ }
280
+ .hlw-menu-muted {
281
+ color: #94a3b8;
282
+ font-size: 20rpx;
283
+ }
284
+ @keyframes hlw-menu-spin {
285
+ from {
286
+ transform: rotate(0deg);
287
+ }
288
+ to {
289
+ transform: rotate(360deg);
290
+ }
291
+ }
148
292
  .hlw-menu-list[data-v-e465b0b4] {
149
293
  background: #fff;
150
294
  border-radius: 16rpx;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hlw-uni/mp-vue",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "hlw-uni Vue 组件库 — 供小程序业务方使用的 UI 组件集合",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -0,0 +1,221 @@
1
+ <template>
2
+ <view class="hlw-menu">
3
+ <template v-for="(item, index) in visibleItems" :key="index">
4
+ <navigator v-if="item.url" :url="item.url" class="hlw-menu-item" hover-class="hlw-menu-item--active">
5
+ <slot name="item" :item="item">
6
+ <hlw-menu-item-content :item="item" />
7
+ </slot>
8
+ </navigator>
9
+ <view v-else class="hlw-menu-item" hover-class="hlw-menu-item--active" @click="handleClick(item)">
10
+ <slot name="item" :item="item">
11
+ <hlw-menu-item-content :item="item" />
12
+ </slot>
13
+ </view>
14
+ <view v-if="index < visibleItems.length - 1" class="hlw-menu-divider"></view>
15
+ </template>
16
+ </view>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { computed } from "vue";
21
+
22
+ export interface HlwMenuItem {
23
+ /** 图标 class,如 'i-fa6-solid-gear' */
24
+ icon: string;
25
+ /** 图标主题色 */
26
+ iconTheme?: "orange" | "purple" | "cyan" | "emerald" | "slate" | "wechat" | "rose" | "blue" | "red";
27
+ /** 菜单文字 */
28
+ label: string;
29
+ /** 跳转路径,有值则用 navigator 包裹 */
30
+ url?: string;
31
+ /** 右侧标签文字 */
32
+ tag?: string;
33
+ /** 标签主题色 */
34
+ tagTheme?: "orange" | "red" | "wechat" | "rose" | "blue";
35
+ /** 标签是否闪烁 */
36
+ tagPulse?: boolean;
37
+ /** 加载中状态(右侧显示 loading 图标) */
38
+ loading?: boolean;
39
+ /** 是否显示,默认 true */
40
+ visible?: boolean;
41
+ }
42
+
43
+ interface Props {
44
+ items: HlwMenuItem[];
45
+ }
46
+
47
+ const props = defineProps<Props>();
48
+ const emit = defineEmits<{
49
+ click: [item: HlwMenuItem];
50
+ }>();
51
+
52
+ const visibleItems = computed(() => props.items.filter((item) => item.visible !== false));
53
+
54
+ const handleClick = (item: HlwMenuItem) => {
55
+ emit("click", item);
56
+ };
57
+ </script>
58
+
59
+ <!-- 子组件:菜单项内容(内部使用) -->
60
+ <script lang="ts">
61
+ // 注册内部组件
62
+ import { defineComponent, h } from "vue";
63
+
64
+ const HlwMenuItemContent = defineComponent({
65
+ name: "HlwMenuItemContent",
66
+ props: {
67
+ item: { type: Object, required: true },
68
+ },
69
+ setup(props) {
70
+ return () => {
71
+ const item = props.item as import("./index.vue").HlwMenuItem;
72
+ return h("view", { class: "hlw-menu-item-inner" }, [
73
+ // 左侧
74
+ h("view", { class: "hlw-menu-left" }, [
75
+ h("view", { class: `hlw-menu-icon hlw-menu-icon--${item.iconTheme || "slate"}` }, [
76
+ h("text", { class: item.icon }),
77
+ ]),
78
+ h("text", { class: "hlw-menu-label" }, item.label),
79
+ ]),
80
+ // 右侧
81
+ h("view", { class: "hlw-menu-right" }, [
82
+ item.loading
83
+ ? h("text", { class: "i-fa6-solid-circle-notch hlw-menu-spin hlw-menu-muted" })
84
+ : null,
85
+ item.tag
86
+ ? h(
87
+ "text",
88
+ { class: `hlw-menu-tag hlw-menu-tag--${item.tagTheme || "rose"} ${item.tagPulse ? "hlw-menu-tag-pulse" : ""}` },
89
+ item.tag,
90
+ )
91
+ : null,
92
+ h("text", { class: "i-fa6-solid-chevron-right hlw-menu-arrow" }),
93
+ ]),
94
+ ]);
95
+ };
96
+ },
97
+ });
98
+
99
+ export { HlwMenuItemContent };
100
+ </script>
101
+
102
+ <style lang="scss" scoped>
103
+ .hlw-menu {
104
+ background: #fff;
105
+ border-radius: var(--radius-lg, 24rpx);
106
+ border: 1rpx solid var(--border-color, #e2e8f0);
107
+ overflow: hidden;
108
+ width: 100%;
109
+ padding: 8rpx 0;
110
+ }
111
+
112
+ .hlw-menu-item {
113
+ display: flex;
114
+ align-items: center;
115
+ justify-content: space-between;
116
+ padding: 16rpx 32rpx;
117
+
118
+ &--active {
119
+ background: #f8fafc;
120
+ }
121
+ }
122
+
123
+ .hlw-menu-divider {
124
+ margin: 8rpx 0;
125
+ height: 0;
126
+ border-bottom: 1rpx dashed var(--border-color, #e2e8f0);
127
+ }
128
+
129
+ /* 下面的样式供 HlwMenuItemContent 内部渲染用(非 scoped) */
130
+ </style>
131
+
132
+ <style lang="scss">
133
+ .hlw-menu-item-inner {
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: space-between;
137
+ width: 100%;
138
+ }
139
+
140
+ .hlw-menu-left {
141
+ display: flex;
142
+ align-items: center;
143
+ gap: 24rpx;
144
+ }
145
+
146
+ .hlw-menu-right {
147
+ display: flex;
148
+ align-items: center;
149
+ gap: 16rpx;
150
+ }
151
+
152
+ .hlw-menu-icon {
153
+ width: 64rpx;
154
+ height: 64rpx;
155
+ border-radius: var(--radius-md, 16rpx);
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ flex-shrink: 0;
160
+
161
+ text { font-size: 20rpx; }
162
+
163
+ &--orange { background: #fff7ed; color: #f97316; }
164
+ &--purple { background: #faf5ff; color: #a855f7; }
165
+ &--wechat { background: #f0fdf4; color: #07C160; }
166
+ &--cyan { background: #ecfeff; color: #06b6d4; }
167
+ &--emerald { background: #ecfdf5; color: #10b981; }
168
+ &--slate { background: #f1f5f9; color: #64748b; }
169
+ &--rose { background: #fff1f2; color: #f43f5e; }
170
+ &--blue { background: #eff6ff; color: #3b82f6; }
171
+ &--red { background: #fef2f2; color: #ef4444; }
172
+ }
173
+
174
+ .hlw-menu-label {
175
+ font-size: 28rpx;
176
+ font-weight: 500;
177
+ color: #334155;
178
+ }
179
+
180
+ .hlw-menu-tag {
181
+ font-size: 20rpx;
182
+ color: #fff;
183
+ padding: 2rpx 12rpx;
184
+ border-radius: 9999rpx;
185
+ box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
186
+
187
+ &--orange { background: #fb923c; }
188
+ &--red { background: #ef4444; }
189
+ &--wechat { background: #07C160; }
190
+ &--rose { background: #f43f5e; }
191
+ &--blue { background: #3b82f6; }
192
+ }
193
+
194
+ .hlw-menu-tag-pulse {
195
+ animation: hlw-menu-tag-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
196
+ }
197
+
198
+ @keyframes hlw-menu-tag-pulse {
199
+ 0%, 100% { opacity: 1; }
200
+ 50% { opacity: 0.5; }
201
+ }
202
+
203
+ .hlw-menu-arrow {
204
+ color: #d1d5db;
205
+ font-size: 20rpx;
206
+ }
207
+
208
+ .hlw-menu-spin {
209
+ animation: hlw-menu-spin 1s linear infinite;
210
+ }
211
+
212
+ .hlw-menu-muted {
213
+ color: #94a3b8;
214
+ font-size: 20rpx;
215
+ }
216
+
217
+ @keyframes hlw-menu-spin {
218
+ from { transform: rotate(0deg); }
219
+ to { transform: rotate(360deg); }
220
+ }
221
+ </style>
package/src/index.ts CHANGED
@@ -8,6 +8,8 @@ export { default as HlwCard } from './components/hlw-card/index.vue';
8
8
  export { default as HlwEmpty } from './components/hlw-empty/index.vue';
9
9
  export { default as HlwHeader } from './components/hlw-header/index.vue';
10
10
  export { default as HlwLoading } from './components/hlw-loading/index.vue';
11
+ export { default as HlwMenu } from './components/hlw-menu/index.vue';
12
+ export type { HlwMenuItem } from './components/hlw-menu/index.vue';
11
13
  export { default as HlwMenuList } from './components/hlw-menu-list/index.vue';
12
14
  export { default as HlwPage } from './components/hlw-page/index.vue';
13
15
  export type { MenuItem } from './components/hlw-menu-list/types';