From 1d2da233ad991a291f307e7e275dff4c458531b2 Mon Sep 17 00:00:00 2001 From: Andrea Gueugnaut Date: Wed, 22 Jan 2025 19:21:29 +0100 Subject: [PATCH] fix(frontend): fix AppSelectNext types --- .../_app/AppSelect/AppSelectNext.tsx | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/_app/AppSelect/AppSelectNext.tsx b/frontend/src/components/_app/AppSelect/AppSelectNext.tsx index d7b7993f4..810fce420 100644 --- a/frontend/src/components/_app/AppSelect/AppSelectNext.tsx +++ b/frontend/src/components/_app/AppSelect/AppSelectNext.tsx @@ -6,7 +6,7 @@ import { MenuItem, Select as MuiSelect } from '@mui/material'; -import { ReactNode, useId } from 'react'; +import { useId } from 'react'; import { noop } from 'ts-essentials'; import { match, Pattern } from 'ts-pattern'; import { useController } from 'react-hook-form'; @@ -17,16 +17,25 @@ interface Option { value: Value; } -type AppSelectNextProps = BaseSelectProps & { +type AppSelectNextProps = Omit< + BaseSelectProps>, + 'multiple' | 'value' +> & { disabled?: boolean; name: string; options: ReadonlyArray>; + // Keep this until upgrading to MUI v6 + multiple?: Multiple; + value?: SelectValue; }; -function AppSelectNext< - Multiple extends boolean = false, - Value extends string | string[] = Multiple extends true ? string[] : string ->(props: AppSelectNextProps) { +type SelectValue = Multiple extends true + ? ReadonlyArray + : Value | null; + +function AppSelectNext( + props: AppSelectNextProps +) { const labelId = `fr-label-${useId()}`; const selectId = `fr-select-${useId()}`; @@ -39,7 +48,9 @@ function AppSelectNext< }); const isControlled = props.value !== undefined; - const value: Value | null = isControlled ? props.value : field.value; + const value: SelectValue = isControlled + ? props.value + : field.value; const onChange = isControlled ? props.onChange : field.onChange; return ( @@ -54,7 +65,6 @@ function AppSelectNext< icon: fr.cx('fr-hidden') }} disabled={props.disabled} - sx={{ width: '100%' }} displayEmpty label={props.label} id={selectId} @@ -80,27 +90,28 @@ function AppSelectNext< native={false} renderValue={(values) => { return match(values) - .returnType() .with(Pattern.string, (value) => { return props.options.find((option) => option.value === value) ?.label; }) .with(Pattern.array(Pattern.string), (values) => { - match(values.length).with(1, () => 'Une valeur sélectionnée'); + return match((values as string[]).length) + .with(1, () => '1 option sélectionnée') + .with( + Pattern.number.int().gte(2), + (nb) => `${nb} options sélectionnées` + ) + .otherwise(() => ''); }) .otherwise(() => ''); }} + sx={{ width: '100%' }} value={value ?? ''} variant="standard" onChange={onChange} > {props.options.map((option) => ( - + {!props.multiple ? ( option.label ) : (