feat(packages): airplay button (#1531)

This commit is contained in:
Santiago Puppo
2026-05-27 10:22:31 -07:00
committed by GitHub
parent 760870fdf2
commit 338020e1d5
50 changed files with 869 additions and 2 deletions
@@ -20,6 +20,8 @@
.media-button--pip .media-icon--pip-exit,
.media-button--cast .media-icon--cast-enter,
.media-button--cast .media-icon--cast-exit,
.media-button--airplay .media-icon--airplay-enter,
.media-button--airplay .media-icon--airplay-exit,
.media-button--captions .media-icon--captions-off,
.media-button--captions .media-icon--captions-on {
display: none;
@@ -52,6 +54,10 @@
.media-button--cast:not([data-cast-state="connected"]) .media-icon--cast-enter,
/* Cast: connected → exit */
.media-button--cast[data-cast-state="connected"] .media-icon--cast-exit,
/* Airplay: not connected → enter */
.media-button--airplay:not([data-airplay-state="connected"]) .media-icon--airplay-enter,
/* Airplay: connected → exit */
.media-button--airplay[data-airplay-state="connected"] .media-icon--airplay-exit,
/* Captions: not active → captions off */
.media-button--captions:not([data-active]) .media-icon--captions-off,
/* Captions: active → captions on */
@@ -59,3 +65,14 @@
display: block;
opacity: 1;
}
/* --- Pause keyframe animations on inactive icons --- */
/* The airplay-exit SVG defines its keyframes against CSS variables (mirroring
the spinner pattern). When the AirPlay session isn't active the SVG is
still in the DOM — just `display: none` — so its animations would keep
running. Set the variables to `none` to short-circuit the keyframes. */
.media-button--airplay:not([data-airplay-state="connected"]) {
--media-icon--airplay__fill-animation: none;
--media-icon--airplay__triangle-animation: none;
}
@@ -39,4 +39,18 @@ export const iconState = {
'hidden opacity-0 group-not-data-[cast-state=connected]:block group-not-data-[cast-state=connected]:opacity-100',
exit: 'hidden opacity-0 group-data-[cast-state=connected]:block group-data-[cast-state=connected]:opacity-100',
},
airplay: {
// `group` enables the icon-state variants below. The two CSS-variable
// overrides mirror the spinner pattern: the airplay-exit SVG stays in
// the DOM while inactive, so we short-circuit its keyframes by setting
// the animation variables to `none` whenever airplay isn't connected.
button: [
'group',
'not-data-[airplay-state=connected]:[--media-icon--airplay__fill-animation:none]',
'not-data-[airplay-state=connected]:[--media-icon--airplay__triangle-animation:none]',
].join(' '),
enter:
'hidden opacity-0 group-not-data-[airplay-state=connected]:block group-not-data-[airplay-state=connected]:opacity-100',
exit: 'hidden opacity-0 group-data-[airplay-state=connected]:block group-data-[airplay-state=connected]:opacity-100',
},
};