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.
@@ -203,11 +203,11 @@ function formatValue(value) {
203
203
  return String(value);
204
204
  }
205
205
  }
206
- function DocKv({ entry }) {
207
- return /* @__PURE__ */ jsxs("dl", { className: "my-2 flex flex-wrap items-baseline gap-x-2 text-sm", children: [
206
+ function DocKv({ entries }) {
207
+ return /* @__PURE__ */ jsx6("dl", { className: "my-2 grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-sm", children: entries.map((entry, i) => /* @__PURE__ */ jsxs("div", { className: "contents", children: [
208
208
  /* @__PURE__ */ jsx6("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
209
209
  /* @__PURE__ */ jsx6("dd", { className: "min-w-0 break-words font-mono text-foreground", children: formatValue(entry.value) })
210
- ] });
210
+ ] }, i)) });
211
211
  }
212
212
 
213
213
  // src/hooks/useRenderers.ts
@@ -294,7 +294,7 @@ function DocSection({ entry }) {
294
294
  if (renderers.section) {
295
295
  return /* @__PURE__ */ jsx10(Fragment2, { children: renderers.section(entry) });
296
296
  }
297
- const html = safeMarkdownHtml(entry.markdown);
297
+ const html = safeMarkdownHtml(dedent(entry.markdown));
298
298
  return /* @__PURE__ */ jsxs4("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
299
299
  entry.title ? /* @__PURE__ */ jsx10("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
300
300
  /* @__PURE__ */ jsx10(
@@ -480,7 +480,7 @@ function DocEntry({ entry }) {
480
480
  case "tag":
481
481
  return /* @__PURE__ */ jsx17(DocTag, { entry });
482
482
  case "kv":
483
- return /* @__PURE__ */ jsx17(DocKv, { entry });
483
+ return /* @__PURE__ */ jsx17(DocKv, { entries: [entry] });
484
484
  case "code":
485
485
  return /* @__PURE__ */ jsx17(DocCode, { entry });
486
486
  case "table":
@@ -508,7 +508,15 @@ function DocEntry({ entry }) {
508
508
  import { Fragment as Fragment5, jsx as jsx18 } from "react/jsx-runtime";
509
509
  function ReportDocEntries({ entries }) {
510
510
  if (entries.length === 0) return null;
511
- return /* @__PURE__ */ jsx18(Fragment5, { children: entries.map((entry, i) => /* @__PURE__ */ jsx18(DocEntry, { entry }, i)) });
511
+ const groups = [];
512
+ for (const entry of entries) {
513
+ const last = groups[groups.length - 1];
514
+ if (entry.kind === "kv" && Array.isArray(last)) last.push(entry);
515
+ else groups.push(entry.kind === "kv" ? [entry] : entry);
516
+ }
517
+ return /* @__PURE__ */ jsx18(Fragment5, { children: groups.map(
518
+ (g, i) => Array.isArray(g) ? /* @__PURE__ */ jsx18(DocKv, { entries: g }, i) : /* @__PURE__ */ jsx18(DocEntry, { entry: g }, i)
519
+ ) });
512
520
  }
513
521
 
514
522
  // src/components/ReportSteps.tsx
@@ -713,42 +721,76 @@ function StateCardView({ card }) {
713
721
 
714
722
  // src/components/ReportAttachments.tsx
715
723
  import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
724
+ function attachmentText(att) {
725
+ if (att.contentEncoding !== "BASE64") return att.body;
726
+ try {
727
+ return new TextDecoder().decode(Uint8Array.from(atob(att.body), (c) => c.charCodeAt(0)));
728
+ } catch {
729
+ return void 0;
730
+ }
731
+ }
732
+ function preview(att) {
733
+ const type = att.mediaType.split(";")[0].trim().toLowerCase();
734
+ const text = attachmentText(att);
735
+ if (text === void 0) return null;
736
+ if (type === "text/plain") {
737
+ return /* @__PURE__ */ jsx21("pre", { className: "max-h-96 overflow-auto rounded-md border border-border bg-muted/40 p-3 text-xs whitespace-pre-wrap", children: text });
738
+ }
739
+ if (type === "text/markdown") {
740
+ return /* @__PURE__ */ jsx21(
741
+ "div",
742
+ {
743
+ className: "es-doc-prose prose prose-sm max-w-none rounded-md border border-border p-3",
744
+ dangerouslySetInnerHTML: { __html: safeMarkdownHtml(text) }
745
+ }
746
+ );
747
+ }
748
+ if (type === "text/html") {
749
+ return /* @__PURE__ */ jsx21(DocHtml, { entry: { kind: "html", content: text, title: att.name, phase: "runtime" } });
750
+ }
751
+ return null;
752
+ }
716
753
  function ReportAttachments({ attachments }) {
717
754
  if (attachments.length === 0) return null;
718
755
  return (
719
756
  // role="group" (not a labelled <section>) so multiple scenarios' attachment
720
757
  // blocks don't create duplicate "Attachments" region landmarks.
721
758
  /* @__PURE__ */ jsx21("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
722
- const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
723
- const isImage = att.mediaType.startsWith("image/");
759
+ const dataUri = att.external ? void 0 : att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
760
+ const href = dataUri ?? safeUrl(att.body);
761
+ const imageSrc = dataUri ?? safeImageUrl(att.body);
762
+ const isImage = att.mediaType.startsWith("image/") && imageSrc !== void 0;
724
763
  return /* @__PURE__ */ jsx21("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs12(Fragment6, { children: [
725
764
  /* @__PURE__ */ jsx21(
726
765
  "img",
727
766
  {
728
- src: dataUri,
767
+ src: imageSrc,
729
768
  alt: att.name,
730
769
  loading: "lazy",
731
770
  className: "max-w-full rounded-md border border-border"
732
771
  }
733
772
  ),
734
773
  /* @__PURE__ */ jsx21("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
735
- ] }) : /* @__PURE__ */ jsxs12(
736
- "a",
737
- {
738
- href: dataUri,
739
- download: att.name,
740
- className: "text-xs text-link underline underline-offset-2",
741
- children: [
742
- att.name,
743
- " ",
744
- /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
745
- "(",
746
- att.mediaType,
747
- ")"
748
- ] })
749
- ]
750
- }
751
- ) }, `${att.name}-${i}`);
774
+ ] }) : /* @__PURE__ */ jsxs12(Fragment6, { children: [
775
+ att.external ? null : preview(att),
776
+ /* @__PURE__ */ jsxs12(
777
+ "a",
778
+ {
779
+ href,
780
+ download: att.name,
781
+ className: "text-xs text-link underline underline-offset-2",
782
+ children: [
783
+ att.name,
784
+ " ",
785
+ /* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
786
+ "(",
787
+ att.mediaType,
788
+ ")"
789
+ ] })
790
+ ]
791
+ }
792
+ )
793
+ ] }) }, `${att.name}-${i}`);
752
794
  }) })
753
795
  );
754
796
  }
@@ -1403,10 +1445,17 @@ function ReportFeatureIntro({ feature }) {
1403
1445
  dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
1404
1446
  }
1405
1447
  ) : null,
1406
- hasGlossary ? /* @__PURE__ */ jsx28("dl", { className: "grid gap-1.5", "aria-label": "Glossary", children: feature.glossary.map((entry) => /* @__PURE__ */ jsxs18("div", { className: "flex flex-wrap gap-x-2 text-xs", children: [
1407
- /* @__PURE__ */ jsx28("dt", { className: "font-medium text-foreground", children: entry.term }),
1408
- /* @__PURE__ */ jsx28("dd", { className: "flex-1 text-muted-foreground", children: entry.definition })
1409
- ] }, entry.term)) }) : null
1448
+ hasGlossary ? /* @__PURE__ */ jsx28(
1449
+ "dl",
1450
+ {
1451
+ className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1.5 text-xs",
1452
+ "aria-label": "Glossary",
1453
+ children: feature.glossary.map((entry) => /* @__PURE__ */ jsxs18("div", { className: "contents", children: [
1454
+ /* @__PURE__ */ jsx28("dt", { className: "font-medium text-foreground", children: entry.term }),
1455
+ /* @__PURE__ */ jsx28("dd", { className: "text-muted-foreground", children: entry.definition })
1456
+ ] }, entry.term))
1457
+ }
1458
+ ) : null
1410
1459
  ] });
1411
1460
  }
1412
1461
  function featureKindLabel(kind) {
@@ -1422,7 +1471,6 @@ function ReportFeature({ feature }) {
1422
1471
  const titleId = `${feature.id}-title`;
1423
1472
  const bodyId = `${feature.id}-body`;
1424
1473
  const s = feature.summary;
1425
- const skipped = s.skipped + s.pending;
1426
1474
  const collapse = useCollapse();
1427
1475
  const collapsed = collapse?.isCollapsed(feature.id) ?? false;
1428
1476
  const kindLabel = featureKindLabel(feature.kind);
@@ -1462,7 +1510,12 @@ function ReportFeature({ feature }) {
1462
1510
  "p",
1463
1511
  {
1464
1512
  className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
1465
- "aria-label": `${s.passed} passed, ${s.failed} failed, ${skipped} skipped`,
1513
+ "aria-label": [
1514
+ `${s.passed} passed`,
1515
+ `${s.failed} failed`,
1516
+ s.skipped > 0 && `${s.skipped} skipped`,
1517
+ s.pending > 0 && `${s.pending} pending`
1518
+ ].filter(Boolean).join(", "),
1466
1519
  children: [
1467
1520
  /* @__PURE__ */ jsxs19("span", { children: [
1468
1521
  s.passed,
@@ -1473,12 +1526,19 @@ function ReportFeature({ feature }) {
1473
1526
  s.failed,
1474
1527
  " failed"
1475
1528
  ] }),
1476
- skipped > 0 ? /* @__PURE__ */ jsxs19(Fragment9, { children: [
1529
+ s.skipped > 0 ? /* @__PURE__ */ jsxs19(Fragment9, { children: [
1477
1530
  /* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
1478
1531
  /* @__PURE__ */ jsxs19("span", { children: [
1479
- skipped,
1532
+ s.skipped,
1480
1533
  " skipped"
1481
1534
  ] })
1535
+ ] }) : null,
1536
+ s.pending > 0 ? /* @__PURE__ */ jsxs19(Fragment9, { children: [
1537
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
1538
+ /* @__PURE__ */ jsxs19("span", { children: [
1539
+ s.pending,
1540
+ " pending"
1541
+ ] })
1482
1542
  ] }) : null
1483
1543
  ]
1484
1544
  }