Skip to main content

ContentDetail

ContentDetail is a scrollable compound component for content that may come from a FHIR Composition. The SDK supplies extraction helpers, but the app controls layout, loading, data fetching, and navigation.

import { ContentDetail } from "@ovok/native";

<ContentDetail composition={composition}>
<ContentDetail.Header>
<ContentDetail.Title />
<ContentDetail.Metadata>
<ContentDetail.Metadata.Author />
<ContentDetail.Metadata.Separator />
<ContentDetail.Metadata.Date />
</ContentDetail.Metadata>
</ContentDetail.Header>
<ContentDetail.Body>
<ContentDetail.RichContent />
</ContentDetail.Body>
<ContentDetail.Footer>
<ContentDetail.Tags />
<ContentDetail.Resource />
</ContentDetail.Footer>
</ContentDetail>;

Root and context​

The root is a ScrollView, accepts ScrollViewProps plus optional composition, and provides that composition through context. Header, Body, and Footer render React Native View containers and accept ViewProps. Metadata also accepts ViewProps and lays out children in a row.

useComposition is a named export from @ovok/native and must be called below ContentDetail; outside the provider it throws useComposition must be used within a CompositionContext.

Title and rich content​

  • ContentDetail.Title accepts optional string children or reads composition.title. It throws if neither exists and renders Paper Text with variant="titleLarge".
  • ContentDetail.RichContent accepts content plus RenderHTMLProps except source. If content is absent, it uses the first composition section with text.div, without excluding sections coded reading-time or resource-link; put the article body first or pass content explicitly. It throws when no HTML is available.
  • Rich content uses react-native-render-html. <img> elements render through OptimizedImage; caller-supplied baseStyle, customHTMLElementModels, and renderers are merged with the SDK defaults.

Metadata​

Metadata items render Paper Text with the bodyMedium variant by default.

  • Metadata.Author uses composition.meta.author.display unless children are supplied.
  • Metadata.Date uses the top-level composition.date, formats valid dates as dd MMM yyyy, and renders Invalid date for an invalid value.
  • Metadata.ReadingTime finds a section coded reading-time, strips HTML from its text.div, and renders the result.
  • Metadata.Item is the base item for caller-owned content.
  • Metadata.Separator defaults to ·.

Each item accepts optional children and Paper text props. There is no built-in author, date, reading-time, or error translation layer beyond the resource label below.

ContentDetail.Tags accepts optional tags?: Coding[], onTagPress, chipProps, and ViewProps. Without tags, it reads composition.meta.tag. Each tag displays tag.display or tag.code; the component returns null when there are no tags. chipProps cannot override the generated children or onPress.

ContentDetail.Resource looks for a composition section containing coding resource-link, extracts the URL using the current anchor parser, and opens it with expo-web-browser by default. Until the parser is corrected, make the anchor's visible text exactly the same as its href; otherwise the visible text can be returned as the URL. Supply onPress(resourceLink) to own the action. It returns null when no resource link is found. Its visible label is localized with content.detail.view-resource.

ContentDetail.Resource props​

PropTypeDefaultDescription
onPress(resourceLink: string) => voidOpens with expo-web-browserOwn the resource action.
styleStyleProp<TextStyle>undefinedStyle for the resource label.
testIDstringundefinedTest identifier.

The matching Composition section must contain a coding with code: "resource-link" and an HTML anchor in section.text.div, for example <a href="https://example.com/manual">Manual</a>. A plain URL string is not parsed; the current parser only works reliably when the visible anchor text is also the URL; when no matching section or anchor is present, the component returns null.

The content-detail module uses only the content.detail.view-resource translation key. Metadata values are formatted directly and do not use built-in content.metadata.* or content.error.* keys.

Styling and ownership​

The root adds theme-based gap and padding to contentContainerStyle; caller values are merged afterward. The component does not validate a FHIR resource beyond the fields it reads, does not load remote content, and does not own authentication, caching, or routing.