@hanzogui/animate-presence 2.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.
- package/LICENSE +21 -0
- package/LICENSE.md +9 -0
- package/README.md +1 -0
- package/dist/cjs/AnimatePresence.cjs +111 -0
- package/dist/cjs/AnimatePresence.native.js +129 -0
- package/dist/cjs/AnimatePresence.native.js.map +1 -0
- package/dist/cjs/LayoutGroupContext.cjs +38 -0
- package/dist/cjs/LayoutGroupContext.native.js +41 -0
- package/dist/cjs/LayoutGroupContext.native.js.map +1 -0
- package/dist/cjs/PresenceChild.cjs +88 -0
- package/dist/cjs/PresenceChild.native.js +116 -0
- package/dist/cjs/PresenceChild.native.js.map +1 -0
- package/dist/cjs/index.cjs +21 -0
- package/dist/cjs/index.native.js +24 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.native.js +19 -0
- package/dist/cjs/types.native.js.map +1 -0
- package/dist/esm/AnimatePresence.mjs +88 -0
- package/dist/esm/AnimatePresence.mjs.map +1 -0
- package/dist/esm/AnimatePresence.native.js +103 -0
- package/dist/esm/AnimatePresence.native.js.map +1 -0
- package/dist/esm/LayoutGroupContext.mjs +4 -0
- package/dist/esm/LayoutGroupContext.mjs.map +1 -0
- package/dist/esm/LayoutGroupContext.native.js +4 -0
- package/dist/esm/LayoutGroupContext.native.js.map +1 -0
- package/dist/esm/PresenceChild.mjs +54 -0
- package/dist/esm/PresenceChild.mjs.map +1 -0
- package/dist/esm/PresenceChild.native.js +79 -0
- package/dist/esm/PresenceChild.native.js.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/index.mjs +5 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +5 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/package.json +55 -0
- package/src/AnimatePresence.tsx +219 -0
- package/src/LayoutGroupContext.tsx +8 -0
- package/src/PresenceChild.tsx +90 -0
- package/src/index.ts +4 -0
- package/src/types.ts +107 -0
- package/types/AnimatePresence.d.ts +4 -0
- package/types/LayoutGroupContext.d.ts +7 -0
- package/types/PresenceChild.d.ts +16 -0
- package/types/index.d.ts +5 -0
- package/types/types.d.ts +96 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { useInsertionEffect } from 'react'
|
|
2
|
+
import { useConstant } from '@hanzogui/use-constant'
|
|
3
|
+
import { useForceUpdate } from '@hanzogui/use-force-update'
|
|
4
|
+
import type { FunctionComponent, PropsWithChildren, ReactElement, ReactNode } from 'react'
|
|
5
|
+
import { Children, isValidElement, useContext, useMemo, useRef, useState } from 'react'
|
|
6
|
+
import { LayoutGroupContext } from './LayoutGroupContext'
|
|
7
|
+
import { PresenceChild } from './PresenceChild'
|
|
8
|
+
import type { AnimatePresenceProps } from './types'
|
|
9
|
+
|
|
10
|
+
type ComponentKey = string | number
|
|
11
|
+
|
|
12
|
+
const getChildKey = (child: ReactElement<any>): ComponentKey => {
|
|
13
|
+
return (
|
|
14
|
+
child.key ||
|
|
15
|
+
(() => {
|
|
16
|
+
// we can help a bit by falling back to gui name or component name
|
|
17
|
+
const ct = child.type
|
|
18
|
+
const defaultName = ct['displayName'] || ct['name'] || ''
|
|
19
|
+
if (ct && typeof ct === 'object' && 'staticConfig' in ct) {
|
|
20
|
+
// @ts-expect-error
|
|
21
|
+
return ct.staticConfig.componentName || defaultName
|
|
22
|
+
}
|
|
23
|
+
return defaultName
|
|
24
|
+
})()
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function onlyElements(children: ReactNode): ReactElement<any>[] {
|
|
29
|
+
const filtered: ReactElement<any>[] = []
|
|
30
|
+
// We use forEach here instead of map as map mutates the component key by preprending `.$`
|
|
31
|
+
Children.forEach(children, (child) => {
|
|
32
|
+
if (isValidElement(child)) filtered.push(child)
|
|
33
|
+
})
|
|
34
|
+
return filtered
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const AnimatePresence: FunctionComponent<
|
|
38
|
+
PropsWithChildren<AnimatePresenceProps>
|
|
39
|
+
> = ({
|
|
40
|
+
children,
|
|
41
|
+
enterVariant,
|
|
42
|
+
exitVariant,
|
|
43
|
+
enterExitVariant,
|
|
44
|
+
initial = true,
|
|
45
|
+
onExitComplete,
|
|
46
|
+
exitBeforeEnter,
|
|
47
|
+
mode,
|
|
48
|
+
presenceAffectsLayout = true,
|
|
49
|
+
custom,
|
|
50
|
+
passThrough,
|
|
51
|
+
}) => {
|
|
52
|
+
// Determine effective mode: mode prop takes precedence, then exitBeforeEnter for backwards compatibility
|
|
53
|
+
const effectiveMode = mode ?? (exitBeforeEnter ? 'wait' : 'sync')
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Filter any children that aren't ReactElements. We can only track components
|
|
57
|
+
* between renders with a props.key.
|
|
58
|
+
* IMPORTANT: useMemo ensures reference stability for the comparison below
|
|
59
|
+
*/
|
|
60
|
+
const presentChildren = useMemo(() => onlyElements(children), [children])
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Track the keys of the currently rendered children.
|
|
64
|
+
*/
|
|
65
|
+
const presentKeys = presentChildren.map(getChildKey)
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* If `initial={false}` we only want to pass this to components in the first render.
|
|
69
|
+
*/
|
|
70
|
+
const isInitialRender = useRef(true)
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Freeze custom prop for exiting children so direction doesn't reverse mid-exit.
|
|
74
|
+
*/
|
|
75
|
+
const frozenCustomRef = useRef(new Map<ComponentKey, any>())
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A ref containing the currently present children. When all exit animations
|
|
79
|
+
* are complete, we use this to re-render with the latest children *committed*
|
|
80
|
+
* rather than the latest children *rendered*.
|
|
81
|
+
*/
|
|
82
|
+
const pendingPresentChildren = useRef(presentChildren)
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Track which exiting children have finished animating out.
|
|
86
|
+
*/
|
|
87
|
+
const exitComplete = useConstant(() => new Map<ComponentKey, boolean>())
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Save children to render as React state. To ensure this component is concurrent-safe,
|
|
91
|
+
* we check for exiting children via an effect.
|
|
92
|
+
*/
|
|
93
|
+
const [diffedChildren, setDiffedChildren] = useState(presentChildren)
|
|
94
|
+
const [renderedChildren, setRenderedChildren] = useState(presentChildren)
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* If we've been provided a forceRender function by the LayoutGroupContext,
|
|
98
|
+
* we can use it to force a re-render amongst all surrounding components once
|
|
99
|
+
* all components have finished animating out.
|
|
100
|
+
*/
|
|
101
|
+
const forceRender = useContext(LayoutGroupContext).forceRender ?? useForceUpdate()
|
|
102
|
+
|
|
103
|
+
if (passThrough) {
|
|
104
|
+
return <>{children}</>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// useInsertionEffect runs before ALL useLayoutEffects (including children's)
|
|
108
|
+
// this ensures pendingPresentChildren and exitComplete are set before
|
|
109
|
+
// animation drivers call sendExitComplete() in their layout effects
|
|
110
|
+
// (critical for immediate completions like animateOnly=[])
|
|
111
|
+
useInsertionEffect(() => {
|
|
112
|
+
isInitialRender.current = false
|
|
113
|
+
pendingPresentChildren.current = presentChildren
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Update complete status of exiting children.
|
|
117
|
+
*/
|
|
118
|
+
for (let i = 0; i < renderedChildren.length; i++) {
|
|
119
|
+
const key = getChildKey(renderedChildren[i])
|
|
120
|
+
|
|
121
|
+
if (!presentKeys.includes(key)) {
|
|
122
|
+
if (exitComplete.get(key) !== true) {
|
|
123
|
+
exitComplete.set(key, false)
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
exitComplete.delete(key)
|
|
127
|
+
frozenCustomRef.current.delete(key)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}, [renderedChildren, presentKeys.length, presentKeys.join('-')])
|
|
131
|
+
|
|
132
|
+
if (presentChildren !== diffedChildren) {
|
|
133
|
+
let nextChildren = [...presentChildren]
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Loop through all the currently rendered components and decide which
|
|
137
|
+
* are exiting.
|
|
138
|
+
*/
|
|
139
|
+
for (let i = 0; i < renderedChildren.length; i++) {
|
|
140
|
+
const child = renderedChildren[i]
|
|
141
|
+
const key = getChildKey(child)
|
|
142
|
+
|
|
143
|
+
if (!presentKeys.includes(key)) {
|
|
144
|
+
nextChildren.splice(i, 0, child)
|
|
145
|
+
// freeze custom at the moment of exit so direction doesn't reverse
|
|
146
|
+
if (!frozenCustomRef.current.has(key)) {
|
|
147
|
+
frozenCustomRef.current.set(key, custom)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* If we're in "wait" mode, and we have exiting children, we want to
|
|
154
|
+
* only render these until they've all exited.
|
|
155
|
+
*/
|
|
156
|
+
const exitingChildren = renderedChildren.filter(
|
|
157
|
+
(child) => !presentKeys.includes(getChildKey(child))
|
|
158
|
+
)
|
|
159
|
+
if (effectiveMode === 'wait' && exitingChildren.length) {
|
|
160
|
+
nextChildren = exitingChildren
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
setRenderedChildren(onlyElements(nextChildren))
|
|
164
|
+
setDiffedChildren(presentChildren)
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Early return to ensure once we've set state with the latest diffed
|
|
168
|
+
* children, we can immediately re-render.
|
|
169
|
+
*/
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<>
|
|
175
|
+
{renderedChildren.map((child) => {
|
|
176
|
+
const key = getChildKey(child)
|
|
177
|
+
const isPresent =
|
|
178
|
+
presentChildren === renderedChildren || presentKeys.includes(key)
|
|
179
|
+
|
|
180
|
+
const onExit = () => {
|
|
181
|
+
if (exitComplete.has(key)) {
|
|
182
|
+
exitComplete.set(key, true)
|
|
183
|
+
} else {
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
let isEveryExitComplete = true
|
|
188
|
+
exitComplete.forEach((isExitComplete) => {
|
|
189
|
+
if (!isExitComplete) isEveryExitComplete = false
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
if (isEveryExitComplete) {
|
|
193
|
+
forceRender?.()
|
|
194
|
+
setRenderedChildren(pendingPresentChildren.current)
|
|
195
|
+
onExitComplete?.()
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<PresenceChild
|
|
201
|
+
key={key}
|
|
202
|
+
isPresent={isPresent}
|
|
203
|
+
initial={!isInitialRender.current || initial ? undefined : false}
|
|
204
|
+
custom={isPresent ? custom : (frozenCustomRef.current.get(key) ?? custom)}
|
|
205
|
+
presenceAffectsLayout={presenceAffectsLayout}
|
|
206
|
+
enterExitVariant={enterExitVariant}
|
|
207
|
+
enterVariant={enterVariant}
|
|
208
|
+
exitVariant={exitVariant}
|
|
209
|
+
onExitComplete={isPresent ? undefined : onExit}
|
|
210
|
+
>
|
|
211
|
+
{child}
|
|
212
|
+
</PresenceChild>
|
|
213
|
+
)
|
|
214
|
+
})}
|
|
215
|
+
</>
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
AnimatePresence.displayName = 'AnimatePresence'
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useConstant } from '@hanzogui/use-constant'
|
|
2
|
+
import { PresenceContext } from '@hanzogui/use-presence'
|
|
3
|
+
import type { PresenceContextProps } from '@hanzogui/web'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
import { useId } from 'react'
|
|
6
|
+
|
|
7
|
+
import type { VariantLabels } from './types'
|
|
8
|
+
|
|
9
|
+
interface PresenceChildProps {
|
|
10
|
+
children: React.ReactElement<any>
|
|
11
|
+
isPresent: boolean
|
|
12
|
+
onExitComplete?: () => void
|
|
13
|
+
initial?: false | VariantLabels
|
|
14
|
+
custom?: any
|
|
15
|
+
presenceAffectsLayout?: boolean
|
|
16
|
+
exitVariant?: string | null
|
|
17
|
+
enterVariant?: string | null
|
|
18
|
+
enterExitVariant?: string | null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// this memo seems to help PopoverContent from continuously re-rendering when open
|
|
22
|
+
export const PresenceChild = React.memo(
|
|
23
|
+
({
|
|
24
|
+
children,
|
|
25
|
+
initial,
|
|
26
|
+
isPresent,
|
|
27
|
+
onExitComplete,
|
|
28
|
+
exitVariant,
|
|
29
|
+
enterVariant,
|
|
30
|
+
enterExitVariant,
|
|
31
|
+
presenceAffectsLayout,
|
|
32
|
+
custom,
|
|
33
|
+
}: PresenceChildProps) => {
|
|
34
|
+
const presenceChildren = useConstant(newChildrenMap)
|
|
35
|
+
const id = useId() || ''
|
|
36
|
+
|
|
37
|
+
const context = React.useMemo(
|
|
38
|
+
(): PresenceContextProps => {
|
|
39
|
+
return {
|
|
40
|
+
id,
|
|
41
|
+
initial,
|
|
42
|
+
isPresent,
|
|
43
|
+
custom,
|
|
44
|
+
exitVariant,
|
|
45
|
+
enterVariant,
|
|
46
|
+
enterExitVariant,
|
|
47
|
+
onExitComplete: () => {
|
|
48
|
+
presenceChildren.set(id, true)
|
|
49
|
+
for (const isComplete of presenceChildren.values()) {
|
|
50
|
+
if (!isComplete) {
|
|
51
|
+
return // can stop searching when any is incomplete
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
onExitComplete?.()
|
|
55
|
+
},
|
|
56
|
+
register: () => {
|
|
57
|
+
presenceChildren.set(id, false)
|
|
58
|
+
return () => presenceChildren.delete(id)
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* If the presence of a child affects the layout of the components around it,
|
|
64
|
+
* we want to make a new context value to ensure they get re-rendered
|
|
65
|
+
* so they can detect that layout change.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
// @ts-expect-error its ok
|
|
69
|
+
presenceAffectsLayout ? undefined : [isPresent, exitVariant, enterVariant]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
React.useMemo(() => {
|
|
73
|
+
presenceChildren.forEach((_, key) => presenceChildren.set(key, false))
|
|
74
|
+
}, [isPresent])
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* If there's no animated components to fire exit animations, we want to remove this
|
|
78
|
+
* component immediately.
|
|
79
|
+
*/
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
!isPresent && !presenceChildren.size && onExitComplete?.()
|
|
82
|
+
}, [isPresent])
|
|
83
|
+
|
|
84
|
+
return <PresenceContext.Provider value={context}>{children}</PresenceContext.Provider>
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
function newChildrenMap(): Map<string, boolean> {
|
|
89
|
+
return new Map()
|
|
90
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export interface Axis {
|
|
2
|
+
min: number
|
|
3
|
+
max: number
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface Box {
|
|
7
|
+
x: Axis
|
|
8
|
+
y: Axis
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type VariantLabels = string | string[]
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export interface AnimatePresenceProps {
|
|
17
|
+
/**
|
|
18
|
+
* Determines how to handle entering and exiting elements.
|
|
19
|
+
* - "sync": Default. Elements animate in and out simultaneously.
|
|
20
|
+
* - "wait": Wait for exit to finish before entering.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
mode?: 'sync' | 'wait'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* By passing `initial={false}`, `AnimatePresence` will disable any initial animations on children
|
|
28
|
+
* that are present when the component is first rendered.
|
|
29
|
+
*
|
|
30
|
+
* ```jsx
|
|
31
|
+
* <AnimatePresence initial={false}>
|
|
32
|
+
* {isVisible && (
|
|
33
|
+
* <motion.div
|
|
34
|
+
* key="modal"
|
|
35
|
+
* initial={{ opacity: 0 }}
|
|
36
|
+
* animate={{ opacity: 1 }}
|
|
37
|
+
* exit={{ opacity: 0 }}
|
|
38
|
+
* />
|
|
39
|
+
* )}
|
|
40
|
+
* </AnimatePresence>
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
initial?: boolean
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* When a component is removed, there's no longer a chance to update its props directly. So if you need to update
|
|
49
|
+
* a variant for that component as it renders for the exit animation, set `custom` to an object value that
|
|
50
|
+
* is applied to the animating childrens props before they render once more to determine their final exit styles.
|
|
51
|
+
*
|
|
52
|
+
* The custom value must be JSON.stringify-able!
|
|
53
|
+
* This lets us memoize it and use it across workers for some animationd drivers.
|
|
54
|
+
*
|
|
55
|
+
* ```tsx
|
|
56
|
+
* <AnimatePresence custom={{ direction: 10 }}>
|
|
57
|
+
* {isVisible && <Child />}
|
|
58
|
+
* </AnimatePresence>
|
|
59
|
+
*
|
|
60
|
+
* const Child = styled(View, { variants: { direction: ... } })
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
custom?: object
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Fires when all exiting nodes have completed animating out.
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
onExitComplete?: () => void
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* If set to `true`, `AnimatePresence` will only render one component at a time. The exiting component
|
|
76
|
+
* will finish its exit animation before the entering component is rendered.
|
|
77
|
+
*
|
|
78
|
+
* @deprecated Use `mode="wait"` instead.
|
|
79
|
+
*/
|
|
80
|
+
exitBeforeEnter?: boolean
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Used in Framer to flag that sibling children *shouldn't* re-render as a result of a
|
|
84
|
+
* child being removed.
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
presenceAffectsLayout?: boolean
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @deprecated use `custom` passing it an Object instead
|
|
92
|
+
*/
|
|
93
|
+
exitVariant?: string | null
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @deprecated use `custom` passing it an Object instead
|
|
97
|
+
*/
|
|
98
|
+
enterVariant?: string | null
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Will use a variant on the child component and apply the true styles for when its entering, false styles for when its exiting
|
|
102
|
+
* @deprecated use `custom` passing it an Object instead
|
|
103
|
+
*/
|
|
104
|
+
enterExitVariant?: string | null
|
|
105
|
+
|
|
106
|
+
passThrough?: boolean
|
|
107
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { VariantLabels } from './types';
|
|
3
|
+
interface PresenceChildProps {
|
|
4
|
+
children: React.ReactElement<any>;
|
|
5
|
+
isPresent: boolean;
|
|
6
|
+
onExitComplete?: () => void;
|
|
7
|
+
initial?: false | VariantLabels;
|
|
8
|
+
custom?: any;
|
|
9
|
+
presenceAffectsLayout?: boolean;
|
|
10
|
+
exitVariant?: string | null;
|
|
11
|
+
enterVariant?: string | null;
|
|
12
|
+
enterExitVariant?: string | null;
|
|
13
|
+
}
|
|
14
|
+
export declare const PresenceChild: React.MemoExoticComponent<({ children, initial, isPresent, onExitComplete, exitVariant, enterVariant, enterExitVariant, presenceAffectsLayout, custom, }: PresenceChildProps) => import("react/jsx-runtime").JSX.Element>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=PresenceChild.d.ts.map
|
package/types/index.d.ts
ADDED
package/types/types.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export interface Axis {
|
|
2
|
+
min: number;
|
|
3
|
+
max: number;
|
|
4
|
+
}
|
|
5
|
+
export interface Box {
|
|
6
|
+
x: Axis;
|
|
7
|
+
y: Axis;
|
|
8
|
+
}
|
|
9
|
+
export type VariantLabels = string | string[];
|
|
10
|
+
/**
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export interface AnimatePresenceProps {
|
|
14
|
+
/**
|
|
15
|
+
* Determines how to handle entering and exiting elements.
|
|
16
|
+
* - "sync": Default. Elements animate in and out simultaneously.
|
|
17
|
+
* - "wait": Wait for exit to finish before entering.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
mode?: 'sync' | 'wait';
|
|
22
|
+
/**
|
|
23
|
+
* By passing `initial={false}`, `AnimatePresence` will disable any initial animations on children
|
|
24
|
+
* that are present when the component is first rendered.
|
|
25
|
+
*
|
|
26
|
+
* ```jsx
|
|
27
|
+
* <AnimatePresence initial={false}>
|
|
28
|
+
* {isVisible && (
|
|
29
|
+
* <motion.div
|
|
30
|
+
* key="modal"
|
|
31
|
+
* initial={{ opacity: 0 }}
|
|
32
|
+
* animate={{ opacity: 1 }}
|
|
33
|
+
* exit={{ opacity: 0 }}
|
|
34
|
+
* />
|
|
35
|
+
* )}
|
|
36
|
+
* </AnimatePresence>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
initial?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* When a component is removed, there's no longer a chance to update its props directly. So if you need to update
|
|
44
|
+
* a variant for that component as it renders for the exit animation, set `custom` to an object value that
|
|
45
|
+
* is applied to the animating childrens props before they render once more to determine their final exit styles.
|
|
46
|
+
*
|
|
47
|
+
* The custom value must be JSON.stringify-able!
|
|
48
|
+
* This lets us memoize it and use it across workers for some animationd drivers.
|
|
49
|
+
*
|
|
50
|
+
* ```tsx
|
|
51
|
+
* <AnimatePresence custom={{ direction: 10 }}>
|
|
52
|
+
* {isVisible && <Child />}
|
|
53
|
+
* </AnimatePresence>
|
|
54
|
+
*
|
|
55
|
+
* const Child = styled(View, { variants: { direction: ... } })
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
custom?: object;
|
|
61
|
+
/**
|
|
62
|
+
* Fires when all exiting nodes have completed animating out.
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
onExitComplete?: () => void;
|
|
67
|
+
/**
|
|
68
|
+
* If set to `true`, `AnimatePresence` will only render one component at a time. The exiting component
|
|
69
|
+
* will finish its exit animation before the entering component is rendered.
|
|
70
|
+
*
|
|
71
|
+
* @deprecated Use `mode="wait"` instead.
|
|
72
|
+
*/
|
|
73
|
+
exitBeforeEnter?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Used in Framer to flag that sibling children *shouldn't* re-render as a result of a
|
|
76
|
+
* child being removed.
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
presenceAffectsLayout?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* @deprecated use `custom` passing it an Object instead
|
|
83
|
+
*/
|
|
84
|
+
exitVariant?: string | null;
|
|
85
|
+
/**
|
|
86
|
+
* @deprecated use `custom` passing it an Object instead
|
|
87
|
+
*/
|
|
88
|
+
enterVariant?: string | null;
|
|
89
|
+
/**
|
|
90
|
+
* Will use a variant on the child component and apply the true styles for when its entering, false styles for when its exiting
|
|
91
|
+
* @deprecated use `custom` passing it an Object instead
|
|
92
|
+
*/
|
|
93
|
+
enterExitVariant?: string | null;
|
|
94
|
+
passThrough?: boolean;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|