Stack
Layout flex vertical com tokens consistentes de gap, alinhamento e justificação.
Visão geral
Stack é um primitive de layout vertical: um <div> pré-configurado como flex flex-col com três variants controladas por token - gap, align, justify. Use sempre que você tiver uma lista de itens fluindo de cima para baixo: conteúdo de card, seções de formulário, rows de configurações, menus verticais, páginas de lista, colunas de footer.
Stack existe para matar strings ad-hoc de flex flex-col gap-X items-Y. Uma vez que gap, alinhamento e justificação pertencem a enums vinculados a design tokens, todo o codebase permanece consistente por meio de reescritas de token em vez de varreduras de regex. Recorra a um <div> puro apenas quando nenhum dos três eixos precisar de configuração.
Preview
'use client';import { Stack } from '@gremorie/rx-containers';export function StackPreview() { return ( <Stack gap="md" className="max-w-sm"> <div className="rounded-md border p-3 text-sm">Item one</div> <div className="rounded-md border p-3 text-sm">Item two</div> <div className="rounded-md border p-3 text-sm">Item three</div> </Stack> );}Anatomia
Stack coluna flex; spacing e alinhamento cross-/main-axis controlados inteiramente por propsInstalação
bash npx gremorie@latest add rx-stack bash pnpm dlx gremorie@latest add rx-stack bash yarn dlx gremorie@latest add rx-stack bash bunx --bun gremorie@latest add rx-stack Uso
import { Stack } from "@gremorie/rx-containers";
export function SettingsRow({ children }) {
return (
<Stack gap="sm" align="stretch">
{children}
</Stack>
);
}A edição Angular deste componente hoje é entregue a partir do código-fonte (veja o workbench para o comparativo lado a lado); a entrada de registry vem em seguida.
API
<Stack>
Renderiza um <div> com flex flex-col mais as classes de gap, alinhamento e justificação derivadas dos enums de variant.
| Prop | Type | Default | Description |
|---|---|---|---|
gap | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | Spacing vertical entre os filhos. Mapeia para gap-0, gap-1, gap-2, gap-4, gap-6, gap-8, gap-12 para que os valores combinem com a escala de spacing do projeto. |
align | "start" | "center" | "end" | "stretch" | "baseline" | "stretch" | Alinhamento cross-axis, aplicado como items-*. A maioria dos contextos de card e formulário quer stretch; menus verticais e colunas de modal querem start. |
justify | "start" | "center" | "end" | "between" | "around" | "evenly" | "start" | Alinhamento main-axis, aplicado como justify-*. Use between quando o último filho deve ancorar no fundo de um Stack com altura limitada. |
className | string | - | Classes extras mescladas após as classes de variant. Use para escape hatches de layout (min-h-0, flex-1, mx-auto); evite sobrescrever as próprias classes de variant. |
ref | Ref<HTMLDivElement> | - | Ref encaminhada para o <div> subjacente. |
...props | React.ComponentPropsWithoutRef<"div"> | - | Atributos padrão de div. |
Apenas vertical. Stack não tem prop direction. Para fluxo horizontal,
combine-o com um helper de row (ou flex flex-row gap-* puro). Para grids de
dois eixos, recorra a um primitive Grid dedicado.
Composição
<Stack>é a coluna. Escolhagappara combinar com o ritmo da superfície (cards geralmente queremmd, listas densas de configurações queremsm, menus verticais queremxs).- Os filhos podem ser qualquer elemento. Stack não os envolve - ele apenas configura o container flex pai.
- Dentro de um Stack, Stacks aninhados compõem naturalmente: cada um escolhe seu próprio
gapenquanto herda o alinhamento cross-axis do pai. - Ancoragem de footer é o caso de uso canônico de
justify="between": header no topo, conteúdo no meio, footer no fundo de um Stack de altura fixa.
Variações
Escala de gap
gap="xs"
gap="sm"
gap="md"
gap="lg"
'use client';import { Stack } from '@gremorie/rx-containers';const gaps = ['xs', 'sm', 'md', 'lg'] as const;export function StackGapsPreview() { return ( <div className="grid gap-6 sm:grid-cols-2"> {gaps.map((gap) => ( <div key={gap}> <p className="mb-2 text-xs font-medium text-muted-foreground"> gap="{gap}" </p> <Stack gap={gap}> <div className="rounded-md border p-2 text-sm">One</div> <div className="rounded-md border p-2 text-sm">Two</div> <div className="rounded-md border p-2 text-sm">Three</div> </Stack> </div> ))} </div> );}A prop gap mapeia para a escala de spacing do projeto. Cards geralmente querem md, listas densas de configurações querem sm, menus verticais querem xs.
Coluna centralizada
'use client';import { Stack } from '@gremorie/rx-containers';export function StackCenteredPreview() { return ( <Stack gap="sm" align="center" className="text-sm"> <div className="rounded-full bg-muted px-3 py-1">Tag</div> <div className="text-muted-foreground">Five matching results</div> </Stack> );}Use align="center" para empty states, callouts, e qualquer coluna onde os filhos devem abraçar a linha central.
Footer ancorado
Invite teammates
Send a magic link or copy the workspace URL.
'use client';import { Stack } from '@gremorie/rx-containers';import { Button } from '@gremorie/rx-forms';export function StackPinnedFooterPreview() { return ( <Stack gap="md" justify="between" className="h-64 max-w-sm rounded-md border p-4" > <Stack gap="sm"> <h2 className="text-lg font-semibold">Invite teammates</h2> <p className="text-sm text-muted-foreground"> Send a magic link or copy the workspace URL. </p> </Stack> <Button>Send invite</Button> </Stack> );}Use justify="between" mais uma restrição de altura para manter o CTA colado no fundo independentemente do tamanho do corpo.
Acessibilidade
- Apenas apresentação: Stack é um primitive de layout. Ele não adiciona nenhum role ARIA e nenhum comportamento de live-region.
- Filhos semânticos: envolva o conteúdo do Stack no elemento certo para o contexto -
<section>para um landmark,<ul>mais<li>para uma lista de verdade,<nav>para menus verticais. - Ordem de leitura combina com a ordem no DOM: Stack é
flex-col, nunca invertido. A ordem de tabulação e a ordem de leitor de tela seguem a ordem no source. - Nenhum movimento injetado: sem transitions, sem autofocus, sem comportamento de scroll. Componha com
Skeleton,Progress, ou primitives de movimento onde necessário.
Relacionados
- Card - o host mais comum para um Stack vertical de conteúdo.
- Separator - coloque entre filhos do Stack para divisores explícitos.
- ScrollArea - envolva um Stack quando a coluna ultrapassar seu container.