@byline/richtext-lexical 1.11.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/dist/field/apply-value-plugin.js +1 -3
  2. package/dist/field/config/default-extensions.d.ts +32 -0
  3. package/dist/field/config/default-extensions.js +49 -0
  4. package/dist/field/config/default.d.ts +8 -0
  5. package/dist/field/config/default.js +0 -28
  6. package/dist/field/config/editor-config-context.js +2 -6
  7. package/dist/field/config/extensions-list.d.ts +44 -0
  8. package/dist/field/config/extensions-list.js +55 -0
  9. package/dist/field/config/types.d.ts +28 -1
  10. package/dist/field/editor-context.d.ts +1 -1
  11. package/dist/field/editor-context.js +39 -35
  12. package/dist/field/editor.js +11 -57
  13. package/dist/field/{plugins/admonition-plugin/index.d.ts → extensions/admonition/admonition-extension.d.ts} +2 -1
  14. package/dist/field/{plugins/admonition-plugin/index.js → extensions/admonition/admonition-extension.js} +51 -4
  15. package/dist/field/{nodes/admonition-node → extensions/admonition}/admonition-node-component.d.ts +1 -1
  16. package/dist/field/{nodes/admonition-node → extensions/admonition}/admonition-node-component.js +1 -1
  17. package/dist/field/{nodes/admonition-node → extensions/admonition}/admonition-node.d.ts +1 -1
  18. package/dist/field/{plugins/admonition-plugin → extensions/admonition}/fields.d.ts +1 -1
  19. package/dist/field/{nodes/admonition-node → extensions/admonition}/index.js +1 -1
  20. package/dist/field/{plugins/admonition-plugin → extensions/admonition}/types.d.ts +1 -1
  21. package/dist/field/{plugins/auto-embed-plugin/index.d.ts → extensions/auto-embed/auto-embed-extension.d.ts} +1 -0
  22. package/dist/field/{plugins/auto-embed-plugin/index.js → extensions/auto-embed/auto-embed-extension.js} +47 -4
  23. package/dist/field/{plugins/auto-embed-plugin → extensions/auto-embed}/auto-embed-modal.d.ts +1 -1
  24. package/dist/field/extensions/byline-floating-ui/byline-floating-ui-extension.d.ts +68 -0
  25. package/dist/field/extensions/byline-floating-ui/byline-floating-ui-extension.js +19 -0
  26. package/dist/field/{nodes/admonition-node → extensions/byline-floating-ui}/index.d.ts +1 -2
  27. package/dist/field/extensions/byline-floating-ui/index.js +1 -0
  28. package/dist/field/extensions/byline-toolbar/byline-toolbar-extension.d.ts +69 -0
  29. package/dist/field/extensions/byline-toolbar/byline-toolbar-extension.js +19 -0
  30. package/dist/field/{nodes/inline-image-node → extensions/byline-toolbar}/index.d.ts +1 -2
  31. package/dist/field/extensions/byline-toolbar/index.js +1 -0
  32. package/dist/field/extensions/code-highlight/code-highlight-extension.d.ts +10 -0
  33. package/dist/field/extensions/code-highlight/code-highlight-extension.js +11 -0
  34. package/dist/field/extensions/floating-text-format/floating-text-format-extension.d.ts +18 -0
  35. package/dist/field/extensions/floating-text-format/floating-text-format-extension.js +17 -0
  36. package/dist/field/{plugins/floating-text-format-toolbar-plugin → extensions/floating-text-format}/index.js +1 -1
  37. package/dist/field/extensions/horizontal-rule/horizontal-rule-extension.d.ts +6 -0
  38. package/dist/field/extensions/horizontal-rule/horizontal-rule-extension.js +45 -0
  39. package/dist/field/{nodes/inline-image-node → extensions/inline-image}/index.js +1 -1
  40. package/dist/field/{plugins/inline-image-plugin/index.d.ts → extensions/inline-image/inline-image-extension.d.ts} +6 -3
  41. package/dist/field/{plugins/inline-image-plugin/index.js → extensions/inline-image/inline-image-extension.js} +57 -5
  42. package/dist/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node-component.d.ts +2 -2
  43. package/dist/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node-component.js +4 -4
  44. package/dist/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node.d.ts +2 -2
  45. package/dist/field/{nodes/inline-image-node/types.d.ts → extensions/inline-image/node-types.d.ts} +1 -1
  46. package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/types.d.ts +1 -1
  47. package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/utils.d.ts +1 -1
  48. package/dist/field/{plugins/layout-plugin/layout-plugin.d.ts → extensions/layout/layout-extension.d.ts} +1 -0
  49. package/dist/field/{plugins/layout-plugin/layout-plugin.js → extensions/layout/layout-extension.js} +53 -5
  50. package/dist/field/extensions/link/auto-link-extension.d.ts +12 -0
  51. package/dist/field/{plugins/link-plugin/auto-link/index.js → extensions/link/auto-link-extension.js} +14 -2
  52. package/dist/field/{plugins/link-plugin/auto-link → extensions/link}/auto-link-plugin.d.ts +1 -1
  53. package/dist/field/{plugins/link-plugin/auto-link → extensions/link}/auto-link-plugin.js +2 -2
  54. package/dist/field/{plugins/link-plugin → extensions}/link/floating-link-editor.css +2 -2
  55. package/dist/field/{plugins/link-plugin → extensions}/link/floating-link-editor.js +4 -4
  56. package/dist/field/extensions/link/index.d.ts +5 -0
  57. package/dist/field/extensions/link/index.js +5 -0
  58. package/dist/field/extensions/link/link-extension.d.ts +14 -0
  59. package/dist/field/extensions/link/link-extension.js +66 -0
  60. package/dist/field/{plugins/link-plugin/link/types.d.ts → extensions/link/link-modal-types.d.ts} +1 -1
  61. package/dist/field/{plugins/link-plugin → extensions}/link/link-modal.d.ts +1 -1
  62. package/dist/field/{plugins/link-plugin → extensions}/link/link-modal.js +3 -3
  63. package/dist/field/{nodes/link-nodes → extensions/link}/types.d.ts +1 -1
  64. package/dist/field/extensions/table/table-action-menu-plugin/index.d.ts +4 -0
  65. package/dist/field/{plugins → extensions/table}/table-action-menu-plugin/index.js +8 -6
  66. package/dist/field/extensions/table/table-extension.d.ts +17 -0
  67. package/dist/field/extensions/table/table-extension.js +58 -0
  68. package/dist/field/extensions/vimeo/vimeo-extension.d.ts +12 -0
  69. package/dist/field/extensions/vimeo/vimeo-extension.js +16 -0
  70. package/dist/field/extensions/youtube/youtube-extension.d.ts +12 -0
  71. package/dist/field/extensions/youtube/youtube-extension.js +16 -0
  72. package/dist/field/nodes/index.js +7 -7
  73. package/dist/field/plugins/table-plugin/index.js +5 -6
  74. package/dist/field/plugins/toolbar-plugin/index.js +40 -114
  75. package/dist/field/plugins/toolbar-plugin/toolbar-active-editor.d.ts +25 -0
  76. package/dist/field/plugins/toolbar-plugin/toolbar-active-editor.js +17 -0
  77. package/dist/field/themes/lexical-editor-theme.css +13 -3
  78. package/dist/field/themes/lexical-editor-theme.js +1 -0
  79. package/dist/index.d.ts +17 -1
  80. package/dist/index.js +16 -0
  81. package/dist/lexical-editor.d.ts +25 -13
  82. package/dist/lexical-editor.js +9 -1
  83. package/dist/richtext-field.js +6 -1
  84. package/dist/server.d.ts +2 -2
  85. package/dist/server.js +2 -2
  86. package/package.json +7 -10
  87. package/src/field/apply-value-plugin.tsx +6 -6
  88. package/src/field/config/default-extensions.ts +104 -0
  89. package/src/field/config/default.ts +8 -28
  90. package/src/field/config/editor-config-context.tsx +1 -7
  91. package/src/field/config/extensions-list.ts +107 -0
  92. package/src/field/config/types.ts +28 -28
  93. package/src/field/editor-context.tsx +77 -41
  94. package/src/field/editor.tsx +24 -72
  95. package/src/field/extensions/README.md +31 -0
  96. package/src/field/{plugins/admonition-plugin/index.tsx → extensions/admonition/admonition-extension.tsx} +45 -2
  97. package/src/field/{plugins/admonition-plugin → extensions/admonition}/admonition-modal.tsx +1 -1
  98. package/src/field/{nodes/admonition-node → extensions/admonition}/admonition-node-component.tsx +5 -5
  99. package/src/field/{nodes/admonition-node → extensions/admonition}/admonition-node.tsx +1 -1
  100. package/src/field/{plugins/admonition-plugin → extensions/admonition}/fields.ts +1 -1
  101. package/src/field/{nodes/admonition-node → extensions/admonition}/index.ts +5 -1
  102. package/src/field/{plugins/admonition-plugin → extensions/admonition}/types.ts +1 -1
  103. package/src/field/{plugins/auto-embed-plugin/index.tsx → extensions/auto-embed/auto-embed-extension.tsx} +46 -3
  104. package/src/field/{plugins/auto-embed-plugin → extensions/auto-embed}/auto-embed-modal.tsx +1 -1
  105. package/src/field/extensions/byline-floating-ui/byline-floating-ui-extension.ts +90 -0
  106. package/src/field/extensions/byline-floating-ui/index.ts +15 -0
  107. package/src/field/extensions/byline-toolbar/byline-toolbar-extension.ts +95 -0
  108. package/src/field/extensions/byline-toolbar/index.ts +15 -0
  109. package/src/field/extensions/code-highlight/code-highlight-extension.ts +18 -0
  110. package/src/field/extensions/floating-text-format/floating-text-format-extension.ts +39 -0
  111. package/src/field/{plugins/floating-text-format-toolbar-plugin → extensions/floating-text-format}/index.tsx +1 -1
  112. package/src/field/extensions/horizontal-rule/horizontal-rule-extension.tsx +57 -0
  113. package/src/field/{nodes/inline-image-node → extensions/inline-image}/index.ts +1 -1
  114. package/src/field/{plugins/inline-image-plugin/index.tsx → extensions/inline-image/inline-image-extension.tsx} +54 -6
  115. package/src/field/{plugins/inline-image-plugin → extensions/inline-image}/inline-image-modal.tsx +1 -1
  116. package/src/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node-component.tsx +6 -6
  117. package/src/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node.tsx +2 -2
  118. package/src/field/{nodes/inline-image-node/types.ts → extensions/inline-image/node-types.ts} +1 -1
  119. package/src/field/{plugins/inline-image-plugin → extensions/inline-image}/types.ts +1 -1
  120. package/src/field/{plugins/inline-image-plugin → extensions/inline-image}/utils.ts +1 -1
  121. package/src/field/{plugins/layout-plugin/layout-plugin.tsx → extensions/layout/layout-extension.tsx} +47 -8
  122. package/src/field/{plugins/link-plugin/auto-link/index.tsx → extensions/link/auto-link-extension.tsx} +13 -3
  123. package/src/field/{plugins/link-plugin/auto-link → extensions/link}/auto-link-plugin.tsx +2 -2
  124. package/src/field/{plugins/link-plugin → extensions}/link/floating-link-editor.css +2 -2
  125. package/src/field/{plugins/link-plugin → extensions}/link/floating-link-editor.tsx +5 -5
  126. package/src/field/extensions/link/index.ts +5 -0
  127. package/src/field/extensions/link/link-extension.tsx +131 -0
  128. package/src/field/{plugins/link-plugin/link/types.ts → extensions/link/link-modal-types.ts} +1 -1
  129. package/src/field/{plugins/link-plugin → extensions}/link/link-modal.tsx +6 -6
  130. package/src/field/{nodes/link-nodes → extensions/link}/types.ts +1 -1
  131. package/src/field/{plugins → extensions/table}/table-action-menu-plugin/index.tsx +12 -8
  132. package/src/field/extensions/table/table-extension.tsx +86 -0
  133. package/src/field/extensions/vimeo/vimeo-extension.ts +36 -0
  134. package/src/field/extensions/youtube/youtube-extension.ts +37 -0
  135. package/src/field/nodes/index.ts +7 -7
  136. package/src/field/plugins/table-plugin/index.tsx +10 -10
  137. package/src/field/plugins/toolbar-plugin/index.tsx +59 -122
  138. package/src/field/plugins/toolbar-plugin/toolbar-active-editor.tsx +48 -0
  139. package/src/field/themes/lexical-editor-theme.css +18 -3
  140. package/src/field/themes/lexical-editor-theme.tsx +1 -0
  141. package/src/index.ts +45 -2
  142. package/src/lexical-editor.tsx +35 -14
  143. package/src/richtext-field.tsx +8 -1
  144. package/src/server.ts +4 -4
  145. package/dist/field/nodes/link-nodes/index.d.ts +0 -3
  146. package/dist/field/nodes/link-nodes/index.js +0 -3
  147. package/dist/field/plugins/code-highlight-plugin/index.d.ts +0 -9
  148. package/dist/field/plugins/code-highlight-plugin/index.js +0 -11
  149. package/dist/field/plugins/link-plugin/auto-link/index.d.ts +0 -9
  150. package/dist/field/plugins/link-plugin/link/index.d.ts +0 -1
  151. package/dist/field/plugins/link-plugin/link/index.js +0 -43
  152. package/dist/field/plugins/table-action-menu-plugin/index.d.ts +0 -5
  153. package/dist/field/plugins/vimeo-plugin/index.d.ts +0 -3
  154. package/dist/field/plugins/vimeo-plugin/index.js +0 -24
  155. package/dist/field/plugins/youtube-plugin/index.d.ts +0 -3
  156. package/dist/field/plugins/youtube-plugin/index.js +0 -24
  157. package/dist/field/toolbar-extensions.d.ts +0 -31
  158. package/dist/field/toolbar-extensions.js +0 -56
  159. package/src/field/nodes/link-nodes/index.ts +0 -3
  160. package/src/field/plugins/code-highlight-plugin/index.ts +0 -23
  161. package/src/field/plugins/link-plugin/link/index.tsx +0 -99
  162. package/src/field/plugins/vimeo-plugin/index.ts +0 -42
  163. package/src/field/plugins/youtube-plugin/index.ts +0 -43
  164. package/src/field/themes/lexical-editor-theme.js +0 -104
  165. package/src/field/toolbar-extensions.tsx +0 -93
  166. /package/dist/field/{plugins/admonition-plugin → extensions/admonition}/admonition-modal.css +0 -0
  167. /package/dist/field/{plugins/admonition-plugin → extensions/admonition}/admonition-modal.d.ts +0 -0
  168. /package/dist/field/{plugins/admonition-plugin → extensions/admonition}/admonition-modal.js +0 -0
  169. /package/dist/field/{nodes/admonition-node → extensions/admonition}/admonition-node-component.css +0 -0
  170. /package/dist/field/{nodes/admonition-node → extensions/admonition}/admonition-node.js +0 -0
  171. /package/dist/field/{plugins/admonition-plugin → extensions/admonition}/fields.js +0 -0
  172. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/danger-icon.css +0 -0
  173. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/danger-icon.d.ts +0 -0
  174. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/danger-icon.js +0 -0
  175. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/index.d.ts +0 -0
  176. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/index.js +0 -0
  177. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/note-icon.css +0 -0
  178. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/note-icon.d.ts +0 -0
  179. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/note-icon.js +0 -0
  180. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/tip-icon.css +0 -0
  181. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/tip-icon.d.ts +0 -0
  182. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/tip-icon.js +0 -0
  183. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/warning-icon.css +0 -0
  184. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/warning-icon.d.ts +0 -0
  185. /package/dist/field/{nodes/admonition-node → extensions/admonition}/icons/warning-icon.js +0 -0
  186. /package/dist/field/{nodes/admonition-node/types.d.ts → extensions/admonition/node-types.d.ts} +0 -0
  187. /package/dist/field/{nodes/admonition-node/types.js → extensions/admonition/node-types.js} +0 -0
  188. /package/dist/field/{nodes/inline-image-node → extensions/admonition}/types.js +0 -0
  189. /package/dist/field/{plugins/auto-embed-plugin → extensions/auto-embed}/auto-embed-modal.css +0 -0
  190. /package/dist/field/{plugins/auto-embed-plugin → extensions/auto-embed}/auto-embed-modal.js +0 -0
  191. /package/dist/field/{plugins/floating-text-format-toolbar-plugin → extensions/floating-text-format}/index.css +0 -0
  192. /package/dist/field/{plugins/floating-text-format-toolbar-plugin → extensions/floating-text-format}/index.d.ts +0 -0
  193. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/fields.d.ts +0 -0
  194. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/fields.js +0 -0
  195. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/inline-image-modal.css +0 -0
  196. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/inline-image-modal.d.ts +0 -0
  197. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/inline-image-modal.js +0 -0
  198. /package/dist/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node-component.css +0 -0
  199. /package/dist/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node.js +0 -0
  200. /package/dist/field/{nodes/link-nodes/types.js → extensions/inline-image/node-types.js} +0 -0
  201. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/populate.d.ts +0 -0
  202. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/populate.js +0 -0
  203. /package/dist/field/{plugins/admonition-plugin → extensions/inline-image}/types.js +0 -0
  204. /package/dist/field/{plugins/inline-image-plugin → extensions/inline-image}/utils.js +0 -0
  205. /package/dist/field/{plugins/layout-plugin → extensions/layout}/insert-layout-modal.css +0 -0
  206. /package/dist/field/{plugins/layout-plugin → extensions/layout}/insert-layout-modal.d.ts +0 -0
  207. /package/dist/field/{plugins/layout-plugin → extensions/layout}/insert-layout-modal.js +0 -0
  208. /package/dist/field/{nodes/layout-container-node → extensions/layout}/layout-container-node.d.ts +0 -0
  209. /package/dist/field/{nodes/layout-container-node → extensions/layout}/layout-container-node.js +0 -0
  210. /package/dist/field/{nodes/layout-container-node → extensions/layout}/layout-item-node.d.ts +0 -0
  211. /package/dist/field/{nodes/layout-container-node → extensions/layout}/layout-item-node.js +0 -0
  212. /package/dist/field/{nodes/link-nodes → extensions/link}/auto-link-node.d.ts +0 -0
  213. /package/dist/field/{nodes/link-nodes → extensions/link}/auto-link-node.js +0 -0
  214. /package/dist/field/{plugins/link-plugin → extensions}/link/floating-link-editor.d.ts +0 -0
  215. /package/dist/field/{plugins/inline-image-plugin/types.js → extensions/link/link-modal-types.js} +0 -0
  216. /package/dist/field/{nodes/link-nodes → extensions/link}/link-node.d.ts +0 -0
  217. /package/dist/field/{nodes/link-nodes → extensions/link}/link-node.js +0 -0
  218. /package/dist/field/{plugins/link-plugin → extensions/link}/populate.d.ts +0 -0
  219. /package/dist/field/{plugins/link-plugin → extensions/link}/populate.js +0 -0
  220. /package/dist/field/{plugins/link-plugin → extensions}/link/types.js +0 -0
  221. /package/dist/field/{nodes/vimeo-node/index.d.ts → extensions/vimeo/vimeo-node.d.ts} +0 -0
  222. /package/dist/field/{nodes/vimeo-node/index.js → extensions/vimeo/vimeo-node.js} +0 -0
  223. /package/dist/field/{nodes/youtube-node/index.d.ts → extensions/youtube/youtube-node.d.ts} +0 -0
  224. /package/dist/field/{nodes/youtube-node/index.js → extensions/youtube/youtube-node.js} +0 -0
  225. /package/src/field/{plugins/admonition-plugin → extensions/admonition}/admonition-modal.css +0 -0
  226. /package/src/field/{nodes/admonition-node → extensions/admonition}/admonition-node-component.css +0 -0
  227. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/danger-icon.css +0 -0
  228. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/danger-icon.js +0 -0
  229. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/danger-icon.tsx +0 -0
  230. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/index.js +0 -0
  231. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/index.ts +0 -0
  232. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/note-icon.css +0 -0
  233. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/note-icon.js +0 -0
  234. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/note-icon.tsx +0 -0
  235. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/tip-icon.css +0 -0
  236. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/tip-icon.js +0 -0
  237. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/tip-icon.tsx +0 -0
  238. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/warning-icon.css +0 -0
  239. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/warning-icon.js +0 -0
  240. /package/src/field/{nodes/admonition-node → extensions/admonition}/icons/warning-icon.tsx +0 -0
  241. /package/src/field/{nodes/admonition-node/types.ts → extensions/admonition/node-types.ts} +0 -0
  242. /package/src/field/{plugins/auto-embed-plugin → extensions/auto-embed}/auto-embed-modal.css +0 -0
  243. /package/src/field/{plugins/floating-text-format-toolbar-plugin → extensions/floating-text-format}/index.css +0 -0
  244. /package/src/field/{plugins/inline-image-plugin → extensions/inline-image}/fields.ts +0 -0
  245. /package/src/field/{plugins/inline-image-plugin → extensions/inline-image}/inline-image-modal.css +0 -0
  246. /package/src/field/{nodes/inline-image-node → extensions/inline-image}/inline-image-node-component.css +0 -0
  247. /package/src/field/{plugins/inline-image-plugin → extensions/inline-image}/populate.ts +0 -0
  248. /package/src/field/{plugins/layout-plugin → extensions/layout}/insert-layout-modal.css +0 -0
  249. /package/src/field/{plugins/layout-plugin → extensions/layout}/insert-layout-modal.tsx +0 -0
  250. /package/src/field/{nodes/layout-container-node → extensions/layout}/layout-container-node.ts +0 -0
  251. /package/src/field/{nodes/layout-container-node → extensions/layout}/layout-item-node.ts +0 -0
  252. /package/src/field/{nodes/link-nodes → extensions/link}/auto-link-node.ts +0 -0
  253. /package/src/field/{nodes/link-nodes → extensions/link}/link-node.ts +0 -0
  254. /package/src/field/{plugins/link-plugin → extensions/link}/populate.ts +0 -0
  255. /package/src/field/{nodes/vimeo-node/index.tsx → extensions/vimeo/vimeo-node.tsx} +0 -0
  256. /package/src/field/{nodes/youtube-node/index.tsx → extensions/youtube/youtube-node.tsx} +0 -0
@@ -0,0 +1,31 @@
1
+ # `@byline/richtext-lexical` extensions
2
+
3
+ Every built-in feature of the Lexical adapter — and every supported way for a third party to extend it — lives in this directory as a Lexical `defineExtension(...)` co-located with its node class(es), modal, decorator, and (where relevant) populate visitor.
4
+
5
+ This README is a navigation aid only. The full reference and authoring contract lives in the project's [`docs/RICHTEXT.md`](../../../../../docs/RICHTEXT.md) — start with the **Extensibility** section.
6
+
7
+ ## What's where
8
+
9
+ | Directory | What it owns |
10
+ |---|---|
11
+ | `byline-toolbar/` | `BylineToolbarExtension` — the registry that built-in and third-party extensions contribute toolbar items into via `peerDependencies`. |
12
+ | `byline-floating-ui/` | `BylineFloatingUIExtension` — the registry every floating UI (link editor, table action menu, format pop-over, third-party) plugs into via `peerDependencies`. |
13
+ | `floating-text-format/` | Standalone extension that contributes the selection-format pop-over to `BylineFloatingUIExtension`. |
14
+ | `link/` | `LinkExtension`, `AutoLinkExtension`, link node + paste handling + `FloatingLinkEditorPlugin` (contributed back via peer dep), and the link populate visitor. |
15
+ | `table/` | `TableExtension` (Byline wrapper over `@lexical/table`), the table modal, and the `TableActionMenuPlugin` (contributed to the floating-UI registry). |
16
+ | `inline-image/` | `InlineImageExtension`, node + decorator + modal, picker-time embed, and the populate visitor for `{ title, altText, image, sizes }`. |
17
+ | `layout/` | `LayoutExtension`, columns layout node + modal. |
18
+ | `admonition/` | `AdmonitionExtension`, admonition node + modal. |
19
+ | `auto-embed/` | `AutoEmbedExtension` — paste-to-embed UX shared by the YouTube/Vimeo embedders. |
20
+ | `youtube/`, `vimeo/` | Embed extensions and their node decorators. |
21
+ | `code-highlight/` | Syntax-highlight extension over `@lexical/code`. |
22
+ | `horizontal-rule/` | Byline wrapper over the upstream `@lexical/react/LexicalHorizontalRuleNode`. |
23
+
24
+ ## Adding a new extension
25
+
26
+ 1. Create a directory next to these.
27
+ 2. Implement your `defineExtension(...)` (and any nodes / decorators).
28
+ 3. To contribute a toolbar item or a floating UI, declare a peer dependency against `BylineToolbarExtension` / `BylineFloatingUIExtension` — see the worked recipes in `docs/RICHTEXT.md`.
29
+ 4. Either register your extension at site level via `lexicalEditor((c) => c.extensions.add(MyExtension))`, or — if it's a built-in being shipped by this package — append it to `defaultExtensionsArray()` in `field/config/default-extensions.ts`.
30
+
31
+ You should never need to touch `field/editor.tsx` to add a feature.
@@ -12,19 +12,29 @@ import * as React from 'react'
12
12
  import { useEffect } from 'react'
13
13
 
14
14
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
15
+ import { ReactExtension } from '@lexical/react/ReactExtension'
15
16
  import { $insertNodeToNearestRoot, mergeRegister } from '@lexical/utils'
16
17
  import {
17
18
  $getSelection,
18
19
  $isRangeSelection,
19
20
  COMMAND_PRIORITY_EDITOR,
20
21
  COMMAND_PRIORITY_NORMAL,
22
+ configExtension,
21
23
  createCommand,
24
+ declarePeerDependency,
25
+ defineExtension,
22
26
  type LexicalCommand,
23
27
  } from 'lexical'
24
28
 
25
- import { $createAdmonitionNode, AdmonitionNode } from '../../nodes/admonition-node'
29
+ import { useToolbarActiveEditor } from '../../plugins/toolbar-plugin/toolbar-active-editor'
30
+ import { DropDownItem } from '../../ui/dropdown'
31
+ import {
32
+ type BylineToolbarConfig,
33
+ BylineToolbarExtension,
34
+ } from '../byline-toolbar/byline-toolbar-extension'
26
35
  import { AdmonitionModal } from './admonition-modal'
27
- import type { AdmonitionAttributes } from '../../nodes/admonition-node/types'
36
+ import { $createAdmonitionNode, AdmonitionNode } from './admonition-node'
37
+ import type { AdmonitionAttributes } from './node-types'
28
38
  import type { AdmonitionData } from './types'
29
39
 
30
40
  export type InsertAdmonitionPayload = Readonly<AdmonitionAttributes>
@@ -103,3 +113,36 @@ export function AdmonitionPlugin(): React.JSX.Element {
103
113
  />
104
114
  )
105
115
  }
116
+
117
+ function AdmonitionInsertItem(): React.JSX.Element {
118
+ const editor = useToolbarActiveEditor()
119
+ return (
120
+ <DropDownItem
121
+ onClick={() => {
122
+ editor.dispatchCommand(OPEN_ADMONITION_MODAL_COMMAND, null)
123
+ }}
124
+ className="item"
125
+ >
126
+ <i className="icon admonition" />
127
+ <span className="text">Admonition</span>
128
+ </DropDownItem>
129
+ )
130
+ }
131
+
132
+ export const AdmonitionExtension = defineExtension({
133
+ name: '@byline/richtext-lexical/Admonition',
134
+ nodes: () => [AdmonitionNode],
135
+ dependencies: [configExtension(ReactExtension, { decorators: [<AdmonitionPlugin key="d" />] })],
136
+ peerDependencies: [
137
+ declarePeerDependency<typeof BylineToolbarExtension>(BylineToolbarExtension.name, {
138
+ items: [
139
+ {
140
+ id: '@byline/richtext-lexical/Admonition/insert',
141
+ placement: 'insert-menu',
142
+ order: 30,
143
+ node: <AdmonitionInsertItem />,
144
+ },
145
+ ],
146
+ } satisfies Partial<BylineToolbarConfig>),
147
+ ],
148
+ })
@@ -22,7 +22,7 @@ import {
22
22
  } from '@byline/ui/react'
23
23
 
24
24
  import { admonitionTypeOptions, getInitialState, validateFields } from './fields'
25
- import type { AdmonitionType } from '../../nodes/admonition-node/types'
25
+ import type { AdmonitionType } from './node-types'
26
26
  import type { AdmonitionDrawerProps, AdmonitionFormState } from './types'
27
27
 
28
28
  import './admonition-modal.css'
@@ -35,18 +35,18 @@ import {
35
35
  } from 'lexical'
36
36
 
37
37
  import { useEditorConfig } from '../../config/editor-config-context'
38
- // import { LinkPlugin } from '../../plugins/link-plugin/link'
39
- // import { FloatingLinkEditorPlugin } from '../../plugins/link-plugin/link/floating-link-editor'
38
+ // import { LinkPlugin } from '../link/link-extension'
39
+ // import { FloatingLinkEditorPlugin } from '../link/floating-link-editor'
40
40
  import { ContentEditable } from '../../content-editable'
41
41
  import { useSharedHistoryContext } from '../../context/shared-history-context'
42
42
  import { useSharedOnChange } from '../../context/shared-on-change-context'
43
- import { AdmonitionModal } from '../../plugins/admonition-plugin/admonition-modal'
44
43
  import { Placeholder } from '../../ui/placeholder'
44
+ import { AdmonitionModal } from './admonition-modal'
45
45
  import { $isAdmonitionNode } from './admonition-node'
46
46
  import { DangerIcon, NoteIcon, TipIcon, WarningIcon } from './icons'
47
- import type { AdmonitionData } from '../../plugins/admonition-plugin/types'
48
47
  import type { AdmonitionNode } from './admonition-node'
49
- import type { AdmonitionAttributes, AdmonitionType } from './types'
48
+ import type { AdmonitionAttributes, AdmonitionType } from './node-types'
49
+ import type { AdmonitionData } from './types'
50
50
 
51
51
  import './admonition-node-component.css'
52
52
 
@@ -21,7 +21,7 @@ import type {
21
21
  } from 'lexical'
22
22
  import { $applyNodeReplacement, createEditor, DecoratorNode } from 'lexical'
23
23
 
24
- import type { AdmonitionAttributes, AdmonitionType, SerializedAdmonitionNode } from './types'
24
+ import type { AdmonitionAttributes, AdmonitionType, SerializedAdmonitionNode } from './node-types'
25
25
 
26
26
  const AdmonitionNodeComponent = React.lazy(async () => await import('./admonition-node-component'))
27
27
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  import type { RadioGroupValue } from '@byline/ui/react'
10
10
 
11
- import type { AdmonitionType } from '../../nodes/admonition-node'
11
+ import type { AdmonitionType } from './node-types'
12
12
  import type { AdmonitionFormState } from './types'
13
13
 
14
14
  export const admonitionTypeOptions: RadioGroupValue[] = [
@@ -11,4 +11,8 @@ export * from './admonition-node'
11
11
  // lazily via `React.lazy` inside `admonition-node.tsx` so it can land in
12
12
  // its own chunk. Re-exporting it here would static-import it back into
13
13
  // any consumer of this barrel and defeat the split.
14
- export * from './types'
14
+ //
15
+ // Likewise NOT re-exported: `admonition-extension.tsx` and its dependencies
16
+ // (`admonition-modal.tsx`, `fields.ts`, `types.ts`) — those pull React UI
17
+ // and would bloat consumers that only want the node class.
18
+ export * from './node-types'
@@ -6,7 +6,7 @@
6
6
  * Copyright (c) Infonomic Company Limited
7
7
  */
8
8
 
9
- import type { AdmonitionType } from '../../nodes/admonition-node/types'
9
+ import type { AdmonitionType } from './node-types'
10
10
 
11
11
  export interface AdmonitionFormState {
12
12
  title: {
@@ -15,13 +15,26 @@ import {
15
15
  AutoEmbedOption,
16
16
  type EmbedConfig,
17
17
  type EmbedMatchResult,
18
+ INSERT_EMBED_COMMAND,
18
19
  LexicalAutoEmbedPlugin,
19
20
  } from '@lexical/react/LexicalAutoEmbedPlugin'
20
- import type { LexicalEditor } from 'lexical'
21
+ import { ReactExtension } from '@lexical/react/ReactExtension'
22
+ import {
23
+ configExtension,
24
+ declarePeerDependency,
25
+ defineExtension,
26
+ type LexicalEditor,
27
+ } from 'lexical'
21
28
  import * as ReactDOM from 'react-dom'
22
29
 
23
- import { INSERT_VIMEO_COMMAND } from '../vimeo-plugin'
24
- import { INSERT_YOUTUBE_COMMAND } from '../youtube-plugin'
30
+ import { useToolbarActiveEditor } from '../../plugins/toolbar-plugin/toolbar-active-editor'
31
+ import { DropDownItem } from '../../ui/dropdown'
32
+ import {
33
+ type BylineToolbarConfig,
34
+ BylineToolbarExtension,
35
+ } from '../byline-toolbar/byline-toolbar-extension'
36
+ import { INSERT_VIMEO_COMMAND } from '../vimeo/vimeo-extension'
37
+ import { INSERT_YOUTUBE_COMMAND } from '../youtube/youtube-extension'
25
38
 
26
39
  // import { INSERT_FIGMA_COMMAND } from '../FigmaPlugin'
27
40
  // import { INSERT_TWEET_COMMAND } from '../TwitterPlugin'
@@ -321,3 +334,33 @@ export function AutoEmbedPlugin(): React.JSX.Element {
321
334
  </>
322
335
  )
323
336
  }
337
+
338
+ function EmbedInsertItem({ embedConfig }: { embedConfig: AutoEmbedConfig }): React.JSX.Element {
339
+ const editor = useToolbarActiveEditor()
340
+ return (
341
+ <DropDownItem
342
+ onClick={() => {
343
+ editor.dispatchCommand(INSERT_EMBED_COMMAND, embedConfig.type)
344
+ }}
345
+ className="item"
346
+ >
347
+ {embedConfig.icon}
348
+ <span className="text">{embedConfig.contentName}</span>
349
+ </DropDownItem>
350
+ )
351
+ }
352
+
353
+ export const AutoEmbedExtension = defineExtension({
354
+ name: '@byline/richtext-lexical/AutoEmbed',
355
+ dependencies: [configExtension(ReactExtension, { decorators: [<AutoEmbedPlugin key="d" />] })],
356
+ peerDependencies: [
357
+ declarePeerDependency<typeof BylineToolbarExtension>(BylineToolbarExtension.name, {
358
+ items: EmbedConfigs.map((embedConfig, idx) => ({
359
+ id: `@byline/richtext-lexical/AutoEmbed/${embedConfig.type}`,
360
+ placement: 'insert-menu' as const,
361
+ order: 60 + idx,
362
+ node: <EmbedInsertItem embedConfig={embedConfig} />,
363
+ })),
364
+ } satisfies Partial<BylineToolbarConfig>),
365
+ ],
366
+ })
@@ -4,7 +4,7 @@ import { Button, CloseIcon, IconButton, Input, Modal } from '@byline/ui/react'
4
4
  import { type EmbedMatchResult, URL_MATCHER } from '@lexical/react/LexicalAutoEmbedPlugin'
5
5
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
6
6
 
7
- import type { AutoEmbedConfig } from './index'
7
+ import type { AutoEmbedConfig } from './auto-embed-extension'
8
8
 
9
9
  const debounce = (callback: (text: string) => void, delay: number): ((text: string) => void) => {
10
10
  let timeoutId: number
@@ -0,0 +1,90 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import type * as React from 'react'
10
+
11
+ import { defineExtension, safeCast, shallowMergeConfig } from 'lexical'
12
+
13
+ /**
14
+ * Props passed by `Editor.tsx` to every registered floating-UI component.
15
+ * The component renders itself (usually via `createPortal(..., anchorElem)`)
16
+ * inside the editor's floating slot.
17
+ */
18
+ export interface BylineFloatingUIProps {
19
+ anchorElem: HTMLElement
20
+ }
21
+
22
+ export interface BylineFloatingUIItem {
23
+ /**
24
+ * Stable identifier — used as React key and for de-duplication.
25
+ * Convention: `<extension-name>/<purpose>`, e.g.
26
+ * `'@byline/richtext-lexical/Link/floating-editor'`.
27
+ */
28
+ id: string
29
+ /**
30
+ * The floating UI component. Receives `anchorElem` (the editor's
31
+ * inner content-editable wrapper) as a prop and is expected to portal
32
+ * itself into that element.
33
+ */
34
+ Component: React.ComponentType<BylineFloatingUIProps>
35
+ /** Sort key — lower numbers render first. Mostly cosmetic. */
36
+ order?: number
37
+ }
38
+
39
+ export interface BylineFloatingUIConfig {
40
+ items: BylineFloatingUIItem[]
41
+ }
42
+
43
+ /**
44
+ * The floating-UI contract. Other extensions contribute floating UIs by
45
+ * listing `BylineFloatingUIExtension` in their `peerDependencies` and
46
+ * supplying an `items` array. The editor's floating slot reads the merged
47
+ * list once and renders every contributor under the shared anchor.
48
+ *
49
+ * Mirror of `BylineToolbarExtension` for the floating-UI surface — same
50
+ * pattern, same authoring shape.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * import { declarePeerDependency, defineExtension } from 'lexical'
55
+ * import { BylineFloatingUIExtension } from '@byline/richtext-lexical'
56
+ *
57
+ * export const MyExtension = defineExtension({
58
+ * name: '@example/MyExtension',
59
+ * peerDependencies: [
60
+ * declarePeerDependency<typeof BylineFloatingUIExtension>(
61
+ * BylineFloatingUIExtension.name,
62
+ * {
63
+ * items: [{
64
+ * id: '@example/MyExtension/floating',
65
+ * Component: MyFloatingPopover,
66
+ * }],
67
+ * }
68
+ * ),
69
+ * ],
70
+ * })
71
+ * ```
72
+ */
73
+ export const BylineFloatingUIExtension = defineExtension({
74
+ name: '@byline/richtext-lexical/FloatingUI',
75
+ config: safeCast<BylineFloatingUIConfig>({ items: [] }),
76
+ mergeConfig(a, b) {
77
+ const merged = shallowMergeConfig(a, b)
78
+ if (b.items && b.items.length > 0) {
79
+ merged.items = [...a.items, ...b.items]
80
+ }
81
+ return merged
82
+ },
83
+ })
84
+
85
+ /** Sort helper used by the editor's floating-UI slot. */
86
+ export function selectFloatingUIItems(
87
+ items: ReadonlyArray<BylineFloatingUIItem>
88
+ ): BylineFloatingUIItem[] {
89
+ return items.slice().sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
90
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ export {
10
+ type BylineFloatingUIConfig,
11
+ BylineFloatingUIExtension,
12
+ type BylineFloatingUIItem,
13
+ type BylineFloatingUIProps,
14
+ selectFloatingUIItems,
15
+ } from './byline-floating-ui-extension'
@@ -0,0 +1,95 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import type * as React from 'react'
10
+
11
+ import { defineExtension, safeCast, shallowMergeConfig } from 'lexical'
12
+
13
+ /**
14
+ * Where in the Byline toolbar a contributed item is rendered. Built-in
15
+ * extensions and third-party extensions both contribute against these
16
+ * placements via `peerDependencies`; the toolbar plugin reads the merged
17
+ * list and dispatches by `placement`.
18
+ *
19
+ * - `'toolbar'` — appended to the end of the main toolbar row.
20
+ * - `'insert-menu'` — listed inside the "Insert" dropdown that the
21
+ * toolbar shows when at least one insert-menu contribution exists.
22
+ */
23
+ export type BylineToolbarPlacement = 'toolbar' | 'insert-menu'
24
+
25
+ export interface BylineToolbarItem {
26
+ /**
27
+ * Stable identifier — used as React key and for de-duplication.
28
+ * Convention: `<extension-name>/<purpose>`, e.g.
29
+ * `'@byline/richtext-lexical/InlineImage/insert'`.
30
+ */
31
+ id: string
32
+ placement: BylineToolbarPlacement
33
+ /** Sort key within `placement`. Lower numbers render first. */
34
+ order?: number
35
+ node: React.ReactNode
36
+ }
37
+
38
+ export interface BylineToolbarConfig {
39
+ items: BylineToolbarItem[]
40
+ }
41
+
42
+ /**
43
+ * The toolbar contract. Other extensions add toolbar entries by listing
44
+ * `BylineToolbarExtension` in their `peerDependencies` and supplying an
45
+ * `items` array — the configs are merged across every contributor and
46
+ * read once by the toolbar plugin.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * import { declarePeerDependency, defineExtension } from 'lexical'
51
+ * import { BylineToolbarExtension } from '@byline/richtext-lexical'
52
+ *
53
+ * export const MyExtension = defineExtension({
54
+ * name: '@example/MyExtension',
55
+ * peerDependencies: [
56
+ * declarePeerDependency<typeof BylineToolbarExtension>(
57
+ * BylineToolbarExtension.name,
58
+ * {
59
+ * items: [{
60
+ * id: '@example/MyExtension/insert',
61
+ * placement: 'insert-menu',
62
+ * order: 100,
63
+ * node: <MyInsertMenuItem />,
64
+ * }],
65
+ * }
66
+ * ),
67
+ * ],
68
+ * })
69
+ * ```
70
+ */
71
+ export const BylineToolbarExtension = defineExtension({
72
+ name: '@byline/richtext-lexical/Toolbar',
73
+ config: safeCast<BylineToolbarConfig>({ items: [] }),
74
+ mergeConfig(a, b) {
75
+ const merged = shallowMergeConfig(a, b)
76
+ if (b.items && b.items.length > 0) {
77
+ merged.items = [...a.items, ...b.items]
78
+ }
79
+ return merged
80
+ },
81
+ })
82
+
83
+ /**
84
+ * Sort and filter helper used by `toolbar-plugin` and any external
85
+ * surface that wants to render Byline toolbar contributions itself.
86
+ */
87
+ export function selectToolbarItems(
88
+ items: ReadonlyArray<BylineToolbarItem>,
89
+ placement: BylineToolbarPlacement
90
+ ): BylineToolbarItem[] {
91
+ return items
92
+ .filter((item) => item.placement === placement)
93
+ .slice()
94
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
95
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ export {
10
+ type BylineToolbarConfig,
11
+ BylineToolbarExtension,
12
+ type BylineToolbarItem,
13
+ type BylineToolbarPlacement,
14
+ selectToolbarItems,
15
+ } from './byline-toolbar-extension'
@@ -0,0 +1,18 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ *
8
+ * Portions Copyright (c) Meta Platforms, Inc. and affiliates.
9
+ */
10
+
11
+ import { CodeHighlightNode, CodeNode, registerCodeHighlighting } from '@lexical/code'
12
+ import { defineExtension } from 'lexical'
13
+
14
+ export const CodeHighlightExtension = defineExtension({
15
+ name: '@byline/richtext-lexical/CodeHighlight',
16
+ nodes: () => [CodeNode, CodeHighlightNode],
17
+ register: (editor) => registerCodeHighlighting(editor),
18
+ })
@@ -0,0 +1,39 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import { declarePeerDependency, defineExtension } from 'lexical'
10
+
11
+ import {
12
+ type BylineFloatingUIConfig,
13
+ BylineFloatingUIExtension,
14
+ } from '../byline-floating-ui/byline-floating-ui-extension'
15
+ import { FloatingTextFormatToolbarPlugin } from './index'
16
+
17
+ /**
18
+ * Standalone Byline extension that contributes the floating text-format
19
+ * toolbar (the popover shown above a non-collapsed range selection) to
20
+ * the editor. Removing this extension from the registered list hides the
21
+ * UI — `c.extensions.remove(FloatingTextFormatExtension)`.
22
+ *
23
+ * Lives in its own extension because the popover isn't owned by any
24
+ * single feature: it handles bold / italic / underline / strikethrough /
25
+ * subscript / superscript / inline-code / link toggle in one place.
26
+ */
27
+ export const FloatingTextFormatExtension = defineExtension({
28
+ name: '@byline/richtext-lexical/FloatingTextFormat',
29
+ peerDependencies: [
30
+ declarePeerDependency<typeof BylineFloatingUIExtension>(BylineFloatingUIExtension.name, {
31
+ items: [
32
+ {
33
+ id: '@byline/richtext-lexical/FloatingTextFormat/popover',
34
+ Component: FloatingTextFormatToolbarPlugin,
35
+ },
36
+ ],
37
+ } satisfies Partial<BylineFloatingUIConfig>),
38
+ ],
39
+ })
@@ -27,10 +27,10 @@ import {
27
27
  } from 'lexical'
28
28
  import { createPortal } from 'react-dom'
29
29
 
30
- import { $isLinkNode, type LinkAttributes, TOGGLE_LINK_COMMAND } from '../../nodes/link-nodes'
31
30
  import { getDOMRangeRect } from '../../utils/getDOMRangeRect'
32
31
  import { getSelectedNode } from '../../utils/getSelectedNode'
33
32
  import { setFloatingElemPosition } from '../../utils/setFloatingElemPosition'
33
+ import { $isLinkNode, type LinkAttributes, TOGGLE_LINK_COMMAND } from '../link'
34
34
 
35
35
  function TextFormatFloatingToolbar({
36
36
  editor,
@@ -0,0 +1,57 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * This Source Code is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
+ *
8
+ * Copyright (c) Infonomic Company Limited
9
+ */
10
+
11
+ import { HorizontalRuleExtension as LexicalHorizontalRuleExtension } from '@lexical/extension'
12
+ import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode'
13
+ import { declarePeerDependency, defineExtension } from 'lexical'
14
+
15
+ import { useToolbarActiveEditor } from '../../plugins/toolbar-plugin/toolbar-active-editor'
16
+ import { DropDownItem } from '../../ui/dropdown'
17
+ import {
18
+ type BylineToolbarConfig,
19
+ BylineToolbarExtension,
20
+ } from '../byline-toolbar/byline-toolbar-extension'
21
+
22
+ function HorizontalRuleInsertItem(): React.JSX.Element {
23
+ const editor = useToolbarActiveEditor()
24
+ return (
25
+ <DropDownItem
26
+ onClick={() => {
27
+ editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined)
28
+ }}
29
+ className="item"
30
+ >
31
+ <i className="icon horizontal-rule" />
32
+ <span className="text">Horizontal Rule</span>
33
+ </DropDownItem>
34
+ )
35
+ }
36
+
37
+ /**
38
+ * Byline wrapper around the upstream `HorizontalRuleExtension`. Adds a
39
+ * single insert-menu contribution; the underlying extension still owns
40
+ * the node registration and command behaviour.
41
+ */
42
+ export const HorizontalRuleExtension = defineExtension({
43
+ name: '@byline/richtext-lexical/HorizontalRule',
44
+ dependencies: [LexicalHorizontalRuleExtension],
45
+ peerDependencies: [
46
+ declarePeerDependency<typeof BylineToolbarExtension>(BylineToolbarExtension.name, {
47
+ items: [
48
+ {
49
+ id: '@byline/richtext-lexical/HorizontalRule/insert',
50
+ placement: 'insert-menu',
51
+ order: 10,
52
+ node: <HorizontalRuleInsertItem />,
53
+ },
54
+ ],
55
+ } satisfies Partial<BylineToolbarConfig>),
56
+ ],
57
+ })
@@ -7,4 +7,4 @@
7
7
  */
8
8
 
9
9
  export * from './inline-image-node'
10
- export * from './types'
10
+ export * from './node-types'