Añade scripts/check-tokens.mjs (npm run lint:tokens, incorporado a
lint) como guardrail: falla si src/**/*.svelte reintroduce valores
arbitrarios fuera de la lista blanca de B.4, rounded-* de fábrica,
pares h-N w-N (deberían ser size-N), espaciado fraccionario en
cuartos, o colores hex/rgba() literales.
Se limpia el repo hasta dejar el script en 0 violaciones: ~40 pares
h-N w-N → size-N (sobre todo iconos, vía script puntual), ~26
espaciados fraccionarios en cuartos redondeados al entero más cercano
(Δ≤1px, p. ej. py-2.75→py-3, gap-1.75→gap-2), radios de fábrica
sueltos (rounded-sm/lg, rounded a secas) migrados a los tokens
correspondientes, y dos tracking-[-0.02em] que coincidían
exactamente con el token tracking-display ya existente pero nunca se
habían migrado. Se retiran las recetas stroke-thin/regular/bold
(creadas en P1, cero consumidores) — decisión tomada, sin bloquear:
no se migra strokeWidth={n} (13 valores, en casi todos los
componentes) a CSS porque no se puede verificar sin Docker que
lucide-svelte respete stroke-width por clase en vez del prop, y una
regresión ahí sería silenciosa en toda la app; el script documenta
este gap explícitamente en vez de fingir cobertura completa.
Detector de huérfanos: 0 componentes sin importadores. Se borra
docs/design-system-refactor-plan.md (plan anterior, superseded por
frontend-refactor-plan.md). web-player/CLAUDE.md gana una sección
"Estilos" con la lista blanca B.4 y los componentes base a reutilizar.
Se recalcula la tabla de línea base (A.4) y se anota en el Registro
(D.1): 61→47 componentes, 44→11 arbitrarios (los 11 restantes en
lista blanca), 13→8 radios distintos, 0 violaciones de lint:tokens.
Verificado con npm run check (0 errores), npm run lint:tokens (0
violaciones) y npm run build. Smoke test de /login sin errores de
consola achacables al cambio (Docker no disponible en esta sesión).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
91 lines
1.7 KiB
Svelte
91 lines
1.7 KiB
Svelte
<script lang="ts">
|
|
import type { Snippet } from 'svelte';
|
|
import MediaIdentity from './MediaIdentity.svelte';
|
|
import { pressable } from '$lib/actions/pressable';
|
|
|
|
interface Props {
|
|
href?: string;
|
|
onclick?: () => void;
|
|
oncontextmenu?: (event: MouseEvent) => void;
|
|
active?: boolean;
|
|
size?: 'xs' | 'sm' | 'lg';
|
|
variant?: 'row' | 'card';
|
|
title: string;
|
|
subtitle?: string | null;
|
|
subtitleHref?: string | number | null;
|
|
explicit?: boolean;
|
|
trackId?: string | number;
|
|
trackIds?: (string | number)[];
|
|
coverSrc?: string | null;
|
|
art?: Snippet;
|
|
overlay?: Snippet;
|
|
leading?: Snippet;
|
|
trailing?: Snippet;
|
|
class?: string;
|
|
style?: string;
|
|
}
|
|
|
|
let {
|
|
href,
|
|
onclick,
|
|
oncontextmenu,
|
|
active = false,
|
|
size = 'sm',
|
|
variant = 'row',
|
|
title,
|
|
subtitle,
|
|
subtitleHref,
|
|
explicit = false,
|
|
trackId,
|
|
trackIds,
|
|
coverSrc,
|
|
art,
|
|
overlay,
|
|
leading,
|
|
trailing,
|
|
class: klass = '',
|
|
style
|
|
}: Props = $props();
|
|
|
|
const classes = $derived(
|
|
`flex items-center gap-3 text-left transition-colors ${
|
|
variant === 'card' ? 'rounded-art p-2 pr-3.5' : 'rounded-control p-2'
|
|
} ${active ? 'bg-accent-tint' : 'hover:bg-hover'} ${klass}`
|
|
);
|
|
</script>
|
|
|
|
{#snippet content()}
|
|
{@render leading?.()}
|
|
<MediaIdentity
|
|
{title}
|
|
artist={subtitle}
|
|
ownerUserId={subtitleHref}
|
|
{trackId}
|
|
{trackIds}
|
|
{coverSrc}
|
|
{size}
|
|
{explicit}
|
|
{active}
|
|
{art}
|
|
{overlay}
|
|
/>
|
|
{@render trailing?.()}
|
|
{/snippet}
|
|
|
|
{#if href}
|
|
<a {href} {oncontextmenu} class={classes} {style}>
|
|
{@render content()}
|
|
</a>
|
|
{:else}
|
|
<div
|
|
role="button"
|
|
tabindex="0"
|
|
use:pressable={onclick ?? (() => {})}
|
|
{oncontextmenu}
|
|
class={classes}
|
|
{style}
|
|
>
|
|
{@render content()}
|
|
</div>
|
|
{/if}
|