Leaflet Blog in Deno Fresh
1import { h } from "preact"; 2import { PubLeafletBlocksText } from "npm:@atcute/leaflet"; 3 4interface TextBlockProps { 5 plaintext: string; 6 facets?: PubLeafletBlocksText.Main["facets"]; 7} 8 9export function TextBlock({ plaintext, facets }: TextBlockProps) { 10 // Only process facets if at least one facet has features 11 if (!facets || !facets.some(f => f.features && f.features.length > 0)) { 12 return <>{plaintext}</>; 13 } 14 15 const parts: (string | { text: string; type: string; uri?: string })[] = []; 16 let lastIndex = 0; 17 18 facets.forEach((facet) => { 19 if (facet.index.byteStart > lastIndex) { 20 parts.push(plaintext.slice(lastIndex, facet.index.byteStart)); 21 } 22 23 const text = plaintext.slice(facet.index.byteStart, facet.index.byteEnd); 24 const feature = facet.features?.[0]; 25 26 if (!feature) { 27 parts.push(text); 28 return; 29 } 30 31 if (feature.$type === "pub.leaflet.richtext.facet#bold") { 32 parts.push({ text, type: feature.$type }); 33 } else if (feature.$type === "pub.leaflet.richtext.facet#highlight") { 34 parts.push({ text, type: feature.$type }); 35 } else if (feature.$type === "pub.leaflet.richtext.facet#italic") { 36 parts.push({ text, type: feature.$type }); 37 } else if (feature.$type === "pub.leaflet.richtext.facet#strikethrough") { 38 parts.push({ text, type: feature.$type }); 39 } else if (feature.$type === "pub.leaflet.richtext.facet#underline") { 40 parts.push({ text, type: feature.$type }); 41 } else { 42 parts.push({ text, type: feature.$type }); 43 } 44 45 lastIndex = facet.index.byteEnd; 46 }); 47 48 if (lastIndex < plaintext.length) { 49 parts.push(plaintext.slice(lastIndex)); 50 } 51 52 return ( 53 <> 54 {parts.map((part, i) => { 55 if (typeof part === "string") { 56 return part; 57 } 58 59 switch (part.type) { 60 case "pub.leaflet.richtext.facet#bold": 61 return <strong key={i}>{part.text}</strong>; 62 case "pub.leaflet.richtext.facet#highlight": 63 return ( 64 <mark 65 key={i} 66 className="bg-blue-100 dark:bg-blue-900 text-inherit rounded px-1" 67 style={{ borderRadius: '0.375rem' }} 68 > 69 {part.text} 70 </mark> 71 ); 72 case "pub.leaflet.richtext.facet#italic": 73 return <em key={i}>{part.text}</em>; 74 case "pub.leaflet.richtext.facet#strikethrough": 75 return <s key={i}>{part.text}</s>; 76 case "pub.leaflet.richtext.facet#underline": 77 return <u key={i}>{part.text}</u>; 78 default: 79 return part.text; 80 } 81 })} 82 </> 83 ); 84}