Skip to content
This repository has been archived by the owner on Jan 2, 2025. It is now read-only.

Commit

Permalink
add arrow navigation to all dropdowns
Browse files Browse the repository at this point in the history
  • Loading branch information
anastasiya1155 committed Jan 30, 2024
1 parent 1f85a6d commit f8edd2b
Show file tree
Hide file tree
Showing 31 changed files with 155 additions and 411 deletions.
2 changes: 2 additions & 0 deletions client/src/CommandBar/Body/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CommandBarSectionType } from '../../types/general';
import useKeyboardNavigation from '../../hooks/useKeyboardNavigation';
import { useArrowNavigation } from '../../hooks/useArrowNavigation';
import { ArrowNavigationContext } from '../../context/arrowNavigationContext';
import { noOp } from '../../utils';
import Section from './Section';

type Props = {
Expand Down Expand Up @@ -31,6 +32,7 @@ const CommandBarBody = ({
() => ({
focusedIndex,
setFocusedIndex,
handleClose: noOp,
}),
[focusedIndex],
);
Expand Down
52 changes: 4 additions & 48 deletions client/src/CommandBar/steps/Documentation/ActionsDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import {
memo,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { memo, useContext, useEffect, useMemo } from 'react';
import SectionItem from '../../../components/Dropdown/Section/SectionItem';
import DropdownSection from '../../../components/Dropdown/Section';
import { CommandBarContext } from '../../../context/commandBarContext';
import useKeyboardNavigation from '../../../hooks/useKeyboardNavigation';

type Props = {
handleClose: () => void;
};

const ActionsDropDown = ({ handleClose }: Props) => {
const { focusedItem } = useContext(CommandBarContext.FooterValues);
const [focusedIndex, setFocusedIndex] = useState(0);

const focusedDropdownItems = useMemo(() => {
return (
Expand All @@ -42,56 +33,21 @@ const ActionsDropDown = ({ handleClose }: Props) => {
}
}, [focusedDropdownItemsLength]);

const handleKeyEvent = useCallback(
(e: KeyboardEvent) => {
if (e.key === 'ArrowDown') {
e.preventDefault();
e.stopPropagation();
setFocusedIndex((prev) =>
prev < focusedDropdownItemsLength - 1 ? prev + 1 : 0,
);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
e.stopPropagation();
setFocusedIndex((prev) =>
prev > 0 ? prev - 1 : focusedDropdownItemsLength - 1,
);
} else if (e.key === 'Enter') {
let currentIndex = 0;

for (let i = 0; i < focusedDropdownItems.length; i++) {
for (let j = 0; j < focusedDropdownItems[i].items.length; j++) {
if (currentIndex === focusedIndex) {
return focusedDropdownItems[i].items[j].onClick();
}
currentIndex++;
}
}
}
},
[focusedIndex, focusedDropdownItems, focusedDropdownItemsLength],
);
useKeyboardNavigation(handleKeyEvent);

return (
<div>
{!!focusedDropdownItems.length &&
focusedDropdownItems.map(
(section: {
items: Record<string, any>[];
key: string;
itemsOffset: number;
}) => (
(section: { items: Record<string, any>[]; key: string }) => (
<DropdownSection key={section.key}>
{section.items.map((item: Record<string, any>, i: number) => (
{section.items.map((item: Record<string, any>) => (
<SectionItem
color="base"
shortcut={item.shortcut}
key={item.key}
isFocused={focusedIndex === i + section.itemsOffset}
onClick={item.onClick}
label={item.label}
icon={item.icon}
index={item.key}
/>
))}
</DropdownSection>
Expand Down
97 changes: 7 additions & 90 deletions client/src/CommandBar/steps/ManageRepos/ActionsDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import {
Dispatch,
memo,
SetStateAction,
useCallback,
useContext,
useMemo,
useState,
} from 'react';
import { Dispatch, memo, SetStateAction, useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import SectionLabel from '../../../components/Dropdown/Section/SectionLabel';
import SectionItem from '../../../components/Dropdown/Section/SectionItem';
import DropdownSection from '../../../components/Dropdown/Section';
import { CommandBarContext } from '../../../context/commandBarContext';
import useKeyboardNavigation from '../../../hooks/useKeyboardNavigation';
import { HardDriveIcon, ShapesIcon } from '../../../icons';
import GitHubIcon from '../../../icons/GitHubIcon';
import { Filter, Provider } from './index';
Expand All @@ -34,7 +25,6 @@ const ActionsDropDown = ({
}: Props) => {
const { t } = useTranslation();
const { focusedItem } = useContext(CommandBarContext.FooterValues);
const [focusedIndex, setFocusedIndex] = useState(0);

const providerIconMap = useMemo(
() => ({
Expand Down Expand Up @@ -63,94 +53,24 @@ const ActionsDropDown = ({
);
}, [focusedItem]);

const focusedDropdownItemsLength = useMemo(() => {
return focusedDropdownItems.reduce(
(prev: number, curr: { items: Record<string, any>[]; key: string }) =>
prev + curr.items.length,
0,
);
}, [focusedDropdownItems]);

const handleKeyEvent = useCallback(
(e: KeyboardEvent) => {
if (e.key === 'ArrowDown') {
e.preventDefault();
e.stopPropagation();
setFocusedIndex((prev) =>
prev <
providerOptions.length +
filterOptions.length +
focusedDropdownItemsLength -
1
? prev + 1
: 0,
);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
e.stopPropagation();
setFocusedIndex((prev) =>
prev > 0
? prev - 1
: providerOptions.length +
filterOptions.length +
focusedDropdownItemsLength -
1,
);
} else if (e.key === 'Enter') {
if (focusedIndex < focusedDropdownItemsLength) {
let currentIndex = 0;

for (let i = 0; i < focusedDropdownItems.length; i++) {
for (let j = 0; j < focusedDropdownItems[i].items.length; j++) {
if (currentIndex === focusedIndex) {
handleClose();
return focusedDropdownItems[i].items[j].onClick();
}
currentIndex++;
}
}
} else if (
focusedIndex <
focusedDropdownItemsLength + providerOptions.length
) {
setRepoType(
providerOptions[focusedIndex - focusedDropdownItemsLength],
);
} else {
setFilter(
filterOptions[
focusedIndex - focusedDropdownItemsLength - providerOptions.length
],
);
}
}
},
[focusedIndex, focusedDropdownItems, focusedDropdownItemsLength],
);
useKeyboardNavigation(handleKeyEvent);

return (
<div>
{!!focusedDropdownItems.length &&
focusedDropdownItems.map(
(section: {
items: Record<string, any>[];
key: string;
itemsOffset: number;
}) => (
(section: { items: Record<string, any>[]; key: string }) => (
<DropdownSection borderBottom key={section.key}>
{section.items.map((item: Record<string, any>, i: number) => (
{section.items.map((item: Record<string, any>) => (
<SectionItem
color="base"
shortcut={item.shortcut}
key={item.key}
isFocused={focusedIndex === i + section.itemsOffset}
onClick={() => {
item.onClick();
handleClose();
}}
label={item.label}
icon={item.icon}
index={item.key}
/>
))}
</DropdownSection>
Expand All @@ -165,8 +85,8 @@ const ActionsDropDown = ({
color="base"
shortcut={['shift', (i + 1).toString()]}
key={type}
index={`provider-${type}`}
isSelected={repoType === type}
isFocused={focusedIndex === i + focusedDropdownItemsLength}
onClick={() => {
setRepoType(type);
handleClose();
Expand All @@ -179,15 +99,12 @@ const ActionsDropDown = ({
</DropdownSection>
<DropdownSection>
<SectionLabel text={t('Display')} />
{filterOptions.map((type, i) => (
{filterOptions.map((type) => (
<SectionItem
color="base"
key={type}
isSelected={filter === type}
isFocused={
focusedIndex ===
i + focusedDropdownItemsLength + providerOptions.length
}
index={`display-${type}`}
onClick={() => {
setFilter(type);
handleClose();
Expand Down
53 changes: 4 additions & 49 deletions client/src/CommandBar/steps/PrivateRepos/ActionsDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { memo, useCallback, useContext, useMemo, useState } from 'react';
import { memo, useContext, useMemo } from 'react';
import SectionItem from '../../../components/Dropdown/Section/SectionItem';
import DropdownSection from '../../../components/Dropdown/Section';
import { CommandBarContext } from '../../../context/commandBarContext';
import useKeyboardNavigation from '../../../hooks/useKeyboardNavigation';

type Props = {};

const ActionsDropDown = ({}: Props) => {
const { focusedItem } = useContext(CommandBarContext.FooterValues);
const [focusedIndex, setFocusedIndex] = useState(0);

const focusedDropdownItems = useMemo(() => {
return (
Expand All @@ -19,61 +17,18 @@ const ActionsDropDown = ({}: Props) => {
);
}, [focusedItem]);

const focusedDropdownItemsLength = useMemo(() => {
return focusedDropdownItems.reduce(
(prev: number, curr: { items: Record<string, any>[]; key: string }) =>
prev + curr.items.length,
0,
);
}, [focusedDropdownItems]);

const handleKeyEvent = useCallback(
(e: KeyboardEvent) => {
if (e.key === 'ArrowDown') {
e.preventDefault();
e.stopPropagation();
setFocusedIndex((prev) =>
prev < focusedDropdownItemsLength - 1 ? prev + 1 : 0,
);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
e.stopPropagation();
setFocusedIndex((prev) =>
prev > 0 ? prev - 1 : focusedDropdownItemsLength - 1,
);
} else if (e.key === 'Enter') {
let currentIndex = 0;

for (let i = 0; i < focusedDropdownItems.length; i++) {
for (let j = 0; j < focusedDropdownItems[i].items.length; j++) {
if (currentIndex === focusedIndex) {
return focusedDropdownItems[i].items[j].onClick();
}
currentIndex++;
}
}
}
},
[focusedIndex, focusedDropdownItems, focusedDropdownItemsLength],
);
useKeyboardNavigation(handleKeyEvent);

return (
<div>
{!!focusedDropdownItems.length &&
focusedDropdownItems.map(
(section: {
items: Record<string, any>[];
key: string;
itemsOffset: number;
}) => (
(section: { items: Record<string, any>[]; key: string }) => (
<DropdownSection key={section.key}>
{section.items.map((item: Record<string, any>, i: number) => (
{section.items.map((item: Record<string, any>) => (
<SectionItem
color="base"
shortcut={item.shortcut}
key={item.key}
isFocused={focusedIndex === i + section.itemsOffset}
index={item.key}
onClick={item.onClick}
label={item.label}
icon={item.icon}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ const ActionsDropdown = ({
<div>
<DropdownSection>
<SectionItem
index={'split-view'}
label={t('Open in split view')}
shortcut={openInSplitViewShortcut}
onClick={handleMoveToAnotherSide}
icon={<SplitViewIcon sizeClassName="w-4 h-4" />}
/>
{conversationId && (
<SectionItem
index={'del-chat'}
label={t('Delete conversation')}
// shortcut={shortcuts.splitView}
onClick={removeConversation}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ const ActionsDropdown = ({
<DropdownSection borderBottom>
{isDocInContext ? (
<SectionItem
index={'del-from-studio'}
label={t('Remove from studio')}
onClick={handleRemoveFromStudio}
shortcut={removeFromStudioShortcut}
icon={<StudioCloseSignIcon sizeClassName="w-4 h-4" />}
/>
) : (
<SectionItem
index={'add-to-studio'}
label={t('Add to studio')}
onClick={handleAddToStudio}
shortcut={addToStudioShortcut}
Expand All @@ -49,6 +51,7 @@ const ActionsDropdown = ({
</DropdownSection>
<DropdownSection>
<SectionItem
index={'split-view'}
label={t('Open in split view')}
shortcut={openInSplitViewShortcut}
onClick={handleMoveToAnotherSide}
Expand Down
Loading

0 comments on commit f8edd2b

Please sign in to comment.