Conversation
There was a problem hiding this comment.
Pull request overview
This PR refreshes the timeline audio clip UI by separating the clip into a dedicated header drag rail and a body surface, while improving selected-clip contrast and updating unit tests to cover the new affordances.
Changes:
- Introduce a semantic “presentation” layer for clip styling (header/body surfaces, waveform/text colors, selection ring/shadow).
- Split the clip surface into a header rail (move handle) and a body surface (waveform/content area), updating drag/hover behavior accordingly.
- Extend unit tests to assert the new header rail semantics and selected (ivory) body styling.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/components/timeline/ClipBlock.tsx |
Adds header rail + body surface, new styling model, and updated hover/drag cursor behavior. |
tests/unit/clipResizeAndFadeVisuals.test.tsx |
Adds coverage for header rail presence/ARIA label and ivory selected body background. |
tests/unit/clipBlockHover.test.tsx |
Adds coverage for header rail move affordance and updates color assertions to match new structure. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const deltaSec = dx / pixelsPerSecond; | ||
|
|
||
| if (mode === 'move') { | ||
| document.body.style.cursor = isShiftCopy ? 'copy' : 'grabbing'; |
There was a problem hiding this comment.
ClipBlock now sets document.body.style.cursor to values like grabbing, copy, and ew-resize during move/slip drags, but the unmount cleanup only clears crosshair (scissor) and col-resize. If the component unmounts mid-drag (e.g., track/clip removed or route change), the cursor can remain stuck globally. Extend the unmount cleanup (and/or centralize via the existing setResizeCursor helper) to also reset these additional cursor values when they were set by this component.
| document.body.style.cursor = isShiftCopy ? 'copy' : 'grabbing'; | |
| if (clipBlockRef.current) { | |
| clipBlockRef.current.style.cursor = isShiftCopy ? 'copy' : 'grabbing'; | |
| } |
- TypeScript type check: 0 errors - Unit tests: 2088 passed, 6 skipped - Build: success - Visual verification: header rail (20px), ivory selected body, dark waveform contrast all working correctly https://claude.ai/code/session_01EUjL9y1SBjw9LRQrFEzysE
Summary
Linked Issues
Verification
npx vitest run tests/unit/clipBlockHover.test.tsx tests/unit/clipResizeAndFadeVisuals.test.tsx tests/unit/clipResizeModifiers.test.tsx tests/unit/clipScissorMode.test.tsx tests/unit/clipWaveform.test.tsxnpx tsc --noEmitnpm run buildNotes
This PR is the first half of the clip selection UX refresh. Range slicing will land in a follow-up PR.