useTitleRegistration
Register headings with the shared title registry so sticky TOCs and scrollspy hooks stay in sync. To read the registry (
titles, registerTitle, unregisterTitle, clearTitles) directly, call useTitleRegistry(), which throws outside a TitleRegistryProvider, or useTitleRegistryOptional(), which returns null there.Use the title registry provider to keep downstream navigation components aware of rendered headings.
Loading demo…
import { View } from 'react-native';
import { Block, DataList, Text, TitleRegistryProvider, useTitleRegistration, useTitleRegistry } from '@plocks/ui';
const SECTIONS = [
{ title: 'Why it matters', order: 1, description: 'Explain how the registry keeps navigation UI in sync with content.' },
{ title: 'When to use it', order: 2, description: 'Wrap large content layouts so scrollspy and tables of contents stay accurate.' },
{ title: 'Implementation tips', order: 3, description: 'Call the hook in section components and pass refs to headings that render in the DOM.' }
] as const;
function Section({ title, order, description }: { title: string; order: number; description: string }) {
const { elementRef, id } = useTitleRegistration({ text: title, order });
return (
<View ref={elementRef} nativeID={id}>
<Text fw="semibold">{title}</Text>
<Text size="sm" c="secondary">{description}</Text>
</View>
);
}
function RegistryPreview() {
const { titles } = useTitleRegistry();
if (!titles.length) {
return <Text size="sm" c="muted">No titles registered yet.</Text>;
}
return (
<DataList
labelWidth={180}
data={titles.map(title => ({ label: title.text, value: `level ${title.order}` }))}
/>
);
}
export function Demo() {
return (
<TitleRegistryProvider>
<Block gap="lg">
<Block gap="xs">
<Text size="sm" fw="semibold">Registered titles</Text>
<RegistryPreview />
</Block>
<Block gap="lg">
{SECTIONS.map(section => (
<Section key={section.title} {...section} />
))}
</Block>
</Block>
</TitleRegistryProvider>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources