Fix/scope hotkeys (#581)

* WIP

* asd

* Fix

* Fix lint

* Removed console log

* asd

* Removed isDefined

* Fix/debounce company card onchange (#580)

* Add internal state and debounce for editable text card

* Use debounce for date fields too

* Update refetch

* Nit

* Removed comments

* Ménage

---------

Co-authored-by: Emilien Chauvet <emilien.chauvet.enpc@gmail.com>
This commit is contained in:
Lucas Bordeau
2023-07-11 03:53:46 +02:00
committed by GitHub
parent 1c8aaff39d
commit 5f98b70c6a
71 changed files with 581 additions and 509 deletions
@@ -1,3 +1,4 @@
import { useRef } from 'react';
import { useTheme } from '@emotion/react';
import { IconPlus } from '@tabler/icons-react';
@@ -7,6 +8,7 @@ import { DropdownMenuButton } from '@/ui/components/menu/DropdownMenuButton';
import { DropdownMenuItemContainer } from '@/ui/components/menu/DropdownMenuItemContainer';
import { DropdownMenuSearch } from '@/ui/components/menu/DropdownMenuSearch';
import { DropdownMenuSeparator } from '@/ui/components/menu/DropdownMenuSeparator';
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
import { isDefined } from '@/utils/type-guards/isDefined';
import { useEntitySelectSearch } from '../hooks/useEntitySelectSearch';
@@ -27,19 +29,27 @@ export function SingleEntitySelect<
entities,
onEntitySelected,
onCreate,
onCancel,
}: {
onCancel?: () => void;
onCreate?: () => void;
entities: EntitiesForSingleEntitySelect<CustomEntityForSelect>;
onEntitySelected: (entity: CustomEntityForSelect) => void;
}) {
const containerRef = useRef<HTMLDivElement>(null);
const theme = useTheme();
const { searchFilter, handleSearchFilterChange } = useEntitySelectSearch();
const showCreateButton = isDefined(onCreate) && searchFilter !== '';
useListenClickOutsideArrayOfRef([containerRef], () => {
onCancel?.();
});
return (
<DropdownMenu>
<DropdownMenu ref={containerRef}>
<DropdownMenuSearch
value={searchFilter}
onChange={handleSearchFilterChange}
@@ -60,6 +70,7 @@ export function SingleEntitySelect<
<SingleEntitySelectBase
entities={entities}
onEntitySelected={onEntitySelected}
onCancel={onCancel}
/>
</DropdownMenu>
);
@@ -1,4 +1,5 @@
import { useRef } from 'react';
import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
@@ -27,30 +28,41 @@ export function SingleEntitySelectBase<
>({
entities,
onEntitySelected,
onCancel,
}: {
entities: EntitiesForSingleEntitySelect<CustomEntityForSelect>;
onEntitySelected: (entity: CustomEntityForSelect) => void;
onCancel?: () => void;
}) {
const containerRef = useRef<HTMLDivElement>(null);
const entitiesInDropdown = isDefined(entities.selectedEntity)
? [entities.selectedEntity, ...(entities.entitiesToSelect ?? [])]
: entities.entitiesToSelect ?? [];
const { hoveredIndex } = useEntitySelectScroll({
const { hoveredIndex, resetScroll } = useEntitySelectScroll({
entities: entitiesInDropdown,
containerRef,
});
// TODO: move to better place for scopping
useScopedHotkeys(
'enter',
Key.Enter,
() => {
onEntitySelected(entitiesInDropdown[hoveredIndex]);
resetScroll();
},
InternalHotkeysScope.RelationPicker,
[entitiesInDropdown, hoveredIndex, onEntitySelected],
);
useScopedHotkeys(
Key.Escape,
() => {
onCancel?.();
},
InternalHotkeysScope.RelationPicker,
[onCancel],
);
return (
<DropdownMenuItemContainer ref={containerRef}>
{entities.loading ? (
@@ -21,6 +21,22 @@ export function useEntitySelectScroll<
relationPickerHoverIndexScopedState,
);
function resetScroll() {
setHoveredIndex(0);
const currentHoveredRef = containerRef.current?.children[0] as HTMLElement;
scrollIntoView(currentHoveredRef, {
align: {
top: 0,
},
isScrollable: (target) => {
return target === containerRef.current;
},
time: 0,
});
}
useScopedHotkeys(
Key.ArrowUp,
() => {
@@ -60,7 +76,6 @@ export function useEntitySelectScroll<
] as HTMLElement;
if (currentHoveredRef) {
console.log({ currentHoveredRef, containerRef });
scrollIntoView(currentHoveredRef, {
align: {
top: 0.15,
@@ -78,5 +93,6 @@ export function useEntitySelectScroll<
return {
hoveredIndex,
resetScroll,
};
}