Skip to content

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)

CancelSave

Last saved: —

Pattern notes:

  1. Typed columns own presentation (declare type for badges / dates / checkmarks), the form owns editing — each side uses the most suitable component
  2. Build form fields from the clicked row's data; validation rules are declared on the oas-form (shape { fieldName: [{ required, pattern, message, ... }] }, matched by field name) — the save button calls form.submit(), and on success the form emits oas-submit (detail.values is the full form value collected by name)
  3. Write-back is "read all → patch one row → setAttribute the whole thing" (the table's uncontrolled data channel, complementary to the inline-editing channel)
  4. 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:

ts
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.

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.

Released under the MIT OR Apache-2.0 License.