UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

174 lines (173 loc) 7.64 kB
"use client"; const require_get_size = require("../../core/utils/get-size/get-size.cjs"); const require_create_vars_resolver = require("../../core/styles-api/create-vars-resolver/create-vars-resolver.cjs"); const require_use_props = require("../../core/MantineProvider/use-props/use-props.cjs"); const require_use_styles = require("../../core/styles-api/use-styles/use-styles.cjs"); const require_factory = require("../../core/factory/factory.cjs"); const require_Box = require("../../core/Box/Box.cjs"); const require_get_row_position_data = require("./get-row-position-data.cjs"); const require_use_dimensions = require("./use-dimensions.cjs"); const require_OverflowList_module = require("./OverflowList.module.cjs"); let react = require("react"); let _mantine_hooks = require("@mantine/hooks"); let react_jsx_runtime = require("react/jsx-runtime"); //#region packages/@mantine/core/src/components/OverflowList/OverflowList.tsx const defaultProps = { maxRows: 1, maxVisibleItems: Infinity }; const varsResolver = require_create_vars_resolver.createVarsResolver((_, { gap }) => ({ root: { "--ol-gap": require_get_size.getSpacing(gap) } })); function getDataSignature(data, getItemKey) { return data.map((item, index) => { if (getItemKey) return getItemKey(item, index); return item !== null && (typeof item === "object" || typeof item === "function") ? index : String(item); }).join("\0"); } const OverflowList = require_factory.genericFactory((_props) => { const props = require_use_props.useProps("OverflowList", defaultProps, _props); const { classNames, className, style, styles, unstyled, vars, attributes, data, renderOverflow, renderItem, maxRows, maxVisibleItems, collapseFrom, getItemKey, ref, ...others } = props; const getStyles = require_use_styles.useStyles({ name: "OverflowList", classes: require_OverflowList_module.default, props, className, style, classNames, styles, unstyled, attributes, vars, varsResolver }); const [visibleCount, setVisibleCount] = (0, react.useState)(data.length); const [subtractCount, setSubtractCount] = (0, react.useState)(0); const [phase, setPhase] = (0, react.useState)("normal"); const containerRef = (0, react.useRef)(null); const rootRef = (0, _mantine_hooks.useMergedRef)(containerRef, ref); const finalVisibleCount = visibleCount - subtractCount; const showOverflow = data.length - finalVisibleCount > 0 && phase !== "measuring"; const isCollapseStart = collapseFrom === "start"; const overflowItems = isCollapseStart ? data.slice(0, data.length - finalVisibleCount) : data.slice(finalVisibleCount); const overflowElement = showOverflow ? renderOverflow?.(overflowItems) : null; const _overflowRef = (0, react.useRef)(null); const overflowRef = (0, _mantine_hooks.useMergedRef)(_overflowRef, overflowElement?.ref); const dimensions = require_use_dimensions.useDimensions(containerRef); (0, _mantine_hooks.useIsomorphicEffect)(() => { setPhase("measuring"); setVisibleCount(data.length); setSubtractCount(0); }, [ (0, react.useMemo)(() => getDataSignature(data, getItemKey), [data, getItemKey]), maxRows, collapseFrom ]); (0, _mantine_hooks.useIsomorphicEffect)(() => { if (phase === "measuring") { countVisibleItems(); setPhase("measuring-overflow-indicator"); } }, [phase]); (0, _mantine_hooks.useIsomorphicEffect)(() => { if (phase === "measuring-overflow-indicator") { if (!updateOverflowIndicator()) setPhase("normal"); } }, [phase, subtractCount]); (0, _mantine_hooks.useIsomorphicEffect)(() => { if (phase === "normal") { setPhase("measuring"); setSubtractCount(0); } }, [dimensions]); const fitsInRows = (itemWidths, containerWidth, columnGap, startIndex = 0) => { let rows = 1; let rowWidth = 0; for (let i = startIndex; i < itemWidths.length; i += 1) { const width = itemWidths[i]; const needed = rowWidth > 0 ? width + columnGap : width; if (rowWidth + needed > containerWidth && rowWidth > 0) { rows++; if (rows > maxRows) return false; rowWidth = width; } else rowWidth += needed; } return true; }; const countVisibleItems = () => { const rowData = require_get_row_position_data.getRowPositionsData(containerRef, _overflowRef); if (!rowData) return; const container = containerRef.current; if (!container) return; if (isCollapseStart) { const containerWidth = container.getBoundingClientRect().width; const columnGap = parseFloat(getComputedStyle(container).columnGap) || 0; const widths = rowData.children.map((child) => child.getBoundingClientRect().width); let count = 0; for (let i = widths.length - 1; i >= 0; i--) { if (!fitsInRows(widths, containerWidth, columnGap, i)) break; count = widths.length - i; } count = Math.min(count, maxVisibleItems); setVisibleCount(count); return; } if (data.length === 1) { const itemRef = rowData.itemsSizesMap[rowData.rowPositions[0]].elements.values().next().value; const containerWidth = container.getBoundingClientRect().width; if ((itemRef?.getBoundingClientRect().width ?? 0) > containerWidth) setVisibleCount(0); else setVisibleCount(1); return; } let fittingCount = rowData.rowPositions.slice(0, maxRows).reduce((acc, position) => { return acc + rowData.itemsSizesMap[position].elements.size; }, 0); fittingCount = Math.min(fittingCount, maxVisibleItems); setVisibleCount(fittingCount); }; const updateOverflowIndicator = () => { if (!_overflowRef.current) return false; const rowData = require_get_row_position_data.getRowPositionsData(containerRef, _overflowRef); if (!rowData) return false; const { rowPositions, itemsSizesMap } = rowData; if (isCollapseStart) { const container = containerRef.current; if (!container) return false; const containerWidth = container.getBoundingClientRect().width; const columnGap = parseFloat(getComputedStyle(container).columnGap) || 0; if (!fitsInRows([_overflowRef.current.getBoundingClientRect().width, ...rowData.children.map((child) => child.getBoundingClientRect().width)], containerWidth, columnGap)) { setSubtractCount((c) => c + 1); return true; } return false; } const overflowRect = _overflowRef.current.getBoundingClientRect(); if (overflowRect.top + overflowRect.height / 2 > itemsSizesMap[rowPositions[rowPositions.length - 1]].bottom) { setSubtractCount((c) => c + 1); return true; } return false; }; const clonedOverflowElement = overflowElement ? (0, react.cloneElement)(overflowElement, { ref: overflowRef }) : null; let finalItems = data; if (maxVisibleItems) finalItems = isCollapseStart ? finalItems.slice(-maxVisibleItems) : finalItems.slice(0, maxVisibleItems); const indexOffset = isCollapseStart ? data.length - finalItems.length : 0; return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Box.Box, { ref: rootRef, ...getStyles("root"), ...others, children: [ isCollapseStart && clonedOverflowElement, finalItems.map((item, index) => { if (!(phase === "measuring" || (isCollapseStart ? index >= finalItems.length - finalVisibleCount : index < finalVisibleCount))) return null; const dataIndex = indexOffset + index; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: renderItem(item, dataIndex) }, dataIndex); }), !isCollapseStart && clonedOverflowElement ] }); }); OverflowList.displayName = "@mantine/core/OverflowList"; OverflowList.classes = require_OverflowList_module.default; OverflowList.varsResolver = varsResolver; //#endregion exports.OverflowList = OverflowList; //# sourceMappingURL=OverflowList.cjs.map