@graphcommerce/next-ui 8.0.6-canary.3 → 8.1.0-canary.10

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,29 @@
1
1
  # Change Log
2
2
 
3
+ ## 8.1.0-canary.10
4
+
5
+ ## 8.1.0-canary.9
6
+
7
+ ### Patch Changes
8
+
9
+ - [#2223](https://github.com/graphcommerce-org/graphcommerce/pull/2223) [`d7459fe`](https://github.com/graphcommerce-org/graphcommerce/commit/d7459feb6e6902af09ab9ff766c0b3b1a74fb723) - Updated canonicalize helper for better multi domain support
10
+ ([@bramvanderholst](https://github.com/bramvanderholst))
11
+
12
+ ## 8.1.0-canary.8
13
+
14
+ ### Patch Changes
15
+
16
+ - [#2247](https://github.com/graphcommerce-org/graphcommerce/pull/2247) [`444e446`](https://github.com/graphcommerce-org/graphcommerce/commit/444e446a218cc9da3defb940a6d5cce0229ff845) - Added clear upgrade instructions for linguiLocale
17
+ ([@paales](https://github.com/paales))
18
+
19
+ ## 8.1.0-canary.7
20
+
21
+ ## 8.1.0-canary.6
22
+
23
+ ## 8.1.0-canary.5
24
+
25
+ ## 8.0.6-canary.4
26
+
3
27
  ## 8.0.6-canary.3
4
28
 
5
29
  ## 8.0.6-canary.2
@@ -249,7 +249,7 @@ export function OverlayBase(incomingProps: LayoutOverlayBaseProps) {
249
249
  const cancelY = scroll.y.on('change', handleScroll)
250
250
 
251
251
  const ro = new ResizeObserver(handleResize)
252
- ro.observe(scrollerRef.current)
252
+ if (scrollerRef.current) ro.observe(scrollerRef.current)
253
253
  ro.observe(beforeRef.current)
254
254
  ro.observe(overlayPaneRef.current)
255
255
  ro.observe(overlayRef.current)
@@ -70,11 +70,16 @@ export function canonicalize(router: PartialNextRouter, incoming?: Canonical) {
70
70
  if (localeDomain) {
71
71
  canonical = localeDomain
72
72
  } else {
73
- href = addBasePath(addLocale(as, curLocale, router.defaultLocale))
73
+ const conf = storefrontConfig(router.locale)
74
+
75
+ href = addBasePath(
76
+ addLocale(as, curLocale, conf?.domain ? conf.locale : router.defaultLocale),
77
+ )
78
+
79
+ let siteUrl = conf?.canonicalBaseUrl || import.meta.graphCommerce.canonicalBaseUrl
80
+
81
+ if (conf?.domain && !conf?.canonicalBaseUrl) siteUrl = `https://${conf.domain}`
74
82
 
75
- let siteUrl =
76
- storefrontConfig(router.locale)?.canonicalBaseUrl ||
77
- import.meta.graphCommerce.canonicalBaseUrl
78
83
  if (siteUrl.endsWith('/')) siteUrl = siteUrl.slice(0, -1)
79
84
 
80
85
  canonical = `${siteUrl}${href}`
@@ -1,7 +1,5 @@
1
- import { normalizeLocale } from '@graphcommerce/lingui-next'
2
1
  import { useMemo } from 'react'
3
- import { useStorefrontConfig } from './useStorefrontConfig'
4
- import { useLocale } from '@graphcommerce/next-ui'
2
+ import { useLocale } from './useLocale'
5
3
 
6
4
  export type DateTimeFormatProps = Intl.DateTimeFormatOptions
7
5
 
@@ -1,5 +1,24 @@
1
1
  import { Breakpoint, useTheme } from '@mui/material'
2
- import { useMemo } from 'react'
2
+ import { useMotionValue } from 'framer-motion'
3
+ import { useEffect, useMemo } from 'react'
4
+
5
+ export function useMatchMediaMotionValue(
6
+ direction: 'up' | 'down',
7
+ breakpointKey: number | Breakpoint,
8
+ ) {
9
+ const matchValue = useMotionValue(false)
10
+ const theme = useTheme()
11
+ const query = theme.breakpoints[direction](breakpointKey).replace(/^@media( ?)/m, '')
12
+
13
+ useEffect(() => {
14
+ const mql = globalThis?.matchMedia(query)
15
+ const matcher = (e: MediaQueryListEvent) => matchValue.set(e.matches)
16
+ mql.addEventListener('change', matcher)
17
+ return () => mql.removeEventListener('change', matcher)
18
+ }, [matchValue, query])
19
+
20
+ return matchValue
21
+ }
3
22
 
4
23
  export function useMatchMedia() {
5
24
  const theme = useTheme()
package/index.ts CHANGED
@@ -59,3 +59,5 @@ export * from './UspList/UspListItem'
59
59
  export * from './hooks'
60
60
  export * from './icons'
61
61
  export * from './utils/cookie'
62
+ export * from './utils/sitemap'
63
+ export * from './utils/robots'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/next-ui",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "8.0.6-canary.3",
5
+ "version": "8.1.0-canary.10",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -17,6 +17,7 @@
17
17
  "@emotion/server": "^11.11.0",
18
18
  "@emotion/styled": "^11.11.0",
19
19
  "cookie": "^0.6.0",
20
+ "next-sitemap": "4.2.3",
20
21
  "react-is": "^18.2.0"
21
22
  },
22
23
  "devDependencies": {
@@ -25,14 +26,14 @@
25
26
  "typescript": "5.3.3"
26
27
  },
27
28
  "peerDependencies": {
28
- "@graphcommerce/eslint-config-pwa": "^8.0.6-canary.3",
29
- "@graphcommerce/framer-next-pages": "^8.0.6-canary.3",
30
- "@graphcommerce/framer-scroller": "^8.0.6-canary.3",
31
- "@graphcommerce/framer-utils": "^8.0.6-canary.3",
32
- "@graphcommerce/image": "^8.0.6-canary.3",
33
- "@graphcommerce/lingui-next": "^8.0.6-canary.3",
34
- "@graphcommerce/prettier-config-pwa": "^8.0.6-canary.3",
35
- "@graphcommerce/typescript-config-pwa": "^8.0.6-canary.3",
29
+ "@graphcommerce/eslint-config-pwa": "^8.1.0-canary.10",
30
+ "@graphcommerce/framer-next-pages": "^8.1.0-canary.10",
31
+ "@graphcommerce/framer-scroller": "^8.1.0-canary.10",
32
+ "@graphcommerce/framer-utils": "^8.1.0-canary.10",
33
+ "@graphcommerce/image": "^8.1.0-canary.10",
34
+ "@graphcommerce/lingui-next": "^8.1.0-canary.10",
35
+ "@graphcommerce/prettier-config-pwa": "^8.1.0-canary.10",
36
+ "@graphcommerce/typescript-config-pwa": "^8.1.0-canary.10",
36
37
  "@lingui/core": "^4.2.1",
37
38
  "@lingui/macro": "^4.2.1",
38
39
  "@lingui/react": "^4.2.1",
@@ -0,0 +1,41 @@
1
+ import { GetServerSidePropsContext } from 'next'
2
+
3
+ type Stringifyable = boolean | string | number | null | undefined
4
+
5
+ /**
6
+ * Tagged template literal for robots.txt that will automatically stringify values and indent them correctly.
7
+ * https://developers.google.com/search/docs/crawling-indexing/robots/robots_txt#syntax
8
+ */
9
+ export function robotsTxt(strings: TemplateStringsArray, ...values: Stringifyable[]) {
10
+ return strings
11
+ .reduce((acc, str, i) => {
12
+ let value = values[i]
13
+
14
+ if (Array.isArray(value)) {
15
+ const [conditional, val] = value
16
+ value = conditional ? val : null
17
+ }
18
+ if (!value) value = ''
19
+ if (typeof value === 'boolean') value = value ? 'true' : 'false'
20
+ if (typeof value === 'number') value = String(value)
21
+
22
+ return acc + str + value
23
+ }, '')
24
+ .split('\n')
25
+ .map((v) => v.trim())
26
+ .join('\n')
27
+ .trim()
28
+ }
29
+
30
+ // eslint-disable-next-line @typescript-eslint/require-await
31
+ export async function getServerSidePropsRobotsTxt(
32
+ context: GetServerSidePropsContext,
33
+ robots: string,
34
+ ) {
35
+ context.res.setHeader('Content-Type', 'text/plain')
36
+ context.res.write(robots)
37
+ context.res.end()
38
+ context.res.setHeader('Cache-Control', `public, s-maxage=${60 * 60 * 2}`)
39
+
40
+ return { props: {} }
41
+ }
@@ -0,0 +1,47 @@
1
+ import { GetServerSidePropsContext, GetStaticPathsResult } from 'next'
2
+ import { getServerSideSitemapLegacy, ISitemapField } from 'next-sitemap'
3
+ import { canonicalize } from '../PageMeta/PageMeta'
4
+
5
+ export function excludeSitemap(excludes: string[]) {
6
+ const regexp = excludes.map((exclude) => new RegExp(exclude.replace(/\*/g, '.*?')))
7
+
8
+ return (path: string) => !regexp.some((pattern) => pattern.test(`/${path}`))
9
+ }
10
+
11
+ export function staticPathsToString(
12
+ path: GetStaticPathsResult<{ url: string[] | string }>['paths'][0],
13
+ ) {
14
+ if (typeof path === 'string') return path
15
+ if (typeof path.params.url === 'string') return path.params.url
16
+ return path.params.url.join('/')
17
+ }
18
+
19
+ export function toSitemapFields(
20
+ context: GetServerSidePropsContext,
21
+ paths: string[],
22
+ ): ISitemapField[] {
23
+ const lastmod = new Date().toISOString()
24
+ const options = {
25
+ locale: context.locale,
26
+ defaultLocale: context.defaultLocale,
27
+ pathname: '/',
28
+ isLocaleDomain: false,
29
+ }
30
+
31
+ const sitemapPaths = paths.map<ISitemapField>((path) => ({
32
+ loc: canonicalize(options, `/${path}`) ?? '',
33
+ lastmod,
34
+ changefreq: 'daily',
35
+ priority: 0.7,
36
+ }))
37
+
38
+ return sitemapPaths
39
+ }
40
+
41
+ export function getServerSidePropsSitemap(
42
+ context: GetServerSidePropsContext,
43
+ paths: ISitemapField[],
44
+ ) {
45
+ context.res.setHeader('Cache-Control', `public, s-maxage=${60 * 60 * 2}`)
46
+ return getServerSideSitemapLegacy(context, paths)
47
+ }