Skip to content

Commit

Permalink
[joy-ui][Select] Support selection of multiple options (#39454)
Browse files Browse the repository at this point in the history
  • Loading branch information
sai6855 authored Oct 30, 2023
1 parent ee8b09e commit f39a827
Show file tree
Hide file tree
Showing 16 changed files with 463 additions and 65 deletions.
31 changes: 31 additions & 0 deletions docs/data/joy/components/select/SelectMultiple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react';
import Select from '@mui/joy/Select';
import Option from '@mui/joy/Option';

export default function SelectMultiple() {
const handleChange = (event, newValue) => {
console.log(`You have choosen "${newValue}"`);
};
return (
<Select
defaultValue={['dog']}
multiple
onChange={handleChange}
sx={{
minWidth: '13rem',
}}
slotProps={{
listbox: {
sx: {
width: '100%',
},
},
}}
>
<Option value="dog">Dog</Option>
<Option value="cat">Cat</Option>
<Option value="fish">Fish</Option>
<Option value="bird">Bird</Option>
</Select>
);
}
34 changes: 34 additions & 0 deletions docs/data/joy/components/select/SelectMultiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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<string> | null,
) => {
console.log(`You have choosen "${newValue}"`);
};
return (
<Select
defaultValue={['dog']}
multiple
onChange={handleChange}
sx={{
minWidth: '13rem',
}}
slotProps={{
listbox: {
sx: {
width: '100%',
},
},
}}
>
<Option value="dog">Dog</Option>
<Option value="cat">Cat</Option>
<Option value="fish">Fish</Option>
<Option value="bird">Bird</Option>
</Select>
);
}
37 changes: 37 additions & 0 deletions docs/data/joy/components/select/SelectMultipleAppearance.js
Original file line number Diff line number Diff line change
@@ -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 (
<Select
multiple
defaultValue={['dog', 'cat']}
renderValue={(selected) => (
<Box sx={{ display: 'flex', gap: '0.25rem' }}>
{selected.map((selectedOption) => (
<Chip variant="soft" color="primary">
{selectedOption.label}
</Chip>
))}
</Box>
)}
sx={{
minWidth: '15rem',
}}
slotProps={{
listbox: {
sx: {
width: '100%',
},
},
}}
>
<Option value="dog">Dog</Option>
<Option value="cat">Cat</Option>
<Option value="fish">Fish</Option>
<Option value="bird">Bird</Option>
</Select>
);
}
37 changes: 37 additions & 0 deletions docs/data/joy/components/select/SelectMultipleAppearance.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Select
multiple
defaultValue={['dog', 'cat']}
renderValue={(selected) => (
<Box sx={{ display: 'flex', gap: '0.25rem' }}>
{selected.map((selectedOption) => (
<Chip variant="soft" color="primary">
{selectedOption.label}
</Chip>
))}
</Box>
)}
sx={{
minWidth: '15rem',
}}
slotProps={{
listbox: {
sx: {
width: '100%',
},
},
}}
>
<Option value="dog">Dog</Option>
<Option value="cat">Cat</Option>
<Option value="fish">Fish</Option>
<Option value="bird">Bird</Option>
</Select>
);
}
36 changes: 36 additions & 0 deletions docs/data/joy/components/select/SelectMultipleFormSubmission.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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 (
<form
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const formJson = Object.fromEntries(formData.entries());
const selectedPets = JSON.parse(formJson.pets);
alert(JSON.stringify(selectedPets));
}}
>
<Stack spacing={2} alignItems="flex-start">
<Select
placeholder="Select a pet"
name="pets"
required
multiple
defaultValue={['dog', 'cat']}
sx={{ minWidth: 200 }}
>
<Option value="dog">Dog</Option>
<Option value="cat">Cat</Option>
<Option value="fish">Fish</Option>
<Option value="bird">Bird</Option>
</Select>
<Button type="submit">Submit</Button>
</Stack>
</form>
);
}
36 changes: 36 additions & 0 deletions docs/data/joy/components/select/SelectMultipleFormSubmission.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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 (
<form
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const formJson = Object.fromEntries((formData as any).entries());
const selectedPets = JSON.parse(formJson.pets);
alert(JSON.stringify(selectedPets));
}}
>
<Stack spacing={2} alignItems="flex-start">
<Select
placeholder="Select a pet"
name="pets"
required
multiple
defaultValue={['dog', 'cat']}
sx={{ minWidth: 200 }}
>
<Option value="dog">Dog</Option>
<Option value="cat">Cat</Option>
<Option value="fish">Fish</Option>
<Option value="bird">Bird</Option>
</Select>
<Button type="submit">Submit</Button>
</Stack>
</form>
);
}
21 changes: 21 additions & 0 deletions docs/data/joy/components/select/select.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,27 @@ 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"}}
#### Selected value appearance
Use the `renderValue` prop to customize the display of the selected options.
{{"demo": "SelectMultipleAppearance.js"}}
#### Form submission
The `Select` component supports `name` and `required` props that will be used when submitting the form.
{{"demo": "SelectMultipleFormSubmission.js"}}
### Listbox
#### Maximum height
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/joy-ui/api/select.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" } },
Expand Down Expand Up @@ -113,6 +114,7 @@
"disabled",
"expanded",
"focusVisible",
"multiple",
"popper",
"sizeLg",
"sizeMd",
Expand Down
6 changes: 6 additions & 0 deletions docs/translations/api-docs-joy/select/select.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
"description": "<code>id</code> attribute of the listbox element. Also used to derive the <code>id</code> attributes of options."
},
"listboxOpen": { "description": "Controls the open state of the select&#39;s listbox." },
"multiple": {
"description": "If <code>true</code>, selecting multiple values is allowed. This affects the type of the <code>value</code>, <code>defaultValue</code>, and <code>onChange</code> 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."
},
Expand Down Expand Up @@ -85,6 +88,9 @@
"description": "Class name applied to {{nodeName}}.",
"nodeName": "the listbox slot"
},
"multiple": {
"description": "Class name applied to the root slot if <code>multiple=true</code>"
},
"colorPrimary": {
"description": "Class name applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root slot",
Expand Down
Loading

0 comments on commit f39a827

Please sign in to comment.