@graphcommerce/ecommerce-ui 9.0.0-canary.99 → 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.
- package/CHANGELOG.md +61 -946
- package/Config.graphqls +6 -0
- package/components/ApolloError/ApolloErrorAlert.tsx +3 -3
- package/components/ApolloError/ApolloErrorFullPage.tsx +4 -3
- package/components/ApolloError/ApolloErrorSnackbar.tsx +4 -3
- package/components/ApolloError/maskNetworkError.tsx +1 -1
- package/components/ComposedSubmitButton/ComposedSubmitButton.tsx +4 -3
- package/components/ComposedSubmitButton/ComposedSubmitLinkOrButton.tsx +4 -3
- package/components/FormComponents/ActionCardListForm.tsx +25 -13
- package/components/FormComponents/CheckboxButtonGroup.tsx +12 -3
- package/components/FormComponents/CheckboxElement.tsx +12 -7
- package/components/FormComponents/EmailElement.tsx +5 -2
- package/components/FormComponents/InputBaseElement.tsx +54 -0
- package/components/FormComponents/MultiSelectElement.tsx +8 -4
- package/components/FormComponents/NumberFieldElement.tsx +21 -15
- package/components/FormComponents/PasswordElement.tsx +8 -4
- package/components/FormComponents/PasswordRepeatElement.tsx +5 -2
- package/components/FormComponents/RadioButtonGroup.tsx +7 -3
- package/components/FormComponents/SelectElement.tsx +8 -12
- package/components/FormComponents/SliderElement.tsx +5 -14
- package/components/FormComponents/SwitchElement.tsx +5 -2
- package/components/FormComponents/TelephoneElement.tsx +6 -3
- package/components/FormComponents/TextFieldElement.tsx +22 -13
- package/components/FormComponents/ToggleButtonGroup.tsx +7 -12
- package/components/FormComponents/index.ts +1 -1
- package/components/PreviewMode/LightTooltip.tsx +1 -1
- package/components/PreviewMode/PreviewMode.tsx +14 -10
- package/components/PreviewMode/PreviewModeActions.tsx +2 -2
- package/components/PreviewMode/PreviewModeToolbar.tsx +1 -1
- package/components/PreviewMode/previewModeDefaults.ts +1 -1
- package/components/PreviewMode/usePreviewModeForm.ts +1 -1
- package/components/WaitForQueries/WaitForQueries.tsx +3 -6
- package/package.json +8 -8
- package/route/preview.ts +2 -2
- package/components/FormComponents/AutoCompleteElement.tsx +0 -169
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
FieldError,
|
|
4
|
-
FieldValues,
|
|
5
|
-
useController,
|
|
6
|
-
} from '@graphcommerce/react-hook-form'
|
|
1
|
+
import type { ControllerProps, FieldValues } from '@graphcommerce/react-hook-form'
|
|
2
|
+
import { useController } from '@graphcommerce/react-hook-form'
|
|
7
3
|
import { i18n } from '@lingui/core'
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
FormControlProps,
|
|
11
|
-
FormHelperText,
|
|
12
|
-
FormLabel,
|
|
13
|
-
Slider,
|
|
14
|
-
SliderProps,
|
|
15
|
-
} from '@mui/material'
|
|
4
|
+
import type { FormControlProps, SliderProps } from '@mui/material'
|
|
5
|
+
import { FormControl, FormHelperText, FormLabel, Slider } from '@mui/material'
|
|
16
6
|
|
|
17
7
|
export type SliderElementProps<T extends FieldValues> = Omit<SliderProps, 'control'> & {
|
|
18
8
|
label?: string
|
|
@@ -20,6 +10,7 @@ export type SliderElementProps<T extends FieldValues> = Omit<SliderProps, 'contr
|
|
|
20
10
|
formControlProps?: FormControlProps
|
|
21
11
|
} & Omit<ControllerProps<T>, 'render'>
|
|
22
12
|
|
|
13
|
+
/** @public */
|
|
23
14
|
export function SliderElement<TFieldValues extends FieldValues>({
|
|
24
15
|
name,
|
|
25
16
|
control,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { ControllerProps, FieldValues } from '@graphcommerce/react-hook-form'
|
|
2
|
+
import { useController } from '@graphcommerce/react-hook-form'
|
|
3
|
+
import type { FormControlLabelProps } from '@mui/material'
|
|
4
|
+
import { FormControlLabel, Switch } from '@mui/material'
|
|
3
5
|
|
|
4
6
|
type IProps = Omit<FormControlLabelProps, 'control'>
|
|
5
7
|
|
|
6
8
|
export type SwitchElementProps<T extends FieldValues> = IProps & Omit<ControllerProps<T>, 'render'>
|
|
7
9
|
|
|
10
|
+
/** @public */
|
|
8
11
|
export function SwitchElement<TFieldValues extends FieldValues>({
|
|
9
12
|
name,
|
|
10
13
|
control,
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { FieldValues
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { FieldValues } from '@graphcommerce/react-hook-form'
|
|
2
|
+
import { phonePattern } from '@graphcommerce/react-hook-form'
|
|
3
|
+
import { t, Trans } from '@lingui/macro'
|
|
4
|
+
import type { TextFieldElementProps } from './TextFieldElement'
|
|
5
|
+
import { TextFieldElement } from './TextFieldElement'
|
|
4
6
|
|
|
5
7
|
export type TelephoneElementProps<T extends FieldValues> = TextFieldElementProps<T>
|
|
6
8
|
|
|
9
|
+
/** @public */
|
|
7
10
|
export function TelephoneElement<TFieldValues extends FieldValues>(
|
|
8
11
|
props: TelephoneElementProps<TFieldValues>,
|
|
9
12
|
): JSX.Element {
|
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
2
|
import { InputCheckmark } from '@graphcommerce/next-ui'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
UseControllerProps,
|
|
6
|
-
emailPattern,
|
|
7
|
-
useController,
|
|
8
|
-
} from '@graphcommerce/react-hook-form'
|
|
3
|
+
import type { FieldValues, UseControllerProps } from '@graphcommerce/react-hook-form'
|
|
4
|
+
import { emailPattern, useController } from '@graphcommerce/react-hook-form'
|
|
9
5
|
import { i18n } from '@lingui/core'
|
|
10
|
-
import {
|
|
6
|
+
import type { TextFieldProps } from '@mui/material'
|
|
7
|
+
import { TextField, useForkRef } from '@mui/material'
|
|
8
|
+
import React, { useState } from 'react'
|
|
11
9
|
|
|
12
10
|
export type TextFieldElementProps<T extends FieldValues = FieldValues> = Omit<
|
|
13
11
|
TextFieldProps,
|
|
14
12
|
'name' | 'defaultValue'
|
|
15
13
|
> & {
|
|
16
|
-
/** @deprecated Please use the rules props instead */
|
|
17
|
-
validation?: UseControllerProps<T>['rules']
|
|
18
|
-
|
|
19
14
|
showValid?: boolean
|
|
20
15
|
} & UseControllerProps<T>
|
|
21
16
|
|
|
17
|
+
/** @public */
|
|
22
18
|
export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
23
|
-
validation = {},
|
|
24
19
|
type,
|
|
25
20
|
required,
|
|
26
21
|
name,
|
|
27
22
|
control,
|
|
28
23
|
defaultValue,
|
|
29
|
-
rules =
|
|
24
|
+
rules = {},
|
|
30
25
|
shouldUnregister,
|
|
31
26
|
showValid,
|
|
32
27
|
disabled,
|
|
@@ -48,20 +43,34 @@ export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
|
48
43
|
fieldState: { error },
|
|
49
44
|
} = useController({ name, control, rules, defaultValue, shouldUnregister, disabled })
|
|
50
45
|
|
|
46
|
+
// https://stackoverflow.com/questions/76830737/chrome-autofill-causes-textbox-collision-for-textfield-label-and-value
|
|
47
|
+
const [hasAutofill, setHasAutofill] = useState(false)
|
|
48
|
+
const shrink = hasAutofill || rest.InputLabelProps?.shrink || Boolean(value)
|
|
49
|
+
const onAnimationStart = (e: React.AnimationEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
50
|
+
if (e.target instanceof HTMLElement) {
|
|
51
|
+
const autofilled = !!e.target.matches('*:-webkit-autofill')
|
|
52
|
+
if (e.animationName === 'mui-auto-fill') setHasAutofill(autofilled)
|
|
53
|
+
if (e.animationName === 'mui-auto-fill-cancel') setHasAutofill(autofilled)
|
|
54
|
+
}
|
|
55
|
+
return rest.inputProps?.onAnimationStart?.(e)
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
return (
|
|
52
59
|
<TextField
|
|
53
60
|
{...rest}
|
|
54
61
|
{...field}
|
|
55
62
|
value={value}
|
|
63
|
+
inputProps={{ ...rest.inputProps, onAnimationStart }}
|
|
56
64
|
onChange={(ev) => {
|
|
57
65
|
onChange(type === 'number' && ev.target.value ? Number(ev.target.value) : ev.target.value)
|
|
58
66
|
rest.onChange?.(ev)
|
|
59
67
|
}}
|
|
60
|
-
inputRef={ref}
|
|
68
|
+
inputRef={useForkRef(ref, rest.inputRef)}
|
|
61
69
|
required={required}
|
|
62
70
|
type={type}
|
|
63
71
|
error={Boolean(error) || rest.error}
|
|
64
72
|
helperText={error ? error.message : rest.helperText}
|
|
73
|
+
InputLabelProps={{ ...rest.InputLabelProps, shrink }}
|
|
65
74
|
InputProps={{
|
|
66
75
|
...rest.InputProps,
|
|
67
76
|
endAdornment:
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
FieldError,
|
|
4
|
-
FieldValues,
|
|
5
|
-
useController,
|
|
6
|
-
} from '@graphcommerce/react-hook-form'
|
|
1
|
+
import type { ControllerProps, FieldValues } from '@graphcommerce/react-hook-form'
|
|
2
|
+
import { useController } from '@graphcommerce/react-hook-form'
|
|
7
3
|
import { i18n } from '@lingui/core'
|
|
4
|
+
import type { FormLabelProps, ToggleButtonGroupProps, ToggleButtonProps } from '@mui/material'
|
|
8
5
|
import {
|
|
9
6
|
FormControl,
|
|
10
7
|
FormHelperText,
|
|
11
8
|
FormLabel,
|
|
12
|
-
FormLabelProps,
|
|
13
9
|
ToggleButton,
|
|
14
10
|
ToggleButtonGroup,
|
|
15
|
-
ToggleButtonGroupProps,
|
|
16
|
-
ToggleButtonProps,
|
|
17
11
|
} from '@mui/material'
|
|
18
|
-
import { ReactNode } from 'react'
|
|
12
|
+
import type { ReactNode } from 'react'
|
|
19
13
|
|
|
20
14
|
type SingleToggleButtonProps = Omit<ToggleButtonProps, 'value' | 'children'> & {
|
|
21
15
|
id: number | string
|
|
@@ -30,6 +24,7 @@ export type ToggleButtonGroupElementProps<T extends FieldValues> = ToggleButtonG
|
|
|
30
24
|
helperText?: string
|
|
31
25
|
} & Omit<ControllerProps<T>, 'render'>
|
|
32
26
|
|
|
27
|
+
/** @public */
|
|
33
28
|
export function ToggleButtonGroupElement<TFieldValues extends FieldValues = FieldValues>({
|
|
34
29
|
name,
|
|
35
30
|
control,
|
|
@@ -87,9 +82,9 @@ export function ToggleButtonGroupElement<TFieldValues extends FieldValues = Fiel
|
|
|
87
82
|
}
|
|
88
83
|
}}
|
|
89
84
|
>
|
|
90
|
-
{options.map(({ label, id, ...toggleProps }) => (
|
|
85
|
+
{options.map(({ label: labelVal, id, ...toggleProps }) => (
|
|
91
86
|
<ToggleButton value={id} {...toggleProps} key={id}>
|
|
92
|
-
{
|
|
87
|
+
{labelVal}
|
|
93
88
|
</ToggleButton>
|
|
94
89
|
))}
|
|
95
90
|
</ToggleButtonGroup>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * from './ActionCardListForm'
|
|
2
|
-
export * from './AutoCompleteElement'
|
|
3
2
|
export * from './CheckboxButtonGroup'
|
|
4
3
|
export * from './CheckboxElement'
|
|
5
4
|
export * from './EmailElement'
|
|
@@ -14,3 +13,4 @@ export * from './SwitchElement'
|
|
|
14
13
|
export * from './TelephoneElement'
|
|
15
14
|
export * from './TextFieldElement'
|
|
16
15
|
export * from './ToggleButtonGroup'
|
|
16
|
+
export * from './InputBaseElement'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tooltip, styled, tooltipClasses } from '@mui/material'
|
|
2
2
|
|
|
3
3
|
export const LightTooltip = styled<typeof Tooltip>(({ className, ...props }) => (
|
|
4
4
|
<Tooltip {...props} classes={{ popper: className }} />
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { PreviewData } from '@graphcommerce/graphql'
|
|
1
|
+
import type { PreviewData } from '@graphcommerce/graphql'
|
|
2
2
|
import {
|
|
3
|
-
Button,
|
|
4
|
-
IconSvg,
|
|
5
|
-
MessageSnackbar,
|
|
6
3
|
iconChevronRight,
|
|
7
4
|
iconClose,
|
|
8
5
|
iconContrast,
|
|
9
6
|
iconInfo,
|
|
10
7
|
iconRefresh,
|
|
8
|
+
IconSvg,
|
|
9
|
+
MessageSnackbar,
|
|
11
10
|
} from '@graphcommerce/next-ui'
|
|
12
11
|
import { FormAutoSubmit, FormPersist, FormProvider, useForm } from '@graphcommerce/react-hook-form'
|
|
13
12
|
import { Box, IconButton } from '@mui/material'
|
|
@@ -16,9 +15,8 @@ import { TextFieldElement } from '../FormComponents'
|
|
|
16
15
|
import { LightTooltip } from './LightTooltip'
|
|
17
16
|
import { PreviewModeActions } from './PreviewModeActions'
|
|
18
17
|
import { PreviewModeToolbar } from './PreviewModeToolbar'
|
|
19
|
-
import { previewModeDefaults } from './previewModeDefaults'
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
function getPreviewUrl() {
|
|
22
20
|
const url = new URL(window.location.href)
|
|
23
21
|
url.pathname = '/api/preview'
|
|
24
22
|
;[...url.searchParams.entries()].forEach(([key]) => url.searchParams.delete(key))
|
|
@@ -26,9 +24,7 @@ export function getPreviewUrl() {
|
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
function PreviewModeEnabled() {
|
|
29
|
-
const form = useForm<{ secret: string; previewData: PreviewData }>({
|
|
30
|
-
defaultValues: { previewData: previewModeDefaults() },
|
|
31
|
-
})
|
|
27
|
+
const form = useForm<{ secret: string; previewData: PreviewData }>({})
|
|
32
28
|
|
|
33
29
|
const submit = form.handleSubmit((formValues) => {
|
|
34
30
|
const url = getPreviewUrl()
|
|
@@ -51,6 +47,7 @@ function PreviewModeEnabled() {
|
|
|
51
47
|
const revalidateHandler = form.handleSubmit((formValues) => {
|
|
52
48
|
const url = getPreviewUrl()
|
|
53
49
|
Object.entries(formValues).forEach(([key, value]) => {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
54
51
|
url.searchParams.append(key, `${value}`)
|
|
55
52
|
})
|
|
56
53
|
url.searchParams.append('action', 'revalidate')
|
|
@@ -102,7 +99,14 @@ function PreviewModeEnabled() {
|
|
|
102
99
|
}
|
|
103
100
|
|
|
104
101
|
function PreviewModeDisabled() {
|
|
105
|
-
const form = useForm<{ secret: string }>({
|
|
102
|
+
const form = useForm<{ secret: string }>({
|
|
103
|
+
defaultValues: {
|
|
104
|
+
secret:
|
|
105
|
+
process.env.NODE_ENV === 'development'
|
|
106
|
+
? (import.meta.graphCommerce.previewSecret ?? '')
|
|
107
|
+
: '',
|
|
108
|
+
},
|
|
109
|
+
})
|
|
106
110
|
|
|
107
111
|
const submit = form.handleSubmit((formValues) => {
|
|
108
112
|
const url = getPreviewUrl()
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { QueryResult } from '@graphcommerce/graphql'
|
|
1
|
+
import type { QueryResult } from '@graphcommerce/graphql'
|
|
2
2
|
import { useIsSSR } from '@graphcommerce/next-ui'
|
|
3
3
|
import React from 'react'
|
|
4
4
|
|
|
5
5
|
export type WaitForQueriesProps = {
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
7
|
waitFor: QueryResult<any, any> | boolean | (QueryResult<any, any> | boolean)[] | undefined
|
|
7
|
-
/**
|
|
8
|
-
* @deprecated Will be automatically correct.
|
|
9
|
-
*/
|
|
10
|
-
noSsr?: boolean
|
|
11
8
|
children: React.ReactNode
|
|
12
9
|
fallback?: React.ReactNode
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
/** Shows the fallback during: SSR, Hydration and Query Loading. */
|
|
16
|
-
export
|
|
13
|
+
export function WaitForQueries(props: WaitForQueriesProps) {
|
|
17
14
|
const { waitFor, fallback, children } = props
|
|
18
15
|
|
|
19
16
|
const mounted = !useIsSSR()
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/ecommerce-ui",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "9.0.0
|
|
5
|
+
"version": "9.0.0",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0
|
|
16
|
-
"@graphcommerce/graphql": "^9.0.0
|
|
17
|
-
"@graphcommerce/next-ui": "^9.0.0
|
|
18
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0
|
|
19
|
-
"@graphcommerce/react-hook-form": "^9.0.0
|
|
20
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0
|
|
15
|
+
"@graphcommerce/eslint-config-pwa": "^9.0.0",
|
|
16
|
+
"@graphcommerce/graphql": "^9.0.0",
|
|
17
|
+
"@graphcommerce/next-ui": "^9.0.0",
|
|
18
|
+
"@graphcommerce/prettier-config-pwa": "^9.0.0",
|
|
19
|
+
"@graphcommerce/react-hook-form": "^9.0.0",
|
|
20
|
+
"@graphcommerce/typescript-config-pwa": "^9.0.0",
|
|
21
21
|
"@lingui/core": "^4.2.1",
|
|
22
22
|
"@lingui/macro": "^4.2.1",
|
|
23
23
|
"@lingui/react": "^4.2.1",
|
|
24
24
|
"@mui/material": "^5.10.16",
|
|
25
|
-
"framer-motion": "^
|
|
25
|
+
"framer-motion": "^11.0.0",
|
|
26
26
|
"next": "*",
|
|
27
27
|
"react": "^18.2.0",
|
|
28
28
|
"react-dom": "^18.2.0"
|
package/route/preview.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PreviewData } from '@graphcommerce/graphql'
|
|
2
|
-
import { NextApiRequest, NextApiResponse } from 'next'
|
|
1
|
+
import type { PreviewData } from '@graphcommerce/graphql'
|
|
2
|
+
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
3
3
|
import { previewModeDefaults } from '../components/PreviewMode/previewModeDefaults'
|
|
4
4
|
|
|
5
5
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-restricted-imports */
|
|
2
|
-
import {
|
|
3
|
-
Controller,
|
|
4
|
-
ControllerProps,
|
|
5
|
-
FieldValues,
|
|
6
|
-
useController,
|
|
7
|
-
} from '@graphcommerce/react-hook-form'
|
|
8
|
-
import { i18n } from '@lingui/core'
|
|
9
|
-
import {
|
|
10
|
-
Autocomplete,
|
|
11
|
-
AutocompleteProps,
|
|
12
|
-
Checkbox,
|
|
13
|
-
TextField,
|
|
14
|
-
TextFieldProps,
|
|
15
|
-
CircularProgress,
|
|
16
|
-
} from '@mui/material'
|
|
17
|
-
|
|
18
|
-
export type AutocompleteElementProps<
|
|
19
|
-
F extends FieldValues,
|
|
20
|
-
T,
|
|
21
|
-
M extends boolean | undefined,
|
|
22
|
-
D extends boolean | undefined,
|
|
23
|
-
> = {
|
|
24
|
-
options: T[]
|
|
25
|
-
loading?: boolean
|
|
26
|
-
multiple?: M
|
|
27
|
-
matchId?: boolean
|
|
28
|
-
required?: boolean
|
|
29
|
-
label?: TextFieldProps['label']
|
|
30
|
-
showCheckbox?: boolean
|
|
31
|
-
autocompleteProps?: Omit<
|
|
32
|
-
AutocompleteProps<T, M, D, any>,
|
|
33
|
-
'name' | 'options' | 'loading' | 'renderInput'
|
|
34
|
-
>
|
|
35
|
-
textFieldProps?: Omit<TextFieldProps, 'name' | 'required' | 'label'>
|
|
36
|
-
} & ControllerProps<F>
|
|
37
|
-
|
|
38
|
-
type AutoDefault = {
|
|
39
|
-
id: string | number // must keep id in case of keepObject
|
|
40
|
-
label: string
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function AutocompleteElement<TFieldValues extends FieldValues>({
|
|
44
|
-
textFieldProps,
|
|
45
|
-
autocompleteProps,
|
|
46
|
-
name,
|
|
47
|
-
control,
|
|
48
|
-
options,
|
|
49
|
-
loading,
|
|
50
|
-
showCheckbox,
|
|
51
|
-
rules,
|
|
52
|
-
required,
|
|
53
|
-
multiple,
|
|
54
|
-
matchId,
|
|
55
|
-
label,
|
|
56
|
-
disabled,
|
|
57
|
-
defaultValue,
|
|
58
|
-
shouldUnregister,
|
|
59
|
-
}: AutocompleteElementProps<
|
|
60
|
-
TFieldValues,
|
|
61
|
-
AutoDefault | string | any,
|
|
62
|
-
boolean | undefined,
|
|
63
|
-
boolean | undefined
|
|
64
|
-
>) {
|
|
65
|
-
const validationRules: ControllerProps<TFieldValues>['rules'] = {
|
|
66
|
-
...rules,
|
|
67
|
-
...(required && {
|
|
68
|
-
required: rules?.required || i18n._(/* i18n */ 'This field is required'),
|
|
69
|
-
}),
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const {
|
|
73
|
-
field: { onChange, onBlur, value, ...fieldRest },
|
|
74
|
-
fieldState: { error },
|
|
75
|
-
} = useController({
|
|
76
|
-
name,
|
|
77
|
-
control,
|
|
78
|
-
rules: validationRules,
|
|
79
|
-
defaultValue,
|
|
80
|
-
disabled,
|
|
81
|
-
shouldUnregister,
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
const values = Array.isArray(value) ? (value as (typeof value)[]) : [value]
|
|
85
|
-
let currentValue = multiple ? value || [] : value || null
|
|
86
|
-
if (matchId) {
|
|
87
|
-
currentValue = multiple
|
|
88
|
-
? values.map((i: any) => options.find((j) => (j.id || j) === i))
|
|
89
|
-
: options.find((i) => (i.id || i) === value) || null
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<Autocomplete
|
|
94
|
-
{...autocompleteProps}
|
|
95
|
-
value={currentValue}
|
|
96
|
-
loading={loading}
|
|
97
|
-
multiple={multiple}
|
|
98
|
-
options={options}
|
|
99
|
-
disableCloseOnSelect={
|
|
100
|
-
typeof autocompleteProps?.disableCloseOnSelect === 'boolean'
|
|
101
|
-
? autocompleteProps.disableCloseOnSelect
|
|
102
|
-
: !!multiple
|
|
103
|
-
}
|
|
104
|
-
isOptionEqualToValue={
|
|
105
|
-
autocompleteProps?.isOptionEqualToValue
|
|
106
|
-
? autocompleteProps.isOptionEqualToValue
|
|
107
|
-
: (option, v) => (v ? option.id === (v?.id || v) : false)
|
|
108
|
-
}
|
|
109
|
-
getOptionLabel={
|
|
110
|
-
autocompleteProps?.getOptionLabel
|
|
111
|
-
? autocompleteProps.getOptionLabel
|
|
112
|
-
: (option) => `${option?.label || option}`
|
|
113
|
-
}
|
|
114
|
-
onChange={(event, value, reason, details) => {
|
|
115
|
-
let changedVal = value
|
|
116
|
-
if (matchId) {
|
|
117
|
-
changedVal = Array.isArray(value) ? value.map((i: any) => i?.id || i) : value?.id || value
|
|
118
|
-
}
|
|
119
|
-
onChange(changedVal)
|
|
120
|
-
if (autocompleteProps?.onChange) {
|
|
121
|
-
autocompleteProps.onChange(event, value, reason, details)
|
|
122
|
-
}
|
|
123
|
-
}}
|
|
124
|
-
renderOption={
|
|
125
|
-
autocompleteProps?.renderOption ??
|
|
126
|
-
(showCheckbox
|
|
127
|
-
? (props, option, { selected }) => (
|
|
128
|
-
<li {...props}>
|
|
129
|
-
<Checkbox sx={{ marginRight: 1 }} checked={selected} />
|
|
130
|
-
{autocompleteProps?.getOptionLabel?.(option) || option.label || option}
|
|
131
|
-
</li>
|
|
132
|
-
)
|
|
133
|
-
: undefined)
|
|
134
|
-
}
|
|
135
|
-
onBlur={(event) => {
|
|
136
|
-
onBlur()
|
|
137
|
-
if (typeof autocompleteProps?.onBlur === 'function') {
|
|
138
|
-
autocompleteProps.onBlur(event)
|
|
139
|
-
}
|
|
140
|
-
}}
|
|
141
|
-
renderInput={(params) => (
|
|
142
|
-
<TextField
|
|
143
|
-
name={name}
|
|
144
|
-
required={rules?.required ? true : required}
|
|
145
|
-
label={label}
|
|
146
|
-
{...textFieldProps}
|
|
147
|
-
{...params}
|
|
148
|
-
error={!!error}
|
|
149
|
-
InputProps={{
|
|
150
|
-
...params.InputProps,
|
|
151
|
-
endAdornment: (
|
|
152
|
-
<>
|
|
153
|
-
{loading ? <CircularProgress color='inherit' size={20} /> : null}
|
|
154
|
-
{params.InputProps.endAdornment}
|
|
155
|
-
</>
|
|
156
|
-
),
|
|
157
|
-
...textFieldProps?.InputProps,
|
|
158
|
-
}}
|
|
159
|
-
inputProps={{
|
|
160
|
-
...params.inputProps,
|
|
161
|
-
...textFieldProps?.inputProps,
|
|
162
|
-
}}
|
|
163
|
-
helperText={error ? error.message : textFieldProps?.helperText}
|
|
164
|
-
/>
|
|
165
|
-
)}
|
|
166
|
-
{...fieldRest}
|
|
167
|
-
/>
|
|
168
|
-
)
|
|
169
|
-
}
|