SectionLane
StableA song's structure as labelled sections on a timeline: select, regenerate one, extend after it or move it, with staged edits and out-of-date sections in amber words.
Also known as song sections, arrangement lane, track lane
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Edit a song
Harbour Light
2:04 (2 minutes 4 seconds) · 6 sections
Arrow keys move between sections, Enter selects one, Alt with an arrow moves it.
Chorus · 0:40 to 1:02
AIUp to dateHold the harbour light Till the boats come home
Style: full band, harmonies
<SectionLane title="Harbour Light" sections={sections} duration={124} peaks={peaks}
position={position} onSeek={setPosition}
selectedId={selected} onSelect={setSelected}
onReorder={reorder} onRegenerate={stageRegenerate} onExtend={addAfter}
onOpenAlternates={openTakes}
pendingChanges={pending} generateCost="about 20 credits" onGenerate={generate} />
const sections = [
{ id: "intro", name: "Intro", start: 0, end: 12, origin: "ai", state: "original" },
{ id: "v1", name: "Verse 1", start: 12, end: 40, origin: "ai", state: "original", lyrics: "Lanterns on the water line…" },
{ id: "ch1", name: "Chorus", start: 40, end: 62, origin: "ai", state: "original" },
{ id: "v2", name: "Verse 2", start: 62, end: 88, origin: "person", state: "original" },
…
];Select a section, then Regenerate, Extend after or move it. Each edit adds to the amber bar and the section after a changed one goes out of date. Generate makes them all at once; the sections then show new takes to compare.
When to use it
Lets a person fix one part of a generated song without regenerating the whole thing, and see which parts the AI made and which need them.
Made of: Title, length, section count and how many are out of date · Staged changes bar (count, cost, Generate) · Whole-song waveform (optional) · Section blocks (name, time, origin, state) · Selected section panel (lyrics, style, actions, move buttons)
Use it for
- Under an AudioPlayer for a kept song in a music studio.
- Replacing or extending one section and generating several edits at once.
- Showing mixed authorship: which sections the AI made and which were recorded or uploaded.
Not for
- Ordering video shots: use SceneStrip.
- Picking between whole takes: use TakePicker.
- Playing one clip: use AudioPlayer.
Do and avoid
Harbour Light
1:02 (1 minute 2 seconds) · 3 sections
Arrow keys move between sections, Enter selects one, Alt with an arrow moves it.
Chorus · 0:40 to 1:02
AIUp to dateHarbour Light
Not happy with the chorus?
Do
- Stage edits and generate them together, with the cost beside Generate.
- Say why a section is out of date, in its note.
- Mark which sections the AI made and which a person recorded or uploaded.
Avoid
- Do not regenerate the whole song for a local fix without saying so.
- Do not use amber for generating sections. Amber is only for edits, out-of-date sections and takes a person must pick.
- Do not use lime for the playhead or the played part. Lime marks AI-made sections and Generate only.
- Do not autoplay new takes when they arrive.
On a phone
- The lane scrolls sideways inside its card; the page does not. Each block is at least 7rem wide.
- Blocks and buttons grow to 44px tall on touch screens, and moving uses buttons, never a drag.
- The keyboard hint is hidden on small screens.
Seen in products
- Suno's Song Editor shows a song as named sections that can be added, removed, reordered, cropped and replaced, then Committed or Regenerated.
- Suno says replacing a section creates a new whole song including the updated section.
- ElevenLabs Music stages several section edits and generates them together.
- ElevenLabs Dubbing marks audio that no longer matches as stale and offers Generate Stale Audio.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| sectionsrequired | SongSection[] | none | Sections in play order: id, name, start, end, origin (ai | person | upload), state, lyrics, styles, alternates, note. |
| durationrequired | number | none | Length of the whole song in seconds. |
| peaks | number[] | null | none | Loudness for the whole-song waveform above the lane. Leave out to hide it; null shows it drawing. |
| position | number | 0 | Playhead in seconds. |
| onSeek | (seconds: number) => void | none | Makes the waveform a seek slider. |
| selectedId | string | null | null | The selected section. |
| onSelect | (id: string | null) => void | none | Called on click, Enter or Space; Escape clears it. |
| onReorder | (ids: string[]) => void | none | New order after Move earlier, Move later or Alt with an arrow key. Leave out to hide moving. |
| onRegenerate | (id: string) => void | none | Stages a new take of one section. |
| onExtend | (id: string) => void | none | Adds a new section after this one. |
| onEdit | (id: string) => void | none | Opens the section's lyrics and style for editing. |
| onOpenAlternates | (id: string) => void | none | Opens the new takes of a section in the has-alternates state. |
| onRetry | (id: string) => void | none | Tries a failed section again. |
| pendingChanges | number | 0 | Staged edits. Above 0 the amber bar shows the count and Generate. |
| onGenerate | () => void | none | Generates every staged change at once. |
| generateCost | string | none | Cost next to Generate, such as "about 20 credits". |
| generateBlocked | string | none | Why Generate cannot run. Turns it off and shows the reason. |
| title | string | "Song structure" | Heading, usually the song name. |
| headingLevel | 2 | 3 | 4 | 5 | 6 | 3 | Level of the heading. |
| className | string | none | Extra classes. |
"Show code under the preview gives the code for the example on the stage."
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- up to date
- A section as it was made or recorded, labelled AI, Recorded or Uploaded.
- edited, not generated
- Changed by the person but not made again yet: amber, in words, because a person has to press Generate.
- out of date
- A section an edit nearby has made stale: amber with Out of date and a dashed border.
- generating
- The lime working ring and the word Generating, because the AI is making it. Still under reduced motion.
- takes to compare
- New takes are ready for this section: amber, N takes to compare.
- did not work
- An alert icon, Try again and whether it was charged.
- changes staged
- One amber bar counts the changes waiting, with the cost and a Generate button.
Tokens
Change one of these and every part that uses it follows.
--surface--surface-sunken--border--fg--fg-muted--lime--attention--attention-soft--attention-fg--radius-card--radius-control--dur-fast--ease-out
Built in
- The sections are a horizontal listbox. Left and Right (or Up and Down) move between them, Home and End go to the ends, Enter or Space selects, and Escape clears the selection. Only one section is in the Tab order.
- Each section is named with its position, time, origin and state, for example "Chorus, 3 of 6, 0:40 to 1:02, Made by AI, Out of date".
- Alt with an arrow key moves the focused section and keeps focus on it. The selected section also has Move earlier and Move later buttons; at the ends they turn off and focus moves to the other one.
- State is always written in words with a mark: amber diamonds for edited, out of date and takes to compare; an alert icon for did not work; the working ring and the word Generating while it is made. The selected block has a check mark and a thicker ink border, and is read as selected.
- One polite status line says moves, the staged count when it changes, and when sections finish, fail or get new takes. It does not repeat progress.
- Under reduced motion the working ring stops and stays as a still outline next to the word Generating.
- The waveform is a seek slider with the time in words when onSeek is set.
What you need to do
- Keep the order, edits and staged count saved, so nothing is lost if the person leaves before Generate.
- Pass generateCost so the price sits next to the button, and generateBlocked when the person cannot afford it.
- Make each new generation a new version of the whole song (for example with VersionHistory), and keep takes that were not chosen.
- Offer the lyrics as text next to the song for people who cannot hear it.
- Set note on a failed section to say whether it was charged, and on an out-of-date one to say why.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide