feat(skin): show scrubber preview timestamps (#1652)

This commit is contained in:
Sam Potts
2026-06-03 19:27:54 +10:00
committed by GitHub
parent d96a8dd474
commit 7453d538a8
35 changed files with 382 additions and 166 deletions
@@ -40,11 +40,11 @@ export const slider = {
base: cn(
'z-10 absolute -translate-x-1/2 -translate-y-1/2',
'bg-current rounded-full',
'shadow-[0_0_0_1px_var(--media-current-shadow-color-subtle,oklch(0_0_0/0.1)),0_1px_3px_0_oklch(0_0_0/0.15),0_1px_2px_-1px_oklch(0_0_0/0.15)]',
'shadow-[0_0_0_1px_var(--media-current-shadow-color,oklch(0_0_0/0.1)),0_1px_3px_0_oklch(0_0_0/0.35),0_1px_2px_-1px_oklch(0_0_0/0.35)]',
'transition-[opacity,height,width,outline-offset] duration-150 ease-out select-none',
'outline-4 outline-transparent -outline-offset-4',
'hover:outline-current/25 hover:outline-offset-0',
'focus-visible:outline-current/25 focus-visible:outline-offset-0',
'hover:outline-current/15 hover:outline-offset-0',
'focus-visible:outline-current/15 focus-visible:outline-offset-0',
// Horizontal
'data-[orientation=horizontal]:top-1/2 data-[orientation=horizontal]:left-(--media-slider-fill)',
// Vertical
@@ -57,4 +57,20 @@ export const slider = {
'group-active/slider:size-3'
),
},
preview: cn(
'group/preview',
'before:block before:min-w-1 before:h-1 before:bg-current before:rounded-full before:opacity-0 before:scale-50',
'before:shadow-[0_0_0_1px_var(--media-current-shadow-color,oklch(0_0_0/0.15)),0_1px_2px_0_oklch(0_0_0/0.35)]',
'before:transition-[opacity,scale] before:duration-200 before:ease-out',
'data-pointing:not-data-dragging:before:opacity-100 data-pointing:not-data-dragging:before:scale-100',
'peer-has-[[role=img]:not([data-hidden])]/thumbnail:*:hidden'
),
value: cn(
'absolute bottom-9 tabular-nums',
'-translate-x-1/2 translate-y-2 scale-50 opacity-0 blur-lg',
'text-shadow-2xs text-shadow-(color:--media-current-shadow-color)',
'transition-[filter,opacity,scale,translate] duration-200 ease-out',
'group-data-pointing/preview:translate-y-0 group-data-pointing/preview:scale-100',
'group-data-pointing/preview:opacity-100 group-data-pointing/preview:blur-none'
),
};
@@ -1,8 +1,8 @@
import { cn } from '@videojs/utils/style';
export const preview = {
root: cn('group/preview pointer-events-none bg-black/90 rounded-xl'),
thumbnail: cn(
export const thumbnail = {
root: cn('group/thumbnail peer/thumbnail pointer-events-none bg-black/90 rounded-xl'),
image: cn(
'block relative overflow-clip rounded-[inherit]',
'transition-opacity duration-150 ease-out',
'after:absolute after:inset-0 after:rounded-[inherit]',
@@ -13,6 +13,6 @@ export const preview = {
spinner: cn(
'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0',
'transition-opacity duration-150 ease-out',
'group-not-has-[[role=img][data-loading]]/preview:[--media-spinner-animation:none] group-has-[[role=img][data-loading]]/preview:opacity-100'
'group-not-has-[[role=img][data-loading]]/thumbnail:[--media-spinner-animation:none] group-has-[[role=img][data-loading]]/thumbnail:opacity-100'
),
};
@@ -5,10 +5,10 @@ import { controls as baseControls } from './components/controls';
import { error as baseError } from './components/error';
import { inputFeedback as baseInputFeedback } from './components/input-feedback';
import { popup as basePopup } from './components/popup';
import { preview as basePreview } from './components/preview';
import { root as baseRoot } from './components/root';
import { slider as baseSlider } from './components/slider';
import { surface } from './components/surface';
import { thumbnail as baseThumbnail } from './components/thumbnail';
import { time as baseTime } from './components/time';
/* ==========================================================================
@@ -133,23 +133,24 @@ export const time = {
};
/* ==========================================================================
Preview (with video surface)
Thumbnail (with video surface)
========================================================================== */
export const preview = {
...basePreview,
export const thumbnail = {
...baseThumbnail,
root: cn(
'[--media-preview-max-width:11rem] [--media-preview-padding:-1.125rem] [--media-preview-inset:calc((100cqi-100%)/2)]',
'absolute [left:clamp(calc(var(--media-preview-max-width)/2+var(--media-preview-padding)-var(--media-preview-inset)),var(--media-slider-pointer),calc(100%-var(--media-preview-max-width)/2-var(--media-preview-padding)+var(--media-preview-inset)))] bottom-[calc(100%+1.2rem)] -translate-x-1/2',
baseThumbnail.root,
surface,
'[--media-slider-thumbnail-max-width:11rem] [--media-slider-thumbnail-padding:-1.125rem] [--media-slider-thumbnail-inset:calc((100cqi-100%)/2)]',
'absolute [left:clamp(calc(var(--media-slider-thumbnail-max-width)/2+var(--media-slider-thumbnail-padding)-var(--media-slider-thumbnail-inset)),var(--media-slider-pointer),calc(100%-var(--media-slider-thumbnail-max-width)/2-var(--media-slider-thumbnail-padding)+var(--media-slider-thumbnail-inset)))] bottom-[calc(100%+1.2rem)] -translate-x-1/2',
'opacity-0 scale-80 blur-sm origin-bottom',
'transition-[scale,opacity,filter] duration-150',
'group-data-pointing/slider:opacity-100 group-data-pointing/slider:scale-100 group-data-pointing/slider:blur-none',
'has-[[role=img][data-hidden]]:opacity-0 has-[[role=img][data-hidden]]:scale-80 has-[[role=img][data-hidden]]:blur-sm',
'has-[[role=img][data-loading]]:max-h-24',
surface,
basePreview.root
'has-[[role=img]:not([data-hidden])]:group-data-pointing/slider:opacity-100',
'has-[[role=img]:not([data-hidden])]:group-data-pointing/slider:scale-100',
'has-[[role=img]:not([data-hidden])]:group-data-pointing/slider:blur-none',
'has-[[role=img][data-loading]]:max-h-24'
),
thumbnail: cn(basePreview.thumbnail, 'max-w-(--media-preview-max-width)'),
image: cn(baseThumbnail.image, 'max-w-(--media-slider-thumbnail-max-width)'),
};
/* ==========================================================================