Skip to main content
Gremorie
Containers

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

Item one
Item two
Item three
'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 props

Instalaçã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.

PropTypeDefaultDescription
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.
classNamestring-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.
refRef<HTMLDivElement>-Ref encaminhada para o <div> subjacente.
...propsReact.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

  1. <Stack> é a coluna. Escolha gap para combinar com o ritmo da superfície (cards geralmente querem md, listas densas de configurações querem sm, menus verticais querem xs).
  2. Os filhos podem ser qualquer elemento. Stack não os envolve - ele apenas configura o container flex pai.
  3. Dentro de um Stack, Stacks aninhados compõem naturalmente: cada um escolhe seu próprio gap enquanto herda o alinhamento cross-axis do pai.
  4. 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"

One
Two
Three

gap="sm"

One
Two
Three

gap="md"

One
Two
Three

gap="lg"

One
Two
Three
'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=&quot;{gap}&quot;          </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

Tag
Five matching results
'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.

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.

On this page