UNPKG

@ui5/webcomponents-react

Version:

React Wrapper for UI5 Web Components and additional components

83 lines (81 loc) 3.26 kB
'use client'; import { useStylesheet, useViewportRange } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; import { forwardRef, isValidElement } from 'react'; import { GridPosition } from '../../enums/index.js'; import { flattenFragments } from '../../internal/utils.js'; import { classNames, styleData } from './Grid.module.css.js'; import { jsx as _jsx } from "react/jsx-runtime"; const INDENT_PATTERN = /^([X][L](?<LargeDesktop>[0-9]|1[0-2]))? ?([L](?<Desktop>[0-9]|1[0-2]))? ?([M](?<Tablet>[0-9]|1[0-2]))? ?([S](?<Phone>[0-9]|1[0-2]))?$/i; const SPAN_PATTERN = /^([X][L](?<LargeDesktop>[1-9]|1[0-2]))? ?([L](?<Desktop>[1-9]|1[0-2]))? ?([M](?<Tablet>[1-9]|1[0-2]))? ?([S](?<Phone>[1-9]|1[0-2]))?$/i; const DefaultSpanMap = new Map(); DefaultSpanMap.set('Phone', 1); DefaultSpanMap.set('Tablet', 2); DefaultSpanMap.set('Desktop', 4); DefaultSpanMap.set('LargeDesktop', 4); const DefaultIndentMap = new Map(); DefaultIndentMap.set('Phone', 0); DefaultIndentMap.set('Tablet', 0); DefaultIndentMap.set('Desktop', 0); DefaultIndentMap.set('LargeDesktop', 0); const getSpanFromString = (span, currentRange) => { const spanConfig = SPAN_PATTERN.exec(span); return Number(spanConfig?.groups[currentRange] ?? DefaultSpanMap.get(currentRange)); }; const getIndentFromString = (indent, currentRange) => { const indentConfig = INDENT_PATTERN.exec(indent); return Number(indentConfig?.groups[currentRange] ?? DefaultIndentMap.get(currentRange)); }; /** * A layout container component used for aligning items with various sizes in a simple grid. */ const Grid = /*#__PURE__*/forwardRef((props, ref) => { const { position, children, hSpacing = '1rem', vSpacing = '1rem', style, className, slot, defaultIndent = 'XL0 L0 M0 S0', defaultSpan = 'XL3 L3 M6 S12', ...rest } = props; useStylesheet(styleData, Grid.displayName); const currentRange = useViewportRange(); const gridClasses = clsx(classNames.grid, GridPosition.Center === position && classNames.positionCenter, GridPosition.Right === position && classNames.positionRight, className); return /*#__PURE__*/_jsx("div", { ref: ref, className: gridClasses, style: { rowGap: vSpacing, columnGap: hSpacing, ...style }, slot: slot, ...rest, children: flattenFragments(children, Infinity).map(child => { if (! /*#__PURE__*/isValidElement(child)) { return null; } const childSpan = getSpanFromString(child.props['data-layout-span'] ?? defaultSpan, currentRange); const childClass = classNames[`gridSpan${childSpan}`]; const childrenWithGridLayout = [/*#__PURE__*/_jsx("div", { className: childClass, children: child }, child.key)]; const indentSpan = getIndentFromString(child.props['data-layout-indent'] ?? defaultIndent, currentRange); if (indentSpan && indentSpan > 0) { childrenWithGridLayout.unshift( /*#__PURE__*/_jsx("span", { className: classNames[`gridSpan${indentSpan}`], "data-component-name": "GridIndentSpacer", "aria-hidden": "true" }, `${child.key}-indent`)); } return childrenWithGridLayout; }) }); }); Grid.displayName = 'Grid'; export { Grid };