Adds keyboard support to the media quality selector

This commit is contained in:
Josh Perez 2021-07-07 13:05:03 -04:00 committed by GitHub
parent 3827f05db9
commit a73d7b42cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 3 deletions

View File

@ -23,6 +23,11 @@
opacity: 0.5;
width: 32px;
&:focus,
&:hover {
opacity: 1;
}
&::after {
content: '';
display: block;
@ -106,6 +111,7 @@
}
}
&--focused,
&:focus,
&:active {
border-radius: 6px;

View File

@ -7,6 +7,7 @@ import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { boolean } from '@storybook/addon-knobs';
import { IMAGE_JPEG } from '../types/MIME';
import { CompositionArea, Props } from './CompositionArea';
import { setup as setupI18n } from '../../js/modules/i18n';
import enMessages from '../../_locales/en/messages.json';
@ -33,7 +34,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
micCellEl,
onChooseAttachment: action('onChooseAttachment'),
// AttachmentList
draftAttachments: [],
draftAttachments: overrideProps.draftAttachments || [],
onAddAttachment: action('onAddAttachment'),
onClearAttachments: action('onClearAttachments'),
onClickAttachment: action('onClickAttachment'),
@ -144,3 +145,15 @@ story.add('SMS-only', () => {
return <CompositionArea {...props} />;
});
story.add('Attachments', () => {
const props = createProps({
draftAttachments: [
{
contentType: IMAGE_JPEG,
},
],
});
return <CompositionArea {...props} />;
});

View File

@ -21,6 +21,9 @@ export const MediaQualitySelector = ({
}: PropsType): JSX.Element => {
const [menuShowing, setMenuShowing] = useState(false);
const [popperRoot, setPopperRoot] = useState<HTMLElement | null>(null);
const [focusedOption, setFocusedOption] = useState<0 | 1 | undefined>(
undefined
);
// We use regular MouseEvent below, and this one uses React.MouseEvent
const handleClick = (ev: KeyboardEvent | React.MouseEvent) => {
@ -29,8 +32,31 @@ export const MediaQualitySelector = ({
ev.preventDefault();
};
const handleKeyDown = (ev: KeyboardEvent) => {
if (!popperRoot) {
if (ev.key === 'Enter') {
setFocusedOption(isHighQuality ? 1 : 0);
}
return;
}
if (ev.key === 'ArrowDown' || ev.key === 'ArrowUp') {
setFocusedOption(oldFocusedOption => (oldFocusedOption === 1 ? 0 : 1));
ev.stopPropagation();
ev.preventDefault();
}
if (ev.key === 'Enter') {
onSelectQuality(Boolean(focusedOption));
setMenuShowing(false);
ev.stopPropagation();
ev.preventDefault();
}
};
const handleClose = useCallback(() => {
setMenuShowing(false);
setFocusedOption(undefined);
}, [setMenuShowing]);
useEffect(() => {
@ -69,6 +95,7 @@ export const MediaQualitySelector = ({
'MediaQualitySelector__button--active': menuShowing,
})}
onClick={handleClick}
onKeyDown={handleKeyDown}
ref={ref}
type="button"
/>
@ -91,7 +118,11 @@ export const MediaQualitySelector = ({
aria-label={i18n(
'MediaQualitySelector--standard-quality-title'
)}
className="MediaQualitySelector__option"
className={classNames({
MediaQualitySelector__option: true,
'MediaQualitySelector__option--focused':
focusedOption === 0,
})}
type="button"
onClick={() => {
onSelectQuality(false);
@ -119,7 +150,11 @@ export const MediaQualitySelector = ({
aria-label={i18n(
'MediaQualitySelector--high-quality-title'
)}
className="MediaQualitySelector__option"
className={classNames({
MediaQualitySelector__option: true,
'MediaQualitySelector__option--focused':
focusedOption === 1,
})}
type="button"
onClick={() => {
onSelectQuality(true);