UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

170 lines (169 loc) 6.64 kB
"use client"; require("../../../_virtual/_rolldown/runtime.cjs"); const require_move_pill = require("./move-pill.cjs"); let react = require("react"); //#region packages/@mantine/core/src/components/Combobox/use-pills-reorder/use-pills-reorder.ts const findSearchInput = (container) => { const lastChild = container.lastElementChild; if (!lastChild) return null; if (lastChild instanceof HTMLInputElement) return lastChild; return lastChild.querySelector("input"); }; const valuesMatch = (a, b) => { if (a === b) return true; if (a.length !== b.length) return false; for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false; return true; }; function usePillsReorder({ value, onChange, enabled }) { const dragStateRef = (0, react.useRef)({ draggedIndex: null, currentDropTarget: null }); const pendingFocusRef = (0, react.useRef)(null); const containerRef = (0, react.useRef)(null); const valueRef = (0, react.useRef)(value); valueRef.current = value; (0, react.useEffect)(() => { const pending = pendingFocusRef.current; if (!pending) return; pendingFocusRef.current = null; if (!valuesMatch(valueRef.current, pending.expectedValue)) return; pending.container?.querySelector(`[data-mantine-pill-index="${pending.index}"]`)?.focus(); }); const setContainer = (0, react.useCallback)((node) => { containerRef.current = node; }, []); const getListProps = () => { if (!enabled) return {}; return { ref: setContainer }; }; const handleInputKeyDown = (event) => { if (!enabled || event.key !== "ArrowLeft") return; const input = event.currentTarget; if (!(input.value.length === 0 || input.selectionStart === 0 && input.selectionEnd === 0)) return; const container = containerRef.current; if (!container) return; const pills = container.querySelectorAll("[data-mantine-pill-index]"); if (pills.length === 0) return; event.preventDefault(); pills[pills.length - 1].focus(); }; const getPillProps = (index) => { if (!enabled) return; return { draggable: true, tabIndex: -1, "data-mantine-pill-index": index, "aria-keyshortcuts": "Alt+ArrowLeft Alt+ArrowRight", onMouseDown: (event) => { if (event.button === 0) event.stopPropagation(); }, onDragStart: (event) => { event.stopPropagation(); event.dataTransfer.effectAllowed = "move"; event.dataTransfer.setData("text/plain", String(index)); dragStateRef.current.draggedIndex = index; const target = event.currentTarget; const rect = target.getBoundingClientRect(); const ghost = target.cloneNode(true); ghost.removeAttribute("data-dragging"); ghost.removeAttribute("data-drag-over"); ghost.style.position = "fixed"; ghost.style.top = "-9999px"; ghost.style.left = "-9999px"; ghost.style.width = `${rect.width}px`; ghost.style.height = `${rect.height}px`; ghost.style.pointerEvents = "none"; document.body.appendChild(ghost); event.dataTransfer.setDragImage(ghost, event.clientX - rect.left, event.clientY - rect.top); setTimeout(() => ghost.parentNode?.removeChild(ghost), 0); requestAnimationFrame(() => { target.setAttribute("data-dragging", "true"); }); }, onDragOver: (event) => { const { draggedIndex } = dragStateRef.current; if (draggedIndex === null || draggedIndex === index) return; const target = event.currentTarget; const rect = target.getBoundingClientRect(); const x = event.clientX - rect.left; const position = (getComputedStyle(target).direction === "rtl" ? x > rect.width / 2 : x < rect.width / 2) ? "before" : "after"; event.preventDefault(); event.stopPropagation(); event.dataTransfer.dropEffect = "move"; const prevTarget = dragStateRef.current.currentDropTarget; if (prevTarget && prevTarget !== target) prevTarget.removeAttribute("data-drag-over"); target.setAttribute("data-drag-over", position); dragStateRef.current.currentDropTarget = target; }, onDragLeave: (event) => { const target = event.currentTarget; const related = event.relatedTarget; if (related && target.contains(related)) return; target.removeAttribute("data-drag-over"); if (dragStateRef.current.currentDropTarget === target) dragStateRef.current.currentDropTarget = null; }, onDrop: (event) => { event.preventDefault(); event.stopPropagation(); const target = event.currentTarget; const position = target.getAttribute("data-drag-over"); target.removeAttribute("data-drag-over"); const { draggedIndex } = dragStateRef.current; if (draggedIndex !== null && position && draggedIndex !== index) { const nextValue = require_move_pill.movePill(valueRef.current, draggedIndex, index, position); if (nextValue !== valueRef.current) onChange(nextValue); } dragStateRef.current.draggedIndex = null; dragStateRef.current.currentDropTarget = null; }, onDragEnd: (event) => { event.currentTarget.removeAttribute("data-dragging"); const prevTarget = dragStateRef.current.currentDropTarget; if (prevTarget) prevTarget.removeAttribute("data-drag-over"); dragStateRef.current.draggedIndex = null; dragStateRef.current.currentDropTarget = null; }, onKeyDown: (event) => { if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return; const target = event.currentTarget; const movingForward = getComputedStyle(target).direction === "rtl" ? event.key === "ArrowLeft" : event.key === "ArrowRight"; const targetIndex = movingForward ? index + 1 : index - 1; if (event.altKey) { if (targetIndex < 0 || targetIndex >= valueRef.current.length) return; event.preventDefault(); event.stopPropagation(); const position = movingForward ? "after" : "before"; const nextValue = require_move_pill.movePill(valueRef.current, index, targetIndex, position); if (nextValue === valueRef.current) return; pendingFocusRef.current = { container: target.parentElement, index: targetIndex, expectedValue: nextValue }; onChange(nextValue); return; } if (targetIndex < 0) return; const container = target.parentElement; if (!container) return; event.preventDefault(); event.stopPropagation(); if (targetIndex >= valueRef.current.length) { findSearchInput(container)?.focus(); return; } container.querySelector(`[data-mantine-pill-index="${targetIndex}"]`)?.focus(); } }; }; return { getPillProps, getListProps, handleInputKeyDown }; } //#endregion exports.usePillsReorder = usePillsReorder; //# sourceMappingURL=use-pills-reorder.cjs.map