@jackuait/blok 0.10.2 → 0.10.4

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 (293) hide show
  1. package/dist/blok.mjs +2 -2
  2. package/dist/chunks/{blok-D-T1XZ92.mjs → blok-NcdNQ0I6.mjs} +2304 -2101
  3. package/dist/chunks/{constants-CaB-mlB5.mjs → constants-DtfShkXT.mjs} +414 -317
  4. package/dist/chunks/{i18next-loader-CDnSPae_.mjs → i18next-loader-D32EUWLr.mjs} +1 -1
  5. package/dist/chunks/{lightweight-i18n-DZmo8dAI.mjs → lightweight-i18n-DpkvRXEd.mjs} +19 -0
  6. package/dist/{messages-Ddq3Ce3E2.mjs → chunks/messages-AD17iDBx.mjs} +18 -0
  7. package/dist/{messages-neGD3WGq.mjs → chunks/messages-B03yUEra2.mjs} +18 -0
  8. package/dist/chunks/{messages-CIfUm1Oa.mjs → messages-B2dU00Z3.mjs} +18 -0
  9. package/dist/chunks/{messages-BKN3YVIj.mjs → messages-B8hICx3L.mjs} +18 -0
  10. package/dist/{messages-Dnd5YSWv.mjs → chunks/messages-BBe45sPH.mjs} +18 -0
  11. package/dist/{messages-C7lJg8fy2.mjs → chunks/messages-BCifzMVO2.mjs} +18 -0
  12. package/dist/chunks/{messages-D7dx_6k8.mjs → messages-BGmvvtg_.mjs} +18 -0
  13. package/dist/{messages-Q5sQeVap2.mjs → chunks/messages-BJNFCDv42.mjs} +18 -0
  14. package/dist/chunks/{messages-BlxwW7M6.mjs → messages-BNy4e7Xl.mjs} +18 -0
  15. package/dist/chunks/{messages-C15z2r5U.mjs → messages-BcHZf9o-.mjs} +18 -0
  16. package/dist/{messages-A96tMxeU.mjs → chunks/messages-BjyYZeBm2.mjs} +18 -0
  17. package/dist/{messages-BbJ7ZXY8.mjs → chunks/messages-Bop7vrhU.mjs} +18 -0
  18. package/dist/{messages-BiTMwiKH.mjs → chunks/messages-BouFtpfO.mjs} +18 -0
  19. package/dist/chunks/{messages-ElIGUi0O2.mjs → messages-Br6bE1FD2.mjs} +18 -0
  20. package/dist/chunks/{messages-BHMiK51R.mjs → messages-C-EBhOHE.mjs} +18 -0
  21. package/dist/chunks/{messages-kGmxkeFH.mjs → messages-C3X7dv3f.mjs} +18 -0
  22. package/dist/chunks/{messages-4Ck88DYZ2.mjs → messages-C7Pjof0d2.mjs} +18 -0
  23. package/dist/{messages-D0lLw9KM.mjs → chunks/messages-C7sBaZOO2.mjs} +18 -0
  24. package/dist/chunks/{messages-QMOmwcZb.mjs → messages-C85zv_7x.mjs} +18 -0
  25. package/dist/chunks/{messages-DSrdy9Nw2.mjs → messages-CCEgR9GN2.mjs} +18 -0
  26. package/dist/chunks/{messages-DUr9WAkD.mjs → messages-CDSyoUft.mjs} +18 -0
  27. package/dist/{messages-bkGniiaz.mjs → chunks/messages-CGFlOwst.mjs} +18 -0
  28. package/dist/chunks/{messages-DBMaLL8b2.mjs → messages-CGLTjtRv2.mjs} +18 -0
  29. package/dist/{messages-2ZWBTerL.mjs → chunks/messages-CGPxUESo.mjs} +18 -0
  30. package/dist/chunks/{messages-BfAcUavP.mjs → messages-CNaaqQVz.mjs} +18 -0
  31. package/dist/{messages-DBhvm8NK.mjs → chunks/messages-CPFB2_m-2.mjs} +18 -0
  32. package/dist/chunks/{messages-zt6zdYWh.mjs → messages-CTdSIOAc.mjs} +18 -0
  33. package/dist/chunks/{messages-1_6UkKLS.mjs → messages-CXVWb9js.mjs} +18 -0
  34. package/dist/{messages-CdEASHDp2.mjs → chunks/messages-Cfbmwdep2.mjs} +18 -0
  35. package/dist/chunks/{messages-DxHh0O8j2.mjs → messages-ChayV9WY2.mjs} +18 -0
  36. package/dist/chunks/{messages-BgM91Lxm2.mjs → messages-Ci7UXRVI2.mjs} +18 -0
  37. package/dist/chunks/{messages-Clku7Cf-2.mjs → messages-CpXvyGWv2.mjs} +18 -0
  38. package/dist/chunks/{messages-DjvaiALg2.mjs → messages-Cql2ozf_2.mjs} +18 -0
  39. package/dist/{messages-DODrhcop.mjs → chunks/messages-Cxy_E2IS.mjs} +18 -0
  40. package/dist/chunks/{messages-CZSlfnkO2.mjs → messages-D9syZVGi2.mjs} +18 -0
  41. package/dist/chunks/{messages-BRAoJpOu.mjs → messages-D9uWAWjW.mjs} +18 -0
  42. package/dist/chunks/{messages-BK8Cp2d0.mjs → messages-DRJxSTqs.mjs} +18 -0
  43. package/dist/{messages-C_Qn9SbQ.mjs → chunks/messages-DSbI0vJf.mjs} +18 -0
  44. package/dist/chunks/{messages-CD_MnBln.mjs → messages-DVvrZRyZ.mjs} +18 -0
  45. package/dist/{messages-BE_z-zrb.mjs → chunks/messages-DY8zPIZW.mjs} +18 -0
  46. package/dist/chunks/{messages-Bz0-KNEB.mjs → messages-D_kZN9rB.mjs} +18 -0
  47. package/dist/{messages-C1vc5584.mjs → chunks/messages-DjSuq0-y2.mjs} +18 -0
  48. package/dist/chunks/{messages-DPzHD51Y.mjs → messages-DkP3Jf4F.mjs} +18 -0
  49. package/dist/{messages-_PLyRfVw.mjs → chunks/messages-DoPdy75l.mjs} +18 -0
  50. package/dist/chunks/{messages-JSQjKQ8I.mjs → messages-DpydMd36.mjs} +18 -0
  51. package/dist/{messages-BckDk9aq2.mjs → chunks/messages-DtZ9U9g72.mjs} +18 -0
  52. package/dist/{messages-JNrYldAa2.mjs → chunks/messages-H6vLy8wJ.mjs} +18 -0
  53. package/dist/chunks/{messages-DTN1XGll.mjs → messages-HzH9_QH8.mjs} +18 -0
  54. package/dist/chunks/{messages-C0IFfhnp.mjs → messages-O6FOfUgF.mjs} +18 -0
  55. package/dist/{messages-Be_2RHZD.mjs → chunks/messages-OSP4Hj5o.mjs} +18 -0
  56. package/dist/chunks/{messages-DMoERagV2.mjs → messages-RiqdVwuN2.mjs} +18 -0
  57. package/dist/chunks/{messages-BJ-vT1SU2.mjs → messages-SP659Sal2.mjs} +18 -0
  58. package/dist/{messages-Che99vKP.mjs → chunks/messages-THR8q8bJ.mjs} +18 -0
  59. package/dist/chunks/{messages-CvANwuht2.mjs → messages-VlEyFUxF2.mjs} +18 -0
  60. package/dist/{messages-apA6BStA.mjs → chunks/messages-VtfKWZ2S.mjs} +18 -0
  61. package/dist/{messages-DpJGbx3q.mjs → chunks/messages-YbckahVx2.mjs} +18 -0
  62. package/dist/{messages-DYuD5-rO.mjs → chunks/messages-ZhHLC6dk.mjs} +18 -0
  63. package/dist/{messages-C0GSBBCo2.mjs → chunks/messages-bFEdH3lv.mjs} +18 -0
  64. package/dist/chunks/{messages-euM2m3wQ.mjs → messages-dpXwA3Sz.mjs} +18 -0
  65. package/dist/chunks/{messages-CQBo3lmL2.mjs → messages-fbL5y58u2.mjs} +18 -0
  66. package/dist/chunks/{messages-CxiURE2X.mjs → messages-oPV2oMxM.mjs} +18 -0
  67. package/dist/{messages-DM4Gjc9h.mjs → chunks/messages-oXBbHW9A.mjs} +18 -0
  68. package/dist/chunks/{messages-QilfinOn2.mjs → messages-vDgsEqQW2.mjs} +18 -0
  69. package/dist/{messages-ClGvlFcH2.mjs → chunks/messages-wYQksm10.mjs} +18 -0
  70. package/dist/{messages-CnuH-BZK2.mjs → chunks/messages-yGedmr61.mjs} +18 -0
  71. package/dist/chunks/{messages-sDdNf8O9.mjs → messages-zQOpKjl3.mjs} +18 -0
  72. package/dist/chunks/{messages-eFd4YYzt.mjs → messages-zWqsggJh.mjs} +18 -0
  73. package/dist/chunks/{tools-BFK2MvVI.mjs → tools-DMSi-3RW.mjs} +3434 -1240
  74. package/dist/full.mjs +10 -10
  75. package/dist/locales.mjs +86 -67
  76. package/dist/{messages-BK_LsgY4.mjs → messages-0lOPMv8u.mjs} +18 -0
  77. package/dist/{messages-LYJbLq_F.mjs → messages-5wuR90qS.mjs} +18 -0
  78. package/dist/{messages-98nQiC7t2.mjs → messages-6eX0fWGR2.mjs} +18 -0
  79. package/dist/{chunks/messages-DUeiPraX.mjs → messages-9L4qqCKh2.mjs} +18 -0
  80. package/dist/{chunks/messages-Q7-4ZJLB2.mjs → messages-B4zPxKl62.mjs} +18 -0
  81. package/dist/{messages-D0005ti32.mjs → messages-BCMFYqKc2.mjs} +18 -0
  82. package/dist/{chunks/messages-CC_noR8y.mjs → messages-BKXjO3NH.mjs} +18 -0
  83. package/dist/{messages-CRNogopy2.mjs → messages-BLW2GX7J2.mjs} +18 -0
  84. package/dist/{messages-D81w6AmW.mjs → messages-BLfK27kX.mjs} +18 -0
  85. package/dist/{chunks/messages-CPBN4zWc.mjs → messages-BM2kx9Td.mjs} +18 -0
  86. package/dist/{messages-E8NjqzWq2.mjs → messages-BORkMoil2.mjs} +18 -0
  87. package/dist/{messages-Dqu4aX9s.mjs → messages-BPw_x-6H.mjs} +18 -0
  88. package/dist/{messages-DSmxJWju2.mjs → messages-BRY51SEw2.mjs} +18 -0
  89. package/dist/{chunks/messages-BONyZroH.mjs → messages-BSNsrZVN.mjs} +18 -0
  90. package/dist/{chunks/messages-BAlZjPcl.mjs → messages-B_UKuqrH.mjs} +18 -0
  91. package/dist/{chunks/messages-DB_-5Xln.mjs → messages-BrYeJsSE2.mjs} +18 -0
  92. package/dist/{messages-Brd5R-da2.mjs → messages-BwttyHDI2.mjs} +18 -0
  93. package/dist/{messages-qfvXgPpu2.mjs → messages-C-8qb9sf2.mjs} +18 -0
  94. package/dist/{chunks/messages-BbEW9bQz.mjs → messages-C34dTwF72.mjs} +18 -0
  95. package/dist/{messages-BmH2cQHQ.mjs → messages-C67YUZ9-.mjs} +18 -0
  96. package/dist/{messages-DpwMKDV0.mjs → messages-C6yKu_PJ.mjs} +18 -0
  97. package/dist/{messages-Do7Xjy0n.mjs → messages-CA6J_QoC.mjs} +18 -0
  98. package/dist/{messages-DVL0KZE5.mjs → messages-CFUBJfnf.mjs} +18 -0
  99. package/dist/{chunks/messages-DVr1sqfI2.mjs → messages-CLUBh7O_.mjs} +18 -0
  100. package/dist/{chunks/messages-wl8YrvGG.mjs → messages-CLZoy5fQ.mjs} +18 -0
  101. package/dist/{messages-CisR4PNV.mjs → messages-CNGwdIEz.mjs} +18 -0
  102. package/dist/{messages-DopaMHC42.mjs → messages-CR4gHjd82.mjs} +18 -0
  103. package/dist/{messages-DK6dA0O2.mjs → messages-CVMngZNA.mjs} +18 -0
  104. package/dist/{messages-Xc0KUbYl.mjs → messages-Cd5CW5Tt.mjs} +18 -0
  105. package/dist/{chunks/messages-ChK7v1PV.mjs → messages-CrjQ2Op0.mjs} +18 -0
  106. package/dist/{chunks/messages-CRF7nNrO.mjs → messages-Cv1PSaNk.mjs} +18 -0
  107. package/dist/{messages-DOGbHYv-2.mjs → messages-CxZarWTm2.mjs} +18 -0
  108. package/dist/{messages-D3rwCtKn.mjs → messages-D0eT_eWA.mjs} +18 -0
  109. package/dist/{messages-C6ONf71u2.mjs → messages-D6RYu9JW2.mjs} +18 -0
  110. package/dist/{messages-DQORja0D.mjs → messages-D8U5D391.mjs} +18 -0
  111. package/dist/{chunks/messages-EDMC5ukV.mjs → messages-D8dO6OMN.mjs} +18 -0
  112. package/dist/{messages-DfFZ6Yj5.mjs → messages-DA4T9WBe.mjs} +18 -0
  113. package/dist/{chunks/messages-D22e9h7V2.mjs → messages-DB4UKN8D.mjs} +18 -0
  114. package/dist/{chunks/messages-DEBy3nuJ2.mjs → messages-DCdP2ujL.mjs} +18 -0
  115. package/dist/{messages-D05jqBIa2.mjs → messages-DPFuzIdF2.mjs} +18 -0
  116. package/dist/{chunks/messages-DrfRYiM32.mjs → messages-DQ1icG7L.mjs} +18 -0
  117. package/dist/{chunks/messages-a07QVz8U.mjs → messages-DT7dwzEe.mjs} +18 -0
  118. package/dist/{chunks/messages-CszmHAvQ.mjs → messages-DUYxMxrQ2.mjs} +18 -0
  119. package/dist/{chunks/messages-DtoId_bw2.mjs → messages-D_V0kHD7.mjs} +18 -0
  120. package/dist/{messages-BesJaI6A.mjs → messages-DfqM_XvD.mjs} +18 -0
  121. package/dist/{messages-CT-Kdas6.mjs → messages-Di3-WVzq.mjs} +18 -0
  122. package/dist/{messages-BcVB3osF.mjs → messages-Dl0bfeA-.mjs} +18 -0
  123. package/dist/{chunks/messages-C1S9ztpF.mjs → messages-Do3mHd9U.mjs} +18 -0
  124. package/dist/{chunks/messages-BeGZqQwz.mjs → messages-DqDlcEPn.mjs} +18 -0
  125. package/dist/{chunks/messages-CTCe595D2.mjs → messages-DwiykEgr2.mjs} +18 -0
  126. package/dist/{chunks/messages-8Ld7P_9j2.mjs → messages-Dx5n6MLQ2.mjs} +18 -0
  127. package/dist/{messages-LMaR2_bE.mjs → messages-DxEiqa-B.mjs} +18 -0
  128. package/dist/{chunks/messages-CxxyR4vY.mjs → messages-Dxr1BBvo.mjs} +18 -0
  129. package/dist/{messages-D6VIFnSW.mjs → messages-DzknMM7W.mjs} +18 -0
  130. package/dist/{chunks/messages-oMc7qugU2.mjs → messages-ELvF3qMl2.mjs} +18 -0
  131. package/dist/{messages-53w0fPZS2.mjs → messages-JVJdC0Er2.mjs} +18 -0
  132. package/dist/{chunks/messages-BMD37y3q2.mjs → messages-KVerxvZC.mjs} +18 -0
  133. package/dist/{chunks/messages-Du2BffA7.mjs → messages-OOiDDmVw.mjs} +18 -0
  134. package/dist/{messages-uwK7ktqk.mjs → messages-PyOr_YgV.mjs} +18 -0
  135. package/dist/{messages-qbKjjvgd2.mjs → messages-VrQw3tQ62.mjs} +18 -0
  136. package/dist/{messages-CTTmWn4Y2.mjs → messages-WsUHzXMu2.mjs} +18 -0
  137. package/dist/{messages-CZbcxlZt2.mjs → messages-ZHgPRUj02.mjs} +18 -0
  138. package/dist/{messages-DKHbt-7l2.mjs → messages-aoO_TtoE2.mjs} +18 -0
  139. package/dist/{chunks/messages-CW35K1pq.mjs → messages-bh8BiOee2.mjs} +18 -0
  140. package/dist/{messages-BrOWqNCu2.mjs → messages-gZEhkRrR2.mjs} +18 -0
  141. package/dist/{chunks/messages-BRoa9tGl.mjs → messages-hya8YLMj.mjs} +18 -0
  142. package/dist/{messages-CdduYw-q.mjs → messages-tb1FD_ge.mjs} +18 -0
  143. package/dist/react.mjs +2 -2
  144. package/dist/tools.mjs +3 -3
  145. package/dist/vendor.LICENSE.txt +135 -0
  146. package/package.json +2 -1
  147. package/src/blok.ts +48 -0
  148. package/src/components/block/index.ts +21 -2
  149. package/src/components/block-tunes/block-tune-copy-link.ts +82 -0
  150. package/src/components/i18n/locales/am/messages.json +18 -0
  151. package/src/components/i18n/locales/ar/messages.json +18 -0
  152. package/src/components/i18n/locales/az/messages.json +18 -0
  153. package/src/components/i18n/locales/bg/messages.json +18 -0
  154. package/src/components/i18n/locales/bn/messages.json +18 -0
  155. package/src/components/i18n/locales/bs/messages.json +18 -0
  156. package/src/components/i18n/locales/cs/messages.json +18 -0
  157. package/src/components/i18n/locales/da/messages.json +18 -0
  158. package/src/components/i18n/locales/de/messages.json +18 -0
  159. package/src/components/i18n/locales/dv/messages.json +18 -0
  160. package/src/components/i18n/locales/el/messages.json +18 -0
  161. package/src/components/i18n/locales/en/messages.json +19 -0
  162. package/src/components/i18n/locales/es/messages.json +18 -0
  163. package/src/components/i18n/locales/et/messages.json +18 -0
  164. package/src/components/i18n/locales/fa/messages.json +18 -0
  165. package/src/components/i18n/locales/fi/messages.json +18 -0
  166. package/src/components/i18n/locales/fil/messages.json +18 -0
  167. package/src/components/i18n/locales/fr/messages.json +18 -0
  168. package/src/components/i18n/locales/gu/messages.json +18 -0
  169. package/src/components/i18n/locales/he/messages.json +18 -0
  170. package/src/components/i18n/locales/hi/messages.json +18 -0
  171. package/src/components/i18n/locales/hr/messages.json +18 -0
  172. package/src/components/i18n/locales/hu/messages.json +18 -0
  173. package/src/components/i18n/locales/hy/messages.json +18 -0
  174. package/src/components/i18n/locales/id/messages.json +18 -0
  175. package/src/components/i18n/locales/it/messages.json +18 -0
  176. package/src/components/i18n/locales/ja/messages.json +18 -0
  177. package/src/components/i18n/locales/ka/messages.json +18 -0
  178. package/src/components/i18n/locales/km/messages.json +18 -0
  179. package/src/components/i18n/locales/kn/messages.json +18 -0
  180. package/src/components/i18n/locales/ko/messages.json +18 -0
  181. package/src/components/i18n/locales/ku/messages.json +18 -0
  182. package/src/components/i18n/locales/lo/messages.json +18 -0
  183. package/src/components/i18n/locales/lt/messages.json +18 -0
  184. package/src/components/i18n/locales/lv/messages.json +18 -0
  185. package/src/components/i18n/locales/mk/messages.json +18 -0
  186. package/src/components/i18n/locales/ml/messages.json +18 -0
  187. package/src/components/i18n/locales/mn/messages.json +18 -0
  188. package/src/components/i18n/locales/mr/messages.json +18 -0
  189. package/src/components/i18n/locales/ms/messages.json +18 -0
  190. package/src/components/i18n/locales/my/messages.json +18 -0
  191. package/src/components/i18n/locales/ne/messages.json +18 -0
  192. package/src/components/i18n/locales/nl/messages.json +18 -0
  193. package/src/components/i18n/locales/no/messages.json +18 -0
  194. package/src/components/i18n/locales/pa/messages.json +18 -0
  195. package/src/components/i18n/locales/pl/messages.json +18 -0
  196. package/src/components/i18n/locales/ps/messages.json +18 -0
  197. package/src/components/i18n/locales/pt/messages.json +18 -0
  198. package/src/components/i18n/locales/ro/messages.json +18 -0
  199. package/src/components/i18n/locales/ru/messages.json +18 -0
  200. package/src/components/i18n/locales/sd/messages.json +18 -0
  201. package/src/components/i18n/locales/si/messages.json +18 -0
  202. package/src/components/i18n/locales/sk/messages.json +18 -0
  203. package/src/components/i18n/locales/sl/messages.json +18 -0
  204. package/src/components/i18n/locales/sq/messages.json +18 -0
  205. package/src/components/i18n/locales/sr/messages.json +18 -0
  206. package/src/components/i18n/locales/sv/messages.json +18 -0
  207. package/src/components/i18n/locales/sw/messages.json +18 -0
  208. package/src/components/i18n/locales/ta/messages.json +18 -0
  209. package/src/components/i18n/locales/te/messages.json +18 -0
  210. package/src/components/i18n/locales/th/messages.json +18 -0
  211. package/src/components/i18n/locales/tr/messages.json +18 -0
  212. package/src/components/i18n/locales/ug/messages.json +18 -0
  213. package/src/components/i18n/locales/uk/messages.json +18 -0
  214. package/src/components/i18n/locales/ur/messages.json +18 -0
  215. package/src/components/i18n/locales/vi/messages.json +18 -0
  216. package/src/components/i18n/locales/yi/messages.json +18 -0
  217. package/src/components/i18n/locales/zh/messages.json +18 -0
  218. package/src/components/icons/index.ts +65 -0
  219. package/src/components/inline-tools/inline-tool-bold.ts +10 -0
  220. package/src/components/inline-tools/inline-tool-code.ts +54 -1
  221. package/src/components/inline-tools/inline-tool-italic.ts +54 -1
  222. package/src/components/inline-tools/inline-tool-strikethrough.ts +54 -1
  223. package/src/components/inline-tools/inline-tool-underline.ts +54 -1
  224. package/src/components/inline-tools/services/bold-normalization-pass.ts +29 -3
  225. package/src/components/inline-tools/utils/formatting-range-utils.ts +83 -0
  226. package/src/components/modules/api/tools.ts +19 -0
  227. package/src/components/modules/blockEvents/composers/keyboardNavigation.ts +5 -5
  228. package/src/components/modules/blockManager/blockManager.ts +22 -0
  229. package/src/components/modules/blockManager/event-binder.ts +12 -1
  230. package/src/components/modules/blockManager/factory.ts +4 -0
  231. package/src/components/modules/blockManager/types.ts +4 -0
  232. package/src/components/modules/blockManager/yjs-sync.ts +16 -2
  233. package/src/components/modules/paste/google-docs-preprocessor.ts +49 -3
  234. package/src/components/modules/paste/handlers/table-cells-handler.ts +12 -2
  235. package/src/components/modules/paste/index.ts +8 -4
  236. package/src/components/modules/paste/types.ts +2 -0
  237. package/src/components/modules/renderer.ts +22 -2
  238. package/src/components/modules/saver.ts +19 -1
  239. package/src/components/modules/themeManager.ts +3 -1
  240. package/src/components/modules/toolbar/blockSettings.ts +51 -1
  241. package/src/components/modules/toolbar/index.ts +95 -3
  242. package/src/components/modules/toolbar/inline/index.ts +0 -3
  243. package/src/components/modules/toolbar/plus-button.ts +37 -0
  244. package/src/components/modules/toolbar/settings-toggler.ts +6 -0
  245. package/src/components/modules/tools.ts +5 -0
  246. package/src/components/modules/uiControllers/controllers/keyboard.ts +85 -22
  247. package/src/components/modules/uiControllers/controllers/selection.ts +14 -2
  248. package/src/components/modules/yjs/document-store.ts +22 -0
  249. package/src/components/modules/yjs/index.ts +10 -0
  250. package/src/components/modules/yjs/serializer.ts +20 -0
  251. package/src/components/selection/cursor.ts +12 -2
  252. package/src/components/ui/toolbox.ts +31 -5
  253. package/src/components/utils/id-generator.ts +11 -0
  254. package/src/components/utils/key-icon.ts +187 -0
  255. package/src/components/utils/popover/components/hint/hint.ts +3 -1
  256. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +18 -5
  257. package/src/components/utils/popover/popover-abstract.ts +45 -0
  258. package/src/components/utils/popover/popover-desktop.ts +1 -0
  259. package/src/components/utils/popover/popover-position.ts +12 -5
  260. package/src/components/utils/popover/popover.const.ts +2 -0
  261. package/src/components/utils.ts +1 -0
  262. package/src/styles/main.css +1269 -0
  263. package/src/tools/code/index.ts +4 -0
  264. package/src/tools/database/database-backend-sync.ts +132 -0
  265. package/src/tools/database/database-board-view.ts +410 -0
  266. package/src/tools/database/database-card-drag.ts +306 -0
  267. package/src/tools/database/database-card-drawer.ts +546 -0
  268. package/src/tools/database/database-column-controls.ts +141 -0
  269. package/src/tools/database/database-column-drag.ts +262 -0
  270. package/src/tools/database/database-keyboard.ts +35 -0
  271. package/src/tools/database/database-list-row-drag.ts +245 -0
  272. package/src/tools/database/database-list-view.ts +333 -0
  273. package/src/tools/database/database-model.ts +214 -0
  274. package/src/tools/database/database-property-type-popover.ts +108 -0
  275. package/src/tools/database/database-tab-bar.ts +558 -0
  276. package/src/tools/database/database-view-popover.ts +129 -0
  277. package/src/tools/database/database-view-renderer.ts +25 -0
  278. package/src/tools/database/index.ts +1223 -0
  279. package/src/tools/database/types.ts +152 -0
  280. package/src/tools/database-row/index.ts +74 -0
  281. package/src/tools/index.ts +4 -0
  282. package/src/tools/table/index.ts +10 -19
  283. package/src/tools/table/table-cell-selection.ts +126 -7
  284. package/src/tools/table/table-core.ts +59 -5
  285. package/src/tools/table/table-model.ts +8 -0
  286. package/src/tools/table/table-row-col-controls.ts +40 -18
  287. package/types/api/tools.d.ts +18 -0
  288. package/types/configs/blok-config.d.ts +27 -0
  289. package/types/data-formats/output-data.d.ts +13 -0
  290. package/types/index.d.ts +17 -0
  291. package/types/tools/database.d.ts +152 -0
  292. package/types/tools-entry.d.ts +7 -4
  293. package/types/utils/popover/popover.d.ts +6 -0
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Utilities for rendering keyboard shortcut keys as inline SVG icons.
3
+ *
4
+ * Each key token is wrapped in a minimal inline SVG that renders the Unicode
5
+ * glyph as SVG <text>. No borders, no boxes — visually identical to plain
6
+ * Unicode text, but each symbol is a proper SVG element.
7
+ *
8
+ * The result matches the compact Mac-style shortcut display:
9
+ * ⌘⌃L ⌘D ⌘⇧P Del
10
+ *
11
+ * Usage:
12
+ * element.innerHTML = makeShortcutHtml('⌘ + B');
13
+ */
14
+
15
+ /**
16
+ * Canonical Unicode glyph for each key name.
17
+ * All modifier symbols and common key names are covered.
18
+ */
19
+ const KEY_LABEL_MAP: Record<string, string> = {
20
+ '⌘': '⌘',
21
+ '⇧': '⇧',
22
+ '⌥': '⌥',
23
+ '⌃': '⌃',
24
+ '⌫': '⌫',
25
+ '⏎': '⏎',
26
+ '⎋': '⎋',
27
+ '␡': '⌦',
28
+ '↑': '↑',
29
+ '↓': '↓',
30
+ '←': '←',
31
+ '→': '→',
32
+ 'ctrl': '⌃',
33
+ 'alt': '⌥',
34
+ 'shift': '⇧',
35
+ 'enter': '↵',
36
+ 'backspace': '⌫',
37
+ 'escape': '⎋',
38
+ 'esc': '⎋',
39
+ 'delete': '⌦',
40
+ 'del': 'Del',
41
+ 'tab': '⇥',
42
+ 'ins': 'Ins',
43
+ 'win': '⊞',
44
+ };
45
+
46
+ /**
47
+ * Resolves a raw token string to its canonical display glyph.
48
+ */
49
+ function resolveLabel(token: string): string {
50
+ const trimmed = token.trim();
51
+
52
+ return KEY_LABEL_MAP[trimmed.toLowerCase()] ?? KEY_LABEL_MAP[trimmed] ?? trimmed;
53
+ }
54
+
55
+ /**
56
+ * Splits a shortcut segment into individual key tokens.
57
+ * Handles concatenated modifier symbols like "⌃⌘L" → ['⌃', '⌘', 'L'].
58
+ */
59
+ function tokenizeSegment(segment: string): string[] {
60
+ const modifierPattern = /([⌘⇧⌥⌃⌫⏎⎋⌦↑↓←→↵⇥])|([^⌘⇧⌥⌃⌫⏎⎋⌦↑↓←→↵⇥]+)/gu;
61
+ const tokens: string[] = [];
62
+
63
+ for (const match of segment.matchAll(modifierPattern)) {
64
+ const token = match[0].trim();
65
+
66
+ if (token) {
67
+ tokens.push(token);
68
+ }
69
+ }
70
+
71
+ return tokens;
72
+ }
73
+
74
+ /**
75
+ * Renders a single key glyph as an inline SVG <text> element.
76
+ * No border, no background — just the Unicode character as SVG.
77
+ * Font size and width adapt to single-char symbols vs multi-char labels.
78
+ */
79
+ function makeKeySvg(label: string): string {
80
+ const isSymbol = label.length === 1;
81
+ // Symbols (⌘, ⇧, …) are wider glyphs; short text (Del, Ins) is narrower per-char
82
+ const fontSize = isSymbol ? 13 : 11;
83
+ const charWidth = isSymbol ? 13 : 7.5;
84
+ const w = Math.ceil(label.length * charWidth);
85
+ const h = 16;
86
+
87
+ return (
88
+ `<svg xmlns="http://www.w3.org/2000/svg"` +
89
+ ` width="${w}" height="${h}"` +
90
+ ` viewBox="0 0 ${w} ${h}"` +
91
+ ` style="display:inline-block;vertical-align:middle;flex-shrink:0"` +
92
+ ` aria-hidden="true">` +
93
+ `<text` +
94
+ ` x="${w / 2}"` +
95
+ ` y="${h / 2 + 1}"` +
96
+ ` text-anchor="middle"` +
97
+ ` dominant-baseline="middle"` +
98
+ ` font-family="-apple-system,BlinkMacSystemFont,'SF Pro Text','Helvetica Neue',sans-serif"` +
99
+ ` font-size="${fontSize}"` +
100
+ ` font-weight="400"` +
101
+ ` fill="currentColor"` +
102
+ `>${label}</text>` +
103
+ `</svg>`
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Converts a beautified shortcut string (e.g. "⌘ + B" or "⌃⌘L") into an
109
+ * HTML string of inline SVG glyph elements, tightly concatenated with no
110
+ * separator — matching the compact Mac shortcut display style.
111
+ *
112
+ * Accepts the output of `beautifyShortcut()` which uses " + " as separator.
113
+ */
114
+ export function makeShortcutHtml(shortcut: string): string {
115
+ const tokens = shortcut
116
+ .split(' + ')
117
+ .flatMap(tokenizeSegment);
118
+
119
+ if (tokens.length === 0) {
120
+ return shortcut;
121
+ }
122
+
123
+ const svgs = tokens.map((token) => makeKeySvg(resolveLabel(token)));
124
+
125
+ return `<span style="display:inline-flex;align-items:center;line-height:1">${svgs.join('')}</span>`;
126
+ }
127
+
128
+ /**
129
+ * Maps Unicode glyphs and short labels back to full English key names
130
+ * for use in human-readable tooltip descriptions.
131
+ */
132
+ const READABLE_KEY_MAP: Record<string, string> = {
133
+ '⌘': 'Command',
134
+ '⇧': 'Shift',
135
+ '⌥': 'Option',
136
+ '⌃': 'Control',
137
+ '⌫': 'Backspace',
138
+ '⌦': 'Delete',
139
+ '⏎': 'Return',
140
+ '↵': 'Return',
141
+ '⎋': 'Escape',
142
+ '⇥': 'Tab',
143
+ '↑': 'Up',
144
+ '↓': 'Down',
145
+ '←': 'Left',
146
+ '→': 'Right',
147
+ 'del': 'Delete',
148
+ 'ins': 'Insert',
149
+ '⊞': 'Win',
150
+ };
151
+
152
+ /**
153
+ * Converts a shortcut string (e.g. "⌃⌘L" or "⌘ + C") into a human-readable
154
+ * description like "Control+Command+L" or "Command+C".
155
+ *
156
+ * Each token is expanded to its full English key name. Plain letter/number
157
+ * tokens are uppercased. Unknown glyphs are passed through as-is.
158
+ */
159
+ export function shortcutToReadable(shortcut: string): string {
160
+ const tokens = shortcut
161
+ .split(' + ')
162
+ .flatMap(tokenizeSegment);
163
+
164
+ if (tokens.length === 0) {
165
+ return shortcut;
166
+ }
167
+
168
+ return tokens
169
+ .map((token) => {
170
+ const trimmed = token.trim();
171
+ const lower = trimmed.toLowerCase();
172
+
173
+ return READABLE_KEY_MAP[trimmed] ?? READABLE_KEY_MAP[lower] ?? trimmed.toUpperCase();
174
+ })
175
+ .join('+');
176
+ }
177
+
178
+ /**
179
+ * Creates a DOM element containing the SVG glyph icons for a shortcut.
180
+ */
181
+ export function makeShortcutElement(shortcut: string): HTMLElement {
182
+ const el = document.createElement('span');
183
+
184
+ el.innerHTML = makeShortcutHtml(shortcut);
185
+
186
+ return el.firstElementChild as HTMLElement ?? el;
187
+ }
@@ -1,4 +1,5 @@
1
1
  import { Dom } from '../../../../dom';
2
+ import { makeShortcutHtml } from '../../../key-icon';
2
3
 
3
4
  import { css } from './hint.const';
4
5
 
@@ -33,7 +34,8 @@ export class Hint {
33
34
  this.nodes.root.appendChild(this.nodes.title);
34
35
 
35
36
  if (params.description !== undefined) {
36
- this.nodes.description = Dom.make('div', css.description, { textContent: params.description });
37
+ this.nodes.description = Dom.make('div', css.description);
38
+ this.nodes.description.innerHTML = makeShortcutHtml(params.description);
37
39
 
38
40
  this.nodes.root.appendChild(this.nodes.description);
39
41
  }
@@ -1,5 +1,7 @@
1
1
  import { DATA_ATTR } from '../../../../../constants/data-attributes';
2
2
  import { IconChevronRight } from '../../../../../icons';
3
+ import { makeShortcutHtml, shortcutToReadable } from '../../../../key-icon';
4
+ import { onHover } from '../../../../tooltip';
3
5
  import { twMerge } from '../../../../tw';
4
6
  import { PopoverItem } from '../popover-item';
5
7
 
@@ -272,13 +274,22 @@ export class PopoverItemDefault extends PopoverItem {
272
274
  if (params.secondaryLabel) {
273
275
  const secondaryEl = document.createElement('div');
274
276
 
275
- secondaryEl.className = 'ml-auto shrink-0 flex items-center whitespace-nowrap pl-20 font-mono text-[13px] tracking-wide text-text-secondary/60';
277
+ secondaryEl.className = 'ml-auto shrink-0 inline-flex items-center whitespace-nowrap pl-20 leading-none text-text-secondary/60';
276
278
  secondaryEl.setAttribute(DATA_ATTR.popoverItemSecondaryTitle, '');
277
279
  secondaryEl.setAttribute('data-blok-testid', 'popover-item-secondary-title');
278
- secondaryEl.textContent = params.secondaryLabel;
280
+ secondaryEl.innerHTML = makeShortcutHtml(params.secondaryLabel);
279
281
 
280
282
  root.appendChild(secondaryEl);
281
283
  this.nodes.secondaryLabelEl = secondaryEl;
284
+
285
+ if (params.title !== undefined) {
286
+ // Anchor tooltip to the inner SVG span (the visible glyphs), not the
287
+ // outer container which has large left padding — so the tooltip centers
288
+ // directly over the shortcut keys rather than over the padded div.
289
+ const glyphSpan = (secondaryEl.firstElementChild ?? secondaryEl) as HTMLElement;
290
+
291
+ onHover(glyphSpan, shortcutToReadable(params.secondaryLabel), { placement: 'top' });
292
+ }
282
293
  }
283
294
 
284
295
  // Trailing icon (right-side indicator, e.g. checkmark)
@@ -552,8 +563,10 @@ export class PopoverItemDefault extends PopoverItem {
552
563
  return;
553
564
  }
554
565
 
555
- this.nodes.secondaryLabelEl.textContent = this.params.secondaryLabel ?? '';
556
- this.nodes.secondaryLabelEl.style.display = this.params.secondaryLabel ? '' : 'none';
566
+ const label = this.params.secondaryLabel;
567
+
568
+ this.nodes.secondaryLabelEl.innerHTML = label ? makeShortcutHtml(label) : '';
569
+ this.nodes.secondaryLabelEl.style.display = label ? '' : 'none';
557
570
  }
558
571
 
559
572
  /**
@@ -586,7 +599,7 @@ export class PopoverItemDefault extends PopoverItem {
586
599
  return;
587
600
  }
588
601
 
589
- this.nodes.secondaryLabelEl.textContent = secondaryLabel ?? '';
602
+ this.nodes.secondaryLabelEl.innerHTML = secondaryLabel ? makeShortcutHtml(secondaryLabel) : '';
590
603
  this.nodes.secondaryLabelEl.style.display = secondaryLabel ? '' : 'none';
591
604
  }
592
605
 
@@ -86,6 +86,11 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
86
86
  if (this.nodes.popoverContainer) {
87
87
  this.listeners.on(this.nodes.popoverContainer, 'click', (event: Event) => this.handleClick(event));
88
88
  }
89
+
90
+ // Set up scroll listener on items container for scroll hazes
91
+ if (this.nodes.items) {
92
+ this.listeners.on(this.nodes.items, 'scroll', () => this.updateScrollHazes());
93
+ }
89
94
  }
90
95
 
91
96
  /**
@@ -136,6 +141,8 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
136
141
  this.search.focus();
137
142
  }
138
143
 
144
+ this.updateScrollHazes();
145
+
139
146
  const { trigger } = this.params;
140
147
  const isRootWithTrigger = (this.params.nestingLevel ?? 0) === 0 && trigger !== undefined;
141
148
 
@@ -156,6 +163,9 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
156
163
 
157
164
  this.itemsDefault.forEach(item => item.reset());
158
165
 
166
+ this.nodes.scrollHazeTop.style.opacity = '0';
167
+ this.nodes.scrollHazeBottom.style.opacity = '0';
168
+
159
169
  if (this.search !== undefined) {
160
170
  this.search.clear();
161
171
  }
@@ -429,6 +439,24 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
429
439
  }
430
440
  }
431
441
 
442
+ /**
443
+ * Updates scroll haze visibility based on the items container scroll state.
444
+ * Shows top haze when scrolled down, bottom haze when more content below.
445
+ */
446
+ protected updateScrollHazes(): void {
447
+ const { items, scrollHazeTop, scrollHazeBottom } = this.nodes;
448
+
449
+ const hasOverflow = items.scrollHeight > items.clientHeight;
450
+ const isAtTop = items.scrollTop <= 0;
451
+ const isAtBottom = items.scrollTop + items.clientHeight >= items.scrollHeight - 1;
452
+
453
+ scrollHazeTop.style.opacity = hasOverflow && !isAtTop ? '1' : '0';
454
+ scrollHazeBottom.style.opacity = hasOverflow && !isAtBottom ? '1' : '0';
455
+
456
+ scrollHazeTop.style.top = `${items.offsetTop}px`;
457
+ scrollHazeBottom.style.top = `${items.offsetTop + items.clientHeight - scrollHazeBottom.offsetHeight}px`;
458
+ }
459
+
432
460
  /**
433
461
  * Checks if popover contains the node
434
462
  * @param node - node to check
@@ -485,9 +513,24 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
485
513
  items.setAttribute(DATA_ATTR.popoverItems, '');
486
514
  items.setAttribute('data-blok-testid', 'popover-items');
487
515
 
516
+ // Create scroll haze overlays
517
+ const scrollHazeTop = document.createElement('div');
518
+
519
+ scrollHazeTop.className = css.scrollHaze;
520
+ scrollHazeTop.style.background = 'linear-gradient(to bottom, var(--blok-popover-bg), transparent)';
521
+ scrollHazeTop.style.opacity = '0';
522
+
523
+ const scrollHazeBottom = document.createElement('div');
524
+
525
+ scrollHazeBottom.className = css.scrollHaze;
526
+ scrollHazeBottom.style.background = 'linear-gradient(to top, var(--blok-popover-bg), transparent)';
527
+ scrollHazeBottom.style.opacity = '0';
528
+
488
529
  // Assemble DOM structure
489
530
  popoverContainer.appendChild(nothingFoundMessage);
490
531
  popoverContainer.appendChild(items);
532
+ popoverContainer.appendChild(scrollHazeTop);
533
+ popoverContainer.appendChild(scrollHazeBottom);
491
534
  popover.appendChild(popoverContainer);
492
535
 
493
536
  return {
@@ -495,6 +538,8 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
495
538
  popoverContainer,
496
539
  nothingFoundMessage,
497
540
  items,
541
+ scrollHazeTop,
542
+ scrollHazeBottom,
498
543
  };
499
544
  }
500
545
 
@@ -1077,6 +1077,7 @@ export class PopoverDesktop extends PopoverAbstract {
1077
1077
  }
1078
1078
 
1079
1079
  this.toggleNothingFoundMessage(isNothingFound);
1080
+ this.updateScrollHazes();
1080
1081
 
1081
1082
  // Recalculate position since popover height may have changed (trigger-based popovers only;
1082
1083
  // non-trigger popovers use CSS variable positioning that doesn't need pixel recalculation)
@@ -32,7 +32,9 @@ export interface ResolvedPosition {
32
32
 
33
33
  /**
34
34
  * Determines whether the popover should flip to the alternate side.
35
- * Returns true when the popover doesn't fit on the preferred side and the alternate side has more (or equal) space.
35
+ * Returns true only when the popover fits on the alternate side but not the preferred side.
36
+ * When neither side fits, stays on the preferred side so the popover remains adjacent
37
+ * to the anchor instead of getting clamped to a distant boundary edge.
36
38
  */
37
39
  function shouldFlip(popoverDimension: number, spaceOnPreferred: number, spaceOnAlternate: number): boolean {
38
40
  if (popoverDimension <= spaceOnPreferred) {
@@ -43,7 +45,7 @@ function shouldFlip(popoverDimension: number, spaceOnPreferred: number, spaceOnA
43
45
  return true;
44
46
  }
45
47
 
46
- return spaceOnAlternate > spaceOnPreferred;
48
+ return false;
47
49
  }
48
50
 
49
51
  /**
@@ -75,9 +77,14 @@ export function resolvePosition(input: PositionInput): ResolvedPosition {
75
77
  ? anchor.top - offset - popoverSize.height + scrollOffset.y
76
78
  : anchor.bottom + offset + scrollOffset.y;
77
79
 
78
- // Clamp: ensure popover doesn't overflow above top boundary
79
- const top = rawTop < boundaryTop + scrollOffset.y
80
- ? boundaryTop + scrollOffset.y
80
+ // Clamp: ensure popover doesn't overflow above top boundary.
81
+ // Use the scope's top in document coords (scopeBounds.top + scrollOffset.y) rather
82
+ // than the viewport-clamped boundaryTop, so the clamp is correct when the page is
83
+ // scrolled (boundaryTop is viewport-relative; adding scrollOffset converts it to
84
+ // document coords but discards any negative scope top that was clamped to 0).
85
+ const scopeTopInDocCoords = scopeBounds.top + scrollOffset.y;
86
+ const top = rawTop < scopeTopInDocCoords
87
+ ? scopeTopInDocCoords
81
88
  : rawTop;
82
89
 
83
90
  // --- Horizontal ---
@@ -18,6 +18,8 @@ export const css = {
18
18
  popoverOverlay: 'hidden bg-dark',
19
19
 
20
20
  items: 'overflow-y-auto overscroll-contain',
21
+
22
+ scrollHaze: 'absolute inset-x-0 h-6 pointer-events-none z-1 transition-opacity duration-300 ease-in-out',
21
23
  };
22
24
 
23
25
  /**
@@ -73,6 +73,7 @@ export {
73
73
  export {
74
74
  generateBlockId,
75
75
  generateId,
76
+ isValidBlockId,
76
77
  } from './utils/id-generator';
77
78
 
78
79
  // HTML utilities