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/index.cjs +98 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.js +98 -34
- package/dist/index.js.map +1 -1
- package/dist/interactive.cjs +94 -34
- package/dist/interactive.cjs.map +1 -1
- package/dist/interactive.js +94 -34
- package/dist/interactive.js.map +1 -1
- package/dist/parse.cjs +4 -0
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.js +4 -0
- package/dist/parse.js.map +1 -1
- package/dist/report-island.global.js +61 -58
- package/dist/ssr.cjs +94 -34
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.js +94 -34
- package/dist/ssr.js.map +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +20 -20
package/dist/index.d.cts
CHANGED
|
@@ -100,9 +100,9 @@ declare function ReportSummaryView({ summary, className, ariaLabel }: ReportSumm
|
|
|
100
100
|
declare function ReportMeta(): react.JSX.Element | null;
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Renders scenario attachments.
|
|
104
|
-
*
|
|
105
|
-
*
|
|
103
|
+
* Renders scenario attachments. Images embed inline; text documents preview
|
|
104
|
+
* above their download link; other types get a labelled download link. An
|
|
105
|
+
* `external` attachment links to its file path and shows no preview.
|
|
106
106
|
*/
|
|
107
107
|
declare function ReportAttachments({ attachments }: {
|
|
108
108
|
attachments: ReportAttachment[];
|
|
@@ -192,8 +192,13 @@ declare function DocTag({ entry }: {
|
|
|
192
192
|
entry: ReportDocTag;
|
|
193
193
|
}): react.JSX.Element;
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Consecutive `story.kv()` entries share one two-column grid so the values
|
|
197
|
+
* line up whatever the label lengths; a lone entry is just a one-row grid.
|
|
198
|
+
* `ReportDocEntries` groups the runs.
|
|
199
|
+
*/
|
|
200
|
+
declare function DocKv({ entries }: {
|
|
201
|
+
entries: readonly ReportDocKv[];
|
|
197
202
|
}): react.JSX.Element;
|
|
198
203
|
|
|
199
204
|
declare function DocCode({ entry }: {
|
package/dist/index.d.ts
CHANGED
|
@@ -100,9 +100,9 @@ declare function ReportSummaryView({ summary, className, ariaLabel }: ReportSumm
|
|
|
100
100
|
declare function ReportMeta(): react.JSX.Element | null;
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Renders scenario attachments.
|
|
104
|
-
*
|
|
105
|
-
*
|
|
103
|
+
* Renders scenario attachments. Images embed inline; text documents preview
|
|
104
|
+
* above their download link; other types get a labelled download link. An
|
|
105
|
+
* `external` attachment links to its file path and shows no preview.
|
|
106
106
|
*/
|
|
107
107
|
declare function ReportAttachments({ attachments }: {
|
|
108
108
|
attachments: ReportAttachment[];
|
|
@@ -192,8 +192,13 @@ declare function DocTag({ entry }: {
|
|
|
192
192
|
entry: ReportDocTag;
|
|
193
193
|
}): react.JSX.Element;
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Consecutive `story.kv()` entries share one two-column grid so the values
|
|
197
|
+
* line up whatever the label lengths; a lone entry is just a one-row grid.
|
|
198
|
+
* `ReportDocEntries` groups the runs.
|
|
199
|
+
*/
|
|
200
|
+
declare function DocKv({ entries }: {
|
|
201
|
+
entries: readonly ReportDocKv[];
|
|
197
202
|
}): react.JSX.Element;
|
|
198
203
|
|
|
199
204
|
declare function DocCode({ entry }: {
|
package/dist/index.js
CHANGED
|
@@ -341,11 +341,11 @@ function formatValue(value) {
|
|
|
341
341
|
return String(value);
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
|
-
function DocKv({
|
|
345
|
-
return /* @__PURE__ */
|
|
344
|
+
function DocKv({ entries }) {
|
|
345
|
+
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__ */ jsxs2("div", { className: "contents", children: [
|
|
346
346
|
/* @__PURE__ */ jsx6("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
|
|
347
347
|
/* @__PURE__ */ jsx6("dd", { className: "min-w-0 break-words font-mono text-foreground", children: formatValue(entry.value) })
|
|
348
|
-
] });
|
|
348
|
+
] }, i)) });
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
// src/hooks/useRenderers.ts
|
|
@@ -432,7 +432,7 @@ function DocSection({ entry }) {
|
|
|
432
432
|
if (renderers.section) {
|
|
433
433
|
return /* @__PURE__ */ jsx10(Fragment2, { children: renderers.section(entry) });
|
|
434
434
|
}
|
|
435
|
-
const html = safeMarkdownHtml(entry.markdown);
|
|
435
|
+
const html = safeMarkdownHtml(dedent(entry.markdown));
|
|
436
436
|
return /* @__PURE__ */ jsxs5("section", { className: "my-3 text-sm", "aria-label": entry.title, children: [
|
|
437
437
|
entry.title ? /* @__PURE__ */ jsx10("h4", { className: "mb-1 font-semibold text-foreground", children: entry.title }) : null,
|
|
438
438
|
/* @__PURE__ */ jsx10(
|
|
@@ -618,7 +618,7 @@ function DocEntry({ entry }) {
|
|
|
618
618
|
case "tag":
|
|
619
619
|
return /* @__PURE__ */ jsx17(DocTag, { entry });
|
|
620
620
|
case "kv":
|
|
621
|
-
return /* @__PURE__ */ jsx17(DocKv, { entry });
|
|
621
|
+
return /* @__PURE__ */ jsx17(DocKv, { entries: [entry] });
|
|
622
622
|
case "code":
|
|
623
623
|
return /* @__PURE__ */ jsx17(DocCode, { entry });
|
|
624
624
|
case "table":
|
|
@@ -646,7 +646,15 @@ function DocEntry({ entry }) {
|
|
|
646
646
|
import { Fragment as Fragment5, jsx as jsx18 } from "react/jsx-runtime";
|
|
647
647
|
function ReportDocEntries({ entries }) {
|
|
648
648
|
if (entries.length === 0) return null;
|
|
649
|
-
|
|
649
|
+
const groups = [];
|
|
650
|
+
for (const entry of entries) {
|
|
651
|
+
const last = groups[groups.length - 1];
|
|
652
|
+
if (entry.kind === "kv" && Array.isArray(last)) last.push(entry);
|
|
653
|
+
else groups.push(entry.kind === "kv" ? [entry] : entry);
|
|
654
|
+
}
|
|
655
|
+
return /* @__PURE__ */ jsx18(Fragment5, { children: groups.map(
|
|
656
|
+
(g, i) => Array.isArray(g) ? /* @__PURE__ */ jsx18(DocKv, { entries: g }, i) : /* @__PURE__ */ jsx18(DocEntry, { entry: g }, i)
|
|
657
|
+
) });
|
|
650
658
|
}
|
|
651
659
|
|
|
652
660
|
// src/components/ReportSteps.tsx
|
|
@@ -851,42 +859,76 @@ function StateCardView({ card }) {
|
|
|
851
859
|
|
|
852
860
|
// src/components/ReportAttachments.tsx
|
|
853
861
|
import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
862
|
+
function attachmentText(att) {
|
|
863
|
+
if (att.contentEncoding !== "BASE64") return att.body;
|
|
864
|
+
try {
|
|
865
|
+
return new TextDecoder().decode(Uint8Array.from(atob(att.body), (c) => c.charCodeAt(0)));
|
|
866
|
+
} catch {
|
|
867
|
+
return void 0;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
function preview(att) {
|
|
871
|
+
const type = att.mediaType.split(";")[0].trim().toLowerCase();
|
|
872
|
+
const text = attachmentText(att);
|
|
873
|
+
if (text === void 0) return null;
|
|
874
|
+
if (type === "text/plain") {
|
|
875
|
+
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 });
|
|
876
|
+
}
|
|
877
|
+
if (type === "text/markdown") {
|
|
878
|
+
return /* @__PURE__ */ jsx21(
|
|
879
|
+
"div",
|
|
880
|
+
{
|
|
881
|
+
className: "es-doc-prose prose prose-sm max-w-none rounded-md border border-border p-3",
|
|
882
|
+
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(text) }
|
|
883
|
+
}
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
if (type === "text/html") {
|
|
887
|
+
return /* @__PURE__ */ jsx21(DocHtml, { entry: { kind: "html", content: text, title: att.name, phase: "runtime" } });
|
|
888
|
+
}
|
|
889
|
+
return null;
|
|
890
|
+
}
|
|
854
891
|
function ReportAttachments({ attachments }) {
|
|
855
892
|
if (attachments.length === 0) return null;
|
|
856
893
|
return (
|
|
857
894
|
// role="group" (not a labelled <section>) so multiple scenarios' attachment
|
|
858
895
|
// blocks don't create duplicate "Attachments" region landmarks.
|
|
859
896
|
/* @__PURE__ */ jsx21("div", { role: "group", "aria-label": "Attachments", className: "mt-3 flex flex-col gap-2", children: attachments.map((att, i) => {
|
|
860
|
-
const dataUri = att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
861
|
-
const
|
|
897
|
+
const dataUri = att.external ? void 0 : att.contentEncoding === "BASE64" ? `data:${att.mediaType};base64,${att.body}` : `data:${att.mediaType},${encodeURIComponent(att.body)}`;
|
|
898
|
+
const href = dataUri ?? safeUrl(att.body);
|
|
899
|
+
const imageSrc = dataUri ?? safeImageUrl(att.body);
|
|
900
|
+
const isImage = att.mediaType.startsWith("image/") && imageSrc !== void 0;
|
|
862
901
|
return /* @__PURE__ */ jsx21("figure", { className: "m-0", children: isImage ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
|
|
863
902
|
/* @__PURE__ */ jsx21(
|
|
864
903
|
"img",
|
|
865
904
|
{
|
|
866
|
-
src:
|
|
905
|
+
src: imageSrc,
|
|
867
906
|
alt: att.name,
|
|
868
907
|
loading: "lazy",
|
|
869
908
|
className: "max-w-full rounded-md border border-border"
|
|
870
909
|
}
|
|
871
910
|
),
|
|
872
911
|
/* @__PURE__ */ jsx21("figcaption", { className: "mt-1 text-xs text-muted-foreground", children: att.name })
|
|
873
|
-
] }) : /* @__PURE__ */ jsxs13(
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
"
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
912
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment6, { children: [
|
|
913
|
+
att.external ? null : preview(att),
|
|
914
|
+
/* @__PURE__ */ jsxs13(
|
|
915
|
+
"a",
|
|
916
|
+
{
|
|
917
|
+
href,
|
|
918
|
+
download: att.name,
|
|
919
|
+
className: "text-xs text-link underline underline-offset-2",
|
|
920
|
+
children: [
|
|
921
|
+
att.name,
|
|
922
|
+
" ",
|
|
923
|
+
/* @__PURE__ */ jsxs13("span", { className: "text-muted-foreground", children: [
|
|
924
|
+
"(",
|
|
925
|
+
att.mediaType,
|
|
926
|
+
")"
|
|
927
|
+
] })
|
|
928
|
+
]
|
|
929
|
+
}
|
|
930
|
+
)
|
|
931
|
+
] }) }, `${att.name}-${i}`);
|
|
890
932
|
}) })
|
|
891
933
|
);
|
|
892
934
|
}
|
|
@@ -1436,10 +1478,17 @@ function ReportFeatureIntro({ feature }) {
|
|
|
1436
1478
|
dangerouslySetInnerHTML: { __html: safeMarkdownHtml(dedent(feature.narrative)) }
|
|
1437
1479
|
}
|
|
1438
1480
|
) : null,
|
|
1439
|
-
hasGlossary ? /* @__PURE__ */ jsx28(
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1481
|
+
hasGlossary ? /* @__PURE__ */ jsx28(
|
|
1482
|
+
"dl",
|
|
1483
|
+
{
|
|
1484
|
+
className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1.5 text-xs",
|
|
1485
|
+
"aria-label": "Glossary",
|
|
1486
|
+
children: feature.glossary.map((entry) => /* @__PURE__ */ jsxs19("div", { className: "contents", children: [
|
|
1487
|
+
/* @__PURE__ */ jsx28("dt", { className: "font-medium text-foreground", children: entry.term }),
|
|
1488
|
+
/* @__PURE__ */ jsx28("dd", { className: "text-muted-foreground", children: entry.definition })
|
|
1489
|
+
] }, entry.term))
|
|
1490
|
+
}
|
|
1491
|
+
) : null
|
|
1443
1492
|
] });
|
|
1444
1493
|
}
|
|
1445
1494
|
function featureKindLabel(kind) {
|
|
@@ -1455,7 +1504,6 @@ function ReportFeature({ feature }) {
|
|
|
1455
1504
|
const titleId = `${feature.id}-title`;
|
|
1456
1505
|
const bodyId = `${feature.id}-body`;
|
|
1457
1506
|
const s = feature.summary;
|
|
1458
|
-
const skipped = s.skipped + s.pending;
|
|
1459
1507
|
const collapse = useCollapse();
|
|
1460
1508
|
const collapsed = collapse?.isCollapsed(feature.id) ?? false;
|
|
1461
1509
|
const kindLabel = featureKindLabel(feature.kind);
|
|
@@ -1495,7 +1543,12 @@ function ReportFeature({ feature }) {
|
|
|
1495
1543
|
"p",
|
|
1496
1544
|
{
|
|
1497
1545
|
className: "flex shrink-0 items-center gap-1.5 text-xs text-muted-foreground",
|
|
1498
|
-
"aria-label":
|
|
1546
|
+
"aria-label": [
|
|
1547
|
+
`${s.passed} passed`,
|
|
1548
|
+
`${s.failed} failed`,
|
|
1549
|
+
s.skipped > 0 && `${s.skipped} skipped`,
|
|
1550
|
+
s.pending > 0 && `${s.pending} pending`
|
|
1551
|
+
].filter(Boolean).join(", "),
|
|
1499
1552
|
children: [
|
|
1500
1553
|
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1501
1554
|
s.passed,
|
|
@@ -1506,12 +1559,19 @@ function ReportFeature({ feature }) {
|
|
|
1506
1559
|
s.failed,
|
|
1507
1560
|
" failed"
|
|
1508
1561
|
] }),
|
|
1509
|
-
skipped > 0 ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
1562
|
+
s.skipped > 0 ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
1510
1563
|
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1511
1564
|
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1512
|
-
skipped,
|
|
1565
|
+
s.skipped,
|
|
1513
1566
|
" skipped"
|
|
1514
1567
|
] })
|
|
1568
|
+
] }) : null,
|
|
1569
|
+
s.pending > 0 ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
1570
|
+
/* @__PURE__ */ jsx29("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1571
|
+
/* @__PURE__ */ jsxs20("span", { children: [
|
|
1572
|
+
s.pending,
|
|
1573
|
+
" pending"
|
|
1574
|
+
] })
|
|
1515
1575
|
] }) : null
|
|
1516
1576
|
]
|
|
1517
1577
|
}
|
|
@@ -2502,6 +2562,10 @@ var story_report_v1_default = {
|
|
|
2502
2562
|
contentEncoding: {
|
|
2503
2563
|
type: "string",
|
|
2504
2564
|
enum: ["BASE64", "IDENTITY"]
|
|
2565
|
+
},
|
|
2566
|
+
external: {
|
|
2567
|
+
const: true,
|
|
2568
|
+
description: "body holds the file's path or URL (file missing or too large to embed)."
|
|
2505
2569
|
}
|
|
2506
2570
|
},
|
|
2507
2571
|
required: ["name", "mediaType", "body", "contentEncoding"],
|