UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

127 lines (126 loc) 5.35 kB
import { useMemo } from "react"; import { useSmartSelect } from "../context.js"; import { isSelectableOption } from "./is-selectable-option.js"; export function useSelectControls(isMulti, setActiveChip) { const { open, onOpenChange, openOnClick, setActiveId, container, rtl, trigger, onOptionsChange, kindAndValue: { value }, openKeys, closeKeys, options, onOptionSelect, } = useSmartSelect(); return useMemo(() => { return { onClick: () => { if (!open && openOnClick) onOpenChange(true); }, onBlur: (e) => { if (e.currentTarget.contains(e.relatedTarget)) return; onOpenChange(false); return; }, onKeyDown: (e) => { if (!open && openKeys.includes(e.key)) { e.preventDefault(); e.stopPropagation(); onOpenChange(true); return; } if (open && closeKeys.includes(e.key)) { e.preventDefault(); e.stopPropagation(); onOpenChange(false); return; } if ((e.key === "Enter" || e.key === " ") && open) { e.preventDefault(); e.stopPropagation(); const active = container?.querySelector('[data-ln-active="true"]'); if (!active) return; const id = active.getAttribute("data-ln-smart-option"); const option = options.find((x) => x.id === id); if (!option) return; onOptionSelect(option); if (active.getAttribute("data-ln-close-on-select")) { onOpenChange(false); } return; } if (isMulti) { const key = rtl ? "ArrowRight" : "ArrowLeft"; if (e.key === "Backspace") { const chips = Array.from(trigger.querySelectorAll("[data-ln-smart-select-chip]")); const lastChip = chips.at(-1); if (!lastChip) return; const id = lastChip.getAttribute("data-ln-smart-select-chip"); onOptionsChange(value.filter((x) => x.id !== id)); return; } if (e.key === key) { const chips = Array.from(trigger.querySelectorAll("[data-ln-smart-select-chip]")); const first = chips.at(-1); if (!first) return; first.focus(); onOpenChange(false); setActiveChip(first.getAttribute("data-ln-smart-select-chip")); return; } } if (!open || !container) return; if (e.key === "ArrowUp") { e.preventDefault(); e.stopPropagation(); const active = container.querySelector('[data-ln-active="true"]'); let current = active?.previousElementSibling; while (current && !isSelectableOption(current)) current = current.previousElementSibling; if (!current) { current = container.lastElementChild; while (current && !isSelectableOption(current)) current = current.previousElementSibling; } if (current) { setActiveId(current.getAttribute("data-ln-smart-option")); current.scrollIntoView({ block: "nearest" }); } return; } if (e.key === "ArrowDown") { e.preventDefault(); e.stopPropagation(); const active = container.querySelector('[data-ln-active="true"]'); let current = active?.nextElementSibling; while (current && !isSelectableOption(current)) current = current.nextElementSibling; if (!current) { current = container.firstElementChild; while (current && !isSelectableOption(current)) current = current.nextElementSibling; } if (current) { setActiveId(current.getAttribute("data-ln-smart-option")); current.scrollIntoView({ block: "nearest" }); } return; } }, }; }, [ closeKeys, container, isMulti, onOpenChange, onOptionSelect, onOptionsChange, open, openKeys, openOnClick, options, rtl, setActiveChip, setActiveId, trigger, value, ]); }