@veltra/compositions 1.0.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.
Files changed (67) hide show
  1. package/dist/index.d.ts +14 -0
  2. package/dist/index.js +14 -0
  3. package/dist/use-component-props/index.d.ts +12 -0
  4. package/dist/use-component-props/index.js +52 -0
  5. package/dist/use-component-props/index.js.map +1 -0
  6. package/dist/use-config/index.d.ts +25 -0
  7. package/dist/use-config/index.js +51 -0
  8. package/dist/use-config/index.js.map +1 -0
  9. package/dist/use-drag/index.d.ts +47 -0
  10. package/dist/use-drag/index.js +87 -0
  11. package/dist/use-drag/index.js.map +1 -0
  12. package/dist/use-fallback-props/index.d.ts +31 -0
  13. package/dist/use-fallback-props/index.js +35 -0
  14. package/dist/use-fallback-props/index.js.map +1 -0
  15. package/dist/use-focus/index.d.ts +16 -0
  16. package/dist/use-focus/index.js +27 -0
  17. package/dist/use-focus/index.js.map +1 -0
  18. package/dist/use-form-component/index.d.ts +22 -0
  19. package/dist/use-form-component/index.js +15 -0
  20. package/dist/use-form-component/index.js.map +1 -0
  21. package/dist/use-lock/index.d.ts +28 -0
  22. package/dist/use-lock/index.js +36 -0
  23. package/dist/use-lock/index.js.map +1 -0
  24. package/dist/use-model/index.d.ts +35 -0
  25. package/dist/use-model/index.js +46 -0
  26. package/dist/use-model/index.js.map +1 -0
  27. package/dist/use-pop/index.d.ts +53 -0
  28. package/dist/use-pop/index.js +121 -0
  29. package/dist/use-pop/index.js.map +1 -0
  30. package/dist/use-reactive-size/index.d.ts +17 -0
  31. package/dist/use-reactive-size/index.js +40 -0
  32. package/dist/use-reactive-size/index.js.map +1 -0
  33. package/dist/use-resize-observer/index.d.ts +33 -0
  34. package/dist/use-resize-observer/index.js +92 -0
  35. package/dist/use-resize-observer/index.js.map +1 -0
  36. package/dist/use-transition/index.d.ts +18 -0
  37. package/dist/use-transition/index.js +11 -0
  38. package/dist/use-transition/index.js.map +1 -0
  39. package/dist/use-transition/type.d.ts +47 -0
  40. package/dist/use-transition/use-css-transition.js +129 -0
  41. package/dist/use-transition/use-css-transition.js.map +1 -0
  42. package/dist/use-transition/use-style-transition.js +127 -0
  43. package/dist/use-transition/use-style-transition.js.map +1 -0
  44. package/dist/use-transition/utils.js +41 -0
  45. package/dist/use-transition/utils.js.map +1 -0
  46. package/dist/use-virtual/index.d.ts +30 -0
  47. package/dist/use-virtual/index.js +67 -0
  48. package/dist/use-virtual/index.js.map +1 -0
  49. package/package.json +32 -0
  50. package/src/index.ts +25 -0
  51. package/src/use-component-props/index.ts +63 -0
  52. package/src/use-config/index.ts +77 -0
  53. package/src/use-drag/index.ts +151 -0
  54. package/src/use-fallback-props/index.ts +76 -0
  55. package/src/use-focus/index.ts +26 -0
  56. package/src/use-form-component/index.ts +31 -0
  57. package/src/use-lock/index.ts +50 -0
  58. package/src/use-model/index.ts +96 -0
  59. package/src/use-pop/index.ts +206 -0
  60. package/src/use-reactive-size/index.ts +53 -0
  61. package/src/use-resize-observer/index.ts +148 -0
  62. package/src/use-transition/index.ts +22 -0
  63. package/src/use-transition/type.ts +50 -0
  64. package/src/use-transition/use-css-transition.ts +186 -0
  65. package/src/use-transition/use-style-transition.ts +182 -0
  66. package/src/use-transition/utils.ts +56 -0
  67. package/src/use-virtual/index.ts +130 -0
@@ -0,0 +1,46 @@
1
+ import { ref, shallowRef, watch } from "vue";
2
+ //#region src/use-model/index.ts
3
+ /**
4
+ * 返回一个基于提供的选项的响应式模型值。
5
+ * 该方法在将来可能会被替代, 目前使用是为了类型提示可用
6
+ * 如果 local 选项为true, 模型值将是响应式的,并与属性值同步。
7
+ * 如果 local 选项为 false,则模型值将是一个代理对象,具有 getter 和 setter。当值发生更改时,它会触发一个更新事件。
8
+ * @param options - 选项
9
+ * @returns - 一个模型值
10
+ */
11
+ function useModel(options) {
12
+ const { props, propName = "modelValue", emit, local = true, defaultValue, shallow = false } = options;
13
+ if (local) {
14
+ const _default = props[propName] ?? defaultValue;
15
+ const _value = (shallow ? shallowRef : ref)(_default);
16
+ watch(() => props[propName], (v) => {
17
+ _value.value = v;
18
+ });
19
+ const getLocal = () => {
20
+ return typeof local === "function" ? local() : local;
21
+ };
22
+ return {
23
+ __v_isRef: true,
24
+ get value() {
25
+ return _value.value;
26
+ },
27
+ set value(v) {
28
+ if (v !== _value.value) emit(`update:${propName}`, v);
29
+ if (getLocal()) _value.value = v;
30
+ }
31
+ };
32
+ }
33
+ return {
34
+ __v_isRef: true,
35
+ get value() {
36
+ return props[propName] ?? defaultValue;
37
+ },
38
+ set value(v) {
39
+ emit(`update:${propName}`, v);
40
+ }
41
+ };
42
+ }
43
+ //#endregion
44
+ export { useModel };
45
+
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/use-model/index.ts"],"sourcesContent":["import { type Ref, ref, watch, shallowRef } from 'vue'\n\ninterface ModelOptions<Props extends Record<string, unknown>, Name extends keyof Props> {\n /** 组件定义的属性 */\n props: Props\n /** 属性名称 */\n propName?: Name\n /** 事件触发函数 */\n emit: (...args: any[]) => void\n /** 是否为本地模式, 默认为true, 本地模式允许组件不受控来触发视图更新 */\n local?: boolean | (() => boolean)\n /** 默认值 */\n defaultValue?: Props[Name]\n /**\n * 是否浅层响应\n * @default false\n */\n shallow?: boolean\n}\n\n/**\n * 返回一个基于提供的选项的响应式模型值。\n * 该方法在将来可能会被替代, 目前使用是为了类型提示可用\n * 如果 local 选项为true, 模型值将是响应式的,并与属性值同步。\n * 如果 local 选项为 false,则模型值将是一个代理对象,具有 getter 和 setter。当值发生更改时,它会触发一个更新事件。\n * @param options - 选项\n * @returns - 一个模型值\n */\n\nexport function useModel<\n Props extends Record<string, any>,\n Name extends keyof Props = 'modelValue'\n>(\n options: ModelOptions<Props, Name>\n): Ref<Props[Name] | undefined> | { __v_isRef: boolean; value: Props[Name] } {\n const {\n props,\n propName = 'modelValue',\n emit,\n local = true,\n defaultValue,\n shallow = false\n } = options\n\n if (local) {\n const _default = props[propName] ?? defaultValue\n const r = shallow ? shallowRef : ref\n\n // 创建一个响应式对象\n const _value = r(_default)\n\n // 监听属性的变更\n watch(\n () => props[propName],\n (v) => {\n _value.value = v\n }\n )\n\n const getLocal = () => {\n return typeof local === 'function' ? local() : local\n }\n\n const value = {\n __v_isRef: true,\n get value() {\n return _value.value\n },\n set value(v) {\n if (v !== _value.value) {\n emit(`update:${propName as string}`, v)\n }\n if (getLocal()) {\n _value.value = v\n }\n }\n }\n\n return value\n }\n\n // 创建一个拥有getter和setter的对象\n const value = {\n __v_isRef: true,\n\n get value(): Props[Name] {\n return (props[propName] ?? defaultValue) as Props[Name]\n },\n\n set value(v: Props[Name]) {\n emit(`update:${propName as string}`, v)\n }\n }\n\n return value\n}\n"],"mappings":";;;;;;;;;;AA6BA,SAAgB,SAId,SAC2E;CAC3E,MAAM,EACJ,OACA,WAAW,cACX,MACA,QAAQ,MACR,cACA,UAAU,UACR;AAEJ,KAAI,OAAO;EACT,MAAM,WAAW,MAAM,aAAa;EAIpC,MAAM,UAHI,UAAU,aAAa,KAGhB,SAAS;AAG1B,cACQ,MAAM,YACX,MAAM;AACL,UAAO,QAAQ;IAElB;EAED,MAAM,iBAAiB;AACrB,UAAO,OAAO,UAAU,aAAa,OAAO,GAAG;;AAkBjD,SAfc;GACZ,WAAW;GACX,IAAI,QAAQ;AACV,WAAO,OAAO;;GAEhB,IAAI,MAAM,GAAG;AACX,QAAI,MAAM,OAAO,MACf,MAAK,UAAU,YAAsB,EAAE;AAEzC,QAAI,UAAU,CACZ,QAAO,QAAQ;;GAGpB;;AAkBH,QAZc;EACZ,WAAW;EAEX,IAAI,QAAqB;AACvB,UAAQ,MAAM,aAAa;;EAG7B,IAAI,MAAM,GAAgB;AACxB,QAAK,UAAU,YAAsB,EAAE;;EAE1C"}
@@ -0,0 +1,53 @@
1
+ import { ShallowRef } from "vue";
2
+ import { ComputePositionReturn } from "@floating-ui/dom";
3
+
4
+ //#region src/use-pop/index.d.ts
5
+ type TipDirection = 'top' | 'bottom' | 'left' | 'right';
6
+ type TipAlign = 'center' | 'start' | 'end';
7
+ interface Options {
8
+ /** 触发元素 */
9
+ triggerRef: ShallowRef<HTMLElement | undefined>;
10
+ /** 内容元素 */
11
+ contentRef: ShallowRef<HTMLElement | undefined>;
12
+ /**
13
+ * 箭头元素,如果存在,则会在弹框的箭头位置显示箭头
14
+ */
15
+ arrowRef?: ShallowRef<HTMLElement | undefined>;
16
+ /** 方向 */
17
+ direction?: ShallowRef<TipDirection> | TipDirection;
18
+ /** 对齐方式 */
19
+ alignment?: ShallowRef<TipAlign> | TipAlign;
20
+ /**
21
+ * 箭头大小
22
+ * @default 10
23
+ */
24
+ arrowSize?: number;
25
+ /**
26
+ * 触发器元素位置变更时回调,
27
+ * 一般用于在触发器元素位置变更时更新弹框位置
28
+ */
29
+ onTriggerPositionChange?: () => void;
30
+ /** 更新元素前回调 */
31
+ onBeforeUpdate?: (triggerEl: HTMLElement, contentEl: HTMLElement) => void;
32
+ /** 更新元素后回调 */
33
+ onAfterUpdate?: (position: ComputePositionReturn) => void;
34
+ /** 弹框弹出时回调 */
35
+ onPop?: (position: ComputePositionReturn) => void;
36
+ }
37
+ interface PopResult {
38
+ /**
39
+ * 更新弹框位置
40
+ */
41
+ update: () => Promise<void>;
42
+ /** 浮框容器id */
43
+ popperContainerId: string;
44
+ }
45
+ /**
46
+ * 浮框组合式函数
47
+ * @param options 选项
48
+ * @returns
49
+ */
50
+ declare function usePop(options: Options): PopResult;
51
+ //#endregion
52
+ export { usePop };
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,121 @@
1
+ import { getScrollParents, setStyles } from "@veltra/utils";
2
+ import { isRef, onBeforeUnmount, watch } from "vue";
3
+ import { arrow, computePosition, flip, offset, shift } from "@floating-ui/dom";
4
+ //#region src/use-pop/index.ts
5
+ let popperContainer = null;
6
+ const popperContainerId = "pop-container";
7
+ /**
8
+ * 浮框组合式函数
9
+ * @param options 选项
10
+ * @returns
11
+ */
12
+ function usePop(options) {
13
+ if (!popperContainer) {
14
+ popperContainer = document.createElement("div");
15
+ popperContainer.id = popperContainerId;
16
+ document.body.appendChild(popperContainer);
17
+ }
18
+ const { triggerRef, contentRef, arrowRef, arrowSize = 10, onTriggerPositionChange, onAfterUpdate, onBeforeUpdate, direction, alignment, onPop } = options;
19
+ /** 箭头位置 */
20
+ const arrowPlacementDict = {
21
+ top: "bottom",
22
+ right: "left",
23
+ bottom: "top",
24
+ left: "right"
25
+ };
26
+ function getMaybeRefValue(value) {
27
+ return isRef(value) ? value.value : value;
28
+ }
29
+ /**
30
+ * 更新浮框位置
31
+ * @param callbackOnPop 是否在弹出时回调
32
+ */
33
+ async function update(callbackOnPop = false) {
34
+ const triggerEl = triggerRef.value;
35
+ const contentEl = contentRef.value;
36
+ if (!(triggerEl instanceof HTMLElement) || !(contentEl instanceof HTMLElement)) return;
37
+ onBeforeUpdate?.(triggerEl, contentEl);
38
+ const middleware = [
39
+ offset(arrowRef?.value ? arrowSize : 6),
40
+ flip(),
41
+ shift()
42
+ ];
43
+ if (arrowRef?.value) middleware.push(arrow({ element: arrowRef.value }));
44
+ const _direction = getMaybeRefValue(direction) ?? "top";
45
+ const _alignment = getMaybeRefValue(alignment) ?? "center";
46
+ const position = await computePosition(triggerEl, contentEl, {
47
+ middleware,
48
+ placement: `${_direction}${_alignment === "center" ? "" : `-${_alignment}`}`
49
+ });
50
+ const { x, y, middlewareData, placement } = position;
51
+ setStyles(contentEl, {
52
+ left: `${x}px`,
53
+ top: `${y}px`
54
+ });
55
+ callbackOnPop && onPop?.(position);
56
+ onAfterUpdate?.(position);
57
+ if (middlewareData.arrow) {
58
+ const { x: arrowX, y: arrowY } = middlewareData.arrow;
59
+ const arrowPlacement = arrowPlacementDict[placement.split("-")[0]];
60
+ const size = `${arrowSize}px`;
61
+ const arrowRadius = arrowSize / 2;
62
+ setStyles(arrowRef.value, {
63
+ width: size,
64
+ height: size,
65
+ left: arrowX && `${arrowX - arrowRadius}px`,
66
+ top: arrowY && `${arrowY - arrowRadius}px`,
67
+ [arrowPlacement]: `-${arrowRadius}px`
68
+ });
69
+ }
70
+ }
71
+ let scrollParents = [];
72
+ /** 为触发器元素的祖先元素添加滚动事件 */
73
+ function addScrollEvents() {
74
+ if (!triggerRef.value) return;
75
+ if (onTriggerPositionChange) {
76
+ scrollParents = getScrollParents(triggerRef.value);
77
+ scrollParents.forEach((el) => {
78
+ el.addEventListener("scroll", onTriggerPositionChange);
79
+ });
80
+ }
81
+ }
82
+ /** 移除触发器元素祖先元素的滚动事件 */
83
+ function removeScrollEvents() {
84
+ if (onTriggerPositionChange) scrollParents.forEach((el) => {
85
+ el.removeEventListener("scroll", onTriggerPositionChange);
86
+ });
87
+ scrollParents = [];
88
+ }
89
+ function addResizeEvents() {
90
+ onTriggerPositionChange && window.addEventListener("resize", onTriggerPositionChange);
91
+ }
92
+ function removeResizeEvents() {
93
+ onTriggerPositionChange && window.removeEventListener("resize", onTriggerPositionChange);
94
+ }
95
+ watch([
96
+ contentRef,
97
+ () => getMaybeRefValue(direction),
98
+ () => getMaybeRefValue(alignment)
99
+ ], ([content]) => {
100
+ if (content) {
101
+ update(true);
102
+ addScrollEvents();
103
+ addResizeEvents();
104
+ return;
105
+ }
106
+ removeScrollEvents();
107
+ removeResizeEvents();
108
+ });
109
+ onBeforeUnmount(() => {
110
+ removeScrollEvents();
111
+ removeResizeEvents();
112
+ });
113
+ return {
114
+ update,
115
+ popperContainerId
116
+ };
117
+ }
118
+ //#endregion
119
+ export { usePop };
120
+
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/use-pop/index.ts"],"sourcesContent":["import {\n computePosition,\n flip,\n shift,\n arrow,\n offset,\n type ComputePositionReturn,\n type Placement\n} from '@floating-ui/dom'\nimport { getScrollParents, setStyles } from '@veltra/utils'\nimport { isRef, onBeforeUnmount, watch, type Ref, type ShallowRef } from 'vue'\n\ntype TipDirection = 'top' | 'bottom' | 'left' | 'right'\ntype TipAlign = 'center' | 'start' | 'end'\n\ninterface Options {\n /** 触发元素 */\n triggerRef: ShallowRef<HTMLElement | undefined>\n /** 内容元素 */\n contentRef: ShallowRef<HTMLElement | undefined>\n /**\n * 箭头元素,如果存在,则会在弹框的箭头位置显示箭头\n */\n arrowRef?: ShallowRef<HTMLElement | undefined>\n /** 方向 */\n direction?: ShallowRef<TipDirection> | TipDirection\n /** 对齐方式 */\n alignment?: ShallowRef<TipAlign> | TipAlign\n /**\n * 箭头大小\n * @default 10\n */\n arrowSize?: number\n /**\n * 触发器元素位置变更时回调,\n * 一般用于在触发器元素位置变更时更新弹框位置\n */\n onTriggerPositionChange?: () => void\n /** 更新元素前回调 */\n onBeforeUpdate?: (triggerEl: HTMLElement, contentEl: HTMLElement) => void\n /** 更新元素后回调 */\n onAfterUpdate?: (position: ComputePositionReturn) => void\n /** 弹框弹出时回调 */\n onPop?: (position: ComputePositionReturn) => void\n}\n\ninterface PopResult {\n /**\n * 更新弹框位置\n */\n update: () => Promise<void>\n /** 浮框容器id */\n popperContainerId: string\n}\n\nlet popperContainer: HTMLElement | null = null\n\nconst popperContainerId = 'pop-container'\n\n/**\n * 浮框组合式函数\n * @param options 选项\n * @returns\n */\nexport function usePop(options: Options): PopResult {\n if (!popperContainer) {\n popperContainer = document.createElement('div')\n popperContainer.id = popperContainerId\n document.body.appendChild(popperContainer)\n }\n\n const {\n triggerRef,\n contentRef,\n arrowRef,\n arrowSize = 10,\n onTriggerPositionChange,\n onAfterUpdate,\n onBeforeUpdate,\n direction,\n alignment,\n onPop\n } = options\n\n /** 箭头位置 */\n const arrowPlacementDict = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }\n\n function getMaybeRefValue<T>(value?: Ref<T> | T) {\n return isRef(value) ? value.value : value\n }\n\n /**\n * 更新浮框位置\n * @param callbackOnPop 是否在弹出时回调\n */\n async function update(callbackOnPop = false) {\n const triggerEl = triggerRef.value\n const contentEl = contentRef.value\n\n if (!(triggerEl instanceof HTMLElement) || !(contentEl instanceof HTMLElement)) {\n return\n }\n\n onBeforeUpdate?.(triggerEl, contentEl)\n\n // 计算位置 ↓↓↓\n const middleware = [offset(arrowRef?.value ? arrowSize : 6), flip(), shift()]\n\n if (arrowRef?.value) {\n middleware.push(arrow({ element: arrowRef.value }))\n }\n\n const _direction = getMaybeRefValue(direction) ?? 'top'\n const _alignment = getMaybeRefValue(alignment) ?? 'center'\n\n const position = await computePosition(triggerEl, contentEl, {\n middleware,\n\n placement: `${_direction}${_alignment === 'center' ? '' : `-${_alignment}`}` as Placement\n })\n\n const { x, y, middlewareData, placement } = position\n\n setStyles(contentEl, { left: `${x}px`, top: `${y}px` })\n callbackOnPop && onPop?.(position)\n onAfterUpdate?.(position)\n\n // 设置箭头位置 ↓↓↓\n if (middlewareData.arrow) {\n const { x: arrowX, y: arrowY } = middlewareData.arrow\n\n const arrowPlacement =\n arrowPlacementDict[placement.split('-')[0]! as keyof typeof arrowPlacementDict]\n const size = `${arrowSize}px`\n // 箭头半径\n const arrowRadius = arrowSize / 2\n\n setStyles(arrowRef!.value!, {\n width: size,\n height: size,\n left: arrowX && `${arrowX - arrowRadius}px`,\n top: arrowY && `${arrowY - arrowRadius}px`,\n [arrowPlacement]: `-${arrowRadius}px`\n })\n }\n // 设置箭头位置 ↑↑↑\n }\n\n let scrollParents: HTMLElement[] = []\n\n /** 为触发器元素的祖先元素添加滚动事件 */\n function addScrollEvents() {\n if (!triggerRef.value) return\n if (onTriggerPositionChange) {\n scrollParents = getScrollParents(triggerRef.value)\n scrollParents.forEach((el) => {\n el.addEventListener('scroll', onTriggerPositionChange)\n })\n }\n }\n\n /** 移除触发器元素祖先元素的滚动事件 */\n function removeScrollEvents() {\n if (onTriggerPositionChange) {\n scrollParents.forEach((el) => {\n el.removeEventListener('scroll', onTriggerPositionChange)\n })\n }\n\n scrollParents = []\n }\n\n function addResizeEvents() {\n onTriggerPositionChange && window.addEventListener('resize', onTriggerPositionChange)\n }\n\n function removeResizeEvents() {\n onTriggerPositionChange && window.removeEventListener('resize', onTriggerPositionChange)\n }\n\n watch(\n [contentRef, () => getMaybeRefValue(direction), () => getMaybeRefValue(alignment)],\n ([content]) => {\n if (content) {\n update(true)\n addScrollEvents()\n addResizeEvents()\n return\n }\n removeScrollEvents()\n removeResizeEvents()\n }\n )\n\n onBeforeUnmount(() => {\n removeScrollEvents()\n removeResizeEvents()\n })\n\n return {\n /** 更新浮框位置 */\n update,\n /** 浮框容器id */\n popperContainerId\n }\n}\n"],"mappings":";;;;AAuDA,IAAI,kBAAsC;AAE1C,MAAM,oBAAoB;;;;;;AAO1B,SAAgB,OAAO,SAA6B;AAClD,KAAI,CAAC,iBAAiB;AACpB,oBAAkB,SAAS,cAAc,MAAM;AAC/C,kBAAgB,KAAK;AACrB,WAAS,KAAK,YAAY,gBAAgB;;CAG5C,MAAM,EACJ,YACA,YACA,UACA,YAAY,IACZ,yBACA,eACA,gBACA,WACA,WACA,UACE;;CAGJ,MAAM,qBAAqB;EAAE,KAAK;EAAU,OAAO;EAAQ,QAAQ;EAAO,MAAM;EAAS;CAEzF,SAAS,iBAAoB,OAAoB;AAC/C,SAAO,MAAM,MAAM,GAAG,MAAM,QAAQ;;;;;;CAOtC,eAAe,OAAO,gBAAgB,OAAO;EAC3C,MAAM,YAAY,WAAW;EAC7B,MAAM,YAAY,WAAW;AAE7B,MAAI,EAAE,qBAAqB,gBAAgB,EAAE,qBAAqB,aAChE;AAGF,mBAAiB,WAAW,UAAU;EAGtC,MAAM,aAAa;GAAC,OAAO,UAAU,QAAQ,YAAY,EAAE;GAAE,MAAM;GAAE,OAAO;GAAC;AAE7E,MAAI,UAAU,MACZ,YAAW,KAAK,MAAM,EAAE,SAAS,SAAS,OAAO,CAAC,CAAC;EAGrD,MAAM,aAAa,iBAAiB,UAAU,IAAI;EAClD,MAAM,aAAa,iBAAiB,UAAU,IAAI;EAElD,MAAM,WAAW,MAAM,gBAAgB,WAAW,WAAW;GAC3D;GAEA,WAAW,GAAG,aAAa,eAAe,WAAW,KAAK,IAAI;GAC/D,CAAC;EAEF,MAAM,EAAE,GAAG,GAAG,gBAAgB,cAAc;AAE5C,YAAU,WAAW;GAAE,MAAM,GAAG,EAAE;GAAK,KAAK,GAAG,EAAE;GAAK,CAAC;AACvD,mBAAiB,QAAQ,SAAS;AAClC,kBAAgB,SAAS;AAGzB,MAAI,eAAe,OAAO;GACxB,MAAM,EAAE,GAAG,QAAQ,GAAG,WAAW,eAAe;GAEhD,MAAM,iBACJ,mBAAmB,UAAU,MAAM,IAAI,CAAC;GAC1C,MAAM,OAAO,GAAG,UAAU;GAE1B,MAAM,cAAc,YAAY;AAEhC,aAAU,SAAU,OAAQ;IAC1B,OAAO;IACP,QAAQ;IACR,MAAM,UAAU,GAAG,SAAS,YAAY;IACxC,KAAK,UAAU,GAAG,SAAS,YAAY;KACtC,iBAAiB,IAAI,YAAY;IACnC,CAAC;;;CAKN,IAAI,gBAA+B,EAAE;;CAGrC,SAAS,kBAAkB;AACzB,MAAI,CAAC,WAAW,MAAO;AACvB,MAAI,yBAAyB;AAC3B,mBAAgB,iBAAiB,WAAW,MAAM;AAClD,iBAAc,SAAS,OAAO;AAC5B,OAAG,iBAAiB,UAAU,wBAAwB;KACtD;;;;CAKN,SAAS,qBAAqB;AAC5B,MAAI,wBACF,eAAc,SAAS,OAAO;AAC5B,MAAG,oBAAoB,UAAU,wBAAwB;IACzD;AAGJ,kBAAgB,EAAE;;CAGpB,SAAS,kBAAkB;AACzB,6BAA2B,OAAO,iBAAiB,UAAU,wBAAwB;;CAGvF,SAAS,qBAAqB;AAC5B,6BAA2B,OAAO,oBAAoB,UAAU,wBAAwB;;AAG1F,OACE;EAAC;QAAkB,iBAAiB,UAAU;QAAQ,iBAAiB,UAAU;EAAC,GACjF,CAAC,aAAa;AACb,MAAI,SAAS;AACX,UAAO,KAAK;AACZ,oBAAiB;AACjB,oBAAiB;AACjB;;AAEF,sBAAoB;AACpB,sBAAoB;GAEvB;AAED,uBAAsB;AACpB,sBAAoB;AACpB,sBAAoB;GACpB;AAEF,QAAO;EAEL;EAEA;EACD"}
@@ -0,0 +1,17 @@
1
+ import { RefElement } from "../use-resize-observer/index.js";
2
+
3
+ //#region src/use-reactive-size/index.d.ts
4
+ interface ElementSize {
5
+ width: number;
6
+ height: number;
7
+ }
8
+ /**
9
+ * 响应式尺寸
10
+ * @param targets 目标元素
11
+ * @returns 目标元素的宽高
12
+ */
13
+ declare function useReactiveSize(target: RefElement): ElementSize;
14
+ declare function useReactiveSize(targets: RefElement[]): ElementSize[];
15
+ //#endregion
16
+ export { useReactiveSize };
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,40 @@
1
+ import { useResizeObserver } from "../use-resize-observer/index.js";
2
+ import { computed, reactive } from "vue";
3
+ //#region src/use-reactive-size/index.ts
4
+ function useReactiveSize(targets) {
5
+ const sizes = Array.isArray(targets) ? targets.map(() => {
6
+ return reactive({
7
+ width: 0,
8
+ height: 0
9
+ });
10
+ }) : reactive({
11
+ width: 0,
12
+ height: 0
13
+ });
14
+ const sizesMap = Array.isArray(targets) ? computed(() => {
15
+ const entries = targets.map((target, index) => {
16
+ return [target.value, sizes[index]];
17
+ }).filter(([target]) => target);
18
+ return new WeakMap(entries);
19
+ }) : computed(() => {
20
+ return new WeakMap(targets.value ? [[targets.value, sizes]] : []);
21
+ });
22
+ useResizeObserver({
23
+ targets,
24
+ onResize(entries) {
25
+ entries.forEach((entry) => {
26
+ const borderBoxSize = entry.borderBoxSize[0];
27
+ const size = sizesMap.value.get(entry.target);
28
+ if (size && borderBoxSize) {
29
+ size.width = borderBoxSize.inlineSize;
30
+ size.height = borderBoxSize.blockSize;
31
+ }
32
+ });
33
+ }
34
+ });
35
+ return sizes;
36
+ }
37
+ //#endregion
38
+ export { useReactiveSize };
39
+
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/use-reactive-size/index.ts"],"sourcesContent":["import { computed, reactive } from 'vue'\n\nimport { useResizeObserver, type RefElement } from '../use-resize-observer'\n\ninterface ElementSize {\n width: number\n height: number\n}\n\n/**\n * 响应式尺寸\n * @param targets 目标元素\n * @returns 目标元素的宽高\n */\nexport function useReactiveSize(target: RefElement): ElementSize\nexport function useReactiveSize(targets: RefElement[]): ElementSize[]\nexport function useReactiveSize(targets: RefElement | RefElement[]): ElementSize | ElementSize[] {\n const sizes = Array.isArray(targets)\n ? targets.map(() => {\n return reactive({ width: 0, height: 0 })\n })\n : reactive({ width: 0, height: 0 })\n\n const sizesMap = Array.isArray(targets)\n ? computed(() => {\n const entries = targets\n .map((target, index) => {\n return [target.value!, (sizes as ElementSize[])[index]!]\n })\n .filter(([target]) => target) as [HTMLElement, ElementSize][]\n\n return new WeakMap(entries)\n })\n : computed(() => {\n return new WeakMap(targets.value ? [[targets.value, sizes as ElementSize]] : [])\n })\n\n useResizeObserver({\n targets,\n onResize(entries) {\n entries.forEach((entry) => {\n const borderBoxSize = entry.borderBoxSize[0]!\n const size = sizesMap.value.get(entry.target as HTMLElement)\n if (size && borderBoxSize) {\n size.width = borderBoxSize.inlineSize\n size.height = borderBoxSize.blockSize\n }\n })\n }\n })\n\n return sizes\n}\n"],"mappings":";;;AAgBA,SAAgB,gBAAgB,SAAiE;CAC/F,MAAM,QAAQ,MAAM,QAAQ,QAAQ,GAChC,QAAQ,UAAU;AAChB,SAAO,SAAS;GAAE,OAAO;GAAG,QAAQ;GAAG,CAAC;GACxC,GACF,SAAS;EAAE,OAAO;EAAG,QAAQ;EAAG,CAAC;CAErC,MAAM,WAAW,MAAM,QAAQ,QAAQ,GACnC,eAAe;EACb,MAAM,UAAU,QACb,KAAK,QAAQ,UAAU;AACtB,UAAO,CAAC,OAAO,OAAS,MAAwB,OAAQ;IACxD,CACD,QAAQ,CAAC,YAAY,OAAO;AAE/B,SAAO,IAAI,QAAQ,QAAQ;GAC3B,GACF,eAAe;AACb,SAAO,IAAI,QAAQ,QAAQ,QAAQ,CAAC,CAAC,QAAQ,OAAO,MAAqB,CAAC,GAAG,EAAE,CAAC;GAChF;AAEN,mBAAkB;EAChB;EACA,SAAS,SAAS;AAChB,WAAQ,SAAS,UAAU;IACzB,MAAM,gBAAgB,MAAM,cAAc;IAC1C,MAAM,OAAO,SAAS,MAAM,IAAI,MAAM,OAAsB;AAC5D,QAAI,QAAQ,eAAe;AACzB,UAAK,QAAQ,cAAc;AAC3B,UAAK,SAAS,cAAc;;KAE9B;;EAEL,CAAC;AAEF,QAAO"}
@@ -0,0 +1,33 @@
1
+ import { Ref, ShallowRef } from "vue";
2
+
3
+ //#region src/use-resize-observer/index.d.ts
4
+ type RefElement = ShallowRef<HTMLElement | undefined | null> | Ref<HTMLElement | undefined | null>;
5
+ interface ResizeObserverOptions {
6
+ /** 目标节点 */
7
+ targets: RefElement | RefElement[];
8
+ /** resize事件 */
9
+ onResize: ResizeObserverCallback;
10
+ /** 指定观察条件 */
11
+ when?: () => boolean;
12
+ }
13
+ /** 监听器 */
14
+ type ResizeObserverReturn = {
15
+ /** 终止监听 */disconnect: () => void;
16
+ };
17
+ /**
18
+ * 监听目标尺寸变化
19
+ * @param options 选项
20
+ */
21
+ declare function useResizeObserver(options: ResizeObserverOptions): ResizeObserverReturn;
22
+ /**
23
+ * 监听元素尺寸变化
24
+ */
25
+ declare function useObserverCallback(): {
26
+ observeEl: <El extends HTMLElement>(el: El, cb: (entry: Omit<ResizeObserverEntry, 'target'> & {
27
+ target: El;
28
+ }) => void) => void;
29
+ unobserveEl: (el: HTMLElement) => void;
30
+ };
31
+ //#endregion
32
+ export { RefElement, ResizeObserverReturn, useObserverCallback, useResizeObserver };
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,92 @@
1
+ import { onBeforeUnmount, watch } from "vue";
2
+ //#region src/use-resize-observer/index.ts
3
+ /**
4
+ * 取消监听
5
+ * @param targets 目标节点
6
+ * @param observer 观察器
7
+ */
8
+ function unobserve(targets, observer) {
9
+ if (Array.isArray(targets)) return targets.forEach((target) => unobserve(target, observer));
10
+ if (!targets.value || !observer) return;
11
+ observer.unobserve(targets.value);
12
+ observer.disconnect();
13
+ }
14
+ /**
15
+ * 监听目标尺寸变化
16
+ * @param options 选项
17
+ */
18
+ function useResizeObserver(options) {
19
+ const { targets, onResize } = options;
20
+ let observer;
21
+ if (Array.isArray(targets)) watch(targets, (val, oldVal) => {
22
+ oldVal.forEach((target) => {
23
+ target && observer?.unobserve(target);
24
+ });
25
+ if (!observer && !!val.length) observer = new ResizeObserver(onResize);
26
+ val.forEach((target) => {
27
+ target && observer?.observe(target);
28
+ });
29
+ }, { immediate: true });
30
+ else watch(targets, (val, oldVal) => {
31
+ oldVal && observer?.unobserve(oldVal);
32
+ if (!observer && val) observer = new ResizeObserver(onResize);
33
+ val && observer?.observe(val);
34
+ }, { immediate: true });
35
+ onBeforeUnmount(() => {
36
+ unobserve(targets, observer);
37
+ observer = void 0;
38
+ });
39
+ return { disconnect() {
40
+ unobserve(targets, observer);
41
+ observer = void 0;
42
+ } };
43
+ }
44
+ /**
45
+ * 监听元素尺寸变化
46
+ */
47
+ function useObserverCallback() {
48
+ const observerElMap = /* @__PURE__ */ new Map();
49
+ const observer = new ResizeObserver((entries) => {
50
+ entries.forEach((entry) => {
51
+ const target = entry.target;
52
+ if (!target.dataset.ob) {
53
+ target.dataset.ob = "true";
54
+ return;
55
+ }
56
+ observerElMap.get(target)?.(entry);
57
+ });
58
+ });
59
+ /**
60
+ * 监听元素尺寸
61
+ * @param el 元素
62
+ * @param cb 回调
63
+ */
64
+ function observeEl(el, cb) {
65
+ observer.observe(el);
66
+ observerElMap.set(el, cb);
67
+ }
68
+ /**
69
+ * 取消监听元素尺寸
70
+ * @param el 元素
71
+ */
72
+ function unobserveEl(el) {
73
+ observer.unobserve(el);
74
+ delete el.dataset.ob;
75
+ observerElMap.delete(el);
76
+ }
77
+ onBeforeUnmount(() => {
78
+ observerElMap.forEach((_, el) => {
79
+ observer.unobserve(el);
80
+ });
81
+ observerElMap.clear();
82
+ observer.disconnect();
83
+ });
84
+ return {
85
+ observeEl,
86
+ unobserveEl
87
+ };
88
+ }
89
+ //#endregion
90
+ export { useObserverCallback, useResizeObserver };
91
+
92
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/use-resize-observer/index.ts"],"sourcesContent":["import { type Ref, type ShallowRef, onBeforeUnmount, watch } from 'vue'\n\nexport type RefElement =\n | ShallowRef<HTMLElement | undefined | null>\n | Ref<HTMLElement | undefined | null>\n\ninterface ResizeObserverOptions {\n /** 目标节点 */\n targets: RefElement | RefElement[]\n /** resize事件 */\n onResize: ResizeObserverCallback\n /** 指定观察条件 */\n when?: () => boolean\n}\n\n/** 监听器 */\nexport type ResizeObserverReturn = {\n /** 终止监听 */\n disconnect: () => void\n}\n\n/**\n * 取消监听\n * @param targets 目标节点\n * @param observer 观察器\n */\nfunction unobserve(targets: RefElement | RefElement[], observer?: ResizeObserver) {\n if (Array.isArray(targets)) {\n return targets.forEach((target) => unobserve(target, observer))\n }\n if (!targets.value || !observer) return\n observer.unobserve(targets.value)\n observer.disconnect()\n}\n\n/**\n * 监听目标尺寸变化\n * @param options 选项\n */\nexport function useResizeObserver(options: ResizeObserverOptions): ResizeObserverReturn {\n const { targets, onResize } = options\n\n let observer: ResizeObserver | undefined\n\n if (Array.isArray(targets)) {\n watch(\n targets,\n (val, oldVal) => {\n // 清除旧的观察\n oldVal.forEach((target) => {\n target && observer?.unobserve(target)\n })\n\n if (!observer && !!val.length) {\n observer = new ResizeObserver(onResize)\n }\n\n val.forEach((target) => {\n target && observer?.observe(target)\n })\n },\n { immediate: true }\n )\n } else {\n watch(\n targets,\n (val, oldVal) => {\n oldVal && observer?.unobserve(oldVal)\n if (!observer && val) {\n observer = new ResizeObserver(onResize)\n }\n val && observer?.observe(val)\n },\n { immediate: true }\n )\n }\n\n onBeforeUnmount(() => {\n unobserve(targets, observer)\n observer = undefined\n })\n\n return {\n disconnect() {\n unobserve(targets, observer)\n observer = undefined\n }\n }\n}\n\n/**\n * 监听元素尺寸变化\n */\nexport function useObserverCallback(): {\n observeEl: <El extends HTMLElement>(\n el: El,\n cb: (entry: Omit<ResizeObserverEntry, 'target'> & { target: El }) => void\n ) => void\n unobserveEl: (el: HTMLElement) => void\n} {\n const observerElMap = new Map<HTMLElement, Function>()\n\n const observer = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const target = entry.target as HTMLElement\n if (!target.dataset.ob) {\n target.dataset.ob = 'true'\n return\n }\n const fn = observerElMap.get(target)\n\n fn?.(entry)\n })\n })\n\n /**\n * 监听元素尺寸\n * @param el 元素\n * @param cb 回调\n */\n function observeEl<El extends HTMLElement>(\n el: El,\n cb: (entry: Omit<ResizeObserverEntry, 'target'> & { target: El }) => void\n ) {\n observer.observe(el)\n observerElMap.set(el, cb)\n }\n\n /**\n * 取消监听元素尺寸\n * @param el 元素\n */\n function unobserveEl(el: HTMLElement) {\n observer.unobserve(el)\n delete el.dataset.ob\n observerElMap.delete(el)\n }\n\n onBeforeUnmount(() => {\n observerElMap.forEach((_, el) => {\n observer.unobserve(el)\n })\n observerElMap.clear()\n observer.disconnect()\n })\n\n return { observeEl, unobserveEl }\n}\n"],"mappings":";;;;;;;AA0BA,SAAS,UAAU,SAAoC,UAA2B;AAChF,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QAAQ,SAAS,WAAW,UAAU,QAAQ,SAAS,CAAC;AAEjE,KAAI,CAAC,QAAQ,SAAS,CAAC,SAAU;AACjC,UAAS,UAAU,QAAQ,MAAM;AACjC,UAAS,YAAY;;;;;;AAOvB,SAAgB,kBAAkB,SAAsD;CACtF,MAAM,EAAE,SAAS,aAAa;CAE9B,IAAI;AAEJ,KAAI,MAAM,QAAQ,QAAQ,CACxB,OACE,UACC,KAAK,WAAW;AAEf,SAAO,SAAS,WAAW;AACzB,aAAU,UAAU,UAAU,OAAO;IACrC;AAEF,MAAI,CAAC,YAAY,CAAC,CAAC,IAAI,OACrB,YAAW,IAAI,eAAe,SAAS;AAGzC,MAAI,SAAS,WAAW;AACtB,aAAU,UAAU,QAAQ,OAAO;IACnC;IAEJ,EAAE,WAAW,MAAM,CACpB;KAED,OACE,UACC,KAAK,WAAW;AACf,YAAU,UAAU,UAAU,OAAO;AACrC,MAAI,CAAC,YAAY,IACf,YAAW,IAAI,eAAe,SAAS;AAEzC,SAAO,UAAU,QAAQ,IAAI;IAE/B,EAAE,WAAW,MAAM,CACpB;AAGH,uBAAsB;AACpB,YAAU,SAAS,SAAS;AAC5B,aAAW,KAAA;GACX;AAEF,QAAO,EACL,aAAa;AACX,YAAU,SAAS,SAAS;AAC5B,aAAW,KAAA;IAEd;;;;;AAMH,SAAgB,sBAMd;CACA,MAAM,gCAAgB,IAAI,KAA4B;CAEtD,MAAM,WAAW,IAAI,gBAAgB,YAAY;AAC/C,UAAQ,SAAS,UAAU;GACzB,MAAM,SAAS,MAAM;AACrB,OAAI,CAAC,OAAO,QAAQ,IAAI;AACtB,WAAO,QAAQ,KAAK;AACpB;;AAES,iBAAc,IAAI,OAAO,GAE/B,MAAM;IACX;GACF;;;;;;CAOF,SAAS,UACP,IACA,IACA;AACA,WAAS,QAAQ,GAAG;AACpB,gBAAc,IAAI,IAAI,GAAG;;;;;;CAO3B,SAAS,YAAY,IAAiB;AACpC,WAAS,UAAU,GAAG;AACtB,SAAO,GAAG,QAAQ;AAClB,gBAAc,OAAO,GAAG;;AAG1B,uBAAsB;AACpB,gBAAc,SAAS,GAAG,OAAO;AAC/B,YAAS,UAAU,GAAG;IACtB;AACF,gBAAc,OAAO;AACrB,WAAS,YAAY;GACrB;AAEF,QAAO;EAAE;EAAW;EAAa"}
@@ -0,0 +1,18 @@
1
+ import { CssTransitionOptions, Returned, StyleTransitionOptions } from "./type.js";
2
+
3
+ //#region src/use-transition/index.d.ts
4
+ /**
5
+ * 使用CSS类过渡
6
+ * @param type 过渡类型
7
+ * @param options 过渡选项
8
+ */
9
+ declare function useTransition(type: 'css', options: CssTransitionOptions): Returned;
10
+ /**
11
+ * 使用style样式过渡
12
+ * @param type 过渡类型
13
+ * @param options 过渡选项
14
+ */
15
+ declare function useTransition(type: 'style', options: StyleTransitionOptions): Returned;
16
+ //#endregion
17
+ export { useTransition };
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { useCssTransition } from "./use-css-transition.js";
2
+ import { useStyleTransition } from "./use-style-transition.js";
3
+ //#region src/use-transition/index.ts
4
+ function useTransition(type, options) {
5
+ if (type === "css") return useCssTransition(options);
6
+ return useStyleTransition(options);
7
+ }
8
+ //#endregion
9
+ export { useTransition };
10
+
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/use-transition/index.ts"],"sourcesContent":["import type { Returned, CssTransitionOptions, StyleTransitionOptions } from './type'\nimport { useCssTransition } from './use-css-transition'\nimport { useStyleTransition } from './use-style-transition'\n\n/**\n * 使用CSS类过渡\n * @param type 过渡类型\n * @param options 过渡选项\n */\nexport function useTransition(type: 'css', options: CssTransitionOptions): Returned\n/**\n * 使用style样式过渡\n * @param type 过渡类型\n * @param options 过渡选项\n */\nexport function useTransition(type: 'style', options: StyleTransitionOptions): Returned\nexport function useTransition(type: string, options: any): Returned {\n if (type === 'css') {\n return useCssTransition(options)\n }\n return useStyleTransition(options)\n}\n"],"mappings":";;;AAgBA,SAAgB,cAAc,MAAc,SAAwB;AAClE,KAAI,SAAS,MACX,QAAO,iBAAiB,QAAQ;AAElC,QAAO,mBAAmB,QAAQ"}
@@ -0,0 +1,47 @@
1
+ import { CSSProperties, Ref, ShallowRef } from "vue";
2
+
3
+ //#region src/use-transition/type.d.ts
4
+ interface TransitionBase {
5
+ /** 被应用的目标元素 */
6
+ target: ShallowRef<HTMLElement | undefined> | HTMLElement;
7
+ /** 进入动画结束回调 */
8
+ afterEnter?: () => void;
9
+ /** 进入动画被取消回调 */
10
+ enterCanceled?: () => void;
11
+ /** 离开动画结束回调 */
12
+ afterLeave?: () => void;
13
+ /** 离开动画被取消回调 */
14
+ leaveCanceled?: () => void;
15
+ }
16
+ interface CssTransitionOptions extends TransitionBase {
17
+ /** 类的名称, 会生成 `${name}-enter-${'to' | 'active' | 'from'}`, `${name}-leave-${'to' | 'active' | 'from'}这几种类` */
18
+ name: ShallowRef<string> | string | Ref<string>;
19
+ /** 保留进入类 */
20
+ keepEnterTo?: boolean;
21
+ }
22
+ interface StyleTransitionOptions extends TransitionBase {
23
+ /** 进入后的样式 */
24
+ enterTo: CSSProperties;
25
+ /** 进入过渡时的样式 */
26
+ enterActive: CSSProperties;
27
+ /** 离开过渡时的样式 */
28
+ leaveActive: CSSProperties;
29
+ }
30
+ interface Returned {
31
+ /**
32
+ * 切换进入/离开动画
33
+ * @param active 是否激活
34
+ */
35
+ toggle(active: boolean | ((active: boolean) => boolean)): void;
36
+ /**
37
+ * 标记进入动画, toggle(true)的别名
38
+ */
39
+ enter(): void;
40
+ /**
41
+ * 标记离开动画, toggle(false)的别名
42
+ */
43
+ leave(): void;
44
+ }
45
+ //#endregion
46
+ export { CssTransitionOptions, Returned, StyleTransitionOptions };
47
+ //# sourceMappingURL=type.d.ts.map
@@ -0,0 +1,129 @@
1
+ import { createToggle } from "@veltra/utils";
2
+ import { computed, isRef, onBeforeUnmount, watch } from "vue";
3
+ //#region src/use-transition/use-css-transition.ts
4
+ const increaseTransitionCount = (el) => {
5
+ el._count = (el._count ?? 0) + 1;
6
+ };
7
+ const decreaseTransitionCount = (el) => {
8
+ el._count = (el._count ?? 0) - 1;
9
+ if (el._count <= 0) delete el._count;
10
+ };
11
+ /**
12
+ * 使用css过渡
13
+ * @param options 过渡选项
14
+ */
15
+ function useCssTransition(options) {
16
+ const { name, target, afterEnter, afterLeave, enterCanceled, leaveCanceled, keepEnterTo = false } = options;
17
+ const getDom = () => isRef(target) ? target.value : target;
18
+ const classes = computed(() => {
19
+ const _name = typeof name === "string" ? name : name.value;
20
+ return {
21
+ enterFrom: `${_name}-enter-from`,
22
+ enterTo: `${_name}-enter-to`,
23
+ enterActive: `${_name}-enter-active`,
24
+ leaveFrom: `${_name}-leave-from`,
25
+ leaveTo: `${_name}-leave-to`,
26
+ leaveActive: `${_name}-leave-active`
27
+ };
28
+ });
29
+ /** 开始进入动画 */
30
+ const startTransitionIn = () => {
31
+ const { enterActive, enterTo, enterFrom } = classes.value;
32
+ const dom = getDom();
33
+ dom?.classList.add(enterFrom);
34
+ requestAnimationFrame(() => {
35
+ dom?.classList.add(enterActive);
36
+ requestAnimationFrame(() => {
37
+ dom?.classList.remove(enterFrom);
38
+ dom?.classList.add(enterTo);
39
+ });
40
+ });
41
+ };
42
+ /** 开始离开动画 */
43
+ const startTransitionOut = () => {
44
+ const { leaveTo, leaveActive, leaveFrom, enterTo } = classes.value;
45
+ const dom = getDom();
46
+ if (keepEnterTo) dom?.classList.remove(enterTo);
47
+ dom?.classList.add(leaveFrom, leaveActive);
48
+ requestAnimationFrame(() => {
49
+ dom?.classList.add(leaveActive);
50
+ requestAnimationFrame(() => {
51
+ dom?.classList.remove(leaveFrom);
52
+ dom?.classList.add(leaveTo);
53
+ });
54
+ });
55
+ };
56
+ const [active, toggle] = createToggle(false, (_active) => {
57
+ _active ? startTransitionIn() : startTransitionOut();
58
+ });
59
+ const transitionEndHandler = (e) => {
60
+ e.stopPropagation();
61
+ const { leaveActive, enterActive, enterTo, leaveTo } = classes.value;
62
+ const dom = getDom();
63
+ if (dom !== e.target) return;
64
+ decreaseTransitionCount(dom);
65
+ if (dom._count) return;
66
+ if (active.value) {
67
+ if (keepEnterTo) dom?.classList.remove(enterActive);
68
+ else dom?.classList.remove(enterActive, enterTo);
69
+ afterEnter?.();
70
+ } else {
71
+ dom?.classList.remove(leaveActive, leaveTo);
72
+ afterLeave?.();
73
+ }
74
+ };
75
+ const transitionRunHandler = (e) => {
76
+ e.stopPropagation();
77
+ const dom = getDom();
78
+ if (dom !== e.target) return;
79
+ increaseTransitionCount(dom);
80
+ };
81
+ const transitionCancelHandler = (e) => {
82
+ e.stopPropagation();
83
+ const dom = getDom();
84
+ if (dom !== e.target) return;
85
+ decreaseTransitionCount(dom);
86
+ if (dom._count) return;
87
+ const { leaveActive, enterActive } = classes.value;
88
+ if (active.value) {
89
+ dom?.classList.remove(enterActive);
90
+ enterCanceled?.();
91
+ } else {
92
+ dom?.classList.remove(leaveActive);
93
+ leaveCanceled?.();
94
+ }
95
+ };
96
+ /** 添加事件 */
97
+ const addEvent = (el) => {
98
+ el?.addEventListener("transitioncancel", transitionCancelHandler);
99
+ el?.addEventListener("transitionend", transitionEndHandler);
100
+ el?.addEventListener("transitionrun", transitionRunHandler);
101
+ };
102
+ /** 移除事件 */
103
+ const removeEvent = (el) => {
104
+ el?.removeEventListener("transitioncancel", transitionCancelHandler);
105
+ el?.removeEventListener("transitionend", transitionEndHandler);
106
+ el?.removeEventListener("transitionrun", transitionRunHandler);
107
+ };
108
+ if (isRef(target)) watch(target, (_target, oldTarget) => {
109
+ if (oldTarget) removeEvent(oldTarget);
110
+ _target && addEvent(_target);
111
+ });
112
+ else if (target) addEvent(target);
113
+ onBeforeUnmount(() => {
114
+ removeEvent(getDom());
115
+ });
116
+ return {
117
+ toggle,
118
+ enter() {
119
+ toggle(true);
120
+ },
121
+ leave() {
122
+ toggle(false);
123
+ }
124
+ };
125
+ }
126
+ //#endregion
127
+ export { useCssTransition };
128
+
129
+ //# sourceMappingURL=use-css-transition.js.map