import React, { HTMLAttributes, forwardRef } from "react"; import { type OverridableComponent } from "../../utils-external"; import { omit } from "../../utils-external"; import { Slot } from "../../utils/components/slot/Slot"; import { cl } from "../../utils/helpers"; import BasePrimitive, { PRIMITIVE_PROPS, PrimitiveProps, } from "../base/BasePrimitive"; import { PrimitiveAsChildProps } from "../base/PrimitiveAsChildProps"; import { getResponsiveProps, getResponsiveValue } from "../utilities/css"; import { ResponsiveProp, SpacingScale } from "../utilities/types"; export type StackProps = HTMLAttributes & { /** * CSS `justify-content` property. * * @example * justify='center' * justify={{xs: 'start', sm: 'center', md: 'end', lg: 'space-around', xl: 'space-between'}} */ justify?: ResponsiveProp< | "start" | "center" | "end" | "space-around" | "space-between" | "space-evenly" >; /** * CSS `align-items` property. * @default "stretch" * * @example * align='center' * align={{xs: 'start', sm: 'center', md: 'end', lg: 'baseline', xl: 'stretch'}} */ align?: ResponsiveProp<"start" | "center" | "end" | "baseline" | "stretch">; /** * Sets the CSS `flex-wrap` property. */ wrap?: boolean; /** * CSS `gap` property. * Accepts a [spacing token](https://aksel.nav.no/grunnleggende/styling/design-tokens#space) * or an object of spacing tokens for different breakpoints. * * @example * gap='space-16' * gap='space-32 space-16' * gap={{xs: 'space-8', sm: 'space-12', md: 'space-16', lg: 'space-20', xl: 'space-24'}} */ gap?: ResponsiveProp; /** * CSS `flex-direction` property. * @default "row" * * @example * direction='row' * direction={{xs: 'row', sm: 'column'}} */ direction?: ResponsiveProp< "row" | "column" | "row-reverse" | "column-reverse" >; } & PrimitiveProps & PrimitiveAsChildProps; export const Stack: OverridableComponent = forwardRef( ( { children, className, as: Component = "div", align, justify, wrap = true, gap, style: _style, direction = "row", asChild, ...rest }, ref, ) => { const style: React.CSSProperties = { ..._style, ...getResponsiveProps(`stack`, "gap", "space", gap), ...getResponsiveValue(`stack`, "direction", direction), ...getResponsiveValue(`stack`, "align", align), ...getResponsiveValue(`stack`, "justify", justify), }; const Comp = asChild ? Slot : Component; return ( {children} ); }, ); export default Stack;