UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

125 lines (124 loc) 6.09 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("react"); var _clsx = _interopRequireDefault(require("clsx")); var _ScrollView = _interopRequireDefault(require("../../fragments/scroll-view/ScrollView.js")); var _useIsomorphicLayoutEffect = require("../../shared/helpers/useIsomorphicLayoutEffect.js"); var _useCombinedRef = _interopRequireDefault(require("../../shared/helpers/useCombinedRef.js")); var _ListContext = require("./ListContext.js"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const defaultListItemOutlineCompensation = '0.125rem'; function ListScrollView(props) { var _parentContext$varian, _parentContext$separa; const parentContext = (0, _react.useContext)(_ListContext.ListContext); const { className, children, maxVisibleListItems, skeleton, disabled, style, ref, ...rest } = props; const localRef = (0, _react.useRef)(null); const combinedRef = (0, _useCombinedRef.default)(ref, localRef); const [measuredMaxHeight, setMeasuredMaxHeight] = (0, _react.useState)(undefined); const [outlineCompensation, setOutlineCompensation] = (0, _react.useState)(defaultListItemOutlineCompensation); const hasValidMaxVisibleListItems = typeof maxVisibleListItems === 'number' && Number.isFinite(maxVisibleListItems) && maxVisibleListItems > 0; const fallbackMaxHeight = hasValidMaxVisibleListItems ? `calc(var(--item-height, 4rem) * ${maxVisibleListItems})` : undefined; const measureMaxHeight = (0, _react.useCallback)(() => { if (!hasValidMaxVisibleListItems || style !== null && style !== void 0 && style.maxHeight) { setMeasuredMaxHeight(undefined); return undefined; } setOutlineCompensation(getListItemOutlineCompensation(localRef.current)); const measuredHeight = getVisibleListItemsHeight(localRef.current, maxVisibleListItems); setMeasuredMaxHeight(measuredHeight ? `${measuredHeight}px` : undefined); }, [hasValidMaxVisibleListItems, maxVisibleListItems, style === null || style === void 0 ? void 0 : style.maxHeight]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { measureMaxHeight(); }, [children, measureMaxHeight]); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(() => { if (!hasValidMaxVisibleListItems || style !== null && style !== void 0 && style.maxHeight) { return undefined; } window.addEventListener('resize', measureMaxHeight); return () => { window.removeEventListener('resize', measureMaxHeight); }; }, [hasValidMaxVisibleListItems, measureMaxHeight, style === null || style === void 0 ? void 0 : style.maxHeight]); const resolvedMaxHeight = style !== null && style !== void 0 && style.maxHeight ? undefined : measuredMaxHeight || fallbackMaxHeight; const scrollViewStyle = { ...(resolvedMaxHeight ? { maxHeight: `calc(${resolvedMaxHeight} + ${outlineCompensation})`, marginBottom: `-${outlineCompensation}` } : null), ...style }; const scrollViewContent = (0, _jsxRuntime.jsx)(_ScrollView.default, { className: (0, _clsx.default)("dnb-list__card__scroll-view dnb-list--inset-outline", className), interactive: "auto", ref: combinedRef, style: scrollViewStyle, ...rest, children: children }); const appliedSkeleton = skeleton !== null && skeleton !== void 0 ? skeleton : parentContext === null || parentContext === void 0 ? void 0 : parentContext.skeleton; const appliedDisabled = disabled !== null && disabled !== void 0 ? disabled : parentContext === null || parentContext === void 0 ? void 0 : parentContext.disabled; return (0, _jsxRuntime.jsx)(_ListContext.ListContext, { value: { variant: (_parentContext$varian = parentContext === null || parentContext === void 0 ? void 0 : parentContext.variant) !== null && _parentContext$varian !== void 0 ? _parentContext$varian : 'basic', separated: (_parentContext$separa = parentContext === null || parentContext === void 0 ? void 0 : parentContext.separated) !== null && _parentContext$separa !== void 0 ? _parentContext$separa : false, skeleton: appliedSkeleton, disabled: appliedDisabled }, children: scrollViewContent }); } function getVisibleListItemsHeight(scrollViewElement, maxVisibleListItems) { if (!scrollViewElement) { return null; } const listElement = scrollViewElement.querySelector('.dnb-list__container'); if (!(listElement instanceof HTMLElement)) { return null; } const items = Array.from(listElement.children).filter(element => element instanceof HTMLElement); const firstVisibleItem = items[0]; const lastVisibleItem = items[maxVisibleListItems - 1]; if (!firstVisibleItem || !lastVisibleItem) { return null; } return Math.ceil(lastVisibleItem.offsetTop + lastVisibleItem.offsetHeight - firstVisibleItem.offsetTop); } function getListItemOutlineCompensation(scrollViewElement) { if (!scrollViewElement || typeof getComputedStyle === 'undefined') { return defaultListItemOutlineCompensation; } const cardElement = scrollViewElement.closest('.dnb-card'); const targetElement = (cardElement === null || cardElement === void 0 ? void 0 : cardElement.querySelector('.dnb-list__container')) || scrollViewElement.querySelector('.dnb-list__container'); if (!(targetElement instanceof HTMLElement)) { return defaultListItemOutlineCompensation; } const outlineWidth = getComputedStyle(targetElement).getPropertyValue('--item-outline-width').trim(); return doubleCssLength(outlineWidth) || defaultListItemOutlineCompensation; } function doubleCssLength(value) { if (!value) { return null; } const match = value.match(/^(-?\d*\.?\d+)([a-z%]+)$/i); if (match) { return `${parseFloat(match[1]) * 2}${match[2]}`; } return `calc(${value} * 2)`; } ListScrollView._supportsSpacingProps = true; var _default = exports.default = ListScrollView; //# sourceMappingURL=ListScrollView.js.map