Results, profiles and relationship evidence
Reuse the same controller and identity grammar
Section titled “Reuse the same controller and identity grammar”The ready-made search application now follows recommendation → query tag → result → mention candidate → entity profile → textual relation → evidence → source → another query tag. The textual relation navigator is a permanent accessible alternative, not disposable placeholder graph UI. No graph pixels are required to inspect evidence.
import { createElement as h } from 'react';import { contextSignature } from 'entity-viz-kit/core';import type { EntityController, PairRelation } from 'entity-viz-kit/core';import { SearchResults, InspectionPanel, useEntityController } from 'entity-viz-kit/react';// controller is stable and host-owned; the host starts and disposes it.export function ReadingWorkspace({ controller, relations }: { readonly controller: EntityController; readonly relations: readonly PairRelation[] }) { const snapshot = useEntityController(controller); return h('div', null, h(SearchResults, { registry: controller.registry, documents: snapshot.search.data?.documents ?? [], phase: snapshot.search.phase, sourceRevision: snapshot.search.dataRevision, currentRevision: snapshot.revision, contextKey: contextSignature(snapshot.state.context), selectedEntityIds: snapshot.state.query.entityIds, onAddEntity: entityId => controller.dispatch({ type: 'query.add', entityId }), onInspectEntity: entityId => controller.dispatch({ type: 'inspect', inspection: { kind: 'entity', entityId } }), onOpenSource: doc => controller.dispatch({ type: 'inspect', inspection: { kind: 'source', documentId: doc.id } }) }), h(InspectionPanel, { controller, relations }) );}This is JavaScript-style composition. The runnable, fully typed application is integration/examples/search/src/ts/main.ts; generated API declarations provide exact prop types. When a host context revision changes without changing its ID, include that revision in contextKey (the reference application uses contextSignature). Results and recommendations retained during refresh keep their prior revision label. Your adapter owns ranking and multi-entity query semantics.
Result documents and passages
Section titled “Result documents and passages”Pass supplied document identity/version, title, source label, optional date/attribution/availability and a structured snippet. Empty title/snippet has a neutral fallback, not an invented fact. Withdrawn/unavailable results do not expose stale passage text or source actions. Malformed data displays an error. HTTP(S) URLs reject credentials and unsafe protocols; no raw-HTML rendering route exists.
SearchResults defaults to 10 documents per page, accepts 1–100, and rejects duplicate IDs or more than 1,000 supplied documents. page/onPageChange permit controlled host navigation. Selection changes do not reset page state. Explicit context changes reset an uncontrolled page; shrinking data clamps the page. Page controls focus the region without forcing page scroll. A host-controlled nextCursor/onLoadMore supports additional retrieval without baking backend pagination syntax into EVK.
EvidencePassage partitions overlapping mentions rather than choosing an identity by processing order. A mention can carry several entity IDs. The chooser gives explicit Add and Inspect actions with disambiguating registry metadata. Query inclusion, inspected entity, source-term match, supplied endpoint and selected evidence have separate style states.
Copied paragraph text stays exactly the supplied text. Pointer text selection does not trigger query addition; native source anchors retain navigation. A companion entity navigator supports keyboard actions even on linked passages. Chooser actions are siblings outside the source paragraph, not nested buttons or injected label text. Escape closes the chooser and restores its invoking focus. Plain-text copy and unsafe-string tests exercise real DOM text.
Profiles and capabilities
Section titled “Profiles and capabilities”EntityCard is compact; EntityProfile displays the expanded variant. Both accept a valid entity or explicit unavailable/withdrawn state. Metadata and alias lists are bounded (card starts with three, profile six; Show all expands within the schema’s 100-item bound). IDs remain authoritative when labels change. Accepted lazy profiles update registry display metadata only after the existing controller accepts the request; a late response cannot overwrite the selected profile.
No images load by default. Supply allowImage(url) only when the host permits that resource; the URL must also satisfy EVK’s HTTP(S) policy. A load failure uses the local glyph fallback. No avatar provider or hidden image proxy is used. Add, Inspect, Show connections and Open source appear only when their corresponding callback or safe source URL is supplied. The reference application exposes real textual connections rather than a dead graph button.
Details, source navigation and failure states
Section titled “Details, source navigation and failure states”DetailContainer supports panel, sheet, popover or automatic presentation. Automatic mode uses a modal native dialog at up to 720 CSS pixels; desktop uses a nonmodal region. Modal Tab wrapping, Escape, accessible title, source-focus restoration, bounded scroll and safe-area sizing are implemented. focusKey moves focus to the new detail title without changing query state. Hosts can override navigation/container choice and provide fallbackFocus for an unmounted source trigger.
InspectionPanel is optional convenience around InspectionContent. It keeps up to 32 inspection IDs for Back, not a second cache of documents. Only identity/context changes initiate keyed lazy loads. Same-context source failure retains a valid original citation and return route. Changing host context clears resource applicability and old navigation; it must not retain restricted record snapshots privately.
Loading, retrieval failure/retry, unavailable/inaccessible source, successful empty evidence, absent relation and not-yet-loaded current source are different states. The host supplies optional profile/relation/evidence/source adapter methods. Missing capabilities never become fake successful fixture results.
Relations and source evidence
Section titled “Relations and source evidence”One PairId selects a pair with all supplied directional assertions. Each assertion retains its own ID, endpoints, predicate, status/date fields and supporting/contradictory/uncertain links. No predicate or confidence is derived from co-occurrence. Multiple assertions may reference the same evidence without destructive deduplication. Standalone RelationEvidencePanel accepts loaded evidence or an onOpenEvidence loader callback.
EvidenceItem always identifies the original citation. SourceViewer shows original quote/version separately from a bounded current-source window. Only exact or uniquely re-anchored results receive a current target highlight; ambiguous and unavailable outcomes do not guess. Its window defaults to 4,000 UTF-16 units, configurable 100–10,000 with surrogate-safe edges, and retains clipped supplied entity actions. Offset rules and concrete payload examples are in the canonical-text guide.
The future graph handler is simply controller.dispatch({ type: 'inspect', inspection: { kind: 'relation', pairId } }). It must reuse these components/contracts instead of reimplementing evidence retrieval.
Theme and localization
Section titled “Theme and localization”The existing EntityVizProvider scopes the same tokens and action strings. Override readingStrings independently from search strings, including pagination and offset labels. Light/dark, forced colors, reduced motion, RTL logical spacing and sheet sizing use the existing CSS boundary. Real device, assistive-technology and viewing-distance evaluation remain separate acceptance requirements; automated screenshots alone do not certify them.
Run /reading.html for original/changed/ambiguous quotations, overlapping mentions, profiles, withdrawal, opt-in failed image loading, paging, source failures, native links, Unicode and static DOM mapping. Run /gallery.html for inherited search controls, and /legacy.html for the native-DOM regression consumer.