From c175ea774da9625ed3beac5f1fc59cd078757fac Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 3 Oct 2026 13:33:00 -0700 Subject: [PATCH] feat(studio): resize every timeline layer at once from the toolbar or a layer's bottom edge --- .../studio/src/components/TimelineToolbar.tsx | 27 ++++++++-- .../src/hooks/useRenderClipContent.test.ts | 11 +++- .../studio/src/hooks/useRenderClipContent.ts | 5 +- packages/studio/src/index.ts | 2 +- .../player/components/LayerDisclosureRow.tsx | 5 +- .../components/TimelineAutomationLaneSlot.tsx | 5 +- .../src/player/components/TimelineCanvas.tsx | 15 +++--- .../player/components/TimelineGroupHeader.tsx | 5 +- .../player/components/TimelineGroupRow.tsx | 9 ++-- .../src/player/components/TimelineLanes.tsx | 7 +-- .../components/TimelinePropertyLanes.tsx | 6 ++- .../player/components/TimelineTrackHeader.tsx | 18 ++++--- .../components/TrackHeightGrip.test.tsx | 51 +++++++++++++++++++ .../src/player/components/TrackHeightGrip.tsx | 43 ++++++++++++++++ .../components/timelineClipDragPreview.ts | 5 +- .../player/components/timelineLayout.test.ts | 21 ++++++++ .../src/player/components/timelineLayout.ts | 44 +++++++++++----- .../src/player/components/timelineMarquee.ts | 4 +- .../components/trackHeaderLabelRows.tsx | 7 +-- .../components/useTimelineKeyboardActor.ts | 6 +-- .../components/useTimelineTrackLayout.ts | 28 ++++++---- .../src/player/store/playerStore.test.ts | 16 ++++++ .../studio/src/player/store/playerStore.ts | 6 +++ 23 files changed, 280 insertions(+), 66 deletions(-) create mode 100644 packages/studio/src/player/components/TrackHeightGrip.test.tsx create mode 100644 packages/studio/src/player/components/TrackHeightGrip.tsx diff --git a/packages/studio/src/components/TimelineToolbar.tsx b/packages/studio/src/components/TimelineToolbar.tsx index dfa9dbe937..f7632dbfa2 100644 --- a/packages/studio/src/components/TimelineToolbar.tsx +++ b/packages/studio/src/components/TimelineToolbar.tsx @@ -5,6 +5,7 @@ import { Magnet, MagnifyingGlassMinus, MagnifyingGlassPlus, + Rows, } from "@phosphor-icons/react"; import { useEnableKeyframes, @@ -20,6 +21,7 @@ import { timelineSliderToZoomPercent, } from "../player/components/timelineZoom"; import { useTimelineZoom } from "../player/components/useTimelineZoom"; +import { TRACK_H_MAX, TRACK_H_MIN } from "../player/components/timelineLayout"; import { usePlayerStore, type TimelineElement } from "../player"; import { Tooltip } from "./ui"; import { AudioMetersIcon } from "./icons/AudioMetersIcon"; @@ -41,6 +43,10 @@ interface DomEditSessionSlice extends EnableKeyframesSession { selectedGsapAnimations: GsapAnimation[]; } +// h-6 on a range input is the 24x24 WCAG 2.2 (2.5.8) target: the visible track stays 2px and the thumb 10px. +const RANGE_INPUT_CLASS = + "cursor-pointer appearance-none bg-transparent [&::-webkit-slider-runnable-track]:h-[2px] [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-neutral-700 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-[10px] [&::-webkit-slider-thumb]:h-[10px] [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-text-0 [&::-webkit-slider-thumb]:-mt-1 [&::-webkit-slider-thumb]:shadow-[0_0_0_2px_#0a0a0a,0_1px_3px_rgba(0,0,0,0.5)] [&::-webkit-slider-thumb]:cursor-grab [&::-webkit-slider-thumb:active]:cursor-grabbing"; + export interface TimelineToolbarProps { domEditSession?: DomEditSessionSlice; onSplitElement?: (element: TimelineElement, splitTime: number) => void; @@ -159,6 +165,8 @@ export const TimelineToolbar = memo(function TimelineToolbar({ const thumbnailMode = usePlayerStore((s) => s.thumbnailMode); const setThumbnailMode = usePlayerStore((s) => s.setThumbnailMode); const thumbnailsVisible = thumbnailMode === "adaptive"; + const trackHeight = usePlayerStore((s) => s.trackHeight); + const setTrackHeight = usePlayerStore((s) => s.setTrackHeight); const audioMetersVisible = useAudioMetersVisible((s) => s.visible); const setAudioMetersVisible = useAudioMetersVisible((s) => s.setVisible); const projectHasAudio = useProjectHasAudio(); @@ -485,6 +493,21 @@ export const TimelineToolbar = memo(function TimelineToolbar({ + + + +