feat(web): improve keyboard navigation in RootAppSidebar (#2256)

Co-authored-by: Himself65 <himself65@outlook.com>
This commit is contained in:
Doma 2023-05-08 22:57:14 +08:00 committed by GitHub
parent d040a7fb50
commit d1457075b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 10 deletions

View File

@ -2,6 +2,7 @@ import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
import { CloudWorkspaceIcon, LocalWorkspaceIcon } from '@blocksuite/icons';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
import type React from 'react';
import { useCallback } from 'react';
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
import type { AllWorkspace } from '../../../../shared';
@ -18,6 +19,10 @@ export type WorkspaceSelectorProps = {
onClick: () => void;
};
/**
* @todo-Doma Co-locate WorkspaceListModal with {@link WorkspaceSelector},
* because it's never used elsewhere.
*/
export const WorkspaceSelector: React.FC<WorkspaceSelectorProps> = ({
currentWorkspace,
onClick,
@ -26,8 +31,28 @@ export const WorkspaceSelector: React.FC<WorkspaceSelectorProps> = ({
currentWorkspace?.blockSuiteWorkspace ?? null
);
const [workspace] = useCurrentWorkspace();
// Open dialog when `Enter` or `Space` pressed
// TODO-Doma Refactor with `@radix-ui/react-dialog` or other libraries that handle these out of the box and be accessible by default
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
// TODO-Doma Rename this callback to `onOpenDialog` or something to reduce ambiguity.
onClick();
}
},
[onClick]
);
return (
<StyledSelectorContainer onClick={onClick} data-testid="current-workspace">
<StyledSelectorContainer
role="button"
tabIndex={0}
onClick={onClick}
onKeyDown={handleKeyDown}
data-testid="current-workspace"
>
<WorkspaceAvatar
data-testid="workspace-avatar"
className={workspaceAvatarStyle}

View File

@ -36,14 +36,6 @@ export const Favorite = ({
(currentWorkspaceId && paths.favorite(currentWorkspaceId))
}
>
<StyledCollapseButton
onClick={useCallback(() => {
setOpenSubFavorite(!showSubFavorite);
}, [showSubFavorite])}
collapse={showSubFavorite}
>
<ArrowDownSmallIcon />
</StyledCollapseButton>
<StyledLink
href={{
pathname: currentWorkspaceId && paths.favorite(currentWorkspaceId),
@ -52,6 +44,14 @@ export const Favorite = ({
<FavoriteIcon />
{t['Favorites']()}
</StyledLink>
<StyledCollapseButton
onClick={useCallback(() => {
setOpenSubFavorite(!showSubFavorite);
}, [showSubFavorite])}
collapse={showSubFavorite}
>
<ArrowDownSmallIcon />
</StyledCollapseButton>
</StyledListItem>
<FavoriteList
currentPageId={currentPageId}

View File

@ -63,6 +63,9 @@ export const StyledCollapseButton = styled('button')<{
':hover': {
opacity: '1',
},
':focus-visible': {
outline: '-webkit-focus-ring-color auto 1px',
},
};
});

View File

@ -17,7 +17,8 @@ import {
import type { Page } from '@blocksuite/store';
import { useAtomValue } from 'jotai';
import type { ReactElement, UIEvent } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import type React from 'react';
import { useCallback, useEffect, useState } from 'react';
import type { AllWorkspace } from '../../shared';
import ChangeLog from '../pure/workspace-slider-bar/changeLog';
@ -80,6 +81,16 @@ export const RootAppSidebar = ({
}
}, [sidebarOpen]);
const [ref, setRef] = useState<HTMLElement | null>(null);
const handleQuickSearchButtonKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onOpenQuickSearchModal();
}
},
[onOpenQuickSearchModal]
);
return (
<>
<AppSidebar
@ -104,8 +115,11 @@ export const RootAppSidebar = ({
onClick={useCallback(() => {
onOpenQuickSearchModal();
}, [onOpenQuickSearchModal])}
onKeyDown={handleQuickSearchButtonKeyDown}
>
<div
role="button"
tabIndex={0}
style={{
display: 'flex',
flex: 1,