fix(studio): only expose front trim for offsettable clips#413
Merged
miguel-heygen merged 5 commits intomainfrom Apr 22, 2026
Merged
fix(studio): only expose front trim for offsettable clips#413miguel-heygen merged 5 commits intomainfrom
miguel-heygen merged 5 commits intomainfrom
Conversation
jrusso1020
approved these changes
Apr 22, 2026
Collaborator
jrusso1020
left a comment
There was a problem hiding this comment.
LGTM — clean, well-scoped fix with good defense-in-depth.
What I checked
- Predicate (
timelineEditing.tscanOffsetTrimClipStart): logic is correct.playbackStart != nullproperly allowsplaybackStart === 0,sourceDuration > 0rejects zero-length sources, andtag.toLowerCase()is safely defensive. - Preview vs. source consistency:
getPreviewElementonly overridesstart/duration/playbackStart, preservingtag/playbackStartAttr/sourceDuration— so the UI check inTimelineClip(onpreviewElement) and the handler guard inTimeline.tsx(onel) will always agree. - Defense in depth: hiding the handle visually and early-returning from
onResizeStartis the right call — either one alone would be brittle. - Test rename of
buildTrackZIndexMapfrom "maps sorted tracks onto stable positive z-index values" → "maps higher track numbers onto higher z-index values" is a real improvement: describes the invariant instead of the mechanism.
Minor, non-blocking
- Consider a one-line comment at the handler guard so a future refactor doesn't delete it as "redundant":
// Defense in depth: the handle is also hidden in TimelineClip when this is false. if (edge === "start" && !canOffsetTrimClipStart(el)) return;
- No integration test for the handler guard — the predicate unit tests + browser verification are probably sufficient for a visual-affordance change, but a cheap
Timeline.test.tscase asserting the early-return for asectionclip would be belt-and-suspenders.
Nice browser verification artifact too. Ship it.
Collaborator
Author
Merge activity
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why This Is Needed
Generic GSAP/DOM timeline clips do not have a playback-offset model like media clips do.
That means a left trim affordance on those clips is misleading today:
Instead of exposing a control that implies unsupported behavior, this PR keeps true front trim only on clips that can actually offset their content.
The PR also fixes the stacking convention so the timeline matches normal editor expectations:
Current Flow By Element Type
Generic motion / DOM clips
Examples:
section,div,aside, GSAP-driven cards and overlays.Current supported flow:
data-startdata-track-indexNot supported yet:
Behavior after this PR:
Media clips
Examples:
video/audioclips, or wrappers carryingdata-media-start/data-playback-start.Current supported flow:
data-startdata-durationBehavior after this PR:
data-startplusdata-media-start/data-playback-startdata-durationZ-Index Rule
This PR now follows the normal timeline-editor convention:
z-indexz-indexConcretely, because Studio renders tracks in ascending numeric order from top to bottom, lower numeric track values now map to higher
z-indexvalues.Validation
Automated
bun test packages/studio/src/player/components/timelineEditing.test.ts packages/studio/src/player/components/Timeline.test.ts packages/studio/src/player/store/playerStore.test.ts packages/studio/src/utils/sourcePatcher.test.tsbun run --filter @hyperframes/studio typecheckBrowser verification
Verified with
agent-browserontimeline-edit-playground:media-cardpersisteddata-startanddata-media-startmedia-cardpersisteddata-durationonlytitle-cardfrom the bottom row to the top row persisted the highestz-indexfor the top-row clips/tmp/trim-fix-artifacts/trim-flow.webm/tmp/trim-fix-artifacts/z-index-flow.webm