@graphcommerce/magento-search 6.2.0-canary.9 → 6.2.0-canary.91

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,189 @@
1
1
  # Change Log
2
2
 
3
+ ## 6.2.0-canary.91
4
+
5
+ ## 6.2.0-canary.90
6
+
7
+ ## 6.2.0-canary.89
8
+
9
+ ## 6.2.0-canary.88
10
+
11
+ ## 6.2.0-canary.87
12
+
13
+ ## 6.2.0-canary.86
14
+
15
+ ## 6.2.0-canary.85
16
+
17
+ ## 6.2.0-canary.84
18
+
19
+ ## 6.2.0-canary.83
20
+
21
+ ## 6.2.0-canary.82
22
+
23
+ ## 6.2.0-canary.81
24
+
25
+ ## 6.2.0-canary.80
26
+
27
+ ## 6.2.0-canary.79
28
+
29
+ ### Patch Changes
30
+
31
+ - [#2013](https://github.com/graphcommerce-org/graphcommerce/pull/2013) [`c57bdf8a4`](https://github.com/graphcommerce-org/graphcommerce/commit/c57bdf8a4ce936c3eedc4dfada3a464a113ac68a) - Updated @mui and framer-motion packages to latest versions ([@paales](https://github.com/paales))
32
+
33
+ ## 6.2.0-canary.78
34
+
35
+ ## 6.2.0-canary.77
36
+
37
+ ## 6.2.0-canary.76
38
+
39
+ ## 6.2.0-canary.75
40
+
41
+ ## 6.2.0-canary.74
42
+
43
+ ## 6.2.0-canary.73
44
+
45
+ ## 6.2.0-canary.72
46
+
47
+ ## 6.2.0-canary.71
48
+
49
+ ## 6.2.0-canary.70
50
+
51
+ ## 6.2.0-canary.69
52
+
53
+ ## 6.2.0-canary.68
54
+
55
+ ### Minor Changes
56
+
57
+ - [#1990](https://github.com/graphcommerce-org/graphcommerce/pull/1990) [`0729105cd`](https://github.com/graphcommerce-org/graphcommerce/commit/0729105cdb84b9f73d1fda7dac7daf867f4e0b9b) - Add CategorySearchResults component that can be injected with a plugin instead of SearchForm, fix various styling issues with search ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
58
+
59
+ ## 6.2.0-canary.67
60
+
61
+ ## 6.2.0-canary.66
62
+
63
+ ## 6.2.0-canary.65
64
+
65
+ ## 6.2.0-canary.64
66
+
67
+ ## 6.2.0-canary.63
68
+
69
+ ## 6.2.0-canary.62
70
+
71
+ ## 6.2.0-canary.61
72
+
73
+ ## 6.2.0-canary.60
74
+
75
+ ## 6.2.0-canary.59
76
+
77
+ ## 6.2.0-canary.58
78
+
79
+ ## 6.2.0-canary.57
80
+
81
+ ## 6.2.0-canary.56
82
+
83
+ ## 6.2.0-canary.55
84
+
85
+ ## 6.2.0-canary.54
86
+
87
+ ## 6.2.0-canary.53
88
+
89
+ ## 6.2.0-canary.52
90
+
91
+ ## 6.2.0-canary.51
92
+
93
+ ## 6.2.0-canary.50
94
+
95
+ ### Minor Changes
96
+
97
+ - [`e55d8c390`](https://github.com/graphcommerce-org/graphcommerce/commit/e55d8c390d90b4bb7bab11c6a99027ac72bd7e3e) - Created a new sidebar layout system, can be configured with productFiltersLayout in the graphcommerce.config.js ([@paales](https://github.com/paales))
98
+
99
+ ## 6.2.0-canary.49
100
+
101
+ ## 6.2.0-canary.48
102
+
103
+ ## 6.2.0-canary.47
104
+
105
+ ## 6.2.0-canary.46
106
+
107
+ ## 6.2.0-canary.45
108
+
109
+ ### Minor Changes
110
+
111
+ - [#1962](https://github.com/graphcommerce-org/graphcommerce/pull/1962) [`518b6ca24`](https://github.com/graphcommerce-org/graphcommerce/commit/518b6ca248fc94624dc06eb02de5b3eac0fc9483) - Created a new `<ValidatedPasswordElement/>` which validates according to Magento's validation groups and implement on all locations. Move remaining password fields to `<PasswordElement />` ([@carlocarels90](https://github.com/carlocarels90))
112
+
113
+ ## 6.2.0-canary.44
114
+
115
+ ## 6.2.0-canary.43
116
+
117
+ ## 6.2.0-canary.42
118
+
119
+ ## 6.2.0-canary.41
120
+
121
+ ## 6.2.0-canary.40
122
+
123
+ ## 6.2.0-canary.39
124
+
125
+ ## 6.2.0-canary.38
126
+
127
+ ## 6.2.0-canary.37
128
+
129
+ ## 6.2.0-canary.36
130
+
131
+ ## 6.2.0-canary.35
132
+
133
+ ## 6.2.0-canary.34
134
+
135
+ ## 6.2.0-canary.33
136
+
137
+ ## 6.2.0-canary.32
138
+
139
+ ## 6.2.0-canary.31
140
+
141
+ ## 6.2.0-canary.30
142
+
143
+ ## 6.2.0-canary.29
144
+
145
+ ## 6.2.0-canary.28
146
+
147
+ ## 6.2.0-canary.27
148
+
149
+ ## 6.2.0-canary.26
150
+
151
+ ## 6.2.0-canary.25
152
+
153
+ ## 6.2.0-canary.24
154
+
155
+ ## 6.2.0-canary.23
156
+
157
+ ## 6.2.0-canary.22
158
+
159
+ ## 6.2.0-canary.21
160
+
161
+ ## 6.2.0-canary.20
162
+
163
+ ## 6.2.0-canary.19
164
+
165
+ ## 6.2.0-canary.18
166
+
167
+ ## 6.2.0-canary.17
168
+
169
+ ## 6.2.0-canary.16
170
+
171
+ ### Patch Changes
172
+
173
+ - [#1930](https://github.com/graphcommerce-org/graphcommerce/pull/1930) [`c8d023e9e`](https://github.com/graphcommerce-org/graphcommerce/commit/c8d023e9e874131cd9f8fe192b1fca5fe1a26ee3) - Fix the close menu on search and add the option to secondary menu items ([@StefanAngenent](https://github.com/StefanAngenent))
174
+
175
+ ## 6.2.0-canary.15
176
+
177
+ ## 6.2.0-canary.14
178
+
179
+ ## 6.2.0-canary.13
180
+
181
+ ## 6.2.0-canary.12
182
+
183
+ ## 6.2.0-canary.11
184
+
185
+ ## 6.2.0-canary.10
186
+
3
187
  ## 6.2.0-canary.9
4
188
 
5
189
  ## 6.2.0-canary.8
@@ -21,7 +21,6 @@ export function CategorySearchResult(props: CategorySearchResultProps) {
21
21
  fullWidth
22
22
  variant='pill'
23
23
  className={classes.root}
24
- disableElevation
25
24
  endIcon={<IconSvg src={iconChevronRight} size='small' />}
26
25
  sx={[
27
26
  (theme) => ({
@@ -46,14 +45,14 @@ export function CategorySearchResult(props: CategorySearchResultProps) {
46
45
  ]}
47
46
  >
48
47
  <div>
49
- {catProps?.breadcrumbs?.map((breadcrumb) => (
48
+ {catProps?.breadcrumbs?.map((breadcrumb, index) => (
50
49
  <React.Fragment key={breadcrumb?.category_url_path}>
51
50
  <Highlight
52
51
  key={breadcrumb?.category_url_path}
53
52
  text={breadcrumb?.category_name ?? ''}
54
53
  highlight={search}
55
54
  />
56
- {' / '}
55
+ {(catProps.breadcrumbs?.length ?? 0) > index + 1 && ' / '}
57
56
  </React.Fragment>
58
57
  ))}
59
58
  <Highlight text={catProps?.name ?? ''} highlight={search} />
@@ -0,0 +1,11 @@
1
+ import { Box, SxProps, Theme } from '@mui/material'
2
+
3
+ export type CategorySearchResultsProps = {
4
+ children: React.ReactNode
5
+ sx?: SxProps<Theme>
6
+ }
7
+
8
+ export function CategorySearchResults(props: CategorySearchResultsProps) {
9
+ const { children, sx = [] } = props
10
+ return <Box sx={sx}>{children}</Box>
11
+ }
@@ -1,5 +1,6 @@
1
1
  import { iconSearch, responsiveVal, IconSvg, extendableComponent } from '@graphcommerce/next-ui'
2
2
  import { Trans } from '@lingui/react'
3
+ // eslint-disable-next-line @typescript-eslint/no-restricted-imports
3
4
  import { TextField, TextFieldProps } from '@mui/material'
4
5
 
5
6
  export type SearchButtonProps = TextFieldProps
@@ -0,0 +1,10 @@
1
+ export type SearchContextProps = React.PropsWithChildren<{
2
+ serverProps?: unknown
3
+ // rendersInsideNextjs is needed, because of the InstantSearchSSRProvider data hydration inside the getStaticProps.
4
+ rendersInsideNextjs?: boolean
5
+ }>
6
+
7
+ export function SearchContext(props: SearchContextProps) {
8
+ const { children } = props
9
+ return <>{children}</>
10
+ }
@@ -1,17 +1,10 @@
1
1
  import { TextFieldElement, TextFieldElementProps } from '@graphcommerce/ecommerce-ui'
2
- import {
3
- FormRow,
4
- iconClose,
5
- iconSearch,
6
- IconSvg,
7
- extendableComponent,
8
- } from '@graphcommerce/next-ui'
9
- import { useForm, useFormAutoSubmit } from '@graphcommerce/react-hook-form'
10
- import { i18n } from '@lingui/core'
11
- import { Trans } from '@lingui/react'
12
- import { Box, IconButton, SxProps, Theme } from '@mui/material'
2
+ import { extendableComponent } from '@graphcommerce/next-ui'
3
+ import { FormAutoSubmit, useForm } from '@graphcommerce/react-hook-form'
4
+ import { Box, SxProps, Theme } from '@mui/material'
13
5
  import { useRouter } from 'next/router'
14
6
  import { useEffect, useRef } from 'react'
7
+ import { SearchFormAdornment } from './SearchFormAdornment'
15
8
 
16
9
  export type SearchFormProps = {
17
10
  totalResults?: number
@@ -22,9 +15,7 @@ export type SearchFormProps = {
22
15
  sx?: SxProps<Theme>
23
16
  }
24
17
 
25
- const name = 'SearchForm' as const
26
- const parts = ['root', 'totalProducts'] as const
27
- const { classes } = extendableComponent(name, parts)
18
+ const { classes } = extendableComponent('SearchForm' as const, ['root'] as const)
28
19
 
29
20
  export function SearchForm(props: SearchFormProps) {
30
21
  const searchInputElement = useRef<HTMLInputElement>(null)
@@ -32,78 +23,45 @@ export function SearchForm(props: SearchFormProps) {
32
23
  useEffect(() => {
33
24
  searchInputElement.current?.focus()
34
25
  }, [])
35
- const { totalResults = 0, search = '', urlHandle = 'search', textFieldProps, sx = [] } = props
26
+ const { search = '', urlHandle = 'search', textFieldProps, sx = [] } = props
36
27
  const router = useRouter()
37
28
 
38
- const form = useForm({ mode: 'onChange', defaultValues: { search } })
39
- const { handleSubmit, formState, reset, watch, getValues, control } = form
29
+ const form = useForm({ defaultValues: { search } })
30
+ const { handleSubmit, setValue, control } = form
40
31
 
41
- const submit = handleSubmit((formData) => {
42
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
43
- router.replace(`/${urlHandle}/${formData.search}`)
44
- reset(getValues())
45
- })
46
- useFormAutoSubmit({ form, submit })
32
+ const submit = handleSubmit((formData) => router.replace(`/${urlHandle}/${formData.search}`))
47
33
 
48
- const handleReset = () => {
49
- reset({ search: '' })
50
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
51
- router.replace(`/${urlHandle}`)
52
- }
53
-
54
- const endAdornment = !watch('search') ? (
55
- <IconButton size='small' aria-label={i18n._(/* i18n */ 'Search')}>
56
- <IconSvg src={iconSearch} />
57
- </IconButton>
58
- ) : (
59
- <>
60
- {totalResults > 0 && (
61
- <Box
62
- className={classes.totalProducts}
63
- sx={(theme) => ({
64
- minWidth: 'max-content',
65
- color: theme.palette.text.disabled,
66
- paddingRight: '7px',
67
- })}
68
- >
69
- {totalResults === 1 && <Trans id='{totalResults} result' values={{ totalResults }} />}
70
- {totalResults > 1 && <Trans id='{totalResults} results' values={{ totalResults }} />}
71
- </Box>
72
- )}
73
- <IconButton onClick={handleReset} size='small'>
74
- <IconSvg src={iconClose} />
75
- </IconButton>
76
- </>
34
+ const endAdornment = (
35
+ <SearchFormAdornment
36
+ control={form.control}
37
+ name='search'
38
+ onReset={() => {
39
+ setValue('search', '')
40
+ return submit()
41
+ }}
42
+ />
77
43
  )
78
44
 
79
45
  return (
80
- <Box
81
- className={classes.root}
82
- component='form'
83
- noValidate
84
- onSubmit={submit}
85
- onChange={() => {
86
- if (watch('search') === '') {
87
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
88
- router.replace(`/search`)
89
- }
90
- }}
91
- sx={sx}
92
- >
93
- <FormRow>
94
- <TextFieldElement
95
- variant='outlined'
96
- type='text'
97
- name='search'
98
- control={control}
99
- defaultValue={search}
100
- error={formState.isSubmitted && !!formState.errors.search}
101
- helperText={formState.isSubmitted && formState.errors.search?.message}
102
- InputProps={{ endAdornment }}
103
- inputRef={searchInputElement}
104
- {...textFieldProps}
105
- />
106
- </FormRow>
46
+ <Box className={classes.root} component='form' noValidate onSubmit={submit} sx={sx}>
47
+ <FormAutoSubmit
48
+ control={form.control}
49
+ submit={submit}
50
+ wait={200}
51
+ maxWait={400}
52
+ initialWait={0}
53
+ />
54
+ <TextFieldElement
55
+ variant='outlined'
56
+ type='text'
57
+ name='search'
58
+ color='primary'
59
+ control={control}
60
+ InputProps={{ ...textFieldProps?.InputProps, endAdornment }}
61
+ validation={{ minLength: 3 }}
62
+ inputRef={searchInputElement}
63
+ {...textFieldProps}
64
+ />
107
65
  </Box>
108
66
  )
109
67
  }
@@ -0,0 +1,25 @@
1
+ import { IconSvg, iconSearch, iconClose } from '@graphcommerce/next-ui'
2
+ import { Control, FieldPath, FieldValues, useWatch } from '@graphcommerce/react-hook-form'
3
+ import { i18n } from '@lingui/core'
4
+ import { IconButton } from '@mui/material'
5
+
6
+ export function SearchFormAdornment<TFieldValues extends FieldValues = FieldValues>(props: {
7
+ control: Control<TFieldValues>
8
+ /** Autosubmit only when these field names update */
9
+ name: FieldPath<TFieldValues>
10
+
11
+ onReset?: () => void
12
+ }) {
13
+ const { name, control, onReset } = props
14
+ const searchValue = useWatch({ control, name })
15
+
16
+ return !searchValue ? (
17
+ <IconButton size='small' aria-label={i18n._(/* i18n */ 'Search')}>
18
+ <IconSvg src={iconSearch} />
19
+ </IconButton>
20
+ ) : (
21
+ <IconButton onClick={onReset} size='small'>
22
+ <IconSvg src={iconClose} />
23
+ </IconButton>
24
+ )
25
+ }
@@ -7,12 +7,13 @@ import {
7
7
  } from '@graphcommerce/next-ui'
8
8
  import { Breakpoint, Fab, FabProps, Link, LinkProps } from '@mui/material'
9
9
  import { useRouter } from 'next/router'
10
+ import { MouseEventHandler } from 'react'
10
11
  import type { SetRequired } from 'type-fest'
11
12
 
12
13
  export type SearchLinkProps = {
13
14
  breakpoint?: Breakpoint
14
15
  fab?: FabProps
15
- } & SetRequired<Pick<LinkProps, 'href' | 'sx' | 'children'>, 'href'>
16
+ } & SetRequired<Pick<LinkProps<'a'>, 'href' | 'sx' | 'children' | 'onClick'>, 'href'>
16
17
 
17
18
  const name = 'SearchLink' as const
18
19
  const parts = ['root', 'text', 'svg'] as const
@@ -26,21 +27,24 @@ const { classes } = extendableComponent(name, parts)
26
27
  * ```
27
28
  */
28
29
  export function SearchLink(props: SearchLinkProps) {
29
- const { href, sx = [], children, breakpoint, fab, ...linkProps } = props
30
+ const { href, sx = [], children, breakpoint, fab, onClick, ...linkProps } = props
30
31
  const router = useRouter()
31
32
  const fabSize = useFabSize('responsive')
32
33
  const { sx: fabSx = [], size, color, ...fabProps } = fab ?? {}
33
34
 
35
+ const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {
36
+ e.preventDefault()
37
+ onClick?.(e)
38
+ return router.push(href)
39
+ }
40
+
34
41
  return (
35
42
  <>
36
43
  <Link
37
- component='button'
44
+ component='a'
38
45
  className={classes.root}
39
46
  underline='none'
40
- onClick={(e) => {
41
- e.preventDefault()
42
- return router.push(href)
43
- }}
47
+ onClick={handleClick}
44
48
  sx={[
45
49
  (theme) => ({
46
50
  justifySelf: 'center',
@@ -75,6 +79,7 @@ export function SearchLink(props: SearchLinkProps) {
75
79
  </Link>
76
80
  {breakpoint && (
77
81
  <Fab
82
+ component='a'
78
83
  href={href}
79
84
  size={size ?? 'large'}
80
85
  color={color ?? 'inherit'}
package/index.ts CHANGED
@@ -1,7 +1,21 @@
1
1
  export * from './components/SearchDivider/SearchDivider'
2
2
  export * from './components/NoSearchResults/NoSearchResults'
3
3
  export * from './components/CategorySearchResult/CategorySearchResult'
4
+ export * from './components/CategorySearchResult/CategorySearchResults'
4
5
  export * from './components/SearchForm/SearchForm'
5
6
  export * from './components/SearchLink/SearchLink'
6
7
  export * from './CategorySearch.gql'
7
8
  export * from './components/SearchButton/SearchButton'
9
+ export * from './components/SearchContext/SearchContext'
10
+
11
+ export {
12
+ ProductListSort,
13
+ ProductListFilters,
14
+ ProductListCount,
15
+ ProductListItemsBase,
16
+ ProductListPagination,
17
+ ProductListFiltersContainer,
18
+ ProductListParamsProvider,
19
+ } from '@graphcommerce/magento-product'
20
+
21
+ export * from '@graphcommerce/magento-product/components/ProductFiltersPro'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-search",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "6.2.0-canary.9",
5
+ "version": "6.2.0-canary.91",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,20 +12,22 @@
12
12
  }
13
13
  },
14
14
  "devDependencies": {
15
- "@graphcommerce/eslint-config-pwa": "6.2.0-canary.9",
16
- "@graphcommerce/prettier-config-pwa": "6.2.0-canary.9",
17
- "@graphcommerce/typescript-config-pwa": "6.2.0-canary.9"
15
+ "@graphcommerce/eslint-config-pwa": "6.2.0-canary.91",
16
+ "@graphcommerce/prettier-config-pwa": "6.2.0-canary.91",
17
+ "@graphcommerce/typescript-config-pwa": "6.2.0-canary.91"
18
18
  },
19
19
  "dependencies": {
20
- "@graphcommerce/ecommerce-ui": "6.2.0-canary.9",
21
- "@graphcommerce/graphql": "6.2.0-canary.9",
22
- "@graphcommerce/image": "6.2.0-canary.9",
23
- "@graphcommerce/next-ui": "6.2.0-canary.9",
24
- "@graphcommerce/react-hook-form": "6.2.0-canary.9"
20
+ "@graphcommerce/ecommerce-ui": "6.2.0-canary.91",
21
+ "@graphcommerce/graphql": "6.2.0-canary.91",
22
+ "@graphcommerce/image": "6.2.0-canary.91",
23
+ "@graphcommerce/magento-product": "6.2.0-canary.91",
24
+ "@graphcommerce/next-ui": "6.2.0-canary.91",
25
+ "@graphcommerce/react-hook-form": "6.2.0-canary.91"
25
26
  },
26
27
  "peerDependencies": {
27
- "@lingui/react": "^3.13.2",
28
- "@lingui/core": "^3.13.2",
28
+ "@lingui/react": "^4.2.1",
29
+ "@lingui/core": "^4.2.1",
30
+ "@lingui/macro": "^4.2.1",
29
31
  "@mui/material": "^5.10.16",
30
32
  "next": "^13.2.0",
31
33
  "react": "^18.2.0",