mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(skin): add audio skins for HTML and React presets (#772)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
038ad8b4f5
commit
d751fdabea
@@ -0,0 +1,37 @@
|
||||
/* ==========================================================================
|
||||
Icon State Visibility for Audio Skins
|
||||
|
||||
Data-attribute-driven visibility rules for multi-state icon buttons.
|
||||
Uses :is() with both element selectors (for HTML custom element wrappers)
|
||||
and class selectors (for React rendered SVG elements).
|
||||
========================================================================== */
|
||||
|
||||
/* --- All icons hidden by default --- */
|
||||
|
||||
.media-button--play .media-icon--restart,
|
||||
.media-button--play .media-icon--play,
|
||||
.media-button--play .media-icon--pause,
|
||||
.media-button--mute .media-icon--volume-off,
|
||||
.media-button--mute .media-icon--volume-low,
|
||||
.media-button--mute .media-icon--volume-high {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* --- Active icon per state --- */
|
||||
|
||||
/* Play: ended → restart */
|
||||
.media-button--play[data-ended] .media-icon--restart,
|
||||
/* Play: paused (not ended) → play */
|
||||
.media-button--play:not([data-ended])[data-paused] .media-icon--play,
|
||||
/* Play: playing (not paused, not ended) → pause */
|
||||
.media-button--play:not([data-paused]):not([data-ended]) .media-icon--pause,
|
||||
/* Mute: muted → volume off */
|
||||
.media-button--mute[data-muted] .media-icon--volume-off,
|
||||
/* Mute: volume low (not muted) → volume low */
|
||||
.media-button--mute:not([data-muted])[data-volume-level="low"] .media-icon--volume-low,
|
||||
/* Mute: volume high (not muted, not low) → volume high */
|
||||
.media-button--mute:not([data-muted]):not([data-volume-level="low"]) .media-icon--volume-high {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/* ==========================================================================
|
||||
Native Caption Bridge
|
||||
---------------------------------------------------------------------------
|
||||
Receives CSS custom properties set by any skin and applies them to the
|
||||
native WebKit text track container on the slotted <video> element.
|
||||
|
||||
This stylesheet MUST live in the light DOM because ::slotted() cannot be
|
||||
chained with vendor pseudo-elements like ::-webkit-media-text-track-container.
|
||||
|
||||
CSS custom properties cascade through the shadow DOM boundary, so skins
|
||||
define the values and this bridge reads them.
|
||||
========================================================================== */
|
||||
|
||||
.media-skin > video::-webkit-media-text-track-container {
|
||||
transition: transform var(--media-caption-track-duration, 150ms) ease-out;
|
||||
transition-delay: var(--media-caption-track-delay, 600ms);
|
||||
transform: translateY(var(--media-caption-track-y, 0)) scale(0.98);
|
||||
z-index: var(--media-caption-track-z, 1);
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.media-skin > video::-webkit-media-text-track-container {
|
||||
transition-duration: 50ms;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* ==========================================================================
|
||||
Icon State Visibility for Video Skins
|
||||
|
||||
Data-attribute-driven visibility rules for multi-state icon buttons.
|
||||
Uses :is() with both element selectors (for HTML custom element wrappers)
|
||||
and class selectors (for React rendered SVG elements).
|
||||
========================================================================== */
|
||||
|
||||
/* --- All icons hidden by default --- */
|
||||
|
||||
.media-button--play .media-icon--restart,
|
||||
.media-button--play .media-icon--play,
|
||||
.media-button--play .media-icon--pause,
|
||||
.media-button--mute .media-icon--volume-off,
|
||||
.media-button--mute .media-icon--volume-low,
|
||||
.media-button--mute .media-icon--volume-high,
|
||||
.media-button--fullscreen .media-icon--fullscreen-enter,
|
||||
.media-button--fullscreen .media-icon--fullscreen-exit,
|
||||
.media-button--captions .media-icon--captions-off,
|
||||
.media-button--captions .media-icon--captions-on {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* --- Active icon per state --- */
|
||||
|
||||
/* Play: ended → restart */
|
||||
.media-button--play[data-ended] .media-icon--restart,
|
||||
/* Play: paused (not ended) → play */
|
||||
.media-button--play:not([data-ended])[data-paused] .media-icon--play,
|
||||
/* Play: playing (not paused, not ended) → pause */
|
||||
.media-button--play:not([data-paused]):not([data-ended]) .media-icon--pause,
|
||||
/* Mute: muted → volume off */
|
||||
.media-button--mute[data-muted] .media-icon--volume-off,
|
||||
/* Mute: volume low (not muted) → volume low */
|
||||
.media-button--mute:not([data-muted])[data-volume-level="low"] .media-icon--volume-low,
|
||||
/* Mute: volume high (not muted, not low) → volume high */
|
||||
.media-button--mute:not([data-muted]):not([data-volume-level="low"]) .media-icon--volume-high,
|
||||
/* Fullscreen: not fullscreen → enter */
|
||||
.media-button--fullscreen:not([data-fullscreen]) .media-icon--fullscreen-enter,
|
||||
/* Fullscreen: fullscreen → exit */
|
||||
.media-button--fullscreen[data-fullscreen] .media-icon--fullscreen-exit,
|
||||
/* Captions: not active → captions off */
|
||||
.media-button--captions:not([data-active]) .media-icon--captions-off,
|
||||
/* Captions: active → captions on */
|
||||
.media-button--captions[data-active] .media-icon--captions-on {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
Reference in New Issue
Block a user