executable-stories-react 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/interactive/index.ts","../src/interactive/ReportInteractive.tsx","../src/context/ReportRoot.tsx","../src/context/ReportContext.ts","../src/hooks/useReport.ts","../src/components/ReportSummary.tsx","../src/components/doc/DocNote.tsx","../src/components/doc/DocTag.tsx","../src/components/doc/DocKv.tsx","../src/hooks/useRenderers.ts","../src/components/doc/DocCode.tsx","../src/components/doc/DocTable.tsx","../src/components/doc/DocLink.tsx","../src/components/doc/DocSection.tsx","../src/components/doc/DocMermaid.tsx","../src/components/doc/DocScreenshot.tsx","../src/components/doc/DocCustom.tsx","../src/components/doc/DocEntry.tsx","../src/components/ReportDocEntries.tsx","../src/components/ReportSteps.tsx","../src/components/ReportScenario.tsx","../src/components/ReportScenarioList.tsx","../src/components/ReportFeature.tsx","../src/components/ReportFeatureList.tsx","../src/components/ReportEmpty.tsx","../src/components/ReportSchemaError.tsx","../src/interactive/ReportSearch.tsx","../src/interactive/ReportFailureBanner.tsx","../src/interactive/ReportShortcutsHelp.tsx","../src/interactive/use-keyboard-shortcuts.ts","../src/interactive/use-deep-link-scroll.ts","../src/interactive/filter.ts"],"sourcesContent":["/**\n * Client-only entry. Importing this module pulls in everything that uses\n * useState/useEffect; the package.json export points Next.js at a bundle\n * with a \"use client\" directive at the top so the App Router treats it\n * correctly.\n */\n\nexport { ReportInteractive } from \"./ReportInteractive\";\nexport type { ReportInteractiveProps } from \"./ReportInteractive\";\nexport { ReportSearch } from \"./ReportSearch\";\nexport type { ReportSearchProps } from \"./ReportSearch\";\nexport { ReportFailureBanner } from \"./ReportFailureBanner\";\nexport type { ReportFailureBannerProps } from \"./ReportFailureBanner\";\nexport { ReportShortcutsHelp } from \"./ReportShortcutsHelp\";\nexport type { ReportShortcutsHelpProps } from \"./ReportShortcutsHelp\";\nexport { filterReport, listFailures, normalizeQuery } from \"./filter\";\nexport type { FailureRef } from \"./filter\";\nexport { useKeyboardShortcuts } from \"./use-keyboard-shortcuts\";\nexport type { KeyboardShortcutHandlers } from \"./use-keyboard-shortcuts\";\nexport { useDeepLinkScroll } from \"./use-deep-link-scroll\";\n","\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { StoryReport } from \"executable-stories-formatters\";\nimport type { Result } from \"../result\";\nimport type { BuiltinRenderers, CustomRenderers } from \"../renderers\";\nimport { ReportRoot } from \"../context/ReportRoot\";\nimport { ReportSummary } from \"../components/ReportSummary\";\nimport { ReportFeatureList } from \"../components/ReportFeatureList\";\nimport { ReportEmpty } from \"../components/ReportEmpty\";\nimport { ReportSchemaError } from \"../components/ReportSchemaError\";\nimport { ReportSearch } from \"./ReportSearch\";\nimport { ReportFailureBanner } from \"./ReportFailureBanner\";\nimport { ReportShortcutsHelp } from \"./ReportShortcutsHelp\";\nimport { useKeyboardShortcuts } from \"./use-keyboard-shortcuts\";\nimport { useDeepLinkScroll } from \"./use-deep-link-scroll\";\nimport { filterReport, listFailures } from \"./filter\";\n\nexport interface ReportInteractiveProps {\n /** A StoryReport, or a Result-wrapped one (e.g., from parseStoryReport). */\n report: StoryReport | Result<StoryReport>;\n /** Renderers keyed by `story.custom({ type })` strings. */\n customRenderers?: CustomRenderers;\n /** Optional overrides for the heavy built-ins (mermaid, code, section). */\n renderers?: BuiltinRenderers;\n className?: string;\n title?: string;\n dataTheme?: \"light\" | \"dark\";\n}\n\nfunction isResult(value: ReportInteractiveProps[\"report\"]): value is Result<StoryReport> {\n return typeof value === \"object\"\n && value !== null\n && \"ok\" in (value as object)\n && typeof (value as { ok: unknown }).ok === \"boolean\";\n}\n\nexport function ReportInteractive(props: ReportInteractiveProps) {\n const { report, className, title, dataTheme } = props;\n\n if (isResult(report)) {\n if (!report.ok) {\n return (\n <main\n className={[\"es-report\", className].filter(Boolean).join(\" \")}\n aria-label={title ?? \"Test report\"}\n data-theme={dataTheme}\n >\n <ReportSchemaError error={report.error} />\n </main>\n );\n }\n return <ReportInteractiveView {...props} report={report.data} />;\n }\n\n return <ReportInteractiveView {...props} report={report} />;\n}\n\ninterface ReportInteractiveViewProps extends Omit<ReportInteractiveProps, \"report\"> {\n report: StoryReport;\n}\n\nfunction ReportInteractiveView({\n report,\n customRenderers,\n renderers,\n className,\n title,\n dataTheme,\n}: ReportInteractiveViewProps) {\n const [query, setQuery] = useState(\"\");\n const [helpOpen, setHelpOpen] = useState(false);\n const searchRef = useRef<HTMLInputElement>(null);\n const failures = useMemo(() => listFailures(report), [report]);\n const filtered = useMemo(() => filterReport(report, query), [report, query]);\n const failureIndexRef = useRef(0);\n\n const focusSearch = useCallback(() => {\n searchRef.current?.focus();\n }, []);\n\n const scrollToScenario = useCallback((scenarioId: string) => {\n if (typeof document === \"undefined\") return;\n const el = document.getElementById(scenarioId);\n if (!el) return;\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n if (typeof history !== \"undefined\") {\n history.replaceState(null, \"\", `#${scenarioId}`);\n }\n }, []);\n\n const stepFailure = useCallback(\n (direction: 1 | -1) => {\n if (failures.length === 0) return;\n failureIndexRef.current =\n (failureIndexRef.current + direction + failures.length) % failures.length;\n const target = failures[failureIndexRef.current];\n if (target) scrollToScenario(target.scenarioId);\n },\n [failures, scrollToScenario],\n );\n\n const toggleHelp = useCallback(() => {\n setHelpOpen((v) => !v);\n }, []);\n\n const escape = useCallback(() => {\n if (helpOpen) setHelpOpen(false);\n else if (query !== \"\") setQuery(\"\");\n }, [helpOpen, query]);\n\n useKeyboardShortcuts({\n onFocusSearch: focusSearch,\n onNextFailure: () => stepFailure(1),\n onPrevFailure: () => stepFailure(-1),\n onToggleHelp: toggleHelp,\n onEscape: escape,\n });\n\n useDeepLinkScroll();\n\n const hasContent = filtered.features.length > 0;\n const totalScenarios = report.summary.total;\n const matchedScenarios = filtered.summary.total;\n\n return (\n <ReportRoot\n report={filtered}\n customRenderers={customRenderers}\n renderers={renderers}\n >\n <main\n className={[\"es-report\", \"es-report-interactive\", className].filter(Boolean).join(\" \")}\n aria-label={title ?? \"Test report\"}\n data-theme={dataTheme}\n >\n <header className=\"es-report-header\">\n <h1>{title ?? \"Story Report\"}</h1>\n <ReportSummary />\n <ReportSearch\n ref={searchRef}\n value={query}\n onChange={setQuery}\n matchedCount={matchedScenarios}\n totalCount={totalScenarios}\n />\n </header>\n <ReportFailureBanner failures={failures} />\n {hasContent ? <ReportFeatureList /> : <ReportEmpty message={query ? \"No scenarios match the search.\" : undefined} />}\n <button\n type=\"button\"\n className=\"es-shortcuts-trigger\"\n aria-label=\"Keyboard shortcuts\"\n aria-keyshortcuts=\"Shift+?\"\n onClick={toggleHelp}\n >\n ?\n </button>\n <ReportShortcutsHelp open={helpOpen} onClose={() => setHelpOpen(false)} />\n </main>\n </ReportRoot>\n );\n}\n","import { useMemo, type ReactNode } from \"react\";\nimport type { StoryReport } from \"executable-stories-formatters\";\nimport type { BuiltinRenderers, CustomRenderers } from \"../renderers\";\nimport { ReportContext, type ReportContextValue } from \"./ReportContext\";\n\nexport interface ReportRootProps {\n report: StoryReport;\n customRenderers?: CustomRenderers;\n renderers?: BuiltinRenderers;\n children: ReactNode;\n}\n\nconst EMPTY_CUSTOM: CustomRenderers = {};\nconst EMPTY_RENDERERS: BuiltinRenderers = {};\n\nexport function ReportRoot({\n report,\n customRenderers,\n renderers,\n children,\n}: ReportRootProps) {\n const value = useMemo<ReportContextValue>(\n () => ({\n report,\n customRenderers: customRenderers ?? EMPTY_CUSTOM,\n renderers: renderers ?? EMPTY_RENDERERS,\n }),\n [report, customRenderers, renderers],\n );\n return <ReportContext.Provider value={value}>{children}</ReportContext.Provider>;\n}\n","import { createContext } from \"react\";\nimport type { StoryReport } from \"executable-stories-formatters\";\nimport type { BuiltinRenderers, CustomRenderers } from \"../renderers\";\n\nexport interface ReportContextValue {\n report: StoryReport;\n customRenderers: CustomRenderers;\n renderers: BuiltinRenderers;\n}\n\nexport const ReportContext = createContext<ReportContextValue | null>(null);\n","import { useContext } from \"react\";\nimport { ReportContext } from \"../context/ReportContext\";\n\nexport function useReport() {\n const ctx = useContext(ReportContext);\n if (!ctx) {\n throw new Error(\n \"useReport must be used inside <ReportRoot> or <Report>. Wrap your tree with one of those.\",\n );\n }\n return ctx.report;\n}\n","import type { ReportSummary as ReportSummaryT } from \"executable-stories-formatters\";\nimport { useReport } from \"../hooks/useReport\";\n\nexport interface ReportSummaryProps {\n className?: string;\n}\n\nexport function ReportSummary({ className }: ReportSummaryProps) {\n const report = useReport();\n return (\n <ReportSummaryView\n summary={report.summary}\n {...(className !== undefined && { className })}\n ariaLabel=\"Run summary\"\n />\n );\n}\n\nexport interface ReportSummaryViewProps {\n summary: ReportSummaryT;\n className?: string;\n ariaLabel?: string;\n}\n\nexport function ReportSummaryView({ summary, className, ariaLabel }: ReportSummaryViewProps) {\n return (\n <p\n className={[\"es-report-summary\", className].filter(Boolean).join(\" \")}\n aria-label={ariaLabel}\n >\n <span>\n <strong>{summary.total}</strong> scenario{summary.total === 1 ? \"\" : \"s\"}\n </span>\n {\" · \"}\n <span data-status=\"passed\">{summary.passed} passed</span>\n {\" · \"}\n <span data-status=\"failed\">{summary.failed} failed</span>\n {summary.skipped > 0 ? (\n <>\n {\" · \"}\n <span data-status=\"skipped\">{summary.skipped} skipped</span>\n </>\n ) : null}\n {summary.pending > 0 ? (\n <>\n {\" · \"}\n <span data-status=\"pending\">{summary.pending} pending</span>\n </>\n ) : null}\n </p>\n );\n}\n","import type { ReportDocNote } from \"executable-stories-formatters\";\n\nexport function DocNote({ entry }: { entry: ReportDocNote }) {\n return <p className=\"es-doc es-doc-note\">{entry.text}</p>;\n}\n","import type { ReportDocTag } from \"executable-stories-formatters\";\n\nexport function DocTag({ entry }: { entry: ReportDocTag }) {\n return (\n <ul className=\"es-doc es-tags\" aria-label=\"Tags\">\n {entry.names.map((n) => (\n <li key={n}>{n}</li>\n ))}\n </ul>\n );\n}\n","import type { ReportDocKv } from \"executable-stories-formatters\";\n\nfunction formatValue(value: unknown): string {\n if (value === null) return \"null\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport function DocKv({ entry }: { entry: ReportDocKv }) {\n return (\n <dl className=\"es-doc es-doc-kv\">\n <dt>{entry.label}</dt>\n <dd>{formatValue(entry.value)}</dd>\n </dl>\n );\n}\n","import { useContext } from \"react\";\nimport { ReportContext } from \"../context/ReportContext\";\nimport type { BuiltinRenderers, CustomRenderers } from \"../renderers\";\n\nconst EMPTY_CUSTOM: CustomRenderers = {};\nconst EMPTY_RENDERERS: BuiltinRenderers = {};\n\nexport function useCustomRenderers(): CustomRenderers {\n const ctx = useContext(ReportContext);\n return ctx?.customRenderers ?? EMPTY_CUSTOM;\n}\n\nexport function useBuiltinRenderers(): BuiltinRenderers {\n const ctx = useContext(ReportContext);\n return ctx?.renderers ?? EMPTY_RENDERERS;\n}\n","import type { ReportDocCode } from \"executable-stories-formatters\";\nimport { useBuiltinRenderers } from \"../../hooks/useRenderers\";\n\nexport function DocCode({ entry }: { entry: ReportDocCode }) {\n const renderers = useBuiltinRenderers();\n if (renderers.code) {\n return <>{renderers.code(entry)}</>;\n }\n return (\n <figure className=\"es-doc es-doc-code\">\n <figcaption>{entry.label}</figcaption>\n <pre>\n <code className={entry.lang ? `language-${entry.lang}` : undefined}>\n {entry.content}\n </code>\n </pre>\n </figure>\n );\n}\n","import type { ReportDocTable } from \"executable-stories-formatters\";\n\nexport function DocTable({ entry }: { entry: ReportDocTable }) {\n return (\n <figure className=\"es-doc es-doc-table\">\n <figcaption>{entry.label}</figcaption>\n <table>\n <thead>\n <tr>\n {entry.columns.map((c) => (\n <th key={c} scope=\"col\">{c}</th>\n ))}\n </tr>\n </thead>\n <tbody>\n {entry.rows.map((row, i) => (\n <tr key={i}>\n {row.map((cell, j) => (\n <td key={j}>{cell}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </figure>\n );\n}\n","import type { ReportDocLink } from \"executable-stories-formatters\";\n\nexport function DocLink({ entry }: { entry: ReportDocLink }) {\n return (\n <a\n className=\"es-doc es-doc-link\"\n href={entry.url}\n rel=\"noreferrer noopener\"\n target=\"_blank\"\n >\n {entry.label}\n </a>\n );\n}\n","import { marked } from \"marked\";\nimport type { ReportDocSection } from \"executable-stories-formatters\";\nimport { useBuiltinRenderers } from \"../../hooks/useRenderers\";\n\n/**\n * Strips the most common dangerous patterns from marked-generated HTML:\n * - <script>...</script> blocks\n * - <style>...</style> blocks\n * - on* event-handler attributes\n * - javascript: URLs on href / src\n *\n * Not a substitute for a full HTML sanitizer (DOMPurify, sanitize-html).\n * For high-untrust input, supply `renderers.section` with your own sanitizer.\n */\nfunction safeMarkdownHtml(markdown: string): string {\n const raw = marked.parse(markdown, { async: false }) as string;\n return raw\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, \"\")\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, \"\")\n .replace(/\\son[a-z]+\\s*=\\s*\"[^\"]*\"/gi, \"\")\n .replace(/\\son[a-z]+\\s*=\\s*'[^']*'/gi, \"\")\n .replace(/\\son[a-z]+\\s*=\\s*[^\\s>]+/gi, \"\")\n .replace(/(href|src)\\s*=\\s*\"\\s*javascript:[^\"]*\"/gi, '$1=\"#\"')\n .replace(/(href|src)\\s*=\\s*'\\s*javascript:[^']*'/gi, \"$1='#'\");\n}\n\nexport function DocSection({ entry }: { entry: ReportDocSection }) {\n const renderers = useBuiltinRenderers();\n if (renderers.section) {\n return <>{renderers.section(entry)}</>;\n }\n const html = safeMarkdownHtml(entry.markdown);\n return (\n <section className=\"es-doc es-doc-section\" aria-label={entry.title}>\n {entry.title ? <h4 className=\"es-doc-section-title\">{entry.title}</h4> : null}\n <div\n className=\"es-doc-section-content\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n </section>\n );\n}\n","import type { ReportDocMermaid } from \"executable-stories-formatters\";\nimport { useBuiltinRenderers } from \"../../hooks/useRenderers\";\n\n/**\n * Renders mermaid source as a semantic <pre data-mermaid> by default.\n *\n * AI agents and screen readers get the raw source. To render the diagram\n * visually, supply a `renderers.mermaid` prop with a client-only component\n * (e.g., one that dynamically imports the mermaid library on mount).\n */\nexport function DocMermaid({ entry }: { entry: ReportDocMermaid }) {\n const renderers = useBuiltinRenderers();\n if (renderers.mermaid) {\n return <>{renderers.mermaid(entry)}</>;\n }\n return (\n <figure\n className=\"es-doc es-doc-mermaid\"\n aria-label={entry.title ?? \"Diagram\"}\n >\n {entry.title ? <figcaption>{entry.title}</figcaption> : null}\n <pre data-mermaid>{entry.code}</pre>\n </figure>\n );\n}\n","import type { ReportDocScreenshot } from \"executable-stories-formatters\";\n\nexport function DocScreenshot({ entry }: { entry: ReportDocScreenshot }) {\n return (\n <figure className=\"es-doc es-doc-screenshot\">\n <img src={entry.path} alt={entry.alt ?? \"\"} loading=\"lazy\" />\n {entry.alt ? <figcaption>{entry.alt}</figcaption> : null}\n </figure>\n );\n}\n","import type { ReportDocCustom } from \"executable-stories-formatters\";\nimport { useCustomRenderers } from \"../../hooks/useRenderers\";\n\nexport function DocCustom({ entry }: { entry: ReportDocCustom }) {\n const renderers = useCustomRenderers();\n const renderer = renderers[entry.type];\n if (renderer) {\n return <>{renderer(entry)}</>;\n }\n return (\n <div className=\"es-doc es-doc-custom\" data-type={entry.type}>\n <p className=\"es-doc-custom-type\">{entry.type}</p>\n <pre>{safeStringify(entry.data)}</pre>\n </div>\n );\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n","import type { ReportDocEntry } from \"executable-stories-formatters\";\nimport { DocNote } from \"./DocNote\";\nimport { DocTag } from \"./DocTag\";\nimport { DocKv } from \"./DocKv\";\nimport { DocCode } from \"./DocCode\";\nimport { DocTable } from \"./DocTable\";\nimport { DocLink } from \"./DocLink\";\nimport { DocSection } from \"./DocSection\";\nimport { DocMermaid } from \"./DocMermaid\";\nimport { DocScreenshot } from \"./DocScreenshot\";\nimport { DocCustom } from \"./DocCustom\";\n\nexport function DocEntry({ entry }: { entry: ReportDocEntry }) {\n switch (entry.kind) {\n case \"note\":\n return <DocNote entry={entry} />;\n case \"tag\":\n return <DocTag entry={entry} />;\n case \"kv\":\n return <DocKv entry={entry} />;\n case \"code\":\n return <DocCode entry={entry} />;\n case \"table\":\n return <DocTable entry={entry} />;\n case \"link\":\n return <DocLink entry={entry} />;\n case \"section\":\n return <DocSection entry={entry} />;\n case \"mermaid\":\n return <DocMermaid entry={entry} />;\n case \"screenshot\":\n return <DocScreenshot entry={entry} />;\n case \"custom\":\n return <DocCustom entry={entry} />;\n }\n}\n","import type { ReportDocEntry } from \"executable-stories-formatters\";\nimport { DocEntry } from \"./doc/DocEntry\";\n\nexport interface ReportDocEntriesProps {\n entries: readonly ReportDocEntry[];\n}\n\nexport function ReportDocEntries({ entries }: ReportDocEntriesProps) {\n if (entries.length === 0) return null;\n return (\n <>\n {entries.map((entry, i) => (\n <DocEntry key={i} entry={entry} />\n ))}\n </>\n );\n}\n","import type { ReportStep, ReportScenario } from \"executable-stories-formatters\";\nimport { ReportDocEntries } from \"./ReportDocEntries\";\n\nexport interface ReportStepsProps {\n scenario: ReportScenario;\n}\n\nexport function ReportSteps({ scenario }: ReportStepsProps) {\n if (scenario.steps.length === 0) return null;\n return (\n <ol className=\"es-steps\">\n {scenario.steps.map((step) => (\n <ReportStepItem key={step.id} step={step} />\n ))}\n </ol>\n );\n}\n\nexport function ReportStepItem({ step }: { step: ReportStep }) {\n return (\n <li\n id={step.id}\n className={`es-step es-step-${step.status}`}\n data-status={step.status}\n >\n <span className=\"es-step-keyword\">{step.keyword}</span>\n <span className=\"es-step-text\">{step.text}</span>\n {step.errorMessage ? (\n <pre className=\"es-scenario-error\" role=\"alert\">{step.errorMessage}</pre>\n ) : null}\n {step.docEntries.length > 0 ? (\n <div className=\"es-step-docs\">\n <ReportDocEntries entries={step.docEntries} />\n </div>\n ) : null}\n </li>\n );\n}\n","import type { ReportScenario as ReportScenarioT } from \"executable-stories-formatters\";\nimport { ReportSteps } from \"./ReportSteps\";\nimport { ReportDocEntries } from \"./ReportDocEntries\";\n\nexport interface ReportScenarioProps {\n scenario: ReportScenarioT;\n}\n\nconst STATUS_LABEL: Record<ReportScenarioT[\"status\"], string> = {\n passed: \"Passed\",\n failed: \"Failed\",\n skipped: \"Skipped\",\n pending: \"Pending\",\n};\n\nexport function ReportScenario({ scenario }: ReportScenarioProps) {\n const titleId = `${scenario.id}-title`;\n return (\n <article\n id={scenario.id}\n className={`es-scenario es-status-${scenario.status}`}\n aria-labelledby={titleId}\n data-status={scenario.status}\n >\n <h3 id={titleId} className=\"es-scenario-title\">\n <span>{scenario.title}</span>\n <span className=\"es-scenario-status\" aria-label={`Status: ${STATUS_LABEL[scenario.status]}`}>\n {STATUS_LABEL[scenario.status]}\n </span>\n </h3>\n {scenario.tags.length > 0 ? (\n <ul className=\"es-tags\" aria-label=\"Tags\">\n {scenario.tags.map((t) => (\n <li key={t}>{t}</li>\n ))}\n </ul>\n ) : null}\n {scenario.errorMessage ? (\n <pre className=\"es-scenario-error\" role=\"alert\">{scenario.errorMessage}</pre>\n ) : null}\n {scenario.docEntries.length > 0 ? (\n <div className=\"es-scenario-docs\">\n <ReportDocEntries entries={scenario.docEntries} />\n </div>\n ) : null}\n <ReportSteps scenario={scenario} />\n </article>\n );\n}\n","import type { ReportFeature } from \"executable-stories-formatters\";\nimport { ReportScenario } from \"./ReportScenario\";\n\nexport interface ReportScenarioListProps {\n feature: ReportFeature;\n}\n\nexport function ReportScenarioList({ feature }: ReportScenarioListProps) {\n return (\n <>\n {feature.scenarios.map((scenario) => (\n <ReportScenario key={scenario.id} scenario={scenario} />\n ))}\n </>\n );\n}\n","import type { ReportFeature as ReportFeatureT } from \"executable-stories-formatters\";\nimport { ReportScenarioList } from \"./ReportScenarioList\";\nimport { ReportSummaryView } from \"./ReportSummary\";\n\nexport interface ReportFeatureProps {\n feature: ReportFeatureT;\n}\n\nexport function ReportFeature({ feature }: ReportFeatureProps) {\n const titleId = `${feature.id}-title`;\n return (\n <section\n id={feature.id}\n className=\"es-feature\"\n aria-labelledby={titleId}\n >\n <h2 id={titleId} className=\"es-feature-title\">{feature.title}</h2>\n <p className=\"es-feature-source\">{feature.sourceFile}</p>\n <ReportSummaryView summary={feature.summary} className=\"es-feature-summary\" />\n <ReportScenarioList feature={feature} />\n </section>\n );\n}\n","import { useReport } from \"../hooks/useReport\";\nimport { ReportFeature } from \"./ReportFeature\";\n\nexport function ReportFeatureList() {\n const report = useReport();\n return (\n <>\n {report.features.map((feature) => (\n <ReportFeature key={feature.id} feature={feature} />\n ))}\n </>\n );\n}\n","export interface ReportEmptyProps {\n message?: string;\n}\n\nexport function ReportEmpty({ message }: ReportEmptyProps) {\n return (\n <section className=\"es-empty\" aria-live=\"polite\">\n <p>{message ?? \"No scenarios in this report.\"}</p>\n </section>\n );\n}\n","import type { ReportParseError } from \"../result\";\n\nexport interface ReportSchemaErrorProps {\n error: ReportParseError;\n}\n\nexport function ReportSchemaError({ error }: ReportSchemaErrorProps) {\n return (\n <section className=\"es-schema-error\" role=\"alert\" aria-live=\"assertive\">\n <p>\n <strong>Report could not be displayed.</strong>\n </p>\n <p>{error.message}</p>\n {error.code === \"SCHEMA_VERSION_MISMATCH\" ? (\n <p>\n The report bundle is newer than this version of <code>executable-stories-react</code>.\n Upgrade the package, or regenerate the report with an older formatters CLI.\n </p>\n ) : null}\n {error.issues && error.issues.length > 0 ? (\n <details>\n <summary>{error.issues.length} validation issue{error.issues.length === 1 ? \"\" : \"s\"}</summary>\n <pre>\n {error.issues\n .slice(0, 20)\n .map((i) => `${i.path}: ${i.message}`)\n .join(\"\\n\")}\n </pre>\n </details>\n ) : null}\n </section>\n );\n}\n","\"use client\";\n\nimport {\n forwardRef,\n useId,\n type ChangeEvent,\n type KeyboardEvent,\n} from \"react\";\n\nexport interface ReportSearchProps {\n value: string;\n onChange: (next: string) => void;\n matchedCount?: number;\n totalCount?: number;\n placeholder?: string;\n className?: string;\n}\n\nexport const ReportSearch = forwardRef<HTMLInputElement, ReportSearchProps>(\n function ReportSearch(props, ref) {\n const {\n value,\n onChange,\n matchedCount,\n totalCount,\n placeholder = \"Search scenarios, tags, or step text…\",\n className,\n } = props;\n const inputId = useId();\n const showCounts =\n typeof matchedCount === \"number\" && typeof totalCount === \"number\";\n\n function handleChange(e: ChangeEvent<HTMLInputElement>) {\n onChange(e.target.value);\n }\n\n function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {\n if (e.key === \"Escape\" && value !== \"\") {\n onChange(\"\");\n e.preventDefault();\n }\n }\n\n return (\n <div className={[\"es-search\", className].filter(Boolean).join(\" \")}>\n <label htmlFor={inputId} className=\"es-search-label\">\n Search\n </label>\n <input\n ref={ref}\n id={inputId}\n type=\"search\"\n value={value}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n autoComplete=\"off\"\n spellCheck={false}\n aria-keyshortcuts=\"/\"\n />\n {showCounts ? (\n <span className=\"es-search-counts\" aria-live=\"polite\">\n {value\n ? `${matchedCount} of ${totalCount}`\n : `${totalCount} total`}\n </span>\n ) : null}\n </div>\n );\n },\n);\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport type { FailureRef } from \"./filter\";\n\nexport interface ReportFailureBannerProps {\n failures: readonly FailureRef[];\n}\n\nexport function ReportFailureBanner({ failures }: ReportFailureBannerProps) {\n const first = failures[0];\n\n const jumpToFirst = useCallback(() => {\n if (!first) return;\n if (typeof window === \"undefined\") return;\n const el = document.getElementById(first.scenarioId);\n el?.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n if (typeof history !== \"undefined\") {\n history.replaceState(null, \"\", `#${first.scenarioId}`);\n }\n }, [first]);\n\n if (failures.length === 0) return null;\n\n return (\n <aside\n className=\"es-failure-banner\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Failure summary\"\n >\n <span className=\"es-failure-banner-text\">\n <strong>{failures.length}</strong>{\" \"}\n failure{failures.length === 1 ? \"\" : \"s\"}\n </span>\n <button\n type=\"button\"\n className=\"es-failure-banner-jump\"\n onClick={jumpToFirst}\n aria-label=\"Jump to first failure\"\n >\n Jump to first ↓\n </button>\n </aside>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nexport interface ReportShortcutsHelpProps {\n open: boolean;\n onClose: () => void;\n}\n\nconst SHORTCUTS: ReadonlyArray<{ keys: string; description: string }> = [\n { keys: \"/\", description: \"Focus search\" },\n { keys: \"f\", description: \"Jump to next failure\" },\n { keys: \"Shift+F\", description: \"Jump to previous failure\" },\n { keys: \"Esc\", description: \"Clear search / close dialog\" },\n { keys: \"?\", description: \"Toggle this help\" },\n];\n\nexport function ReportShortcutsHelp({ open, onClose }: ReportShortcutsHelpProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n if (open && !dialog.open) dialog.showModal();\n else if (!open && dialog.open) dialog.close();\n }, [open]);\n\n return (\n <dialog\n ref={dialogRef}\n className=\"es-shortcuts-help\"\n aria-label=\"Keyboard shortcuts\"\n onClose={onClose}\n >\n <h2>Keyboard shortcuts</h2>\n <dl>\n {SHORTCUTS.map((s) => (\n <div key={s.keys}>\n <dt>\n <kbd>{s.keys}</kbd>\n </dt>\n <dd>{s.description}</dd>\n </div>\n ))}\n </dl>\n <form method=\"dialog\">\n <button type=\"submit\" className=\"es-shortcuts-close\">Close</button>\n </form>\n </dialog>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nexport interface KeyboardShortcutHandlers {\n onFocusSearch?: () => void;\n onNextFailure?: () => void;\n onPrevFailure?: () => void;\n onToggleHelp?: () => void;\n onEscape?: () => void;\n}\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") return true;\n if (target.isContentEditable) return true;\n return false;\n}\n\n/**\n * Attaches one keydown listener for the lifetime of the component, regardless\n * of how often the consumer passes a fresh handlers object. Handlers are read\n * from a ref so each keypress hits the latest version — see Vercel's\n * advanced-use-latest pattern.\n */\nexport function useKeyboardShortcuts(handlers: KeyboardShortcutHandlers): void {\n const ref = useRef(handlers);\n ref.current = handlers;\n\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent) {\n const h = ref.current;\n if (e.key === \"Escape\") {\n h.onEscape?.();\n return;\n }\n\n if (isEditableTarget(e.target)) return;\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n\n switch (e.key) {\n case \"/\":\n h.onFocusSearch?.();\n e.preventDefault();\n return;\n case \"?\":\n h.onToggleHelp?.();\n e.preventDefault();\n return;\n case \"f\":\n h.onNextFailure?.();\n e.preventDefault();\n return;\n case \"F\":\n h.onPrevFailure?.();\n e.preventDefault();\n return;\n default:\n return;\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, []);\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\n/**\n * Scrolls to a scenario by URL hash on mount and whenever the hash changes.\n * No-op in SSR (only runs in useEffect).\n */\nexport function useDeepLinkScroll(): void {\n useEffect(() => {\n function scrollToHash() {\n const hash = window.location.hash.replace(/^#/, \"\");\n if (!hash) return;\n const el = document.getElementById(hash);\n if (!el) return;\n requestAnimationFrame(() => {\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n });\n }\n scrollToHash();\n window.addEventListener(\"hashchange\", scrollToHash);\n return () => window.removeEventListener(\"hashchange\", scrollToHash);\n }, []);\n}\n","/**\n * Pure functions for filtering a StoryReport by a search query.\n * Used by <ReportInteractive>. Kept side-effect-free so it can be unit-tested.\n */\n\nimport type {\n ReportScenario,\n ReportFeature,\n StoryReport,\n} from \"executable-stories-formatters\";\n\nexport function normalizeQuery(query: string): string {\n return query.trim().toLowerCase();\n}\n\nfunction scenarioMatches(scenario: ReportScenario, q: string): boolean {\n if (q === \"\") return true;\n if (scenario.title.toLowerCase().includes(q)) return true;\n for (const tag of scenario.tags) {\n if (tag.toLowerCase().includes(q)) return true;\n }\n for (const step of scenario.steps) {\n if (step.text.toLowerCase().includes(q)) return true;\n }\n return false;\n}\n\nfunction summarizeScenarios(scenarios: ReportScenario[]) {\n let total = 0,\n passed = 0,\n failed = 0,\n skipped = 0,\n pending = 0,\n durationMs = 0;\n for (const s of scenarios) {\n total += 1;\n durationMs += s.durationMs;\n if (s.status === \"passed\") passed += 1;\n else if (s.status === \"failed\") failed += 1;\n else if (s.status === \"skipped\") skipped += 1;\n else pending += 1;\n }\n return { total, passed, failed, skipped, pending, durationMs };\n}\n\nexport function filterReport(report: StoryReport, query: string): StoryReport {\n const q = normalizeQuery(query);\n if (q === \"\") return report;\n\n const features: ReportFeature[] = [];\n let topTotal = 0,\n topPassed = 0,\n topFailed = 0,\n topSkipped = 0,\n topPending = 0,\n topDuration = 0;\n\n for (const feature of report.features) {\n const matched = feature.scenarios.filter((s) => scenarioMatches(s, q));\n if (matched.length === 0) continue;\n const summary = summarizeScenarios(matched);\n features.push({ ...feature, summary, scenarios: matched });\n topTotal += summary.total;\n topPassed += summary.passed;\n topFailed += summary.failed;\n topSkipped += summary.skipped;\n topPending += summary.pending;\n topDuration += summary.durationMs;\n }\n\n return {\n ...report,\n summary: {\n total: topTotal,\n passed: topPassed,\n failed: topFailed,\n skipped: topSkipped,\n pending: topPending,\n durationMs: topDuration,\n },\n features,\n };\n}\n\nexport interface FailureRef {\n featureId: string;\n scenarioId: string;\n scenarioTitle: string;\n errorMessage?: string;\n}\n\nexport function listFailures(report: StoryReport): FailureRef[] {\n const out: FailureRef[] = [];\n for (const feature of report.features) {\n for (const scenario of feature.scenarios) {\n if (scenario.status === \"failed\") {\n const ref: FailureRef = {\n featureId: feature.id,\n scenarioId: scenario.id,\n scenarioTitle: scenario.title,\n };\n if (scenario.errorMessage !== undefined) {\n ref.errorMessage = scenario.errorMessage;\n }\n out.push(ref);\n }\n }\n }\n return out;\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","EMPTY_CUSTOM","EMPTY_RENDERERS","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","ReportSearch","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime"]}
@@ -0,0 +1,116 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReportDocCustom, ReportDocMermaid, ReportDocCode, ReportDocSection, StoryReport } from 'executable-stories-formatters';
3
+ import * as react from 'react';
4
+ import { ReactNode } from 'react';
5
+
6
+ /**
7
+ * Result<T> — explicit success/error type matching the cookbook convention.
8
+ *
9
+ * Used at the boundary where a StoryReport is parsed: the consumer hands us
10
+ * an unknown value (file contents, fetch body, prop) and we return a Result.
11
+ */
12
+ type Result<T, E = ReportParseError> = {
13
+ ok: true;
14
+ data: T;
15
+ } | {
16
+ ok: false;
17
+ error: E;
18
+ };
19
+ interface ReportParseError {
20
+ message: string;
21
+ code: ReportParseErrorCode;
22
+ issues?: readonly {
23
+ path: string;
24
+ message: string;
25
+ }[];
26
+ }
27
+ type ReportParseErrorCode = "INVALID_INPUT" | "SCHEMA_VERSION_MISMATCH" | "VALIDATION_FAILED";
28
+
29
+ /**
30
+ * Renderer registries — extension points for custom rendering of doc entries.
31
+ *
32
+ * - customRenderers: keyed by user-defined `story.custom({ type })` strings.
33
+ * - renderers: optional overrides for the three heavy built-ins
34
+ * (mermaid, code, section). Other doc kinds are not overridable — drop
35
+ * to primitives if you need a fully custom layout.
36
+ */
37
+
38
+ type CustomRenderer = (entry: ReportDocCustom) => ReactNode;
39
+ type CustomRenderers = Record<string, CustomRenderer>;
40
+ interface BuiltinRenderers {
41
+ mermaid?: (entry: ReportDocMermaid) => ReactNode;
42
+ code?: (entry: ReportDocCode) => ReactNode;
43
+ section?: (entry: ReportDocSection) => ReactNode;
44
+ }
45
+
46
+ interface ReportInteractiveProps {
47
+ /** A StoryReport, or a Result-wrapped one (e.g., from parseStoryReport). */
48
+ report: StoryReport | Result<StoryReport>;
49
+ /** Renderers keyed by `story.custom({ type })` strings. */
50
+ customRenderers?: CustomRenderers;
51
+ /** Optional overrides for the heavy built-ins (mermaid, code, section). */
52
+ renderers?: BuiltinRenderers;
53
+ className?: string;
54
+ title?: string;
55
+ dataTheme?: "light" | "dark";
56
+ }
57
+ declare function ReportInteractive(props: ReportInteractiveProps): react_jsx_runtime.JSX.Element;
58
+
59
+ interface ReportSearchProps {
60
+ value: string;
61
+ onChange: (next: string) => void;
62
+ matchedCount?: number;
63
+ totalCount?: number;
64
+ placeholder?: string;
65
+ className?: string;
66
+ }
67
+ declare const ReportSearch: react.ForwardRefExoticComponent<ReportSearchProps & react.RefAttributes<HTMLInputElement>>;
68
+
69
+ /**
70
+ * Pure functions for filtering a StoryReport by a search query.
71
+ * Used by <ReportInteractive>. Kept side-effect-free so it can be unit-tested.
72
+ */
73
+
74
+ declare function normalizeQuery(query: string): string;
75
+ declare function filterReport(report: StoryReport, query: string): StoryReport;
76
+ interface FailureRef {
77
+ featureId: string;
78
+ scenarioId: string;
79
+ scenarioTitle: string;
80
+ errorMessage?: string;
81
+ }
82
+ declare function listFailures(report: StoryReport): FailureRef[];
83
+
84
+ interface ReportFailureBannerProps {
85
+ failures: readonly FailureRef[];
86
+ }
87
+ declare function ReportFailureBanner({ failures }: ReportFailureBannerProps): react_jsx_runtime.JSX.Element | null;
88
+
89
+ interface ReportShortcutsHelpProps {
90
+ open: boolean;
91
+ onClose: () => void;
92
+ }
93
+ declare function ReportShortcutsHelp({ open, onClose }: ReportShortcutsHelpProps): react_jsx_runtime.JSX.Element;
94
+
95
+ interface KeyboardShortcutHandlers {
96
+ onFocusSearch?: () => void;
97
+ onNextFailure?: () => void;
98
+ onPrevFailure?: () => void;
99
+ onToggleHelp?: () => void;
100
+ onEscape?: () => void;
101
+ }
102
+ /**
103
+ * Attaches one keydown listener for the lifetime of the component, regardless
104
+ * of how often the consumer passes a fresh handlers object. Handlers are read
105
+ * from a ref so each keypress hits the latest version — see Vercel's
106
+ * advanced-use-latest pattern.
107
+ */
108
+ declare function useKeyboardShortcuts(handlers: KeyboardShortcutHandlers): void;
109
+
110
+ /**
111
+ * Scrolls to a scenario by URL hash on mount and whenever the hash changes.
112
+ * No-op in SSR (only runs in useEffect).
113
+ */
114
+ declare function useDeepLinkScroll(): void;
115
+
116
+ export { type FailureRef, type KeyboardShortcutHandlers, ReportFailureBanner, type ReportFailureBannerProps, ReportInteractive, type ReportInteractiveProps, ReportSearch, type ReportSearchProps, ReportShortcutsHelp, type ReportShortcutsHelpProps, filterReport, listFailures, normalizeQuery, useDeepLinkScroll, useKeyboardShortcuts };
@@ -0,0 +1,116 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReportDocCustom, ReportDocMermaid, ReportDocCode, ReportDocSection, StoryReport } from 'executable-stories-formatters';
3
+ import * as react from 'react';
4
+ import { ReactNode } from 'react';
5
+
6
+ /**
7
+ * Result<T> — explicit success/error type matching the cookbook convention.
8
+ *
9
+ * Used at the boundary where a StoryReport is parsed: the consumer hands us
10
+ * an unknown value (file contents, fetch body, prop) and we return a Result.
11
+ */
12
+ type Result<T, E = ReportParseError> = {
13
+ ok: true;
14
+ data: T;
15
+ } | {
16
+ ok: false;
17
+ error: E;
18
+ };
19
+ interface ReportParseError {
20
+ message: string;
21
+ code: ReportParseErrorCode;
22
+ issues?: readonly {
23
+ path: string;
24
+ message: string;
25
+ }[];
26
+ }
27
+ type ReportParseErrorCode = "INVALID_INPUT" | "SCHEMA_VERSION_MISMATCH" | "VALIDATION_FAILED";
28
+
29
+ /**
30
+ * Renderer registries — extension points for custom rendering of doc entries.
31
+ *
32
+ * - customRenderers: keyed by user-defined `story.custom({ type })` strings.
33
+ * - renderers: optional overrides for the three heavy built-ins
34
+ * (mermaid, code, section). Other doc kinds are not overridable — drop
35
+ * to primitives if you need a fully custom layout.
36
+ */
37
+
38
+ type CustomRenderer = (entry: ReportDocCustom) => ReactNode;
39
+ type CustomRenderers = Record<string, CustomRenderer>;
40
+ interface BuiltinRenderers {
41
+ mermaid?: (entry: ReportDocMermaid) => ReactNode;
42
+ code?: (entry: ReportDocCode) => ReactNode;
43
+ section?: (entry: ReportDocSection) => ReactNode;
44
+ }
45
+
46
+ interface ReportInteractiveProps {
47
+ /** A StoryReport, or a Result-wrapped one (e.g., from parseStoryReport). */
48
+ report: StoryReport | Result<StoryReport>;
49
+ /** Renderers keyed by `story.custom({ type })` strings. */
50
+ customRenderers?: CustomRenderers;
51
+ /** Optional overrides for the heavy built-ins (mermaid, code, section). */
52
+ renderers?: BuiltinRenderers;
53
+ className?: string;
54
+ title?: string;
55
+ dataTheme?: "light" | "dark";
56
+ }
57
+ declare function ReportInteractive(props: ReportInteractiveProps): react_jsx_runtime.JSX.Element;
58
+
59
+ interface ReportSearchProps {
60
+ value: string;
61
+ onChange: (next: string) => void;
62
+ matchedCount?: number;
63
+ totalCount?: number;
64
+ placeholder?: string;
65
+ className?: string;
66
+ }
67
+ declare const ReportSearch: react.ForwardRefExoticComponent<ReportSearchProps & react.RefAttributes<HTMLInputElement>>;
68
+
69
+ /**
70
+ * Pure functions for filtering a StoryReport by a search query.
71
+ * Used by <ReportInteractive>. Kept side-effect-free so it can be unit-tested.
72
+ */
73
+
74
+ declare function normalizeQuery(query: string): string;
75
+ declare function filterReport(report: StoryReport, query: string): StoryReport;
76
+ interface FailureRef {
77
+ featureId: string;
78
+ scenarioId: string;
79
+ scenarioTitle: string;
80
+ errorMessage?: string;
81
+ }
82
+ declare function listFailures(report: StoryReport): FailureRef[];
83
+
84
+ interface ReportFailureBannerProps {
85
+ failures: readonly FailureRef[];
86
+ }
87
+ declare function ReportFailureBanner({ failures }: ReportFailureBannerProps): react_jsx_runtime.JSX.Element | null;
88
+
89
+ interface ReportShortcutsHelpProps {
90
+ open: boolean;
91
+ onClose: () => void;
92
+ }
93
+ declare function ReportShortcutsHelp({ open, onClose }: ReportShortcutsHelpProps): react_jsx_runtime.JSX.Element;
94
+
95
+ interface KeyboardShortcutHandlers {
96
+ onFocusSearch?: () => void;
97
+ onNextFailure?: () => void;
98
+ onPrevFailure?: () => void;
99
+ onToggleHelp?: () => void;
100
+ onEscape?: () => void;
101
+ }
102
+ /**
103
+ * Attaches one keydown listener for the lifetime of the component, regardless
104
+ * of how often the consumer passes a fresh handlers object. Handlers are read
105
+ * from a ref so each keypress hits the latest version — see Vercel's
106
+ * advanced-use-latest pattern.
107
+ */
108
+ declare function useKeyboardShortcuts(handlers: KeyboardShortcutHandlers): void;
109
+
110
+ /**
111
+ * Scrolls to a scenario by URL hash on mount and whenever the hash changes.
112
+ * No-op in SSR (only runs in useEffect).
113
+ */
114
+ declare function useDeepLinkScroll(): void;
115
+
116
+ export { type FailureRef, type KeyboardShortcutHandlers, ReportFailureBanner, type ReportFailureBannerProps, ReportInteractive, type ReportInteractiveProps, ReportSearch, type ReportSearchProps, ReportShortcutsHelp, type ReportShortcutsHelpProps, filterReport, listFailures, normalizeQuery, useDeepLinkScroll, useKeyboardShortcuts };