@lofcz/streamdown 2.9.0 → 2.9.2
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/chunk-NE4QKYRI.js +29 -0
- package/dist/highlighted-body-5PIGDDHF.js +2 -0
- package/dist/hooks/use-deferred-render.d.ts +57 -0
- package/dist/index.d.ts +53 -498
- package/dist/index.js +1 -1
- package/dist/lib/animate.d.ts +66 -0
- package/dist/lib/block-incomplete-context.d.ts +14 -0
- package/dist/lib/code-block/body.d.ts +12 -0
- package/dist/lib/code-block/container.d.ts +8 -0
- package/dist/lib/code-block/context.d.ts +6 -0
- package/dist/lib/code-block/copy-button.d.ts +9 -0
- package/dist/lib/code-block/download-button.d.ts +9 -0
- package/dist/lib/code-block/header.d.ts +5 -0
- package/dist/lib/code-block/highlighted-body.d.ts +12 -0
- package/dist/lib/code-block/index.d.ts +13 -0
- package/dist/lib/code-block/skeleton.d.ts +1 -0
- package/dist/lib/components.d.ts +2 -0
- package/dist/lib/detect-direction.d.ts +13 -0
- package/dist/lib/icon-context.d.ts +23 -0
- package/dist/lib/icons.d.ts +14 -0
- package/dist/lib/image.d.ts +5 -0
- package/dist/lib/incomplete-code-utils.d.ts +24 -0
- package/dist/lib/link-modal.d.ts +8 -0
- package/dist/lib/markdown.d.ts +30 -0
- package/dist/lib/mermaid/download-button.d.ts +11 -0
- package/dist/lib/mermaid/fullscreen-button.d.ts +10 -0
- package/dist/lib/mermaid/index.d.ts +10 -0
- package/dist/lib/mermaid/pan-zoom.d.ts +19 -0
- package/dist/lib/mermaid/utils.d.ts +41 -0
- package/dist/lib/parse-blocks.d.ts +12 -0
- package/dist/lib/plugin-context.d.ts +29 -0
- package/dist/lib/plugin-types.d.ts +156 -0
- package/dist/lib/prefix-context.d.ts +12 -0
- package/dist/lib/preprocess-custom-tags.d.ts +19 -0
- package/dist/lib/preprocess-literal-tag-content.d.ts +24 -0
- package/dist/lib/rehype/literal-tag-content.d.ts +12 -0
- package/dist/lib/rehype/markdown-in-custom-tags.d.ts +16 -0
- package/dist/lib/remark/code-meta.d.ts +9 -0
- package/dist/lib/remark/container-alerts.d.ts +60 -0
- package/dist/lib/remark/escape-html.d.ts +3 -0
- package/dist/lib/remark/github-alerts.d.ts +16 -0
- package/dist/lib/scroll-lock.d.ts +2 -0
- package/dist/lib/scrollable.d.ts +7 -0
- package/dist/lib/streamdown-context.d.ts +107 -0
- package/dist/lib/table/copy-dropdown.d.ts +8 -0
- package/dist/lib/table/download-dropdown.d.ts +16 -0
- package/dist/lib/table/fullscreen-button.d.ts +8 -0
- package/dist/lib/table/index.d.ts +10 -0
- package/dist/lib/table/utils.d.ts +9 -0
- package/dist/lib/tailwind-classes.d.ts +2 -4
- package/dist/lib/tailwind-classes.js +1 -1
- package/dist/lib/translations-context.d.ts +39 -0
- package/dist/lib/utils.d.ts +23 -0
- package/dist/mermaid-L7RAWDBU.js +2 -0
- package/package.json +9 -6
- package/styles.css +28 -0
- package/dist/chunk-TA335CDR.js +0 -27
- package/dist/highlighted-body-7HCBLPPD.js +0 -2
- package/dist/mermaid-36ZAAFZN.js +0 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Root } from "mdast";
|
|
2
|
+
import type { Plugin } from "unified";
|
|
3
|
+
/**
|
|
4
|
+
* Custom container alerts / callouts:
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* >>> [My Section]{red}
|
|
8
|
+
* body markdown
|
|
9
|
+
* <<<
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* Variants:
|
|
13
|
+
* - `>>> [Title]` — no color (neutral tint)
|
|
14
|
+
* - `>>> (heart)[Title]{red}` — optional icon before the title
|
|
15
|
+
* - `>>> {heart}[Title]{red}` — wrong-brace icon, tolerated
|
|
16
|
+
* - color may be a named color (`red`) or hex (`#FF0000`)
|
|
17
|
+
*
|
|
18
|
+
* Graceful degradation (critical for streaming): a missing or malformed
|
|
19
|
+
* closer (`>>>`, `>`, `<`, or end-of-input) still renders the callout with
|
|
20
|
+
* whatever content is present, never crashes, and never swallows the
|
|
21
|
+
* leftover marker line.
|
|
22
|
+
*
|
|
23
|
+
* Implementation note: `>>>` is not standard markdown. CommonMark lexes it
|
|
24
|
+
* as three nested blockquotes whose content lazily continues plain text but
|
|
25
|
+
* breaks at lists, blank lines, and inline-markdown splits — so a post-
|
|
26
|
+
* parse AST collapse cannot reliably recover the whole container body.
|
|
27
|
+
* Instead, {@link extractCallouts} scans the raw source **before** markdown
|
|
28
|
+
* parsing (the Streamdown component runs it on the raw text before the
|
|
29
|
+
* streaming block-splitter): it extracts each `>>> ... <<<` region and
|
|
30
|
+
* replaces it with a placeholder HTML node that carries the body verbatim
|
|
31
|
+
* (base64) in `data-callout-body`. The React component (MemoCallout) decodes
|
|
32
|
+
* and re-parses that body as markdown, so nested markdown/lists/math render
|
|
33
|
+
* correctly and streaming partial input works.
|
|
34
|
+
*/
|
|
35
|
+
export interface CalloutData {
|
|
36
|
+
/** Raw markdown body (never includes the opener/closer lines). */
|
|
37
|
+
body: string;
|
|
38
|
+
color?: string;
|
|
39
|
+
icon?: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract `>>> ... <<<` regions from the raw markdown source, replacing each
|
|
44
|
+
* with a placeholder HTML node. Exported so the streaming pipeline can run it
|
|
45
|
+
* on the raw source *before* the marked block-splitter (which would otherwise
|
|
46
|
+
* split a container at a list/blank line and truncate the body).
|
|
47
|
+
*/
|
|
48
|
+
export declare const extractCallouts: (source: string) => string;
|
|
49
|
+
/**
|
|
50
|
+
* Remark plugin for custom container alerts (`>>> [Title]{color} ... <<<`).
|
|
51
|
+
*
|
|
52
|
+
* The actual extraction is done by {@link extractCallouts}, which the
|
|
53
|
+
* Streamdown component runs on the raw source before the streaming
|
|
54
|
+
* block-splitter (and the same path feeds static mode). This transformer is
|
|
55
|
+
* registered so the plugin appears in `defaultRemarkPlugins` (and so a
|
|
56
|
+
* consumer using only the remark plugin list still has the extraction
|
|
57
|
+
* applied); it is a no-op on the already-parsed tree because the placeholder
|
|
58
|
+
* `<div class="sdm-callout">` parses as an ordinary HTML block.
|
|
59
|
+
*/
|
|
60
|
+
export declare const remarkContainerAlerts: Plugin<[], Root>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Root } from "mdast";
|
|
2
|
+
import type { Plugin } from "unified";
|
|
3
|
+
export type AlertKind = "note" | "tip" | "important" | "warning" | "caution";
|
|
4
|
+
/**
|
|
5
|
+
* Remark plugin for GitHub-flavored alerts (`> [!NOTE]`, `> [!TIP]`,
|
|
6
|
+
* `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]`), aligned with
|
|
7
|
+
* `rehype-github-alerts` / GitHub rendering semantics:
|
|
8
|
+
*
|
|
9
|
+
* - Marker must be alone on the blockquote's first line; any same-line text
|
|
10
|
+
* after `[!TYPE]` renders as a plain blockquote.
|
|
11
|
+
* - Output is `<div class="markdown-alert markdown-alert-{kind}">` with a
|
|
12
|
+
* `<p class="markdown-alert-title">` (octicon + capitalized title) followed
|
|
13
|
+
* by the body content.
|
|
14
|
+
* - An alert with no body stays a plain blockquote (GitHub behavior).
|
|
15
|
+
*/
|
|
16
|
+
export declare const remarkGithubAlerts: Plugin<[], Root>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScrollableProps } from "./streamdown-context";
|
|
2
|
+
/**
|
|
3
|
+
* Default horizontal-scroll region: a plain `<div>`. Consumers can override
|
|
4
|
+
* via the `scrollable` prop / `StreamdownContext.scrollable` to plug in a
|
|
5
|
+
* custom scrollbar implementation declaratively.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DefaultScrollable: ({ scrollRef, ...props }: ScrollableProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type ComponentProps, type ComponentType, type CSSProperties } from "react";
|
|
2
|
+
import type { PluggableList } from "unified";
|
|
3
|
+
import type { Components } from "./markdown";
|
|
4
|
+
import type { MermaidConfig, ThemeInput } from "./plugin-types";
|
|
5
|
+
export type ControlsConfig = boolean | {
|
|
6
|
+
table?: boolean | {
|
|
7
|
+
copy?: boolean;
|
|
8
|
+
download?: boolean;
|
|
9
|
+
fullscreen?: boolean;
|
|
10
|
+
};
|
|
11
|
+
code?: boolean | {
|
|
12
|
+
copy?: boolean;
|
|
13
|
+
download?: boolean;
|
|
14
|
+
};
|
|
15
|
+
mermaid?: boolean | {
|
|
16
|
+
download?: boolean;
|
|
17
|
+
copy?: boolean;
|
|
18
|
+
fullscreen?: boolean;
|
|
19
|
+
panZoom?: boolean;
|
|
20
|
+
};
|
|
21
|
+
image?: boolean | {
|
|
22
|
+
download?: boolean;
|
|
23
|
+
fullscreen?: boolean;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export interface LinkSafetyModalProps {
|
|
27
|
+
isOpen: boolean;
|
|
28
|
+
onClose: () => void;
|
|
29
|
+
onConfirm: () => void;
|
|
30
|
+
url: string;
|
|
31
|
+
}
|
|
32
|
+
export interface LinkSafetyConfig {
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
onLinkCheck?: (url: string) => Promise<boolean> | boolean;
|
|
35
|
+
renderModal?: (props: LinkSafetyModalProps) => React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
export interface MermaidErrorComponentProps {
|
|
38
|
+
chart: string;
|
|
39
|
+
error: string;
|
|
40
|
+
retry: () => void;
|
|
41
|
+
}
|
|
42
|
+
export interface MermaidOptions {
|
|
43
|
+
config?: MermaidConfig;
|
|
44
|
+
errorComponent?: React.ComponentType<MermaidErrorComponentProps>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Built-in list bullet style presets for nested unordered lists.
|
|
48
|
+
* - `"flat"` — all levels use disc
|
|
49
|
+
* - `"hierarchical"` — disc → circle → square, cycling
|
|
50
|
+
*/
|
|
51
|
+
export type ListStylePreset = "flat" | "hierarchical";
|
|
52
|
+
/**
|
|
53
|
+
* Resolves a custom-callout icon name (`>>> (heart)[Title]`) to a node.
|
|
54
|
+
* Consumer supplies e.g. lucide's DynamicIcon; return `null`/`undefined`
|
|
55
|
+
* for a blank placeholder while the icon chunk loads.
|
|
56
|
+
*/
|
|
57
|
+
export type CalloutIconResolver = (name: string) => React.ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Computes the inline style (background tint + accent border/title color)
|
|
60
|
+
* for a custom callout from its optional `{color}` value. Default is a
|
|
61
|
+
* neutral `color-mix()` tint (see components.tsx).
|
|
62
|
+
*/
|
|
63
|
+
export type CalloutStyleResolver = (color?: string) => CSSProperties;
|
|
64
|
+
/**
|
|
65
|
+
* Props passed to the component used for a horizontal-scroll region
|
|
66
|
+
* (code-block body, table inner scroll). `scrollRef` must be attached to the
|
|
67
|
+
* actual scrolling element so Streamdown's auto-pin-on-stream logic keeps
|
|
68
|
+
* working.
|
|
69
|
+
*/
|
|
70
|
+
export type ScrollableProps = ComponentProps<"div"> & {
|
|
71
|
+
scrollRef?: React.Ref<HTMLDivElement>;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Component used to render a horizontal-scroll region (code-block body,
|
|
75
|
+
* table inner scroll). Defaults to a plain `<div>`; override to plug in a
|
|
76
|
+
* custom scrollbar implementation (e.g. OverlayScrollbars) declaratively,
|
|
77
|
+
* without DOM observers or per-element wiring.
|
|
78
|
+
*/
|
|
79
|
+
export type ScrollableComponent = ComponentType<ScrollableProps>;
|
|
80
|
+
export interface StreamdownContextType {
|
|
81
|
+
/** Icon resolver for custom callouts (`>>> (icon)[Title]{color}`). */
|
|
82
|
+
calloutIcon?: CalloutIconResolver;
|
|
83
|
+
/** Style resolver for custom callouts (background tint + accent). */
|
|
84
|
+
calloutStyle?: CalloutStyleResolver;
|
|
85
|
+
/** Max height for code blocks (px number or CSS length). `0` / `Infinity` disables. @default 400 */
|
|
86
|
+
codeBlockMaxHeight?: number | string;
|
|
87
|
+
/** Merged components/plugins so custom renderers (e.g. callout body) can re-parse nested markdown identically to the outer pass. */
|
|
88
|
+
components?: Components;
|
|
89
|
+
controls: ControlsConfig;
|
|
90
|
+
isAnimating: boolean;
|
|
91
|
+
/** Show line numbers in code blocks. @default true */
|
|
92
|
+
lineNumbers: boolean;
|
|
93
|
+
linkSafety?: LinkSafetyConfig;
|
|
94
|
+
/** Bullet style cycling for nested unordered lists. @default "hierarchical" */
|
|
95
|
+
listStyle: ListStylePreset;
|
|
96
|
+
mermaid?: MermaidOptions;
|
|
97
|
+
mode: "static" | "streaming";
|
|
98
|
+
rehypePlugins?: PluggableList;
|
|
99
|
+
remarkPlugins?: PluggableList;
|
|
100
|
+
/** Component used for horizontal-scroll regions (code body, table). @default plain div */
|
|
101
|
+
scrollable?: ScrollableComponent;
|
|
102
|
+
shikiTheme: [ThemeInput, ThemeInput];
|
|
103
|
+
/** Max height for tables (px number or CSS length). `0` / `Infinity` disables. @default 300 */
|
|
104
|
+
tableMaxHeight?: number | string;
|
|
105
|
+
}
|
|
106
|
+
export declare const defaultStreamdownContext: StreamdownContextType;
|
|
107
|
+
export declare const StreamdownContext: import("react").Context<StreamdownContextType>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface TableCopyDropdownProps {
|
|
2
|
+
children?: React.ReactNode;
|
|
3
|
+
className?: string;
|
|
4
|
+
onCopy?: (format: "csv" | "tsv" | "md") => void;
|
|
5
|
+
onError?: (error: Error) => void;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const TableCopyDropdown: ({ children, className, onCopy, onError, timeout, }: TableCopyDropdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface TableDownloadButtonProps {
|
|
2
|
+
children?: React.ReactNode;
|
|
3
|
+
className?: string;
|
|
4
|
+
filename?: string;
|
|
5
|
+
format?: "csv" | "markdown";
|
|
6
|
+
onDownload?: () => void;
|
|
7
|
+
onError?: (error: Error) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const TableDownloadButton: ({ children, className, onDownload, onError, format, filename, }: TableDownloadButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export interface TableDownloadDropdownProps {
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
onDownload?: (format: "csv" | "markdown") => void;
|
|
14
|
+
onError?: (error: Error) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare const TableDownloadDropdown: ({ children, className, onDownload, onError, }: TableDownloadDropdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface TableFullscreenButtonProps {
|
|
2
|
+
children: React.ReactNode;
|
|
3
|
+
className?: string;
|
|
4
|
+
showCopy?: boolean;
|
|
5
|
+
showDownload?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const TableFullscreenButton: ({ children, className, showCopy, showDownload, }: TableFullscreenButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
|
+
type TableProps = ComponentProps<"table"> & {
|
|
3
|
+
maxHeight?: number | string;
|
|
4
|
+
showControls?: boolean;
|
|
5
|
+
showCopy?: boolean;
|
|
6
|
+
showDownload?: boolean;
|
|
7
|
+
showFullscreen?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const Table: ({ children, className, maxHeight, showControls, showCopy, showDownload, showFullscreen, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface TableData {
|
|
2
|
+
headers: string[];
|
|
3
|
+
rows: string[][];
|
|
4
|
+
}
|
|
5
|
+
export declare const extractTableDataFromElement: (tableElement: HTMLElement) => TableData;
|
|
6
|
+
export declare const tableDataToCSV: (data: TableData) => string;
|
|
7
|
+
export declare const tableDataToTSV: (data: TableData) => string;
|
|
8
|
+
export declare const escapeMarkdownTableCell: (cell: string) => string;
|
|
9
|
+
export declare const tableDataToMarkdown: (data: TableData) => string;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Use this list to configure Tailwind v4's `@source inline()` directive when
|
|
7
7
|
* you need a custom prefix. See the README for details.
|
|
8
8
|
*/
|
|
9
|
-
declare const STREAMDOWN_CLASSES: readonly string[];
|
|
9
|
+
export declare const STREAMDOWN_CLASSES: readonly string[];
|
|
10
10
|
/**
|
|
11
11
|
* Generates a Tailwind v4 `@source inline()` directive containing all
|
|
12
12
|
* streamdown classes, optionally prefixed.
|
|
@@ -21,6 +21,4 @@ declare const STREAMDOWN_CLASSES: readonly string[];
|
|
|
21
21
|
* console.log(getSourceInline('tw'));
|
|
22
22
|
* // → @source inline("tw:{absolute,animate-spin,...}");
|
|
23
23
|
*/
|
|
24
|
-
declare function getSourceInline(prefix?: string): string;
|
|
25
|
-
|
|
26
|
-
export { STREAMDOWN_CLASSES, getSourceInline };
|
|
24
|
+
export declare function getSourceInline(prefix?: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=["-mt-10","[&>p]:inline","[&_svg]:h-auto","[&_svg]:w-auto","[counter-increment:line_0]","[counter-reset:line]","[li_&]:pl-6","absolute","animate-spin","appearance-none","backdrop-blur-sm","before:[counter-increment:line]","before:content-[counter(line)]","before:font-mono","before:inline-block","before:mr-4","before:select-none","before:text-[13px]","before:text-muted-foreground/50","before:text-right","before:w-6","bg-[var(--sdm-bg,inherit]","bg-[var(--sdm-tbg)]","bg-background","bg-background/50","bg-background/80","bg-background/90","bg-background/95","bg-black/10","bg-muted","bg-muted/40","bg-muted/80","bg-primary","bg-red-100","bg-red-50","bg-sidebar","bg-sidebar/80","block","border","border-b","border-b-2","border-border","border-collapse","border-current","border-l-4","border-muted-foreground/30","border-red-200","border-sidebar","border-t","bottom-2","bottom-4","break-all","cursor-pointer","dark:bg-[var(--shiki-dark-bg,var(--sdm-bg,inherit)]","dark:bg-[var(--shiki-dark-bg,var(--sdm-tbg))]","dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]","disabled:cursor-not-allowed","disabled:opacity-50","divide-border","divide-y","duration-150","duration-200","ease-out","fixed","flex","flex-1","flex-col","font-medium","font-mono","font-semibold","gap-1","gap-2","gap-4","group","group-hover:block","group-hover:opacity-100","h-4","h-8","h-[46px]","h-auto","h-full","hidden","hover:bg-background","hover:bg-muted","hover:bg-muted/40","hover:bg-primary/90","hover:text-foreground","inline-block","inset-0","italic","items-center","justify-between","justify-center","justify-end","left-2","left-4","list-decimal","list-disc","list-inside","lowercase","max-h-32","max-w-full","max-w-md","mb-2","min-h-28","min-h-[200px]","min-w-[120px]","ml-1","mt-1","mt-2","mt-6","mx-4","my-4","my-6","opacity-0","origin-center","overflow-hidden","overflow-x-auto","overflow-y-auto","overscroll-y-auto","p-1","p-1.5","p-2","p-3","p-4","p-6","pl-4","pointer-events-auto","pointer-events-none","px-1.5","px-3","px-4","py-0.5","py-1","py-2","relative","right-0","right-2","right-4","rounded","rounded-full","rounded-lg","rounded-md","rounded-xl","shadow-lg","shadow-sm","shrink-0","size-4","size-full","space-x-2","space-y-2","space-y-4","sticky","table-fixed","supports-[backdrop-filter]:backdrop-blur","supports-[backdrop-filter]:backdrop-blur-sm","supports-[backdrop-filter]:bg-background/70","supports-[backdrop-filter]:bg-sidebar/70","text-2xl","text-3xl","text-[var(--sdm-c,inherit)]","text-base","text-left","text-lg","text-muted-foreground","text-primary","text-primary-foreground","text-red-600","text-red-700","text-red-800","text-sm","text-xl","text-xs","top-2","top-4","top-full","transition-all","transition-colors","transition-transform","w-4","w-8","w-full","whitespace-normal","whitespace-nowrap","wrap-anywhere","z-10","z-50"];function n(e){let r=[...t];return `@source inline("${e?`${e}:{${r.join(",")}}`:`{${r.join(",")}}`}");`}export{t as STREAMDOWN_CLASSES,n as getSourceInline};
|
|
1
|
+
var t=["-mt-10","[&>p]:inline","[&>p:last-child]:mb-0","[&>svg]:inline-block","[&_svg]:h-auto","[&_svg]:w-auto","[counter-increment:line_0]","[counter-reset:line]","[li_&]:pl-6","absolute","animate-spin","appearance-none","backdrop-blur-sm","before:[counter-increment:line]","before:content-[counter(line)]","before:font-mono","before:inline-block","before:mr-4","before:select-none","before:text-[13px]","before:text-muted-foreground/50","before:text-right","before:w-6","bg-[var(--sdm-bg,inherit]","bg-[var(--sdm-tbg)]","bg-background","bg-background/50","bg-background/80","bg-background/90","bg-background/95","bg-black/10","bg-muted","bg-muted/40","bg-muted/80","bg-primary","bg-red-100","bg-red-50","bg-sidebar","bg-sidebar/80","block","border","border-b","border-b-2","border-border","border-collapse","border-current","border-l-4","border-muted-foreground/30","border-red-200","border-sidebar","border-t","bottom-2","bottom-4","break-all","cursor-pointer","dark:bg-[var(--shiki-dark-bg,var(--sdm-bg,inherit)]","dark:bg-[var(--shiki-dark-bg,var(--sdm-tbg))]","dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]","disabled:cursor-not-allowed","disabled:opacity-50","divide-border","divide-y","duration-150","duration-200","ease-out","fixed","flex","flex-1","flex-col","font-medium","font-mono","font-semibold","gap-1","gap-2","gap-4","group","group-hover:block","group-hover:opacity-100","h-4","h-8","h-[46px]","h-auto","h-full","hidden","hover:bg-background","hover:bg-muted","hover:bg-muted/40","hover:bg-primary/90","hover:text-foreground","inline-block","inset-0","italic","items-center","justify-between","justify-center","justify-end","left-2","left-4","list-decimal","list-disc","list-inside","lowercase","max-h-32","max-w-full","max-w-md","mb-2","min-h-28","min-h-[200px]","min-w-[120px]","ml-1","mt-1","mt-2","mt-6","mx-4","my-4","my-6","opacity-0","origin-center","overflow-hidden","overflow-x-auto","overflow-y-auto","overscroll-y-auto","p-1","p-1.5","p-2","p-3","p-4","p-6","pl-4","pointer-events-auto","pointer-events-none","px-1.5","px-3","px-4","py-0.5","py-1","py-2","relative","right-0","right-2","right-4","rounded","rounded-full","rounded-lg","rounded-md","rounded-r-md","rounded-xl","shadow-lg","shadow-sm","shrink-0","size-4","size-full","space-x-2","space-y-2","space-y-4","sticky","table-fixed","supports-[backdrop-filter]:backdrop-blur","supports-[backdrop-filter]:backdrop-blur-sm","supports-[backdrop-filter]:bg-background/70","supports-[backdrop-filter]:bg-sidebar/70","text-2xl","text-3xl","text-[var(--sdm-c,inherit)]","text-base","text-left","text-lg","text-muted-foreground","text-primary","text-primary-foreground","text-red-600","text-red-700","text-red-800","text-sm","text-xl","text-xs","top-2","top-4","top-full","transition-all","transition-colors","transition-transform","w-4","w-8","w-full","whitespace-normal","whitespace-nowrap","wrap-anywhere","z-10","z-50"];function n(e){let r=[...t];return `@source inline("${e?`${e}:{${r.join(",")}}`:`{${r.join(",")}}`}");`}export{t as STREAMDOWN_CLASSES,n as getSourceInline};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface StreamdownTranslations {
|
|
2
|
+
alertCaution: string;
|
|
3
|
+
alertImportant: string;
|
|
4
|
+
alertNote: string;
|
|
5
|
+
alertTip: string;
|
|
6
|
+
alertWarning: string;
|
|
7
|
+
close: string;
|
|
8
|
+
copied: string;
|
|
9
|
+
copyCode: string;
|
|
10
|
+
copyLink: string;
|
|
11
|
+
copyTable: string;
|
|
12
|
+
copyTableAsCsv: string;
|
|
13
|
+
copyTableAsMarkdown: string;
|
|
14
|
+
copyTableAsTsv: string;
|
|
15
|
+
downloadDiagram: string;
|
|
16
|
+
downloadDiagramAsMmd: string;
|
|
17
|
+
downloadDiagramAsPng: string;
|
|
18
|
+
downloadDiagramAsSvg: string;
|
|
19
|
+
downloadFile: string;
|
|
20
|
+
downloadImage: string;
|
|
21
|
+
downloadTable: string;
|
|
22
|
+
downloadTableAsCsv: string;
|
|
23
|
+
downloadTableAsMarkdown: string;
|
|
24
|
+
exitFullscreen: string;
|
|
25
|
+
externalLinkWarning: string;
|
|
26
|
+
imageNotAvailable: string;
|
|
27
|
+
mermaidFormatMmd: string;
|
|
28
|
+
mermaidFormatPng: string;
|
|
29
|
+
mermaidFormatSvg: string;
|
|
30
|
+
openExternalLink: string;
|
|
31
|
+
openLink: string;
|
|
32
|
+
tableFormatCsv: string;
|
|
33
|
+
tableFormatMarkdown: string;
|
|
34
|
+
tableFormatTsv: string;
|
|
35
|
+
viewFullscreen: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const defaultTranslations: StreamdownTranslations;
|
|
38
|
+
export declare const TranslationsContext: import("react").Context<StreamdownTranslations>;
|
|
39
|
+
export declare const useTranslations: () => StreamdownTranslations;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ClassValue } from 'clsx';
|
|
2
|
+
export declare const cn: (...inputs: ClassValue[]) => string;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a max-height prop to a CSS length string.
|
|
5
|
+
* `undefined`, non-finite numbers, and `<= 0` disable the constraint.
|
|
6
|
+
*/
|
|
7
|
+
export declare const resolveMaxHeight: (maxHeight: number | string | undefined) => string | undefined;
|
|
8
|
+
export type CnFunction = (...inputs: ClassValue[]) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Prepends a prefix to each Tailwind utility class in a class string.
|
|
11
|
+
* Used to support Tailwind v4's `prefix()` feature.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* prefixClasses("tw", "flex items-center") // "tw:flex tw:items-center"
|
|
15
|
+
* prefixClasses("tw", "dark:bg-red-500") // "tw:dark:bg-red-500"
|
|
16
|
+
*/
|
|
17
|
+
export declare const prefixClasses: (prefix: string, classString: string) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a prefix-aware `cn` function. When no prefix is provided,
|
|
20
|
+
* returns the standard `cn` with zero overhead.
|
|
21
|
+
*/
|
|
22
|
+
export declare const createCn: (prefix?: string) => CnFunction;
|
|
23
|
+
export declare const save: (filename: string, content: string | Blob, mimeType: string) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lofcz/streamdown",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"homepage": "https://streamdown.ai",
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/lofcz/streamdown.git",
|
|
27
|
+
"url": "git+https://github.com/lofcz/streamdown-ng.git",
|
|
28
28
|
"directory": "packages/streamdown"
|
|
29
29
|
},
|
|
30
30
|
"publishConfig": {
|
|
@@ -37,20 +37,23 @@
|
|
|
37
37
|
"@testing-library/jest-dom": "^6.9.1",
|
|
38
38
|
"@testing-library/react": "^16.3.0",
|
|
39
39
|
"@types/hast": "^3.0.4",
|
|
40
|
+
"@types/mdast": "^4.0.4",
|
|
40
41
|
"@types/react": "^19.2.7",
|
|
41
42
|
"@types/react-dom": "^19.2.3",
|
|
42
|
-
"
|
|
43
|
+
"@types/unist": "^2.0.11",
|
|
43
44
|
"@vitejs/plugin-react": "^5.1.2",
|
|
44
45
|
"@vitest/coverage-v8": "^4.0.15",
|
|
45
46
|
"jsdom": "^27.3.0",
|
|
47
|
+
"react-dom": "^19.2.3",
|
|
46
48
|
"react-markdown": "^10.1.0",
|
|
47
49
|
"rehype-parse": "^9.0.1",
|
|
48
50
|
"rehype-stringify": "^10.0.1",
|
|
49
51
|
"shiki": "^3.19.0",
|
|
50
52
|
"tsup": "^8.5.1",
|
|
53
|
+
"typescript": "^7.0.2",
|
|
51
54
|
"vitest": "^4.0.15",
|
|
52
|
-
"@streamdown/cjk": "npm:@lofcz/streamdown-cjk@1.0.3",
|
|
53
55
|
"@streamdown/math": "npm:@lofcz/streamdown-math@1.0.3",
|
|
56
|
+
"@streamdown/cjk": "npm:@lofcz/streamdown-cjk@1.0.3",
|
|
54
57
|
"@streamdown/mermaid": "npm:@lofcz/streamdown-mermaid@1.0.2"
|
|
55
58
|
},
|
|
56
59
|
"peerDependencies": {
|
|
@@ -61,7 +64,7 @@
|
|
|
61
64
|
"clsx": "^2.1.1",
|
|
62
65
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
63
66
|
"html-url-attributes": "^3.0.1",
|
|
64
|
-
"marked": "^
|
|
67
|
+
"marked": "^18.0.9",
|
|
65
68
|
"rehype-harden": "^1.1.8",
|
|
66
69
|
"rehype-raw": "^7.0.0",
|
|
67
70
|
"rehype-sanitize": "^6.0.0",
|
|
@@ -75,7 +78,7 @@
|
|
|
75
78
|
"unist-util-visit-parents": "^6.0.0"
|
|
76
79
|
},
|
|
77
80
|
"scripts": {
|
|
78
|
-
"build": "
|
|
81
|
+
"build": "node scripts/build.mjs",
|
|
79
82
|
"postbuild": "node scripts/postbuild.js",
|
|
80
83
|
"test": "vitest run",
|
|
81
84
|
"test:ui": "vitest --ui run",
|
package/styles.css
CHANGED
|
@@ -108,3 +108,31 @@
|
|
|
108
108
|
color: hsl(0 84% 60%);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* The caret has nowhere sensible to sit after a code block or a table, so it is
|
|
114
|
+
* suppressed while one of those trails the stream. Expressing that in CSS rather
|
|
115
|
+
* than in the container's class list keeps the container's style constant for the
|
|
116
|
+
* life of the stream: a container whose class or custom property changes per token
|
|
117
|
+
* invalidates style for the whole document subtree, which on a large document costs
|
|
118
|
+
* tens of milliseconds of recalculation per token.
|
|
119
|
+
*
|
|
120
|
+
* The second selector covers per-block direction, which wraps each block in a
|
|
121
|
+
* display:contents element.
|
|
122
|
+
*/
|
|
123
|
+
[data-streamdown="container"]
|
|
124
|
+
> :last-child:is(
|
|
125
|
+
[data-streamdown="code-block"][data-incomplete],
|
|
126
|
+
[data-streamdown="mermaid-block"][data-incomplete],
|
|
127
|
+
[data-streamdown="table-wrapper"]
|
|
128
|
+
)::after,
|
|
129
|
+
[data-streamdown="container"]
|
|
130
|
+
> :last-child:has(
|
|
131
|
+
> :is(
|
|
132
|
+
[data-streamdown="code-block"][data-incomplete],
|
|
133
|
+
[data-streamdown="mermaid-block"][data-incomplete],
|
|
134
|
+
[data-streamdown="table-wrapper"]
|
|
135
|
+
):last-child
|
|
136
|
+
)::after {
|
|
137
|
+
content: none;
|
|
138
|
+
}
|