draftly 1.0.7 → 2.0.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.
Files changed (79) hide show
  1. package/README.md +12 -0
  2. package/dist/chunk-3T55CBNZ.cjs +33 -0
  3. package/dist/chunk-3T55CBNZ.cjs.map +1 -0
  4. package/dist/chunk-5MC4T7JH.cjs +58 -0
  5. package/dist/chunk-5MC4T7JH.cjs.map +1 -0
  6. package/dist/{chunk-72ZYRGRT.cjs → chunk-BWJLMREN.cjs} +11 -9
  7. package/dist/chunk-BWJLMREN.cjs.map +1 -0
  8. package/dist/{chunk-KBQDZ5IW.cjs → chunk-CLW73JRX.cjs} +100 -75
  9. package/dist/chunk-CLW73JRX.cjs.map +1 -0
  10. package/dist/{chunk-DFQYXFOP.js → chunk-EEHILRG5.js} +26 -3
  11. package/dist/chunk-EEHILRG5.js.map +1 -0
  12. package/dist/{chunk-HPSMS2WB.js → chunk-I563H35S.js} +101 -75
  13. package/dist/chunk-I563H35S.js.map +1 -0
  14. package/dist/chunk-IAXF4SJL.js +55 -0
  15. package/dist/chunk-IAXF4SJL.js.map +1 -0
  16. package/dist/chunk-JF3WXXMJ.js +31 -0
  17. package/dist/chunk-JF3WXXMJ.js.map +1 -0
  18. package/dist/{chunk-N3WL3XPB.js → chunk-L2XSK57Y.js} +1761 -478
  19. package/dist/chunk-L2XSK57Y.js.map +1 -0
  20. package/dist/{chunk-KDEDLC3D.cjs → chunk-TBVZEK2H.cjs} +27 -2
  21. package/dist/chunk-TBVZEK2H.cjs.map +1 -0
  22. package/dist/{chunk-2B3A3VSQ.cjs → chunk-W5ALMXG2.cjs} +1808 -504
  23. package/dist/chunk-W5ALMXG2.cjs.map +1 -0
  24. package/dist/{chunk-CG4M4TC7.js → chunk-ZUI3GI3W.js} +7 -5
  25. package/dist/chunk-ZUI3GI3W.js.map +1 -0
  26. package/dist/{draftly-BLnx3uGX.d.cts → draftly-BBL-AdOl.d.cts} +5 -1
  27. package/dist/{draftly-BLnx3uGX.d.ts → draftly-BBL-AdOl.d.ts} +5 -1
  28. package/dist/editor/index.cjs +22 -14
  29. package/dist/editor/index.d.cts +2 -1
  30. package/dist/editor/index.d.ts +2 -1
  31. package/dist/editor/index.js +2 -2
  32. package/dist/index.cjs +65 -39
  33. package/dist/index.d.cts +6 -3
  34. package/dist/index.d.ts +6 -3
  35. package/dist/index.js +6 -4
  36. package/dist/lib/index.cjs +12 -0
  37. package/dist/lib/index.cjs.map +1 -0
  38. package/dist/lib/index.d.cts +16 -0
  39. package/dist/lib/index.d.ts +16 -0
  40. package/dist/lib/index.js +3 -0
  41. package/dist/lib/index.js.map +1 -0
  42. package/dist/plugins/index.cjs +27 -17
  43. package/dist/plugins/index.d.cts +144 -9
  44. package/dist/plugins/index.d.ts +144 -9
  45. package/dist/plugins/index.js +5 -3
  46. package/dist/preview/index.cjs +16 -11
  47. package/dist/preview/index.d.cts +19 -4
  48. package/dist/preview/index.d.ts +19 -4
  49. package/dist/preview/index.js +3 -2
  50. package/package.json +8 -1
  51. package/src/editor/draftly.ts +1 -0
  52. package/src/editor/plugin.ts +5 -1
  53. package/src/editor/theme.ts +1 -0
  54. package/src/editor/utils.ts +31 -0
  55. package/src/index.ts +5 -4
  56. package/src/lib/index.ts +2 -0
  57. package/src/lib/input-handler.ts +45 -0
  58. package/src/plugins/code-plugin.theme.ts +426 -0
  59. package/src/plugins/code-plugin.ts +810 -561
  60. package/src/plugins/emoji-plugin.ts +140 -0
  61. package/src/plugins/index.ts +63 -57
  62. package/src/plugins/inline-plugin.ts +305 -291
  63. package/src/plugins/math-plugin.ts +12 -0
  64. package/src/plugins/table-plugin.ts +900 -0
  65. package/src/preview/context.ts +4 -1
  66. package/src/preview/css-generator.ts +14 -1
  67. package/src/preview/index.ts +9 -1
  68. package/src/preview/preview.ts +2 -1
  69. package/src/preview/renderer.ts +21 -20
  70. package/src/preview/syntax-theme.ts +110 -0
  71. package/src/preview/types.ts +14 -0
  72. package/dist/chunk-2B3A3VSQ.cjs.map +0 -1
  73. package/dist/chunk-72ZYRGRT.cjs.map +0 -1
  74. package/dist/chunk-CG4M4TC7.js.map +0 -1
  75. package/dist/chunk-DFQYXFOP.js.map +0 -1
  76. package/dist/chunk-HPSMS2WB.js.map +0 -1
  77. package/dist/chunk-KBQDZ5IW.cjs.map +0 -1
  78. package/dist/chunk-KDEDLC3D.cjs.map +0 -1
  79. package/dist/chunk-N3WL3XPB.js.map +0 -1
@@ -1,11 +1,14 @@
1
1
  import * as _lezer_markdown from '@lezer/markdown';
2
2
  import { MarkdownConfig } from '@lezer/markdown';
3
- import { d as DraftlyPlugin, T as ThemeEnum } from '../draftly-BLnx3uGX.cjs';
3
+ import { d as DraftlyPlugin, T as ThemeEnum } from '../draftly-BBL-AdOl.cjs';
4
+ import * as _lezer_highlight from '@lezer/highlight';
5
+ import * as _codemirror_state from '@codemirror/state';
6
+ import * as _codemirror_language from '@codemirror/language';
4
7
  import { SyntaxNode } from '@lezer/common';
5
- import '@codemirror/state';
6
8
  import '@codemirror/view';
7
9
  import 'style-mod';
8
10
 
11
+ type SyntaxThemeInput = _codemirror_language.HighlightStyle | _codemirror_state.Extension | readonly _codemirror_state.Extension[];
9
12
  /**
10
13
  * Context passed to plugin preview methods
11
14
  */
@@ -20,6 +23,8 @@ interface PreviewContext {
20
23
  sanitize(html: string): string;
21
24
  /** Render children of a node to HTML */
22
25
  renderChildren(node: SyntaxNode): Promise<string>;
26
+ /** Active syntax highlighters used for code rendering */
27
+ readonly syntaxHighlighters?: readonly _lezer_highlight.Highlighter[];
23
28
  }
24
29
  /**
25
30
  * Configuration for the preview renderer
@@ -37,6 +42,8 @@ interface PreviewConfig {
37
42
  sanitize?: boolean;
38
43
  /** Theme to use */
39
44
  theme?: ThemeEnum;
45
+ /** CodeMirror syntax theme input used for static preview highlighting */
46
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
40
47
  }
41
48
  /**
42
49
  * Result of CSS generation
@@ -50,6 +57,8 @@ interface GenerateCSSConfig {
50
57
  wrapperClass?: string;
51
58
  /** Include base styles */
52
59
  includeBase?: boolean;
60
+ /** CodeMirror syntax theme input used for static preview syntax highlighting */
61
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
53
62
  }
54
63
  /**
55
64
  * Node renderer function type
@@ -100,6 +109,11 @@ declare function preview(markdown: string, config?: PreviewConfig): Promise<stri
100
109
  */
101
110
  declare function generateCSS(config?: GenerateCSSConfig): string;
102
111
 
112
+ /**
113
+ * Extract syntax highlight CSS from resolved CodeMirror HighlightStyle modules.
114
+ */
115
+ declare function generateSyntaxThemeCSS(syntaxTheme: SyntaxThemeInput | SyntaxThemeInput[] | undefined, _wrapperClass: string): string;
116
+
103
117
  /**
104
118
  * Escape HTML special characters
105
119
  */
@@ -118,10 +132,11 @@ declare class PreviewRenderer {
118
132
  private plugins;
119
133
  private markdown;
120
134
  private sanitizeHtml;
135
+ private syntaxTheme;
121
136
  private renderers;
122
137
  private ctx;
123
138
  private nodeToPlugins;
124
- constructor(doc: string, plugins: DraftlyPlugin[] | undefined, markdown: MarkdownConfig[], theme?: ThemeEnum, sanitize?: boolean);
139
+ constructor(doc: string, plugins: DraftlyPlugin[] | undefined, markdown: MarkdownConfig[], theme?: ThemeEnum, sanitize?: boolean, syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[]);
125
140
  /**
126
141
  * Build a map from node names to plugins that handle them
127
142
  */
@@ -140,4 +155,4 @@ declare class PreviewRenderer {
140
155
  private renderChildren;
141
156
  }
142
157
 
143
- export { type GenerateCSSConfig, type NodeRenderer, type NodeRendererMap, type PreviewConfig, type PreviewContext, PreviewRenderer, defaultRenderers, escapeHtml, generateCSS, preview };
158
+ export { type GenerateCSSConfig, type NodeRenderer, type NodeRendererMap, type PreviewConfig, type PreviewContext, PreviewRenderer, type SyntaxThemeInput, defaultRenderers, escapeHtml, generateCSS, generateSyntaxThemeCSS, preview };
@@ -1,11 +1,14 @@
1
1
  import * as _lezer_markdown from '@lezer/markdown';
2
2
  import { MarkdownConfig } from '@lezer/markdown';
3
- import { d as DraftlyPlugin, T as ThemeEnum } from '../draftly-BLnx3uGX.js';
3
+ import { d as DraftlyPlugin, T as ThemeEnum } from '../draftly-BBL-AdOl.js';
4
+ import * as _lezer_highlight from '@lezer/highlight';
5
+ import * as _codemirror_state from '@codemirror/state';
6
+ import * as _codemirror_language from '@codemirror/language';
4
7
  import { SyntaxNode } from '@lezer/common';
5
- import '@codemirror/state';
6
8
  import '@codemirror/view';
7
9
  import 'style-mod';
8
10
 
11
+ type SyntaxThemeInput = _codemirror_language.HighlightStyle | _codemirror_state.Extension | readonly _codemirror_state.Extension[];
9
12
  /**
10
13
  * Context passed to plugin preview methods
11
14
  */
@@ -20,6 +23,8 @@ interface PreviewContext {
20
23
  sanitize(html: string): string;
21
24
  /** Render children of a node to HTML */
22
25
  renderChildren(node: SyntaxNode): Promise<string>;
26
+ /** Active syntax highlighters used for code rendering */
27
+ readonly syntaxHighlighters?: readonly _lezer_highlight.Highlighter[];
23
28
  }
24
29
  /**
25
30
  * Configuration for the preview renderer
@@ -37,6 +42,8 @@ interface PreviewConfig {
37
42
  sanitize?: boolean;
38
43
  /** Theme to use */
39
44
  theme?: ThemeEnum;
45
+ /** CodeMirror syntax theme input used for static preview highlighting */
46
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
40
47
  }
41
48
  /**
42
49
  * Result of CSS generation
@@ -50,6 +57,8 @@ interface GenerateCSSConfig {
50
57
  wrapperClass?: string;
51
58
  /** Include base styles */
52
59
  includeBase?: boolean;
60
+ /** CodeMirror syntax theme input used for static preview syntax highlighting */
61
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
53
62
  }
54
63
  /**
55
64
  * Node renderer function type
@@ -100,6 +109,11 @@ declare function preview(markdown: string, config?: PreviewConfig): Promise<stri
100
109
  */
101
110
  declare function generateCSS(config?: GenerateCSSConfig): string;
102
111
 
112
+ /**
113
+ * Extract syntax highlight CSS from resolved CodeMirror HighlightStyle modules.
114
+ */
115
+ declare function generateSyntaxThemeCSS(syntaxTheme: SyntaxThemeInput | SyntaxThemeInput[] | undefined, _wrapperClass: string): string;
116
+
103
117
  /**
104
118
  * Escape HTML special characters
105
119
  */
@@ -118,10 +132,11 @@ declare class PreviewRenderer {
118
132
  private plugins;
119
133
  private markdown;
120
134
  private sanitizeHtml;
135
+ private syntaxTheme;
121
136
  private renderers;
122
137
  private ctx;
123
138
  private nodeToPlugins;
124
- constructor(doc: string, plugins: DraftlyPlugin[] | undefined, markdown: MarkdownConfig[], theme?: ThemeEnum, sanitize?: boolean);
139
+ constructor(doc: string, plugins: DraftlyPlugin[] | undefined, markdown: MarkdownConfig[], theme?: ThemeEnum, sanitize?: boolean, syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[]);
125
140
  /**
126
141
  * Build a map from node names to plugins that handle them
127
142
  */
@@ -140,4 +155,4 @@ declare class PreviewRenderer {
140
155
  private renderChildren;
141
156
  }
142
157
 
143
- export { type GenerateCSSConfig, type NodeRenderer, type NodeRendererMap, type PreviewConfig, type PreviewContext, PreviewRenderer, defaultRenderers, escapeHtml, generateCSS, preview };
158
+ export { type GenerateCSSConfig, type NodeRenderer, type NodeRendererMap, type PreviewConfig, type PreviewContext, PreviewRenderer, type SyntaxThemeInput, defaultRenderers, escapeHtml, generateCSS, generateSyntaxThemeCSS, preview };
@@ -1,4 +1,5 @@
1
- export { PreviewRenderer, defaultRenderers, escapeHtml, generateCSS, preview } from '../chunk-HPSMS2WB.js';
2
- import '../chunk-DFQYXFOP.js';
1
+ export { generateCSS, preview } from '../chunk-IAXF4SJL.js';
2
+ export { PreviewRenderer, defaultRenderers, escapeHtml, generateSyntaxThemeCSS } from '../chunk-I563H35S.js';
3
+ import '../chunk-EEHILRG5.js';
3
4
  //# sourceMappingURL=index.js.map
4
5
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "draftly",
3
- "version": "1.0.7",
3
+ "version": "2.0.0",
4
4
  "description": "Core library for draftly",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -35,6 +35,7 @@
35
35
  "dompurify": "^3.3.1",
36
36
  "katex": "^0.16.28",
37
37
  "mermaid": "^11.12.2",
38
+ "node-emoji": "^2.2.0",
38
39
  "style-mod": "^4.1.3",
39
40
  "zod": "^4.3.6"
40
41
  },
@@ -63,6 +64,12 @@
63
64
  "require": "./dist/preview/index.cjs",
64
65
  "default": "./dist/preview/index.js"
65
66
  },
67
+ "./lib": {
68
+ "types": "./dist/lib/index.d.ts",
69
+ "import": "./dist/lib/index.js",
70
+ "require": "./dist/lib/index.cjs",
71
+ "default": "./dist/lib/index.js"
72
+ },
66
73
  "./src": {
67
74
  "types": "./src/index.ts",
68
75
  "default": "./src/index.ts"
@@ -156,6 +156,7 @@ export function draftly(config: DraftlyConfig = {}): Extension[] {
156
156
  extensions: markdownExtensions,
157
157
  addKeymap: true,
158
158
  completeHTMLTags: true,
159
+ pasteURLAsLink: true,
159
160
  });
160
161
 
161
162
  // Core CodeMirror extensions (in order)
@@ -214,7 +214,11 @@ export abstract class DraftlyPlugin {
214
214
  renderToHTML?(
215
215
  node: SyntaxNode,
216
216
  children: string,
217
- ctx: { sliceDoc(from: number, to: number): string; sanitize(html: string): string }
217
+ ctx: {
218
+ sliceDoc(from: number, to: number): string;
219
+ sanitize(html: string): string;
220
+ syntaxHighlighters?: readonly import("@lezer/highlight").Highlighter[];
221
+ }
218
222
  ): string | null | Promise<string | null>;
219
223
 
220
224
  /**
@@ -9,6 +9,7 @@ export const draftlyBaseTheme = EditorView.theme({
9
9
  "&.cm-draftly": {
10
10
  fontSize: "16px",
11
11
  lineHeight: "1.6",
12
+ backgroundColor: "transparent !important",
12
13
  },
13
14
 
14
15
  "&.cm-draftly .cm-content": {
@@ -59,6 +59,10 @@ export function createTheme({
59
59
  light?: ThemeStyle;
60
60
  }): (theme: ThemeEnum) => ThemeStyle {
61
61
  return (theme: ThemeEnum) => {
62
+ defaultTheme = flattenThemeStyles(defaultTheme);
63
+ darkTheme = flattenThemeStyles(darkTheme || {});
64
+ lightTheme = flattenThemeStyles(lightTheme || {});
65
+
62
66
  let style: ThemeStyle = defaultTheme;
63
67
 
64
68
  if (theme === ThemeEnum.DARK) {
@@ -73,6 +77,33 @@ export function createTheme({
73
77
  };
74
78
  }
75
79
 
80
+ export function flattenThemeStyles(themeStyles: ThemeStyle, parentSelector?: string): ThemeStyle {
81
+ const flattened: ThemeStyle = {};
82
+
83
+ for (const [selector, styles] of Object.entries(themeStyles)) {
84
+ if (typeof styles === "object" && !Array.isArray(styles)) {
85
+ // Flatten nested styles
86
+ const fullSelector = fixSelector(parentSelector ? `${parentSelector} ${selector}` : selector);
87
+ const nestedStyles = flattenThemeStyles(styles as ThemeStyle, fullSelector);
88
+ Object.assign(flattened, nestedStyles);
89
+ } else {
90
+ // Add styles to the flattened object
91
+ if (parentSelector) {
92
+ flattened[parentSelector] = { ...flattened[parentSelector], [selector]: styles };
93
+ } else {
94
+ flattened[selector] = styles as StyleSpec;
95
+ }
96
+ }
97
+ }
98
+
99
+ return flattened;
100
+ }
101
+
102
+ export function fixSelector(selector: string): string {
103
+ // Replace all occurrences of "&" with the parent selector
104
+ return selector.replace(/\s&/g, "");
105
+ }
106
+
76
107
  /**
77
108
  * Check if cursor is within the given range
78
109
  */
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- // Re-export everything for backward compatibility
2
- export * from "./editor";
3
- export * from "./plugins";
4
- export * from "./preview";
1
+ // Re-export everything for backward compatibility
2
+ export * from "./editor";
3
+ export * from "./plugins";
4
+ export * from "./preview";
5
+ export * from "./lib";
@@ -0,0 +1,2 @@
1
+ export { createWrapSelectionInputHandler } from "./input-handler";
2
+ export type { WrapSelectionMarkerMap } from "./input-handler";
@@ -0,0 +1,45 @@
1
+ import { EditorSelection, Extension } from "@codemirror/state";
2
+ import { EditorView } from "@codemirror/view";
3
+
4
+ /**
5
+ * Mapping of typed input characters to surrounding markers.
6
+ *
7
+ * Example:
8
+ * { "*": "*", "=": "==" }
9
+ */
10
+ export type WrapSelectionMarkerMap = Record<string, string>;
11
+
12
+ /**
13
+ * Creates an input handler that wraps non-empty selections with markdown markers
14
+ * when a mapped character is typed.
15
+ */
16
+ export function createWrapSelectionInputHandler(markersByInput: WrapSelectionMarkerMap): Extension {
17
+ return EditorView.inputHandler.of((view, _from, _to, text) => {
18
+ const marker = markersByInput[text];
19
+ if (!marker) {
20
+ return false;
21
+ }
22
+
23
+ const ranges = view.state.selection.ranges;
24
+ if (ranges.length === 0 || ranges.some((range) => range.empty)) {
25
+ return false;
26
+ }
27
+
28
+ const changes = ranges
29
+ .map((range) => ({
30
+ from: range.from,
31
+ to: range.to,
32
+ insert: `${marker}${view.state.sliceDoc(range.from, range.to)}${marker}`,
33
+ }))
34
+ .reverse();
35
+
36
+ const nextRanges = ranges.map((range) => EditorSelection.range(range.from + marker.length, range.to + marker.length));
37
+
38
+ view.dispatch({
39
+ changes,
40
+ selection: EditorSelection.create(nextRanges, view.state.selection.mainIndex),
41
+ });
42
+
43
+ return true;
44
+ });
45
+ }