@graphcommerce/magento-search 9.0.0-canary.98 → 9.0.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.
@@ -1,14 +1,15 @@
1
- import { Highlight, iconChevronRight, IconSvg, extendableComponent } from '@graphcommerce/next-ui'
2
- import { Button, SxProps, Theme } from '@mui/material'
1
+ import { Highlight, IconSvg, extendableComponent, iconChevronRight } from '@graphcommerce/next-ui'
2
+ import type { SxProps, Theme } from '@mui/material'
3
+ import { Button } from '@mui/material'
3
4
  import React from 'react'
4
- import { CategorySearchResultFragment } from './CategorySearchResult.gql'
5
+ import type { CategorySearchResultFragment } from './CategorySearchResult.gql'
5
6
 
6
7
  export type CategorySearchResultProps = Omit<CategorySearchResultFragment, 'uid'> & {
7
8
  search?: string
8
9
  sx?: SxProps<Theme>
9
10
  }
10
11
 
11
- const name = 'CategorySearchResult' as const
12
+ const name = 'CategorySearchResult'
12
13
  const parts = ['root'] as const
13
14
  const { classes } = extendableComponent(name, parts)
14
15
 
@@ -1,10 +1,12 @@
1
- import { Box, SxProps, Theme } from '@mui/material'
1
+ import type { SxProps, Theme } from '@mui/material'
2
+ import { Box } from '@mui/material'
2
3
 
3
4
  export type CategorySearchResultsProps = {
4
5
  children: React.ReactNode
5
6
  sx?: SxProps<Theme>
6
7
  }
7
8
 
9
+ /** @public */
8
10
  export function CategorySearchResults(props: CategorySearchResultsProps) {
9
11
  const { children, sx = [] } = props
10
12
  return <Box sx={sx}>{children}</Box>
@@ -1,13 +1,18 @@
1
1
  import { extendableComponent } from '@graphcommerce/next-ui'
2
2
  import { Trans } from '@lingui/react'
3
- import { Box, SxProps, Theme, Typography } from '@mui/material'
3
+ import type { SxProps, Theme } from '@mui/material'
4
+ import { Box, Typography } from '@mui/material'
4
5
 
5
6
  export type NoSearchResultsProps = { sx?: SxProps<Theme> }
6
7
 
7
- const name = 'NoSearchResults' as const
8
+ const name = 'NoSearchResults'
8
9
  const parts = ['root'] as const
9
10
  const { classes } = extendableComponent(name, parts)
10
11
 
12
+ /**
13
+ * @deprecated
14
+ * @public
15
+ */
11
16
  export function NoSearchResults(props: NoSearchResultsProps) {
12
17
  const { sx = [] } = props
13
18
 
@@ -1,11 +1,11 @@
1
1
  import type {
2
- MenuQueryFragment,
3
2
  CategoryTreeItem,
3
+ MenuQueryFragment,
4
4
  NavigationItemFragment,
5
5
  } from '@graphcommerce/magento-category'
6
+ import type { ProductFiltersProCategoryAccordionProps } from '@graphcommerce/magento-product'
6
7
  import {
7
8
  ProductFiltersProCategoryAccordion,
8
- ProductFiltersProCategoryAccordionProps,
9
9
  useProductFiltersPro,
10
10
  } from '@graphcommerce/magento-product'
11
11
  import { filterNonNullableKeys } from '@graphcommerce/next-ui'
@@ -79,7 +79,7 @@ function isParent<U extends TreeItem>(item: U, parent: U): boolean {
79
79
  return false
80
80
  }
81
81
 
82
- type ProductFiltersProCategorySectionSearchProps = Omit<
82
+ export type ProductFiltersProCategorySectionSearchProps = Omit<
83
83
  ProductFiltersProCategoryAccordionProps,
84
84
  'categoryTree' | 'onChange'
85
85
  > & {
@@ -90,7 +90,7 @@ export function ProductFiltersProCategorySectionSearch(
90
90
  props: ProductFiltersProCategorySectionSearchProps,
91
91
  ) {
92
92
  const { menu } = props
93
- const { form, submit, params, aggregations, appliedAggregations } = useProductFiltersPro()
93
+ const { form, submit, params, aggregations } = useProductFiltersPro()
94
94
  const currentFilter = params.filters.category_uid?.in
95
95
 
96
96
  const categoryTree = useMemo(() => {
@@ -148,9 +148,9 @@ export function ProductFiltersProCategorySectionSearch(
148
148
  })
149
149
  .slice(1)
150
150
  .filter((c) => c.visible)
151
- }, [appliedAggregations, currentFilter, menu?.items])
151
+ }, [aggregations, currentFilter, menu?.items])
152
152
 
153
- if (!categoryTree) return null
153
+ if (!categoryTree.length) return null
154
154
 
155
155
  return (
156
156
  <ProductFiltersProCategoryAccordion
@@ -1,9 +1,10 @@
1
- import { ProductListParams, useProductFiltersPro } from '@graphcommerce/magento-product'
1
+ import type { ProductListParams } from '@graphcommerce/magento-product'
2
+ import { useProductFiltersPro } from '@graphcommerce/magento-product'
2
3
  import { useWatch } from '@graphcommerce/react-hook-form'
3
4
  import { Trans } from '@lingui/macro'
4
5
  import { Box } from '@mui/material'
5
6
 
6
- type ProductFiltersProSearchHeaderProps = {
7
+ export type ProductFiltersProSearchHeaderProps = {
7
8
  params: ProductListParams
8
9
  /**
9
10
  * Provide a text when there is no term searched
@@ -11,8 +12,7 @@ type ProductFiltersProSearchHeaderProps = {
11
12
  children: React.ReactNode
12
13
  }
13
14
 
14
- export function ProductFiltersProSearchTerm(props: ProductFiltersProSearchHeaderProps) {
15
- const { params, children } = props
15
+ export function useSearchResultRemaining(params: ProductListParams) {
16
16
  const { form } = useProductFiltersPro()
17
17
  const resultSearch = params.search ?? ''
18
18
  const targetSearch = useWatch({ control: form.control, name: 'search' }) ?? ''
@@ -21,6 +21,17 @@ export function ProductFiltersProSearchTerm(props: ProductFiltersProSearchHeader
21
21
  ? targetSearch.slice(resultSearch.length)
22
22
  : ''
23
23
 
24
+ return {
25
+ resultSearch,
26
+ targetSearch,
27
+ remaining,
28
+ }
29
+ }
30
+
31
+ export function ProductFiltersProSearchTerm(props: ProductFiltersProSearchHeaderProps) {
32
+ const { params, children } = props
33
+
34
+ const { remaining, resultSearch, targetSearch } = useSearchResultRemaining(params)
24
35
  if (!resultSearch && !targetSearch) return children
25
36
 
26
37
  const search = (
@@ -1,17 +1,14 @@
1
1
  import { globalFormContextRef } from '@graphcommerce/magento-product'
2
2
  import { IconSvg, iconClose } from '@graphcommerce/next-ui'
3
3
  import { t } from '@lingui/macro'
4
- import {
4
+ import type {
5
5
  ButtonBaseProps,
6
- FormControl,
7
6
  FormControlProps,
8
- IconButton,
9
7
  IconButtonProps,
10
8
  InputBaseProps,
11
- OutlinedInput,
12
9
  OutlinedInputProps,
13
- useForkRef,
14
10
  } from '@mui/material'
11
+ import { FormControl, IconButton, OutlinedInput, useForkRef } from '@mui/material'
15
12
  import { useRouter } from 'next/router'
16
13
  import { useEffect, useRef } from 'react'
17
14
  import { useSearchPageAndParam } from './useSearchPageAndParam'
@@ -1,20 +1,23 @@
1
- import { IconSvg, iconSearch, showPageLoadIndicator } from '@graphcommerce/next-ui'
2
- import { Fab, FabProps } from '@mui/material'
1
+ import { iconSearch, IconSvg, showPageLoadIndicator } from '@graphcommerce/next-ui'
2
+ import type { FabProps } from '@mui/material'
3
+ import { Fab } from '@mui/material'
3
4
  import dynamic from 'next/dynamic'
4
5
  import { useMemo, useState } from 'react'
5
- import { ProductFiltersProSearchInputProps } from './ProductFiltersProSearchInput'
6
+ import type { ProductFiltersProSearchInputProps } from './ProductFiltersProSearchInput'
6
7
  import { useSearchPageAndParam } from './useSearchPageAndParam'
7
8
 
8
- type ProductFiltersProSearchFieldProps = ProductFiltersProSearchInputProps & {
9
+ export type SearchFieldProps = ProductFiltersProSearchInputProps & {
9
10
  fab?: FabProps
11
+ visible?: boolean
12
+ searchField?: Record<string, unknown>
10
13
  }
11
14
 
12
15
  const ProductFiltersProSearchInputLazy = dynamic(
13
16
  async () => (await import('./ProductFiltersProSearchInput')).ProductFiltersProSearchOutlinedInput,
14
17
  )
15
18
 
16
- export function ProductFiltersProSearchField(props: ProductFiltersProSearchFieldProps) {
17
- const { fab, formControl } = props
19
+ export function SearchField(props: SearchFieldProps) {
20
+ const { fab, formControl, visible: incomingVisible } = props
18
21
 
19
22
  const [searchPage] = useSearchPageAndParam()
20
23
  const [expanded, setExpanded] = useState(searchPage)
@@ -22,7 +25,7 @@ export function ProductFiltersProSearchField(props: ProductFiltersProSearchField
22
25
  if (!searchPage) setExpanded(searchPage)
23
26
  }, [searchPage])
24
27
 
25
- const visible = expanded || searchPage
28
+ const visible = incomingVisible || expanded || searchPage
26
29
 
27
30
  return (
28
31
  <>
@@ -5,7 +5,7 @@ export function useSearchPageAndParam() {
5
5
  const router = useRouter()
6
6
 
7
7
  const path = router.asPath.startsWith('/c/') ? router.asPath.slice(3) : router.asPath.slice(1)
8
- const [url, query] = extractUrlQuery({ url: path.split('#')[0].split('/') })
8
+ const [url] = extractUrlQuery({ url: path.split('#')[0].split('/') })
9
9
  const searchParam = url?.startsWith('search') ? decodeURI(url.split('/')[1] ?? '') : null
10
10
  const searchPage = router.asPath.startsWith('/search')
11
11
  return [searchPage, searchParam] as const
@@ -1,12 +1,13 @@
1
- import { iconSearch, responsiveVal, IconSvg, extendableComponent } from '@graphcommerce/next-ui'
1
+ import { IconSvg, extendableComponent, iconSearch, responsiveVal } from '@graphcommerce/next-ui'
2
2
  import { Trans } from '@lingui/react'
3
3
  // eslint-disable-next-line @typescript-eslint/no-restricted-imports
4
- import { TextField, TextFieldProps } from '@mui/material'
4
+ import type { TextFieldProps } from '@mui/material'
5
+ import { TextField } from '@mui/material'
5
6
 
6
7
  export type SearchButtonProps = TextFieldProps
7
8
 
8
9
  type OwnerState = { fullWidth?: boolean }
9
- const name = 'SearchButton' as const
10
+ const name = 'SearchButton'
10
11
  const parts = ['root', 'inputRoot'] as const
11
12
  const { withState } = extendableComponent<OwnerState, typeof name, typeof parts>(name, parts)
12
13
 
@@ -0,0 +1,24 @@
1
+ import type { FabProps } from '@graphcommerce/next-ui'
2
+ import { Fab, iconSearch } from '@graphcommerce/next-ui'
3
+ import { useRouter } from 'next/router'
4
+ import type { SetOptional } from 'type-fest'
5
+
6
+ export type SearchFabProps = SetOptional<FabProps, 'icon'>
7
+
8
+ export function SearchFab(props: SearchFabProps) {
9
+ const { sx, ...fabProps } = props
10
+ const router = useRouter()
11
+ return (
12
+ <Fab
13
+ color='inherit'
14
+ size='medium'
15
+ sx={sx}
16
+ icon={iconSearch}
17
+ onClick={async () => {
18
+ await router.push('/search')
19
+ globalThis.document.body.querySelector<HTMLInputElement>('[name="search"]')?.focus()
20
+ }}
21
+ {...fabProps}
22
+ />
23
+ )
24
+ }
@@ -1,7 +1,9 @@
1
- import { TextFieldElement, TextFieldElementProps } from '@graphcommerce/ecommerce-ui'
1
+ import type { TextFieldElementProps } from '@graphcommerce/ecommerce-ui'
2
+ import { TextFieldElement } from '@graphcommerce/ecommerce-ui'
2
3
  import { extendableComponent } from '@graphcommerce/next-ui'
3
4
  import { FormAutoSubmit, useForm } from '@graphcommerce/react-hook-form'
4
- import { Box, SxProps, Theme } from '@mui/material'
5
+ import type { SxProps, Theme } from '@mui/material'
6
+ import { Box } from '@mui/material'
5
7
  import { useRouter } from 'next/router'
6
8
  import { useEffect, useRef } from 'react'
7
9
  import { SearchFormAdornment } from './SearchFormAdornment'
@@ -1,5 +1,6 @@
1
- import { IconSvg, iconSearch, iconClose } from '@graphcommerce/next-ui'
2
- import { Control, FieldPath, FieldValues, useWatch } from '@graphcommerce/react-hook-form'
1
+ import { IconSvg, iconClose, iconSearch } from '@graphcommerce/next-ui'
2
+ import type { Control, FieldPath, FieldValues } from '@graphcommerce/react-hook-form'
3
+ import { useWatch } from '@graphcommerce/react-hook-form'
3
4
  import { i18n } from '@lingui/core'
4
5
  import { IconButton } from '@mui/material'
5
6
 
@@ -1,14 +1,15 @@
1
1
  import {
2
- iconSearch,
3
- responsiveVal,
4
2
  IconSvg,
5
3
  extendableComponent,
4
+ iconSearch,
5
+ responsiveVal,
6
6
  useFabSize,
7
7
  useIconSvgSize,
8
8
  } from '@graphcommerce/next-ui'
9
- import { Breakpoint, Fab, FabProps, Link, LinkProps } from '@mui/material'
9
+ import type { Breakpoint, FabProps, LinkProps } from '@mui/material'
10
+ import { Fab, Link } from '@mui/material'
10
11
  import { useRouter } from 'next/router'
11
- import { KeyboardEventHandler, MouseEventHandler } from 'react'
12
+ import type { KeyboardEventHandler, MouseEventHandler } from 'react'
12
13
  import type { SetRequired } from 'type-fest'
13
14
 
14
15
  export type SearchLinkProps = {
@@ -16,7 +17,7 @@ export type SearchLinkProps = {
16
17
  fab?: FabProps
17
18
  } & SetRequired<Pick<LinkProps<'a'>, 'href' | 'sx' | 'children' | 'onClick'>, 'href'>
18
19
 
19
- const name = 'SearchLink' as const
20
+ const name = 'SearchLink'
20
21
  const parts = ['root', 'text', 'svg'] as const
21
22
  const { classes } = extendableComponent(name, parts)
22
23
 
@@ -1,12 +1,14 @@
1
- import { useInContextQuery, useQuery } from '@graphcommerce/graphql'
2
- import {
1
+ import { usePrivateQuery, useQuery } from '@graphcommerce/graphql'
2
+ import type {
3
3
  FilterFormProviderProps,
4
- ProductFiltersDocument,
5
4
  ProductFiltersQuery,
6
- ProductListDocument,
7
5
  ProductListParams,
8
6
  ProductListQuery,
7
+ } from '@graphcommerce/magento-product'
8
+ import {
9
9
  prefetchProductList,
10
+ ProductFiltersDocument,
11
+ ProductListDocument,
10
12
  toProductListParams,
11
13
  useRouterFilterParams,
12
14
  } from '@graphcommerce/magento-product'
@@ -24,15 +26,17 @@ import {
24
26
  * - Creates a prefetch function to preload the product list
25
27
  */
26
28
  export function useProductList<
27
- T extends ProductListQuery &
28
- ProductFiltersQuery & {
29
- params?: ProductListParams
30
- },
29
+ T extends ProductListQuery & ProductFiltersQuery & { params?: ProductListParams },
31
30
  >(props: T) {
32
31
  const { params, shallow } = useRouterFilterParams(props)
33
32
  const variables = useProductListApplySearchDefaults(params)
34
- const result = useInContextQuery(ProductListDocument, { variables, skip: !shallow }, props)
35
- const filters = useInContextQuery(
33
+ const result = usePrivateQuery(
34
+ ProductListDocument,
35
+ { variables: { ...variables }, skip: !shallow },
36
+ props,
37
+ )
38
+
39
+ const filters = usePrivateQuery(
36
40
  ProductFiltersDocument,
37
41
  { variables: searchDefaultsToProductListFilters(variables), skip: !shallow },
38
42
  props,
package/index.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  export * from './CategorySearch.gql'
2
2
  export * from './components/CategorySearchResult/CategorySearchResult'
3
3
  export * from './components/CategorySearchResult/CategorySearchResults'
4
+ export * from './components/CategorySearchResult/CategorySearchResult.gql'
4
5
  export * from './components/NoSearchResults/NoSearchResults'
5
6
  export * from './components/SearchButton/SearchButton'
6
7
  export * from './components/SearchContext/SearchContext'
7
8
  export * from './components/SearchDivider/SearchDivider'
8
9
  export * from './components/SearchForm/SearchForm'
9
10
  export * from './components/SearchLink/SearchLink'
11
+ export * from './components/SearchFab/SearchFab'
10
12
  export * from './hooks/useProductList'
11
13
  export * from './components/ProductFiltersPro/ProductFiltersProCategorySectionSearch'
12
14
  export * from './components/ProductFiltersPro/ProductFiltersProSearchHeader'
@@ -23,4 +25,4 @@ export {
23
25
 
24
26
  export * from '@graphcommerce/magento-product/components/ProductFiltersPro'
25
27
  export * from './utils/productListApplySearchDefaults'
26
- export * from './components/ProductFiltersPro/ProductFiltersProSearchField'
28
+ export * from './components/ProductFiltersPro/SearchField'
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": "9.0.0-canary.98",
5
+ "version": "9.0.0",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,20 +12,22 @@
12
12
  }
13
13
  },
14
14
  "peerDependencies": {
15
- "@graphcommerce/ecommerce-ui": "^9.0.0-canary.98",
16
- "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.98",
17
- "@graphcommerce/graphql": "^9.0.0-canary.98",
18
- "@graphcommerce/image": "^9.0.0-canary.98",
19
- "@graphcommerce/magento-product": "^9.0.0-canary.98",
20
- "@graphcommerce/magento-store": "^9.0.0-canary.98",
21
- "@graphcommerce/next-ui": "^9.0.0-canary.98",
22
- "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.98",
23
- "@graphcommerce/react-hook-form": "^9.0.0-canary.98",
24
- "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.98",
15
+ "@graphcommerce/ecommerce-ui": "^9.0.0",
16
+ "@graphcommerce/eslint-config-pwa": "^9.0.0",
17
+ "@graphcommerce/framer-utils": "^9.0.0",
18
+ "@graphcommerce/graphql": "^9.0.0",
19
+ "@graphcommerce/image": "^9.0.0",
20
+ "@graphcommerce/magento-product": "^9.0.0",
21
+ "@graphcommerce/magento-store": "^9.0.0",
22
+ "@graphcommerce/next-ui": "^9.0.0",
23
+ "@graphcommerce/prettier-config-pwa": "^9.0.0",
24
+ "@graphcommerce/react-hook-form": "^9.0.0",
25
+ "@graphcommerce/typescript-config-pwa": "^9.0.0",
25
26
  "@lingui/core": "^4.2.1",
26
27
  "@lingui/macro": "^4.2.1",
27
28
  "@lingui/react": "^4.2.1",
28
29
  "@mui/material": "^5.10.16",
30
+ "framer-motion": "*",
29
31
  "next": "*",
30
32
  "react": "^18.2.0",
31
33
  "react-dom": "^18.2.0"
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "exclude": ["**/node_modules", "**/.*/"],
3
- "include": ["**/*.ts", "**/*.tsx"],
3
+ "include": ["**/*.ts", "**/*.tsx", "../magento-search-overlay/index.ts"],
4
4
  "extends": "@graphcommerce/typescript-config-pwa/nextjs.json"
5
5
  }
@@ -1,6 +1,11 @@
1
1
  import { cloneDeep, useQuery } from '@graphcommerce/graphql'
2
- import { ProductListParams, ProductListQueryVariables } from '@graphcommerce/magento-product'
3
- import { StoreConfigDocument, StoreConfigQuery } from '@graphcommerce/magento-store'
2
+ import type {
3
+ ProductFiltersQueryVariables,
4
+ ProductListParams,
5
+ ProductListQueryVariables,
6
+ } from '@graphcommerce/magento-product'
7
+ import type { StoreConfigQuery } from '@graphcommerce/magento-store'
8
+ import { StoreConfigDocument } from '@graphcommerce/magento-store'
4
9
 
5
10
  export function useProductListApplySearchDefaults(
6
11
  params: ProductListParams | undefined,
@@ -42,7 +47,7 @@ export function productListApplySearchDefaults(
42
47
 
43
48
  export function searchDefaultsToProductListFilters(
44
49
  variables: ProductListQueryVariables | undefined,
45
- ): ProductListQueryVariables {
50
+ ): ProductFiltersQueryVariables {
46
51
  return {
47
52
  ...variables,
48
53
  filters: {},