@done-coding/admin-core 0.30.0 → 0.30.1-alpha.0
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/es/bridge/badge.mjs +7 -1
- package/es/components/app-layout/AppPage.vue.mjs +1 -1
- package/es/components/app-layout/AppPage.vue2.mjs +15 -8
- package/es/components/app-layout/app-page-geometry.mjs +7 -3
- package/es/components/app-layout/use-slot-misuse-warn.mjs +40 -0
- package/es/components/data-view/DataGridView.vue.mjs +1 -1
- package/es/components/data-view/DataGridView.vue2.mjs +83 -32
- package/es/components/data-view/DataGridViewCard.vue.mjs +41 -0
- package/es/components/data-view/DataGridViewCard.vue2.mjs +4 -0
- package/es/components/data-view/InfiniteListView.vue.mjs +1 -1
- package/es/components/data-view/InfiniteListView.vue2.mjs +38 -11
- package/es/components/display/BadgeMark.vue.mjs +1 -1
- package/es/components/display/BadgeMark.vue2.mjs +31 -33
- package/es/components/display/use-badge.mjs +37 -33
- package/es/components/form/FormGroupTitle.vue.mjs +1 -1
- package/es/components/form/FormItem.vue.mjs +1 -1
- package/es/components/form/FormItemNestForm.vue.mjs +1 -1
- package/es/components/form/FormItemNestFormList.vue.mjs +1 -1
- package/es/components/form/FormTree.vue.mjs +5 -30
- package/es/components/form/FormTree.vue2.mjs +30 -1
- package/es/components/form/FormUpload.vue.mjs +1 -1
- package/es/components/modal/ModalPorter.vue.mjs +2 -0
- package/es/components/modal/use-slot-misuse-warn.mjs +22 -0
- package/es/components/page-layout/AppPageListDetailSplit.vue.mjs +1 -1
- package/es/components/page-layout/AppPageListDetailSplit.vue2.mjs +7 -7
- package/es/components/view-layout/ViewLayout.vue.mjs +1 -1
- package/es/components/view-layout/ViewLayout.vue2.mjs +71 -91
- package/es/components/view-layout/ViewLayoutToolbar.vue.mjs +7 -0
- package/es/components/view-layout/ViewLayoutToolbar.vue2.mjs +189 -0
- package/es/config/slot-region.mjs +23 -1
- package/es/hooks/use-custom-breakpoint.mjs +12 -2
- package/es/hooks/use-is-dev.mjs +16 -0
- package/es/hooks/use-theme-apply.mjs +2 -2
- package/es/index.mjs +90 -88
- package/es/style.css +138 -87
- package/package.json +2 -2
- package/src/bridge/docs/README.md +34 -4
- package/src/components/app-layout/docs/README-AppPage.md +68 -0
- package/src/components/data-view/docs/README-DataGridView.md +83 -1
- package/src/components/data-view/docs/README-DataListView.md +5 -2
- package/src/components/display/docs/README-BadgeMark.md +102 -41
- package/src/components/form/README.md +14 -0
- package/src/components/form/docs/README-FormItemNestForm.md +3 -0
- package/src/components/form/docs/README-FormItemNestFormList.md +3 -0
- package/src/components/form/docs/README-FormUpload.md +3 -0
- package/src/components/modal/docs/README-ModalPorter.md +26 -0
- package/src/components/page-layout/docs/README-AppPageListDetailLayout.md +1 -1
- package/src/components/view-layout/docs/README-ViewLayout.md +152 -9
- package/src/hooks/docs/README.md +37 -1
- package/types/bridge/badge.d.ts +38 -2
- package/types/components/app-layout/AppPage.vue.d.ts +16 -0
- package/types/components/app-layout/app-page-geometry.d.ts +26 -2
- package/types/components/app-layout/use-slot-misuse-warn.d.ts +19 -0
- package/types/components/data-view/DataGridView.vue.d.ts +9 -0
- package/types/components/data-view/DataGridViewCard.vue.d.ts +25 -0
- package/types/components/data-view/types.d.ts +63 -0
- package/types/components/display/BadgeMark.vue.d.ts +9 -8
- package/types/components/display/use-badge.d.ts +22 -14
- package/types/components/modal/use-slot-misuse-warn.d.ts +21 -0
- package/types/components/view-layout/ViewLayout.vue.d.ts +16 -0
- package/types/components/view-layout/ViewLayoutToolbar.vue.d.ts +52 -0
- package/types/components/view-layout/types.d.ts +56 -0
- package/types/config/slot-region.d.ts +12 -0
- package/types/hooks/use-custom-breakpoint.d.ts +1 -12
- package/types/hooks/use-is-dev.d.ts +24 -0
- package/types/injectInfo.json.d.ts +1 -1
package/es/bridge/badge.mjs
CHANGED
|
@@ -4,6 +4,7 @@ const BADGE_MASK_KINDS = [
|
|
|
4
4
|
];
|
|
5
5
|
function createBridgeBadgeHook(init = {}) {
|
|
6
6
|
const marks = shallowRef({ ...init.marks ?? {} });
|
|
7
|
+
const defaultVisible = shallowRef(init.defaultVisible ?? true);
|
|
7
8
|
const setAll = (next) => {
|
|
8
9
|
marks.value = { ...next };
|
|
9
10
|
};
|
|
@@ -16,12 +17,17 @@ function createBridgeBadgeHook(init = {}) {
|
|
|
16
17
|
delete next[key];
|
|
17
18
|
marks.value = next;
|
|
18
19
|
};
|
|
20
|
+
const setDefaultVisible = (visible) => {
|
|
21
|
+
defaultVisible.value = visible;
|
|
22
|
+
};
|
|
19
23
|
return {
|
|
20
24
|
badge: {
|
|
21
25
|
marks: readonly(marks),
|
|
22
26
|
setAll,
|
|
23
27
|
set,
|
|
24
|
-
remove
|
|
28
|
+
remove,
|
|
29
|
+
defaultVisible: readonly(defaultVisible),
|
|
30
|
+
setDefaultVisible
|
|
25
31
|
}
|
|
26
32
|
};
|
|
27
33
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./AppPage.vue2.mjs";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
4
|
-
const AppPage = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const AppPage = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-73e3d4a9"]]);
|
|
5
5
|
export {
|
|
6
6
|
AppPage as default
|
|
7
7
|
};
|
|
@@ -4,6 +4,7 @@ import _sfc_main$1 from "../modal/ModalShelf.vue.mjs";
|
|
|
4
4
|
import _sfc_main$2 from "../display/WatchSize.vue.mjs";
|
|
5
5
|
import { computeAppPageReducedViewportHeight, computeAppPageReducedViewportWidth, computeAppPageContentInset, computeAppPageSlotStyles, computeAppPageSlotShimStyles } from "./app-page-geometry.mjs";
|
|
6
6
|
import { useAppPageContentBox } from "./use-content-box.mjs";
|
|
7
|
+
import { useAppPageSlotMisuseWarn } from "./use-slot-misuse-warn.mjs";
|
|
7
8
|
import { APP_PAGE_LIST_LAYOUT_RECOMMENDED } from "./app-page-recommended.mjs";
|
|
8
9
|
import { BODY_CONTENT_VIEWPORT_RECT, APP_LAYOUT_BRIDGE_KEY, SCOPE_VIEWPORT_MAX_HEIGHT, BODY_CONTENT_VIEWPORT_HEIGHT, BODY_CONTENT_VIEWPORT_INSET, APP_PAGE_CONTENT_INSET } from "../../inject/key.mjs";
|
|
9
10
|
import { useActivated } from "../../hooks/activated.mjs";
|
|
@@ -34,18 +35,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
34
35
|
bottomObserveResize: { type: Boolean, default: false },
|
|
35
36
|
leftObserveResize: { type: Boolean, default: false },
|
|
36
37
|
rightObserveResize: { type: Boolean, default: false },
|
|
38
|
+
leftWidth: {},
|
|
39
|
+
rightWidth: {},
|
|
37
40
|
contentCentered: { type: Boolean, default: false },
|
|
38
41
|
contentMaxWidth: { default: 1200 }
|
|
39
42
|
},
|
|
40
43
|
setup(__props) {
|
|
41
44
|
useCssVars((_ctx) => ({
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
45
|
+
"v62d8191f": pageCssVars.value.top,
|
|
46
|
+
"v7adfb621": pageCssVars.value.bottom,
|
|
47
|
+
"v0fb17d06": pageCssVars.value.left,
|
|
48
|
+
"v0d174f66": pageCssVars.value.right,
|
|
49
|
+
"v0d5dbb10": pageCssVars.value.width,
|
|
50
|
+
"f6eaa5c6": pageCssVars.value.height,
|
|
51
|
+
"v4ad30b28": props.nextViewportMaxHeight
|
|
49
52
|
}));
|
|
50
53
|
const props = __props;
|
|
51
54
|
const style = computed(() => {
|
|
@@ -167,6 +170,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
167
170
|
}
|
|
168
171
|
});
|
|
169
172
|
}
|
|
173
|
+
useAppPageSlotMisuseWarn({ root: () => appPageRef.value });
|
|
170
174
|
const reducedViewportWidth = computed(
|
|
171
175
|
() => computeAppPageReducedViewportWidth(
|
|
172
176
|
pageBoxWidth.value,
|
|
@@ -211,7 +215,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
211
215
|
};
|
|
212
216
|
});
|
|
213
217
|
const slotStyles = computed(
|
|
214
|
-
() => computeAppPageSlotStyles(rectInset.value, slotSizes.value,
|
|
218
|
+
() => computeAppPageSlotStyles(rectInset.value, slotSizes.value, {
|
|
219
|
+
outerGap: outerGap.value,
|
|
220
|
+
sideWidth: { left: props.leftWidth, right: props.rightWidth }
|
|
221
|
+
})
|
|
215
222
|
);
|
|
216
223
|
const shimStyles = computed(() => {
|
|
217
224
|
const base = computeAppPageSlotShimStyles();
|
|
@@ -23,7 +23,8 @@ function computeAppPageContentInset(appInset, slotSizes, gap) {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
const APP_PAGE_SLOT_Z_INDEX = 1;
|
|
26
|
-
function computeAppPageSlotStyles(rect, slotSizes,
|
|
26
|
+
function computeAppPageSlotStyles(rect, slotSizes, options) {
|
|
27
|
+
const { outerGap, sideWidth = {} } = options;
|
|
27
28
|
const z = APP_PAGE_SLOT_Z_INDEX;
|
|
28
29
|
const { topH, bottomH } = slotSizes;
|
|
29
30
|
const midTop = `calc(${rect.top} + ${appPageSlotInset(topH, outerGap)}px)`;
|
|
@@ -51,14 +52,17 @@ function computeAppPageSlotStyles(rect, slotSizes, outerGap) {
|
|
|
51
52
|
left: rect.left,
|
|
52
53
|
top: midTop,
|
|
53
54
|
bottom: midBottom,
|
|
54
|
-
zIndex: z
|
|
55
|
+
zIndex: z,
|
|
56
|
+
// 缺省不写 width ⇒ 保持 shrink-to-fit(老行为逐字不变)
|
|
57
|
+
...sideWidth.left ? { width: sideWidth.left } : {}
|
|
55
58
|
},
|
|
56
59
|
right: {
|
|
57
60
|
position: "fixed",
|
|
58
61
|
right: rect.right,
|
|
59
62
|
top: midTop,
|
|
60
63
|
bottom: midBottom,
|
|
61
|
-
zIndex: z
|
|
64
|
+
zIndex: z,
|
|
65
|
+
...sideWidth.right ? { width: sideWidth.right } : {}
|
|
62
66
|
}
|
|
63
67
|
};
|
|
64
68
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useIsDev } from "../../hooks/use-is-dev.mjs";
|
|
2
|
+
import { useActivated } from "../../hooks/activated.mjs";
|
|
3
|
+
import { APP_PAGE_SIDE_SLOTS } from "../../config/slot-region.mjs";
|
|
4
|
+
const occupiesLayout = (host) => Array.from(host.childNodes).some(
|
|
5
|
+
(node) => {
|
|
6
|
+
var _a;
|
|
7
|
+
return node.nodeType === 1 || node.nodeType === 3 && !!((_a = node.nodeValue) == null ? void 0 : _a.trim());
|
|
8
|
+
}
|
|
9
|
+
);
|
|
10
|
+
const findSlotShim = (root, slot) => {
|
|
11
|
+
var _a;
|
|
12
|
+
return ((_a = Array.from(root.children).find(
|
|
13
|
+
(el) => el.classList.contains(`app-page-slot--${slot}`)
|
|
14
|
+
)) == null ? void 0 : _a.firstElementChild) ?? void 0;
|
|
15
|
+
};
|
|
16
|
+
const useAppPageSlotMisuseWarn = (options) => {
|
|
17
|
+
const isDev = useIsDev();
|
|
18
|
+
const reported = /* @__PURE__ */ new Set();
|
|
19
|
+
useActivated((info) => {
|
|
20
|
+
if (!info.isActivated) return;
|
|
21
|
+
if (!isDev()) return;
|
|
22
|
+
const root = options.root();
|
|
23
|
+
if (!root) return;
|
|
24
|
+
for (const slot of APP_PAGE_SIDE_SLOTS) {
|
|
25
|
+
if (reported.has(slot)) continue;
|
|
26
|
+
const shim = findSlotShim(root, slot);
|
|
27
|
+
if (!shim || occupiesLayout(shim)) continue;
|
|
28
|
+
reported.add(slot);
|
|
29
|
+
console.error(
|
|
30
|
+
`[AppPage] #${slot} 槽里没有占版面的内容,但槽本身照样渲染(fixed + padding + 背景)并从默认内容里扣掉让位 —— 白占一条。
|
|
31
|
+
· 若放的是 ModalPorter:移到**默认槽**(page 架子就住在默认槽里,与 AppPage 并列同样够不到,evoke() 一样恒为 null);
|
|
32
|
+
· 若放的是自己 teleport 走、不需要 page 架子的弹窗:移到默认槽或与 AppPage 并列均可;
|
|
33
|
+
· 若是 v-if 条件渲染的内容:此刻恰好为空,忽略本条。`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export {
|
|
39
|
+
useAppPageSlotMisuseWarn
|
|
40
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./DataGridView.vue2.mjs";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
4
|
-
const DataGridView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const DataGridView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b4c213bc"]]);
|
|
5
5
|
export {
|
|
6
6
|
DataGridView as default
|
|
7
7
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { defineComponent, useCssVars, unref, useModel, shallowRef, ref, computed, onMounted, onActivated,
|
|
1
|
+
import { defineComponent, useCssVars, unref, useModel, shallowRef, ref, computed, watch, nextTick, onMounted, onActivated, openBlock, createElementBlock, normalizeClass, createBlock, withCtx, createVNode, mergeProps, createCommentVNode, createElementVNode, toDisplayString, createTextVNode, normalizeStyle, renderSlot, normalizeProps, guardReactiveProps, Fragment, renderList, mergeModels } from "vue";
|
|
2
2
|
import { ElButton } from "element-plus";
|
|
3
3
|
import TableToolbar from "../table/TableToolbar.vue.mjs";
|
|
4
4
|
import _sfc_main$2 from "../table/TableEmpty.vue.mjs";
|
|
5
5
|
import TableSkeleton from "../table/TableSkeleton.vue.mjs";
|
|
6
|
+
import { useObserveSize } from "../../hooks/use-observe-size.mjs";
|
|
6
7
|
import { useDataViewGridLayout } from "./use-grid-layout.mjs";
|
|
8
|
+
import _sfc_main$3 from "./DataGridViewCard.vue.mjs";
|
|
7
9
|
import { useSurface } from "../../hooks/use-surface.mjs";
|
|
8
10
|
import _sfc_main$1 from "../display/WatchSize.vue.mjs";
|
|
9
11
|
import _cloneDeep from "lodash/cloneDeep";
|
|
@@ -18,10 +20,8 @@ import { pickExportColumns } from "../../utils/export.mjs";
|
|
|
18
20
|
import { useChannelViewportHeight } from "../../hooks/use-channel-viewport-height.mjs";
|
|
19
21
|
import { APP_API_LIST_MODEL_KEY_CONFIG } from "../../config/list-model.mjs";
|
|
20
22
|
const _hoisted_1 = ["onClick"];
|
|
21
|
-
const _hoisted_2 =
|
|
22
|
-
const _hoisted_3 = {
|
|
23
|
-
const _hoisted_4 = { class: "data-grid-view__field-value" };
|
|
24
|
-
const _hoisted_5 = {
|
|
23
|
+
const _hoisted_2 = ["onClick"];
|
|
24
|
+
const _hoisted_3 = {
|
|
25
25
|
key: 0,
|
|
26
26
|
class: "data-grid-view__empty-error"
|
|
27
27
|
};
|
|
@@ -36,6 +36,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
36
36
|
gridColumns: { default: 4 },
|
|
37
37
|
gap: {},
|
|
38
38
|
card: { type: Boolean, default: true },
|
|
39
|
+
masonry: { type: Boolean },
|
|
40
|
+
estimateItemHeight: {},
|
|
39
41
|
surface: { type: Boolean, default: void 0 },
|
|
40
42
|
itemCard: { type: Boolean, default: void 0 },
|
|
41
43
|
maxHeight: { default: "100vh" },
|
|
@@ -65,7 +67,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
65
67
|
emits: /* @__PURE__ */ mergeModels(["pageChange", "pageSizeChange", "dataChange", "selectionChange", "loadingChange", "pageInfoChange"], ["update:isAutoRefresh", "update:refreshInterval", "update:activeId", "update:activeData"]),
|
|
66
68
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
67
69
|
useCssVars((_ctx) => ({
|
|
68
|
-
"
|
|
70
|
+
"v081d8ea3": unref(surfacePadCss)
|
|
69
71
|
}));
|
|
70
72
|
const props = __props;
|
|
71
73
|
const emits = __emit;
|
|
@@ -226,6 +228,40 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
226
228
|
const gridColumnsFinal = computed(
|
|
227
229
|
() => resolveGridColumnsByBreakpoint(props.gridColumns, activeBreakpoint.value)
|
|
228
230
|
);
|
|
231
|
+
const masonryActive = computed(
|
|
232
|
+
() => !!props.masonry && !!props.estimateItemHeight && typeof props.gridColumns !== "object"
|
|
233
|
+
);
|
|
234
|
+
const gridBoxRef = shallowRef();
|
|
235
|
+
const gridBoxWidth = ref(0);
|
|
236
|
+
const measureGridBox = () => {
|
|
237
|
+
const el = gridBoxRef.value;
|
|
238
|
+
if (el) gridBoxWidth.value = el.clientWidth;
|
|
239
|
+
};
|
|
240
|
+
useObserveSize({
|
|
241
|
+
getTarget: () => gridBoxRef.value,
|
|
242
|
+
onResize: measureGridBox,
|
|
243
|
+
enabled: () => masonryActive.value
|
|
244
|
+
});
|
|
245
|
+
watch(masonryActive, (on) => on && nextTick(measureGridBox), {
|
|
246
|
+
immediate: true
|
|
247
|
+
});
|
|
248
|
+
const columnWidth = computed(() => {
|
|
249
|
+
const cols = gridColumnsFinal.value;
|
|
250
|
+
const inner = gridBoxWidth.value - (cols - 1) * gridGap.value;
|
|
251
|
+
return cols > 0 ? Math.max(0, inner / cols) : 0;
|
|
252
|
+
});
|
|
253
|
+
const estimateSizeAt = (index) => {
|
|
254
|
+
const row = store.value[index];
|
|
255
|
+
if (!row || !props.estimateItemHeight) return 0;
|
|
256
|
+
return props.estimateItemHeight(row, columnWidth.value);
|
|
257
|
+
};
|
|
258
|
+
const virtualData = computed(
|
|
259
|
+
() => masonryActive.value ? store.value : gridRows.value
|
|
260
|
+
);
|
|
261
|
+
const asRow = (item) => item;
|
|
262
|
+
const virtualItemKey = computed(
|
|
263
|
+
() => masonryActive.value ? (row) => keyOf(row) : (row) => rowKeyOfRow(row)
|
|
264
|
+
);
|
|
229
265
|
const gridRows = computed(() => {
|
|
230
266
|
const rows = [];
|
|
231
267
|
const cols = gridColumnsFinal.value;
|
|
@@ -392,6 +428,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
392
428
|
});
|
|
393
429
|
return (_ctx, _cache) => {
|
|
394
430
|
return openBlock(), createElementBlock("div", {
|
|
431
|
+
ref_key: "gridBoxRef",
|
|
432
|
+
ref: gridBoxRef,
|
|
395
433
|
class: normalizeClass(["dc-data-grid-view data-grid-view", {
|
|
396
434
|
"data-grid-view_surface": unref(surfaceActive),
|
|
397
435
|
"data-grid-view_surface-bg": unref(surfaceBgActive)
|
|
@@ -428,8 +466,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
428
466
|
key: 2,
|
|
429
467
|
ref_key: "infiniteList",
|
|
430
468
|
ref: infiniteList,
|
|
431
|
-
data:
|
|
432
|
-
"item-key":
|
|
469
|
+
data: virtualData.value,
|
|
470
|
+
"item-key": virtualItemKey.value,
|
|
471
|
+
lanes: masonryActive.value ? gridColumnsFinal.value : 1,
|
|
472
|
+
"lane-gap": masonryActive.value ? unref(gridGap) : 0,
|
|
473
|
+
"item-gap": masonryActive.value ? unref(gridGap) : 0,
|
|
474
|
+
"estimate-size-at": masonryActive.value ? estimateSizeAt : void 0,
|
|
433
475
|
loading: loading.value && !store.value.length,
|
|
434
476
|
"loading-more": loadingMore.value,
|
|
435
477
|
error: error.value && store.value.length ? error.value : null,
|
|
@@ -440,11 +482,29 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
440
482
|
onRetry
|
|
441
483
|
}), {
|
|
442
484
|
item: withCtx(({ item, index }) => [
|
|
443
|
-
|
|
485
|
+
masonryActive.value ? (openBlock(), createElementBlock("div", {
|
|
486
|
+
key: 0,
|
|
487
|
+
class: normalizeClass(["data-grid-view__cell", { "is-active": unref(isActive)(item), "is-card": __props.card }]),
|
|
488
|
+
style: normalizeStyle(cellStyle.value),
|
|
489
|
+
onClick: ($event) => unref(setActive)(item)
|
|
490
|
+
}, [
|
|
491
|
+
renderSlot(_ctx.$slots, "custom-view-item", normalizeProps(guardReactiveProps(assertItemScope(item, index))), () => [
|
|
492
|
+
createVNode(_sfc_main$3, {
|
|
493
|
+
row: item,
|
|
494
|
+
index,
|
|
495
|
+
columns: __props.columns,
|
|
496
|
+
"field-component-map": unref(fieldComponentMap),
|
|
497
|
+
"field-key-of": fieldKeyOf,
|
|
498
|
+
"is-selected": isSelected,
|
|
499
|
+
"toggle-select": toggleSelect
|
|
500
|
+
}, null, 8, ["row", "index", "columns", "field-component-map"])
|
|
501
|
+
], true)
|
|
502
|
+
], 14, _hoisted_1)) : (openBlock(), createElementBlock("div", {
|
|
503
|
+
key: 1,
|
|
444
504
|
class: "data-grid-view__grid",
|
|
445
505
|
style: normalizeStyle(gridContainerStyle.value)
|
|
446
506
|
}, [
|
|
447
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(item, (row, colIndex) => {
|
|
507
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(asRow(item), (row, colIndex) => {
|
|
448
508
|
return openBlock(), createElementBlock("div", {
|
|
449
509
|
key: keyOf(row),
|
|
450
510
|
class: normalizeClass(["data-grid-view__cell", { "is-active": unref(isActive)(row), "is-card": __props.card }]),
|
|
@@ -452,31 +512,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
452
512
|
onClick: ($event) => unref(setActive)(row)
|
|
453
513
|
}, [
|
|
454
514
|
renderSlot(_ctx.$slots, "custom-view-item", mergeProps({ ref_for: true }, assertItemScope(row, index * gridColumnsFinal.value + colIndex)), () => [
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
row,
|
|
465
|
-
index: index * gridColumnsFinal.value + colIndex,
|
|
466
|
-
selected: isSelected(row),
|
|
467
|
-
"toggle-select": () => toggleSelect(row)
|
|
468
|
-
}, null, 8, ["row", "index", "selected", "toggle-select"]))
|
|
469
|
-
])
|
|
470
|
-
]);
|
|
471
|
-
}), 128))
|
|
472
|
-
])
|
|
515
|
+
createVNode(_sfc_main$3, {
|
|
516
|
+
row,
|
|
517
|
+
index: index * gridColumnsFinal.value + colIndex,
|
|
518
|
+
columns: __props.columns,
|
|
519
|
+
"field-component-map": unref(fieldComponentMap),
|
|
520
|
+
"field-key-of": fieldKeyOf,
|
|
521
|
+
"is-selected": isSelected,
|
|
522
|
+
"toggle-select": toggleSelect
|
|
523
|
+
}, null, 8, ["row", "index", "columns", "field-component-map"])
|
|
473
524
|
], true)
|
|
474
|
-
], 14,
|
|
525
|
+
], 14, _hoisted_2);
|
|
475
526
|
}), 128))
|
|
476
|
-
], 4)
|
|
527
|
+
], 4))
|
|
477
528
|
]),
|
|
478
529
|
empty: withCtx(() => [
|
|
479
|
-
error.value && !store.value.length ? (openBlock(), createElementBlock("div",
|
|
530
|
+
error.value && !store.value.length ? (openBlock(), createElementBlock("div", _hoisted_3, [
|
|
480
531
|
createElementVNode("span", null, toDisplayString(errorText.value), 1),
|
|
481
532
|
createVNode(unref(ElButton), {
|
|
482
533
|
size: "small",
|
|
@@ -494,7 +545,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
494
545
|
}, null, 8, ["loading", "has-requested"]))
|
|
495
546
|
]),
|
|
496
547
|
_: 3
|
|
497
|
-
}, 16, ["data", "loading", "loading-more", "error", "finished", "max-height"]))
|
|
548
|
+
}, 16, ["data", "item-key", "lanes", "lane-gap", "item-gap", "estimate-size-at", "loading", "loading-more", "error", "finished", "max-height"]))
|
|
498
549
|
], 2);
|
|
499
550
|
};
|
|
500
551
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { defineComponent, openBlock, createElementBlock, Fragment, renderList, createElementVNode, toDisplayString, createBlock, resolveDynamicComponent } from "vue";
|
|
2
|
+
const _hoisted_1 = { class: "data-grid-view__card" };
|
|
3
|
+
const _hoisted_2 = { class: "data-grid-view__field-label" };
|
|
4
|
+
const _hoisted_3 = { class: "data-grid-view__field-value" };
|
|
5
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
6
|
+
__name: "DataGridViewCard",
|
|
7
|
+
props: {
|
|
8
|
+
row: {},
|
|
9
|
+
index: {},
|
|
10
|
+
columns: {},
|
|
11
|
+
fieldComponentMap: {},
|
|
12
|
+
fieldKeyOf: { type: Function },
|
|
13
|
+
isSelected: { type: Function },
|
|
14
|
+
toggleSelect: { type: Function }
|
|
15
|
+
},
|
|
16
|
+
setup(__props) {
|
|
17
|
+
return (_ctx, _cache) => {
|
|
18
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
19
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column) => {
|
|
20
|
+
return openBlock(), createElementBlock("div", {
|
|
21
|
+
key: column.prop ?? column.type,
|
|
22
|
+
class: "data-grid-view__field"
|
|
23
|
+
}, [
|
|
24
|
+
createElementVNode("span", _hoisted_2, toDisplayString(column.label ?? column.prop) + ":", 1),
|
|
25
|
+
createElementVNode("span", _hoisted_3, [
|
|
26
|
+
(openBlock(), createBlock(resolveDynamicComponent(__props.fieldComponentMap[__props.fieldKeyOf(column)]), {
|
|
27
|
+
row: __props.row,
|
|
28
|
+
index: __props.index,
|
|
29
|
+
selected: __props.isSelected(__props.row),
|
|
30
|
+
"toggle-select": () => __props.toggleSelect(__props.row)
|
|
31
|
+
}, null, 8, ["row", "index", "selected", "toggle-select"]))
|
|
32
|
+
])
|
|
33
|
+
]);
|
|
34
|
+
}), 128))
|
|
35
|
+
]);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
export {
|
|
40
|
+
_sfc_main as default
|
|
41
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./InfiniteListView.vue2.mjs";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
4
|
-
const InfiniteListView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const InfiniteListView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4f0267ce"]]);
|
|
5
5
|
export {
|
|
6
6
|
InfiniteListView as default
|
|
7
7
|
};
|
|
@@ -33,12 +33,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
33
33
|
surface: { type: Boolean, default: void 0 },
|
|
34
34
|
itemCard: { type: Boolean },
|
|
35
35
|
maxHeight: { default: void 0 },
|
|
36
|
-
pullRefresh: { type: Boolean, default: false }
|
|
36
|
+
pullRefresh: { type: Boolean, default: false },
|
|
37
|
+
lanes: { default: 1 },
|
|
38
|
+
estimateSizeAt: {},
|
|
39
|
+
laneGap: { default: 0 },
|
|
40
|
+
itemGap: { default: 0 }
|
|
37
41
|
},
|
|
38
42
|
emits: ["loadMore", "retry", "refresh"],
|
|
39
43
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
40
44
|
useCssVars((_ctx) => ({
|
|
41
|
-
"
|
|
45
|
+
"v407ba190": unref(surfacePadCss)
|
|
42
46
|
}));
|
|
43
47
|
const props = __props;
|
|
44
48
|
const emits = __emit;
|
|
@@ -57,10 +61,39 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
57
61
|
computed(() => ({
|
|
58
62
|
count: props.data.length,
|
|
59
63
|
getScrollElement: () => scrollContainer.value ?? null,
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
// 逐项估高优先;没给就退回常量估值(= 本 prop 引入前的行为)
|
|
65
|
+
estimateSize: (index) => {
|
|
66
|
+
var _a;
|
|
67
|
+
return ((_a = props.estimateSizeAt) == null ? void 0 : _a.call(props, index)) ?? props.estimateSize;
|
|
68
|
+
},
|
|
69
|
+
overscan: props.overscan,
|
|
70
|
+
// 🔴 多列即**瀑布流装箱**:virtual-core 前 `lanes` 项按 `i % lanes` 铺满首行
|
|
71
|
+
// (顺序行优先),之后逐项落 end 最小的列。[MUST NOT] 自己写这段。
|
|
72
|
+
lanes: props.lanes,
|
|
73
|
+
// 同列相邻项的纵向间距(virtual-core 把它算进 measurements,总高与位置都正确;
|
|
74
|
+
// [MUST NOT] 改用项自身的 margin —— measureElement 量的是 borderBox、吃不到 margin)
|
|
75
|
+
gap: props.itemGap,
|
|
76
|
+
// `"estimate"`(默认)= **列归属按估值定下来就缓存**,卡片不会在量准后跳到另一列。
|
|
77
|
+
// 🔴 [MUST NOT] 改 `"measured"`:那会让首屏卡片换列,比一点留白刺眼得多。
|
|
78
|
+
laneAssignmentMode: "estimate"
|
|
62
79
|
}))
|
|
63
80
|
);
|
|
81
|
+
const rowStyle = (item) => {
|
|
82
|
+
const base = {
|
|
83
|
+
position: "absolute",
|
|
84
|
+
top: 0,
|
|
85
|
+
left: 0,
|
|
86
|
+
transform: `translateY(${item.start}px)`
|
|
87
|
+
};
|
|
88
|
+
if (props.lanes <= 1) return { ...base, width: "100%" };
|
|
89
|
+
const gapTotal = `${(props.lanes - 1) * props.laneGap}px`;
|
|
90
|
+
const colWidth = `calc((100% - ${gapTotal}) / ${props.lanes})`;
|
|
91
|
+
return {
|
|
92
|
+
...base,
|
|
93
|
+
width: colWidth,
|
|
94
|
+
left: `calc((${colWidth} + ${props.laneGap}px) * ${item.lane})`
|
|
95
|
+
};
|
|
96
|
+
};
|
|
64
97
|
const virtualItems = computed(() => virtualizer.value.getVirtualItems());
|
|
65
98
|
const totalSize = computed(() => virtualizer.value.getTotalSize());
|
|
66
99
|
const measureElementRef = (el) => {
|
|
@@ -165,13 +198,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
165
198
|
ref: measureElementRef,
|
|
166
199
|
class: "infinite-list-view__row",
|
|
167
200
|
"data-index": item.index,
|
|
168
|
-
style: normalizeStyle(
|
|
169
|
-
position: "absolute",
|
|
170
|
-
top: 0,
|
|
171
|
-
left: 0,
|
|
172
|
-
width: "100%",
|
|
173
|
-
transform: `translateY(${item.start}px)`
|
|
174
|
-
})
|
|
201
|
+
style: normalizeStyle(rowStyle(item))
|
|
175
202
|
}, [
|
|
176
203
|
renderSlot(_ctx.$slots, "item", {
|
|
177
204
|
item: __props.data[item.index],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _sfc_main from "./BadgeMark.vue2.mjs";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
4
|
-
const BadgeMark = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
4
|
+
const BadgeMark = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-64f0421b"]]);
|
|
5
5
|
export {
|
|
6
6
|
BadgeMark as default
|
|
7
7
|
};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { defineComponent, computed, useTemplateRef, openBlock, createBlock, unref, normalizeProps, createSlots, withCtx, renderSlot,
|
|
2
|
-
import { ElBadge
|
|
3
|
-
import {
|
|
1
|
+
import { defineComponent, inject, computed, useTemplateRef, openBlock, createBlock, unref, normalizeProps, createSlots, withCtx, renderSlot, createElementVNode, toDisplayString } from "vue";
|
|
2
|
+
import { ElBadge } from "element-plus";
|
|
3
|
+
import { useIsDev } from "../../hooks/use-is-dev.mjs";
|
|
4
|
+
import { useBadgeHit, badgeResolveDisplay, badgeWarnHideRefused } from "./use-badge.mjs";
|
|
4
5
|
import { useBadgeMask } from "./use-badge-mask.mjs";
|
|
6
|
+
import { CORE_BRIDGE_KEY } from "../../inject/key.mjs";
|
|
5
7
|
import { BADGE_KEY_ATTR } from "../../config/badge-attr.mjs";
|
|
8
|
+
const _hoisted_1 = { "aria-hidden": "true" };
|
|
6
9
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
7
10
|
__name: "BadgeMark",
|
|
8
11
|
props: {
|
|
@@ -12,15 +15,24 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12
15
|
setup(__props) {
|
|
13
16
|
const props = __props;
|
|
14
17
|
const hit = useBadgeHit(() => props.badgeKey);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
const bridge = inject(CORE_BRIDGE_KEY, void 0);
|
|
19
|
+
const isDev = useIsDev();
|
|
20
|
+
const resolved = computed(
|
|
21
|
+
() => {
|
|
22
|
+
var _a;
|
|
23
|
+
return badgeResolveDisplay(
|
|
24
|
+
(_a = hit.value) == null ? void 0 : _a.entry,
|
|
25
|
+
(bridge == null ? void 0 : bridge.badge.defaultVisible.value) ?? true,
|
|
26
|
+
// 遮挡档挡回隐藏请求 ⇒ dev 下点名一次(静默忽略 = 消费方以为设了其实没设)。
|
|
27
|
+
// 闸在调用侧、不在纯函数里:`badgeResolveDisplay` [MUST] 保持无副作用可直测。
|
|
28
|
+
() => {
|
|
29
|
+
if (!isDev()) return;
|
|
30
|
+
const h = hit.value;
|
|
31
|
+
if (h) badgeWarnHideRefused(h.key, h.entry.kind);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
);
|
|
24
36
|
const badgeRef = useTemplateRef("badgeRef");
|
|
25
37
|
useBadgeMask(
|
|
26
38
|
() => {
|
|
@@ -38,8 +50,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
38
50
|
key: 0,
|
|
39
51
|
ref_key: "badgeRef",
|
|
40
52
|
ref: badgeRef,
|
|
41
|
-
class: ["dc-badge-mark badge-mark",
|
|
42
|
-
|
|
53
|
+
class: ["dc-badge-mark badge-mark", [
|
|
54
|
+
`badge-mark_${__props.align ?? "middle"}`,
|
|
55
|
+
{ "badge-mark_hidden": resolved.value.hidden }
|
|
56
|
+
]],
|
|
43
57
|
value: resolved.value.value,
|
|
44
58
|
max: resolved.value.max,
|
|
45
59
|
type: resolved.value.type,
|
|
@@ -50,30 +64,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
50
64
|
]),
|
|
51
65
|
_: 2
|
|
52
66
|
}, [
|
|
53
|
-
resolved.value.
|
|
67
|
+
resolved.value.hidden ? {
|
|
54
68
|
name: "content",
|
|
55
69
|
fn: withCtx(() => [
|
|
56
|
-
|
|
57
|
-
content: resolved.value.label,
|
|
58
|
-
placement: "top"
|
|
59
|
-
}, {
|
|
60
|
-
default: withCtx(() => [
|
|
61
|
-
createVNode(unref(ElIcon), {
|
|
62
|
-
class: "badge-mark__icon",
|
|
63
|
-
style: normalizeStyle(iconStyle.value)
|
|
64
|
-
}, {
|
|
65
|
-
default: withCtx(() => [
|
|
66
|
-
(openBlock(), createBlock(resolveDynamicComponent(resolved.value.icon)))
|
|
67
|
-
]),
|
|
68
|
-
_: 1
|
|
69
|
-
}, 8, ["style"])
|
|
70
|
-
]),
|
|
71
|
-
_: 1
|
|
72
|
-
}, 8, ["content"])
|
|
70
|
+
createElementVNode("span", _hoisted_1, toDisplayString(resolved.value.value), 1)
|
|
73
71
|
]),
|
|
74
72
|
key: "0"
|
|
75
73
|
} : void 0
|
|
76
|
-
]), 1040, ["class", "
|
|
74
|
+
]), 1040, ["class", "value", "max", "type"])) : renderSlot(_ctx.$slots, "default", { key: 1 }, void 0, true);
|
|
77
75
|
};
|
|
78
76
|
}
|
|
79
77
|
});
|