mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(skins): slightly more idiomatic Tailwind, added custom properties (#175)
This commit is contained in:
@@ -33,12 +33,12 @@ export default function FrostedSkin({ children, className = '' }: SkinProps): JS
|
||||
|
||||
<div className={styles.Overlay} />
|
||||
|
||||
<div className={`${styles.Surface} ${styles.Controls}`} data-testid="media-controls">
|
||||
<div className={`${styles.Surface} ${styles.Controls}`}>
|
||||
<Tooltip.Root delay={500}>
|
||||
<Tooltip.Trigger>
|
||||
<PlayButton className={`${styles.Button} ${styles.IconButton} ${styles.PlayButton}`}>
|
||||
<PlayIcon className={`${styles.PlayIcon} ${styles.Icon}`} />
|
||||
<PauseIcon className={`${styles.PauseIcon} ${styles.Icon}`} />
|
||||
<PlayButton className={`${styles.Button} ${styles.IconButton}`}>
|
||||
<PlayIcon className={`${styles.Icon} ${styles.PlayIcon}`} />
|
||||
<PauseIcon className={`${styles.Icon} ${styles.PauseIcon}`} />
|
||||
</PlayButton>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
@@ -82,10 +82,10 @@ export default function FrostedSkin({ children, className = '' }: SkinProps): JS
|
||||
|
||||
<Popover.Root openOnHover delay={200} closeDelay={100}>
|
||||
<Popover.Trigger>
|
||||
<MuteButton className={`${styles.Button} ${styles.IconButton} ${styles.MuteButton}`}>
|
||||
<VolumeHighIcon className={`${styles.VolumeHighIcon} ${styles.Icon}`} />
|
||||
<VolumeLowIcon className={`${styles.VolumeLowIcon} ${styles.Icon}`} />
|
||||
<VolumeOffIcon className={`${styles.VolumeOffIcon} ${styles.Icon}`} />
|
||||
<MuteButton className={`${styles.Button} ${styles.IconButton}`}>
|
||||
<VolumeHighIcon className={`${styles.Icon} ${styles.VolumeHighIcon}`} />
|
||||
<VolumeLowIcon className={`${styles.Icon} ${styles.VolumeLowIcon}`} />
|
||||
<VolumeOffIcon className={`${styles.Icon} ${styles.VolumeOffIcon}`} />
|
||||
</MuteButton>
|
||||
</Popover.Trigger>
|
||||
<Popover.Portal>
|
||||
@@ -104,9 +104,9 @@ export default function FrostedSkin({ children, className = '' }: SkinProps): JS
|
||||
|
||||
<Tooltip.Root delay={500}>
|
||||
<Tooltip.Trigger>
|
||||
<FullscreenButton className={`${styles.Button} ${styles.IconButton} ${styles.FullscreenButton}`}>
|
||||
<FullscreenEnterIcon className={`${styles.FullscreenEnterIcon} ${styles.Icon}`} />
|
||||
<FullscreenExitIcon className={`${styles.FullscreenExitIcon} ${styles.Icon}`} />
|
||||
<FullscreenButton className={`${styles.Button} ${styles.IconButton}`}>
|
||||
<FullscreenEnterIcon className={`${styles.Icon} ${styles.FullscreenEnterIcon} `} />
|
||||
<FullscreenExitIcon className={`${styles.Icon} ${styles.FullscreenExitIcon}`} />
|
||||
</FullscreenButton>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
|
||||
@@ -3,6 +3,3 @@
|
||||
@import 'tailwindcss/utilities.css' layer(utilities) prefix(vjs);
|
||||
/* Custom variants used by the frosted skin */
|
||||
@custom-variant reduced-transparency @media (prefers-reduced-transparency: reduce);
|
||||
.vjs {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
@@ -12,24 +12,25 @@ function cn(...classes: (string | undefined)[]): string {
|
||||
const styles: FrostedSkinStyles = {
|
||||
MediaContainer: cn(
|
||||
'vjs', // Scope preflight
|
||||
'vjs:relative vjs:isolate vjs:@container/root vjs:group/root vjs:overflow-clip vjs:bg-black',
|
||||
'vjs:relative vjs:isolate vjs:@container/root vjs:group/root vjs:overflow-clip vjs:bg-black vjs:rounded-(--vjs-border-radius,2rem)',
|
||||
// Base typography
|
||||
'vjs:text-[0.8125rem]', // 13px
|
||||
// Fancy borders.
|
||||
'vjs:text-[0.8125rem]',
|
||||
// Fancy borders
|
||||
'vjs:after:absolute vjs:after:inset-0 vjs:after:ring-black/10 vjs:after:ring-1 vjs:dark:after:ring-white/10 vjs:after:ring-inset vjs:after:z-10 vjs:after:pointer-events-none vjs:after:rounded-[inherit]',
|
||||
'vjs:before:absolute vjs:before:inset-px vjs:before:rounded-[inherit] vjs:before:ring-white/15 vjs:before:ring-1 vjs:before:ring-inset vjs:before:z-10 vjs:before:pointer-events-none vjs:dark:before:ring-0',
|
||||
// Prevent rounded corners in fullscreen.
|
||||
// Prevent rounded corners in fullscreen
|
||||
'vjs:[&:fullscreen]:rounded-none',
|
||||
// Ensure the nested video inherits the radius.
|
||||
// Ensure the nested video inherits the radius
|
||||
'vjs:[&_video]:w-full vjs:[&_video]:h-full',
|
||||
),
|
||||
Overlay: cn(
|
||||
'vjs:opacity-0 vjs:delay-500 vjs:duration-300 vjs:rounded-[inherit] vjs:absolute vjs:inset-0 vjs:pointer-events-none vjs:bg-gradient-to-t vjs:from-black/50 vjs:via-black/20 vjs:to-transparent vjs:transition-opacity vjs:backdrop-saturate-150 vjs:backdrop-brightness-90',
|
||||
// Hide when playing (for now).
|
||||
// ------------------------------------
|
||||
// FIXME: This is crude temporary logic, we'll improve it later I guess with a [data-show-controls] attribute or something?
|
||||
'vjs:has-[+.controls_[data-paused]]:opacity-100 vjs:has-[+.controls_[data-paused]]:delay-0 vjs:has-[+.controls_[data-paused]]:duration-100',
|
||||
'vjs:has-[+.controls_[aria-expanded="true"]]:opacity-100 vjs:has-[+.controls_[aria-expanded="true"]]:delay-0 vjs:has-[+.controls_[aria-expanded="true"]]:duration-100',
|
||||
'vjs:group-hover/root:opacity-100 vjs:group-hover/root:delay-0 vjs:group-hover/root:duration-100',
|
||||
// ------------------------------------
|
||||
),
|
||||
Surface: cn(
|
||||
'vjs:bg-white/10 vjs:backdrop-blur-3xl vjs:backdrop-saturate-150 vjs:backdrop-brightness-90',
|
||||
@@ -44,18 +45,22 @@ const styles: FrostedSkinStyles = {
|
||||
'vjs:contrast-more:bg-black/90 vjs:contrast-more:ring-black vjs:contrast-more:after:ring-white/20',
|
||||
),
|
||||
Controls: cn(
|
||||
// ------------------------------------
|
||||
// FIXME: Temporary className hook for above logic in the overlay. Can be removed once have a proper way to handle controls visibility.
|
||||
'controls',
|
||||
// ------------------------------------
|
||||
'vjs:@container/controls vjs:absolute vjs:inset-x-3 vjs:bottom-3 vjs:rounded-full vjs:flex vjs:items-center vjs:p-1 vjs:gap-0.5 vjs:text-white',
|
||||
// Animation
|
||||
'vjs:transition vjs:will-change-[transform,scale,filter,opacity] vjs:origin-bottom vjs:ease-out',
|
||||
// FIXME: Temporary className hook for above logic in the overlay. Can be removed once have a proper way to handle controls visibility.
|
||||
'controls',
|
||||
// FIXME: Temporary hide/show logic
|
||||
// ------------------------------------
|
||||
// FIXME: Temporary hide/show logic, related to above.
|
||||
'vjs:scale-90 vjs:opacity-0 vjs:blur-sm vjs:delay-500 vjs:duration-300',
|
||||
'vjs:has-[[data-paused]]:scale-100 vjs:has-[[data-paused]]:opacity-100 vjs:has-[[data-paused]]:blur-none vjs:has-[[data-paused]]:delay-0 vjs:has-[[data-paused]]:duration-100',
|
||||
'vjs:has-[[aria-expanded="true"]]:scale-100 vjs:has-[[aria-expanded="true"]]:opacity-100 vjs:has-[[aria-expanded="true"]]:blur-none vjs:has-[[aria-expanded="true"]]:delay-0 vjs:has-[[aria-expanded="true"]]:duration-100',
|
||||
'vjs:group-hover/root:scale-100 vjs:group-hover/root:opacity-100 vjs:group-hover/root:blur-none vjs:group-hover/root:delay-0 vjs:group-hover/root:duration-100',
|
||||
// ------------------------------------
|
||||
),
|
||||
Icon: cn('icon'),
|
||||
Icon: cn('icon vjs:[&_path]:transition-transform vjs:[&_path]:ease-out'),
|
||||
Button: cn(
|
||||
'vjs:group/button vjs:cursor-pointer vjs:relative vjs:shrink-0 vjs:transition-[color,background,outline-offset] vjs:select-none vjs:p-2 vjs:rounded-full',
|
||||
// Background/foreground
|
||||
@@ -75,48 +80,32 @@ const styles: FrostedSkinStyles = {
|
||||
'vjs:grid vjs:[&_.icon]:[grid-area:1/1]',
|
||||
'vjs:[&_.icon]:shrink-0 vjs:[&_.icon]:transition-opacity vjs:[&_.icon]:duration-150 vjs:[&_.icon]:ease-linear vjs:[&_.icon]:drop-shadow-[0_1px_0_var(--tw-shadow-color)] vjs:[&_.icon]:shadow-black/25',
|
||||
),
|
||||
PlayButton: cn(
|
||||
'vjs:[&_.pause-icon]:opacity-100 vjs:[&[data-paused]_.pause-icon]:opacity-0',
|
||||
'vjs:[&_.play-icon]:opacity-0 vjs:[&[data-paused]_.play-icon]:opacity-100',
|
||||
),
|
||||
PlayIcon: cn('play-icon'),
|
||||
PauseIcon: cn('pause-icon'),
|
||||
PlayIcon: cn('vjs:opacity-0 vjs:group-data-paused/button:opacity-100'),
|
||||
PauseIcon: cn('vjs:group-data-paused/button:opacity-0'),
|
||||
PlayTooltipPopup: cn(
|
||||
'vjs:[&_.pause-tooltip]:inline vjs:[&[data-paused]_.pause-tooltip]:hidden',
|
||||
'vjs:[&_.play-tooltip]:hidden vjs:[&[data-paused]_.play-tooltip]:inline',
|
||||
'vjs:[&_.pause-tooltip]:inline vjs:[&_.play-tooltip]:hidden',
|
||||
'vjs:data-paused:[&_.pause-tooltip]:hidden vjs:data-paused:[&_.play-tooltip]:inline',
|
||||
),
|
||||
PlayTooltip: cn('play-tooltip'),
|
||||
PauseTooltip: cn('pause-tooltip'),
|
||||
MuteButton: cn(
|
||||
'vjs:[&_.icon]:hidden',
|
||||
'vjs:[&[data-volume-level="high"]_.volume-high-icon]:inline',
|
||||
'vjs:[&[data-volume-level="medium"]_.volume-low-icon]:inline',
|
||||
'vjs:[&[data-volume-level="low"]_.volume-low-icon]:inline',
|
||||
'vjs:[&[data-volume-level="off"]_.volume-off-icon]:inline',
|
||||
),
|
||||
VolumeHighIcon: cn('volume-high-icon'),
|
||||
VolumeLowIcon: cn('volume-low-icon'),
|
||||
VolumeOffIcon: cn('volume-off-icon'),
|
||||
FullscreenButton: cn(
|
||||
'vjs:[&_.fullscreen-enter-icon]:opacity-100 vjs:[&[data-fullscreen]_.fullscreen-enter-icon]:opacity-0',
|
||||
'vjs:[&_.fullscreen-exit-icon]:opacity-0 vjs:[&[data-fullscreen]_.fullscreen-exit-icon]:opacity-100',
|
||||
'vjs:[&_path]:transition-transform vjs:ease-out',
|
||||
),
|
||||
VolumeHighIcon: cn('vjs:hidden vjs:group-data-[volume-level=high]/button:inline vjs:group-data-[volume-level=medium]/button:inline'),
|
||||
VolumeLowIcon: cn('vjs:hidden vjs:group-data-[volume-level=low]/button:inline'),
|
||||
VolumeOffIcon: cn('vjs:hidden vjs:group-data-[volume-level=off]/button:inline'),
|
||||
FullscreenEnterIcon: cn(
|
||||
'fullscreen-enter-icon',
|
||||
'vjs:group-data-fullscreen/button:hidden',
|
||||
'vjs:group-hover/button:[&_.arrow-1]:-translate-x-px vjs:group-hover/button:[&_.arrow-1]:-translate-y-px',
|
||||
'vjs:group-hover/button:[&_.arrow-2]:translate-x-px vjs:group-hover/button:[&_.arrow-2]:translate-y-px',
|
||||
),
|
||||
FullscreenExitIcon: cn(
|
||||
'fullscreen-exit-icon',
|
||||
'vjs:hidden vjs:group-data-fullscreen/button:inline',
|
||||
'vjs:[&_.arrow-1]:-translate-x-px vjs:[&_.arrow-1]:-translate-y-px',
|
||||
'vjs:[&_.arrow-2]:translate-x-px vjs:[&_.arrow-2]:translate-y-px',
|
||||
'vjs:group-hover/button:[&_.arrow-1]:translate-0',
|
||||
'vjs:group-hover/button:[&_.arrow-2]:translate-0',
|
||||
),
|
||||
FullscreenTooltipPopup: cn(
|
||||
'vjs:[&_.fullscreen-enter-tooltip]:inline vjs:[&[data-fullscreen]_.fullscreen-enter-tooltip]:hidden',
|
||||
'vjs:[&_.fullscreen-exit-tooltip]:hidden vjs:[&[data-fullscreen]_.fullscreen-exit-tooltip]:inline',
|
||||
'vjs:[&_.fullscreen-enter-tooltip]:inline vjs:data-fullscreen:[&_.fullscreen-enter-tooltip]:hidden',
|
||||
'vjs:[&_.fullscreen-exit-tooltip]:hidden vjs:data-fullscreen:[&_.fullscreen-exit-tooltip]:inline',
|
||||
),
|
||||
FullscreenEnterTooltip: cn('fullscreen-enter-tooltip'),
|
||||
FullscreenExitTooltip: cn('fullscreen-exit-tooltip'),
|
||||
@@ -124,13 +113,13 @@ const styles: FrostedSkinStyles = {
|
||||
TimeDisplay: cn('vjs:tabular-nums vjs:text-shadow-2xs/25'),
|
||||
SliderRoot: cn(
|
||||
'vjs:group/slider vjs:outline-0 vjs:flex vjs:items-center vjs:justify-center vjs:flex-1 vjs:relative vjs:rounded-full',
|
||||
'vjs:[&[data-orientation="horizontal"]]:h-5 vjs:[&[data-orientation="horizontal"]]:min-w-20',
|
||||
'vjs:[&[data-orientation="vertical"]]:w-5 vjs:[&[data-orientation="vertical"]]:h-20',
|
||||
'vjs:data-[orientation=horizontal]:h-5 vjs:data-[orientation=horizontal]:min-w-20',
|
||||
'vjs:data-[orientation=vertical]:w-5 vjs:data-[orientation=vertical]:h-20',
|
||||
),
|
||||
SliderTrack: cn(
|
||||
'vjs:relative vjs:select-none vjs:transition-[outline-offset] vjs:rounded-[inherit] vjs:bg-white/20 vjs:ring-1 vjs:ring-black/5',
|
||||
'vjs:[&[data-orientation="horizontal"]]:w-full vjs:[&[data-orientation="horizontal"]]:h-1',
|
||||
'vjs:[&[data-orientation="vertical"]]:w-1',
|
||||
'vjs:data-[orientation=horizontal]:w-full vjs:data-[orientation=horizontal]:h-1',
|
||||
'vjs:data-[orientation=vertical]:w-1',
|
||||
'vjs:-outline-offset-2 vjs:group-focus-visible/slider:outline-2 vjs:group-focus-visible/slider:outline-offset-6 vjs:group-focus-visible/slider:outline-blue-500',
|
||||
),
|
||||
SliderProgress: cn('vjs:bg-white vjs:rounded-[inherit]'),
|
||||
@@ -140,22 +129,18 @@ const styles: FrostedSkinStyles = {
|
||||
'vjs:bg-white vjs:z-10 vjs:select-none vjs:ring vjs:ring-black/10 vjs:rounded-full vjs:shadow-sm vjs:shadow-black/15 vjs:opacity-0 vjs:transition-[opacity,height,width] vjs:ease-out',
|
||||
'vjs:group-hover/slider:opacity-100 vjs:group-focus-within/slider:opacity-100',
|
||||
'vjs:size-2.5 vjs:active:size-3 vjs:group-active/slider:size-3',
|
||||
'vjs:[&[data-orientation="horizontal"]]:hover:cursor-ew-resize',
|
||||
'vjs:[&[data-orientation="vertical"]]:hover:cursor-ns-resize',
|
||||
'vjs:data-[orientation=horizontal]:hover:cursor-ew-resize',
|
||||
'vjs:data-[orientation=vertical]:hover:cursor-ns-resize',
|
||||
),
|
||||
PopupAnimation: cn(
|
||||
// Animation
|
||||
// XXX: We can't use transforms since floating UI uses them for positioning.
|
||||
'vjs:transition-[transform,scale,opacity,filter] vjs:origin-bottom vjs:duration-200 vjs:data-[instant]:duration-0',
|
||||
'vjs:data-[starting-style]:scale-0 vjs:data-[starting-style]:opacity-0 vjs:data-[starting-style]:blur-sm',
|
||||
'vjs:data-[ending-style]:scale-0 vjs:data-[ending-style]:opacity-0 vjs:data-[ending-style]:blur-sm',
|
||||
),
|
||||
PopoverPopup: cn(
|
||||
'vjs:relative vjs:px-1 vjs:py-3 vjs:rounded-full',
|
||||
),
|
||||
TooltipPopup: cn(
|
||||
'vjs:whitespace-nowrap vjs:rounded-full vjs:text-white vjs:text-xs vjs:@7xl/root:text-sm vjs:px-2.5 vjs:py-1',
|
||||
'vjs:transition-[transform,scale,opacity,filter] vjs:origin-bottom vjs:duration-200 vjs:data-instant:duration-0',
|
||||
'vjs:data-starting-style:scale-0 vjs:data-starting-style:opacity-0 vjs:data-starting-style:blur-sm',
|
||||
'vjs:data-ending-style:scale-0 vjs:data-ending-style:opacity-0 vjs:data-ending-style:blur-sm',
|
||||
),
|
||||
PopoverPopup: cn('vjs:relative vjs:px-1 vjs:py-3 vjs:rounded-full'),
|
||||
TooltipPopup: cn('vjs:whitespace-nowrap vjs:rounded-full vjs:text-white vjs:text-xs vjs:@7xl/root:text-sm vjs:px-2.5 vjs:py-1'),
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,17 +6,14 @@ export interface FrostedSkinStyles {
|
||||
readonly Icon: string;
|
||||
readonly Button: string;
|
||||
readonly IconButton: string;
|
||||
readonly PlayButton: string;
|
||||
readonly PlayIcon: string;
|
||||
readonly PauseIcon: string;
|
||||
readonly PlayTooltipPopup: string;
|
||||
readonly PlayTooltip: string;
|
||||
readonly PauseTooltip: string;
|
||||
readonly MuteButton: string;
|
||||
readonly VolumeHighIcon: string;
|
||||
readonly VolumeLowIcon: string;
|
||||
readonly VolumeOffIcon: string;
|
||||
readonly FullscreenButton: string;
|
||||
readonly FullscreenEnterIcon: string;
|
||||
readonly FullscreenExitIcon: string;
|
||||
readonly FullscreenTooltipPopup: string;
|
||||
|
||||
@@ -36,9 +36,9 @@ export default function MinimalSkin({ children, className = '' }: SkinProps): JS
|
||||
<div className={styles.Controls}>
|
||||
<Tooltip.Root delay={500} closeDelay={0}>
|
||||
<Tooltip.Trigger>
|
||||
<PlayButton className={`${styles.Button} ${styles.IconButton} ${styles.PlayButton}`}>
|
||||
<PlayIcon className={`${styles.PlayIcon} ${styles.Icon}`} />
|
||||
<PauseIcon className={`${styles.PauseIcon} ${styles.Icon}`} />
|
||||
<PlayButton className={`${styles.Button} ${styles.IconButton}`}>
|
||||
<PlayIcon className={`${styles.Icon} ${styles.PlayIcon}`} />
|
||||
<PauseIcon className={`${styles.Icon} ${styles.PauseIcon}`} />
|
||||
</PlayButton>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
@@ -86,10 +86,10 @@ export default function MinimalSkin({ children, className = '' }: SkinProps): JS
|
||||
<div className={styles.ButtonGroup}>
|
||||
<Popover.Root openOnHover delay={200} closeDelay={300}>
|
||||
<Popover.Trigger>
|
||||
<MuteButton className={`${styles.Button} ${styles.IconButton} ${styles.MuteButton}`}>
|
||||
<VolumeHighIcon className={`${styles.VolumeHighIcon} ${styles.Icon}`} />
|
||||
<VolumeLowIcon className={`${styles.VolumeLowIcon} ${styles.Icon}`} />
|
||||
<VolumeOffIcon className={`${styles.VolumeOffIcon} ${styles.Icon}`} />
|
||||
<MuteButton className={`${styles.Button} ${styles.IconButton}`}>
|
||||
<VolumeHighIcon className={`${styles.Icon} ${styles.VolumeHighIcon}`} />
|
||||
<VolumeLowIcon className={`${styles.Icon} ${styles.VolumeLowIcon}`} />
|
||||
<VolumeOffIcon className={`${styles.Icon} ${styles.VolumeOffIcon}`} />
|
||||
</MuteButton>
|
||||
</Popover.Trigger>
|
||||
<Popover.Portal>
|
||||
@@ -108,9 +108,9 @@ export default function MinimalSkin({ children, className = '' }: SkinProps): JS
|
||||
|
||||
<Tooltip.Root delay={500} closeDelay={0}>
|
||||
<Tooltip.Trigger>
|
||||
<FullscreenButton className={`${styles.Button} ${styles.IconButton} ${styles.FullscreenButton}`}>
|
||||
<FullscreenEnterAltIcon className={`${styles.FullscreenEnterIcon} ${styles.Icon}`} />
|
||||
<FullscreenExitAltIcon className={`${styles.FullscreenExitIcon} ${styles.Icon}`} />
|
||||
<FullscreenButton className={`${styles.Button} ${styles.IconButton}`}>
|
||||
<FullscreenEnterAltIcon className={`${styles.Icon} ${styles.FullscreenEnterIcon}`} />
|
||||
<FullscreenExitAltIcon className={`${styles.Icon} ${styles.FullscreenExitIcon}`} />
|
||||
</FullscreenButton>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
@layer theme, base, components, utilities;
|
||||
@import 'tailwindcss/theme.css' layer(theme) prefix(vjs);
|
||||
@import 'tailwindcss/utilities.css' layer(utilities) prefix(vjs);
|
||||
.vjs {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
@@ -12,38 +12,46 @@ function cn(...classes: (string | undefined)[]): string {
|
||||
const styles: MinimalSkinStyles = {
|
||||
MediaContainer: cn(
|
||||
'vjs', // Scope preflight
|
||||
'vjs:relative vjs:isolate vjs:@container/root vjs:group/root vjs:overflow-clip vjs:bg-black',
|
||||
'vjs:relative vjs:isolate vjs:@container/root vjs:group/root vjs:overflow-clip vjs:bg-black vjs:rounded-(--vjs-border-radius,0.75rem)',
|
||||
// Base typography
|
||||
'vjs:text-[0.8125rem]', // 13px
|
||||
'vjs:after:absolute vjs:after:inset-0 vjs:after:ring-black/20 vjs:after:ring-1 vjs:dark:after:ring-white/20 vjs:after:ring-inset vjs:after:z-10 vjs:after:pointer-events-none vjs:after:rounded-[inherit]',
|
||||
// Prevent rounded corners in fullscreen.
|
||||
'vjs:text-[0.8125rem]',
|
||||
// Fancy borders
|
||||
'vjs:after:absolute vjs:after:inset-0 vjs:after:ring-black/15 vjs:after:ring-1 vjs:dark:after:ring-white/15 vjs:after:ring-inset vjs:after:z-10 vjs:after:pointer-events-none vjs:after:rounded-[inherit]',
|
||||
// Prevent rounded corners in fullscreen
|
||||
'vjs:[&:fullscreen]:rounded-none',
|
||||
// Ensure the nested video inherits the radius.
|
||||
// Ensure the nested video inherits the radius
|
||||
'vjs:[&_video]:w-full vjs:[&_video]:h-full',
|
||||
),
|
||||
Overlay: cn(
|
||||
'vjs:absolute vjs:inset-0 vjs:rounded-[inherit] vjs:pointer-events-none',
|
||||
'vjs:bg-gradient-to-t vjs:from-black/70 vjs:via-black/50 vjs:via-[7.5rem] vjs:to-transparent',
|
||||
'vjs:opacity-0 vjs:delay-500 vjs:duration-300',
|
||||
// High contrast mode
|
||||
'vjs:contrast-more:from-black/75',
|
||||
// ------------------------------------
|
||||
// FIXME: Temporary hide/show logic
|
||||
'vjs:has-[+.controls_[data-paused]]:opacity-100 vjs:has-[+.controls_[data-paused]]:delay-0 vjs:has-[+.controls_[data-paused]]:duration-75',
|
||||
'vjs:has-[+.controls_[aria-expanded="true"]]:opacity-100 vjs:has-[+.controls_[aria-expanded="true"]]:delay-0 vjs:has-[+.controls_[aria-expanded="true"]]:duration-75',
|
||||
'vjs:group-hover/root:opacity-100 vjs:group-hover/root:delay-0 vjs:group-hover/root:duration-75',
|
||||
// High contrast mode
|
||||
'vjs:contrast-more:from-black/75',
|
||||
// ------------------------------------
|
||||
),
|
||||
Controls: cn(
|
||||
'controls', // FIXME: Temporary className hook for above logic in the overlay. Can be removed once have a proper way to handle controls visibility.
|
||||
// ------------------------------------
|
||||
// FIXME: Temporary className hook for above logic in the overlay. Can be removed once have a proper way to handle controls visibility.
|
||||
'controls',
|
||||
// ------------------------------------
|
||||
'vjs:@container/controls vjs:absolute vjs:inset-x-0 vjs:bottom-0 vjs:flex vjs:items-center vjs:gap-3.5 vjs:z-20 vjs:px-3 vjs:pb-3 vjs:pt-10 vjs:text-white',
|
||||
// Animation
|
||||
'vjs:transition vjs:will-change-[transform,filter,opacity] vjs:ease-out',
|
||||
// ------------------------------------
|
||||
// FIXME: Temporary hide/show logic
|
||||
'vjs:translate-y-full vjs:opacity-0 vjs:blur-sm vjs:delay-500 vjs:duration-300',
|
||||
'vjs:has-[[data-paused]]:translate-y-0 vjs:has-[[data-paused]]:opacity-100 vjs:has-[[data-paused]]:blur-none vjs:has-[[data-paused]]:delay-0 vjs:has-[[data-paused]]:duration-75',
|
||||
'vjs:has-[[aria-expanded="true"]]:translate-y-0 vjs:has-[[aria-expanded="true"]]:opacity-100 vjs:has-[[aria-expanded="true"]]:blur-none vjs:has-[[aria-expanded="true"]]:delay-0 vjs:has-[[aria-expanded="true"]]:duration-75',
|
||||
'vjs:group-hover/root:translate-y-0 vjs:group-hover/root:opacity-100 vjs:group-hover/root:blur-none vjs:group-hover/root:delay-0 vjs:group-hover/root:duration-75',
|
||||
// ------------------------------------
|
||||
),
|
||||
Icon: cn('icon'),
|
||||
Icon: cn('icon vjs:[&_path]:transition-transform vjs:[&_path]:ease-out'),
|
||||
TimeDisplayGroup: cn('flex items-center gap-1'),
|
||||
Button: cn(
|
||||
'vjs:group/button vjs:cursor-pointer vjs:relative vjs:shrink-0 vjs:transition-[color,background,outline-offset] vjs:select-none vjs:p-2.5 vjs:rounded-md',
|
||||
@@ -65,48 +73,32 @@ const styles: MinimalSkinStyles = {
|
||||
'vjs:grid vjs:[&_.icon]:[grid-area:1/1]',
|
||||
'vjs:[&_.icon]:shrink-0 vjs:[&_.icon]:transition-opacity vjs:[&_.icon]:duration-150 vjs:[&_.icon]:ease-linear vjs:[&_.icon]:drop-shadow-[0_1px_0_var(--tw-shadow-color)] vjs:[&_.icon]:shadow-black/40',
|
||||
),
|
||||
PlayButton: cn(
|
||||
'vjs:[&_.pause-icon]:opacity-100 vjs:[&[data-paused]_.pause-icon]:opacity-0',
|
||||
'vjs:[&_.play-icon]:opacity-0 vjs:[&[data-paused]_.play-icon]:opacity-100',
|
||||
),
|
||||
PlayIcon: cn('play-icon'),
|
||||
PauseIcon: cn('pause-icon'),
|
||||
PlayIcon: cn('vjs:opacity-0 vjs:group-data-paused/button:opacity-100'),
|
||||
PauseIcon: cn('vjs:group-data-paused/button:opacity-0'),
|
||||
PlayTooltipPopup: cn(
|
||||
'vjs:[&_.pause-tooltip]:inline vjs:[&[data-paused]_.pause-tooltip]:hidden',
|
||||
'vjs:[&_.play-tooltip]:hidden vjs:[&[data-paused]_.play-tooltip]:inline',
|
||||
'vjs:[&_.pause-tooltip]:inline vjs:data-paused:[&_.pause-tooltip]:hidden',
|
||||
'vjs:[&_.play-tooltip]:hidden vjs:data-paused:[&_.play-tooltip]:inline',
|
||||
),
|
||||
PlayTooltip: cn('play-tooltip'),
|
||||
PauseTooltip: cn('pause-tooltip'),
|
||||
MuteButton: cn(
|
||||
'vjs:[&_.icon]:hidden',
|
||||
'vjs:[&[data-volume-level="high"]_.volume-high-icon]:inline',
|
||||
'vjs:[&[data-volume-level="medium"]_.volume-low-icon]:inline',
|
||||
'vjs:[&[data-volume-level="low"]_.volume-low-icon]:inline',
|
||||
'vjs:[&[data-volume-level="off"]_.volume-off-icon]:inline',
|
||||
),
|
||||
VolumeHighIcon: cn('volume-high-icon'),
|
||||
VolumeLowIcon: cn('volume-low-icon'),
|
||||
VolumeOffIcon: cn('volume-off-icon'),
|
||||
FullscreenButton: cn(
|
||||
'vjs:[&_.fullscreen-enter-icon]:opacity-100 vjs:[&[data-fullscreen]_.fullscreen-enter-icon]:opacity-0',
|
||||
'vjs:[&_.fullscreen-exit-icon]:opacity-0 vjs:[&[data-fullscreen]_.fullscreen-exit-icon]:opacity-100',
|
||||
'vjs:[&_path]:transition-transform vjs:ease-out',
|
||||
),
|
||||
VolumeHighIcon: cn('vjs:hidden vjs:group-data-[volume-level=high]/button:inline vjs:group-data-[volume-level=medium]/button:inline'),
|
||||
VolumeLowIcon: cn('vjs:hidden vjs:group-data-[volume-level=low]/button:inline'),
|
||||
VolumeOffIcon: cn('vjs:hidden vjs:group-data-[volume-level=off]/button:inline'),
|
||||
FullscreenEnterIcon: cn(
|
||||
'fullscreen-enter-icon',
|
||||
'vjs:group-data-fullscreen/button:hidden',
|
||||
'vjs:group-hover/button:[&_.arrow-1]:translate-x-px vjs:group-hover/button:[&_.arrow-1]:-translate-y-px',
|
||||
'vjs:group-hover/button:[&_.arrow-2]:-translate-x-px vjs:group-hover/button:[&_.arrow-2]:translate-y-px',
|
||||
),
|
||||
FullscreenExitIcon: cn(
|
||||
'fullscreen-exit-icon',
|
||||
'vjs:hidden vjs:group-data-fullscreen/button:inline',
|
||||
'vjs:[&_.arrow-1]:translate-x-px vjs:[&_.arrow-1]:-translate-y-px',
|
||||
'vjs:[&_.arrow-2]:-translate-x-px vjs:[&_.arrow-2]:translate-y-px',
|
||||
'vjs:group-hover/button:[&_.arrow-1]:translate-0',
|
||||
'vjs:group-hover/button:[&_.arrow-2]:translate-0',
|
||||
),
|
||||
FullscreenTooltipPopup: cn(
|
||||
'vjs:[&_.fullscreen-enter-tooltip]:inline vjs:[&[data-fullscreen]_.fullscreen-enter-tooltip]:hidden',
|
||||
'vjs:[&_.fullscreen-exit-tooltip]:hidden vjs:[&[data-fullscreen]_.fullscreen-exit-tooltip]:inline',
|
||||
'vjs:[&_.fullscreen-enter-tooltip]:inline vjs:data-fullscreen:[&_.fullscreen-enter-tooltip]:hidden',
|
||||
'vjs:[&_.fullscreen-exit-tooltip]:hidden vjs:data-fullscreen:[&_.fullscreen-exit-tooltip]:inline',
|
||||
),
|
||||
FullscreenEnterTooltip: cn('fullscreen-enter-tooltip'),
|
||||
FullscreenExitTooltip: cn('fullscreen-exit-tooltip'),
|
||||
@@ -115,13 +107,13 @@ const styles: MinimalSkinStyles = {
|
||||
DurationDisplay: cn('vjs:text-white/50 vjs:contents'),
|
||||
SliderRoot: cn(
|
||||
'vjs:group/slider vjs:outline-0 vjs:flex vjs:items-center vjs:justify-center vjs:flex-1 vjs:group/slider vjs:relative vjs:rounded-full',
|
||||
'vjs:[&[data-orientation="horizontal"]]:h-5 vjs:[&[data-orientation="horizontal"]]:min-w-20',
|
||||
'vjs:[&[data-orientation="vertical"]]:w-5 vjs:[&[data-orientation="vertical"]]:h-18',
|
||||
'vjs:data-[orientation=horizontal]:h-5 vjs:data-[orientation=horizontal]:min-w-20',
|
||||
'vjs:data-[orientation=vertical]:w-5 vjs:data-[orientation=vertical]:h-18',
|
||||
),
|
||||
SliderTrack: cn(
|
||||
'vjs:relative vjs:select-none vjs:rounded-[inherit] vjs:bg-white/10',
|
||||
'vjs:[&[data-orientation="horizontal"]]:w-full vjs:[&[data-orientation="horizontal"]]:h-[0.1875rem]',
|
||||
'vjs:[&[data-orientation="vertical"]]:w-[0.1875rem]',
|
||||
'vjs:data-[orientation=horizontal]:w-full vjs:data-[orientation=horizontal]:h-[0.1875rem]',
|
||||
'vjs:data-[orientation=vertical]:w-[0.1875rem]',
|
||||
'vjs:-outline-offset-2 vjs:group-focus-visible/slider:outline-2 vjs:group-focus-visible/slider:outline-offset-6 vjs:group-focus-visible/slider:outline-white',
|
||||
),
|
||||
SliderProgress: cn('vjs:bg-white vjs:rounded-[inherit]'),
|
||||
@@ -129,19 +121,17 @@ const styles: MinimalSkinStyles = {
|
||||
SliderThumb: cn(
|
||||
'vjs:bg-white vjs:z-10 vjs:size-3 vjs:select-none vjs:ring vjs:ring-black/10 vjs:rounded-full vjs:shadow-sm vjs:shadow-black/15 vjs:transition-[opacity,scale] vjs:ease-out vjs:opacity-0 vjs:scale-70 vjs:origin-center',
|
||||
'vjs:group-hover/slider:opacity-100 vjs:group-hover/slider:scale-100',
|
||||
'vjs:[&[data-orientation="horizontal"]]:hover:cursor-ew-resize',
|
||||
'vjs:[&[data-orientation="vertical"]]:hover:cursor-ns-resize',
|
||||
'vjs:data-[orientation=horizontal]:hover:cursor-ew-resize',
|
||||
'vjs:data-[orientation=vertical]:hover:cursor-ns-resize',
|
||||
),
|
||||
PopupAnimation: cn(
|
||||
// Animation
|
||||
// XXX: We can't use transforms since floating UI uses them for positioning.
|
||||
'vjs:transition-[transform,scale,opacity,filter] vjs:origin-bottom vjs:duration-200 vjs:data-[instant]:duration-0',
|
||||
'vjs:data-[starting-style]:scale-0 vjs:data-[starting-style]:opacity-0 vjs:data-[starting-style]:blur-sm',
|
||||
'vjs:data-[ending-style]:scale-0 vjs:data-[ending-style]:opacity-0 vjs:data-[ending-style]:blur-sm',
|
||||
),
|
||||
PopoverPopup: cn(
|
||||
'vjs:py-2',
|
||||
'vjs:transition-[transform,scale,opacity,filter] vjs:origin-bottom vjs:duration-200 vjs:data-instant:duration-0',
|
||||
'vjs:data-starting-style:scale-0 vjs:data-starting-style:opacity-0 vjs:data-starting-style:blur-sm',
|
||||
'vjs:data-ending-style:scale-0 vjs:data-ending-style:opacity-0 vjs:data-ending-style:blur-sm',
|
||||
),
|
||||
PopoverPopup: cn('vjs:py-2'),
|
||||
TooltipPopup: cn(
|
||||
'vjs:whitespace-nowrap vjs:flex vjs:flex-col vjs:rounded vjs:text-white vjs:text-xs vjs:@7xl/root:text-sm vjs:px-2 vjs:py-1 vjs:bg-white/20 vjs:backdrop-blur-3xl vjs:backdrop-saturate-150 vjs:backdrop-brightness-90 vjs:shadow-md vjs:shadow-black/5',
|
||||
),
|
||||
|
||||
@@ -6,17 +6,14 @@ export interface MinimalSkinStyles {
|
||||
readonly Button: string;
|
||||
readonly ButtonGroup: string;
|
||||
readonly IconButton: string;
|
||||
readonly PlayButton: string;
|
||||
readonly PlayIcon: string;
|
||||
readonly PauseIcon: string;
|
||||
readonly PlayTooltipPopup: string;
|
||||
readonly PlayTooltip: string;
|
||||
readonly PauseTooltip: string;
|
||||
readonly MuteButton: string;
|
||||
readonly VolumeHighIcon: string;
|
||||
readonly VolumeLowIcon: string;
|
||||
readonly VolumeOffIcon: string;
|
||||
readonly FullscreenButton: string;
|
||||
readonly FullscreenEnterIcon: string;
|
||||
readonly FullscreenExitIcon: string;
|
||||
readonly FullscreenTooltipPopup: string;
|
||||
|
||||
Reference in New Issue
Block a user