@pyreon/kinetic 0.11.5 → 0.11.7
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/README.md +27 -24
- package/lib/index.d.ts +8 -8
- package/package.json +22 -22
- package/src/Collapse.tsx +44 -44
- package/src/Stagger.tsx +7 -7
- package/src/Transition.tsx +18 -18
- package/src/TransitionGroup.tsx +6 -6
- package/src/__tests__/Collapse.test.tsx +125 -125
- package/src/__tests__/GroupRenderer.test.tsx +78 -78
- package/src/__tests__/StaggerRenderer.test.tsx +99 -99
- package/src/__tests__/Transition.test.tsx +89 -89
- package/src/__tests__/TransitionItem.test.tsx +120 -120
- package/src/__tests__/kinetic.test.tsx +135 -135
- package/src/__tests__/presets.test.ts +15 -15
- package/src/__tests__/useAnimationEnd.test.ts +33 -33
- package/src/__tests__/useReducedMotion.test.ts +22 -22
- package/src/__tests__/useTransitionState.test.ts +38 -38
- package/src/__tests__/utils.test.ts +63 -63
- package/src/index.ts +9 -17
- package/src/kinetic/CollapseRenderer.tsx +42 -42
- package/src/kinetic/GroupRenderer.tsx +8 -8
- package/src/kinetic/StaggerRenderer.tsx +9 -9
- package/src/kinetic/TransitionItem.tsx +18 -18
- package/src/kinetic/TransitionRenderer.tsx +19 -19
- package/src/kinetic/createKineticComponent.tsx +27 -27
- package/src/kinetic/types.ts +13 -13
- package/src/kinetic.ts +4 -4
- package/src/presets.ts +33 -33
- package/src/types.ts +3 -3
- package/src/useAnimationEnd.ts +8 -8
- package/src/useReducedMotion.ts +5 -5
- package/src/useTransitionState.ts +12 -12
- package/src/utils.ts +4 -4
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import type { VNode } from
|
|
2
|
-
import type { CSSProperties, TransitionCallbacks } from
|
|
3
|
-
import CollapseRenderer from
|
|
4
|
-
import GroupRenderer from
|
|
5
|
-
import StaggerRenderer from
|
|
6
|
-
import TransitionRenderer from
|
|
7
|
-
import type { ClassConfig, KineticComponent, KineticConfig, KineticMode } from
|
|
1
|
+
import type { VNode } from '@pyreon/core'
|
|
2
|
+
import type { CSSProperties, TransitionCallbacks } from '../types'
|
|
3
|
+
import CollapseRenderer from './CollapseRenderer'
|
|
4
|
+
import GroupRenderer from './GroupRenderer'
|
|
5
|
+
import StaggerRenderer from './StaggerRenderer'
|
|
6
|
+
import TransitionRenderer from './TransitionRenderer'
|
|
7
|
+
import type { ClassConfig, KineticComponent, KineticConfig, KineticMode } from './types'
|
|
8
8
|
|
|
9
9
|
/** Keys that are kinetic-specific and should not be forwarded as HTML attrs. */
|
|
10
10
|
const KINETIC_KEYS = new Set([
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
'show',
|
|
12
|
+
'appear',
|
|
13
|
+
'unmount',
|
|
14
|
+
'timeout',
|
|
15
|
+
'transition',
|
|
16
|
+
'interval',
|
|
17
|
+
'reverseLeave',
|
|
18
|
+
'onEnter',
|
|
19
|
+
'onAfterEnter',
|
|
20
|
+
'onLeave',
|
|
21
|
+
'onAfterLeave',
|
|
22
22
|
])
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -26,7 +26,7 @@ const KINETIC_KEYS = new Set([
|
|
|
26
26
|
* renderer based on config.mode, then attaches immutable chain methods
|
|
27
27
|
* via Object.assign.
|
|
28
28
|
*/
|
|
29
|
-
const createKineticComponent = <Tag extends string, Mode extends KineticMode =
|
|
29
|
+
const createKineticComponent = <Tag extends string, Mode extends KineticMode = 'transition'>(
|
|
30
30
|
config: KineticConfig,
|
|
31
31
|
): KineticComponent<Tag, Mode> => {
|
|
32
32
|
const Component = (props: Record<string, unknown>): VNode | null => {
|
|
@@ -74,7 +74,7 @@ const createKineticComponent = <Tag extends string, Mode extends KineticMode = "
|
|
|
74
74
|
// Extract children from htmlProps (it's not an HTML attribute)
|
|
75
75
|
const { children, ...restHtml } = htmlProps
|
|
76
76
|
|
|
77
|
-
if (config.mode ===
|
|
77
|
+
if (config.mode === 'collapse') {
|
|
78
78
|
return (
|
|
79
79
|
<CollapseRenderer
|
|
80
80
|
config={config}
|
|
@@ -90,7 +90,7 @@ const createKineticComponent = <Tag extends string, Mode extends KineticMode = "
|
|
|
90
90
|
)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
if (config.mode ===
|
|
93
|
+
if (config.mode === 'stagger') {
|
|
94
94
|
return (
|
|
95
95
|
<StaggerRenderer
|
|
96
96
|
config={config}
|
|
@@ -107,7 +107,7 @@ const createKineticComponent = <Tag extends string, Mode extends KineticMode = "
|
|
|
107
107
|
)
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
if (config.mode ===
|
|
110
|
+
if (config.mode === 'group') {
|
|
111
111
|
return (
|
|
112
112
|
<GroupRenderer
|
|
113
113
|
config={config}
|
|
@@ -191,20 +191,20 @@ const createKineticComponent = <Tag extends string, Mode extends KineticMode = "
|
|
|
191
191
|
createKineticComponent<Tag, Mode>({ ...config, ...cbs }),
|
|
192
192
|
|
|
193
193
|
collapse: (opts?: { transition?: string }) =>
|
|
194
|
-
createKineticComponent<Tag,
|
|
194
|
+
createKineticComponent<Tag, 'collapse'>({
|
|
195
195
|
...config,
|
|
196
|
-
mode:
|
|
196
|
+
mode: 'collapse',
|
|
197
197
|
...opts,
|
|
198
198
|
}),
|
|
199
199
|
|
|
200
200
|
stagger: (opts?: { interval?: number; reverseLeave?: boolean }) =>
|
|
201
|
-
createKineticComponent<Tag,
|
|
201
|
+
createKineticComponent<Tag, 'stagger'>({
|
|
202
202
|
...config,
|
|
203
|
-
mode:
|
|
203
|
+
mode: 'stagger',
|
|
204
204
|
...opts,
|
|
205
205
|
}),
|
|
206
206
|
|
|
207
|
-
group: () => createKineticComponent<Tag,
|
|
207
|
+
group: () => createKineticComponent<Tag, 'group'>({ ...config, mode: 'group' }),
|
|
208
208
|
}) as unknown as KineticComponent<Tag, Mode>
|
|
209
209
|
}
|
|
210
210
|
|
package/src/kinetic/types.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { ComponentFn, VNodeChild } from
|
|
1
|
+
import type { ComponentFn, VNodeChild } from '@pyreon/core'
|
|
2
2
|
import type {
|
|
3
3
|
ClassTransitionProps,
|
|
4
4
|
CSSProperties,
|
|
5
5
|
StyleTransitionProps,
|
|
6
6
|
TransitionCallbacks,
|
|
7
|
-
} from
|
|
7
|
+
} from '../types'
|
|
8
8
|
|
|
9
9
|
// ─── Kinetic Modes ────────────────────────────────────────
|
|
10
10
|
|
|
11
|
-
export type KineticMode =
|
|
11
|
+
export type KineticMode = 'transition' | 'collapse' | 'stagger' | 'group'
|
|
12
12
|
|
|
13
13
|
// ─── Internal Config (accumulated through chaining) ──────
|
|
14
14
|
|
|
@@ -100,21 +100,21 @@ export type KineticGroupProps<_Tag extends string> = Record<string, unknown> & {
|
|
|
100
100
|
export type KineticComponentProps<
|
|
101
101
|
Tag extends string,
|
|
102
102
|
Mode extends KineticMode,
|
|
103
|
-
> = Mode extends
|
|
103
|
+
> = Mode extends 'collapse'
|
|
104
104
|
? KineticCollapseProps<Tag>
|
|
105
|
-
: Mode extends
|
|
105
|
+
: Mode extends 'stagger'
|
|
106
106
|
? KineticStaggerProps<Tag>
|
|
107
|
-
: Mode extends
|
|
107
|
+
: Mode extends 'group'
|
|
108
108
|
? KineticGroupProps<Tag>
|
|
109
109
|
: KineticTransitionProps<Tag>
|
|
110
110
|
|
|
111
111
|
// ─── Conditional config opts based on mode ───────────────
|
|
112
112
|
|
|
113
|
-
type ConfigOpts<Mode extends KineticMode> = Mode extends
|
|
113
|
+
type ConfigOpts<Mode extends KineticMode> = Mode extends 'collapse'
|
|
114
114
|
? CollapseConfigOpts
|
|
115
|
-
: Mode extends
|
|
115
|
+
: Mode extends 'stagger'
|
|
116
116
|
? StaggerConfigOpts
|
|
117
|
-
: Mode extends
|
|
117
|
+
: Mode extends 'group'
|
|
118
118
|
? GroupConfigOpts
|
|
119
119
|
: TransitionConfigOpts
|
|
120
120
|
|
|
@@ -133,17 +133,17 @@ export type KineticChain<Tag extends string, Mode extends KineticMode> = {
|
|
|
133
133
|
leaveClass: (opts: ClassConfig) => KineticComponent<Tag, Mode>
|
|
134
134
|
config: (opts: ConfigOpts<Mode>) => KineticComponent<Tag, Mode>
|
|
135
135
|
on: (callbacks: Partial<TransitionCallbacks>) => KineticComponent<Tag, Mode>
|
|
136
|
-
collapse: (opts?: CollapseConfigOpts) => KineticComponent<Tag,
|
|
136
|
+
collapse: (opts?: CollapseConfigOpts) => KineticComponent<Tag, 'collapse'>
|
|
137
137
|
stagger: (opts?: {
|
|
138
138
|
interval?: number | undefined
|
|
139
139
|
reverseLeave?: boolean | undefined
|
|
140
|
-
}) => KineticComponent<Tag,
|
|
141
|
-
group: () => KineticComponent<Tag,
|
|
140
|
+
}) => KineticComponent<Tag, 'stagger'>
|
|
141
|
+
group: () => KineticComponent<Tag, 'group'>
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
// ─── The full kinetic component: renderable + chainable ───
|
|
145
145
|
|
|
146
146
|
export type KineticComponent<
|
|
147
147
|
Tag extends string,
|
|
148
|
-
Mode extends KineticMode =
|
|
148
|
+
Mode extends KineticMode = 'transition',
|
|
149
149
|
> = ComponentFn<KineticComponentProps<Tag, Mode>> & KineticChain<Tag, Mode>
|
package/src/kinetic.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import createKineticComponent from
|
|
2
|
-
import type { KineticComponent } from
|
|
1
|
+
import createKineticComponent from './kinetic/createKineticComponent'
|
|
2
|
+
import type { KineticComponent } from './kinetic/types'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Creates a reusable animated component via immutable chaining.
|
|
@@ -19,7 +19,7 @@ import type { KineticComponent } from "./kinetic/types"
|
|
|
19
19
|
* const AnimatedList = kinetic('ul').preset(fade).group()
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
const kinetic = <Tag extends string>(tag: Tag): KineticComponent<Tag,
|
|
23
|
-
createKineticComponent<Tag,
|
|
22
|
+
const kinetic = <Tag extends string>(tag: Tag): KineticComponent<Tag, 'transition'> =>
|
|
23
|
+
createKineticComponent<Tag, 'transition'>({ tag, mode: 'transition' })
|
|
24
24
|
|
|
25
25
|
export default kinetic
|
package/src/presets.ts
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import type { ClassTransitionProps, StyleTransitionProps } from
|
|
1
|
+
import type { ClassTransitionProps, StyleTransitionProps } from './types'
|
|
2
2
|
|
|
3
3
|
export type Preset = StyleTransitionProps & ClassTransitionProps
|
|
4
4
|
|
|
5
5
|
export const fade: Preset = {
|
|
6
6
|
enterStyle: { opacity: 0 },
|
|
7
7
|
enterToStyle: { opacity: 1 },
|
|
8
|
-
enterTransition:
|
|
8
|
+
enterTransition: 'opacity 300ms ease-out',
|
|
9
9
|
leaveStyle: { opacity: 1 },
|
|
10
10
|
leaveToStyle: { opacity: 0 },
|
|
11
|
-
leaveTransition:
|
|
11
|
+
leaveTransition: 'opacity 200ms ease-in',
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export const scaleIn: Preset = {
|
|
15
|
-
enterStyle: { opacity: 0, transform:
|
|
16
|
-
enterToStyle: { opacity: 1, transform:
|
|
17
|
-
enterTransition:
|
|
18
|
-
leaveStyle: { opacity: 1, transform:
|
|
19
|
-
leaveToStyle: { opacity: 0, transform:
|
|
20
|
-
leaveTransition:
|
|
15
|
+
enterStyle: { opacity: 0, transform: 'scale(0.95)' },
|
|
16
|
+
enterToStyle: { opacity: 1, transform: 'scale(1)' },
|
|
17
|
+
enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',
|
|
18
|
+
leaveStyle: { opacity: 1, transform: 'scale(1)' },
|
|
19
|
+
leaveToStyle: { opacity: 0, transform: 'scale(0.95)' },
|
|
20
|
+
leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export const slideUp: Preset = {
|
|
24
|
-
enterStyle: { opacity: 0, transform:
|
|
25
|
-
enterToStyle: { opacity: 1, transform:
|
|
26
|
-
enterTransition:
|
|
27
|
-
leaveStyle: { opacity: 1, transform:
|
|
28
|
-
leaveToStyle: { opacity: 0, transform:
|
|
29
|
-
leaveTransition:
|
|
24
|
+
enterStyle: { opacity: 0, transform: 'translateY(16px)' },
|
|
25
|
+
enterToStyle: { opacity: 1, transform: 'translateY(0)' },
|
|
26
|
+
enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',
|
|
27
|
+
leaveStyle: { opacity: 1, transform: 'translateY(0)' },
|
|
28
|
+
leaveToStyle: { opacity: 0, transform: 'translateY(16px)' },
|
|
29
|
+
leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export const slideDown: Preset = {
|
|
33
|
-
enterStyle: { opacity: 0, transform:
|
|
34
|
-
enterToStyle: { opacity: 1, transform:
|
|
35
|
-
enterTransition:
|
|
36
|
-
leaveStyle: { opacity: 1, transform:
|
|
37
|
-
leaveToStyle: { opacity: 0, transform:
|
|
38
|
-
leaveTransition:
|
|
33
|
+
enterStyle: { opacity: 0, transform: 'translateY(-16px)' },
|
|
34
|
+
enterToStyle: { opacity: 1, transform: 'translateY(0)' },
|
|
35
|
+
enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',
|
|
36
|
+
leaveStyle: { opacity: 1, transform: 'translateY(0)' },
|
|
37
|
+
leaveToStyle: { opacity: 0, transform: 'translateY(-16px)' },
|
|
38
|
+
leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export const slideLeft: Preset = {
|
|
42
|
-
enterStyle: { opacity: 0, transform:
|
|
43
|
-
enterToStyle: { opacity: 1, transform:
|
|
44
|
-
enterTransition:
|
|
45
|
-
leaveStyle: { opacity: 1, transform:
|
|
46
|
-
leaveToStyle: { opacity: 0, transform:
|
|
47
|
-
leaveTransition:
|
|
42
|
+
enterStyle: { opacity: 0, transform: 'translateX(16px)' },
|
|
43
|
+
enterToStyle: { opacity: 1, transform: 'translateX(0)' },
|
|
44
|
+
enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',
|
|
45
|
+
leaveStyle: { opacity: 1, transform: 'translateX(0)' },
|
|
46
|
+
leaveToStyle: { opacity: 0, transform: 'translateX(16px)' },
|
|
47
|
+
leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export const slideRight: Preset = {
|
|
51
|
-
enterStyle: { opacity: 0, transform:
|
|
52
|
-
enterToStyle: { opacity: 1, transform:
|
|
53
|
-
enterTransition:
|
|
54
|
-
leaveStyle: { opacity: 1, transform:
|
|
55
|
-
leaveToStyle: { opacity: 0, transform:
|
|
56
|
-
leaveTransition:
|
|
51
|
+
enterStyle: { opacity: 0, transform: 'translateX(-16px)' },
|
|
52
|
+
enterToStyle: { opacity: 1, transform: 'translateX(0)' },
|
|
53
|
+
enterTransition: 'opacity 300ms ease-out, transform 300ms ease-out',
|
|
54
|
+
leaveStyle: { opacity: 1, transform: 'translateX(0)' },
|
|
55
|
+
leaveToStyle: { opacity: 0, transform: 'translateX(-16px)' },
|
|
56
|
+
leaveTransition: 'opacity 200ms ease-in, transform 200ms ease-in',
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export const presets = {
|
package/src/types.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Ref, VNode } from
|
|
2
|
-
import type { Signal } from
|
|
1
|
+
import type { Ref, VNode } from '@pyreon/core'
|
|
2
|
+
import type { Signal } from '@pyreon/reactivity'
|
|
3
3
|
|
|
4
4
|
export type CSSProperties = Record<string, string | number | undefined>
|
|
5
5
|
|
|
6
6
|
/** Internal lifecycle stages of a transition. */
|
|
7
|
-
export type TransitionStage =
|
|
7
|
+
export type TransitionStage = 'hidden' | 'entering' | 'entered' | 'leaving'
|
|
8
8
|
|
|
9
9
|
/** Class-based transition definition. */
|
|
10
10
|
export type ClassTransitionProps = {
|
package/src/useAnimationEnd.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Ref } from
|
|
2
|
-
import { watch } from
|
|
1
|
+
import type { Ref } from '@pyreon/core'
|
|
2
|
+
import { watch } from '@pyreon/reactivity'
|
|
3
3
|
|
|
4
4
|
const DEFAULT_TIMEOUT = 5000
|
|
5
5
|
|
|
@@ -29,8 +29,8 @@ const useAnimationEnd: UseAnimationEnd = ({ ref, onEnd, active, timeout = DEFAUL
|
|
|
29
29
|
const done = () => {
|
|
30
30
|
if (called) return
|
|
31
31
|
called = true
|
|
32
|
-
el.removeEventListener(
|
|
33
|
-
el.removeEventListener(
|
|
32
|
+
el.removeEventListener('transitionend', handleEnd)
|
|
33
|
+
el.removeEventListener('animationend', handleEnd)
|
|
34
34
|
clearTimeout(timer)
|
|
35
35
|
onEnd()
|
|
36
36
|
}
|
|
@@ -41,14 +41,14 @@ const useAnimationEnd: UseAnimationEnd = ({ ref, onEnd, active, timeout = DEFAUL
|
|
|
41
41
|
done()
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
el.addEventListener(
|
|
45
|
-
el.addEventListener(
|
|
44
|
+
el.addEventListener('transitionend', handleEnd)
|
|
45
|
+
el.addEventListener('animationend', handleEnd)
|
|
46
46
|
|
|
47
47
|
const timer = setTimeout(done, timeout)
|
|
48
48
|
|
|
49
49
|
return () => {
|
|
50
|
-
el.removeEventListener(
|
|
51
|
-
el.removeEventListener(
|
|
50
|
+
el.removeEventListener('transitionend', handleEnd)
|
|
51
|
+
el.removeEventListener('animationend', handleEnd)
|
|
52
52
|
clearTimeout(timer)
|
|
53
53
|
}
|
|
54
54
|
},
|
package/src/useReducedMotion.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { onMount, onUnmount } from
|
|
2
|
-
import { signal } from
|
|
1
|
+
import { onMount, onUnmount } from '@pyreon/core'
|
|
2
|
+
import { signal } from '@pyreon/reactivity'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Inline reduced-motion check for kinetic package.
|
|
@@ -14,14 +14,14 @@ export function useReducedMotion(): () => boolean {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
onMount(() => {
|
|
17
|
-
mql = window.matchMedia(
|
|
17
|
+
mql = window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
18
18
|
matches.set(mql.matches)
|
|
19
|
-
mql.addEventListener(
|
|
19
|
+
mql.addEventListener('change', onChange)
|
|
20
20
|
return undefined
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
onUnmount(() => {
|
|
24
|
-
mql?.removeEventListener(
|
|
24
|
+
mql?.removeEventListener('change', onChange)
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
return matches
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createRef } from
|
|
2
|
-
import { runUntracked, signal, watch } from
|
|
3
|
-
import type { TransitionStage, TransitionStateResult } from
|
|
1
|
+
import { createRef } from '@pyreon/core'
|
|
2
|
+
import { runUntracked, signal, watch } from '@pyreon/reactivity'
|
|
3
|
+
import type { TransitionStage, TransitionStateResult } from './types'
|
|
4
4
|
|
|
5
5
|
export type UseTransitionState = (options: {
|
|
6
6
|
show: () => boolean
|
|
@@ -12,7 +12,7 @@ const useTransitionState: UseTransitionState = ({ show, appear = false }) => {
|
|
|
12
12
|
// When appear=true and show starts true, mount the element (stage='entered')
|
|
13
13
|
// but defer the enter animation until the ref is connected.
|
|
14
14
|
const needsAppear = appear && initialShow
|
|
15
|
-
const stage = signal<TransitionStage>(initialShow ?
|
|
15
|
+
const stage = signal<TransitionStage>(initialShow ? 'entered' : 'hidden')
|
|
16
16
|
const elementRef = createRef<HTMLElement>()
|
|
17
17
|
let isInitialMount = true
|
|
18
18
|
let appearTriggered = false
|
|
@@ -22,7 +22,7 @@ const useTransitionState: UseTransitionState = ({ show, appear = false }) => {
|
|
|
22
22
|
elementRef.current = node
|
|
23
23
|
if (node && needsAppear && !appearTriggered) {
|
|
24
24
|
appearTriggered = true
|
|
25
|
-
stage.set(
|
|
25
|
+
stage.set('entering')
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -36,10 +36,10 @@ const useTransitionState: UseTransitionState = ({ show, appear = false }) => {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const currentStage = runUntracked(() => stage())
|
|
39
|
-
if (showVal && (currentStage ===
|
|
40
|
-
stage.set(
|
|
41
|
-
} else if (!showVal && (currentStage ===
|
|
42
|
-
stage.set(
|
|
39
|
+
if (showVal && (currentStage === 'hidden' || currentStage === 'leaving')) {
|
|
40
|
+
stage.set('entering')
|
|
41
|
+
} else if (!showVal && (currentStage === 'entered' || currentStage === 'entering')) {
|
|
42
|
+
stage.set('leaving')
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
{ immediate: true },
|
|
@@ -47,14 +47,14 @@ const useTransitionState: UseTransitionState = ({ show, appear = false }) => {
|
|
|
47
47
|
|
|
48
48
|
const complete = () => {
|
|
49
49
|
const current = stage()
|
|
50
|
-
if (current ===
|
|
51
|
-
if (current ===
|
|
50
|
+
if (current === 'entering') stage.set('entered')
|
|
51
|
+
if (current === 'leaving') stage.set('hidden')
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
return {
|
|
55
55
|
stage,
|
|
56
56
|
ref: refCallback,
|
|
57
|
-
shouldMount: () => stage() !==
|
|
57
|
+
shouldMount: () => stage() !== 'hidden',
|
|
58
58
|
complete,
|
|
59
59
|
}
|
|
60
60
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Ref, VNode } from
|
|
2
|
-
import type { CSSProperties } from
|
|
1
|
+
import type { Ref, VNode } from '@pyreon/core'
|
|
2
|
+
import type { CSSProperties } from './types'
|
|
3
3
|
|
|
4
4
|
const splitCache = new Map<string, string[]>()
|
|
5
5
|
const splitClasses = (classes: string): string[] => {
|
|
@@ -41,7 +41,7 @@ export const mergeClassNames = (
|
|
|
41
41
|
additional: string | undefined,
|
|
42
42
|
): string | undefined => {
|
|
43
43
|
const parts = [existing, additional].filter(Boolean)
|
|
44
|
-
return parts.length > 0 ? parts.join(
|
|
44
|
+
return parts.length > 0 ? parts.join(' ') : undefined
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/** Merges two CSSProperties objects, with `b` taking precedence. */
|
|
@@ -65,7 +65,7 @@ export const mergeRefs = <T>(...refs: (RefLike<T> | undefined)[]): ((node: T | n
|
|
|
65
65
|
return (node: T | null) => {
|
|
66
66
|
for (const ref of refs) {
|
|
67
67
|
if (!ref) continue
|
|
68
|
-
if (typeof ref ===
|
|
68
|
+
if (typeof ref === 'function') {
|
|
69
69
|
ref(node)
|
|
70
70
|
} else {
|
|
71
71
|
;(ref as { current: unknown }).current = node
|