Themes, scale, localization and host rendering hooks
The provider
Section titled “The provider”EntityVizProvider (from entity-viz-kit/react) renders one scoped <div class="evk"> and passes configuration to every EVK component inside it. It sets no global styles and uses no storage, network assets or global store. Providers nest: an inner provider inherits from its parent and overrides only the props it receives.
import { createElement as h } from 'react';import { EntityVizProvider } from 'entity-viz-kit/react';import type { EntityType } from 'entity-viz-kit/core';import 'entity-viz-kit/styles.css';
export const themed = h(EntityVizProvider, { theme: 'auto', // 'light' | 'dark' | 'auto' (follows prefers-color-scheme) density: 'compact', // 'comfortable' | 'compact' mode: 'standard', // 'standard' | 'compact' | 'presentation' (1.5× type) scale: 1.25, // 0.75–3; anything else throws RangeError direction: 'rtl', locale: 'ar', strings: { searchLabel: 'بحث في المستندات', search: 'بحث' }, typeLabel: (type: EntityType) => type.id === 'person' ? 'شخص' : type.label, // Your own 24×24 artwork; null keeps EVK's glyph. (Do not render EntityGlyph here: it calls this hook.) renderGlyph: (name: string) => name === 'person' ? h('svg', { viewBox: '0 0 24 24' }, h('circle', { cx: 12, cy: 8, r: 4 })) : null}, children);| Prop | Effect |
|---|---|
theme | data-theme on the root; auto switches with the operating system. |
density, mode | Spacing and type-size multipliers (--evk-gap, --evk-mode-scale). |
scale | --evk-scale, multiplying all EVK type sizes. Use it for text scaling or distance viewing. |
direction, locale | dir and lang on the root. The CSS uses logical properties, so layouts mirror. |
strings | Search and query copy (EvkStrings, DEFAULT_STRINGS). |
readingStrings | Results, profiles, evidence and anchor-status copy (ReadingStrings, DEFAULT_READING_STRINGS). |
surfaceStrings | WorkspaceLayout, PresentationControls and AudienceDisplay copy (SurfaceStrings, DEFAULT_SURFACE_STRINGS). |
typeLabel | Localized entity-type names. |
renderGlyph, renderLabel | Host rendering hooks for glyphs and entity labels. Return null or undefined to fall back to EVK’s rendering. |
String entries that take arguments are functions, for example add: name => ..., resultCount: count => ... and livePublication: (n, changed) => ..., so plural and word-order rules stay in your code. Any key you leave out keeps its English default.
Entity labels, type labels, reasons and documents are host data. EVK displays them as text, never as HTML, and never translates them.
Theme tokens
Section titled “Theme tokens”Colors and spacing are CSS custom properties on .evk, including --evk-bg, --evk-surface, --evk-text, --evk-muted, --evk-border, --evk-accent, --evk-accent-text, --evk-selected, --evk-focus, --evk-warning, --evk-radius, --evk-gap and --evk-duration. Override them on your own class:
.my-brand.evk { --evk-accent: #7a2e8e; --evk-focus: #7a2e8e; --evk-radius: 6px; }Pass className: 'my-brand' to the provider. Because every rule is scoped, two differently themed providers can share a page. The gallery shows light, dark and RTL instances side by side, and the browser suite checks that they stay independent.
EVK respects prefers-reduced-motion (no animated scrolling or transitions) and forced-colors (system colors and visible borders). If you override tokens, keep the default contrast: the accessibility suite runs axe WCAG 2.1 A/AA against the built-in themes, not yours.
The graph is not a React component internally, so it takes its own options (mountGraph, EntityGraph, ControllerGraph):
import { mountGraph, DEFAULT_GRAPH_STRINGS } from 'entity-viz-kit/graph';
const handle = mountGraph(container, { snapshot, registry, contextKey: 'page-1', theme: 'dark', // 'light' | 'dark'; update() can change it later labelScale: 1.5, // canvas label size, 0.75–3; larger labels mean fewer labels fit strings: { ...DEFAULT_GRAPH_STRINGS, title: 'Verbindungen', pin: 'Anheften', unpin: 'Lösen', page: (page, pages) => `Seite ${page} von ${pages}`, status: d => `${d.visibleNodes}/${d.nodes} Entitäten · ${d.visibleEdges}/${d.edges} Beziehungen` }});handle.update({ theme: 'light' });GraphStrings covers every piece of text the graph draws or announces: toolbar, navigator, status line, pair summary, pin controls, the canvas “pinned” suffix and the stage’s role description. The graph does not read the React provider. Pass the same locale’s strings to both.
The audience display sets labelScale from the published presentation scale, so labels stay readable at a distance (see the presentation guide).
Live highlighter
Section titled “Live highlighter”The highlighter paints with fixed translucent colors that are readable on light and dark pages. It draws no text, so it has nothing to localize. Mention labels in the sidebar come from your annotations.
Checked behavior
Section titled “Checked behavior”- Gallery scenarios check independent light, dark and RTL instances, localized anchor status, host hooks, and localized workspace and presentation copy with two operator panels (instance-unique IDs).
- A graph scenario checks German graph strings in the real renderer.
- The accessibility suite checks every surface with axe, and the long-label and 320 px scenarios check wrapping.
Screen readers and real devices have not been used. See docs/checklists/assistive-technology.md.