muddle/samples/react/modules/app/albumStyle.ts
2026-10-23 08:53:07 -04:00

27 lines
1.2 KiB
TypeScript

/**
* Server-generated stylesheet for the discography navbar entries. Each album
* gets a `$refer` rule that moves the ribbon under its navbar item plus a
* cross-fade rule that reveals its pane.
*/
import { compileCss } from "../../../../views/css/index.ts";
import type { Album } from "./musicbrainz.ts";
export function albumRibbonCss(albums: Album[]): string {
if (albums.length === 0) return "";
const ids = albums.map((entry) => entry.id);
const source = `@each $id in ${ids.join(" ")} {
.navbar:has([data-muddle-anchor="navitem#{$id}"]:hover) .navbar__ribbon,
.navbar:has([data-muddle-anchor="navitem#{$id}"]:focus-visible) .navbar__ribbon {
--ribbon-x: calc($refer[left](@navitem#{$id}) + $refer[width](@navitem#{$id}) / 2 - $refer[left](@navbar) - ($refer[width](@pane#{$id}) + 2.4rem + 2px) / 2);
--ribbon-w: calc($refer[width](@pane#{$id}) + 2.4rem + 2px);
--ribbon-h: calc($refer[height](@pane#{$id}) + 1.6rem + 2px);
}
.navbar:has([data-muddle-anchor="navitem#{$id}"]:hover) [data-muddle-anchor="pane#{$id}"],
.navbar:has([data-muddle-anchor="navitem#{$id}"]:focus-visible) [data-muddle-anchor="pane#{$id}"] {
opacity: 1;
visibility: visible;
animation: fadein var(--dur) var(--ease);
}
}`;
return compileCss(source, { measured: [] });
}