Ir para o conteúdo
Secções
Idioma, atualmente Português
Sistema de design Rastrillo

Ecrã de lista

Ecrã de lista genérico com título, barra de ferramentas e linhas que funcionam em computador e em telemóvel.

Cada exemplo funciona de verdade, mas as suas ligações não levam a lado nenhum. HTML mostra a marcação para copiar.

page-header

A barra de título do ecrã: um h1, um subtítulo opcional e uma ação principal.

Título, subtítulo e uma ação principal

Pré-visualização
<header rst-page-header>
  <div rst-page-header-titles>
    <h1>Publicações</h1>
    <p rst-page-header-sub>Tudo o que escreveu, o mais recente primeiro.</p>
  </div>
  <a rst-btn="primary" href="/posts/new">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    Escrever uma publicação
  </a>
</header>
{{template "page-header" dict
    "Title" "Publicações"
    "Sub" "Tudo o que escreveu, o mais recente primeiro."
    "ActionHref" "/posts/new"
    "ActionLabel" "Escrever uma publicação"
    "ActionIcon" "plus"}}

Só o título

Pré-visualização
<header rst-page-header>
  <div rst-page-header-titles>
    <h1>Definições</h1>
  </div>
</header>
{{template "page-header" dict "Title" "Definições"}}

list-bar

A barra de ferramentas no topo de um cartão de lista, com pesquisa e filtro.

Pesquisa com um menu de filtro

Pré-visualização

Coloque isto dentro de <div rst-list>.

<div rst-lbar>
  <search>
    <form rst-search method="get" action="/posts">
      <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
      <input type="search" name="q" value="versão" placeholder="Pesquisar publicações" aria-label="Pesquisar publicações">
      <a rst-search-clear href="/posts?sort=newest" aria-label="Limpar a pesquisa">
        <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
      </a>
      <input type="hidden" name="sort" value="newest">
      <button class="rst-sr-only" type="submit">Pesquisar</button>
    </form>
  </search>
  <details rst-dropdown name="rst-menus">
    <summary rst-btn aria-label="Filtrar por estado: Pago">
      Pago
      <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
    </summary>
    <div rst-dropdown-menu>
      <a href="/posts">Tudo</a>
      <a href="/posts?status=paid" aria-current="true">Pago <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></a>
      <a href="/posts?status=free">Gratuito</a>
    </div>
  </details>
</div>

Coloque isto dentro de <div rst-list>.

{{template "list-bar" dict
    "Filter" (dict "Aria" "Filtrar por estado: Pago" "Items" (list (dict "Href" "/posts" "Label" "Tudo") (dict "Current" true "Href" "/posts?status=paid" "Label" "Pago") (dict "Href" "/posts?status=free" "Label" "Gratuito")) "Label" "Pago")
    "Hidden" (list (list "sort" "newest"))
    "Placeholder" "Pesquisar publicações"
    "Query" "versão"
    "SearchAction" "/posts"}}

list-search-submit

O verdadeiro botão de envio do formulário de pesquisa: escondido à vista, dentro da ordem de tabulação, e aparece quando recebe o foco do teclado.

Etiqueta por omissão

Pré-visualização

Coloque isto dentro de <section rst-box>.

<button class="rst-sr-only" type="submit">Pesquisar</button>

Coloque isto dentro de <section rst-box>.

{{template "list-search-submit" dict}}

Aqui não se vê nada até chegar com a tecla de tabulação.

list-row-action

Uma linha de lista: o nome do registo como ligação principal, uma linha de dados e uma ação secundária.

Marca inicial, estado e uma ação

Pré-visualização

Coloque isto dentro de <div rst-list>.

<div rst-row>
  <span rst-row-lead data-lead="accent" aria-hidden="true">RN</span>
  <span rst-row-main><a href="/posts/1">Notas da versão, agosto</a>
    <small rst-row-sub>Publicado a 2 de agosto · 4 min de leitura</small>
  </span>
  <span rst-status rst-tone="positive">Publicado</span>
  <a rst-row-action href="/posts/1/edit" aria-label="Editar Notas da versão, agosto">Editar</a>
</div>

Coloque isto dentro de <div rst-list>.

{{template "list-row-action" dict
    "Href" "/posts/1"
    "Main" "Notas da versão, agosto"
    "Sub" "Publicado a 2 de agosto · 4 min de leitura"
    "ActionHref" "/posts/1/edit"
    "ActionLabel" "Editar"
    "ActionAria" "Editar Notas da versão, agosto"
    "StatusTone" "positive"
    "StatusLabel" "Publicado"
    "Lead" "accent"
    "LeadInitial" "RN"}}

Só o nome e a linha de detalhe

Pré-visualização

Coloque isto dentro de <div rst-list>.

<div rst-row>
  <span rst-row-main><a href="/posts/2">Porque deixámos o antigo executor</a>
    <small rst-row-sub>Rascunho · guardado há 20 minutos</small>
  </span>
</div>

Coloque isto dentro de <div rst-list>.

{{template "list-row-action" dict
    "Href" "/posts/2"
    "Main" "Porque deixámos o antigo executor"
    "Sub" "Rascunho · guardado há 20 minutos"}}

row-menu

As outras ações de uma linha, atrás de um botão ⋮. Uma destrutiva leva à sua página de confirmação.

Links, um formulário e um item destrutivo

Pré-visualização
<details rst-row-menu name="rst-menus">
  <summary aria-label="Ações para Grace Hopper">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
  </summary>
  <div rst-row-menu-panel>
    <a href="/orders/AB3PX/edit">Editar</a>
    <form method="post" action="/orders/AB3PX/archive">
      <input type="hidden" name="state" value="archived">
      <button type="submit">Arquivar</button>
    </form>
    <hr>
    <a class="rst-danger" href="/orders/AB3PX/delete">Eliminar encomenda…</a>
  </div>
</details>
{{template "row-menu" dict
    "Name" "Grace Hopper"
    "Items" (list
        (dict "Href" "/orders/AB3PX/edit" "Label" "Editar")
        (dict "Action" "/orders/AB3PX/archive" "Hidden" (list (list "state" "archived")) "Label" "Arquivar")
        (dict "Danger" true "Href" "/orders/AB3PX/delete" "Label" "Eliminar encomenda…"))}}

Coloque o item destrutivo por último e termine o rótulo com …. Ele abre uma página que pergunta antes de apagar qualquer coisa.

Só links, para uma lista dentro de um formulário de seleção

Pré-visualização
<details rst-row-menu name="rst-menus">
  <summary aria-label="Ações para Alan Turing">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
  </summary>
  <div rst-row-menu-panel>
    <a href="/orders/CD4QY/edit">Editar</a>
    <hr>
    <a class="rst-danger" href="/orders/CD4QY/delete">Eliminar encomenda…</a>
  </div>
</details>
{{template "row-menu" dict
    "Name" "Alan Turing"
    "Items" (list
        (dict "Href" "/orders/CD4QY/edit" "Label" "Editar")
        (dict "Danger" true "Href" "/orders/CD4QY/delete" "Label" "Eliminar encomenda…"))}}

Dentro de um formulário, todo item deve ser um link. Uma ação que envia dados passa por uma página própria.

seg-tabs

Um controlo segmentado de ligações renderizadas no servidor. O separador atual é aria-current numa ligação.

Duas secções

Pré-visualização
<nav rst-seg-tabs aria-label="Secções da publicação">
  <a href="?tab=basics" aria-current="page">Básico</a>
  <a href="?tab=advanced">Avançado</a>
</nav>
{{template "seg-tabs" dict
    "Label" "Secções da publicação"
    "Items" (list
        (dict "Current" true "Href" "?tab=basics" "Label" "Básico")
        (dict "Href" "?tab=advanced" "Label" "Avançado"))}}

dropdown

Um desdobrável sem JavaScript nenhum: um botão summary sobre um painel de ligações simples.

Um menu de filtro com uma opção aplicada

Pré-visualização
<details rst-dropdown name="rst-menus">
  <summary rst-btn aria-label="Ordenar publicações: mais recentes primeiro">
    Mais recentes
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
  </summary>
  <div rst-dropdown-menu>
    <a href="/posts?sort=newest" aria-current="true">Mais recentes <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></a>
    <a href="/posts?sort=oldest">Mais antigas</a>
    <a href="/posts?sort=title">Por título</a>
  </div>
</details>
{{template "dropdown" dict
    "Label" "Mais recentes"
    "Aria" "Ordenar publicações: mais recentes primeiro"
    "Items" (list
        (dict "Current" true "Href" "/posts?sort=newest" "Label" "Mais recentes")
        (dict "Href" "/posts?sort=oldest" "Label" "Mais antigas")
        (dict "Href" "/posts?sort=title" "Label" "Por título"))}}

bulk-bar

A faixa de cabeçalho do modo de seleção, que substitui a barra de lista: a contagem, uma ligação para alargar a seleção e o menu de ações.

Três linhas selecionadas

Pré-visualização

Coloque isto dentro de <div rst-list>.

<div rst-bulkbar>
  <a rst-bulkbar-close href="/posts" aria-label="Seleção concluída">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
  </a>
  <span rst-bulkbar-selection><span rst-bulkbar-count>3 selecionadas</span><a rst-bulkbar-escalate href="/posts?select=all">Selecionar as 412 correspondências</a></span>
  <details rst-dropdown name="rst-menus">
    <summary>
      Ações
      <span rst-caret aria-hidden="true">
        <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
      </span>
    </summary>
    <div rst-dropdown-menu>
      <button type="submit" name="action" value="export">Exportar</button>
      <button type="submit" name="action" value="unpublish">Despublicar</button>
      <button type="submit" name="action" value="delete" class="rst-danger">Eliminar…</button>
    </div>
  </details>
</div>

Coloque isto dentro de <div rst-list>.

{{template "bulk-bar" dict
    "DoneHref" "/posts"
    "Count" "3 selecionadas"
    "EscalateHref" "/posts?select=all"
    "EscalateLabel" "Selecionar as 412 correspondências"
    "Actions" (list
        (dict "Label" "Exportar" "Value" "export")
        (dict "Label" "Despublicar" "Value" "unpublish")
        (dict "Danger" true "Label" "Eliminar…" "Value" "delete"))
    "MenuLabel" "Ações"}}

O item destrutivo fica em último: a primeira entrada é o valor que o Enter do formulário à volta dispara por omissão.

media-grid

Uma grelha de mosaicos de imagem. Cada moldura é 4:3, por isso capturas altas e banners largos cabem numa mesma grelha uniforme.

Capturas, um logótipo e um banner

Pré-visualização

Coloque isto dentro de <div rst-list>.

<div rst-media>
  <div rst-media-tile>
    <div rst-media-frame>
      <img src="/images/checkout.png" alt="" loading="lazy" decoding="async" width="1280" height="3200">
    </div>
    <div rst-media-caption>
      <div rst-media-name>
        <a href="/images/1">Checkout, passo 2</a>
        <details rst-row-menu name="rst-menus">
          <summary aria-label="Ações para Checkout, passo 2">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
          </summary>
          <div rst-row-menu-panel>
            <a href="/images/1/edit">Editar</a>
            <hr>
            <a class="rst-danger" href="/images/1/delete">Eliminar…</a>
          </div>
        </details>
      </div>
      <p rst-media-desc>O passo do pagamento, com o formulário do cartão aberto.</p>
      <p rst-media-meta>1280 × 3200 · 412 KB</p>
    </div>
  </div>
  <div rst-media-tile>
    <div rst-media-frame>
      <img src="/images/pricing.png" alt="" loading="lazy" decoding="async" width="1280" height="2400">
    </div>
    <div rst-media-caption>
      <div rst-media-name>
        <a href="/images/2">Página de preços</a>
        <details rst-row-menu name="rst-menus">
          <summary aria-label="Ações para Página de preços">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
          </summary>
          <div rst-row-menu-panel>
            <a href="/images/2/edit">Editar</a>
            <hr>
            <a class="rst-danger" href="/images/2/delete">Eliminar…</a>
          </div>
        </details>
      </div>
      <p rst-media-desc="none">Sem descrição</p>
      <p rst-media-meta>1280 × 2400 · 318 KB</p>
    </div>
  </div>
  <div rst-media-tile>
    <div rst-media-frame="contain">
      <img src="/images/logo.svg" alt="Harbour" loading="lazy" decoding="async" width="240" height="240">
    </div>
    <div rst-media-caption>
      <div rst-media-name>
        <a href="/images/3">Logótipo Harbour</a>
        <details rst-row-menu name="rst-menus">
          <summary aria-label="Ações para Logótipo Harbour">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
          </summary>
          <div rst-row-menu-panel>
            <a href="/images/3/edit">Editar</a>
            <hr>
            <a class="rst-danger" href="/images/3/delete">Eliminar…</a>
          </div>
        </details>
      </div>
      <p rst-media-desc>A marca sozinha, para fundos escuros e claros.</p>
      <p rst-media-meta>240 × 240 · 3 KB</p>
    </div>
  </div>
  <div rst-media-tile>
    <div rst-media-frame="contain">
      <img src="/images/banner.png" alt="" loading="lazy" decoding="async" width="1200" height="200">
    </div>
    <div rst-media-caption>
      <div rst-media-name>
        <a href="/images/4">Banner de primavera</a>
        <details rst-row-menu name="rst-menus">
          <summary aria-label="Ações para Banner de primavera">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
          </summary>
          <div rst-row-menu-panel>
            <a href="/images/4/edit">Editar</a>
            <hr>
            <a class="rst-danger" href="/images/4/delete">Eliminar…</a>
          </div>
        </details>
      </div>
      <p rst-media-desc>A faixa no topo da loja em março.</p>
      <p rst-media-meta>1200 × 200 · 64 KB</p>
    </div>
  </div>
</div>

Coloque isto dentro de <div rst-list>.

{{template "media-grid" dict
    "Items" (list
        (dict "Desc" "O passo do pagamento, com o formulário do cartão aberto." "Height" 3200 "Href" "/images/1" "Menu" (list (dict "Href" "/images/1/edit" "Label" "Editar") (dict "Danger" true "Href" "/images/1/delete" "Label" "Eliminar…")) "Meta" "1280 × 3200 · 412 KB" "Name" "Checkout, passo 2" "Src" "/images/checkout.png" "Width" 1280)
        (dict "Desc" "" "Height" 2400 "Href" "/images/2" "Menu" (list (dict "Href" "/images/2/edit" "Label" "Editar") (dict "Danger" true "Href" "/images/2/delete" "Label" "Eliminar…")) "Meta" "1280 × 2400 · 318 KB" "Name" "Página de preços" "Src" "/images/pricing.png" "Width" 1280)
        (dict "Alt" "Harbour" "Desc" "A marca sozinha, para fundos escuros e claros." "Fit" "contain" "Height" 240 "Href" "/images/3" "Menu" (list (dict "Href" "/images/3/edit" "Label" "Editar") (dict "Danger" true "Href" "/images/3/delete" "Label" "Eliminar…")) "Meta" "240 × 240 · 3 KB" "Name" "Logótipo Harbour" "Src" "/images/logo.svg" "Width" 240)
        (dict "Desc" "A faixa no topo da loja em março." "Fit" "contain" "Height" 200 "Href" "/images/4" "Menu" (list (dict "Href" "/images/4/edit" "Label" "Editar") (dict "Danger" true "Href" "/images/4/delete" "Label" "Eliminar…")) "Meta" "1200 × 200 · 64 KB" "Name" "Banner de primavera" "Src" "/images/banner.png" "Width" 1200))}}

Defina Fit como "contain" para um logótipo ou um banner. Uma captura mantém a predefinição e mostra o topo. Um mosaico sem Desc diz "Sem descrição".

Modo de seleção, um mosaico selecionado

Pré-visualização

Coloque isto dentro de <div rst-list>.

<div rst-media>
  <div rst-media-tile>
    <div rst-media-frame>
      <img src="/images/checkout.png" alt="" loading="lazy" decoding="async" width="1280" height="3200">
      <label rst-selbox>
        <input type="checkbox" name="id" value="1" checked aria-label="Selecionar Checkout, passo 2">
      </label>
    </div>
    <div rst-media-caption>
      <div rst-media-name>
        <a href="/images/1">Checkout, passo 2</a>
        <details rst-row-menu name="rst-menus">
          <summary aria-label="Ações para Checkout, passo 2">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
          </summary>
          <div rst-row-menu-panel>
            <a href="/images/1/edit">Editar</a>
            <hr>
            <a class="rst-danger" href="/images/1/delete">Eliminar…</a>
          </div>
        </details>
      </div>
      <p rst-media-desc>O passo do pagamento, com o formulário do cartão aberto.</p>
      <p rst-media-meta>1280 × 3200 · 412 KB</p>
    </div>
  </div>
  <div rst-media-tile>
    <div rst-media-frame>
      <img src="/images/pricing.png" alt="" loading="lazy" decoding="async" width="1280" height="2400">
      <label rst-selbox>
        <input type="checkbox" name="id" value="2" aria-label="Selecionar Página de preços">
      </label>
    </div>
    <div rst-media-caption>
      <div rst-media-name>
        <a href="/images/2">Página de preços</a>
        <details rst-row-menu name="rst-menus">
          <summary aria-label="Ações para Página de preços">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
          </summary>
          <div rst-row-menu-panel>
            <a href="/images/2/edit">Editar</a>
            <hr>
            <a class="rst-danger" href="/images/2/delete">Eliminar…</a>
          </div>
        </details>
      </div>
      <p rst-media-desc="none">Sem descrição</p>
      <p rst-media-meta>1280 × 2400 · 318 KB</p>
    </div>
  </div>
</div>

Coloque isto dentro de <div rst-list>.

{{template "media-grid" dict
    "Items" (list
        (dict "Desc" "O passo do pagamento, com o formulário do cartão aberto." "Height" 3200 "Href" "/images/1" "Menu" (list (dict "Href" "/images/1/edit" "Label" "Editar") (dict "Danger" true "Href" "/images/1/delete" "Label" "Eliminar…")) "Meta" "1280 × 3200 · 412 KB" "Name" "Checkout, passo 2" "Select" "1" "Selected" true "Src" "/images/checkout.png" "Width" 1280)
        (dict "Desc" "" "Height" 2400 "Href" "/images/2" "Menu" (list (dict "Href" "/images/2/edit" "Label" "Editar") (dict "Danger" true "Href" "/images/2/delete" "Label" "Eliminar…")) "Meta" "1280 × 2400 · 318 KB" "Name" "Página de preços" "Select" "2" "Src" "/images/pricing.png" "Width" 1280))}}

Envolva a grelha e um bulk-bar num único formulário. Cada caixa envia o valor Select do seu mosaico com o nome "id"; defina SelectName para o mudar. Dentro do formulário, os itens do menu têm de ser links.

pagination

Uma tira numerada de ligações normais, para que a paginação continue a funcionar com o JavaScript desligado.

A meio de uma lista longa

Pré-visualização
<nav rst-pagination aria-label="Páginas de publicações">
  <a href="/posts?page=3" rst-pagination-step="prev"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><span rst-pagination-word>Anterior</span></a>
  <a href="/posts?page=1">1</a>
  <span rst-pagination-gap aria-hidden="true">…</span>
  <a href="/posts?page=3" rst-pagination-wide>3</a>
  <span aria-current="page">4</span>
  <a href="/posts?page=5" rst-pagination-wide>5</a>
  <span rst-pagination-gap aria-hidden="true">…</span>
  <a href="/posts?page=9">9</a>
  <a href="/posts?page=5" rst-pagination-step="next"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><span rst-pagination-word>Seguinte</span></a>
</nav>
{{template "pagination" dict
    "Items" (list
        (dict "Href" "/posts?page=3" "Label" "Anterior" "Rel" "prev")
        (dict "Href" "/posts?page=1" "Label" "1")
        (dict "Gap" true)
        (dict "Href" "/posts?page=3" "Label" "3")
        (dict "Current" true "Label" "4")
        (dict "Href" "/posts?page=5" "Label" "5")
        (dict "Gap" true)
        (dict "Href" "/posts?page=9" "Label" "9")
        (dict "Href" "/posts?page=5" "Label" "Seguinte" "Rel" "next"))
    "Label" "Páginas de publicações"}}

Primeira página, com o nome acessível por omissão

Pré-visualização
<nav rst-pagination aria-label="Paginação">
  <span rst-pagination-disabled rst-pagination-step="prev"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><span rst-pagination-word>Anterior</span></span>
  <span aria-current="page">1</span>
  <a href="/posts?page=2">2</a>
  <a href="/posts?page=2" rst-pagination-step="next"><svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><span rst-pagination-word>Seguinte</span></a>
</nav>
{{template "pagination" dict
    "Items" (list
        (dict "Disabled" true "Label" "Anterior" "Rel" "prev")
        (dict "Current" true "Label" "1")
        (dict "Href" "/posts?page=2" "Label" "2")
        (dict "Href" "/posts?page=2" "Label" "Seguinte" "Rel" "next"))}}

Sem Label, por isso o nome acessível do nav vem do catálogo.

empty-state

O cartão de estado vazio. Um estado vazio com caminhos para os primeiros passos.

Com um apelo à ação por POST

Pré-visualização
<div rst-empty>
  <h2 rst-empty-title>Ainda não há nada aqui</h2>
  <p rst-empty-body>Ainda não há publicações. A primeira é um bom ponto de partida.</p>
  <form rst-empty-cta method="post" action="/posts/seed">
    <input type="hidden" name="csrf" value="tok-123">
    <button rst-btn="primary" type="submit">Adicionar publicações de exemplo</button>
  </form>
</div>
{{template "empty-state" dict
    "Body" "Ainda não há publicações. A primeira é um bom ponto de partida."
    "Title" "Ainda não há nada aqui"
    "ActionLabel" "Adicionar publicações de exemplo"
    "PostAction" "/posts/seed"
    "Hidden" (list (list "csrf" "tok-123"))}}

Só a frase

Pré-visualização
<div rst-empty>
  <p rst-empty-body>Esta publicação ainda não tem comentários.</p>
</div>
{{template "empty-state" dict
    "Body" "Esta publicação ainda não tem comentários."}}