@graphcommerce/next-ui 9.1.0-canary.55 → 10.0.0-canary.57

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.
@@ -1,4 +1,4 @@
1
- import { Trans } from '@lingui/react'
1
+ import { Trans } from '@lingui/react/macro'
2
2
  import type { SxProps, Theme } from '@mui/material'
3
3
  import { Alert } from '@mui/material'
4
4
  import React from 'react'
@@ -168,7 +168,7 @@ export const ActionCardList = React.forwardRef<HTMLDivElement, ActionCardListPro
168
168
  variant='text'
169
169
  onClick={() => setShow(!show)}
170
170
  >
171
- {!show ? <Trans id='More options' /> : <Trans id='Less options' />}{' '}
171
+ {!show ? <Trans>More options</Trans> : <Trans>Less options</Trans>}{' '}
172
172
  <IconSvg
173
173
  sx={{
174
174
  transform: show ? 'rotate(180deg)' : 'rotate(0deg)',
@@ -1,5 +1,5 @@
1
- import { i18n } from '@lingui/core'
2
- import { Trans } from '@lingui/react'
1
+ import { t } from '@lingui/core/macro'
2
+ import { Trans } from '@lingui/react/macro'
3
3
  import type {
4
4
  LinkProps,
5
5
  BreadcrumbsProps as MuiBreadcrumbProps,
@@ -71,7 +71,7 @@ export function Breadcrumbs(props: BreadcrumbsProps) {
71
71
  return (
72
72
  <MuiBreadcrumbs
73
73
  {...rest}
74
- aria-label={i18n._(/* i18n*/ 'Breadcrumbs')}
74
+ aria-label={t`Breadcrumbs`}
75
75
  maxItems={maxItems}
76
76
  color='inherit'
77
77
  sx={[
@@ -167,7 +167,7 @@ export function Breadcrumbs(props: BreadcrumbsProps) {
167
167
  {...linkProps}
168
168
  sx={[...(Array.isArray(itemSx) ? itemSx : [itemSx])]}
169
169
  >
170
- <Trans id='Home' />
170
+ <Trans>Home</Trans>
171
171
  </Link>
172
172
  )}
173
173
  {breadcrumbLinks.map((breadcrumb) => (
@@ -1,4 +1,4 @@
1
- import { Trans } from '@lingui/react'
1
+ import { Trans } from '@lingui/react/macro'
2
2
  import { alpha, Box, Link, useTheme } from '@mui/material'
3
3
  import type { KeyboardEvent } from 'react'
4
4
  import { useEffect, useRef } from 'react'
@@ -74,7 +74,7 @@ export function BreadcrumbsList(props: PopperBreadcrumbsListProps) {
74
74
  },
75
75
  }}
76
76
  >
77
- <Trans id='Home' />
77
+ <Trans>Home</Trans>
78
78
  </Link>
79
79
  {breadcrumbs.slice(0, breadcrumbs.length).map((breadcrumb) => (
80
80
  <Link
package/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # Change Log
2
2
 
3
+ ## 10.0.0-canary.57
4
+
5
+ ## 10.0.0-canary.56
6
+
7
+ ### Major Changes
8
+
9
+ - [#2546](https://github.com/graphcommerce-org/graphcommerce/pull/2546) [`ed9332a`](https://github.com/graphcommerce-org/graphcommerce/commit/ed9332a7f78966d932041d9a7725641edc92b28d) - ## GraphCommerce 10 - Turbopack Support
10
+
11
+ This major release brings full Turbopack compatibility, dramatically improving development speed.
12
+
13
+ ### 🚀 Turbopack-Compatible Interceptor System
14
+
15
+ The entire plugin/interceptor system has been rewritten to work with Turbopack:
16
+
17
+ - **No more Webpack plugins** - Removed `InterceptorPlugin` webpack plugin entirely
18
+ - **File-based interception** - Original files are moved to `.original.tsx` and replaced with interceptor content
19
+ - **Direct imports** - Interceptors import from `.original` files instead of embedding source
20
+ - **New CLI commands**:
21
+ - `graphcommerce codegen-interceptors` - Generate interceptor files
22
+ - `graphcommerce cleanup-interceptors` - Reset interceptor system, restore original files
23
+ - **Stable file hashing** - Deterministic interceptor generation for better caching
24
+
25
+ ### ⚙️ Treeshakable Configuration System
26
+
27
+ Replaced Webpack `DefinePlugin`-based `import.meta.graphCommerce` with a new generated configuration system:
28
+
29
+ - **New `codegen-config-values` command** - Generates TypeScript files with precise typing
30
+ - **Schema-driven** - Dynamically introspects Zod schemas to determine all available properties
31
+ - **Fully treeshakable** - Unused config values are eliminated from the bundle
32
+ - **Type-safe** - Uses `Get<GraphCommerceConfig, 'path'>` for nested property access
33
+ - **Separate files for nested objects** - Optimal treeshaking for complex configurations
34
+
35
+ ### 🔧 withGraphCommerce Changes
36
+
37
+ - **Removed** `InterceptorPlugin` - No longer needed with file-based interception
38
+ - **Removed** `DefinePlugin` for `import.meta.graphCommerce` - Replaced with generated config
39
+ - **Removed** `@mui/*` alias rewrites - No longer required
40
+ - **Added** Turbopack loader rules for `.yaml`, `.yml`, and `.po` files
41
+ - **Added** `serverExternalPackages` for all `@whatwg-node/*` packages
42
+ - **Added** `optimizePackageImports` for better bundle optimization
43
+ - **Added** `images.qualities: [52, 75]` for Next.js image optimization
44
+
45
+ ### 📦 Lingui Configuration
46
+
47
+ - **Renamed** `lingui.config.js` → `lingui.config.ts` with TypeScript support
48
+ - **Updated** `@graphcommerce/lingui-next/config` to TypeScript with proper exports
49
+ - **Simplified** formatter options
50
+
51
+ ### ⚛️ React 19 & Next.js 16 Compatibility
52
+
53
+ - Updated `RefObject<T>` types for React 19 (now includes `null` by default)
54
+ - Replaced deprecated `React.VFC` with `React.FC`
55
+ - Fixed `useRef` calls to require explicit initial values
56
+ - Updated `MutableRefObject` usage in `framer-scroller`
57
+
58
+ ### 📋 ESLint 9 Flat Config
59
+
60
+ - Migrated from legacy `.eslintrc` to new flat config format (`eslint.config.mjs`)
61
+ - Updated `@typescript-eslint/*` packages to v8
62
+ - Fixed AST selector for `SxProps` rule (`typeParameters` → `typeArguments`)
63
+
64
+ ### 🔄 Apollo Client
65
+
66
+ - Fixed deprecated `name` option → `clientAwareness: { name: 'ssr' }`
67
+ - Updated error handling types to accept `ApolloError | null | undefined`
68
+
69
+ ### ⚠️ Breaking Changes
70
+
71
+ - **Node.js 24.x not supported** - Restricted to `>=20 <24.0.0` due to [nodejs/undici#4290](https://github.com/nodejs/undici/issues/4290)
72
+ - **Interceptor files changed** - Original components now at `.original.tsx`
73
+ - **Config access changed** - Use generated config values instead of `import.meta.graphCommerce`
74
+ - **ESLint config format** - Must use flat config (`eslint.config.mjs`)
75
+ - **Lingui config** - Rename `lingui.config.js` to `lingui.config.ts`
76
+
77
+ ### 🗑️ Removed
78
+
79
+ - `InterceptorPlugin` webpack plugin
80
+ - `configToImportMeta` utility
81
+ - Webpack `DefinePlugin` usage for config
82
+ - `@mui/*` modern alias rewrites
83
+ - Debug plugins (`CircularDependencyPlugin`, `DuplicatesPlugin`) ([@paales](https://github.com/paales))
84
+
3
85
  ## 9.1.0-canary.55
4
86
 
5
87
  ### Patch Changes
@@ -10,6 +10,7 @@ import {
10
10
  unstable_usePreventScroll as usePreventScroll,
11
11
  } from '@graphcommerce/framer-scroller'
12
12
  import { dvh } from '@graphcommerce/framer-utils'
13
+ import { sidebarGallery } from '@graphcommerce/next-config/config'
13
14
  import type { SxProps, Theme } from '@mui/material'
14
15
  import { Box, Fab, styled, Unstable_TrapFocus as TrapFocus, useTheme } from '@mui/material'
15
16
  import { m, useDomEvent, useMotionValue } from 'framer-motion'
@@ -350,8 +351,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
350
351
  },
351
352
  }}
352
353
  >
353
- {import.meta.graphCommerce.sidebarGallery?.paginationVariant ===
354
- 'THUMBNAILS_BOTTOM' ? (
354
+ {sidebarGallery?.paginationVariant === 'THUMBNAILS_BOTTOM' ? (
355
355
  <ScrollerThumbnails layoutDependency={zoomed} images={images} />
356
356
  ) : (
357
357
  <ScrollerDots layout />
@@ -4,7 +4,7 @@ import {
4
4
  usePrevUp,
5
5
  useUp,
6
6
  } from '@graphcommerce/framer-next-pages'
7
- import { i18n } from '@lingui/core'
7
+ import { t } from '@lingui/core/macro'
8
8
  import type { SxProps, Theme } from '@mui/material'
9
9
  import { Box } from '@mui/material'
10
10
  import { useRouter } from 'next/router'
@@ -55,7 +55,7 @@ export function LayoutHeaderBack(props: BackProps) {
55
55
  const backIcon = <IconSvg src={iconChevronLeft} size='medium' />
56
56
  const canClickBack = backSteps > 0 && path !== prevUp?.href && !disableBackNavigation
57
57
 
58
- let label = i18n._(/* i18n */ 'Back')
58
+ let label = t`Back`
59
59
  if (up?.href === path && up?.title) label = up.title
60
60
  if (prevUp?.href === path && prevUp?.title) label = prevUp.title
61
61
 
@@ -1,5 +1,5 @@
1
1
  import { useGo, usePageContext } from '@graphcommerce/framer-next-pages'
2
- import { i18n } from '@lingui/core'
2
+ import { t } from '@lingui/core/macro'
3
3
  import { Fab, type ButtonProps } from '@mui/material'
4
4
  import { useState } from 'react'
5
5
  import { Button } from '../../Button'
@@ -43,7 +43,7 @@ export function LayoutHeaderClose(props: LayoutHeaderCloseProps) {
43
43
  }}
44
44
  size={size}
45
45
  disabled={disabled}
46
- aria-label={i18n._(/* i18n */ 'Close')}
46
+ aria-label={t`Close`}
47
47
  >
48
48
  <IconSvg src={iconClose} size='large' />
49
49
  </Fab>
@@ -39,8 +39,8 @@ export const NavigationList = React.memo<NavigationItemsProps>((props) => {
39
39
  {items.map((item, idx) => (
40
40
  <NavigationItem
41
41
  NavigationList={NavigationList}
42
- key={item.id}
43
42
  {...item}
43
+ key={item.id ?? idx}
44
44
  parentPath={parentPath}
45
45
  idx={idx}
46
46
  first={idx === 0}
@@ -1,5 +1,5 @@
1
1
  import { dvw, useMotionSelector, useMotionValueValue } from '@graphcommerce/framer-utils'
2
- import { i18n } from '@lingui/core'
2
+ import { t } from '@lingui/core/macro'
3
3
  import type { SxProps, Theme } from '@mui/material'
4
4
  import { Box, Fab, styled, useEventCallback, useTheme } from '@mui/material'
5
5
  import { m } from 'framer-motion'
@@ -160,7 +160,7 @@ export const NavigationOverlay = React.memo((props: NavigationOverlayProps) => {
160
160
  onClick={handleOnBack}
161
161
  sx={{ boxShadow: 'none', my: fabMarginY }}
162
162
  size='responsive'
163
- aria-label={i18n._(/* i18n */ 'Back')}
163
+ aria-label={t`Back`}
164
164
  >
165
165
  <IconSvg src={iconChevronLeft} size='large' aria-hidden />
166
166
  </Fab>
@@ -173,7 +173,7 @@ export const NavigationOverlay = React.memo((props: NavigationOverlayProps) => {
173
173
  onClick={handleClose}
174
174
  sx={{ boxShadow: 'none', my: fabMarginY }}
175
175
  size='responsive'
176
- aria-label={i18n._(/* i18n */ 'Close')}
176
+ aria-label={t`Close`}
177
177
  ref={a11yFocusRef}
178
178
  >
179
179
  <IconSvg src={iconClose} size='large' aria-hidden />
@@ -1,5 +1,5 @@
1
1
  import { useMotionValueValue } from '@graphcommerce/framer-utils'
2
- import { Trans } from '@lingui/react'
2
+ import { Trans } from '@lingui/react/macro'
3
3
  import type {
4
4
  NavigationNodeButton,
5
5
  NavigationNodeHref,
@@ -35,6 +35,6 @@ function findCurrent(
35
35
  export function NavigationTitle() {
36
36
  const { selection, items } = useNavigation()
37
37
  return (
38
- <>{useMotionValueValue(selection, (v) => findCurrent(items, v))?.name ?? <Trans id='Menu' />}</>
38
+ <>{useMotionValueValue(selection, (v) => findCurrent(items, v))?.name ?? <Trans>Menu</Trans>}</>
39
39
  )
40
40
  }
@@ -160,7 +160,7 @@ export function OverlayBase(incomingProps: LayoutOverlayBaseProps) {
160
160
  () => (match.up('md') ? variantMd : variantSm),
161
161
  [match, variantMd, variantSm],
162
162
  )
163
- const prevVariant = useRef<LayoutOverlayVariant>()
163
+ const prevVariant = useRef<LayoutOverlayVariant | null>(null)
164
164
 
165
165
  const openClosePositions = useCallback((): {
166
166
  open: [number, number]
@@ -418,7 +418,7 @@ export function OverlayBase(incomingProps: LayoutOverlayBaseProps) {
418
418
  return (
419
419
  <>
420
420
  <MotionDiv
421
- inert={active ? undefined : ('true' as unknown as boolean)}
421
+ inert={active}
422
422
  className={classes.backdrop}
423
423
  style={{ opacity: positions.open.visible }}
424
424
  sx={[
@@ -440,7 +440,7 @@ export function OverlayBase(incomingProps: LayoutOverlayBaseProps) {
440
440
  ]}
441
441
  />
442
442
  <Scroller
443
- inert={disableInert || active ? undefined : ('true' as unknown as boolean)}
443
+ inert={disableInert || active ? false : true}
444
444
  className={`${classes.scroller} ${className ?? ''}`}
445
445
  grid={false}
446
446
  onClick={onClickAway}
@@ -1,5 +1,5 @@
1
1
  import { useGo, usePageContext } from '@graphcommerce/framer-next-pages'
2
- import { i18n } from '@lingui/core'
2
+ import { t } from '@lingui/core/macro'
3
3
  import { useState } from 'react'
4
4
  import { Button, type ButtonProps } from '../../Button'
5
5
 
@@ -18,7 +18,7 @@ export function OverlayCloseButton(props: ButtonProps) {
18
18
  <Button
19
19
  onClick={onClick}
20
20
  disabled={isDisabled}
21
- aria-label={i18n._(/* i18n */ 'Close overlay')}
21
+ aria-label={t`Close overlay`}
22
22
  {...buttonProps}
23
23
  />
24
24
  )
@@ -1,5 +1,5 @@
1
- import { i18n } from '@lingui/core'
2
- import { Trans } from '@lingui/react'
1
+ import { t } from '@lingui/core/macro'
2
+ import { Trans } from '@lingui/react/macro'
3
3
  import { Box, Button, Fab, Typography } from '@mui/material'
4
4
  import { iconClose } from '../icons'
5
5
  import { IconSvg, useIconSvgSize } from '../IconSvg'
@@ -30,7 +30,7 @@ export function OverlayPanelActions(props: PanelActionsProps) {
30
30
  primary={
31
31
  onReset && (
32
32
  <Button variant='inline' color='primary' onClick={onReset}>
33
- <Trans id='Reset' />
33
+ <Trans>Reset</Trans>
34
34
  </Button>
35
35
  )
36
36
  }
@@ -43,7 +43,7 @@ export function OverlayPanelActions(props: PanelActionsProps) {
43
43
  ml: `calc((${fabSize} - ${svgSize}) * -0.5)`,
44
44
  }}
45
45
  size='small'
46
- aria-label={i18n._(/* i18n */ 'Close')}
46
+ aria-label={t`Close`}
47
47
  >
48
48
  <IconSvg src={iconClose} size='large' aria-hidden />
49
49
  </Fab>
@@ -68,7 +68,7 @@ export function OverlayPanelActions(props: PanelActionsProps) {
68
68
  fullWidth
69
69
  // sx={(theme) => ({ mt: theme.spacings.md })}
70
70
  >
71
- <Trans id='Apply' />
71
+ <Trans>Apply</Trans>
72
72
  </Button>
73
73
  </OverlayStickyBottom>
74
74
  </>
@@ -1,5 +1,5 @@
1
- import { i18n } from '@lingui/core'
2
- import { Trans } from '@lingui/react'
1
+ import { t } from '@lingui/core/macro'
2
+ import { Trans } from '@lingui/react/macro'
3
3
  import { Box, Button, Fab, Typography } from '@mui/material'
4
4
  import { iconClose } from '../icons'
5
5
  import { IconSvg, useIconSvgSize } from '../IconSvg'
@@ -24,7 +24,7 @@ export function PopperPanelActions(props: PanelActionsProps) {
24
24
  primary={
25
25
  onReset && (
26
26
  <Button variant='text' color='primary' size='medium' onClick={onReset}>
27
- <Trans id='Reset' />
27
+ <Trans>Reset</Trans>
28
28
  </Button>
29
29
  )
30
30
  }
@@ -37,7 +37,7 @@ export function PopperPanelActions(props: PanelActionsProps) {
37
37
  ml: `calc((${fabSize} - ${svgSize}) * -0.5)`,
38
38
  }}
39
39
  size='small'
40
- aria-label={i18n._(/* i18n */ 'Close')}
40
+ aria-label={t`Close`}
41
41
  >
42
42
  <IconSvg src={iconClose} size='large' aria-hidden />
43
43
  </Fab>
@@ -68,7 +68,7 @@ export function PopperPanelActions(props: PanelActionsProps) {
68
68
  color='primary'
69
69
  fullWidth
70
70
  >
71
- <Trans id='Apply' />
71
+ <Trans>Apply</Trans>
72
72
  </Button>
73
73
  </OverlayStickyBottom>
74
74
  </>
package/Page/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ParsedUrlQuery } from 'querystring'
2
- import type { UpPage } from '@graphcommerce/framer-next-pages/types'
2
+ import type { UpPage } from '@graphcommerce/framer-next-pages'
3
3
  // todo: remove references to GraphQL
4
4
  // eslint-disable-next-line import/no-extraneous-dependencies
5
5
  import type { NormalizedCacheObject } from '@graphcommerce/graphql'
@@ -1,4 +1,5 @@
1
1
  import type {} from '@graphcommerce/next-config'
2
+ import { canonicalBaseUrl } from '@graphcommerce/next-config/config'
2
3
  import { addBasePath } from 'next/dist/client/add-base-path'
3
4
  import { addLocale } from 'next/dist/client/add-locale'
4
5
  import { getDomainLocale } from 'next/dist/client/get-domain-locale'
@@ -49,7 +50,7 @@ export function canonicalize(router: PartialNextRouter, incoming?: Canonical) {
49
50
  addLocale(as, curLocale, conf?.domain ? conf.locale : router.defaultLocale),
50
51
  )
51
52
 
52
- let siteUrl = conf?.canonicalBaseUrl || import.meta.graphCommerce.canonicalBaseUrl
53
+ let siteUrl = conf?.canonicalBaseUrl || canonicalBaseUrl
53
54
 
54
55
  if (conf?.domain && !conf?.canonicalBaseUrl) siteUrl = `https://${conf.domain}`
55
56
 
@@ -1,4 +1,4 @@
1
- import { Trans } from '@lingui/react'
1
+ import { Trans } from '@lingui/react/macro'
2
2
  import type { PaginationProps, SxProps, Theme } from '@mui/material'
3
3
  import { Box, IconButton } from '@mui/material'
4
4
  import type { UsePaginationItem } from '@mui/material/usePagination'
@@ -59,6 +59,7 @@ export function Pagination(props: PagePaginationProps) {
59
59
  <IconSvg src={iconChevronRight} className={classes.icon} size='medium' />
60
60
  </IconButton>
61
61
  )
62
+ const max = Math.max(1, count)
62
63
 
63
64
  return (
64
65
  <Box
@@ -82,7 +83,9 @@ export function Pagination(props: PagePaginationProps) {
82
83
  {page === 1 ? chevronLeft : renderLink(page - 1, chevronLeft, prevBtnProps)}
83
84
 
84
85
  <Box typography='body1'>
85
- <Trans id='Page {page} of {count}' values={{ page, count: Math.max(1, count) }} />
86
+ <Trans>
87
+ Page {page} of {max}
88
+ </Trans>
86
89
  </Box>
87
90
 
88
91
  {page === count ? chevronRight : renderLink(page + 1, chevronRight, nextBtnProps)}
@@ -1,4 +1,4 @@
1
- import { Trans } from '@lingui/react'
1
+ import { Trans } from '@lingui/react/macro'
2
2
  import { Link } from '@mui/material'
3
3
 
4
4
  export function SkipLink() {
@@ -32,7 +32,7 @@ export function SkipLink() {
32
32
  },
33
33
  })}
34
34
  >
35
- <Trans id='Skip to main content' />
35
+ <Trans>Skip to main content</Trans>
36
36
  </Link>
37
37
  )
38
38
  }
@@ -1,4 +1,4 @@
1
- import { Trans } from '@lingui/react'
1
+ import { Trans } from '@lingui/react/macro'
2
2
  import { Button } from '@mui/material'
3
3
  import { MessageSnackbar } from './MessageSnackbar'
4
4
  import type { MessageSnackbarProps } from './MessageSnackbarImpl'
@@ -15,7 +15,7 @@ export function ErrorSnackbar(props: ErrorSnackbarProps) {
15
15
  action={
16
16
  action ?? (
17
17
  <Button size='medium' variant='pill' color='secondary' fullWidth>
18
- <Trans id='Ok' />
18
+ <Trans>Ok</Trans>
19
19
  </Button>
20
20
  )
21
21
  }
@@ -1,4 +1,4 @@
1
- import { i18n } from '@lingui/core'
1
+ import { t } from '@lingui/core/macro'
2
2
  import type { SnackbarProps, SxProps, Theme } from '@mui/material'
3
3
  import { Box, Fab, lighten, Portal, Snackbar, SnackbarContent } from '@mui/material'
4
4
  import React, { useEffect, useState } from 'react'
@@ -190,7 +190,7 @@ export default function MessageSnackbarImpl(props: MessageSnackbarProps) {
190
190
  {!disableClose && (
191
191
  <Fab
192
192
  className={classes.close}
193
- aria-label={i18n._(/* i18n */ 'Close')}
193
+ aria-label={t`Close`}
194
194
  size='small'
195
195
  onClick={hideSnackbar}
196
196
  onMouseDown={preventAnimationBubble}
@@ -1,4 +1,3 @@
1
- import type { EmotionJSX } from '@emotion/react/types/jsx-namespace'
2
1
  import createEmotionServer from '@emotion/server/create-instance'
3
2
  import type { AppType } from 'next/app'
4
3
  // eslint-disable-next-line @next/next/no-document-import-in-page
@@ -8,7 +7,7 @@ import type { DocumentContext } from 'next/document'
8
7
  import { createEmotionCache } from './createEmotionCache'
9
8
  import type { EmotionProviderProps } from './EmotionProvider'
10
9
 
11
- export type EmotionCacheProps = { emotionStyleTags: EmotionJSX.Element[] }
10
+ export type EmotionCacheProps = { emotionStyleTags: React.ReactNode[] }
12
11
 
13
12
  export function withEmotionCache(Document: typeof NextDocument): typeof NextDocument {
14
13
  return class DocumentWithEmotionCache extends Document {
@@ -32,7 +31,6 @@ export function withEmotionCache(Document: typeof NextDocument): typeof NextDocu
32
31
  <style
33
32
  data-emotion={`${style.key} ${style.ids.join(' ')}`}
34
33
  key={style.key}
35
- // eslint-disable-next-line react/no-danger
36
34
  dangerouslySetInnerHTML={{ __html: style.css }}
37
35
  />
38
36
  ))
@@ -1,4 +1,4 @@
1
- import { i18n } from '@lingui/core'
1
+ import { t } from '@lingui/core/macro'
2
2
  import type { IconButtonProps, SxProps, TextFieldProps, Theme } from '@mui/material'
3
3
  import {
4
4
  Box,
@@ -125,7 +125,7 @@ export function TextInputNumber(props: TextInputNumberProps) {
125
125
  startAdornment: (
126
126
  <Box>
127
127
  <Fab
128
- aria-label={i18n._(/* i18n */ 'Decrease')}
128
+ aria-label={t`Decrease`}
129
129
  size='smaller'
130
130
  sx={{ boxShadow: variant === 'standard' ? 4 : 0, minHeight: '30px' }}
131
131
  onPointerDown={() => setDirection('down')}
@@ -141,7 +141,7 @@ export function TextInputNumber(props: TextInputNumberProps) {
141
141
  endAdornment: (
142
142
  <Box>
143
143
  <Fab
144
- aria-label={i18n._(/* i18n */ 'Increase')}
144
+ aria-label={t`Increase`}
145
145
  size='smaller'
146
146
  sx={{ boxShadow: variant === 'standard' ? 4 : 0, minHeight: '30px' }}
147
147
  onPointerDown={() => setDirection('up')}
@@ -160,7 +160,7 @@ export function TextInputNumber(props: TextInputNumberProps) {
160
160
  updateDisabled(e.target)
161
161
  }}
162
162
  inputProps={{
163
- 'aria-label': i18n._(/* i18n */ 'Number'),
163
+ 'aria-label': t`Number`,
164
164
  ...inputProps,
165
165
  sx: [
166
166
  {
@@ -1,4 +1,4 @@
1
- import { Trans } from '@lingui/react'
1
+ import { Trans } from '@lingui/react/macro'
2
2
  import type { FabProps, ListItemButtonProps, Theme } from '@mui/material'
3
3
  import {
4
4
  Fab,
@@ -133,7 +133,7 @@ export function DarkLightModeMenuSecondaryItem(props: ListItemButtonProps) {
133
133
  <IconSvg src={currentMode === 'light' ? iconMoon : iconSun} size='medium' />
134
134
  </ListItemIcon>
135
135
  <ListItemText>
136
- {currentMode === 'light' ? <Trans id='Dark Mode' /> : <Trans id='Light Mode' />}
136
+ {currentMode === 'light' ? <Trans>Dark Mode</Trans> : <Trans>Light Mode</Trans>}
137
137
  </ListItemText>
138
138
  </ListItemButton>
139
139
  )
@@ -1,3 +1,4 @@
1
+ import { canonicalBaseUrl } from '@graphcommerce/next-config/config'
1
2
  import type { LinkProps as NextLinkProps } from 'next/link'
2
3
  import Link from 'next/link'
3
4
  import { useRouter } from 'next/router'
@@ -30,8 +31,7 @@ export const NextLink = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) =>
30
31
  let { href, target, relative, locale, ...rest } = props
31
32
 
32
33
  const router = useRouter()
33
- const canonicalBaseUrl =
34
- useStorefrontConfig().canonicalBaseUrl ?? import.meta.graphCommerce.canonicalBaseUrl
34
+ const canonical = useStorefrontConfig().canonicalBaseUrl ?? canonicalBaseUrl
35
35
 
36
36
  // The href is optional in a MUI link, but required in a Next.js link
37
37
  // When the href is not a string, we pass it through directly
@@ -44,14 +44,14 @@ export const NextLink = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) =>
44
44
  * and make the URL relative without the locale. Prevents Next.js prefixing again with the current
45
45
  * locale.
46
46
  */
47
- if (!locale && isFullUrl && href.startsWith(canonicalBaseUrl)) {
47
+ if (!locale && isFullUrl && href.startsWith(canonical)) {
48
48
  const url = new URL(href)
49
49
  locale = router.locales?.find((l) => url.pathname.startsWith(`/${l}/`))
50
50
  href = locale ? url.pathname.replace(`/${locale}/`, '/') : url.pathname
51
51
  href += url.search
52
52
  }
53
53
 
54
- const isExternal = isFullUrl && !href.startsWith(canonicalBaseUrl)
54
+ const isExternal = isFullUrl && !href.startsWith(canonical)
55
55
  if (isExternal) target = target || '_blank'
56
56
 
57
57
  // Relative URL's cause more pain than they're worth
package/hooks/memoDeep.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // eslint-disable-next-line import/no-extraneous-dependencies
2
- import diff from '@graphcommerce/react-hook-form/src/diff'
2
+ import { diff } from '@graphcommerce/react-hook-form'
3
3
  // eslint-disable-next-line import/no-extraneous-dependencies
4
4
  import { equal } from '@wry/equality'
5
5
  import type { FunctionComponent, NamedExoticComponent } from 'react'
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": "9.1.0-canary.55",
5
+ "version": "10.0.0-canary.57",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -11,35 +11,53 @@
11
11
  "project": "./tsconfig.json"
12
12
  }
13
13
  },
14
+ "exports": {
15
+ ".": "./index.ts",
16
+ "./types": "./types.ts",
17
+ "./server": "./server.ts",
18
+ "./Layout/components/LayoutHeaderClose": "./Layout/components/LayoutHeaderClose.tsx",
19
+ "./LayoutOverlay/test/LayoutOverlayDemo": "./LayoutOverlay/test/LayoutOverlayDemo.tsx",
20
+ "./Styles/extendableComponent": "./Styles/extendableComponent.ts",
21
+ "./Styles": "./Styles/index.ts",
22
+ "./hooks/useMatchMedia": "./hooks/useMatchMedia.ts",
23
+ "./hooks/useStorefrontConfig": "./hooks/useStorefrontConfig.ts",
24
+ "./hooks/useIsSsr": "./hooks/useIsSsr.ts",
25
+ "./hooks/useMemoObject": "./hooks/useMemoObject.ts",
26
+ "./utils/cssFlags": "./utils/cssFlags.tsx",
27
+ "./Intl/DateTimeFormat/toDate": "./Intl/DateTimeFormat/toDate.ts",
28
+ "./Breadcrumbs/BreadcrumbsJsonLd": "./Breadcrumbs/BreadcrumbsJsonLd.tsx",
29
+ "./Breadcrumbs/jsonLdBreadcrumb": "./Breadcrumbs/jsonLdBreadcrumb.tsx",
30
+ "./RenderType/filterNonNullableKeys": "./RenderType/filterNonNullableKeys.ts"
31
+ },
14
32
  "dependencies": {
15
33
  "cookie": "^1.0.2",
16
- "react-is": "^18.3.1"
34
+ "react-is": "^19.2.0"
17
35
  },
18
36
  "devDependencies": {
19
- "@types/react-is": "^18.3.1",
20
- "typescript": "5.7.2"
37
+ "@types/react-is": "^19.2.0",
38
+ "typescript": "5.9.3"
21
39
  },
22
40
  "peerDependencies": {
23
41
  "@emotion/cache": "^11",
24
42
  "@emotion/react": "^11",
25
43
  "@emotion/server": "^11",
26
44
  "@emotion/styled": "^11",
27
- "@graphcommerce/eslint-config-pwa": "^9.1.0-canary.55",
28
- "@graphcommerce/framer-next-pages": "^9.1.0-canary.55",
29
- "@graphcommerce/framer-scroller": "^9.1.0-canary.55",
30
- "@graphcommerce/framer-utils": "^9.1.0-canary.55",
31
- "@graphcommerce/image": "^9.1.0-canary.55",
32
- "@graphcommerce/prettier-config-pwa": "^9.1.0-canary.55",
33
- "@graphcommerce/typescript-config-pwa": "^9.1.0-canary.55",
34
- "@lingui/core": "^4.2.1",
35
- "@lingui/macro": "^4.2.1",
36
- "@lingui/react": "^4.2.1",
45
+ "@graphcommerce/eslint-config-pwa": "^10.0.0-canary.57",
46
+ "@graphcommerce/framer-next-pages": "^10.0.0-canary.57",
47
+ "@graphcommerce/framer-scroller": "^10.0.0-canary.57",
48
+ "@graphcommerce/framer-utils": "^10.0.0-canary.57",
49
+ "@graphcommerce/image": "^10.0.0-canary.57",
50
+ "@graphcommerce/prettier-config-pwa": "^10.0.0-canary.57",
51
+ "@graphcommerce/typescript-config-pwa": "^10.0.0-canary.57",
52
+ "@lingui/core": "^5",
53
+ "@lingui/macro": "^5",
54
+ "@lingui/react": "^5",
37
55
  "@mui/lab": "^5.0.0-alpha.68",
38
56
  "@mui/material": "^5.10.16",
39
57
  "framer-motion": "^11.0.0",
40
58
  "next": "*",
41
59
  "next-sitemap": "4.2.3",
42
- "react": "^18.2.0",
43
- "react-dom": "^18.2.0"
60
+ "react": "^19.2.0",
61
+ "react-dom": "^19.2.0"
44
62
  }
45
63
  }
package/po.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ declare module '*.po' {
2
+ export const messages: Record<
3
+ string,
4
+ string | Array<string | Array<string | (string | undefined) | Record<string, unknown>>>
5
+ >
6
+ }
@@ -5,12 +5,3 @@
5
5
  import './Theme/createTheme'
6
6
  // eslint-disable-next-line react/no-typos
7
7
  import 'react'
8
-
9
- declare module '*.po' {
10
- const messages: Record<
11
- string,
12
- string | Array<string | Array<string | (string | undefined) | Record<string, unknown>>>
13
- >
14
-
15
- export const messages
16
- }
@@ -1,8 +1,10 @@
1
- export const storefrontAll = import.meta.graphCommerce.storefront
1
+ import { storefront } from '@graphcommerce/next-config/config'
2
+
3
+ export const storefrontAll = storefront
2
4
 
3
5
  /** Get the current storefront config based on the provided locale */
4
6
  export const storefrontConfig = (locale?: string | undefined) =>
5
- storefrontAll.find((l) => l.locale === locale)
7
+ storefront.find((l) => l.locale === locale)
6
8
 
7
9
  export const storefrontConfigDefault = () =>
8
- storefrontAll.find((l) => l.defaultLocale) ?? storefrontAll[0]
10
+ storefront.find((l) => l.defaultLocale) ?? storefrontAll[0]