Scenarios
Copy-ready composition patterns: each recipe shows how multiple components form a real business shape.
Spreadsheet-style Record Editing Form
Scenario: oas-table displays structured records with typed columns (badges / progress / dates / checkmarks); clicking a row opens an oas-form editing dialog, and validated submissions write back into the table — a complete "browse in table → edit in form" loop.
Click a row to open the editing form (validation + write-back)
Last saved: —
Pattern notes:
- Typed columns own presentation (declare
typefor badges / dates / checkmarks), the form owns editing — each side uses the most suitable component - Build form fields from the clicked row's data; validation rules are declared on the
oas-form(shape{ fieldName: [{ required, pattern, message, ... }] }, matched by fieldname) — the save button callsform.submit(), and on success the form emitsoas-submit(detail.valuesis the full form value collected byname) - Write-back is "read all → patch one row → setAttribute the whole thing" (the table's uncontrolled data channel, complementary to the inline-editing channel)
- For quick single-cell edits use
editable+editComponent(see the Table page); for multi-field row editing use this form recipe
Kanban-driven Task Flow
oas-kanban's oas-change event is the data-change protocol — map from/to/index to your backend state transitions:
const laneField = 'state' // swimlane field (replace with your actual field name)
document.querySelector('oas-kanban').addEventListener('oas-change', async (e) => {
const { id, from, to, index, ids, swimlane } = e.detail
await api.moveCards({
cardIds: ids ?? [id], // ids is an array on multi-select batch moves
toColumn: to,
toIndex: index,
...(swimlane ? { [laneField]: swimlane.to } : {}),
})
})WIP limits are advisory (the data-over-limit marker); hard blocking is the host's choice, enforced after the event.
Gallery View (Cards Grouped by Field)
Scenario: the "gallery" form of a spreadsheet — records are shown as rich card stacks grouped by a field value instead of rows. Compose it with oas-card + grouping; no dedicated component needed.
Product gallery grouped by category
Pattern notes: the group key drives columns (new Set(records.map(r => r.cat))), and each card is a rich record view (oas-card + oas-tag status badge). The gallery is essentially "group + cards" — the badge/format semantics stay aligned with the table's type column (price/stock/status share one dataset).
Calendar View (Records Laid Out by Date)
Scenario: the "calendar" form — lay records into calendar day cells by a date field. oas-calendar's oas-cell-render event is the channel (fired for every day cell; the host appends content).
Release schedule calendar (event dots + hover details)
Pattern notes: oas-cell-render's detail.element is the day-cell container — append .cell-dot (the built-in dot style) and set element.title for hover details; index events by the date field — note that detail.date is a Date object (from parseISODate): format it to an ISO key (YYYY-MM-DD) before comparing with your event data (a direct ev.date === detail.date comparison always fails on type mismatch). With one shared dataset, table / gallery / calendar become three projections of the same records.