UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

115 lines (114 loc) 4.75 kB
"use client"; import { getSpacing } from "../../core/utils/get-size/get-size.mjs"; import { createVarsResolver } from "../../core/styles-api/create-vars-resolver/create-vars-resolver.mjs"; import { useProps } from "../../core/MantineProvider/use-props/use-props.mjs"; import { useStyles } from "../../core/styles-api/use-styles/use-styles.mjs"; import { genericFactory } from "../../core/factory/factory.mjs"; import { Box } from "../../core/Box/Box.mjs"; import { getRowPositionsData } from "./get-row-position-data.mjs"; import { useDimensions } from "./use-dimensions.mjs"; import OverflowList_module_default from "./OverflowList.module.mjs"; import { cloneElement, useRef, useState } from "react"; import { useIsomorphicEffect, useMergedRef } from "@mantine/hooks"; import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime"; //#region packages/@mantine/core/src/components/OverflowList/OverflowList.tsx const defaultProps = { maxRows: 1, maxVisibleItems: Infinity }; const varsResolver = createVarsResolver((_, { gap }) => ({ root: { "--ol-gap": getSpacing(gap) } })); const OverflowList = genericFactory((_props) => { const props = useProps("OverflowList", defaultProps, _props); const { classNames, className, style, styles, unstyled, vars, attributes, data, renderOverflow, renderItem, maxRows, maxVisibleItems, ref, ...others } = props; const getStyles = useStyles({ name: "OverflowList", classes: OverflowList_module_default, props, className, style, classNames, styles, unstyled, attributes, vars, varsResolver }); const [visibleCount, setVisibleCount] = useState(data.length); const [subtractCount, setSubtractCount] = useState(0); const [phase, setPhase] = useState("normal"); const containerRef = useRef(null); const rootRef = useMergedRef(containerRef, ref); const finalVisibleCount = visibleCount - subtractCount; const overflowElement = data.length - finalVisibleCount > 0 && phase !== "measuring" ? renderOverflow?.(data.slice(finalVisibleCount)) : null; const _overflowRef = useRef(null); const overflowRef = useMergedRef(_overflowRef, overflowElement?.ref); const dimensions = useDimensions(containerRef); useIsomorphicEffect(() => { setPhase("measuring"); setVisibleCount(data.length); setSubtractCount(0); }, [data.length, maxRows]); useIsomorphicEffect(() => { if (phase === "measuring") { countVisibleItems(); setPhase("measuring-overflow-indicator"); } }, [phase]); useIsomorphicEffect(() => { if (phase === "measuring-overflow-indicator") { if (!updateOverflowIndicator()) setPhase("normal"); } }, [phase, subtractCount]); useIsomorphicEffect(() => { if (phase === "normal") { setPhase("measuring"); setSubtractCount(0); } }, [dimensions]); const countVisibleItems = () => { const rowData = getRowPositionsData(containerRef, _overflowRef); if (!rowData) return; if (data.length === 1) { const itemRef = rowData.itemsSizesMap[rowData.rowPositions[0]].elements.values().next().value; const containerWidth = containerRef.current?.getBoundingClientRect().width ?? 0; 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 = getRowPositionsData(containerRef, _overflowRef); if (!rowData) return false; const { rowPositions, itemsSizesMap } = rowData; 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 ? cloneElement(overflowElement, { ref: overflowRef }) : null; let finalItems = data; if (maxVisibleItems) finalItems = finalItems.slice(0, maxVisibleItems); return /* @__PURE__ */ jsxs(Box, { ref: rootRef, ...getStyles("root"), ...others, children: [finalItems.map((item, index) => { if (!(phase === "measuring" || index < finalVisibleCount)) return null; return /* @__PURE__ */ jsx(Fragment$1, { children: renderItem(item, index) }, index); }), clonedOverflowElement] }); }); OverflowList.displayName = "@mantine/core/OverflowList"; OverflowList.classes = OverflowList_module_default; OverflowList.varsResolver = varsResolver; //#endregion export { OverflowList }; //# sourceMappingURL=OverflowList.mjs.map