Files
Musify/web-player/src/lib/components/ui/Slider.svelte
T
AdminandClaude Sonnet 5 39e6c2d552 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>
2026-09-21 14:39:20 +02:00

63 lines
1.3 KiB
Svelte

<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>