Skip to content

Commit 7a70667

Browse files
committed
fix: a11y in CreateDiscussion and RoomAutoComplete components
1 parent c4bd8b9 commit 7a70667

2 files changed

Lines changed: 19 additions & 19 deletions

File tree

apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
1515
import { GenericModal } from '@rocket.chat/ui-client';
1616
import { useTranslation, useEndpoint } from '@rocket.chat/ui-contexts';
1717
import { useMutation } from '@tanstack/react-query';
18-
import { useId, useState } from 'react';
18+
import { useState } from 'react';
1919
import { useForm, Controller } from 'react-hook-form';
2020

2121
import { useEncryptedRoomDescription } from '../../navbar/NavBarPagesGroup/actions/useEncryptedRoomDescription';
@@ -49,7 +49,6 @@ const CreateDiscussion = ({
4949
encryptedParentRoom = false,
5050
}: CreateDiscussionProps) => {
5151
const t = useTranslation();
52-
const parentRoomId = useId();
5352

5453
const [encryptedDisabled, setEncryptedDisabled] = useState(encryptedParentRoom);
5554

@@ -133,27 +132,21 @@ const CreateDiscussion = ({
133132
control={control}
134133
name='parentRoom'
135134
rules={{ required: t('Required_field', { field: t('Discussion_target_channel') }) }}
136-
render={({ field: { name, onBlur, onChange, value } }) => (
135+
render={({ field }) => (
137136
<RoomAutoComplete
138-
aria-label={t('Discussion_target_channel')}
139-
name={name}
140-
onBlur={onBlur}
141-
onChange={onChange}
142-
value={value}
137+
{...field}
143138
error={Boolean(errors.parentRoom?.message)}
144139
placeholder={t('Search_options')}
145140
disabled={Boolean(defaultParentRoom)}
146141
aria-required='true'
147-
aria-invalid={Boolean(errors.parentRoom?.message)}
148-
aria-describedby={errors.parentRoom ? `${parentRoomId}-error` : undefined}
149142
setSelectedRoom={onParentRoomChange}
150143
renderRoomIcon={({ encrypted }) => (encrypted ? <Icon name='key' /> : null)}
151144
/>
152145
)}
153146
/>
154147
)}
155148
</FieldRow>
156-
{errors.parentRoom && <FieldError id={`${parentRoomId}-error`}>{errors.parentRoom.message}</FieldError>}
149+
{errors.parentRoom && <FieldError>{errors.parentRoom.message}</FieldError>}
157150
</Field>
158151
<Field>
159152
<FieldLabel required>{t('Name')}</FieldLabel>

apps/meteor/client/components/RoomAutoComplete/RoomAutoComplete.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import type { IRoom } from '@rocket.chat/core-typings';
2-
import { AutoComplete, Option, Box } from '@rocket.chat/fuselage';
2+
import { Option, Box } from '@rocket.chat/fuselage';
3+
import { AutoComplete, type AutoCompleteProps } from '@rocket.chat/fuselage';
34
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
45
import { RoomAvatar } from '@rocket.chat/ui-avatar';
56
import { useEndpoint } from '@rocket.chat/ui-contexts';
67
import { keepPreviousData, useQuery } from '@tanstack/react-query';
7-
import type { ComponentProps, ReactElement } from 'react';
8-
import { memo, useMemo, useState } from 'react';
8+
import type { ReactElement } from 'react';
9+
import { forwardRef, memo, useMemo, useState } from 'react';
10+
11+
type LabelType = { name: string; avatarETag?: string; type: IRoom['t']; encrypted?: IRoom['encrypted'] };
912

1013
const generateQuery = (
1114
term = '',
1215
): {
1316
selector: string;
1417
} => ({ selector: JSON.stringify({ name: term }) });
1518

16-
type RoomAutoCompleteProps = Omit<ComponentProps<typeof AutoComplete>, 'filter'> & {
19+
type RoomAutoCompleteProps = Omit<AutoCompleteProps<LabelType>, 'filter'> & {
1720
scope?: 'admin' | 'regular';
1821
renderRoomIcon?: (props: { encrypted: IRoom['encrypted']; type: IRoom['t'] }) => ReactElement | null;
1922
setSelectedRoom?: (room: IRoom | undefined) => void;
@@ -32,7 +35,10 @@ const ROOM_AUTOCOMPLETE_PARAMS = {
3235
},
3336
} as const;
3437

35-
const RoomAutoComplete = ({ value, onChange, scope = 'regular', renderRoomIcon, setSelectedRoom, ...props }: RoomAutoCompleteProps) => {
38+
const RoomAutoComplete = forwardRef<HTMLInputElement, RoomAutoCompleteProps>(function RoomAutoComplete(
39+
{ value, onChange, scope = 'regular', renderRoomIcon, setSelectedRoom, ...props },
40+
ref,
41+
) {
3642
const [filter, setFilter] = useState('');
3743
const filterDebounced = useDebouncedValue(filter, 300);
3844
const roomsAutoCompleteEndpoint = useEndpoint('GET', ROOM_AUTOCOMPLETE_PARAMS[scope].endpoint);
@@ -57,6 +63,7 @@ const RoomAutoComplete = ({ value, onChange, scope = 'regular', renderRoomIcon,
5763
return (
5864
<AutoComplete
5965
{...props}
66+
ref={ref}
6067
value={value}
6168
onChange={(val) => {
6269
onChange(val);
@@ -76,7 +83,7 @@ const RoomAutoComplete = ({ value, onChange, scope = 'regular', renderRoomIcon,
7683
<Box margin='none' mi={2}>
7784
{label?.name}
7885
</Box>
79-
{renderRoomIcon?.({ ...label })}
86+
{renderRoomIcon?.({ encrypted: label?.encrypted, type: label?.type })}
8087
</>
8188
)}
8289
renderItem={({ value, label, ...props }) => (
@@ -85,7 +92,7 @@ const RoomAutoComplete = ({ value, onChange, scope = 'regular', renderRoomIcon,
8592
label={
8693
<>
8794
{label?.name}
88-
{renderRoomIcon?.({ ...label })}
95+
{renderRoomIcon?.({ encrypted: label?.encrypted, type: label?.type })}
8996
</>
9097
}
9198
avatar={<RoomAvatar size={AVATAR_SIZE} room={{ _id: value, ...label }} />}
@@ -94,6 +101,6 @@ const RoomAutoComplete = ({ value, onChange, scope = 'regular', renderRoomIcon,
94101
options={options}
95102
/>
96103
);
97-
};
104+
});
98105

99106
export default memo(RoomAutoComplete);

0 commit comments

Comments
 (0)