@v-c/image 1.0.7 → 1.0.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/Image.d.ts +2 -0
- package/dist/Image.js +31 -0
- package/dist/Preview/Footer.js +5 -2
- package/dist/Preview/PrevNext.js +10 -8
- package/dist/Preview/index.js +14 -3
- package/dist/common.js +2 -1
- package/dist/interface.d.ts +1 -1
- package/dist/util/dist/Dom/findDOMNode.js +20 -0
- package/dist/util/dist/Dom/focus.js +129 -0
- package/dist/util/dist/Dom/isVisible.js +16 -0
- package/dist/util/dist/hooks/useId.js +12 -0
- package/package.json +3 -3
package/dist/Image.d.ts
CHANGED
|
@@ -39,8 +39,10 @@ export interface ImageProps extends Partial<Omit<ImageElementProps, 'src'>> {
|
|
|
39
39
|
preview?: boolean | PreviewConfig;
|
|
40
40
|
onClick?: (e: MouseEvent) => void;
|
|
41
41
|
onError?: (e: Event) => void;
|
|
42
|
+
onKeydown?: (e: KeyboardEvent) => void;
|
|
42
43
|
width?: string | number;
|
|
43
44
|
height?: string | number;
|
|
45
|
+
fetchPriority?: HTMLImageElement['fetchPriority'];
|
|
44
46
|
}
|
|
45
47
|
declare const Image: import('vue').DefineSetupFnComponent<ImageProps, {}, {}, ImageProps & {}, import('vue').PublicProps>;
|
|
46
48
|
export default Image;
|
package/dist/Image.js
CHANGED
|
@@ -69,6 +69,24 @@ var Image_default = /* @__PURE__ */ defineComponent((props, { attrs, slots }) =>
|
|
|
69
69
|
const onImgError = (e) => {
|
|
70
70
|
props.onError?.(e);
|
|
71
71
|
};
|
|
72
|
+
const onPreviewKeyDown = (event) => {
|
|
73
|
+
props.onKeydown?.(event);
|
|
74
|
+
if (!canPreview) return;
|
|
75
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
const rect = event.target.getBoundingClientRect();
|
|
78
|
+
const left = rect.x + rect.width / 2;
|
|
79
|
+
const top = rect.y + rect.height / 2;
|
|
80
|
+
if (groupContext) groupContext.onPreview(imageId, src.value || "", left, top);
|
|
81
|
+
else {
|
|
82
|
+
mousePosition.value = {
|
|
83
|
+
x: left,
|
|
84
|
+
y: top
|
|
85
|
+
};
|
|
86
|
+
triggerPreviewOpen(true);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
72
90
|
return () => {
|
|
73
91
|
const { width, height } = props;
|
|
74
92
|
const { className, style: attrStyle, restAttrs } = getAttrStyleAndClass(attrs);
|
|
@@ -96,6 +114,10 @@ var Image_default = /* @__PURE__ */ defineComponent((props, { attrs, slots }) =>
|
|
|
96
114
|
return createVNode(Fragment, null, [createVNode("div", mergeProps(pickAttrs(restAttrs, false), {
|
|
97
115
|
"class": rootCls,
|
|
98
116
|
"onClick": canPreview.value ? onPreview : onInternalClick,
|
|
117
|
+
"role": canPreview ? "button" : restAttrs.role,
|
|
118
|
+
"tabindex": canPreview && restAttrs.tabIndex == null ? 0 : restAttrs.tabIndex,
|
|
119
|
+
"aria-label": canPreview ? restAttrs["aria-label"] ?? restAttrs.alt : restAttrs["aria-label"],
|
|
120
|
+
"onKeydown": onPreviewKeyDown,
|
|
99
121
|
"style": rootStyle
|
|
100
122
|
}), [
|
|
101
123
|
createVNode("img", mergeProps(imgCommonProps.value, {
|
|
@@ -203,6 +225,11 @@ var Image_default = /* @__PURE__ */ defineComponent((props, { attrs, slots }) =>
|
|
|
203
225
|
required: false,
|
|
204
226
|
default: void 0
|
|
205
227
|
},
|
|
228
|
+
onKeydown: {
|
|
229
|
+
type: Function,
|
|
230
|
+
required: false,
|
|
231
|
+
default: void 0
|
|
232
|
+
},
|
|
206
233
|
width: {
|
|
207
234
|
type: [String, Number],
|
|
208
235
|
required: false,
|
|
@@ -212,6 +239,10 @@ var Image_default = /* @__PURE__ */ defineComponent((props, { attrs, slots }) =>
|
|
|
212
239
|
type: [String, Number],
|
|
213
240
|
required: false,
|
|
214
241
|
default: void 0
|
|
242
|
+
},
|
|
243
|
+
fetchPriority: {
|
|
244
|
+
required: false,
|
|
245
|
+
default: void 0
|
|
215
246
|
}
|
|
216
247
|
}, {
|
|
217
248
|
prefixCls: "vc-image",
|
package/dist/Preview/Footer.js
CHANGED
|
@@ -3,12 +3,15 @@ import { clsx } from "@v-c/util";
|
|
|
3
3
|
var Footer_default = /* @__PURE__ */ defineComponent((props) => {
|
|
4
4
|
const renderOperation = ({ type, disabled, onClick, icon }) => {
|
|
5
5
|
const actionCls = `${props.prefixCls}-actions-action`;
|
|
6
|
-
return createVNode("
|
|
6
|
+
return createVNode("button", {
|
|
7
|
+
"type": "button",
|
|
7
8
|
"key": type,
|
|
8
9
|
"class": clsx(actionCls, `${actionCls}-${type}`, { [`${actionCls}-disabled`]: !!disabled }),
|
|
9
10
|
"onClick": () => {
|
|
10
11
|
if (!disabled) onClick();
|
|
11
|
-
}
|
|
12
|
+
},
|
|
13
|
+
"disabled": !!disabled,
|
|
14
|
+
"aria-label": type
|
|
12
15
|
}, [icon]);
|
|
13
16
|
};
|
|
14
17
|
return () => {
|
package/dist/Preview/PrevNext.js
CHANGED
|
@@ -6,17 +6,19 @@ var PrevNext_default = /* @__PURE__ */ defineComponent((props) => {
|
|
|
6
6
|
const switchCls = `${prefixCls}-switch`;
|
|
7
7
|
const prevIcon = icons.prev ?? icons.left;
|
|
8
8
|
const nextIcon = icons.next ?? icons.right;
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
return createVNode(Fragment, null, [createVNode("
|
|
12
|
-
"
|
|
9
|
+
const prevDisabled = current === 0;
|
|
10
|
+
const nextDisabled = current === count - 1;
|
|
11
|
+
return createVNode(Fragment, null, [createVNode("button", {
|
|
12
|
+
"type": "button",
|
|
13
|
+
"class": clsx(switchCls, `${switchCls}-prev`, { [`${switchCls}-disabled`]: prevDisabled }),
|
|
13
14
|
"onClick": () => {
|
|
14
|
-
if (!
|
|
15
|
+
if (!prevDisabled) onActive(-1);
|
|
15
16
|
}
|
|
16
|
-
}, [prevIcon]), createVNode("
|
|
17
|
-
"
|
|
17
|
+
}, [prevIcon]), createVNode("button", {
|
|
18
|
+
"type": "button",
|
|
19
|
+
"class": clsx(switchCls, `${switchCls}-next`, { [`${switchCls}-disabled`]: nextDisabled }),
|
|
18
20
|
"onClick": () => {
|
|
19
|
-
if (!
|
|
21
|
+
if (!nextDisabled) onActive(1);
|
|
20
22
|
}
|
|
21
23
|
}, [nextIcon])]);
|
|
22
24
|
};
|
package/dist/Preview/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { usePreviewGroupContext } from "../context.js";
|
|
2
2
|
import useStatus from "../hooks/useStatus.js";
|
|
3
3
|
import { canUseDom } from "../util/dist/Dom/canUseDom.js";
|
|
4
|
+
import { useLockFocus } from "../util/dist/Dom/focus.js";
|
|
4
5
|
import { KeyCodeStr } from "../util/dist/KeyCode.js";
|
|
5
6
|
import { getTransitionProps } from "../util/dist/utils/transition.js";
|
|
6
7
|
import useImageTransform from "../hooks/useImageTransform.js";
|
|
@@ -15,6 +16,7 @@ import { clsx } from "@v-c/util";
|
|
|
15
16
|
import Portal from "@v-c/portal";
|
|
16
17
|
var Preview_default = /* @__PURE__ */ defineComponent((props, { attrs, slots }) => {
|
|
17
18
|
const imgEl = shallowRef();
|
|
19
|
+
const wrapperRef = shallowRef(null);
|
|
18
20
|
const groupContext = usePreviewGroupContext();
|
|
19
21
|
const showLeftOrRightSwitches = computed(() => !!groupContext && (props.count ?? 1) > 1);
|
|
20
22
|
const showOperationsProgress = computed(() => !!groupContext && (props.count ?? 1) >= 1);
|
|
@@ -112,8 +114,9 @@ var Preview_default = /* @__PURE__ */ defineComponent((props, { attrs, slots })
|
|
|
112
114
|
src: computed(() => props.src),
|
|
113
115
|
fallback: computed(() => props.fallback)
|
|
114
116
|
});
|
|
117
|
+
useLockFocus(portalRender, () => wrapperRef.value);
|
|
115
118
|
return () => {
|
|
116
|
-
const { prefixCls, rootClassName, src, alt, imageInfo, open, closeIcon, getContainer, current = 0, count = 1, countRender, motionName = "fade", imageRender, imgCommonProps, actionsRender = slots?.actionsRender, classNames = {}, styles = {}, mousePosition, zIndex, icons = {} } = props;
|
|
119
|
+
const { prefixCls, rootClassName, src, alt, imageInfo, open, closeIcon, getContainer, current = 0, count = 1, countRender, motionName = "fade", imageRender, imgCommonProps, actionsRender = slots?.actionsRender, classNames = {}, styles = {}, mousePosition, zIndex, icons = {}, movable = true } = props;
|
|
117
120
|
const bodyStyle = { ...styles.body ?? {} };
|
|
118
121
|
if (mousePosition) bodyStyle.transformOrigin = `${mousePosition.x}px ${mousePosition.y}px`;
|
|
119
122
|
const image = {
|
|
@@ -149,7 +152,10 @@ var Preview_default = /* @__PURE__ */ defineComponent((props, { attrs, slots })
|
|
|
149
152
|
...attrs.style
|
|
150
153
|
};
|
|
151
154
|
if (zIndex) mergedRootStyle.zIndex = zIndex;
|
|
152
|
-
const mergedRootCls = clsx(prefixCls, rootClassName, classNames.root, {
|
|
155
|
+
const mergedRootCls = clsx(prefixCls, rootClassName, classNames.root, {
|
|
156
|
+
[`${prefixCls}-movable`]: movable,
|
|
157
|
+
[`${prefixCls}-moving`]: isMoving.value
|
|
158
|
+
});
|
|
153
159
|
const transitionProps = getTransitionProps(motionName);
|
|
154
160
|
return createVNode(Portal, {
|
|
155
161
|
"open": open || animatedVisible.value || portalRender.value,
|
|
@@ -161,8 +167,13 @@ var Preview_default = /* @__PURE__ */ defineComponent((props, { attrs, slots })
|
|
|
161
167
|
}), { default: () => {
|
|
162
168
|
if (!(portalRender.value && open)) return null;
|
|
163
169
|
return createVNode("div", {
|
|
170
|
+
"ref": wrapperRef,
|
|
164
171
|
"class": mergedRootCls,
|
|
165
|
-
"style": mergedRootStyle
|
|
172
|
+
"style": mergedRootStyle,
|
|
173
|
+
"role": "dialog",
|
|
174
|
+
"aria-modal": "true",
|
|
175
|
+
"aria-label": alt,
|
|
176
|
+
"tabindex": -1
|
|
166
177
|
}, [
|
|
167
178
|
createVNode("div", {
|
|
168
179
|
"class": clsx(`${prefixCls}-mask`, classNames.mask),
|
package/dist/common.js
CHANGED
package/dist/interface.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Used for PreviewGroup passed image data
|
|
3
3
|
*/
|
|
4
|
-
export type ImageElementProps = Pick<HTMLImageElement, 'src' | 'crossOrigin' | 'decoding' | 'draggable' | 'loading' | 'referrerPolicy' | 'sizes' | 'srcset' | 'useMap' | 'alt'>;
|
|
4
|
+
export type ImageElementProps = Pick<HTMLImageElement, 'src' | 'crossOrigin' | 'decoding' | 'draggable' | 'loading' | 'referrerPolicy' | 'sizes' | 'srcset' | 'useMap' | 'alt' | 'fetchPriority'>;
|
|
5
5
|
export interface PreviewImageElementProps {
|
|
6
6
|
data: ImageElementProps;
|
|
7
7
|
canPreview: boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { canUseDom } from "./canUseDom.js";
|
|
2
|
+
import { unref } from "vue";
|
|
3
|
+
function isDOM(node) {
|
|
4
|
+
return node instanceof HTMLElement || node instanceof SVGElement;
|
|
5
|
+
}
|
|
6
|
+
function getDOM(elementRef) {
|
|
7
|
+
const unrefElementRef = unref(elementRef);
|
|
8
|
+
if (!canUseDom()) return unrefElementRef;
|
|
9
|
+
const dom = findDOMNode(unrefElementRef) || (unrefElementRef && typeof unrefElementRef === "object" ? findDOMNode(unrefElementRef.nativeElement) : null);
|
|
10
|
+
if (dom && (dom.nodeType === 3 || dom.nodeType === 8) && dom.nextElementSibling) return dom.nextElementSibling;
|
|
11
|
+
return dom;
|
|
12
|
+
}
|
|
13
|
+
function findDOMNode(_node) {
|
|
14
|
+
const node = unref(_node);
|
|
15
|
+
if (!canUseDom()) return node;
|
|
16
|
+
if (isDOM(node)) return node;
|
|
17
|
+
else if (node && "$el" in node) return node.$el;
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
export { getDOM };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useId_default } from "../hooks/useId.js";
|
|
2
|
+
import { getDOM } from "./findDOMNode.js";
|
|
3
|
+
import { isVisible_default } from "./isVisible.js";
|
|
4
|
+
import { watch } from "vue";
|
|
5
|
+
function focusable(node, includePositive = false) {
|
|
6
|
+
if (isVisible_default(node)) {
|
|
7
|
+
const nodeName = node.nodeName.toLowerCase();
|
|
8
|
+
const isFocusableElement = [
|
|
9
|
+
"input",
|
|
10
|
+
"select",
|
|
11
|
+
"textarea",
|
|
12
|
+
"button"
|
|
13
|
+
].includes(nodeName) || node.isContentEditable || nodeName === "a" && !!node.getAttribute("href");
|
|
14
|
+
const tabIndexAttr = node.getAttribute("tabindex");
|
|
15
|
+
const tabIndexNum = Number(tabIndexAttr);
|
|
16
|
+
let tabIndex = null;
|
|
17
|
+
if (tabIndexAttr && !Number.isNaN(tabIndexNum)) tabIndex = tabIndexNum;
|
|
18
|
+
else if (isFocusableElement && tabIndex === null) tabIndex = 0;
|
|
19
|
+
if (isFocusableElement && node.disabled) tabIndex = null;
|
|
20
|
+
return tabIndex !== null && (tabIndex >= 0 || includePositive && tabIndex < 0);
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
function getFocusNodeList(node, includePositive = false) {
|
|
25
|
+
const res = [...node.querySelectorAll("*")].filter((child) => {
|
|
26
|
+
return focusable(child, includePositive);
|
|
27
|
+
});
|
|
28
|
+
if (focusable(node, includePositive)) res.unshift(node);
|
|
29
|
+
return res;
|
|
30
|
+
}
|
|
31
|
+
var lastFocusElement = null;
|
|
32
|
+
var focusElements = [];
|
|
33
|
+
var idToElementMap = /* @__PURE__ */ new Map();
|
|
34
|
+
var ignoredElementMap = /* @__PURE__ */ new Map();
|
|
35
|
+
var allowedElementMap = /* @__PURE__ */ new Map();
|
|
36
|
+
function getLastElement() {
|
|
37
|
+
return focusElements[focusElements.length - 1];
|
|
38
|
+
}
|
|
39
|
+
function getLastLockId() {
|
|
40
|
+
const lastElement = getLastElement();
|
|
41
|
+
if (!lastElement) return void 0;
|
|
42
|
+
for (const [id, ele] of idToElementMap.entries()) if (ele === lastElement) return id;
|
|
43
|
+
}
|
|
44
|
+
function isIgnoredElement(element) {
|
|
45
|
+
const lockId = getLastLockId();
|
|
46
|
+
if (!lockId || !element) return false;
|
|
47
|
+
const ignoredEle = ignoredElementMap.get(lockId);
|
|
48
|
+
return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
|
|
49
|
+
}
|
|
50
|
+
function isAllowedElement(element) {
|
|
51
|
+
const lockId = getLastLockId();
|
|
52
|
+
if (!lockId || !element) return false;
|
|
53
|
+
const allowedElements = allowedElementMap.get(lockId);
|
|
54
|
+
if (!allowedElements?.size) return false;
|
|
55
|
+
for (const allowedElement of allowedElements) if (allowedElement === element || allowedElement.contains(element)) return true;
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
function hasFocus(element) {
|
|
59
|
+
const { activeElement } = document;
|
|
60
|
+
return element === activeElement || element.contains(activeElement);
|
|
61
|
+
}
|
|
62
|
+
function syncFocus() {
|
|
63
|
+
const lastElement = getLastElement();
|
|
64
|
+
const { activeElement } = document;
|
|
65
|
+
if (isIgnoredElement(activeElement) || isAllowedElement(activeElement)) return;
|
|
66
|
+
if (lastElement && !hasFocus(lastElement)) {
|
|
67
|
+
const focusableList = getFocusNodeList(lastElement);
|
|
68
|
+
(focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0])?.focus({ preventScroll: true });
|
|
69
|
+
} else lastFocusElement = activeElement;
|
|
70
|
+
}
|
|
71
|
+
function onWindowKeyDown(e) {
|
|
72
|
+
if (e.key === "Tab") {
|
|
73
|
+
const { activeElement } = document;
|
|
74
|
+
const focusableList = getFocusNodeList(getLastElement());
|
|
75
|
+
const last = focusableList[focusableList.length - 1];
|
|
76
|
+
if (e.shiftKey && activeElement === focusableList[0]) lastFocusElement = last;
|
|
77
|
+
else if (!e.shiftKey && activeElement === last) lastFocusElement = focusableList[0];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function lockFocus(element, id) {
|
|
81
|
+
if (element) {
|
|
82
|
+
idToElementMap.set(id, element);
|
|
83
|
+
focusElements = focusElements.filter((ele) => ele !== element);
|
|
84
|
+
focusElements.push(element);
|
|
85
|
+
window.addEventListener("focusin", syncFocus);
|
|
86
|
+
window.addEventListener("keydown", onWindowKeyDown, true);
|
|
87
|
+
syncFocus();
|
|
88
|
+
}
|
|
89
|
+
return () => {
|
|
90
|
+
lastFocusElement = null;
|
|
91
|
+
focusElements = focusElements.filter((ele) => ele !== element);
|
|
92
|
+
idToElementMap.delete(id);
|
|
93
|
+
ignoredElementMap.delete(id);
|
|
94
|
+
allowedElementMap.delete(id);
|
|
95
|
+
if (focusElements.length === 0) {
|
|
96
|
+
window.removeEventListener("focusin", syncFocus);
|
|
97
|
+
window.removeEventListener("keydown", onWindowKeyDown, true);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function useLockFocus(lock, getElement) {
|
|
102
|
+
const id = useId_default();
|
|
103
|
+
watch([lock, () => getElement()], ([nextLock, element], _o, onCleanup) => {
|
|
104
|
+
element = getDOM(element);
|
|
105
|
+
if (nextLock && element) onCleanup(lockFocus(element, id));
|
|
106
|
+
}, {
|
|
107
|
+
flush: "post",
|
|
108
|
+
immediate: true
|
|
109
|
+
});
|
|
110
|
+
const ignoreElement = (ele) => {
|
|
111
|
+
if (ele) ignoredElementMap.set(id, ele);
|
|
112
|
+
};
|
|
113
|
+
const registerAllowedElement = (ele) => {
|
|
114
|
+
if (!ele) return () => {};
|
|
115
|
+
let allowedElements = allowedElementMap.get(id);
|
|
116
|
+
if (!allowedElements) {
|
|
117
|
+
allowedElements = /* @__PURE__ */ new Set();
|
|
118
|
+
allowedElementMap.set(id, allowedElements);
|
|
119
|
+
}
|
|
120
|
+
allowedElements.add(ele);
|
|
121
|
+
return () => {
|
|
122
|
+
const nextAllowedElements = allowedElementMap.get(id);
|
|
123
|
+
nextAllowedElements?.delete(ele);
|
|
124
|
+
if (!nextAllowedElements?.size) allowedElementMap.delete(id);
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
return [ignoreElement, registerAllowedElement];
|
|
128
|
+
}
|
|
129
|
+
export { useLockFocus };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var isVisible_default = (element) => {
|
|
2
|
+
if (!element) return false;
|
|
3
|
+
if (element instanceof Element) {
|
|
4
|
+
if (element.offsetParent) return true;
|
|
5
|
+
if (element.getBBox) {
|
|
6
|
+
const { width, height } = element.getBBox();
|
|
7
|
+
if (width || height) return true;
|
|
8
|
+
}
|
|
9
|
+
if (element.getBoundingClientRect) {
|
|
10
|
+
const { width, height } = element.getBoundingClientRect();
|
|
11
|
+
if (width || height) return true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
export { isVisible_default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useId } from "vue";
|
|
2
|
+
function getUseId() {
|
|
3
|
+
return useId;
|
|
4
|
+
}
|
|
5
|
+
var useOriginalId = getUseId();
|
|
6
|
+
function useId_default(id) {
|
|
7
|
+
const vueId = useOriginalId();
|
|
8
|
+
if (id) return id;
|
|
9
|
+
if (process.env.NODE_ENV === "test") return "test-id";
|
|
10
|
+
return vueId;
|
|
11
|
+
}
|
|
12
|
+
export { useId_default };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-c/image",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.9",
|
|
5
5
|
"description": "image component",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"vue": "^3.0.0"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@v-c/
|
|
36
|
-
"@v-c/
|
|
35
|
+
"@v-c/portal": "^1.0.8",
|
|
36
|
+
"@v-c/util": "^1.0.19"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@ant-design/icons-vue": "^7.0.1"
|