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

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 (402) 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-oNSQ3HA6.mjs +13217 -0
  7. package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
  8. package/dist/chunks/i18next-loader-BdNRw4n4.mjs +43 -0
  9. package/dist/{index-CEXLTV6f.mjs → chunks/index-DHgXmfki.mjs} +2 -2
  10. package/dist/chunks/inline-tool-convert-CRqgjRim.mjs +1989 -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 +3117 -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 +141 -0
  248. package/src/components/inline-tools/inline-tool-italic.ts +500 -0
  249. package/src/components/inline-tools/inline-tool-link.ts +539 -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 +781 -0
  284. package/src/components/modules/toolbar/index.ts +1315 -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 +601 -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 +186 -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 +676 -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 +844 -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 +123 -0
  366. package/src/tools/header/index.ts +646 -0
  367. package/src/tools/index.ts +45 -0
  368. package/src/tools/list/index.ts +1819 -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/data-attributes.d.ts +170 -0
  386. package/types/data-formats/output-data.d.ts +15 -0
  387. package/types/full.d.ts +80 -0
  388. package/types/index.d.ts +29 -13
  389. package/types/locales.d.ts +59 -0
  390. package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
  391. package/types/tools/block-tool.d.ts +9 -0
  392. package/types/tools/header.d.ts +18 -0
  393. package/types/tools/index.d.ts +1 -0
  394. package/types/tools/list.d.ts +91 -0
  395. package/types/tools/paragraph.d.ts +71 -0
  396. package/types/tools/tool-settings.d.ts +92 -6
  397. package/types/tools/tool.d.ts +6 -0
  398. package/types/tools-entry.d.ts +49 -0
  399. package/types/utils/popover/popover-item.d.ts +18 -5
  400. package/types/utils/popover/popover.d.ts +7 -0
  401. package/dist/blok-C8XbyLHh.mjs +0 -25795
  402. package/dist/blok.umd.js +0 -181
@@ -0,0 +1,601 @@
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
+ * Toolbox constructor
150
+ * @param options - available parameters
151
+ * @param options.api - Blok API methods
152
+ * @param options.tools - Tools available to check whether some of them should be displayed at the Toolbox or not
153
+ * @param options.i18n - I18n instance for translations
154
+ * @param options.triggerElement - Element relative to which the popover should be positioned
155
+ */
156
+ constructor({ api, tools, i18nLabels, i18n, triggerElement }: {
157
+ api: API;
158
+ tools: ToolsCollection<BlockToolAdapter>;
159
+ i18nLabels: Record<ToolboxTextLabelsKeys, string>;
160
+ i18n: I18nInstance;
161
+ triggerElement?: HTMLElement;
162
+ }) {
163
+ super();
164
+
165
+ this.api = api;
166
+ this.tools = tools;
167
+ this.i18nLabels = i18nLabels;
168
+ this.i18n = i18n;
169
+ this.triggerElement = triggerElement;
170
+
171
+ this.enableShortcuts();
172
+
173
+ this.nodes = {
174
+ toolbox: Dom.make('div'),
175
+ };
176
+ this.nodes.toolbox.setAttribute('data-blok-testid', 'toolbox');
177
+
178
+ this.initPopover();
179
+
180
+ this.api.events.on(BlokMobileLayoutToggled, this.handleMobileLayoutToggle);
181
+ }
182
+
183
+ /**
184
+ * Returns root block settings element
185
+ */
186
+ public getElement(): HTMLElement | null {
187
+ return this.nodes.toolbox;
188
+ }
189
+
190
+ /**
191
+ * Checks if the element is contained in the Toolbox or its Popover
192
+ * @param element - element to check
193
+ */
194
+ public contains(element: HTMLElement): boolean {
195
+ if (this.nodes.toolbox.contains(element)) {
196
+ return true;
197
+ }
198
+
199
+ if (this.popover?.getElement().contains(element)) {
200
+ return true;
201
+ }
202
+
203
+ return false;
204
+ }
205
+
206
+ /**
207
+ * Returns true if the Toolbox has the Flipper activated and the Flipper has selected button
208
+ */
209
+ public hasFocus(): boolean | undefined {
210
+ if (this.popover === null) {
211
+ return;
212
+ }
213
+
214
+ return 'hasFocus' in this.popover ? this.popover.hasFocus() : undefined;
215
+ }
216
+
217
+ /**
218
+ * Destroy Module
219
+ */
220
+ public destroy(): void {
221
+ super.destroy();
222
+
223
+ if (this.nodes && this.nodes.toolbox) {
224
+ this.nodes.toolbox.remove();
225
+ }
226
+
227
+ this.removeAllShortcuts();
228
+ this.popover?.off(PopoverEvent.Closed, this.onPopoverClose);
229
+ this.listeners.destroy();
230
+ this.api.events.off(BlokMobileLayoutToggled, this.handleMobileLayoutToggle);
231
+ }
232
+
233
+ /**
234
+ * Toolbox Tool's button click handler
235
+ * @param toolName - tool type to be activated
236
+ * @param blockDataOverrides - Block data predefined by the activated Toolbox item
237
+ */
238
+ public async toolButtonActivated(toolName: string, blockDataOverrides?: BlockToolData): Promise<void> {
239
+ await this.insertNewBlock(toolName, blockDataOverrides);
240
+ }
241
+
242
+ /**
243
+ * Open Toolbox with Tools
244
+ */
245
+ public open(): void {
246
+ if (this.isEmpty) {
247
+ return;
248
+ }
249
+
250
+ /**
251
+ * Stop mutation watching on the current block when toolbox opens.
252
+ * This prevents spurious block-changed events from DOM manipulations
253
+ * that may occur during toolbox interactions (focus changes, etc).
254
+ */
255
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
256
+
257
+ this.api.blocks.stopBlockMutationWatching(currentBlockIndex);
258
+
259
+ this.popover?.show();
260
+ this.opened = true;
261
+ this.emit(ToolboxEvent.Opened);
262
+ this.startListeningToBlockInput();
263
+ }
264
+
265
+ /**
266
+ * Close Toolbox
267
+ */
268
+ public close(): void {
269
+ this.popover?.hide();
270
+ this.opened = false;
271
+ this.emit(ToolboxEvent.Closed);
272
+ }
273
+
274
+ /**
275
+ * Close Toolbox
276
+ */
277
+ public toggle(): void {
278
+ if (!this.opened) {
279
+ this.open();
280
+ } else {
281
+ this.close();
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Destroys existing popover instance and contructs the new one.
287
+ */
288
+ public handleMobileLayoutToggle = (): void => {
289
+ this.destroyPopover();
290
+ this.initPopover();
291
+ };
292
+
293
+ /**
294
+ * Creates toolbox popover and appends it inside wrapper element
295
+ */
296
+ private initPopover(): void {
297
+ const PopoverClass = isMobileScreen() ? PopoverMobile : PopoverDesktop;
298
+
299
+ this.popover = new PopoverClass({
300
+ scopeElement: this.api.ui.nodes.redactor,
301
+ trigger: this.triggerElement || this.nodes.toolbox,
302
+ messages: {
303
+ nothingFound: this.i18nLabels.nothingFound,
304
+ search: this.i18nLabels.filter,
305
+ },
306
+ items: this.toolboxItemsToBeDisplayed,
307
+ handleContentEditableNavigation: true,
308
+ });
309
+
310
+ this.popover.on(PopoverEvent.Closed, this.onPopoverClose);
311
+ this.popover.getElement().setAttribute('data-blok-testid', 'toolbox-popover');
312
+ }
313
+
314
+ /**
315
+ * Destroys popover instance and removes it from DOM
316
+ */
317
+ private destroyPopover(): void {
318
+ if (this.popover !== null) {
319
+ this.popover.hide();
320
+ this.popover.off(PopoverEvent.Closed, this.onPopoverClose);
321
+ this.popover.destroy();
322
+ this.popover = null;
323
+ }
324
+
325
+ if (this.nodes.toolbox !== null) {
326
+ this.nodes.toolbox.innerHTML = '';
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Handles popover close event
332
+ */
333
+ private onPopoverClose = (): void => {
334
+ this.stopListeningToBlockInput();
335
+ this.opened = false;
336
+ this.emit(ToolboxEvent.Closed);
337
+ };
338
+
339
+ /**
340
+ * Returns list of tools that enables the Toolbox (by specifying the 'toolbox' getter)
341
+ */
342
+ private get toolsToBeDisplayed(): BlockToolAdapter[] {
343
+ if (this._toolsToBeDisplayed) {
344
+ return this._toolsToBeDisplayed;
345
+ }
346
+
347
+ const result: BlockToolAdapter[] = [];
348
+
349
+ this.tools.forEach((tool) => {
350
+ const toolToolboxSettings = tool.toolbox;
351
+
352
+ if (toolToolboxSettings) {
353
+ result.push(tool);
354
+ }
355
+ });
356
+
357
+ this._toolsToBeDisplayed = result;
358
+
359
+ return result;
360
+ }
361
+
362
+ /**
363
+ * Returns list of items that will be displayed in toolbox
364
+ */
365
+ private get toolboxItemsToBeDisplayed(): PopoverItemParams[] {
366
+ if (this._toolboxItemsToBeDisplayed) {
367
+ return this._toolboxItemsToBeDisplayed;
368
+ }
369
+
370
+ /**
371
+ * Maps tool data to popover item structure
372
+ */
373
+ const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockToolAdapter, displaySecondaryLabel = true): PopoverItemParams => {
374
+ // Get English title for search fallback
375
+ const titleKey = toolboxItem.titleKey;
376
+ const englishTitleKey = titleKey ? `toolNames.${titleKey}` : undefined;
377
+ const englishTitle = englishTitleKey
378
+ ? this.api.i18n.getEnglishTranslation(englishTitleKey)
379
+ : toolboxItem.title;
380
+
381
+ // Merge library searchTerms with user-provided searchTerms
382
+ const librarySearchTerms = toolboxItem.searchTerms ?? [];
383
+ const userSearchTerms = tool.searchTerms ?? [];
384
+ const mergedSearchTerms = [...new Set([...librarySearchTerms, ...userSearchTerms])];
385
+
386
+ return {
387
+ icon: toolboxItem.icon,
388
+ title: translateToolTitle(this.i18n, toolboxItem, capitalize(tool.name)),
389
+ name: toolboxItem.name ?? tool.name,
390
+ onActivate: (): void => {
391
+ void this.toolButtonActivated(tool.name, toolboxItem.data);
392
+ },
393
+ secondaryLabel: (tool.shortcut && displaySecondaryLabel) ? beautifyShortcut(tool.shortcut) : '',
394
+ englishTitle,
395
+ searchTerms: mergedSearchTerms,
396
+ };
397
+ };
398
+
399
+ const result = this.toolsToBeDisplayed
400
+ .reduce<PopoverItemParams[]>((acc, tool) => {
401
+ const { toolbox } = tool;
402
+
403
+ if (toolbox === undefined) {
404
+ return acc;
405
+ }
406
+
407
+ const items = Array.isArray(toolbox) ? toolbox : [ toolbox ];
408
+
409
+ items.forEach((item, index) => {
410
+ acc.push(toPopoverItem(item, tool, index === 0));
411
+ });
412
+
413
+ return acc;
414
+ }, []);
415
+
416
+ this._toolboxItemsToBeDisplayed = result;
417
+
418
+ return result;
419
+ }
420
+
421
+ /**
422
+ * Iterate all tools and enable theirs shortcuts if specified
423
+ */
424
+ private enableShortcuts(): void {
425
+ this.toolsToBeDisplayed.forEach((tool: BlockToolAdapter) => {
426
+ const shortcut = tool.shortcut;
427
+
428
+ if (shortcut) {
429
+ this.enableShortcutForTool(tool.name, shortcut);
430
+ }
431
+ });
432
+ }
433
+
434
+ /**
435
+ * Enable shortcut Block Tool implemented shortcut
436
+ * @param {string} toolName - Tool name
437
+ * @param {string} shortcut - shortcut according to the ShortcutData Module format
438
+ */
439
+ private enableShortcutForTool(toolName: string, shortcut: string): void {
440
+ Shortcuts.add({
441
+ name: shortcut,
442
+ on: this.api.ui.nodes.redactor,
443
+ handler: async (event: KeyboardEvent) => {
444
+ event.preventDefault();
445
+
446
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
447
+ const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
448
+
449
+ /**
450
+ * Try to convert current Block to shortcut's tool
451
+ * If conversion is not possible, insert a new Block below
452
+ */
453
+ if (currentBlock) {
454
+ try {
455
+ const newBlock = await this.api.blocks.convert(currentBlock.id, toolName);
456
+
457
+ this.api.caret.setToBlock(newBlock, 'end');
458
+
459
+ return;
460
+ } catch (_error) {}
461
+ }
462
+
463
+ await this.insertNewBlock(toolName);
464
+ },
465
+ });
466
+ }
467
+
468
+ /**
469
+ * Removes all added shortcuts
470
+ * Fired when the Read-Only mode is activated
471
+ */
472
+ private removeAllShortcuts(): void {
473
+ this.toolsToBeDisplayed.forEach((tool: BlockToolAdapter) => {
474
+ const shortcut = tool.shortcut;
475
+
476
+ if (shortcut) {
477
+ Shortcuts.remove(this.api.ui.nodes.redactor, shortcut);
478
+ }
479
+ });
480
+ }
481
+
482
+ /**
483
+ * Inserts new block
484
+ * Can be called when button clicked on Toolbox or by ShortcutData
485
+ * @param {string} toolName - Tool name
486
+ * @param blockDataOverrides - predefined Block data
487
+ */
488
+ private async insertNewBlock(toolName: string, blockDataOverrides?: BlockToolData): Promise<void> {
489
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
490
+ const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
491
+
492
+ if (!currentBlock) {
493
+ return;
494
+ }
495
+
496
+ /**
497
+ * Check if the block contains only slash search text (e.g., "/head").
498
+ * If so, treat it as empty and replace it with the new block.
499
+ */
500
+ const shouldReplaceBlock = currentBlock.isEmpty || this.isBlockSlashSearchOnly(currentBlock.holder);
501
+
502
+ /**
503
+ * On mobile version, we see the Plus Button even near non-empty blocks,
504
+ * so if current block is not empty, add the new block below the current
505
+ */
506
+ const index = shouldReplaceBlock ? currentBlockIndex : currentBlockIndex + 1;
507
+
508
+ const hasBlockDataOverrides = blockDataOverrides !== undefined && Object.keys(blockDataOverrides as Record<string, unknown>).length > 0;
509
+
510
+ const blockData: BlockToolData | undefined = hasBlockDataOverrides
511
+ ? Object.assign(await this.api.blocks.composeBlockData(toolName), blockDataOverrides)
512
+ : undefined;
513
+
514
+ const newBlock = this.api.blocks.insert(
515
+ toolName,
516
+ blockData,
517
+ undefined,
518
+ index,
519
+ undefined,
520
+ shouldReplaceBlock
521
+ );
522
+
523
+ this.api.caret.setToBlock(index);
524
+
525
+ this.emit(ToolboxEvent.BlockAdded, {
526
+ block: newBlock,
527
+ });
528
+
529
+ /**
530
+ * close toolbar when node is changed
531
+ */
532
+ this.api.toolbar.close();
533
+ }
534
+
535
+ /**
536
+ * Starts listening to input events on the current block for inline slash search.
537
+ * When the user types after "/", the toolbox filters based on the typed text.
538
+ */
539
+ private startListeningToBlockInput(): void {
540
+ const currentBlockIndex = this.api.blocks.getCurrentBlockIndex();
541
+ const currentBlock = this.api.blocks.getBlockByIndex(currentBlockIndex);
542
+
543
+ if (!currentBlock) {
544
+ return;
545
+ }
546
+
547
+ this.currentBlockForSearch = currentBlock.holder;
548
+ this.listeners.on(this.currentBlockForSearch, 'input', this.handleBlockInput);
549
+ }
550
+
551
+ /**
552
+ * Stops listening to block input events and resets the filter.
553
+ */
554
+ private stopListeningToBlockInput(): void {
555
+ if (this.currentBlockForSearch !== null) {
556
+ this.listeners.off(this.currentBlockForSearch, 'input', this.handleBlockInput);
557
+ this.currentBlockForSearch = null;
558
+ }
559
+
560
+ this.popover?.filterItems('');
561
+ }
562
+
563
+ /**
564
+ * Handles input events on the block to filter the toolbox.
565
+ * Extracts text after "/" and applies it as a filter query.
566
+ */
567
+ private handleBlockInput = (): void => {
568
+ if (this.currentBlockForSearch === null) {
569
+ return;
570
+ }
571
+
572
+ // Get text from the contenteditable element inside the block
573
+ const contentEditable = this.currentBlockForSearch.querySelector('[contenteditable="true"]');
574
+ const text = contentEditable?.textContent || '';
575
+ const slashIndex = text.lastIndexOf('/');
576
+
577
+ if (slashIndex === -1) {
578
+ this.close();
579
+
580
+ return;
581
+ }
582
+
583
+ const query = text.slice(slashIndex + 1);
584
+
585
+ this.popover?.filterItems(query);
586
+ };
587
+
588
+ /**
589
+ * Checks if a block contains only slash search text (e.g., "/head").
590
+ * A block is considered "slash search only" if its text starts with "/" and contains no other content before it.
591
+ * @param blockHolder - the block's holder element
592
+ * @returns true if the block only contains slash search text
593
+ */
594
+ private isBlockSlashSearchOnly(blockHolder: HTMLElement): boolean {
595
+ const contentEditable = blockHolder.querySelector('[contenteditable="true"]');
596
+ const text = contentEditable?.textContent?.trim() || '';
597
+
598
+ // Block must start with "/" to be considered slash search only
599
+ return text.startsWith('/');
600
+ }
601
+ }