@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 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 { Fab, FabProps, styled, SxProps, Theme } from '@mui/material'
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, getScrollSnapPositions } = useScrollerContext()
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
- <Fab
45
- // eslint-disable-next-line react/no-array-index-key
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
  )
@@ -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
- return async (to: Point) => {
11
- const ref = scrollerRef.current
12
- if (!ref) return
11
+ const scrollTo = useCallback(
12
+ async (to: Point) => {
13
+ const ref = scrollerRef.current
14
+ if (!ref) return
13
15
 
14
- // 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.
15
- // if ('scrollBehavior' in document.documentElement.style) {
16
- // scrollerRef.current.scrollTo({ left: to.x, top: to.y, behavior: 'smooth' })
17
- // await new Promise((onComplete) => {
18
- // setTimeout(onComplete, 2000)
19
- // })
20
- // return
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
- const xDone = new Promise<void>((onComplete) => {
24
- if (ref.scrollLeft !== to.x) {
25
- disableSnap()
26
- register(
27
- animate({
28
- from: ref.scrollLeft,
29
- to: to.x,
30
- velocity: scroll.x.getVelocity(),
31
- onUpdate: (v) => {
32
- ref.scrollLeft = v
33
- },
34
- onComplete,
35
- onStop: onComplete,
36
- duration: 500,
37
- }),
38
- )
39
- } else onComplete()
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
- const yDone = new Promise<void>((onComplete) => {
43
- if (ref.scrollTop !== to.y) {
44
- disableSnap()
45
- register(
46
- animate({
47
- from: ref.scrollTop,
48
- to: to.y,
49
- velocity: scroll.y.getVelocity(),
50
- onUpdate: (v) => {
51
- ref.scrollTop = v
52
- },
53
- onComplete,
54
- onStop: onComplete,
55
- duration: 500,
56
- }),
57
- )
58
- } else onComplete()
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
- await xDone
62
- await yDone
63
- enableSnap()
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
  }
@@ -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.0.6",
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.4",
18
+ "@graphcommerce/framer-utils": "^3.1.0",
19
19
  "@graphcommerce/image": "^3.1.1",
20
- "@graphcommerce/next-ui": "^4.2.4"
20
+ "@graphcommerce/next-ui": "^4.4.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@graphcommerce/eslint-config-pwa": "^4.0.5",
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"