@jackuait/blok 0.4.1-beta.1 → 0.4.1-beta.12

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 (403) hide show
  1. package/README.md +138 -17
  2. package/codemod/README.md +45 -7
  3. package/codemod/migrate-editorjs-to-blok.js +960 -92
  4. package/codemod/test.js +780 -77
  5. package/dist/blok.mjs +5 -2
  6. package/dist/chunks/blok-BU6NwVkN.mjs +13239 -0
  7. package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
  8. package/dist/chunks/i18next-loader-D8GzSwio.mjs +43 -0
  9. package/dist/{index-CEXLTV6f.mjs → chunks/index-C5e_WLFg.mjs} +2 -2
  10. package/dist/chunks/inline-tool-convert-CLUxkCe_.mjs +1990 -0
  11. package/dist/chunks/messages-0tDXLuyH.mjs +48 -0
  12. package/dist/chunks/messages-2_xedlYw.mjs +48 -0
  13. package/dist/chunks/messages-AHESHJm_.mjs +48 -0
  14. package/dist/chunks/messages-B5hdXZwA.mjs +48 -0
  15. package/dist/chunks/messages-B5jGUnOy.mjs +48 -0
  16. package/dist/chunks/messages-B5puUm7R.mjs +48 -0
  17. package/dist/chunks/messages-B66ZSDCJ.mjs +48 -0
  18. package/dist/chunks/messages-B9Oba7sq.mjs +48 -0
  19. package/dist/chunks/messages-BA0rcTCY.mjs +48 -0
  20. package/dist/chunks/messages-BBJgd5jG.mjs +48 -0
  21. package/dist/chunks/messages-BPqWKx5Z.mjs +48 -0
  22. package/dist/chunks/messages-Bdv-IkfG.mjs +48 -0
  23. package/dist/chunks/messages-BeUhMpsr.mjs +48 -0
  24. package/dist/chunks/messages-Bf6Y3_GI.mjs +48 -0
  25. package/dist/chunks/messages-BiExzWJv.mjs +48 -0
  26. package/dist/chunks/messages-BlpqL8vG.mjs +48 -0
  27. package/dist/chunks/messages-BmKCChWZ.mjs +48 -0
  28. package/dist/chunks/messages-Bn253WWC.mjs +48 -0
  29. package/dist/chunks/messages-BrJHUxQL.mjs +48 -0
  30. package/dist/chunks/messages-C5b7hr_E.mjs +48 -0
  31. package/dist/chunks/messages-C7I_AVH2.mjs +48 -0
  32. package/dist/chunks/messages-CJoBtXU6.mjs +48 -0
  33. package/dist/chunks/messages-CQj2JU2j.mjs +48 -0
  34. package/dist/chunks/messages-CUZ1x1QD.mjs +48 -0
  35. package/dist/chunks/messages-CUy1vn-b.mjs +48 -0
  36. package/dist/chunks/messages-CVeWVKsV.mjs +48 -0
  37. package/dist/chunks/messages-CXHd9SUK.mjs +48 -0
  38. package/dist/chunks/messages-CbMyJSzS.mjs +48 -0
  39. package/dist/chunks/messages-CbhuIWRJ.mjs +48 -0
  40. package/dist/chunks/messages-CeCjVKMW.mjs +48 -0
  41. package/dist/chunks/messages-Cj-t1bdy.mjs +48 -0
  42. package/dist/chunks/messages-CkFT2gle.mjs +48 -0
  43. package/dist/chunks/messages-Cm9aLHeX.mjs +48 -0
  44. package/dist/chunks/messages-CnvW8Slp.mjs +48 -0
  45. package/dist/chunks/messages-Cr-RJ7YB.mjs +48 -0
  46. package/dist/chunks/messages-CrsJ1TEJ.mjs +48 -0
  47. package/dist/chunks/messages-Cu08aLS3.mjs +48 -0
  48. package/dist/chunks/messages-CvaqJFN-.mjs +48 -0
  49. package/dist/chunks/messages-CyDU5lz9.mjs +48 -0
  50. package/dist/chunks/messages-CySyfkMU.mjs +48 -0
  51. package/dist/chunks/messages-Cyi2AMmz.mjs +48 -0
  52. package/dist/chunks/messages-D00OjS2n.mjs +48 -0
  53. package/dist/chunks/messages-DDLgIPDF.mjs +48 -0
  54. package/dist/chunks/messages-DMQIHGRj.mjs +48 -0
  55. package/dist/chunks/messages-DOlC_Tty.mjs +48 -0
  56. package/dist/chunks/messages-DV6shA9b.mjs +48 -0
  57. package/dist/chunks/messages-DY94ykcE.mjs +48 -0
  58. package/dist/chunks/messages-DbVquYKN.mjs +48 -0
  59. package/dist/chunks/messages-DcKOuncK.mjs +48 -0
  60. package/dist/chunks/messages-Dg92dXZ5.mjs +48 -0
  61. package/dist/chunks/messages-DnbbyJT3.mjs +48 -0
  62. package/dist/chunks/messages-DteYq0rv.mjs +48 -0
  63. package/dist/chunks/messages-GC2PhgV3.mjs +48 -0
  64. package/dist/chunks/messages-JGsXAReJ.mjs +48 -0
  65. package/dist/chunks/messages-JZUhXTuV.mjs +48 -0
  66. package/dist/chunks/messages-LvFKBBPa.mjs +48 -0
  67. package/dist/chunks/messages-NP1myMGI.mjs +48 -0
  68. package/dist/chunks/messages-Q4kc_ZtL.mjs +48 -0
  69. package/dist/chunks/messages-RvMHb2Ht.mjs +48 -0
  70. package/dist/chunks/messages-ftMcCEuO.mjs +48 -0
  71. package/dist/chunks/messages-o24dK6CU.mjs +48 -0
  72. package/dist/chunks/messages-pA5TvcAj.mjs +48 -0
  73. package/dist/chunks/messages-rRSHQDCX.mjs +48 -0
  74. package/dist/chunks/messages-srxrv8Yh.mjs +48 -0
  75. package/dist/chunks/messages-wdqp4610.mjs +48 -0
  76. package/dist/chunks/messages-zS1AXZ0y.mjs +48 -0
  77. package/dist/chunks/messages-zSzDzXej.mjs +48 -0
  78. package/dist/full.mjs +50 -0
  79. package/dist/locales.mjs +228 -0
  80. package/dist/messages-0tDXLuyH.mjs +48 -0
  81. package/dist/messages-2_xedlYw.mjs +48 -0
  82. package/dist/messages-AHESHJm_.mjs +48 -0
  83. package/dist/messages-B5hdXZwA.mjs +48 -0
  84. package/dist/messages-B5jGUnOy.mjs +48 -0
  85. package/dist/messages-B5puUm7R.mjs +48 -0
  86. package/dist/messages-B66ZSDCJ.mjs +48 -0
  87. package/dist/messages-B9Oba7sq.mjs +48 -0
  88. package/dist/messages-BA0rcTCY.mjs +48 -0
  89. package/dist/messages-BBJgd5jG.mjs +48 -0
  90. package/dist/messages-BPqWKx5Z.mjs +48 -0
  91. package/dist/messages-Bdv-IkfG.mjs +48 -0
  92. package/dist/messages-BeUhMpsr.mjs +48 -0
  93. package/dist/messages-Bf6Y3_GI.mjs +48 -0
  94. package/dist/messages-BiExzWJv.mjs +48 -0
  95. package/dist/messages-BlpqL8vG.mjs +48 -0
  96. package/dist/messages-BmKCChWZ.mjs +48 -0
  97. package/dist/messages-Bn253WWC.mjs +48 -0
  98. package/dist/messages-BrJHUxQL.mjs +48 -0
  99. package/dist/messages-C5b7hr_E.mjs +48 -0
  100. package/dist/messages-C7I_AVH2.mjs +48 -0
  101. package/dist/messages-CJoBtXU6.mjs +48 -0
  102. package/dist/messages-CQj2JU2j.mjs +48 -0
  103. package/dist/messages-CUZ1x1QD.mjs +48 -0
  104. package/dist/messages-CUy1vn-b.mjs +48 -0
  105. package/dist/messages-CVeWVKsV.mjs +48 -0
  106. package/dist/messages-CXHd9SUK.mjs +48 -0
  107. package/dist/messages-CbMyJSzS.mjs +48 -0
  108. package/dist/messages-CbhuIWRJ.mjs +48 -0
  109. package/dist/messages-CeCjVKMW.mjs +48 -0
  110. package/dist/messages-Cj-t1bdy.mjs +48 -0
  111. package/dist/messages-CkFT2gle.mjs +48 -0
  112. package/dist/messages-Cm9aLHeX.mjs +48 -0
  113. package/dist/messages-CnvW8Slp.mjs +48 -0
  114. package/dist/messages-Cr-RJ7YB.mjs +48 -0
  115. package/dist/messages-CrsJ1TEJ.mjs +48 -0
  116. package/dist/messages-Cu08aLS3.mjs +48 -0
  117. package/dist/messages-CvaqJFN-.mjs +48 -0
  118. package/dist/messages-CyDU5lz9.mjs +48 -0
  119. package/dist/messages-CySyfkMU.mjs +48 -0
  120. package/dist/messages-Cyi2AMmz.mjs +48 -0
  121. package/dist/messages-D00OjS2n.mjs +48 -0
  122. package/dist/messages-DDLgIPDF.mjs +48 -0
  123. package/dist/messages-DMQIHGRj.mjs +48 -0
  124. package/dist/messages-DOlC_Tty.mjs +48 -0
  125. package/dist/messages-DV6shA9b.mjs +48 -0
  126. package/dist/messages-DY94ykcE.mjs +48 -0
  127. package/dist/messages-DbVquYKN.mjs +48 -0
  128. package/dist/messages-DcKOuncK.mjs +48 -0
  129. package/dist/messages-Dg92dXZ5.mjs +48 -0
  130. package/dist/messages-DnbbyJT3.mjs +48 -0
  131. package/dist/messages-DteYq0rv.mjs +48 -0
  132. package/dist/messages-GC2PhgV3.mjs +48 -0
  133. package/dist/messages-JGsXAReJ.mjs +48 -0
  134. package/dist/messages-JZUhXTuV.mjs +48 -0
  135. package/dist/messages-LvFKBBPa.mjs +48 -0
  136. package/dist/messages-NP1myMGI.mjs +48 -0
  137. package/dist/messages-Q4kc_ZtL.mjs +48 -0
  138. package/dist/messages-RvMHb2Ht.mjs +48 -0
  139. package/dist/messages-ftMcCEuO.mjs +48 -0
  140. package/dist/messages-o24dK6CU.mjs +48 -0
  141. package/dist/messages-pA5TvcAj.mjs +48 -0
  142. package/dist/messages-rRSHQDCX.mjs +48 -0
  143. package/dist/messages-srxrv8Yh.mjs +48 -0
  144. package/dist/messages-wdqp4610.mjs +48 -0
  145. package/dist/messages-zS1AXZ0y.mjs +48 -0
  146. package/dist/messages-zSzDzXej.mjs +48 -0
  147. package/dist/tools.mjs +3126 -0
  148. package/dist/vendor.LICENSE.txt +26 -225
  149. package/package.json +63 -24
  150. package/src/blok.ts +267 -0
  151. package/src/components/__module.ts +139 -0
  152. package/src/components/block/api.ts +155 -0
  153. package/src/components/block/index.ts +1428 -0
  154. package/src/components/block-tunes/block-tune-delete.ts +51 -0
  155. package/src/components/blocks.ts +352 -0
  156. package/src/components/constants/data-attributes.ts +344 -0
  157. package/src/components/constants.ts +76 -0
  158. package/src/components/core.ts +392 -0
  159. package/src/components/dom.ts +773 -0
  160. package/src/components/domIterator.ts +189 -0
  161. package/src/components/errors/critical.ts +5 -0
  162. package/src/components/events/BlockChanged.ts +16 -0
  163. package/src/components/events/BlockHovered.ts +21 -0
  164. package/src/components/events/BlockSettingsClosed.ts +12 -0
  165. package/src/components/events/BlockSettingsOpened.ts +12 -0
  166. package/src/components/events/BlokMobileLayoutToggled.ts +15 -0
  167. package/src/components/events/FakeCursorAboutToBeToggled.ts +17 -0
  168. package/src/components/events/FakeCursorHaveBeenSet.ts +17 -0
  169. package/src/components/events/HistoryStateChanged.ts +19 -0
  170. package/src/components/events/RedactorDomChanged.ts +14 -0
  171. package/src/components/events/index.ts +46 -0
  172. package/src/components/flipper.ts +497 -0
  173. package/src/components/i18n/i18next-loader.ts +84 -0
  174. package/src/components/i18n/lightweight-i18n.ts +86 -0
  175. package/src/components/i18n/locales/TRANSLATION_GUIDELINES.md +113 -0
  176. package/src/components/i18n/locales/am/messages.json +45 -0
  177. package/src/components/i18n/locales/ar/messages.json +45 -0
  178. package/src/components/i18n/locales/az/messages.json +45 -0
  179. package/src/components/i18n/locales/bg/messages.json +45 -0
  180. package/src/components/i18n/locales/bn/messages.json +45 -0
  181. package/src/components/i18n/locales/bs/messages.json +45 -0
  182. package/src/components/i18n/locales/cs/messages.json +45 -0
  183. package/src/components/i18n/locales/da/messages.json +45 -0
  184. package/src/components/i18n/locales/de/messages.json +45 -0
  185. package/src/components/i18n/locales/dv/messages.json +45 -0
  186. package/src/components/i18n/locales/el/messages.json +45 -0
  187. package/src/components/i18n/locales/en/messages.json +45 -0
  188. package/src/components/i18n/locales/es/messages.json +45 -0
  189. package/src/components/i18n/locales/et/messages.json +45 -0
  190. package/src/components/i18n/locales/fa/messages.json +45 -0
  191. package/src/components/i18n/locales/fi/messages.json +45 -0
  192. package/src/components/i18n/locales/fil/messages.json +45 -0
  193. package/src/components/i18n/locales/fr/messages.json +45 -0
  194. package/src/components/i18n/locales/gu/messages.json +45 -0
  195. package/src/components/i18n/locales/he/messages.json +45 -0
  196. package/src/components/i18n/locales/hi/messages.json +45 -0
  197. package/src/components/i18n/locales/hr/messages.json +45 -0
  198. package/src/components/i18n/locales/hu/messages.json +45 -0
  199. package/src/components/i18n/locales/hy/messages.json +45 -0
  200. package/src/components/i18n/locales/id/messages.json +45 -0
  201. package/src/components/i18n/locales/index.ts +231 -0
  202. package/src/components/i18n/locales/it/messages.json +45 -0
  203. package/src/components/i18n/locales/ja/messages.json +45 -0
  204. package/src/components/i18n/locales/ka/messages.json +45 -0
  205. package/src/components/i18n/locales/km/messages.json +45 -0
  206. package/src/components/i18n/locales/kn/messages.json +45 -0
  207. package/src/components/i18n/locales/ko/messages.json +45 -0
  208. package/src/components/i18n/locales/ku/messages.json +45 -0
  209. package/src/components/i18n/locales/lo/messages.json +45 -0
  210. package/src/components/i18n/locales/lt/messages.json +45 -0
  211. package/src/components/i18n/locales/lv/messages.json +45 -0
  212. package/src/components/i18n/locales/mk/messages.json +45 -0
  213. package/src/components/i18n/locales/ml/messages.json +45 -0
  214. package/src/components/i18n/locales/mn/messages.json +45 -0
  215. package/src/components/i18n/locales/mr/messages.json +45 -0
  216. package/src/components/i18n/locales/ms/messages.json +45 -0
  217. package/src/components/i18n/locales/my/messages.json +45 -0
  218. package/src/components/i18n/locales/ne/messages.json +45 -0
  219. package/src/components/i18n/locales/nl/messages.json +45 -0
  220. package/src/components/i18n/locales/no/messages.json +45 -0
  221. package/src/components/i18n/locales/pa/messages.json +45 -0
  222. package/src/components/i18n/locales/pl/messages.json +45 -0
  223. package/src/components/i18n/locales/ps/messages.json +45 -0
  224. package/src/components/i18n/locales/pt/messages.json +45 -0
  225. package/src/components/i18n/locales/ro/messages.json +45 -0
  226. package/src/components/i18n/locales/ru/messages.json +45 -0
  227. package/src/components/i18n/locales/sd/messages.json +45 -0
  228. package/src/components/i18n/locales/si/messages.json +45 -0
  229. package/src/components/i18n/locales/sk/messages.json +45 -0
  230. package/src/components/i18n/locales/sl/messages.json +45 -0
  231. package/src/components/i18n/locales/sq/messages.json +45 -0
  232. package/src/components/i18n/locales/sr/messages.json +45 -0
  233. package/src/components/i18n/locales/sv/messages.json +45 -0
  234. package/src/components/i18n/locales/sw/messages.json +45 -0
  235. package/src/components/i18n/locales/ta/messages.json +45 -0
  236. package/src/components/i18n/locales/te/messages.json +45 -0
  237. package/src/components/i18n/locales/th/messages.json +45 -0
  238. package/src/components/i18n/locales/tr/messages.json +45 -0
  239. package/src/components/i18n/locales/ug/messages.json +45 -0
  240. package/src/components/i18n/locales/uk/messages.json +45 -0
  241. package/src/components/i18n/locales/ur/messages.json +45 -0
  242. package/src/components/i18n/locales/vi/messages.json +45 -0
  243. package/src/components/i18n/locales/yi/messages.json +45 -0
  244. package/src/components/i18n/locales/zh/messages.json +45 -0
  245. package/src/components/icons/index.ts +242 -0
  246. package/src/components/inline-tools/inline-tool-bold.ts +2213 -0
  247. package/src/components/inline-tools/inline-tool-convert.ts +142 -0
  248. package/src/components/inline-tools/inline-tool-italic.ts +500 -0
  249. package/src/components/inline-tools/inline-tool-link.ts +540 -0
  250. package/src/components/modules/api/blocks.ts +377 -0
  251. package/src/components/modules/api/caret.ts +125 -0
  252. package/src/components/modules/api/events.ts +51 -0
  253. package/src/components/modules/api/history.ts +73 -0
  254. package/src/components/modules/api/i18n.ts +35 -0
  255. package/src/components/modules/api/index.ts +39 -0
  256. package/src/components/modules/api/inlineToolbar.ts +33 -0
  257. package/src/components/modules/api/listeners.ts +56 -0
  258. package/src/components/modules/api/notifier.ts +46 -0
  259. package/src/components/modules/api/readonly.ts +39 -0
  260. package/src/components/modules/api/sanitizer.ts +30 -0
  261. package/src/components/modules/api/saver.ts +52 -0
  262. package/src/components/modules/api/selection.ts +48 -0
  263. package/src/components/modules/api/styles.ts +72 -0
  264. package/src/components/modules/api/toolbar.ts +79 -0
  265. package/src/components/modules/api/tools.ts +16 -0
  266. package/src/components/modules/api/tooltip.ts +67 -0
  267. package/src/components/modules/api/ui.ts +36 -0
  268. package/src/components/modules/blockEvents.ts +1591 -0
  269. package/src/components/modules/blockManager.ts +1356 -0
  270. package/src/components/modules/blockSelection.ts +708 -0
  271. package/src/components/modules/caret.ts +853 -0
  272. package/src/components/modules/crossBlockSelection.ts +329 -0
  273. package/src/components/modules/dragManager.ts +1204 -0
  274. package/src/components/modules/history.ts +1098 -0
  275. package/src/components/modules/i18n.ts +332 -0
  276. package/src/components/modules/index.ts +139 -0
  277. package/src/components/modules/modificationsObserver.ts +147 -0
  278. package/src/components/modules/paste.ts +1092 -0
  279. package/src/components/modules/readonly.ts +136 -0
  280. package/src/components/modules/rectangleSelection.ts +711 -0
  281. package/src/components/modules/renderer.ts +155 -0
  282. package/src/components/modules/saver.ts +283 -0
  283. package/src/components/modules/toolbar/blockSettings.ts +782 -0
  284. package/src/components/modules/toolbar/index.ts +1296 -0
  285. package/src/components/modules/toolbar/inline.ts +956 -0
  286. package/src/components/modules/tools.ts +625 -0
  287. package/src/components/modules/ui.ts +1283 -0
  288. package/src/components/polyfills.ts +113 -0
  289. package/src/components/selection.ts +1179 -0
  290. package/src/components/tools/base.ts +301 -0
  291. package/src/components/tools/block.ts +339 -0
  292. package/src/components/tools/collection.ts +67 -0
  293. package/src/components/tools/factory.ts +138 -0
  294. package/src/components/tools/inline.ts +71 -0
  295. package/src/components/tools/tune.ts +33 -0
  296. package/src/components/ui/toolbox.ts +610 -0
  297. package/src/components/utils/announcer.ts +205 -0
  298. package/src/components/utils/api.ts +20 -0
  299. package/src/components/utils/bem.ts +26 -0
  300. package/src/components/utils/blocks.ts +284 -0
  301. package/src/components/utils/caret.ts +1067 -0
  302. package/src/components/utils/data-model-transform.ts +382 -0
  303. package/src/components/utils/events.ts +117 -0
  304. package/src/components/utils/keyboard.ts +60 -0
  305. package/src/components/utils/listeners.ts +296 -0
  306. package/src/components/utils/mutations.ts +39 -0
  307. package/src/components/utils/notifier/draw.ts +190 -0
  308. package/src/components/utils/notifier/index.ts +66 -0
  309. package/src/components/utils/notifier/types.ts +1 -0
  310. package/src/components/utils/notifier.ts +77 -0
  311. package/src/components/utils/placeholder.ts +140 -0
  312. package/src/components/utils/popover/components/hint/hint.const.ts +10 -0
  313. package/src/components/utils/popover/components/hint/hint.ts +46 -0
  314. package/src/components/utils/popover/components/hint/index.ts +6 -0
  315. package/src/components/utils/popover/components/popover-header/index.ts +2 -0
  316. package/src/components/utils/popover/components/popover-header/popover-header.const.ts +8 -0
  317. package/src/components/utils/popover/components/popover-header/popover-header.ts +80 -0
  318. package/src/components/utils/popover/components/popover-header/popover-header.types.ts +14 -0
  319. package/src/components/utils/popover/components/popover-item/index.ts +13 -0
  320. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +50 -0
  321. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +680 -0
  322. package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts +14 -0
  323. package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts +136 -0
  324. package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +20 -0
  325. package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts +117 -0
  326. package/src/components/utils/popover/components/popover-item/popover-item.ts +197 -0
  327. package/src/components/utils/popover/components/search-input/index.ts +2 -0
  328. package/src/components/utils/popover/components/search-input/search-input.const.ts +8 -0
  329. package/src/components/utils/popover/components/search-input/search-input.ts +178 -0
  330. package/src/components/utils/popover/components/search-input/search-input.types.ts +59 -0
  331. package/src/components/utils/popover/index.ts +13 -0
  332. package/src/components/utils/popover/popover-abstract.ts +457 -0
  333. package/src/components/utils/popover/popover-desktop.ts +682 -0
  334. package/src/components/utils/popover/popover-inline.ts +338 -0
  335. package/src/components/utils/popover/popover-mobile.ts +201 -0
  336. package/src/components/utils/popover/popover.const.ts +81 -0
  337. package/src/components/utils/popover/utils/popover-states-history.ts +72 -0
  338. package/src/components/utils/promise-queue.ts +43 -0
  339. package/src/components/utils/sanitizer.ts +537 -0
  340. package/src/components/utils/scroll-locker.ts +87 -0
  341. package/src/components/utils/shortcut.ts +231 -0
  342. package/src/components/utils/shortcuts.ts +113 -0
  343. package/src/components/utils/tools.ts +110 -0
  344. package/src/components/utils/tooltip.ts +591 -0
  345. package/src/components/utils/tw.ts +241 -0
  346. package/src/components/utils.ts +1081 -0
  347. package/src/env.d.ts +13 -0
  348. package/src/full.ts +69 -0
  349. package/src/locales.ts +51 -0
  350. package/src/stories/Block.stories.ts +498 -0
  351. package/src/stories/EditorModes.stories.ts +505 -0
  352. package/src/stories/Header.stories.ts +137 -0
  353. package/src/stories/InlineToolbar.stories.ts +498 -0
  354. package/src/stories/List.stories.ts +259 -0
  355. package/src/stories/Notifier.stories.ts +340 -0
  356. package/src/stories/Paragraph.stories.ts +112 -0
  357. package/src/stories/Placeholder.stories.ts +319 -0
  358. package/src/stories/Popover.stories.ts +759 -0
  359. package/src/stories/Selection.stories.ts +250 -0
  360. package/src/stories/StubBlock.stories.ts +156 -0
  361. package/src/stories/Toolbar.stories.ts +223 -0
  362. package/src/stories/Toolbox.stories.ts +166 -0
  363. package/src/stories/Tooltip.stories.ts +198 -0
  364. package/src/stories/helpers.ts +463 -0
  365. package/src/styles/main.css +126 -0
  366. package/src/tools/header/index.ts +647 -0
  367. package/src/tools/index.ts +45 -0
  368. package/src/tools/list/index.ts +1826 -0
  369. package/src/tools/paragraph/index.ts +412 -0
  370. package/src/tools/stub/index.ts +107 -0
  371. package/src/types-internal/blok-modules.d.ts +87 -0
  372. package/src/types-internal/html-janitor.d.ts +28 -0
  373. package/src/types-internal/module-config.d.ts +11 -0
  374. package/src/variants/all-locales.ts +155 -0
  375. package/src/variants/blok-maximum.ts +20 -0
  376. package/src/variants/blok-minimum.ts +243 -0
  377. package/types/api/blocks.d.ts +9 -1
  378. package/types/api/history.d.ts +7 -0
  379. package/types/api/i18n.d.ts +22 -3
  380. package/types/api/selection.d.ts +6 -0
  381. package/types/api/styles.d.ts +23 -10
  382. package/types/configs/blok-config.d.ts +29 -0
  383. package/types/configs/i18n-config.d.ts +52 -2
  384. package/types/configs/i18n-dictionary.d.ts +16 -90
  385. package/types/configs/sanitizer-config.d.ts +25 -1
  386. package/types/data-attributes.d.ts +170 -0
  387. package/types/data-formats/output-data.d.ts +15 -0
  388. package/types/full.d.ts +80 -0
  389. package/types/index.d.ts +30 -13
  390. package/types/locales.d.ts +59 -0
  391. package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
  392. package/types/tools/block-tool.d.ts +11 -2
  393. package/types/tools/header.d.ts +18 -0
  394. package/types/tools/index.d.ts +1 -0
  395. package/types/tools/list.d.ts +91 -0
  396. package/types/tools/paragraph.d.ts +71 -0
  397. package/types/tools/tool-settings.d.ts +99 -6
  398. package/types/tools/tool.d.ts +6 -0
  399. package/types/tools-entry.d.ts +49 -0
  400. package/types/utils/popover/popover-item.d.ts +24 -5
  401. package/types/utils/popover/popover.d.ts +13 -0
  402. package/dist/blok-C8XbyLHh.mjs +0 -25795
  403. package/dist/blok.umd.js +0 -181
@@ -0,0 +1,610 @@
1
+ import { beautifyShortcut, capitalize, isMobileScreen } from '../utils';
2
+ import { Shortcuts } from '../utils/shortcuts';
3
+ import type { BlockToolAdapter } from '../tools/block';
4
+ import type { ToolsCollection } from '../tools/collection';
5
+ import type { API, BlockToolData, ToolboxConfigEntry, PopoverItemParams, BlockAPI } from '@/types';
6
+ import { EventsDispatcher } from '../utils/events';
7
+ import { translateToolTitle, type I18nInstance } from '../utils/tools';
8
+ import { PopoverEvent } from '@/types/utils/popover/popover-event';
9
+ import { Listeners } from '../utils/listeners';
10
+ import { Dom } from '../dom';
11
+ import type { Popover } from '../utils/popover';
12
+ import { PopoverDesktop, PopoverMobile } from '../utils/popover';
13
+ import { BlokMobileLayoutToggled } from '../events';
14
+
15
+ /**
16
+ * @todo the first Tab on the Block — focus Plus Button, the second — focus Block Tunes Toggler, the third — focus next Block
17
+ */
18
+
19
+ /**
20
+ * Event that can be triggered by the Toolbox
21
+ */
22
+ export enum ToolboxEvent {
23
+ /**
24
+ * When the Toolbox is opened
25
+ */
26
+ Opened = 'toolbox-opened',
27
+
28
+ /**
29
+ * When the Toolbox is closed
30
+ */
31
+ Closed = 'toolbox-closed',
32
+
33
+ /**
34
+ * When the new Block added by Toolbox
35
+ */
36
+ BlockAdded = 'toolbox-block-added',
37
+ }
38
+
39
+ /**
40
+ * Events fired by the Toolbox
41
+ *
42
+ * Event name -> payload
43
+ */
44
+ export interface ToolboxEventMap {
45
+ [ToolboxEvent.Opened]: undefined;
46
+ [ToolboxEvent.Closed]: undefined;
47
+ [ToolboxEvent.BlockAdded]: {
48
+ block: BlockAPI
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Available i18n dict keys that should be passed to the constructor
54
+ */
55
+ type ToolboxTextLabelsKeys = 'filter' | 'nothingFound';
56
+
57
+ /**
58
+ * Toolbox
59
+ * This UI element contains list of Block Tools available to be inserted
60
+ * It appears after click on the Plus Button
61
+ * @implements {EventsDispatcher} with some events, see {@link ToolboxEvent}
62
+ */
63
+ export class Toolbox extends EventsDispatcher<ToolboxEventMap> {
64
+ /**
65
+ * Returns True if Toolbox is Empty and nothing to show
66
+ * @returns {boolean}
67
+ */
68
+ public get isEmpty(): boolean {
69
+ return this.toolsToBeDisplayed.length === 0;
70
+ }
71
+
72
+ /**
73
+ * Opening state
74
+ * @type {boolean}
75
+ */
76
+ public opened = false;
77
+
78
+ /**
79
+ * Listeners util instance
80
+ */
81
+ protected listeners: Listeners = new Listeners();
82
+
83
+ /**
84
+ * Blok API
85
+ */
86
+ private api: API;
87
+
88
+ /**
89
+ * Popover instance. There is a util for vertical lists.
90
+ * Null until initialized
91
+ */
92
+ private popover: Popover | null = null;
93
+
94
+ /**
95
+ * List of Tools available. Some of them will be shown in the Toolbox
96
+ */
97
+ private tools: ToolsCollection<BlockToolAdapter>;
98
+
99
+ /**
100
+ * Cache for tools to be displayed
101
+ */
102
+ private _toolsToBeDisplayed: BlockToolAdapter[] | undefined;
103
+
104
+ /**
105
+ * Cache for toolbox items to be displayed
106
+ */
107
+ private _toolboxItemsToBeDisplayed: PopoverItemParams[] | undefined;
108
+
109
+ /**
110
+ * Text labels used in the Toolbox. Should be passed from the i18n module
111
+ */
112
+ private i18nLabels: Record<ToolboxTextLabelsKeys, string>;
113
+
114
+ /**
115
+ * I18n instance for translations
116
+ */
117
+ private i18n: I18nInstance;
118
+
119
+ /**
120
+ * Current module HTML Elements
121
+ */
122
+ private nodes: {
123
+ toolbox: HTMLElement;
124
+ } ;
125
+
126
+ /**
127
+ * CSS styles
128
+ * @deprecated Use data attributes for identification instead
129
+ */
130
+ private static get CSS(): {
131
+ toolbox: string;
132
+ } {
133
+ return {
134
+ toolbox: '',
135
+ };
136
+ }
137
+
138
+ /**
139
+ * Element relative to which the popover should be positioned
140
+ */
141
+ private triggerElement?: HTMLElement;
142
+
143
+ /**
144
+ * The block element currently being listened to for inline slash search
145
+ */
146
+ private currentBlockForSearch: HTMLElement | null = null;
147
+
148
+ /**
149
+ * Cached contentEditable element for the current block being searched.
150
+ * Avoids repeated DOM queries on each input event.
151
+ */
152
+ private currentContentEditable: Element | null = null;
153
+
154
+ /**
155
+ * Toolbox constructor
156
+ * @param options - available parameters
157
+ * @param options.api - Blok API methods
158
+ * @param options.tools - Tools available to check whether some of them should be displayed at the Toolbox or not
159
+ * @param options.i18n - I18n instance for translations
160
+ * @param options.triggerElement - Element relative to which the popover should be positioned
161
+ */
162
+ constructor({ api, tools, i18nLabels, i18n, triggerElement }: {
163
+ api: API;
164
+ tools: ToolsCollection<BlockToolAdapter>;
165
+ i18nLabels: Record<ToolboxTextLabelsKeys, string>;
166
+ i18n: I18nInstance;
167
+ triggerElement?: HTMLElement;
168
+ }) {
169
+ super();
170
+
171
+ this.api = api;
172
+ this.tools = tools;
173
+ this.i18nLabels = i18nLabels;
174
+ this.i18n = i18n;
175
+ this.triggerElement = triggerElement;
176
+
177
+ this.enableShortcuts();
178
+
179
+ this.nodes = {
180
+ toolbox: Dom.make('div'),
181
+ };
182
+ this.nodes.toolbox.setAttribute('data-blok-testid', 'toolbox');
183
+
184
+ this.initPopover();
185
+
186
+ this.api.events.on(BlokMobileLayoutToggled, this.handleMobileLayoutToggle);
187
+ }
188
+
189
+ /**
190
+ * Returns root block settings element
191
+ */
192
+ public getElement(): HTMLElement | null {
193
+ return this.nodes.toolbox;
194
+ }
195
+
196
+ /**
197
+ * Checks if the element is contained in the Toolbox or its Popover
198
+ * @param element - element to check
199
+ */
200
+ public contains(element: HTMLElement): boolean {
201
+ if (this.nodes.toolbox.contains(element)) {
202
+ return true;
203
+ }
204
+
205
+ if (this.popover?.getElement().contains(element)) {
206
+ return true;
207
+ }
208
+
209
+ return false;
210
+ }
211
+
212
+ /**
213
+ * Returns true if the Toolbox has the Flipper activated and the Flipper has selected button
214
+ */
215
+ public hasFocus(): boolean | undefined {
216
+ if (this.popover === null) {
217
+ return;
218
+ }
219
+
220
+ return 'hasFocus' in this.popover ? this.popover.hasFocus() : undefined;
221
+ }
222
+
223
+ /**
224
+ * Destroy Module
225
+ */
226
+ public destroy(): void {
227
+ super.destroy();
228
+
229
+ if (this.nodes && this.nodes.toolbox) {
230
+ this.nodes.toolbox.remove();
231
+ }
232
+
233
+ this.removeAllShortcuts();
234
+ this.popover?.off(PopoverEvent.Closed, this.onPopoverClose);
235
+ this.listeners.destroy();
236
+ this.api.events.off(BlokMobileLayoutToggled, this.handleMobileLayoutToggle);
237
+ }
238
+
239
+ /**
240
+ * Toolbox Tool's button click handler
241
+ * @param toolName - tool type to be activated
242
+ * @param blockDataOverrides - Block data predefined by the activated Toolbox item
243
+ */
244
+ public async toolButtonActivated(toolName: string, blockDataOverrides?: BlockToolData): Promise<void> {
245
+ await this.insertNewBlock(toolName, blockDataOverrides);
246
+ }
247
+
248
+ /**
249
+ * Open Toolbox with Tools
250
+ */
251
+ public open(): void {
252
+ if (this.isEmpty) {
253
+ return;
254
+ }
255
+
256
+ /**
257
+ * Stop mutation watching on the current block when toolbox opens.
258
+ * This prevents spurious block-changed events from DOM manipulations
259
+ * that may occur during toolbox interactions (focus changes, etc).
260
+ */
261
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
262
+
263
+ this.api.blocks.stopBlockMutationWatching(currentBlockIndex);
264
+
265
+ this.popover?.show();
266
+ this.opened = true;
267
+ this.emit(ToolboxEvent.Opened);
268
+ this.startListeningToBlockInput();
269
+ }
270
+
271
+ /**
272
+ * Close Toolbox
273
+ */
274
+ public close(): void {
275
+ this.popover?.hide();
276
+ this.opened = false;
277
+ this.emit(ToolboxEvent.Closed);
278
+ }
279
+
280
+ /**
281
+ * Close Toolbox
282
+ */
283
+ public toggle(): void {
284
+ if (!this.opened) {
285
+ this.open();
286
+ } else {
287
+ this.close();
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Destroys existing popover instance and contructs the new one.
293
+ */
294
+ public handleMobileLayoutToggle = (): void => {
295
+ this.destroyPopover();
296
+ this.initPopover();
297
+ };
298
+
299
+ /**
300
+ * Creates toolbox popover and appends it inside wrapper element
301
+ */
302
+ private initPopover(): void {
303
+ const PopoverClass = isMobileScreen() ? PopoverMobile : PopoverDesktop;
304
+
305
+ this.popover = new PopoverClass({
306
+ scopeElement: this.api.ui.nodes.redactor,
307
+ trigger: this.triggerElement || this.nodes.toolbox,
308
+ messages: {
309
+ nothingFound: this.i18nLabels.nothingFound,
310
+ search: this.i18nLabels.filter,
311
+ },
312
+ items: this.toolboxItemsToBeDisplayed,
313
+ handleContentEditableNavigation: true,
314
+ });
315
+
316
+ this.popover.on(PopoverEvent.Closed, this.onPopoverClose);
317
+ this.popover.getElement().setAttribute('data-blok-testid', 'toolbox-popover');
318
+ }
319
+
320
+ /**
321
+ * Destroys popover instance and removes it from DOM
322
+ */
323
+ private destroyPopover(): void {
324
+ if (this.popover !== null) {
325
+ this.popover.hide();
326
+ this.popover.off(PopoverEvent.Closed, this.onPopoverClose);
327
+ this.popover.destroy();
328
+ this.popover = null;
329
+ }
330
+
331
+ if (this.nodes.toolbox !== null) {
332
+ this.nodes.toolbox.innerHTML = '';
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Handles popover close event
338
+ */
339
+ private onPopoverClose = (): void => {
340
+ this.stopListeningToBlockInput();
341
+ this.opened = false;
342
+ this.emit(ToolboxEvent.Closed);
343
+ };
344
+
345
+ /**
346
+ * Returns list of tools that enables the Toolbox (by specifying the 'toolbox' getter)
347
+ */
348
+ private get toolsToBeDisplayed(): BlockToolAdapter[] {
349
+ if (this._toolsToBeDisplayed) {
350
+ return this._toolsToBeDisplayed;
351
+ }
352
+
353
+ const result: BlockToolAdapter[] = [];
354
+
355
+ this.tools.forEach((tool) => {
356
+ const toolToolboxSettings = tool.toolbox;
357
+
358
+ if (toolToolboxSettings) {
359
+ result.push(tool);
360
+ }
361
+ });
362
+
363
+ this._toolsToBeDisplayed = result;
364
+
365
+ return result;
366
+ }
367
+
368
+ /**
369
+ * Returns list of items that will be displayed in toolbox
370
+ */
371
+ private get toolboxItemsToBeDisplayed(): PopoverItemParams[] {
372
+ if (this._toolboxItemsToBeDisplayed) {
373
+ return this._toolboxItemsToBeDisplayed;
374
+ }
375
+
376
+ /**
377
+ * Maps tool data to popover item structure
378
+ */
379
+ const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockToolAdapter, displaySecondaryLabel = true): PopoverItemParams => {
380
+ // Get English title for search fallback
381
+ const titleKey = toolboxItem.titleKey;
382
+ const englishTitleKey = titleKey ? `toolNames.${titleKey}` : undefined;
383
+ const englishTitle = englishTitleKey
384
+ ? this.api.i18n.getEnglishTranslation(englishTitleKey)
385
+ : toolboxItem.title;
386
+
387
+ // Merge library searchTerms with user-provided searchTerms
388
+ const librarySearchTerms = toolboxItem.searchTerms ?? [];
389
+ const userSearchTerms = tool.searchTerms ?? [];
390
+ const mergedSearchTerms = [...new Set([...librarySearchTerms, ...userSearchTerms])];
391
+
392
+ // Use entry-level shortcut if available, otherwise fall back to tool-level shortcut (for first entry only)
393
+ const shortcut = toolboxItem.shortcut ?? (displaySecondaryLabel ? tool.shortcut : undefined);
394
+
395
+ return {
396
+ icon: toolboxItem.icon,
397
+ title: translateToolTitle(this.i18n, toolboxItem, capitalize(tool.name)),
398
+ name: toolboxItem.name ?? tool.name,
399
+ onActivate: (): void => {
400
+ void this.toolButtonActivated(tool.name, toolboxItem.data);
401
+ },
402
+ secondaryLabel: shortcut ? beautifyShortcut(shortcut) : '',
403
+ englishTitle,
404
+ searchTerms: mergedSearchTerms,
405
+ };
406
+ };
407
+
408
+ const result = this.toolsToBeDisplayed
409
+ .reduce<PopoverItemParams[]>((acc, tool) => {
410
+ const { toolbox } = tool;
411
+
412
+ if (toolbox === undefined) {
413
+ return acc;
414
+ }
415
+
416
+ const items = Array.isArray(toolbox) ? toolbox : [ toolbox ];
417
+
418
+ items.forEach((item, index) => {
419
+ acc.push(toPopoverItem(item, tool, index === 0));
420
+ });
421
+
422
+ return acc;
423
+ }, []);
424
+
425
+ this._toolboxItemsToBeDisplayed = result;
426
+
427
+ return result;
428
+ }
429
+
430
+ /**
431
+ * Iterate all tools and enable theirs shortcuts if specified
432
+ */
433
+ private enableShortcuts(): void {
434
+ this.toolsToBeDisplayed.forEach((tool: BlockToolAdapter) => {
435
+ const shortcut = tool.shortcut;
436
+
437
+ if (shortcut) {
438
+ this.enableShortcutForTool(tool.name, shortcut);
439
+ }
440
+ });
441
+ }
442
+
443
+ /**
444
+ * Enable shortcut Block Tool implemented shortcut
445
+ * @param {string} toolName - Tool name
446
+ * @param {string} shortcut - shortcut according to the ShortcutData Module format
447
+ */
448
+ private enableShortcutForTool(toolName: string, shortcut: string): void {
449
+ Shortcuts.add({
450
+ name: shortcut,
451
+ on: this.api.ui.nodes.redactor,
452
+ handler: async (event: KeyboardEvent) => {
453
+ event.preventDefault();
454
+
455
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
456
+ const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
457
+
458
+ /**
459
+ * Try to convert current Block to shortcut's tool
460
+ * If conversion is not possible, insert a new Block below
461
+ */
462
+ if (currentBlock) {
463
+ try {
464
+ const newBlock = await this.api.blocks.convert(currentBlock.id, toolName);
465
+
466
+ this.api.caret.setToBlock(newBlock, 'end');
467
+
468
+ return;
469
+ } catch (_error) {}
470
+ }
471
+
472
+ await this.insertNewBlock(toolName);
473
+ },
474
+ });
475
+ }
476
+
477
+ /**
478
+ * Removes all added shortcuts
479
+ * Fired when the Read-Only mode is activated
480
+ */
481
+ private removeAllShortcuts(): void {
482
+ this.toolsToBeDisplayed.forEach((tool: BlockToolAdapter) => {
483
+ const shortcut = tool.shortcut;
484
+
485
+ if (shortcut) {
486
+ Shortcuts.remove(this.api.ui.nodes.redactor, shortcut);
487
+ }
488
+ });
489
+ }
490
+
491
+ /**
492
+ * Inserts new block
493
+ * Can be called when button clicked on Toolbox or by ShortcutData
494
+ * @param {string} toolName - Tool name
495
+ * @param blockDataOverrides - predefined Block data
496
+ */
497
+ private async insertNewBlock(toolName: string, blockDataOverrides?: BlockToolData): Promise<void> {
498
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
499
+ const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
500
+
501
+ if (!currentBlock) {
502
+ return;
503
+ }
504
+
505
+ /**
506
+ * Check if the block contains only slash search text (e.g., "/head").
507
+ * If so, treat it as empty and replace it with the new block.
508
+ */
509
+ const shouldReplaceBlock = currentBlock.isEmpty || this.isBlockSlashSearchOnly(currentBlock.holder);
510
+
511
+ /**
512
+ * On mobile version, we see the Plus Button even near non-empty blocks,
513
+ * so if current block is not empty, add the new block below the current
514
+ */
515
+ const index = shouldReplaceBlock ? currentBlockIndex : currentBlockIndex + 1;
516
+
517
+ const hasBlockDataOverrides = blockDataOverrides !== undefined && Object.keys(blockDataOverrides as Record<string, unknown>).length > 0;
518
+
519
+ const blockData: BlockToolData | undefined = hasBlockDataOverrides
520
+ ? Object.assign(await this.api.blocks.composeBlockData(toolName), blockDataOverrides)
521
+ : undefined;
522
+
523
+ const newBlock = this.api.blocks.insert(
524
+ toolName,
525
+ blockData,
526
+ undefined,
527
+ index,
528
+ undefined,
529
+ shouldReplaceBlock
530
+ );
531
+
532
+ this.api.caret.setToBlock(index);
533
+
534
+ this.emit(ToolboxEvent.BlockAdded, {
535
+ block: newBlock,
536
+ });
537
+
538
+ /**
539
+ * close toolbar when node is changed
540
+ */
541
+ this.api.toolbar.close();
542
+ }
543
+
544
+ /**
545
+ * Starts listening to input events on the current block for inline slash search.
546
+ * When the user types after "/", the toolbox filters based on the typed text.
547
+ */
548
+ private startListeningToBlockInput(): void {
549
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
550
+ const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
551
+
552
+ if (!currentBlock) {
553
+ return;
554
+ }
555
+
556
+ this.currentBlockForSearch = currentBlock.holder;
557
+ this.currentContentEditable = this.currentBlockForSearch.querySelector('[contenteditable="true"]');
558
+ this.listeners.on(this.currentBlockForSearch, 'input', this.handleBlockInput);
559
+ }
560
+
561
+ /**
562
+ * Stops listening to block input events and resets the filter.
563
+ */
564
+ private stopListeningToBlockInput(): void {
565
+ if (this.currentBlockForSearch !== null) {
566
+ this.listeners.off(this.currentBlockForSearch, 'input', this.handleBlockInput);
567
+ this.currentBlockForSearch = null;
568
+ this.currentContentEditable = null;
569
+ }
570
+
571
+ this.popover?.filterItems('');
572
+ }
573
+
574
+ /**
575
+ * Handles input events on the block to filter the toolbox.
576
+ * Extracts text after "/" and applies it as a filter query.
577
+ */
578
+ private handleBlockInput = (): void => {
579
+ if (this.currentContentEditable === null) {
580
+ return;
581
+ }
582
+
583
+ const text = this.currentContentEditable.textContent || '';
584
+ const slashIndex = text.lastIndexOf('/');
585
+
586
+ if (slashIndex === -1) {
587
+ this.close();
588
+
589
+ return;
590
+ }
591
+
592
+ const query = text.slice(slashIndex + 1);
593
+
594
+ this.popover?.filterItems(query);
595
+ };
596
+
597
+ /**
598
+ * Checks if a block contains only slash search text (e.g., "/head").
599
+ * A block is considered "slash search only" if its text starts with "/" and contains no other content before it.
600
+ * @param blockHolder - the block's holder element
601
+ * @returns true if the block only contains slash search text
602
+ */
603
+ private isBlockSlashSearchOnly(blockHolder: HTMLElement): boolean {
604
+ const contentEditable = blockHolder.querySelector('[contenteditable="true"]');
605
+ const text = contentEditable?.textContent?.trim() || '';
606
+
607
+ // Block must start with "/" to be considered slash search only
608
+ return text.startsWith('/');
609
+ }
610
+ }