Skip to content

Commit

Permalink
a11y: use useShell for global announcements (#2734)
Browse files Browse the repository at this point in the history
* start using useShell for announcements

* fix crashing issue

* Update ObjectArrayField.tsx

* Update ObjectArrayField.tsx

* fixes from PR

Co-authored-by: Andy Brown <asbrown002@gmail.com>
Co-authored-by: Chris Whitten <christopher.whitten@microsoft.com>
  • Loading branch information
3 people authored Apr 22, 2020
1 parent 557bff2 commit 751dc67
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import formatMessage from 'format-message';
import { NeutralColors, FontSizes } from '@uifabric/fluent-theme';
import { RouteComponentProps } from '@reach/router';
import { LgTemplate } from '@bfc/shared';
import { Async } from 'office-ui-fabric-react/lib/Utilities';

import { StoreContext } from '../../store';
import { increaseNameUtilNotExist } from '../../utils/lgUtil';
Expand All @@ -36,23 +35,13 @@ const TableView: React.FC<TableViewProps> = props => {
const createLgTemplate = useRef(debounce(actions.createLgTemplate, 500)).current;
const copyLgTemplate = useRef(debounce(actions.copyLgTemplate, 500)).current;
const removeLgTemplate = useRef(debounce(actions.removeLgTemplate, 500)).current;
const setMessage = useRef(debounce(actions.setMessage, 500)).current;
const [templates, setTemplates] = useState<LgTemplate[]>([]);
const listRef = useRef(null);

const activeDialog = dialogs.find(({ id }) => id === dialogId);

const [focusedIndex, setFocusedIndex] = useState(0);

const _async = new Async();

const announce = (message: string) => {
setMessage(message);
_async.setTimeout(() => {
setMessage(undefined);
}, 2000);
};

useEffect(() => {
if (!file || isEmpty(file)) return;

Expand Down Expand Up @@ -123,15 +112,15 @@ const TableView: React.FC<TableViewProps> = props => {
key: 'delete',
name: formatMessage('Delete'),
onClick: () => {
announce('item deleted');
actions.setMessage('item deleted');
onRemoveTemplate(index);
},
},
{
key: 'copy',
name: formatMessage('Make a copy'),
onClick: () => {
announce('item copied');
actions.setMessage('item copied');
onCopyTemplate(index);
},
},
Expand Down Expand Up @@ -257,7 +246,7 @@ const TableView: React.FC<TableViewProps> = props => {
iconProps={{ iconName: 'CirclePlus' }}
onClick={() => {
onCreateNewTemplate();
announce('item added');
actions.setMessage('item added');
}}
>
{formatMessage('New template')}
Expand Down
1 change: 1 addition & 0 deletions Composer/packages/client/src/shell/useShell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export function useShell(source: EventSource): { api: ShellApi; data: ShellData
redo: actions.redo,
addCoachMarkRef: actions.onboardingAddCoachMarkRef,
updateUserSettings: actions.updateUserSettings,
announce: actions.setMessage,
};

const currentDialog = useMemo(() => dialogs.find(d => d.id === dialogId), [dialogs, dialogId]);
Expand Down
17 changes: 16 additions & 1 deletion Composer/packages/client/src/store/action/error.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import debounce from 'lodash/debounce';

import { ActionCreator } from '../types';

import { ActionTypes } from './../../constants';
Expand All @@ -12,9 +14,22 @@ export const setError: ActionCreator = ({ dispatch }, error) => {
});
};

export const setMessage: ActionCreator = ({ dispatch }, message) => {
const _setMessage = debounce((dispatch, message: string) => {
dispatch({
type: ActionTypes.SET_MESSAGE,
payload: message,
});

setTimeout(
() =>
dispatch({
type: ActionTypes.SET_MESSAGE,
payload: undefined,
}),
2000
);
}, 500);

export const setMessage: ActionCreator = ({ dispatch }, message) => {
_setMessage(dispatch, message);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
import React, { useState, useMemo, useRef } from 'react';
import { FieldProps } from '@bfc/extension';
import { FieldProps, useShellApi } from '@bfc/extension';
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import { JSONSchema7 } from 'json-schema';
import { IconButton } from 'office-ui-fabric-react/lib/Button';
Expand Down Expand Up @@ -39,6 +39,13 @@ const ObjectArrayField: React.FC<FieldProps<any[]>> = props => {
const [newObject, setNewObject] = useState({});
const { arrayItems, handleChange, addItem } = useArrayItems(value, onChange);
const firstNewFieldRef: React.RefObject<ITextField> = useRef(null);
const { announce } = useShellApi().shellApi;

const END_OF_ROW_LABEL = formatMessage('press Enter to add this item or Tab to move to the next interactive element');

const INSIDE_ROW_LABEL = formatMessage(
'press Enter to add this name and advance to the next row, or press Tab to advance to the value field'
);

const handleNewObjectChange = (property: string) => (_e: React.FormEvent, newValue?: string) => {
setNewObject({ ...newObject, [property]: newValue });
Expand All @@ -54,6 +61,7 @@ const ObjectArrayField: React.FC<FieldProps<any[]>> = props => {
return { ...obj, [key]: typeof serializeValue === 'function' ? serializeValue(value) : value };
}, {});

announce(INSIDE_ROW_LABEL);
addItem(formattedData);
setNewObject({});
firstNewFieldRef.current?.focus();
Expand Down Expand Up @@ -153,15 +161,7 @@ const ObjectArrayField: React.FC<FieldProps<any[]>> = props => {
value={newObject[property] || ''}
onChange={handleNewObjectChange(property)}
onKeyDown={handleKeyDown}
ariaLabel={
lastField
? formatMessage(
'press Enter to add this item or Tab to move to the next interactive element'
)
: formatMessage(
'press Enter to add this name and advance to the next row, or press Tab to advance to the value field'
)
}
ariaLabel={lastField ? END_OF_ROW_LABEL : INSIDE_ROW_LABEL}
componentRef={index === 0 ? firstNewFieldRef : undefined}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions Composer/packages/lib/shared/src/types/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@ export interface ShellApi {
redo: () => void;
updateUserSettings: (settings: AllPartial<UserSettings>) => void;
addSkillDialog: () => Promise<{ manifestUrl: string } | null>;
announce: (message: string) => void;
}

0 comments on commit 751dc67

Please sign in to comment.