The React widget in this panel shares the controller that was
started before paint. Change it here or in the vanilla control
below; both update together.
Use Display inside a React app
Optional binding · Shared state · Site-owned CSS
React binding
Subscribe, then render.
DisplayWidget uses the same native markup and public
CSS hooks as the vanilla widget. Pass className to
scope your design; keep the controller stable between renders.
This control is mounted directly into the DOM. It shares the
existing controller with React.
A shared configuration
Presets work in both bindings.
Composition happens in config.js, outside React.
Vision adds text-spacing tokens; Vision + High Contrast adds paired
colors and borders. Both widgets inherit the page’s new presentation.
Source code
These are the files behind this example. The tabs support arrow keys, Home and End.
<!doctype html><htmllang="en"><head><metacharset="UTF-8" /><metaname="viewport"content="width=device-width,initial-scale=1" /><title>React binding — Open Regard Display</title><!-- Self-host synchronous scripts so the saved profile applies before paint. --><scriptsrc="../dist/display.browser.js"></script><scriptsrc="../dist/presets.browser.js"></script><scriptsrc="./config.js"></script><linkrel="stylesheet"href="../dist/style.css" /><linkrel="stylesheet"href="./demo.css" /><linkrel="icon"href="./mark.svg"type="image/svg+xml" /></head><body><aclass="skip"href="#main">Skip to content</a><headerclass="masthead shell"><aclass="brand"href="https://openregard.org/"
><imgsrc="./mark.svg"alt="" />open regard.</a
>
<spanclass="meta">Module 01 / Display / Runnable examples</span></header><navclass="example-nav shell"aria-label="Example navigation"><ahref="./">Vanilla HTML</a><ahref="./docs.html">Static docs</a
><ahref="./react.html"aria-current="page">React</a
><ahref="https://openregard.org/docs/">Library documentation ↗</a></nav><mainid="main"class="shell"><sectionclass="hero"><div><pclass="eyebrow">03 / React + vanilla</p><h1>Two bindings.<br /><em>One controller.</em></h1><pclass="intro">
The React widget in this panel shares the controller that was
started before paint. Change it here or in the vanilla control
below; both update together.
</p></div><asideclass="control-card"aria-label="Display settings"><pclass="eyebrow">Try a display profile</p><divid="react-controls"></div></aside></section><divclass="section-head"><h2>Use Display inside a React app</h2><p>Optional binding · Shared state · Site-owned CSS</p></div><divclass="grid"><articleclass="card"><pclass="eyebrow">React binding</p><h2>Subscribe, then render.</h2><p><code>DisplayWidget</code> uses the same native markup and public
CSS hooks as the vanilla widget. Pass <code>className</code> to
scope your design; keep the controller stable between renders.
</p><preclass="code-note"><code><DisplayWidget
display={regard}
className="demo-widget"
/></code></pre></article><articleclass="card"><pclass="eyebrow">Vanilla binding</p><h2>Same profile. No bridge.</h2><p>
This control is mounted directly into the DOM. It shares the
existing controller with React.
</p><divid="controls"></div></article></div><sectionclass="sync-row"><div><pclass="eyebrow">A shared configuration</p><h2>Presets work in both bindings.</h2></div><p>
Composition happens in <strong>config.js</strong>, outside React.
Vision adds text-spacing tokens; Vision + High Contrast adds paired
colors and borders. Both widgets inherit the page’s new presentation.
</p></section></main><footerclass="shell"><p>
Open Regard / Display. Profiles and page styles are configured by the
site. Test your integration with your content and users.
</p><ahref="https://github.com/inferal-oss/openregard">View the project ↗</a></footer><scriptsrc="../dist/react-demo.js"defer></script></body></html>
config.js
// Optional token recipes. Profile names, composition and site styling are yours.const { wcagPresets, htmlPresets } = OpenRegardPresets;
window.regardConfig = {
version: 1,
defaultProfile: "standard",
storageKey: "openregard-example",
controlLabel: "Reading and display preferences",
profiles: [
{
id: "standard",
label: "Standard",
description: "The original site presentation.",
},
{
id: "roomy",
label: "Vision",
description: "Larger text with the WCAG text-spacing override values.",
tokens: {
...wcagPresets.textSpacing,
...htmlPresets.nativeControls,
"--regard-font-size": "125%",
},
},
{
id: "vision-contrast",
label: "Vision + High Contrast",
description:
"Larger, spaced text with a restrained palette and stronger borders.",
tokens: {
...wcagPresets.textSpacing,
...wcagPresets.contrastLight,
...htmlPresets.nativeControls,
"--regard-font-size": "125%",
},
},
{
id: "strong",
label: "Max Contrast",
description:
"Larger text, generous spacing and black-and-white surfaces.",
tokens: {
...wcagPresets.textSpacing,
...htmlPresets.nativeControls,
"--regard-font-size": "150%",
"--regard-page-ink": "#000",
"--regard-page-paper": "#fff",
"--regard-panel-ink": "#fff",
"--regard-panel-paper": "#000",
"--regard-border-color": "#000",
},
},
],
};
window.regard = OpenRegardDisplay.createDisplay(window.regardConfig);
window.stopRegard = window.regard.start();