@graphcommerce/framer-scroller 2.0.6 → 2.1.2
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/CHANGELOG.md +47 -0
- package/components/ScrollerDot.tsx +58 -0
- package/components/ScrollerDots.tsx +5 -33
- package/hooks/useScrollTo.ts +57 -51
- package/hooks/useScroller.ts +3 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 2.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1360](https://github.com/graphcommerce-org/graphcommerce/pull/1360) [`829b8690b`](https://github.com/graphcommerce-org/graphcommerce/commit/829b8690bc5d0a46e596299e4120e9837a9f179c) Thanks [@paales](https://github.com/paales)! - Make sure the useScrollTo return value doesn't change on when rerendered.
|
|
8
|
+
|
|
9
|
+
* [#1353](https://github.com/graphcommerce-org/graphcommerce/pull/1353) [`0e5ee7ba8`](https://github.com/graphcommerce-org/graphcommerce/commit/0e5ee7ba89698e5e711001e846ed182528060cba) Thanks [@paales](https://github.com/paales)! - Eslint: enable rules that were previously disabled and make fixes
|
|
10
|
+
|
|
11
|
+
* Updated dependencies [[`49a2d6617`](https://github.com/graphcommerce-org/graphcommerce/commit/49a2d661712e1787fba46c6195f7b559189e23d9), [`f67da3cfb`](https://github.com/graphcommerce-org/graphcommerce/commit/f67da3cfbe2dcf5ea23519d088c5aa0074029182), [`218766869`](https://github.com/graphcommerce-org/graphcommerce/commit/218766869f7468c067a590857c942f3819f8add4), [`829b8690b`](https://github.com/graphcommerce-org/graphcommerce/commit/829b8690bc5d0a46e596299e4120e9837a9f179c), [`0e5ee7ba8`](https://github.com/graphcommerce-org/graphcommerce/commit/0e5ee7ba89698e5e711001e846ed182528060cba), [`829b8690b`](https://github.com/graphcommerce-org/graphcommerce/commit/829b8690bc5d0a46e596299e4120e9837a9f179c)]:
|
|
12
|
+
- @graphcommerce/next-ui@4.4.0
|
|
13
|
+
- @graphcommerce/framer-utils@3.1.0
|
|
14
|
+
|
|
15
|
+
## 2.1.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#1330](https://github.com/graphcommerce-org/graphcommerce/pull/1330) [`b7ce24fbc`](https://github.com/graphcommerce-org/graphcommerce/commit/b7ce24fbc1fbebf913faf8f5ad0bf1a126cb56d2) Thanks [@paales](https://github.com/paales)! - cyclic dependency issue with next-ui
|
|
20
|
+
|
|
21
|
+
## 2.1.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- [#1322](https://github.com/graphcommerce-org/graphcommerce/pull/1322) [`1e2a07141`](https://github.com/graphcommerce-org/graphcommerce/commit/1e2a071414154600430e6dcf0513d86ab78e0b28) Thanks [@paales](https://github.com/paales)! - Add a state-class to ScrollerDot when the dot is active to customize the colors of the dots.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
<ScrollerDots
|
|
29
|
+
layout
|
|
30
|
+
sx={{
|
|
31
|
+
'& .ScrollerDot-circle': {
|
|
32
|
+
bgcolor: 'green',
|
|
33
|
+
},
|
|
34
|
+
'& .ScrollerDot-circle.active': {
|
|
35
|
+
bgcolor: 'hotpink',
|
|
36
|
+
opacity: '1 !important',
|
|
37
|
+
},
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- [#1322](https://github.com/graphcommerce-org/graphcommerce/pull/1322) [`d91359871`](https://github.com/graphcommerce-org/graphcommerce/commit/d91359871b023a9f0d305b37353c1ee2d0912248) Thanks [@paales](https://github.com/paales)! - useScroller set userSelect/userDrag for all types of scrollers instead of only when it is rendered as a grid
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [[`5266388ea`](https://github.com/graphcommerce-org/graphcommerce/commit/5266388eaffda41592623ef7a3ddbbe03c8e0dad), [`9b35403d9`](https://github.com/graphcommerce-org/graphcommerce/commit/9b35403d9dbb2606ac7cf3bb641a0f9cc3d8a2ba), [`0298a0de1`](https://github.com/graphcommerce-org/graphcommerce/commit/0298a0de1d13e543c4124a6a099297b4e27e2b05), [`815132ea4`](https://github.com/graphcommerce-org/graphcommerce/commit/815132ea43937b4b84b59ec9974ac593cb4eb456), [`3326742a0`](https://github.com/graphcommerce-org/graphcommerce/commit/3326742a0dceb45f0cac4741ca09dc4d4f09ad90), [`7a3799bfc`](https://github.com/graphcommerce-org/graphcommerce/commit/7a3799bfc107f26aa9991a91db5f228e3476f4aa), [`9a77f88ed`](https://github.com/graphcommerce-org/graphcommerce/commit/9a77f88ed26cbecdae9a135c3cb234a5b7ecf4df), [`0eeaad304`](https://github.com/graphcommerce-org/graphcommerce/commit/0eeaad30461b1d5b486438f0287fa76d49429044), [`bc5213547`](https://github.com/graphcommerce-org/graphcommerce/commit/bc52135471479c83d989449dad24798112e898f4), [`3f1912f55`](https://github.com/graphcommerce-org/graphcommerce/commit/3f1912f553318d5888f8af2b841918ef4ae96a84), [`b6c68cda8`](https://github.com/graphcommerce-org/graphcommerce/commit/b6c68cda8836a1d0c78ef351899cec9ec1037385), [`bec88d0d7`](https://github.com/graphcommerce-org/graphcommerce/commit/bec88d0d70b679e15150917df89986ecee5b39a6)]:
|
|
47
|
+
- @graphcommerce/next-ui@4.3.0
|
|
48
|
+
- @graphcommerce/framer-utils@3.0.5
|
|
49
|
+
|
|
3
50
|
## 2.0.6
|
|
4
51
|
|
|
5
52
|
### Patch Changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useMotionValueValue } from '@graphcommerce/framer-utils'
|
|
2
|
+
import { extendableComponent } from '@graphcommerce/next-ui/Styles'
|
|
3
|
+
import { t } from '@lingui/macro'
|
|
4
|
+
import { Fab, FabProps, styled } from '@mui/material'
|
|
5
|
+
import { m } from 'framer-motion'
|
|
6
|
+
import { useScrollTo } from '../hooks/useScrollTo'
|
|
7
|
+
import { useScrollerContext } from '../hooks/useScrollerContext'
|
|
8
|
+
import { ItemState } from '../types'
|
|
9
|
+
|
|
10
|
+
const name = 'ScrollerDot'
|
|
11
|
+
const parts = ['dot', 'circle'] as const
|
|
12
|
+
type OwnerProps = { active: boolean }
|
|
13
|
+
|
|
14
|
+
const { withState } = extendableComponent<OwnerProps, typeof name, typeof parts>(name, parts)
|
|
15
|
+
|
|
16
|
+
type ScrollerDotProps = Omit<FabProps, 'onClick' | 'className'> & ItemState & { idx: number }
|
|
17
|
+
|
|
18
|
+
const MotionBox = styled(m.div)({})
|
|
19
|
+
|
|
20
|
+
export function ScrollerDot(props: ScrollerDotProps) {
|
|
21
|
+
const { el, visibility, opacity, idx, ...fabProps } = props
|
|
22
|
+
const scrollTo = useScrollTo()
|
|
23
|
+
const { getScrollSnapPositions } = useScrollerContext()
|
|
24
|
+
|
|
25
|
+
const active = useMotionValueValue(visibility, (v) => v > 0.5)
|
|
26
|
+
const classes = withState({ active })
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Fab
|
|
30
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
31
|
+
color='inherit'
|
|
32
|
+
size='small'
|
|
33
|
+
{...fabProps}
|
|
34
|
+
onClick={() => {
|
|
35
|
+
const positions = getScrollSnapPositions()
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
37
|
+
scrollTo({ x: positions.x[idx] ?? 0, y: positions.y[idx] ?? 0 })
|
|
38
|
+
}}
|
|
39
|
+
className={classes.dot}
|
|
40
|
+
aria-label={t`Navigate to item ${idx + 1}`}
|
|
41
|
+
sx={{
|
|
42
|
+
boxShadow: 'none',
|
|
43
|
+
background: 'transparent',
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<MotionBox
|
|
47
|
+
className={classes.circle}
|
|
48
|
+
sx={(theme) => ({
|
|
49
|
+
borderRadius: '99em',
|
|
50
|
+
width: 10,
|
|
51
|
+
height: 10,
|
|
52
|
+
background: theme.palette.text.primary,
|
|
53
|
+
})}
|
|
54
|
+
style={{ opacity }}
|
|
55
|
+
/>
|
|
56
|
+
</Fab>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useMotionValueValue } from '@graphcommerce/framer-utils'
|
|
2
2
|
import { extendableComponent } from '@graphcommerce/next-ui/Styles'
|
|
3
|
-
import {
|
|
3
|
+
import { FabProps, styled, SxProps, Theme } from '@mui/material'
|
|
4
4
|
import { m } from 'framer-motion'
|
|
5
5
|
import React from 'react'
|
|
6
|
-
import { useScrollTo } from '../hooks/useScrollTo'
|
|
7
6
|
import { useScrollerContext } from '../hooks/useScrollerContext'
|
|
7
|
+
import { ScrollerDot } from './ScrollerDot'
|
|
8
8
|
|
|
9
9
|
const MotionBox = styled(m.div)({})
|
|
10
10
|
|
|
@@ -20,9 +20,8 @@ export const ScrollerDots = m(
|
|
|
20
20
|
React.forwardRef<HTMLDivElement, DotsProps>((props, ref) => {
|
|
21
21
|
const { fabProps, sx = [], ...containerProps } = props
|
|
22
22
|
|
|
23
|
-
const { items
|
|
23
|
+
const { items } = useScrollerContext()
|
|
24
24
|
const itemsArr = useMotionValueValue(items, (v) => v)
|
|
25
|
-
const scrollTo = useScrollTo()
|
|
26
25
|
|
|
27
26
|
return (
|
|
28
27
|
<MotionBox
|
|
@@ -41,35 +40,8 @@ export const ScrollerDots = m(
|
|
|
41
40
|
]}
|
|
42
41
|
>
|
|
43
42
|
{itemsArr.map((item, idx) => (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
key={idx}
|
|
47
|
-
color='inherit'
|
|
48
|
-
size='small'
|
|
49
|
-
{...fabProps}
|
|
50
|
-
onClick={() => {
|
|
51
|
-
const positions = getScrollSnapPositions()
|
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
53
|
-
scrollTo({ x: positions.x[idx] ?? 0, y: positions.y[idx] ?? 0 })
|
|
54
|
-
}}
|
|
55
|
-
className={classes.dot}
|
|
56
|
-
aria-label={`img-${idx}`}
|
|
57
|
-
sx={{
|
|
58
|
-
boxShadow: 'none',
|
|
59
|
-
background: 'transparent',
|
|
60
|
-
}}
|
|
61
|
-
>
|
|
62
|
-
<MotionBox
|
|
63
|
-
className={classes.circle}
|
|
64
|
-
sx={(theme) => ({
|
|
65
|
-
borderRadius: '99em',
|
|
66
|
-
width: 10,
|
|
67
|
-
height: 10,
|
|
68
|
-
background: theme.palette.text.primary,
|
|
69
|
-
})}
|
|
70
|
-
style={{ opacity: item.opacity }}
|
|
71
|
-
/>
|
|
72
|
-
</Fab>
|
|
43
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
44
|
+
<ScrollerDot key={idx} {...item} idx={idx} />
|
|
73
45
|
))}
|
|
74
46
|
</MotionBox>
|
|
75
47
|
)
|
package/hooks/useScrollTo.ts
CHANGED
|
@@ -1,65 +1,71 @@
|
|
|
1
1
|
import { useElementScroll } from '@graphcommerce/framer-utils'
|
|
2
2
|
import { Point } from 'framer-motion'
|
|
3
3
|
import { animate } from 'popmotion'
|
|
4
|
+
import { useCallback } from 'react'
|
|
4
5
|
import { useScrollerContext } from './useScrollerContext'
|
|
5
6
|
|
|
6
7
|
export function useScrollTo() {
|
|
7
8
|
const { scrollerRef, register, disableSnap, enableSnap } = useScrollerContext()
|
|
8
9
|
const scroll = useElementScroll(scrollerRef)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const scrollTo = useCallback(
|
|
12
|
+
async (to: Point) => {
|
|
13
|
+
const ref = scrollerRef.current
|
|
14
|
+
if (!ref) return
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
// In the future we want to move to browser native scrolling behavior, but since it is too slow we're not moving to that yet.
|
|
17
|
+
// if ('scrollBehavior' in document.documentElement.style) {
|
|
18
|
+
// scrollerRef.current.scrollTo({ left: to.x, top: to.y, behavior: 'smooth' })
|
|
19
|
+
// await new Promise((onComplete) => {
|
|
20
|
+
// setTimeout(onComplete, 2000)
|
|
21
|
+
// })
|
|
22
|
+
// return
|
|
23
|
+
// }
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
const xDone = new Promise<void>((onComplete) => {
|
|
26
|
+
if (ref.scrollLeft !== to.x) {
|
|
27
|
+
disableSnap()
|
|
28
|
+
register(
|
|
29
|
+
animate({
|
|
30
|
+
from: ref.scrollLeft,
|
|
31
|
+
to: to.x,
|
|
32
|
+
velocity: scroll.x.getVelocity(),
|
|
33
|
+
onUpdate: (v) => {
|
|
34
|
+
ref.scrollLeft = v
|
|
35
|
+
},
|
|
36
|
+
onComplete,
|
|
37
|
+
onStop: onComplete,
|
|
38
|
+
duration: 500,
|
|
39
|
+
}),
|
|
40
|
+
)
|
|
41
|
+
} else onComplete()
|
|
42
|
+
})
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
const yDone = new Promise<void>((onComplete) => {
|
|
45
|
+
if (ref.scrollTop !== to.y) {
|
|
46
|
+
disableSnap()
|
|
47
|
+
register(
|
|
48
|
+
animate({
|
|
49
|
+
from: ref.scrollTop,
|
|
50
|
+
to: to.y,
|
|
51
|
+
velocity: scroll.y.getVelocity(),
|
|
52
|
+
onUpdate: (v) => {
|
|
53
|
+
ref.scrollTop = v
|
|
54
|
+
},
|
|
55
|
+
onComplete,
|
|
56
|
+
onStop: onComplete,
|
|
57
|
+
duration: 500,
|
|
58
|
+
}),
|
|
59
|
+
)
|
|
60
|
+
} else onComplete()
|
|
61
|
+
})
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
await xDone
|
|
64
|
+
await yDone
|
|
65
|
+
enableSnap()
|
|
66
|
+
},
|
|
67
|
+
[disableSnap, enableSnap, register, scroll.x, scroll.y, scrollerRef],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return scrollTo
|
|
65
71
|
}
|
package/hooks/useScroller.ts
CHANGED
|
@@ -30,6 +30,7 @@ type OwnerProps = {
|
|
|
30
30
|
isPanning: boolean
|
|
31
31
|
hideScrollbar: boolean
|
|
32
32
|
canGrab: boolean
|
|
33
|
+
grid: boolean
|
|
33
34
|
}
|
|
34
35
|
const name = 'Scroller' as const
|
|
35
36
|
const parts = ['root'] as const
|
|
@@ -117,6 +118,7 @@ export function useScroller<
|
|
|
117
118
|
const mdSnapDir = scrollSnapTypeDirection(scrollSnap.scrollSnapTypeMd)
|
|
118
119
|
|
|
119
120
|
const classes = withState({
|
|
121
|
+
grid,
|
|
120
122
|
smSnapDir,
|
|
121
123
|
smGridDir: grid && smSnapDir,
|
|
122
124
|
mdSnapDir,
|
|
@@ -128,7 +130,7 @@ export function useScroller<
|
|
|
128
130
|
})
|
|
129
131
|
|
|
130
132
|
const sx: SxProps<Theme> = (theme) => ({
|
|
131
|
-
'
|
|
133
|
+
'&.grid *': {
|
|
132
134
|
userSelect: 'none',
|
|
133
135
|
userDrag: 'none',
|
|
134
136
|
WebkitUserDrag: 'none',
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/framer-scroller",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.1.2",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"scripts": {
|
|
8
8
|
"dev": "tsc -W"
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@graphcommerce/framer-utils": "^3.0
|
|
18
|
+
"@graphcommerce/framer-utils": "^3.1.0",
|
|
19
19
|
"@graphcommerce/image": "^3.1.1",
|
|
20
|
-
"@graphcommerce/next-ui": "^4.
|
|
20
|
+
"@graphcommerce/next-ui": "^4.4.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@graphcommerce/eslint-config-pwa": "^4.
|
|
23
|
+
"@graphcommerce/eslint-config-pwa": "^4.1.2",
|
|
24
24
|
"@graphcommerce/prettier-config-pwa": "^4.0.3",
|
|
25
25
|
"@graphcommerce/typescript-config-pwa": "^4.0.2",
|
|
26
26
|
"@playwright/test": "^1.19.2"
|