Skip to content

Commit 5e30a73

Browse files
committed
feat: useScroll supports VueInstance for container/target
1 parent 7091d24 commit 5e30a73

File tree

5 files changed

+23
-63
lines changed

5 files changed

+23
-63
lines changed

.cursorignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

.cursorrules

Lines changed: 0 additions & 37 deletions
This file was deleted.

packages/motion/src/components/hooks/use-motion-elm.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
1+
import { type MaybeComputedElementRef, unrefElement } from '@vueuse/core'
12
import { getCurrentInstance, onMounted } from 'vue'
23

34
/**
45
* Get the actual motion element, skipping text and comment nodes
56
* @param el - The HTML element to check
67
* @returns The first non-text/comment element
78
*/
8-
export function getMotionElement(el: HTMLElement) {
9+
export function getMotionElement(el: HTMLElement | SVGElement) {
910
if (el?.nodeType === 3 || el?.nodeType === 8)
1011
return getMotionElement(el.nextSibling as HTMLElement)
1112

1213
return el
1314
}
1415

16+
/**
17+
* Get the actual element, skipping text and comment nodes
18+
* @param target - The element to check
19+
* @returns The first non-text/comment element
20+
*/
21+
export function getElement(target: MaybeComputedElementRef) {
22+
return getMotionElement(unrefElement(target))
23+
}
24+
1525
/**
1626
* Hook to get the motion element of current component instance
1727
* @returns Function that returns the motion element
1828
*/
1929
export function useMotionElm() {
2030
const instance = getCurrentInstance().proxy
2131
const motionElement = {
22-
value: null as HTMLElement | null,
32+
value: null as HTMLElement | SVGElement | null,
2333
}
2434
onMounted(() => {
2535
motionElement.value = getMotionElement(instance.$el)

packages/motion/src/state/motion-state.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const mountedLayoutIds = new Set<string>()
2525
export class MotionState {
2626
public readonly id: string
2727
public type: 'html' | 'svg'
28-
public element: HTMLElement | null = null
28+
public element: HTMLElement | SVGElement | null = null
2929
// Parent reference for handling component tree relationships
3030
public parent?: MotionState
3131
public options: Options & {
@@ -130,7 +130,7 @@ export class MotionState {
130130
}
131131

132132
// Mount motion state to DOM element, handles parent-child relationships
133-
mount(element: HTMLElement, options: Options, notAnimate = false) {
133+
mount(element: HTMLElement | SVGElement, options: Options, notAnimate = false) {
134134
invariant(
135135
Boolean(element),
136136
'Animation state must be mounted with valid Element',

packages/motion/src/value/use-scroll.ts

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
1-
import type { Ref } from 'vue'
2-
import { onMounted, watch } from 'vue'
1+
import { watch } from 'vue'
32
import { motionValue, scroll } from 'framer-motion/dom'
43
import type { ScrollInfoOptions } from '@/types'
5-
import { warning } from 'hey-listen'
64
import { isSSR } from '@/utils/is'
5+
import type { MaybeComputedElementRef } from '@vueuse/core'
6+
import { getElement } from '@/components/hooks/use-motion-elm'
77

88
export interface UseScrollOptions
99
extends Omit<ScrollInfoOptions, 'container' | 'target'> {
10-
container?: Ref<HTMLElement | null>
11-
target?: Ref<HTMLElement | null>
12-
}
13-
14-
function refWarning(name: string, ref?: Ref<HTMLElement | null>) {
15-
warning(
16-
Boolean(!ref || ref.value),
17-
`You have defined a ${name} options but the provided ref is not yet hydrated, probably because it's defined higher up the tree. Try calling useScroll() in the same component as the ref.`,
18-
)
10+
container?: MaybeComputedElementRef
11+
target?: MaybeComputedElementRef
1912
}
2013

2114
function createScrollMotionValues() {
@@ -34,14 +27,9 @@ export function useScroll({
3427
}: UseScrollOptions = {}) {
3528
const values = createScrollMotionValues()
3629

37-
onMounted(() => {
38-
refWarning('target', target)
39-
refWarning('container', container)
40-
})
41-
4230
watch(
43-
[() => container?.value, () => target?.value, () => options.offset],
44-
(n, o, onCleanup) => {
31+
[() => getElement(container), () => getElement(target), () => options.offset],
32+
([newContainer, newTarget], _, onCleanup) => {
4533
if (isSSR) {
4634
return
4735
}
@@ -54,8 +42,8 @@ export function useScroll({
5442
},
5543
{
5644
...options,
57-
container: container?.value ?? undefined,
58-
target: target?.value ?? undefined,
45+
container: newContainer ?? undefined,
46+
target: newTarget ?? undefined,
5947
},
6048
)
6149
onCleanup(() => {

0 commit comments

Comments
 (0)