UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

115 lines (114 loc) 4.45 kB
"use client"; import { createEventHandler } from "../../../core/utils/create-event-handler/create-event-handler.mjs"; import { useProps } from "../../../core/MantineProvider/use-props/use-props.mjs"; import { factory } from "../../../core/factory/factory.mjs"; import { Input } from "../../Input/Input.mjs"; import { useMenuContext } from "../Menu.context.mjs"; import Menu_module_default from "../Menu.module.mjs"; import { useEffect, useRef } from "react"; import { useMergedRef } from "@mantine/hooks"; import { jsx } from "react/jsx-runtime"; //#region packages/@mantine/core/src/components/Menu/MenuSearch/MenuSearch.tsx const ITEM_SELECTOR = "[data-menu-item]:not([data-disabled])"; const ACTIVE_SELECTOR = "[data-menu-active]"; function getDropdown(node) { return node?.closest("[data-menu-dropdown]"); } function getItems(dropdown) { if (!dropdown) return []; return Array.from(dropdown.querySelectorAll(ITEM_SELECTOR)).filter((item) => item.closest("[data-menu-dropdown]") === dropdown); } function clearActive(dropdown) { if (!dropdown) return; dropdown.querySelectorAll(ACTIVE_SELECTOR).forEach((node) => { if (node.closest("[data-menu-dropdown]") === dropdown) node.removeAttribute("data-menu-active"); }); } function setActive(item, dropdown) { clearActive(dropdown); if (item) { item.setAttribute("data-menu-active", "true"); item.scrollIntoView({ block: "nearest" }); } } function getActiveIndex(items) { return items.findIndex((item) => item.hasAttribute("data-menu-active")); } const defaultProps = { clearSearchOnClose: true }; const MenuSearch = factory((props) => { const { classNames, styles, onKeyDown, onChange, size, clearSearchOnClose, ref, ...others } = useProps("MenuSearch", defaultProps, props); const ctx = useMenuContext(); const inputRef = useRef(null); const mergedRef = useMergedRef(ref, inputRef); const onChangeRef = useRef(onChange); onChangeRef.current = onChange; useEffect(() => { return ctx.registerSearch(); }, [ctx.registerSearch]); useEffect(() => { if (clearSearchOnClose) ctx.searchExitClearRef.current = () => { onChangeRef.current?.({ currentTarget: { value: "" } }); }; else ctx.searchExitClearRef.current = null; }, [clearSearchOnClose, ctx.searchExitClearRef]); useEffect(() => { if (!ctx.opened) clearActive(getDropdown(inputRef.current)); }, [ctx.opened]); const handleChange = createEventHandler(onChange, (event) => { clearActive(getDropdown(event.currentTarget)); }); const handleKeyDown = createEventHandler(onKeyDown, (event) => { if (event.defaultPrevented) return; const dropdown = getDropdown(event.currentTarget); const items = getItems(dropdown); if (event.key === "ArrowDown") { event.preventDefault(); if (items.length === 0) return; const current = getActiveIndex(items); setActive(items[current >= items.length - 1 ? ctx.loop ? 0 : current : current + 1] ?? null, dropdown); } else if (event.key === "ArrowUp") { event.preventDefault(); if (items.length === 0) return; const current = getActiveIndex(items); setActive(items[current <= 0 ? current === -1 ? items.length - 1 : ctx.loop ? items.length - 1 : 0 : current - 1] ?? null, dropdown); } else if (event.key === "Home") { event.preventDefault(); if (items.length > 0) setActive(items[0], dropdown); } else if (event.key === "End") { event.preventDefault(); if (items.length > 0) setActive(items[items.length - 1], dropdown); } else if (event.key === "Enter") { if (event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return; const target = items[getActiveIndex(items)]; if (target) { event.preventDefault(); if (target.hasAttribute("data-sub-menu-item")) { target.focus(); target.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowRight", bubbles: true })); } else target.click(); } } }); const _styles = ctx.getStyles("search"); return /* @__PURE__ */ jsx(Input, { "data-autofocus": true, "data-mantine-stop-propagation": true, type: "search", size, ...others, ref: mergedRef, classNames: [{ input: _styles.className }, classNames], styles: [{ input: _styles.style }, styles], onKeyDown: handleKeyDown, onChange: handleChange, __staticSelector: "Menu" }); }); MenuSearch.classes = Menu_module_default; MenuSearch.displayName = "@mantine/core/MenuSearch"; //#endregion export { MenuSearch }; //# sourceMappingURL=MenuSearch.mjs.map