UNPKG

@zendeskgarden/react-grid

Version:

Components relating to layout grids in the Garden Design System

1,132 lines (1,106 loc) 40.2 kB
/** * Copyright Zendesk, Inc. * * Use of this source code is governed under the Apache License, Version 2.0 * found at http://www.apache.org/licenses/LICENSE-2.0. */ 'use strict'; var React = require('react'); var PropTypes = require('prop-types'); var styled = require('styled-components'); var polished = require('polished'); var reactTheming = require('@zendeskgarden/react-theming'); var reactButtons = require('@zendeskgarden/react-buttons'); var containerUtilities = require('@zendeskgarden/container-utilities'); var useResizeObserver = require('use-resize-observer'); var reactMergeRefs = require('react-merge-refs'); var containerSplitter = require('@zendeskgarden/container-splitter'); var reactTooltips = require('@zendeskgarden/react-tooltips'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var React__default = /*#__PURE__*/_interopDefault(React); var PropTypes__default = /*#__PURE__*/_interopDefault(PropTypes); var styled__default = /*#__PURE__*/_interopDefault(styled); var useResizeObserver__default = /*#__PURE__*/_interopDefault(useResizeObserver); const ALIGN_ITEMS = ['start', 'end', 'center', 'baseline', 'stretch']; const ALIGN_SELF = ['auto', ...ALIGN_ITEMS]; const DIRECTION = ['row', 'row-reverse', 'column', 'column-reverse']; const JUSTIFY_CONTENT = ['start', 'end', 'center', 'between', 'around']; const TEXT_ALIGN = ['start', 'end', 'center', 'justify']; const SPACE = [false, 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl']; const WRAP = ['nowrap', 'wrap', 'wrap-reverse']; const ORIENTATION = ['top', 'bottom', 'start', 'end']; const COMPONENT_ID$6 = 'grid.col'; const colorStyles$4 = _ref => { let { theme } = _ref; const backgroundColor = reactTheming.getColor({ theme, variable: 'background.primaryEmphasis', dark: { transparency: theme.opacity[200] }, light: { transparency: theme.opacity[100] } }); return styled.css(["background-clip:content-box;background-color:", ";"], backgroundColor); }; const flexStyles$1 = (size, alignSelf, textAlign, offset, order, props) => { const margin = offset && `${polished.math(`${offset} / ${props.$columns} * 100`)}%`; let flexBasis; let flexGrow; let maxWidth; let width; if (typeof size === 'boolean') { flexBasis = 0; flexGrow = 1; maxWidth = '100%'; } else if (size === 'auto') { flexBasis = 'auto'; flexGrow = 0; maxWidth = '100%'; width = 'auto'; } else if (size !== undefined) { flexBasis = `${polished.math(`${size} / ${props.$columns} * 100`)}%`; flexGrow = 0; maxWidth = flexBasis; } let horizontalAlign; if (textAlign === 'start') { horizontalAlign = props.theme.rtl ? 'right' : 'left'; } else if (textAlign === 'end') { horizontalAlign = props.theme.rtl ? 'left' : 'right'; } else { horizontalAlign = textAlign; } let flexOrder; if (order === 'first') { flexOrder = -1; } else if (order === 'last') { flexOrder = polished.math(`${props.$columns} + 1`); } else { flexOrder = order; } return styled.css(["flex-basis:", ";flex-grow:", ";flex-shrink:", ";align-self:", ";order:", ";margin-", ":", ";width:", ";max-width:", ";text-align:", ";"], flexBasis, flexGrow, size && 0, alignSelf === 'start' || alignSelf === 'end' ? `flex-${alignSelf}` : alignSelf, flexOrder, props.theme.rtl ? 'right' : 'left', margin, width, maxWidth, horizontalAlign); }; const mediaStyles$1 = (minWidth, size, alignSelf, textAlign, offset, order, props) => { return styled.css(["@media (min-width:", "){", ";}"], minWidth, flexStyles$1(size, alignSelf, textAlign, offset, order, props)); }; const sizeStyles$5 = _ref2 => { let { theme, $gutters } = _ref2; const padding = $gutters ? polished.math(`${theme.space[$gutters]} / 2`) : 0; return styled.css(["padding-right:", ";padding-left:", ";"], padding, padding); }; const StyledCol = styled__default.default.div.attrs(props => ({ 'data-garden-id': COMPONENT_ID$6, 'data-garden-version': '9.12.0', $columns: props.$columns ?? 12 })).withConfig({ displayName: "StyledCol", componentId: "sc-inuw62-0" })(["box-sizing:border-box;width:100%;", ";", ";", ";", ";", ";", ";", ";", ";", ";"], props => flexStyles$1(!props.$sizeAll && (props.$xs || props.$sm || props.$md || props.$lg || props.$xl) ? undefined : props.$sizeAll || false, props.$alignSelf, props.$textAlign, props.$offset, props.$order, props), sizeStyles$5, props => props.$debug && colorStyles$4(props), props => mediaStyles$1(props.theme.breakpoints.xs, props.$xs, props.$alignSelfXs, props.$textAlignXs, props.$offsetXs, props.$orderXs, props), props => mediaStyles$1(props.theme.breakpoints.sm, props.$sm, props.$alignSelfSm, props.$textAlignSm, props.$offsetSm, props.$orderSm, props), props => mediaStyles$1(props.theme.breakpoints.md, props.$md, props.$alignSelfMd, props.$textAlignMd, props.$offsetMd, props.$orderMd, props), props => mediaStyles$1(props.theme.breakpoints.lg, props.$lg, props.$alignSelfLg, props.$textAlignLg, props.$offsetLg, props.$orderLg, props), props => mediaStyles$1(props.theme.breakpoints.xl, props.$xl, props.$alignSelfXl, props.$textAlignXl, props.$offsetXl, props.$orderXl, props), reactTheming.componentStyles); const COMPONENT_ID$5 = 'grid.grid'; const colorStyles$3 = _ref => { let { theme, $debug } = _ref; const borderColor = $debug && reactTheming.getColor({ theme, hue: 'crimson', shade: 700, transparency: theme.opacity[600] }); const borderWidth = $debug && polished.math(`${theme.borderWidths.sm} * 2`); return styled.css(["color-scheme:only ", ";box-shadow:", ";"], theme.colors.base, $debug && ` -${borderWidth} 0 0 0 ${borderColor}, ${borderWidth} 0 0 0 ${borderColor} `); }; const sizeStyles$4 = _ref2 => { let { theme, $gutters } = _ref2; const padding = $gutters ? polished.math(`${theme.space[$gutters]} / 2`) : 0; return styled.css(["padding-right:", ";padding-left:", ";"], padding, padding); }; const StyledGrid = styled__default.default.div.attrs(props => ({ 'data-garden-id': COMPONENT_ID$5, 'data-garden-version': '9.12.0', $gutters: props.$gutters ?? 'md' })).withConfig({ displayName: "StyledGrid", componentId: "sc-oxgg5i-0" })(["direction:", ";margin-right:auto;margin-left:auto;width:100%;box-sizing:border-box;", ";", ";", ";"], props => props.theme.rtl && 'rtl', sizeStyles$4, colorStyles$3, reactTheming.componentStyles); const COMPONENT_ID$4 = 'grid.row'; const colorStyles$2 = _ref => { let { theme } = _ref; const borderColor = reactTheming.getColor({ theme, hue: 'mint', shade: 700, transparency: theme.opacity[600] }); const borderWidth = theme.borderWidths.sm; return styled.css(["box-shadow:inset 0 ", " 0 0 ", ",inset 0 -", " 0 0 ", ";"], borderWidth, borderColor, borderWidth, borderColor); }; const flexStyles = (alignItems, justifyContent, wrap) => { let flexAlignItems; let flexJustifyContent; if (alignItems === 'start' || alignItems === 'end') { flexAlignItems = `flex-${alignItems}`; } else { flexAlignItems = alignItems; } if (justifyContent === 'start' || justifyContent === 'end') { flexJustifyContent = `flex-${justifyContent}`; } else if (justifyContent === 'between' || justifyContent === 'around') { flexJustifyContent = `space-${justifyContent}`; } else { flexJustifyContent = justifyContent; } return styled.css(["flex-wrap:", ";align-items:", ";justify-content:", ";"], wrap, flexAlignItems, flexJustifyContent); }; const mediaStyles = (minWidth, alignItems, justifyContent, wrap) => { return styled.css(["@media (min-width:", "){", ";}"], minWidth, flexStyles(alignItems, justifyContent, wrap)); }; const sizeStyles$3 = _ref2 => { let { theme, $gutters } = _ref2; const margin = $gutters ? polished.math(`${theme.space[$gutters]} / 2`) : 0; return styled.css(["margin-right:-", ";margin-left:-", ";"], margin, margin); }; const StyledRow = styled__default.default.div.attrs(props => ({ 'data-garden-id': COMPONENT_ID$4, 'data-garden-version': '9.12.0', $wrapAll: props.$wrapAll ?? 'wrap' })).withConfig({ displayName: "StyledRow", componentId: "sc-xjsdg1-0" })(["display:flex;box-sizing:border-box;", " ", ";", ";", ";", ";", ";", ";", ";", ";"], props => flexStyles(props.$alignItems, props.$justifyContent, props.$wrapAll), sizeStyles$3, props => props.$debug && colorStyles$2(props), props => mediaStyles(props.theme.breakpoints.xs, props.$alignItemsXs, props.$justifyContentXs, props.$wrapXs), props => mediaStyles(props.theme.breakpoints.sm, props.$alignItemsSm, props.$justifyContentSm, props.$wrapSm), props => mediaStyles(props.theme.breakpoints.md, props.$alignItemsMd, props.$justifyContentMd, props.$wrapMd), props => mediaStyles(props.theme.breakpoints.lg, props.$alignItemsLg, props.$justifyContentLg, props.$wrapLg), props => mediaStyles(props.theme.breakpoints.xl, props.$alignItemsXl, props.$justifyContentXl, props.$wrapXl), reactTheming.componentStyles); const COMPONENT_ID$3 = 'pane'; const StyledPane = styled__default.default.div.attrs({ 'data-garden-id': COMPONENT_ID$3, 'data-garden-version': '9.12.0' }).withConfig({ displayName: "StyledPane", componentId: "sc-1ltjst7-0" })(["position:relative;min-width:0;min-height:0;", ";"], reactTheming.componentStyles); const COMPONENT_ID$2 = 'pane.content'; const StyledPaneContent = styled__default.default.div.attrs({ 'data-garden-id': COMPONENT_ID$2, 'data-garden-version': '9.12.0' }).withConfig({ displayName: "StyledPaneContent", componentId: "sc-1b38mbh-0" })(["height:100%;overflow:auto;color-scheme:only ", ";&[hidden]{display:none;}", ";"], p => p.theme.colors.base, reactTheming.componentStyles); const COMPONENT_ID$1 = 'pane.splitter'; const colorStyles$1 = _ref => { let { theme } = _ref; const color = reactTheming.getColor({ theme, variable: 'border.default' }); const options = { theme, variable: 'border.primaryEmphasis' }; const hoverColor = reactTheming.getColor(options); const activeColor = reactTheming.getColor({ ...options, dark: { offset: -200 }, light: { offset: 200 } }); return styled.css(["&::before{background-color:", ";}&:hover::before{background-color:", ";}", " &:active::before{background-color:", ";}"], color, hoverColor, reactTheming.focusStyles({ theme, styles: { backgroundColor: hoverColor }, selector: '&:focus-visible::before' }), activeColor); }; const sizeStyles$2 = _ref2 => { let { theme, $orientation, $isFixed } = _ref2; const size = polished.math(`${theme.shadowWidths.md} * 2`); const separatorSize = polished.math(`${theme.borderWidths.sm} * 2`); const offset = polished.math(`-${size} / 2`); let cursor; let top; let right; let left; let bottom; let width; let height; let separatorWidth; let separatorHeight; switch ($orientation) { case 'top': cursor = 'row-resize'; top = offset; width = '100%'; height = size; separatorWidth = width; separatorHeight = theme.borderWidths.sm; break; case 'bottom': cursor = 'row-resize'; bottom = offset; width = '100%'; height = size; separatorWidth = width; separatorHeight = theme.borderWidths.sm; break; case 'start': cursor = 'col-resize'; top = 0; width = size; height = '100%'; separatorWidth = theme.borderWidths.sm; separatorHeight = height; if (theme.rtl) { right = offset; } else { left = offset; } break; case 'end': default: cursor = 'col-resize'; top = 0; width = size; height = '100%'; separatorWidth = theme.borderWidths.sm; separatorHeight = height; if (theme.rtl) { left = offset; } else { right = offset; } break; } const dimensionProperty = width === '100%' ? 'height' : 'width'; return styled.css(["top:", ";right:", ";bottom:", ";left:", ";cursor:", ";width:", ";height:", ";&::before{width:", ";height:", ";}&:hover::before{", ":", ";}&:focus::before,&:focus-visible::before{", ":", ";}&:focus-visible::before{border-radius:", ";}"], top, right, bottom, left, $isFixed ? 'pointer' : cursor, width, height, separatorWidth, separatorHeight, dimensionProperty, separatorSize, dimensionProperty, separatorSize, theme.borderRadii.md); }; const StyledPaneSplitter = styled__default.default.div.attrs({ 'data-garden-id': COMPONENT_ID$1, 'data-garden-version': '9.12.0' }).withConfig({ displayName: "StyledPaneSplitter", componentId: "sc-jylemn-0" })(["display:flex;position:absolute;align-items:center;justify-content:center;z-index:1;user-select:none;", ";", "{z-index:2;}&::before{position:absolute;transition:box-shadow 0.1s ease-in-out,background-color 0.25s ease-in-out;z-index:-1;content:'';}", ";", ";"], sizeStyles$2, reactTheming.SELECTOR_FOCUS_VISIBLE, colorStyles$1, reactTheming.componentStyles); const getSize = theme => theme.space.base * 6; const sizeStyles$1 = _ref => { let { theme } = _ref; const size = `${getSize(theme)}px`; return styled.css(["width:", ";min-width:", ";height:", ";"], size, size, size); }; const transformStyles = _ref2 => { let { $isRotated, $orientation, theme } = _ref2; let degrees = 0; if ($isRotated) { degrees = theme.rtl ? -180 : 180; } if ($orientation === 'end') { degrees += theme.rtl ? -90 : 90; } else if ($orientation === 'start') { degrees += theme.rtl ? 90 : -90; } else if ($orientation === 'bottom') { degrees += 180; } return styled.css(["& > svg{transform:rotate(", "deg);}"], degrees); }; const StyledPaneSplitterButton = styled__default.default(reactButtons.ChevronButton).attrs({ 'data-garden-version': '9.12.0', isBasic: true, isPill: true, size: 'small' }).withConfig({ displayName: "StyledPaneSplitterButton", componentId: "sc-zh032e-0" })(["", ";", ";", ";"], sizeStyles$1, transformStyles, reactTheming.componentStyles); const COMPONENT_ID = 'pane.splitter_button_container'; const colorStyles = _ref => { let { theme } = _ref; const backgroundColor = reactTheming.getColor({ theme, variable: 'background.raised' }); const boxShadow = theme.shadows.lg(`${theme.space.base}px`, `${theme.space.base * 2}px`, reactTheming.getColor({ variable: 'shadow.small', theme })); return styled.css(["box-shadow:", ";background-color:", ";"], boxShadow, backgroundColor); }; const positionStyles = _ref2 => { let { theme, $orientation, $placement, $splitterSize } = _ref2; let top; let left; let right; let bottom; const size = getSize(theme); const inset = `-${size / 2}px`; if ($placement === 'center' || $splitterSize < size * 3) { const center = `${$splitterSize / 2 - size / 2}px`; switch (`${$orientation}-${theme.rtl ? 'rtl' : 'ltr'}`) { case 'top-ltr': case 'top-rtl': top = inset; left = center; break; case 'start-ltr': case 'end-rtl': top = center; left = inset; break; case 'end-ltr': case 'start-rtl': top = center; right = inset; break; case 'bottom-ltr': case 'bottom-rtl': bottom = inset; right = center; break; } } else { const offset = `${size}px`; switch (`${$orientation}-${$placement}-${theme.rtl ? 'rtl' : 'ltr'}`) { case 'top-end-ltr': case 'top-end-rtl': case 'top-start-rtl': top = inset; right = offset; break; case 'bottom-end-ltr': case 'bottom-end-rtl': case 'bottom-start-rtl': bottom = inset; right = offset; break; case 'start-start-ltr': case 'end-start-rtl': top = offset; left = inset; break; case 'start-end-ltr': case 'end-end-rtl': bottom = offset; left = inset; break; case 'end-start-ltr': case 'start-start-rtl': top = offset; right = inset; break; case 'end-end-ltr': case 'start-end-rtl': bottom = offset; right = inset; break; case 'top-start-ltr': top = inset; left = offset; break; case 'bottom-start-ltr': bottom = inset; left = offset; break; } } return styled.css(["top:", ";right:", ";bottom:", ";left:", ";"], top, right, bottom, left); }; const sizeStyles = _ref3 => { let { theme } = _ref3; const size = getSize(theme); return styled.css(["border-radius:", "px;width:", "px;height:", "px;"], size, size, size); }; const minimumSplitterSize = theme => polished.stripUnit(polished.math(`${theme.shadowWidths.md} * 2 + ${getSize(theme)}`)); const StyledPaneSplitterButtonContainer = styled__default.default.div.attrs({ 'data-garden-id': COMPONENT_ID, 'data-garden-version': '9.12.0' }).withConfig({ displayName: "StyledPaneSplitterButtonContainer", componentId: "sc-1w84y62-0" })(["display:", ";position:absolute;transition:box-shadow 0.1s ease-in-out,opacity 0.25s ease-in-out 0.1s;opacity:0;z-index:2;", ";", ";", ";&:hover,&:focus-within,", ":hover ~ &,", ":focus-visible ~ &{opacity:1;}", ";"], props => props.$splitterSize <= minimumSplitterSize(props.theme) ? 'none' : undefined, positionStyles, sizeStyles, colorStyles, StyledPaneSplitter, StyledPaneSplitter, reactTheming.componentStyles); const GridContext = React.createContext({ gutters: 'md' }); const useGridContext = () => { return React.useContext(GridContext); }; const Col = React__default.default.forwardRef((_ref, ref) => { let { alignSelf, alignSelfLg, alignSelfMd, alignSelfSm, alignSelfXl, alignSelfXs, lg, md, offset, offsetLg, offsetMd, offsetSm, offsetXl, offsetXs, order, orderLg, orderMd, orderSm, orderXl, orderXs, size, sm, textAlign, textAlignLg, textAlignMd, textAlignSm, textAlignXl, textAlignXs, xl, xs, ...other } = _ref; const { columns, gutters, debug } = useGridContext(); return React__default.default.createElement(StyledCol, Object.assign({ $xs: xs, $sm: sm, $md: md, $lg: lg, $xl: xl, $alignSelf: alignSelf, $alignSelfXs: alignSelfXs, $alignSelfSm: alignSelfSm, $alignSelfMd: alignSelfMd, $alignSelfLg: alignSelfLg, $alignSelfXl: alignSelfXl, $textAlign: textAlign, $textAlignXs: textAlignXs, $textAlignSm: textAlignSm, $textAlignMd: textAlignMd, $textAlignLg: textAlignLg, $textAlignXl: textAlignXl, $offset: offset, $offsetXs: offsetXs, $offsetSm: offsetSm, $offsetMd: offsetMd, $offsetLg: offsetLg, $offsetXl: offsetXl, $order: order, $orderXs: orderXs, $orderSm: orderSm, $orderMd: orderMd, $orderLg: orderLg, $orderXl: orderXl, $sizeAll: size, $columns: columns, $gutters: gutters, $debug: debug, ref: ref }, other)); }); Col.displayName = 'Grid.Col'; Col.propTypes = { size: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), xs: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string, PropTypes__default.default.bool]), sm: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string, PropTypes__default.default.bool]), md: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string, PropTypes__default.default.bool]), lg: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string, PropTypes__default.default.bool]), xl: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string, PropTypes__default.default.bool]), alignSelf: PropTypes__default.default.oneOf(ALIGN_SELF), alignSelfXs: PropTypes__default.default.oneOf(ALIGN_SELF), alignSelfSm: PropTypes__default.default.oneOf(ALIGN_SELF), alignSelfMd: PropTypes__default.default.oneOf(ALIGN_SELF), alignSelfLg: PropTypes__default.default.oneOf(ALIGN_SELF), alignSelfXl: PropTypes__default.default.oneOf(ALIGN_SELF), textAlign: PropTypes__default.default.oneOf(TEXT_ALIGN), textAlignXs: PropTypes__default.default.oneOf(TEXT_ALIGN), textAlignSm: PropTypes__default.default.oneOf(TEXT_ALIGN), textAlignMd: PropTypes__default.default.oneOf(TEXT_ALIGN), textAlignLg: PropTypes__default.default.oneOf(TEXT_ALIGN), textAlignXl: PropTypes__default.default.oneOf(TEXT_ALIGN), offset: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), offsetXs: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), offsetSm: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), offsetMd: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), offsetLg: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), offsetXl: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), order: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), orderXs: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), orderSm: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), orderMd: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), orderLg: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), orderXl: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]) }; const Row = React__default.default.forwardRef((_ref, ref) => { let { alignItems, alignItemsXs, alignItemsSm, alignItemsMd, alignItemsLg, alignItemsXl, justifyContent, justifyContentXs, justifyContentSm, justifyContentMd, justifyContentLg, justifyContentXl, wrap, wrapXs, wrapSm, wrapMd, wrapLg, wrapXl, ...props } = _ref; const { gutters, debug } = useGridContext(); return React__default.default.createElement(StyledRow, Object.assign({ $gutters: gutters, $debug: debug, $alignItems: alignItems, $alignItemsXs: alignItemsXs, $alignItemsSm: alignItemsSm, $alignItemsMd: alignItemsMd, $alignItemsLg: alignItemsLg, $alignItemsXl: alignItemsXl, $justifyContent: justifyContent, $justifyContentXs: justifyContentXs, $justifyContentSm: justifyContentSm, $justifyContentMd: justifyContentMd, $justifyContentLg: justifyContentLg, $justifyContentXl: justifyContentXl, $wrapAll: wrap, $wrapXs: wrapXs, $wrapSm: wrapSm, $wrapMd: wrapMd, $wrapLg: wrapLg, $wrapXl: wrapXl, ref: ref }, props)); }); Row.displayName = 'Grid.Row'; Row.propTypes = { alignItems: PropTypes__default.default.oneOf(ALIGN_ITEMS), alignItemsXs: PropTypes__default.default.oneOf(ALIGN_ITEMS), alignItemsSm: PropTypes__default.default.oneOf(ALIGN_ITEMS), alignItemsMd: PropTypes__default.default.oneOf(ALIGN_ITEMS), alignItemsLg: PropTypes__default.default.oneOf(ALIGN_ITEMS), alignItemsXl: PropTypes__default.default.oneOf(ALIGN_ITEMS), justifyContent: PropTypes__default.default.oneOf(JUSTIFY_CONTENT), justifyContentXs: PropTypes__default.default.oneOf(JUSTIFY_CONTENT), justifyContentSm: PropTypes__default.default.oneOf(JUSTIFY_CONTENT), justifyContentMd: PropTypes__default.default.oneOf(JUSTIFY_CONTENT), justifyContentLg: PropTypes__default.default.oneOf(JUSTIFY_CONTENT), justifyContentXl: PropTypes__default.default.oneOf(JUSTIFY_CONTENT), wrap: PropTypes__default.default.oneOf(WRAP), wrapXs: PropTypes__default.default.oneOf(WRAP), wrapSm: PropTypes__default.default.oneOf(WRAP), wrapMd: PropTypes__default.default.oneOf(WRAP), wrapLg: PropTypes__default.default.oneOf(WRAP), wrapXl: PropTypes__default.default.oneOf(WRAP) }; const GridComponent = React__default.default.forwardRef((_ref, ref) => { let { columns = 12, gutters = 'md', debug, ...other } = _ref; const value = React.useMemo(() => ({ columns, gutters: gutters, debug }), [columns, gutters, debug]); return React__default.default.createElement(GridContext.Provider, { value: value }, React__default.default.createElement(StyledGrid, Object.assign({ $debug: debug, $gutters: gutters, ref: ref }, other))); }); GridComponent.displayName = 'Grid'; GridComponent.propTypes = { columns: PropTypes__default.default.oneOfType([PropTypes__default.default.number, PropTypes__default.default.string]), gutters: PropTypes__default.default.oneOf(SPACE), debug: PropTypes__default.default.bool }; const Grid = GridComponent; Grid.Row = Row; Grid.Col = Col; const PaneProviderContext = React.createContext({}); const usePaneProviderContextData = providerId => { const context = React.useContext(PaneProviderContext); const id = providerId || context.providerId; return id && context.contextData ? context.contextData[id] : undefined; }; const usePaneProviderContext = () => React.useContext(PaneProviderContext); const getPixelsPerFr = (totalFrs, totalDimension) => { return totalDimension / totalFrs; }; const convertToPixels = (values, pixelsPerFr) => { return Object.entries(values).reduce((prev, _ref) => { let [key, value] = _ref; prev[key] = value * pixelsPerFr; return prev; }, {}); }; const PaneProvider = _ref2 => { let { id, totalPanesWidth, totalPanesHeight, defaultRowValues, defaultColumnValues, rowValues, columnValues, onChange, children } = _ref2; const isControlled = rowValues !== undefined && rowValues !== null && columnValues !== undefined && columnValues !== null; const [rowState, setRowState] = React.useState(defaultRowValues || {}); const [columnState, setColumnState] = React.useState(defaultColumnValues || {}); const rowsTrack = isControlled ? rowValues : rowState; const columnsTrack = isControlled ? columnValues : columnState; const setRowsTrack = React.useCallback(values => { if (isControlled && onChange) { return onChange(values(rowsTrack), columnsTrack); } return setRowState(values); }, [isControlled, onChange, setRowState, columnsTrack, rowsTrack]); const setColumnsTrack = React.useCallback(values => { if (isControlled && onChange) { return onChange(rowsTrack, values(columnsTrack)); } return setColumnState(values); }, [isControlled, onChange, setColumnState, rowsTrack, columnsTrack]); const totalFractions = React.useMemo(() => ({ rows: Object.values(rowsTrack).reduce((prev, value) => value + prev, 0), columns: Object.values(columnsTrack).reduce((prev, value) => value + prev, 0) }), [rowsTrack, columnsTrack]); const pixelsPerFr = React.useMemo(() => ({ rows: getPixelsPerFr(totalFractions.rows, totalPanesHeight), columns: getPixelsPerFr(totalFractions.columns, totalPanesWidth) }), [totalFractions, totalPanesHeight, totalPanesWidth]); const layoutStateInPixels = React.useMemo(() => ({ rows: convertToPixels(rowsTrack, pixelsPerFr.rows), columns: convertToPixels(columnsTrack, pixelsPerFr.columns) }), [rowsTrack, columnsTrack, pixelsPerFr]); const layoutIndices = React.useMemo(() => { const rowArray = Object.keys(rowsTrack); const columnArray = Object.keys(columnsTrack); const rows = rowArray.reduce((prev, key, index) => { prev[key] = index; return prev; }, {}); const columns = columnArray.reduce((prev, key, index) => { prev[key] = index; return prev; }, {}); return { rows, columns, rowArray, columnArray }; }, [rowsTrack, columnsTrack]); const setRowValue = React.useCallback((isTop, splitterId, value) => { const { rows, rowArray } = layoutIndices; const stealFromTraversal = isTop ? -1 : 1; const addToTraversal = 0; setRowsTrack(state => { const oldValue = rowsTrack[splitterId]; const stealFromIndex = rows[splitterId] + stealFromTraversal; const addToIndex = rows[splitterId] + addToTraversal; const stealFromKey = rowArray[stealFromIndex]; const addToKey = rowArray[addToIndex]; const difference = oldValue - value; const nextState = { ...state }; nextState[addToKey] = rowsTrack[addToKey] - difference; nextState[stealFromKey] = rowsTrack[stealFromKey] + difference; return nextState; }); }, [layoutIndices, rowsTrack, setRowsTrack]); const setColumnValue = React.useCallback((isStart, splitterId, value) => { const { columns, columnArray } = layoutIndices; const stealFromTraversal = isStart ? -1 : 1; const addToTraversal = 0; setColumnsTrack(state => { const stealFromIndex = columns[splitterId] + stealFromTraversal; const addToIndex = columns[splitterId] + addToTraversal; const oldValue = columnsTrack[splitterId]; const stealFromKey = columnArray[stealFromIndex]; const addToKey = columnArray[addToIndex]; const difference = oldValue - value; const nextState = { ...state }; nextState[addToKey] = columnsTrack[addToKey] - difference; nextState[stealFromKey] = columnsTrack[stealFromKey] + difference; return nextState; }); }, [layoutIndices, columnsTrack, setColumnsTrack]); const getColumnValue = React.useCallback((splitterKey, isPixels) => { if (isPixels) { return layoutStateInPixels.columns[splitterKey]; } return columnsTrack[splitterKey]; }, [columnsTrack, layoutStateInPixels]); const getRowValue = React.useCallback((splitterKey, isPixels) => { if (isPixels) { return layoutStateInPixels.rows[splitterKey]; } return rowsTrack[splitterKey]; }, [rowsTrack, layoutStateInPixels]); const getGridTemplateColumns = React.useCallback(isPixels => { const { columnArray } = layoutIndices; if (isPixels) { return columnArray.map(col => `${layoutStateInPixels.columns[col]}px`).join(' '); } return columnArray.map(col => `${columnsTrack[col]}fr`).join(' '); }, [layoutIndices, columnsTrack, layoutStateInPixels]); const getGridTemplateRows = React.useCallback(isPixels => { const { rowArray } = layoutIndices; if (isPixels) { return rowArray.map(row => `${layoutStateInPixels.rows[row]}px`).join(' '); } return rowArray.map(row => `${rowsTrack[row]}fr`).join(' '); }, [layoutIndices, rowsTrack, layoutStateInPixels]); const providerId = containerUtilities.useId(id); const parentPaneProviderContext = usePaneProviderContext(); const paneProviderContext = React.useMemo(() => providerId ? { providerId, contextData: { ...parentPaneProviderContext.contextData, [providerId]: { columnState, rowState, setRowValue, setColumnValue, getRowValue, getColumnValue, totalPanesHeight, totalPanesWidth, pixelsPerFr } } } : {}, [providerId, parentPaneProviderContext, rowState, columnState, setRowValue, setColumnValue, getRowValue, getColumnValue, totalPanesHeight, totalPanesWidth, pixelsPerFr]); return React__default.default.createElement(PaneProviderContext.Provider, { value: paneProviderContext }, children?.({ id: providerId, getRowValue, getColumnValue, getGridTemplateColumns, getGridTemplateRows })); }; PaneProvider.displayName = 'PaneProvider'; PaneProvider.propTypes = { id: PropTypes__default.default.string, totalPanesWidth: PropTypes__default.default.number.isRequired, totalPanesHeight: PropTypes__default.default.number.isRequired, defaultRowValues: PropTypes__default.default.object, defaultColumnValues: PropTypes__default.default.object, rowValues: PropTypes__default.default.object, columnValues: PropTypes__default.default.object, onChange: PropTypes__default.default.func, children: PropTypes__default.default.func }; const PaneContext = React.createContext({ setId: () => undefined }); const usePaneContext = () => { return React.useContext(PaneContext); }; const PaneSplitterContext = React.createContext({ orientation: 'start', min: 0, max: 0, layoutKey: '', valueNow: 0, size: 0, isRow: false }); const usePaneSplitterContext = () => { return React.useContext(PaneSplitterContext); }; const paneToSplitterOrientation = { start: 'vertical', end: 'vertical', top: 'horizontal', bottom: 'horizontal' }; const orientationToDimension = { start: 'columns', end: 'columns', top: 'rows', bottom: 'rows' }; const SplitterComponent = React.forwardRef((_ref, ref) => { let { children, providerId, layoutKey, min, max, orientation = 'end', isFixed, onMouseDown, onTouchStart, onKeyDown, onClick, ...props } = _ref; const paneProviderContext = usePaneProviderContextData(providerId); const paneContext = usePaneContext(); const themeContext = React.useContext(styled.ThemeContext); const environment = reactTheming.useDocument(themeContext); const isRow = orientationToDimension[orientation] === 'rows'; const separatorRef = React.useRef(null); const splitterOrientation = paneToSplitterOrientation[orientation || 'end']; const pixelsPerFr = paneProviderContext ? paneProviderContext.pixelsPerFr[orientationToDimension[orientation]] : 0; const value = isRow ? paneProviderContext?.getRowValue(layoutKey, true) : paneProviderContext?.getColumnValue(layoutKey, true); const valueInFr = isRow ? paneProviderContext?.getRowValue(layoutKey) : paneProviderContext?.getColumnValue(layoutKey); const { getSeparatorProps, getPrimaryPaneProps } = containerSplitter.useSplitter({ orientation: splitterOrientation, isLeading: orientation === 'start' || orientation === 'top', min: min * pixelsPerFr, max: max * pixelsPerFr, rtl: themeContext.rtl, isFixed, environment, onChange: valueNow => { if (isRow) { return paneProviderContext?.setRowValue(orientation === 'top', layoutKey, valueNow / pixelsPerFr); } return paneProviderContext?.setColumnValue(orientation === 'start', layoutKey, valueNow / pixelsPerFr); }, valueNow: value, separatorRef }); React.useEffect(() => { if (!paneContext.id) { paneContext.setId(getPrimaryPaneProps().id); } }, [paneContext, getPrimaryPaneProps]); const ariaLabel = reactTheming.useText(SplitterComponent, props, 'aria-label', `${splitterOrientation} splitter`); const separatorProps = getSeparatorProps({ 'aria-controls': paneContext.id, 'aria-label': ariaLabel, onMouseDown, onTouchStart, onKeyDown, onClick }); const size = isRow ? separatorRef.current?.clientWidth : separatorRef.current?.clientHeight; return React__default.default.createElement(PaneSplitterContext.Provider, { value: React.useMemo(() => ({ orientation, layoutKey, min, max, valueNow: valueInFr, size, isRow }), [orientation, layoutKey, min, max, valueInFr, size, isRow]) }, React__default.default.createElement(StyledPaneSplitter, Object.assign({ $isFixed: isFixed, $orientation: orientation }, separatorProps, props, { ref: reactMergeRefs.mergeRefs([separatorRef, ref]) })), children ); }); SplitterComponent.displayName = 'Pane.Splitter'; SplitterComponent.propTypes = { layoutKey: PropTypes__default.default.string.isRequired, min: PropTypes__default.default.number.isRequired, max: PropTypes__default.default.number.isRequired, orientation: PropTypes__default.default.oneOf(ORIENTATION), isFixed: PropTypes__default.default.bool }; const Splitter = SplitterComponent; const ContentComponent = React.forwardRef((props, ref) => { const { isVisible } = usePaneContext(); return React__default.default.createElement(StyledPaneContent, Object.assign({ hidden: !isVisible, ref: ref }, props)); }); ContentComponent.displayName = 'Pane.Content'; const Content = ContentComponent; const SplitterButtonComponent = React.forwardRef((_ref, ref) => { let { label, placement: defaultPlacement, ...other } = _ref; const { orientation, layoutKey, min, max, isRow, valueNow, size, providerId } = usePaneSplitterContext(); const paneProviderContext = usePaneProviderContextData(providerId); const isTop = orientation === 'top'; const isStart = orientation === 'start'; const isMin = valueNow === min; let placement = defaultPlacement; if (!defaultPlacement) { if (isRow) { placement = 'center'; } else { placement = 'start'; } } const setValue = React.useCallback(value => { if (isRow) { paneProviderContext.setRowValue(isTop, layoutKey, value); } else { paneProviderContext.setColumnValue(isStart, layoutKey, value); } }, [isRow, isTop, isStart, layoutKey, paneProviderContext]); const onClick = containerUtilities.composeEventHandlers(other.onClick, () => { if (isMin) { setValue(max); } else { setValue(min); } }); const onKeyDown = containerUtilities.composeEventHandlers(other.onKeyDown, event => event.stopPropagation() ); const onMouseDown = containerUtilities.composeEventHandlers(other.onMouseDown, event => event.stopPropagation() ); return React__default.default.createElement(StyledPaneSplitterButtonContainer, { $orientation: orientation, $placement: placement, $splitterSize: size || 0 }, React__default.default.createElement(reactTooltips.Tooltip, { content: label, placement: "auto", zIndex: 2, style: { cursor: 'default' }, onMouseDown: e => e.stopPropagation() }, React__default.default.createElement(StyledPaneSplitterButton, Object.assign({ "aria-label": label }, other, { $orientation: orientation, $isRotated: isMin, ref: ref, onClick: onClick, onKeyDown: onKeyDown, onMouseDown: onMouseDown })))); }); SplitterButtonComponent.displayName = 'Pane.SplitterButton'; const SplitterButton = SplitterButtonComponent; const PaneComponent = React.forwardRef((_ref, ref) => { let { children, ...props } = _ref; const [paneId, setPaneId] = React.useState(); const observerRef = React.useRef(null); const { width = 0, height = 0 } = useResizeObserver__default.default({ ref: observerRef }); const isVisible = React.useMemo(() => observerRef.current ? width > 0 && height > 0 : true, [width, height]); const paneContext = React.useMemo(() => ({ isVisible, id: paneId, setId: id => setPaneId(id) }), [paneId, isVisible]); return React__default.default.createElement(PaneContext.Provider, { value: paneContext }, React__default.default.createElement(StyledPane, Object.assign({ id: paneId, ref: reactMergeRefs.mergeRefs([ref, observerRef]) }, props), children)); }); PaneComponent.displayName = 'Pane'; const Pane = PaneComponent; Pane.Content = Content; Pane.Splitter = Splitter; Pane.SplitterButton = SplitterButton; exports.ALIGN_ITEMS = ALIGN_ITEMS; exports.ALIGN_SELF = ALIGN_SELF; exports.Col = Col; exports.DIRECTION = DIRECTION; exports.Grid = Grid; exports.JUSTIFY_CONTENT = JUSTIFY_CONTENT; exports.Pane = Pane; exports.PaneProvider = PaneProvider; exports.Row = Row; exports.SPACE = SPACE; exports.TEXT_ALIGN = TEXT_ALIGN; exports.WRAP = WRAP;