Skip to content

Commit

Permalink
[SelectUnstyled] Add ability to post the select's value when submitti…
Browse files Browse the repository at this point in the history
…ng a form
  • Loading branch information
michaldudak committed Jul 29, 2022
1 parent 6a96f9c commit 71b115d
Show file tree
Hide file tree
Showing 16 changed files with 791 additions and 21 deletions.
190 changes: 190 additions & 0 deletions docs/data/base/components/select/UnstyledSelectObjectValuesForm.js
@@ -0,0 +1,190 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import SelectUnstyled, { selectUnstyledClasses } from '@mui/base/SelectUnstyled';
import OptionUnstyled, { optionUnstyledClasses } from '@mui/base/OptionUnstyled';
import PopperUnstyled from '@mui/base/PopperUnstyled';
import { styled } from '@mui/system';

const blue = {
100: '#DAECFF',
200: '#99CCF3',
400: '#3399FF',
500: '#007FFF',
600: '#0072E5',
900: '#003A75',
};

const grey = {
50: '#F3F6F9',
100: '#E7EBF0',
200: '#E0E3E7',
300: '#CDD2D7',
400: '#B2BAC2',
500: '#A0AAB4',
600: '#6F7E8C',
700: '#3E5060',
800: '#2D3843',
900: '#1A2027',
};

const StyledButton = styled('button')(
({ theme }) => `
font-family: IBM Plex Sans, sans-serif;
font-size: 0.875rem;
box-sizing: border-box;
min-height: calc(1.5em + 22px);
min-width: 320px;
background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'};
border: 1px solid ${theme.palette.mode === 'dark' ? grey[800] : grey[300]};
border-radius: 0.75em;
margin: 0.5em;
padding: 10px;
text-align: left;
line-height: 1.5;
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
&:hover {
background: ${theme.palette.mode === 'dark' ? '' : grey[100]};
border-color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
&.${selectUnstyledClasses.focusVisible} {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[100]};
}
&.${selectUnstyledClasses.expanded} {
&::after {
content: '▴';
}
}
&::after {
content: '▾';
float: right;
}
`,
);

const StyledListbox = styled('ul')(
({ theme }) => `
font-family: IBM Plex Sans, sans-serif;
font-size: 0.875rem;
box-sizing: border-box;
padding: 5px;
margin: 10px 0;
min-width: 320px;
background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'};
border: 1px solid ${theme.palette.mode === 'dark' ? grey[800] : grey[300]};
border-radius: 0.75em;
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
overflow: auto;
outline: 0px;
`,
);

const StyledOption = styled(OptionUnstyled)(
({ theme }) => `
list-style: none;
padding: 8px;
border-radius: 0.45em;
cursor: default;
&:last-of-type {
border-bottom: none;
}
&.${optionUnstyledClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&.${optionUnstyledClasses.highlighted} {
background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]};
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&.${optionUnstyledClasses.highlighted}.${optionUnstyledClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&.${optionUnstyledClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
&:hover:not(.${optionUnstyledClasses.disabled}) {
background-color: ${theme.palette.mode === 'dark' ? grey[800] : grey[100]};
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
`,
);

const StyledPopper = styled(PopperUnstyled)`
z-index: 1;
`;

function CustomSelect(props) {
const components = {
Root: StyledButton,
Listbox: StyledListbox,
Popper: StyledPopper,
...props.components,
};

return <SelectUnstyled {...props} components={components} />;
}

CustomSelect.propTypes = {
/**
* The components used for each slot inside the Select.
* Either a string to use a HTML element or a component.
* @default {}
*/
components: PropTypes.shape({
Listbox: PropTypes.elementType,
Popper: PropTypes.func,
Root: PropTypes.elementType,
}),
};

const characters = [
{ name: 'Frodo', race: 'Hobbit' },
{ name: 'Sam', race: 'Hobbit' },
{ name: 'Merry', race: 'Hobbit' },
{ name: 'Gandalf', race: 'Maia' },
{ name: 'Gimli', race: 'Dwarf' },
];

export default function UnstyledSelectObjectValues() {
const [character, setCharacter] = React.useState(characters[0]);

const formValueProvider = (option) => option?.value?.name ?? '';

const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const formProps = Object.fromEntries(formData);
console.log(formProps);
};

return (
<div>
<form onSubmit={handleSubmit}>
<CustomSelect
value={character}
onChange={setCharacter}
formValueProvider={formValueProvider}
name="character"
>
{characters.map((c) => (
<StyledOption key={c.name} value={c}>
{c.name}
</StyledOption>
))}
</CustomSelect>

<button type="submit">Submit</button>
</form>
</div>
);
}

0 comments on commit 71b115d

Please sign in to comment.