Cartão

Um cartão agrupa conteúdo relacionado na sua própria superfície. As partes — cardHeader(), cardMedia(), cardBody(), cardFooter() — são funções separadas em vez de props, por isso usas só as que precisas e pões na ordem que o desenho pedir.

Cartão básico

Rotas por ficheiros

src/about.ht.js → /about

As pastas passam a caminhos. Os parênteses retos passam a parâmetros. Não há router para configurar.

card(
  cardHeader({ title: 'Rotas por ficheiros', subtitle: 'src/about.ht.js → /about' }),
  cardBody(text({ variant: 'small', tone: 'muted' }, 'As pastas passam a caminhos. Os parênteses retos passam a parâmetros. Não há router para configurar.')),
)

Variantes

Outlined é a predefinição. Elevated troca o contorno por uma sombra, e flat tinge a superfície em vez de qualquer um dos dois.

Outlined

Elevated

Flat

grid({ min: '13rem' },
  card({ variant: 'outlined' }, cardBody(text({ variant: 'small' }, 'Outlined'))),
  card({ variant: 'elevated' }, cardBody(text({ variant: 'small' }, 'Elevated'))),
  card({ variant: 'flat' }, cardBody(text({ variant: 'small' }, 'Flat'))),
)

Com rodapé

divided acrescenta o fio por cima do rodapé. O rodapé é empurrado para baixo, por isso cartões numa fila alinham as suas ações mesmo quando o texto acima tem comprimentos diferentes.

Site básico

Um projeto mínimo mais configurações de publicação.

Blogue em Markdown

Uma pasta de ficheiros .md renderizados em páginas estáticas, com feed RSS e sem qualquer JavaScript no cliente.

grid({ min: '14rem' },
  card(
    cardHeader({ title: 'Site básico' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Um projeto mínimo mais configurações de publicação.')),
    cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, 'Abrir')),
  ),
  card(
    cardHeader({ title: 'Blogue em Markdown' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Uma pasta de ficheiros .md renderizados em páginas estáticas, com feed RSS e sem qualquer JavaScript no cliente.')),
    cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, 'Abrir')),
  ),
)

Média

cardMedia() preenche o topo do cartão numa proporção fixa, para que uma fila de cartões fique certa sejam quais forem as medidas das imagens de origem.

Predefinição 16 / 9

ratio: 4 / 3

grid({ min: '13rem' },
  card(
    cardMedia({ src: '/logo.svg', alt: '', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
    cardBody(text({ variant: 'small' }, 'Predefinição 16 / 9')),
  ),
  card(
    cardMedia({ src: '/logo.svg', alt: '', ratio: '4 / 3', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
    cardBody(text({ variant: 'small' }, 'ratio: 4 / 3')),
  ),
)

Um cartão inteiro como ligação

Dá ao cartão um href e a superfície toda passa a ser uma ligação, com a subida ao passar o rato que a acompanha. Não ponhas botões nem outras ligações dentro de um cartão nesta forma — conteúdo interativo não pode ficar aninhado dentro de uma ligação. Usa antes um botão no rodapé de um cartão simples.

grid({ min: '14rem' },
  card({ href: '/pt/docs/routing' },
    cardHeader({ title: 'Rotas', subtitle: 'Ler o guia' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'Rotas dinâmicas, apanha-tudo e grupos de rotas.')),
  ),
  card({ href: '/pt/docs/data' },
    cardHeader({ title: 'Carregamento de dados', subtitle: 'Ler o guia' }),
    cardBody(text({ variant: 'small', tone: 'muted' }, 'data() corre na construção, com cache de fetch.')),
  ),
)

Espaçamento interno

Uma prop define de uma vez o espaçamento de todas as partes do cartão.

padding: sm

padding: xl

stack({ gap: 'md' },
  card({ padding: 'sm' }, cardBody(text({ variant: 'small' }, 'padding: sm'))),
  card({ padding: 'xl' }, cardBody(text({ variant: 'small' }, 'padding: xl'))),
)

Conteúdo livre

As partes são uma conveniência, não uma obrigação — um cartão aceita quaisquer filhos, e cardHeader() aceita filhos próprios ao lado do título, para um avatar ou um botão de menu à direita.

Paul Browne

Publicado há 4 minutos

PB
Construção passou12 páginas4,1 kB
card(
  cardHeader(
    { title: 'Paul Browne', subtitle: 'Publicado há 4 minutos' },
    avatar({ name: 'Paul Browne', size: 'sm' }),
  ),
  cardBody(
    stack({ direction: 'row', gap: 'sm', wrap: true },
      chip({ color: 'success', dot: true }, 'Construção passou'),
      chip({ color: 'neutral' }, '12 páginas'),
      chip({ color: 'neutral' }, '4,1 kB'),
    ),
  ),
)

Props

card():

PropTipoPredefiniçãoDescrição
variant'outlined' | 'elevated' | 'flat''outlined'Como a superfície se separa da página.
hrefstring—Desenha o cartão inteiro como uma ligação.
paddingSpace'lg'Espaçamento usado por todas as partes do cartão.

As partes:

PartePropsPredefiniçãoDescrição
cardHeadertitle, subtitle—Título e subtítulo, mais quaisquer filhos ao lado.
cardTitleas'h3'O título sozinho, quando o cabeçalho é feito à mão.
cardSubtitle—A linha esbatida sob um título.
cardMediasrc, alt, ratio'16 / 9'Uma imagem de capa numa proporção fixa.
cardBody—A região de conteúdo principal.
cardFooterdividedfalseFila de ações em baixo; divided acrescenta o fio por cima.