footprint-explainable-ui 0.14.1 → 0.14.3

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
@@ -4091,9 +4091,15 @@ function detectKeyedSteps(data) {
4091
4091
  const obj = data;
4092
4092
  for (const val of Object.values(obj)) {
4093
4093
  if (val && typeof val === "object" && !Array.isArray(val)) {
4094
- const keys = Object.keys(val);
4095
- if (keys.length > 0 && keys.every((k) => k.includes("#"))) {
4096
- return val;
4094
+ const entries = Object.entries(val);
4095
+ if (entries.length === 0) continue;
4096
+ const allObjectsWithNumbers = entries.every(([, v2]) => {
4097
+ if (!v2 || typeof v2 !== "object" || Array.isArray(v2)) return false;
4098
+ return Object.values(v2).some((f) => typeof f === "number");
4099
+ });
4100
+ if (allObjectsWithNumbers) {
4101
+ const keyType = entries.some(([k]) => k.includes("#")) ? "runtimeStageId" : "stageName";
4102
+ return { steps: val, keyType };
4097
4103
  }
4098
4104
  }
4099
4105
  }
@@ -4112,21 +4118,27 @@ function KeyedRecorderView({
4112
4118
  selectedIndex
4113
4119
  }) {
4114
4120
  const [showAggregate, setShowAggregate] = (0, import_react19.useState)(false);
4115
- const steps = (0, import_react19.useMemo)(() => detectKeyedSteps(data), [data]);
4116
- const visibleIds = (0, import_react19.useMemo)(() => {
4117
- const ids = /* @__PURE__ */ new Set();
4121
+ const detected = (0, import_react19.useMemo)(() => detectKeyedSteps(data), [data]);
4122
+ const visibleKeys = (0, import_react19.useMemo)(() => {
4123
+ const keys = /* @__PURE__ */ new Set();
4118
4124
  for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
4119
- const id = snapshots[i].runtimeStageId;
4120
- if (id) ids.add(id);
4125
+ const snap = snapshots[i];
4126
+ if (detected?.keyType === "runtimeStageId") {
4127
+ if (snap.runtimeStageId) keys.add(snap.runtimeStageId);
4128
+ } else {
4129
+ if (snap.stageName) keys.add(snap.stageName);
4130
+ if (snap.stageLabel) keys.add(snap.stageLabel);
4131
+ }
4121
4132
  }
4122
- return ids;
4123
- }, [snapshots, selectedIndex]);
4133
+ return keys;
4134
+ }, [snapshots, selectedIndex, detected?.keyType]);
4124
4135
  const isAtEnd = selectedIndex >= snapshots.length - 1;
4125
- if (!steps) {
4136
+ if (!detected) {
4126
4137
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { padding: 12, fontFamily: theme.fontMono, fontSize: 11, whiteSpace: "pre-wrap", overflow: "auto", height: "100%" }, children: typeof data === "string" ? data : JSON.stringify(data, null, 2) });
4127
4138
  }
4139
+ const steps = detected.steps;
4128
4140
  const allKeys = Object.keys(steps);
4129
- const visibleEntries = allKeys.filter((k) => visibleIds.has(k));
4141
+ const visibleEntries = allKeys.filter((k) => visibleKeys.has(k));
4130
4142
  const numField = allKeys.length > 0 ? findNumericField(steps[allKeys[0]]) : null;
4131
4143
  const numFieldKey = numField?.key ?? "";
4132
4144
  let runningTotal = 0;
@@ -4144,6 +4156,7 @@ function KeyedRecorderView({
4144
4156
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
4145
4157
  description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
4146
4158
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
4159
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Translate \u2014 per-step detail" }),
4147
4160
  visibleEntries.map((key) => {
4148
4161
  const entry = steps[key];
4149
4162
  const label = entry.stageName ?? key;
@@ -4155,22 +4168,19 @@ function KeyedRecorderView({
4155
4168
  ] }, key);
4156
4169
  }),
4157
4170
  visibleEntries.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", padding: "8px 0" }, children: "Scrub the slider to reveal entries..." }),
4158
- numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { marginTop: 12, padding: "8px 12px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, fontSize: 12 }, children: [
4159
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: { color: theme.textMuted }, children: [
4160
- "Running total (",
4161
- numFieldKey,
4162
- "):"
4163
- ] }),
4164
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontWeight: 700, marginLeft: 8, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
4171
+ numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { marginTop: 16, padding: "8px 12px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, fontSize: 12 }, children: [
4172
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4, fontWeight: 600 }, children: "Accumulate \u2014 running total up to this step" }),
4173
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontWeight: 700, fontSize: 16, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
4165
4174
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
4166
- "(",
4175
+ numFieldKey,
4176
+ " \xB7 ",
4167
4177
  visibleEntries.length,
4168
4178
  " of ",
4169
4179
  allKeys.length,
4170
- " steps)"
4180
+ " steps"
4171
4181
  ] })
4172
4182
  ] }),
4173
- isAtEnd && numFieldKey && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: 12 }, children: !showAggregate ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4183
+ isAtEnd && numFieldKey && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: 16 }, children: !showAggregate ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4174
4184
  "button",
4175
4185
  {
4176
4186
  onClick: () => setShowAggregate(true),
@@ -4179,21 +4189,18 @@ function KeyedRecorderView({
4179
4189
  color: "#fff",
4180
4190
  border: "none",
4181
4191
  borderRadius: 6,
4182
- padding: "8px 16px",
4192
+ padding: "10px 20px",
4183
4193
  fontSize: 12,
4184
4194
  fontWeight: 600,
4185
4195
  cursor: "pointer",
4186
- fontFamily: "inherit"
4196
+ fontFamily: "inherit",
4197
+ width: "100%"
4187
4198
  },
4188
- children: [
4189
- "Aggregate (",
4190
- numFieldKey,
4191
- ")"
4192
- ]
4199
+ children: "Show Aggregate \u2014 Grand Total"
4193
4200
  }
4194
4201
  ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.success} 12%, transparent)`, borderRadius: 6, border: `1px solid ${theme.success}44` }, children: [
4195
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4 }, children: "Aggregate \u2014 Grand Total" }),
4196
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 20, fontWeight: 700, color: theme.success }, children: grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1) }),
4202
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4, fontWeight: 600 }, children: "Aggregate \u2014 grand total across all steps" }),
4203
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 22, fontWeight: 700, color: theme.success }, children: grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1) }),
4197
4204
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { fontSize: 10, color: theme.textMuted, marginTop: 2 }, children: [
4198
4205
  allKeys.length,
4199
4206
  " steps \xB7 ",