From 3b56f582e20dd63ddef991ee1881e438767eec00 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 29 Sep 2023 11:07:48 +0530 Subject: [PATCH 01/27] add mutiple in Props.ts --- packages/mui-joy/src/Select/SelectProps.ts | 40 ++++++++++++---------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/mui-joy/src/Select/SelectProps.ts b/packages/mui-joy/src/Select/SelectProps.ts index 0ab6e0c6822f9b..3af60330845543 100644 --- a/packages/mui-joy/src/Select/SelectProps.ts +++ b/packages/mui-joy/src/Select/SelectProps.ts @@ -53,14 +53,14 @@ export interface SelectPropsVariantOverrides {} export interface SelectPropsColorOverrides {} export interface SelectPropsSizeOverrides {} -export type SelectSlotsAndSlotProps = CreateSlotsAndSlotProps< +export type SelectSlotsAndSlotProps = CreateSlotsAndSlotProps< SelectSlots, { - root: SlotProps<'div', {}, SelectOwnerState>; - button: SlotProps<'button', {}, SelectOwnerState>; - startDecorator: SlotProps<'span', {}, SelectOwnerState>; - endDecorator: SlotProps<'span', {}, SelectOwnerState>; - indicator: SlotProps<'span', {}, SelectOwnerState>; + root: SlotProps<'div', {}, SelectOwnerState>; + button: SlotProps<'button', {}, SelectOwnerState>; + startDecorator: SlotProps<'span', {}, SelectOwnerState>; + endDecorator: SlotProps<'span', {}, SelectOwnerState>; + indicator: SlotProps<'span', {}, SelectOwnerState>; listbox: SlotProps< 'ul', { @@ -68,7 +68,7 @@ export type SelectSlotsAndSlotProps = CreateSlotsAndSlotProps< variant?: OverridableStringUnion; size?: OverridableStringUnion<'sm' | 'md' | 'lg', SelectPropsSizeOverrides>; } & Omit, - SelectOwnerState + SelectOwnerState >; } >; @@ -165,40 +165,40 @@ export interface SelectStaticProps { variant?: OverridableStringUnion; } -export type SelectOwnProps = SelectStaticProps & - SelectSlotsAndSlotProps & { +export type SelectOwnProps = SelectStaticProps & + SelectSlotsAndSlotProps & { /** * The default selected value. Use when the component is not controlled. */ - defaultValue?: OptionValue | null; + defaultValue?: SelectValue; /** * A function to convert the currently selected value to a string. * Used to set a value of a hidden input associated with the select, * so that the selected value can be posted with a form. */ getSerializedValue?: ( - option: SelectValue, false>, + option: SelectValue, Multiple>, ) => React.InputHTMLAttributes['value']; /** * Callback fired when an option is selected. */ onChange?: ( event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, - value: OptionValue | null, + value: SelectValue, ) => void; /** * Function that customizes the rendering of the selected value. */ - renderValue?: (option: SelectOption | null) => React.ReactNode; + renderValue?: (option: SelectValue, Multiple>) => React.ReactNode; /** * The selected value. * Set to `null` to deselect all options. */ - value?: OptionValue | null; + value?: SelectValue; }; -export interface SelectOwnerState - extends ApplyColorInversion> { +export interface SelectOwnerState + extends ApplyColorInversion> { /** * If `true`, the select button is active. */ @@ -219,16 +219,18 @@ export interface SelectOwnerState export interface SelectTypeMap< OptionValue extends {}, + Multiple extends boolean = false, P = {}, D extends React.ElementType = 'button', > { - props: P & SelectOwnProps; + props: P & SelectOwnProps; defaultComponent: D; } export type SelectProps< OptionValue extends {}, - D extends React.ElementType = SelectTypeMap['defaultComponent'], -> = OverrideProps, D> & { + Multiple extends boolean, + D extends React.ElementType = SelectTypeMap['defaultComponent'], +> = OverrideProps, D> & { component?: D; }; From d653462a9384c0e022e83088c797427cbd8f7a46 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 29 Sep 2023 12:39:38 +0530 Subject: [PATCH 02/27] add mutiple in select.tsx --- packages/mui-joy/src/Select/Select.tsx | 30 ++++++++++++++-------- packages/mui-joy/src/Select/SelectProps.ts | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index 2b3f19a198941f..b1060523085668 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -5,7 +5,7 @@ import clsx from 'clsx'; import { OverrideProps, DefaultComponentProps } from '@mui/types'; import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef } from '@mui/utils'; import { Popper, PopperProps } from '@mui/base/Popper'; -import { useSelect, SelectProvider } from '@mui/base/useSelect'; +import { useSelect, SelectProvider, SelectValue } from '@mui/base/useSelect'; import { SelectOption } from '@mui/base/useOption'; import { unstable_composeClasses as composeClasses } from '@mui/base/composeClasses'; import { StyledList } from '../List/List'; @@ -22,10 +22,15 @@ import { ListOwnerState } from '../List'; import FormControlContext from '../FormControl/FormControlContext'; import { VariantColorProvider } from '../styles/variantColorInheritance'; -function defaultRenderSingleValue(selectedOption: SelectOption | null) { - return selectedOption?.label ?? ''; -} +function defaultRenderValue( + selectedOptions: SelectOption | SelectOption[] | null, +) { + if (Array.isArray(selectedOptions)) { + return {selectedOptions.map((o) => o.label).join(', ')}; + } + return selectedOptions?.label ?? ''; +} const defaultModifiers: PopperProps['modifiers'] = [ { name: 'offset', @@ -311,8 +316,8 @@ const SelectIndicator = styled('span', { * * - [Select API](https://mui.com/joy-ui/api/select/) */ -const Select = React.forwardRef(function Select( - inProps: SelectOwnProps, +const Select = React.forwardRef(function Select( + inProps: SelectOwnProps, ref: React.ForwardedRef, ) { const props = useThemeProps({ @@ -383,7 +388,9 @@ const Select = React.forwardRef(function Select( formControl?.error ? 'danger' : formControl?.color ?? colorProp, ); - const renderValue = renderValueProp ?? defaultRenderSingleValue; + const renderValue: (option: SelectValue, Multiple>) => React.ReactNode = + renderValueProp ?? defaultRenderValue; + const [anchorEl, setAnchorEl] = React.useState(null); const rootRef = React.useRef(null); @@ -440,7 +447,7 @@ const Select = React.forwardRef(function Select( disabled: disabledProp, getSerializedValue, listboxId, - multiple: false, + multiple: false as Multiple, name, required, onChange, @@ -467,10 +474,13 @@ const Select = React.forwardRef(function Select( const externalForwardedProps = { ...other, slots, slotProps }; const selectedOption = React.useMemo( - () => getOptionMetadata(value as TValue) ?? null, + () => + (getOptionMetadata(value as TValue) ?? null) as SelectValue, Multiple>, [getOptionMetadata, value], ); + // SelectValue, Multiple> + const [SlotRoot, rootProps] = useSlot('root', { ref: handleRef, className: classes.root, @@ -512,7 +522,7 @@ const Select = React.forwardRef(function Select( nesting: false, row: false, wrap: false, - } as SelectOwnerState & ListOwnerState, + } as SelectOwnerState & ListOwnerState, getSlotOwnerState: (mergedProps) => ({ size: mergedProps.size || size, variant: mergedProps.variant || variant, diff --git a/packages/mui-joy/src/Select/SelectProps.ts b/packages/mui-joy/src/Select/SelectProps.ts index 3af60330845543..768f61ab2a77ae 100644 --- a/packages/mui-joy/src/Select/SelectProps.ts +++ b/packages/mui-joy/src/Select/SelectProps.ts @@ -177,7 +177,7 @@ export type SelectOwnProps = S * so that the selected value can be posted with a form. */ getSerializedValue?: ( - option: SelectValue, Multiple>, + option: SelectValue, Multiple>, ) => React.InputHTMLAttributes['value']; /** * Callback fired when an option is selected. From 7723f2263908d2f5563212dd22ca661a3e641bd8 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:10:33 +0530 Subject: [PATCH 03/27] fix types --- packages/mui-joy/src/Select/Select.tsx | 14 +++++++------- packages/mui-joy/src/Select/SelectProps.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index b1060523085668..56a848e9e7ab45 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -50,7 +50,7 @@ const defaultModifiers: PopperProps['modifiers'] = [ }, ]; -const useUtilityClasses = (ownerState: SelectOwnerState) => { +const useUtilityClasses = (ownerState: SelectOwnerState) => { const { color, disabled, focusVisible, size, variant, open } = ownerState; const slots = { @@ -77,7 +77,7 @@ const SelectRoot = styled('div', { name: 'JoySelect', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: SelectOwnerState }>(({ theme, ownerState }) => { +})<{ ownerState: SelectOwnerState }>(({ theme, ownerState }) => { const variantStyle = theme.variants[`${ownerState.variant!}`]?.[ownerState.color!]; const { borderRadius } = resolveSxValue({ theme, ownerState }, ['borderRadius']); return [ @@ -186,7 +186,7 @@ const SelectButton = styled('button', { name: 'JoySelect', slot: 'Button', overridesResolver: (props, styles) => styles.button, -})<{ ownerState: SelectOwnerState }>(({ ownerState }) => ({ +})<{ ownerState: SelectOwnerState }>(({ ownerState }) => ({ // reset user-agent button style border: 0, outline: 0, @@ -223,7 +223,7 @@ const SelectListbox = styled(StyledList, { name: 'JoySelect', slot: 'Listbox', overridesResolver: (props, styles) => styles.listbox, -})<{ ownerState: SelectOwnerState }>(({ theme, ownerState }) => { +})<{ ownerState: SelectOwnerState }>(({ theme, ownerState }) => { const variantStyle = ownerState.color === 'context' ? undefined @@ -254,7 +254,7 @@ const SelectStartDecorator = styled('span', { name: 'JoySelect', slot: 'StartDecorator', overridesResolver: (props, styles) => styles.startDecorator, -})<{ ownerState: SelectOwnerState }>({ +})<{ ownerState: SelectOwnerState }>({ '--Button-margin': '0 0 0 calc(var(--Select-decoratorChildOffset) * -1)', '--IconButton-margin': '0 0 0 calc(var(--Select-decoratorChildOffset) * -1)', '--Icon-margin': '0 0 0 calc(var(--Select-paddingInline) / -4)', @@ -268,7 +268,7 @@ const SelectEndDecorator = styled('span', { name: 'JoySelect', slot: 'EndDecorator', overridesResolver: (props, styles) => styles.endDecorator, -})<{ ownerState: SelectOwnerState }>({ +})<{ ownerState: SelectOwnerState }>({ '--Button-margin': '0 calc(var(--Select-decoratorChildOffset) * -1) 0 0', '--IconButton-margin': '0 calc(var(--Select-decoratorChildOffset) * -1) 0 0', '--Icon-margin': '0 calc(var(--Select-paddingInline) / -4) 0 0', @@ -281,7 +281,7 @@ const SelectEndDecorator = styled('span', { const SelectIndicator = styled('span', { name: 'JoySelect', slot: 'Indicator', -})<{ ownerState: SelectOwnerState }>(({ ownerState, theme }) => ({ +})<{ ownerState: SelectOwnerState }>(({ ownerState, theme }) => ({ ...(ownerState.size === 'sm' && { '--Icon-fontSize': theme.vars.fontSize.lg, }), diff --git a/packages/mui-joy/src/Select/SelectProps.ts b/packages/mui-joy/src/Select/SelectProps.ts index 768f61ab2a77ae..3af60330845543 100644 --- a/packages/mui-joy/src/Select/SelectProps.ts +++ b/packages/mui-joy/src/Select/SelectProps.ts @@ -177,7 +177,7 @@ export type SelectOwnProps = S * so that the selected value can be posted with a form. */ getSerializedValue?: ( - option: SelectValue, Multiple>, + option: SelectValue, Multiple>, ) => React.InputHTMLAttributes['value']; /** * Callback fired when an option is selected. From 6a7961b8ecab33bedd93bed722720641c7c11919 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:01:10 +0530 Subject: [PATCH 04/27] fix types --- packages/mui-joy/src/Select/Select.spec.tsx | 12 ++++++------ packages/mui-joy/src/Select/Select.tsx | 7 +++---- packages/mui-joy/src/Select/SelectProps.ts | 3 ++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/mui-joy/src/Select/Select.spec.tsx b/packages/mui-joy/src/Select/Select.spec.tsx index a5f4084c690a5e..90ddb9d95b3121 100644 --- a/packages/mui-joy/src/Select/Select.spec.tsx +++ b/packages/mui-joy/src/Select/Select.spec.tsx @@ -105,37 +105,37 @@ interface Value { + + + + + + ); +} diff --git a/docs/data/joy/components/select/SelectMultiple.tsx b/docs/data/joy/components/select/SelectMultiple.tsx new file mode 100644 index 00000000000000..fa69a136724b32 --- /dev/null +++ b/docs/data/joy/components/select/SelectMultiple.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import Select from '@mui/joy/Select'; +import Option from '@mui/joy/Option'; + +export default function SelectMultiple() { + const handleChange = ( + event: React.SyntheticEvent | null, + newValue: Array | null, + ) => { + console.log(`You have choosen "${newValue}"`); + }; + return ( + + ); +} diff --git a/docs/data/joy/components/select/select.md b/docs/data/joy/components/select/select.md index 9007ed7ed01cdd..d5ab0f288b43ef 100644 --- a/docs/data/joy/components/select/select.md +++ b/docs/data/joy/components/select/select.md @@ -123,6 +123,15 @@ const App = () => ( ); ``` +### Multiple selections + +Set the `multiple` prop to let your users select multiple options from the list. +In contrast with single-selection mode, the options popup doesn't close after an item is selected, which enables users to continue choosing more options. + +Note that in multiple selection mode, the `value` prop (and `defaultValue`) is an array. + +{{"demo": "SelectMultiple.js", "defaultCodeOpen": false}} + ### Listbox #### Maximum height diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index dfd9fa2671e82a..6dde81084fe1d1 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -477,14 +477,21 @@ const Select = React.forwardRef(function Select & typeof other; - const selectedOption = React.useMemo( - () => - (getOptionMetadata(value as OptionValue) ?? null) as SelectValue< + const selectedOption = React.useMemo(() => { + let selectedOptionsMetadata: SelectValue, Multiple>; + if (multiple) { + selectedOptionsMetadata = (value as OptionValue[]) + .map((v) => getOptionMetadata(v)) + .filter((o) => o !== undefined) as SelectValue, Multiple>; + } else { + selectedOptionsMetadata = (getOptionMetadata(value as OptionValue) ?? null) as SelectValue< SelectOption, Multiple - >, - [getOptionMetadata, value], - ); + >; + } + + return selectedOptionsMetadata; + }, [getOptionMetadata, value, multiple]); const [SlotRoot, rootProps] = useSlot('root', { ref: handleRef, @@ -616,6 +623,11 @@ interface SelectComponent { ( props: DefaultComponentProps>, ): JSX.Element | null; + ( + props: { + multiple?: Multiple; + } & DefaultComponentProps>, + ): JSX.Element | null; propTypes?: any; } diff --git a/packages/mui-joy/src/Select/SelectProps.ts b/packages/mui-joy/src/Select/SelectProps.ts index b91ea4fe6865a3..bb32ef7e23dc94 100644 --- a/packages/mui-joy/src/Select/SelectProps.ts +++ b/packages/mui-joy/src/Select/SelectProps.ts @@ -171,12 +171,18 @@ export type SelectOwnProps = S * The default selected value. Use when the component is not controlled. */ defaultValue?: SelectValue; + /** + * If `true`, selecting multiple values is allowed. + * This affects the type of the `value`, `defaultValue`, and `onChange` props. + * + * @default false + */ + multiple?: Multiple; /** * A function to convert the currently selected value to a string. * Used to set a value of a hidden input associated with the select, * so that the selected value can be posted with a form. */ - multiple?: Multiple; getSerializedValue?: ( option: SelectValue, Multiple>, ) => React.InputHTMLAttributes['value']; From 1dba21a809449b8939d79765feffed0e29d2e2e5 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:42:36 +0530 Subject: [PATCH 11/27] ran static scripts --- .../data/joy/components/select/SelectMultiple.js | 16 +++++++++++++++- .../joy/components/select/SelectMultiple.tsx | 16 +++++++++++++++- docs/pages/joy-ui/api/select.json | 1 + .../translations/api-docs-joy/select/select.json | 3 +++ packages/mui-joy/src/Select/Select.tsx | 7 +++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/docs/data/joy/components/select/SelectMultiple.js b/docs/data/joy/components/select/SelectMultiple.js index 0e446a4e5962ea..85e43ba38cb004 100644 --- a/docs/data/joy/components/select/SelectMultiple.js +++ b/docs/data/joy/components/select/SelectMultiple.js @@ -7,7 +7,21 @@ export default function SelectMultiple() { console.log(`You have choosen "${newValue}"`); }; return ( - diff --git a/docs/data/joy/components/select/SelectMultiple.tsx b/docs/data/joy/components/select/SelectMultiple.tsx index fa69a136724b32..2f576ef505201c 100644 --- a/docs/data/joy/components/select/SelectMultiple.tsx +++ b/docs/data/joy/components/select/SelectMultiple.tsx @@ -10,7 +10,21 @@ export default function SelectMultiple() { console.log(`You have choosen "${newValue}"`); }; return ( - diff --git a/docs/pages/joy-ui/api/select.json b/docs/pages/joy-ui/api/select.json index af8f6611339328..62656eef2230d3 100644 --- a/docs/pages/joy-ui/api/select.json +++ b/docs/pages/joy-ui/api/select.json @@ -113,6 +113,7 @@ "disabled", "expanded", "focusVisible", + "multiple", "popper", "sizeLg", "sizeMd", diff --git a/docs/translations/api-docs-joy/select/select.json b/docs/translations/api-docs-joy/select/select.json index e3f5399432fec2..bbcdf3b0582159 100644 --- a/docs/translations/api-docs-joy/select/select.json +++ b/docs/translations/api-docs-joy/select/select.json @@ -85,6 +85,9 @@ "description": "Class name applied to {{nodeName}}.", "nodeName": "the listbox slot" }, + "multiple": { + "description": "Class name applied to the root slot if multiple=true" + }, "colorPrimary": { "description": "Class name applied to {{nodeName}} if {{conditions}}.", "nodeName": "the root slot", diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index 6dde81084fe1d1..a1c0006f71a2a4 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -714,6 +714,13 @@ Select.propTypes /* remove-proptypes */ = { * @default undefined */ listboxOpen: PropTypes.bool, + /** + * If `true`, selecting multiple values is allowed. + * This affects the type of the `value`, `defaultValue`, and `onChange` props. + * + * @default false + */ + multiple: PropTypes.bool, /** * Name of the element. For example used by the server to identify the fields in form submits. * If the name is provided, the component will render a hidden input element that can be submitted to a server. From b6ffd0825c9b21d421e7df701f2a0f4ab47f2b71 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Sun, 15 Oct 2023 14:41:53 +0530 Subject: [PATCH 12/27] docs:api --- docs/pages/joy-ui/api/select.json | 1 + docs/translations/api-docs-joy/select/select.json | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/pages/joy-ui/api/select.json b/docs/pages/joy-ui/api/select.json index 62656eef2230d3..7e2c557988416d 100644 --- a/docs/pages/joy-ui/api/select.json +++ b/docs/pages/joy-ui/api/select.json @@ -23,6 +23,7 @@ "indicator": { "type": { "name": "node" } }, "listboxId": { "type": { "name": "string" } }, "listboxOpen": { "type": { "name": "bool" } }, + "multiple": { "type": { "name": "bool" } }, "name": { "type": { "name": "string" } }, "onChange": { "type": { "name": "func" } }, "onClose": { "type": { "name": "func" } }, diff --git a/docs/translations/api-docs-joy/select/select.json b/docs/translations/api-docs-joy/select/select.json index bbcdf3b0582159..248396717d8ae2 100644 --- a/docs/translations/api-docs-joy/select/select.json +++ b/docs/translations/api-docs-joy/select/select.json @@ -31,6 +31,9 @@ "description": "id attribute of the listbox element. Also used to derive the id attributes of options." }, "listboxOpen": { "description": "Controls the open state of the select's listbox." }, + "multiple": { + "description": "If true, selecting multiple values is allowed. This affects the type of the value, defaultValue, and onChange props." + }, "name": { "description": "Name of the element. For example used by the server to identify the fields in form submits. If the name is provided, the component will render a hidden input element that can be submitted to a server." }, From ca191f6497a25878d25d64781f1372beafa92fa2 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:55:54 +0530 Subject: [PATCH 13/27] fix types --- packages/mui-joy/src/styles/extendTheme.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/mui-joy/src/styles/extendTheme.spec.ts b/packages/mui-joy/src/styles/extendTheme.spec.ts index 38c31364a17de1..4123819575c786 100644 --- a/packages/mui-joy/src/styles/extendTheme.spec.ts +++ b/packages/mui-joy/src/styles/extendTheme.spec.ts @@ -1012,37 +1012,37 @@ extendTheme({ }, styleOverrides: { root: ({ ownerState }) => { - expectType & Record, typeof ownerState>( + expectType & Record, typeof ownerState>( ownerState, ); return {}; }, button: ({ ownerState }) => { - expectType & Record, typeof ownerState>( + expectType & Record, typeof ownerState>( ownerState, ); return {}; }, startDecorator: ({ ownerState }) => { - expectType & Record, typeof ownerState>( + expectType & Record, typeof ownerState>( ownerState, ); return {}; }, endDecorator: ({ ownerState }) => { - expectType & Record, typeof ownerState>( + expectType & Record, typeof ownerState>( ownerState, ); return {}; }, indicator: ({ ownerState }) => { - expectType & Record, typeof ownerState>( + expectType & Record, typeof ownerState>( ownerState, ); return {}; }, listbox: ({ ownerState }) => { - expectType & Record, typeof ownerState>( + expectType & Record, typeof ownerState>( ownerState, ); return {}; From 3b63d414405cdadc0d76de813276485c4c67139d Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:19:54 +0530 Subject: [PATCH 14/27] add ts tests --- packages/mui-joy/src/Select/Select.spec.tsx | 13 +++++++++++++ packages/mui-joy/src/Select/Select.tsx | 13 ++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/mui-joy/src/Select/Select.spec.tsx b/packages/mui-joy/src/Select/Select.spec.tsx index 90ddb9d95b3121..499432a1825992 100644 --- a/packages/mui-joy/src/Select/Select.spec.tsx +++ b/packages/mui-joy/src/Select/Select.spec.tsx @@ -142,3 +142,16 @@ interface Value { }, }} />; + +// @ts-expect-error + value={[10]} />; + value={[10]} />; +; +// @ts-expect-error +; + +; diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index a1c0006f71a2a4..508b67a6041e40 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -618,7 +618,18 @@ interface SelectComponent { * Either a string to use a HTML element or a component. */ component: C; - } & OverrideProps, C>, + multiple?: false; + } & OverrideProps, C>, + ): JSX.Element | null; + ( + props: { + /** + * The component used for the root node. + * Either a string to use a HTML element or a component. + */ + component: C; + multiple: Multiple; + } & OverrideProps, C>, ): JSX.Element | null; ( props: DefaultComponentProps>, From da543e5a845db680b162bc910f48e7334b4d40e8 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:45:56 +0530 Subject: [PATCH 15/27] add ts tests --- packages/mui-joy/src/Select/Select.spec.tsx | 6 ++++++ packages/mui-joy/src/Select/Select.tsx | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/mui-joy/src/Select/Select.spec.tsx b/packages/mui-joy/src/Select/Select.spec.tsx index 499432a1825992..4c951b5e2aabff 100644 --- a/packages/mui-joy/src/Select/Select.spec.tsx +++ b/packages/mui-joy/src/Select/Select.spec.tsx @@ -154,4 +154,10 @@ interface Value { ; +// @ts-expect-error +; + +// @ts-expect-error +; ; + value={[10]} />; + value={[10]} component="a" />; +; +; -; // @ts-expect-error ; // @ts-expect-error ; - // @ts-expect-error ; - value={[10]} />; +const handleChange = ( + e: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, + val: number | null, +) => {}; + +const handleMultiChange = ( + e: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, + val: number[] | null, +) => {}; + +; ; + + handleMultiChange(event)} +/>; + + + defaultValue={[10]} + // @ts-expect-error + onChange={(event) => handleChange(event)} +/>; + // @ts-expect-error value={[10]} />; // @ts-expect-error From 6398e3e71d6cc40e48a144582953a84649470464 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:46:02 +0530 Subject: [PATCH 20/27] proptypes --- packages/mui-joy/src/Select/Select.test.tsx | 28 +++++++++++++++++++++ packages/mui-joy/src/Select/Select.tsx | 2 -- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/mui-joy/src/Select/Select.test.tsx b/packages/mui-joy/src/Select/Select.test.tsx index 06c7060b14c3ba..550b2e3f53bd35 100644 --- a/packages/mui-joy/src/Select/Select.test.tsx +++ b/packages/mui-joy/src/Select/Select.test.tsx @@ -646,4 +646,32 @@ describe('Joy values.map((v) => `${v.label} (${v.value})`).join(', ')} + > + + + , + ); + + expect(getByRole('combobox')).to.have.text('One (1), Two (2)'); + }); + + it('renders the selected values (multiple) as comma-separated list of labels if renderValue is not provided', () => { + const { getByRole } = render( + , + ); + + expect(getByRole('combobox')).to.have.text('One, Two'); + }); + }); }); diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index 2909eced90851b..0bf261300def0d 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -715,8 +715,6 @@ Select.propTypes /* remove-proptypes */ = { /** * If `true`, selecting multiple values is allowed. * This affects the type of the `value`, `defaultValue`, and `onChange` props. - * - * @default false */ multiple: PropTypes.bool, /** From a0bd5e46072d8588607277e61e93b813e5a8e920 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:18:27 +0530 Subject: [PATCH 21/27] add-demo --- .../select/SelectMultipleAppearance.js | 37 +++++++++++++++++++ .../select/SelectMultipleAppearance.tsx | 37 +++++++++++++++++++ docs/data/joy/components/select/select.md | 12 +++++- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 docs/data/joy/components/select/SelectMultipleAppearance.js create mode 100644 docs/data/joy/components/select/SelectMultipleAppearance.tsx diff --git a/docs/data/joy/components/select/SelectMultipleAppearance.js b/docs/data/joy/components/select/SelectMultipleAppearance.js new file mode 100644 index 00000000000000..0e4a75297de6a2 --- /dev/null +++ b/docs/data/joy/components/select/SelectMultipleAppearance.js @@ -0,0 +1,37 @@ +import * as React from 'react'; +import Select from '@mui/joy/Select'; +import Option from '@mui/joy/Option'; +import { Box, Chip } from '@mui/joy'; + +export default function SelectMultipleAppearance() { + return ( + + ); +} diff --git a/docs/data/joy/components/select/SelectMultipleAppearance.tsx b/docs/data/joy/components/select/SelectMultipleAppearance.tsx new file mode 100644 index 00000000000000..0e4a75297de6a2 --- /dev/null +++ b/docs/data/joy/components/select/SelectMultipleAppearance.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; +import Select from '@mui/joy/Select'; +import Option from '@mui/joy/Option'; +import { Box, Chip } from '@mui/joy'; + +export default function SelectMultipleAppearance() { + return ( + + ); +} diff --git a/docs/data/joy/components/select/select.md b/docs/data/joy/components/select/select.md index d5ab0f288b43ef..5f155a6d6d1b3c 100644 --- a/docs/data/joy/components/select/select.md +++ b/docs/data/joy/components/select/select.md @@ -130,7 +130,17 @@ In contrast with single-selection mode, the options popup doesn't close after an Note that in multiple selection mode, the `value` prop (and `defaultValue`) is an array. -{{"demo": "SelectMultiple.js", "defaultCodeOpen": false}} +{{"demo": "SelectMultiple.js"}} + +#### Selected value appearance + +Use the `renderValue` prop to customize the display of the selected options. + +{{"demo": "SelectMultipleAppearance.js"}} + +#### Form submission + +Show what the value looks like after submitted a form. ### Listbox From 41c2327485875a80776a0676f55e7895a5e58c96 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:29:49 +0530 Subject: [PATCH 22/27] add ts tests --- packages/mui-joy/src/Select/Select.spec.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/mui-joy/src/Select/Select.spec.tsx b/packages/mui-joy/src/Select/Select.spec.tsx index c4b6baf25b7bb8..97769c275088fc 100644 --- a/packages/mui-joy/src/Select/Select.spec.tsx +++ b/packages/mui-joy/src/Select/Select.spec.tsx @@ -163,26 +163,33 @@ const handleMultiChange = ( handleMultiChange(event)} + onChange={handleMultiChange} />; defaultValue={[10]} // @ts-expect-error - onChange={(event) => handleChange(event)} + onChange={handleChange} />; +; + + defaultValue={[10]} onChange={handleMultiChange} />; // @ts-expect-error value={[10]} />; From 0110e9ea51b36d426015310cd6c2b7432171c09f Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:01:59 +0530 Subject: [PATCH 23/27] add ts tests --- packages/mui-joy/src/Select/Select.spec.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/mui-joy/src/Select/Select.spec.tsx b/packages/mui-joy/src/Select/Select.spec.tsx index 97769c275088fc..bc3db85409e56d 100644 --- a/packages/mui-joy/src/Select/Select.spec.tsx +++ b/packages/mui-joy/src/Select/Select.spec.tsx @@ -160,6 +160,22 @@ const handleMultiChange = ( ; +; + +; + + + + + + + + + + ); +} diff --git a/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx b/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx new file mode 100644 index 00000000000000..61536e114f8954 --- /dev/null +++ b/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import Button from '@mui/joy/Button'; +import Select from '@mui/joy/Select'; +import Option from '@mui/joy/Option'; +import Stack from '@mui/joy/Stack'; + +export default function SelectMultipleFormSubmission() { + return ( +
{ + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + alert(JSON.stringify(formJson, null, 2)); + }} + > + + + + +
+ ); +} diff --git a/docs/data/joy/components/select/select.md b/docs/data/joy/components/select/select.md index 5f155a6d6d1b3c..9ba7298c176184 100644 --- a/docs/data/joy/components/select/select.md +++ b/docs/data/joy/components/select/select.md @@ -140,7 +140,9 @@ Use the `renderValue` prop to customize the display of the selected options. #### Form submission -Show what the value looks like after submitted a form. +The `Select` component supports `name` and `required` props that will be used when submitting the form. + +{{"demo": "SelectMultipleFormSubmission.js"}} ### Listbox From f54b1ab1883c0e4412834e55e65e20db82ad2f6e Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:36:30 +0530 Subject: [PATCH 26/27] convert form data from string to array --- .../data/joy/components/select/SelectMultipleFormSubmission.js | 3 ++- .../joy/components/select/SelectMultipleFormSubmission.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/data/joy/components/select/SelectMultipleFormSubmission.js b/docs/data/joy/components/select/SelectMultipleFormSubmission.js index 390661389856dd..ae2a45d5f8ff06 100644 --- a/docs/data/joy/components/select/SelectMultipleFormSubmission.js +++ b/docs/data/joy/components/select/SelectMultipleFormSubmission.js @@ -11,7 +11,8 @@ export default function SelectMultipleFormSubmission() { event.preventDefault(); const formData = new FormData(event.currentTarget); const formJson = Object.fromEntries(formData.entries()); - alert(JSON.stringify(formJson, null, 2)); + const selectedPets = JSON.parse(formJson.pets); + alert(JSON.stringify(selectedPets, null, 2)); }} > diff --git a/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx b/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx index 61536e114f8954..ca6f42a2e20f17 100644 --- a/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx +++ b/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx @@ -11,7 +11,8 @@ export default function SelectMultipleFormSubmission() { event.preventDefault(); const formData = new FormData(event.currentTarget); const formJson = Object.fromEntries((formData as any).entries()); - alert(JSON.stringify(formJson, null, 2)); + const selectedPets = JSON.parse(formJson.pets); + alert(JSON.stringify(selectedPets, null, 2)); }} > From 5ba3592cec00c6b343b75b20f65ce9516bc1b0b2 Mon Sep 17 00:00:00 2001 From: sai6855 <60743144+sai6855@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:16:09 +0530 Subject: [PATCH 27/27] remove null,2 --- docs/data/joy/components/select/SelectMultipleFormSubmission.js | 2 +- .../data/joy/components/select/SelectMultipleFormSubmission.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/joy/components/select/SelectMultipleFormSubmission.js b/docs/data/joy/components/select/SelectMultipleFormSubmission.js index ae2a45d5f8ff06..c08b2a2d6e0c60 100644 --- a/docs/data/joy/components/select/SelectMultipleFormSubmission.js +++ b/docs/data/joy/components/select/SelectMultipleFormSubmission.js @@ -12,7 +12,7 @@ export default function SelectMultipleFormSubmission() { const formData = new FormData(event.currentTarget); const formJson = Object.fromEntries(formData.entries()); const selectedPets = JSON.parse(formJson.pets); - alert(JSON.stringify(selectedPets, null, 2)); + alert(JSON.stringify(selectedPets)); }} > diff --git a/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx b/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx index ca6f42a2e20f17..b16c85696fe035 100644 --- a/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx +++ b/docs/data/joy/components/select/SelectMultipleFormSubmission.tsx @@ -12,7 +12,7 @@ export default function SelectMultipleFormSubmission() { const formData = new FormData(event.currentTarget); const formJson = Object.fromEntries((formData as any).entries()); const selectedPets = JSON.parse(formJson.pets); - alert(JSON.stringify(selectedPets, null, 2)); + alert(JSON.stringify(selectedPets)); }} >