mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-09-21 08:28:58 +03:00
feat(web): improve keyboard navigation in RootAppSidebar (#2256)
Co-authored-by: Himself65 <himself65@outlook.com>
This commit is contained in:
parent
d040a7fb50
commit
d1457075b3
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -63,6 +63,9 @@ export const StyledCollapseButton = styled('button')<{
|
||||
':hover': {
|
||||
opacity: '1',
|
||||
},
|
||||
':focus-visible': {
|
||||
outline: '-webkit-focus-ring-color auto 1px',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user