Vanilla Breeze

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