@graphcommerce/framer-next-pages 2.108.11 → 2.109.0
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 +11 -0
- package/README.md +3 -17
- package/components/PageRenderer.tsx +52 -0
- package/components/Pages.tsx +60 -57
- package/context/pageRouterContext.ts +2 -36
- package/hooks/useGo.ts +16 -0
- package/hooks/useHistoryLink.ts +4 -3
- package/hooks/usePageRouter.ts +4 -22
- package/hooks/usePrevPageRouter.ts +3 -4
- package/index.ts +1 -0
- package/package.json +4 -4
- package/types.ts +11 -11
- package/utils/createRouterProxy.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [2.109.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/framer-next-pages@2.108.11...@graphcommerce/framer-next-pages@2.109.0) (2022-01-03)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **framer-next-pages:** reduce rerenders when navigating to a new page ([5cf3301](https://github.com/ho-nl/m2-pwa/commit/5cf330130bb3527057da015e3c4a6fa295d7262e))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [2.108.10](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/framer-next-pages@2.108.9...@graphcommerce/framer-next-pages@2.108.10) (2021-12-23)
|
|
7
18
|
|
|
8
19
|
|
package/README.md
CHANGED
|
@@ -156,23 +156,9 @@ We have multiple hooks available to animate based on certain states, etc.
|
|
|
156
156
|
```tsx
|
|
157
157
|
export default function MyComponent() {
|
|
158
158
|
const { level, depth, direction } = usePageContext()
|
|
159
|
-
const pageRouter = usePageRouter()
|
|
160
159
|
}
|
|
161
160
|
```
|
|
162
161
|
|
|
163
|
-
### usePageRouter
|
|
164
|
-
|
|
165
|
-
The pageRouter maintains state for the old page.
|
|
166
|
-
|
|
167
|
-
E.g.:
|
|
168
|
-
|
|
169
|
-
- `/my-regular-page`:
|
|
170
|
-
- `useRouter().asPath === '/overlay'`
|
|
171
|
-
- `usePageRouter().asPath === '/my-regular-page'` We maintain the state here!
|
|
172
|
-
- `/overlay`:
|
|
173
|
-
- `useRouter().asPath === '/overlay'`
|
|
174
|
-
- `usePageRouter().asPath === '/overlay'`
|
|
175
|
-
|
|
176
162
|
### usePageContext().level
|
|
177
163
|
|
|
178
164
|
If we have multiple pages layered on top of each other we get the level the page
|
|
@@ -226,7 +212,7 @@ count that shows us if we can go back
|
|
|
226
212
|
```tsx
|
|
227
213
|
function MyComponent {
|
|
228
214
|
const { backSteps } = usePageContext();
|
|
229
|
-
const router =
|
|
215
|
+
const router = useRouter();
|
|
230
216
|
return <button onClick={backSteps > 0 && () => router.back()}>back</button>
|
|
231
217
|
}
|
|
232
218
|
```
|
|
@@ -239,8 +225,8 @@ close the overlay. So we give the times it needs to go back.
|
|
|
239
225
|
```tsx
|
|
240
226
|
function MyComponent {
|
|
241
227
|
const { closeSteps } = usePageContext();
|
|
242
|
-
const
|
|
243
|
-
return <button onClick={closeSteps > 0 && () =>
|
|
228
|
+
const go = useGo();
|
|
229
|
+
return <button onClick={closeSteps > 0 && () => go(closeSteps * -1)}>close</button>
|
|
244
230
|
}
|
|
245
231
|
```
|
|
246
232
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { RouterContext } from 'next/dist/shared/lib/router-context'
|
|
2
|
+
import { AppPropsType } from 'next/dist/shared/lib/utils'
|
|
3
|
+
import { NextRouter, useRouter } from 'next/router'
|
|
4
|
+
import React, { useMemo } from 'react'
|
|
5
|
+
import { pageRouterContext } from '../context/pageRouterContext'
|
|
6
|
+
import { PageItem } from '../types'
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
9
|
+
const NoLayout: React.FC = ({ children }) => <>{children}</>
|
|
10
|
+
|
|
11
|
+
export type PageRendererProps = Omit<AppPropsType, 'router'> & {
|
|
12
|
+
Layout: React.ComponentType<AppPropsType>
|
|
13
|
+
layoutProps: AppPropsType
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const PageRendererLayout = React.memo((props: PageItem) => {
|
|
17
|
+
const { PageComponent, layoutProps, pageProps, routerContext } = props
|
|
18
|
+
|
|
19
|
+
const Layout = PageComponent.pageOptions?.Layout ?? NoLayout
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<pageRouterContext.Provider value={routerContext}>
|
|
23
|
+
<Layout {...layoutProps}>
|
|
24
|
+
<PageComponent {...pageProps} />
|
|
25
|
+
</Layout>
|
|
26
|
+
</pageRouterContext.Provider>
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
export function PageRenderer(props: PageItem) {
|
|
31
|
+
const { routerContext } = props
|
|
32
|
+
const router = useRouter()
|
|
33
|
+
|
|
34
|
+
const { asPath, pathname, locale, query } = routerContext.pageInfo
|
|
35
|
+
|
|
36
|
+
const pageRouter = useMemo(() => {
|
|
37
|
+
const overrideProps = { asPath, pathname, locale, query }
|
|
38
|
+
return new Proxy<NextRouter>(router, {
|
|
39
|
+
get: (target, prop: string, receiver) =>
|
|
40
|
+
overrideProps[prop] ?? Reflect.get(target, prop, receiver),
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// We don't want to re-render when the router changes
|
|
44
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
45
|
+
}, [asPath, locale, pathname, query])
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<RouterContext.Provider value={pageRouter}>
|
|
49
|
+
<PageRendererLayout {...props} />
|
|
50
|
+
</RouterContext.Provider>
|
|
51
|
+
)
|
|
52
|
+
}
|
package/components/Pages.tsx
CHANGED
|
@@ -1,27 +1,42 @@
|
|
|
1
1
|
import { AnimatePresence } from 'framer-motion'
|
|
2
2
|
import { requestIdleCallback, cancelIdleCallback } from 'next/dist/client/request-idle-callback'
|
|
3
3
|
import { AppPropsType } from 'next/dist/shared/lib/utils'
|
|
4
|
-
import
|
|
4
|
+
import { NextRouter, Router, useRouter } from 'next/router'
|
|
5
5
|
import React, { useEffect, useRef, useState } from 'react'
|
|
6
|
+
import {} from 'react-dom'
|
|
6
7
|
import { pageContext } from '../context/pageContext'
|
|
7
|
-
import { createRouterProxy, pageRouterContext } from '../context/pageRouterContext'
|
|
8
8
|
import type { PageComponent, PageItem, UpPage } from '../types'
|
|
9
9
|
import Page from './Page'
|
|
10
|
+
import { PageRenderer } from './PageRenderer'
|
|
10
11
|
|
|
11
12
|
function findPlainIdx(items: PageItem[]) {
|
|
12
13
|
return items.reduce((acc, item, i) => (typeof item.overlayGroup === 'string' ? acc : i), -1)
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
type PagesProps = Omit<AppPropsType<NextRouter>, 'pageProps'> & {
|
|
16
|
+
type PagesProps = Omit<AppPropsType<NextRouter>, 'pageProps' | 'Component'> & {
|
|
16
17
|
Component: PageComponent
|
|
17
|
-
pageProps?: { up?: UpPage }
|
|
18
|
+
pageProps?: { up?: UpPage | null }
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
const
|
|
21
|
+
function getPageInfo(router: NextRouter) {
|
|
22
|
+
const { asPath, pathname, query, locale } = router
|
|
23
|
+
return { asPath, pathname, query, locale }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// function useEarlyRerender() {
|
|
27
|
+
// const router = useRouter()
|
|
28
|
+
// const [url, set] = useState<string>()
|
|
29
|
+
|
|
30
|
+
// useEffect(() => {
|
|
31
|
+
// router.events.on('routeChangeStart', set)
|
|
32
|
+
// return () => router.events.off('routeChangeStart', set)
|
|
33
|
+
// }, [router.events])
|
|
34
|
+
|
|
35
|
+
// return url
|
|
36
|
+
// }
|
|
22
37
|
|
|
23
38
|
export default function FramerNextPages(props: PagesProps) {
|
|
24
|
-
const { router, Component, pageProps } = props
|
|
39
|
+
const { router, Component, pageProps: incomingProps } = props
|
|
25
40
|
|
|
26
41
|
const items = useRef<PageItem[]>([])
|
|
27
42
|
const idx = Number(global.window?.history.state?.idx ?? 0)
|
|
@@ -35,22 +50,31 @@ export default function FramerNextPages(props: PagesProps) {
|
|
|
35
50
|
|
|
36
51
|
let activeItem: PageItem = items.current[idx]
|
|
37
52
|
|
|
38
|
-
const
|
|
39
|
-
|
|
53
|
+
const currentItem = items.current[idx]
|
|
54
|
+
|
|
55
|
+
const mustRerender = () => {
|
|
56
|
+
const differentRouter =
|
|
57
|
+
JSON.stringify(currentItem?.routerContext.pageInfo) !== JSON.stringify(getPageInfo(router))
|
|
58
|
+
const differentProps = JSON.stringify(incomingProps) !== JSON.stringify(currentItem?.pageProps)
|
|
59
|
+
return differentRouter || differentProps
|
|
60
|
+
}
|
|
40
61
|
|
|
41
62
|
if (!activeItem || mustRerender()) {
|
|
42
|
-
const
|
|
63
|
+
const pageInfo = getPageInfo(router)
|
|
43
64
|
|
|
44
65
|
activeItem = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
actualPageProps: pageProps,
|
|
50
|
-
sharedKey: Component.pageOptions?.sharedKey?.(proxy) ?? proxy.pathname,
|
|
66
|
+
PageComponent: Component,
|
|
67
|
+
layoutProps: { ...Component.pageOptions?.layoutProps, ...incomingProps },
|
|
68
|
+
pageProps: incomingProps,
|
|
69
|
+
sharedKey: Component.pageOptions?.sharedKey?.(pageInfo) ?? pageInfo.pathname,
|
|
51
70
|
overlayGroup: Component.pageOptions?.overlayGroup,
|
|
52
71
|
historyIdx: idx,
|
|
53
|
-
|
|
72
|
+
routerContext: {
|
|
73
|
+
pageInfo,
|
|
74
|
+
prevPage: items.current[idx - 1]?.routerContext,
|
|
75
|
+
prevUp: items.current[idx - 1]?.routerContext.up,
|
|
76
|
+
up: Component.pageOptions?.up ?? incomingProps?.up ?? undefined,
|
|
77
|
+
},
|
|
54
78
|
}
|
|
55
79
|
items.current[idx] = activeItem
|
|
56
80
|
}
|
|
@@ -68,21 +92,24 @@ export default function FramerNextPages(props: PagesProps) {
|
|
|
68
92
|
let cancel: number
|
|
69
93
|
async function loadFallback() {
|
|
70
94
|
try {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
95
|
+
// todo: implement fallback loading for up property
|
|
96
|
+
// const up = items.current[0].PageComponent.pageOptions?.up?.href ?? '/'
|
|
97
|
+
const up = '/'
|
|
98
|
+
const info = await (router as Router).getRouteInfo(up, up, {}, up, up, { shallow: false })
|
|
99
|
+
|
|
100
|
+
const pageInfo = { asPath: up, pathname: up, locale: router.locale, query: {} }
|
|
75
101
|
const Fallback = info.Component as PageComponent
|
|
76
102
|
const fbItem: PageItem = {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
actualPageProps: info.props?.pageProps,
|
|
82
|
-
sharedKey: Fallback.pageOptions?.sharedKey?.(proxy) ?? proxy.pathname,
|
|
103
|
+
PageComponent: Fallback,
|
|
104
|
+
layoutProps: { ...Fallback.pageOptions?.layoutProps, ...info.props?.pageProps },
|
|
105
|
+
pageProps: info.props?.pageProps,
|
|
106
|
+
sharedKey: Fallback.pageOptions?.sharedKey?.(pageInfo) ?? pageInfo.pathname,
|
|
83
107
|
overlayGroup: Fallback.pageOptions?.overlayGroup,
|
|
84
108
|
historyIdx: -1,
|
|
85
|
-
|
|
109
|
+
routerContext: {
|
|
110
|
+
pageInfo,
|
|
111
|
+
up: Fallback.pageOptions?.up ?? info.props?.pageProps?.up,
|
|
112
|
+
},
|
|
86
113
|
}
|
|
87
114
|
|
|
88
115
|
cancel = requestIdleCallback(() => setFallback(fbItem))
|
|
@@ -118,57 +145,33 @@ export default function FramerNextPages(props: PagesProps) {
|
|
|
118
145
|
if (!item || seen.has(item.sharedKey)) return false
|
|
119
146
|
seen.add(item.sharedKey)
|
|
120
147
|
|
|
121
|
-
|
|
148
|
+
return !(
|
|
122
149
|
typeof activeItem.overlayGroup === 'string' &&
|
|
123
150
|
typeof item.overlayGroup === 'string' &&
|
|
124
151
|
activeItem.overlayGroup !== item.overlayGroup
|
|
125
|
-
)
|
|
126
|
-
return false
|
|
127
|
-
}
|
|
128
|
-
return true
|
|
152
|
+
)
|
|
129
153
|
})
|
|
130
154
|
.reverse()
|
|
131
155
|
|
|
132
156
|
return (
|
|
133
157
|
<AnimatePresence initial={false}>
|
|
134
158
|
{renderItems.map((item, itemIdx) => {
|
|
135
|
-
const {
|
|
136
|
-
children,
|
|
137
|
-
historyIdx,
|
|
138
|
-
sharedKey,
|
|
139
|
-
Layout = NoopLayout,
|
|
140
|
-
layoutProps,
|
|
141
|
-
actualPageProps,
|
|
142
|
-
currentRouter,
|
|
143
|
-
overlayGroup,
|
|
144
|
-
up,
|
|
145
|
-
} = item
|
|
159
|
+
const { historyIdx, sharedKey, overlayGroup } = item
|
|
146
160
|
const active = itemIdx === renderItems.length - 1
|
|
147
161
|
const depth = itemIdx - (renderItems.length - 1)
|
|
148
|
-
|
|
149
162
|
const closeIdx = renderItems[itemIdx - 1]?.historyIdx ?? -1
|
|
150
163
|
const closeSteps = closeIdx > -1 ? historyIdx - closeIdx : 0
|
|
151
|
-
|
|
152
164
|
const backSteps = historyIdx - closeIdx - 1
|
|
153
165
|
|
|
154
|
-
const { currentRouter: prevRouter, up: prevUp } = items.current[historyIdx - 1] ?? {}
|
|
155
|
-
|
|
156
166
|
return (
|
|
157
167
|
<pageContext.Provider
|
|
158
168
|
key={sharedKey}
|
|
159
|
-
//
|
|
169
|
+
// We're actually rerendering here but since the actual page renderer is memoized we can safely do this
|
|
160
170
|
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
|
161
171
|
value={{ depth, active, direction, closeSteps, backSteps, historyIdx, overlayGroup }}
|
|
162
172
|
>
|
|
163
173
|
<Page active={active} historyIdx={historyIdx}>
|
|
164
|
-
<
|
|
165
|
-
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
|
166
|
-
value={{ currentRouter, prevRouter, up, prevUp }}
|
|
167
|
-
>
|
|
168
|
-
<Layout {...actualPageProps} {...layoutProps}>
|
|
169
|
-
{children}
|
|
170
|
-
</Layout>
|
|
171
|
-
</pageRouterContext.Provider>
|
|
174
|
+
<PageRenderer {...item} />
|
|
172
175
|
</Page>
|
|
173
176
|
</pageContext.Provider>
|
|
174
177
|
)
|
|
@@ -1,39 +1,5 @@
|
|
|
1
|
-
import { NextRouter } from 'next/router'
|
|
2
1
|
import { createContext } from 'react'
|
|
3
|
-
import {
|
|
2
|
+
import { PageContext } from '../types'
|
|
4
3
|
|
|
5
|
-
export const pageRouterContext = createContext(undefined as unknown as
|
|
4
|
+
export const pageRouterContext = createContext(undefined as unknown as PageContext)
|
|
6
5
|
pageRouterContext.displayName = 'PageRouterContext'
|
|
7
|
-
|
|
8
|
-
type OverrideProps = Partial<Pick<NextRouter, 'asPath' | 'pathname' | 'query' | 'locale'>>
|
|
9
|
-
|
|
10
|
-
export function createRouterProxy(router: NextRouter, override?: OverrideProps): RouterProxy {
|
|
11
|
-
function go(delta: number) {
|
|
12
|
-
if (delta >= 0) {
|
|
13
|
-
console.error(`Called .go(${delta}), only negative numbers are allowed. Redirecting to home`)
|
|
14
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
15
|
-
router.push('/', '/')
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const deltaAbs = Math.abs(delta)
|
|
20
|
-
for (let i = 0; i < deltaAbs; i++) {
|
|
21
|
-
router.back()
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// We create an object with the current stale properties
|
|
26
|
-
const overrideProps = {
|
|
27
|
-
asPath: router.asPath,
|
|
28
|
-
pathname: router.pathname,
|
|
29
|
-
query: router.query,
|
|
30
|
-
locale: router.locale,
|
|
31
|
-
go,
|
|
32
|
-
...override,
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return new Proxy<RouterProxy>(router as RouterProxy, {
|
|
36
|
-
get: (target, prop: string, receiver) =>
|
|
37
|
-
overrideProps[prop] ?? Reflect.get(target, prop, receiver),
|
|
38
|
-
})
|
|
39
|
-
}
|
package/hooks/useGo.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useRouter } from 'next/router'
|
|
2
|
+
|
|
3
|
+
export function useGo(delta: number) {
|
|
4
|
+
const { push, back } = useRouter()
|
|
5
|
+
return () => {
|
|
6
|
+
if (delta >= 0) {
|
|
7
|
+
// console.error(`Called .go(${delta}), only negative numbers are allowed. Redirecting to home`)
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
9
|
+
// push('/', '/')
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const deltaAbs = Math.abs(delta)
|
|
14
|
+
for (let i = 0; i < deltaAbs; i++) back()
|
|
15
|
+
}
|
|
16
|
+
}
|
package/hooks/useHistoryLink.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useRouter } from 'next/router'
|
|
2
2
|
import { usePrevPageRouter } from './usePrevPageRouter'
|
|
3
3
|
|
|
4
4
|
export type UseHistoryLink = { href: string }
|
|
@@ -8,12 +8,13 @@ type ClickEvent = { preventDefault: () => void }
|
|
|
8
8
|
export function useHistoryLink(options: UseHistoryLink) {
|
|
9
9
|
const { href } = options
|
|
10
10
|
const prevRouter = usePrevPageRouter()
|
|
11
|
+
const router = useRouter()
|
|
11
12
|
|
|
12
13
|
const onClick =
|
|
13
14
|
href === prevRouter?.asPath
|
|
14
15
|
? (e: ClickEvent) => {
|
|
15
16
|
e.preventDefault()
|
|
16
|
-
|
|
17
|
+
router.back()
|
|
17
18
|
}
|
|
18
19
|
: undefined
|
|
19
20
|
|
|
@@ -22,7 +23,7 @@ export function useHistoryLink(options: UseHistoryLink) {
|
|
|
22
23
|
|
|
23
24
|
export function useHistoryGo(options: UseHistoryLink) {
|
|
24
25
|
const { onClick, href } = useHistoryLink(options)
|
|
25
|
-
const router =
|
|
26
|
+
const router = useRouter()
|
|
26
27
|
|
|
27
28
|
return () => {
|
|
28
29
|
if (onClick) onClick({ preventDefault: () => {} })
|
package/hooks/usePageRouter.ts
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { pageRouterContext } from '../context/pageRouterContext'
|
|
3
|
-
import { RouterProxy } from '../types'
|
|
1
|
+
import { useRouter } from 'next/router'
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* E.g.:
|
|
9
|
-
*
|
|
10
|
-
* `/my-regular-page`:
|
|
11
|
-
*
|
|
12
|
-
* - `useRouter().asPath === '/overlay'`
|
|
13
|
-
* - `usePageRouter().asPath === '/my-regular-page'` We maintain the state
|
|
14
|
-
*
|
|
15
|
-
* `/overlay`:
|
|
16
|
-
*
|
|
17
|
-
* - `useRouter().asPath === '/overlay'`
|
|
18
|
-
* - `usePageRouter().asPath === '/overlay'`
|
|
19
|
-
*
|
|
20
|
-
* Adds an additional method: usePageRouter().go(-1)
|
|
21
|
-
*/
|
|
22
|
-
export function usePageRouter(): RouterProxy {
|
|
23
|
-
return useContext(pageRouterContext).currentRouter
|
|
3
|
+
export const usePageRouter = () => {
|
|
4
|
+
console.warn('usePageRouter does nothing, use next/router useRouter instead')
|
|
5
|
+
return useRouter()
|
|
24
6
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { useContext } from 'react'
|
|
2
2
|
import { pageRouterContext } from '../context/pageRouterContext'
|
|
3
|
-
import { RouterProxy } from '../types'
|
|
4
3
|
|
|
5
|
-
/** Same as
|
|
6
|
-
export function usePrevPageRouter()
|
|
7
|
-
return useContext(pageRouterContext).
|
|
4
|
+
/** Same as useRouter but gives back the router of the previous page. */
|
|
5
|
+
export function usePrevPageRouter() {
|
|
6
|
+
return useContext(pageRouterContext).prevPage?.pageInfo
|
|
8
7
|
}
|
package/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './context/pageContext'
|
|
|
4
4
|
export * from './context/pageRouterContext'
|
|
5
5
|
export type { PageOptions, PageComponent } from './types'
|
|
6
6
|
|
|
7
|
+
export * from './hooks/useGo'
|
|
7
8
|
export * from './hooks/usePageContext'
|
|
8
9
|
export * from './hooks/usePageRouter'
|
|
9
10
|
export * from './hooks/useHistoryLink'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphcommerce/framer-next-pages",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.109.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "tsc -W"
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@graphcommerce/framer-utils": "^2.103.
|
|
19
|
+
"@graphcommerce/framer-utils": "^2.103.21"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@graphcommerce/browserslist-config-pwa": "^3.0.3",
|
|
23
|
-
"@graphcommerce/eslint-config-pwa": "^3.1.
|
|
23
|
+
"@graphcommerce/eslint-config-pwa": "^3.1.10",
|
|
24
24
|
"@graphcommerce/prettier-config-pwa": "^3.0.5",
|
|
25
25
|
"@graphcommerce/typescript-config-pwa": "^3.1.2",
|
|
26
26
|
"@playwright/test": "^1.17.1"
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"react": "^17.0.2",
|
|
32
32
|
"react-dom": "^17.0.2"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "bc5423d7547f8685db4cd8fc6d8f7a2a51ebed05"
|
|
35
35
|
}
|
package/types.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { NextComponentType, NextPageContext } from 'next'
|
|
|
2
2
|
import { NextRouter } from 'next/router'
|
|
3
3
|
import React from 'react'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
type PageInfo = Pick<NextRouter, 'asPath' | 'query' | 'locale' | 'pathname'>
|
|
6
6
|
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export type PageContext = {
|
|
8
|
+
pageInfo: PageInfo
|
|
9
|
+
prevPage?: PageContext
|
|
10
10
|
up?: UpPage
|
|
11
11
|
prevUp?: UpPage
|
|
12
12
|
}
|
|
@@ -111,7 +111,7 @@ export type PageOptions<T extends Record<string, unknown> = Record<string, unkno
|
|
|
111
111
|
* }
|
|
112
112
|
* ```
|
|
113
113
|
*/
|
|
114
|
-
sharedKey?: (
|
|
114
|
+
sharedKey?: (pageInfo: PageInfo) => string | undefined
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
117
|
* Create a Layout to share a wrapping component between multiple routes.
|
|
@@ -124,7 +124,7 @@ export type PageOptions<T extends Record<string, unknown> = Record<string, unkno
|
|
|
124
124
|
/** Pass props to the SharedComponent */
|
|
125
125
|
layoutProps?: Partial<Omit<T, 'children'>>
|
|
126
126
|
|
|
127
|
-
up?: UpPage
|
|
127
|
+
up?: UpPage | null
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
export type PageComponent<T = Record<string, unknown>> = NextComponentType<NextPageContext, T> & {
|
|
@@ -140,10 +140,10 @@ export type UpPage = { href: string; title: string }
|
|
|
140
140
|
* @private
|
|
141
141
|
*/
|
|
142
142
|
export type PageItem = {
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
routerOverride?: Partial<NextRouter>
|
|
144
|
+
PageComponent: PageComponent
|
|
145
145
|
historyIdx: number
|
|
146
146
|
sharedKey: string
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
} & Omit<PageOptions<Record<string, unknown>>, 'sharedKey'>
|
|
147
|
+
pageProps?: Record<string, unknown>
|
|
148
|
+
routerContext: PageContext
|
|
149
|
+
} & Omit<PageOptions<Record<string, unknown>>, 'sharedKey' | 'up'>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NextRouter } from 'next/router'
|
|
2
|
+
|
|
3
|
+
export type OverrideProps = Partial<Pick<NextRouter, 'asPath' | 'pathname' | 'query' | 'locale'>>
|
|
4
|
+
|
|
5
|
+
export function createRouterProxy(router: NextRouter, override?: OverrideProps): NextRouter {
|
|
6
|
+
// We create an object with the current stale properties
|
|
7
|
+
const { asPath, pathname, query, locale } = router
|
|
8
|
+
|
|
9
|
+
const overrideProps: OverrideProps = { asPath, pathname, query, locale, ...override }
|
|
10
|
+
|
|
11
|
+
return new Proxy<NextRouter>(router, {
|
|
12
|
+
get: (target, prop: string, receiver) =>
|
|
13
|
+
overrideProps[prop] ?? Reflect.get(target, prop, receiver),
|
|
14
|
+
})
|
|
15
|
+
}
|