@contember/react-richtext-renderer 1.3.0-alpha.10

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 (238) hide show
  1. package/dist/development/RichTextRendererError.cjs +6 -0
  2. package/dist/development/RichTextRendererError.cjs.map +1 -0
  3. package/dist/development/RichTextRendererError.js +6 -0
  4. package/dist/development/RichTextRendererError.js.map +1 -0
  5. package/dist/development/components/RichText.cjs +32 -0
  6. package/dist/development/components/RichText.cjs.map +1 -0
  7. package/dist/development/components/RichText.js +32 -0
  8. package/dist/development/components/RichText.js.map +1 -0
  9. package/dist/development/components/RichTextBlocksRenderer.cjs +30 -0
  10. package/dist/development/components/RichTextBlocksRenderer.cjs.map +1 -0
  11. package/dist/development/components/RichTextBlocksRenderer.js +30 -0
  12. package/dist/development/components/RichTextBlocksRenderer.js.map +1 -0
  13. package/dist/development/components/RichTextFieldRenderer.cjs +28 -0
  14. package/dist/development/components/RichTextFieldRenderer.cjs.map +1 -0
  15. package/dist/development/components/RichTextFieldRenderer.js +28 -0
  16. package/dist/development/components/RichTextFieldRenderer.js.map +1 -0
  17. package/dist/development/components/RichTextRenderer.cjs +14 -0
  18. package/dist/development/components/RichTextRenderer.cjs.map +1 -0
  19. package/dist/development/components/RichTextRenderer.js +14 -0
  20. package/dist/development/components/RichTextRenderer.js.map +1 -0
  21. package/dist/development/hooks/useRichTextBlocksSource.cjs +62 -0
  22. package/dist/development/hooks/useRichTextBlocksSource.cjs.map +1 -0
  23. package/dist/development/hooks/useRichTextBlocksSource.js +62 -0
  24. package/dist/development/hooks/useRichTextBlocksSource.js.map +1 -0
  25. package/dist/development/hooks/useRichTextFieldSource.cjs +26 -0
  26. package/dist/development/hooks/useRichTextFieldSource.cjs.map +1 -0
  27. package/dist/development/hooks/useRichTextFieldSource.js +26 -0
  28. package/dist/development/hooks/useRichTextFieldSource.js.map +1 -0
  29. package/dist/development/index.cjs +17 -0
  30. package/dist/development/index.cjs.map +1 -0
  31. package/dist/development/index.js +17 -0
  32. package/dist/development/index.js.map +1 -0
  33. package/dist/development/internal/components/ElementRenderer.cjs +24 -0
  34. package/dist/development/internal/components/ElementRenderer.cjs.map +1 -0
  35. package/dist/development/internal/components/ElementRenderer.js +24 -0
  36. package/dist/development/internal/components/ElementRenderer.js.map +1 -0
  37. package/dist/development/internal/components/LeafRenderer.cjs +23 -0
  38. package/dist/development/internal/components/LeafRenderer.cjs.map +1 -0
  39. package/dist/development/internal/components/LeafRenderer.js +23 -0
  40. package/dist/development/internal/components/LeafRenderer.js.map +1 -0
  41. package/dist/development/internal/components/RenderElementFallback.cjs +84 -0
  42. package/dist/development/internal/components/RenderElementFallback.cjs.map +1 -0
  43. package/dist/development/internal/components/RenderElementFallback.js +84 -0
  44. package/dist/development/internal/components/RenderElementFallback.js.map +1 -0
  45. package/dist/development/internal/components/RenderLeafFallback.cjs +38 -0
  46. package/dist/development/internal/components/RenderLeafFallback.cjs.map +1 -0
  47. package/dist/development/internal/components/RenderLeafFallback.js +38 -0
  48. package/dist/development/internal/components/RenderLeafFallback.js.map +1 -0
  49. package/dist/development/internal/defaultDeserialize.cjs +14 -0
  50. package/dist/development/internal/defaultDeserialize.cjs.map +1 -0
  51. package/dist/development/internal/defaultDeserialize.js +14 -0
  52. package/dist/development/internal/defaultDeserialize.js.map +1 -0
  53. package/dist/development/internal/renderChildren.cjs +18 -0
  54. package/dist/development/internal/renderChildren.cjs.map +1 -0
  55. package/dist/development/internal/renderChildren.js +18 -0
  56. package/dist/development/internal/renderChildren.js.map +1 -0
  57. package/dist/development/internal/useReferenceMetadata.cjs +37 -0
  58. package/dist/development/internal/useReferenceMetadata.cjs.map +1 -0
  59. package/dist/development/internal/useReferenceMetadata.js +37 -0
  60. package/dist/development/internal/useReferenceMetadata.js.map +1 -0
  61. package/dist/production/RichTextRendererError.cjs +6 -0
  62. package/dist/production/RichTextRendererError.cjs.map +1 -0
  63. package/dist/production/RichTextRendererError.js +6 -0
  64. package/dist/production/RichTextRendererError.js.map +1 -0
  65. package/dist/production/components/RichText.cjs +32 -0
  66. package/dist/production/components/RichText.cjs.map +1 -0
  67. package/dist/production/components/RichText.js +32 -0
  68. package/dist/production/components/RichText.js.map +1 -0
  69. package/dist/production/components/RichTextBlocksRenderer.cjs +30 -0
  70. package/dist/production/components/RichTextBlocksRenderer.cjs.map +1 -0
  71. package/dist/production/components/RichTextBlocksRenderer.js +30 -0
  72. package/dist/production/components/RichTextBlocksRenderer.js.map +1 -0
  73. package/dist/production/components/RichTextFieldRenderer.cjs +28 -0
  74. package/dist/production/components/RichTextFieldRenderer.cjs.map +1 -0
  75. package/dist/production/components/RichTextFieldRenderer.js +28 -0
  76. package/dist/production/components/RichTextFieldRenderer.js.map +1 -0
  77. package/dist/production/components/RichTextRenderer.cjs +14 -0
  78. package/dist/production/components/RichTextRenderer.cjs.map +1 -0
  79. package/dist/production/components/RichTextRenderer.js +14 -0
  80. package/dist/production/components/RichTextRenderer.js.map +1 -0
  81. package/dist/production/hooks/useRichTextBlocksSource.cjs +62 -0
  82. package/dist/production/hooks/useRichTextBlocksSource.cjs.map +1 -0
  83. package/dist/production/hooks/useRichTextBlocksSource.js +62 -0
  84. package/dist/production/hooks/useRichTextBlocksSource.js.map +1 -0
  85. package/dist/production/hooks/useRichTextFieldSource.cjs +26 -0
  86. package/dist/production/hooks/useRichTextFieldSource.cjs.map +1 -0
  87. package/dist/production/hooks/useRichTextFieldSource.js +26 -0
  88. package/dist/production/hooks/useRichTextFieldSource.js.map +1 -0
  89. package/dist/production/index.cjs +17 -0
  90. package/dist/production/index.cjs.map +1 -0
  91. package/dist/production/index.js +17 -0
  92. package/dist/production/index.js.map +1 -0
  93. package/dist/production/internal/components/ElementRenderer.cjs +24 -0
  94. package/dist/production/internal/components/ElementRenderer.cjs.map +1 -0
  95. package/dist/production/internal/components/ElementRenderer.js +24 -0
  96. package/dist/production/internal/components/ElementRenderer.js.map +1 -0
  97. package/dist/production/internal/components/LeafRenderer.cjs +23 -0
  98. package/dist/production/internal/components/LeafRenderer.cjs.map +1 -0
  99. package/dist/production/internal/components/LeafRenderer.js +23 -0
  100. package/dist/production/internal/components/LeafRenderer.js.map +1 -0
  101. package/dist/production/internal/components/RenderElementFallback.cjs +84 -0
  102. package/dist/production/internal/components/RenderElementFallback.cjs.map +1 -0
  103. package/dist/production/internal/components/RenderElementFallback.js +84 -0
  104. package/dist/production/internal/components/RenderElementFallback.js.map +1 -0
  105. package/dist/production/internal/components/RenderLeafFallback.cjs +38 -0
  106. package/dist/production/internal/components/RenderLeafFallback.cjs.map +1 -0
  107. package/dist/production/internal/components/RenderLeafFallback.js +38 -0
  108. package/dist/production/internal/components/RenderLeafFallback.js.map +1 -0
  109. package/dist/production/internal/defaultDeserialize.cjs +14 -0
  110. package/dist/production/internal/defaultDeserialize.cjs.map +1 -0
  111. package/dist/production/internal/defaultDeserialize.js +14 -0
  112. package/dist/production/internal/defaultDeserialize.js.map +1 -0
  113. package/dist/production/internal/renderChildren.cjs +18 -0
  114. package/dist/production/internal/renderChildren.cjs.map +1 -0
  115. package/dist/production/internal/renderChildren.js +18 -0
  116. package/dist/production/internal/renderChildren.js.map +1 -0
  117. package/dist/production/internal/useReferenceMetadata.cjs +37 -0
  118. package/dist/production/internal/useReferenceMetadata.cjs.map +1 -0
  119. package/dist/production/internal/useReferenceMetadata.js +37 -0
  120. package/dist/production/internal/useReferenceMetadata.js.map +1 -0
  121. package/dist/types/RichTextRendererError.d.ts +3 -0
  122. package/dist/types/RichTextRendererError.d.ts.map +1 -0
  123. package/dist/types/components/RichText.d.ts +13 -0
  124. package/dist/types/components/RichText.d.ts.map +1 -0
  125. package/dist/types/components/RichTextBlocksRenderer.d.ts +10 -0
  126. package/dist/types/components/RichTextBlocksRenderer.d.ts.map +1 -0
  127. package/dist/types/components/RichTextFieldRenderer.d.ts +10 -0
  128. package/dist/types/components/RichTextFieldRenderer.d.ts.map +1 -0
  129. package/dist/types/components/RichTextRenderer.d.ts +12 -0
  130. package/dist/types/components/RichTextRenderer.d.ts.map +1 -0
  131. package/dist/types/components/index.d.ts +5 -0
  132. package/dist/types/components/index.d.ts.map +1 -0
  133. package/dist/types/hooks/index.d.ts +3 -0
  134. package/dist/types/hooks/index.d.ts.map +1 -0
  135. package/dist/types/hooks/useRichTextBlocksSource.d.ts +3 -0
  136. package/dist/types/hooks/useRichTextBlocksSource.d.ts.map +1 -0
  137. package/dist/types/hooks/useRichTextFieldSource.d.ts +3 -0
  138. package/dist/types/hooks/useRichTextFieldSource.d.ts.map +1 -0
  139. package/dist/types/index.d.ts +5 -0
  140. package/dist/types/index.d.ts.map +1 -0
  141. package/dist/types/internal/components/ElementRenderer.d.ts +14 -0
  142. package/dist/types/internal/components/ElementRenderer.d.ts.map +1 -0
  143. package/dist/types/internal/components/LeafRenderer.d.ts +12 -0
  144. package/dist/types/internal/components/LeafRenderer.d.ts.map +1 -0
  145. package/dist/types/internal/components/RenderElementFallback.d.ts +14 -0
  146. package/dist/types/internal/components/RenderElementFallback.d.ts.map +1 -0
  147. package/dist/types/internal/components/RenderLeafFallback.d.ts +6 -0
  148. package/dist/types/internal/components/RenderLeafFallback.d.ts.map +1 -0
  149. package/dist/types/internal/defaultDeserialize.d.ts +5 -0
  150. package/dist/types/internal/defaultDeserialize.d.ts.map +1 -0
  151. package/dist/types/internal/renderChildren.d.ts +8 -0
  152. package/dist/types/internal/renderChildren.d.ts.map +1 -0
  153. package/dist/types/internal/useReferenceMetadata.d.ts +9 -0
  154. package/dist/types/internal/useReferenceMetadata.d.ts.map +1 -0
  155. package/dist/types/tsconfig.tsbuildinfo +1 -0
  156. package/dist/types/types/RenderChildren.d.ts +9 -0
  157. package/dist/types/types/RenderChildren.d.ts.map +1 -0
  158. package/dist/types/types/RichTextBlock.d.ts +8 -0
  159. package/dist/types/types/RichTextBlock.d.ts.map +1 -0
  160. package/dist/types/types/RichTextBlockSource.d.ts +9 -0
  161. package/dist/types/types/RichTextBlockSource.d.ts.map +1 -0
  162. package/dist/types/types/RichTextFieldSource.d.ts +6 -0
  163. package/dist/types/types/RichTextFieldSource.d.ts.map +1 -0
  164. package/dist/types/types/RichTextReference.d.ts +5 -0
  165. package/dist/types/types/RichTextReference.d.ts.map +1 -0
  166. package/dist/types/types/RichTextReferenceMetadata.d.ts +15 -0
  167. package/dist/types/types/RichTextReferenceMetadata.d.ts.map +1 -0
  168. package/dist/types/types/RichTextRenderingOptions.d.ts +14 -0
  169. package/dist/types/types/RichTextRenderingOptions.d.ts.map +1 -0
  170. package/dist/types/types/builtin/BuiltinElements.d.ts +48 -0
  171. package/dist/types/types/builtin/BuiltinElements.d.ts.map +1 -0
  172. package/dist/types/types/builtin/BuiltinLeaves.d.ts +21 -0
  173. package/dist/types/types/builtin/BuiltinLeaves.d.ts.map +1 -0
  174. package/dist/types/types/builtin/index.d.ts +3 -0
  175. package/dist/types/types/builtin/index.d.ts.map +1 -0
  176. package/dist/types/types/custom/ReferenceRenderer.d.ts +17 -0
  177. package/dist/types/types/custom/ReferenceRenderer.d.ts.map +1 -0
  178. package/dist/types/types/custom/RenderBlock.d.ts +7 -0
  179. package/dist/types/types/custom/RenderBlock.d.ts.map +1 -0
  180. package/dist/types/types/custom/RenderElement.d.ts +24 -0
  181. package/dist/types/types/custom/RenderElement.d.ts.map +1 -0
  182. package/dist/types/types/custom/RenderLeaf.d.ts +11 -0
  183. package/dist/types/types/custom/RenderLeaf.d.ts.map +1 -0
  184. package/dist/types/types/custom/index.d.ts +5 -0
  185. package/dist/types/types/custom/index.d.ts.map +1 -0
  186. package/dist/types/types/index.d.ts +11 -0
  187. package/dist/types/types/index.d.ts.map +1 -0
  188. package/dist/types/types/structure/RichTextChild.d.ts +5 -0
  189. package/dist/types/types/structure/RichTextChild.d.ts.map +1 -0
  190. package/dist/types/types/structure/RichTextElement.d.ts +8 -0
  191. package/dist/types/types/structure/RichTextElement.d.ts.map +1 -0
  192. package/dist/types/types/structure/RichTextLeaf.d.ts +4 -0
  193. package/dist/types/types/structure/RichTextLeaf.d.ts.map +1 -0
  194. package/dist/types/types/structure/RootEditorNode.d.ts +8 -0
  195. package/dist/types/types/structure/RootEditorNode.d.ts.map +1 -0
  196. package/dist/types/types/structure/index.d.ts +5 -0
  197. package/dist/types/types/structure/index.d.ts.map +1 -0
  198. package/package.json +50 -0
  199. package/readme.md +106 -0
  200. package/src/RichTextRendererError.ts +1 -0
  201. package/src/components/RichText.tsx +52 -0
  202. package/src/components/RichTextBlocksRenderer.tsx +40 -0
  203. package/src/components/RichTextFieldRenderer.tsx +42 -0
  204. package/src/components/RichTextRenderer.tsx +31 -0
  205. package/src/components/index.ts +4 -0
  206. package/src/hooks/index.ts +2 -0
  207. package/src/hooks/useRichTextBlocksSource.ts +75 -0
  208. package/src/hooks/useRichTextFieldSource.ts +26 -0
  209. package/src/index.ts +6 -0
  210. package/src/internal/components/ElementRenderer.tsx +48 -0
  211. package/src/internal/components/LeafRenderer.tsx +36 -0
  212. package/src/internal/components/RenderElementFallback.tsx +153 -0
  213. package/src/internal/components/RenderLeafFallback.tsx +43 -0
  214. package/src/internal/defaultDeserialize.ts +19 -0
  215. package/src/internal/renderChildren.tsx +37 -0
  216. package/src/internal/useReferenceMetadata.ts +62 -0
  217. package/src/tsconfig.json +6 -0
  218. package/src/types/RenderChildren.ts +16 -0
  219. package/src/types/RichTextBlock.ts +11 -0
  220. package/src/types/RichTextBlockSource.ts +10 -0
  221. package/src/types/RichTextFieldSource.ts +6 -0
  222. package/src/types/RichTextReference.ts +6 -0
  223. package/src/types/RichTextReferenceMetadata.ts +27 -0
  224. package/src/types/RichTextRenderingOptions.ts +23 -0
  225. package/src/types/builtin/BuiltinElements.ts +111 -0
  226. package/src/types/builtin/BuiltinLeaves.ts +33 -0
  227. package/src/types/builtin/index.ts +2 -0
  228. package/src/types/custom/ReferenceRenderer.ts +33 -0
  229. package/src/types/custom/RenderBlock.ts +8 -0
  230. package/src/types/custom/RenderElement.ts +37 -0
  231. package/src/types/custom/RenderLeaf.ts +14 -0
  232. package/src/types/custom/index.ts +4 -0
  233. package/src/types/index.ts +11 -0
  234. package/src/types/structure/RichTextChild.ts +11 -0
  235. package/src/types/structure/RichTextElement.ts +11 -0
  236. package/src/types/structure/RichTextLeaf.ts +3 -0
  237. package/src/types/structure/RootEditorNode.ts +11 -0
  238. 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,5 @@
1
+ export * from './RichTextChild';
2
+ export * from './RichTextElement';
3
+ export * from './RichTextLeaf';
4
+ export * from './RootEditorNode';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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.10",
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,4 @@
1
+ export * from './RichText'
2
+ export * from './RichTextFieldRenderer'
3
+ export * from './RichTextBlocksRenderer'
4
+ export * from './RichTextRenderer'
@@ -0,0 +1,2 @@
1
+ export * from './useRichTextFieldSource'
2
+ export * from './useRichTextBlocksSource'
@@ -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,
10
+ sourceField,
11
+ referenceDiscriminationField,
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 (!(sourceFieldResolved 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,6 @@
1
+ export * from './components'
2
+ export * from './hooks'
3
+ export * from './types'
4
+
5
+ export * from './RichTextRendererError'
6
+
@@ -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
+ }