@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
174 lines (173 loc) • 7.64 kB
JavaScript
"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