88e21e41e2
URL param timing was unreliable with SvelteKit client-side routing. Now CrossLink calls requestHighlight(id) setting a global variable before goto(), and highlightFromUrl() reads it after data loads. Double requestAnimationFrame ensures DOM has rendered after loaded=true. Falls back to ?highlight= URL param for direct links.
57 lines
1.1 KiB
Svelte
57 lines
1.1 KiB
Svelte
<script lang="ts">
|
|
import { goto } from '$app/navigation';
|
|
import MdiIcon from './MdiIcon.svelte';
|
|
import { requestHighlight } from '$lib/highlight';
|
|
|
|
let {
|
|
href,
|
|
icon = 'mdiLink',
|
|
label,
|
|
entityId = null,
|
|
title = '',
|
|
}: {
|
|
href: string;
|
|
icon?: string;
|
|
label: string;
|
|
entityId?: number | string | null;
|
|
title?: string;
|
|
} = $props();
|
|
|
|
function navigate(e: MouseEvent) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
if (entityId != null) {
|
|
requestHighlight(entityId);
|
|
}
|
|
goto(href);
|
|
}
|
|
</script>
|
|
|
|
<a {href} class="crosslink" title={title || label} onclick={navigate}>
|
|
<MdiIcon name={icon} size={12} />
|
|
<span>{label}</span>
|
|
</a>
|
|
|
|
<style>
|
|
.crosslink {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
font-size: 0.65rem;
|
|
font-weight: 500;
|
|
padding: 0.1rem 0.4rem;
|
|
border-radius: 9999px;
|
|
background: var(--color-muted);
|
|
color: var(--color-muted-foreground);
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
transition: all 0.15s;
|
|
white-space: nowrap;
|
|
font-family: var(--font-mono);
|
|
}
|
|
.crosslink:hover {
|
|
background: var(--color-primary);
|
|
color: var(--color-primary-foreground);
|
|
}
|
|
</style>
|