grain.social is a photo sharing platform built on atproto.
1import { Facet, RichText } from "@atproto/api";
2
3type Props = Readonly<{
4 text: string;
5 facets?: Facet[];
6}>;
7
8export function RenderFacetedText({ text, facets }: Props) {
9 const rt = new RichText({ text, facets });
10 return (
11 <>
12 {[...rt.segments()].map((segment) => {
13 const content = segment.text;
14
15 if (segment.isMention()) {
16 return (
17 <a
18 key={segment.mention?.did || segment.text}
19 href={`/profile/${segment.mention?.did}`}
20 class="text-sky-500 hover:underline"
21 >
22 {content}
23 </a>
24 );
25 }
26
27 if (segment.isLink()) {
28 return (
29 <a
30 key={segment.link?.uri || segment.text}
31 href={segment.link?.uri}
32 class="text-sky-500 underline"
33 target="_blank"
34 rel="noopener noreferrer"
35 >
36 {content}
37 </a>
38 );
39 }
40
41 if (segment.isTag() && segment.tag?.tag) {
42 return (
43 <a
44 key={segment.tag.tag}
45 href={`/hashtag/${segment.tag.tag}`}
46 class="text-sky-500 hover:underline"
47 >
48 #{segment.tag.tag}
49 </a>
50 );
51 }
52
53 return <span key={segment.text}>{content}</span>;
54 })}
55 </>
56 );
57}