styleui-components
Version:
Lightweight, modular UI component library with zero dependencies
193 lines (170 loc) • 4.19 kB
CSS
.timeline {
position: relative;
width: 100%;
height: 40px; /* Taller to feel more like Blender's timeline */
margin: var(--space-2) 0;
touch-action: none;
user-select: none;
background-color: var(--surface-2);
padding-top: 16px; /* Space for labels */
border-radius: var(--radius-md);
}
.timeline-track {
position: absolute;
top: 16px; /* Position below the padding */
left: 0;
width: 100%;
height: 24px;
background-color: var(--surface-3); /* Darker track */
border-radius: 0;
}
.timeline-progress {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: transparent; /* Blender's playhead is just a line */
opacity: 0;
border-radius: 2px;
}
/* Playhead */
.timeline-handle {
position: absolute;
top: -8px; /* Align with track area */
height: calc(100% + 16px); /* Full height grab area */
background-color: transparent;
cursor: pointer;
z-index: 10;
}
/* No ::before content for handle */
.timeline-handle::before {
content: none;
}
.timeline-playhead-label {
position: absolute;
top: 8px; /* Align with the top of the playhead line */
left: 50%;
transform: translate(calc(-50% - 2px), -100%);
background-color: var(--accent);
color: var(--grey-100);
padding: 2px 5px;
border-radius: var(--radius-sm);
font-family: var(--font-mono);
font-size: 11px;
font-weight: 600;
white-space: nowrap;
z-index: 12;
pointer-events: none;
}
/* Playhead icon styling */
.timeline-handle .lucide {
position: absolute;
left: 50%;
color: var(--accent);
pointer-events: none; /* Icon shouldn't capture events */
}
.timeline-playhead-line {
position: absolute;
top: 8px;
left: 50%;
transform: translateX(calc(-50% - 2px));
width: 2px;
height: calc(100% - 16px);
background-color: var(--accent);
}
/* Increased grab zone for the playhead */
.timeline-handle::after {
content: "";
position: absolute;
top: -8px;
left: -6px;
width: 14px;
height: calc(100% + 16px);
background: transparent; /* Invisible but clickable */
cursor: pointer;
}
/* Markers - styled as diamonds like keyframes */
.timeline-marker {
position: absolute;
top: auto;
bottom: 7px; /* Vertically centered in track */
width: 10px;
height: 10px;
background-color: var(--warning); /* Default keyframe color */
transform: translateX(calc(-50% + 1px)) rotate(45deg);
border: 1px solid var(--surface-2);
}
/* Ruler & Ticks */
.timeline-ruler {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
font-family: var(--font-mono);
font-size: 10px;
color: var(--text-secondary);
}
/* Ticks */
.timeline-tick {
position: absolute;
top: 0;
width: 1px;
height: 35%;
background-color: var(--grey-600);
opacity: 0.8;
}
.timeline-tick-five {
height: 45%;
background-color: var(--grey-500);
}
.timeline-tick-ten {
height: 55%;
background-color: var(--grey-400);
}
.timeline-tick-major {
height: 70%;
background-color: var(--grey-300);
}
.timeline-label {
position: absolute;
top: -4px; /* Position above the track */
transform: translate(-50%, -100%);
white-space: nowrap;
pointer-events: none;
color: var(--text-secondary);
}
.timeline-range {
position: absolute;
top: 0;
height: 100%;
background-color: var(--accent, var(--primary));
opacity: 0.15;
pointer-events: none;
}
.timeline-range-handle {
position: absolute;
top: 0;
width: 2px;
height: 100%;
background-color: var(--accent);
cursor: ew-resize;
z-index: 11;
}
.timeline-range-handle::before {
content: none;
}
/* Light theme specific styles */
html:not(.dark-theme) .timeline-tick {
background-color: var(--grey-400);
}
html:not(.dark-theme) .timeline-tick-five {
background-color: var(--grey-500);
}
html:not(.dark-theme) .timeline-tick-ten {
background-color: var(--grey-600);
}
html:not(.dark-theme) .timeline-tick-major {
background-color: var(--grey-700);
}