️(frontend) limit share modal opening announcement for screen readers

Autofocus close and hide modal body from SR when search input is hidden.
This commit is contained in:
Cyril
2026-08-26 13:42:37 +02:00
committed by Ovgodd
parent 2c5577d026
commit 5eb330f22f
2 changed files with 21 additions and 1 deletions
+1
View File
@@ -55,6 +55,7 @@ and this project adheres to
### Changed
- ♻️(backend) reset collaboration connection in cascade for all children #2507
- ♿️(frontend) limit share modal opening announcement for screen readers #2452
### Fixed
@@ -40,6 +40,8 @@ import {
import { QuickSearchGroupMember } from './DocShareMember';
import { DocShareModalFooter } from './DocShareModalFooter';
const DEBOUNCE_MS = 300;
const ShareModalStyle = createGlobalStyle`
.--docs--doc-share-modal [cmdk-item] {
cursor: auto;
@@ -84,6 +86,7 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
const [listHeight, setListHeight] = useState<string>('400px');
const canShare = doc.abilities.accesses_manage && isRootDoc;
const [isContentAccessible, setIsContentAccessible] = useState(canShare);
const canViewAccesses = doc.abilities.accesses_view;
const showMemberSection = inputValue === '' && selectedUsers.length === 0;
const showFooter = selectedUsers.length === 0 && !inputValue;
@@ -119,7 +122,7 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
const onFilter = useDebouncedCallback((str: string) => {
setUserQuery(str);
}, 300);
}, DEBOUNCE_MS);
const onRemoveUser = (row: User) => {
setSelectedUsers((prevState) => {
@@ -161,6 +164,20 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
const showInheritedShareContent =
inheritedAccesses.length > 0 && showMemberSection && !isRootDoc;
// When the search input is hidden, keep the modal content out of the
// accessibility tree during the opening announcement, then restore it.
useEffect(() => {
if (canShare) {
return;
}
const id = window.setTimeout(() => {
setIsContentAccessible(true);
}, DEBOUNCE_MS);
return () => window.clearTimeout(id);
}, [canShare]);
// Invalidate relevant queries to ensure fresh data on modal open
useEffect(() => {
[
@@ -197,6 +214,7 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
{t('Share the document')}
</Text>
<ButtonCloseModal
autoFocus={!canShare}
aria-label={t('Close the share modal')}
onClick={onClose}
/>
@@ -206,6 +224,7 @@ export const DocShareModal = ({ doc, onClose, isRootDoc = true }: Props) => {
>
<ShareModalStyle />
<Box
aria-hidden={isContentAccessible ? undefined : true}
$height="auto"
$maxHeight={canViewAccesses ? modalContentHeight : 'none'}
$overflow="hidden"