Uniformize folder structure (#693)
* Uniformize folder structure * Fix icons * Fix icons * Fix tests * Fix tests
This commit is contained in:
@ -0,0 +1,98 @@
|
||||
import scrollIntoView from 'scroll-into-view';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
||||
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
|
||||
|
||||
import { relationPickerHoverIndexScopedState } from '../states/relationPickerHoverIndexScopedState';
|
||||
import { EntityForSelect } from '../types/EntityForSelect';
|
||||
import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope';
|
||||
|
||||
export function useEntitySelectScroll<
|
||||
CustomEntityForSelect extends EntityForSelect,
|
||||
>({
|
||||
containerRef,
|
||||
entities,
|
||||
}: {
|
||||
entities: CustomEntityForSelect[];
|
||||
containerRef: React.RefObject<HTMLDivElement>;
|
||||
}) {
|
||||
const [hoveredIndex, setHoveredIndex] = useRecoilScopedState(
|
||||
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,
|
||||
() => {
|
||||
setHoveredIndex((prevSelectedIndex) =>
|
||||
Math.max(prevSelectedIndex - 1, 0),
|
||||
);
|
||||
|
||||
const currentHoveredRef = containerRef.current?.children[
|
||||
hoveredIndex
|
||||
] as HTMLElement;
|
||||
|
||||
if (currentHoveredRef) {
|
||||
scrollIntoView(currentHoveredRef, {
|
||||
align: {
|
||||
top: 0.5,
|
||||
},
|
||||
isScrollable: (target) => {
|
||||
return target === containerRef.current;
|
||||
},
|
||||
time: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
RelationPickerHotkeyScope.RelationPicker,
|
||||
[setHoveredIndex, entities],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.ArrowDown,
|
||||
() => {
|
||||
setHoveredIndex((prevSelectedIndex) =>
|
||||
Math.min(prevSelectedIndex + 1, (entities?.length ?? 0) - 1),
|
||||
);
|
||||
|
||||
const currentHoveredRef = containerRef.current?.children[
|
||||
hoveredIndex
|
||||
] as HTMLElement;
|
||||
|
||||
if (currentHoveredRef) {
|
||||
scrollIntoView(currentHoveredRef, {
|
||||
align: {
|
||||
top: 0.15,
|
||||
},
|
||||
isScrollable: (target) => {
|
||||
return target === containerRef.current;
|
||||
},
|
||||
time: 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
RelationPickerHotkeyScope.RelationPicker,
|
||||
[setHoveredIndex, entities],
|
||||
);
|
||||
|
||||
return {
|
||||
hoveredIndex,
|
||||
resetScroll,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
import debounce from 'lodash.debounce';
|
||||
|
||||
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
|
||||
|
||||
import { relationPickerHoverIndexScopedState } from '../states/relationPickerHoverIndexScopedState';
|
||||
import { relationPickerSearchFilterScopedState } from '../states/relationPickerSearchFilterScopedState';
|
||||
|
||||
export function useEntitySelectSearch() {
|
||||
const [, setHoveredIndex] = useRecoilScopedState(
|
||||
relationPickerHoverIndexScopedState,
|
||||
);
|
||||
|
||||
const [searchFilter, setSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
|
||||
const debouncedSetSearchFilter = debounce(setSearchFilter, 100, {
|
||||
leading: true,
|
||||
});
|
||||
|
||||
function handleSearchFilterChange(
|
||||
event: React.ChangeEvent<HTMLInputElement>,
|
||||
) {
|
||||
debouncedSetSearchFilter(event.currentTarget.value);
|
||||
setHoveredIndex(0);
|
||||
}
|
||||
|
||||
return {
|
||||
searchFilter,
|
||||
handleSearchFilterChange,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user