@@ -4,6 +4,26 @@ import { useTimelineClips, useClipVisibilityState } from "../lib/timeline"
44export const ClipVisibilityPanel = ( ) => {
55 const clips = useTimelineClips ( )
66 const { hiddenMap, setClipVisibility } = useClipVisibilityState ( )
7+ const scrollbarStyles = `
8+ .fs-scroll {
9+ scrollbar-color: #334155 #0f172a;
10+ }
11+ .fs-scroll::-webkit-scrollbar {
12+ width: 8px;
13+ }
14+ .fs-scroll::-webkit-scrollbar-track {
15+ background: #0f172a;
16+ border-radius: 999px;
17+ }
18+ .fs-scroll::-webkit-scrollbar-thumb {
19+ background: linear-gradient(180deg, #1f2937, #334155);
20+ border-radius: 999px;
21+ border: 2px solid #0f172a;
22+ }
23+ .fs-scroll::-webkit-scrollbar-thumb:hover {
24+ background: linear-gradient(180deg, #2b384c, #4b5563);
25+ }
26+ `
727
828 const sorted = useMemo (
929 ( ) => [ ...clips ] . sort ( ( a , b ) => a . start - b . start || a . end - b . end ) ,
@@ -43,41 +63,56 @@ export const ClipVisibilityPanel = () => {
4363 flexDirection : "column" ,
4464 gap : 8 ,
4565 boxSizing : "border-box" ,
66+ minHeight : 0 ,
4667 } }
4768 >
69+ < style > { scrollbarStyles } </ style >
4870 < div style = { { fontWeight : 600 , fontSize : 13 , color : "#cbd5e1" } } > Clips</ div >
49- { sorted . map ( ( clip , idx ) => {
50- const isVisible = isClipVisible ( clip . id )
51- const label = clip . label ?? `Clip ${ idx + 1 } `
52- return (
53- < label
54- key = { clip . id }
55- style = { {
56- display : "flex" ,
57- alignItems : "center" ,
58- gap : 8 ,
59- width : "100%" ,
60- padding : "8px 10px" ,
61- borderRadius : 8 ,
62- border : "1px solid #1f2a3c" ,
63- background : isVisible ? "linear-gradient(90deg, #1f2937, #111827)" : "#0f172a" ,
64- color : isVisible ? "#e5e7eb" : "#94a3b8" ,
65- cursor : "pointer" ,
66- textAlign : "left" ,
67- userSelect : "none" ,
68- boxSizing : "border-box" ,
69- } }
70- >
71- < input
72- type = "checkbox"
73- checked = { isVisible }
74- onChange = { ( e ) => setClipVisibility ( clip . id , e . target . checked ) }
75- style = { { accentColor : "#5bd5ff" , width : 14 , height : 14 , cursor : "pointer" } }
76- />
77- < span style = { { flex : "1 1 auto" , whiteSpace : "nowrap" , overflow : "hidden" , textOverflow : "ellipsis" } } > { label } </ span >
78- </ label >
79- )
80- } ) }
71+ < div
72+ className = "fs-scroll"
73+ style = { {
74+ flex : "1 1 auto" ,
75+ minHeight : 0 ,
76+ overflow : "auto" ,
77+ paddingRight : 2 ,
78+ display : "flex" ,
79+ flexDirection : "column" ,
80+ gap : 8 ,
81+ } }
82+ >
83+ { sorted . map ( ( clip , idx ) => {
84+ const isVisible = isClipVisible ( clip . id )
85+ const label = clip . label ?? `Clip ${ idx + 1 } `
86+ return (
87+ < label
88+ key = { clip . id }
89+ style = { {
90+ display : "flex" ,
91+ alignItems : "center" ,
92+ gap : 8 ,
93+ width : "100%" ,
94+ padding : "8px 10px" ,
95+ borderRadius : 8 ,
96+ border : "1px solid #1f2a3c" ,
97+ background : isVisible ? "linear-gradient(90deg, #1f2937, #111827)" : "#0f172a" ,
98+ color : isVisible ? "#e5e7eb" : "#94a3b8" ,
99+ cursor : "pointer" ,
100+ textAlign : "left" ,
101+ userSelect : "none" ,
102+ boxSizing : "border-box" ,
103+ } }
104+ >
105+ < input
106+ type = "checkbox"
107+ checked = { isVisible }
108+ onChange = { ( e ) => setClipVisibility ( clip . id , e . target . checked ) }
109+ style = { { accentColor : "#5bd5ff" , width : 14 , height : 14 , cursor : "pointer" } }
110+ />
111+ < span style = { { flex : "1 1 auto" , whiteSpace : "nowrap" , overflow : "hidden" , textOverflow : "ellipsis" } } > { label } </ span >
112+ </ label >
113+ )
114+ } ) }
115+ </ div >
81116 </ div >
82117 )
83118}
0 commit comments