learn and share notes on atproto (wip) 馃 malfestio.stormlightlabs.org/
readability solid axum atproto srs
at main 62 lines 2.2 kB view raw
1import type { Note } from "$lib/model"; 2import type { WikiLink } from "$lib/wikilink"; 3import { A } from "@solidjs/router"; 4import type { Component } from "solid-js"; 5import { For, Show } from "solid-js"; 6 7type WikilinksPanelProps = { links: WikiLink[]; notes: Note[]; resolveNote: (title: string) => Note | null }; 8 9/** 10 * Panel showing outgoing wikilinks from the current note 11 * 12 * Displays links with status (resolved/unresolved) 13 */ 14export const WikilinksPanel: Component<WikilinksPanelProps> = (props) => { 15 const uniqueTitles = () => { 16 const seen = new Set<string>(); 17 return props.links.filter((link) => { 18 const normalized = link.title.toLowerCase(); 19 if (seen.has(normalized)) return false; 20 seen.add(normalized); 21 return true; 22 }); 23 }; 24 25 return ( 26 <div class="space-y-2"> 27 <h3 class="text-sm font-semibold text-slate-400 uppercase tracking-wide">Wikilinks</h3> 28 <Show when={props.links.length > 0} fallback={<p class="text-sm text-slate-500 italic">No outgoing links</p>}> 29 <ul class="space-y-1"> 30 <For each={uniqueTitles()}> 31 {(link) => { 32 const resolved = () => props.resolveNote(link.title); 33 return ( 34 <li class="text-sm"> 35 <Show 36 when={resolved()} 37 fallback={ 38 <span class="text-slate-500 flex items-center gap-1"> 39 <span class="i-ri-link-unlink text-amber-500" /> 40 <span class="line-through">{link.title}</span> 41 </span> 42 }> 43 {(note) => ( 44 <A 45 href={`/notes/${note().id}`} 46 class="text-blue-400 hover:text-blue-300 flex items-center gap-1 transition-colors"> 47 <span class="i-ri-link" /> 48 {link.alias || link.title} 49 </A> 50 )} 51 </Show> 52 </li> 53 ); 54 }} 55 </For> 56 </ul> 57 </Show> 58 </div> 59 ); 60}; 61 62export default WikilinksPanel;