KQ-1743 · SERIES/EDIT

Series Edit

A recurring meeting's editor whose strip of upcoming occurrences always shows what Save would do. Choosing This and following cleaves the row at the chosen date: a gap opens before it and the chips after it reflow on springs.glide while a dashed rule draws down the gap on springs.flick, then the chips in scope slide to the new time — later dropping, earlier rising — each a cascade step after the one before, their times rolling on springs.snap, while earlier chips stay put; a one-off save stamps its mark in on springs.recoil. The strip is a horizontal listbox whose arrow keys move the edit (and the cleave) to another date, the scope is a radio group, and clashes with other events are listed before saving.

KQ-1743 · SERIES/EDIT

Gaugeworks weekly review

Weekly on Thursday · 10:00–10:45 · Ops room 2

Arrow keys choose another date to edit; Home and End jump to the first and last.

Upcoming

Thu 22 Oct10:00
Thu 29 Oct10:00
Thu 5 Nov14:00
Thu 12 Nov11:00
Thu 19 Nov10:00
Thu 26 Nov—
Thu 3 Dec10:00
Thu 10 Dec10:00

Thu 12 Nov · the day

11:00–11:45 · nothing else on

Apply to

Moves Thu 12 Nov to 11:00–11:45 · a one-off

editing thu 12 nov · this meeting

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/series-edit

Props

chipStyle
"tile" | "pill" | "stub"
default "tile"
How each occurrence chip is drawn: a two-line tile, a one-line pill, or a calendar stub with a month band.
density
"compact" | "regular" | "roomy"
default "regular"
Chip size, gaps, padding and field height.
accent
"cobalt" | "moss" | "plum" | "ember"
default "cobalt"
The colour of the edit — chips in scope, the cleave, the day lane and Save — as pigments at a fixed lightness.
series
SeriesInfo
default defaultSeries
The recurring meeting: { id, title, weekday (0 is Monday), start, duration, room }.
occurrences / defaultOccurrences
SeriesOccurrence[]
default — / defaultSeriesOccurrences
Each { id, date, start?, duration?, room?, exception?: "moved" | "cancelled", split? }; controlled or initial.
onOccurrencesChange
(occurrences) => void
default —
Fires from Save with every occurrence.
busy
SeriesBusy[]
default defaultSeriesBusy
Other events ({ id, title, date, start, end }) checked for clashes before saving.
rooms
string[]
default defaultSeriesRooms
Rooms offered by the Room field.
now
number
default defaultSeriesNow
The current time in ms; occurrences before today are not shown. Never read from the clock.
anchor / defaultAnchor
string
default — / the first upcoming meeting
The occurrence being edited, by id; controlled or initial.
onAnchorChange
(id) => void
default —
Fires from the press or arrow key that chose another occurrence.
scope / defaultScope
"one" | "following" | "all"
default — / "one"
Which meetings the edit applies to; controlled or initial.
onScopeChange
(scope) => void
default —
Fires from the press or key that changed the scope.
defaultChanges
Partial<SeriesChanges>
default —
Pre-fills the form ({ start, duration, room }) on top of the anchor's own values.
onEditOne
(occurrence, changes) => void
default —
Save with scope "one": the occurrence, now a one-off, and its new values.
onEditFollowing
(occurrence, changes) => void
default —
Save with scope "following": the first occurrence of the new series and its values.
onEditAll
(changes) => void
default —
Save with scope "all": the series' new values. One-off changes keep their own.
onDiscard
() => void
default —
Discard was pressed: the form went back to the anchor's values.
status
"ready" | "loading" | "error"
default "ready"
Loading shows placeholder chips and fields; error explains and offers Try again.
onRetry
() => void
default —
Try again was pressed after the series failed to load.
height
number
default 540
Height of the surface in px; the body scrolls inside it.
disabled
boolean
default false
Read only: nothing can be chosen, changed or saved.
className
string
default —
Classes for the surface.