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
@@ -187,7 +187,7 @@ export function MinimalAudioSkinTailwind(props: MinimalAudioSkinProps): ReactNod
</SeekButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}>Seek backward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top" boundary="viewport">
@@ -201,7 +201,7 @@ export function MinimalAudioSkinTailwind(props: MinimalAudioSkinProps): ReactNod
</SeekButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}>Seek forward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
</div>
@@ -218,6 +218,9 @@ export function MinimalAudioSkinTailwind(props: MinimalAudioSkinProps): ReactNod
<TimeSlider.Buffer render={<SliderBuffer />} />
</TimeSlider.Track>
<TimeSlider.Thumb render={<SliderThumb />} />
<TimeSlider.Preview className={slider.preview}>
<TimeSlider.Value type="pointer" className={slider.value} />
</TimeSlider.Preview>
</TimeSlider.Root>
</div>
@@ -134,7 +134,7 @@ export function MinimalAudioSkin(props: MinimalAudioSkinProps): ReactNode {
</SeekButton>
}
/>
<Tooltip.Popup className="media-tooltip">Seek backward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className="media-tooltip" />
</Tooltip.Root>
<Tooltip.Root side="top" boundary="viewport">
@@ -148,7 +148,7 @@ export function MinimalAudioSkin(props: MinimalAudioSkinProps): ReactNode {
</SeekButton>
}
/>
<Tooltip.Popup className="media-tooltip">Seek forward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className="media-tooltip" />
</Tooltip.Root>
</div>
@@ -165,6 +165,9 @@ export function MinimalAudioSkin(props: MinimalAudioSkinProps): ReactNode {
<TimeSlider.Buffer className="media-slider__buffer" />
</TimeSlider.Track>
<TimeSlider.Thumb className="media-slider__thumb" />
<TimeSlider.Preview className="media-slider__preview">
<TimeSlider.Value type="pointer" className="media-slider__value media-time" />
</TimeSlider.Preview>
</TimeSlider.Root>
</div>
@@ -189,7 +189,7 @@ export function AudioSkinTailwind(props: AudioSkinProps): ReactNode {
</SeekButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}>Seek backward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top" boundary="viewport">
@@ -203,7 +203,7 @@ export function AudioSkinTailwind(props: AudioSkinProps): ReactNode {
</SeekButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}>Seek forward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
</div>
@@ -215,6 +215,9 @@ export function AudioSkinTailwind(props: AudioSkinProps): ReactNode {
<TimeSlider.Buffer render={<SliderBuffer />} />
</TimeSlider.Track>
<TimeSlider.Thumb render={<SliderThumb />} />
<TimeSlider.Preview className={slider.preview}>
<TimeSlider.Value type="pointer" className={slider.value} />
</TimeSlider.Preview>
</TimeSlider.Root>
<Time.Value type="duration" className={time.duration} />
</div>
+5 -2
View File
@@ -134,7 +134,7 @@ export function AudioSkin(props: AudioSkinProps): ReactNode {
</SeekButton>
}
/>
<Tooltip.Popup className="media-surface media-tooltip">Seek backward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className="media-surface media-tooltip" />
</Tooltip.Root>
<Tooltip.Root side="top" boundary="viewport">
@@ -148,7 +148,7 @@ export function AudioSkin(props: AudioSkinProps): ReactNode {
</SeekButton>
}
/>
<Tooltip.Popup className="media-surface media-tooltip">Seek forward {SEEK_TIME} seconds</Tooltip.Popup>
<Tooltip.Popup className="media-surface media-tooltip" />
</Tooltip.Root>
</div>
@@ -160,6 +160,9 @@ export function AudioSkin(props: AudioSkinProps): ReactNode {
<TimeSlider.Buffer className="media-slider__buffer" />
</TimeSlider.Track>
<TimeSlider.Thumb className="media-slider__thumb" />
<TimeSlider.Preview className="media-slider__preview">
<TimeSlider.Value type="pointer" className="media-slider__value media-time" />
</TimeSlider.Preview>
</TimeSlider.Root>
<Time.Value type="duration" className="media-time" />
</div>
@@ -129,7 +129,7 @@ export function MinimalLiveAudioSkinTailwind(props: MinimalLiveAudioSkinProps):
</PlayButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<LiveButton className={cn(button.base, button.subtle, button.live)} />
@@ -129,7 +129,7 @@ export function LiveAudioSkinTailwind(props: LiveAudioSkinProps): ReactNode {
</PlayButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<LiveButton className={cn(button.base, button.subtle, button.live)} />
@@ -187,7 +187,7 @@ export function MinimalLiveVideoSkinTailwind(props: MinimalLiveVideoSkinProps):
</PlayButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<LiveButton className={cn(button.base, button.subtle, button.live)} />
@@ -207,7 +207,7 @@ export function MinimalLiveVideoSkinTailwind(props: MinimalLiveVideoSkinProps):
</CaptionsButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top">
@@ -219,7 +219,7 @@ export function MinimalLiveVideoSkinTailwind(props: MinimalLiveVideoSkinProps):
</CastButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top">
@@ -243,7 +243,7 @@ export function MinimalLiveVideoSkinTailwind(props: MinimalLiveVideoSkinProps):
</PiPButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top">
@@ -255,7 +255,7 @@ export function MinimalLiveVideoSkinTailwind(props: MinimalLiveVideoSkinProps):
</FullscreenButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
</div>
</Tooltip.Provider>
@@ -189,7 +189,7 @@ export function LiveVideoSkinTailwind(props: LiveVideoSkinProps): ReactNode {
</PlayButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<LiveButton className={cn(button.base, button.subtle, button.live)} />
@@ -209,7 +209,7 @@ export function LiveVideoSkinTailwind(props: LiveVideoSkinProps): ReactNode {
</CaptionsButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top">
@@ -221,7 +221,7 @@ export function LiveVideoSkinTailwind(props: LiveVideoSkinProps): ReactNode {
</CastButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top">
@@ -245,7 +245,7 @@ export function LiveVideoSkinTailwind(props: LiveVideoSkinProps): ReactNode {
</PiPButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
<Tooltip.Root side="top">
@@ -257,7 +257,7 @@ export function LiveVideoSkinTailwind(props: LiveVideoSkinProps): ReactNode {
</FullscreenButton>
}
/>
<Tooltip.Popup className={cn(popup.tooltip)}></Tooltip.Popup>
<Tooltip.Popup className={cn(popup.tooltip)} />
</Tooltip.Root>
</div>
</Tooltip.Provider>
@@ -15,10 +15,10 @@ import {
playbackRate,
popup,
poster,
preview,
root,
seek,
slider,
thumbnail,
time,
} from '@videojs/skins/minimal/tailwind/video.tailwind';
import { isString } from '@videojs/utils/predicate';
@@ -274,13 +274,16 @@ export function MinimalVideoSkinTailwind(props: MinimalVideoSkinProps): ReactNod
<TimeSlider.Buffer render={<SliderBuffer />} />
</TimeSlider.Track>
<TimeSlider.Thumb render={<SliderThumb />} />
<div className={preview.root}>
<div className={preview.thumbnailWrapper}>
<Slider.Thumbnail className={preview.thumbnail} />
<div className={thumbnail.root}>
<div className={thumbnail.imageWrapper}>
<Slider.Thumbnail className={thumbnail.image} />
</div>
<TimeSlider.Value type="pointer" className={preview.time} />
<SpinnerIcon className={cn(icon, preview.spinner)} />
<TimeSlider.Value type="pointer" className={cn(time.current, thumbnail.time)} />
<SpinnerIcon className={cn(icon, thumbnail.spinner)} />
</div>
<TimeSlider.Preview className={slider.preview}>
<TimeSlider.Value type="pointer" className={cn(slider.value, time.current)} />
</TimeSlider.Preview>
</TimeSlider.Root>
</div>
@@ -207,13 +207,17 @@ export function MinimalVideoSkin(props: MinimalVideoSkinProps): ReactNode {
</TimeSlider.Track>
<TimeSlider.Thumb className="media-slider__thumb" />
<div className="media-preview media-slider__preview">
<div className="media-preview__thumbnail-wrapper">
<Slider.Thumbnail className="media-preview__thumbnail" />
<div className="media-thumbnail media-slider__thumbnail">
<div className="media-thumbnail__image-wrapper">
<Slider.Thumbnail className="media-thumbnail__image" />
</div>
<TimeSlider.Value type="pointer" className="media-time media-preview__time" />
<SpinnerIcon className="media-preview__spinner media-icon" />
<TimeSlider.Value type="pointer" className="media-time media-thumbnail__time" />
<SpinnerIcon className="media-thumbnail__spinner media-icon" />
</div>
<TimeSlider.Preview className="media-slider__preview">
<TimeSlider.Value type="pointer" className="media-slider__value media-time" />
</TimeSlider.Preview>
</TimeSlider.Root>
</div>
@@ -15,10 +15,10 @@ import {
playbackRate,
popup,
poster,
preview,
root,
seek,
slider,
thumbnail,
time,
} from '@videojs/skins/default/tailwind/video.tailwind';
import { isString } from '@videojs/utils/predicate';
@@ -271,11 +271,14 @@ export function VideoSkinTailwind(props: VideoSkinProps): ReactNode {
<TimeSlider.Buffer render={<SliderBuffer />} />
</TimeSlider.Track>
<TimeSlider.Thumb render={<SliderThumb />} />
<div className={preview.root}>
<Slider.Thumbnail className={preview.thumbnail} />
<TimeSlider.Value type="pointer" className={preview.time} />
<SpinnerIcon className={cn(icon, preview.spinner)} />
<div className={thumbnail.root}>
<Slider.Thumbnail className={thumbnail.image} />
<TimeSlider.Value type="pointer" className={cn(time.current, thumbnail.time)} />
<SpinnerIcon className={cn(icon, thumbnail.spinner)} />
</div>
<TimeSlider.Preview className={slider.preview}>
<TimeSlider.Value type="pointer" className={cn(slider.value, time.current)} />
</TimeSlider.Preview>
</TimeSlider.Root>
<Time.Value type="duration" className={time.duration} />
</div>
+8 -4
View File
@@ -204,11 +204,15 @@ export function VideoSkin(props: VideoSkinProps): ReactNode {
</TimeSlider.Track>
<TimeSlider.Thumb className="media-slider__thumb" />
<div className="media-surface media-preview media-slider__preview">
<Slider.Thumbnail className="media-preview__thumbnail" />
<TimeSlider.Value type="pointer" className="media-time media-preview__time" />
<SpinnerIcon className="media-preview__spinner media-icon" />
<div className="media-surface media-thumbnail media-slider__thumbnail">
<Slider.Thumbnail className="media-thumbnail__image" />
<TimeSlider.Value type="pointer" className="media-time media-thumbnail__time" />
<SpinnerIcon className="media-thumbnail__spinner media-icon" />
</div>
<TimeSlider.Preview className="media-slider__preview">
<TimeSlider.Value type="pointer" className="media-slider__value media-time" />
</TimeSlider.Preview>
</TimeSlider.Root>
<Time.Value type="duration" className="media-time" />
</div>