@noirmd/previewer 1.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.
- package/dist/NReditor.d.mts +29 -0
- package/dist/NReditor.d.ts +29 -0
- package/dist/NReditor.js +2375 -0
- package/dist/NReditor.js.map +1 -0
- package/dist/NReditor.mjs +2344 -0
- package/dist/NReditor.mjs.map +1 -0
- package/dist/index.d.mts +219 -0
- package/dist/index.d.ts +219 -0
- package/dist/index.js +12041 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12015 -0
- package/dist/index.mjs.map +1 -0
- package/dist/markdown.css +344 -0
- package/markdown.css +344 -0
- package/package.json +106 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface NRpreviewerProps {
|
|
4
|
+
/** Markdown string to render */
|
|
5
|
+
content?: string;
|
|
6
|
+
/** Raw HTML string to render (used when content is not provided) */
|
|
7
|
+
html?: string;
|
|
8
|
+
/** Inject Tailwind v4 browser CDN at runtime for directive styling. Default: false */
|
|
9
|
+
tailwindCDN?: boolean;
|
|
10
|
+
/** Additional CSS class on the wrapper element */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Inline styles on the wrapper element */
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* NRpreviewer — drop-in markdown/HTML preview component.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { NRpreviewer } from '@noirmd/previewer';
|
|
21
|
+
* import '@noirmd/previewer/markdown.css';
|
|
22
|
+
*
|
|
23
|
+
* <NRpreviewer content="# Hello **world**" />
|
|
24
|
+
* <NRpreviewer content=":::note Title\nContent\n:::" tailwindCDN />
|
|
25
|
+
* <NRpreviewer html="<h1>Raw HTML</h1>" />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare const NRpreviewer: React.FC<NRpreviewerProps>;
|
|
29
|
+
|
|
30
|
+
interface CustomMarkdownRendererProps {
|
|
31
|
+
content: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* V2 CustomMarkdownRenderer — main orchestrator.
|
|
35
|
+
*
|
|
36
|
+
* Pipeline:
|
|
37
|
+
* content (string)
|
|
38
|
+
* → parseMarkdown() → allElements (Token[])
|
|
39
|
+
* → processAndRenderElements() → React tree
|
|
40
|
+
*
|
|
41
|
+
* Note: Tailwind CDN injection is NOT handled here.
|
|
42
|
+
* Use NRpreviewer (which wraps this) or call useLazyTailwindCDN yourself.
|
|
43
|
+
*/
|
|
44
|
+
declare const CustomMarkdownRenderer: React.FC<CustomMarkdownRendererProps>;
|
|
45
|
+
|
|
46
|
+
interface HeaderToken {
|
|
47
|
+
type: 'header';
|
|
48
|
+
level: number;
|
|
49
|
+
text: string;
|
|
50
|
+
id: string;
|
|
51
|
+
classes?: string;
|
|
52
|
+
}
|
|
53
|
+
interface ParagraphToken {
|
|
54
|
+
type: 'paragraph';
|
|
55
|
+
content: string;
|
|
56
|
+
align?: 'center' | 'right';
|
|
57
|
+
classes?: string;
|
|
58
|
+
id?: string;
|
|
59
|
+
}
|
|
60
|
+
interface CodeblockToken {
|
|
61
|
+
type: 'codeblock';
|
|
62
|
+
language: string;
|
|
63
|
+
content: string;
|
|
64
|
+
title?: string;
|
|
65
|
+
}
|
|
66
|
+
interface DirectiveToken {
|
|
67
|
+
type: 'directive';
|
|
68
|
+
directiveType: string;
|
|
69
|
+
props: Record<string, string>;
|
|
70
|
+
slots: Record<string, string>;
|
|
71
|
+
scopeId: string;
|
|
72
|
+
}
|
|
73
|
+
interface HtmlToken {
|
|
74
|
+
type: 'html';
|
|
75
|
+
content: string;
|
|
76
|
+
scopeId: string;
|
|
77
|
+
}
|
|
78
|
+
interface HtmlBlockToken {
|
|
79
|
+
type: 'html-block';
|
|
80
|
+
tag: string;
|
|
81
|
+
attrs: string;
|
|
82
|
+
children: Token[];
|
|
83
|
+
}
|
|
84
|
+
interface ImageToken {
|
|
85
|
+
type: 'image';
|
|
86
|
+
alt: string;
|
|
87
|
+
src: string;
|
|
88
|
+
style: React.CSSProperties;
|
|
89
|
+
}
|
|
90
|
+
interface TableToken {
|
|
91
|
+
type: 'table';
|
|
92
|
+
content: string;
|
|
93
|
+
}
|
|
94
|
+
interface ListToken {
|
|
95
|
+
type: 'list';
|
|
96
|
+
content: string;
|
|
97
|
+
}
|
|
98
|
+
interface BlockquoteToken {
|
|
99
|
+
type: 'blockquote';
|
|
100
|
+
content: string;
|
|
101
|
+
classes?: string;
|
|
102
|
+
id?: string;
|
|
103
|
+
}
|
|
104
|
+
interface HrToken {
|
|
105
|
+
type: 'hr';
|
|
106
|
+
}
|
|
107
|
+
interface TocToken {
|
|
108
|
+
type: 'toc';
|
|
109
|
+
}
|
|
110
|
+
type Token = HeaderToken | ParagraphToken | CodeblockToken | DirectiveToken | HtmlToken | HtmlBlockToken | ImageToken | TableToken | ListToken | BlockquoteToken | HrToken | TocToken;
|
|
111
|
+
interface RenderContext {
|
|
112
|
+
modals: Record<string, boolean>;
|
|
113
|
+
setModals: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
|
|
114
|
+
articleClass: string;
|
|
115
|
+
allElements: Token[];
|
|
116
|
+
parseMarkdown: (md: string) => Token[];
|
|
117
|
+
renderElement: (element: Token, index: number, depth?: number) => React.ReactNode;
|
|
118
|
+
renderInline: (text: string) => React.ReactNode;
|
|
119
|
+
processAndRenderElements: (elements: Token[], depth?: number) => React.ReactNode[];
|
|
120
|
+
}
|
|
121
|
+
type DirectiveComponent = React.FC<DirectiveComponentProps>;
|
|
122
|
+
interface DirectiveComponentProps {
|
|
123
|
+
/** The directive type string, e.g. 'card', 'note', 'modal' */
|
|
124
|
+
directiveType: string;
|
|
125
|
+
/** Parsed key="value" attributes from the {props} block */
|
|
126
|
+
props: Record<string, string>;
|
|
127
|
+
/** Named slots → raw content strings (to be parsed recursively) */
|
|
128
|
+
slots: Record<string, string>;
|
|
129
|
+
/** Convenience: render a named slot as parsed markdown */
|
|
130
|
+
renderSlot: (name: string) => React.ReactNode;
|
|
131
|
+
/** Full render context access */
|
|
132
|
+
context: RenderContext;
|
|
133
|
+
/** Position index in the parent element list */
|
|
134
|
+
index: string | number;
|
|
135
|
+
/** Full parsed AST */
|
|
136
|
+
allElements: Token[];
|
|
137
|
+
/** Extra flags from the orchestrator */
|
|
138
|
+
options?: Record<string, any>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* V2 Markdown Parser — line-by-line state machine.
|
|
143
|
+
*/
|
|
144
|
+
declare function parseMarkdown(markdown: string): Token[];
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Extract all header tokens from an AST for TOC generation.
|
|
148
|
+
*/
|
|
149
|
+
declare function extractHeaders(elements: Token[]): Token[];
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* useDebounce — delays updating a value until after a specified delay.
|
|
153
|
+
* Useful for reducing expensive operations (like preview rendering) during rapid input.
|
|
154
|
+
*/
|
|
155
|
+
declare function useDebounce<T>(value: T, delay: number): T;
|
|
156
|
+
|
|
157
|
+
interface IconRendererProps {
|
|
158
|
+
iconName: string;
|
|
159
|
+
extraClasses?: string;
|
|
160
|
+
}
|
|
161
|
+
declare const IconRenderer: React.FC<IconRendererProps>;
|
|
162
|
+
interface CodeBlockProps {
|
|
163
|
+
code: string;
|
|
164
|
+
language: string;
|
|
165
|
+
title?: string;
|
|
166
|
+
}
|
|
167
|
+
declare const CodeBlock: React.FC<CodeBlockProps>;
|
|
168
|
+
interface AdmonitionProps {
|
|
169
|
+
type: string;
|
|
170
|
+
title?: string;
|
|
171
|
+
icon?: string;
|
|
172
|
+
className?: string;
|
|
173
|
+
style?: React.CSSProperties;
|
|
174
|
+
children: React.ReactNode;
|
|
175
|
+
}
|
|
176
|
+
declare const Admonition: React.FC<AdmonitionProps>;
|
|
177
|
+
interface DetailsProps {
|
|
178
|
+
title: string;
|
|
179
|
+
icon?: string;
|
|
180
|
+
defaultOpen?: boolean;
|
|
181
|
+
className?: string;
|
|
182
|
+
style?: React.CSSProperties;
|
|
183
|
+
children: React.ReactNode;
|
|
184
|
+
}
|
|
185
|
+
declare const Details: React.FC<DetailsProps>;
|
|
186
|
+
interface ModalProps {
|
|
187
|
+
title: string;
|
|
188
|
+
isOpen: boolean;
|
|
189
|
+
onClose: () => void;
|
|
190
|
+
children: React.ReactNode;
|
|
191
|
+
}
|
|
192
|
+
declare const Modal: React.FC<ModalProps>;
|
|
193
|
+
|
|
194
|
+
declare global {
|
|
195
|
+
interface Window {
|
|
196
|
+
__twCDNRefs?: number;
|
|
197
|
+
tailwind?: {
|
|
198
|
+
config: object;
|
|
199
|
+
scan?: () => void;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Lazy CDN hook — only loads the Tailwind Browser CDN when `enabled` is true.
|
|
205
|
+
* Call this from the component that hosts the preview panel.
|
|
206
|
+
*/
|
|
207
|
+
declare function useLazyTailwindCDN(enabled: boolean): void;
|
|
208
|
+
/**
|
|
209
|
+
* Trigger a Tailwind CDN re-scan (use after DOM mutations with new classes).
|
|
210
|
+
*/
|
|
211
|
+
declare function scanTailwindCDN(): void;
|
|
212
|
+
/**
|
|
213
|
+
* Preload the Tailwind Browser CDN right after page load.
|
|
214
|
+
* Uses requestIdleCallback so it doesn't block the main thread.
|
|
215
|
+
* By the time the user opens preview, the CDN is already loaded.
|
|
216
|
+
*/
|
|
217
|
+
declare function preloadTailwindCDN(): void;
|
|
218
|
+
|
|
219
|
+
export { Admonition, CodeBlock, CustomMarkdownRenderer, Details, type DirectiveComponent, type DirectiveComponentProps, IconRenderer, Modal, NRpreviewer, type NRpreviewerProps, type RenderContext, type Token, extractHeaders, parseMarkdown, preloadTailwindCDN, scanTailwindCDN, useDebounce, useLazyTailwindCDN };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface NRpreviewerProps {
|
|
4
|
+
/** Markdown string to render */
|
|
5
|
+
content?: string;
|
|
6
|
+
/** Raw HTML string to render (used when content is not provided) */
|
|
7
|
+
html?: string;
|
|
8
|
+
/** Inject Tailwind v4 browser CDN at runtime for directive styling. Default: false */
|
|
9
|
+
tailwindCDN?: boolean;
|
|
10
|
+
/** Additional CSS class on the wrapper element */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Inline styles on the wrapper element */
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* NRpreviewer — drop-in markdown/HTML preview component.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { NRpreviewer } from '@noirmd/previewer';
|
|
21
|
+
* import '@noirmd/previewer/markdown.css';
|
|
22
|
+
*
|
|
23
|
+
* <NRpreviewer content="# Hello **world**" />
|
|
24
|
+
* <NRpreviewer content=":::note Title\nContent\n:::" tailwindCDN />
|
|
25
|
+
* <NRpreviewer html="<h1>Raw HTML</h1>" />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare const NRpreviewer: React.FC<NRpreviewerProps>;
|
|
29
|
+
|
|
30
|
+
interface CustomMarkdownRendererProps {
|
|
31
|
+
content: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* V2 CustomMarkdownRenderer — main orchestrator.
|
|
35
|
+
*
|
|
36
|
+
* Pipeline:
|
|
37
|
+
* content (string)
|
|
38
|
+
* → parseMarkdown() → allElements (Token[])
|
|
39
|
+
* → processAndRenderElements() → React tree
|
|
40
|
+
*
|
|
41
|
+
* Note: Tailwind CDN injection is NOT handled here.
|
|
42
|
+
* Use NRpreviewer (which wraps this) or call useLazyTailwindCDN yourself.
|
|
43
|
+
*/
|
|
44
|
+
declare const CustomMarkdownRenderer: React.FC<CustomMarkdownRendererProps>;
|
|
45
|
+
|
|
46
|
+
interface HeaderToken {
|
|
47
|
+
type: 'header';
|
|
48
|
+
level: number;
|
|
49
|
+
text: string;
|
|
50
|
+
id: string;
|
|
51
|
+
classes?: string;
|
|
52
|
+
}
|
|
53
|
+
interface ParagraphToken {
|
|
54
|
+
type: 'paragraph';
|
|
55
|
+
content: string;
|
|
56
|
+
align?: 'center' | 'right';
|
|
57
|
+
classes?: string;
|
|
58
|
+
id?: string;
|
|
59
|
+
}
|
|
60
|
+
interface CodeblockToken {
|
|
61
|
+
type: 'codeblock';
|
|
62
|
+
language: string;
|
|
63
|
+
content: string;
|
|
64
|
+
title?: string;
|
|
65
|
+
}
|
|
66
|
+
interface DirectiveToken {
|
|
67
|
+
type: 'directive';
|
|
68
|
+
directiveType: string;
|
|
69
|
+
props: Record<string, string>;
|
|
70
|
+
slots: Record<string, string>;
|
|
71
|
+
scopeId: string;
|
|
72
|
+
}
|
|
73
|
+
interface HtmlToken {
|
|
74
|
+
type: 'html';
|
|
75
|
+
content: string;
|
|
76
|
+
scopeId: string;
|
|
77
|
+
}
|
|
78
|
+
interface HtmlBlockToken {
|
|
79
|
+
type: 'html-block';
|
|
80
|
+
tag: string;
|
|
81
|
+
attrs: string;
|
|
82
|
+
children: Token[];
|
|
83
|
+
}
|
|
84
|
+
interface ImageToken {
|
|
85
|
+
type: 'image';
|
|
86
|
+
alt: string;
|
|
87
|
+
src: string;
|
|
88
|
+
style: React.CSSProperties;
|
|
89
|
+
}
|
|
90
|
+
interface TableToken {
|
|
91
|
+
type: 'table';
|
|
92
|
+
content: string;
|
|
93
|
+
}
|
|
94
|
+
interface ListToken {
|
|
95
|
+
type: 'list';
|
|
96
|
+
content: string;
|
|
97
|
+
}
|
|
98
|
+
interface BlockquoteToken {
|
|
99
|
+
type: 'blockquote';
|
|
100
|
+
content: string;
|
|
101
|
+
classes?: string;
|
|
102
|
+
id?: string;
|
|
103
|
+
}
|
|
104
|
+
interface HrToken {
|
|
105
|
+
type: 'hr';
|
|
106
|
+
}
|
|
107
|
+
interface TocToken {
|
|
108
|
+
type: 'toc';
|
|
109
|
+
}
|
|
110
|
+
type Token = HeaderToken | ParagraphToken | CodeblockToken | DirectiveToken | HtmlToken | HtmlBlockToken | ImageToken | TableToken | ListToken | BlockquoteToken | HrToken | TocToken;
|
|
111
|
+
interface RenderContext {
|
|
112
|
+
modals: Record<string, boolean>;
|
|
113
|
+
setModals: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
|
|
114
|
+
articleClass: string;
|
|
115
|
+
allElements: Token[];
|
|
116
|
+
parseMarkdown: (md: string) => Token[];
|
|
117
|
+
renderElement: (element: Token, index: number, depth?: number) => React.ReactNode;
|
|
118
|
+
renderInline: (text: string) => React.ReactNode;
|
|
119
|
+
processAndRenderElements: (elements: Token[], depth?: number) => React.ReactNode[];
|
|
120
|
+
}
|
|
121
|
+
type DirectiveComponent = React.FC<DirectiveComponentProps>;
|
|
122
|
+
interface DirectiveComponentProps {
|
|
123
|
+
/** The directive type string, e.g. 'card', 'note', 'modal' */
|
|
124
|
+
directiveType: string;
|
|
125
|
+
/** Parsed key="value" attributes from the {props} block */
|
|
126
|
+
props: Record<string, string>;
|
|
127
|
+
/** Named slots → raw content strings (to be parsed recursively) */
|
|
128
|
+
slots: Record<string, string>;
|
|
129
|
+
/** Convenience: render a named slot as parsed markdown */
|
|
130
|
+
renderSlot: (name: string) => React.ReactNode;
|
|
131
|
+
/** Full render context access */
|
|
132
|
+
context: RenderContext;
|
|
133
|
+
/** Position index in the parent element list */
|
|
134
|
+
index: string | number;
|
|
135
|
+
/** Full parsed AST */
|
|
136
|
+
allElements: Token[];
|
|
137
|
+
/** Extra flags from the orchestrator */
|
|
138
|
+
options?: Record<string, any>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* V2 Markdown Parser — line-by-line state machine.
|
|
143
|
+
*/
|
|
144
|
+
declare function parseMarkdown(markdown: string): Token[];
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Extract all header tokens from an AST for TOC generation.
|
|
148
|
+
*/
|
|
149
|
+
declare function extractHeaders(elements: Token[]): Token[];
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* useDebounce — delays updating a value until after a specified delay.
|
|
153
|
+
* Useful for reducing expensive operations (like preview rendering) during rapid input.
|
|
154
|
+
*/
|
|
155
|
+
declare function useDebounce<T>(value: T, delay: number): T;
|
|
156
|
+
|
|
157
|
+
interface IconRendererProps {
|
|
158
|
+
iconName: string;
|
|
159
|
+
extraClasses?: string;
|
|
160
|
+
}
|
|
161
|
+
declare const IconRenderer: React.FC<IconRendererProps>;
|
|
162
|
+
interface CodeBlockProps {
|
|
163
|
+
code: string;
|
|
164
|
+
language: string;
|
|
165
|
+
title?: string;
|
|
166
|
+
}
|
|
167
|
+
declare const CodeBlock: React.FC<CodeBlockProps>;
|
|
168
|
+
interface AdmonitionProps {
|
|
169
|
+
type: string;
|
|
170
|
+
title?: string;
|
|
171
|
+
icon?: string;
|
|
172
|
+
className?: string;
|
|
173
|
+
style?: React.CSSProperties;
|
|
174
|
+
children: React.ReactNode;
|
|
175
|
+
}
|
|
176
|
+
declare const Admonition: React.FC<AdmonitionProps>;
|
|
177
|
+
interface DetailsProps {
|
|
178
|
+
title: string;
|
|
179
|
+
icon?: string;
|
|
180
|
+
defaultOpen?: boolean;
|
|
181
|
+
className?: string;
|
|
182
|
+
style?: React.CSSProperties;
|
|
183
|
+
children: React.ReactNode;
|
|
184
|
+
}
|
|
185
|
+
declare const Details: React.FC<DetailsProps>;
|
|
186
|
+
interface ModalProps {
|
|
187
|
+
title: string;
|
|
188
|
+
isOpen: boolean;
|
|
189
|
+
onClose: () => void;
|
|
190
|
+
children: React.ReactNode;
|
|
191
|
+
}
|
|
192
|
+
declare const Modal: React.FC<ModalProps>;
|
|
193
|
+
|
|
194
|
+
declare global {
|
|
195
|
+
interface Window {
|
|
196
|
+
__twCDNRefs?: number;
|
|
197
|
+
tailwind?: {
|
|
198
|
+
config: object;
|
|
199
|
+
scan?: () => void;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Lazy CDN hook — only loads the Tailwind Browser CDN when `enabled` is true.
|
|
205
|
+
* Call this from the component that hosts the preview panel.
|
|
206
|
+
*/
|
|
207
|
+
declare function useLazyTailwindCDN(enabled: boolean): void;
|
|
208
|
+
/**
|
|
209
|
+
* Trigger a Tailwind CDN re-scan (use after DOM mutations with new classes).
|
|
210
|
+
*/
|
|
211
|
+
declare function scanTailwindCDN(): void;
|
|
212
|
+
/**
|
|
213
|
+
* Preload the Tailwind Browser CDN right after page load.
|
|
214
|
+
* Uses requestIdleCallback so it doesn't block the main thread.
|
|
215
|
+
* By the time the user opens preview, the CDN is already loaded.
|
|
216
|
+
*/
|
|
217
|
+
declare function preloadTailwindCDN(): void;
|
|
218
|
+
|
|
219
|
+
export { Admonition, CodeBlock, CustomMarkdownRenderer, Details, type DirectiveComponent, type DirectiveComponentProps, IconRenderer, Modal, NRpreviewer, type NRpreviewerProps, type RenderContext, type Token, extractHeaders, parseMarkdown, preloadTailwindCDN, scanTailwindCDN, useDebounce, useLazyTailwindCDN };
|