@v-c/util 1.0.18 → 1.0.20

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.
Files changed (61) hide show
  1. package/dist/Children/isFragment.js +2 -0
  2. package/dist/Children/toArray.js +2 -0
  3. package/dist/Dom/addEventListener.js +2 -0
  4. package/dist/Dom/canUseDom.js +2 -0
  5. package/dist/Dom/class.js +2 -0
  6. package/dist/Dom/contains.js +2 -0
  7. package/dist/Dom/css.js +2 -0
  8. package/dist/Dom/dynamicCSS.js +13 -1
  9. package/dist/Dom/findDOMNode.js +5 -0
  10. package/dist/Dom/focus.d.ts +4 -1
  11. package/dist/Dom/focus.js +47 -13
  12. package/dist/Dom/focusBoundary.d.ts +5 -0
  13. package/dist/Dom/focusBoundary.js +11 -0
  14. package/dist/Dom/isVisible.js +2 -0
  15. package/dist/Dom/scrollLocker.js +5 -3
  16. package/dist/Dom/shadow.js +8 -0
  17. package/dist/Dom/styleChecker.js +2 -0
  18. package/dist/Dom/support.js +4 -2
  19. package/dist/KeyCode.js +329 -3
  20. package/dist/Portal.js +5 -4
  21. package/dist/PortalWrapper.d.ts +1 -1
  22. package/dist/PortalWrapper.js +28 -15
  23. package/dist/RenderComponent.js +9 -7
  24. package/dist/classnames.js +3 -1
  25. package/dist/composeProps.js +3 -2
  26. package/dist/createRef.js +6 -2
  27. package/dist/debug/diff.js +3 -1
  28. package/dist/deprecated.js +2 -0
  29. package/dist/getScrollBarSize.js +2 -0
  30. package/dist/guid.js +2 -0
  31. package/dist/hooks/useControlledState.js +2 -0
  32. package/dist/hooks/useEvent.js +3 -2
  33. package/dist/hooks/useId.js +9 -0
  34. package/dist/hooks/useLayoutEffect.js +2 -0
  35. package/dist/hooks/useMemo.js +2 -0
  36. package/dist/hooks/useMergedState.js +2 -0
  37. package/dist/hooks/useMobile.js +6 -5
  38. package/dist/hooks/useState.js +2 -0
  39. package/dist/index.js +4 -4
  40. package/dist/isEqual.js +11 -4
  41. package/dist/isMobile.js +3 -2
  42. package/dist/isValid.js +3 -2
  43. package/dist/omit.js +2 -0
  44. package/dist/pickAttrs.js +7 -0
  45. package/dist/props-util/index.js +5 -3
  46. package/dist/raf.js +3 -2
  47. package/dist/setStyle.js +9 -2
  48. package/dist/switchScrollingEffect.js +5 -3
  49. package/dist/test/domHook.js +2 -0
  50. package/dist/type.js +4 -2
  51. package/dist/utils/checkSlotProp.js +2 -0
  52. package/dist/utils/get.js +2 -0
  53. package/dist/utils/omit.js +2 -0
  54. package/dist/utils/set.js +14 -0
  55. package/dist/utils/transition.js +2 -0
  56. package/dist/utils/watchState.js +2 -0
  57. package/dist/vnode.d.ts +13 -0
  58. package/dist/vnode.js +32 -4
  59. package/dist/vueuse/unref-element.js +7 -0
  60. package/dist/warning.js +7 -2
  61. package/package.json +7 -1
@@ -1,5 +1,7 @@
1
1
  import { Fragment, isVNode } from "vue";
2
+ //#region src/Children/isFragment.ts
2
3
  function isFragment(node) {
3
4
  return isVNode(node) && node.type === Fragment;
4
5
  }
6
+ //#endregion
5
7
  export { isFragment };
@@ -1,4 +1,5 @@
1
1
  import { isFragment } from "./isFragment.js";
2
+ //#region src/Children/toArray.ts
2
3
  function toArray(children, option = {}) {
3
4
  let ret = [];
4
5
  if (!Array.isArray(children)) children = [children];
@@ -10,4 +11,5 @@ function toArray(children, option = {}) {
10
11
  }
11
12
  return ret;
12
13
  }
14
+ //#endregion
13
15
  export { toArray };
@@ -1,3 +1,4 @@
1
+ //#region src/Dom/addEventListener.ts
1
2
  function addEventListener(...args) {
2
3
  const [target, eventType, cb, option] = args;
3
4
  if (target?.addEventListener) target.addEventListener(eventType, cb, option);
@@ -5,4 +6,5 @@ function addEventListener(...args) {
5
6
  target?.removeEventListener?.(eventType, cb, option);
6
7
  } };
7
8
  }
9
+ //#endregion
8
10
  export { addEventListener };
@@ -1,4 +1,6 @@
1
+ //#region src/Dom/canUseDom.ts
1
2
  function canUseDom() {
2
3
  return !!(typeof window !== "undefined" && window.document && window.document.createElement);
3
4
  }
5
+ //#endregion
4
6
  export { canUseDom as default };
package/dist/Dom/class.js CHANGED
@@ -1,3 +1,4 @@
1
+ //#region src/Dom/class.ts
1
2
  function hasClass(node, className) {
2
3
  if (node.classList) return node.classList.contains(className);
3
4
  return ` ${node.className} `.includes(` ${className} `);
@@ -10,4 +11,5 @@ function removeClass(node, className) {
10
11
  if (node.classList) node.classList.remove(className);
11
12
  else if (hasClass(node, className)) node.className = ` ${node.className} `.replace(` ${className} `, " ");
12
13
  }
14
+ //#endregion
13
15
  export { addClass, hasClass, removeClass };
@@ -1,3 +1,4 @@
1
+ //#region src/Dom/contains.ts
1
2
  function contains(root, n) {
2
3
  if (!root) return false;
3
4
  if (root.contains) return root.contains(n);
@@ -8,4 +9,5 @@ function contains(root, n) {
8
9
  }
9
10
  return false;
10
11
  }
12
+ //#endregion
11
13
  export { contains as default };
package/dist/Dom/css.js CHANGED
@@ -1,3 +1,4 @@
1
+ //#region src/Dom/css.ts
1
2
  var PIXEL_PATTERN = /margin|padding|width|height|max|min|offset/;
2
3
  var removePixel = {
3
4
  left: true,
@@ -71,4 +72,5 @@ function getOffset(node) {
71
72
  top: box.top + (window.pageYOffset || docElem.scrollTop) - (docElem.clientTop || document.body.clientTop || 0)
72
73
  };
73
74
  }
75
+ //#endregion
74
76
  export { get, getClientSize, getDocSize, getOffset, getOuterHeight, getOuterWidth, getScroll, set };
@@ -1,5 +1,6 @@
1
1
  import canUseDom from "./canUseDom.js";
2
2
  import contains from "./contains.js";
3
+ //#region src/Dom/dynamicCSS.ts
3
4
  var APPEND_ORDER = "data-vc-order";
4
5
  var APPEND_PRIORITY = "data-vc-priority";
5
6
  var MARK_KEY = `vc-util-key`;
@@ -16,6 +17,9 @@ function getOrder(prepend) {
16
17
  if (prepend === "queue") return "prependQueue";
17
18
  return prepend ? "prepend" : "append";
18
19
  }
20
+ /**
21
+ * Find style which inject by rc-util
22
+ */
19
23
  function findStyles(container) {
20
24
  return Array.from((containerCache.get(container) || container).children).filter((node) => node.tagName === "STYLE");
21
25
  }
@@ -35,7 +39,8 @@ function injectCSS(css, option = {}) {
35
39
  if (isPrependQueue) {
36
40
  const existStyle = findStyles(container).filter((node) => {
37
41
  if (!["prepend", "prependQueue"].includes(node.getAttribute(APPEND_ORDER))) return false;
38
- return priority >= Number(node.getAttribute(APPEND_PRIORITY) || 0);
42
+ const nodePriority = Number(node.getAttribute(APPEND_PRIORITY) || 0);
43
+ return priority >= nodePriority;
39
44
  });
40
45
  if (existStyle.length) {
41
46
  container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);
@@ -54,6 +59,9 @@ function removeCSS(key, option = {}) {
54
59
  const existNode = findExistNode(key, option);
55
60
  if (existNode) getContainer(option).removeChild(existNode);
56
61
  }
62
+ /**
63
+ * qiankun will inject `appendChild` to insert into other
64
+ */
57
65
  function syncRealContainer(container, option) {
58
66
  const cachedRealContainer = containerCache.get(container);
59
67
  if (!cachedRealContainer || !contains(document, cachedRealContainer)) {
@@ -63,6 +71,9 @@ function syncRealContainer(container, option) {
63
71
  container.removeChild(placeholderStyle);
64
72
  }
65
73
  }
74
+ /**
75
+ * manually clear container cache to avoid global cache in unit testes
76
+ */
66
77
  function clearContainerCache() {
67
78
  containerCache.clear();
68
79
  }
@@ -79,4 +90,5 @@ function updateCSS(css, key, option = {}) {
79
90
  newNode.setAttribute(getMark(option), key);
80
91
  return newNode;
81
92
  }
93
+ //#endregion
82
94
  export { clearContainerCache, injectCSS, removeCSS, updateCSS };
@@ -1,5 +1,6 @@
1
1
  import canUseDom from "./canUseDom.js";
2
2
  import { unref } from "vue";
3
+ //#region src/Dom/findDOMNode.ts
3
4
  function isDOM(node) {
4
5
  return node instanceof HTMLElement || node instanceof SVGElement;
5
6
  }
@@ -10,6 +11,9 @@ function getDOM(elementRef) {
10
11
  if (dom && (dom.nodeType === 3 || dom.nodeType === 8) && dom.nextElementSibling) return dom.nextElementSibling;
11
12
  return dom;
12
13
  }
14
+ /**
15
+ * Return if a node is a DOM node. Else will return by `findDOMNode`
16
+ */
13
17
  function findDOMNode(_node) {
14
18
  const node = unref(_node);
15
19
  if (!canUseDom()) return node;
@@ -17,4 +21,5 @@ function findDOMNode(_node) {
17
21
  else if (node && "$el" in node) return node.$el;
18
22
  return null;
19
23
  }
24
+ //#endregion
20
25
  export { findDOMNode as default, getDOM, isDOM };
@@ -16,4 +16,7 @@ export declare function lockFocus(element: HTMLElement, id: string): VoidFunctio
16
16
  * If multiple elements are locked, only the last locked element will be effective.
17
17
  * @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
18
18
  */
19
- export declare function useLockFocus(lock: Ref<boolean>, getElement: () => HTMLElement | null): [ignoreElement: (ele: HTMLElement) => void];
19
+ export declare function useLockFocus(lock: Ref<boolean>, getElement: () => HTMLElement | null): [
20
+ ignoreElement: (ele: HTMLElement) => void,
21
+ registerAllowedElement: (ele: HTMLElement) => VoidFunction
22
+ ];
package/dist/Dom/focus.js CHANGED
@@ -2,6 +2,7 @@ import useId_default from "../hooks/useId.js";
2
2
  import { getDOM } from "./findDOMNode.js";
3
3
  import isVisible_default from "./isVisible.js";
4
4
  import { watch } from "vue";
5
+ //#region src/Dom/focus.ts
5
6
  function focusable(node, includePositive = false) {
6
7
  if (isVisible_default(node)) {
7
8
  const nodeName = node.nodeName.toLowerCase();
@@ -49,21 +50,27 @@ var lastFocusElement = null;
49
50
  var focusElements = [];
50
51
  var idToElementMap = /* @__PURE__ */ new Map();
51
52
  var ignoredElementMap = /* @__PURE__ */ new Map();
53
+ var allowedElementMap = /* @__PURE__ */ new Map();
52
54
  function getLastElement() {
53
55
  return focusElements[focusElements.length - 1];
54
56
  }
55
- function isIgnoredElement(element) {
57
+ function getLastLockId() {
56
58
  const lastElement = getLastElement();
57
- if (element && lastElement) {
58
- let lockId;
59
- for (const [id, ele] of idToElementMap.entries()) if (ele === lastElement) {
60
- lockId = id;
61
- break;
62
- }
63
- if (!lockId) return false;
64
- const ignoredEle = ignoredElementMap.get(lockId);
65
- return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
66
- }
59
+ if (!lastElement) return void 0;
60
+ for (const [id, ele] of idToElementMap.entries()) if (ele === lastElement) return id;
61
+ }
62
+ function isIgnoredElement(element) {
63
+ const lockId = getLastLockId();
64
+ if (!lockId || !element) return false;
65
+ const ignoredEle = ignoredElementMap.get(lockId);
66
+ return !!ignoredEle && (ignoredEle === element || ignoredEle.contains(element));
67
+ }
68
+ function isAllowedElement(element) {
69
+ const lockId = getLastLockId();
70
+ if (!lockId || !element) return false;
71
+ const allowedElements = allowedElementMap.get(lockId);
72
+ if (!allowedElements?.size) return false;
73
+ for (const allowedElement of allowedElements) if (allowedElement === element || allowedElement.contains(element)) return true;
67
74
  return false;
68
75
  }
69
76
  function hasFocus(element) {
@@ -73,7 +80,7 @@ function hasFocus(element) {
73
80
  function syncFocus() {
74
81
  const lastElement = getLastElement();
75
82
  const { activeElement } = document;
76
- if (isIgnoredElement(activeElement)) return;
83
+ if (isIgnoredElement(activeElement) || isAllowedElement(activeElement)) return;
77
84
  if (lastElement && !hasFocus(lastElement)) {
78
85
  const focusableList = getFocusNodeList(lastElement);
79
86
  (focusableList.includes(lastFocusElement) ? lastFocusElement : focusableList[0])?.focus({ preventScroll: true });
@@ -88,6 +95,11 @@ function onWindowKeyDown(e) {
88
95
  else if (!e.shiftKey && activeElement === last) lastFocusElement = focusableList[0];
89
96
  }
90
97
  }
98
+ /**
99
+ * Lock focus in the element.
100
+ * It will force back to the first focusable element when focus leaves the element.
101
+ * @param id - A stable ID for this lock instance
102
+ */
91
103
  function lockFocus(element, id) {
92
104
  if (element) {
93
105
  idToElementMap.set(id, element);
@@ -102,12 +114,19 @@ function lockFocus(element, id) {
102
114
  focusElements = focusElements.filter((ele) => ele !== element);
103
115
  idToElementMap.delete(id);
104
116
  ignoredElementMap.delete(id);
117
+ allowedElementMap.delete(id);
105
118
  if (focusElements.length === 0) {
106
119
  window.removeEventListener("focusin", syncFocus);
107
120
  window.removeEventListener("keydown", onWindowKeyDown, true);
108
121
  }
109
122
  };
110
123
  }
124
+ /**
125
+ * Lock focus within an element.
126
+ * When locked, focus will be restricted to focusable elements within the specified element.
127
+ * If multiple elements are locked, only the last locked element will be effective.
128
+ * @returns A function to mark an element as ignored, which will temporarily allow focus on that element even if it's outside the locked area.
129
+ */
111
130
  function useLockFocus(lock, getElement) {
112
131
  const id = useId_default();
113
132
  watch([lock, () => getElement()], ([nextLock, element], _o, onCleanup) => {
@@ -120,6 +139,21 @@ function useLockFocus(lock, getElement) {
120
139
  const ignoreElement = (ele) => {
121
140
  if (ele) ignoredElementMap.set(id, ele);
122
141
  };
123
- return [ignoreElement];
142
+ const registerAllowedElement = (ele) => {
143
+ if (!ele) return () => {};
144
+ let allowedElements = allowedElementMap.get(id);
145
+ if (!allowedElements) {
146
+ allowedElements = /* @__PURE__ */ new Set();
147
+ allowedElementMap.set(id, allowedElements);
148
+ }
149
+ allowedElements.add(ele);
150
+ return () => {
151
+ const nextAllowedElements = allowedElementMap.get(id);
152
+ nextAllowedElements?.delete(ele);
153
+ if (!nextAllowedElements?.size) allowedElementMap.delete(id);
154
+ };
155
+ };
156
+ return [ignoreElement, registerAllowedElement];
124
157
  }
158
+ //#endregion
125
159
  export { getFocusNodeList, lockFocus, triggerFocus, useLockFocus };
@@ -0,0 +1,5 @@
1
+ export interface FocusBoundaryContextProps {
2
+ registerAllowedElement: (element: HTMLElement) => VoidFunction;
3
+ }
4
+ export declare function useFocusBoundaryProvider(props: FocusBoundaryContextProps): void;
5
+ export declare function useFocusBoundary(): FocusBoundaryContextProps;
@@ -0,0 +1,11 @@
1
+ import { inject, provide } from "vue";
2
+ //#region src/Dom/focusBoundary.ts
3
+ var FocusBoundaryContextKey = Symbol("FocusBoundaryContext");
4
+ function useFocusBoundaryProvider(props) {
5
+ provide(FocusBoundaryContextKey, props);
6
+ }
7
+ function useFocusBoundary() {
8
+ return inject(FocusBoundaryContextKey, null);
9
+ }
10
+ //#endregion
11
+ export { useFocusBoundary, useFocusBoundaryProvider };
@@ -1,3 +1,4 @@
1
+ //#region src/Dom/isVisible.ts
1
2
  var isVisible_default = (element) => {
2
3
  if (!element) return false;
3
4
  if (element instanceof Element) {
@@ -13,4 +14,5 @@ var isVisible_default = (element) => {
13
14
  }
14
15
  return false;
15
16
  };
17
+ //#endregion
16
18
  export { isVisible_default as default };
@@ -1,5 +1,6 @@
1
1
  import getScrollBarSize from "../getScrollBarSize.js";
2
- import setStyle_default from "../setStyle.js";
2
+ import setStyle from "../setStyle.js";
3
+ //#region src/Dom/scrollLocker.ts
3
4
  var uuid = 0;
4
5
  var locks = [];
5
6
  var scrollingEffectClassName = "ant-scrolling-effect";
@@ -39,7 +40,7 @@ var ScrollLocker = class {
39
40
  if (getComputedStyle(container).overflow !== "hidden") scrollBarSize = getScrollBarSize();
40
41
  }
41
42
  const containerClassName = container.className;
42
- if (locks.filter(({ options }) => options?.container === this.options?.container).length === 0) cacheStyle.set(container, setStyle_default({
43
+ if (locks.filter(({ options }) => options?.container === this.options?.container).length === 0) cacheStyle.set(container, setStyle({
43
44
  width: scrollBarSize !== 0 ? `calc(100% - ${scrollBarSize}px)` : void 0,
44
45
  overflow: "hidden",
45
46
  overflowX: "hidden",
@@ -58,9 +59,10 @@ var ScrollLocker = class {
58
59
  const container = this.options?.container || document.body;
59
60
  const containerClassName = container.className;
60
61
  if (!scrollingEffectClassNameReg.test(containerClassName)) return;
61
- setStyle_default(cacheStyle.get(container), { element: container });
62
+ setStyle(cacheStyle.get(container), { element: container });
62
63
  cacheStyle.delete(container);
63
64
  container.className = container.className.replace(scrollingEffectClassNameReg, "").trim();
64
65
  };
65
66
  };
67
+ //#endregion
66
68
  export { ScrollLocker as default };
@@ -1,10 +1,18 @@
1
+ //#region src/Dom/shadow.ts
1
2
  function getRoot(ele) {
2
3
  return ele?.getRootNode?.();
3
4
  }
5
+ /**
6
+ * Check if is in shadowRoot
7
+ */
4
8
  function inShadow(ele) {
5
9
  return getRoot(ele) instanceof ShadowRoot;
6
10
  }
11
+ /**
12
+ * Return shadowRoot if possible
13
+ */
7
14
  function getShadowRoot(ele) {
8
15
  return inShadow(ele) ? getRoot(ele) : null;
9
16
  }
17
+ //#endregion
10
18
  export { getShadowRoot, inShadow };
@@ -1,4 +1,5 @@
1
1
  import canUseDom from "./canUseDom.js";
2
+ //#region src/Dom/styleChecker.ts
2
3
  function isStyleNameSupport(styleName) {
3
4
  if (canUseDom() && window.document.documentElement) {
4
5
  const styleNameList = Array.isArray(styleName) ? styleName : [styleName];
@@ -18,4 +19,5 @@ function isStyleSupport(styleName, styleValue) {
18
19
  if (!Array.isArray(styleName) && styleValue !== void 0) return isStyleValueSupport(styleName, styleValue);
19
20
  return isStyleNameSupport(styleName);
20
21
  }
22
+ //#endregion
21
23
  export { isStyleSupport };
@@ -1,4 +1,5 @@
1
1
  import canUseDom from "./canUseDom.js";
2
+ //#region src/Dom/support.ts
2
3
  var animationEndEventNames = {
3
4
  WebkitAnimation: "webkitAnimationEnd",
4
5
  OAnimation: "oAnimationEnd",
@@ -14,6 +15,7 @@ function supportEnd(names) {
14
15
  for (const name in names) if (names.hasOwnProperty(name) && el.style[name] !== void 0) return { end: names[name] };
15
16
  return false;
16
17
  }
17
- const animation = canUseDom() && supportEnd(animationEndEventNames);
18
- const transition = canUseDom() && supportEnd(transitionEventNames);
18
+ var animation = canUseDom() && supportEnd(animationEndEventNames);
19
+ var transition = canUseDom() && supportEnd(transitionEventNames);
20
+ //#endregion
19
21
  export { animation, transition };