Detent web components
By Shane Logsdon

Data & tables

Content Card

Implemented

Linkable card with media, tags and status

detent-content-card

Port status
Catalog status
implemented
Origin
native-only
Phase
6
Wave
native-only
Group
Data & tables
Docs

Example description: a short summary of what this sample entry would cover.

3.2 KB gzip for the class module

Variants

Example content: every label, status and tag on this page is sample data written for this preview — no catalog claims.

Components

Example description: the same card with no status, tags or media — the empty state.

Guides

Example description: the status tone tints the badge; the label always carries the meaning.

Tag chips come from the tags property (plain data, never an attribute), so this static preview has none — the usage example sets them.

Example anchor target. The card’s link is the page’s own anchor, so it behaves like one with and without JavaScript.

Recorded states

  • hover recorded state; no setter
  • focus-visible recorded state; no setter
  • empty recorded state; no setter

Usage

Import

import '/components/content-card/define.js';

// or register it yourself
import { DetentContentCard } from '/components/content-card/content-card.js';

Attributes

  • status
  • status-tone

Properties

  • status
  • statusTone
  • tags

Slots

  • link
  • media
  • default

Events

No events are recorded for this component.

Example

Runnable example: site/examples/content-card.ts. The snippet below is generated from the catalogued attributes.

<detent-content-card
  status=""
  status-tone="neutral"
></detent-content-card>

Property-only values

const element = document.querySelector('detent-content-card');
if (element !== null) {
  // tags: string[]
  element.tags = [];
}

Source

Native-only row: there is no upstream source. The native module lives at:

  • src/components/content-card/content-card.ts

Native files

The native module and its artifacts:

  • src/components/content-card/content-card.ts
  • src/components/content-card/styles.css
  • src/components/content-card/define.ts
  • docs/components/content-card.md
  • site/examples/content-card.ts
  • tests/browser/content-card.spec.ts
  • evidence/components/content-card.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
statusstatusstring''Kebab-case attribute; camelCase property.
status-tonestatusTone'neutral' | 'info' | 'success' | 'warning' | 'danger''neutral'Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
statusstring''Property-only: assign from script; not accepted as an attribute.
statusTone'neutral' | 'info' | 'success' | 'warning' | 'danger''neutral'Property-only: assign from script; not accepted as an attribute.
tagsstring[][]Property-only: assign from script; not accepted as an attribute.

Events

No custom events are recorded for this component.

Slots

Slots
SlotNotes
linkConsumer content; rendered through a slot, never re-created.
mediaConsumer content; rendered through a slot, never re-created.
defaultConsumer content; rendered through a slot, never re-created.

CSS customisation

  • Native-only row: no upstream source file, no upstream route (docs/migration/native-only.md).
  • The link lives in a required slot, so the card never wraps or moves consumer content and stays readable without JavaScript.
  • Status and tags are presentation only; nothing is inferred from the catalog at runtime.
  • tags is plain data: trimmed, de-duplicated and blank entries dropped; a non-array assignment resolves to [] and the tags attribute is ignored, never parsed.
  • The empty state is data-empty on part="card" when there is no status, no tags and no media; link, media and description stay consumer light-DOM nodes and are never moved, cloned or removed.
  • The focus ring is drawn on the slotted anchor with ::slotted(a:focus-visible); the card adds no tabindex, heading level or href of its own.
  • The page own <a> rules outrank the card ::slotted link styling, so the card never overrides a site link colour. The card hairline is decorative (1.49:1 light, 1.39:1 dark) and is not scored against WCAG 1.4.11, while the status tone indicator and the focus ring are.

What it does

A linkable summary card with a title link, a status badge, tag chips, an optional media area and a description.

Upstream behaviour
  • The slotted anchor is the only interactive element in the card
  • Status badge with a tone, rendered as text
  • Tag chips from plain data
  • Optional media slot above the body
  • Hover elevation plus a focus-visible ring on the link
  • Description arrives through the default slot as consumer content
  • Readable with JavaScript disabled as a plain link and text
Differences from upstream
  • Native-only row: no upstream source file, no upstream route (docs/migration/native-only.md).
  • The link lives in a required slot, so the card never wraps or moves consumer content and stays readable without JavaScript.
  • Status and tags are presentation only; nothing is inferred from the catalog at runtime.
  • tags is plain data: trimmed, de-duplicated and blank entries dropped; a non-array assignment resolves to [] and the tags attribute is ignored, never parsed.
  • The empty state is data-empty on part="card" when there is no status, no tags and no media; link, media and description stay consumer light-DOM nodes and are never moved, cloned or removed.
  • The focus ring is drawn on the slotted anchor with ::slotted(a:focus-visible); the card adds no tabindex, heading level or href of its own.
  • The page own <a> rules outrank the card ::slotted link styling, so the card never overrides a site link colour. The card hairline is decorative (1.49:1 light, 1.39:1 dark) and is not scored against WCAG 1.4.11, while the status tone indicator and the focus ring are.
Previous: Page Nav Next: Site Footer

Docs

Components

Project