UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

167 lines (166 loc) 7.49 kB
"use client"; const require_ScrollArea = require("../ScrollArea/ScrollArea.cjs"); const require_UnstyledButton = require("../UnstyledButton/UnstyledButton.cjs"); const require_AccordionChevron = require("../Accordion/AccordionChevron.cjs"); const require_CheckIcon = require("../Checkbox/CheckIcon.cjs"); const require_get_cascader_columns = require("./get-cascader-columns.cjs"); const require_use_cascader_safe_area = require("./use-cascader-safe-area.cjs"); let react = require("react"); let react_jsx_runtime = require("react/jsx-runtime"); //#region packages/@mantine/core/src/components/Cascader/CascaderColumns.tsx function getCascaderOptionId(listId, level, value) { return listId ? `${listId}-${level}-${value}` : void 0; } function CascaderColumns({ data, activePath, value, keyboardNav, withCheckIcon, checkIconPosition, renderOption, columnWidth, maxDisplayedLevels, previousLevelsControlLabel, nextLevelsControlLabel, maxDropdownHeight, nothingFoundMessage, getStyles, unstyled, scrollAreaProps, onOptionClick, onOptionMouseEnter, onColumnsMouseLeave, onPointerActivity, listId, safeAreaPolygon }) { const allColumns = require_get_cascader_columns.getCascaderColumns(data, activePath); const totalColumns = allColumns.length; const maxLevels = maxDisplayedLevels && maxDisplayedLevels > 0 ? maxDisplayedLevels : totalColumns; const maxOffset = Math.max(0, totalColumns - maxLevels); const focusedLevel = activePath.length - 1; const showCheckIcon = withCheckIcon !== false; const activePathKey = JSON.stringify(activePath); const [windowState, setWindowState] = (0, react.useState)({ key: activePathKey, offset: 0 }); const windowOffset = windowState.key === activePathKey ? windowState.offset : 0; if (windowState.key !== activePathKey) setWindowState({ key: activePathKey, offset: 0 }); const setWindowOffset = (updater) => setWindowState((current) => ({ key: activePathKey, offset: updater(current.offset) })); const windowStart = Math.max(0, maxOffset - Math.min(windowOffset, maxOffset)); const windowEnd = Math.min(totalColumns, windowStart + maxLevels); const visibleColumns = allColumns.slice(windowStart, windowEnd); const hiddenBefore = windowStart; const hiddenAfter = totalColumns - windowEnd; const check = showCheckIcon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_CheckIcon.CheckIcon, { ...getStyles("columnOptionCheck") }) : null; const columnRefs = (0, react.useRef)({}); const safeArea = require_use_cascader_safe_area.useCascaderSafeArea({ safeAreaPolygon, onFlush: onOptionMouseEnter }); return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { ...getStyles("columnsList"), role: "presentation", onMouseLeave: () => { safeArea.disarm(); onColumnsMouseLeave?.(); }, onMouseMove: onPointerActivity, children: [ hiddenBefore > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_UnstyledButton.UnstyledButton, { ...getStyles("columnsOverflow"), "data-position": "start", tabIndex: -1, unstyled, "aria-label": previousLevelsControlLabel, title: previousLevelsControlLabel, onMouseDown: (event) => event.preventDefault(), onClick: () => setWindowOffset((current) => Math.min(maxOffset, current + 1)), children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AccordionChevron.AccordionChevron, {}) }), visibleColumns.map((options, index) => { const level = windowStart + index; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: (node) => { columnRefs.current[level] = node; }, "data-last": index === visibleColumns.length - 1 && hiddenAfter === 0 || void 0, ...getStyles("column", { style: columnWidth ? { width: columnWidth, minWidth: columnWidth } : void 0 }), children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScrollArea.ScrollArea.Autosize, { mah: maxDropdownHeight ?? 260, type: "scroll", scrollbarSize: "var(--combobox-padding)", role: "listbox", ...scrollAreaProps, ...getStyles("columnScroll"), children: options.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ...getStyles("columnEmpty"), children: nothingFoundMessage }) : options.map((option) => { const isActive = activePath[level] === option.value; const isCurrent = isActive && level === focusedLevel && keyboardNav; const isInPath = isActive && level < focusedLevel; const hasChildren = require_get_cascader_columns.cascaderOptionHasChildren(option); const isSelected = !!value && value.length === level + 1 && value[level] === option.value; return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_UnstyledButton.UnstyledButton, { id: getCascaderOptionId(listId, level, option.value), role: "option", "aria-selected": isCurrent || void 0, "aria-disabled": option.disabled || void 0, "data-active": isCurrent || void 0, "data-in-path": isInPath || void 0, "data-selected": isSelected || void 0, "data-disabled": option.disabled || void 0, tabIndex: -1, unstyled, onMouseDown: (event) => event.preventDefault(), onClick: () => { if (!option.disabled) onOptionClick(level, option); }, onMouseEnter: () => { if (option.disabled) return; if (safeArea.isBlocked(level)) { safeArea.setPending(level, option); return; } onOptionMouseEnter(level, option); }, onMouseLeave: (event) => { safeArea.clearPending(level, option); if (!safeArea.enabled || option.disabled) return; if (activePath[level] !== option.value) return; const floating = columnRefs.current[level + 1]; if (!floating) return; safeArea.arm({ level, reference: event.currentTarget, floating, clientX: event.clientX, clientY: event.clientY }); }, ...getStyles("columnOption"), children: [ isSelected && checkIconPosition === "left" && check, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { ...getStyles("columnOptionLabel"), children: renderOption ? renderOption(option, level) : option.label ?? option.value }), isSelected && checkIconPosition !== "left" && check, hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { ...getStyles("columnOptionIcon"), children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AccordionChevron.AccordionChevron, {}) }) ] }, option.value); }) }) }, level); }), hiddenAfter > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_UnstyledButton.UnstyledButton, { ...getStyles("columnsOverflow"), "data-position": "end", tabIndex: -1, unstyled, "aria-label": nextLevelsControlLabel, title: nextLevelsControlLabel, onMouseDown: (event) => event.preventDefault(), onClick: () => setWindowOffset((current) => Math.max(0, current - 1)), children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AccordionChevron.AccordionChevron, {}) }) ] }); } CascaderColumns.displayName = "@mantine/core/CascaderColumns"; //#endregion exports.CascaderColumns = CascaderColumns; exports.getCascaderOptionId = getCascaderOptionId; //# sourceMappingURL=CascaderColumns.cjs.map