opsinjs
ComponentsHealth communication

DisclaimerNote

The short standing note saying this is information, not medical advice. It is placed by rule, so it is always in the same place and never in the way.

Preview

Theme
Density
Text
Status
disclaimer-note · base base · style base-lyraOpen under the product theme

Installation

pnpm dlx shadcn@latest add @opsinjs/disclaimer-note

The @opsinjs namespace is declared in your components.json. Everything it installs is code you then own. There is no runtime package to keep in step.

Usage

import { DisclaimerNote } from "@/components/ui/disclaimer-note"
<DisclaimerNote placement="footer">
  The product's own two sentences go here. opsinjs ships none of them.
</DisclaimerNote>

When to use it

Use it when

  • Any surface that shows a health value, range, status or derived score to the person it belongs to.
  • The end of a flow that gathered health information, where the reader may expect an assessment they will not get.
  • Wherever a product could be mistaken for a clinical service, such as a symptom questionnaire or a result summary.

Do not use it when

  • The reader needs to do something now, and the note would sit above the instruction.Use care-card instead.
  • The message is specific to one result rather than a standing statement about the product.Use callout instead.
  • Something has changed and needs the reader's attention.Use alert-banner instead.
  • You are explaining a word rather than the product's limits.Use term instead.
  • The reader must acknowledge the statement before continuing, and the product needs a record of it.Use consent-sheet instead.

Clinical meaning

Asserts. That the product provides information rather than clinical assessment, does not replace a clinician's advice and, where relevant, is not a medical device. The component supplies position, type size, ink and boundary, and none of the content.

Never read as. A waiver or a substitute for designing safely: a disclaimer does not make an unsafe screen safe. It is never this number is unreliable, since the note is about the product's role, not the measurement. The safety review checklist judges the screen.

Colour axis. Neither. There is no status or category prop, no data-status or data-category, and no fill. See The two colour axes.

Thresholds. None. No clinical number is written into the component and none passes through it: no threshold, reference range, score band or staleness boundary.

Words. The consuming product's, under the clinical interaction guidelines. opsinjs ships no legal text: no default string, no placeholder, no vetted variant and no translation fallback. Regulatory context sets out what DCB0129, DCB0160, the EU MDR and FDA SaMD ask of the product.

Anatomy

  1. DisclaimerNoteThe root, outside both colour axes: no status or category prop, no fill, no role, no live region.Controlled by placement
  2. DisclaimerNote.IconOptional, off by default, decorative and aria-hidden. The glyph is fixed, so it is never a warning triangle.Controlled by icon
  3. DisclaimerNote.TextThe product's one or two sentences, at body size in body ink. Prints an admission when nothing is supplied.Controlled by children
  4. DisclaimerNote.LinkThe fuller statement. Label and href arrive as one object, and a vague label warns in development.Controlled by more
  5. DisclaimerNote.VersionThe wording's id, rendered exactly as written at footnote size in secondary ink.Controlled by textVersion

Examples

One note, at the foot of the surface

Three rows and one placement="footer" note under all of them: not one per row, and never above them.

Theme
Density
Text
Status
disclaimer-note-once-at-the-foot-of-a-surface · base base · style base-lyraOpen under the product theme

When nobody wrote the words

Copy from a content service can arrive empty. children of undefined, false, 0, an empty array or whitespace prints an admission and warns in development. Copy in an element is taken at its word.

Theme
Density
Text
Status
disclaimer-note-no-text-supplied · base base · style base-lyraOpen under the product theme

Content guidelines

Two sentences at most: what the product does, then what it does not do. Use plain words, this app rather than the Service, and the job title a reader recognises. Name the link for where it goes, because learn more raises a development warning.

Do

Name what the product does, then the one limit that matters most, one sentence each, in the product's register.

Don’t

Open with the trading name, stack abstract nouns for what it is not, and close by placing reliance on the reader.

Accessibility

Audited against WCAG 2.2 AA. A source pass and a rendered pass, author-run rather than independent, clinical review still pending. The rendered pass on /view/base/base-lyra/component/disclaimer-note was clean: zero axe violations, the link kept its target floor, focus-visible held, and nothing scrolled sideways at 320px or 200% text. Nothing in the source needed changing. The standing guarantees hold: type sizes and colours are role tokens, the decorative glyph is aria-hidden, the statement is a real paragraph, and the only interactive element is a real anchor that warns on unhelpful labels.

One deferred item. The root is a plain <div> with no role and no accessible name, so a screen reader meets the note as ordinary sentences rather than a bounded "note". Reading order and content are fully conveyed, so this is not an AA failure. The boundary is an enhancement left out on purpose: a role is a spec decision reserved to review, and an aria-label would inject an English string into a translation-neutral component. Standing gates still cover its one string on every commit: no px type size, no raw colour literal, no banned word.

KeyActionNotes
TabMoves to the link, when there is oneThe note is text, not a tab stop. The link is the only focusable part.
Shift+TabMoves back out of the linkOne stop, so reverse order matches visual order.
EnterFollows the linkAn ordinary anchor, so modifier-clicks keep the browser's behaviour.
SpaceScrolls the page, as it does anywhere elseNothing here captures Space.
PairThemeAPCA LcWCAG 2.2Floor
body text on the pagelight101.617.18:1Pass
body text on the pagedark-100.518.00:1Pass
body text on a cardlight104.717.96:1Pass
body text on a carddark-99.616.32:1Pass
body text on the muted groundlight98.116.32:1Pass
body text on the muted grounddark-97.513.77:1Pass
secondary text on the pagelight83.97.42:1Pass
secondary text on the pagedark-80.713.44:1Pass
secondary text on a cardlight87.07.76:1Pass
secondary text on a carddark-79.812.19:1Pass
secondary text on the muted groundlight80.47.05:1Pass
secondary text on the muted grounddark-77.810.28:1Pass
a hairline boundary on the pagelight19.31.41:1Below floor
a hairline boundary on the pagedark-8.21.90:1Below floor
a hairline boundary on a cardlight22.41.47:1Below floor
a hairline boundary on a carddark-7.31.72:1Below floor
a hairline boundary on the muted groundlight15.81.34:1Below floor
a hairline boundary on the muted grounddark0.01.45:1Below floor
a placeholder boundary on the pagelight69.84.52:1Pass
a placeholder boundary on the pagedark-51.07.62:1Pass
a placeholder boundary on a cardlight72.84.72:1Pass
a placeholder boundary on a carddark-50.16.91:1Pass
a placeholder boundary on the muted groundlight66.24.29:1Pass
a placeholder boundary on the muted grounddark-48.15.83:1Pass
a placeholder fill on the pagelight8.31.18:1Below floor
a placeholder fill on the pagedark-8.21.90:1Below floor
a placeholder fill on a cardlight11.41.23:1Below floor
a placeholder fill on a carddark-7.31.72:1Below floor
a placeholder fill on the muted groundlight0.01.12:1Below floor
a placeholder fill on the muted grounddark0.01.45:1Below floor
a placeholder boundary on its own filllight58.93.84:1Pass
a placeholder boundary on its own filldark-41.54.01:1Below floor
the card hairline on the pagelight69.84.52:1Pass
the card hairline on the pagedark-28.74.19:1Below floor
the card hairline on a cardlight72.84.72:1Pass
the card hairline on a carddark-27.93.80:1Below floor

These are the measured token pairs this component draws colour from, not a measurement of the component itself.

API reference

Prop

Type

Generated from DisclaimerNoteProps in registry/bases/base/disclaimer-note.tsx.

children is typed optional and required by the contract, so the missing state can render and print its admission. placement changes only the space above the note, and there is no top value: never above the result. There is no default text and no colour prop, and an axis class through className raises a development warning.

  • Callout is information about the content. A disclaimer is about the product.
  • AlertBanner is entitled to speak; styling a disclaimer as one is the commonest mistake.
  • ConsentSheet is a request the reader answers, not a statement they read.
  • CareCard is an instruction with an author. A disclaimer asks for nothing.

On this page