react-use#useKeyPressEvent TypeScript Examples
The following examples show how to use
react-use#useKeyPressEvent.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Modals.tsx From flood with GNU General Public License v3.0 | 6 votes |
Modals: FC = observer(() => {
const {id} = UIStore.activeModal || {};
useKeyPressEvent('Escape', () => UIStore.setActiveModal(null));
let modal;
if (id != null) {
modal = (
<CSSTransition key={id} classNames="modal__animation" timeout={{enter: 500, exit: 500}}>
<div className="modal">
<div
className="modal__overlay"
role="none"
onClick={() => {
UIStore.setActiveModal(null);
}}
/>
{createModal(id)}
</div>
</CSSTransition>
);
}
return <TransitionGroup>{modal}</TransitionGroup>;
})
Example #2
Source File: ContextMenuMountPoint.tsx From flood with GNU General Public License v3.0 | 4 votes |
ContextMenuMountPoint: FC<ContextMenuMountPointProps> = observer(({id}: ContextMenuMountPointProps) => {
const isOpen = UIStore.activeContextMenu?.id === id;
const items = UIStore.activeContextMenu?.items ?? [];
const triggerCoordinates = UIStore.activeContextMenu?.clickPosition ?? {
x: 0,
y: 0,
};
const {i18n} = useLingui();
useKeyPressEvent('Escape', () => UIStore.dismissContextMenu(id));
return (
<ContextMenu
triggerCoordinates={triggerCoordinates}
onOverlayClick={() => {
UIStore.dismissContextMenu(id);
}}
onOverlayRightClick={(e) => {
e.preventDefault();
}}
isIn={isOpen}
>
{items.map((item, index) => {
let menuItemContent;
let menuItemClasses;
switch (item.type) {
case 'action':
menuItemClasses = classnames('menu__item', {
'is-selectable': item.clickHandler,
});
menuItemContent = (
<span>
<span
className={classnames('menu__item__label--primary', {
'has-action': item.labelAction,
})}
>
<span className="menu__item__label">{i18n._(item.label)}</span>
{item.labelAction ? (
<span className="menu__item__label__action">
<item.labelAction />
</span>
) : undefined}
</span>
{item.labelSecondary ? (
<span className="menu__item__label--secondary">
<item.labelSecondary />
</span>
) : undefined}
</span>
);
break;
case 'separator':
default:
menuItemClasses = classnames('menu__item', {
'menu__item--separator': item.type === 'separator',
});
break;
}
return (
<li className={menuItemClasses} key={item.type === 'action' ? item.action : `sep-${index}`}>
<button
type="button"
disabled={item.type !== 'action' || !item.clickHandler}
onClick={(event) => {
if (item.type !== 'separator') {
if (item.dismissMenu === false) {
event.nativeEvent.stopImmediatePropagation();
}
if (item.clickHandler) {
item.clickHandler(event);
}
if (item.dismissMenu !== false) {
UIStore.dismissContextMenu(id);
}
}
return false;
}}
onContextMenu={(event) => {
event.preventDefault();
}}
>
{menuItemContent}
</button>
</li>
);
})}
</ContextMenu>
);
})
Example #3
Source File: Dropdown.tsx From flood with GNU General Public License v3.0 | 4 votes |
Dropdown = observer( <T extends string = string>({ baseClassName, dropdownWrapperClass, dropdownButtonClass, dropdownClickRef, direction, header, matchButtonWidth, menuItems, noWrap, trigger, width, isFocusHandled, handleItemSelect, onOpen, }: DropdownProps<T>) => { const id = useRef<string>(uniqueId('dropdown_')); const isOpen = UIStore.activeDropdownMenu === id.current; const dropdownWrapperClassName = classnames(dropdownWrapperClass, `${baseClassName}--direction-${direction}`, { [`${baseClassName}--match-button-width`]: matchButtonWidth, [`${baseClassName}--width-${width}`]: width != null, [`${baseClassName}--no-wrap`]: noWrap, 'is-expanded': isOpen, }); const closeDropdown = useCallback(() => { window.removeEventListener('click', closeDropdown); UIStore.setActiveDropdownMenu(null); }, []); useKeyPressEvent('Escape', () => closeDropdown()); const openDropdown = useCallback(() => { window.addEventListener('click', closeDropdown); if (onOpen) { onOpen(); } UIStore.setActiveDropdownMenu(id.current); }, [closeDropdown, onOpen]); const handleDropdownClick = (event?: SyntheticEvent): void => { event?.stopPropagation(); if (isOpen) { closeDropdown(); } else { openDropdown(); } }; if (dropdownClickRef) { // eslint-disable-next-line no-param-reassign dropdownClickRef.current = handleDropdownClick; } let contentElement: ReactNode; if (isOpen) { const headerElement = ( <div className="dropdown__header" key="dropdown-header"> <DropdownButton className={dropdownButtonClass} label={header} isFocusHandled={isFocusHandled ?? false} onClick={handleDropdownClick} /> </div> ); const listElement = ( <ul className="dropdown__items" key="dropdown-items"> {menuItems.map((items, index) => ( // eslint-disable-next-line react/no-array-index-key <div className="dropdown__list" key={index}> {items.map((item, itemIndex) => { const classes = classnames('dropdown__item menu__item', item.className, { 'is-selectable': item.selectable !== false, 'is-selected': item.selected, }); return ( // eslint-disable-next-line react/no-array-index-key <li className={classes} key={itemIndex}> <button type="button" disabled={item.selectable === false} onClick={ item.selectable === false ? undefined : () => { closeDropdown(); handleItemSelect(item); } } > {item.displayName} </button> </li> ); })} </div> ))} </ul> ); contentElement = ( <CSSTransition classNames="menu" timeout={{enter: 250, exit: 250}}> <div className="dropdown__content menu"> {direction === 'up' ? [listElement, headerElement] : [headerElement, listElement]} </div> </CSSTransition> ); } return ( <div className={dropdownWrapperClassName}> <DropdownButton className={dropdownButtonClass} label={trigger ?? header} isFocusHandled={isFocusHandled ?? false} onClick={handleDropdownClick} /> <TransitionGroup>{contentElement}</TransitionGroup> </div> ); }, )
Example #4
Source File: TagSelect.tsx From flood with GNU General Public License v3.0 | 4 votes |
TagSelect: FC<TagSelectProps> = ({defaultValue, placeholder, id, label, onTagSelected}: TagSelectProps) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [selectedTags, setSelectedTags] = useState<Array<string>>(defaultValue ?? []);
const formRowRef = useRef<HTMLDivElement>(null);
const menuRef = useRef<HTMLDivElement>(null);
const textboxRef = useRef<HTMLInputElement>(null);
const classes = classnames('select form__element', {
'select--is-open': isOpen,
});
useKeyPressEvent('Escape', (e) => {
e.preventDefault();
setIsOpen(false);
});
useEffect(() => {
const handleDocumentClick = (e: Event) => {
if (!formRowRef.current?.contains(e.target as unknown as Node)) {
setIsOpen(false);
}
};
document.addEventListener('click', handleDocumentClick);
return () => {
document.removeEventListener('click', handleDocumentClick);
};
}, []);
useEffect(() => {
if (textboxRef.current != null) {
textboxRef.current.value = selectedTags.join();
}
if (onTagSelected) {
onTagSelected(selectedTags);
}
}, [selectedTags, onTagSelected]);
return (
<FormRowItem ref={formRowRef}>
<div className={classes}>
<Textbox
autoComplete={isOpen ? 'off' : undefined}
id={id || 'tags'}
addonPlacement="after"
defaultValue={defaultValue}
label={label}
onChange={() => {
if (textboxRef.current != null) {
let selectedTagsArray = textboxRef.current.value
.split(',')
.map((tag) => tag.trim())
.filter((tag) => tag.length > 0);
if (textboxRef.current.value.trimEnd().endsWith(',')) {
// Ensures that the trailing ',' does not get removed automatically.
selectedTagsArray.push('');
// Deduplicate
selectedTagsArray = [...new Set(selectedTagsArray)];
}
setSelectedTags(selectedTagsArray);
}
}}
placeholder={placeholder}
ref={textboxRef}
>
<FormElementAddon
onClick={() => {
setIsOpen(!isOpen);
}}
className="select__indicator"
>
<Chevron />
</FormElementAddon>
<Portal>
<ContextMenu
isIn={isOpen}
onClick={(event) => {
if (SettingStore.floodSettings.UITagSelectorMode !== 'single') {
event.nativeEvent.stopImmediatePropagation();
}
}}
overlayProps={{isInteractive: false}}
ref={menuRef}
triggerRef={textboxRef}
>
{[
...new Set([
'untagged',
...sort(Object.keys(TorrentFilterStore.taxonomy.tagCounts)).asc(),
...selectedTags,
]),
].reduce((accumulator: Array<ReactElement>, tag) => {
if (tag === '') {
return accumulator;
}
accumulator.push(
<SelectItem
id={tag}
key={tag}
isSelected={selectedTags.includes(tag)}
onClick={() => {
if (tag === 'untagged') {
setSelectedTags([]);
} else if (selectedTags.includes(tag)) {
setSelectedTags(selectedTags.filter((key) => key !== tag && key !== ''));
} else {
setSelectedTags([...selectedTags.filter((key) => key !== ''), tag]);
}
}}
>
{tag === 'untagged' ? <Trans id="filter.untagged" /> : tag}
</SelectItem>,
);
return accumulator;
}, [])}
</ContextMenu>
</Portal>
</Textbox>
</div>
</FormRowItem>
);
}