@antdv-next/cssinjs 1.0.0-rc.1 → 1.0.0-rc.3

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.
@@ -1,11 +1,11 @@
1
1
  import { Linter } from "./linters/interface.mjs";
2
2
  import "./linters/index.mjs";
3
3
  import { Entity, KeyType } from "./Cache.mjs";
4
- import * as vue0 from "vue";
4
+ import * as vue7 from "vue";
5
5
  import { App, Ref } from "vue";
6
6
 
7
7
  //#region src/StyleContext.d.ts
8
- declare function createCache(): vue0.Raw<Entity>;
8
+ declare function createCache(): vue7.Raw<Entity>;
9
9
  declare function useStyleContextProvide(props: Ref<StyleContextProps>): void;
10
10
  declare function provideStyleContext(app: App, props: Ref<StyleContextProps>): void;
11
11
  declare function useStyleContext(): Ref<{
@@ -105,6 +105,6 @@ interface StyleContextProps {
105
105
  autoPrefix?: boolean;
106
106
  }
107
107
  type StyleProviderProps = StyleContextProps;
108
- declare const StyleProvider: vue0.DefineSetupFnComponent<Partial<StyleContextProps>, {}, {}, Partial<StyleContextProps> & {}, vue0.PublicProps>;
108
+ declare const StyleProvider: vue7.DefineSetupFnComponent<Partial<StyleContextProps>, {}, {}, Partial<StyleContextProps> & {}, vue7.PublicProps>;
109
109
  //#endregion
110
110
  export { StyleProvider, StyleProviderProps, createCache, provideStyleContext, useStyleContext, useStyleContextProvide };
@@ -6,7 +6,7 @@ import "../../index.mjs";
6
6
  import { UseCSP } from "../hooks/useCSP.mjs";
7
7
  import { UsePrefix } from "../hooks/usePrefix.mjs";
8
8
  import { UseToken } from "../hooks/useToken.mjs";
9
- import * as vue2 from "vue";
9
+ import * as vue0 from "vue";
10
10
  import { Ref, UnwrapRef } from "vue";
11
11
 
12
12
  //#region src/cssinjs-utils/util/genStyleUtils.d.ts
@@ -81,7 +81,7 @@ declare function genStyleUtils<CompTokenMap extends TokenMap, AliasToken extends
81
81
  * @default true
82
82
  */
83
83
  injectStyle?: boolean;
84
- }) => (prefixCls: Ref<string>, rootCls?: Ref<string | undefined>) => readonly [Ref<string, string>, vue2.ComputedRef<string | undefined>];
84
+ }) => (prefixCls: Ref<string>, rootCls?: Ref<string | undefined>) => readonly [Ref<string, string>, vue0.ComputedRef<string | undefined>];
85
85
  genSubStyleComponent: <C extends TokenMapKey<CompTokenMap>>(componentName: C | [C, string], styleFn: GenStyleFn<CompTokenMap, AliasToken, C>, getDefaultToken?: GetDefaultToken<CompTokenMap, AliasToken, C>, options?: {
86
86
  resetStyle?: boolean;
87
87
  resetFont?: boolean;
@@ -96,13 +96,13 @@ declare function genStyleUtils<CompTokenMap extends TokenMap, AliasToken extends
96
96
  order?: number;
97
97
  injectStyle?: boolean;
98
98
  unitless?: Partial<Record<ComponentTokenKey<CompTokenMap, AliasToken, C>, boolean>>;
99
- }) => vue2.DefineComponent<vue2.ExtractPropTypes<{
99
+ }) => vue0.DefineComponent<vue0.ExtractPropTypes<{
100
100
  prefixCls: StringConstructor;
101
101
  rootCls: StringConstructor;
102
- }>, () => null, {}, {}, {}, vue2.ComponentOptionsMixin, vue2.ComponentOptionsMixin, {}, string, vue2.PublicProps, Readonly<vue2.ExtractPropTypes<{
102
+ }>, () => null, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {}, string, vue0.PublicProps, Readonly<vue0.ExtractPropTypes<{
103
103
  prefixCls: StringConstructor;
104
104
  rootCls: StringConstructor;
105
- }>> & Readonly<{}>, {}, {}, {}, {}, string, vue2.ComponentProvideOptions, true, {}, any>;
105
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, vue0.ComponentProvideOptions, true, {}, any>;
106
106
  genComponentStyleHook: <C extends TokenMapKey<CompTokenMap>>(componentName: C | [C, string], styleFn: GenStyleFn<CompTokenMap, AliasToken, C>, getDefaultToken?: GetDefaultToken<CompTokenMap, AliasToken, C>, options?: {
107
107
  resetStyle?: boolean;
108
108
  resetFont?: boolean;
@@ -1,11 +1,17 @@
1
1
  import { pathKey } from "../Cache.mjs";
2
2
  import { useStyleContext } from "../StyleContext.mjs";
3
3
  import { isClientSide } from "../util/index.mjs";
4
- import { computed, watch } from "vue";
4
+ import { computed, onBeforeUnmount, shallowRef, watch } from "vue";
5
5
 
6
6
  //#region src/hooks/useGlobalCache.ts
7
7
  const effectMap = /* @__PURE__ */ new Map();
8
8
  /**
9
+ * 延迟移除样式的时间(毫秒)
10
+ * 用于解决 Vue Transition 动画期间样式被过早移除的问题
11
+ */
12
+ const REMOVE_STYLE_DELAY = 500;
13
+ const delayedRemoveInfo = /* @__PURE__ */ new Map();
14
+ /**
9
15
  * Global cache for CSS-in-JS styles
10
16
  *
11
17
  * This hook manages a reference-counted cache to ensure styles are properly
@@ -15,54 +21,115 @@ const effectMap = /* @__PURE__ */ new Map();
15
21
  * - No useInsertionEffect needed - Vue's watchEffect handles timing naturally
16
22
  * - No StrictMode double-mounting issues - Vue doesn't double-mount
17
23
  * - HMR handling is simpler - can rely on Vue's reactivity system
18
- * - No need for cleanup register pattern - onBeforeUnmount is sufficient
24
+ * - Uses onBeforeUnmount for cleanup instead of watch's onCleanup to have
25
+ * better control over cleanup timing (important for Transition animations)
19
26
  */
20
27
  function useGlobalCache(prefix, keyPath, cacheFn, onCacheRemove, onCacheEffect) {
21
28
  const styleContext = useStyleContext();
22
29
  const fullPath = computed(() => [prefix.value, ...keyPath.value]);
23
30
  const fullPathStr = computed(() => pathKey(fullPath.value));
24
- const buildCache = (updater) => {
25
- styleContext.value.cache.opUpdate(fullPathStr.value, (prevCache) => {
26
- const [times = 0, cache] = prevCache || [void 0, void 0];
27
- const data = [times, cache || cacheFn()];
28
- return updater ? updater(data) : data;
29
- });
31
+ const currentPathRef = shallowRef(fullPathStr.value);
32
+ const globalCache = () => styleContext.value.cache;
33
+ const isServerSide = () => styleContext.value.mock !== void 0 ? styleContext.value.mock === "server" : !isClientSide;
34
+ const clearCache = (pathStr, immediate = false) => {
35
+ if (isServerSide()) return;
36
+ const doSingleDecrement = () => {
37
+ globalCache().opUpdate(pathStr, (prevCache) => {
38
+ const [times = 0, cache] = prevCache || [];
39
+ const nextCount = times - 1;
40
+ if (nextCount === 0) {
41
+ onCacheRemove?.(cache, false);
42
+ effectMap.delete(pathStr);
43
+ return null;
44
+ }
45
+ return [nextCount, cache];
46
+ });
47
+ };
48
+ const doAllPendingDecrements = (count) => {
49
+ for (let i = 0; i < count; i++) doSingleDecrement();
50
+ };
51
+ if (immediate || !isClientSide) doSingleDecrement();
52
+ else {
53
+ const existingInfo = delayedRemoveInfo.get(pathStr);
54
+ if (existingInfo) {
55
+ clearTimeout(existingInfo.timer);
56
+ const newPendingDecrements = existingInfo.pendingDecrements + 1;
57
+ const timer = setTimeout(() => {
58
+ delayedRemoveInfo.delete(pathStr);
59
+ doAllPendingDecrements(newPendingDecrements);
60
+ }, REMOVE_STYLE_DELAY);
61
+ delayedRemoveInfo.set(pathStr, {
62
+ timer,
63
+ pendingDecrements: newPendingDecrements
64
+ });
65
+ } else {
66
+ const timer = setTimeout(() => {
67
+ delayedRemoveInfo.delete(pathStr);
68
+ doSingleDecrement();
69
+ }, REMOVE_STYLE_DELAY);
70
+ delayedRemoveInfo.set(pathStr, {
71
+ timer,
72
+ pendingDecrements: 1
73
+ });
74
+ }
75
+ }
30
76
  };
31
- const getCacheEntity = () => styleContext.value.cache.opGet(fullPathStr.value);
32
- buildCache();
33
77
  const cacheContent = computed(() => {
34
- let entity = styleContext.value.cache.opGet(fullPathStr.value);
78
+ let entity = globalCache().opGet(fullPathStr.value);
35
79
  if (!entity) {
36
- buildCache();
37
- entity = getCacheEntity();
80
+ globalCache().opUpdate(fullPathStr.value, (prevCache) => {
81
+ const [times = 0, cache] = prevCache || [void 0, void 0];
82
+ return [times, cache || cacheFn()];
83
+ });
84
+ entity = globalCache().opGet(fullPathStr.value);
38
85
  }
39
86
  return entity[1];
40
87
  });
41
- watch(fullPathStr, (_, _1, onCleanup) => {
42
- const currentPath = fullPathStr.value;
43
- buildCache(([times, cache]) => [times + 1, cache]);
44
- if (!effectMap.has(currentPath)) {
88
+ watch(fullPathStr, (newPath, oldPath) => {
89
+ if (oldPath) clearCache(oldPath, true);
90
+ currentPathRef.value = newPath;
91
+ const existingInfo = delayedRemoveInfo.get(newPath);
92
+ if (existingInfo) {
93
+ const newPendingDecrements = existingInfo.pendingDecrements - 1;
94
+ if (newPendingDecrements <= 0) {
95
+ clearTimeout(existingInfo.timer);
96
+ delayedRemoveInfo.delete(newPath);
97
+ } else {
98
+ clearTimeout(existingInfo.timer);
99
+ const timer = setTimeout(() => {
100
+ delayedRemoveInfo.delete(newPath);
101
+ for (let i = 0; i < newPendingDecrements; i++) globalCache().opUpdate(newPath, (prevCache) => {
102
+ const [times = 0, cache] = prevCache || [];
103
+ const nextCount = times - 1;
104
+ if (nextCount === 0) {
105
+ onCacheRemove?.(cache, false);
106
+ effectMap.delete(newPath);
107
+ return null;
108
+ }
109
+ return [nextCount, cache];
110
+ });
111
+ }, REMOVE_STYLE_DELAY);
112
+ delayedRemoveInfo.set(newPath, {
113
+ timer,
114
+ pendingDecrements: newPendingDecrements
115
+ });
116
+ }
117
+ } else globalCache().opUpdate(newPath, (prevCache) => {
118
+ const [times = 0, cache] = prevCache || [void 0, void 0];
119
+ const mergedCache = cache || cacheFn();
120
+ return [times + 1, mergedCache];
121
+ });
122
+ if (!effectMap.has(newPath)) {
45
123
  onCacheEffect?.(cacheContent.value);
46
- effectMap.set(currentPath, true);
124
+ effectMap.set(newPath, true);
47
125
  Promise.resolve().then(() => {
48
- effectMap.delete(currentPath);
126
+ effectMap.delete(newPath);
49
127
  });
50
128
  }
51
- const globalCache = styleContext.value.cache;
52
- const isServerSide = styleContext.value.mock !== void 0 ? styleContext.value.mock === "server" : !isClientSide;
53
- onCleanup(() => {
54
- if (isServerSide) return;
55
- globalCache.opUpdate(currentPath, (prevCache) => {
56
- const [times = 0, cache] = prevCache || [];
57
- if (times - 1 === 0) {
58
- onCacheRemove?.(cache, false);
59
- effectMap.delete(currentPath);
60
- return null;
61
- }
62
- return [times - 1, cache];
63
- });
64
- });
65
129
  }, { immediate: true });
130
+ onBeforeUnmount(() => {
131
+ clearCache(currentPathRef.value);
132
+ });
66
133
  return cacheContent;
67
134
  }
68
135
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@antdv-next/cssinjs",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.1",
4
+ "version": "1.0.0-rc.3",
5
5
  "description": "cssinjs solution for ant-design-vue",
6
6
  "exports": {
7
7
  ".": {