50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import React, { ReactNode } from 'react';
|
|
import FocusTrap from 'focus-trap-react';
|
|
import { isKeyHotkey } from 'is-hotkey';
|
|
import { Menu, Scroll, config } from 'folds';
|
|
|
|
import * as css from './AutocompleteMenu.css';
|
|
import { preventScrollWithArrowKey, stopPropagation } from '../../../utils/keyboard';
|
|
import { useAlive } from '../../../hooks/useAlive';
|
|
|
|
type AutocompleteMenuProps = {
|
|
requestClose: () => void;
|
|
headerContent: ReactNode;
|
|
children: ReactNode;
|
|
};
|
|
export function AutocompleteMenu({ headerContent, requestClose, children }: AutocompleteMenuProps) {
|
|
const alive = useAlive();
|
|
|
|
const handleDeactivate = () => {
|
|
if (alive()) {
|
|
// The component is unmounted so we will not call for `requestClose`
|
|
requestClose();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={css.AutocompleteMenuBase}>
|
|
<div className={css.AutocompleteMenuContainer}>
|
|
<FocusTrap
|
|
focusTrapOptions={{
|
|
initialFocus: false,
|
|
onPostDeactivate: handleDeactivate,
|
|
returnFocusOnDeactivate: false,
|
|
clickOutsideDeactivates: true,
|
|
allowOutsideClick: true,
|
|
isKeyForward: (evt: KeyboardEvent) => isKeyHotkey('arrowdown', evt),
|
|
isKeyBackward: (evt: KeyboardEvent) => isKeyHotkey('arrowup', evt),
|
|
escapeDeactivates: stopPropagation,
|
|
}}
|
|
>
|
|
<Menu className={css.AutocompleteMenu}>
|
|
<span className={css.AutocompleteMenuHeader}>{headerContent}</span>
|
|
<Scroll style={{ flexGrow: 1 }} onKeyDown={preventScrollWithArrowKey}>
|
|
<div style={{ padding: config.space.S200 }}>{children}</div>
|
|
</Scroll>
|
|
</Menu>
|
|
</FocusTrap>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|