mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-13 13:48:59 +02:00
fix: add accessible descriptions to the dropdowns
This commit is contained in:
parent
9bebd88707
commit
4b238ca39e
@ -161,6 +161,25 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
|
||||
const stickinessOptions = useStickinessOptions(projectStickiness);
|
||||
|
||||
const selectionButtonData = {
|
||||
environments: {
|
||||
icon: <EnvironmentsIcon />,
|
||||
text: `Each feature flag can have a separate configuration per environment. This setting configures which environments your project should start with.`,
|
||||
},
|
||||
stickiness: {
|
||||
icon: <StickinessIcon />,
|
||||
text: 'Stickiness is used to guarantee that your users see the same result when using a gradual rollout. Default stickiness allows you to choose which field is used by default in this project.',
|
||||
},
|
||||
mode: {
|
||||
icon: <ProjectModeIcon />,
|
||||
text: 'Mode defines who should be allowed to interact and see your project. Private mode hides the project from anyone except the project owner and members.',
|
||||
},
|
||||
changeRequests: {
|
||||
icon: <ChangeRequestIcon />,
|
||||
text: 'Change requests can be configured per environment and require changes to go through an approval process before being applied.',
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledForm
|
||||
onSubmit={(submitEvent) => {
|
||||
@ -200,6 +219,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
|
||||
<OptionButtons>
|
||||
<MultiselectList
|
||||
description={selectionButtonData.environments.text}
|
||||
selectedOptions={projectEnvironments}
|
||||
options={activeEnvironments.map((env) => ({
|
||||
label: env.name,
|
||||
@ -218,15 +238,13 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
placeholder: 'Select project environments',
|
||||
}}
|
||||
onOpen={() =>
|
||||
overrideDocumentation({
|
||||
icon: <EnvironmentsIcon />,
|
||||
text: `Each feature flag can have a separate configuration per environment. This setting configures which environments your project should start with.`,
|
||||
})
|
||||
overrideDocumentation(selectionButtonData.environments)
|
||||
}
|
||||
onClose={clearDocumentationOverride}
|
||||
/>
|
||||
|
||||
<SingleSelectList
|
||||
description={selectionButtonData.stickiness.text}
|
||||
options={stickinessOptions.map(({ key, ...rest }) => ({
|
||||
value: key,
|
||||
...rest,
|
||||
@ -243,10 +261,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
placeholder: 'Select default stickiness',
|
||||
}}
|
||||
onOpen={() =>
|
||||
overrideDocumentation({
|
||||
icon: <StickinessIcon />,
|
||||
text: 'Stickiness is used to guarantee that your users see the same result when using a gradual rollout. Default stickiness allows you to choose which field is used by default in this project.',
|
||||
})
|
||||
overrideDocumentation(selectionButtonData.stickiness)
|
||||
}
|
||||
onClose={clearDocumentationOverride}
|
||||
/>
|
||||
@ -255,6 +270,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<SingleSelectList
|
||||
description={selectionButtonData.mode.text}
|
||||
options={projectModeOptions}
|
||||
onChange={(value: any) => {
|
||||
setProjectMode(value);
|
||||
@ -268,10 +284,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
placeholder: 'Select project mode',
|
||||
}}
|
||||
onOpen={() =>
|
||||
overrideDocumentation({
|
||||
icon: <ProjectModeIcon />,
|
||||
text: 'Mode defines who should be allowed to interact and see your project. Private mode hides the project from anyone except the project owner and members.',
|
||||
})
|
||||
overrideDocumentation(selectionButtonData.mode)
|
||||
}
|
||||
onClose={clearDocumentationOverride}
|
||||
/>
|
||||
@ -281,6 +294,9 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<TableSelect
|
||||
description={
|
||||
selectionButtonData.changeRequests.text
|
||||
}
|
||||
disabled={projectEnvironments.size === 0}
|
||||
activeEnvironments={activeEnvironments
|
||||
.filter((env) =>
|
||||
@ -314,10 +330,9 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
projectChangeRequestConfiguration
|
||||
}
|
||||
onOpen={() =>
|
||||
overrideDocumentation({
|
||||
icon: <ChangeRequestIcon />,
|
||||
text: 'Change requests can be configured per environment and require changes to go through an approval process before being applied.',
|
||||
})
|
||||
overrideDocumentation(
|
||||
selectionButtonData.changeRequests,
|
||||
)
|
||||
}
|
||||
onClose={clearDocumentationOverride}
|
||||
/>
|
||||
|
@ -39,6 +39,11 @@ const visuallyHiddenStyles = {
|
||||
whiteSpace: 'nowrap',
|
||||
};
|
||||
|
||||
export const HiddenDescription = styled('p')(() => ({
|
||||
...visuallyHiddenStyles,
|
||||
position: 'absolute',
|
||||
}));
|
||||
|
||||
export const StyledDropdownSearch = styled(TextField, {
|
||||
shouldForwardProp: (prop) => prop !== 'hideLabel',
|
||||
})<{ hideLabel?: boolean }>(({ theme, hideLabel }) => ({
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Search from '@mui/icons-material/Search';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { Box, Button, InputAdornment, List, ListItemText } from '@mui/material';
|
||||
import { type FC, type ReactNode, useRef, useState, useMemo } from 'react';
|
||||
import {
|
||||
@ -8,6 +9,7 @@ import {
|
||||
StyledPopover,
|
||||
StyledDropdownSearch,
|
||||
TableSearchInput,
|
||||
HiddenDescription,
|
||||
} from './SelectionButton.styles';
|
||||
import { ChangeRequestTable } from './ChangeRequestTable';
|
||||
|
||||
@ -81,6 +83,7 @@ type CombinedSelectProps = {
|
||||
multiselect?: { selectedOptions: Set<string> };
|
||||
onOpen?: () => void;
|
||||
onClose?: () => void;
|
||||
description: string; // visually hidden, for assistive tech
|
||||
};
|
||||
|
||||
const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
@ -91,10 +94,12 @@ const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
multiselect,
|
||||
onOpen = () => {},
|
||||
onClose = () => {},
|
||||
description,
|
||||
}) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>();
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const descriptionId = uuidv4();
|
||||
|
||||
const open = () => {
|
||||
setSearchText('');
|
||||
@ -151,7 +156,10 @@ const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<StyledDropdown>
|
||||
<HiddenDescription id={descriptionId}>
|
||||
{description}
|
||||
</HiddenDescription>
|
||||
<StyledDropdown aria-describedby={descriptionId}>
|
||||
<StyledDropdownSearch
|
||||
variant='outlined'
|
||||
size='small'
|
||||
@ -181,6 +189,7 @@ const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
|
||||
return (
|
||||
<StyledListItem
|
||||
aria-describedby={labelId}
|
||||
key={option.value}
|
||||
dense
|
||||
disablePadding
|
||||
@ -229,7 +238,7 @@ const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
|
||||
type MultiselectListProps = Pick<
|
||||
CombinedSelectProps,
|
||||
'options' | 'button' | 'search' | 'onOpen' | 'onClose'
|
||||
'options' | 'button' | 'search' | 'onOpen' | 'onClose' | 'description'
|
||||
> & {
|
||||
selectedOptions: Set<string>;
|
||||
onChange: (values: Set<string>) => void;
|
||||
@ -265,7 +274,13 @@ export const MultiselectList: FC<MultiselectListProps> = ({
|
||||
|
||||
type SingleSelectListProps = Pick<
|
||||
CombinedSelectProps,
|
||||
'options' | 'button' | 'search' | 'onChange' | 'onOpen' | 'onClose'
|
||||
| 'options'
|
||||
| 'button'
|
||||
| 'search'
|
||||
| 'onChange'
|
||||
| 'onOpen'
|
||||
| 'onClose'
|
||||
| 'description'
|
||||
>;
|
||||
|
||||
export const SingleSelectList: FC<SingleSelectListProps> = (props) => {
|
||||
@ -274,7 +289,7 @@ export const SingleSelectList: FC<SingleSelectListProps> = (props) => {
|
||||
|
||||
type TableSelectProps = Pick<
|
||||
CombinedSelectProps,
|
||||
'button' | 'search' | 'onOpen' | 'onClose'
|
||||
'button' | 'search' | 'onOpen' | 'onClose' | 'description'
|
||||
> & {
|
||||
updateProjectChangeRequestConfiguration: {
|
||||
disableChangeRequests: (env: string) => void;
|
||||
|
Loading…
Reference in New Issue
Block a user