Edit group title/description: fix focus issues

This commit is contained in:
Evan Hahn 2021-06-04 09:55:34 -05:00 committed by GitHub
parent e61354fd55
commit 2d6b0ecfe9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 11 deletions

View file

@ -148,9 +148,11 @@ export const ConversationDetails: React.ComponentType<Props> = ({
modalNode = (
<EditConversationAttributesModal
avatarPath={conversation.avatarPath}
focusDescription={modalState === ModalState.EditingGroupDescription}
groupDescription={conversation.groupDescription}
i18n={i18n}
initiallyFocusDescription={
modalState === ModalState.EditingGroupDescription
}
makeRequest={async (
options: Readonly<{
avatar?: undefined | ArrayBuffer;

View file

@ -23,6 +23,7 @@ type PropsType = ComponentProps<typeof EditConversationAttributesModal>;
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
avatarPath: undefined,
i18n,
initiallyFocusDescription: false,
onClose: action('onClose'),
makeRequest: action('onMakeRequest'),
requestState: RequestState.Inactive,
@ -42,6 +43,12 @@ story.add('Avatar and title', () => (
/>
));
story.add('Initially focusing description', () => (
<EditConversationAttributesModal
{...createProps({ title: 'Has title', initiallyFocusDescription: true })}
/>
));
story.add('Request active', () => (
<EditConversationAttributesModal
{...createProps({ requestState: RequestState.Active })}

View file

@ -25,9 +25,9 @@ const TEMPORARY_AVATAR_VALUE = new ArrayBuffer(0);
type PropsType = {
avatarPath?: string;
focusDescription?: boolean;
groupDescription?: string;
i18n: LocalizerType;
initiallyFocusDescription: boolean;
makeRequest: (
_: Readonly<{
avatar?: undefined | ArrayBuffer;
@ -40,22 +40,21 @@ type PropsType = {
title: string;
};
function focusRef(el: HTMLElement | null) {
if (el) {
el.focus();
}
}
export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
avatarPath: externalAvatarPath,
focusDescription = false,
groupDescription: externalGroupDescription = '',
i18n,
initiallyFocusDescription,
makeRequest,
onClose,
requestState,
title: externalTitle,
}) => {
const focusDescriptionRef = useRef<undefined | boolean>(
initiallyFocusDescription
);
const focusDescription = focusDescriptionRef.current;
const startingTitleRef = useRef<string>(externalTitle);
const startingAvatarPathRef = useRef<undefined | string>(externalAvatarPath);
@ -71,6 +70,13 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
const trimmedTitle = rawTitle.trim();
const trimmedDescription = rawGroupDescription.trim();
const focusRef = (el: null | HTMLElement) => {
if (el) {
el.focus();
focusDescriptionRef.current = undefined;
}
};
useEffect(() => {
const startingAvatarPath = startingAvatarPathRef.current;
if (!startingAvatarPath) {
@ -164,7 +170,7 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
disabled={isRequestActive}
i18n={i18n}
onChangeValue={setRawTitle}
ref={!focusDescription ? focusRef : undefined}
ref={focusDescription === false ? focusRef : undefined}
value={rawTitle}
/>
@ -172,7 +178,7 @@ export const EditConversationAttributesModal: FunctionComponent<PropsType> = ({
disabled={isRequestActive}
i18n={i18n}
onChangeValue={setRawGroupDescription}
ref={focusDescription ? focusRef : undefined}
ref={focusDescription === true ? focusRef : undefined}
value={rawGroupDescription}
/>

View file

@ -14123,6 +14123,14 @@
"updated": "2021-03-05T22:52:40.572Z",
"reasonDetail": "Doesn't interact with the DOM."
},
{
"rule": "React-useRef",
"path": "ts/components/conversation/conversation-details/EditConversationAttributesModal.js",
"line": " const focusDescriptionRef = react_1.useRef(initiallyFocusDescription);",
"reasonCategory": "usageTrusted",
"updated": "2021-06-04T14:19:49.714Z",
"reasonDetail": "Only stores undefined/true/false, not DOM references."
},
{
"rule": "React-createRef",
"path": "ts/components/conversation/media-gallery/MediaGallery.js",