Skip to content

Commit

Permalink
[base-ui][useSelect] Refactor to use DOM focus management instead of …
Browse files Browse the repository at this point in the history
…active descendant (mui#39675)
  • Loading branch information
DiegoAndai authored Dec 21, 2023
1 parent 60c08fa commit c9b8879
Show file tree
Hide file tree
Showing 42 changed files with 460 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ function Styles() {
color: ${isDarkMode ? cyan[50] : cyan[900]};
}
&:focus-visible {
outline: 3px solid ${isDarkMode ? cyan[400] : cyan[300]};
}
&.${optionClasses.disabled} {
color: ${isDarkMode ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ function Styles() {
color: ${isDarkMode ? cyan[50] : cyan[900]};
}
&:focus-visible {
outline: 3px solid ${isDarkMode ? cyan[400] : cyan[300]};
}
&.${optionClasses.disabled} {
color: ${isDarkMode ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const getOptionColorClasses = ({ selected, highlighted, disabled }) => {
}
classes +=
' hover:dark:bg-neutral-800 hover:bg-slate-100 hover:dark:text-slate-300 hover:text-slate-900';
classes +=
' focus-visible:outline focus-visible:outline-2 focus-visible:outline-purple-400 focus-visible:dark:outline-purple-300';
}
return classes;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const getOptionColorClasses = ({
}
classes +=
' hover:dark:bg-neutral-800 hover:bg-slate-100 hover:dark:text-slate-300 hover:text-slate-900';
classes +=
' focus-visible:outline focus-visible:outline-2 focus-visible:outline-purple-400 focus-visible:dark:outline-purple-300';
}
return classes;
};
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectControlled.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectControlled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ export default function UnstyledSelectCustomRenderValue() {
<Select
defaultValue={10}
renderValue={(option) => {
if (option == null || option.value === null) {
if (option == null || option.value === 0) {
return 'Select an option…';
}
return `${option.label} (${option.value})`;
}}
>
<Option value={null}>None</Option>
<Option value={0}>None</Option>
<Option value={10}>Ten</Option>
<Option value={20}>Twenty</Option>
<Option value={30}>Thirty</Option>
Expand Down Expand Up @@ -177,6 +177,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ export default function UnstyledSelectCustomRenderValue() {
<Select
defaultValue={10}
renderValue={(option: SelectOption<number> | null) => {
if (option == null || option.value === null) {
if (option == null || option.value === 0) {
return 'Select an option…';
}
return `${option.label} (${option.value})`;
}}
>
<Option value={null}>None</Option>
<Option value={0}>None</Option>
<Option value={10}>Ten</Option>
<Option value={20}>Twenty</Option>
<Option value={30}>Thirty</Option>
Expand Down Expand Up @@ -169,6 +169,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Select
defaultValue={10}
renderValue={(option: SelectOption<number> | null) => {
if (option == null || option.value === null) {
if (option == null || option.value === 0) {
return 'Select an option…';
}
return `${option.label} (${option.value})`;
}}
>
<Option value={null}>None</Option>
<Option value={0}>None</Option>
<Option value={10}>Ten</Option>
<Option value={20}>Twenty</Option>
<Option value={30}>Thirty</Option>
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectGrouping.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectGrouping.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ function Styles() {
color: ${isDarkMode ? cyan[50] : cyan[900]};
}
&:focus-visible {
outline: 3px solid ${isDarkMode ? cyan[400] : cyan[300]};
}
&.${optionClasses.disabled} {
color: ${isDarkMode ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ function Styles() {
color: ${isDarkMode ? cyan[50] : cyan[900]};
}
&:focus-visible {
outline: 3px solid ${isDarkMode ? cyan[400] : cyan[300]};
}
&.${optionClasses.disabled} {
color: ${isDarkMode ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const getOptionColorClasses = ({ selected, highlighted, disabled }) => {
}
classes +=
' hover:dark:bg-slate-800 hover:bg-slate-100 hover:dark:text-slate-300 hover:text-slate-900';
classes +=
' focus-visible:outline focus-visible:outline-2 focus-visible:outline-purple-400 focus-visible:dark:outline-purple-300';
}
return classes;
};
Expand Down Expand Up @@ -100,9 +102,9 @@ const Select = React.forwardRef(function CustomSelect(props, ref) {
return {
...resolvedSlotProps,
className: clsx(
`relative text-sm font-sans box-border w-80 px-3 py-2 rounded-lg text-left bg-white dark:bg-slate-800 border border-solid border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-300 transition-all hover:bg-slate-50 dark:hover:bg-slate-700 outline-0 shadow-[0_2px_4px_rgb(0_0_0/_0.05)] dark:shadow-[0_2px_4px_rgb(0_0_0/_0.5)] ${
`relative text-sm font-sans box-border w-80 px-3 py-2 rounded-lg text-left bg-white dark:bg-neutral-900 border border-solid border-slate-200 dark:border-neutral-700 text-slate-900 dark:text-neutral-300 transition-all hover:bg-slate-50 dark:hover:bg-neutral-800 outline-0 shadow-md shadow-slate-100 dark:shadow-slate-900 ${
ownerState.focusVisible
? 'border-purple-400 shadow-outline-purple'
? 'focus-visible:ring-4 ring-purple-500/30 focus-visible:border-purple-500 focus-visible:dark:border-purple-500'
: ''
} [&>svg]:text-base [&>svg]:absolute [&>svg]:h-full [&>svg]:top-0 [&>svg]:right-2.5`,
resolvedSlotProps?.className,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const getOptionColorClasses = ({
}
classes +=
' hover:dark:bg-slate-800 hover:bg-slate-100 hover:dark:text-slate-300 hover:text-slate-900';
classes +=
' focus-visible:outline focus-visible:outline-2 focus-visible:outline-purple-400 focus-visible:dark:outline-purple-300';
}
return classes;
};
Expand Down Expand Up @@ -116,9 +118,9 @@ const Select = React.forwardRef(function CustomSelect<
return {
...resolvedSlotProps,
className: clsx(
`relative text-sm font-sans box-border w-80 px-3 py-2 rounded-lg text-left bg-white dark:bg-slate-800 border border-solid border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-300 transition-all hover:bg-slate-50 dark:hover:bg-slate-700 outline-0 shadow-[0_2px_4px_rgb(0_0_0/_0.05)] dark:shadow-[0_2px_4px_rgb(0_0_0/_0.5)] ${
`relative text-sm font-sans box-border w-80 px-3 py-2 rounded-lg text-left bg-white dark:bg-neutral-900 border border-solid border-slate-200 dark:border-neutral-700 text-slate-900 dark:text-neutral-300 transition-all hover:bg-slate-50 dark:hover:bg-neutral-800 outline-0 shadow-md shadow-slate-100 dark:shadow-slate-900 ${
ownerState.focusVisible
? 'border-purple-400 shadow-outline-purple'
? 'focus-visible:ring-4 ring-purple-500/30 focus-visible:border-purple-500 focus-visible:dark:border-purple-500'
: ''
} [&>svg]:text-base [&>svg]:absolute [&>svg]:h-full [&>svg]:top-0 [&>svg]:right-2.5`,
resolvedSlotProps?.className,
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectMultiple.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectMultiple.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.disabled} {
color: ${theme.palette.mode === 'dark' ? grey[700] : grey[400]};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
4 changes: 4 additions & 0 deletions docs/data/base/components/select/UnstyledSelectRichOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ const Option = styled(BaseOption)(
color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&.${optionClasses.highlighted}.${optionClasses.selected} {
background-color: ${theme.palette.mode === 'dark' ? blue[900] : blue[100]};
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
Expand Down
10 changes: 4 additions & 6 deletions docs/data/base/components/select/UseSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ const Option = styled('li')(
color: ${theme.palette.mode === 'dark' ? blue[100] : blue[900]};
}
&:focus-visible {
outline: 3px solid ${theme.palette.mode === 'dark' ? blue[600] : blue[200]};
}
&:before {
content: '';
width: 1ex;
Expand Down Expand Up @@ -189,12 +193,6 @@ function CustomSelect({ options, placeholder }) {
open: listboxVisible,
});

React.useEffect(() => {
if (listboxVisible) {
listboxRef.current?.focus();
}
}, [listboxVisible]);

return (
<Root>
<Toggle {...getButtonProps()} style={{ '--color': value }}>
Expand Down
Loading

0 comments on commit c9b8879

Please sign in to comment.