Skip to main content

Bits UI Map Table (v0.1)

Evalium frontend shared component mapping: Interface pattern → Evalium reusable component → Bits UI primitives → API/data → contracts → build rules.

This doc is intended to be expanded page-by-page. It aligns to:

  • COMPONENT-INTERACTION-MAP.md (URL-as-state, shallow routing, drawer semantics, focus restore, param preservation).
  • UX-SHARED-COMPONENTS-CONTRACT.md (standard hub/table/drawer patterns, import, bulk, sidekick, etc.).

Key doctrine:

  • Calm by default: show essentials; push depth into drawers/Explain.
  • Two worlds: authoring can feel “editable”; Execution truth is append-only and must not look overwritable.
  • Capability-first gating: UI gates by capabilities, not role names.

0) Power Upgrades (to keep this table enforceable)

To make this table a real build contract, we include:

  • Mutability Class: authoring (Save Lie OK) vs Execution (NO Save Lie) vs Projection/Queue.
  • Risk Tier: Safe / Destructive / Irreversible / Legal.
  • Capability Gates: the capabilities that control visibility/enabled state of actions.
  • URL State Contract: which URL params represent state and what must be preserved.
  • Freshness/Caching: expected staleness behavior + “Updated X ago”.
  • Redaction/Safety: anti-leak rules, especially for Glass Box or portal-scoped surfaces.
  • Telemetry Hooks: suggested instrumentation events.
  • Loading/Error/Empty: standard states for consistency.
  • Props Contract: standardized props to force reusability.
  • Do Not Do: regression prevention.
  • Testing Contract: minimum unit/e2e expectations.

1) Terms

  • Bits UI primitives: accessible building blocks (Dialog, DropdownMenu, Tabs, Combobox, etc.).
  • Evalium components: app-level reusable components built using Bits primitives and Evalium contracts.
  • Drawer-supported entity types: types that can be opened as a right-side ContextDrawer without full navigation (see Interaction Map baseline).

2) Table A — Pattern Map (high-level)

Pattern IDInterface typeEvalium component (reusable)Mutability classBits UI primitivesExample endpoints/data sourcesCapability gates (examples)URL state contractRisk tierFreshness/cachingA11y notes
NAV-01Link & navigationEntityLinkn/aTooltip (optional)Any entity reference*.read capsMust be real <a>; intercept only drawer-supported types; preserve paramsSafen/aDon’t break Cmd/Ctrl click; focus visible; SR reads target
DRW-01Drawer state orchestrationDrawerCoordinator / DrawerServicen/an/aDerived from URL + fetchesn/adrawer=type:id, drawerTab=; shallow routing; preserve all inventory paramsSafecache optionalBack closes drawer; abort fetch on close; restore focus
DRW-02Context surfaceContextDrawer (right sheet)Mixed (mostly read)Dialog (sheet-style) + ScrollArea + Tabs + TooltipDrawer read models per entity typeGate actions inside drawerDeep-linkable; always include “Open full page”Safe→DestructiveCache keyed by type:id (SHOULD)Focus trap; ESC closes; permission-safe notfound/forbidden
HUB-01Page shellStandardHubDepends on pageTabs + DropdownMenu + Separator + Toolbar (layout)Any hub pageGate CTAsTabs must preserve drawer paramsSafeLive-ish bannersConsistent tab naming; SR-friendly headings
INV-01Dense inventory listDataTable / InventoryTableProjection/QueueCheckbox + DropdownMenu + ContextMenu + Popover + Combobox + Select + Pagination + ScrollAreaUsers/Groups lists; Questions/Evals inventoriesGate bulk+row actionsviewId/q/sort/page preserved on drawer open/closeSafeShow “Updated X ago”; stale thresholdStable row keys; keyboard access to row actions
INV-02Saved viewsSavedViewsDrawerauthoring-liteDialog or Popover + Tabs/questions/views, /evaluations/viewsGate create/delete/shareviewId= canonical; view switching must not lose other params unexpectedlyDestructive (delete)LiveDialog focus; SR announces changes
FIL-01FilteringFilterBarn/aCombobox + Select + Popover + ToggleGroup/SwitchInventory query paramsn/aFilters round-trip in URLSafeCache option listsLabels + clear actions; chips keyboard removable
CHIP-01Status semanticsStatusChipn/aTooltipBackend status codesn/an/aSafen/aTooltip explains meaning; avoid color-only signaling
BULK-01Bulk operationsBulkActionBar + BulkActionDrawerauthoring / ProjectionDialog (sheet) + Progress + Tabs + TooltipBulk endpoints (e.g., /questions/bulk)Gate by capability + object stateMust not break inventory params; selection must persistDestructiveLiveConfirmations accessible; progress announced
IMP-01Import wizardImportWizardauthoringTabs-as-steps + Progress + Dialog confirm + TooltipImport preview/commit endpointsGate import by capabilityOptional step=; protect against accidental navigation lossDestructive-ishLivePreview table navigable; clear error reporting
VAL-01Validation gatingValidationSidekickauthoringAccordion/Collapsible + ScrollArea + TooltipValidation codes + preview/validate flowsGate publish actionAnchor/focus registry; deep-link where possibleSafeLive“Go to” focuses the exact control reliably
MOD-01Risk confirmationImpactSummaryModalauthoringAlertDialog (preferred) + Tabs/ToggleGroup (optional)Usage/dependency dataGate destructive actionsn/aIrreversible-ishLiveAlert semantics for destructive; explicit wording
INS-01Report blockInsightBlockProjectionTooltip + Popover + “Explain” link → DrawerSummary endpoints (e.g., evaluation-summary)Gate reporting accessExplain opens drawer/page; deep-linkableSafeMust show freshness + “insufficient data”Explain must be keyboard reachable
AUD-01Durable historyLedgerTable / TimelineExecution readScrollArea + Separator + TooltipLedger-projected recordsGate ledger viewDeep links per event where possibleLegalSnapshot/truthRead-only semantics; expandable details accessible
GBX-01Glass Box viewerGlassBoxViewerShellExecution (NO Save Lie)Tabs + ScrollArea + Tooltip (sparingly)Glass Box endpoints (submission/programme/engagement)Gate access + redaction by scopeCanonical full-page; shareable URLsLegalSnapshot-orientedNo edit affordances; “truth projector” posture
EXC-01Ops queue + triageExceptionsQueueTable + TriageDrawerProjection/QueueDataTable primitives + Dialog(sheet)Defensibility exception endpointsGate triageFilters preserved; triage deep-linkableDestructive-ishLive-ish + manual refresh CTAState transitions SR-announced

3) Table B — Build Contract Add-ons (props, states, telemetry, redaction, do-not-do, tests)

These rows define the minimum contract required to keep components reusable and consistent.

Pattern IDStandard props contract (v0)Loading/Error/Empty statesTelemetry hooks (suggested)Redaction / safetyDo Not DoMinimum tests
NAV-01href, entityType, entityId, `mode=drawerpageauto, disabledReasonKey?`n/aui.link.clickPermission-safe tooltip copy
DRW-01open(type,id,tab?), close(), replace(type,id,tab?), cacheKey?Must: loading, ready, forbidden, notfound, error+retryui.drawer.open/close/replaceDon’t leak raw errors; show request id if availableDon’t stack/nest drawers; replace semantics onlye2e: back closes drawer; fetch aborted on close; params preserved
DRW-02params={type,id,tab}, prefetchModel?, onCloseFocusId?Must: skeleton + retry + permission safeui.drawer.tab.changeGate actions inside drawerDon’t show actions that user cannot performe2e: focus trap + restore; ESC closes; open full page link exists
INV-01queryState, columns, rowKey, rowActions, bulkActions?, lastUpdatedAt?, staleAfterMs?Must: loading, empty, error+retryui.table.sort/filter/page/selectAvoid leaking PII in telemetryDon’t churn rows; stable keys requirede2e: filter round-trip; selection persists; drawer open/close preserves state
INV-02views[], activeViewId, onCreate/onDelete/onShareMust: empty + errorui.views.switch/create/deleteView sharing obeys capabilityDon’t reset unrelated query paramse2e: switching view updates URL + table; back restores
FIL-01filtersSchema, value, onChange, optionsProvidersMust: option loading statesui.filters.open/clear/changeDon’t put PII in query string without purposeDon’t hide active filtersunit: serialize/deserialize filters; e2e: chips clear correctly
BULK-01actionDefs[], selectedIds[], `dryRun=truefalse, onApply(result)`Must: dryRun preview + partial successui.bulk.open/dryrun/applyRequire explicit confirmation for large blast radiusDon’t treat partial success as full failure
IMP-01steps=[upload,preview,commit], templateLink?, onCommit(result)Must: preview error rows + commit resultsui.import.preview/commitDon’t allow commit when preview invalidDon’t hide row-level errorse2e: invalid blocks commit; commit results durable
VAL-01issues[], focusRegistry, onGoTo(issue)Must: grouped issues + clear severityui.validation.gotoMap backend codes → i18n keysDon’t implement GoTo without stable focus registrye2e: go-to focuses correct field; publish blocked correctly
MOD-01title, summary, impactList[], confirmLabel, danger=trueMust: no silent failureui.confirm.open/confirm/cancelAvoid vague “are you sure”Don’t use plain Dialog for destructive without reasonunit: confirm logic; e2e: enter/esc behaviour
INS-01title, kpis[], explainHref, freshnessMust: insufficient data stateui.insight.view/explainExplain must not leak internal-only signalsDon’t show chart without drilldowne2e: explain opens drawer and preserves inventory params
AUD-01events[], expandableFields, grouping?Must: empty + paging if neededui.ledger.expandRedact internal-only fields by capabilityDon’t present edits as overwritese2e: expand/collapse accessible; stable ordering
GBX-01lensModel, tabs, openInNewTabHref, langMust: forbidden/notfound safeui.glassbox.view/tabStrict redaction; portal scope safeDon’t add edit controls; don’t reframe as dashboarde2e: shareable URL; correct redaction; content is read-only
EXC-01filters, triageModel, onTriageSave, refresh()Must: live-ish refresh statesui.exceptions.refresh/triage/saveTriage comments treated as audit contextDon’t imply triage mutates execution truthe2e: refresh updates; triage persists; suppressedUntil works

To avoid drift, define an app baseline for Bits UI behavior:

  • Dialog defaults (escape closes, focus trap on, scroll lock consistent).
  • Dropdown/Menu alignment + collision behavior consistent.
  • Tooltip delays consistent.

Use a single configuration layer (BitsConfig) to standardize this.


5) Mutability Rules (Save Lie allowed vs forbidden)

Save Lie allowed (authoring)

  • Questions authoring
  • Passage/stimulus authoring
  • Evaluation authoring
  • Saved views, library organisation
  • Import workflows (authoring creates new content/versions)

Save Lie forbidden (Execution/Truth)

  • Glass Box pages (truth projector)
  • Submission truth, evidence lifecycle, approvals/ratifications
  • Ledger timelines and audit record displays
  • Anything presented as “what happened” must be append-only and show history