@surrealdb/ui 1.2.3 → 1.2.4

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.
Files changed (40) hide show
  1. package/README.md +16 -0
  2. package/REVIEW.md +2 -2
  3. package/dist/ui.css +1 -1
  4. package/dist/ui.d.ts +257 -110
  5. package/dist/ui.js +7036 -6307
  6. package/dist/ui.js.map +1 -1
  7. package/package.json +1 -1
  8. package/tests/e2e/MarkdownEditor/__screenshots__/jsx-inline-click.test.tsx/MarkdownEditor---inline-JSX-click-reveal-reveals-the-raw-source-when-an-inline-component-badge-is-clicked-1.png +0 -0
  9. package/tests/e2e/MarkdownEditor/__screenshots__/jsx-inline-click.test.tsx/MarkdownEditor---inline-JSX-click-reveal-reveals-the-raw-source-when-an-inline-component-badge-is-clicked-2.png +0 -0
  10. package/tests/e2e/MarkdownEditor/__screenshots__/jsx-inline-click.test.tsx/MarkdownEditor---inline-JSX-click-reveal-reveals-the-raw-source-when-an-inline-component-badge-is-clicked-3.png +0 -0
  11. package/tests/e2e/MarkdownEditor/image-on-image.test.tsx +72 -0
  12. package/tests/e2e/MarkdownEditor/jsx-inline-click.test.tsx +53 -0
  13. package/tests/e2e/MarkdownEditor/onimage-parity.test.tsx +49 -0
  14. package/tests/e2e/MarkdownEditor/regressions.test.tsx +40 -0
  15. package/tests/unit/MarkdownConformance/error-isolation.test.tsx +43 -0
  16. package/tests/unit/MarkdownConformance/indentation.test.tsx +29 -0
  17. package/tests/unit/MarkdownConformance/jsx-attributes.test.tsx +56 -0
  18. package/tests/unit/MarkdownConformance/jsx-fuzz.test.tsx +165 -0
  19. package/tests/unit/MarkdownConformance/links.test.tsx +71 -0
  20. package/tests/unit/MarkdownConformance/render-helpers.tsx +88 -0
  21. package/tests/unit/MarkdownEditor/decorations.test.ts +2 -2
  22. package/tests/unit/MarkdownEditor/indented-fence.test.ts +103 -0
  23. package/tests/unit/MarkdownEditor/jsx-attr-scan.test.ts +1 -1
  24. package/tests/unit/MarkdownEditor/jsx-block-widget.test.ts +92 -0
  25. package/tests/unit/MarkdownEditor/jsx-tag-grammar.test.ts +2 -2
  26. package/tests/unit/MarkdownEditor/list-indent.test.ts +2 -2
  27. package/tests/unit/MarkdownEditor/slash-commands.test.ts +2 -2
  28. package/tests/unit/MarkdownEditor/triggers.test.ts +2 -2
  29. package/tests/unit/MarkdownViewer/callout.test.tsx +60 -0
  30. package/tests/unit/MarkdownViewer/code-highlight.test.tsx +61 -0
  31. package/tests/unit/MarkdownViewer/features.test.tsx +55 -1
  32. package/tests/unit/MarkdownViewer/indented-jsx-children.test.tsx +98 -0
  33. package/tests/unit/MarkdownViewer/jsx-block-nesting.test.tsx +234 -0
  34. package/tests/unit/MarkdownViewer/jsx.test.tsx +2 -2
  35. package/tests/unit/MarkdownViewer/preserve-newlines.test.tsx +143 -0
  36. package/tests/unit/MarkdownViewer/read-time.test.ts +21 -0
  37. package/tests/unit/MarkdownViewer/renderers.test.tsx +16 -0
  38. package/tests/unit/MarkdownViewer/syntax-highlighting.test.tsx +73 -0
  39. package/tests/unit/MarkdownViewer/tabs-fenced-code.test.tsx +196 -0
  40. package/tests/unit/MarkdownViewer/tabs.test.tsx +115 -0
package/dist/ui.d.ts CHANGED
@@ -294,12 +294,13 @@ export declare interface CodeRendererProps {
294
294
  language: string;
295
295
  }
296
296
 
297
+ /** Map of lower-cased fenced-code info string to renderer component. */
298
+ declare type CodeRenderers = Record<string, CodeRenderer>;
299
+
297
300
  export declare type ColorScheme = keyof ThemeConfig;
298
301
 
299
302
  declare type ColorScheme_2 = keyof ThemeConfig_2;
300
303
 
301
- declare type CommandAction = (view: EditorView, range: SlashCommandRange) => void;
302
-
303
304
  declare interface CommentNode {
304
305
  type: "Comment";
305
306
  text: string;
@@ -354,10 +355,16 @@ export declare function createStyleHighlighter(theme: ThemeConfig_2, colorScheme
354
355
  */
355
356
  export declare const customHistoryKeymap: readonly KeyBinding[];
356
357
 
357
- /** Default fenced-code renderers keyed by lower-cased info string (e.g. `mermaid`). */
358
- export declare const DEFAULT_CODE_RENDERERS: Record<string, CodeRenderer>;
358
+ /**
359
+ * Default fenced-code renderers keyed by lower-cased info string (e.g. `mermaid`).
360
+ */
361
+ export declare const DEFAULT_CODE_RENDERERS: CodeRenderers;
359
362
 
360
- /** Default JSX components for `<PascalCase />` tags in markdown (e.g. `<Since />`, `<Tabs>`). */
363
+ /**
364
+ * Default JSX components for `<PascalCase />` tags in markdown (e.g. `<Since />`,
365
+ * `<Tabs>`). Inline components register as a bare `ComponentType`; block
366
+ * components use the explicit `{ component, block: true }` form.
367
+ */
361
368
  export declare const DEFAULT_COMPONENTS: MarkdownComponents;
362
369
 
363
370
  /** Default mode used when no mode is provided. */
@@ -406,17 +413,58 @@ export declare interface EditorController {
406
413
  export declare const editorExtensions: () => Extension;
407
414
 
408
415
  export declare interface EditorOptions {
416
+ /**
417
+ * The state fields to use for the editor.
418
+ */
409
419
  fields?: StateFields;
420
+ /**
421
+ * The theme to use for the editor.
422
+ * @default VIVID_THEME
423
+ */
410
424
  theme?: ThemeConfig;
425
+ /**
426
+ * The initial document to use for the editor.
427
+ * Do not set this if you are using the `state` prop.
428
+ */
411
429
  document?: string;
430
+ /**
431
+ * The initial state to use for the editor.
432
+ * Do not set this if you are using the `document` prop.
433
+ */
412
434
  state?: EditorStateSnapshot;
435
+ /**
436
+ * Whether the editor is read-only.
437
+ * @default false
438
+ */
413
439
  readOnly?: boolean;
440
+ /**
441
+ * Additional extensions to add to the editor.
442
+ */
414
443
  extensions?: Extension;
444
+ /**
445
+ * The language to use for the editor.
446
+ */
415
447
  language?: Language;
448
+ /**
449
+ * Whether to show line numbers.
450
+ * @default false
451
+ */
416
452
  lineNumbers?: boolean;
453
+ /**
454
+ * Callback to call when the editor is mounted.
455
+ */
417
456
  onMounted?: (editor: EditorView) => void;
457
+ /**
458
+ * Callback to call when the document changes.
459
+ */
418
460
  onChangeDocument?: (document: string) => void;
461
+ /**
462
+ * Callback to call when the selection changes.
463
+ */
419
464
  onChangeSelection?: (selection: EditorSelection) => void;
465
+ /**
466
+ * Callback to call when the state changes.
467
+ */
420
468
  onChangeState?: (snapshot: EditorStateSnapshot) => void;
421
469
  }
422
470
 
@@ -427,6 +475,9 @@ export declare type EditorStateSnapshot = Record<string, unknown>;
427
475
  */
428
476
  export declare function editorTheme(theme: ThemeConfig_2, colorScheme: MantineColorScheme): Extension;
429
477
 
478
+ /** Estimated reading time in minutes (minimum 1). */
479
+ export declare function estimateMarkdownReadTimeMinutes(markdown: string): number;
480
+
430
481
  export declare function extractCdnId(query: string): string | undefined;
431
482
 
432
483
  export declare interface ExtractedCode {
@@ -454,6 +505,9 @@ export declare function extractTest(input: string): ExtractedCode;
454
505
  /** Case-insensitive filter over command titles and keywords. */
455
506
  export declare function filterSlashCommands(commands: readonly SlashCommand[], query: string): SlashCommand[];
456
507
 
508
+ /** Human-readable reading time label, e.g. `5 min read`. */
509
+ export declare function formatMarkdownReadTime(markdown: string): string;
510
+
457
511
  /**
458
512
  * Generate a 24-character hex string suitable for use as a
459
513
  * stable block identifier. Uses `crypto.getRandomValues` for
@@ -461,7 +515,7 @@ export declare function filterSlashCommands(commands: readonly SlashCommand[], q
461
515
  */
462
516
  export declare function generateRandomId(): string;
463
517
 
464
- export declare function getCDNImageURL(imageId: string | undefined, width?: number, quality?: number): string | undefined;
518
+ export declare function getCDNImageURL(imageId: string | undefined, width?: number, quality?: number, extension?: string): string | undefined;
465
519
 
466
520
  export declare function getCDNVideoURL(videoId: string | undefined, format?: "mp4" | "webm" | "mov", controls?: boolean): string | undefined;
467
521
 
@@ -901,30 +955,32 @@ export declare type Identified<T = object, I = string> = T & {
901
955
  id: I;
902
956
  };
903
957
 
904
- /** Normalised image descriptor for viewer renderers and `onImage` callbacks. */
905
- export declare interface ImageDescriptor {
906
- src: string;
907
- alt?: string;
908
- title?: string;
909
- darkSrc?: string;
910
- }
958
+ /**
959
+ * Build a `run` that inserts a block-level JSX tag on its own line with blank lines before when needed.
960
+ */
961
+ export declare function insertBlock(block: string): SlashCommandAction;
911
962
 
912
963
  /**
913
964
  * Build a `run` that inserts a callout of the given kind.
914
965
  */
915
- export declare function insertCallout(kind: CalloutKind): CommandAction;
966
+ export declare function insertCallout(kind: CalloutKind): SlashCommandAction;
916
967
 
917
968
  /**
918
- * Build a `run` that inserts the given markdown and positions the caret at the end of the inserted text,
919
- * or at the given offset.
969
+ * Build a `run` that inserts the given markdown and positions the caret.
970
+ * Use `$` in the insert string to mark the initial caret position.
920
971
  */
921
- export declare function insertMarkdown(insert: string, caretOffset?: number): CommandAction;
972
+ export declare function insertMarkdown(markdown: string): SlashCommandAction;
922
973
 
923
974
  export declare function isCDNId(query: string): boolean;
924
975
 
925
976
  /** True when the registered component declares `block: true`. */
926
977
  export declare function isMarkdownComponentBlock(components: MarkdownComponents | undefined, name: string): boolean;
927
978
 
979
+ /**
980
+ * Returns whether the given URL points at a recognised video container.
981
+ */
982
+ export declare function isVideoUrl(src: string): boolean;
983
+
928
984
  /** How `<Component />` tags are handled. */
929
985
  export declare type JsxMode = "render" | "throw" | "graceful" | "omit";
930
986
 
@@ -934,7 +990,36 @@ export declare interface LabelProps extends Omit<BadgeProps, "children"> {
934
990
  label: string;
935
991
  }
936
992
 
937
- declare type Language = "csharp" | "rust" | "javascript" | "typescript" | "surrealql" | "json" | "yaml" | "java" | "go" | "python" | "html" | "cli" | "php" | "markdown" | "syntax";
993
+ declare type Language = "csharp" | "rust" | "javascript" | "typescript" | "surrealql" | "json" | "yaml" | "java" | "go" | "python" | "html" | "bash" | "cli" | "php" | "markdown" | "syntax";
994
+
995
+ /**
996
+ * A CodeMirror extension that provides support for live markdown editing.
997
+ */
998
+ export declare function liveMarkdownEditor(opts: LiveMarkdownEditorOptions): Extension;
999
+
1000
+ /**
1001
+ * Options to configure the behaviour of the live markdown editor
1002
+ */
1003
+ export declare interface LiveMarkdownEditorOptions {
1004
+ /** Required widget store, typically returned by `useMarkdownWidgetStore()`. */
1005
+ widgetStore: WidgetStore;
1006
+ /** Enable automatic table formatting on edit. */
1007
+ withTableFormatter?: boolean;
1008
+ /** Custom code renderers for fenced code blocks. */
1009
+ codeRenderers?: CodeRenderers;
1010
+ /** Whether to install the markdown language alongside the live preview. */
1011
+ includeLanguage?: boolean;
1012
+ /** Optional language resolver for embedded fenced code blocks. */
1013
+ resolveCodeLanguage?: (info: string) => Language_2 | undefined;
1014
+ /** Custom JSX components to expose in the editor. */
1015
+ components?: MarkdownComponents;
1016
+ /** How unsupported JSX is handled in preview mode. */
1017
+ jsxMode?: JsxMode;
1018
+ /** Rewrite image/video sources before preview render. */
1019
+ onResolveMedia?: (node: MediaDescriptor) => MediaDescriptor;
1020
+ /** Optional slash command store, typically returned by `useMarkdownSlashStore()`. */
1021
+ slashStore?: SlashStore;
1022
+ }
938
1023
 
939
1024
  /**
940
1025
  * The Mantine theme configurtation
@@ -949,6 +1034,15 @@ export declare const MANTINE_THEME: MantineThemeOverride;
949
1034
  export declare interface MarkdownComponentConfig {
950
1035
  component: ComponentType<any>;
951
1036
  block?: boolean;
1037
+ /**
1038
+ * Whether source newlines inside the component's children are preserved as
1039
+ * `<br />` (and the resulting inline runs wrapped in `<p>`). Defaults to
1040
+ * `true`, matching prose components that want line breaks honoured. Set to
1041
+ * `false` for layout components (e.g. a grid/columns wrapper) where the
1042
+ * whitespace between child blocks would otherwise inject stray
1043
+ * `<p><br /></p>` nodes and break the layout.
1044
+ */
1045
+ preserveNewlines?: boolean;
952
1046
  }
953
1047
 
954
1048
  /** A registered component is either a bare React component (inline) or a config object. */
@@ -957,6 +1051,26 @@ export declare type MarkdownComponentDef = ComponentType<any> | MarkdownComponen
957
1051
  /** Map of PascalCase JSX tag names to viewer/editor component registrations. */
958
1052
  export declare type MarkdownComponents = Record<string, MarkdownComponentDef>;
959
1053
 
1054
+ /**
1055
+ * Wraps a run of rendered markdown so it gets the same block spacing / vertical
1056
+ * rhythm as top-level {@link MarkdownViewer} content.
1057
+ *
1058
+ * ```tsx
1059
+ * function ElementWithContent({ children }) {
1060
+ * return <MarkdownContent>{children}</MarkdownContent>;
1061
+ * }
1062
+ * ```
1063
+ *
1064
+ * **Note**: This component is only used in the Markdown viewer. Markdown editors do not
1065
+ * support JSX sub-content.
1066
+ */
1067
+ export declare const MarkdownContent: FC<MarkdownContentProps>;
1068
+
1069
+ export declare interface MarkdownContentProps extends BoxProps {
1070
+ /** Rendered markdown nodes (e.g. the `children` a custom JSX component receives). */
1071
+ children?: ReactNode;
1072
+ }
1073
+
960
1074
  /**
961
1075
  * Rendering mode of the markdown editor.
962
1076
  *
@@ -967,43 +1081,62 @@ export declare type MarkdownComponents = Record<string, MarkdownComponentDef>;
967
1081
  export declare type MarkdownEditMode = "source" | "preview";
968
1082
 
969
1083
  /**
970
- * High-level Markdown editor primitive that wires together the
971
- * `CodeEditor` shell, the live preview extension, the widget store and
972
- * the React portal host.
1084
+ * High-level self contained live markdown editor component.
1085
+ *
1086
+ * Wires together the `CodeEditor` shell, the live preview extension, the widget store and the React portal host.
973
1087
  *
974
1088
  * See {@link MarkdownViewer} for a Markdown viewer equivalent.
975
1089
  */
976
1090
  export declare const MarkdownEditor: FC<MarkdownEditorProps>;
977
1091
 
978
- export declare interface MarkdownEditorProps extends Omit<EditorOptions, "language" | "extensions">, Omit<BoxProps, "onChange"> {
979
- /** `source` or `preview` (live preview). Defaults to `preview`. */
1092
+ export declare interface MarkdownEditorProps extends Omit<EditorOptions, "language">, Omit<BoxProps, "onChange"> {
1093
+ /**
1094
+ * The display mode of the editor. Defaults to `preview`.
1095
+ */
980
1096
  mode?: MarkdownEditMode;
981
- /** Additional CodeMirror extensions to layer on top of the live preview. */
982
- extensions?: Extension;
983
- /** GFM table preview widgets in preview mode. Defaults to `true`. */
984
- tables?: boolean;
985
1097
  /**
986
- * Auto-format GFM table source while editing: align columns and pad cells
987
- * with trailing spaces. Defaults to `false`.
1098
+ * Custom JSX components to expose in the editor.
988
1099
  */
989
- withTableFormatter?: boolean;
990
- /** React components for `<PascalCase />` tags (preview widgets). */
991
1100
  components?: MarkdownComponents;
992
- /** How unsupported JSX is handled in preview. Default `render` (uses {@link DEFAULT_COMPONENTS}). */
1101
+ /**
1102
+ * How unsupported JSX is handled in preview mode.
1103
+ * @default `render`
1104
+ */
993
1105
  jsxMode?: JsxMode;
994
- /** Auto-focus the editor on mount. */
1106
+ /**
1107
+ * Whether to auto-focus the editor on mount.
1108
+ * @default false
1109
+ */
995
1110
  autoFocus?: boolean;
1111
+ /**
1112
+ * The placeholder text to display in the editor when it is empty.
1113
+ */
1114
+ placeholder?: string;
996
1115
  /**
997
1116
  * Custom per-language renderers for fenced code blocks. Keys are the
998
- * lower-cased fenced-code info string (e.g. `mermaid`). When the block
999
- * is inactive, a matching renderer fully replaces the source. Defaults
1000
- * to `{ mermaid: MermaidCodeRenderer }`; pass `{}` to disable.
1117
+ * lower-cased fenced-code info string (e.g. `mermaid`).
1118
+ * @default `{ mermaid: MermaidCodeRenderer }`
1119
+ */
1120
+ codeRenderers?: CodeRenderers;
1121
+ /**
1122
+ * Whether to enable the slash command palette.
1123
+ * @default true
1001
1124
  */
1002
- codeRenderers?: Record<string, CodeRenderer>;
1003
- /** Enable the slash command palette. Defaults to `true`. */
1004
1125
  slashCommands?: boolean;
1005
- /** Override the slash command set. Defaults to {@link DEFAULT_SLASH_COMMANDS}. */
1126
+ /**
1127
+ * Override the slash command set.
1128
+ * @default {@link DEFAULT_SLASH_COMMANDS}
1129
+ */
1006
1130
  commands?: readonly SlashCommand[];
1131
+ /**
1132
+ * Auto-format GFM table source while editing.
1133
+ * @default false
1134
+ */
1135
+ withTableFormatter?: boolean;
1136
+ /**
1137
+ * Rewrite image/video sources before preview render.
1138
+ */
1139
+ onResolveMedia?: (node: MediaDescriptor) => MediaDescriptor;
1007
1140
  }
1008
1141
 
1009
1142
  /**
@@ -1020,47 +1153,6 @@ export declare function markdownEditorReady(): Extension;
1020
1153
  */
1021
1154
  export declare const markdownEditorReadyField: StateField<boolean>;
1022
1155
 
1023
- /**
1024
- * Live preview stack: language (optional), mode field, folding, decorations, theme.
1025
- */
1026
- export declare function markdownLivePreview(opts: MarkdownLivePreviewOptions): Extension;
1027
-
1028
- /** Options for {@link markdownLivePreview}. */
1029
- export declare interface MarkdownLivePreviewOptions {
1030
- /** GFM table preview widgets in preview mode. Defaults to `true`. */
1031
- tables?: boolean;
1032
- /**
1033
- * Auto-format GFM table source on edit: align columns, pad cells with
1034
- * trailing spaces, and normalise the delimiter row. Defaults to `false`.
1035
- */
1036
- withTableFormatter?: boolean;
1037
- /**
1038
- * Per-language renderers used when a fenced code block is inactive (preview
1039
- * unfocused / caret outside the block). Keys are the lower-cased fenced-code
1040
- * info string (e.g. `mermaid`). Defaults to `{}`.
1041
- */
1042
- codeRenderers?: Record<string, CodeRenderer>;
1043
- /** Required widget store, typically returned by `useMarkdownWidgetStore()`. */
1044
- widgetStore: WidgetStore;
1045
- /** Whether to install the markdown language alongside the live preview. */
1046
- includeLanguage?: boolean;
1047
- /**
1048
- * Optional language resolver for embedded fenced code blocks.
1049
- */
1050
- resolveCodeLanguage?: (info: string) => Language_2 | undefined;
1051
- /** JSX/HTML preview widgets (viewer parity). Omit to leave raw source in preview. */
1052
- components?: MarkdownComponents;
1053
- jsxMode?: JsxMode;
1054
- /**
1055
- * Slash command palette. Pass a store (from `useSlashStore()`) to enable
1056
- * the slash (`/`) command menu. Render `<SlashCommandMenu>` with the
1057
- * same store. Omit to disable.
1058
- */
1059
- slash?: {
1060
- store: SlashStore;
1061
- };
1062
- }
1063
-
1064
1156
  /**
1065
1157
  * State field tracking the current {@link MarkdownEditMode}.
1066
1158
  */
@@ -1108,41 +1200,67 @@ export declare function markdownSourceFromString(source: string): MarkdownSource
1108
1200
  /**
1109
1201
  * Editor base theme for the markdown live preview. Cursor / scroller rules and
1110
1202
  * editor-only chrome; shared surface styles live in `markdown.module.scss`.
1203
+ *
1204
+ * Line wrapping is enabled so long lines (prose and fenced code alike) wrap to
1205
+ * the editor width instead of growing the content box and scrolling the whole
1206
+ * editor horizontally.
1111
1207
  */
1112
1208
  export declare function markdownTheme(): Extension;
1113
1209
 
1210
+ /** Strip common Markdown syntax to approximate plain text for word counting. */
1211
+ export declare function markdownToPlainText(markdown: string): string;
1212
+
1114
1213
  /**
1115
- * High-level Markdown viewer primitive that renders a Markdown structure
1116
- * as a React tree.
1214
+ * High-level self contained live markdown viewer component.
1215
+ *
1216
+ * Renders a Markdown structure as a React tree.
1117
1217
  *
1118
1218
  * See {@link MarkdownEditor} for a Markdown editor equivalent.
1119
1219
  */
1120
1220
  export declare const MarkdownViewer: FC<MarkdownViewerProps>;
1121
1221
 
1122
1222
  export declare interface MarkdownViewerProps extends BoxProps {
1123
- /** Markdown source string. Ignored when `tree` is provided. */
1223
+ /**
1224
+ * Markdown source string. Ignored when `tree` is provided.
1225
+ */
1124
1226
  content?: string;
1125
- /** Pre-parsed tree and markdown source. */
1227
+ /**
1228
+ * Pre-parsed tree and markdown source.
1229
+ */
1126
1230
  tree?: MarkdownViewerTreeInput;
1127
- /** Collapse consecutive blank lines into a single line break. Defaults to `true`. */
1128
- collapseBlankLines?: boolean;
1129
- /** Override built-in element renderers. */
1231
+ /**
1232
+ * Override built-in element renderers.
1233
+ */
1130
1234
  renderers?: MarkdownViewerRenderers;
1131
- /** Rewrite image URLs before render (e.g. CDN resolution). */
1132
- onImage?: (node: ImageDescriptor) => ImageDescriptor;
1133
- /** Add slug IDs and hover anchor links on headings. */
1134
- autoLink?: boolean;
1135
1235
  /**
1136
1236
  * Custom per-language renderers for fenced code blocks. Keys are the
1137
- * lower-cased fenced-code info string (e.g. `mermaid`). When the block
1138
- * is inactive, a matching renderer fully replaces the source. Defaults
1139
- * to `{ mermaid: MermaidCodeRenderer }`; pass `{}` to disable.
1237
+ * lower-cased fenced-code info string (e.g. `mermaid`).
1238
+ * @default `{ mermaid: MermaidCodeRenderer }`
1239
+ */
1240
+ codeRenderers?: CodeRenderers;
1241
+ /**
1242
+ * Custom JSX components to expose in the viewer.
1140
1243
  */
1141
- codeRenderers?: Record<string, CodeRenderer>;
1142
- /** React components for `<PascalCase />` tags. */
1143
1244
  components?: MarkdownComponents;
1144
- /** How unsupported JSX is handled. Default `render` (uses {@link DEFAULT_COMPONENTS}). */
1245
+ /**
1246
+ * How unsupported JSX is handled.
1247
+ * @default `render`
1248
+ */
1145
1249
  jsxMode?: JsxMode;
1250
+ /**
1251
+ * Add slug IDs and hover anchor links on headings.
1252
+ * @default true
1253
+ */
1254
+ withAutoLink?: boolean;
1255
+ /**
1256
+ * Collapse consecutive blank lines into a single line break.
1257
+ * @default true
1258
+ */
1259
+ withBlankLineCollapse?: boolean;
1260
+ /**
1261
+ * Rewrite image/video sources before render.
1262
+ */
1263
+ onResolveMedia?: (node: MediaDescriptor) => MediaDescriptor;
1146
1264
  }
1147
1265
 
1148
1266
  /**
@@ -1188,7 +1306,7 @@ export declare type MarkdownViewerRenderers = Partial<{
1188
1306
  children: ReactNode;
1189
1307
  }) => ReactNode;
1190
1308
  thematicBreak: () => ReactNode;
1191
- image: (props: ImageDescriptor) => ReactNode;
1309
+ image: (props: MediaDescriptor) => ReactNode;
1192
1310
  strong: (props: {
1193
1311
  children: ReactNode;
1194
1312
  }) => ReactNode;
@@ -1226,6 +1344,17 @@ export declare interface MarkdownWidgetPortalsProps {
1226
1344
  store: WidgetStore;
1227
1345
  }
1228
1346
 
1347
+ /** Normalised media descriptor for viewer renderers and `onResolveMedia` callbacks. */
1348
+ export declare interface MediaDescriptor {
1349
+ src: string;
1350
+ alt?: string;
1351
+ title?: string;
1352
+ darkSrc?: string;
1353
+ }
1354
+
1355
+ /** Merge default code renderers with caller overrides (caller wins on key clash). */
1356
+ export declare function mergeCodeRenderers(renderers?: CodeRenderers): CodeRenderers;
1357
+
1229
1358
  /** Merge default JSX components with caller overrides (caller wins on key clash). */
1230
1359
  export declare function mergeMarkdownComponents(components?: MarkdownComponents): MarkdownComponents;
1231
1360
 
@@ -1330,10 +1459,16 @@ declare interface ParsedHeadingTitle {
1330
1459
  export declare function parseHeadingTitleText(plain: string): ParsedHeadingTitle;
1331
1460
 
1332
1461
  /**
1333
- * Parse markdown into a Lezer syntax tree using the same grammar as CodeMirror.
1462
+ * Parse markdown into a Lezer syntax tree using the same grammar as the editor.
1334
1463
  * Safe in SSR: no {@link EditorState} or DOM.
1335
1464
  */
1336
- export declare function parseMarkdownTree(source: string): Tree;
1465
+ export declare function parseMarkdownTree(source: string, options?: ParseMarkdownTreeOptions): Tree;
1466
+
1467
+ /** Options for {@link parseMarkdownTree}. */
1468
+ export declare interface ParseMarkdownTreeOptions {
1469
+ /** Recognise GFM callout syntax (`> [!note]`). Defaults to `true`. */
1470
+ callouts?: boolean;
1471
+ }
1337
1472
 
1338
1473
  export declare const picto2106: string;
1339
1474
 
@@ -2358,7 +2493,15 @@ export declare type RailroadNode = DiagramNode | SequenceNode | TerminalNode | N
2358
2493
  /** Resolve heading `id` from `{#custom}` suffix or slugged plain title. */
2359
2494
  export declare function resolveHeadingId(node: SyntaxNode, source: MarkdownSource, slugger: default_2): string | undefined;
2360
2495
 
2361
- /** Normalise a component registration into its `{ component, block }` form. */
2496
+ /**
2497
+ * Resolve a markdown image destination into an {@link MediaDescriptor}. Splits
2498
+ * the optional `light|dark` source pair and applies the caller's `onResolveMedia`
2499
+ * rewrite (e.g. CDN code → full URL). Shared by the editor preview widgets and
2500
+ * the read-only viewer so both surfaces resolve sources identically.
2501
+ */
2502
+ export declare function resolveImageDescriptor(url: string, alt: string, title?: string, onResolveMedia?: (node: MediaDescriptor) => MediaDescriptor): MediaDescriptor;
2503
+
2504
+ /** Normalise a component registration into its `{ component, block, preserveNewlines }` form. */
2362
2505
  export declare function resolveMarkdownComponent(def: MarkdownComponentDef | undefined): MarkdownComponentConfig | undefined;
2363
2506
 
2364
2507
  export declare interface ResponsiveTabItem {
@@ -2441,9 +2584,11 @@ export declare interface SlashCommand {
2441
2584
  /** React node for the leading icon. */
2442
2585
  readonly icon?: ReactNode;
2443
2586
  /** Apply the command — typically replaces `range` with markdown. */
2444
- readonly run: CommandAction;
2587
+ readonly run: SlashCommandAction;
2445
2588
  }
2446
2589
 
2590
+ export declare type SlashCommandAction = (view: SlashCommandView, range: SlashCommandRange) => void;
2591
+
2447
2592
  /**
2448
2593
  * Renders the slash command palette. Reads the active session
2449
2594
  * from the {@link SlashStore}, filters {@link SlashCommand}s by the typed
@@ -2458,7 +2603,7 @@ export declare interface SlashCommand {
2458
2603
  export declare const SlashCommandMenu: FC<SlashCommandMenuProps>;
2459
2604
 
2460
2605
  export declare interface SlashCommandMenuProps {
2461
- /** Store fed by `markdownSlashCommands` (see {@link useSlashStore}). */
2606
+ /** Store fed by `markdownSlashCommands` (see {@link useMarkdownSlashStore}). */
2462
2607
  store: SlashStore;
2463
2608
  /** Accessor for the live editor view (e.g. `controller.getEditor`). */
2464
2609
  getEditor: () => EditorView;
@@ -2472,6 +2617,8 @@ export declare interface SlashCommandRange {
2472
2617
  readonly to: number;
2473
2618
  }
2474
2619
 
2620
+ export declare type SlashCommandView = EditorView;
2621
+
2475
2622
  /** Viewport coordinates of the slash anchor (from `view.coordsAtPos`). */
2476
2623
  export declare interface SlashCoords {
2477
2624
  readonly left: number;
@@ -2632,6 +2779,13 @@ export declare function useKeyNavigation<T extends Identified>(items: T[], onSub
2632
2779
  */
2633
2780
  export declare function useLater<T extends unknown[]>(doLater: (...args: T) => unknown): (...args: T) => void;
2634
2781
 
2782
+ /**
2783
+ * Hook returning a stable {@link SlashStore} for the lifetime of the calling
2784
+ * component. Pair with {@link SlashCommandMenu} and pass the same store into
2785
+ * `markdownLivePreview({ slash: { store } })`.
2786
+ */
2787
+ export declare function useMarkdownSlashStore(): SlashStore;
2788
+
2635
2789
  /**
2636
2790
  * Hook returning a stable {@link WidgetStore} reference for the lifetime of
2637
2791
  * the calling component. Pair with {@link MarkdownWidgetPortals} and pass
@@ -2641,13 +2795,6 @@ export declare function useMarkdownWidgetStore(): WidgetStore;
2641
2795
 
2642
2796
  export declare function useMiniController(): [RefObject<HTMLIFrameElement | null>, MiniController];
2643
2797
 
2644
- /**
2645
- * Hook returning a stable {@link SlashStore} for the lifetime of the calling
2646
- * component. Pair with {@link SlashCommandMenu} and pass the same store into
2647
- * `markdownLivePreview({ slash: { store } })`.
2648
- */
2649
- export declare function useSlashStore(): SlashStore;
2650
-
2651
2798
  export declare function useSort<T = DefaultSort>(options?: SortOptions<T>): SortHandle<T>;
2652
2799
 
2653
2800
  /**