@graphcommerce/next-ui 4.15.0 → 4.17.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 CHANGED
@@ -1,5 +1,38 @@
1
1
  # Change Log
2
2
 
3
+ ## 4.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1583](https://github.com/graphcommerce-org/graphcommerce/pull/1583) [`b6ce5548c`](https://github.com/graphcommerce-org/graphcommerce/commit/b6ce5548c66a8ca62d3aee29467045f7f07f30c8) Thanks [@ErwinOtten](https://github.com/ErwinOtten)! - Navigation fixes
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies []:
12
+ - @graphcommerce/framer-scroller@2.1.28
13
+
14
+ ## 4.16.0
15
+
16
+ ### Minor Changes
17
+
18
+ - [#1573](https://github.com/graphcommerce-org/graphcommerce/pull/1573) [`1eb131766`](https://github.com/graphcommerce-org/graphcommerce/commit/1eb131766c32db6fcb0a8e83dba2c3d241658595) Thanks [@paales](https://github.com/paales)! - Solve issue where the products query would return multiple products while requesting a single url_key. Filter the result by findByTypename which finds the correct `typename` but also narrows the typescript type.
19
+
20
+ ### Patch Changes
21
+
22
+ - [#1573](https://github.com/graphcommerce-org/graphcommerce/pull/1573) [`87a188d6f`](https://github.com/graphcommerce-org/graphcommerce/commit/87a188d6f216b7f7b9ec95afbe74f1146cb07ce4) Thanks [@paales](https://github.com/paales)! - Sovle issue where changing images in the scroller causes issues rerendering
23
+
24
+ - Updated dependencies [[`87a188d6f`](https://github.com/graphcommerce-org/graphcommerce/commit/87a188d6f216b7f7b9ec95afbe74f1146cb07ce4)]:
25
+ - @graphcommerce/framer-scroller@2.1.27
26
+
27
+ ## 4.15.1
28
+
29
+ ### Patch Changes
30
+
31
+ - [#1570](https://github.com/graphcommerce-org/graphcommerce/pull/1570) [`a88f166f0`](https://github.com/graphcommerce-org/graphcommerce/commit/a88f166f0115c58254fe47171da51a5850658a32) Thanks [@paales](https://github.com/paales)! - Solve issue where chrome would report duplicate ids
32
+
33
+ - Updated dependencies []:
34
+ - @graphcommerce/framer-scroller@2.1.26
35
+
3
36
  ## 4.15.0
4
37
 
5
38
  ### Minor Changes
@@ -211,7 +211,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
211
211
  ))}
212
212
  </Scroller>
213
213
  <MotionBox
214
- layout
214
+ layout='position'
215
215
  layoutDependency={zoomed}
216
216
  className={classes.topRight}
217
217
  sx={{
@@ -293,7 +293,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
293
293
  }}
294
294
  >
295
295
  <ScrollerDots
296
- layout
296
+ layout='position'
297
297
  layoutDependency={zoomed}
298
298
  sx={{ backgroundColor: 'background.paper', boxShadow: 6 }}
299
299
  />
@@ -328,7 +328,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
328
328
  ]}
329
329
  >
330
330
  <MotionBox
331
- layout
331
+ layout='position'
332
332
  layoutDependency={zoomed}
333
333
  className={classes.sidebar}
334
334
  sx={{
package/JsonLd/JsonLd.tsx CHANGED
@@ -1,19 +1,21 @@
1
1
  import Head from 'next/head'
2
- import { jsonLdScriptProps } from 'react-schemaorg'
3
- import { Thing, WithContext } from 'schema-dts'
2
+ import { safeJsonLdReplacer } from './safeJsonLdReplacer'
4
3
 
5
4
  export * as SchemaDts from 'schema-dts'
6
5
 
7
- export type JsonLdProps<T extends Thing> = {
8
- item: WithContext<T>
9
- }
10
-
11
- export function JsonLd<T extends Thing>(props: JsonLdProps<T>) {
6
+ export function JsonLd<T extends { '@type': string }>(props: {
7
+ item: T & { '@context': 'https://schema.org' }
8
+ }) {
12
9
  const { item } = props
13
10
 
14
11
  return (
15
12
  <Head>
16
- <script key='jsonld' {...jsonLdScriptProps<T>(item)} />
13
+ <script
14
+ key='jsonld'
15
+ type='application/ld+json'
16
+ // eslint-disable-next-line react/no-danger
17
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(item, safeJsonLdReplacer) }}
18
+ />
17
19
  </Head>
18
20
  )
19
21
  }
@@ -0,0 +1,47 @@
1
+ type JsonValueScalar = string | boolean | number
2
+ type JsonValue = JsonValueScalar | Array<JsonValue> | { [key: string]: JsonValue }
3
+ type JsonReplacer = (_: string, value: JsonValue) => JsonValue | undefined
4
+
5
+ const ESCAPE_ENTITIES = Object.freeze({
6
+ '&': '&amp;',
7
+ '<': '&lt;',
8
+ '>': '&gt;',
9
+ '"': '&quot;',
10
+ "'": '&apos;',
11
+ })
12
+ const ESCAPE_REGEX = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join('')}]`, 'g')
13
+ const ESCAPE_REPLACER = (t: string): string => ESCAPE_ENTITIES[t as keyof typeof ESCAPE_ENTITIES]
14
+
15
+ // Utility: Assert never
16
+ function isNever(_: never): void {}
17
+
18
+ /**
19
+ * A replacer for JSON.stringify to strip JSON-LD of illegal HTML entities per
20
+ * https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements
21
+ */
22
+ export const safeJsonLdReplacer: JsonReplacer = (
23
+ () =>
24
+ // Replace per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements
25
+ // Solution from https://stackoverflow.com/a/5499821/864313
26
+ (_: string, value: JsonValue): JsonValue | undefined => {
27
+ switch (typeof value) {
28
+ case 'object':
29
+ // Omit null values.
30
+ if (value === null) return undefined
31
+ return value // JSON.stringify will recursively call replacer.
32
+ case 'number':
33
+ case 'boolean':
34
+ case 'bigint':
35
+ return value // These values are not risky.
36
+ case 'string':
37
+ return value.replace(ESCAPE_REGEX, ESCAPE_REPLACER)
38
+ default: {
39
+ // We shouldn't expect other types.
40
+ isNever(value)
41
+
42
+ // JSON.stringify will remove this element.
43
+ return undefined
44
+ }
45
+ }
46
+ }
47
+ )()
@@ -102,7 +102,7 @@ export function NavigationItem(props: NavigationItemProps) {
102
102
  select(itemPath)
103
103
  }
104
104
  }}
105
- onMouseEnter={
105
+ onMouseMove={
106
106
  itemPath.length > 1 && mouseEvent === 'hover'
107
107
  ? (e) => {
108
108
  if (isDesktop && animating.current === false && !isSelected) {
@@ -3,7 +3,7 @@ import { i18n } from '@lingui/core'
3
3
  import { Trans } from '@lingui/react'
4
4
  import { Box, Fab, SxProps, Theme, useEventCallback, useMediaQuery } from '@mui/material'
5
5
  import { m } from 'framer-motion'
6
- import { useState } from 'react'
6
+ import { useEffect, useState } from 'react'
7
7
  import { IconSvg, useIconSvgSize } from '../../IconSvg'
8
8
  import { LayoutHeaderContent } from '../../Layout/components/LayoutHeaderContent'
9
9
  import { LayoutTitle } from '../../Layout/components/LayoutTitle'
@@ -93,6 +93,10 @@ export function NavigationOverlay(props: NavigationOverlayProps) {
93
93
  else select([])
94
94
  })
95
95
 
96
+ useEffect(() => {
97
+ animating.current = false
98
+ }, [active, animating])
99
+
96
100
  const showBack = selected.length > 0
97
101
 
98
102
  return (
@@ -38,3 +38,10 @@ export function RenderType<
38
38
 
39
39
  return <TypeItem {...typeItemProps} __typename={__typename} />
40
40
  }
41
+
42
+ export function findByTypename<T extends TypeObject, Typename extends T['__typename']>(
43
+ type: (T | undefined | null)[] | undefined | null,
44
+ typename: Typename,
45
+ ): FilterTypeByTypename<T, Typename> {
46
+ return type?.find((item) => item?.__typename === typename) as FilterTypeByTypename<T, Typename>
47
+ }
@@ -0,0 +1,20 @@
1
+ import type { OptionalKeysOf, Simplify } from 'type-fest'
2
+
3
+ export function filterNonNullableKeys<
4
+ T extends Record<string, unknown>,
5
+ Keys extends OptionalKeysOf<T>,
6
+ >(items: (T | null | undefined)[] | null | undefined, values: Keys[]) {
7
+ if (!items) return []
8
+
9
+ type ResultWithRequired = Simplify<
10
+ Omit<T, Keys> & {
11
+ [K in Keys]: NonNullable<T[K]>
12
+ }
13
+ >
14
+
15
+ const result = items.filter(
16
+ (item) => item !== null && typeof item !== 'undefined' && values.every((v) => item?.[v]),
17
+ )
18
+
19
+ return result as ResultWithRequired[]
20
+ }
@@ -0,0 +1,3 @@
1
+ export * from './nonNullable'
2
+ export * from './filterNonNullableKeys'
3
+ export * from './RenderType'
@@ -0,0 +1,3 @@
1
+ export function nonNullable<T>(value: T): value is NonNullable<T> {
2
+ return value !== null && value !== undefined
3
+ }
@@ -100,7 +100,6 @@ export function TextInputNumber(props: TextInputNumberProps) {
100
100
  ...(Array.isArray(sx) ? sx : [sx]),
101
101
  ]}
102
102
  autoComplete='off'
103
- id='quantity-input'
104
103
  InputProps={{
105
104
  ...textFieldProps.InputProps,
106
105
  startAdornment: (
package/index.ts CHANGED
@@ -38,7 +38,7 @@ export * from './Page'
38
38
  export * from './PageLoadIndicator/PageLoadIndicator'
39
39
  export * from './PageMeta/PageMeta'
40
40
  export * from './Pagination/Pagination'
41
- export * from './RenderType/RenderType'
41
+ export * from './RenderType'
42
42
  export * from './Row'
43
43
  export * from './SectionContainer/SectionContainer'
44
44
  export * from './SectionHeader/SectionHeader'
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": "4.15.0",
5
+ "version": "4.17.0",
6
6
  "author": "",
7
7
  "license": "MIT",
8
8
  "sideEffects": false,
@@ -20,12 +20,11 @@
20
20
  "@emotion/server": "^11.4.0",
21
21
  "@emotion/styled": "^11.9.3",
22
22
  "@graphcommerce/framer-next-pages": "3.2.4",
23
- "@graphcommerce/framer-scroller": "2.1.25",
23
+ "@graphcommerce/framer-scroller": "2.1.28",
24
24
  "@graphcommerce/framer-utils": "3.1.4",
25
25
  "@graphcommerce/image": "3.1.7",
26
26
  "cookie": "^0.5.0",
27
27
  "react-is": "^18.2.0",
28
- "react-schemaorg": "^2.0.0",
29
28
  "schema-dts": "^1.1.0"
30
29
  },
31
30
  "peerDependencies": {