@editorcn/static-renderer 0.1.0 → 0.2.1

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/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  module.exports = __toCommonJS(index_exports);
26
26
 
27
27
  // src/static-renderer.tsx
28
+ var import_static_renderer = require("@tiptap/static-renderer");
28
29
  var import_react = require("react");
29
30
 
30
31
  // src/lib/utils.ts
@@ -33,16 +34,41 @@ var import_tailwind_merge = require("tailwind-merge");
33
34
  var cn = (...inputs) => (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
34
35
 
35
36
  // src/static-renderer.tsx
37
+ var resolveUniqueExtensions = (extensions) => {
38
+ const byName = /* @__PURE__ */ new Map();
39
+ for (const extension of extensions) {
40
+ byName.set(extension.name, extension);
41
+ }
42
+ return [...byName.values()];
43
+ };
36
44
  var StaticRenderer = ({
37
45
  as: Tag = "div",
38
46
  className,
39
47
  content,
48
+ extensions,
49
+ staticEditorOptions,
50
+ options,
40
51
  ...props
41
- }) => (0, import_react.createElement)(Tag, {
42
- ...props,
43
- className: cn("rte-static-renderer", className),
44
- dangerouslySetInnerHTML: { __html: content }
45
- });
52
+ }) => {
53
+ if (typeof content === "string") {
54
+ return (0, import_react.createElement)(Tag, {
55
+ ...props,
56
+ className: cn("rte-static-renderer", className),
57
+ dangerouslySetInnerHTML: { __html: content }
58
+ });
59
+ }
60
+ const children = (0, import_static_renderer.renderToReactElement)({
61
+ content,
62
+ extensions: resolveUniqueExtensions(extensions ?? []),
63
+ options,
64
+ staticEditorOptions
65
+ });
66
+ return (0, import_react.createElement)(
67
+ Tag,
68
+ { ...props, className: cn("rte-static-renderer", className) },
69
+ children
70
+ );
71
+ };
46
72
  // Annotate the CommonJS export names for ESM import in node:
47
73
  0 && (module.exports = {
48
74
  StaticRenderer
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/static-renderer.tsx","../src/lib/utils.ts"],"sourcesContent":["export * from \"./static-renderer\";\n","import type { ElementType, HTMLAttributes } from \"react\";\nimport { createElement } from \"react\";\n\nimport { cn } from \"./lib/utils\";\n\nexport type StaticRendererProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"dangerouslySetInnerHTML\"\n> & {\n /**\n * HTML produced by `editor.getHTML()` from either `@editorcn/editor` or\n * `@editorcn/block-editor`. Rendered read-only.\n */\n content: string;\n /**\n * Element used as the renderer's root. Defaults to `\"div\"`.\n */\n as?: ElementType;\n};\n\nexport const StaticRenderer = ({\n as: Tag = \"div\",\n className,\n content,\n ...props\n}: StaticRendererProps) =>\n createElement(Tag, {\n ...props,\n className: cn(\"rte-static-renderer\", className),\n dangerouslySetInnerHTML: { __html: content },\n });\n","import { clsx } from \"clsx\";\nimport type { ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,mBAA8B;;;ACD9B,kBAAqB;AAErB,4BAAwB;AAEjB,IAAM,KAAK,IAAI,eAAyB,mCAAQ,kBAAK,MAAM,CAAC;;;ADgB5D,IAAM,iBAAiB,CAAC;AAAA,EAC7B,IAAI,MAAM;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,UACE,4BAAc,KAAK;AAAA,EACjB,GAAG;AAAA,EACH,WAAW,GAAG,uBAAuB,SAAS;AAAA,EAC9C,yBAAyB,EAAE,QAAQ,QAAQ;AAC7C,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/static-renderer.tsx","../src/lib/utils.ts"],"sourcesContent":["export * from \"./static-renderer\";\r\n","import type { Extensions, JSONContent } from \"@tiptap/core\";\nimport type { Mark, Node } from \"@tiptap/pm/model\";\nimport { renderToReactElement } from \"@tiptap/static-renderer\";\nimport type {\n StaticEditorOptions,\n TiptapStaticRendererOptions,\n} from \"@tiptap/static-renderer\";\nimport { createElement } from \"react\";\nimport type { ElementType, HTMLAttributes, ReactNode } from \"react\";\n\nimport { cn } from \"./lib/utils\";\n\nconst resolveUniqueExtensions = (extensions: Extensions) => {\n const byName = new Map<string, (typeof extensions)[number]>();\n for (const extension of extensions) {\n byName.set(extension.name, extension);\n }\n return [...byName.values()];\n};\n\nexport type StaticRendererProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"content\" | \"dangerouslySetInnerHTML\"\n> & {\n // HTML from editor.getHTML() rendered read-only, or a ProseMirror JSON document.\n content: string | JSONContent | Node;\n // Root element, defaults to \"div\".\n as?: ElementType;\n // Tiptap extensions used to render JSON content; every node/mark in the document must be registered.\n extensions?: Extensions;\n // Editor-level options applied while rendering JSON.\n staticEditorOptions?: StaticEditorOptions;\n // renderToReactElement options — nodeMapping/markMapping for custom nodes.\n options?: Partial<TiptapStaticRendererOptions<ReactNode, Mark, Node>>;\n};\n\nexport const StaticRenderer = ({\n as: Tag = \"div\",\n className,\n content,\n extensions,\n staticEditorOptions,\n options,\n ...props\n}: StaticRendererProps) => {\n if (typeof content === \"string\") {\n return createElement(Tag, {\n ...props,\n className: cn(\"rte-static-renderer\", className),\n dangerouslySetInnerHTML: { __html: content },\n });\n }\n\n const children = renderToReactElement({\n content,\n extensions: resolveUniqueExtensions(extensions ?? []),\n options,\n staticEditorOptions,\n });\n\n return createElement(\n Tag,\n { ...props, className: cn(\"rte-static-renderer\", className) },\n children\n );\n};\n","import { clsx } from \"clsx\";\r\nimport type { ClassValue } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,6BAAqC;AAKrC,mBAA8B;;;ACP9B,kBAAqB;AAErB,4BAAwB;AAEjB,IAAM,KAAK,IAAI,eAAyB,mCAAQ,kBAAK,MAAM,CAAC;;;ADQnE,IAAM,0BAA0B,CAAC,eAA2B;AAC1D,QAAM,SAAS,oBAAI,IAAyC;AAC5D,aAAW,aAAa,YAAY;AAClC,WAAO,IAAI,UAAU,MAAM,SAAS;AAAA,EACtC;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AAkBO,IAAM,iBAAiB,CAAC;AAAA,EAC7B,IAAI,MAAM;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA2B;AACzB,MAAI,OAAO,YAAY,UAAU;AAC/B,eAAO,4BAAc,KAAK;AAAA,MACxB,GAAG;AAAA,MACH,WAAW,GAAG,uBAAuB,SAAS;AAAA,MAC9C,yBAAyB,EAAE,QAAQ,QAAQ;AAAA,IAC7C,CAAC;AAAA,EACH;AAEA,QAAM,eAAW,6CAAqB;AAAA,IACpC;AAAA,IACA,YAAY,wBAAwB,cAAc,CAAC,CAAC;AAAA,IACpD;AAAA,IACA;AAAA,EACF,CAAC;AAED,aAAO;AAAA,IACL;AAAA,IACA,EAAE,GAAG,OAAO,WAAW,GAAG,uBAAuB,SAAS,EAAE;AAAA,IAC5D;AAAA,EACF;AACF;","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,17 +1,16 @@
1
1
  import * as react from 'react';
2
- import { HTMLAttributes, ElementType } from 'react';
2
+ import { HTMLAttributes, ElementType, ReactNode } from 'react';
3
+ import { JSONContent, Extensions } from '@tiptap/core';
4
+ import { Node, Mark } from '@tiptap/pm/model';
5
+ import { StaticEditorOptions, TiptapStaticRendererOptions } from '@tiptap/static-renderer';
3
6
 
4
- type StaticRendererProps = Omit<HTMLAttributes<HTMLElement>, "dangerouslySetInnerHTML"> & {
5
- /**
6
- * HTML produced by `editor.getHTML()` from either `@editorcn/editor` or
7
- * `@editorcn/block-editor`. Rendered read-only.
8
- */
9
- content: string;
10
- /**
11
- * Element used as the renderer's root. Defaults to `"div"`.
12
- */
7
+ type StaticRendererProps = Omit<HTMLAttributes<HTMLElement>, "content" | "dangerouslySetInnerHTML"> & {
8
+ content: string | JSONContent | Node;
13
9
  as?: ElementType;
10
+ extensions?: Extensions;
11
+ staticEditorOptions?: StaticEditorOptions;
12
+ options?: Partial<TiptapStaticRendererOptions<ReactNode, Mark, Node>>;
14
13
  };
15
- declare const StaticRenderer: ({ as: Tag, className, content, ...props }: StaticRendererProps) => react.ReactElement<any, string | react.JSXElementConstructor<any>>;
14
+ declare const StaticRenderer: ({ as: Tag, className, content, extensions, staticEditorOptions, options, ...props }: StaticRendererProps) => react.ReactElement<any, string | react.JSXElementConstructor<any>>;
16
15
 
17
16
  export { StaticRenderer, type StaticRendererProps };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,16 @@
1
1
  import * as react from 'react';
2
- import { HTMLAttributes, ElementType } from 'react';
2
+ import { HTMLAttributes, ElementType, ReactNode } from 'react';
3
+ import { JSONContent, Extensions } from '@tiptap/core';
4
+ import { Node, Mark } from '@tiptap/pm/model';
5
+ import { StaticEditorOptions, TiptapStaticRendererOptions } from '@tiptap/static-renderer';
3
6
 
4
- type StaticRendererProps = Omit<HTMLAttributes<HTMLElement>, "dangerouslySetInnerHTML"> & {
5
- /**
6
- * HTML produced by `editor.getHTML()` from either `@editorcn/editor` or
7
- * `@editorcn/block-editor`. Rendered read-only.
8
- */
9
- content: string;
10
- /**
11
- * Element used as the renderer's root. Defaults to `"div"`.
12
- */
7
+ type StaticRendererProps = Omit<HTMLAttributes<HTMLElement>, "content" | "dangerouslySetInnerHTML"> & {
8
+ content: string | JSONContent | Node;
13
9
  as?: ElementType;
10
+ extensions?: Extensions;
11
+ staticEditorOptions?: StaticEditorOptions;
12
+ options?: Partial<TiptapStaticRendererOptions<ReactNode, Mark, Node>>;
14
13
  };
15
- declare const StaticRenderer: ({ as: Tag, className, content, ...props }: StaticRendererProps) => react.ReactElement<any, string | react.JSXElementConstructor<any>>;
14
+ declare const StaticRenderer: ({ as: Tag, className, content, extensions, staticEditorOptions, options, ...props }: StaticRendererProps) => react.ReactElement<any, string | react.JSXElementConstructor<any>>;
16
15
 
17
16
  export { StaticRenderer, type StaticRendererProps };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/static-renderer.tsx
2
+ import { renderToReactElement } from "@tiptap/static-renderer";
2
3
  import { createElement } from "react";
3
4
 
4
5
  // src/lib/utils.ts
@@ -7,16 +8,41 @@ import { twMerge } from "tailwind-merge";
7
8
  var cn = (...inputs) => twMerge(clsx(inputs));
8
9
 
9
10
  // src/static-renderer.tsx
11
+ var resolveUniqueExtensions = (extensions) => {
12
+ const byName = /* @__PURE__ */ new Map();
13
+ for (const extension of extensions) {
14
+ byName.set(extension.name, extension);
15
+ }
16
+ return [...byName.values()];
17
+ };
10
18
  var StaticRenderer = ({
11
19
  as: Tag = "div",
12
20
  className,
13
21
  content,
22
+ extensions,
23
+ staticEditorOptions,
24
+ options,
14
25
  ...props
15
- }) => createElement(Tag, {
16
- ...props,
17
- className: cn("rte-static-renderer", className),
18
- dangerouslySetInnerHTML: { __html: content }
19
- });
26
+ }) => {
27
+ if (typeof content === "string") {
28
+ return createElement(Tag, {
29
+ ...props,
30
+ className: cn("rte-static-renderer", className),
31
+ dangerouslySetInnerHTML: { __html: content }
32
+ });
33
+ }
34
+ const children = renderToReactElement({
35
+ content,
36
+ extensions: resolveUniqueExtensions(extensions ?? []),
37
+ options,
38
+ staticEditorOptions
39
+ });
40
+ return createElement(
41
+ Tag,
42
+ { ...props, className: cn("rte-static-renderer", className) },
43
+ children
44
+ );
45
+ };
20
46
  export {
21
47
  StaticRenderer
22
48
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/static-renderer.tsx","../src/lib/utils.ts"],"sourcesContent":["import type { ElementType, HTMLAttributes } from \"react\";\nimport { createElement } from \"react\";\n\nimport { cn } from \"./lib/utils\";\n\nexport type StaticRendererProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"dangerouslySetInnerHTML\"\n> & {\n /**\n * HTML produced by `editor.getHTML()` from either `@editorcn/editor` or\n * `@editorcn/block-editor`. Rendered read-only.\n */\n content: string;\n /**\n * Element used as the renderer's root. Defaults to `\"div\"`.\n */\n as?: ElementType;\n};\n\nexport const StaticRenderer = ({\n as: Tag = \"div\",\n className,\n content,\n ...props\n}: StaticRendererProps) =>\n createElement(Tag, {\n ...props,\n className: cn(\"rte-static-renderer\", className),\n dangerouslySetInnerHTML: { __html: content },\n });\n","import { clsx } from \"clsx\";\nimport type { ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\n"],"mappings":";AACA,SAAS,qBAAqB;;;ACD9B,SAAS,YAAY;AAErB,SAAS,eAAe;AAEjB,IAAM,KAAK,IAAI,WAAyB,QAAQ,KAAK,MAAM,CAAC;;;ADgB5D,IAAM,iBAAiB,CAAC;AAAA,EAC7B,IAAI,MAAM;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,cAAc,KAAK;AAAA,EACjB,GAAG;AAAA,EACH,WAAW,GAAG,uBAAuB,SAAS;AAAA,EAC9C,yBAAyB,EAAE,QAAQ,QAAQ;AAC7C,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/static-renderer.tsx","../src/lib/utils.ts"],"sourcesContent":["import type { Extensions, JSONContent } from \"@tiptap/core\";\nimport type { Mark, Node } from \"@tiptap/pm/model\";\nimport { renderToReactElement } from \"@tiptap/static-renderer\";\nimport type {\n StaticEditorOptions,\n TiptapStaticRendererOptions,\n} from \"@tiptap/static-renderer\";\nimport { createElement } from \"react\";\nimport type { ElementType, HTMLAttributes, ReactNode } from \"react\";\n\nimport { cn } from \"./lib/utils\";\n\nconst resolveUniqueExtensions = (extensions: Extensions) => {\n const byName = new Map<string, (typeof extensions)[number]>();\n for (const extension of extensions) {\n byName.set(extension.name, extension);\n }\n return [...byName.values()];\n};\n\nexport type StaticRendererProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"content\" | \"dangerouslySetInnerHTML\"\n> & {\n // HTML from editor.getHTML() rendered read-only, or a ProseMirror JSON document.\n content: string | JSONContent | Node;\n // Root element, defaults to \"div\".\n as?: ElementType;\n // Tiptap extensions used to render JSON content; every node/mark in the document must be registered.\n extensions?: Extensions;\n // Editor-level options applied while rendering JSON.\n staticEditorOptions?: StaticEditorOptions;\n // renderToReactElement options — nodeMapping/markMapping for custom nodes.\n options?: Partial<TiptapStaticRendererOptions<ReactNode, Mark, Node>>;\n};\n\nexport const StaticRenderer = ({\n as: Tag = \"div\",\n className,\n content,\n extensions,\n staticEditorOptions,\n options,\n ...props\n}: StaticRendererProps) => {\n if (typeof content === \"string\") {\n return createElement(Tag, {\n ...props,\n className: cn(\"rte-static-renderer\", className),\n dangerouslySetInnerHTML: { __html: content },\n });\n }\n\n const children = renderToReactElement({\n content,\n extensions: resolveUniqueExtensions(extensions ?? []),\n options,\n staticEditorOptions,\n });\n\n return createElement(\n Tag,\n { ...props, className: cn(\"rte-static-renderer\", className) },\n children\n );\n};\n","import { clsx } from \"clsx\";\r\nimport type { ClassValue } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\r\n"],"mappings":";AAEA,SAAS,4BAA4B;AAKrC,SAAS,qBAAqB;;;ACP9B,SAAS,YAAY;AAErB,SAAS,eAAe;AAEjB,IAAM,KAAK,IAAI,WAAyB,QAAQ,KAAK,MAAM,CAAC;;;ADQnE,IAAM,0BAA0B,CAAC,eAA2B;AAC1D,QAAM,SAAS,oBAAI,IAAyC;AAC5D,aAAW,aAAa,YAAY;AAClC,WAAO,IAAI,UAAU,MAAM,SAAS;AAAA,EACtC;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AAkBO,IAAM,iBAAiB,CAAC;AAAA,EAC7B,IAAI,MAAM;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA2B;AACzB,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,cAAc,KAAK;AAAA,MACxB,GAAG;AAAA,MACH,WAAW,GAAG,uBAAuB,SAAS;AAAA,MAC9C,yBAAyB,EAAE,QAAQ,QAAQ;AAAA,IAC7C,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,qBAAqB;AAAA,IACpC;AAAA,IACA,YAAY,wBAAwB,cAAc,CAAC,CAAC;AAAA,IACpD;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,EAAE,GAAG,OAAO,WAAW,GAAG,uBAAuB,SAAS,EAAE;AAAA,IAC5D;AAAA,EACF;AACF;","names":[]}
package/dist/style.css CHANGED
@@ -1,335 +1,335 @@
1
- /* Static renderer styles using shadcn CSS variables.
2
- * Targets the HTML produced by editor.getHTML() from both
3
- * @editorcn/editor and @editorcn/block-editor.
4
- */
5
- .rte-static-renderer {
6
- color: var(--foreground);
7
- }
8
-
9
- .rte-static-renderer > *:last-child {
10
- margin-bottom: 0;
11
- }
12
-
13
- /* ── Typography ── */
14
- .rte-static-renderer h1 {
15
- font-size: 1.875rem;
16
- font-weight: 700;
17
- line-height: 1.2;
18
- margin: 0.5em 0 0.25em;
19
- }
20
-
21
- .rte-static-renderer h2 {
22
- font-size: 1.5rem;
23
- font-weight: 600;
24
- line-height: 1.25;
25
- margin: 0.5em 0 0.25em;
26
- }
27
-
28
- .rte-static-renderer h3 {
29
- font-size: 1.25rem;
30
- font-weight: 600;
31
- line-height: 1.3;
32
- margin: 0.5em 0 0.25em;
33
- }
34
-
35
- .rte-static-renderer h4 {
36
- font-size: 1.125rem;
37
- font-weight: 600;
38
- line-height: 1.35;
39
- margin: 0.5em 0 0.25em;
40
- }
41
-
42
- .rte-static-renderer h5 {
43
- font-size: 1rem;
44
- font-weight: 600;
45
- line-height: 1.4;
46
- margin: 0.5em 0 0.25em;
47
- }
48
-
49
- .rte-static-renderer h6 {
50
- font-size: 0.875rem;
51
- font-weight: 600;
52
- line-height: 1.45;
53
- margin: 0.5em 0 0.25em;
54
- }
55
-
56
- .rte-static-renderer h1:first-child,
57
- .rte-static-renderer h2:first-child,
58
- .rte-static-renderer h3:first-child,
59
- .rte-static-renderer h4:first-child,
60
- .rte-static-renderer h5:first-child,
61
- .rte-static-renderer h6:first-child {
62
- margin-top: 0;
63
- }
64
-
65
- .rte-static-renderer p {
66
- margin: 0.25em 0;
67
- line-height: 1.6;
68
- }
69
-
70
- .rte-static-renderer ul {
71
- list-style-type: disc;
72
- padding-left: 1.5rem;
73
- margin: 0.25em 0;
74
- }
75
-
76
- .rte-static-renderer ul ul {
77
- list-style-type: circle;
78
- }
79
-
80
- .rte-static-renderer ul ul ul {
81
- list-style-type: square;
82
- }
83
-
84
- .rte-static-renderer ol {
85
- list-style-type: decimal;
86
- padding-left: 1.5rem;
87
- margin: 0.25em 0;
88
- }
89
-
90
- .rte-static-renderer li {
91
- margin: 0.125em 0;
92
- }
93
-
94
- .rte-static-renderer li > p {
95
- margin: 0;
96
- }
97
-
98
- .rte-static-renderer blockquote {
99
- border-left: 3px solid var(--border);
100
- padding-left: 1rem;
101
- color: var(--muted-foreground);
102
- margin: 0.5em 0;
103
- }
104
-
105
- /* ── Links ── */
106
- .rte-static-renderer a {
107
- color: var(--primary);
108
- text-decoration: underline;
109
- text-underline-offset: 4px;
110
- text-decoration-color: color-mix(in srgb, var(--primary) 40%, transparent);
111
- }
112
-
113
- /* ── Horizontal rule ── */
114
- .rte-static-renderer hr {
115
- border: none;
116
- border-top: 1px solid var(--border);
117
- margin: 1em 0;
118
- }
119
-
120
- /* ── Inline code ── */
121
- .rte-static-renderer code {
122
- font-size: 0.875em;
123
- font-weight: 500;
124
- font-family: var(--font-mono, monospace);
125
- background: color-mix(in srgb, var(--muted) 70%, transparent);
126
- padding: 0.125rem 0.375rem;
127
- border-radius: calc(var(--radius) - 4px);
128
- }
129
-
130
- /* ── Code blocks ── */
131
- .rte-static-renderer pre {
132
- background: #1e1e2e;
133
- border-radius: var(--radius);
134
- border: 1px solid var(--border);
135
- padding: 1rem;
136
- overflow-x: auto;
137
- font-size: 0.875rem;
138
- line-height: 1.5;
139
- margin: 0.5em 0;
140
- color: #cdd6f4;
141
- }
142
-
143
- .rte-static-renderer pre code {
144
- color: inherit;
145
- background: none;
146
- padding: 0;
147
- font-weight: 400;
148
- font-family: var(--font-mono, monospace);
149
- }
150
-
151
- /* ── Syntax Highlighting (lowlight / highlight.js) ── */
152
- .rte-static-renderer pre .hljs-comment,
153
- .rte-static-renderer pre .hljs-quote {
154
- color: #6c7086;
155
- }
156
-
157
- .rte-static-renderer pre .hljs-variable,
158
- .rte-static-renderer pre .hljs-template-variable,
159
- .rte-static-renderer pre .hljs-attribute,
160
- .rte-static-renderer pre .hljs-tag,
161
- .rte-static-renderer pre .hljs-regexp,
162
- .rte-static-renderer pre .hljs-link,
163
- .rte-static-renderer pre .hljs-name,
164
- .rte-static-renderer pre .hljs-selector-id,
165
- .rte-static-renderer pre .hljs-selector-class {
166
- color: #89b4fa;
167
- }
168
-
169
- .rte-static-renderer pre .hljs-number,
170
- .rte-static-renderer pre .hljs-meta,
171
- .rte-static-renderer pre .hljs-built_in,
172
- .rte-static-renderer pre .hljs-builtin-name,
173
- .rte-static-renderer pre .hljs-literal,
174
- .rte-static-renderer pre .hljs-type,
175
- .rte-static-renderer pre .hljs-params {
176
- color: #fab387;
177
- }
178
-
179
- .rte-static-renderer pre .hljs-string,
180
- .rte-static-renderer pre .hljs-symbol,
181
- .rte-static-renderer pre .hljs-bullet {
182
- color: #a6e3a1;
183
- }
184
-
185
- .rte-static-renderer pre .hljs-title,
186
- .rte-static-renderer pre .hljs-section {
187
- color: #f9e2af;
188
- }
189
-
190
- .rte-static-renderer pre .hljs-keyword,
191
- .rte-static-renderer pre .hljs-selector-tag {
192
- color: #cba6f7;
193
- }
194
-
195
- /* Object/JSON keys & HTML/XML attribute names */
196
- .rte-static-renderer pre .hljs-attr {
197
- color: #89b4fa;
198
- }
199
-
200
- /* JSDoc-style tags, e.g. @param, @returns */
201
- .rte-static-renderer pre .hljs-doctag {
202
- color: #f38ba8;
203
- font-weight: 600;
204
- }
205
-
206
- /* Operators & punctuation (finer-grained grammars) */
207
- .rte-static-renderer pre .hljs-operator,
208
- .rte-static-renderer pre .hljs-punctuation {
209
- color: #9399b2;
210
- }
211
-
212
- /* CSS selector attributes/pseudo-classes, e.g. [type="text"], :hover */
213
- .rte-static-renderer pre .hljs-selector-attr,
214
- .rte-static-renderer pre .hljs-selector-pseudo {
215
- color: #94e2d5;
216
- }
217
-
218
- /* Language-level variables, e.g. this, super */
219
- .rte-static-renderer pre .hljs-variable.language_ {
220
- color: #cba6f7;
221
- font-style: italic;
222
- }
223
-
224
- /* Template literal substitutions, e.g. ${...} */
225
- .rte-static-renderer pre .hljs-subst {
226
- color: #cdd6f4;
227
- }
228
-
229
- .rte-static-renderer pre .hljs-emphasis {
230
- font-style: italic;
231
- }
232
-
233
- .rte-static-renderer pre .hljs-strong {
234
- font-weight: 700;
235
- }
236
-
237
- .rte-static-renderer pre .hljs-addition {
238
- color: #a6e3a1;
239
- background-color: color-mix(in srgb, #a6e3a1 10%, transparent);
240
- }
241
-
242
- .rte-static-renderer pre .hljs-deletion {
243
- color: #f38ba8;
244
- background-color: color-mix(in srgb, #f38ba8 10%, transparent);
245
- }
246
-
247
- /* ── Images ── */
248
- .rte-static-renderer img {
249
- max-width: 100%;
250
- height: auto;
251
- border-radius: var(--radius);
252
- }
253
-
254
- /* ── Tables ── */
255
- .rte-static-renderer table {
256
- border-collapse: collapse;
257
- width: 100%;
258
- margin: 0.5em 0;
259
- }
260
-
261
- .rte-static-renderer th,
262
- .rte-static-renderer td {
263
- border: 1px solid var(--border);
264
- padding: 0.5rem;
265
- min-width: 100px;
266
- text-align: left;
267
- vertical-align: top;
268
- }
269
-
270
- .rte-static-renderer th {
271
- background: var(--muted);
272
- font-weight: 600;
273
- }
274
-
275
- /* Table wrapper for horizontal scroll */
276
- .rte-static-renderer .tableWrapper {
277
- overflow-x: auto;
278
- }
279
-
280
- /* ── Task lists ── */
281
- .rte-static-renderer ul[data-type="taskList"] {
282
- list-style: none;
283
- padding-left: 0;
284
- }
285
-
286
- .rte-static-renderer ul[data-type="taskList"] li {
287
- display: flex;
288
- align-items: flex-start;
289
- gap: 0.5rem;
290
- }
291
-
292
- .rte-static-renderer ul[data-type="taskList"] li > label {
293
- flex-shrink: 0;
294
- margin-top: 0.25rem;
295
- }
296
-
297
- .rte-static-renderer ul[data-type="taskList"] li > div > p {
298
- margin: 0;
299
- }
300
-
301
- .rte-static-renderer
302
- ul[data-type="taskList"]
303
- li[data-checked="true"]
304
- > div
305
- > p {
306
- text-decoration: line-through;
307
- color: var(--muted-foreground);
308
- }
309
-
310
- .rte-static-renderer ul[data-type="taskList"] input[type="checkbox"] {
311
- accent-color: var(--primary);
312
- }
313
-
314
- /* ── Embeds (toolbar editor only) ──
315
- * Serialized as empty divs with data attributes. Styled as 16:9 placeholder
316
- * cards; swap the inner markup for an iframe/widget if you need the live
317
- * media to render. */
318
- .rte-static-renderer div[data-type="youtube"],
319
- .rte-static-renderer div[data-type="twitter"] {
320
- width: 100%;
321
- max-width: 100%;
322
- margin: 0.5em 0;
323
- border-radius: var(--radius);
324
- border: 1px solid var(--border);
325
- background: var(--muted);
326
- aspect-ratio: 16 / 9;
327
- display: flex;
328
- align-items: center;
329
- justify-content: center;
330
- }
331
-
332
- /* ── Selection ── */
333
- .rte-static-renderer ::selection {
334
- background: color-mix(in srgb, var(--primary) 20%, transparent);
335
- }
1
+ /* Static renderer styles using shadcn CSS variables.
2
+ * Targets the HTML produced by editor.getHTML() from both
3
+ * @editorcn/editor and @editorcn/block-editor.
4
+ */
5
+ .rte-static-renderer {
6
+ color: var(--foreground);
7
+ }
8
+
9
+ .rte-static-renderer > *:last-child {
10
+ margin-bottom: 0;
11
+ }
12
+
13
+ /* ── Typography ── */
14
+ .rte-static-renderer h1 {
15
+ font-size: 1.875rem;
16
+ font-weight: 700;
17
+ line-height: 1.2;
18
+ margin: 0.5em 0 0.25em;
19
+ }
20
+
21
+ .rte-static-renderer h2 {
22
+ font-size: 1.5rem;
23
+ font-weight: 600;
24
+ line-height: 1.25;
25
+ margin: 0.5em 0 0.25em;
26
+ }
27
+
28
+ .rte-static-renderer h3 {
29
+ font-size: 1.25rem;
30
+ font-weight: 600;
31
+ line-height: 1.3;
32
+ margin: 0.5em 0 0.25em;
33
+ }
34
+
35
+ .rte-static-renderer h4 {
36
+ font-size: 1.125rem;
37
+ font-weight: 600;
38
+ line-height: 1.35;
39
+ margin: 0.5em 0 0.25em;
40
+ }
41
+
42
+ .rte-static-renderer h5 {
43
+ font-size: 1rem;
44
+ font-weight: 600;
45
+ line-height: 1.4;
46
+ margin: 0.5em 0 0.25em;
47
+ }
48
+
49
+ .rte-static-renderer h6 {
50
+ font-size: 0.875rem;
51
+ font-weight: 600;
52
+ line-height: 1.45;
53
+ margin: 0.5em 0 0.25em;
54
+ }
55
+
56
+ .rte-static-renderer h1:first-child,
57
+ .rte-static-renderer h2:first-child,
58
+ .rte-static-renderer h3:first-child,
59
+ .rte-static-renderer h4:first-child,
60
+ .rte-static-renderer h5:first-child,
61
+ .rte-static-renderer h6:first-child {
62
+ margin-top: 0;
63
+ }
64
+
65
+ .rte-static-renderer p {
66
+ margin: 0.25em 0;
67
+ line-height: 1.6;
68
+ }
69
+
70
+ .rte-static-renderer ul {
71
+ list-style-type: disc;
72
+ padding-left: 1.5rem;
73
+ margin: 0.25em 0;
74
+ }
75
+
76
+ .rte-static-renderer ul ul {
77
+ list-style-type: circle;
78
+ }
79
+
80
+ .rte-static-renderer ul ul ul {
81
+ list-style-type: square;
82
+ }
83
+
84
+ .rte-static-renderer ol {
85
+ list-style-type: decimal;
86
+ padding-left: 1.5rem;
87
+ margin: 0.25em 0;
88
+ }
89
+
90
+ .rte-static-renderer li {
91
+ margin: 0.125em 0;
92
+ }
93
+
94
+ .rte-static-renderer li > p {
95
+ margin: 0;
96
+ }
97
+
98
+ .rte-static-renderer blockquote {
99
+ border-left: 3px solid var(--border);
100
+ padding-left: 1rem;
101
+ color: var(--muted-foreground);
102
+ margin: 0.5em 0;
103
+ }
104
+
105
+ /* ── Links ── */
106
+ .rte-static-renderer a {
107
+ color: var(--primary);
108
+ text-decoration: underline;
109
+ text-underline-offset: 4px;
110
+ text-decoration-color: color-mix(in srgb, var(--primary) 40%, transparent);
111
+ }
112
+
113
+ /* ── Horizontal rule ── */
114
+ .rte-static-renderer hr {
115
+ border: none;
116
+ border-top: 1px solid var(--border);
117
+ margin: 1em 0;
118
+ }
119
+
120
+ /* ── Inline code ── */
121
+ .rte-static-renderer code {
122
+ font-size: 0.875em;
123
+ font-weight: 500;
124
+ font-family: var(--font-mono, monospace);
125
+ background: color-mix(in srgb, var(--muted) 70%, transparent);
126
+ padding: 0.125rem 0.375rem;
127
+ border-radius: calc(var(--radius) - 4px);
128
+ }
129
+
130
+ /* ── Code blocks ── */
131
+ .rte-static-renderer pre {
132
+ background: #1e1e2e;
133
+ border-radius: var(--radius);
134
+ border: 1px solid var(--border);
135
+ padding: 1rem;
136
+ overflow-x: auto;
137
+ font-size: 0.875rem;
138
+ line-height: 1.5;
139
+ margin: 0.5em 0;
140
+ color: #cdd6f4;
141
+ }
142
+
143
+ .rte-static-renderer pre code {
144
+ color: inherit;
145
+ background: none;
146
+ padding: 0;
147
+ font-weight: 400;
148
+ font-family: var(--font-mono, monospace);
149
+ }
150
+
151
+ /* ── Syntax Highlighting (lowlight / highlight.js) ── */
152
+ .rte-static-renderer pre .hljs-comment,
153
+ .rte-static-renderer pre .hljs-quote {
154
+ color: #6c7086;
155
+ }
156
+
157
+ .rte-static-renderer pre .hljs-variable,
158
+ .rte-static-renderer pre .hljs-template-variable,
159
+ .rte-static-renderer pre .hljs-attribute,
160
+ .rte-static-renderer pre .hljs-tag,
161
+ .rte-static-renderer pre .hljs-regexp,
162
+ .rte-static-renderer pre .hljs-link,
163
+ .rte-static-renderer pre .hljs-name,
164
+ .rte-static-renderer pre .hljs-selector-id,
165
+ .rte-static-renderer pre .hljs-selector-class {
166
+ color: #89b4fa;
167
+ }
168
+
169
+ .rte-static-renderer pre .hljs-number,
170
+ .rte-static-renderer pre .hljs-meta,
171
+ .rte-static-renderer pre .hljs-built_in,
172
+ .rte-static-renderer pre .hljs-builtin-name,
173
+ .rte-static-renderer pre .hljs-literal,
174
+ .rte-static-renderer pre .hljs-type,
175
+ .rte-static-renderer pre .hljs-params {
176
+ color: #fab387;
177
+ }
178
+
179
+ .rte-static-renderer pre .hljs-string,
180
+ .rte-static-renderer pre .hljs-symbol,
181
+ .rte-static-renderer pre .hljs-bullet {
182
+ color: #a6e3a1;
183
+ }
184
+
185
+ .rte-static-renderer pre .hljs-title,
186
+ .rte-static-renderer pre .hljs-section {
187
+ color: #f9e2af;
188
+ }
189
+
190
+ .rte-static-renderer pre .hljs-keyword,
191
+ .rte-static-renderer pre .hljs-selector-tag {
192
+ color: #cba6f7;
193
+ }
194
+
195
+ /* Object/JSON keys & HTML/XML attribute names */
196
+ .rte-static-renderer pre .hljs-attr {
197
+ color: #89b4fa;
198
+ }
199
+
200
+ /* JSDoc-style tags, e.g. @param, @returns */
201
+ .rte-static-renderer pre .hljs-doctag {
202
+ color: #f38ba8;
203
+ font-weight: 600;
204
+ }
205
+
206
+ /* Operators & punctuation (finer-grained grammars) */
207
+ .rte-static-renderer pre .hljs-operator,
208
+ .rte-static-renderer pre .hljs-punctuation {
209
+ color: #9399b2;
210
+ }
211
+
212
+ /* CSS selector attributes/pseudo-classes, e.g. [type="text"], :hover */
213
+ .rte-static-renderer pre .hljs-selector-attr,
214
+ .rte-static-renderer pre .hljs-selector-pseudo {
215
+ color: #94e2d5;
216
+ }
217
+
218
+ /* Language-level variables, e.g. this, super */
219
+ .rte-static-renderer pre .hljs-variable.language_ {
220
+ color: #cba6f7;
221
+ font-style: italic;
222
+ }
223
+
224
+ /* Template literal substitutions, e.g. ${...} */
225
+ .rte-static-renderer pre .hljs-subst {
226
+ color: #cdd6f4;
227
+ }
228
+
229
+ .rte-static-renderer pre .hljs-emphasis {
230
+ font-style: italic;
231
+ }
232
+
233
+ .rte-static-renderer pre .hljs-strong {
234
+ font-weight: 700;
235
+ }
236
+
237
+ .rte-static-renderer pre .hljs-addition {
238
+ color: #a6e3a1;
239
+ background-color: color-mix(in srgb, #a6e3a1 10%, transparent);
240
+ }
241
+
242
+ .rte-static-renderer pre .hljs-deletion {
243
+ color: #f38ba8;
244
+ background-color: color-mix(in srgb, #f38ba8 10%, transparent);
245
+ }
246
+
247
+ /* ── Images ── */
248
+ .rte-static-renderer img {
249
+ max-width: 100%;
250
+ height: auto;
251
+ border-radius: var(--radius);
252
+ }
253
+
254
+ /* ── Tables ── */
255
+ .rte-static-renderer table {
256
+ border-collapse: collapse;
257
+ width: 100%;
258
+ margin: 0.5em 0;
259
+ }
260
+
261
+ .rte-static-renderer th,
262
+ .rte-static-renderer td {
263
+ border: 1px solid var(--border);
264
+ padding: 0.5rem;
265
+ min-width: 100px;
266
+ text-align: left;
267
+ vertical-align: top;
268
+ }
269
+
270
+ .rte-static-renderer th {
271
+ background: var(--muted);
272
+ font-weight: 600;
273
+ }
274
+
275
+ /* Table wrapper for horizontal scroll */
276
+ .rte-static-renderer .tableWrapper {
277
+ overflow-x: auto;
278
+ }
279
+
280
+ /* ── Task lists ── */
281
+ .rte-static-renderer ul[data-type="taskList"] {
282
+ list-style: none;
283
+ padding-left: 0;
284
+ }
285
+
286
+ .rte-static-renderer ul[data-type="taskList"] li {
287
+ display: flex;
288
+ align-items: flex-start;
289
+ gap: 0.5rem;
290
+ }
291
+
292
+ .rte-static-renderer ul[data-type="taskList"] li > label {
293
+ flex-shrink: 0;
294
+ margin-top: 0.25rem;
295
+ }
296
+
297
+ .rte-static-renderer ul[data-type="taskList"] li > div > p {
298
+ margin: 0;
299
+ }
300
+
301
+ .rte-static-renderer
302
+ ul[data-type="taskList"]
303
+ li[data-checked="true"]
304
+ > div
305
+ > p {
306
+ text-decoration: line-through;
307
+ color: var(--muted-foreground);
308
+ }
309
+
310
+ .rte-static-renderer ul[data-type="taskList"] input[type="checkbox"] {
311
+ accent-color: var(--primary);
312
+ }
313
+
314
+ /* ── Embeds (toolbar editor only) ──
315
+ * Serialized as empty divs with data attributes. Styled as 16:9 placeholder
316
+ * cards; swap the inner markup for an iframe/widget if you need the live
317
+ * media to render. */
318
+ .rte-static-renderer div[data-type="youtube"],
319
+ .rte-static-renderer div[data-type="twitter"] {
320
+ width: 100%;
321
+ max-width: 100%;
322
+ margin: 0.5em 0;
323
+ border-radius: var(--radius);
324
+ border: 1px solid var(--border);
325
+ background: var(--muted);
326
+ aspect-ratio: 16 / 9;
327
+ display: flex;
328
+ align-items: center;
329
+ justify-content: center;
330
+ }
331
+
332
+ /* ── Selection ── */
333
+ .rte-static-renderer ::selection {
334
+ background: color-mix(in srgb, var(--primary) 20%, transparent);
335
+ }
package/package.json CHANGED
@@ -1,41 +1,44 @@
1
- {
2
- "name": "@editorcn/static-renderer",
3
- "version": "0.1.0",
4
- "files": [
5
- "dist"
6
- ],
7
- "type": "module",
8
- "main": "./dist/index.cjs",
9
- "module": "./dist/index.js",
10
- "types": "./dist/index.d.ts",
11
- "exports": {
12
- ".": {
13
- "types": "./dist/index.d.ts",
14
- "import": "./dist/index.js",
15
- "require": "./dist/index.cjs"
16
- },
17
- "./style.css": "./dist/style.css"
18
- },
19
- "publishConfig": {
20
- "access": "public"
21
- },
22
- "scripts": {
23
- "build": "tsup && node -e \"require('fs').copyFileSync('src/style.css','dist/style.css')\"",
24
- "dev": "tsup --watch",
25
- "typecheck": "tsc --noEmit",
26
- "prepublishOnly": "pnpm build"
27
- },
28
- "dependencies": {
29
- "clsx": "^2.1.1",
30
- "tailwind-merge": "^3.0.0"
31
- },
32
- "devDependencies": {
33
- "@types/react": "^19",
34
- "tsup": "^8.4.0",
35
- "typescript": "^5"
36
- },
37
- "peerDependencies": {
38
- "react": "^18 || ^19",
39
- "react-dom": "^18 || ^19"
40
- }
41
- }
1
+ {
2
+ "name": "@editorcn/static-renderer",
3
+ "version": "0.2.1",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "type": "module",
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ },
17
+ "./style.css": "./dist/style.css"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "build": "tsup && node -e \"require('fs').copyFileSync('src/style.css','dist/style.css')\"",
24
+ "dev": "tsup --watch",
25
+ "typecheck": "tsc --noEmit",
26
+ "prepublishOnly": "pnpm build"
27
+ },
28
+ "dependencies": {
29
+ "clsx": "^2.1.1",
30
+ "tailwind-merge": "^3.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^19",
34
+ "tsup": "^8.4.0",
35
+ "typescript": "^5"
36
+ },
37
+ "peerDependencies": {
38
+ "@tiptap/core": ">=3.21.0 <4",
39
+ "@tiptap/pm": ">=3.21.0 <4",
40
+ "@tiptap/static-renderer": ">=3.21.0 <4",
41
+ "react": "^18 || ^19",
42
+ "react-dom": "^18 || ^19"
43
+ }
44
+ }