mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(skin): extract transition properties into CSS custom properties (#1075)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
df927f67fc
commit
657e7111b4
@@ -215,6 +215,22 @@ Information must not rely on color alone (WCAG 1.4.1).
|
||||
|
||||
### No Reduced Motion Support
|
||||
|
||||
It's not always required to completely nuke transitions/animations. Sometimes we can instead reduce their duration and delay. People enabling reduced motion often still benefit from some transition - it helps orientation and avoids jarring state changes.
|
||||
|
||||
```css
|
||||
--transition-duration: 200ms;
|
||||
--animation-duration: 200ms;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.popup {
|
||||
--transition-duration: 50ms;
|
||||
--animation-duration: 50ms;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Remove non-essential motion - e.g. parallax, large transforms, bouncing, zooming, auto-playing animations.
|
||||
|
||||
```css
|
||||
.element {
|
||||
animation: bounce 1s infinite;
|
||||
|
||||
@@ -19,8 +19,8 @@ Accessibility patterns specific to video and audio players. Covers controls, key
|
||||
The root player element needs proper identification:
|
||||
|
||||
```html
|
||||
<div
|
||||
role="region"
|
||||
<div
|
||||
role="region"
|
||||
aria-label="Video Player: {title}"
|
||||
tabindex="-1"
|
||||
>
|
||||
@@ -29,6 +29,7 @@ The root player element needs proper identification:
|
||||
```
|
||||
|
||||
**Attributes:**
|
||||
|
||||
- `role="region"` or `role="application"` (if fully keyboard-managed)
|
||||
- `aria-label` includes media type and title
|
||||
- `tabindex="-1"` allows programmatic focus
|
||||
@@ -57,6 +58,7 @@ The root player element needs proper identification:
|
||||
### Key Scope
|
||||
|
||||
Configure whether shortcuts work:
|
||||
|
||||
- **Document-wide**: Work anywhere on page (YouTube-style)
|
||||
- **Player-scoped**: Only when player has focus
|
||||
|
||||
@@ -82,6 +84,7 @@ Use toolbar pattern with roving tabindex:
|
||||
```
|
||||
|
||||
**Navigation:**
|
||||
|
||||
- `Tab` enters/exits toolbar (single stop)
|
||||
- `←` `→` moves between controls
|
||||
- `Enter`/`Space` activates control
|
||||
@@ -123,6 +126,7 @@ aria-orientation="horizontal"
|
||||
```
|
||||
|
||||
**Key behavior:**
|
||||
|
||||
- `←` `→`: Seek by step (5 seconds)
|
||||
- `PageUp` `PageDown`: Seek by large step (10%)
|
||||
- `Home` `End`: Start/end of video
|
||||
@@ -166,8 +170,8 @@ aria-keyshortcuts="c"
|
||||
### Menu Structure
|
||||
|
||||
```html
|
||||
<button
|
||||
aria-haspopup="menu"
|
||||
<button
|
||||
aria-haspopup="menu"
|
||||
aria-expanded="{isOpen}"
|
||||
aria-controls="settings-menu"
|
||||
aria-label="Settings"
|
||||
@@ -208,9 +212,9 @@ aria-keyshortcuts="c"
|
||||
Create a dedicated live region for status messages:
|
||||
|
||||
```html
|
||||
<div
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
<div
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
aria-atomic="true"
|
||||
class="visually-hidden"
|
||||
>
|
||||
@@ -244,6 +248,7 @@ Create a dedicated live region for status messages:
|
||||
### CVAA Compliance Requirements
|
||||
|
||||
Users must be able to customize:
|
||||
|
||||
- Font family
|
||||
- Font size
|
||||
- Font color
|
||||
@@ -311,7 +316,7 @@ Audio description tracks should be clearly labeled.
|
||||
## Live/Streaming Indicator
|
||||
|
||||
```html
|
||||
<button
|
||||
<button
|
||||
aria-label="Go to live"
|
||||
aria-hidden="{!isLive}"
|
||||
>
|
||||
@@ -320,6 +325,7 @@ Audio description tracks should be clearly labeled.
|
||||
```
|
||||
|
||||
For live streams, indicate:
|
||||
|
||||
- Whether currently at live edge
|
||||
- Option to jump to live edge
|
||||
|
||||
@@ -330,18 +336,21 @@ For live streams, indicate:
|
||||
### After Fullscreen
|
||||
|
||||
When exiting fullscreen, return focus to:
|
||||
|
||||
1. The fullscreen button
|
||||
2. Or the last focused control
|
||||
|
||||
### Menu Close
|
||||
|
||||
When closing settings menu:
|
||||
|
||||
1. Return focus to settings button
|
||||
2. Keep user in control bar context
|
||||
|
||||
### Control Bar Hide/Show
|
||||
|
||||
When controls auto-hide:
|
||||
|
||||
- Keep focus on last active control
|
||||
- Don't trap focus on hidden elements
|
||||
- Re-show controls on `Tab` key
|
||||
@@ -350,21 +359,33 @@ When controls auto-hide:
|
||||
|
||||
## Reduced Motion
|
||||
|
||||
Respect `prefers-reduced-motion`:
|
||||
It's not always required to completely nuke transitions/animations. Sometimes we can instead reduce their duration and delay. People enabling reduced motion often still benefit from some transition - it helps orientation and avoids jarring state changes.
|
||||
|
||||
```css
|
||||
--transition-duration: 200ms;
|
||||
--animation-duration: 200ms;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.player-animation {
|
||||
animation: none;
|
||||
transition: none;
|
||||
.popup {
|
||||
--transition-duration: 50ms;
|
||||
--animation-duration: 50ms;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Consider:
|
||||
- Disable auto-playing animations
|
||||
- Reduce or remove control transitions
|
||||
- Pause decorative motion
|
||||
Remove non-essential motion - e.g. parallax, large transforms, bouncing, zooming, auto-playing animations.
|
||||
|
||||
```css
|
||||
.element {
|
||||
animation: bounce 1s infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.element {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -219,12 +219,29 @@ Animating `height: auto` requires measurement.
|
||||
|
||||
## Reduced Motion
|
||||
|
||||
Respect user preferences:
|
||||
It's not always required to completely nuke transitions/animations. Sometimes we can instead reduce their duration and delay. People enabling reduced motion often still benefit from some transition - it helps orientation and avoids jarring state changes.
|
||||
|
||||
```css
|
||||
--transition-duration: 200ms;
|
||||
--animation-duration: 200ms;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.popup {
|
||||
transition: none;
|
||||
--transition-duration: 50ms;
|
||||
--animation-duration: 50ms;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Remove non-essential motion - e.g. parallax, large transforms, bouncing, zooming, auto-playing animations.
|
||||
|
||||
```css
|
||||
.element {
|
||||
animation: bounce 1s infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.element {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ const ERROR_CLASSNAMES = {
|
||||
title: 'media-error__title',
|
||||
description: 'media-error__description',
|
||||
actions: 'media-error__actions',
|
||||
close: 'media-button media-button--subtle',
|
||||
close: 'media-button media-button--primary',
|
||||
};
|
||||
|
||||
export type MinimalVideoSkinProps = BaseVideoSkinProps;
|
||||
|
||||
@@ -42,12 +42,12 @@ const SEEK_TIME = 10;
|
||||
|
||||
const ERROR_CLASSNAMES = {
|
||||
root: 'media-error',
|
||||
dialog: 'media-error__dialog',
|
||||
dialog: 'media-error__dialog media-surface',
|
||||
content: 'media-error__content',
|
||||
title: 'media-error__title',
|
||||
description: 'media-error__description',
|
||||
actions: 'media-error__actions',
|
||||
close: 'media-button media-button--subtle',
|
||||
close: 'media-button media-button--primary',
|
||||
};
|
||||
|
||||
export type VideoSkinProps = BaseVideoSkinProps;
|
||||
|
||||
@@ -24,6 +24,16 @@
|
||||
--media-surface-shadow-color: oklch(0 0 0 / 0.15);
|
||||
--media-surface-backdrop-filter: blur(16px) saturate(1.5);
|
||||
--media-text-color: var(--media-color-primary, oklch(0 0 0));
|
||||
--media-error-dialog-transition-duration: 250ms;
|
||||
--media-error-dialog-transition-delay: 100ms;
|
||||
--media-popup-transition-duration: 100ms;
|
||||
--media-popup-transition-timing-function: ease-out;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
--media-error-dialog-transition-duration: 50ms;
|
||||
--media-error-dialog-transition-delay: 0ms;
|
||||
--media-popup-transition-duration: 0ms;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--media-border-color: oklch(1 0 0 / 0.1);
|
||||
@@ -45,19 +55,13 @@
|
||||
gap: 0.75rem;
|
||||
padding-inline: 1.25rem 0.125rem;
|
||||
transition-property: opacity, filter;
|
||||
transition-duration: 300ms;
|
||||
transition-delay: 100ms;
|
||||
transition-duration: var(--media-error-dialog-transition-duration);
|
||||
transition-delay: var(--media-error-dialog-transition-delay);
|
||||
transition-timing-function: ease-out;
|
||||
border-radius: calc(infinity * 1px);
|
||||
background-color: var(--media-surface-background-color);
|
||||
backdrop-filter: var(--media-surface-backdrop-filter);
|
||||
color: var(--media-text-color);
|
||||
|
||||
/* Simple, fast transition for reduced motion users */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition-duration: 100ms;
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
}
|
||||
|
||||
.media-default-skin .media-error[data-starting-style] .media-error__dialog,
|
||||
@@ -65,6 +69,9 @@
|
||||
opacity: 0;
|
||||
filter: blur(4px);
|
||||
}
|
||||
.media-default-skin .media-error[data-ending-style] .media-error__dialog {
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
|
||||
.media-default-skin--audio .media-error__content {
|
||||
flex: 1;
|
||||
|
||||
@@ -10,27 +10,20 @@
|
||||
backdrop-filter: blur(0) saturate(1.5);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition-property: opacity, backdrop-filter;
|
||||
transition-duration: var(--media-controls-transition-duration);
|
||||
transition-delay: var(--media-controls-transition-delay);
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
@media (pointer: fine) {
|
||||
transition-property: opacity, backdrop-filter;
|
||||
transition-duration: 300ms;
|
||||
transition-delay: 500ms;
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition-duration: 100ms;
|
||||
}
|
||||
}
|
||||
.media-default-skin .media-error ~ .media-overlay {
|
||||
transition-duration: var(--media-error-dialog-transition-duration);
|
||||
transition-delay: var(--media-error-dialog-transition-delay);
|
||||
}
|
||||
|
||||
.media-default-skin .media-controls[data-visible] ~ .media-overlay,
|
||||
.media-default-skin .media-error[data-open] ~ .media-overlay {
|
||||
opacity: 1;
|
||||
|
||||
@media (pointer: fine) {
|
||||
transition-duration: 150ms;
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
}
|
||||
|
||||
.media-default-skin .media-error[data-open] ~ .media-overlay {
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
color: inherit;
|
||||
overflow: visible;
|
||||
transition-property: scale, opacity, filter;
|
||||
transition-duration: 150ms;
|
||||
transition-duration: var(--media-popup-transition-duration);
|
||||
transition-timing-function: var(--media-popup-transition-timing-function);
|
||||
|
||||
&[data-starting-style],
|
||||
&[data-ending-style] {
|
||||
|
||||
@@ -23,6 +23,17 @@
|
||||
|
||||
.media-default-skin--video {
|
||||
background: oklch(0 0 0);
|
||||
--media-spring-transition: linear(
|
||||
0,
|
||||
0.034 1.5%,
|
||||
0.763 9.7%,
|
||||
1.066 13.9%,
|
||||
1.198 19.9%,
|
||||
1.184 21.8%,
|
||||
0.963 37.5%,
|
||||
0.997 50.9%,
|
||||
1
|
||||
);
|
||||
--media-border-color: oklch(0 0 0 / 0.1);
|
||||
--media-surface-background-color: oklch(1 0 0 / 0.1);
|
||||
--media-surface-inner-border-color: oklch(1 0 0 / 0.05);
|
||||
@@ -32,6 +43,19 @@
|
||||
--media-video-border-radius: var(--media-border-radius, 2rem);
|
||||
--media-controls-transition-duration: 100ms;
|
||||
--media-controls-transition-delay: 0ms;
|
||||
--media-controls-transition-timing-function: ease-out;
|
||||
--media-error-dialog-transition-duration: 350ms;
|
||||
--media-error-dialog-transition-delay: 100ms;
|
||||
--media-error-dialog-transition-timing-function: var(--media-spring-transition);
|
||||
--media-popup-transition-duration: 100ms;
|
||||
--media-popup-transition-timing-function: ease-out;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
--media-error-dialog-transition-duration: 50ms;
|
||||
--media-error-dialog-transition-delay: 0ms;
|
||||
--media-error-dialog-transition-timing-function: ease-out;
|
||||
--media-popup-transition-duration: 0ms;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--media-border-color: oklch(1 0 0 / 0.15);
|
||||
@@ -47,7 +71,7 @@
|
||||
--media-controls-transition-duration: 150ms;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
--media-controls-transition-duration: 100ms;
|
||||
--media-controls-transition-duration: 50ms;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,33 +114,19 @@
|
||||
color: oklch(1 0 0);
|
||||
text-shadow: 0 1px 0 oklch(0 0 0 / 0.25);
|
||||
transition-property: opacity, scale;
|
||||
transition-duration: 500ms;
|
||||
transition-delay: 100ms;
|
||||
transition-timing-function: linear(
|
||||
0,
|
||||
0.034 1.5%,
|
||||
0.763 9.7%,
|
||||
1.066 13.9%,
|
||||
1.198 19.9%,
|
||||
1.184 21.8%,
|
||||
0.963 37.5%,
|
||||
0.997 50.9%,
|
||||
1
|
||||
);
|
||||
|
||||
/* Simple, fast transition for reduced motion users */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition-duration: 100ms;
|
||||
transition-delay: 0ms;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
transition-duration: var(--media-error-dialog-transition-duration);
|
||||
transition-delay: var(--media-error-dialog-transition-delay);
|
||||
transition-timing-function: var(--media-error-dialog-transition-timing-function);
|
||||
}
|
||||
|
||||
.media-default-skin .media-error[data-starting-style] .media-error__dialog,
|
||||
.media-default-skin .media-error[data-ending-style] .media-error__dialog {
|
||||
.media-default-skin--video .media-error[data-starting-style] .media-error__dialog,
|
||||
.media-default-skin--video .media-error[data-ending-style] .media-error__dialog {
|
||||
opacity: 0;
|
||||
scale: 0.5;
|
||||
}
|
||||
.media-default-skin--video .media-error[data-ending-style] .media-error__dialog {
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
|
||||
.media-default-skin--video .media-error__content {
|
||||
display: flex;
|
||||
@@ -140,9 +150,9 @@
|
||||
inset-inline: 0.75rem;
|
||||
z-index: 10;
|
||||
color: var(--media-color-primary, oklch(1 0 0));
|
||||
transition-timing-function: ease-out;
|
||||
transition-duration: var(--media-controls-transition-duration);
|
||||
transition-delay: var(--media-controls-transition-delay);
|
||||
transition-timing-function: var(--media-controls-transition-timing-function);
|
||||
transform-origin: bottom;
|
||||
|
||||
@media (pointer: fine) {
|
||||
@@ -160,12 +170,8 @@
|
||||
pointer-events: none;
|
||||
scale: 0.9;
|
||||
|
||||
@media (pointer: fine) {
|
||||
@media (pointer: fine) and (prefers-reduced-motion: no-preference) {
|
||||
filter: blur(8px);
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
filter: blur(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
@@ -194,7 +200,7 @@
|
||||
box-shadow: 0 0 0 1px oklch(0 0 0 / 0.05);
|
||||
}
|
||||
|
||||
.media-default-skin .media-slider__preview {
|
||||
.media-default-skin--video .media-slider__preview {
|
||||
position: absolute;
|
||||
left: var(--media-slider-pointer);
|
||||
bottom: calc(100% + 1.2rem);
|
||||
@@ -216,7 +222,7 @@
|
||||
max-height: 6rem;
|
||||
}
|
||||
}
|
||||
.media-default-skin .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
|
||||
.media-default-skin--video .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
filter: blur(0);
|
||||
|
||||
@@ -14,6 +14,13 @@ import { surface as baseSurface } from './components/surface';
|
||||
export const root = cn(
|
||||
baseRoot,
|
||||
'[--media-text-color:var(--media-color-primary,oklch(0_0_0))]',
|
||||
'[--media-error-dialog-transition-duration:250ms]',
|
||||
'[--media-error-dialog-transition-delay:100ms]',
|
||||
'[--media-popup-transition-duration:100ms]',
|
||||
'[--media-popup-transition-timing-function:ease-out]',
|
||||
'motion-reduce:[--media-error-dialog-transition-duration:50ms]',
|
||||
'motion-reduce:[--media-error-dialog-transition-delay:0ms]',
|
||||
'motion-reduce:[--media-popup-transition-duration:0ms]',
|
||||
'dark:[--media-text-color:var(--media-color-primary,oklch(1_0_0))]'
|
||||
);
|
||||
|
||||
@@ -79,10 +86,12 @@ export const error = {
|
||||
'absolute inset-0 z-20 flex items-center gap-3 rounded-full px-5 pr-0.5',
|
||||
'bg-(--media-surface-background-color) text-(--media-text-color)',
|
||||
'backdrop-blur-lg backdrop-saturate-150',
|
||||
'transition-[opacity,filter] duration-300 delay-100 ease-out',
|
||||
'transition-[opacity,filter] ease-out',
|
||||
'duration-(--media-error-dialog-transition-duration)',
|
||||
'delay-(--media-error-dialog-transition-delay)',
|
||||
'group-data-starting-style/error:opacity-0 group-data-starting-style/error:blur-[4px]',
|
||||
'group-data-ending-style/error:opacity-0 group-data-ending-style/error:blur-[4px]',
|
||||
'motion-reduce:duration-100 motion-reduce:delay-0'
|
||||
'group-data-ending-style/error:delay-0'
|
||||
),
|
||||
content: 'flex flex-1 items-center gap-2',
|
||||
};
|
||||
|
||||
@@ -5,12 +5,13 @@ export const error = {
|
||||
dialog: cn(
|
||||
'flex flex-col gap-3 max-w-72 p-3 rounded-[1.75rem] text-white',
|
||||
// Animation
|
||||
'transition-[opacity,scale,transform] duration-500 delay-100',
|
||||
'ease-[linear(0,0.034_1.5%,0.763_9.7%,1.066_13.9%,1.198_19.9%,1.184_21.8%,0.963_37.5%,0.997_50.9%,1)]',
|
||||
'transition-[opacity,scale,transform]',
|
||||
'duration-(--media-error-dialog-transition-duration)',
|
||||
'delay-(--media-error-dialog-transition-delay)',
|
||||
'ease-(--media-error-dialog-transition-timing-function)',
|
||||
'group-data-starting-style/error:opacity-0 group-data-starting-style/error:scale-50',
|
||||
'group-data-ending-style/error:opacity-0 group-data-ending-style/error:scale-50',
|
||||
// Simple, fast transition for reduced motion users
|
||||
'motion-reduce:duration-100 motion-reduce:ease-out motion-reduce:delay-0'
|
||||
'group-data-ending-style/error:delay-0'
|
||||
),
|
||||
content: 'flex flex-col gap-2 px-2 pt-2 pb-1.5',
|
||||
title: 'font-semibold leading-tight',
|
||||
|
||||
@@ -8,19 +8,16 @@ export const overlay = cn(
|
||||
'opacity-0',
|
||||
'bg-linear-to-t from-black/50 via-black/30 to-transparent',
|
||||
'backdrop-blur-none backdrop-saturate-150',
|
||||
// Transitions (fine pointer only)
|
||||
'[@media(pointer:fine)]:transition-[opacity,backdrop-filter]',
|
||||
'[@media(pointer:fine)]:ease-out',
|
||||
'[@media(pointer:fine)]:duration-300 [@media(pointer:fine)]:delay-500',
|
||||
// Transitions
|
||||
'transition-[opacity,backdrop-filter]',
|
||||
'duration-(--media-controls-transition-duration)',
|
||||
'delay-(--media-controls-transition-delay)',
|
||||
'ease-out',
|
||||
// Shown when controls visible
|
||||
'peer-data-visible/controls:opacity-100',
|
||||
'[@media(pointer:fine)]:peer-data-visible/controls:duration-150',
|
||||
'[@media(pointer:fine)]:peer-data-visible/controls:delay-0',
|
||||
// Shown when error visible (+ blur)
|
||||
'peer-data-open/error:opacity-100',
|
||||
'[@media(pointer:fine)]:peer-data-open/error:duration-150',
|
||||
'[@media(pointer:fine)]:peer-data-open/error:delay-0',
|
||||
'peer-data-open/error:backdrop-blur-lg',
|
||||
// Reduced motion
|
||||
'[@media(pointer:fine)]:motion-reduce:duration-100'
|
||||
'peer-data-open/error:duration-(--media-error-dialog-transition-duration)',
|
||||
'peer-data-open/error:delay-(--media-error-dialog-transition-delay)',
|
||||
'peer-data-open/error:backdrop-blur-lg'
|
||||
);
|
||||
|
||||
@@ -4,7 +4,9 @@ const base = cn(
|
||||
// Reset default popover styles
|
||||
'm-0 border-0 text-inherit overflow-visible',
|
||||
// Animation
|
||||
'transition-[transform,scale,opacity,filter] duration-150',
|
||||
'transition-[transform,scale,opacity,filter]',
|
||||
'duration-(--media-popup-transition-duration)',
|
||||
'ease-(--media-popup-transition-timing-function)',
|
||||
'data-starting-style:opacity-0 data-starting-style:scale-50 data-starting-style:blur-sm',
|
||||
'data-ending-style:opacity-0 data-ending-style:scale-50 data-ending-style:blur-sm',
|
||||
'data-instant:duration-0',
|
||||
|
||||
@@ -26,13 +26,24 @@ export const root = (isShadowDOM: boolean) =>
|
||||
'[&_video]:block [&_video]:w-full [&_video]:h-full [&_video]:rounded-[inherit] [&_video]:[object-fit:var(--media-object-fit,contain)] [&_video]:[object-position:var(--media-object-position,center)]':
|
||||
!isShadowDOM,
|
||||
},
|
||||
'[--media-spring-transition:linear(0,0.034_1.5%,0.763_9.7%,1.066_13.9%,1.198_19.9%,1.184_21.8%,0.963_37.5%,0.997_50.9%,1)]',
|
||||
'[--media-video-border-radius:var(--media-border-radius,2rem)]',
|
||||
'[--media-controls-transition-duration:100ms]',
|
||||
'[--media-controls-transition-delay:0ms]',
|
||||
'[--media-controls-transition-timing-function:ease-out]',
|
||||
'[--media-error-dialog-transition-duration:350ms]',
|
||||
'[--media-error-dialog-transition-delay:100ms]',
|
||||
'[--media-error-dialog-transition-timing-function:var(--media-spring-transition)]',
|
||||
'[--media-popup-transition-duration:100ms]',
|
||||
'[--media-popup-transition-timing-function:ease-out]',
|
||||
'motion-reduce:[--media-error-dialog-transition-duration:50ms]',
|
||||
'motion-reduce:[--media-error-dialog-transition-delay:0ms]',
|
||||
'motion-reduce:[--media-error-dialog-transition-timing-function:ease-out]',
|
||||
'motion-reduce:[--media-popup-transition-duration:0ms]',
|
||||
'[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-delay:500ms]',
|
||||
'[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:300ms]',
|
||||
'[@media(pointer:coarse)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:150ms]',
|
||||
'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:100ms]',
|
||||
'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:50ms]',
|
||||
// Caption track CSS variables (consumed by the native caption bridge in light DOM)
|
||||
'[--media-caption-track-y:-0.5rem]',
|
||||
'[--media-caption-track-delay:calc(var(--media-controls-transition-delay)_+_25ms)]',
|
||||
@@ -88,7 +99,7 @@ export const controls = cn(
|
||||
'absolute bottom-3 inset-x-3',
|
||||
'[color:var(--media-color-primary,oklch(1_0_0))] z-10',
|
||||
'peer-data-open/error:hidden',
|
||||
'ease-out origin-bottom',
|
||||
'ease-(--media-controls-transition-timing-function) origin-bottom',
|
||||
'duration-(--media-controls-transition-duration)',
|
||||
'delay-(--media-controls-transition-delay)',
|
||||
'[@media(pointer:fine)]:will-change-[scale,filter,opacity]',
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
--media-controls-border-color: oklch(0 0 0 / 0.1);
|
||||
--media-controls-padding: 0.375rem;
|
||||
--media-text-color: var(--media-color-primary, oklch(0 0 0));
|
||||
--media-error-dialog-transition-duration: 250ms;
|
||||
--media-error-dialog-transition-delay: 100ms;
|
||||
--media-popup-transition-duration: 100ms;
|
||||
--media-popup-transition-timing-function: ease-out;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
--media-error-dialog-transition-duration: 50ms;
|
||||
--media-error-dialog-transition-delay: 0ms;
|
||||
--media-popup-transition-duration: 0ms;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--media-controls-background-color: oklch(0 0 0);
|
||||
@@ -41,25 +51,22 @@
|
||||
gap: 1rem;
|
||||
padding-inline: 1.25rem 0.5rem;
|
||||
transition-property: opacity, filter, scale;
|
||||
transition-duration: 300ms;
|
||||
transition-delay: 100ms;
|
||||
transition-duration: var(--media-error-dialog-transition-duration);
|
||||
transition-delay: var(--media-error-dialog-transition-delay);
|
||||
transition-timing-function: ease-out;
|
||||
border-radius: calc(infinity * 1px);
|
||||
background-color: oklch(from var(--media-controls-background-color) l c h / 1);
|
||||
|
||||
/* Simple, fast transition for reduced motion users */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition-duration: 100ms;
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
}
|
||||
|
||||
.media-minimal-skin .media-error[data-starting-style] .media-error__dialog,
|
||||
.media-minimal-skin .media-error[data-ending-style] .media-error__dialog {
|
||||
.media-minimal-skin--audio .media-error[data-starting-style] .media-error__dialog,
|
||||
.media-minimal-skin--audio .media-error[data-ending-style] .media-error__dialog {
|
||||
opacity: 0;
|
||||
filter: blur(4px);
|
||||
scale: 0.95;
|
||||
}
|
||||
.media-minimal-skin--audio .media-error[data-ending-style] .media-error__dialog {
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
|
||||
.media-minimal-skin--audio .media-error__content {
|
||||
flex: 1;
|
||||
|
||||
@@ -10,27 +10,20 @@
|
||||
backdrop-filter: blur(0) saturate(1.5);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition-property: opacity, backdrop-filter;
|
||||
transition-duration: var(--media-controls-transition-duration);
|
||||
transition-delay: var(--media-controls-transition-delay);
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
@media (pointer: fine) {
|
||||
transition-property: opacity, backdrop-filter;
|
||||
transition-duration: 500ms;
|
||||
transition-delay: 500ms;
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition-duration: 100ms;
|
||||
}
|
||||
}
|
||||
.media-minimal-skin .media-error ~ .media-overlay {
|
||||
transition-duration: var(--media-error-dialog-transition-duration);
|
||||
transition-delay: var(--media-error-dialog-transition-delay);
|
||||
}
|
||||
|
||||
.media-minimal-skin .media-controls[data-visible] ~ .media-overlay,
|
||||
.media-minimal-skin .media-error[data-open] ~ .media-overlay {
|
||||
opacity: 1;
|
||||
|
||||
@media (pointer: fine) {
|
||||
transition-duration: 150ms;
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
}
|
||||
|
||||
.media-minimal-skin .media-error[data-open] ~ .media-overlay {
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
color: inherit;
|
||||
overflow: visible;
|
||||
transition-property: scale, opacity, filter;
|
||||
transition-duration: 150ms;
|
||||
transition-duration: var(--media-popup-transition-duration);
|
||||
transition-timing-function: var(--media-popup-transition-timing-function);
|
||||
|
||||
&[data-starting-style],
|
||||
&[data-ending-style] {
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
--media-controls-padding: 0.375rem;
|
||||
--media-controls-transition-duration: 100ms;
|
||||
--media-controls-transition-delay: 0ms;
|
||||
--media-controls-transition-timing-function: ease-out;
|
||||
--media-error-dialog-transition-duration: 250ms;
|
||||
--media-error-dialog-transition-delay: 100ms;
|
||||
--media-error-dialog-transition-timing-function: ease-out;
|
||||
--media-popup-transition-duration: 100ms;
|
||||
--media-popup-transition-timing-function: ease-out;
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
--media-error-dialog-transition-duration: 50ms;
|
||||
--media-error-dialog-transition-delay: 0ms;
|
||||
--media-popup-transition-duration: 0ms;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--media-border-color: oklch(1 0 0 / 0.15);
|
||||
@@ -43,7 +55,7 @@
|
||||
--media-controls-transition-duration: 150ms;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
--media-controls-transition-duration: 100ms;
|
||||
--media-controls-transition-duration: 50ms;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,27 +100,10 @@
|
||||
color: oklch(1 0 0);
|
||||
text-shadow: 0 1px 0 oklch(0 0 0 / 0.5);
|
||||
transition-property: opacity, scale;
|
||||
transition-duration: 500ms;
|
||||
transition-delay: 100ms;
|
||||
transition-timing-function: linear(
|
||||
0,
|
||||
0.034 1.5%,
|
||||
0.763 9.7%,
|
||||
1.066 13.9%,
|
||||
1.198 19.9%,
|
||||
1.184 21.8%,
|
||||
0.963 37.5%,
|
||||
0.997 50.9%,
|
||||
1
|
||||
);
|
||||
transition-duration: var(--media-error-dialog-transition-duration);
|
||||
transition-delay: var(--media-error-dialog-transition-delay);
|
||||
transition-timing-function: var(--media-error-dialog-transition-timing-function);
|
||||
pointer-events: auto;
|
||||
|
||||
/* Simple, fast transition for reduced motion users */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition-duration: 100ms;
|
||||
transition-delay: 0ms;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.media-minimal-skin--video .media-error[data-starting-style] .media-error__dialog,
|
||||
@@ -116,6 +111,9 @@
|
||||
opacity: 0;
|
||||
scale: 0.5;
|
||||
}
|
||||
.media-minimal-skin--video .media-error[data-ending-style] .media-error__dialog {
|
||||
transition-delay: 0ms;
|
||||
}
|
||||
|
||||
.media-minimal-skin--video .media-error__content {
|
||||
display: flex;
|
||||
@@ -146,7 +144,7 @@
|
||||
color: var(--media-color-primary, oklch(1 0 0));
|
||||
transition-duration: var(--media-controls-transition-duration);
|
||||
transition-delay: var(--media-controls-transition-delay);
|
||||
transition-timing-function: ease-out;
|
||||
transition-timing-function: var(--media-controls-transition-timing-function);
|
||||
|
||||
@media (pointer: fine) {
|
||||
will-change: translate, filter, opacity;
|
||||
@@ -206,7 +204,7 @@
|
||||
Slider preview
|
||||
========================================================================== */
|
||||
|
||||
.media-minimal-skin .media-slider__preview {
|
||||
.media-minimal-skin--video .media-slider__preview {
|
||||
position: absolute;
|
||||
left: var(--media-slider-pointer);
|
||||
bottom: calc(100% + 0.5rem);
|
||||
@@ -242,7 +240,7 @@
|
||||
max-height: 6rem;
|
||||
}
|
||||
}
|
||||
.media-minimal-skin .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
|
||||
.media-minimal-skin--video .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
filter: blur(0);
|
||||
|
||||
@@ -14,6 +14,13 @@ export const root = cn(
|
||||
'[--media-controls-border-color:oklch(0_0_0/0.1)]',
|
||||
'[--media-controls-padding:0.375rem]',
|
||||
'[--media-text-color:var(--media-color-primary,oklch(0_0_0))]',
|
||||
'[--media-error-dialog-transition-duration:250ms]',
|
||||
'[--media-error-dialog-transition-delay:100ms]',
|
||||
'[--media-popup-transition-duration:100ms]',
|
||||
'[--media-popup-transition-timing-function:ease-out]',
|
||||
'motion-reduce:[--media-error-dialog-transition-duration:50ms]',
|
||||
'motion-reduce:[--media-error-dialog-transition-delay:0ms]',
|
||||
'motion-reduce:[--media-popup-transition-duration:0ms]',
|
||||
'dark:[--media-controls-background-color:oklch(0_0_0)]',
|
||||
'dark:[--media-controls-border-color:oklch(1_0_0/0.1)]',
|
||||
'dark:[--media-text-color:var(--media-color-primary,oklch(1_0_0))]'
|
||||
@@ -61,10 +68,12 @@ export const error = {
|
||||
dialog: cn(
|
||||
'absolute inset-0 z-20 flex items-center gap-4 rounded-full px-5 pr-2',
|
||||
'bg-(--media-controls-background-color)',
|
||||
'transition-[opacity,filter,scale] duration-300 delay-100 ease-out',
|
||||
'transition-[opacity,filter,scale] ease-out',
|
||||
'duration-(--media-error-dialog-transition-duration)',
|
||||
'delay-(--media-error-dialog-transition-delay)',
|
||||
'group-data-starting-style/error:opacity-0 group-data-starting-style/error:blur-[4px] group-data-starting-style/error:scale-95',
|
||||
'group-data-ending-style/error:opacity-0 group-data-ending-style/error:blur-[4px] group-data-ending-style/error:scale-95',
|
||||
'motion-reduce:duration-100 motion-reduce:delay-0'
|
||||
'group-data-ending-style/error:delay-0'
|
||||
),
|
||||
content: 'flex flex-1 items-center gap-2',
|
||||
};
|
||||
|
||||
@@ -6,12 +6,13 @@ export const error = {
|
||||
'flex flex-col gap-3 max-w-64 p-4 text-white',
|
||||
'text-shadow-2xs text-shadow-black/50',
|
||||
// Animation
|
||||
'transition-[opacity,scale,transform] duration-500 delay-100',
|
||||
'ease-[linear(0,0.034_1.5%,0.763_9.7%,1.066_13.9%,1.198_19.9%,1.184_21.8%,0.963_37.5%,0.997_50.9%,1)]',
|
||||
'transition-[opacity,scale,transform]',
|
||||
'duration-(--media-error-dialog-transition-duration)',
|
||||
'delay-(--media-error-dialog-transition-delay)',
|
||||
'ease-(--media-error-dialog-transition-timing-function)',
|
||||
'group-data-starting-style/error:opacity-0 group-data-starting-style/error:scale-50',
|
||||
'group-data-ending-style/error:opacity-0 group-data-ending-style/error:scale-50',
|
||||
// Simple, fast transition for reduced motion users
|
||||
'motion-reduce:duration-100 motion-reduce:ease-out motion-reduce:delay-0'
|
||||
'group-data-ending-style/error:delay-0'
|
||||
),
|
||||
content: 'flex flex-col gap-2 py-1.5',
|
||||
title: 'font-semibold leading-tight',
|
||||
|
||||
@@ -8,19 +8,16 @@ export const overlay = cn(
|
||||
'opacity-0',
|
||||
'bg-linear-to-t from-black/70 via-black/50 via-[7.5rem] to-transparent',
|
||||
'backdrop-blur-none backdrop-saturate-150',
|
||||
// Transitions (fine pointer only)
|
||||
'[@media(pointer:fine)]:transition-[opacity,backdrop-filter]',
|
||||
'[@media(pointer:fine)]:ease-out',
|
||||
'[@media(pointer:fine)]:duration-500 [@media(pointer:fine)]:delay-500',
|
||||
// Transitions
|
||||
'transition-[opacity,backdrop-filter]',
|
||||
'duration-(--media-controls-transition-duration)',
|
||||
'delay-(--media-controls-transition-delay)',
|
||||
'ease-out',
|
||||
// Shown when controls visible
|
||||
'peer-data-visible/controls:opacity-100',
|
||||
'[@media(pointer:fine)]:peer-data-visible/controls:duration-150',
|
||||
'[@media(pointer:fine)]:peer-data-visible/controls:delay-0',
|
||||
// Shown when error visible (+ blur)
|
||||
'peer-data-open/error:opacity-100',
|
||||
'[@media(pointer:fine)]:peer-data-open/error:duration-150',
|
||||
'[@media(pointer:fine)]:peer-data-open/error:delay-0',
|
||||
'peer-data-open/error:backdrop-blur-lg',
|
||||
// Reduced motion
|
||||
'[@media(pointer:fine)]:motion-reduce:duration-100'
|
||||
'peer-data-open/error:duration-(--media-error-dialog-transition-duration)',
|
||||
'peer-data-open/error:delay-(--media-error-dialog-transition-delay)',
|
||||
'peer-data-open/error:backdrop-blur-lg'
|
||||
);
|
||||
|
||||
@@ -4,7 +4,9 @@ const base = cn(
|
||||
// Reset default popover styles
|
||||
'm-0 border-0 text-inherit overflow-visible',
|
||||
// Animation
|
||||
'transition-[transform,scale,opacity,filter] duration-150',
|
||||
'transition-[transform,scale,opacity,filter]',
|
||||
'duration-(--media-popup-transition-duration)',
|
||||
'ease-(--media-popup-transition-timing-function)',
|
||||
'data-starting-style:opacity-0 data-starting-style:scale-50 data-starting-style:blur-sm',
|
||||
'data-ending-style:opacity-0 data-ending-style:scale-50 data-ending-style:blur-sm',
|
||||
'data-instant:duration-0',
|
||||
|
||||
@@ -28,10 +28,19 @@ export const root = (isShadowDOM: boolean) =>
|
||||
'[--media-controls-padding:0.375rem]',
|
||||
'[--media-controls-transition-duration:100ms]',
|
||||
'[--media-controls-transition-delay:0ms]',
|
||||
'[--media-controls-transition-timing-function:ease-out]',
|
||||
'[--media-error-dialog-transition-duration:250ms]',
|
||||
'[--media-error-dialog-transition-delay:100ms]',
|
||||
'[--media-error-dialog-transition-timing-function:ease-out]',
|
||||
'[--media-popup-transition-duration:100ms]',
|
||||
'[--media-popup-transition-timing-function:ease-out]',
|
||||
'motion-reduce:[--media-error-dialog-transition-duration:50ms]',
|
||||
'motion-reduce:[--media-error-dialog-transition-delay:0ms]',
|
||||
'motion-reduce:[--media-popup-transition-duration:0ms]',
|
||||
'[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-delay:500ms]',
|
||||
'[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:300ms]',
|
||||
'[@media(pointer:coarse)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:150ms]',
|
||||
'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:100ms]',
|
||||
'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:50ms]',
|
||||
// Caption track CSS variables (consumed by the native caption bridge in light DOM)
|
||||
'[--media-caption-track-y:-0.5rem]',
|
||||
'[--media-caption-track-delay:calc(var(--media-controls-transition-delay)_+_25ms)]',
|
||||
@@ -69,7 +78,7 @@ export const controls = cn(
|
||||
'pt-8 px-(--media-controls-padding) pb-(--media-controls-padding) gap-2',
|
||||
'[color:var(--media-color-primary,oklch(1_0_0))] z-10',
|
||||
'peer-data-open/error:hidden',
|
||||
'ease-out',
|
||||
'ease-(--media-controls-transition-timing-function)',
|
||||
'duration-(--media-controls-transition-duration)',
|
||||
'delay-(--media-controls-transition-delay)',
|
||||
'[@media(pointer:fine)]:will-change-[translate,filter,opacity]',
|
||||
|
||||
Reference in New Issue
Block a user