mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
fix: add accessible descriptions to the dropdowns (#7112)
This PR adds accessible descriptions to the dropdown widgets in the new project creation form. The description is the same as we show in the background
This commit is contained in:
parent
57f66f3b55
commit
be4bb86b92
@ -154,6 +154,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) => {
|
||||
@ -207,6 +226,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
|
||||
<OptionButtons>
|
||||
<MultiselectList
|
||||
description={selectionButtonData.environments.text}
|
||||
selectedOptions={projectEnvironments}
|
||||
options={activeEnvironments.map((env) => ({
|
||||
label: env.name,
|
||||
@ -225,15 +245,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,
|
||||
@ -250,10 +268,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}
|
||||
/>
|
||||
@ -262,6 +277,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<SingleSelectList
|
||||
description={selectionButtonData.mode.text}
|
||||
options={projectModeOptions}
|
||||
onChange={(value: any) => {
|
||||
setProjectMode(value);
|
||||
@ -275,10 +291,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}
|
||||
/>
|
||||
@ -288,6 +301,9 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<TableSelect
|
||||
description={
|
||||
selectionButtonData.changeRequests.text
|
||||
}
|
||||
disabled={projectEnvironments.size === 0}
|
||||
activeEnvironments={activeEnvironments
|
||||
.filter((env) =>
|
||||
@ -321,10 +337,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}
|
||||
/>
|
||||
|
@ -40,6 +40,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 [recentlyClosed, setRecentlyClosed] = useState(false);
|
||||
|
||||
const open = () => {
|
||||
@ -156,7 +161,10 @@ const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<StyledDropdown>
|
||||
<HiddenDescription id={descriptionId}>
|
||||
{description}
|
||||
</HiddenDescription>
|
||||
<StyledDropdown aria-describedby={descriptionId}>
|
||||
<StyledDropdownSearch
|
||||
variant='outlined'
|
||||
size='small'
|
||||
@ -186,6 +194,7 @@ const CombinedSelect: FC<CombinedSelectProps> = ({
|
||||
|
||||
return (
|
||||
<StyledListItem
|
||||
aria-describedby={labelId}
|
||||
key={option.value}
|
||||
dense
|
||||
disablePadding
|
||||
@ -234,7 +243,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;
|
||||
@ -270,7 +279,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) => {
|
||||
@ -279,7 +294,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