executable-stories-react 0.17.1 → 0.19.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/ssr.cjs CHANGED
@@ -363,11 +363,11 @@ function formatValue(value) {
363
363
  return String(value);
364
364
  }
365
365
  }
366
- function DocKv({ entry }) {
367
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
366
+ function DocKv({ entries }) {
367
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dl", { className: "my-2 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm", children: entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "contents", children: [
368
368
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
369
369
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("dd", { className: "min-w-0 break-words font-mono text-foreground", children: formatValue(entry.value) })
370
- ] });
370
+ ] }, i)) });
371
371
  }
372
372
 
373
373
  // src/hooks/useRenderers.ts
@@ -454,7 +454,7 @@ function DocSection({ entry }) {
454
454
  if (renderers.section) {
455
455
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: renderers.section(entry) });
456
456
  }
457
- const html = safeMarkdownHtml(entry.markdown);
457
+ const html = safeMarkdownHtml(dedent(entry.markdown));
458
458
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
459
459
  entry.title ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
460
460
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -640,7 +640,7 @@ function DocEntry({ entry }) {
640
640
  case "tag":
641
641
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocTag, { entry });
642
642
  case "kv":
643
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocKv, { entry });
643
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocKv, { entries: [entry] });
644
644
  case "code":
645
645
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DocCode, { entry });
646
646
  case "table":
@@ -668,7 +668,15 @@ function DocEntry({ entry }) {
668
668
  var import_jsx_runtime18 = require("react/jsx-runtime");
669
669
  function ReportDocEntries({ entries }) {
670
670
  if (entries.length === 0) return null;
671
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DocEntry, { entry }, i)) });
671
+ const groups = [];
672
+ for (const entry of entries) {
673
+ const last = groups[groups.length - 1];
674
+ if (entry.kind === "kv" && Array.isArray(last)) last.push(entry);
675
+ else groups.push(entry.kind === "kv" ? [entry] : entry);
676
+ }
677
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: groups.map(
678
+ (g, i) => Array.isArray(g) ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DocKv, { entries: g }, i) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DocEntry, { entry: g }, i)
679
+ ) });
672
680
  }
673
681
 
674
682
  // src/components/ReportSteps.tsx
@@ -873,42 +881,76 @@ function StateCardView({ card }) {
873
881
 
874
882
  // src/components/ReportAttachments.tsx
875
883
  var import_jsx_runtime21 = require("react/jsx-runtime");
884
+ function attachmentText(att) {
885
+ if (att.contentEncoding !== "BASE64") return att.body;
886
+ try {
887
+ return new TextDecoder().decode(Uint8Array.from(atob(att.body), (c) => c.charCodeAt(0)));
888
+ } catch {
889
+ return void 0;
890
+ }
891
+ }
892
+ function preview(att) {
893
+ const type = att.mediaType.split(";")[0].trim().toLowerCase();
894
+ const text = attachmentText(att);
895
+ if (text === void 0) return null;
896
+ if (type === "text/plain") {
897
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "max-h-96 overflow-auto rounded-md border border-border bg-muted/40 p-3 text-xs whitespace-pre-wrap", children: text });
898
+ }
899
+ if (type === "text/markdown") {
900
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
901
+ "div",
902
+ {
903
+ className: "es-doc-prose prose prose-sm max-w-none rounded-md border border-border p-3",
904
+ dangerouslySetInnerHTML: { __html: safeMarkdownHtml(text) }
905
+ }
906
+ );
907
+ }
908
+ if (type === "text/html") {
909
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DocHtml, { entry: { kind: "html", content: text, title: att.name, phase: "runtime" } });
910
+ }
911
+ return null;
912
+ }
876
913
  function ReportAttachments({ attachments }) {
877
914
  if (attachments.length === 0) return null;
878
915
  return (
879
916
  // role="group" (not a labelled <section>) so multiple scenarios' attachment
880
917
  // blocks don't create duplicate "Attachments" region landmarks.
881
918
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
882
- const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
883
- const isImage = att.mediaType.startsWith("image/");
919
+ const dataUri = att.external ? void 0 : att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
920
+ const href = dataUri ?? (0, import_url.safeUrl)(att.body);
921
+ const imageSrc = dataUri ?? (0, import_url.safeImageUrl)(att.body);
922
+ const isImage = att.mediaType.startsWith("image/") && imageSrc !== void 0;
884
923
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
885
924
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
886
925
  "img",
887
926
  {
888
- src: dataUri,
927
+ src: imageSrc,
889
928
  alt: att.name,
890
929
  loading: "lazy",
891
930
  className: "max-w-full rounded-md border border-border"
892
931
  }
893
932
  ),
894
933
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
895
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
896
- "a",
897
- {
898
- href: dataUri,
899
- download: att.name,
900
- className: "text-xs text-link underline underline-offset-2",
901
- children: [
902
- att.name,
903
- " ",
904
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-muted-foreground", children: [
905
- "(",
906
- att.mediaType,
907
- ")"
908
- ] })
909
- ]
910
- }
911
- ) }, `${att.name}-${i}`);
934
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
935
+ att.external ? null : preview(att),
936
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
937
+ "a",
938
+ {
939
+ href,
940
+ download: att.name,
941
+ className: "text-xs text-link underline underline-offset-2",
942
+ children: [
943
+ att.name,
944
+ " ",
945
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-muted-foreground", children: [
946
+ "(",
947
+ att.mediaType,
948
+ ")"
949
+ ] })
950
+ ]
951
+ }
952
+ )
953
+ ] }) }, `${att.name}-${i}`);
912
954
  }) })
913
955
  );
914
956
  }
@@ -1449,10 +1491,17 @@ function ReportFeatureIntro({ feature }) {
1449
1491
  dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
1450
1492
  }
1451
1493
  ) : null,
1452
- hasGlossary ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap gap-x-2 text-xs", children: [
1453
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dt", { className: "font-medium text-foreground", children: entry.term }),
1454
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
1455
- ] }, entry.term)) }) : null
1494
+ hasGlossary ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1495
+ "dl",
1496
+ {
1497
+ className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1.5 text-xs",
1498
+ "aria-label": "Glossary",
1499
+ children: feature.glossary.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "contents", children: [
1500
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dt", { className: "font-medium text-foreground", children: entry.term }),
1501
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dd", { className: "text-muted-foreground", children: entry.definition })
1502
+ ] }, entry.term))
1503
+ }
1504
+ ) : null
1456
1505
  ] });
1457
1506
  }
1458
1507
  function featureKindLabel(kind) {
@@ -1468,7 +1517,6 @@ function ReportFeature({ feature }) {
1468
1517
  const titleId = `${feature.id}-title`;
1469
1518
  const bodyId = `${feature.id}-body`;
1470
1519
  const s = feature.summary;
1471
- const skipped = s.skipped + s.pending;
1472
1520
  const collapse = useCollapse();
1473
1521
  const collapsed = collapse?.isCollapsed(feature.id) ?? false;
1474
1522
  const kindLabel = featureKindLabel(feature.kind);
@@ -1508,7 +1556,12 @@ function ReportFeature({ feature }) {
1508
1556
  "p",
1509
1557
  {
1510
1558
  className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
1511
- "aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
1559
+ "aria-label": [
1560
+ `${s.passed} passed`,
1561
+ `${s.failed} failed`,
1562
+ s.skipped > 0 && `${s.skipped} skipped`,
1563
+ s.pending > 0 && `${s.pending} pending`
1564
+ ].filter(Boolean).join(", "),
1512
1565
  children: [
1513
1566
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
1514
1567
  s.passed,
@@ -1519,12 +1572,19 @@ function ReportFeature({ feature }) {
1519
1572
  s.failed,
1520
1573
  " failed"
1521
1574
  ] }),
1522
- skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
1575
+ s.skipped > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
1523
1576
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
1524
1577
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
1525
- skipped,
1578
+ s.skipped,
1526
1579
  " skipped"
1527
1580
  ] })
1581
+ ] }) : null,
1582
+ s.pending > 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
1583
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": true, children: "\xB7" }),
1584
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { children: [
1585
+ s.pending,
1586
+ " pending"
1587
+ ] })
1528
1588
  ] }) : null
1529
1589
  ]
1530
1590
  }