@jackuait/blok 0.4.3-beta.1 → 0.4.3-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/README.md +7 -5
  2. package/dist/blok.mjs +2 -2
  3. package/dist/chunks/{blok-8ptWuVZC.mjs → blok-D85C_iyk.mjs} +1863 -1736
  4. package/dist/chunks/{i18next-loader-bLawSYRV.mjs → i18next-loader-exc8oN3J.mjs} +1 -1
  5. package/dist/chunks/{index-5nYtWZD2.mjs → index-fqgWb6Ue.mjs} +1 -1
  6. package/dist/chunks/{inline-tool-convert-CvMDAIzb.mjs → inline-tool-convert-CYkcoF1r.mjs} +201 -203
  7. package/dist/chunks/{messages-BFiUomgG.mjs → messages--yMo5vYp.mjs} +1 -1
  8. package/dist/chunks/{messages-2434tVOK.mjs → messages-82j7Sb1f.mjs} +1 -1
  9. package/dist/chunks/{messages-p9BZJaFV.mjs → messages-9-pnvSWZ.mjs} +1 -1
  10. package/dist/{messages-D5WeksbV.mjs → chunks/messages-B-b_IFZh.mjs} +1 -1
  11. package/dist/chunks/{messages-ez3w5NBn.mjs → messages-B5OIvtYB.mjs} +1 -1
  12. package/dist/{messages-FTOZNhRD.mjs → chunks/messages-B7zIiLTq.mjs} +1 -1
  13. package/dist/{messages-JF2fzCkK.mjs → chunks/messages-BCidD-VB.mjs} +1 -1
  14. package/dist/chunks/{messages-WYWIbQwo.mjs → messages-BWDnoNq0.mjs} +1 -1
  15. package/dist/chunks/{messages-BIPNHHAV.mjs → messages-BXsoyz5-.mjs} +1 -1
  16. package/dist/{messages-CXHt3eCC.mjs → chunks/messages-BYeiscyc.mjs} +1 -1
  17. package/dist/chunks/{messages-er-kd-VO.mjs → messages-BZ-Ia4tk.mjs} +1 -1
  18. package/dist/chunks/{messages-CmymP_Ar.mjs → messages-BaaIMBL8.mjs} +1 -1
  19. package/dist/chunks/{messages-Dd5iZN3c.mjs → messages-BgbVziWf.mjs} +1 -1
  20. package/dist/chunks/{messages-76-iJV9Q.mjs → messages-BgmPDL9Z.mjs} +1 -1
  21. package/dist/chunks/{messages-BextV3Qh.mjs → messages-Bi0X1QMU.mjs} +1 -1
  22. package/dist/chunks/{messages-QgYhPL-3.mjs → messages-BjZll4R7.mjs} +1 -1
  23. package/dist/{messages-D_FCyfW6.mjs → chunks/messages-BnmcUH66.mjs} +1 -1
  24. package/dist/chunks/{messages-DueVe0F1.mjs → messages-Bo9JrN9m.mjs} +1 -1
  25. package/dist/{messages-f3uXjegd.mjs → chunks/messages-BuKgyEeU.mjs} +1 -1
  26. package/dist/chunks/{messages-ohwI1UGv.mjs → messages-CJQt8nzO.mjs} +1 -1
  27. package/dist/chunks/{messages-D3vTzIpL.mjs → messages-CNRsIuSS.mjs} +1 -1
  28. package/dist/chunks/{messages-qWkXPggi.mjs → messages-CPdlHIEi.mjs} +1 -1
  29. package/dist/{messages-CbmsBrB0.mjs → chunks/messages-CTeYgNo1.mjs} +1 -1
  30. package/dist/{messages-BCm2eudQ.mjs → chunks/messages-CVvHbBlx.mjs} +1 -1
  31. package/dist/{messages-D3GrDwXh.mjs → chunks/messages-CbP4KoKV.mjs} +1 -1
  32. package/dist/chunks/{messages-Dg1OHftD.mjs → messages-CbepBt3K.mjs} +1 -1
  33. package/dist/{messages-BqWaOGMn.mjs → chunks/messages-CbtBGtJT.mjs} +1 -1
  34. package/dist/chunks/{messages-BqkL2_Ro.mjs → messages-CcYGSGRh.mjs} +1 -1
  35. package/dist/{messages-57uL5htT.mjs → chunks/messages-CjksZqgf.mjs} +1 -1
  36. package/dist/chunks/{messages-CFrKE-TN.mjs → messages-Cm4WhO4g.mjs} +1 -1
  37. package/dist/{messages-BiXe9G-O.mjs → chunks/messages-CoY-hJgp.mjs} +1 -1
  38. package/dist/chunks/{messages-qIQ4L4rw.mjs → messages-CpkO-V0C.mjs} +1 -1
  39. package/dist/{messages-DKha57ZU.mjs → chunks/messages-CwYueRo5.mjs} +1 -1
  40. package/dist/chunks/{messages-3DcCwXMF.mjs → messages-D-tDNAzW.mjs} +1 -1
  41. package/dist/{messages-DehM7135.mjs → chunks/messages-D2h_bTrn.mjs} +1 -1
  42. package/dist/chunks/{messages-IQxGfQIV.mjs → messages-D5J2Xlpx.mjs} +1 -1
  43. package/dist/chunks/{messages-Cm0LJLtB.mjs → messages-D8VsV_Ro.mjs} +1 -1
  44. package/dist/chunks/{messages-CHz8VlG-.mjs → messages-D8sk1mxH.mjs} +1 -1
  45. package/dist/chunks/{messages-MOGl7I5v.mjs → messages-D8tlQmPj.mjs} +1 -1
  46. package/dist/chunks/{messages-BiPSFlUG.mjs → messages-D9xzl8Wn.mjs} +1 -1
  47. package/dist/{messages-BoO8gsVD.mjs → chunks/messages-DG2QXu_f.mjs} +1 -1
  48. package/dist/{messages-DGaab4EP.mjs → chunks/messages-DHdkT1vy.mjs} +1 -1
  49. package/dist/{messages-4kMwVAKY.mjs → chunks/messages-DIbeBo-6.mjs} +1 -1
  50. package/dist/{messages-DVbPLd_0.mjs → chunks/messages-DR0sRlko.mjs} +1 -1
  51. package/dist/{messages-BX-DPa-z.mjs → chunks/messages-DRTt_xBc.mjs} +1 -1
  52. package/dist/{messages-CV7OM_qk.mjs → chunks/messages-DT43ZUKr.mjs} +1 -1
  53. package/dist/{messages-Di6Flq-b.mjs → chunks/messages-DT5djAjs.mjs} +1 -1
  54. package/dist/{messages-C6tbPLoj.mjs → chunks/messages-Df6LYOt5.mjs} +1 -1
  55. package/dist/chunks/{messages-BUlwu9mo.mjs → messages-DhdzbzrS.mjs} +1 -1
  56. package/dist/chunks/{messages-Ceo1KtFx.mjs → messages-DiyoZ_Oa.mjs} +1 -1
  57. package/dist/chunks/{messages-8p86Eyf2.mjs → messages-DkJ5aV3V.mjs} +1 -1
  58. package/dist/{messages-Dx3eFwI0.mjs → chunks/messages-DvwZEFTL.mjs} +1 -1
  59. package/dist/{messages-Bl5z_Igo.mjs → chunks/messages-Dw5GZ4YT.mjs} +1 -1
  60. package/dist/chunks/{messages-CLixzySl.mjs → messages-HSxl9MoN.mjs} +1 -1
  61. package/dist/chunks/{messages-DOaujgMW.mjs → messages-JztkG3tZ.mjs} +1 -1
  62. package/dist/{messages-BnsE97ku.mjs → chunks/messages-KLzTvDED.mjs} +1 -1
  63. package/dist/{messages-BBX0p0Pi.mjs → chunks/messages-TulYnz1f.mjs} +1 -1
  64. package/dist/chunks/{messages-D0ohMB5H.mjs → messages-Uexhy7C9.mjs} +1 -1
  65. package/dist/{messages-Dqhhex6e.mjs → chunks/messages-ctRNTfv5.mjs} +1 -1
  66. package/dist/chunks/{messages-CA6T3-gQ.mjs → messages-dIzxSHR2.mjs} +1 -1
  67. package/dist/chunks/{messages-bSf31LJi.mjs → messages-g7Njot5w.mjs} +1 -1
  68. package/dist/chunks/{messages-w5foGze_.mjs → messages-iNIhRBkQ.mjs} +1 -1
  69. package/dist/chunks/{messages-FOtiUoKl.mjs → messages-jmh1Gbfd.mjs} +1 -1
  70. package/dist/chunks/{messages-a6A_LgDv.mjs → messages-oO_lJ-_I.mjs} +1 -1
  71. package/dist/chunks/{messages-BvCkXKX-.mjs → messages-qFesO1Lu.mjs} +1 -1
  72. package/dist/{messages-diGozhTn.mjs → chunks/messages-sSYZ0Mz9.mjs} +1 -1
  73. package/dist/chunks/{messages-CFFPFdWP.mjs → messages-zs9AgeBF.mjs} +1 -1
  74. package/dist/full.mjs +2 -2
  75. package/dist/locales.mjs +68 -68
  76. package/dist/{messages-BFiUomgG.mjs → messages--yMo5vYp.mjs} +1 -1
  77. package/dist/{messages-2434tVOK.mjs → messages-82j7Sb1f.mjs} +1 -1
  78. package/dist/{messages-p9BZJaFV.mjs → messages-9-pnvSWZ.mjs} +1 -1
  79. package/dist/{chunks/messages-D5WeksbV.mjs → messages-B-b_IFZh.mjs} +1 -1
  80. package/dist/{messages-ez3w5NBn.mjs → messages-B5OIvtYB.mjs} +1 -1
  81. package/dist/{chunks/messages-FTOZNhRD.mjs → messages-B7zIiLTq.mjs} +1 -1
  82. package/dist/{chunks/messages-JF2fzCkK.mjs → messages-BCidD-VB.mjs} +1 -1
  83. package/dist/{messages-WYWIbQwo.mjs → messages-BWDnoNq0.mjs} +1 -1
  84. package/dist/{messages-BIPNHHAV.mjs → messages-BXsoyz5-.mjs} +1 -1
  85. package/dist/{chunks/messages-CXHt3eCC.mjs → messages-BYeiscyc.mjs} +1 -1
  86. package/dist/{messages-er-kd-VO.mjs → messages-BZ-Ia4tk.mjs} +1 -1
  87. package/dist/{messages-CmymP_Ar.mjs → messages-BaaIMBL8.mjs} +1 -1
  88. package/dist/{messages-Dd5iZN3c.mjs → messages-BgbVziWf.mjs} +1 -1
  89. package/dist/{messages-76-iJV9Q.mjs → messages-BgmPDL9Z.mjs} +1 -1
  90. package/dist/{messages-BextV3Qh.mjs → messages-Bi0X1QMU.mjs} +1 -1
  91. package/dist/{messages-QgYhPL-3.mjs → messages-BjZll4R7.mjs} +1 -1
  92. package/dist/{chunks/messages-D_FCyfW6.mjs → messages-BnmcUH66.mjs} +1 -1
  93. package/dist/{messages-DueVe0F1.mjs → messages-Bo9JrN9m.mjs} +1 -1
  94. package/dist/{chunks/messages-f3uXjegd.mjs → messages-BuKgyEeU.mjs} +1 -1
  95. package/dist/{messages-ohwI1UGv.mjs → messages-CJQt8nzO.mjs} +1 -1
  96. package/dist/{messages-D3vTzIpL.mjs → messages-CNRsIuSS.mjs} +1 -1
  97. package/dist/{messages-qWkXPggi.mjs → messages-CPdlHIEi.mjs} +1 -1
  98. package/dist/{chunks/messages-CbmsBrB0.mjs → messages-CTeYgNo1.mjs} +1 -1
  99. package/dist/{chunks/messages-BCm2eudQ.mjs → messages-CVvHbBlx.mjs} +1 -1
  100. package/dist/{chunks/messages-D3GrDwXh.mjs → messages-CbP4KoKV.mjs} +1 -1
  101. package/dist/{messages-Dg1OHftD.mjs → messages-CbepBt3K.mjs} +1 -1
  102. package/dist/{chunks/messages-BqWaOGMn.mjs → messages-CbtBGtJT.mjs} +1 -1
  103. package/dist/{messages-BqkL2_Ro.mjs → messages-CcYGSGRh.mjs} +1 -1
  104. package/dist/{chunks/messages-57uL5htT.mjs → messages-CjksZqgf.mjs} +1 -1
  105. package/dist/{messages-CFrKE-TN.mjs → messages-Cm4WhO4g.mjs} +1 -1
  106. package/dist/{chunks/messages-BiXe9G-O.mjs → messages-CoY-hJgp.mjs} +1 -1
  107. package/dist/{messages-qIQ4L4rw.mjs → messages-CpkO-V0C.mjs} +1 -1
  108. package/dist/{chunks/messages-DKha57ZU.mjs → messages-CwYueRo5.mjs} +1 -1
  109. package/dist/{messages-3DcCwXMF.mjs → messages-D-tDNAzW.mjs} +1 -1
  110. package/dist/{chunks/messages-DehM7135.mjs → messages-D2h_bTrn.mjs} +1 -1
  111. package/dist/{messages-IQxGfQIV.mjs → messages-D5J2Xlpx.mjs} +1 -1
  112. package/dist/{messages-Cm0LJLtB.mjs → messages-D8VsV_Ro.mjs} +1 -1
  113. package/dist/{messages-CHz8VlG-.mjs → messages-D8sk1mxH.mjs} +1 -1
  114. package/dist/{messages-MOGl7I5v.mjs → messages-D8tlQmPj.mjs} +1 -1
  115. package/dist/{messages-BiPSFlUG.mjs → messages-D9xzl8Wn.mjs} +1 -1
  116. package/dist/{chunks/messages-BoO8gsVD.mjs → messages-DG2QXu_f.mjs} +1 -1
  117. package/dist/{chunks/messages-DGaab4EP.mjs → messages-DHdkT1vy.mjs} +1 -1
  118. package/dist/{chunks/messages-4kMwVAKY.mjs → messages-DIbeBo-6.mjs} +1 -1
  119. package/dist/{chunks/messages-DVbPLd_0.mjs → messages-DR0sRlko.mjs} +1 -1
  120. package/dist/{chunks/messages-BX-DPa-z.mjs → messages-DRTt_xBc.mjs} +1 -1
  121. package/dist/{chunks/messages-CV7OM_qk.mjs → messages-DT43ZUKr.mjs} +1 -1
  122. package/dist/{chunks/messages-Di6Flq-b.mjs → messages-DT5djAjs.mjs} +1 -1
  123. package/dist/{chunks/messages-C6tbPLoj.mjs → messages-Df6LYOt5.mjs} +1 -1
  124. package/dist/{messages-BUlwu9mo.mjs → messages-DhdzbzrS.mjs} +1 -1
  125. package/dist/{messages-Ceo1KtFx.mjs → messages-DiyoZ_Oa.mjs} +1 -1
  126. package/dist/{messages-8p86Eyf2.mjs → messages-DkJ5aV3V.mjs} +1 -1
  127. package/dist/{chunks/messages-Dx3eFwI0.mjs → messages-DvwZEFTL.mjs} +1 -1
  128. package/dist/{chunks/messages-Bl5z_Igo.mjs → messages-Dw5GZ4YT.mjs} +1 -1
  129. package/dist/{messages-CLixzySl.mjs → messages-HSxl9MoN.mjs} +1 -1
  130. package/dist/{messages-DOaujgMW.mjs → messages-JztkG3tZ.mjs} +1 -1
  131. package/dist/{chunks/messages-BnsE97ku.mjs → messages-KLzTvDED.mjs} +1 -1
  132. package/dist/{chunks/messages-BBX0p0Pi.mjs → messages-TulYnz1f.mjs} +1 -1
  133. package/dist/{messages-D0ohMB5H.mjs → messages-Uexhy7C9.mjs} +1 -1
  134. package/dist/{chunks/messages-Dqhhex6e.mjs → messages-ctRNTfv5.mjs} +1 -1
  135. package/dist/{messages-CA6T3-gQ.mjs → messages-dIzxSHR2.mjs} +1 -1
  136. package/dist/{messages-bSf31LJi.mjs → messages-g7Njot5w.mjs} +1 -1
  137. package/dist/{messages-w5foGze_.mjs → messages-iNIhRBkQ.mjs} +1 -1
  138. package/dist/{messages-FOtiUoKl.mjs → messages-jmh1Gbfd.mjs} +1 -1
  139. package/dist/{messages-a6A_LgDv.mjs → messages-oO_lJ-_I.mjs} +1 -1
  140. package/dist/{messages-BvCkXKX-.mjs → messages-qFesO1Lu.mjs} +1 -1
  141. package/dist/{chunks/messages-diGozhTn.mjs → messages-sSYZ0Mz9.mjs} +1 -1
  142. package/dist/{messages-CFFPFdWP.mjs → messages-zs9AgeBF.mjs} +1 -1
  143. package/dist/tools.mjs +131 -90
  144. package/package.json +3 -3
  145. package/src/components/flipper.ts +17 -1
  146. package/src/components/i18n/locales/am/messages.json +1 -1
  147. package/src/components/i18n/locales/ar/messages.json +1 -1
  148. package/src/components/i18n/locales/az/messages.json +1 -1
  149. package/src/components/i18n/locales/bg/messages.json +1 -1
  150. package/src/components/i18n/locales/bn/messages.json +1 -1
  151. package/src/components/i18n/locales/bs/messages.json +1 -1
  152. package/src/components/i18n/locales/cs/messages.json +1 -1
  153. package/src/components/i18n/locales/da/messages.json +1 -1
  154. package/src/components/i18n/locales/de/messages.json +1 -1
  155. package/src/components/i18n/locales/dv/messages.json +1 -1
  156. package/src/components/i18n/locales/el/messages.json +1 -1
  157. package/src/components/i18n/locales/en/messages.json +1 -1
  158. package/src/components/i18n/locales/es/messages.json +1 -1
  159. package/src/components/i18n/locales/et/messages.json +1 -1
  160. package/src/components/i18n/locales/fa/messages.json +1 -1
  161. package/src/components/i18n/locales/fi/messages.json +1 -1
  162. package/src/components/i18n/locales/fil/messages.json +1 -1
  163. package/src/components/i18n/locales/fr/messages.json +1 -1
  164. package/src/components/i18n/locales/gu/messages.json +1 -1
  165. package/src/components/i18n/locales/he/messages.json +1 -1
  166. package/src/components/i18n/locales/hi/messages.json +1 -1
  167. package/src/components/i18n/locales/hr/messages.json +1 -1
  168. package/src/components/i18n/locales/hu/messages.json +1 -1
  169. package/src/components/i18n/locales/hy/messages.json +1 -1
  170. package/src/components/i18n/locales/id/messages.json +1 -1
  171. package/src/components/i18n/locales/it/messages.json +1 -1
  172. package/src/components/i18n/locales/ja/messages.json +1 -1
  173. package/src/components/i18n/locales/ka/messages.json +1 -1
  174. package/src/components/i18n/locales/km/messages.json +1 -1
  175. package/src/components/i18n/locales/kn/messages.json +1 -1
  176. package/src/components/i18n/locales/ko/messages.json +1 -1
  177. package/src/components/i18n/locales/ku/messages.json +1 -1
  178. package/src/components/i18n/locales/lo/messages.json +1 -1
  179. package/src/components/i18n/locales/lt/messages.json +1 -1
  180. package/src/components/i18n/locales/lv/messages.json +1 -1
  181. package/src/components/i18n/locales/mk/messages.json +1 -1
  182. package/src/components/i18n/locales/ml/messages.json +1 -1
  183. package/src/components/i18n/locales/mn/messages.json +1 -1
  184. package/src/components/i18n/locales/mr/messages.json +1 -1
  185. package/src/components/i18n/locales/ms/messages.json +1 -1
  186. package/src/components/i18n/locales/my/messages.json +1 -1
  187. package/src/components/i18n/locales/ne/messages.json +1 -1
  188. package/src/components/i18n/locales/nl/messages.json +1 -1
  189. package/src/components/i18n/locales/no/messages.json +1 -1
  190. package/src/components/i18n/locales/pa/messages.json +1 -1
  191. package/src/components/i18n/locales/pl/messages.json +1 -1
  192. package/src/components/i18n/locales/ps/messages.json +1 -1
  193. package/src/components/i18n/locales/pt/messages.json +1 -1
  194. package/src/components/i18n/locales/ro/messages.json +1 -1
  195. package/src/components/i18n/locales/ru/messages.json +1 -1
  196. package/src/components/i18n/locales/sd/messages.json +1 -1
  197. package/src/components/i18n/locales/si/messages.json +1 -1
  198. package/src/components/i18n/locales/sk/messages.json +1 -1
  199. package/src/components/i18n/locales/sl/messages.json +1 -1
  200. package/src/components/i18n/locales/sq/messages.json +1 -1
  201. package/src/components/i18n/locales/sr/messages.json +1 -1
  202. package/src/components/i18n/locales/sv/messages.json +1 -1
  203. package/src/components/i18n/locales/sw/messages.json +1 -1
  204. package/src/components/i18n/locales/ta/messages.json +1 -1
  205. package/src/components/i18n/locales/te/messages.json +1 -1
  206. package/src/components/i18n/locales/th/messages.json +1 -1
  207. package/src/components/i18n/locales/tr/messages.json +1 -1
  208. package/src/components/i18n/locales/ug/messages.json +1 -1
  209. package/src/components/i18n/locales/uk/messages.json +1 -1
  210. package/src/components/i18n/locales/ur/messages.json +1 -1
  211. package/src/components/i18n/locales/vi/messages.json +1 -1
  212. package/src/components/i18n/locales/yi/messages.json +1 -1
  213. package/src/components/i18n/locales/zh/messages.json +1 -1
  214. package/src/components/modules/api/i18n.ts +1 -0
  215. package/src/components/modules/dragManager.ts +71 -13
  216. package/src/components/modules/i18n.ts +6 -11
  217. package/src/components/modules/rectangleSelection.ts +62 -19
  218. package/src/components/modules/toolbar/index.ts +2 -2
  219. package/src/components/modules/tools.ts +39 -3
  220. package/src/components/modules/ui.ts +83 -18
  221. package/src/components/selection.ts +2 -12
  222. package/src/components/tools/base.ts +29 -2
  223. package/src/components/tools/block.ts +20 -3
  224. package/src/components/tools/factory.ts +50 -1
  225. package/src/components/utils/tooltip.ts +0 -14
  226. package/src/tools/header/index.ts +82 -0
  227. package/src/tools/index.ts +13 -6
  228. package/src/tools/list/index.ts +2 -2
  229. package/types/api/i18n.d.ts +8 -0
  230. package/types/tools/tool-settings.d.ts +62 -4
@@ -5,6 +5,7 @@ import { BlockTuneAdapter } from './tune';
5
5
  import { BlockToolAdapter } from './block';
6
6
  import type { API as ApiModule } from '../modules/api';
7
7
  import type { BlokConfig } from '../../../types/configs';
8
+ import type { API as ApiMethods, I18n } from '../../../types';
8
9
 
9
10
  type ToolConstructor = typeof InlineToolAdapter | typeof BlockToolAdapter | typeof BlockTuneAdapter;
10
11
 
@@ -56,18 +57,66 @@ export class ToolsFactory {
56
57
  }
57
58
 
58
59
  const Constructor = this.getConstructor(constructable);
60
+ const toolApi = this.createToolApi(name);
59
61
 
60
62
  return new Constructor({
61
63
  name,
62
64
  constructable,
63
65
  config,
64
- api: this.api.methods,
66
+ api: toolApi,
65
67
  isDefault: name === this.blokConfig.defaultBlock,
66
68
  defaultPlaceholder: this.blokConfig.placeholder,
67
69
  isInternal,
68
70
  });
69
71
  }
70
72
 
73
+ /**
74
+ * Creates a tool-specific API with namespaced i18n.
75
+ *
76
+ * EditorJS tools expect `api.i18n.t('key')` to automatically look up
77
+ * `tools.{toolName}.key`. This wrapper provides that behavior while
78
+ * falling back to direct key lookup for Blok internal tools that use
79
+ * fully-qualified keys like `tools.stub.error`.
80
+ *
81
+ * @param toolName - Name of the tool
82
+ * @returns API object with tool-namespaced i18n
83
+ */
84
+ private createToolApi(toolName: string): ApiMethods {
85
+ const baseApi = this.api.methods;
86
+ const namespace = `tools.${toolName}`;
87
+
88
+ const namespacedI18n: I18n = {
89
+ t: (dictKey: string): string => {
90
+ /**
91
+ * Try namespaced key first for EditorJS compatibility.
92
+ * External tools call t('Add row') expecting lookup of 'tools.table.Add row'.
93
+ */
94
+ const namespacedKey = `${namespace}.${dictKey}`;
95
+
96
+ if (baseApi.i18n.has(namespacedKey)) {
97
+ return baseApi.i18n.t(namespacedKey);
98
+ }
99
+
100
+ /**
101
+ * Fall back to direct key lookup for Blok internal tools.
102
+ * Internal tools use fully-qualified keys like 'tools.stub.error'.
103
+ */
104
+ return baseApi.i18n.t(dictKey);
105
+ },
106
+
107
+ has: (dictKey: string): boolean => {
108
+ const namespacedKey = `${namespace}.${dictKey}`;
109
+
110
+ return baseApi.i18n.has(namespacedKey) || baseApi.i18n.has(dictKey);
111
+ },
112
+ };
113
+
114
+ return {
115
+ ...baseApi,
116
+ i18n: namespacedI18n,
117
+ };
118
+ }
119
+
71
120
  /**
72
121
  * Find appropriate Tool object constructor for Tool constructable
73
122
  * @param constructable - Tools constructable
@@ -583,20 +583,6 @@ class Tooltip {
583
583
  }
584
584
  }
585
585
 
586
- /**
587
- * Append element or a couple to the beginning of the parent elements
588
- * @param {Element} parent - where to append
589
- * @param {Element|Element[]} elements - element or elements list
590
- */
591
- private prepend(parent: Element, elements: Element | Element[]): void {
592
- if (Array.isArray(elements)) {
593
- const reversed = elements.reverse();
594
-
595
- reversed.forEach((el) => parent.prepend(el));
596
- } else {
597
- parent.prepend(elements);
598
- }
599
- }
600
586
  }
601
587
 
602
588
  /**
@@ -16,6 +16,7 @@ import type {
16
16
  BlockToolData,
17
17
  PasteEvent,
18
18
  ToolboxConfig,
19
+ ToolboxConfigEntry,
19
20
  ConversionConfig,
20
21
  SanitizerConfig,
21
22
  PasteConfig,
@@ -60,6 +61,11 @@ export interface HeaderConfig {
60
61
  defaultLevel?: number;
61
62
  /** Level-specific overrides keyed by level number (1-6) */
62
63
  levelOverrides?: Record<number, HeaderLevelConfig>;
64
+ /**
65
+ * @internal Injected by BlockToolAdapter - merged toolbox entries.
66
+ * When present, renderSettings() will use these entries instead of the default levels.
67
+ */
68
+ _toolboxEntries?: ToolboxConfigEntry[];
63
69
  }
64
70
 
65
71
  /**
@@ -195,6 +201,28 @@ export class Header implements BlockTool {
195
201
  * @returns MenuConfig array
196
202
  */
197
203
  public renderSettings(): MenuConfig {
204
+ const toolboxEntries = this._settings._toolboxEntries;
205
+
206
+ /**
207
+ * If user provided custom toolbox entries, use them to build settings menu.
208
+ * This ensures block settings match the toolbox configuration.
209
+ * Entries without explicit level data will default to the configured defaultLevel.
210
+ *
211
+ * Only fall back to levels config when _toolboxEntries is not provided or empty,
212
+ * or when using the default single "Heading" toolbox entry (detected by having
213
+ * exactly one entry with no level data and no custom title or the default "Heading" title).
214
+ */
215
+ const isDefaultToolboxEntry = toolboxEntries?.length === 1 &&
216
+ toolboxEntries[0].data === undefined &&
217
+ (toolboxEntries[0].title === undefined || toolboxEntries[0].title === 'Heading');
218
+
219
+ if (toolboxEntries !== undefined && toolboxEntries.length > 0 && !isDefaultToolboxEntry) {
220
+ return this.buildSettingsFromToolboxEntries(toolboxEntries);
221
+ }
222
+
223
+ /**
224
+ * Fall back to existing behavior using levels config
225
+ */
198
226
  return this.levels.map(level => {
199
227
  const translated = this.api.i18n.t(level.nameKey);
200
228
  const title = translated !== level.nameKey ? translated : level.name;
@@ -212,6 +240,60 @@ export class Header implements BlockTool {
212
240
  });
213
241
  }
214
242
 
243
+ /**
244
+ * Build settings menu items from toolbox entries.
245
+ * This allows users to customize which levels appear in block settings
246
+ * by configuring the toolbox.
247
+ *
248
+ * @param entries - Merged toolbox entries from user config
249
+ * @returns MenuConfig array
250
+ */
251
+ private buildSettingsFromToolboxEntries(entries: ToolboxConfigEntry[]): MenuConfig {
252
+ return entries.map(entry => {
253
+ const entryData = entry.data as { level?: number } | undefined;
254
+ const level = entryData?.level ?? this.defaultLevel.number;
255
+ const defaultLevel = Header.DEFAULT_LEVELS.find(l => l.number === level);
256
+ const fallbackTitle = defaultLevel?.name ?? `Heading ${level}`;
257
+
258
+ const title = this.resolveToolboxEntryTitle(entry, fallbackTitle);
259
+ const icon = entry.icon ?? defaultLevel?.icon ?? IconHeading;
260
+
261
+ return {
262
+ icon,
263
+ title,
264
+ onActivate: (): void => this.setLevel(level),
265
+ closeOnActivate: true,
266
+ isActive: this.currentLevel.number === level,
267
+ dataset: {
268
+ 'blok-header-level': String(level),
269
+ },
270
+ };
271
+ });
272
+ }
273
+
274
+ /**
275
+ * Resolves the title for a toolbox entry.
276
+ * Priority: custom title > i18n key translation > fallback
277
+ *
278
+ * @param entry - Toolbox entry
279
+ * @param fallback - Fallback title if no custom title or translation found
280
+ * @returns Resolved title string
281
+ */
282
+ private resolveToolboxEntryTitle(entry: ToolboxConfigEntry, fallback: string): string {
283
+ if (entry.title !== undefined) {
284
+ return entry.title;
285
+ }
286
+
287
+ if (entry.titleKey === undefined) {
288
+ return fallback;
289
+ }
290
+
291
+ const namespacedKey = `toolNames.${entry.titleKey}`;
292
+ const translated = this.api.i18n.t(namespacedKey);
293
+
294
+ return translated !== namespacedKey ? translated : fallback;
295
+ }
296
+
215
297
  /**
216
298
  * Callback for Block's settings buttons
217
299
  *
@@ -6,10 +6,16 @@
6
6
  * // Import specific tools
7
7
  * import { Paragraph, Header, List, Bold, Italic, Link } from '@jackuait/blok/tools';
8
8
  *
9
- * // Use in Blok configuration
9
+ * // Use in Blok configuration (flat config style)
10
10
  * new Blok({
11
- * tools: { paragraph: Paragraph, header: Header, list: List },
12
- * inlineTools: { bold: Bold, italic: Italic, link: Link }
11
+ * tools: {
12
+ * paragraph: Paragraph,
13
+ * header: { class: Header, levels: [1, 2, 3] },
14
+ * list: List,
15
+ * bold: Bold,
16
+ * italic: Italic,
17
+ * link: Link,
18
+ * }
13
19
  * });
14
20
  */
15
21
 
@@ -25,10 +31,11 @@ export { LinkInlineTool as Link } from '../components/inline-tools/inline-tool-l
25
31
  export { ConvertInlineTool as Convert } from '../components/inline-tools/inline-tool-convert';
26
32
 
27
33
  // Default tools configuration for convenience
34
+ // Note: inlineToolbar defaults to true, so it doesn't need to be specified
28
35
  export const defaultBlockTools = {
29
- paragraph: { inlineToolbar: true, config: { preserveBlank: true } },
30
- header: { inlineToolbar: true },
31
- list: { inlineToolbar: true },
36
+ paragraph: { preserveBlank: true },
37
+ header: {},
38
+ list: {},
32
39
  } as const;
33
40
 
34
41
  export const defaultInlineTools = {
@@ -226,10 +226,10 @@ export class ListItem implements BlockTool {
226
226
  return this._settings.itemSize;
227
227
  }
228
228
 
229
- private static readonly DEFAULT_PLACEHOLDER = 'List';
229
+ private static readonly PLACEHOLDER_KEY = 'tools.list.placeholder';
230
230
 
231
231
  private get placeholder(): string {
232
- return this.api.i18n.t(ListItem.DEFAULT_PLACEHOLDER);
232
+ return this.api.i18n.t(ListItem.PLACEHOLDER_KEY);
233
233
  }
234
234
 
235
235
  private applyItemStyles(element: HTMLElement): void {
@@ -10,4 +10,12 @@ export interface I18n {
10
10
  * @returns Translated string, or the key itself if translation is missing
11
11
  */
12
12
  t(dictKey: string): string;
13
+
14
+ /**
15
+ * Check if a translation exists for the given key.
16
+ *
17
+ * @param dictKey - Full translation key to check
18
+ * @returns True if translation exists, false otherwise
19
+ */
20
+ has(dictKey: string): boolean;
13
21
  }
@@ -1,6 +1,12 @@
1
1
  import { ToolConfig } from './tool-config';
2
2
  import { ToolConstructable, BlockToolData, MenuConfig, MenuConfigItem } from './index';
3
3
 
4
+ /**
5
+ * Permissive type for tool class - accepts any constructor.
6
+ * Runtime validation ensures the tool has required methods.
7
+ */
8
+ export type ToolClass = new (...args: any[]) => any;
9
+
4
10
  /**
5
11
  * Tool may specify its toolbox configuration
6
12
  * It may include several entries as well
@@ -49,9 +55,9 @@ export interface ToolboxConfigEntry {
49
55
  export interface ExternalToolSettings<Config extends object = any> {
50
56
 
51
57
  /**
52
- * Tool's class
58
+ * Tool's class - accepts any constructor, validated at runtime
53
59
  */
54
- class: ToolConstructable;
60
+ class: ToolConstructable | ToolClass;
55
61
 
56
62
  /**
57
63
  * User configuration object that will be passed to the Tool's constructor
@@ -88,6 +94,58 @@ export interface ExternalToolSettings<Config extends object = any> {
88
94
  export type InternalToolSettings<Config extends object = any> = Omit<ExternalToolSettings<Config>, 'class'> & Partial<Pick<ExternalToolSettings<Config>, 'class'>>;
89
95
 
90
96
  /**
91
- * Union of external and internal Tools settings
97
+ * Keys that Blok extracts from tool settings (not passed to tool constructor)
98
+ */
99
+ export type BlokToolSettingsKeys = 'class' | 'inlineToolbar' | 'tunes' | 'shortcut' | 'toolbox' | 'config';
100
+
101
+ /**
102
+ * Flat tool settings - tool-specific options at top level.
103
+ * Blok extracts known keys and passes the rest as `config` to the tool.
104
+ */
105
+ export interface FlatToolSettings<Config extends object = any> {
106
+ /**
107
+ * Tool's class
108
+ */
109
+ class: ToolConstructable | ToolClass;
110
+
111
+ /**
112
+ * Is need to show Inline Toolbar.
113
+ * Defaults to true for block tools.
114
+ */
115
+ inlineToolbar?: boolean | string[];
116
+
117
+ /**
118
+ * BlockTunes for Tool
119
+ */
120
+ tunes?: boolean | string[];
121
+
122
+ /**
123
+ * Define shortcut that will render Tool
124
+ */
125
+ shortcut?: string;
126
+
127
+ /**
128
+ * Tool's Toolbox settings
129
+ */
130
+ toolbox?: ToolboxConfig | false;
131
+
132
+ /**
133
+ * Legacy nested config - merged with top-level tool options
134
+ * @deprecated Use flat config instead
135
+ */
136
+ config?: ToolConfig<Config>;
137
+
138
+ /**
139
+ * Tool-specific options (placeholder, levels, etc.)
140
+ * These are passed to the tool constructor as `config`
141
+ */
142
+ [key: string]: unknown;
143
+ }
144
+
145
+ /**
146
+ * Union of all tool settings formats
92
147
  */
93
- export type ToolSettings<Config extends object = any> = InternalToolSettings<Config> | ExternalToolSettings<Config>;
148
+ export type ToolSettings<Config extends object = any> =
149
+ | InternalToolSettings<Config>
150
+ | ExternalToolSettings<Config>
151
+ | FlatToolSettings<Config>;