HabListRow
One standalone row in a list of things you can open — recent activity, search results, entity lists. The whole row is the target.
<HabListRow
:icon="mdiInboxOutline"
title="Evening briefing"
meta="Session · Ada Lovelace"
when="12m"
chevron
interactive
>
<template #flag>
<HabBadge tone="success">Live</HabBadge>
</template>
</HabListRow>Which row
Four things in this system are a row, and they look similar in a screenshot. The question that separates them is what the user does with it:
| Component | The row is… |
|---|---|
HabListRow | a thing you open — bordered, spaced apart |
HabListItem | a thing you operate — on a shared surface |
HabDataTable | a record whose fields line up in columns |
HabCard | a thing whose left border classifies it |
If the row navigates away it is a HabListRow. If it changes something in place, or is one of a set being managed, it is a HabListItem.
Keep the chevron
It is the only thing distinguishing a row that opens from a row that merely holds controls — so the component warns when a row is interactive without one.
It is a warning rather than a forced chevron because a row whose trailing edge already carries a flag may deliberately skip it. But that is a decision, not a default.
Anatomy
The leading tile is a HabIconTile, carrying the entity hue — what kind of thing this is, not decoration. Swap the leading slot for a HabAvatar when the row is about a person: a tile says what, an avatar says who.
when is rendered tabular, so a column of timestamps lines up down the page rather than jittering.
Static, button or link
A row with href stays an anchor; a row that is only interactive becomes a real <button>; a row with neither is a plain div with no hover at all. Same rule as HabButton: a link that looks like a row must still be a link, because middle-click, copy-link and open-in-new-tab are the browser's to provide.
Saving
<HabListRow :saving="saving" … />A write against one row reports itself on the row — this is where it belongs, not on the panel around the list. The wave goes on the row itself, the button or link, and marks it aria-busy.
blocking is off by default, unlike every other host. A row's writes are small and frequent, and locking it for each one feels heavy; the wave alone says the write is in flight. Turn it on when acting on the row again mid-write would race — and note an inert row drops focus if it had it. The wave is the same one HabSavingFrame draws; its page has the rules.
Accessibility
titlenames the row. The component warns when there is neither a title nor content in the default slot, because the row is then an unnamed target.- A disabled button is disabled natively; a disabled link takes
aria-disabled, sincedisabledmeans nothing on an anchor. - The leading tile is decorative and hidden from assistive tech — it repeats what
metaalready says in words.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
blocking | boolean | false | Whether a saving wave also swallows input: a veil washes the row out and it goes inert. OFF by default, unlike every other host. A row's write is small and frequent, and locking it for every one feels heavy; the wave alone says the write is in flight. Turn it on when acting on the row again mid-write would race. Note an inert row drops focus if it had it — move focus deliberately first. |
chevron | boolean | false | Trailing chevron. Keep it when the row navigates — it is the only thing distinguishing a row that opens from a row that merely holds controls. |
disabled | boolean | false | — |
href | string | undefined | Renders as an anchor to this href instead of a button. |
icon | string | undefined | SVG path data from @mdi/js, for the leading tile. |
iconColor | string | undefined | The tile's hue — the entity color, not decoration. Any CSS color, including one from data. |
interactive | boolean | false | Makes the whole row the hit target, rendering it as a real <button>. Omit for a static row. |
meta | string | undefined | Second line: kind, who touched it, when. |
saving | boolean | false | A write against this row's thing is in flight: a wave sweeps the row and it is marked aria-busy. This is the "a row reports itself on the row" case — a write against one row belongs here, not on the panel around the list. |
title | string | undefined | The thing's name. The row's own accessible name when it navigates. |
when | string | undefined | Short tabular timestamp, e.g. 12m. |
Slots
| Slot | Bindings | Description |
|---|---|---|
default | any | Body, in place of title and meta. |
flag | any | Right-aligned state pill, usually a HabBadge. |
leading | any | Replaces the leading tile — pass a HabAvatar when the row is about a person. |