fix(striker-ui): add getGroupLabel, apply useMemo, simplify props passthrough in autocomplete

main
Tsu-ba-me 11 months ago
parent 9bc2f2988c
commit 1f5bf604e1
  1. 160
      striker-ui/components/Autocomplete.tsx

@ -5,11 +5,14 @@ import {
AutocompleteRenderInputParams as MUIAutocompleteRenderInputParams, AutocompleteRenderInputParams as MUIAutocompleteRenderInputParams,
Box, Box,
Grow as MUIGrow, Grow as MUIGrow,
ListSubheader,
outlinedInputClasses as muiOutlinedInputClasses, outlinedInputClasses as muiOutlinedInputClasses,
Paper as MUIPaper, Paper as MUIPaper,
PaperProps as MUIPaperProps, PaperProps as MUIPaperProps,
svgIconClasses as muiSvgIconClasses, svgIconClasses as muiSvgIconClasses,
styled,
} from '@mui/material'; } from '@mui/material';
import { useMemo } from 'react';
import { GREY, TEXT } from '../lib/consts/DEFAULT_THEME'; import { GREY, TEXT } from '../lib/consts/DEFAULT_THEME';
@ -24,6 +27,7 @@ type AutocompleteOptionalProps = {
inputWithLabelProps: OutlinedInputWithLabelProps, inputWithLabelProps: OutlinedInputWithLabelProps,
renderInputParams?: MUIAutocompleteRenderInputParams, renderInputParams?: MUIAutocompleteRenderInputParams,
) => void; ) => void;
getGroupLabel?: (group: string) => React.ReactNode;
messageBoxProps?: Partial<MessageBoxProps>; messageBoxProps?: Partial<MessageBoxProps>;
}; };
@ -49,6 +53,12 @@ const GrowPaper = (paperProps: MUIPaperProps): JSX.Element => (
</MUIGrow> </MUIGrow>
); );
const GroupChildren = styled('ul')({
padding: 0,
});
const GroupHeader = ListSubheader;
const Autocomplete = < const Autocomplete = <
T, T,
Multiple extends boolean | undefined = undefined, Multiple extends boolean | undefined = undefined,
@ -60,77 +70,121 @@ const Autocomplete = <
const { const {
componentsProps, componentsProps,
extendRenderInput, extendRenderInput,
getGroupLabel,
label, label,
messageBoxProps, messageBoxProps,
renderGroup,
renderInput, renderInput,
sx, sx,
...autocompleteRestProps ...autocompleteRestProps
} = autocompleteProps; } = autocompleteProps;
const combinedComponentsProps: AutocompleteProps<
T, const combinedComponentsProps = useMemo<
Multiple, AutocompleteProps<
DisableClearable, T,
FreeSolo Multiple,
>['componentsProps'] = { DisableClearable,
paper: { FreeSolo
sx: { >['componentsProps']
backgroundColor: TEXT, >(
() => ({
[`& .${muiAutocompleteClasses.groupLabel}`]: { paper: {
sx: {
backgroundColor: TEXT, backgroundColor: TEXT,
[`& .${muiAutocompleteClasses.groupLabel}`]: {
backgroundColor: TEXT,
},
}, },
}, },
},
...componentsProps,
};
const combinedRenderInput =
renderInput ??
((renderInputParams) => {
const { fullWidth, InputProps, InputLabelProps, inputProps } =
renderInputParams;
const inputWithLabelProps: OutlinedInputWithLabelProps = {
formControlProps: {
fullWidth,
ref: InputProps.ref,
},
inputLabelProps: InputLabelProps,
inputProps: {
className: InputProps.className,
endAdornment: InputProps.endAdornment,
inputProps,
startAdornment: InputProps.startAdornment,
},
label,
};
extendRenderInput?.call(null, inputWithLabelProps, renderInputParams); ...componentsProps,
}),
[componentsProps],
);
const combinedRenderGroup = useMemo<
AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>['renderGroup']
>(() => {
if (renderGroup) return renderGroup;
return <OutlinedInputWithLabel {...inputWithLabelProps} />; return (
}); getGroupLabel &&
const combinedSx = { ((params) => (
[`& .${muiOutlinedInputClasses.root} .${muiAutocompleteClasses.endAdornment}`]: <li key={params.key}>
{ <GroupHeader
right: `7px`, component="div"
className={muiAutocompleteClasses.groupLabel}
>
{getGroupLabel(params.group)}
</GroupHeader>
<GroupChildren className={muiAutocompleteClasses.groupUl}>
{params.children}
</GroupChildren>
</li>
))
);
}, [getGroupLabel, renderGroup]);
[`& .${muiSvgIconClasses.root}`]: { const combinedRenderInput = useMemo<
color: GREY, Exclude<
AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>['renderInput'],
undefined
>
>(
() =>
renderInput ??
((params) => {
const { fullWidth, InputProps, InputLabelProps, inputProps } = params;
const inputWithLabelProps: OutlinedInputWithLabelProps = {
formControlProps: {
fullWidth,
ref: InputProps.ref,
},
inputLabelProps: InputLabelProps,
inputProps: {
className: InputProps.className,
endAdornment: InputProps.endAdornment,
inputProps,
startAdornment: InputProps.startAdornment,
},
label,
};
extendRenderInput?.call(null, inputWithLabelProps, params);
return <OutlinedInputWithLabel {...inputWithLabelProps} />;
}),
[extendRenderInput, label, renderInput],
);
const combinedSx = useMemo<
AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>['sx']
>(
() => ({
[`& .${muiOutlinedInputClasses.root} .${muiAutocompleteClasses.endAdornment}`]:
{
right: `7px`,
[`& .${muiSvgIconClasses.root}`]: {
color: GREY,
},
}, },
},
...sx, ...sx,
}; }),
[sx],
);
return ( return (
<Box sx={{ display: 'flex', flexDirection: 'column' }}> <Box sx={{ display: 'flex', flexDirection: 'column' }}>
<MUIAutocomplete <MUIAutocomplete
{...{ PaperComponent={GrowPaper}
PaperComponent: GrowPaper, {...autocompleteRestProps}
...autocompleteRestProps, componentsProps={combinedComponentsProps}
componentsProps: combinedComponentsProps, renderGroup={combinedRenderGroup}
renderInput: combinedRenderInput, renderInput={combinedRenderInput}
sx: combinedSx, sx={combinedSx}
}}
/> />
<InputMessageBox {...messageBoxProps} /> <InputMessageBox {...messageBoxProps} />
</Box> </Box>

Loading…
Cancel
Save