@patreon/studio
Version:
Patreon Studio Design System
94 lines • 4.37 kB
JSX
'use client';
import cx from 'classnames';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { classNameForGap } from '../../styles/classNameForGap';
import { tokens } from '../../tokens';
import { wrapResponsive } from '../../utilities/opaque-responsive';
import { classNameForResponsiveValue, createResponsiveClassNameLookup } from '../../utilities/responsive-style';
import styles from './Stack.module.css';
const classNameFlexDirectionLookup = createResponsiveClassNameLookup(styles, {
column: 'flexDirectionColumn',
row: 'flexDirectionRow',
'column-reverse': 'flexDirectionColumnReverse',
'row-reverse': 'flexDirectionRowReverse',
});
const classNameJustifyContentLookup = createResponsiveClassNameLookup(styles, {
initial: 'justifyContentInitial',
'space-around': 'justifyContentSpaceAround',
'space-between': 'justifyContentSpaceBetween',
'space-evenly': 'justifyContentSpaceEvenly',
'flex-start': 'justifyContentFlexStart',
'flex-end': 'justifyContentFlexEnd',
stretch: 'justifyContentStretch',
center: 'justifyContentCenter',
});
const classNameAlignItemsLookup = createResponsiveClassNameLookup(styles, {
initial: 'alignItemsInitial',
'flex-start': 'alignItemsFlexStart',
'flex-end': 'alignItemsFlexEnd',
center: 'alignItemsCenter',
stretch: 'alignItemsStretch',
baseline: 'alignItemsBaseline',
});
const classNameFlexWrapLookup = createResponsiveClassNameLookup(styles, {
wrap: 'flexWrapWrap',
nowrap: 'flexWrapNoWrap',
});
const classNameForWidthLookup = createResponsiveClassNameLookup(styles, {
fluid: 'widthFluid',
'min-content': 'widthMinContent',
'max-content': 'widthMaxContent',
'fit-contents': 'widthFitContents',
auto: 'widthAuto',
});
const classNameForHeightLookup = createResponsiveClassNameLookup(styles, {
fluid: 'heightFluid',
'min-content': 'heightMinContent',
'max-content': 'heightMaxContent',
'fit-contents': 'heightFitContents',
auto: 'heightAuto',
});
function useClassList({ display, flexDirection, justifyContent, alignItems, flexWrap, gap, height, width, className, }) {
return useMemo(() => {
const responsiveFlexDirection = wrapResponsive(flexDirection);
const responsiveJustifyContent = wrapResponsive(justifyContent);
const responsiveAlignItems = wrapResponsive(alignItems);
const responsiveFlexWrap = wrapResponsive(flexWrap);
const responsiveHeight = wrapResponsive(height);
const responsiveWidth = wrapResponsive(width);
return cx({
[styles.flowBlock]: display === 'flex',
[styles.flowInline]: display === 'inline-flex',
}, classNameForResponsiveValue(responsiveFlexDirection, classNameFlexDirectionLookup), classNameForResponsiveValue(responsiveJustifyContent, classNameJustifyContentLookup), classNameForResponsiveValue(responsiveAlignItems, classNameAlignItemsLookup), classNameForResponsiveValue(responsiveFlexWrap, classNameFlexWrapLookup), classNameForResponsiveValue(responsiveWidth, classNameForWidthLookup), classNameForResponsiveValue(responsiveHeight, classNameForHeightLookup), classNameForGap({ gap }), className);
}, [alignItems, className, display, flexDirection, flexWrap, gap, height, justifyContent, width]);
}
/**
* A stack is a layout component that arranges its children in a row or column. It surfaces common
* flexbox properties as props and enforces the use of space tokens for flex gap.
*/
export function Stack({ as = 'div', display = 'flex', flexDirection = 'column', justifyContent = 'initial', alignItems = 'initial', flexWrap = 'wrap', gap = tokens.global.space.x0, height = 'auto', width = 'auto', className, style, id, 'data-tag': dataTag, children, ...props // aria props
}) {
const Component = as;
const classList = useClassList({
display,
flexDirection,
justifyContent,
alignItems,
flexWrap,
gap,
height,
width,
className,
});
return (<Component className={classList} style={style} id={id} data-tag={dataTag} {...props}>
{children}
</Component>);
}
/** @deprecated use `Stack` with `className` and css modules instead. */
export const StackWithCss = styled(Stack) `
&& {
${({ css }) => css};
}
`;
//# sourceMappingURL=index.jsx.map