A React component library for rendering common AT Protocol records for applications such as Bluesky and Leaflet.
1import React from 'react';
2import { AtProtoRecord } from '../core/AtProtoRecord';
3import { TangledStringRenderer } from '../renderers/TangledStringRenderer';
4import type { TangledStringRecord } from '../renderers/TangledStringRenderer';
5
6/**
7 * Props for rendering Tangled String records.
8 */
9export interface TangledStringProps {
10 /** DID of the repository that stores the string record. */
11 did: string;
12 /** Record key within the `sh.tangled.string` collection. */
13 rkey: string;
14 /** Optional renderer override for custom presentation. */
15 renderer?: React.ComponentType<TangledStringRendererInjectedProps>;
16 /** Fallback node displayed before loading begins. */
17 fallback?: React.ReactNode;
18 /** Indicator node shown while data is loading. */
19 loadingIndicator?: React.ReactNode;
20 /** Preferred color scheme for theming. */
21 colorScheme?: 'light' | 'dark' | 'system';
22}
23
24/**
25 * Values injected into custom Tangled String renderer implementations.
26 */
27export type TangledStringRendererInjectedProps = {
28 /** Loaded Tangled String record value. */
29 record: TangledStringRecord;
30 /** Indicates whether the record is currently loading. */
31 loading: boolean;
32 /** Fetch error, if any. */
33 error?: Error;
34 /** Preferred color scheme for downstream components. */
35 colorScheme?: 'light' | 'dark' | 'system';
36 /** DID associated with the record. */
37 did: string;
38 /** Record key for the string. */
39 rkey: string;
40 /** Canonical external URL for linking to the string. */
41 canonicalUrl: string;
42};
43
44/** NSID for Tangled String records. */
45export const TANGLED_COLLECTION = 'sh.tangled.string';
46
47/**
48 * Resolves a Tangled String record and renders it with optional overrides while computing a canonical link.
49 *
50 * @param did - DID whose Tangled String should be fetched.
51 * @param rkey - Record key within the Tangled String collection.
52 * @param renderer - Optional component override that will receive injected props.
53 * @param fallback - Node rendered before the first load begins.
54 * @param loadingIndicator - Node rendered while the Tangled String is loading.
55 * @param colorScheme - Preferred color scheme for theming the renderer.
56 * @returns A JSX subtree representing the Tangled String record with loading states handled.
57 */
58export const TangledString: React.FC<TangledStringProps> = ({ did, rkey, renderer, fallback, loadingIndicator, colorScheme }) => {
59 const Comp: React.ComponentType<TangledStringRendererInjectedProps> = renderer ?? ((props) => <TangledStringRenderer {...props} />);
60 const Wrapped: React.FC<{ record: TangledStringRecord; loading: boolean; error?: Error }> = (props) => (
61 <Comp
62 {...props}
63 colorScheme={colorScheme}
64 did={did}
65 rkey={rkey}
66 canonicalUrl={`https://tangled.org/strings/${did}/${encodeURIComponent(rkey)}`}
67 />
68 );
69 return (
70 <AtProtoRecord<TangledStringRecord>
71 did={did}
72 collection={TANGLED_COLLECTION}
73 rkey={rkey}
74 renderer={Wrapped}
75 fallback={fallback}
76 loadingIndicator={loadingIndicator}
77 />
78 );
79};
80
81export default TangledString;