Animate library tabs, rows, editor track lists, status badges and dropzone
Tabs get a sliding indicator that persists across library routes, grid rows flip and collapse on removal, the selection bar and filters crossfade, album tracks move between lists with a crossfade, processing badges pulse and the dropzone scales while dragging.
This commit is contained in:
@@ -12,16 +12,43 @@
|
||||
}
|
||||
|
||||
let { label, tabs, class: klass = '' }: Props = $props();
|
||||
|
||||
let links = $state<Record<string, HTMLAnchorElement | undefined>>({});
|
||||
let indicator = $state({ x: 0, width: 0 });
|
||||
let measured = $state(false);
|
||||
let animated = $state(false);
|
||||
|
||||
const activeHref = $derived(tabs.find((tab) => tab.active)?.href);
|
||||
|
||||
$effect(() => {
|
||||
const link = activeHref ? links[activeHref] : undefined;
|
||||
if (!link) return;
|
||||
indicator = { x: link.offsetLeft, width: link.offsetWidth };
|
||||
measured = true;
|
||||
if (!animated) requestAnimationFrame(() => (animated = true));
|
||||
});
|
||||
</script>
|
||||
|
||||
<nav aria-label={label} class="flex gap-2 {klass}">
|
||||
<nav
|
||||
aria-label={label}
|
||||
class="relative inline-flex max-w-full rounded-full bg-surface-2 p-1 {klass}"
|
||||
>
|
||||
{#if measured}
|
||||
<div
|
||||
class="absolute inset-y-1 left-0 rounded-full bg-fg ease-snappy {animated
|
||||
? 'transition-[transform,width] duration-200'
|
||||
: ''}"
|
||||
style="width:{indicator.width}px; transform:translateX({indicator.x}px)"
|
||||
></div>
|
||||
{/if}
|
||||
{#each tabs as tab (tab.href)}
|
||||
<a
|
||||
bind:this={links[tab.href]}
|
||||
href={tab.href}
|
||||
aria-current={tab.active ? 'page' : undefined}
|
||||
class="rounded-full px-4 py-1.5 text-xs font-medium focus-ring transition-colors {tab.active
|
||||
? 'bg-fg text-ink'
|
||||
: 'bg-surface-2 text-fg-2 hover:text-fg'}"
|
||||
class="relative z-(--z-raised) rounded-full px-4 py-1.5 text-xs font-medium focus-ring transition-colors {tab.active
|
||||
? 'text-ink'
|
||||
: 'text-fg-2 hover:text-fg'}"
|
||||
>
|
||||
{tab.label}
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user