react-native-screen-transitions 2.1.0 → 2.2.1
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/lib/commonjs/components/bound-capture.js +7 -2
- package/lib/commonjs/components/bound-capture.js.map +1 -1
- package/lib/commonjs/components/controllers/screen-lifecycle.js +3 -9
- package/lib/commonjs/components/controllers/screen-lifecycle.js.map +1 -1
- package/lib/commonjs/components/create-transition-aware-component.js +12 -2
- package/lib/commonjs/components/create-transition-aware-component.js.map +1 -1
- package/lib/commonjs/components/root-transition-aware.js +3 -1
- package/lib/commonjs/components/root-transition-aware.js.map +1 -1
- package/lib/commonjs/hooks/animation/use-associated-style.js +41 -6
- package/lib/commonjs/hooks/animation/use-associated-style.js.map +1 -1
- package/lib/commonjs/hooks/bounds/use-bound-registry.js +9 -16
- package/lib/commonjs/hooks/bounds/use-bound-registry.js.map +1 -1
- package/lib/commonjs/providers/transition-styles.js +5 -1
- package/lib/commonjs/providers/transition-styles.js.map +1 -1
- package/lib/commonjs/stores/bounds/_utils.js +118 -0
- package/lib/commonjs/stores/bounds/_utils.js.map +1 -0
- package/lib/commonjs/stores/bounds/index.js +116 -0
- package/lib/commonjs/stores/bounds/index.js.map +1 -0
- package/lib/commonjs/stores/utils/reset-stores-for-screen.js +1 -4
- package/lib/commonjs/stores/utils/reset-stores-for-screen.js.map +1 -1
- package/lib/module/components/bound-capture.js +7 -2
- package/lib/module/components/bound-capture.js.map +1 -1
- package/lib/module/components/controllers/screen-lifecycle.js +3 -9
- package/lib/module/components/controllers/screen-lifecycle.js.map +1 -1
- package/lib/module/components/create-transition-aware-component.js +12 -2
- package/lib/module/components/create-transition-aware-component.js.map +1 -1
- package/lib/module/components/root-transition-aware.js +3 -1
- package/lib/module/components/root-transition-aware.js.map +1 -1
- package/lib/module/hooks/animation/use-associated-style.js +42 -7
- package/lib/module/hooks/animation/use-associated-style.js.map +1 -1
- package/lib/module/hooks/bounds/use-bound-registry.js +9 -16
- package/lib/module/hooks/bounds/use-bound-registry.js.map +1 -1
- package/lib/module/providers/transition-styles.js +5 -1
- package/lib/module/providers/transition-styles.js.map +1 -1
- package/lib/module/stores/bounds/_utils.js +113 -0
- package/lib/module/stores/bounds/_utils.js.map +1 -0
- package/lib/module/stores/bounds/index.js +112 -0
- package/lib/module/stores/bounds/index.js.map +1 -0
- package/lib/module/stores/utils/reset-stores-for-screen.js +1 -4
- package/lib/module/stores/utils/reset-stores-for-screen.js.map +1 -1
- package/lib/typescript/components/bound-capture.d.ts.map +1 -1
- package/lib/typescript/components/create-transition-aware-component.d.ts.map +1 -1
- package/lib/typescript/hooks/animation/use-associated-style.d.ts +4 -4
- package/lib/typescript/hooks/animation/use-associated-style.d.ts.map +1 -1
- package/lib/typescript/hooks/bounds/use-bound-registry.d.ts +0 -1
- package/lib/typescript/hooks/bounds/use-bound-registry.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/providers/transition-styles.d.ts +4 -1
- package/lib/typescript/providers/transition-styles.d.ts.map +1 -1
- package/lib/typescript/stores/bounds/_utils.d.ts +24 -0
- package/lib/typescript/stores/bounds/_utils.d.ts.map +1 -0
- package/lib/typescript/stores/{bounds.d.ts → bounds/index.d.ts} +3 -13
- package/lib/typescript/stores/bounds/index.d.ts.map +1 -0
- package/lib/typescript/stores/utils/reset-stores-for-screen.d.ts +1 -3
- package/lib/typescript/stores/utils/reset-stores-for-screen.d.ts.map +1 -1
- package/lib/typescript/types/core.d.ts +8 -0
- package/lib/typescript/types/core.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/bounds.store.test.ts +185 -0
- package/src/components/bound-capture.tsx +5 -2
- package/src/components/controllers/screen-lifecycle.tsx +3 -3
- package/src/components/create-transition-aware-component.tsx +19 -3
- package/src/components/root-transition-aware.tsx +1 -1
- package/src/hooks/animation/use-associated-style.tsx +42 -7
- package/src/hooks/bounds/use-bound-registry.tsx +10 -21
- package/src/providers/transition-styles.tsx +8 -2
- package/src/stores/bounds/_utils.ts +161 -0
- package/src/stores/bounds/index.ts +125 -0
- package/src/stores/utils/reset-stores-for-screen.ts +1 -7
- package/src/types/core.ts +9 -0
- package/LICENSE +0 -21
- package/lib/commonjs/stores/bounds.js +0 -205
- package/lib/commonjs/stores/bounds.js.map +0 -1
- package/lib/module/stores/bounds.js +0 -201
- package/lib/module/stores/bounds.js.map +0 -1
- package/lib/typescript/stores/bounds.d.ts.map +0 -1
- package/src/stores/bounds.ts +0 -227
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { type StyleProps } from "react-native-reanimated";
|
|
1
2
|
type Props = {
|
|
2
3
|
id?: string;
|
|
4
|
+
style?: StyleProps;
|
|
3
5
|
};
|
|
4
6
|
/**
|
|
5
|
-
* This hook is used to get the associated styles for a given styleId.
|
|
6
|
-
* It is used to get the associated styles for a given styleId.
|
|
7
|
-
* It is used to get the associated styles for a given styleId.
|
|
7
|
+
* This hook is used to get the associated styles for a given styleId / boundTag.
|
|
8
8
|
*/
|
|
9
|
-
export declare const useAssociatedStyles: ({ id }?: Props) => {
|
|
9
|
+
export declare const useAssociatedStyles: ({ id, style }?: Props) => {
|
|
10
10
|
associatedStyles: Readonly<{}>;
|
|
11
11
|
};
|
|
12
12
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-associated-style.d.ts","sourceRoot":"","sources":["../../../../src/hooks/animation/use-associated-style.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-associated-style.d.ts","sourceRoot":"","sources":["../../../../src/hooks/animation/use-associated-style.tsx"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,UAAU,EAIf,MAAM,yBAAyB,CAAC;AAGjC,KAAK,KAAK,GAAG;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,gBAAe,KAAU;;CA6C5D,CAAC"}
|
|
@@ -13,7 +13,6 @@ interface BoundMeasurerHookProps {
|
|
|
13
13
|
export declare const useBoundsRegistry: ({ sharedBoundTag, animatedRef, current, style, }: BoundMeasurerHookProps) => {
|
|
14
14
|
measureBounds: () => void;
|
|
15
15
|
handleLayout: () => void;
|
|
16
|
-
measureOnTouchStart: () => void;
|
|
17
16
|
};
|
|
18
17
|
export {};
|
|
19
18
|
//# sourceMappingURL=use-bound-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-bound-registry.d.ts","sourceRoot":"","sources":["../../../../src/hooks/bounds/use-bound-registry.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACN,KAAK,WAAW,EAEhB,KAAK,UAAU,EAEf,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-bound-registry.d.ts","sourceRoot":"","sources":["../../../../src/hooks/bounds/use-bound-registry.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACN,KAAK,WAAW,EAEhB,KAAK,UAAU,EAEf,MAAM,yBAAyB,CAAC;AAMjC,UAAU,sBAAsB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,EAAE;QAAE,KAAK,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACpC,KAAK,EAAE,UAAU,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,GAAI,kDAK/B,sBAAsB;;;CA8CxB,CAAC"}
|
|
@@ -209,6 +209,7 @@ declare const _default: {
|
|
|
209
209
|
} & {
|
|
210
210
|
styleId?: string;
|
|
211
211
|
sharedBoundTag?: string;
|
|
212
|
+
measureOnLayout?: boolean;
|
|
212
213
|
} & import("react").RefAttributes<never>>>;
|
|
213
214
|
Pressable: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<{
|
|
214
215
|
id?: string | import("react-native-reanimated").SharedValue<string | undefined> | undefined;
|
|
@@ -457,6 +458,7 @@ declare const _default: {
|
|
|
457
458
|
} & {
|
|
458
459
|
styleId?: string;
|
|
459
460
|
sharedBoundTag?: string;
|
|
461
|
+
measureOnLayout?: boolean;
|
|
460
462
|
} & import("react").RefAttributes<View | import("react").Component<import("react-native").PressableProps & import("react").RefAttributes<View>, any, any>>>>;
|
|
461
463
|
ScrollView: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<{
|
|
462
464
|
id?: string | import("react-native-reanimated").SharedValue<string | undefined> | undefined;
|
|
@@ -793,6 +795,7 @@ declare const _default: {
|
|
|
793
795
|
} & {
|
|
794
796
|
styleId?: string;
|
|
795
797
|
sharedBoundTag?: string;
|
|
798
|
+
measureOnLayout?: boolean;
|
|
796
799
|
} & import("react").RefAttributes<never>>>;
|
|
797
800
|
FlatList: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<{
|
|
798
801
|
id?: string | import("react-native-reanimated").SharedValue<string | undefined> | undefined;
|
|
@@ -1263,6 +1266,7 @@ declare const _default: {
|
|
|
1263
1266
|
} & {
|
|
1264
1267
|
styleId?: string;
|
|
1265
1268
|
sharedBoundTag?: string;
|
|
1269
|
+
measureOnLayout?: boolean;
|
|
1266
1270
|
} & import("react").RefAttributes<never>>>;
|
|
1267
1271
|
MaskedView: typeof MaskedView;
|
|
1268
1272
|
presets: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,IAAI,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,UAAU,MAAM,uCAAuC,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,IAAI,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,UAAU,MAAM,uCAAuC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAgC4iE,CAAC;;;;;;;;;;;AA7B5mE,wBAaE;AAEF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,mEAAmE,CAAC;AAE/G,YAAY,EACX,0BAA0B,EAC1B,sBAAsB,EACtB,2BAA2B,EAC3B,6BAA6B,EAC7B,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GACtB,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { useDerivedValue } from "react-native-reanimated";
|
|
1
2
|
import type { TransitionInterpolatedStyle } from "../types/animation";
|
|
2
3
|
type Props = {
|
|
3
4
|
children: React.ReactNode;
|
|
4
5
|
};
|
|
5
6
|
export declare function TransitionStylesProvider({ children }: Props): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export declare function useTransitionStyles():
|
|
7
|
+
export declare function useTransitionStyles(): {
|
|
8
|
+
stylesMap: ReturnType<typeof useDerivedValue<TransitionInterpolatedStyle>>;
|
|
9
|
+
};
|
|
7
10
|
export {};
|
|
8
11
|
//# sourceMappingURL=transition-styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transition-styles.d.ts","sourceRoot":"","sources":["../../../src/providers/transition-styles.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transition-styles.d.ts","sourceRoot":"","sources":["../../../src/providers/transition-styles.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE7E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEtE,KAAK,KAAK,GAAG;IACZ,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B,CAAC;AAUF,wBAAgB,wBAAwB,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA8B3D;AAED,wBAAgB,mBAAmB;eApCtB,UAAU,CAAC,OAAO,eAAe,CAAC,2BAA2B,CAAC,CAAC;EA4C3E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ScreenTransitionState } from "../../types/animation";
|
|
2
|
+
type GetCache = (fromKey: string, toKey: string) => string | null;
|
|
3
|
+
type SetCache = (fromKey: string, toKey: string, id: string) => void;
|
|
4
|
+
type GetRouteActive = (routeKey: string) => string | null;
|
|
5
|
+
interface ResolveActiveBoundParams {
|
|
6
|
+
current: ScreenTransitionState;
|
|
7
|
+
next?: ScreenTransitionState;
|
|
8
|
+
previous?: ScreenTransitionState;
|
|
9
|
+
getPairCache: GetCache;
|
|
10
|
+
setPairCache: SetCache;
|
|
11
|
+
getRouteActive: GetRouteActive;
|
|
12
|
+
}
|
|
13
|
+
export declare function pairKey(fromKey?: string, toKey?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Util function to get the active bound id for a given transition state.
|
|
16
|
+
*
|
|
17
|
+
* It will check by ( priority from highest to lowest ):
|
|
18
|
+
* 1. Requested id
|
|
19
|
+
* 2. Cache
|
|
20
|
+
* 3. Intersection
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveActiveBound({ current, next, previous, getPairCache, setPairCache, getRouteActive, }: ResolveActiveBoundParams): string;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=_utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../../../../src/stores/bounds/_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAClE,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AACrE,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAE1D,UAAU,wBAAwB;IACjC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,YAAY,EAAE,QAAQ,CAAC;IACvB,YAAY,EAAE,QAAQ,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;CAC/B;AAED,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,UAGvD;AA2ED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAClC,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,cAAc,GACd,EAAE,wBAAwB,UAoD1B"}
|
|
@@ -1,32 +1,22 @@
|
|
|
1
1
|
import { type MeasuredDimensions, type StyleProps } from "react-native-reanimated";
|
|
2
|
-
import type { ScreenTransitionState } from "
|
|
3
|
-
import type { ScreenKey } from "
|
|
2
|
+
import type { ScreenTransitionState } from "../../types/animation";
|
|
3
|
+
import type { ScreenKey } from "../../types/navigator";
|
|
4
4
|
declare function setBounds(screenId: string, boundId: string, bounds?: MeasuredDimensions | null, styles?: StyleProps): void;
|
|
5
5
|
declare function getBounds(screenId: string): Record<string, {
|
|
6
6
|
bounds: MeasuredDimensions;
|
|
7
7
|
styles: StyleProps;
|
|
8
8
|
}>;
|
|
9
|
-
declare function setActiveBoundId(boundId: string): void;
|
|
10
|
-
declare function getActiveBoundId(): string | null;
|
|
11
9
|
declare function setRouteActive(routeKey: string, boundId: string): void;
|
|
12
10
|
declare function getRouteActive(routeKey: string): string;
|
|
13
|
-
declare function setTransitionHint(fromKey: string, toKey: string, boundId: string): void;
|
|
14
|
-
declare function getTransitionHint(fromKey: string, toKey: string): string | null;
|
|
15
11
|
declare function clear(routeKey: ScreenKey): void;
|
|
16
|
-
declare function clearActive(): void;
|
|
17
12
|
declare function getActiveBound(current: ScreenTransitionState, next: ScreenTransitionState | undefined, previous: ScreenTransitionState | undefined): string;
|
|
18
13
|
export declare const Bounds: {
|
|
19
14
|
setBounds: typeof setBounds;
|
|
20
15
|
getBounds: typeof getBounds;
|
|
21
|
-
setActiveBoundId: typeof setActiveBoundId;
|
|
22
|
-
getActiveBoundId: typeof getActiveBoundId;
|
|
23
16
|
setRouteActive: typeof setRouteActive;
|
|
24
17
|
getRouteActive: typeof getRouteActive;
|
|
25
|
-
setTransitionHint: typeof setTransitionHint;
|
|
26
|
-
getTransitionHint: typeof getTransitionHint;
|
|
27
18
|
clear: typeof clear;
|
|
28
|
-
clearActive: typeof clearActive;
|
|
29
19
|
getActiveBound: typeof getActiveBound;
|
|
30
20
|
};
|
|
31
21
|
export {};
|
|
32
|
-
//# sourceMappingURL=
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/stores/bounds/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAavD,iBAAS,SAAS,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,kBAAkB,GAAG,IAAW,EACxC,MAAM,GAAE,UAAe,QAYvB;AAED,iBAAS,SAAS,CAAC,QAAQ,EAAE,MAAM;YAzBT,kBAAkB;YAAU,UAAU;GA4B/D;AAED,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAOxD;AAED,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,UAGvC;AAoBD,iBAAS,KAAK,CAAC,QAAQ,EAAE,SAAS,QAyBjC;AAED,iBAAS,cAAc,CACtB,OAAO,EAAE,qBAAqB,EAC9B,IAAI,EAAE,qBAAqB,GAAG,SAAS,EACvC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,UAW3C;AAED,eAAO,MAAM,MAAM;;;;;;;CAOlB,CAAC"}
|
|
@@ -2,7 +2,5 @@ import type { NativeStackDescriptor } from "../../types/navigator";
|
|
|
2
2
|
/**
|
|
3
3
|
* Reset all stores for a given screen
|
|
4
4
|
*/
|
|
5
|
-
export declare const resetStoresForScreen: (current: NativeStackDescriptor
|
|
6
|
-
clearActive?: boolean;
|
|
7
|
-
}) => void;
|
|
5
|
+
export declare const resetStoresForScreen: (current: NativeStackDescriptor) => void;
|
|
8
6
|
//# sourceMappingURL=reset-stores-for-screen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reset-stores-for-screen.d.ts","sourceRoot":"","sources":["../../../../src/stores/utils/reset-stores-for-screen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAKnE;;GAEG;AACH,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"reset-stores-for-screen.d.ts","sourceRoot":"","sources":["../../../../src/stores/utils/reset-stores-for-screen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAKnE;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,qBAAqB,SAIlE,CAAC"}
|
|
@@ -39,6 +39,14 @@ export type TransitionAwareProps<T extends object> = AnimatedProps<T> & {
|
|
|
39
39
|
* </Transition.View>
|
|
40
40
|
*/
|
|
41
41
|
sharedBoundTag?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Eagerly measure this component on layout and store the result in the
|
|
44
|
+
* Bounds registry. Useful for nested shared elements that may not receive
|
|
45
|
+
* the press event but still need up-to-date measurements at navigation time.
|
|
46
|
+
*
|
|
47
|
+
* Only has an effect when used together with `sharedBoundTag`.
|
|
48
|
+
*/
|
|
49
|
+
measureOnLayout?: boolean;
|
|
42
50
|
};
|
|
43
51
|
export type TransitionConfig = {
|
|
44
52
|
open: TransitionSpec;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/types/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG;IACvE;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/types/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG;IACvE;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;CACtB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-screen-transitions",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Easy screen transitions for React Native and Expo",
|
|
5
5
|
"author": "Ed",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@testing-library/react-native": "^13.2.0",
|
|
50
50
|
"@types/react": "~19.0.10",
|
|
51
51
|
"react-native-builder-bob": "0.39.0",
|
|
52
|
-
"typescript": "
|
|
52
|
+
"typescript": "catalog:"
|
|
53
53
|
},
|
|
54
54
|
"react-native-builder-bob": {
|
|
55
55
|
"source": "src",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
]
|
|
66
66
|
]
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "888d4df9936ec0e3b8221bea7cd81115e6301693"
|
|
69
69
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from "bun:test";
|
|
2
|
+
import { resolveActiveBound } from "../stores/bounds/_utils";
|
|
3
|
+
import type { ScreenTransitionState } from "../types/animation";
|
|
4
|
+
|
|
5
|
+
type Dim = {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
pageX: number;
|
|
9
|
+
pageY: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getDimensions = (x = 0, y = 0, w = 100, h = 100): Dim => ({
|
|
15
|
+
x,
|
|
16
|
+
y,
|
|
17
|
+
pageX: x,
|
|
18
|
+
pageY: y,
|
|
19
|
+
width: w,
|
|
20
|
+
height: h,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const mockState = (
|
|
24
|
+
routeKey: string,
|
|
25
|
+
ids: string[] = [],
|
|
26
|
+
): ScreenTransitionState => {
|
|
27
|
+
const bounds: Record<
|
|
28
|
+
string,
|
|
29
|
+
{ bounds: Dim; styles: Record<string, unknown> }
|
|
30
|
+
> = {};
|
|
31
|
+
ids.forEach((id, i) => {
|
|
32
|
+
bounds[id] = { bounds: getDimensions(i * 10, i * 10), styles: {} };
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
progress: 1,
|
|
36
|
+
closing: 0,
|
|
37
|
+
animating: 1,
|
|
38
|
+
gesture: {
|
|
39
|
+
x: 0,
|
|
40
|
+
y: 0,
|
|
41
|
+
normalizedX: 0,
|
|
42
|
+
normalizedY: 0,
|
|
43
|
+
isDismissing: 0,
|
|
44
|
+
isDragging: 0,
|
|
45
|
+
},
|
|
46
|
+
bounds,
|
|
47
|
+
// @ts-expect-error partial route
|
|
48
|
+
route: { key: routeKey },
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
let cache: Record<string, string>;
|
|
53
|
+
let lastActiveByRoute: Record<string, string>;
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
cache = {};
|
|
56
|
+
lastActiveByRoute = {};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const getPairCache = (from: string, to: string) =>
|
|
60
|
+
cache[`${from}|${to}`] ?? null;
|
|
61
|
+
const setPairCache = (from: string, to: string, id: string) => {
|
|
62
|
+
cache[`${from}|${to}`] = id;
|
|
63
|
+
};
|
|
64
|
+
const getRouteActive = (routeKey: string) =>
|
|
65
|
+
lastActiveByRoute[routeKey] ?? null;
|
|
66
|
+
|
|
67
|
+
describe("Bounds.getActiveBound - requested id priority and acceptance", () => {
|
|
68
|
+
it("selects requested id when present only on current (opening)", () => {
|
|
69
|
+
const A = "A-1";
|
|
70
|
+
const B = "B-1";
|
|
71
|
+
const current = mockState(A, ["container"]);
|
|
72
|
+
const previous = mockState(B, ["icon"]);
|
|
73
|
+
|
|
74
|
+
// Opening: fromKey is previous.route.key (B)
|
|
75
|
+
lastActiveByRoute[B] = "container";
|
|
76
|
+
const active = resolveActiveBound({
|
|
77
|
+
current,
|
|
78
|
+
previous,
|
|
79
|
+
getPairCache,
|
|
80
|
+
setPairCache,
|
|
81
|
+
getRouteActive,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(active).toBe("container");
|
|
85
|
+
expect(getPairCache(B, A)).toBeNull();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("selects requested id when present only on other (closing)", () => {
|
|
89
|
+
const A = "A-2";
|
|
90
|
+
const B = "B-2";
|
|
91
|
+
const current = mockState(A, ["icon"]);
|
|
92
|
+
const next = mockState(B, ["container"]);
|
|
93
|
+
|
|
94
|
+
// Closing: fromKey is current.route.key (A)
|
|
95
|
+
lastActiveByRoute[A] = "container";
|
|
96
|
+
const active = resolveActiveBound({
|
|
97
|
+
current,
|
|
98
|
+
next,
|
|
99
|
+
getPairCache,
|
|
100
|
+
setPairCache,
|
|
101
|
+
getRouteActive,
|
|
102
|
+
});
|
|
103
|
+
expect(active).toBe("container");
|
|
104
|
+
expect(getPairCache(A, B)).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe("Bounds.getActiveBound - hint behavior (guarded writes)", () => {
|
|
109
|
+
it("writes cache only when both sides have the id", () => {
|
|
110
|
+
const A = "A-3";
|
|
111
|
+
const B = "B-3";
|
|
112
|
+
// Both have the same id measured
|
|
113
|
+
const current = mockState(A, ["container"]);
|
|
114
|
+
const previous = mockState(B, ["container"]);
|
|
115
|
+
|
|
116
|
+
// Opening: fromKey is previous.route.key (B)
|
|
117
|
+
lastActiveByRoute[B] = "container";
|
|
118
|
+
const active = resolveActiveBound({
|
|
119
|
+
current,
|
|
120
|
+
previous,
|
|
121
|
+
getPairCache,
|
|
122
|
+
setPairCache,
|
|
123
|
+
getRouteActive,
|
|
124
|
+
});
|
|
125
|
+
expect(active).toBe("container");
|
|
126
|
+
expect(getPairCache(B, A)).toBe("container");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("requested id overrides existing cache and updates it when both sides measured", () => {
|
|
130
|
+
const A = "A-4";
|
|
131
|
+
const B = "B-4";
|
|
132
|
+
// Both sides have icon and container
|
|
133
|
+
// Pre-seed a conflicting cache
|
|
134
|
+
setPairCache(B, A, "icon");
|
|
135
|
+
|
|
136
|
+
const current = mockState(A, ["icon", "container"]);
|
|
137
|
+
const previous = mockState(B, ["icon", "container"]);
|
|
138
|
+
|
|
139
|
+
// Opening: fromKey is previous.route.key (B)
|
|
140
|
+
lastActiveByRoute[B] = "container";
|
|
141
|
+
const active = resolveActiveBound({
|
|
142
|
+
current,
|
|
143
|
+
previous,
|
|
144
|
+
getPairCache,
|
|
145
|
+
setPairCache,
|
|
146
|
+
getRouteActive,
|
|
147
|
+
});
|
|
148
|
+
expect(active).toBe("container");
|
|
149
|
+
expect(getPairCache(B, A)).toBe("container");
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe("Bounds.getActiveBound - set intersection and fallbacks", () => {
|
|
154
|
+
it("falls back to intersection when no request or cache", () => {
|
|
155
|
+
const A = "A-5";
|
|
156
|
+
const B = "B-5";
|
|
157
|
+
const current = mockState(A, ["alpha", "beta"]);
|
|
158
|
+
const previous = mockState(B, ["beta", "gamma"]);
|
|
159
|
+
|
|
160
|
+
const active = resolveActiveBound({
|
|
161
|
+
current,
|
|
162
|
+
previous,
|
|
163
|
+
getPairCache,
|
|
164
|
+
setPairCache,
|
|
165
|
+
getRouteActive,
|
|
166
|
+
});
|
|
167
|
+
expect(active).toBe("beta");
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("when other has a single bound, selects it (no request/cache)", () => {
|
|
171
|
+
const A = "A-6";
|
|
172
|
+
const B = "B-6";
|
|
173
|
+
const current = mockState(A, ["alpha"]);
|
|
174
|
+
const previous = mockState(B, ["only"]);
|
|
175
|
+
|
|
176
|
+
const active = resolveActiveBound({
|
|
177
|
+
current,
|
|
178
|
+
previous,
|
|
179
|
+
getPairCache,
|
|
180
|
+
setPairCache,
|
|
181
|
+
getRouteActive,
|
|
182
|
+
});
|
|
183
|
+
expect(active).toBe("only");
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
3
|
+
import { useKeys } from "../providers/keys";
|
|
3
4
|
import { Bounds } from "../stores/bounds";
|
|
4
5
|
|
|
5
6
|
interface BoundActivatorProps {
|
|
@@ -13,15 +14,17 @@ export const BoundCapture = ({
|
|
|
13
14
|
children,
|
|
14
15
|
measure,
|
|
15
16
|
}: BoundActivatorProps) => {
|
|
17
|
+
const { current } = useKeys();
|
|
18
|
+
const routeKey = current.route.key;
|
|
16
19
|
const tapGesture = useMemo(() => {
|
|
17
20
|
return Gesture.Tap().onStart(() => {
|
|
18
21
|
"worklet";
|
|
19
22
|
if (sharedBoundTag) {
|
|
20
|
-
Bounds.
|
|
23
|
+
Bounds.setRouteActive(routeKey, sharedBoundTag);
|
|
21
24
|
measure();
|
|
22
25
|
}
|
|
23
26
|
});
|
|
24
|
-
}, [sharedBoundTag, measure]);
|
|
27
|
+
}, [sharedBoundTag, measure, routeKey]);
|
|
25
28
|
|
|
26
29
|
if (!sharedBoundTag) return children;
|
|
27
30
|
|
|
@@ -24,13 +24,13 @@ export const ScreenLifecycleController = ({
|
|
|
24
24
|
|
|
25
25
|
// Don't run e.preventDefault when the dismissal was on the local root
|
|
26
26
|
if (requestedDismissOnNavigator) {
|
|
27
|
-
resetStoresForScreen(current
|
|
27
|
+
resetStoresForScreen(current);
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Don't run e.preventDefault when this is the first screen of the stack
|
|
32
32
|
if (current.navigation.getState().index === 0) {
|
|
33
|
-
resetStoresForScreen(current
|
|
33
|
+
resetStoresForScreen(current);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -41,7 +41,7 @@ export const ScreenLifecycleController = ({
|
|
|
41
41
|
|
|
42
42
|
// we'll ensure the dispatch is complete before resetting stores
|
|
43
43
|
requestAnimationFrame(() => {
|
|
44
|
-
resetStoresForScreen(current
|
|
44
|
+
resetStoresForScreen(current);
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
};
|
|
@@ -53,14 +53,22 @@ export function createTransitionAwareComponent<P extends object>(
|
|
|
53
53
|
React.ComponentRef<typeof AnimatedComponent>,
|
|
54
54
|
TransitionAwareProps<P>
|
|
55
55
|
>((props, ref) => {
|
|
56
|
-
const {
|
|
57
|
-
|
|
56
|
+
const {
|
|
57
|
+
children,
|
|
58
|
+
style,
|
|
59
|
+
sharedBoundTag,
|
|
60
|
+
styleId,
|
|
61
|
+
onPress,
|
|
62
|
+
measureOnLayout,
|
|
63
|
+
...rest
|
|
64
|
+
} = props as Any;
|
|
58
65
|
|
|
59
66
|
const animatedRef = useAnimatedRef<View>();
|
|
60
67
|
const { current } = useKeys();
|
|
61
68
|
|
|
62
69
|
const { associatedStyles } = useAssociatedStyles({
|
|
63
70
|
id: sharedBoundTag || styleId,
|
|
71
|
+
style,
|
|
64
72
|
});
|
|
65
73
|
|
|
66
74
|
const { measureBounds, handleLayout } = useBoundsRegistry({
|
|
@@ -81,6 +89,14 @@ export function createTransitionAwareComponent<P extends object>(
|
|
|
81
89
|
);
|
|
82
90
|
}
|
|
83
91
|
|
|
92
|
+
const onLayoutHandler = runOnUI(() => {
|
|
93
|
+
"worklet";
|
|
94
|
+
handleLayout();
|
|
95
|
+
if (measureOnLayout && sharedBoundTag) {
|
|
96
|
+
measureBounds();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
84
100
|
return (
|
|
85
101
|
<BoundCapture sharedBoundTag={sharedBoundTag} measure={measureBounds}>
|
|
86
102
|
<AnimatedComponent
|
|
@@ -88,7 +104,7 @@ export function createTransitionAwareComponent<P extends object>(
|
|
|
88
104
|
ref={animatedRef}
|
|
89
105
|
style={[style, associatedStyles]}
|
|
90
106
|
onPress={onPress}
|
|
91
|
-
onLayout={
|
|
107
|
+
onLayout={onLayoutHandler}
|
|
92
108
|
>
|
|
93
109
|
{children}
|
|
94
110
|
</AnimatedComponent>
|
|
@@ -13,7 +13,7 @@ type Props = {
|
|
|
13
13
|
const EMPTY_STYLE = Object.freeze({} as StyleProps);
|
|
14
14
|
|
|
15
15
|
export const RootTransitionAware = memo(({ children }: Props) => {
|
|
16
|
-
const stylesMap = useTransitionStyles();
|
|
16
|
+
const { stylesMap } = useTransitionStyles();
|
|
17
17
|
|
|
18
18
|
const animatedContentStyle = useAnimatedStyle(() => {
|
|
19
19
|
"worklet";
|
|
@@ -1,19 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type StyleProps,
|
|
3
|
+
useAnimatedStyle,
|
|
4
|
+
useDerivedValue,
|
|
5
|
+
useSharedValue,
|
|
6
|
+
} from "react-native-reanimated";
|
|
2
7
|
import { useTransitionStyles } from "../../providers/transition-styles";
|
|
3
8
|
|
|
4
9
|
type Props = {
|
|
5
10
|
id?: string;
|
|
11
|
+
style?: StyleProps;
|
|
6
12
|
};
|
|
7
13
|
|
|
8
14
|
const EMPTY_STYLE = Object.freeze({});
|
|
9
15
|
|
|
10
16
|
/**
|
|
11
|
-
* This hook is used to get the associated styles for a given styleId.
|
|
12
|
-
* It is used to get the associated styles for a given styleId.
|
|
13
|
-
* It is used to get the associated styles for a given styleId.
|
|
17
|
+
* This hook is used to get the associated styles for a given styleId / boundTag.
|
|
14
18
|
*/
|
|
15
|
-
export const useAssociatedStyles = ({ id }: Props = {}) => {
|
|
16
|
-
const stylesMap = useTransitionStyles();
|
|
19
|
+
export const useAssociatedStyles = ({ id, style }: Props = {}) => {
|
|
20
|
+
const { stylesMap } = useTransitionStyles();
|
|
21
|
+
const showAfterFirstFrame = useSharedValue(false);
|
|
22
|
+
|
|
23
|
+
useDerivedValue(() => {
|
|
24
|
+
"worklet";
|
|
25
|
+
if (!id) {
|
|
26
|
+
showAfterFirstFrame.value = true;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (!showAfterFirstFrame.value) {
|
|
30
|
+
requestAnimationFrame(() => {
|
|
31
|
+
showAfterFirstFrame.value = true;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
17
35
|
|
|
18
36
|
const associatedStyles = useAnimatedStyle(() => {
|
|
19
37
|
"worklet";
|
|
@@ -21,8 +39,25 @@ export const useAssociatedStyles = ({ id }: Props = {}) => {
|
|
|
21
39
|
if (!id || !stylesMap) {
|
|
22
40
|
return EMPTY_STYLE;
|
|
23
41
|
}
|
|
42
|
+
const base =
|
|
43
|
+
(stylesMap.value[id] as Record<string, unknown>) || EMPTY_STYLE;
|
|
44
|
+
|
|
45
|
+
let opacity = 1;
|
|
46
|
+
|
|
47
|
+
if ("opacity" in base) {
|
|
48
|
+
opacity = base.opacity as number;
|
|
49
|
+
}
|
|
50
|
+
if (style && "opacity" in style) {
|
|
51
|
+
opacity = style.opacity as number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Only force opacity to 0 during the initial frame; once ready,
|
|
55
|
+
// return base unchanged so we never override user-provided opacity.
|
|
56
|
+
if (!showAfterFirstFrame.value) {
|
|
57
|
+
return { ...base, opacity: 0 } as Record<string, unknown>;
|
|
58
|
+
}
|
|
24
59
|
|
|
25
|
-
return
|
|
60
|
+
return { ...base, opacity };
|
|
26
61
|
});
|
|
27
62
|
|
|
28
63
|
return { associatedStyles };
|