Opcional: componer MuteButton + VolumeSlider al lado sigue siendo la forma en linea; esta es la otra y la elige el desarrollador. POR QUE UN FLOAT Y NO UN DESPLIEGUE EN LA FILA. Se probo lo segundo —el patron de YouTube, rail a inline-size 0 creciendo al hover— y se descarto con el usuario delante: un slider que se expande dentro de una fila flex EMPUJA todo lo que va detras (tiempo, scrubber, subtitulos, PiP, pantalla completa) y en una fila apretada desborda. YouTube se lo permite porque su barra ocupa la ventana entera; la nuestra no. El panel va fuera de flujo. VERIFICADO que no mueve nada: se compararon las posiciones de los DIEZ controles con el panel cerrado y abierto — identicas, cero diferencias. Es la promesa que incumpli con el hover y que esta vez se midio. Todo compuesto del catalogo, sin reinventar el flotado: Popover con openOnHover (ya existia; solo se acorto la apertura a 120ms —esto es un control, no un tooltip— y se alargo el cierre a 400ms para poder viajar hasta el), MuteButton como trigger via child (sigue siendo el boton de verdad: conserva aria-pressed, el atajo m y el glifo por nivel) y VolumeSlider vertical, el eje que el morfo declaraba desde el principio. El gesto: hover abre, CLIC SILENCIA y cierra, que es el remate natural de esa accion. En tactil no hay hover, asi que el toque hace las dos cosas; es ademas la unica via por la que un usuario tactil llega al slider. TRAMPA ENCARADA: los tokens --_mp-* NO cruzan el portal (se declaran en [data-media-player] y el contenido sale fuera), asi que el tinte del slider lleva fallback al rol que envuelve. Sin el, el control sale sin color dentro del panel. Demo con chip volume inline|float para compararlos en la misma barra. check 0 errores propios · player 14/14 · eidos-lint invalid 0 · docs:check 0 · prettier limpio. Panel 48x131, slider 32x96 vertical, visto en Chrome. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>alpha-0.1-dir-prefs
parent
1061e94a59
commit
26ddbaa1c9
@ -0,0 +1,48 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* `<MediaPlayer.VolumeFloat>` — the volume as a floating panel instead of an
|
||||
* always-visible rail. Optional: composing `<MuteButton>` + `<VolumeSlider>`
|
||||
* side by side is still the inline shape, and this is the other one.
|
||||
*
|
||||
* Why a float and not an in-row reveal: a slider that expands inside the
|
||||
* control row PUSHES everything after it — time, scrubber, captions, PiP,
|
||||
* fullscreen all shift on hover, and a tight row overflows. The panel is
|
||||
* positioned out of flow, so opening it moves nothing.
|
||||
*
|
||||
* The speaker stays the real `<MuteButton>`: it keeps `aria-pressed`, the `m`
|
||||
* hotkey and the loudness glyph. Hover opens the panel, click mutes — and
|
||||
* closes it, which is the right end to that gesture. On touch there is no
|
||||
* hover, so the tap does both: it is also the only way a touch user reaches
|
||||
* the slider at all.
|
||||
*
|
||||
* Composed from the catalogue's own `Popover` (its `openOnHover` already
|
||||
* exists); nothing about floating is reinvented here.
|
||||
*/
|
||||
import { Popover } from '$uix/eidos/components/popover';
|
||||
import MuteButton from './media-player-mute-button.svelte';
|
||||
import VolumeSlider from './media-player-volume-slider.svelte';
|
||||
import type { MediaPlayerVolumeFloatProps } from './types';
|
||||
|
||||
let {
|
||||
openDelay = 120,
|
||||
closeDelay = 400,
|
||||
side = 'top',
|
||||
...rest
|
||||
}: MediaPlayerVolumeFloatProps = $props();
|
||||
</script>
|
||||
|
||||
<Popover {...rest}>
|
||||
<Popover.Trigger openOnHover {openDelay} {closeDelay}>
|
||||
{#snippet child({ props })}
|
||||
<MuteButton {...props} />
|
||||
{/snippet}
|
||||
</Popover.Trigger>
|
||||
<Popover.Portal>
|
||||
<!-- The panel hugs the control. Popover's own sizes are made for prose and
|
||||
forms; a vertical rail needs its hit area and nothing more, so the
|
||||
width is overridden on the space scale rather than inherited. -->
|
||||
<Popover.Content {side} size="sm" width="calc(var(--space-8) * 1.5)">
|
||||
<VolumeSlider orientation="vertical" />
|
||||
</Popover.Content>
|
||||
</Popover.Portal>
|
||||
</Popover>
|
||||
Loading…
Reference in new issue