UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

159 lines (158 loc) 6.54 kB
"use client"; import _extends from "@babel/runtime-corejs3/helpers/esm/extends"; import React, { Fragment, useMemo } from 'react'; import classnames from 'classnames'; import Space from "../space/Space.js"; import { Hr } from "../../elements/index.js"; import useMedia from "../../shared/useMedia.js"; import { getSpaceValue, isHeadingElement, renderWithSpacing } from "./utils.js"; const propNames = ['direction', 'wrap', 'wrapChildrenInSpace', 'justify', 'align', 'divider', 'spacing', 'gap']; export function pickFlexContainerProps(props, defaults = {}, skip = []) { return { ...defaults, ...Object.fromEntries(Object.entries(props !== null && props !== void 0 ? props : {}).filter(([key]) => propNames.includes(key) && !skip.includes(key))) }; } function handleDeprecatedProps({ spacing, gap, rowGap, ...rest }) { return { ...rest, rowGap: rowGap === true ? undefined : rowGap, gap: spacing !== null && spacing !== void 0 ? spacing : gap }; } function FlexContainer(props) { const { className, style, children, element = 'div', direction = 'horizontal', wrap = true, wrapChildrenInSpace = true, sizeCount = 12, rowGap, justify = 'flex-start', align = 'flex-start', alignSelf, divider = 'space', gap = 'small', breakpoints, queries, ...rest } = handleDeprecatedProps(props); const spacing = useMemo(() => { var _ref; return (_ref = direction === 'vertical' ? rowGap : undefined) !== null && _ref !== void 0 ? _ref : gap; }, [direction, gap, rowGap]); const childrenArray = replaceRootFragment(wrapChildren(props, children)); const hasHeading = childrenArray.some((child, i) => { const previousChild = childrenArray === null || childrenArray === void 0 ? void 0 : childrenArray[i - 1]; return isHeadingElement(child) || i > 0 && isHeadingElement(previousChild); }); const hasSizeProp = !hasHeading && direction === 'horizontal' && childrenArray.some(child => { var _child$props; return (_child$props = child['props']) === null || _child$props === void 0 ? void 0 : _child$props.size; }); const { key: mediaKey } = useMedia({ disabled: !hasSizeProp, breakpoints, queries }); const content = childrenArray.map((child, i) => { var _previousChild$type; const isFirst = i === 0; const isLast = i >= childrenArray.length - 1; const previousChild = childrenArray === null || childrenArray === void 0 ? void 0 : childrenArray[i - 1]; const isHeading = hasHeading && isHeadingElement(previousChild); const start = direction === 'horizontal' ? 'left' : 'top'; const end = direction === 'horizontal' ? 'right' : 'bottom'; const endSpacing = 0; let startSpacing = null; if (!isHeading && (divider === 'line' && !isFirst || divider === 'line-framed')) { var _getSpaceValue, _getSpaceValue2; const spaceAboveLine = (_getSpaceValue = getSpaceValue(end, previousChild)) !== null && _getSpaceValue !== void 0 ? _getSpaceValue : spacing; startSpacing = (_getSpaceValue2 = getSpaceValue(start, child)) !== null && _getSpaceValue2 !== void 0 ? _getSpaceValue2 : spacing; return React.createElement(React.Fragment, { key: `element-${i}` }, React.createElement(Hr, { top: !isFirst ? spaceAboveLine : 0, space: 0, className: "dnb-flex-container__hr" }), renderWithSpacing(child, { space: { [start]: startSpacing, [end]: endSpacing }, wrapInSpace: wrapChildrenInSpace }), divider === 'line-framed' && isLast && React.createElement(Hr, { top: spaceAboveLine, space: 0, className: "dnb-flex-container__hr" })); } if (isFirst && direction !== 'horizontal') { startSpacing = 0; } else { var _ref2, _getSpaceValue3; startSpacing = (_ref2 = (_getSpaceValue3 = getSpaceValue(start, child)) !== null && _getSpaceValue3 !== void 0 ? _getSpaceValue3 : getSpaceValue(end, previousChild)) !== null && _ref2 !== void 0 ? _ref2 : spacing; } if (React.isValidElement(previousChild) && (previousChild === null || previousChild === void 0 || (_previousChild$type = previousChild.type) === null || _previousChild$type === void 0 ? void 0 : _previousChild$type['_supportsSpacingProps']) === false) { startSpacing = 0; } const space = direction === 'horizontal' ? { [start]: endSpacing, [end]: startSpacing } : { [start]: startSpacing, [end]: endSpacing }; return renderWithSpacing(child, { key: (child === null || child === void 0 ? void 0 : child['key']) || `element-${i}`, space, wrapInSpace: wrapChildrenInSpace }); }); const n = 'dnb-flex-container'; const rowGapClass = useMemo(() => { if (rowGap !== false && direction === 'horizontal') { return `${n}--row-gap-${rowGap !== null && rowGap !== void 0 ? rowGap : 'small'}`; } return undefined; }, [direction, rowGap]); const cn = classnames('dnb-flex-container', rowGapClass, className, direction && `${n}--direction-${direction}`, justify && `${n}--justify-${justify}`, align && `${n}--align-${align}`, alignSelf && `${n}--align-self-${alignSelf}`, spacing && `${n}--spacing-${spacing}`, wrap && `${n}--wrap`, hasSizeProp && `${n}--has-size`, divider && `${n}--divider-${divider}`); return React.createElement(Space, _extends({ element: element, className: cn, "data-media-key": mediaKey, style: hasSizeProp ? { '--sizeCount': sizeCount, ...style } : style }, rest), content); } function wrapChildren(props, children) { return React.Children.toArray(children).map(child => { if (React.isValidElement(child) && child.type['_supportsSpacingProps'] === 'children') { return React.cloneElement(child, child.props, React.createElement(FlexContainer, props, child.props.children)); } return child; }); } function replaceRootFragment(children) { const firstChild = children[0]; if (React.Children.count(children) === 1 && (firstChild === null || firstChild === void 0 ? void 0 : firstChild.type) === Fragment) { var _firstChild$props; return React.Children.toArray(firstChild === null || firstChild === void 0 || (_firstChild$props = firstChild.props) === null || _firstChild$props === void 0 ? void 0 : _firstChild$props.children); } return children; } FlexContainer._supportsSpacingProps = true; export default FlexContainer; //# sourceMappingURL=Container.js.map