footprint-explainable-ui 0.9.0 → 0.10.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.
package/dist/index.cjs CHANGED
@@ -3970,7 +3970,14 @@ function ExplainableShell({
3970
3970
  ro.observe(el);
3971
3971
  return () => ro.disconnect();
3972
3972
  }, []);
3973
- const [activeTab, setActiveTab] = (0, import_react19.useState)(defaultTab ?? tabs[0]);
3973
+ const builtInViews = [
3974
+ { id: "result", name: "Result" },
3975
+ { id: "memory", name: "Memory" },
3976
+ { id: "narrative", name: "Narrative" }
3977
+ ];
3978
+ const customViewIds = (recorderViews ?? []).map((v2) => ({ id: v2.id, name: v2.name }));
3979
+ const allTabs = [...builtInViews, ...customViewIds];
3980
+ const [activeTab, setActiveTab] = (0, import_react19.useState)(defaultTab ?? "memory");
3974
3981
  const [snapshotIdx, setSnapshotIdx] = (0, import_react19.useState)(0);
3975
3982
  const [drillDownStack, setDrillDownStack] = (0, import_react19.useState)([]);
3976
3983
  const [rightExpanded, setRightExpanded] = (0, import_react19.useState)(defaultExpanded?.details ?? true);
@@ -4091,14 +4098,10 @@ function ExplainableShell({
4091
4098
  },
4092
4099
  [spec, snapshots, narrativeEntries, snapshotIdx]
4093
4100
  );
4094
- const tabLabels = {
4095
- result: "Result",
4096
- explainable: "Explainable",
4097
- "ai-compatible": "AI-Compatible"
4098
- };
4101
+ const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
4099
4102
  if (unstyled) {
4100
4103
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className, style, "data-fp": "explainable-shell", children: [
4101
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { "data-fp": "shell-tabs", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { "data-fp": "shell-tab", "data-active": tab === activeTab, onClick: () => handleTabChange(tab), children: tabLabels[tab] }, tab)) }),
4104
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { "data-fp": "shell-tabs", children: allTabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { "data-fp": "shell-tab", "data-active": tab.id === activeTab, onClick: () => handleTabChange(tab.id), children: tab.name }, tab.id)) }),
4102
4105
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
4103
4106
  activeTab === "result" && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ResultPanel, { data: resultData ?? null, logs, hideConsole, unstyled: true }),
4104
4107
  (activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
@@ -4112,7 +4115,18 @@ function ExplainableShell({
4112
4115
  ] })
4113
4116
  ] });
4114
4117
  }
4115
- const isVisualizationTab = activeTab === "explainable" || activeTab === "ai-compatible";
4118
+ const isVisualizationTab = activeTab !== "result";
4119
+ const activeRecorderRender = (0, import_react19.useMemo)(() => {
4120
+ if (activeTab === "result") return null;
4121
+ if (activeTab === "memory") {
4122
+ return ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MemoryPanel, { snapshots: snaps, selectedIndex: idx, size, style: { height: "100%" } });
4123
+ }
4124
+ if (activeTab === "narrative") {
4125
+ return ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NarrativePanel, { snapshots: snaps, selectedIndex: idx, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, size, style: { height: "100%" } });
4126
+ }
4127
+ const customView = recorderViews?.find((v2) => v2.id === activeTab);
4128
+ return customView?.render ?? null;
4129
+ }, [activeTab, recorderViews, activeNarrativeEntries, activeNarrative, size]);
4116
4130
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4117
4131
  "div",
4118
4132
  {
@@ -4131,17 +4145,18 @@ function ExplainableShell({
4131
4145
  },
4132
4146
  "data-fp": "explainable-shell",
4133
4147
  children: [
4134
- tabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: {
4148
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: {
4135
4149
  display: "flex",
4136
4150
  borderBottom: `1px solid ${theme.border}`,
4137
4151
  background: theme.bgSecondary,
4138
- flexShrink: 0
4139
- }, children: tabs.map((tab) => {
4140
- const active = tab === activeTab;
4152
+ flexShrink: 0,
4153
+ overflowX: "auto"
4154
+ }, children: allTabs.map((tab) => {
4155
+ const active = tab.id === activeTab;
4141
4156
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4142
4157
  "button",
4143
4158
  {
4144
- onClick: () => handleTabChange(tab),
4159
+ onClick: () => handleTabChange(tab.id),
4145
4160
  style: {
4146
4161
  padding: "6px 14px",
4147
4162
  fontSize: 11,
@@ -4153,11 +4168,12 @@ function ExplainableShell({
4153
4168
  border: "none",
4154
4169
  borderBottom: active ? `2px solid ${theme.primary}` : "2px solid transparent",
4155
4170
  cursor: "pointer",
4156
- fontFamily: "inherit"
4171
+ fontFamily: "inherit",
4172
+ whiteSpace: "nowrap"
4157
4173
  },
4158
- children: tabLabels[tab]
4174
+ children: tab.name
4159
4175
  },
4160
- tab
4176
+ tab.id
4161
4177
  );
4162
4178
  }) }),
4163
4179
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { flex: 1, overflow: isNarrow ? "auto" : "hidden", display: "flex", flexDirection: "column" }, children: [
@@ -4195,17 +4211,7 @@ function ExplainableShell({
4195
4211
  ) })
4196
4212
  ] }),
4197
4213
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HLinePill, { label: rightLabel, expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
4198
- rightExpanded && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { maxHeight: 250, flexShrink: 0, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4199
- DetailsContent,
4200
- {
4201
- snapshots: activeSnapshots,
4202
- selectedIndex: safeIdx,
4203
- narrativeEntries: activeNarrativeEntries,
4204
- narrative: activeNarrative,
4205
- size,
4206
- extraViews: recorderViews
4207
- }
4208
- ) }),
4214
+ rightExpanded && activeRecorderRender && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { maxHeight: 250, flexShrink: 0, overflow: "auto" }, children: activeRecorderRender({ snapshots: activeSnapshots, selectedIndex: safeIdx }) }),
4209
4215
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
4210
4216
  timelineExpanded && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { flexShrink: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, size }) })
4211
4217
  ] })
@@ -4231,20 +4237,9 @@ function ExplainableShell({
4231
4237
  selectedIndex: safeIdx,
4232
4238
  onNodeClick: handleNodeClick
4233
4239
  }) }),
4234
- rightExpanded ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { width: "38%", minWidth: 300, maxWidth: 500, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
4240
+ rightExpanded && activeRecorderRender ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { width: "38%", minWidth: 300, maxWidth: 500, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
4235
4241
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VLinePill, { label: rightLabel, expanded: true, onClick: () => toggleRight(false) }),
4236
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4237
- DetailsContent,
4238
- {
4239
- snapshots: activeSnapshots,
4240
- selectedIndex: safeIdx,
4241
- narrativeEntries: activeNarrativeEntries,
4242
- narrative: activeNarrative,
4243
- size,
4244
- fillHeight: true,
4245
- extraViews: recorderViews
4246
- }
4247
- )
4242
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: activeRecorderRender({ snapshots: activeSnapshots, selectedIndex: safeIdx }) })
4248
4243
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VLinePill, { label: rightLabel, expanded: false, onClick: () => toggleRight(true) })
4249
4244
  ] }),
4250
4245
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),