Spaces:
Configuration error
Configuration error
File size: 3,408 Bytes
e8a6c67 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | <svelte:options
customElement={{
tag: "r-sources-footer",
props: {
labels: { type: "Object" },
urls: { type: "Object" },
vintages: { type: "Object" },
},
}} />
<script>
import { citeIndex, highlightedDocId } from "./stores.js";
import { fade, scale } from "svelte/transition";
import { cubicOut } from "svelte/easing";
let { labels = {}, urls = {}, vintages = {} } = $props();
let entries = $derived(
Object.entries($citeIndex || {}).sort((a, b) => a[1] - b[1])
);
let hl = $derived($highlightedDocId);
</script>
{#if entries.length}
<div class="src-h" in:fade={{ duration: 200 }}>Sources</div>
<ol>
{#each entries as [id, n] (id)}
{@const url = urls[id]}
{@const label = labels[id] || id}
{@const vintage = vintages[id]}
<li class:hl={id === hl}
in:scale={{ start: 0.96, duration: 220, easing: cubicOut }}
onmouseenter={() => highlightedDocId.set(id)}
onclick={() => highlightedDocId.set(hl === id ? null : id)}>
<span class="src-num">[{n}]</span>
<div>
{#if url}
<a class="src-link" href={url} target="_blank" rel="noopener noreferrer"
onclick={(e) => e.stopPropagation()}>
{label} <span class="src-ext">↗</span>
</a>
{:else}
<span>{label}</span>
{/if}
<span class="src-id">{id}</span>
{#if vintage}<span class="src-vintage">{vintage}</span>{/if}
</div>
</li>
{/each}
</ol>
{/if}
<style>
:host {
display: block;
border-top: 1px solid var(--line, #e5e7eb);
background: var(--bg-soft, #f5f7fb);
padding: 12px 16px 14px;
}
:host(:not(:has(ol))) { display: none; }
.src-h {
font-size: 10px; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.10em;
color: var(--text-muted, #6b7280);
margin: 0 0 8px;
}
ol {
margin: 0; padding: 0; list-style: none;
display: grid; gap: 6px;
font-size: 11.5px; line-height: 1.45;
}
li {
display: grid; grid-template-columns: 22px 1fr;
gap: 8px; align-items: baseline;
padding: 4px 6px; border-radius: 3px;
cursor: pointer;
transition: background 0.15s;
}
li:hover, li.hl { background: rgba(22, 66, 223, 0.10); }
li.hl {
/* Brief pulse each time a chip selects this row. */
animation: pulse 360ms cubic-bezier(.2,.7,.3,1);
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(22, 66, 223, 0.35); }
60% { box-shadow: 0 0 0 6px rgba(22, 66, 223, 0.00); }
100% { box-shadow: 0 0 0 0 rgba(22, 66, 223, 0.00); }
}
.src-num {
font-family: var(--mono, monospace); font-size: 10.5px;
font-weight: 700; color: var(--nyc-blue, #1642DF);
text-align: right;
}
.src-link {
color: var(--text, #111); text-decoration: none;
border-bottom: 1px dotted var(--text-muted, #6b7280);
}
.src-link:hover {
color: var(--nyc-blue, #1642DF);
border-bottom-color: var(--nyc-blue, #1642DF);
}
.src-ext { font-size: 9.5px; color: var(--text-faint, #9ca3af); margin-left: 2px; vertical-align: super; }
.src-vintage { display: block; color: var(--text-muted, #6b7280); font-size: 9.5px; margin-top: 2px; }
.src-id { display: inline-block; font-family: var(--mono, monospace); font-size: 9.5px; color: var(--text-faint, #9ca3af); margin-left: 6px; }
</style>
|