card-list
Template-based list rendering with safe data binding. Fetch or inline JSON, bind to templates, and render lists with grid, stack, or reel layouts.
Overview
The <card-list> component renders a list of items from JSON data using an HTML <template>. Data binding uses data-field attributes — only safe property paths are allowed, no expressions or method calls.
Supply data inline via data-items or fetch from a URL via src. Choose a layout with data-layout: grid, stack, or reel.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
src |
URL | — | URL to fetch JSON data from. Expects an array or an object with items or data property. |
data-items |
JSON string | — | Inline JSON array of items. Takes priority over src. |
data-key |
string | id |
Property name to use as the unique key for each item. |
data-layout |
string | block |
Layout mode: grid (auto-fit columns), stack (vertical), or reel (horizontal scroll). |
Binding Attributes
These go on elements inside the <template> to bind item data.
| Attribute | Description |
|---|---|
data-field="path" |
Set the element's text content from a property path (e.g. user.name). |
data-field-attr="href: url, title: name" |
Set one or more HTML attributes from property paths. Comma-separated pairs of attribute: path. |
data-field-html="path" |
Set innerHTML from a property path. Content is sanitized (scripts, iframes, and event handlers are stripped). |
data-field-if="path" |
Keep element only if the property value is truthy. Removed from DOM otherwise. |
data-field-unless="path" |
Keep element only if the property value is falsy. Removed from DOM otherwise. |
Data Sources
Inline Data
Pass a JSON array directly in the data-items attribute. Good for small, static datasets.
Remote Data
Set src to fetch JSON from a URL. The component shows a loading state while fetching and an error state on failure.
The response can be a plain array, or an object with an items or data property containing the array.
Nested Properties
Access nested data with dot notation. Array indices are also supported: items[0].title.
Attribute Binding
Use data-field-attr to set HTML attributes from item properties. Comma-separated pairs map attributes to property paths.
Conditional Rendering
Use data-field-if and data-field-unless to conditionally include or exclude elements based on item data. Elements are removed from the DOM, not hidden.
Rich HTML Content
Use data-field-html to render HTML content from a property. Content is sanitized — <script>, <iframe>, <object>, <embed>, <form>, event handlers, and javascript: URIs are all stripped.
Layout Modes
| Value | Display | Description |
|---|---|---|
grid |
CSS Grid | Auto-fit columns with minmax(280px, 1fr). Responsive by default. |
stack |
Flex column | Vertical stack with gap. |
reel |
Flex row | Horizontal scroll with snap points. |
States
| Attribute | When | Visual |
|---|---|---|
data-loading |
During src fetch |
Reduced opacity with "Loading..." message. |
data-error |
Fetch failure | Error message banner with the HTTP status. |
Events
| Event | Detail | Description |
|---|---|---|
card-list:rendered |
{ count: number } |
Fired after items are rendered. Bubbles. |
JavaScript API
| Method / Property | Description |
|---|---|
setItems(items) |
Replace the item list and re-render. |
getItems() |
Returns a shallow copy of the current items array. |
Security
All data-field paths are validated against a strict regex. Only simple property access is allowed:
- Allowed:
name,user.email,items[0].title - Rejected:
price.toFixed(2),`${price}`,price * 1.1,stock > 0 ? 'yes' : 'no'
Invalid paths log a console warning and resolve to empty content.
Progressive Enhancement
Without JavaScript, the <template> is hidden by default. Consider providing a <noscript> fallback or static content before the template for no-JS contexts.
Related
<layout-card>— Card visual shell for list items<layout-grid>— CSS grid layout primitive<layout-stack>— Vertical stack layout<layout-reel>— Horizontal scroll layout<data-table>— For tabular data display