sdxc

Type to search, or start from one of these:

GridList

An interactive row list built from plain, already-ordered markup.

0 selected
Today
Marta RuizQ3 invoice is readyAttached, due the 30th.
Deploy botapi-gateway deployed to production12 commits, 4 minutes.
Earlier this week
Tomás OliveiraRe: onboarding copyTwo notes on the second screen.
SecurityNew sign-in from LisbonChrome on macOS, 14:02.
View code
let model = new SelectionModel({ keys: THREADS.map((thread) => thread.id) });

// ref() fires on insert, so the subscription is set up in the browser and torn
// down with the node — the server renders the list without one.
let followSelection = ref((_node, signal) => {
	model.addEventListener("change", () => void handle.update(), { signal });
});

<div mix={[followSelection]}>
	<div mix={[hstack({ gap: 2, align: "center" })]}>
		<Button variant="outline" color="neutral" size="sm" disabled={model.isEmpty}>
			<ArchiveIcon />
			Archive
		</Button>
		<Button variant="outline" color="danger" size="sm" disabled={model.isEmpty}>
			<Trash2Icon />
			Delete
		</Button>
		<Badge color="neutral">{model.size} selected</Badge>
	</div>

	<GridList aria-label="Inbox" mix={[gridListKeys(model)]}>
		{SECTIONS.map((section) => (
			<GridList.Section key={section} aria-labelledby={`inbox-${section}`}>
				<GridList.Header id={`inbox-${section}`}>{section}</GridList.Header>
				{THREADS.filter((thread) => thread.section === section).map((thread) => (
					<GridList.Item key={thread.id} id={thread.id}>
						<MailIcon aria-hidden="true" />
						<span mix={[is("7rem"), shrink(), truncate()]}>{thread.from}</span>
						<span mix={[basis(0), grow(), truncate()]}>{thread.subject}</span>
						<span mix={[basis(0), grow(), truncate()]}>{thread.preview}</span>
					</GridList.Item>
				))}
			</GridList.Section>
		))}
	</GridList>
</div>

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

npm add @sdxc/ui
import "@sdxc/ui/theme.css";

Usage

import { GridList } from "@sdxc/ui";

Renders the list's root host as a bordered <div> with role="grid", keeping its row-list layer in an inner wrapper since a @container query can't resolve against the host that declares it; reach parts.list to adjust it.

Composition

The parts the component publishes, each a static property of the host.

  • GridList
  • GridList.ItemRenders a single row: a <div> carrying role="row", its id mirrored onto a data-rmx-key attribute so a paired selection, keyboard-navigation, or reorder behavior can correlate the row with its own state.
  • GridList.SectionRenders a titled group of rows: a <div> carrying role="rowgroup", stacking an optional GridList.Header above its GridList.Item rows, with a block-start rule before every section but the first.
  • GridList.HeaderRenders a section's label: a <header> styled as small, muted, uppercase text for the GridList.Item rows nested beneath it in a GridList.Section; point the section's aria-labelledby at its id.
  • GridList.DragHandleRenders the drag-grab element of a row: a native <button type="button"> written before the consumer's own attributes, so a command/commandfor pair still runs inside a <form> — a type seen only after them is ignored.

Examples

<GridList aria-label={t("gallery.title")} layout="grid">
	<GridList.Item id="photo-1">{t("gallery.photo", { name: "Sunset" })}</GridList.Item>
	<GridList.Item id="photo-2">{t("gallery.photo", { name: "Harbor" })}</GridList.Item>
</GridList>

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

PropTypeDescription
layout?"stack" | "grid"Row arrangement. Defaults to DEFAULT_LAYOUT.
childrenRemixNodeGridList.Item, GridList.Section, and GridList.LoadMoreItem rows to render.
parts?PartsPropsPer-part styling for the list's internal row-list wrapper.

Also accepts everything in TagProps<"div">.

GridList.Item

PropTypeDescription
idstringStable identifier for this row, mirrored onto both the rendered element's own id and a data-rmx-key attribute, so the row is already correlation-ready for a paired behavior once one is attached.

Also accepts everything in TagProps<"div">.

GridList.Section

PropTypeDescription
childrenRemixNodeThe section's optional GridList.Header label, followed by its GridList.Item rows.

Also accepts everything in TagProps<"div">.

GridList.Header

Also accepts everything in TagProps<"header">.

GridList.DragHandle

PropTypeDescription
"aria-label"stringAccessible name for the icon-only control, e.g. "Reorder" or "Drag to reorder".

Also accepts everything in Omit<TagProps<"button">, "type" | "children">.

Types

NameValuesWhat it decides
Layout"stack" | "grid"Arrangement of GridList.Item rows: "stack" renders them as a single column, "grid" wraps them into a multi-column layout growing from two columns up to four as the list's own container widens.