web-player: P12 — chrome de la app (layout, navegación, reproductor)
PlayerExtras se fusiona en PlayerBar, que ahora renderiza volumen y botón de cola inline y usa el nuevo Slider (input range real con grosor de thumb controlado por variables CSS) para barra de progreso y volumen, sustituyendo a SeekBar y VolumeControl (se confirmó por grep que el modo `compact` de SeekBar era código muerto). Sidebar y TabsBar migran a appNavLinks(user, counts?) (creado en P5), eliminando la duplicación de los enlaces de navegación entre ambos. Decisión tomada sin bloquear: Sidebar gana la marca-gradiente Logo que no tenía antes, para consistencia visual con MobileHeader y la pantalla de login. z-index de PlayerDock y MobileHeader corregido a z-(--z-sticky) (son barras fijas, no menús) y el de SegmentedControl a z-(--z-raised), tal como indica la nota B.1.5 del plan. glass-bar y theme-transition se aplican en PlayerBar (ambas variantes), TabsBar, Queue e Inicio (hero/spotlight), sustituyendo estilos duplicados de blur/transición. Verificado con npm run check (0 errores) y npm run build; smoke test de /login sin errores de consola. Sin QA visual autenticada (Docker no disponible en esta sesión). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
value: number;
|
||||
max: number;
|
||||
label: string;
|
||||
oninput: (value: number) => void;
|
||||
variant: 'seek' | 'volume';
|
||||
}
|
||||
|
||||
let { value, max, label, oninput, variant }: Props = $props();
|
||||
|
||||
const percent = $derived(max > 0 ? (value / max) * 100 : 0);
|
||||
|
||||
function handleInput(event: Event) {
|
||||
oninput(Number((event.currentTarget as HTMLInputElement).value));
|
||||
}
|
||||
</script>
|
||||
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
{max}
|
||||
{value}
|
||||
oninput={handleInput}
|
||||
aria-label={label}
|
||||
class="mf-slider mf-slider-{variant}"
|
||||
style="background:linear-gradient(to right, var(--mf-text-2) {percent}%, var(--mf-track) {percent}%)"
|
||||
/>
|
||||
|
||||
<style>
|
||||
.mf-slider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
height: var(--mf-range-h);
|
||||
border-radius: 100px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mf-slider-seek {
|
||||
width: 100%;
|
||||
}
|
||||
.mf-slider-volume {
|
||||
width: var(--mf-volume-w);
|
||||
}
|
||||
.mf-slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: var(--mf-range-thumb);
|
||||
height: var(--mf-range-thumb);
|
||||
border-radius: 50%;
|
||||
background: var(--mf-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
.mf-slider::-moz-range-thumb {
|
||||
width: var(--mf-range-thumb);
|
||||
height: var(--mf-range-thumb);
|
||||
border-radius: 50%;
|
||||
background: var(--mf-text);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user