@graphcommerce/framer-utils 3.1.2 → 3.1.5

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,25 @@
1
1
  # Change Log
2
2
 
3
+ ## 3.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1598](https://github.com/graphcommerce-org/graphcommerce/pull/1598) [`707dbc73d`](https://github.com/graphcommerce-org/graphcommerce/commit/707dbc73d181204d88fdbbd2e09340e25b2b5f7b) Thanks [@paales](https://github.com/paales)! - Upgraded dependencies
8
+
9
+ * [#1600](https://github.com/graphcommerce-org/graphcommerce/pull/1600) [`5c5645e6e`](https://github.com/graphcommerce-org/graphcommerce/commit/5c5645e6eaf5314c063f05547707fcd4b34a8717) Thanks [@paales](https://github.com/paales)! - Reduce the required properties for useMotionValueValue
10
+
11
+ ## 3.1.4
12
+
13
+ ### Patch Changes
14
+
15
+ - [#1490](https://github.com/graphcommerce-org/graphcommerce/pull/1490) [`d311ef48b`](https://github.com/graphcommerce-org/graphcommerce/commit/d311ef48bb3e97806d992af5516d6b7f183ec9cb) Thanks [@paales](https://github.com/paales)! - upgraded packages
16
+
17
+ ## 3.1.3
18
+
19
+ ### Patch Changes
20
+
21
+ - [#1477](https://github.com/graphcommerce-org/graphcommerce/pull/1477) [`f167f9963`](https://github.com/graphcommerce-org/graphcommerce/commit/f167f99630966a7de43717937d43669e66132494) Thanks [@paales](https://github.com/paales)! - LayoutOverlay performance improvements
22
+
3
23
  ## 3.1.2
4
24
 
5
25
  ### Patch Changes
@@ -45,6 +45,8 @@ export function useClientSizeCssVar() {
45
45
  * return <motion.div style={{ height: y }}>bla</motion.div>
46
46
  * }
47
47
  * ```
48
+ *
49
+ * @deprecated Use `var(--client-size-y)` or `var(--client-size-x)` instead
48
50
  */
49
51
  export function useClientSize(options?: UseClientSizeOptions): UseClientSizeReturn {
50
52
  const ret = useConstant<UseClientSizeReturn>(() => ({
@@ -1,9 +1,10 @@
1
- import { motionValue, MotionValue } from 'framer-motion'
1
+ import { motionValue, MotionValue, useTransform } from 'framer-motion'
2
2
  import sync from 'framesync'
3
- import { RefObject } from 'react'
4
- import { useConstant } from './useConstant'
3
+ import { RefObject, useMemo } from 'react'
5
4
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
6
5
 
6
+ type ScrollMotionValue = { x: number; y: number; xMax: number; yMax: number }
7
+
7
8
  interface ScrollMotionValues {
8
9
  x: MotionValue<number>
9
10
  y: MotionValue<number>
@@ -11,41 +12,62 @@ interface ScrollMotionValues {
11
12
  yProgress: MotionValue<number>
12
13
  xMax: MotionValue<number>
13
14
  yMax: MotionValue<number>
15
+ scroll: MotionValue<ScrollMotionValue>
16
+ }
17
+
18
+ const refScrollMap = new Map<
19
+ RefObject<HTMLElement | undefined> | string,
20
+ MotionValue<ScrollMotionValue>
21
+ >()
22
+
23
+ const initval = () => motionValue({ x: 0, y: 0, xMax: 0, yMax: 0 })
24
+
25
+ const getScrollMotion = (ref?: RefObject<HTMLElement | undefined>, sharedKey?: string) => {
26
+ if (!ref) return initval()
27
+
28
+ const key = sharedKey || ref
29
+
30
+ if (!refScrollMap.has(key)) {
31
+ const scroll = initval()
32
+ refScrollMap.set(key, scroll)
33
+ }
34
+
35
+ return refScrollMap.get(key) as MotionValue<ScrollMotionValue>
14
36
  }
15
37
 
16
- export function useElementScroll(
17
- ref?: RefObject<HTMLElement | undefined>,
18
- noScroll = 0,
19
- ): ScrollMotionValues {
20
- const values = useConstant<ScrollMotionValues>(() => ({
21
- x: motionValue(0),
22
- y: motionValue(0),
23
- xProgress: motionValue(0),
24
- yProgress: motionValue(0),
25
- xMax: motionValue(0),
26
- yMax: motionValue(0),
27
- }))
38
+ export function useElementScroll(ref?: RefObject<HTMLElement | undefined>): ScrollMotionValues {
39
+ const scroll = getScrollMotion(ref)
40
+
41
+ const x = useTransform(scroll, (v) => v.x)
42
+ const y = useTransform(scroll, (v) => v.y)
43
+ const xProgress = useTransform(scroll, (v) => (!v.x && !v.xMax ? 0 : v.x / v.xMax))
44
+ const yProgress = useTransform(scroll, (v) => (!v.y && !v.yMax ? 0 : v.y / v.yMax))
45
+ const xMax = useTransform(scroll, (v) => v.xMax)
46
+ const yMax = useTransform(scroll, (v) => v.yMax)
28
47
 
29
48
  useIsomorphicLayoutEffect(() => {
30
49
  const element = ref?.current
31
50
  if (!element) return () => {}
32
51
 
33
52
  const updater = () => {
34
- sync.read(() => {
35
- const { scrollLeft, scrollTop, scrollWidth, scrollHeight, offsetWidth, offsetHeight } =
36
- element
37
-
38
- const xMax = Math.max(0, scrollWidth - offsetWidth)
39
- const yMax = Math.max(0, scrollHeight - offsetHeight)
53
+ if (scroll.isAnimating()) return
40
54
 
41
- values.x.set(scrollLeft)
42
- values.y.set(scrollTop)
43
- values.xMax.set(xMax)
44
- values.yMax.set(yMax)
55
+ sync.read(() => {
56
+ const scrollnew = {
57
+ x: element.scrollLeft,
58
+ y: element.scrollTop,
59
+ xMax: Math.max(0, element.scrollWidth - element.offsetWidth),
60
+ yMax: Math.max(0, element.scrollHeight - element.offsetHeight),
61
+ }
45
62
 
46
- // Set 0-1 progress
47
- values.xProgress.set(!scrollLeft && !xMax ? noScroll : scrollLeft / xMax)
48
- values.yProgress.set(!scrollTop && !yMax ? noScroll : scrollTop / yMax)
63
+ if (JSON.stringify(scrollnew) !== JSON.stringify(scroll.get())) {
64
+ scroll.set({
65
+ x: element.scrollLeft,
66
+ y: element.scrollTop,
67
+ xMax: Math.max(0, element.scrollWidth - element.offsetWidth),
68
+ yMax: Math.max(0, element.scrollHeight - element.offsetHeight),
69
+ })
70
+ }
49
71
  })
50
72
  }
51
73
 
@@ -58,7 +80,10 @@ export function useElementScroll(
58
80
  element.removeEventListener('scroll', updater)
59
81
  ro.disconnect()
60
82
  }
61
- }, [noScroll, ref, values])
83
+ }, [ref, scroll])
62
84
 
63
- return values
85
+ return useMemo(
86
+ () => ({ x, y, xProgress, yProgress, xMax, yMax, scroll }),
87
+ [x, xMax, xProgress, y, yMax, yProgress, scroll],
88
+ )
64
89
  }
@@ -1,14 +1,17 @@
1
1
  import { MotionValue } from 'framer-motion'
2
- import { useState } from 'react'
2
+ import { startTransition, useState } from 'react'
3
3
  import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
4
4
 
5
5
  /** Get the MotionValue's value and return the value as a state update. */
6
- export function useMotionValueValue<T, R>(motionValue: MotionValue<T>, effect: (v: T) => R) {
6
+ export function useMotionValueValue<T, R>(
7
+ motionValue: Pick<MotionValue<T>, 'onChange' | 'get'>,
8
+ effect: (v: T) => R,
9
+ ) {
7
10
  const [result, setResult] = useState<R>(effect(motionValue.get()))
8
11
 
9
12
  useIsomorphicLayoutEffect(() => {
10
- const set = (v: T) => setResult(effect(v))
11
- set(motionValue.get())
13
+ const set = (v: T) => startTransition(() => setResult(effect(v)))
14
+ setResult(effect(motionValue.get()))
12
15
  return motionValue.onChange(set)
13
16
  // we're not recalculating
14
17
  // eslint-disable-next-line react-hooks/exhaustive-deps
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/framer-utils",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "3.1.2",
5
+ "version": "3.1.5",
6
6
  "sideEffects": false,
7
7
  "scripts": {
8
8
  "dev": "tsc -W"
@@ -15,17 +15,17 @@
15
15
  }
16
16
  },
17
17
  "devDependencies": {
18
- "@graphcommerce/eslint-config-pwa": "^4.1.5",
18
+ "@graphcommerce/eslint-config-pwa": "^4.1.10",
19
19
  "@graphcommerce/prettier-config-pwa": "^4.0.6",
20
20
  "@graphcommerce/typescript-config-pwa": "^4.0.2",
21
21
  "@playwright/test": "^1.21.1"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "framer-motion": "^6.2.4",
25
- "react": "^17.0.2",
26
- "react-dom": "^17.0.2"
25
+ "react": "^18.0.0",
26
+ "react-dom": "^18.0.0"
27
27
  },
28
28
  "dependencies": {
29
- "framesync": "^6.1.0"
29
+ "framesync": "^6.1.1"
30
30
  }
31
31
  }