Pantalla de lista genérica con título, barra de herramientas y filas que funcionan en escritorio y en móvil.
Cada ejemplo funciona de verdad, pero sus enlaces no llevan a ninguna parte. HTML muestra el marcado para copiar.
page-header
La barra de título de la pantalla: un h1, un subtítulo opcional y una acción principal.
Título, subtítulo y una acción principal
<headerrst-page-header>
<divrst-page-header-titles>
<h1>Entradas</h1>
<prst-page-header-sub>Todo lo que has escrito, lo más reciente primero.</p>
</div>
<arst-btn="primary"href="/posts/new">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><pathd="M5 12h14"/><pathd="M12 5v14"/></svg>
Escribir una entrada
</a>
</header>
{{template"page-header"dict"Title""Entradas""Sub""Todo lo que has escrito, lo más reciente primero.""ActionHref""/posts/new""ActionLabel""Escribir una entrada""ActionIcon""plus"}}
Nada en Hidden dice qué par es la página, así que el valor por omisión llevaría page=4 a un conjunto de resultados que ya no tiene cuatro páginas. ClearHref es como una aplicación lo reinicia.
Vacío, con el nombre accesible tomado del catálogo
Aquí no se ve nada hasta que llegas con el tabulador.
list-row-action
Una fila de lista: el nombre del registro como enlace principal, una línea de datos y una acción secundaria.
Marca inicial, estado y una acción
Pon esto dentro de <div rst-list>.
<divrst-row>
<spanrst-row-leaddata-lead="accent"aria-hidden="true">RN</span>
<spanrst-row-main><ahref="/posts/1">Notas de la versión, agosto</a>
<smallrst-row-sub>Publicado el 2 de agosto · 4 min de lectura</small>
</span>
<spanrst-statusrst-tone="positive">Publicado</span>
<arst-row-actionhref="/posts/1/edit"aria-label="Editar Notas de la versión, agosto">Editar</a>
</div>
Pon esto dentro de <div rst-list>.
{{template"list-row-action"dict"Href""/posts/1""Main""Notas de la versión, agosto""Sub""Publicado el 2 de agosto · 4 min de lectura""ActionHref""/posts/1/edit""ActionLabel""Editar""ActionAria""Editar Notas de la versión, agosto""StatusTone""positive""StatusLabel""Publicado""Lead""accent""LeadInitial""RN"}}
Solo el nombre y la línea de detalle
Pon esto dentro de <div rst-list>.
<divrst-row>
<spanrst-row-main><ahref="/posts/2">Por qué dejamos el antiguo ejecutor</a>
<smallrst-row-sub>Borrador · guardado hace 20 minutos</small>
</span>
</div>
Pon esto dentro de <div rst-list>.
{{template"list-row-action"dict"Href""/posts/2""Main""Por qué dejamos el antiguo ejecutor""Sub""Borrador · guardado hace 20 minutos"}}
row-menu
Las demás acciones de una fila, tras un botón ⋮. Una destructiva enlaza a su página de confirmación.
Dentro de un formulario, cada elemento debe ser un enlace. Una acción que envía datos pasa por una página propia.
seg-tabs
Un control segmentado de enlaces renderizados en el servidor. La pestaña actual es aria-current en un enlace.
Dos secciones
<navrst-seg-tabsaria-label="Secciones de la entrada">
<ahref="?tab=basics"aria-current="page">Básico</a>
<ahref="?tab=advanced">Avanzado</a>
</nav>
{{template"seg-tabs"dict"Label""Secciones de la entrada""Items" (list
(dict"Current"true"Href""?tab=basics""Label""Básico")
(dict"Href""?tab=advanced""Label""Avanzado"))}}
dropdown
Un desplegable sin nada de JavaScript: un botón summary sobre un panel de enlaces normales.
{{template"bulk-bar"dict"DoneHref""/posts""Count""3 seleccionadas""EscalateHref""/posts?select=all""EscalateLabel""Seleccionar las 412 coincidencias""Actions" (list
(dict"Label""Exportar""Value""export")
(dict"Label""Retirar la publicación""Value""unpublish")
(dict"Danger"true"Label""Eliminar…""Value""delete"))
"MenuLabel""Acciones"}}
El elemento destructivo va al final: la primera entrada es el valor por defecto que dispara Enter en el formulario que lo rodea.
media-grid
Una cuadrícula de mosaicos de imagen. Cada marco es 4:3, así que las capturas altas y los banners anchos caben en una misma cuadrícula uniforme.
Capturas, un logotipo y un banner
Pon esto dentro de <div rst-list>.
<divrst-media>
<divrst-media-tile>
<divrst-media-frame>
<imgsrc="/images/checkout.png"alt=""loading="lazy"decoding="async"width="1280"height="3200">
</div>
<divrst-media-caption>
<divrst-media-name>
<ahref="/images/1">Pago, paso 2</a>
<detailsrst-row-menuname="rst-menus">
<summaryaria-label="Acciones para Pago, paso 2">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><circlecx="12"cy="12"r="1"/><circlecx="12"cy="5"r="1"/><circlecx="12"cy="19"r="1"/></svg>
</summary>
<divrst-row-menu-panel>
<ahref="/images/1/edit">Editar</a>
<hr>
<aclass="rst-danger"href="/images/1/delete">Eliminar…</a>
</div>
</details>
</div>
<prst-media-desc>El paso de pago, con el formulario de la tarjeta abierto.</p>
<prst-media-meta>1280 × 3200 · 412 KB</p>
</div>
</div>
<divrst-media-tile>
<divrst-media-frame>
<imgsrc="/images/pricing.png"alt=""loading="lazy"decoding="async"width="1280"height="2400">
</div>
<divrst-media-caption>
<divrst-media-name>
<ahref="/images/2">Página de precios</a>
<detailsrst-row-menuname="rst-menus">
<summaryaria-label="Acciones para Página de precios">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><circlecx="12"cy="12"r="1"/><circlecx="12"cy="5"r="1"/><circlecx="12"cy="19"r="1"/></svg>
</summary>
<divrst-row-menu-panel>
<ahref="/images/2/edit">Editar</a>
<hr>
<aclass="rst-danger"href="/images/2/delete">Eliminar…</a>
</div>
</details>
</div>
<prst-media-desc="none">Sin descripción</p>
<prst-media-meta>1280 × 2400 · 318 KB</p>
</div>
</div>
<divrst-media-tile>
<divrst-media-frame="contain">
<imgsrc="/images/logo.svg"alt="Harbour"loading="lazy"decoding="async"width="240"height="240">
</div>
<divrst-media-caption>
<divrst-media-name>
<ahref="/images/3">Logotipo de Harbour</a>
<detailsrst-row-menuname="rst-menus">
<summaryaria-label="Acciones para Logotipo de Harbour">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><circlecx="12"cy="12"r="1"/><circlecx="12"cy="5"r="1"/><circlecx="12"cy="19"r="1"/></svg>
</summary>
<divrst-row-menu-panel>
<ahref="/images/3/edit">Editar</a>
<hr>
<aclass="rst-danger"href="/images/3/delete">Eliminar…</a>
</div>
</details>
</div>
<prst-media-desc>La marca sola, para fondos oscuros y claros.</p>
<prst-media-meta>240 × 240 · 3 KB</p>
</div>
</div>
<divrst-media-tile>
<divrst-media-frame="contain">
<imgsrc="/images/banner.png"alt=""loading="lazy"decoding="async"width="1200"height="200">
</div>
<divrst-media-caption>
<divrst-media-name>
<ahref="/images/4">Banner de primavera</a>
<detailsrst-row-menuname="rst-menus">
<summaryaria-label="Acciones para Banner de primavera">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><circlecx="12"cy="12"r="1"/><circlecx="12"cy="5"r="1"/><circlecx="12"cy="19"r="1"/></svg>
</summary>
<divrst-row-menu-panel>
<ahref="/images/4/edit">Editar</a>
<hr>
<aclass="rst-danger"href="/images/4/delete">Eliminar…</a>
</div>
</details>
</div>
<prst-media-desc>La franja de arriba de la tienda en marzo.</p>
<prst-media-meta>1200 × 200 · 64 KB</p>
</div>
</div>
</div>
Pon esto dentro de <div rst-list>.
{{template"media-grid"dict"Items" (list
(dict"Desc""El paso de pago, con el formulario de la tarjeta abierto.""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""Pago, paso 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 precios""Src""/images/pricing.png""Width" 1280)
(dict"Alt""Harbour""Desc""La marca sola, para fondos oscuros y 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""Logotipo de Harbour""Src""/images/logo.svg""Width" 240)
(dict"Desc""La franja de arriba de la tienda en marzo.""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))}}
Pon Fit en "contain" para un logotipo o un banner. Una captura mantiene el valor por defecto y muestra su parte superior. Un mosaico sin Desc dice "Sin descripción".
Modo de selección, un mosaico seleccionado
Pon esto dentro de <div rst-list>.
<divrst-media>
<divrst-media-tile>
<divrst-media-frame>
<imgsrc="/images/checkout.png"alt=""loading="lazy"decoding="async"width="1280"height="3200">
<labelrst-selbox>
<inputtype="checkbox"name="id"value="1"checkedaria-label="Seleccionar Pago, paso 2">
</label>
</div>
<divrst-media-caption>
<divrst-media-name>
<ahref="/images/1">Pago, paso 2</a>
<detailsrst-row-menuname="rst-menus">
<summaryaria-label="Acciones para Pago, paso 2">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><circlecx="12"cy="12"r="1"/><circlecx="12"cy="5"r="1"/><circlecx="12"cy="19"r="1"/></svg>
</summary>
<divrst-row-menu-panel>
<ahref="/images/1/edit">Editar</a>
<hr>
<aclass="rst-danger"href="/images/1/delete">Eliminar…</a>
</div>
</details>
</div>
<prst-media-desc>El paso de pago, con el formulario de la tarjeta abierto.</p>
<prst-media-meta>1280 × 3200 · 412 KB</p>
</div>
</div>
<divrst-media-tile>
<divrst-media-frame>
<imgsrc="/images/pricing.png"alt=""loading="lazy"decoding="async"width="1280"height="2400">
<labelrst-selbox>
<inputtype="checkbox"name="id"value="2"aria-label="Seleccionar Página de precios">
</label>
</div>
<divrst-media-caption>
<divrst-media-name>
<ahref="/images/2">Página de precios</a>
<detailsrst-row-menuname="rst-menus">
<summaryaria-label="Acciones para Página de precios">
<svgclass="icon"viewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"stroke-linecap="round"stroke-linejoin="round"aria-hidden="true"><circlecx="12"cy="12"r="1"/><circlecx="12"cy="5"r="1"/><circlecx="12"cy="19"r="1"/></svg>
</summary>
<divrst-row-menu-panel>
<ahref="/images/2/edit">Editar</a>
<hr>
<aclass="rst-danger"href="/images/2/delete">Eliminar…</a>
</div>
</details>
</div>
<prst-media-desc="none">Sin descripción</p>
<prst-media-meta>1280 × 2400 · 318 KB</p>
</div>
</div>
</div>
Pon esto dentro de <div rst-list>.
{{template"media-grid"dict"Items" (list
(dict"Desc""El paso de pago, con el formulario de la tarjeta abierto.""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""Pago, paso 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 precios""Select""2""Src""/images/pricing.png""Width" 1280))}}
Envuelve la cuadrícula y un bulk-bar en un mismo formulario. Cada casilla envía el valor Select de su mosaico con el nombre "id"; cambia SelectName para usar otro. Dentro del formulario, los elementos del menú deben ser enlaces.
pagination
Una tira numerada de enlaces normales, para que la paginación siga funcionando con JavaScript desactivado.
Sin Label, así que el nombre accesible del nav viene del catálogo.
empty-state
La tarjeta de estado vacío. Un estado vacío con vías para dar los primeros pasos.
Con una llamada a la acción por POST
<divrst-empty>
<h2rst-empty-title>Aún no hay nada aquí</h2>
<prst-empty-body>Aún no hay entradas. La primera es un buen punto de partida.</p>
<formrst-empty-ctamethod="post"action="/posts/seed">
<inputtype="hidden"name="csrf"value="tok-123">
<buttonrst-btn="primary"type="submit">Añadir entradas de ejemplo</button>
</form>
</div>
{{template"empty-state"dict"Body""Aún no hay entradas. La primera es un buen punto de partida.""Title""Aún no hay nada aquí""ActionLabel""Añadir entradas de ejemplo""PostAction""/posts/seed""Hidden" (list (list"csrf""tok-123"))}}
Solo la frase
<divrst-empty>
<prst-empty-body>Esta entrada aún no tiene comentarios.</p>
</div>
{{template"empty-state"dict"Body""Esta entrada aún no tiene comentarios."}}