diff --git a/packages/react/src/presets/video/minimal-skin.tsx b/packages/react/src/presets/video/minimal-skin.tsx
index 4995d502..ffc8d6e3 100644
--- a/packages/react/src/presets/video/minimal-skin.tsx
+++ b/packages/react/src/presets/video/minimal-skin.tsx
@@ -207,13 +207,17 @@ export function MinimalVideoSkin(props: MinimalVideoSkinProps): ReactNode {
-
diff --git a/packages/react/src/presets/video/skin.tailwind.tsx b/packages/react/src/presets/video/skin.tailwind.tsx
index bf39ede1..9b0382d0 100644
--- a/packages/react/src/presets/video/skin.tailwind.tsx
+++ b/packages/react/src/presets/video/skin.tailwind.tsx
@@ -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 {
} />
} />
-
diff --git a/packages/react/src/presets/video/skin.tsx b/packages/react/src/presets/video/skin.tsx
index 6d129612..ae782a52 100644
--- a/packages/react/src/presets/video/skin.tsx
+++ b/packages/react/src/presets/video/skin.tsx
@@ -204,11 +204,15 @@ export function VideoSkin(props: VideoSkinProps): ReactNode {
-
diff --git a/packages/skins/src/default/css/components/slider.css b/packages/skins/src/default/css/components/slider.css
index f2e18055..905017fa 100644
--- a/packages/skins/src/default/css/components/slider.css
+++ b/packages/skins/src/default/css/components/slider.css
@@ -55,9 +55,9 @@
background-color: currentColor;
border-radius: calc(infinity * 1px);
box-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);
+ 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);
opacity: 0;
translate: -50% -50%;
transition-timing-function: ease-out;
@@ -76,7 +76,7 @@
&:hover,
&:focus {
- outline-color: oklch(from currentColor l c h / 0.25);
+ outline-color: oklch(from currentColor l c h / 0.15);
outline-offset: 0;
}
@@ -109,6 +109,49 @@
opacity: 1;
}
+/* Preview */
+.media-default-skin .media-slider__preview {
+ & .media-slider__value,
+ &::before {
+ opacity: 0;
+ scale: 0.5;
+ transition-timing-function: ease-out;
+ transition-duration: 200ms;
+ transition-property: opacity, scale;
+ }
+
+ & .media-slider__value {
+ position: absolute;
+ bottom: 2.25rem;
+ text-shadow: 0 1px 0 var(--media-current-shadow-color);
+ filter: blur(8px);
+ translate: -50% 0.5rem;
+ transition-property: filter, opacity, scale, translate;
+ }
+
+ &::before {
+ display: block;
+ min-width: 0.25rem;
+ height: 0.25rem;
+ content: "";
+ background-color: currentColor;
+ border-radius: 100%;
+ box-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);
+ }
+
+ &[data-pointing] .media-slider__value,
+ &[data-pointing]:not([data-dragging])::before {
+ opacity: 1;
+ scale: 1;
+ }
+ &[data-pointing] .media-slider__value {
+ filter: blur(0);
+ translate: -50% 0;
+ }
+}
+
/* Shared track fills */
.media-default-skin .media-slider__buffer,
.media-default-skin .media-slider__fill {
diff --git a/packages/skins/src/default/css/components/preview.css b/packages/skins/src/default/css/components/thumbnail.css
similarity index 66%
rename from packages/skins/src/default/css/components/preview.css
rename to packages/skins/src/default/css/components/thumbnail.css
index 25b13792..53596bed 100644
--- a/packages/skins/src/default/css/components/preview.css
+++ b/packages/skins/src/default/css/components/thumbnail.css
@@ -1,12 +1,13 @@
/* ==========================================================================
- Media preview
+ Media thumbnail
========================================================================== */
-.media-default-skin .media-preview {
+
+.media-default-skin .media-thumbnail {
pointer-events: none;
background-color: oklch(0 0 0 / 0.9);
border-radius: 0.75rem;
- & .media-preview__thumbnail {
+ & .media-thumbnail__image {
position: relative;
display: block;
overflow: clip;
@@ -21,18 +22,14 @@
}
}
- & .media-preview__time {
+ & .media-thumbnail__time {
position: absolute;
inset-inline: 0;
bottom: 0.5rem;
text-align: center;
}
- & .media-overlay {
- opacity: 1;
- }
-
- & .media-preview__spinner {
+ & .media-thumbnail__spinner {
position: absolute;
top: 50%;
left: 50%;
@@ -40,22 +37,22 @@
translate: -50% -50%;
}
- & .media-preview__thumbnail,
- & .media-preview__spinner {
+ & .media-thumbnail__image,
+ & .media-thumbnail__spinner {
transition: opacity 150ms ease-out;
}
- &:not(:has(.media-preview__thumbnail[data-loading])) {
- & .media-preview__spinner {
+ &:not(:has(.media-thumbnail__image[data-loading])) {
+ & .media-thumbnail__spinner {
--media-spinner-animation: none;
}
}
- &:has(.media-preview__thumbnail[data-loading]) {
- & .media-preview__thumbnail {
+ &:has(.media-thumbnail__image[data-loading]) {
+ & .media-thumbnail__image {
opacity: 0;
}
- & .media-preview__spinner {
+ & .media-thumbnail__spinner {
opacity: 1;
}
}
diff --git a/packages/skins/src/default/css/video.css b/packages/skins/src/default/css/video.css
index 49121569..c3d006d4 100644
--- a/packages/skins/src/default/css/video.css
+++ b/packages/skins/src/default/css/video.css
@@ -12,7 +12,7 @@
@import "./components/icons.css";
@import "./components/menus.css";
@import "./components/poster.css";
-@import "./components/preview.css";
+@import "./components/thumbnail.css";
@import "./components/slider.css";
@import "./components/popup.css";
@import "./components/captions.css";
@@ -245,21 +245,32 @@
box-shadow: 0 0 0 1px oklch(0 0 0 / 0.05);
}
-.media-default-skin--video .media-slider__preview {
- --media-preview-max-width: 11rem;
- --media-preview-padding: -1.125rem;
+.media-default-skin--video .media-slider__thumbnail {
+ --media-slider-thumbnail-max-width: 11rem;
+ --media-slider-thumbnail-padding: -1.125rem;
/**
Inset is the difference between the container width and the slider (100%) width.
Divided by 2 as we render the time on both sides.
*/
- --media-preview-inset: calc((100cqi - 100%) / 2);
+ --media-slider-thumbnail-inset: calc((100cqi - 100%) / 2);
position: absolute;
bottom: calc(100% + 1.2rem);
left: clamp(
- calc(var(--media-preview-max-width) / 2 + var(--media-preview-padding) - var(--media-preview-inset)),
+ 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-preview-max-width) / 2 - var(--media-preview-padding) + var(--media-preview-inset))
+ calc(
+ 100% -
+ var(--media-slider-thumbnail-max-width) /
+ 2 -
+ var(--media-slider-thumbnail-padding) +
+ var(--media-slider-thumbnail-inset)
+ )
);
pointer-events: none;
opacity: 0;
@@ -271,16 +282,22 @@
transition-duration: 150ms;
transition-property: scale, opacity, filter;
- & .media-preview__thumbnail {
- max-width: var(--media-preview-max-width);
+ & .media-thumbnail__image {
+ max-width: var(--media-slider-thumbnail-max-width);
}
- &:has(.media-preview__thumbnail[data-loading]) {
+ &:has(.media-thumbnail__image[data-loading]) {
max-height: 6rem;
}
}
-.media-default-skin--video .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
+.media-default-skin--video .media-slider[data-pointing] .media-slider__thumbnail:has([role="img"]:not([data-hidden])) {
opacity: 1;
filter: blur(0);
scale: 1;
}
+.media-default-skin--video
+ .media-slider__thumbnail:has([role="img"]:not([data-hidden]))
+ + .media-slider__preview
+ .media-slider__value {
+ display: none;
+}
diff --git a/packages/skins/src/default/tailwind/components/slider.ts b/packages/skins/src/default/tailwind/components/slider.ts
index a6c64c36..15901ef5 100644
--- a/packages/skins/src/default/tailwind/components/slider.ts
+++ b/packages/skins/src/default/tailwind/components/slider.ts
@@ -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'
+ ),
};
diff --git a/packages/skins/src/default/tailwind/components/preview.ts b/packages/skins/src/default/tailwind/components/thumbnail.ts
similarity index 65%
rename from packages/skins/src/default/tailwind/components/preview.ts
rename to packages/skins/src/default/tailwind/components/thumbnail.ts
index 0c892334..822a2270 100644
--- a/packages/skins/src/default/tailwind/components/preview.ts
+++ b/packages/skins/src/default/tailwind/components/thumbnail.ts
@@ -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'
),
};
diff --git a/packages/skins/src/default/tailwind/video.tailwind.ts b/packages/skins/src/default/tailwind/video.tailwind.ts
index ac4296b6..b9713a0a 100644
--- a/packages/skins/src/default/tailwind/video.tailwind.ts
+++ b/packages/skins/src/default/tailwind/video.tailwind.ts
@@ -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)'),
};
/* ==========================================================================
diff --git a/packages/skins/src/minimal/css/audio.css b/packages/skins/src/minimal/css/audio.css
index 9c9379d2..e76908fe 100644
--- a/packages/skins/src/minimal/css/audio.css
+++ b/packages/skins/src/minimal/css/audio.css
@@ -112,3 +112,7 @@
padding: 0 0 0 4rem;
background: linear-gradient(to left, var(--media-controls-background-color) 80%, transparent 100%);
}
+
+.media-minimal-skin--audio .media-slider__preview .media-slider__value {
+ bottom: 2.5rem;
+}
diff --git a/packages/skins/src/minimal/css/components/slider.css b/packages/skins/src/minimal/css/components/slider.css
index 4fc03bc3..a8639a52 100644
--- a/packages/skins/src/minimal/css/components/slider.css
+++ b/packages/skins/src/minimal/css/components/slider.css
@@ -56,7 +56,7 @@
background-color: currentColor;
border-radius: calc(infinity * 1px);
box-shadow:
- 0 0 0 1px var(--media-current-shadow-color-subtle, oklch(0 0 0 / 0.1)),
+ 0 0 0 1px var(--media-current-shadow-color, oklch(0 0 0 / 0.15)),
0 1px 3px 0 oklch(0 0 0 / 0.15),
0 1px 2px -1px oklch(0 0 0 / 0.15);
opacity: 0;
@@ -90,6 +90,53 @@
scale: 1;
}
+/* Preview */
+.media-minimal-skin .media-slider__preview {
+ & .media-slider__value,
+ &::before {
+ opacity: 0;
+ scale: 0.5;
+ transition-timing-function: ease-out;
+ transition-duration: 200ms;
+ transition-property: opacity, scale;
+ }
+
+ & .media-slider__value {
+ position: absolute;
+ bottom: 1.5rem;
+ text-shadow: 0 1px 0 var(--media-current-shadow-color);
+ filter: blur(8px);
+ translate: -50% 0.5rem;
+ transition-property: filter, opacity, scale, translate;
+ }
+
+ &::before {
+ display: block;
+ content: "";
+ background-color: oklch(from currentColor l c h / 0.35);
+ }
+
+ &[data-pointing] .media-slider__value,
+ &[data-pointing]:not([data-dragging])::before {
+ opacity: 1;
+ scale: 1;
+ }
+ &[data-pointing] .media-slider__value {
+ filter: blur(0);
+ translate: -50% 0;
+ }
+
+ &[data-orientation="horizontal"]::before {
+ min-width: 1px;
+ height: 1.25rem;
+ }
+
+ &[data-orientation="vertical"]::before {
+ width: 1.25rem;
+ min-height: 1px;
+ }
+}
+
/* Shared track fills */
.media-minimal-skin .media-slider__buffer,
.media-minimal-skin .media-slider__fill {
diff --git a/packages/skins/src/minimal/css/components/preview.css b/packages/skins/src/minimal/css/components/thumbnail.css
similarity index 60%
rename from packages/skins/src/minimal/css/components/preview.css
rename to packages/skins/src/minimal/css/components/thumbnail.css
index f4652f44..d53fbb14 100644
--- a/packages/skins/src/minimal/css/components/preview.css
+++ b/packages/skins/src/minimal/css/components/thumbnail.css
@@ -1,20 +1,21 @@
/* ==========================================================================
- Media preview
+ Media thumbnail
========================================================================== */
-.media-minimal-skin .media-preview {
+
+.media-minimal-skin .media-thumbnail {
pointer-events: none;
- & .media-preview__thumbnail-wrapper {
+ & .media-thumbnail__image-wrapper {
position: relative;
background-color: oklch(0 0 0 / 0.9);
border-radius: 0.5rem;
}
- & .media-preview__thumbnail {
+ & .media-thumbnail__image {
display: block;
border-radius: inherit;
}
- & .media-preview__time {
+ & .media-thumbnail__time {
display: block;
margin-top: 0.5rem;
text-align: center;
@@ -24,7 +25,7 @@
opacity: 1;
}
- & .media-preview__spinner {
+ & .media-thumbnail__spinner {
position: absolute;
top: 50%;
left: 50%;
@@ -32,22 +33,22 @@
translate: -50% -50%;
}
- & .media-preview__thumbnail,
- & .media-preview__spinner {
+ & .media-thumbnail__image,
+ & .media-thumbnail__spinner {
transition: opacity 150ms ease-out;
}
- &:not(:has(.media-preview__thumbnail[data-loading])) {
- & .media-preview__spinner {
+ &:not(:has(.media-thumbnail__image[data-loading])) {
+ & .media-thumbnail__spinner {
--media-spinner-animation: none;
}
}
- &:has(.media-preview__thumbnail[data-loading]) {
- & .media-preview__thumbnail {
+ &:has(.media-thumbnail__image[data-loading]) {
+ & .media-thumbnail__image {
opacity: 0;
}
- & .media-preview__spinner {
+ & .media-thumbnail__spinner {
opacity: 1;
}
}
diff --git a/packages/skins/src/minimal/css/video.css b/packages/skins/src/minimal/css/video.css
index 4796798d..bcae177d 100644
--- a/packages/skins/src/minimal/css/video.css
+++ b/packages/skins/src/minimal/css/video.css
@@ -10,7 +10,7 @@
@import "./components/button-group.css";
@import "./components/icons.css";
@import "./components/poster.css";
-@import "./components/preview.css";
+@import "./components/thumbnail.css";
@import "./components/slider.css";
@import "./components/popup.css";
@import "./components/menus.css";
@@ -261,21 +261,27 @@
Slider preview
========================================================================== */
-.media-minimal-skin--video .media-slider__preview {
- --media-preview-max-width: 11rem;
- --media-preview-padding: -0.5rem;
+.media-minimal-skin--video .media-slider__thumbnail {
+ --media-slider-thumbnail-max-width: 11rem;
+ --media-slider-thumbnail-padding: -0.5rem;
/**
Inset is the difference between the container width and the slider (100%) width.
We only add to the end as we render the time there.
*/
- --media-preview-inset: calc(100cqi - 100%);
+ --media-slider-thumbnail-inset: calc(100cqi - 100%);
position: absolute;
bottom: 100%;
left: clamp(
- calc(var(--media-preview-max-width) / 2 + var(--media-preview-padding)),
+ calc(var(--media-slider-thumbnail-max-width) / 2 + var(--media-slider-thumbnail-padding)),
var(--media-slider-pointer),
- calc(100% - var(--media-preview-max-width) / 2 - var(--media-preview-padding) + var(--media-preview-inset))
+ calc(
+ 100% -
+ var(--media-slider-thumbnail-max-width) /
+ 2 -
+ var(--media-slider-thumbnail-padding) +
+ var(--media-slider-thumbnail-inset)
+ )
);
opacity: 0;
filter: blur(8px);
@@ -287,11 +293,10 @@
transition-property: scale, opacity, filter;
@container media-root (width > 42rem) {
- bottom: calc(100% + 0.25rem);
left: var(--media-slider-pointer);
}
- & .media-preview__thumbnail-wrapper {
+ & .media-thumbnail__image-wrapper {
position: relative;
&::after {
@@ -306,16 +311,22 @@
}
}
- & .media-preview__thumbnail {
- max-width: var(--media-preview-max-width);
+ & .media-thumbnail__image {
+ max-width: var(--media-slider-thumbnail-max-width);
}
- &:has(.media-preview__thumbnail[data-loading]) {
+ &:has(.media-thumbnail__image[data-loading]) {
max-height: 6rem;
}
}
-.media-minimal-skin--video .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
+.media-minimal-skin--video .media-slider[data-pointing] .media-slider__thumbnail:has([role="img"]:not([data-hidden])) {
opacity: 1;
filter: blur(0);
scale: 1;
}
+.media-minimal-skin--video
+ .media-slider__thumbnail:has([role="img"]:not([data-hidden]))
+ + .media-slider__preview
+ .media-slider__value {
+ display: none;
+}
diff --git a/packages/skins/src/minimal/tailwind/audio.tailwind.ts b/packages/skins/src/minimal/tailwind/audio.tailwind.ts
index 75c9dbdf..e197c8f0 100644
--- a/packages/skins/src/minimal/tailwind/audio.tailwind.ts
+++ b/packages/skins/src/minimal/tailwind/audio.tailwind.ts
@@ -3,6 +3,7 @@ import { controls as baseControls } from './components/controls';
import { error as baseError } from './components/error';
import { popup as basePopup } from './components/popup';
import { root as baseRoot } from './components/root';
+import { slider as baseSlider } from './components/slider';
/* ==========================================================================
Root
@@ -67,6 +68,15 @@ export const popup = {
),
};
+/* ==========================================================================
+ Sliders
+ ========================================================================== */
+
+export const slider = {
+ ...baseSlider,
+ value: cn(baseSlider.value, 'bottom-10'),
+};
+
/* ==========================================================================
Error
========================================================================== */
@@ -98,5 +108,4 @@ export { icon, iconContainer, iconFlipped, iconHidden } from './components/icon'
export { menu } from './components/menu';
export { playbackRate } from './components/playback-rate';
export { seek } from './components/seek';
-export { slider } from './components/slider';
export { time } from './components/time';
diff --git a/packages/skins/src/minimal/tailwind/components/preview.ts b/packages/skins/src/minimal/tailwind/components/preview.ts
deleted file mode 100644
index 2689c3a4..00000000
--- a/packages/skins/src/minimal/tailwind/components/preview.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { cn } from '@videojs/utils/style';
-
-export const preview = {
- root: 'group/preview pointer-events-none',
- thumbnailWrapper: 'relative rounded-lg bg-black/90',
- thumbnail: cn('block rounded-[inherit] transition-opacity duration-150 ease-out', 'data-loading:opacity-0'),
- time: 'mt-2 block text-center tabular-nums',
- 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'
- ),
-};
diff --git a/packages/skins/src/minimal/tailwind/components/slider.ts b/packages/skins/src/minimal/tailwind/components/slider.ts
index 0a50dcc6..12ba821a 100644
--- a/packages/skins/src/minimal/tailwind/components/slider.ts
+++ b/packages/skins/src/minimal/tailwind/components/slider.ts
@@ -40,7 +40,7 @@ export const slider = {
base: cn(
'z-10 absolute size-3 -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.15)),0_1px_3px_0_oklch(0_0_0/0.15),0_1px_2px_-1px_oklch(0_0_0/0.15)]',
'transition-[opacity,scale,outline-offset] duration-150 ease-out select-none',
'outline-2 outline-transparent -outline-offset-2',
'focus-visible:outline-current focus-visible:outline-offset-2',
@@ -55,4 +55,21 @@ export const slider = {
'group-focus-within/slider:opacity-100 group-focus-within/slider:scale-100'
),
},
+ preview: cn(
+ 'group/preview',
+ 'before:block before:bg-current/35 before:opacity-0 before:scale-50',
+ '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',
+ 'data-[orientation=horizontal]:before:min-w-px data-[orientation=horizontal]:before:h-5',
+ 'data-[orientation=vertical]:before:w-5 data-[orientation=vertical]:before:min-h-px',
+ 'peer-has-[[role=img]:not([data-hidden])]/thumbnail:*:hidden'
+ ),
+ value: cn(
+ 'absolute bottom-6 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'
+ ),
};
diff --git a/packages/skins/src/minimal/tailwind/components/thumbnail.ts b/packages/skins/src/minimal/tailwind/components/thumbnail.ts
new file mode 100644
index 00000000..6861cf23
--- /dev/null
+++ b/packages/skins/src/minimal/tailwind/components/thumbnail.ts
@@ -0,0 +1,13 @@
+import { cn } from '@videojs/utils/style';
+
+export const thumbnail = {
+ root: 'group/thumbnail peer/thumbnail pointer-events-none',
+ imageWrapper: 'relative rounded-lg bg-black/90',
+ image: cn('block rounded-[inherit] transition-opacity duration-150 ease-out', 'data-loading:opacity-0'),
+ time: 'mt-2 block text-center tabular-nums',
+ 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]]/thumbnail:[--media-spinner-animation:none] group-has-[[role=img][data-loading]]/thumbnail:opacity-100'
+ ),
+};
diff --git a/packages/skins/src/minimal/tailwind/video.tailwind.ts b/packages/skins/src/minimal/tailwind/video.tailwind.ts
index 64cffd64..00b7fd10 100644
--- a/packages/skins/src/minimal/tailwind/video.tailwind.ts
+++ b/packages/skins/src/minimal/tailwind/video.tailwind.ts
@@ -3,9 +3,9 @@ import { buttonGroup as baseButtonGroup } from './components/button-group';
import { controls as baseControls } from './components/controls';
import { error as baseError } from './components/error';
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 { thumbnail as baseThumbnail } from './components/thumbnail';
import { time as baseTime } from './components/time';
/* ==========================================================================
@@ -139,28 +139,29 @@ export const error = {
};
/* ==========================================================================
- Preview
+ Thumbnail
========================================================================== */
-export const preview = {
- ...basePreview,
+export const thumbnail = {
+ ...baseThumbnail,
root: cn(
- '[--media-preview-max-width:11rem] [--media-preview-padding:-0.5rem] [--media-preview-inset:calc(100cqi-100%)]',
- 'absolute [left:clamp(calc(var(--media-preview-max-width)/2+var(--media-preview-padding)),var(--media-slider-pointer),calc(100%-var(--media-preview-max-width)/2-var(--media-preview-padding)+var(--media-preview-inset)))] bottom-full -translate-x-1/2',
- '@2xl/media-root:bottom-[calc(100%+0.25rem)] @2xl/media-root:[left:var(--media-slider-pointer)]',
+ baseThumbnail.root,
+ '[--media-slider-thumbnail-max-width:11rem] [--media-slider-thumbnail-padding:-0.5rem] [--media-slider-thumbnail-inset:calc(100cqi-100%)]',
+ 'absolute [left:clamp(calc(var(--media-slider-thumbnail-max-width)/2+var(--media-slider-thumbnail-padding)),var(--media-slider-pointer),calc(100%-var(--media-slider-thumbnail-max-width)/2-var(--media-slider-thumbnail-padding)+var(--media-slider-thumbnail-inset)))] bottom-full -translate-x-1/2',
+ '@2xl/media-root:[left:var(--media-slider-pointer)]',
'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',
- 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'
),
- thumbnailWrapper: cn(
- basePreview.thumbnailWrapper,
+ imageWrapper: cn(
+ baseThumbnail.imageWrapper,
'after:absolute after:inset-0 after:rounded-[inherit]',
'after:ring-1 after:ring-black/5 after:shadow-sm after:shadow-black/20'
),
- thumbnail: cn(basePreview.thumbnail, 'max-w-(--media-preview-max-width)'),
+ image: cn(baseThumbnail.image, 'max-w-(--media-slider-thumbnail-max-width)'),
};
/* ==========================================================================