UNPKG

@patreon/studio

Version:

Patreon Studio Design System

94 lines 4.37 kB
'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