@zephytiju/prism-evidence-table 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +175 -0
  2. package/dist/AuditLink.d.ts +16 -0
  3. package/dist/AuditLink.d.ts.map +1 -0
  4. package/dist/AuditLink.js +31 -0
  5. package/dist/ConfidenceCell.d.ts +10 -0
  6. package/dist/ConfidenceCell.d.ts.map +1 -0
  7. package/dist/ConfidenceCell.js +11 -0
  8. package/dist/EvidenceListBody.d.ts +15 -0
  9. package/dist/EvidenceListBody.d.ts.map +1 -0
  10. package/dist/EvidenceListBody.js +17 -0
  11. package/dist/EvidenceTable.d.ts +31 -0
  12. package/dist/EvidenceTable.d.ts.map +1 -0
  13. package/dist/EvidenceTable.js +75 -0
  14. package/dist/EvidenceTableHead.d.ts +12 -0
  15. package/dist/EvidenceTableHead.d.ts.map +1 -0
  16. package/dist/EvidenceTableHead.js +16 -0
  17. package/dist/EvidenceTableHeader.d.ts +20 -0
  18. package/dist/EvidenceTableHeader.d.ts.map +1 -0
  19. package/dist/EvidenceTableHeader.js +45 -0
  20. package/dist/EvidenceTableRows.d.ts +16 -0
  21. package/dist/EvidenceTableRows.d.ts.map +1 -0
  22. package/dist/EvidenceTableRows.js +30 -0
  23. package/dist/OpenViewArrow.d.ts +16 -0
  24. package/dist/OpenViewArrow.d.ts.map +1 -0
  25. package/dist/OpenViewArrow.js +29 -0
  26. package/dist/VariantDropdown.d.ts +36 -0
  27. package/dist/VariantDropdown.d.ts.map +1 -0
  28. package/dist/VariantDropdown.js +99 -0
  29. package/dist/index.d.ts +7 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +3 -0
  32. package/dist/locales/en.json +14 -0
  33. package/dist/locales/index.d.ts +59 -0
  34. package/dist/locales/index.d.ts.map +1 -0
  35. package/dist/locales/index.js +27 -0
  36. package/dist/locales/zh-CN.json +14 -0
  37. package/dist/tableColumns.d.ts +11 -0
  38. package/dist/tableColumns.d.ts.map +1 -0
  39. package/dist/tableColumns.js +20 -0
  40. package/dist/tokens.d.ts +23 -0
  41. package/dist/tokens.d.ts.map +1 -0
  42. package/dist/tokens.js +22 -0
  43. package/dist/types.d.ts +71 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +1 -0
  46. package/locales/en.json +14 -0
  47. package/locales/zh-CN.json +14 -0
  48. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # PrismEvidenceTableMicroUI
2
+
3
+ Platform Prism evidence-table micro-UI. Component id: `evidence-table`.
4
+ Published to npm as [`@zephytiju/prism-evidence-table`](https://www.npmjs.com/package/@zephytiju/prism-evidence-table).
5
+
6
+ Dossier **embedded block** (design decision D10): a preview of the evidence view of its source
7
+ file — the SAME file the Geovision Embed references. The card chrome is retained — outlined
8
+ border, kind tag pill (`EVIDENCE TABLE`), header with the `SRC FILE · {file}` chip — the
9
+ source-file **variant dropdown** on top (`VIEW · {saved view} ▾` opening
10
+ `SAVED VIEWS · {file}`), and the ↗ **open arrow** at the block's top-right BESIDE the dropdown
11
+ (the agreed embedded-block chrome shared with the geovision-embed block: the rows are NOT
12
+ click-to-open — the arrow emits the open intent `{ sourceFileRef, viewId }` for the host to turn
13
+ into navigation). Picking a saved view re-previews that variant's `IEvidenceSource`-style
14
+ rows: the four-column table (`SOURCE / OBSERVATION / CONF. / AUDIT ID`) with row separators and
15
+ per-row audit drill links over `IAuditRef` locators; a `list` layout renders the same rows as
16
+ cards. Being a table does NOT make dossier-native tables embedded — only file-preview blocks are
17
+ embedded (D10). Sub-component library per D5 — rendered inside a host axiom component (the
18
+ dossier Block Stack) through configuration, not a Prism composition member. Makes NO Lattice
19
+ calls; rows are interface-typed and generic over evidence models.
20
+
21
+ ## Configuration keys
22
+
23
+ | Prop | Meaning |
24
+ | --- | --- |
25
+ | `sourceFileRef` | Source file the table previews (the SRC FILE chip) — the SAME file the Geovision Embed references, e.g. `"REDWATER-CORRIDOR.WV"` |
26
+ | `savedViews` | Saved views (variants) of the source file — the dropdown list; each carries its evidence rows |
27
+ | `selectedViewId` | Currently previewed variant id (controlled; defaults to the channel value, then the first view) |
28
+ | `layout` | `"table"` four columns (default) or `"list"` row cards |
29
+ | `columns` | Columns rendered, in order — `source` / `observation` / `confidence` / `audit` (default: all four) |
30
+ | `locale` | UI locale for the component-fixed strings: `"en" \| "zh-CN"` (default `"en"`) — see [i18n](#internationalization-i18n) |
31
+ | `onOpenView` | Receives the ↗ arrow's open intent `{ sourceFileRef, viewId }`; the fallback is a console no-op |
32
+
33
+ ## Channel contract
34
+
35
+ | Direction | Kind | Id | Payload |
36
+ | --- | --- | --- | --- |
37
+ | publishes | state | `evidence-table.selected-view` | `{ sourceFileRef, viewId }` when the dropdown switches the previewed saved view |
38
+ | consumes | state | `evidence-table.selected-view` | derives the previewed variant when `selectedViewId` is not set (values addressing a different source file are ignored) |
39
+ | emits | event | `evidence-table.audit-drill` | `{ sourceFileRef, viewId, rowId, auditId }` — ephemeral notification when an analyst drills into a row's audit chain |
40
+
41
+ The ↗ open arrow additionally emits an **open intent** (`onOpenView` callback +
42
+ `console.info`) carrying `{ sourceFileRef, viewId }` of the previewed saved view — a demo
43
+ no-op until the host wires navigation.
44
+
45
+ Channel ids are string literals at every call-site so the build-time channel-graph scanner can
46
+ derive the graph. The state publication is setter-only; the derived selection is what renders.
47
+ The payload carries the source file reference because both embedded blocks of a dossier preview
48
+ the SAME file — the host (Main Editor) re-previews the picked saved view on every block of that
49
+ file, the D10 semantic.
50
+
51
+ ## Audit rule
52
+
53
+ Previewing evidence and drilling into an audit chain are routine reads. This component emits NO
54
+ audit event and appends nothing to any audit chain (`IAuditRef.append` is never invoked). The
55
+ only event it ever emits is the internal `evidence-table.audit-drill` (an ephemeral drill
56
+ notification the host turns into audit-chain navigation, not an observable domain action).
57
+
58
+ ## Internationalization (i18n)
59
+
60
+ The component ships `en` and `zh-CN` locale bundles — `src/locales/en.json` / `src/locales/zh-CN.json` —
61
+ and every component-fixed UI string is resolved from them (kind tag, SRC FILE chip, `VIEW · {view}`
62
+ pill, `SAVED VIEWS · {file}` menu title, the four column headers, and the audit link tooltip).
63
+ The component renders no hardcoded copy.
64
+
65
+ ```json
66
+ {
67
+ "evidence-table": {
68
+ "kindTag": "EVIDENCE TABLE",
69
+ "srcFile": "SRC FILE · {file}",
70
+ "viewPrefix": "VIEW · {view}",
71
+ "savedViewsTitle": "SAVED VIEWS · {file}",
72
+ "colSource": "SOURCE",
73
+ "colObservation": "OBSERVATION",
74
+ "colConfidence": "CONF.",
75
+ "colAuditId": "AUDIT ID",
76
+ "auditLinkTitle": "OPEN AUDIT CHAIN · {auditId}"
77
+ }
78
+ }
79
+ ```
80
+
81
+ - `locale?: "en" | "zh-CN"` prop (default `"en"`) selects the string table per instance.
82
+ - `srcFile` / `viewPrefix` / `savedViewsTitle` / `auditLinkTitle` use simple `{placeholder}`
83
+ interpolation (plain substitution, no regexes — `formatMessage` is exported from the package
84
+ entry).
85
+ - **Composition-authored strings are localized by the composer; component-fixed strings live in the
86
+ locale JSONs.** Saved-view labels, evidence-row observations and audit ids are
87
+ data/configuration: a host with localized row copy passes its own strings per locale.
88
+ - Locale bundles are namespaced under the component id (`"evidence-table"`) so a composer can
89
+ deep-merge every component's bundle into ONE UI language bundle without collisions:
90
+
91
+ ```ts
92
+ import { locales as evidenceTableLocales } from "@zephytiju/prism-evidence-table";
93
+ // evidenceTableLocales["zh-CN"] -> { "evidence-table": { … } }
94
+ const uiBundle = deepMerge(hostStrings, evidenceTableLocales["zh-CN"]);
95
+ ```
96
+
97
+ The parsed bundles are exported from the package entry (`locales`, `en`, `zhCN`,
98
+ `stringsForLocale`), and the raw JSONs are also served by the `./locales/*` exports subpath
99
+ (e.g. `@zephytiju/prism-evidence-table/locales/zh-CN.json`); `files` ships both `dist` and
100
+ `locales`.
101
+
102
+ ## Theme
103
+
104
+ No palette is hardcoded. Every color resolves to SEMANTIC theme tokens (`ok`, `accent`,
105
+ `threat`, `warn`, `signal`, `card`, `card-dark`, `border`, `line`, `muted`, `text`, `input`,
106
+ `deep`, `panel`) consumed as CSS variables, plus `--mantine-font-family-monospace` for the mono
107
+ typography — the palette is supplied entirely by the host's `MantineProvider`. The local demo
108
+ ships TWO themes, both defined in `src/demo.tsx`: `geovisionTheme` (dark), mapping each semantic
109
+ token onto the exact `:root` variables of the CONFIRMED v9 design (deep bg, panel black, card,
110
+ card-dark, mint, blue, amber, red, purple, muted, border, grid2), and the contrasting
111
+ `latticeLightTheme` (light), mapping the SAME semantic token keys onto a different palette — the
112
+ component is skinned purely through the surrounding `MantineProvider`.
113
+
114
+ ## Source layout
115
+
116
+ `src/` is strictly two parts:
117
+
118
+ - Component source (what the package compiles): `EvidenceTable.tsx` (the embedded block: card
119
+ chrome + variant dropdown + the evidence table / list), `VariantDropdown.tsx` (the
120
+ source-file variant dropdown chrome shared by the dossier embedded blocks), `index.ts` (public
121
+ entry), and `src/locales/` (`en.json`, `zh-CN.json`, `index.ts` — the i18n string bundles,
122
+ their resolver, and the `{placeholder}` interpolation helper).
123
+ - Demo: exactly ONE file, `src/demo.tsx` — the two host themes (GeoVision v9 + Lattice Light),
124
+ all demo test data (the shared source file `REDWATER-CORRIDOR.WV` with its three saved views
125
+ CORRIDOR OVERVIEW / CONVOY TIMING / PORT DISRUPTION, each carrying its evidence rows with
126
+ confidence and audit ids), the channel seeding (`seedDemoChannels`) and the channel + audit
127
+ drill event monitors, and the demo page rendering TWO `EvidenceTable` instances side by side
128
+ behind a global EN | 中文 language switcher (plus per-instance switches).
129
+
130
+ The npm package ships `dist` (compiled component + type declarations + locale JSONs) and the
131
+ top-level `locales/` directory (the raw JSON bundles, served by the `./locales/*` exports
132
+ subpath); no demo code is published. `scripts/copy-locales.mjs` copies the JSON bundles into
133
+ both locations during `npm run build`.
134
+
135
+ ## Local development
136
+
137
+ ```sh
138
+ npm install
139
+ npm run typecheck
140
+ npm test
141
+ npm run dev
142
+ npm run shot-demo
143
+ ```
144
+
145
+ `npm install` pulls the platform peers (`@zephytiju/prism-react`,
146
+ `@zephytiju/lattice-common-interfaces`) from the npm registry, along with the host-side peer
147
+ dependencies (`react`, `react-dom`, `@mantine/core`). When consuming the published package,
148
+ install it directly (`npm install @zephytiju/prism-evidence-table`) and provide those peer
149
+ dependencies in the host application.
150
+
151
+ The demo (`npm run dev`, entry `src/demo.tsx`) plays the host: on load it seeds the file-level
152
+ selected view (CONVOY TIMING) the way a host that just materialized the table from a dropped
153
+ evidence pack would (the component itself makes no Lattice calls, so no mock executor is needed)
154
+ and renders TWO `EvidenceTable` instances side by side, each inside its own `MantineProvider`
155
+ with a different theme (GeoVision v9 dark left, Lattice Light right) — both reference the SAME
156
+ source file, so the VIEW ▾ dropdown on EITHER instance switches the previewed saved view on
157
+ BOTH. A global EN | 中文 segmented control switches the `locale` prop of BOTH instances at once,
158
+ and each instance carries its own per-instance control so the two hosts can render DIFFERING
159
+ locales simultaneously; the monitors show the published file-level selection and the last
160
+ `evidence-table.audit-drill` event (click an audit id), and RESEED resets the view to CONVOY
161
+ TIMING. `npm run shot-demo` boots the vite dev server, drives the demo in headless Chrome and
162
+ captures to `/tmp/guanlan-review/`: `evidence-dark-en_dropdown-open.png` (dark theme, EN,
163
+ dropdown open listing the shared saved views; light host renders zh-CN beside it),
164
+ `evidence-zh_dropdown-open-light.png` (both hosts zh-CN, dropdown open on the light host), and
165
+ `evidence-variant-switched.png` (PORT DISRUPTION picked on the dark host — both pills and rows
166
+ switch through the shared channel — plus the audit-drill event monitor showing AUD-4471).
167
+
168
+ ## Design record
169
+
170
+ Component doc: https://qcnwge0wy4s0.feishu.cn/wiki/UuRjwAa4EiZ1cUkS22RcGqAon68 — UX, Lattice
171
+ binding (IEvidenceSource[] with IAuditRef locators), variants and configuration. Parent design:
172
+ https://qcnwge0wy4s0.feishu.cn/wiki/B87YwS2PriaGvlkAcOtctKm8nsd — D5 (sub-component libraries),
173
+ D10 (dossier block surface taxonomy). Visual reference: the authoritative v9 interactive HTML
174
+ prototype attached to the parent design doc (`.block` / `.btag` / `.srcref` / `.vsel` /
175
+ `.vmenu` chrome and the four-column evidence rows).
@@ -0,0 +1,16 @@
1
+ import type { EvidenceTableStrings } from "./locales/index.js";
2
+ import type { EvidenceTableRow } from "./types.js";
3
+ /**
4
+ * The audit cell piece — the row's IAuditRef audit id as a drill link over
5
+ * the locator. Clicking emits the ephemeral "evidence-table.audit-drill"
6
+ * Prism event (an action notification the HOST turns into navigation);
7
+ * drilling into evidence is NOT an audit-worthy action, so no audit event is
8
+ * ever emitted.
9
+ */
10
+ export declare function AuditLink({ row, sourceFileRef, viewId, strings, }: {
11
+ readonly row: EvidenceTableRow;
12
+ readonly sourceFileRef: string;
13
+ readonly viewId: string;
14
+ readonly strings: EvidenceTableStrings;
15
+ }): import("react").JSX.Element;
16
+ //# sourceMappingURL=AuditLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditLink.d.ts","sourceRoot":"","sources":["../src/AuditLink.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGvE;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EACxB,GAAG,EACH,aAAa,EACb,MAAM,EACN,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACxC,+BAgCA"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { UnstyledButton } from "@mantine/core";
3
+ import { emitPrismEvent } from "@zephytiju/prism-react";
4
+ import { formatMessage } from "./locales/index.js";
5
+ import { ACCENT, MONO, TEXT } from "./tokens.js";
6
+ /**
7
+ * The audit cell piece — the row's IAuditRef audit id as a drill link over
8
+ * the locator. Clicking emits the ephemeral "evidence-table.audit-drill"
9
+ * Prism event (an action notification the HOST turns into navigation);
10
+ * drilling into evidence is NOT an audit-worthy action, so no audit event is
11
+ * ever emitted.
12
+ */
13
+ export function AuditLink({ row, sourceFileRef, viewId, strings, }) {
14
+ return (_jsx(UnstyledButton, { type: "button", ff: MONO, fz: 10, style: { color: TEXT, cursor: "pointer", textAlign: "left" }, title: formatMessage(strings.auditLinkTitle, { auditId: row.audit.auditId }), "data-testid": `evidence-table-audit-${row.id}`, onClick: () => {
15
+ // Ephemeral action notification — the host navigates to the audit
16
+ // chain; drilling into evidence is NOT an audit-worthy action.
17
+ emitPrismEvent("evidence-table.audit-drill", {
18
+ sourceFileRef,
19
+ viewId,
20
+ rowId: row.id,
21
+ auditId: row.audit.auditId,
22
+ });
23
+ }, onMouseEnter: (event) => {
24
+ event.currentTarget.style.color = ACCENT;
25
+ event.currentTarget.style.textDecoration = "underline";
26
+ event.currentTarget.style.textUnderlineOffset = "3px";
27
+ }, onMouseLeave: (event) => {
28
+ event.currentTarget.style.color = TEXT;
29
+ event.currentTarget.style.textDecoration = "none";
30
+ }, children: row.audit.auditId }));
31
+ }
@@ -0,0 +1,10 @@
1
+ import type { EvidenceTableRow } from "./types.js";
2
+ /**
3
+ * The confidence cell piece — the row's model confidence as a mint "NN%"
4
+ * string. Rendered empty when the model carries no confidence, so the same
5
+ * piece serves the table column and the list row card.
6
+ */
7
+ export declare function ConfidenceCell({ row }: {
8
+ readonly row: EvidenceTableRow;
9
+ }): import("react").JSX.Element;
10
+ //# sourceMappingURL=ConfidenceCell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfidenceCell.d.ts","sourceRoot":"","sources":["../src/ConfidenceCell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,GAAG,EAAE,EAAE;IACtC,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC;CAChC,+BAYA"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text } from "@mantine/core";
3
+ import { MONO, OK } from "./tokens.js";
4
+ /**
5
+ * The confidence cell piece — the row's model confidence as a mint "NN%"
6
+ * string. Rendered empty when the model carries no confidence, so the same
7
+ * piece serves the table column and the list row card.
8
+ */
9
+ export function ConfidenceCell({ row }) {
10
+ return (_jsx(Text, { ff: MONO, fz: 10, fw: 500, style: { color: OK }, "data-testid": `evidence-table-cell-${row.id}-confidence`, children: row.confidence === undefined ? "" : `${String(row.confidence)}%` }));
11
+ }
@@ -0,0 +1,15 @@
1
+ import type { EvidenceTableStrings } from "./locales/index.js";
2
+ import type { EvidenceColumn, EvidenceTableRow } from "./types.js";
3
+ /**
4
+ * The "list" layout variant — the SAME previewed evidence rows rendered as
5
+ * row cards (source + confidence on top, observation below, audit drill link
6
+ * last) instead of the four-column grid.
7
+ */
8
+ export declare function EvidenceListBody({ rows, columns, sourceFileRef, viewId, strings, }: {
9
+ readonly rows: readonly EvidenceTableRow[];
10
+ readonly columns: readonly EvidenceColumn[];
11
+ readonly sourceFileRef: string;
12
+ readonly viewId: string;
13
+ readonly strings: EvidenceTableStrings;
14
+ }): import("react").JSX.Element;
15
+ //# sourceMappingURL=EvidenceListBody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceListBody.d.ts","sourceRoot":"","sources":["../src/EvidenceListBody.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,OAAO,EACP,aAAa,EACb,MAAM,EACN,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACxC,+BAgCA"}
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Group, Stack, Text } from "@mantine/core";
3
+ import { AuditLink } from "./AuditLink.js";
4
+ import { ConfidenceCell } from "./ConfidenceCell.js";
5
+ import { BORDER, CARD_BG, MONO, TEXT } from "./tokens.js";
6
+ /**
7
+ * The "list" layout variant — the SAME previewed evidence rows rendered as
8
+ * row cards (source + confidence on top, observation below, audit drill link
9
+ * last) instead of the four-column grid.
10
+ */
11
+ export function EvidenceListBody({ rows, columns, sourceFileRef, viewId, strings, }) {
12
+ return (_jsx(Stack, { gap: 8, "data-testid": "evidence-table-list", children: rows.map((row) => (_jsxs(Box, { p: "8px 12px", style: {
13
+ background: CARD_BG,
14
+ border: `1px solid ${BORDER}`,
15
+ borderRadius: 6,
16
+ }, "data-testid": `evidence-table-row-${row.id}`, children: [_jsxs(Group, { justify: "space-between", wrap: "nowrap", gap: 8, children: [_jsx(Text, { ff: MONO, fz: 10, fw: 500, style: { color: TEXT }, "data-testid": `evidence-table-cell-${row.id}-source`, children: row.source }), columns.includes("confidence") && row.confidence !== undefined ? (_jsx(ConfidenceCell, { row: row })) : null] }), _jsx(Text, { ff: MONO, fz: 10, style: { color: TEXT }, "data-testid": `evidence-table-cell-${row.id}-observation`, children: row.observation }), columns.includes("audit") ? (_jsx(AuditLink, { row: row, sourceFileRef: sourceFileRef, viewId: viewId, strings: strings })) : null] }, row.id))) }));
17
+ }
@@ -0,0 +1,31 @@
1
+ import type { EvidenceTableProps } from "./types.js";
2
+ /**
3
+ * Platform Prism evidence-table micro-UI (component id "evidence-table"): the
4
+ * Dossier embedded block (D10) previewing the evidence view of its source
5
+ * file — the SAME file the Geovision Embed references, so both blocks carry
6
+ * the same source-file variant dropdown and picking a saved view on either
7
+ * re-previews that file's variant. Card chrome retained — outlined border,
8
+ * kind tag pill, header with the SRC FILE chip — then the four-column evidence
9
+ * table (SOURCE / OBSERVATION / CONF. / AUDIT ID) with row separators and
10
+ * per-row audit drill links over IAuditRef locators; a "list" layout renders
11
+ * the same rows as cards.
12
+ *
13
+ * Sub-component library per D5: rendered inside a host axiom component (the
14
+ * dossier Block Stack) through configuration; not a Prism composition member.
15
+ * Makes NO Lattice calls — the host supplies the saved views (IFileEntry +
16
+ * IEvidenceSource rows with confidence and audit ids), interface-typed and
17
+ * generic over evidence models. Being a table does NOT make dossier-native
18
+ * tables embedded — only file-preview blocks are embedded (D10).
19
+ *
20
+ * No palette is hardcoded: every color resolves to semantic theme tokens
21
+ * (ok / accent / card / card-dark / border / muted / text …) supplied by the
22
+ * host's MantineProvider. Previewing evidence and drilling into an audit
23
+ * chain are routine reads — NO audit event is ever emitted; the audit drill
24
+ * is an ephemeral Prism event the host turns into navigation.
25
+ *
26
+ * Composition root: wires the shared file-level channel to the header's
27
+ * variant dropdown and the derived active saved view into the table/list
28
+ * bodies; presentation lives in the focused sub-component files.
29
+ */
30
+ export declare function EvidenceTable({ sourceFileRef, savedViews, selectedViewId, layout, columns, locale, onOpenView, }: EvidenceTableProps): import("react").JSX.Element;
31
+ //# sourceMappingURL=EvidenceTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceTable.d.ts","sourceRoot":"","sources":["../src/EvidenceTable.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,EAC5B,aAAa,EACb,UAAU,EACV,cAAc,EACd,MAAgB,EAChB,OAAyB,EACzB,MAAa,EACb,UAAU,GACX,EAAE,kBAAkB,+BAiFpB"}
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Stack } from "@mantine/core";
3
+ import { usePrismStateSetter, usePrismStateValue } from "@zephytiju/prism-react";
4
+ import { EvidenceListBody } from "./EvidenceListBody.js";
5
+ import { EvidenceTableHead } from "./EvidenceTableHead.js";
6
+ import { EvidenceTableHeader } from "./EvidenceTableHeader.js";
7
+ import { EvidenceTableRows } from "./EvidenceTableRows.js";
8
+ import { stringsForLocale } from "./locales/index.js";
9
+ import { DEFAULT_COLUMNS, gridTemplateForColumns } from "./tableColumns.js";
10
+ import { BORDER, CARD_DARK } from "./tokens.js";
11
+ /**
12
+ * Platform Prism evidence-table micro-UI (component id "evidence-table"): the
13
+ * Dossier embedded block (D10) previewing the evidence view of its source
14
+ * file — the SAME file the Geovision Embed references, so both blocks carry
15
+ * the same source-file variant dropdown and picking a saved view on either
16
+ * re-previews that file's variant. Card chrome retained — outlined border,
17
+ * kind tag pill, header with the SRC FILE chip — then the four-column evidence
18
+ * table (SOURCE / OBSERVATION / CONF. / AUDIT ID) with row separators and
19
+ * per-row audit drill links over IAuditRef locators; a "list" layout renders
20
+ * the same rows as cards.
21
+ *
22
+ * Sub-component library per D5: rendered inside a host axiom component (the
23
+ * dossier Block Stack) through configuration; not a Prism composition member.
24
+ * Makes NO Lattice calls — the host supplies the saved views (IFileEntry +
25
+ * IEvidenceSource rows with confidence and audit ids), interface-typed and
26
+ * generic over evidence models. Being a table does NOT make dossier-native
27
+ * tables embedded — only file-preview blocks are embedded (D10).
28
+ *
29
+ * No palette is hardcoded: every color resolves to semantic theme tokens
30
+ * (ok / accent / card / card-dark / border / muted / text …) supplied by the
31
+ * host's MantineProvider. Previewing evidence and drilling into an audit
32
+ * chain are routine reads — NO audit event is ever emitted; the audit drill
33
+ * is an ephemeral Prism event the host turns into navigation.
34
+ *
35
+ * Composition root: wires the shared file-level channel to the header's
36
+ * variant dropdown and the derived active saved view into the table/list
37
+ * bodies; presentation lives in the focused sub-component files.
38
+ */
39
+ export function EvidenceTable({ sourceFileRef, savedViews, selectedViewId, layout = "table", columns = DEFAULT_COLUMNS, locale = "en", onOpenView, }) {
40
+ // Every component-fixed UI string comes from the bundled locale JSONs;
41
+ // configuration-provided strings (saved-view labels, row copy, …) stay
42
+ // composition-authored.
43
+ const strings = stringsForLocale(locale);
44
+ const selectedView = usePrismStateValue("evidence-table.selected-view");
45
+ const publishSelectedView = usePrismStateSetter("evidence-table.selected-view");
46
+ // Controlled prop wins; otherwise the shared channel value (when it addresses
47
+ // THIS source file) drives the preview, so every embed of the same file
48
+ // re-previews the saved view the analyst picked on any of them (D10).
49
+ const channelViewId = selectedView !== null && selectedView.sourceFileRef === sourceFileRef ? selectedView.viewId : null;
50
+ const firstView = savedViews[0];
51
+ const activeView = savedViews.find((view) => view.id === selectedViewId) ??
52
+ savedViews.find((view) => view.id === channelViewId) ??
53
+ firstView;
54
+ const gridTemplate = gridTemplateForColumns(columns);
55
+ const activeRows = activeView?.rows ?? [];
56
+ const activeViewId = activeView?.id ?? "";
57
+ // The ↗ arrow's open intent — {sourceFileRef, viewId} of the previewed
58
+ // saved view. The table body is NOT click-to-open; the arrow is the only
59
+ // open affordance (the demo's fallback is a console no-op).
60
+ const emitOpenIntent = () => {
61
+ const intent = { sourceFileRef, viewId: activeViewId };
62
+ console.info("evidence-table: open intent", intent);
63
+ onOpenView?.(intent);
64
+ };
65
+ return (_jsxs(Stack, { gap: 0, miw: 0, style: {
66
+ width: "100%",
67
+ maxWidth: 860,
68
+ background: CARD_DARK,
69
+ border: `1px solid ${BORDER}`,
70
+ borderRadius: 6,
71
+ position: "relative",
72
+ }, "data-testid": "evidence-table-card", children: [_jsx(EvidenceTableHeader, { sourceFileRef: sourceFileRef, savedViews: savedViews, activeView: activeView, strings: strings, onSelectView: (viewId) => {
73
+ publishSelectedView({ sourceFileRef, viewId });
74
+ }, onOpenView: emitOpenIntent }), _jsx(Box, { px: 18, pb: 10, pt: 2, "data-testid": "evidence-table-body", children: layout === "table" ? (_jsxs(Box, { children: [_jsx(EvidenceTableHead, { columns: columns, gridTemplate: gridTemplate, strings: strings }), _jsx(EvidenceTableRows, { rows: activeRows, columns: columns, gridTemplate: gridTemplate, sourceFileRef: sourceFileRef, viewId: activeViewId, strings: strings })] })) : (_jsx(EvidenceListBody, { rows: activeRows, columns: columns, sourceFileRef: sourceFileRef, viewId: activeViewId, strings: strings })) })] }));
75
+ }
@@ -0,0 +1,12 @@
1
+ import type { EvidenceTableStrings } from "./locales/index.js";
2
+ import type { EvidenceColumn } from "./types.js";
3
+ /**
4
+ * The table layout's column header row — the locale-resolved SOURCE /
5
+ * OBSERVATION / CONF. / AUDIT ID labels on the prototype flex-fraction grid.
6
+ */
7
+ export declare function EvidenceTableHead({ columns, gridTemplate, strings, }: {
8
+ readonly columns: readonly EvidenceColumn[];
9
+ readonly gridTemplate: string;
10
+ readonly strings: EvidenceTableStrings;
11
+ }): import("react").JSX.Element;
12
+ //# sourceMappingURL=EvidenceTableHead.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceTableHead.d.ts","sourceRoot":"","sources":["../src/EvidenceTableHead.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,YAAY,EACZ,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACxC,+BAyBA"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "@mantine/core";
3
+ import { COLUMN_LABELS } from "./tableColumns.js";
4
+ import { MONO, MUTED } from "./tokens.js";
5
+ /**
6
+ * The table layout's column header row — the locale-resolved SOURCE /
7
+ * OBSERVATION / CONF. / AUDIT ID labels on the prototype flex-fraction grid.
8
+ */
9
+ export function EvidenceTableHead({ columns, gridTemplate, strings, }) {
10
+ return (_jsx(Box, { style: {
11
+ display: "grid",
12
+ gridTemplateColumns: gridTemplate,
13
+ height: 20,
14
+ alignItems: "center",
15
+ }, "data-testid": "evidence-table-header", children: columns.map((column) => (_jsx(Text, { ff: MONO, fz: 9, fw: 500, style: { color: MUTED, letterSpacing: "0.07em" }, "data-testid": `evidence-table-col-${column}`, children: COLUMN_LABELS[column](strings) }, column))) }));
16
+ }
@@ -0,0 +1,20 @@
1
+ import type { EvidenceTableStrings } from "./locales/index.js";
2
+ import type { EvidenceSavedView } from "./types.js";
3
+ /**
4
+ * Card-chrome header of the evidence-table block: the kind tag pill, the SRC
5
+ * FILE chip and, at the top-right BESIDE each other, the source-file variant
6
+ * dropdown and the ↗ open-arrow that emits the open intent. Pure
7
+ * presentation — the dropdown's onSelect is wired by the composition root to
8
+ * the file-level "evidence-table.selected-view" publication; the arrow's
9
+ * onOpen carries {sourceFileRef, viewId} to the host. The table rows are NOT
10
+ * click-to-open — the arrow is the only open affordance.
11
+ */
12
+ export declare function EvidenceTableHeader({ sourceFileRef, savedViews, activeView, strings, onSelectView, onOpenView, }: {
13
+ readonly sourceFileRef: string;
14
+ readonly savedViews: readonly EvidenceSavedView[];
15
+ readonly activeView: EvidenceSavedView | undefined;
16
+ readonly strings: EvidenceTableStrings;
17
+ readonly onSelectView: (viewId: string) => void;
18
+ readonly onOpenView: () => void;
19
+ }): import("react").JSX.Element;
20
+ //# sourceMappingURL=EvidenceTableHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceTableHeader.d.ts","sourceRoot":"","sources":["../src/EvidenceTableHeader.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,UAAU,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,UAAU,GACX,EAAE;IACD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;CACjC,+BAkEA"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "@mantine/core";
3
+ import { VariantDropdown } from "./VariantDropdown.js";
4
+ import { OpenViewArrow } from "./OpenViewArrow.js";
5
+ import { formatMessage } from "./locales/index.js";
6
+ import { ACCENT, CARD_BG, MONO, MUTED } from "./tokens.js";
7
+ /**
8
+ * Card-chrome header of the evidence-table block: the kind tag pill, the SRC
9
+ * FILE chip and, at the top-right BESIDE each other, the source-file variant
10
+ * dropdown and the ↗ open-arrow that emits the open intent. Pure
11
+ * presentation — the dropdown's onSelect is wired by the composition root to
12
+ * the file-level "evidence-table.selected-view" publication; the arrow's
13
+ * onOpen carries {sourceFileRef, viewId} to the host. The table rows are NOT
14
+ * click-to-open — the arrow is the only open affordance.
15
+ */
16
+ export function EvidenceTableHeader({ sourceFileRef, savedViews, activeView, strings, onSelectView, onOpenView, }) {
17
+ return (_jsxs(Box, { h: 42, style: { position: "relative" }, children: [_jsx(Box, { h: 22, px: 10, style: {
18
+ position: "absolute",
19
+ left: 12,
20
+ top: 10,
21
+ borderRadius: 11,
22
+ background: CARD_BG,
23
+ border: `1px solid ${ACCENT}`,
24
+ fontFamily: MONO,
25
+ fontSize: 9,
26
+ fontWeight: 500,
27
+ color: ACCENT,
28
+ letterSpacing: "0.05em",
29
+ display: "inline-flex",
30
+ alignItems: "center",
31
+ }, "data-testid": "evidence-table-kind-tag", children: strings.kindTag }), _jsx(Text, { ff: MONO, fz: 9, style: {
32
+ position: "absolute",
33
+ left: 156,
34
+ top: 16,
35
+ color: MUTED,
36
+ letterSpacing: "0.05em",
37
+ }, "data-testid": "evidence-table-src-file", children: formatMessage(strings.srcFile, { file: sourceFileRef }) }), _jsxs(Box, { style: {
38
+ position: "absolute",
39
+ right: 12,
40
+ top: 10,
41
+ display: "flex",
42
+ alignItems: "flex-start",
43
+ gap: 6,
44
+ }, "data-testid": "evidence-table-header-controls", children: [_jsx(VariantDropdown, { pillText: formatMessage(strings.viewPrefix, { view: activeView?.label ?? "" }), menuTitle: formatMessage(strings.savedViewsTitle, { file: sourceFileRef }), options: savedViews.map((view) => ({ id: view.id, label: view.label })), selectedId: activeView?.id, onSelect: onSelectView, testidPrefix: "evidence-table-view" }), _jsx(OpenViewArrow, { title: strings.openViewTitle, onOpen: onOpenView, testid: "evidence-table-open-arrow" })] })] }));
45
+ }
@@ -0,0 +1,16 @@
1
+ import type { EvidenceTableStrings } from "./locales/index.js";
2
+ import type { EvidenceColumn, EvidenceTableRow } from "./types.js";
3
+ /**
4
+ * The table layout's body — the previewed saved view's evidence rows on the
5
+ * prototype flex-fraction grid, one grid row per row with separators, each
6
+ * configured column rendered by its focused cell piece.
7
+ */
8
+ export declare function EvidenceTableRows({ rows, columns, gridTemplate, sourceFileRef, viewId, strings, }: {
9
+ readonly rows: readonly EvidenceTableRow[];
10
+ readonly columns: readonly EvidenceColumn[];
11
+ readonly gridTemplate: string;
12
+ readonly sourceFileRef: string;
13
+ readonly viewId: string;
14
+ readonly strings: EvidenceTableStrings;
15
+ }): import("react").JSX.Element;
16
+ //# sourceMappingURL=EvidenceTableRows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceTableRows.d.ts","sourceRoot":"","sources":["../src/EvidenceTableRows.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,aAAa,EACb,MAAM,EACN,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACxC,+BAwDA"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Text } from "@mantine/core";
3
+ import { AuditLink } from "./AuditLink.js";
4
+ import { ConfidenceCell } from "./ConfidenceCell.js";
5
+ import { BORDER, MONO, TEXT } from "./tokens.js";
6
+ /**
7
+ * The table layout's body — the previewed saved view's evidence rows on the
8
+ * prototype flex-fraction grid, one grid row per row with separators, each
9
+ * configured column rendered by its focused cell piece.
10
+ */
11
+ export function EvidenceTableRows({ rows, columns, gridTemplate, sourceFileRef, viewId, strings, }) {
12
+ return (_jsx(_Fragment, { children: rows.map((row) => (_jsx(Box, { style: {
13
+ display: "grid",
14
+ gridTemplateColumns: gridTemplate,
15
+ height: 28,
16
+ alignItems: "center",
17
+ borderTop: `1px solid ${BORDER}`,
18
+ }, "data-testid": `evidence-table-row-${row.id}`, children: columns.map((column) => {
19
+ switch (column) {
20
+ case "source":
21
+ return (_jsx(Text, { ff: MONO, fz: 10, fw: 500, style: { color: TEXT, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, "data-testid": `evidence-table-cell-${row.id}-source`, children: row.source }, column));
22
+ case "observation":
23
+ return (_jsx(Text, { ff: MONO, fz: 10, style: { color: TEXT, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", paddingRight: 12 }, "data-testid": `evidence-table-cell-${row.id}-observation`, children: row.observation }, column));
24
+ case "confidence":
25
+ return _jsx(ConfidenceCell, { row: row }, column);
26
+ case "audit":
27
+ return (_jsx(Box, { children: _jsx(AuditLink, { row: row, sourceFileRef: sourceFileRef, viewId: viewId, strings: strings }) }, column));
28
+ }
29
+ }) }, row.id))) }));
30
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The ↗ open-arrow at the block's top-right, BESIDE the VIEW ▾ dropdown —
3
+ * the ONLY chrome affordance that emits the open intent
4
+ * ({sourceFileRef, viewId}): the evidence rows are NOT click-to-open, the
5
+ * arrow is. Small bordered square with the arrow glyph; the host turns the
6
+ * intent into navigation (the demo logs it / shows it in a monitor). Pure
7
+ * presentation — the click handler is wired by the header's caller.
8
+ */
9
+ export declare function OpenViewArrow({ title, onOpen, testid, }: {
10
+ /** Tooltip/accessible title, locale-resolved ("Open this view"). */
11
+ readonly title: string;
12
+ /** Emits the open intent — wired by the composition root. */
13
+ readonly onOpen: () => void;
14
+ readonly testid: string;
15
+ }): import("react").JSX.Element;
16
+ //# sourceMappingURL=OpenViewArrow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenViewArrow.d.ts","sourceRoot":"","sources":["../src/OpenViewArrow.tsx"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,MAAM,GACP,EAAE;IACD,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,+BA8BA"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { UnstyledButton } from "@mantine/core";
3
+ import { ACCENT, BORDER, CARD_BG, MONO } from "./tokens.js";
4
+ /**
5
+ * The ↗ open-arrow at the block's top-right, BESIDE the VIEW ▾ dropdown —
6
+ * the ONLY chrome affordance that emits the open intent
7
+ * ({sourceFileRef, viewId}): the evidence rows are NOT click-to-open, the
8
+ * arrow is. Small bordered square with the arrow glyph; the host turns the
9
+ * intent into navigation (the demo logs it / shows it in a monitor). Pure
10
+ * presentation — the click handler is wired by the header's caller.
11
+ */
12
+ export function OpenViewArrow({ title, onOpen, testid, }) {
13
+ return (_jsx(UnstyledButton, { type: "button", h: 22, w: 22, style: {
14
+ flexShrink: 0,
15
+ borderRadius: 5,
16
+ background: CARD_BG,
17
+ border: `1px solid ${BORDER}`,
18
+ fontFamily: MONO,
19
+ fontSize: 11,
20
+ fontWeight: 600,
21
+ lineHeight: 1,
22
+ color: ACCENT,
23
+ display: "inline-flex",
24
+ alignItems: "center",
25
+ justifyContent: "center",
26
+ cursor: "pointer",
27
+ userSelect: "none",
28
+ }, title: title, "aria-label": title, "data-testid": testid, onClick: onOpen, children: "\u2197" }));
29
+ }
@@ -0,0 +1,36 @@
1
+ /** One entry of the source-file variant dropdown (a saved view of the file). */
2
+ export interface VariantDropdownOption {
3
+ readonly id: string;
4
+ readonly label: string;
5
+ }
6
+ export interface VariantDropdownProps {
7
+ /** Pill text while closed, e.g. "VIEW · CORRIDOR OVERVIEW" (locale-resolved by the caller). */
8
+ readonly pillText: string;
9
+ /** Dropdown menu title, e.g. "SAVED VIEWS · REDWATER-CORRIDOR.WV" (locale-resolved by the caller). */
10
+ readonly menuTitle: string;
11
+ /** Saved views of the source file (the dropdown list). */
12
+ readonly options: readonly VariantDropdownOption[];
13
+ /** Currently previewed variant id (rendered as the selected dot). */
14
+ readonly selectedId: string | undefined;
15
+ /** Called when the analyst picks a saved view — the caller re-previews that variant. */
16
+ readonly onSelect: (viewId: string) => void;
17
+ readonly testidPrefix: string;
18
+ }
19
+ /**
20
+ * The source-file variant dropdown every embedded dossier block renders on top
21
+ * of its card chrome (D10): a "VIEW · {saved view} ▾" pill that opens a
22
+ * "SAVED VIEWS · {file}" menu listing the file's saved views; picking one
23
+ * re-previews that variant. Because the embedded blocks of a dossier reference
24
+ * the SAME source file, switching the variant here re-previews the saved view
25
+ * for the whole file — the caller owns what that means for its preview surface.
26
+ *
27
+ * Interaction mirrors the prototype: clicking the pill toggles the menu,
28
+ * clicking anywhere else (including another block's pill) closes it, and the
29
+ * selected option carries the accent-colored dot.
30
+ *
31
+ * No palette is hardcoded: every color resolves to semantic theme tokens
32
+ * (accent / card / input / border / line / text / muted …) supplied by the
33
+ * host's MantineProvider.
34
+ */
35
+ export declare function VariantDropdown({ pillText, menuTitle, options, selectedId, onSelect, testidPrefix, }: VariantDropdownProps): import("react").JSX.Element;
36
+ //# sourceMappingURL=VariantDropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariantDropdown.d.ts","sourceRoot":"","sources":["../src/VariantDropdown.tsx"],"names":[],"mappings":"AAGA,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sGAAsG;IACtG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,wFAAwF;IACxF,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,OAAO,EACP,UAAU,EACV,QAAQ,EACR,YAAY,GACb,EAAE,oBAAoB,+BAgItB"}
@@ -0,0 +1,99 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { Box, Text, UnstyledButton } from "@mantine/core";
4
+ const MONO = "var(--mantine-font-family-monospace)";
5
+ const TEXT = "var(--mantine-color-text-filled)";
6
+ const MUTED = "var(--mantine-color-muted-filled)";
7
+ const CARD_BG = "var(--mantine-color-card-filled)";
8
+ const INPUT_BG = "var(--mantine-color-input-filled)";
9
+ const BORDER = "var(--mantine-color-border-filled)";
10
+ const LINE = "var(--mantine-color-line-filled)";
11
+ const ACCENT = "var(--mantine-color-accent-filled)";
12
+ /**
13
+ * The source-file variant dropdown every embedded dossier block renders on top
14
+ * of its card chrome (D10): a "VIEW · {saved view} ▾" pill that opens a
15
+ * "SAVED VIEWS · {file}" menu listing the file's saved views; picking one
16
+ * re-previews that variant. Because the embedded blocks of a dossier reference
17
+ * the SAME source file, switching the variant here re-previews the saved view
18
+ * for the whole file — the caller owns what that means for its preview surface.
19
+ *
20
+ * Interaction mirrors the prototype: clicking the pill toggles the menu,
21
+ * clicking anywhere else (including another block's pill) closes it, and the
22
+ * selected option carries the accent-colored dot.
23
+ *
24
+ * No palette is hardcoded: every color resolves to semantic theme tokens
25
+ * (accent / card / input / border / line / text / muted …) supplied by the
26
+ * host's MantineProvider.
27
+ */
28
+ export function VariantDropdown({ pillText, menuTitle, options, selectedId, onSelect, testidPrefix, }) {
29
+ const [open, setOpen] = useState(false);
30
+ const rootRef = useRef(null);
31
+ useEffect(() => {
32
+ if (!open) {
33
+ return;
34
+ }
35
+ const onDocumentClick = (event) => {
36
+ if (rootRef.current !== null && !rootRef.current.contains(event.target)) {
37
+ setOpen(false);
38
+ }
39
+ };
40
+ document.addEventListener("click", onDocumentClick);
41
+ return () => {
42
+ document.removeEventListener("click", onDocumentClick);
43
+ };
44
+ }, [open]);
45
+ return (_jsxs(Box, { ref: rootRef, style: { position: "relative" }, "data-testid": `${testidPrefix}-root`, children: [_jsxs(UnstyledButton, { type: "button", h: 22, px: 10, style: {
46
+ borderRadius: 11,
47
+ background: CARD_BG,
48
+ border: `1px solid ${open ? ACCENT : BORDER}`,
49
+ fontFamily: MONO,
50
+ fontSize: 9,
51
+ fontWeight: 500,
52
+ color: ACCENT,
53
+ letterSpacing: "0.05em",
54
+ display: "inline-flex",
55
+ alignItems: "center",
56
+ gap: 7,
57
+ cursor: "pointer",
58
+ userSelect: "none",
59
+ minWidth: 216,
60
+ justifyContent: "center",
61
+ }, "aria-haspopup": "listbox", "aria-expanded": open, "data-testid": `${testidPrefix}-pill`, onClick: () => {
62
+ setOpen((value) => !value);
63
+ }, children: [pillText, _jsx(Text, { component: "span", ff: MONO, fz: 9, style: { color: MUTED }, children: "\u25BE" })] }), open ? (_jsxs(Box, { w: 264, style: {
64
+ position: "absolute",
65
+ top: 26,
66
+ right: 0,
67
+ zIndex: 9,
68
+ background: CARD_BG,
69
+ border: `1px solid ${LINE}`,
70
+ borderRadius: 6,
71
+ padding: "4px 0",
72
+ boxShadow: "0 8px 24px color-mix(in srgb, var(--mantine-color-deep-filled) 55%, transparent)",
73
+ }, role: "listbox", "data-testid": `${testidPrefix}-menu`, children: [_jsx(Text, { ff: MONO, fz: 8, style: { color: MUTED, letterSpacing: "0.07em", height: 22, display: "flex", alignItems: "center", padding: "0 12px" }, "data-testid": `${testidPrefix}-menu-title`, children: menuTitle }), options.map((option) => {
74
+ const selected = option.id === selectedId;
75
+ return (_jsxs(UnstyledButton, { type: "button", w: "100%", h: 26, style: {
76
+ display: "flex",
77
+ alignItems: "center",
78
+ gap: 8,
79
+ padding: "0 12px",
80
+ fontFamily: MONO,
81
+ fontSize: 10,
82
+ color: selected ? ACCENT : TEXT,
83
+ cursor: "pointer",
84
+ }, role: "option", "aria-selected": selected, "data-testid": `${testidPrefix}-option-${option.id}`, onClick: () => {
85
+ onSelect(option.id);
86
+ setOpen(false);
87
+ }, onMouseEnter: (event) => {
88
+ event.currentTarget.style.background = INPUT_BG;
89
+ }, onMouseLeave: (event) => {
90
+ event.currentTarget.style.background = "transparent";
91
+ }, children: [_jsx("span", { style: {
92
+ width: 5,
93
+ height: 5,
94
+ borderRadius: "50%",
95
+ background: selected ? ACCENT : BORDER,
96
+ flexShrink: 0,
97
+ } }), option.label] }, option.id));
98
+ })] })) : null] }));
99
+ }
@@ -0,0 +1,7 @@
1
+ export { EvidenceTable } from "./EvidenceTable.js";
2
+ export type { EvidenceTableProps, EvidenceSavedView, EvidenceTableRow, EvidenceAuditRef, EvidenceSelectedView, EvidenceOpenIntent, EvidenceAuditDrill, EvidenceColumn, } from "./types.js";
3
+ export { VariantDropdown } from "./VariantDropdown.js";
4
+ export type { VariantDropdownOption, VariantDropdownProps } from "./VariantDropdown.js";
5
+ export { en, zhCN, locales, stringsForLocale, formatMessage } from "./locales/index.js";
6
+ export type { EvidenceTableLocale, EvidenceTableStrings } from "./locales/index.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxF,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { EvidenceTable } from "./EvidenceTable.js";
2
+ export { VariantDropdown } from "./VariantDropdown.js";
3
+ export { en, zhCN, locales, stringsForLocale, formatMessage } from "./locales/index.js";
@@ -0,0 +1,14 @@
1
+ {
2
+ "evidence-table": {
3
+ "kindTag": "EVIDENCE TABLE",
4
+ "srcFile": "SRC FILE · {file}",
5
+ "viewPrefix": "VIEW · {view}",
6
+ "savedViewsTitle": "SAVED VIEWS · {file}",
7
+ "colSource": "SOURCE",
8
+ "colObservation": "OBSERVATION",
9
+ "colConfidence": "CONF.",
10
+ "colAuditId": "AUDIT ID",
11
+ "auditLinkTitle": "OPEN AUDIT CHAIN · {auditId}",
12
+ "openViewTitle": "Open this view"
13
+ }
14
+ }
@@ -0,0 +1,59 @@
1
+ import enBundle from "./en.json";
2
+ /**
3
+ * Locales the evidence-table micro-UI bundles. Every component-fixed UI string
4
+ * is resolved from these bundles (statically imported, resolveJsonModule); the
5
+ * component never hardcodes copy. Configuration-provided strings (an explicit
6
+ * kind-tag override, saved-view labels, evidence-row copy, …) stay
7
+ * composition-authored and are localized by the composer.
8
+ */
9
+ export type EvidenceTableLocale = "en" | "zh-CN";
10
+ /**
11
+ * The per-locale string table — the keys of the en bundle. Declared widened
12
+ * (string values) so the zh-CN bundle is checked for exact key parity at
13
+ * compile time while keeping literal JSON types out of the public surface.
14
+ */
15
+ export type EvidenceTableStrings = {
16
+ readonly [K in keyof typeof enBundle["evidence-table"]]: string;
17
+ };
18
+ /** Parsed en locale bundle (namespaced under the component id "evidence-table"). */
19
+ export declare const en: {
20
+ "evidence-table": {
21
+ kindTag: string;
22
+ srcFile: string;
23
+ viewPrefix: string;
24
+ savedViewsTitle: string;
25
+ colSource: string;
26
+ colObservation: string;
27
+ colConfidence: string;
28
+ colAuditId: string;
29
+ auditLinkTitle: string;
30
+ openViewTitle: string;
31
+ };
32
+ };
33
+ /** Parsed zh-CN locale bundle (namespaced under the component id "evidence-table"). */
34
+ export declare const zhCN: {
35
+ "evidence-table": {
36
+ kindTag: string;
37
+ srcFile: string;
38
+ viewPrefix: string;
39
+ savedViewsTitle: string;
40
+ colSource: string;
41
+ colObservation: string;
42
+ colConfidence: string;
43
+ colAuditId: string;
44
+ auditLinkTitle: string;
45
+ openViewTitle: string;
46
+ };
47
+ };
48
+ /** All bundled locale bundles keyed by locale id — for downstream deep-merge. */
49
+ export declare const locales: Record<EvidenceTableLocale, {
50
+ readonly "evidence-table": EvidenceTableStrings;
51
+ }>;
52
+ /** Resolves the string table for a locale. */
53
+ export declare function stringsForLocale(locale: EvidenceTableLocale): EvidenceTableStrings;
54
+ /**
55
+ * Simple `{placeholder}` interpolation (e.g. `"VIEW · {view}"` + view label).
56
+ * Placeholder-for-value substitution only — no ICU, no regexes.
57
+ */
58
+ export declare function formatMessage(template: string, values: Readonly<Record<string, string | number>>): string;
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locales/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,WAAW,CAAC;AAGjC;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,OAAO,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,CAAC,IAAI,MAAM,OAAO,QAAQ,CAAC,gBAAgB,CAAC,GAAG,MAAM;CAChE,CAAC;AAOF,oFAAoF;AACpF,eAAO,MAAM,EAAE;;;;;;;;;;;;;CAAW,CAAC;AAE3B,uFAAuF;AACvF,eAAO,MAAM,IAAI;;;;;;;;;;;;;CAAa,CAAC;AAE/B,iFAAiF;AACjF,eAAO,MAAM,OAAO;+BAZoD,oBAAoB;EAY9D,CAAC;AAE/B,8CAA8C;AAC9C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,oBAAoB,CAElF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAChD,MAAM,CAMR"}
@@ -0,0 +1,27 @@
1
+ import enBundle from "./en.json";
2
+ import zhCNBundle from "./zh-CN.json";
3
+ const bundles = {
4
+ en: enBundle,
5
+ "zh-CN": zhCNBundle,
6
+ };
7
+ /** Parsed en locale bundle (namespaced under the component id "evidence-table"). */
8
+ export const en = enBundle;
9
+ /** Parsed zh-CN locale bundle (namespaced under the component id "evidence-table"). */
10
+ export const zhCN = zhCNBundle;
11
+ /** All bundled locale bundles keyed by locale id — for downstream deep-merge. */
12
+ export const locales = bundles;
13
+ /** Resolves the string table for a locale. */
14
+ export function stringsForLocale(locale) {
15
+ return bundles[locale]["evidence-table"];
16
+ }
17
+ /**
18
+ * Simple `{placeholder}` interpolation (e.g. `"VIEW · {view}"` + view label).
19
+ * Placeholder-for-value substitution only — no ICU, no regexes.
20
+ */
21
+ export function formatMessage(template, values) {
22
+ let result = template;
23
+ for (const [key, value] of Object.entries(values)) {
24
+ result = result.replaceAll(`{${key}}`, String(value));
25
+ }
26
+ return result;
27
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "evidence-table": {
3
+ "kindTag": "证据表",
4
+ "srcFile": "源文件 · {file}",
5
+ "viewPrefix": "视图 · {view}",
6
+ "savedViewsTitle": "保存视图 · {file}",
7
+ "colSource": "来源",
8
+ "colObservation": "观察",
9
+ "colConfidence": "置信度",
10
+ "colAuditId": "审计 ID",
11
+ "auditLinkTitle": "打开审计链 · {auditId}",
12
+ "openViewTitle": "打开此视图"
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ import type { stringsForLocale } from "./locales/index.js";
2
+ import type { EvidenceColumn } from "./types.js";
3
+ /** Default column configuration (prototype order). */
4
+ export declare const DEFAULT_COLUMNS: readonly EvidenceColumn[];
5
+ /** Prototype column widths as flex fractions (190 / 340 / 120 / 174 of 824). */
6
+ export declare const COLUMN_FRACTIONS: Record<EvidenceColumn, string>;
7
+ /** Locale-resolved header label per column. */
8
+ export declare const COLUMN_LABELS: Record<EvidenceColumn, (strings: ReturnType<typeof stringsForLocale>) => string>;
9
+ /** Joins the configured columns' flex fractions into a grid template. */
10
+ export declare function gridTemplateForColumns(columns: readonly EvidenceColumn[]): string;
11
+ //# sourceMappingURL=tableColumns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tableColumns.d.ts","sourceRoot":"","sources":["../src/tableColumns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,sDAAsD;AACtD,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAAqD,CAAC;AAE3G,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAK3D,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,KAAK,MAAM,CAK1G,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,MAAM,CAEjF"}
@@ -0,0 +1,20 @@
1
+ /** Default column configuration (prototype order). */
2
+ export const DEFAULT_COLUMNS = ["source", "observation", "confidence", "audit"];
3
+ /** Prototype column widths as flex fractions (190 / 340 / 120 / 174 of 824). */
4
+ export const COLUMN_FRACTIONS = {
5
+ source: "190fr",
6
+ observation: "340fr",
7
+ confidence: "120fr",
8
+ audit: "174fr",
9
+ };
10
+ /** Locale-resolved header label per column. */
11
+ export const COLUMN_LABELS = {
12
+ source: (strings) => strings.colSource,
13
+ observation: (strings) => strings.colObservation,
14
+ confidence: (strings) => strings.colConfidence,
15
+ audit: (strings) => strings.colAuditId,
16
+ };
17
+ /** Joins the configured columns' flex fractions into a grid template. */
18
+ export function gridTemplateForColumns(columns) {
19
+ return columns.map((column) => COLUMN_FRACTIONS[column]).join(" ");
20
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Semantic theme tokens shared by the evidence-table sub-components — the
3
+ * component side of the theme contract. No palette is hardcoded: every color
4
+ * resolves to a semantic token supplied by the host's MantineProvider, so
5
+ * each sub-component file stays free of concrete design colors.
6
+ */
7
+ /** Monospace font token — every cell string renders in MONO. */
8
+ export declare const MONO = "var(--mantine-font-family-monospace)";
9
+ /** Primary text color. */
10
+ export declare const TEXT = "var(--mantine-color-text-filled)";
11
+ /** Secondary/muted text color (column labels, SRC FILE chip). */
12
+ export declare const MUTED = "var(--mantine-color-muted-filled)";
13
+ /** Raised card background (pills, tags, list row cards). */
14
+ export declare const CARD_BG = "var(--mantine-color-card-filled)";
15
+ /** Recessed card background (card body). */
16
+ export declare const CARD_DARK = "var(--mantine-color-card-dark-filled)";
17
+ /** Card outline / row separator color. */
18
+ export declare const BORDER = "var(--mantine-color-border-filled)";
19
+ /** Semantic accent (blue) — kind tag, pill, audit-link hover. */
20
+ export declare const ACCENT = "var(--mantine-color-accent-filled)";
21
+ /** Semantic ok (mint) — confidence cells. */
22
+ export declare const OK = "var(--mantine-color-ok-filled)";
23
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,gEAAgE;AAChE,eAAO,MAAM,IAAI,yCAAyC,CAAC;AAC3D,0BAA0B;AAC1B,eAAO,MAAM,IAAI,qCAAqC,CAAC;AACvD,iEAAiE;AACjE,eAAO,MAAM,KAAK,sCAAsC,CAAC;AACzD,4DAA4D;AAC5D,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,4CAA4C;AAC5C,eAAO,MAAM,SAAS,0CAA0C,CAAC;AACjE,0CAA0C;AAC1C,eAAO,MAAM,MAAM,uCAAuC,CAAC;AAC3D,iEAAiE;AACjE,eAAO,MAAM,MAAM,uCAAuC,CAAC;AAC3D,6CAA6C;AAC7C,eAAO,MAAM,EAAE,mCAAmC,CAAC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Semantic theme tokens shared by the evidence-table sub-components — the
3
+ * component side of the theme contract. No palette is hardcoded: every color
4
+ * resolves to a semantic token supplied by the host's MantineProvider, so
5
+ * each sub-component file stays free of concrete design colors.
6
+ */
7
+ /** Monospace font token — every cell string renders in MONO. */
8
+ export const MONO = "var(--mantine-font-family-monospace)";
9
+ /** Primary text color. */
10
+ export const TEXT = "var(--mantine-color-text-filled)";
11
+ /** Secondary/muted text color (column labels, SRC FILE chip). */
12
+ export const MUTED = "var(--mantine-color-muted-filled)";
13
+ /** Raised card background (pills, tags, list row cards). */
14
+ export const CARD_BG = "var(--mantine-color-card-filled)";
15
+ /** Recessed card background (card body). */
16
+ export const CARD_DARK = "var(--mantine-color-card-dark-filled)";
17
+ /** Card outline / row separator color. */
18
+ export const BORDER = "var(--mantine-color-border-filled)";
19
+ /** Semantic accent (blue) — kind tag, pill, audit-link hover. */
20
+ export const ACCENT = "var(--mantine-color-accent-filled)";
21
+ /** Semantic ok (mint) — confidence cells. */
22
+ export const OK = "var(--mantine-color-ok-filled)";
@@ -0,0 +1,71 @@
1
+ import type { EvidenceTableLocale } from "./locales/index.js";
2
+ /**
3
+ * Payload published on "evidence-table.selected-view" when the variant
4
+ * dropdown switches the previewed saved view — the file-level selection every
5
+ * embedded block of the SAME source file re-previews (D10).
6
+ */
7
+ export interface EvidenceSelectedView {
8
+ readonly sourceFileRef: string;
9
+ readonly viewId: string;
10
+ }
11
+ /**
12
+ * The ↗ open intent emitted by the arrow beside the VIEW dropdown: the block
13
+ * asks the host to open the saved view ({sourceFileRef, viewId}). The table
14
+ * rows are NOT click-to-open — only the arrow emits this intent (the agreed
15
+ * embedded-block chrome contract shared with the geovision-embed block).
16
+ */
17
+ export interface EvidenceOpenIntent {
18
+ readonly sourceFileRef: string;
19
+ readonly viewId: string;
20
+ }
21
+ /** IAuditRef locator carried by every evidence row (audit id + when/action). */
22
+ export interface EvidenceAuditRef {
23
+ readonly auditId: string;
24
+ readonly at?: string;
25
+ readonly action?: string;
26
+ }
27
+ /**
28
+ * IEvidenceSource-style row the table previews — interface-typed fields,
29
+ * generic over evidence models: source, observation (the claim), confidence
30
+ * and the audit locator.
31
+ */
32
+ export interface EvidenceTableRow {
33
+ readonly id: string;
34
+ readonly source: string;
35
+ readonly observation: string;
36
+ /** Confidence percent 0..100; omitted when the model carries none. */
37
+ readonly confidence?: number;
38
+ readonly audit: EvidenceAuditRef;
39
+ }
40
+ /** One saved view (variant) of the source file with its evidence rows. */
41
+ export interface EvidenceSavedView {
42
+ readonly id: string;
43
+ readonly label: string;
44
+ readonly rows: readonly EvidenceTableRow[];
45
+ }
46
+ /** Ephemeral payload of the "evidence-table.audit-drill" event. */
47
+ export interface EvidenceAuditDrill {
48
+ readonly sourceFileRef: string;
49
+ readonly viewId: string;
50
+ readonly rowId: string;
51
+ readonly auditId: string;
52
+ }
53
+ /** Table columns, in render order. */
54
+ export type EvidenceColumn = "source" | "observation" | "confidence" | "audit";
55
+ export interface EvidenceTableProps {
56
+ /** Source file the table previews (the SRC FILE chip) — the SAME file the Geovision Embed references. */
57
+ readonly sourceFileRef: string;
58
+ /** Saved views (variants) of the source file — the dropdown list. */
59
+ readonly savedViews: readonly EvidenceSavedView[];
60
+ /** Currently previewed variant id; controlled — defaults to the channel value, then the first view. */
61
+ readonly selectedViewId?: string;
62
+ /** Layout variant: "table" four columns (default) or "list" row cards. */
63
+ readonly layout?: "table" | "list";
64
+ /** Columns rendered, in order (default: source, observation, confidence, audit). */
65
+ readonly columns?: readonly EvidenceColumn[];
66
+ /** UI locale for the component-fixed strings (default "en"). */
67
+ readonly locale?: EvidenceTableLocale;
68
+ /** Receives the ↗ arrow's open intent; the fallback is a console no-op. */
69
+ readonly onOpenView?: (intent: EvidenceOpenIntent) => void;
70
+ }
71
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;CAClC;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC5C;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,sCAAsC;AACtC,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,GAAG,OAAO,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,yGAAyG;IACzG,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,uGAAuG;IACvG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CAC5D"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ {
2
+ "evidence-table": {
3
+ "kindTag": "EVIDENCE TABLE",
4
+ "srcFile": "SRC FILE · {file}",
5
+ "viewPrefix": "VIEW · {view}",
6
+ "savedViewsTitle": "SAVED VIEWS · {file}",
7
+ "colSource": "SOURCE",
8
+ "colObservation": "OBSERVATION",
9
+ "colConfidence": "CONF.",
10
+ "colAuditId": "AUDIT ID",
11
+ "auditLinkTitle": "OPEN AUDIT CHAIN · {auditId}",
12
+ "openViewTitle": "Open this view"
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "evidence-table": {
3
+ "kindTag": "证据表",
4
+ "srcFile": "源文件 · {file}",
5
+ "viewPrefix": "视图 · {view}",
6
+ "savedViewsTitle": "保存视图 · {file}",
7
+ "colSource": "来源",
8
+ "colObservation": "观察",
9
+ "colConfidence": "置信度",
10
+ "colAuditId": "审计 ID",
11
+ "auditLinkTitle": "打开审计链 · {auditId}",
12
+ "openViewTitle": "打开此视图"
13
+ }
14
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@zephytiju/prism-evidence-table",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Platform Prism evidence-table micro-UI (component id \"evidence-table\"): Dossier embedded block (D10) \u2014 preview of the evidence view of its source file, the SAME file the Geovision Embed references. Card chrome (outlined border, kind tag pill, header) with a SRC FILE chip and a source-file variant dropdown on top; the dropdown switches the previewed saved view (variant) of the shared source file. Renders IEvidenceSource-style rows (source / observation / confidence / audit ID) with row separators and per-row audit drill links over IAuditRef locators; table (four columns) and list (row cards) layouts. Sub-component library rendered inside a host axiom component; no Lattice calls. Ships en + zh-CN locale bundles.",
6
+ "license": "UNLICENSED",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./locales/*": "./locales/*"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "locales"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite --host 127.0.0.1",
25
+ "build": "tsc -p tsconfig.build.json && node scripts/copy-locales.mjs",
26
+ "typecheck": "tsc --noEmit",
27
+ "test": "vitest run",
28
+ "shot-demo": "node scripts/shot-demo.mjs"
29
+ },
30
+ "peerDependencies": {
31
+ "@mantine/core": "^8.1.1",
32
+ "@zephytiju/lattice-common-interfaces": ">=0.1.0",
33
+ "@zephytiju/prism-react": ">=0.1.0",
34
+ "react": "^19.1.0",
35
+ "react-dom": "^19.1.0"
36
+ },
37
+ "devDependencies": {
38
+ "@mantine/core": "8.1.1",
39
+ "@testing-library/dom": "^10.4.0",
40
+ "@testing-library/react": "^16.1.0",
41
+ "@types/node": "^22.10.2",
42
+ "@types/react": "^19.1.0",
43
+ "@types/react-dom": "^19.1.0",
44
+ "@zephytiju/lattice-common-interfaces": "0.1.0",
45
+ "@zephytiju/prism-react": "0.1.0",
46
+ "jsdom": "^25.0.1",
47
+ "puppeteer-core": "^24.10.0",
48
+ "react": "19.1.0",
49
+ "react-dom": "19.1.0",
50
+ "typescript": "^5.7.2",
51
+ "vite": "6.0.5",
52
+ "vitest": "^2.1.8"
53
+ },
54
+ "engines": {
55
+ "node": ">=20"
56
+ },
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/zephytiju/PrismEvidenceTableMicroUI.git"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/zephytiju/PrismEvidenceTableMicroUI/issues"
63
+ },
64
+ "homepage": "https://github.com/zephytiju/PrismEvidenceTableMicroUI#readme"
65
+ }