@contember/react-richtext-renderer 1.3.0-alpha.9
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/development/RichTextRendererError.cjs +6 -0
- package/dist/development/RichTextRendererError.cjs.map +1 -0
- package/dist/development/RichTextRendererError.js +6 -0
- package/dist/development/RichTextRendererError.js.map +1 -0
- package/dist/development/components/RichText.cjs +32 -0
- package/dist/development/components/RichText.cjs.map +1 -0
- package/dist/development/components/RichText.js +32 -0
- package/dist/development/components/RichText.js.map +1 -0
- package/dist/development/components/RichTextBlocksRenderer.cjs +30 -0
- package/dist/development/components/RichTextBlocksRenderer.cjs.map +1 -0
- package/dist/development/components/RichTextBlocksRenderer.js +30 -0
- package/dist/development/components/RichTextBlocksRenderer.js.map +1 -0
- package/dist/development/components/RichTextFieldRenderer.cjs +28 -0
- package/dist/development/components/RichTextFieldRenderer.cjs.map +1 -0
- package/dist/development/components/RichTextFieldRenderer.js +28 -0
- package/dist/development/components/RichTextFieldRenderer.js.map +1 -0
- package/dist/development/components/RichTextRenderer.cjs +14 -0
- package/dist/development/components/RichTextRenderer.cjs.map +1 -0
- package/dist/development/components/RichTextRenderer.js +14 -0
- package/dist/development/components/RichTextRenderer.js.map +1 -0
- package/dist/development/hooks/useRichTextBlocksSource.cjs +62 -0
- package/dist/development/hooks/useRichTextBlocksSource.cjs.map +1 -0
- package/dist/development/hooks/useRichTextBlocksSource.js +62 -0
- package/dist/development/hooks/useRichTextBlocksSource.js.map +1 -0
- package/dist/development/hooks/useRichTextFieldSource.cjs +26 -0
- package/dist/development/hooks/useRichTextFieldSource.cjs.map +1 -0
- package/dist/development/hooks/useRichTextFieldSource.js +26 -0
- package/dist/development/hooks/useRichTextFieldSource.js.map +1 -0
- package/dist/development/index.cjs +17 -0
- package/dist/development/index.cjs.map +1 -0
- package/dist/development/index.js +17 -0
- package/dist/development/index.js.map +1 -0
- package/dist/development/internal/components/ElementRenderer.cjs +24 -0
- package/dist/development/internal/components/ElementRenderer.cjs.map +1 -0
- package/dist/development/internal/components/ElementRenderer.js +24 -0
- package/dist/development/internal/components/ElementRenderer.js.map +1 -0
- package/dist/development/internal/components/LeafRenderer.cjs +23 -0
- package/dist/development/internal/components/LeafRenderer.cjs.map +1 -0
- package/dist/development/internal/components/LeafRenderer.js +23 -0
- package/dist/development/internal/components/LeafRenderer.js.map +1 -0
- package/dist/development/internal/components/RenderElementFallback.cjs +84 -0
- package/dist/development/internal/components/RenderElementFallback.cjs.map +1 -0
- package/dist/development/internal/components/RenderElementFallback.js +84 -0
- package/dist/development/internal/components/RenderElementFallback.js.map +1 -0
- package/dist/development/internal/components/RenderLeafFallback.cjs +38 -0
- package/dist/development/internal/components/RenderLeafFallback.cjs.map +1 -0
- package/dist/development/internal/components/RenderLeafFallback.js +38 -0
- package/dist/development/internal/components/RenderLeafFallback.js.map +1 -0
- package/dist/development/internal/defaultDeserialize.cjs +14 -0
- package/dist/development/internal/defaultDeserialize.cjs.map +1 -0
- package/dist/development/internal/defaultDeserialize.js +14 -0
- package/dist/development/internal/defaultDeserialize.js.map +1 -0
- package/dist/development/internal/renderChildren.cjs +18 -0
- package/dist/development/internal/renderChildren.cjs.map +1 -0
- package/dist/development/internal/renderChildren.js +18 -0
- package/dist/development/internal/renderChildren.js.map +1 -0
- package/dist/development/internal/useReferenceMetadata.cjs +37 -0
- package/dist/development/internal/useReferenceMetadata.cjs.map +1 -0
- package/dist/development/internal/useReferenceMetadata.js +37 -0
- package/dist/development/internal/useReferenceMetadata.js.map +1 -0
- package/dist/production/RichTextRendererError.cjs +6 -0
- package/dist/production/RichTextRendererError.cjs.map +1 -0
- package/dist/production/RichTextRendererError.js +6 -0
- package/dist/production/RichTextRendererError.js.map +1 -0
- package/dist/production/components/RichText.cjs +32 -0
- package/dist/production/components/RichText.cjs.map +1 -0
- package/dist/production/components/RichText.js +32 -0
- package/dist/production/components/RichText.js.map +1 -0
- package/dist/production/components/RichTextBlocksRenderer.cjs +30 -0
- package/dist/production/components/RichTextBlocksRenderer.cjs.map +1 -0
- package/dist/production/components/RichTextBlocksRenderer.js +30 -0
- package/dist/production/components/RichTextBlocksRenderer.js.map +1 -0
- package/dist/production/components/RichTextFieldRenderer.cjs +28 -0
- package/dist/production/components/RichTextFieldRenderer.cjs.map +1 -0
- package/dist/production/components/RichTextFieldRenderer.js +28 -0
- package/dist/production/components/RichTextFieldRenderer.js.map +1 -0
- package/dist/production/components/RichTextRenderer.cjs +14 -0
- package/dist/production/components/RichTextRenderer.cjs.map +1 -0
- package/dist/production/components/RichTextRenderer.js +14 -0
- package/dist/production/components/RichTextRenderer.js.map +1 -0
- package/dist/production/hooks/useRichTextBlocksSource.cjs +62 -0
- package/dist/production/hooks/useRichTextBlocksSource.cjs.map +1 -0
- package/dist/production/hooks/useRichTextBlocksSource.js +62 -0
- package/dist/production/hooks/useRichTextBlocksSource.js.map +1 -0
- package/dist/production/hooks/useRichTextFieldSource.cjs +26 -0
- package/dist/production/hooks/useRichTextFieldSource.cjs.map +1 -0
- package/dist/production/hooks/useRichTextFieldSource.js +26 -0
- package/dist/production/hooks/useRichTextFieldSource.js.map +1 -0
- package/dist/production/index.cjs +17 -0
- package/dist/production/index.cjs.map +1 -0
- package/dist/production/index.js +17 -0
- package/dist/production/index.js.map +1 -0
- package/dist/production/internal/components/ElementRenderer.cjs +24 -0
- package/dist/production/internal/components/ElementRenderer.cjs.map +1 -0
- package/dist/production/internal/components/ElementRenderer.js +24 -0
- package/dist/production/internal/components/ElementRenderer.js.map +1 -0
- package/dist/production/internal/components/LeafRenderer.cjs +23 -0
- package/dist/production/internal/components/LeafRenderer.cjs.map +1 -0
- package/dist/production/internal/components/LeafRenderer.js +23 -0
- package/dist/production/internal/components/LeafRenderer.js.map +1 -0
- package/dist/production/internal/components/RenderElementFallback.cjs +84 -0
- package/dist/production/internal/components/RenderElementFallback.cjs.map +1 -0
- package/dist/production/internal/components/RenderElementFallback.js +84 -0
- package/dist/production/internal/components/RenderElementFallback.js.map +1 -0
- package/dist/production/internal/components/RenderLeafFallback.cjs +38 -0
- package/dist/production/internal/components/RenderLeafFallback.cjs.map +1 -0
- package/dist/production/internal/components/RenderLeafFallback.js +38 -0
- package/dist/production/internal/components/RenderLeafFallback.js.map +1 -0
- package/dist/production/internal/defaultDeserialize.cjs +14 -0
- package/dist/production/internal/defaultDeserialize.cjs.map +1 -0
- package/dist/production/internal/defaultDeserialize.js +14 -0
- package/dist/production/internal/defaultDeserialize.js.map +1 -0
- package/dist/production/internal/renderChildren.cjs +18 -0
- package/dist/production/internal/renderChildren.cjs.map +1 -0
- package/dist/production/internal/renderChildren.js +18 -0
- package/dist/production/internal/renderChildren.js.map +1 -0
- package/dist/production/internal/useReferenceMetadata.cjs +37 -0
- package/dist/production/internal/useReferenceMetadata.cjs.map +1 -0
- package/dist/production/internal/useReferenceMetadata.js +37 -0
- package/dist/production/internal/useReferenceMetadata.js.map +1 -0
- package/dist/types/RichTextRendererError.d.ts +3 -0
- package/dist/types/RichTextRendererError.d.ts.map +1 -0
- package/dist/types/components/RichText.d.ts +13 -0
- package/dist/types/components/RichText.d.ts.map +1 -0
- package/dist/types/components/RichTextBlocksRenderer.d.ts +10 -0
- package/dist/types/components/RichTextBlocksRenderer.d.ts.map +1 -0
- package/dist/types/components/RichTextFieldRenderer.d.ts +10 -0
- package/dist/types/components/RichTextFieldRenderer.d.ts.map +1 -0
- package/dist/types/components/RichTextRenderer.d.ts +12 -0
- package/dist/types/components/RichTextRenderer.d.ts.map +1 -0
- package/dist/types/components/index.d.ts +5 -0
- package/dist/types/components/index.d.ts.map +1 -0
- package/dist/types/hooks/index.d.ts +3 -0
- package/dist/types/hooks/index.d.ts.map +1 -0
- package/dist/types/hooks/useRichTextBlocksSource.d.ts +3 -0
- package/dist/types/hooks/useRichTextBlocksSource.d.ts.map +1 -0
- package/dist/types/hooks/useRichTextFieldSource.d.ts +3 -0
- package/dist/types/hooks/useRichTextFieldSource.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/internal/components/ElementRenderer.d.ts +14 -0
- package/dist/types/internal/components/ElementRenderer.d.ts.map +1 -0
- package/dist/types/internal/components/LeafRenderer.d.ts +12 -0
- package/dist/types/internal/components/LeafRenderer.d.ts.map +1 -0
- package/dist/types/internal/components/RenderElementFallback.d.ts +14 -0
- package/dist/types/internal/components/RenderElementFallback.d.ts.map +1 -0
- package/dist/types/internal/components/RenderLeafFallback.d.ts +6 -0
- package/dist/types/internal/components/RenderLeafFallback.d.ts.map +1 -0
- package/dist/types/internal/defaultDeserialize.d.ts +5 -0
- package/dist/types/internal/defaultDeserialize.d.ts.map +1 -0
- package/dist/types/internal/renderChildren.d.ts +8 -0
- package/dist/types/internal/renderChildren.d.ts.map +1 -0
- package/dist/types/internal/useReferenceMetadata.d.ts +9 -0
- package/dist/types/internal/useReferenceMetadata.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dist/types/types/RenderChildren.d.ts +9 -0
- package/dist/types/types/RenderChildren.d.ts.map +1 -0
- package/dist/types/types/RichTextBlock.d.ts +8 -0
- package/dist/types/types/RichTextBlock.d.ts.map +1 -0
- package/dist/types/types/RichTextBlockSource.d.ts +9 -0
- package/dist/types/types/RichTextBlockSource.d.ts.map +1 -0
- package/dist/types/types/RichTextFieldSource.d.ts +6 -0
- package/dist/types/types/RichTextFieldSource.d.ts.map +1 -0
- package/dist/types/types/RichTextReference.d.ts +5 -0
- package/dist/types/types/RichTextReference.d.ts.map +1 -0
- package/dist/types/types/RichTextReferenceMetadata.d.ts +15 -0
- package/dist/types/types/RichTextReferenceMetadata.d.ts.map +1 -0
- package/dist/types/types/RichTextRenderingOptions.d.ts +14 -0
- package/dist/types/types/RichTextRenderingOptions.d.ts.map +1 -0
- package/dist/types/types/builtin/BuiltinElements.d.ts +48 -0
- package/dist/types/types/builtin/BuiltinElements.d.ts.map +1 -0
- package/dist/types/types/builtin/BuiltinLeaves.d.ts +21 -0
- package/dist/types/types/builtin/BuiltinLeaves.d.ts.map +1 -0
- package/dist/types/types/builtin/index.d.ts +3 -0
- package/dist/types/types/builtin/index.d.ts.map +1 -0
- package/dist/types/types/custom/ReferenceRenderer.d.ts +17 -0
- package/dist/types/types/custom/ReferenceRenderer.d.ts.map +1 -0
- package/dist/types/types/custom/RenderBlock.d.ts +7 -0
- package/dist/types/types/custom/RenderBlock.d.ts.map +1 -0
- package/dist/types/types/custom/RenderElement.d.ts +24 -0
- package/dist/types/types/custom/RenderElement.d.ts.map +1 -0
- package/dist/types/types/custom/RenderLeaf.d.ts +11 -0
- package/dist/types/types/custom/RenderLeaf.d.ts.map +1 -0
- package/dist/types/types/custom/index.d.ts +5 -0
- package/dist/types/types/custom/index.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +11 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/structure/RichTextChild.d.ts +5 -0
- package/dist/types/types/structure/RichTextChild.d.ts.map +1 -0
- package/dist/types/types/structure/RichTextElement.d.ts +8 -0
- package/dist/types/types/structure/RichTextElement.d.ts.map +1 -0
- package/dist/types/types/structure/RichTextLeaf.d.ts +4 -0
- package/dist/types/types/structure/RichTextLeaf.d.ts.map +1 -0
- package/dist/types/types/structure/RootEditorNode.d.ts +8 -0
- package/dist/types/types/structure/RootEditorNode.d.ts.map +1 -0
- package/dist/types/types/structure/index.d.ts +5 -0
- package/dist/types/types/structure/index.d.ts.map +1 -0
- package/package.json +50 -0
- package/readme.md +106 -0
- package/src/RichTextRendererError.ts +1 -0
- package/src/components/RichText.tsx +52 -0
- package/src/components/RichTextBlocksRenderer.tsx +40 -0
- package/src/components/RichTextFieldRenderer.tsx +42 -0
- package/src/components/RichTextRenderer.tsx +31 -0
- package/src/components/index.ts +4 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useRichTextBlocksSource.ts +75 -0
- package/src/hooks/useRichTextFieldSource.ts +26 -0
- package/src/index.ts +6 -0
- package/src/internal/components/ElementRenderer.tsx +48 -0
- package/src/internal/components/LeafRenderer.tsx +36 -0
- package/src/internal/components/RenderElementFallback.tsx +153 -0
- package/src/internal/components/RenderLeafFallback.tsx +43 -0
- package/src/internal/defaultDeserialize.ts +19 -0
- package/src/internal/renderChildren.tsx +37 -0
- package/src/internal/useReferenceMetadata.ts +62 -0
- package/src/tsconfig.json +6 -0
- package/src/types/RenderChildren.ts +16 -0
- package/src/types/RichTextBlock.ts +11 -0
- package/src/types/RichTextBlockSource.ts +10 -0
- package/src/types/RichTextFieldSource.ts +6 -0
- package/src/types/RichTextReference.ts +6 -0
- package/src/types/RichTextReferenceMetadata.ts +27 -0
- package/src/types/RichTextRenderingOptions.ts +23 -0
- package/src/types/builtin/BuiltinElements.ts +111 -0
- package/src/types/builtin/BuiltinLeaves.ts +33 -0
- package/src/types/builtin/index.ts +2 -0
- package/src/types/custom/ReferenceRenderer.ts +33 -0
- package/src/types/custom/RenderBlock.ts +8 -0
- package/src/types/custom/RenderElement.ts +37 -0
- package/src/types/custom/RenderLeaf.ts +14 -0
- package/src/types/custom/index.ts +4 -0
- package/src/types/index.ts +11 -0
- package/src/types/structure/RichTextChild.ts +11 -0
- package/src/types/structure/RichTextElement.ts +11 -0
- package/src/types/structure/RichTextLeaf.ts +3 -0
- package/src/types/structure/RootEditorNode.ts +11 -0
- package/src/types/structure/index.ts +4 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RichTextElement } from './RichTextElement';
|
|
2
|
+
import type { RichTextLeaf } from './RichTextLeaf';
|
|
3
|
+
import { RichTextChild } from './RichTextChild';
|
|
4
|
+
export interface RootEditorNode<CustomElements extends RichTextElement = never, CustomLeaves extends RichTextLeaf = RichTextLeaf> {
|
|
5
|
+
formatVersion: number;
|
|
6
|
+
children: readonly RichTextChild<CustomElements, CustomLeaves>[];
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=RootEditorNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RootEditorNode.d.ts","sourceRoot":"","sources":["../../../../src/types/structure/RootEditorNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,WAAW,cAAc,CAC9B,cAAc,SAAS,eAAe,GAAG,KAAK,EAC9C,YAAY,SAAS,YAAY,GAAG,YAAY;IAEhD,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,SAAS,aAAa,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,CAAA;CAChE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/types/structure/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contember/react-richtext-renderer",
|
|
3
|
+
"license": "Apache-2.0",
|
|
4
|
+
"version": "1.3.0-alpha.9",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/production/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"development": "./dist/development/index.js",
|
|
13
|
+
"production": "./dist/production/index.js",
|
|
14
|
+
"default": "./dist/production/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/types/index.d.ts",
|
|
18
|
+
"development": "./dist/development/index.cjs",
|
|
19
|
+
"production": "./dist/production/index.cjs",
|
|
20
|
+
"default": "./dist/production/index.cjs"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist/",
|
|
26
|
+
"src/"
|
|
27
|
+
],
|
|
28
|
+
"typings": "./dist/types/index.d.ts",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "yarn build:js:dev && yarn build:js:prod",
|
|
31
|
+
"build:js:dev": "vite build --mode development",
|
|
32
|
+
"build:js:prod": "vite build --mode production",
|
|
33
|
+
"ae:build": "api-extractor run --local",
|
|
34
|
+
"ae:test": "api-extractor run",
|
|
35
|
+
"test": "vitest"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/contember/interface.git",
|
|
40
|
+
"directory": "packages/react-richtext-renderer"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@testing-library/react": "^14.1.2",
|
|
44
|
+
"@testing-library/react-hooks": "^8.0.1"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": "^17 || ^18"
|
|
48
|
+
},
|
|
49
|
+
"stableVersion": "0.0.0"
|
|
50
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Contember Rich Text renderer
|
|
2
|
+
|
|
3
|
+
This package provides a React renderer for Contember Rich Text format.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
yarn add @contember/react-richtext-renderer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage for blocks
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { RichTextBlocksRenderer } from '@contember/react-richtext-renderer'
|
|
15
|
+
|
|
16
|
+
const App = () => {
|
|
17
|
+
const blocks = [] // blocks from Contember API
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<RichTextBlocksRenderer
|
|
21
|
+
blocks={blocks}
|
|
22
|
+
sourceField={'content'}
|
|
23
|
+
referencesField={'references'}
|
|
24
|
+
referenceDiscriminationField={'type'}
|
|
25
|
+
/>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage for standalone rich text field
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { RichTextFieldRenderer } from '@contember/react-richtext-renderer'
|
|
34
|
+
|
|
35
|
+
const App = () => {
|
|
36
|
+
const value = {} // value from Contember API
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<RichTextFieldRenderer
|
|
40
|
+
source={value}
|
|
41
|
+
/>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Custom elements
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { RichTextBlocksRenderer } from '@contember/react-richtext-renderer'
|
|
50
|
+
|
|
51
|
+
const App = () => {
|
|
52
|
+
// ...
|
|
53
|
+
return (
|
|
54
|
+
<RichTextBlocksRenderer
|
|
55
|
+
// ...
|
|
56
|
+
renderElement={it => {
|
|
57
|
+
if (it.element.type === 'blockquote') {
|
|
58
|
+
return <blockquote>{it.children}</blockquote>
|
|
59
|
+
}
|
|
60
|
+
return it.fallback
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Custom leafs
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { RichTextBlocksRenderer } from '@contember/react-richtext-renderer'
|
|
71
|
+
|
|
72
|
+
const App = () => {
|
|
73
|
+
// ...
|
|
74
|
+
return (
|
|
75
|
+
<RichTextBlocksRenderer
|
|
76
|
+
// ...
|
|
77
|
+
renderLeaf={it => {
|
|
78
|
+
if (it.leaf.isSup) {
|
|
79
|
+
return <sup>{it.fallback}</sup>
|
|
80
|
+
}
|
|
81
|
+
return it.fallback
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Make sure to use `it.fallback` instead of `it.children` in `renderLeaf` callback, to render already applied leafs as well.
|
|
89
|
+
|
|
90
|
+
## Custom references
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { RichTextBlocksRenderer } from '@contember/react-richtext-renderer'
|
|
94
|
+
|
|
95
|
+
const App = () => {
|
|
96
|
+
// ...
|
|
97
|
+
return (
|
|
98
|
+
<RichTextBlocksRenderer
|
|
99
|
+
// ...
|
|
100
|
+
referenceRenderers={{
|
|
101
|
+
image: ({ reference }) => <img src={reference.url} />,
|
|
102
|
+
}}
|
|
103
|
+
/>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class RichTextRendererError extends Error {}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createElement } from 'react'
|
|
2
|
+
import { renderChildren } from '../internal/renderChildren'
|
|
3
|
+
import type { RichTextBlock } from '../types'
|
|
4
|
+
import { RichTextElement, RichTextLeaf, RichTextRenderingOptions } from '../types'
|
|
5
|
+
|
|
6
|
+
export type RichTextProps<
|
|
7
|
+
CustomElements extends RichTextElement = never,
|
|
8
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
9
|
+
> =
|
|
10
|
+
& {
|
|
11
|
+
blocks: RichTextBlock<CustomElements, CustomLeaves>[]
|
|
12
|
+
}
|
|
13
|
+
& RichTextRenderingOptions<CustomElements, CustomLeaves>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Accepts normalized decoded RichText blocks and renders them using the provided renderers.
|
|
17
|
+
* To use decoders, use `RichTextBlocksRenderer` or `RichTextFieldRenderer` instead.
|
|
18
|
+
*
|
|
19
|
+
* @group Content rendering
|
|
20
|
+
*/
|
|
21
|
+
export const RichText = <
|
|
22
|
+
CustomElements extends RichTextElement = never,
|
|
23
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
24
|
+
>({
|
|
25
|
+
blocks,
|
|
26
|
+
renderElement,
|
|
27
|
+
renderLeaf,
|
|
28
|
+
renderBlock = ({ children }) => <>{children}</>,
|
|
29
|
+
attributeNamePrefix,
|
|
30
|
+
referenceRenderers,
|
|
31
|
+
undefinedReferenceHandler,
|
|
32
|
+
}: RichTextProps<CustomElements, CustomLeaves>) => {
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
{blocks.map((block, i) => (
|
|
36
|
+
createElement(
|
|
37
|
+
renderBlock, {
|
|
38
|
+
block,
|
|
39
|
+
key: block.id ?? i,
|
|
40
|
+
}, renderChildren(block.content.children, {
|
|
41
|
+
referenceRenderers,
|
|
42
|
+
renderBlock,
|
|
43
|
+
renderLeaf,
|
|
44
|
+
renderElement,
|
|
45
|
+
attributeNamePrefix,
|
|
46
|
+
undefinedReferenceHandler,
|
|
47
|
+
}, block),
|
|
48
|
+
)
|
|
49
|
+
))}
|
|
50
|
+
</>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RichTextBlockSource, RichTextElement, RichTextLeaf, RichTextRenderingOptions } from '../types'
|
|
2
|
+
import { RichText } from './RichText'
|
|
3
|
+
import { useRichTextBlocksSource } from '../hooks'
|
|
4
|
+
|
|
5
|
+
export type { RichTextBlockSource }
|
|
6
|
+
|
|
7
|
+
export type RichTextBlocksRendererProps<CustomElements extends RichTextElement = never, CustomLeaves extends RichTextLeaf = RichTextLeaf> =
|
|
8
|
+
& RichTextBlockSource<CustomElements, CustomLeaves>
|
|
9
|
+
& RichTextRenderingOptions<CustomElements, CustomLeaves>
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Accepts raw RichText blocks and renders them using the provided renderers.
|
|
13
|
+
*
|
|
14
|
+
* @group Content rendering
|
|
15
|
+
*/
|
|
16
|
+
export const RichTextBlocksRenderer = <
|
|
17
|
+
CustomElements extends RichTextElement = never,
|
|
18
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
19
|
+
>({
|
|
20
|
+
renderElement,
|
|
21
|
+
renderLeaf,
|
|
22
|
+
renderBlock = ({ children }) => <>{children}</>,
|
|
23
|
+
attributeNamePrefix,
|
|
24
|
+
referenceRenderers,
|
|
25
|
+
undefinedReferenceHandler,
|
|
26
|
+
...props
|
|
27
|
+
}: RichTextBlocksRendererProps<CustomElements, CustomLeaves>) => {
|
|
28
|
+
const blocks = useRichTextBlocksSource<CustomElements, CustomLeaves>(props)
|
|
29
|
+
return (
|
|
30
|
+
<RichText<CustomElements, CustomLeaves>
|
|
31
|
+
blocks={blocks}
|
|
32
|
+
renderElement={renderElement}
|
|
33
|
+
renderLeaf={renderLeaf}
|
|
34
|
+
renderBlock={renderBlock}
|
|
35
|
+
referenceRenderers={referenceRenderers}
|
|
36
|
+
undefinedReferenceHandler={undefinedReferenceHandler}
|
|
37
|
+
attributeNamePrefix={attributeNamePrefix}
|
|
38
|
+
/>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RichText } from './RichText'
|
|
2
|
+
import { RichTextElement, RichTextFieldSource, RichTextLeaf, RichTextRenderingOptions } from '../types'
|
|
3
|
+
import { useRichTextFieldSource } from '../hooks'
|
|
4
|
+
|
|
5
|
+
export type { RichTextFieldSource }
|
|
6
|
+
|
|
7
|
+
export type RichTextFieldRendererProps<
|
|
8
|
+
CustomElements extends RichTextElement = never,
|
|
9
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
10
|
+
> =
|
|
11
|
+
& RichTextFieldSource<CustomElements, CustomLeaves>
|
|
12
|
+
& RichTextRenderingOptions<CustomElements, CustomLeaves>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Accepts raw RichText field source and renders them using the provided renderers.
|
|
16
|
+
*
|
|
17
|
+
* @group Content rendering
|
|
18
|
+
*/
|
|
19
|
+
export const RichTextFieldRenderer = <
|
|
20
|
+
CustomElements extends RichTextElement = never,
|
|
21
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
22
|
+
>({
|
|
23
|
+
renderLeaf,
|
|
24
|
+
renderBlock,
|
|
25
|
+
renderElement,
|
|
26
|
+
attributeNamePrefix,
|
|
27
|
+
undefinedReferenceHandler,
|
|
28
|
+
...source
|
|
29
|
+
}: RichTextFieldRendererProps<CustomElements, CustomLeaves>) => {
|
|
30
|
+
const blocks = useRichTextFieldSource(source)
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<RichText<CustomElements, CustomLeaves>
|
|
34
|
+
blocks={blocks}
|
|
35
|
+
renderElement={renderElement}
|
|
36
|
+
renderLeaf={renderLeaf}
|
|
37
|
+
renderBlock={renderBlock}
|
|
38
|
+
attributeNamePrefix={attributeNamePrefix}
|
|
39
|
+
undefinedReferenceHandler={undefinedReferenceHandler}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { memo, ReactElement } from 'react'
|
|
2
|
+
import type { RichTextElement } from '../types/structure/RichTextElement'
|
|
3
|
+
import type { RichTextLeaf } from '../types/structure/RichTextLeaf'
|
|
4
|
+
import { RichTextFieldRenderer, RichTextFieldRendererProps } from './RichTextFieldRenderer'
|
|
5
|
+
import { RichTextBlocksRenderer, RichTextBlocksRendererProps } from './RichTextBlocksRenderer'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export type RichTextRendererProps<
|
|
9
|
+
CustomElements extends RichTextElement = never,
|
|
10
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
11
|
+
> =
|
|
12
|
+
| RichTextFieldRendererProps<CustomElements, CustomLeaves>
|
|
13
|
+
| RichTextBlocksRendererProps<CustomElements, CustomLeaves>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use `RichTextBlocksRenderer` or `RichTextFieldRenderer` instead, or directly use `RichText`.
|
|
17
|
+
* @group Content rendering
|
|
18
|
+
*/
|
|
19
|
+
export const RichTextRenderer = memo(function RichTextRenderer<
|
|
20
|
+
CustomElements extends RichTextElement = never,
|
|
21
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
22
|
+
>(props: RichTextRendererProps<CustomElements, CustomLeaves>) {
|
|
23
|
+
|
|
24
|
+
if ('source' in props) {
|
|
25
|
+
return <RichTextFieldRenderer<CustomElements, CustomLeaves> {...props} />
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return <RichTextBlocksRenderer<CustomElements, CustomLeaves> {...props} />
|
|
29
|
+
}) as <CustomElements extends RichTextElement = never, CustomLeaves extends RichTextLeaf = RichTextLeaf>(
|
|
30
|
+
props: RichTextRendererProps<CustomElements, CustomLeaves>,
|
|
31
|
+
) => ReactElement
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { RichTextBlock, RichTextBlockSource, RichTextElement, RichTextLeaf, RichTextReference, RootEditorNode } from '../types'
|
|
2
|
+
import { defaultDeserialize } from '../internal/defaultDeserialize'
|
|
3
|
+
import { useMemo } from 'react'
|
|
4
|
+
import { RichTextRendererError } from '../RichTextRendererError'
|
|
5
|
+
|
|
6
|
+
export const useRichTextBlocksSource = <CustomElements extends RichTextElement, CustomLeaves extends RichTextLeaf>({
|
|
7
|
+
deserialize = defaultDeserialize,
|
|
8
|
+
blocks,
|
|
9
|
+
referencesField = 'references',
|
|
10
|
+
sourceField = 'source',
|
|
11
|
+
referenceDiscriminationField = 'type',
|
|
12
|
+
}: RichTextBlockSource<CustomElements, CustomLeaves>) => {
|
|
13
|
+
return useMemo((): RichTextBlock<CustomElements, CustomLeaves>[] => {
|
|
14
|
+
const sourceFieldResolved = sourceField ?? 'source'
|
|
15
|
+
const referencesFieldResolved = referencesField ?? 'references'
|
|
16
|
+
const referenceDiscriminationFieldResolved = referenceDiscriminationField ?? 'type'
|
|
17
|
+
|
|
18
|
+
return blocks.map(block => {
|
|
19
|
+
if (!(sourceField in block)) {
|
|
20
|
+
throw new RichTextRendererError(
|
|
21
|
+
`Found a block without a '${sourceFieldResolved}' field. ` +
|
|
22
|
+
(sourceField === undefined
|
|
23
|
+
? `The 'sourceField' prop has not been supplied, and so '${sourceFieldResolved}' was used as a default.`
|
|
24
|
+
: `That is what the 'sourceField' prop has been set to, and so either this is a typo, ` +
|
|
25
|
+
`or the data supplied is invalid.`),
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
const source = block[sourceFieldResolved]
|
|
29
|
+
if (typeof source !== 'string' && (typeof source !== 'object' || source === null)) {
|
|
30
|
+
throw new RichTextRendererError(`Found a block whose source is not a string or an object.`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (referencesField !== undefined && !(referencesFieldResolved in block)) {
|
|
34
|
+
throw new RichTextRendererError(
|
|
35
|
+
`The 'referencesField' prop is set to '${referencesFieldResolved}' but a block without such field ` +
|
|
36
|
+
`has been encountered. Unless this is just a typo, ` +
|
|
37
|
+
`if you do not wish to use references, avoid supplying the 'referencesField' prop.`,
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
const references = block[referencesFieldResolved]
|
|
41
|
+
|
|
42
|
+
let normalizedReferences: Record<string, RichTextReference> | undefined = undefined
|
|
43
|
+
if (references) {
|
|
44
|
+
if (typeof Object(references)[Symbol.iterator] !== 'function') {
|
|
45
|
+
throw new RichTextRendererError(`The set of references must be an iterable!`)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
normalizedReferences = Object.fromEntries(Array.from(references as Iterable<RichTextReference>).map(reference => {
|
|
49
|
+
if (!('id' in reference)) {
|
|
50
|
+
throw new RichTextRendererError(`Found a reference without an id field.`)
|
|
51
|
+
}
|
|
52
|
+
if (!(referenceDiscriminationFieldResolved in reference) || typeof reference[referenceDiscriminationFieldResolved] !== 'string') {
|
|
53
|
+
throw new RichTextRendererError(
|
|
54
|
+
`Found a reference without a '${referenceDiscriminationFieldResolved}' field. ` +
|
|
55
|
+
(referenceDiscriminationField === undefined
|
|
56
|
+
? `The 'referenceDiscriminationField' prop has not been supplied, ` +
|
|
57
|
+
`and so '${referenceDiscriminationFieldResolved}' was used as a default.`
|
|
58
|
+
: `That is what the 'referenceDiscriminationField' prop has been set to, ` +
|
|
59
|
+
`and so either this is a typo, or the data supplied is invalid.`),
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
return [reference.id, {
|
|
63
|
+
...reference,
|
|
64
|
+
type: reference[referenceDiscriminationFieldResolved] as string,
|
|
65
|
+
}]
|
|
66
|
+
}))
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
id: typeof block.id === 'string' ? block.id : undefined,
|
|
70
|
+
content: typeof source === 'string' ? deserialize(source) : source as RootEditorNode<CustomElements, CustomLeaves>,
|
|
71
|
+
references: normalizedReferences,
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
}, [blocks, deserialize, referenceDiscriminationField, referencesField, sourceField])
|
|
75
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RichTextBlock, RichTextElement, RichTextFieldSource, RichTextLeaf } from '../types'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { defaultDeserialize } from '../internal/defaultDeserialize'
|
|
4
|
+
|
|
5
|
+
export const useRichTextFieldSource = <CustomElements extends RichTextElement, CustomLeaves extends RichTextLeaf>({
|
|
6
|
+
source,
|
|
7
|
+
deserialize = defaultDeserialize,
|
|
8
|
+
}: RichTextFieldSource<CustomElements, CustomLeaves>): RichTextBlock<CustomElements, CustomLeaves>[] => {
|
|
9
|
+
return useMemo(() => {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
content: source
|
|
13
|
+
? (typeof source === 'string' ? deserialize(source) : source)
|
|
14
|
+
: {
|
|
15
|
+
formatVersion: 0,
|
|
16
|
+
children: [],
|
|
17
|
+
},
|
|
18
|
+
id: undefined,
|
|
19
|
+
referencesField: undefined,
|
|
20
|
+
referenceDiscriminationField: undefined,
|
|
21
|
+
referenceRenderers: {},
|
|
22
|
+
references: undefined,
|
|
23
|
+
},
|
|
24
|
+
]
|
|
25
|
+
}, [deserialize, source])
|
|
26
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ReactElement } from 'react'
|
|
2
|
+
import { createElement } from 'react'
|
|
3
|
+
import type { BuiltinElements } from '../../types/builtin/BuiltinElements'
|
|
4
|
+
import { renderChildren } from '../renderChildren'
|
|
5
|
+
import { RenderElementFallback } from './RenderElementFallback'
|
|
6
|
+
import { useReferenceMetadata } from '../useReferenceMetadata'
|
|
7
|
+
import type { RichTextElement } from '../../types/structure/RichTextElement'
|
|
8
|
+
import type { RichTextLeaf } from '../../types/structure/RichTextLeaf'
|
|
9
|
+
import { RichTextBlock } from '../../types/RichTextBlock'
|
|
10
|
+
import { RichTextRenderingOptions } from '../../types/RichTextRenderingOptions'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export interface ElementRendererProps<
|
|
14
|
+
CustomElements extends RichTextElement = never,
|
|
15
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
16
|
+
> {
|
|
17
|
+
element: CustomElements | BuiltinElements<CustomElements, CustomLeaves>
|
|
18
|
+
children: ReactElement
|
|
19
|
+
options: RichTextRenderingOptions<CustomElements, CustomLeaves>
|
|
20
|
+
block: RichTextBlock<CustomElements, CustomLeaves>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function ElementRenderer<
|
|
24
|
+
CustomElements extends RichTextElement = never,
|
|
25
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
26
|
+
>({ element, children, options, block }: ElementRendererProps<CustomElements, CustomLeaves>) {
|
|
27
|
+
const referenceMetadata = useReferenceMetadata<CustomElements, CustomLeaves>(element, options, block)
|
|
28
|
+
|
|
29
|
+
const fallback = (
|
|
30
|
+
<RenderElementFallback<CustomElements, CustomLeaves> element={element as BuiltinElements<CustomElements, CustomLeaves>} options={options} block={block}>
|
|
31
|
+
{children}
|
|
32
|
+
</RenderElementFallback>
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return options.renderElement
|
|
36
|
+
? createElement(options.renderElement, {
|
|
37
|
+
...referenceMetadata,
|
|
38
|
+
formatVersion: block.content.formatVersion,
|
|
39
|
+
block,
|
|
40
|
+
options,
|
|
41
|
+
element,
|
|
42
|
+
fallback,
|
|
43
|
+
children,
|
|
44
|
+
renderChildren: (children, opts = options) => renderChildren(children, opts, block),
|
|
45
|
+
renderChildrenOptions: options,
|
|
46
|
+
})
|
|
47
|
+
: fallback
|
|
48
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createElement } from 'react'
|
|
2
|
+
import type { BuiltinLeaves } from '../../types/builtin/BuiltinLeaves'
|
|
3
|
+
import { RenderLeafFallback } from './RenderLeafFallback'
|
|
4
|
+
import type { RichTextLeaf } from '../../types/structure/RichTextLeaf'
|
|
5
|
+
import { RichTextElement } from '../../types/structure/RichTextElement'
|
|
6
|
+
import { RichTextRenderingOptions } from '../../types/RichTextRenderingOptions'
|
|
7
|
+
import { RichTextBlock } from '../../types/RichTextBlock'
|
|
8
|
+
|
|
9
|
+
export interface LeafRendererProps<CustomElements extends RichTextElement = never, CustomLeaves extends RichTextLeaf = RichTextLeaf> {
|
|
10
|
+
options: RichTextRenderingOptions<CustomElements, CustomLeaves>
|
|
11
|
+
block: RichTextBlock<CustomElements, CustomLeaves>
|
|
12
|
+
leaf: CustomLeaves & BuiltinLeaves
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function LeafRenderer<
|
|
16
|
+
CustomElements extends RichTextElement = never,
|
|
17
|
+
CustomLeaves extends RichTextLeaf = RichTextLeaf,
|
|
18
|
+
>({
|
|
19
|
+
leaf,
|
|
20
|
+
options: { renderLeaf },
|
|
21
|
+
block: { content: { formatVersion } },
|
|
22
|
+
}: LeafRendererProps<CustomElements, CustomLeaves>) {
|
|
23
|
+
const fallback = <RenderLeafFallback leaf={leaf} />
|
|
24
|
+
|
|
25
|
+
return renderLeaf
|
|
26
|
+
? createElement(
|
|
27
|
+
renderLeaf,
|
|
28
|
+
{
|
|
29
|
+
formatVersion,
|
|
30
|
+
leaf,
|
|
31
|
+
fallback,
|
|
32
|
+
children: leaf.text,
|
|
33
|
+
},
|
|
34
|
+
)
|
|
35
|
+
: fallback
|
|
36
|
+
}
|