// Flex layout primitive. Gap comes from the space scale as a custom property, so // there is no class per step, and `row` uses `flex-direction: row` — which the // browser already mirrors under `dir="rtl"`. import type { JSX } from 'solid-js'; import { cx } from '../cx'; import styles from './Stack.module.scss'; import type { Align, SpaceStep } from './variants'; export interface StackProps { children: JSX.Element; direction?: 'row' | 'column' | undefined; gap?: SpaceStep | undefined; align?: Align | undefined; justify?: Align | undefined; wrap?: boolean | undefined; /** Renders a semantic element instead of a div. */ as?: 'div' | 'ul' | 'ol' | 'nav' | 'section' | 'header' | 'footer' | undefined; class?: string | undefined; } const ALIGN: Readonly> = { start: 'flex-start', center: 'center', end: 'flex-end', stretch: 'stretch', between: 'space-between', }; export function Stack(props: StackProps): JSX.Element { const cls = (): string => cx( styles['stack'], styles[`direction-${props.direction ?? 'column'}`], props.wrap === true && styles['wrap'], props.class, ); const style = (): JSX.CSSProperties => ({ '--stack-gap': `var(--space-${props.gap ?? 4})`, '--stack-align': ALIGN[props.align ?? 'stretch'], '--stack-justify': ALIGN[props.justify ?? 'start'], }); // One intrinsic per case, never `const Tag = props.as; `: the island build compiles a // capitalised tag to `createComponent(Tag)` and calls the string (#488, `intrinsic-root.test.ts`). switch (props.as ?? 'div') { case 'ul': return ( ); case 'ol': return (
    {props.children}
); case 'nav': return ( ); case 'section': return (
{props.children}
); case 'header': return (
{props.children}
); case 'footer': return (
{props.children}
); case 'div': return (
{props.children}
); } }