@jackuait/blok 0.6.0-beta.4 → 0.6.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/README.md +16 -169
  2. package/bin/blok.mjs +10 -0
  3. package/dist/blok.mjs +2 -2
  4. package/dist/chunks/{blok-DK-97ZTf.mjs → blok-BOtlKwVO.mjs} +1486 -1354
  5. package/dist/chunks/{i18next-loader-CRollibS.mjs → i18next-loader-CJNShSyT.mjs} +1 -1
  6. package/dist/chunks/{index-jgHmMDND.mjs → index-BUAPAChM.mjs} +1 -1
  7. package/dist/chunks/{inline-tool-convert-BIwvipPw.mjs → inline-tool-convert-UoYdJJic.mjs} +88 -73
  8. package/dist/chunks/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
  9. package/dist/chunks/{messages-CQj2JU2j.mjs → messages-7QoX8DkW.mjs} +23 -9
  10. package/dist/{messages-LvFKBBPa.mjs → chunks/messages-7W4d0DwD.mjs} +15 -1
  11. package/dist/{messages-Bn253WWC.mjs → chunks/messages-9SihnaXQ.mjs} +14 -0
  12. package/dist/{messages-Bf6Y3_GI.mjs → chunks/messages-B1Aww8q7.mjs} +16 -2
  13. package/dist/{messages-pA5TvcAj.mjs → chunks/messages-BB5z9Uba.mjs} +14 -0
  14. package/dist/chunks/{messages-wdqp4610.mjs → messages-BC86qLvI.mjs} +17 -3
  15. package/dist/chunks/{messages-o24dK6CU.mjs → messages-BELRf6DU.mjs} +16 -2
  16. package/dist/chunks/{messages-CUZ1x1QD.mjs → messages-BFG6Wlgy.mjs} +16 -2
  17. package/dist/{messages-B5puUm7R.mjs → chunks/messages-BL0tXcDf.mjs} +15 -1
  18. package/dist/chunks/{messages-zS1AXZ0y.mjs → messages-BMXCuEKO.mjs} +19 -5
  19. package/dist/{messages-CyDU5lz9.mjs → chunks/messages-BMv4xwIr.mjs} +16 -2
  20. package/dist/chunks/{messages-BeUhMpsr.mjs → messages-BSbjsyHY.mjs} +25 -11
  21. package/dist/chunks/{messages-JGsXAReJ.mjs → messages-BU2nlrLK.mjs} +16 -2
  22. package/dist/chunks/{messages-srxrv8Yh.mjs → messages-BWF-zUpY.mjs} +17 -3
  23. package/dist/{messages-CXHd9SUK.mjs → chunks/messages-BYyy6Wqf.mjs} +14 -0
  24. package/dist/chunks/{messages-DOlC_Tty.mjs → messages-BdeLo0N9.mjs} +24 -10
  25. package/dist/chunks/{messages-B5jGUnOy.mjs → messages-Bmu_S7GM.mjs} +14 -0
  26. package/dist/chunks/{messages-BmKCChWZ.mjs → messages-BoJc_p1r.mjs} +14 -0
  27. package/dist/chunks/{messages-CvaqJFN-.mjs → messages-BogRq8lt.mjs} +15 -1
  28. package/dist/chunks/{messages-NP1myMGI.mjs → messages-BrPFGbM-.mjs} +14 -0
  29. package/dist/chunks/{messages-D00OjS2n.mjs → messages-C2htQ_3F.mjs} +24 -10
  30. package/dist/chunks/{messages-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
  31. package/dist/chunks/{messages-CkFT2gle.mjs → messages-C9eaarcK.mjs} +20 -6
  32. package/dist/chunks/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
  33. package/dist/chunks/messages-CKI54h6O.mjs +62 -0
  34. package/dist/{messages-CrsJ1TEJ.mjs → chunks/messages-CLhcMlTc.mjs} +15 -1
  35. package/dist/{messages-CnvW8Slp.mjs → chunks/messages-CMkNSDTo.mjs} +17 -3
  36. package/dist/{messages-BlpqL8vG.mjs → chunks/messages-CQwpzUFp.mjs} +19 -5
  37. package/dist/chunks/{messages-Cu08aLS3.mjs → messages-CVw84KdI.mjs} +21 -7
  38. package/dist/chunks/{messages-B9Oba7sq.mjs → messages-CY8_RyFE.mjs} +15 -1
  39. package/dist/chunks/{messages-B5hdXZwA.mjs → messages-CZygwLwM.mjs} +15 -1
  40. package/dist/chunks/{messages-CVeWVKsV.mjs → messages-CnwibSvh.mjs} +14 -0
  41. package/dist/chunks/{messages-DbVquYKN.mjs → messages-CqWJcCbY.mjs} +14 -0
  42. package/dist/{messages-Dg92dXZ5.mjs → chunks/messages-CvGLfqmV.mjs} +14 -0
  43. package/dist/{messages-AHESHJm_.mjs → chunks/messages-CzTufCHu.mjs} +14 -0
  44. package/dist/chunks/{messages-Cj-t1bdy.mjs → messages-CznZadDf.mjs} +15 -1
  45. package/dist/chunks/{messages-DMQIHGRj.mjs → messages-D-ZtY5v0.mjs} +14 -0
  46. package/dist/chunks/{messages-rRSHQDCX.mjs → messages-D1Hv8XGo.mjs} +14 -0
  47. package/dist/chunks/{messages-0tDXLuyH.mjs → messages-D5C3J9qr.mjs} +15 -1
  48. package/dist/chunks/{messages-RvMHb2Ht.mjs → messages-D5iv1Kox.mjs} +16 -2
  49. package/dist/{messages-zSzDzXej.mjs → chunks/messages-DBRw-7Zc.mjs} +16 -2
  50. package/dist/chunks/{messages-CeCjVKMW.mjs → messages-DBn76jVV.mjs} +16 -2
  51. package/dist/chunks/{messages-C7I_AVH2.mjs → messages-DJDG55Vq.mjs} +16 -2
  52. package/dist/{messages-DDLgIPDF.mjs → chunks/messages-DLfR5bMd.mjs} +16 -2
  53. package/dist/{messages-CbhuIWRJ.mjs → chunks/messages-DT4dP5uK.mjs} +15 -1
  54. package/dist/chunks/{messages-B66ZSDCJ.mjs → messages-DhLKYm2j.mjs} +15 -1
  55. package/dist/{messages-BPqWKx5Z.mjs → chunks/messages-Diu6jAaR.mjs} +17 -3
  56. package/dist/{messages-BA0rcTCY.mjs → chunks/messages-DnIhyAJk.mjs} +18 -4
  57. package/dist/chunks/{messages-DV6shA9b.mjs → messages-DnXLrlHh.mjs} +14 -0
  58. package/dist/chunks/{messages-DcKOuncK.mjs → messages-DprmQg6V.mjs} +16 -2
  59. package/dist/{messages-CJoBtXU6.mjs → chunks/messages-DqM1LFg5.mjs} +14 -0
  60. package/dist/chunks/{messages-Cyi2AMmz.mjs → messages-DvFLX36Q.mjs} +25 -11
  61. package/dist/chunks/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
  62. package/dist/chunks/{messages-GC2PhgV3.mjs → messages-Dzwxv9v1.mjs} +23 -9
  63. package/dist/chunks/{messages-Q4kc_ZtL.mjs → messages-JELdtT6E.mjs} +15 -1
  64. package/dist/{messages-DY94ykcE.mjs → chunks/messages-LPVfA-8K.mjs} +14 -0
  65. package/dist/{messages-Cr-RJ7YB.mjs → chunks/messages-O5tQus_0.mjs} +14 -0
  66. package/dist/chunks/{messages-CbMyJSzS.mjs → messages-Q7AO_FLv.mjs} +17 -3
  67. package/dist/chunks/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
  68. package/dist/{messages-CUy1vn-b.mjs → chunks/messages-Xq8UmkVs.mjs} +14 -0
  69. package/dist/chunks/{messages-BBJgd5jG.mjs → messages-Z9nEU2xK.mjs} +16 -2
  70. package/dist/chunks/{messages-Cm9aLHeX.mjs → messages-_ErNTNhk.mjs} +15 -1
  71. package/dist/chunks/{messages-JZUhXTuV.mjs → messages-_ncGrKHh.mjs} +16 -2
  72. package/dist/chunks/{messages-ftMcCEuO.mjs → messages-kep5wtm4.mjs} +15 -1
  73. package/dist/chunks/{messages-DteYq0rv.mjs → messages-uKX8WBaD.mjs} +16 -2
  74. package/dist/chunks/{messages-Bdv-IkfG.mjs → messages-w7v1GNaE.mjs} +15 -1
  75. package/dist/cli.mjs +50 -0
  76. package/dist/full.mjs +15 -15
  77. package/dist/locales.mjs +102 -88
  78. package/dist/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
  79. package/dist/{messages-CQj2JU2j.mjs → messages-7QoX8DkW.mjs} +23 -9
  80. package/dist/{chunks/messages-LvFKBBPa.mjs → messages-7W4d0DwD.mjs} +15 -1
  81. package/dist/{chunks/messages-Bn253WWC.mjs → messages-9SihnaXQ.mjs} +14 -0
  82. package/dist/{chunks/messages-Bf6Y3_GI.mjs → messages-B1Aww8q7.mjs} +16 -2
  83. package/dist/{chunks/messages-pA5TvcAj.mjs → messages-BB5z9Uba.mjs} +14 -0
  84. package/dist/{messages-wdqp4610.mjs → messages-BC86qLvI.mjs} +17 -3
  85. package/dist/{messages-o24dK6CU.mjs → messages-BELRf6DU.mjs} +16 -2
  86. package/dist/{messages-CUZ1x1QD.mjs → messages-BFG6Wlgy.mjs} +16 -2
  87. package/dist/{chunks/messages-B5puUm7R.mjs → messages-BL0tXcDf.mjs} +15 -1
  88. package/dist/{messages-zS1AXZ0y.mjs → messages-BMXCuEKO.mjs} +19 -5
  89. package/dist/{chunks/messages-CyDU5lz9.mjs → messages-BMv4xwIr.mjs} +16 -2
  90. package/dist/{messages-BeUhMpsr.mjs → messages-BSbjsyHY.mjs} +25 -11
  91. package/dist/{messages-JGsXAReJ.mjs → messages-BU2nlrLK.mjs} +16 -2
  92. package/dist/{messages-srxrv8Yh.mjs → messages-BWF-zUpY.mjs} +17 -3
  93. package/dist/{chunks/messages-CXHd9SUK.mjs → messages-BYyy6Wqf.mjs} +14 -0
  94. package/dist/{messages-DOlC_Tty.mjs → messages-BdeLo0N9.mjs} +24 -10
  95. package/dist/{messages-B5jGUnOy.mjs → messages-Bmu_S7GM.mjs} +14 -0
  96. package/dist/{messages-BmKCChWZ.mjs → messages-BoJc_p1r.mjs} +14 -0
  97. package/dist/{messages-CvaqJFN-.mjs → messages-BogRq8lt.mjs} +15 -1
  98. package/dist/{messages-NP1myMGI.mjs → messages-BrPFGbM-.mjs} +14 -0
  99. package/dist/{messages-D00OjS2n.mjs → messages-C2htQ_3F.mjs} +24 -10
  100. package/dist/{messages-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
  101. package/dist/{messages-CkFT2gle.mjs → messages-C9eaarcK.mjs} +20 -6
  102. package/dist/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
  103. package/dist/messages-CKI54h6O.mjs +62 -0
  104. package/dist/{chunks/messages-CrsJ1TEJ.mjs → messages-CLhcMlTc.mjs} +15 -1
  105. package/dist/{chunks/messages-CnvW8Slp.mjs → messages-CMkNSDTo.mjs} +17 -3
  106. package/dist/{chunks/messages-BlpqL8vG.mjs → messages-CQwpzUFp.mjs} +19 -5
  107. package/dist/{messages-Cu08aLS3.mjs → messages-CVw84KdI.mjs} +21 -7
  108. package/dist/{messages-B9Oba7sq.mjs → messages-CY8_RyFE.mjs} +15 -1
  109. package/dist/{messages-B5hdXZwA.mjs → messages-CZygwLwM.mjs} +15 -1
  110. package/dist/{messages-CVeWVKsV.mjs → messages-CnwibSvh.mjs} +14 -0
  111. package/dist/{messages-DbVquYKN.mjs → messages-CqWJcCbY.mjs} +14 -0
  112. package/dist/{chunks/messages-Dg92dXZ5.mjs → messages-CvGLfqmV.mjs} +14 -0
  113. package/dist/{chunks/messages-AHESHJm_.mjs → messages-CzTufCHu.mjs} +14 -0
  114. package/dist/{messages-Cj-t1bdy.mjs → messages-CznZadDf.mjs} +15 -1
  115. package/dist/{messages-DMQIHGRj.mjs → messages-D-ZtY5v0.mjs} +14 -0
  116. package/dist/{messages-rRSHQDCX.mjs → messages-D1Hv8XGo.mjs} +14 -0
  117. package/dist/{messages-0tDXLuyH.mjs → messages-D5C3J9qr.mjs} +15 -1
  118. package/dist/{messages-RvMHb2Ht.mjs → messages-D5iv1Kox.mjs} +16 -2
  119. package/dist/{chunks/messages-zSzDzXej.mjs → messages-DBRw-7Zc.mjs} +16 -2
  120. package/dist/{messages-CeCjVKMW.mjs → messages-DBn76jVV.mjs} +16 -2
  121. package/dist/{messages-C7I_AVH2.mjs → messages-DJDG55Vq.mjs} +16 -2
  122. package/dist/{chunks/messages-DDLgIPDF.mjs → messages-DLfR5bMd.mjs} +16 -2
  123. package/dist/{chunks/messages-CbhuIWRJ.mjs → messages-DT4dP5uK.mjs} +15 -1
  124. package/dist/{messages-B66ZSDCJ.mjs → messages-DhLKYm2j.mjs} +15 -1
  125. package/dist/{chunks/messages-BPqWKx5Z.mjs → messages-Diu6jAaR.mjs} +17 -3
  126. package/dist/{chunks/messages-BA0rcTCY.mjs → messages-DnIhyAJk.mjs} +18 -4
  127. package/dist/{messages-DV6shA9b.mjs → messages-DnXLrlHh.mjs} +14 -0
  128. package/dist/{messages-DcKOuncK.mjs → messages-DprmQg6V.mjs} +16 -2
  129. package/dist/{chunks/messages-CJoBtXU6.mjs → messages-DqM1LFg5.mjs} +14 -0
  130. package/dist/{messages-Cyi2AMmz.mjs → messages-DvFLX36Q.mjs} +25 -11
  131. package/dist/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
  132. package/dist/{messages-GC2PhgV3.mjs → messages-Dzwxv9v1.mjs} +23 -9
  133. package/dist/{messages-Q4kc_ZtL.mjs → messages-JELdtT6E.mjs} +15 -1
  134. package/dist/{chunks/messages-DY94ykcE.mjs → messages-LPVfA-8K.mjs} +14 -0
  135. package/dist/{chunks/messages-Cr-RJ7YB.mjs → messages-O5tQus_0.mjs} +14 -0
  136. package/dist/{messages-CbMyJSzS.mjs → messages-Q7AO_FLv.mjs} +17 -3
  137. package/dist/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
  138. package/dist/{chunks/messages-CUy1vn-b.mjs → messages-Xq8UmkVs.mjs} +14 -0
  139. package/dist/{messages-BBJgd5jG.mjs → messages-Z9nEU2xK.mjs} +16 -2
  140. package/dist/{messages-Cm9aLHeX.mjs → messages-_ErNTNhk.mjs} +15 -1
  141. package/dist/{messages-JZUhXTuV.mjs → messages-_ncGrKHh.mjs} +16 -2
  142. package/dist/{messages-ftMcCEuO.mjs → messages-kep5wtm4.mjs} +15 -1
  143. package/dist/{messages-DteYq0rv.mjs → messages-uKX8WBaD.mjs} +16 -2
  144. package/dist/{messages-Bdv-IkfG.mjs → messages-w7v1GNaE.mjs} +15 -1
  145. package/dist/tools.mjs +929 -779
  146. package/dist/vendor.LICENSE.txt +1 -1
  147. package/package.json +15 -14
  148. package/src/cli/commands/migration.ts +16 -0
  149. package/src/cli/commands/migrationContent.ts +6 -0
  150. package/src/cli/index.ts +47 -0
  151. package/src/cli/utils/output.ts +10 -0
  152. package/src/components/i18n/locales/am/messages.json +15 -1
  153. package/src/components/i18n/locales/ar/messages.json +14 -0
  154. package/src/components/i18n/locales/az/messages.json +14 -0
  155. package/src/components/i18n/locales/bg/messages.json +14 -0
  156. package/src/components/i18n/locales/bn/messages.json +25 -11
  157. package/src/components/i18n/locales/bs/messages.json +15 -1
  158. package/src/components/i18n/locales/cs/messages.json +14 -0
  159. package/src/components/i18n/locales/da/messages.json +14 -0
  160. package/src/components/i18n/locales/de/messages.json +14 -0
  161. package/src/components/i18n/locales/dv/messages.json +15 -1
  162. package/src/components/i18n/locales/el/messages.json +15 -1
  163. package/src/components/i18n/locales/en/messages.json +14 -0
  164. package/src/components/i18n/locales/es/messages.json +14 -0
  165. package/src/components/i18n/locales/et/messages.json +14 -0
  166. package/src/components/i18n/locales/fa/messages.json +15 -1
  167. package/src/components/i18n/locales/fi/messages.json +15 -1
  168. package/src/components/i18n/locales/fil/messages.json +20 -6
  169. package/src/components/i18n/locales/fr/messages.json +15 -1
  170. package/src/components/i18n/locales/gu/messages.json +15 -1
  171. package/src/components/i18n/locales/he/messages.json +14 -0
  172. package/src/components/i18n/locales/hi/messages.json +23 -9
  173. package/src/components/i18n/locales/hr/messages.json +14 -0
  174. package/src/components/i18n/locales/hu/messages.json +14 -0
  175. package/src/components/i18n/locales/hy/messages.json +16 -2
  176. package/src/components/i18n/locales/id/messages.json +19 -5
  177. package/src/components/i18n/locales/it/messages.json +14 -0
  178. package/src/components/i18n/locales/ja/messages.json +14 -0
  179. package/src/components/i18n/locales/ka/messages.json +15 -1
  180. package/src/components/i18n/locales/km/messages.json +16 -2
  181. package/src/components/i18n/locales/kn/messages.json +16 -2
  182. package/src/components/i18n/locales/ko/messages.json +14 -0
  183. package/src/components/i18n/locales/ku/messages.json +16 -2
  184. package/src/components/i18n/locales/lo/messages.json +15 -1
  185. package/src/components/i18n/locales/lt/messages.json +15 -1
  186. package/src/components/i18n/locales/lv/messages.json +15 -1
  187. package/src/components/i18n/locales/mk/messages.json +16 -2
  188. package/src/components/i18n/locales/ml/messages.json +16 -2
  189. package/src/components/i18n/locales/mn/messages.json +16 -2
  190. package/src/components/i18n/locales/mr/messages.json +24 -10
  191. package/src/components/i18n/locales/ms/messages.json +17 -3
  192. package/src/components/i18n/locales/my/messages.json +16 -2
  193. package/src/components/i18n/locales/ne/messages.json +24 -10
  194. package/src/components/i18n/locales/nl/messages.json +15 -1
  195. package/src/components/i18n/locales/no/messages.json +16 -2
  196. package/src/components/i18n/locales/pa/messages.json +15 -1
  197. package/src/components/i18n/locales/pl/messages.json +14 -0
  198. package/src/components/i18n/locales/ps/messages.json +17 -3
  199. package/src/components/i18n/locales/pt/messages.json +14 -0
  200. package/src/components/i18n/locales/ro/messages.json +15 -1
  201. package/src/components/i18n/locales/ru/messages.json +14 -0
  202. package/src/components/i18n/locales/sd/messages.json +16 -2
  203. package/src/components/i18n/locales/si/messages.json +23 -9
  204. package/src/components/i18n/locales/sk/messages.json +15 -1
  205. package/src/components/i18n/locales/sl/messages.json +16 -2
  206. package/src/components/i18n/locales/sq/messages.json +16 -2
  207. package/src/components/i18n/locales/sr/messages.json +16 -2
  208. package/src/components/i18n/locales/sv/messages.json +16 -2
  209. package/src/components/i18n/locales/sw/messages.json +16 -2
  210. package/src/components/i18n/locales/ta/messages.json +21 -7
  211. package/src/components/i18n/locales/te/messages.json +40 -26
  212. package/src/components/i18n/locales/th/messages.json +19 -5
  213. package/src/components/i18n/locales/tr/messages.json +15 -1
  214. package/src/components/i18n/locales/ug/messages.json +16 -2
  215. package/src/components/i18n/locales/uk/messages.json +15 -1
  216. package/src/components/i18n/locales/ur/messages.json +15 -1
  217. package/src/components/i18n/locales/vi/messages.json +25 -11
  218. package/src/components/i18n/locales/yi/messages.json +16 -2
  219. package/src/components/i18n/locales/zh/messages.json +15 -1
  220. package/src/components/modules/api/blocks.ts +17 -2
  221. package/src/components/modules/api/history.ts +64 -0
  222. package/src/components/modules/api/index.ts +1 -0
  223. package/src/components/modules/api/readonly.ts +11 -1
  224. package/src/components/modules/blockEvents/composers/markdownShortcuts.ts +12 -1
  225. package/src/components/modules/blockManager/blockManager.ts +7 -0
  226. package/src/components/modules/blockManager/yjs-sync.ts +12 -2
  227. package/src/components/modules/index.ts +3 -0
  228. package/src/components/modules/readonly.ts +11 -0
  229. package/src/components/modules/toolbar/index.ts +29 -7
  230. package/src/components/modules/ui.ts +46 -68
  231. package/src/components/modules/uiControllers/controllers/blockHover.ts +40 -61
  232. package/src/components/modules/yjs/index.ts +23 -0
  233. package/src/components/ui/toolbox.ts +41 -6
  234. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +3 -1
  235. package/src/components/utils/popover/popover-desktop.ts +27 -8
  236. package/src/tools/table/index.ts +87 -70
  237. package/src/tools/table/table-add-controls.ts +33 -7
  238. package/src/tools/table/table-cell-blocks.ts +77 -5
  239. package/src/tools/table/table-cell-selection.ts +70 -46
  240. package/src/tools/table/table-core.ts +20 -15
  241. package/src/tools/table/table-grip-visuals.ts +4 -4
  242. package/src/tools/table/table-operations.ts +22 -12
  243. package/src/tools/table/table-restrictions.ts +64 -0
  244. package/src/tools/table/table-row-col-action-handler.ts +190 -0
  245. package/src/tools/table/table-row-col-controls.ts +91 -182
  246. package/src/tools/table/table-row-col-drag.ts +4 -4
  247. package/src/tools/table/table-row-col-popover.ts +225 -0
  248. package/src/tools/table/types.ts +2 -0
  249. package/src/types-internal/blok-modules.d.ts +2 -0
  250. package/types/api/history.d.ts +33 -0
  251. package/types/api/index.d.ts +1 -0
  252. package/types/api/readonly.d.ts +12 -2
  253. package/types/index.d.ts +3 -0
  254. package/types/utils/popover/popover.d.ts +7 -0
  255. package/dist/chunks/messages-CySyfkMU.mjs +0 -48
  256. package/dist/messages-CySyfkMU.mjs +0 -48
@@ -1,22 +1,11 @@
1
- import {
2
- IconInsertAbove,
3
- IconInsertBelow,
4
- IconInsertLeft,
5
- IconInsertRight,
6
- IconTrash,
7
- IconHeaderRow,
8
- IconHeaderColumn,
9
- } from '../../components/icons';
10
- import { PopoverDesktop, PopoverItemType } from '../../components/utils/popover';
1
+ import type { I18n } from '../../../types/api';
11
2
  import { twMerge } from '../../components/utils/tw';
12
3
 
13
4
  import { BORDER_WIDTH, CELL_ATTR, ROW_ATTR } from './table-core';
14
5
  import { collapseGrip, createGripDotsSvg, expandGrip, GRIP_HOVER_SIZE } from './table-grip-visuals';
15
- import { createHeadingToggle } from './table-heading-toggle';
16
6
  import { getCumulativeColEdges, TableRowColDrag } from './table-row-col-drag';
17
-
18
- import { PopoverEvent } from '@/types/utils/popover/popover-event';
19
- import type { PopoverItemParams } from '@/types/utils/popover/popover-item';
7
+ import { createGripPopover } from './table-row-col-popover';
8
+ import type { PopoverState } from './table-row-col-popover';
20
9
 
21
10
  const GRIP_ATTR = 'data-blok-table-grip';
22
11
  const GRIP_COL_ATTR = 'data-blok-table-grip-col';
@@ -52,6 +41,7 @@ export interface TableRowColControlsOptions {
52
41
  onDragStateChange?: (isDragging: boolean, dragType: 'row' | 'col' | null) => void;
53
42
  onGripClick?: (type: 'row' | 'col', index: number) => void;
54
43
  onGripPopoverClose?: () => void;
44
+ i18n: I18n;
55
45
  }
56
46
 
57
47
  const GRIP_CAPSULE_CLASSES = [
@@ -100,16 +90,18 @@ export class TableRowColControls {
100
90
  private onAction: (action: RowColAction) => void;
101
91
  private onGripClick: ((type: 'row' | 'col', index: number) => void) | undefined;
102
92
  private onGripPopoverClose: (() => void) | undefined;
93
+ private i18n: I18n;
103
94
 
104
95
  private colGrips: HTMLElement[] = [];
105
96
  private rowGrips: HTMLElement[] = [];
106
- private activePopover: PopoverDesktop | null = null;
107
- private activePopoverGrip: HTMLElement | null = null;
97
+ private popoverState: PopoverState = { popover: null, grip: null };
108
98
  private lockedGrip: HTMLElement | null = null;
109
99
  private boundUnlockGrip: (e: PointerEvent) => void;
110
100
  private hideTimeout: ReturnType<typeof setTimeout> | null = null;
111
101
  private activeColGripIndex = -1;
112
102
  private activeRowGripIndex = -1;
103
+ private isInsideTable = false;
104
+ private rowResizeObserver: ResizeObserver | null = null;
113
105
 
114
106
  private drag: TableRowColDrag;
115
107
 
@@ -126,6 +118,7 @@ export class TableRowColControls {
126
118
  this.onAction = options.onAction;
127
119
  this.onGripClick = options.onGripClick;
128
120
  this.onGripPopoverClose = options.onGripPopoverClose;
121
+ this.i18n = options.i18n;
129
122
 
130
123
  this.drag = new TableRowColDrag({
131
124
  grid: this.grid,
@@ -228,15 +221,19 @@ export class TableRowColControls {
228
221
  });
229
222
 
230
223
  this.positionGrips();
224
+ this.observeRowHeights();
231
225
  }
232
226
 
233
227
  private destroyGrips(): void {
228
+ this.rowResizeObserver?.disconnect();
229
+ this.rowResizeObserver = null;
234
230
  this.colGrips.forEach(g => g.remove());
235
231
  this.rowGrips.forEach(g => g.remove());
236
232
  this.colGrips = [];
237
233
  this.rowGrips = [];
238
234
  this.activeColGripIndex = -1;
239
235
  this.activeRowGripIndex = -1;
236
+ this.isInsideTable = false;
240
237
  }
241
238
 
242
239
  private createGripElement(type: 'row' | 'col', index: number): HTMLElement {
@@ -313,8 +310,25 @@ export class TableRowColControls {
313
310
  });
314
311
  }
315
312
 
313
+ /**
314
+ * Set up ResizeObserver to watch for row height changes and reposition grips.
315
+ */
316
+ private observeRowHeights(): void {
317
+ this.rowResizeObserver?.disconnect();
318
+
319
+ this.rowResizeObserver = new ResizeObserver(() => {
320
+ this.positionGrips();
321
+ });
322
+
323
+ const rows = this.grid.querySelectorAll(`[${ROW_ATTR}]`);
324
+
325
+ rows.forEach(row => {
326
+ this.rowResizeObserver?.observe(row as HTMLElement);
327
+ });
328
+ }
329
+
316
330
  private isGripInteractionLocked(): boolean {
317
- return this.activePopover !== null || this.lockedGrip !== null;
331
+ return this.popoverState.popover !== null || this.lockedGrip !== null;
318
332
  }
319
333
 
320
334
  private handleMouseOver(e: MouseEvent): void {
@@ -339,6 +353,7 @@ export class TableRowColControls {
339
353
 
340
354
  this.showColGrip(position.col);
341
355
  this.showRowGrip(position.row);
356
+ this.isInsideTable = true;
342
357
  }
343
358
 
344
359
  private handleMouseLeave(): void {
@@ -385,7 +400,7 @@ export class TableRowColControls {
385
400
  const el: HTMLElement = grip;
386
401
 
387
402
  // Don't hide the grip that has an active popover
388
- if (!visible && grip === this.activePopoverGrip) {
403
+ if (!visible && grip === this.popoverState.grip) {
389
404
  return;
390
405
  }
391
406
 
@@ -400,6 +415,7 @@ export class TableRowColControls {
400
415
  this.clearHideTimeout();
401
416
  this.hideColGrip();
402
417
  this.hideRowGrip();
418
+ this.isInsideTable = false;
403
419
  }
404
420
 
405
421
  private showColGrip(index: number): void {
@@ -440,10 +456,25 @@ export class TableRowColControls {
440
456
 
441
457
  private applyVisibleClasses(grip: HTMLElement): void {
442
458
  const el = grip;
459
+ const isCol = el.hasAttribute(GRIP_COL_ATTR);
460
+ const type: 'col' | 'row' = isCol ? 'col' : 'row';
461
+ const pillSize = isCol ? COL_PILL_HEIGHT : ROW_PILL_WIDTH;
462
+
463
+ // Reset to pill size before making visible
464
+ collapseGrip(el, type, pillSize);
465
+
466
+ if (this.isInsideTable) {
467
+ el.style.transition = 'none';
468
+ }
443
469
 
444
470
  el.className = twMerge(GRIP_CAPSULE_CLASSES, GRIP_VISIBLE_CLASSES);
445
471
  el.setAttribute('data-blok-table-grip-visible', '');
446
472
 
473
+ if (this.isInsideTable) {
474
+ void el.offsetHeight;
475
+ el.style.transition = '';
476
+ }
477
+
447
478
  const svg = el.querySelector('svg');
448
479
 
449
480
  if (svg) {
@@ -453,7 +484,7 @@ export class TableRowColControls {
453
484
  }
454
485
 
455
486
  private applyActiveClasses(grip: HTMLElement): void {
456
- grip.className = twMerge(GRIP_CAPSULE_CLASSES, GRIP_ACTIVE_CLASSES);
487
+ Object.assign(grip, { className: twMerge(GRIP_CAPSULE_CLASSES, GRIP_ACTIVE_CLASSES) });
457
488
  grip.setAttribute('data-blok-table-grip-visible', '');
458
489
 
459
490
  const svg = grip.querySelector('svg');
@@ -476,11 +507,22 @@ export class TableRowColControls {
476
507
  const el = grip;
477
508
  const isCol = el.hasAttribute(GRIP_COL_ATTR);
478
509
  const type: 'col' | 'row' = isCol ? 'col' : 'row';
479
- const pillSize = isCol ? COL_PILL_HEIGHT : ROW_PILL_WIDTH;
510
+ // With border-box, pillSize must account for the 12px padding (6px each side)
511
+ const HIT_AREA_PADDING = 12;
512
+ const pillSize = isCol ? (COL_PILL_HEIGHT + HIT_AREA_PADDING) : (ROW_PILL_WIDTH + HIT_AREA_PADDING);
513
+
514
+ if (this.isInsideTable) {
515
+ el.style.transition = 'none';
516
+ }
480
517
 
481
518
  collapseGrip(el, type, pillSize);
482
519
  el.className = twMerge(GRIP_CAPSULE_CLASSES, GRIP_IDLE_CLASSES);
483
520
  el.removeAttribute('data-blok-table-grip-visible');
521
+
522
+ if (this.isInsideTable) {
523
+ void el.offsetHeight;
524
+ el.style.transition = '';
525
+ }
484
526
  }
485
527
 
486
528
  private handleDragStateChange(isDragging: boolean, _dragType: 'row' | 'col' | null): void {
@@ -495,6 +537,7 @@ export class TableRowColControls {
495
537
  this.hideTimeout = setTimeout(() => {
496
538
  this.hideColGrip();
497
539
  this.hideRowGrip();
540
+ this.isInsideTable = false;
498
541
  this.hideTimeout = null;
499
542
  }, HIDE_DELAY_MS);
500
543
  }
@@ -553,175 +596,41 @@ export class TableRowColControls {
553
596
  // ── Popover menus ────────────────────────────────────────────
554
597
 
555
598
  private openPopover(type: 'row' | 'col', index: number): void {
556
- this.destroyPopover();
557
- this.clearHideTimeout();
558
-
559
- const grip = type === 'col'
560
- ? this.colGrips[index]
561
- : this.rowGrips[index];
562
-
563
- if (!grip) {
564
- return;
565
- }
566
-
567
- const items = type === 'col'
568
- ? this.buildColumnMenu(index)
569
- : this.buildRowMenu(index);
570
-
571
- this.activePopover = new PopoverDesktop({
572
- items,
573
- trigger: grip,
574
- flippable: true,
575
- });
576
-
577
- // Track which grip has the popover so setGripsDisplay won't hide it
578
- this.activePopoverGrip = grip;
579
-
580
- this.activePopover.on(PopoverEvent.Closed, () => {
581
- // Guard against re-entrant calls: destroyPopover() calls popover.destroy()
582
- // which calls hide() and re-emits Closed. Skip the re-entrant invocation.
583
- if (this.activePopover === null) {
584
- return;
599
+ this.popoverState = createGripPopover(
600
+ type,
601
+ index,
602
+ { col: this.colGrips, row: this.rowGrips },
603
+ {
604
+ getColumnCount: this.getColumnCount,
605
+ getRowCount: this.getRowCount,
606
+ isHeadingRow: this.isHeadingRow,
607
+ isHeadingColumn: this.isHeadingColumn,
608
+ onAction: this.onAction,
609
+ i18n: this.i18n,
610
+ },
611
+ {
612
+ clearHideTimeout: () => this.clearHideTimeout(),
613
+ hideAllGripsExcept: (grip) => this.hideAllGripsExcept(grip),
614
+ applyActiveClasses: (grip) => this.applyActiveClasses(grip),
615
+ applyVisibleClasses: (grip) => this.applyVisibleClasses(grip),
616
+ scheduleHideAll: () => this.scheduleHideAll(),
617
+ destroyPopover: () => this.destroyPopover(),
618
+ onGripPopoverClose: this.onGripPopoverClose,
585
619
  }
620
+ );
586
621
 
587
- this.destroyPopover();
588
- this.applyVisibleClasses(grip);
589
- this.scheduleHideAll();
590
- this.onGripPopoverClose?.();
591
- });
592
-
593
- // Hide all other grips and make the active one blue
594
- this.hideAllGripsExcept(grip);
595
- this.applyActiveClasses(grip);
596
-
597
- // Expand the grip to hover size so it remains visible while popover is open
598
- if (type === 'col') {
599
- grip.style.height = `${GRIP_HOVER_SIZE}px`;
600
- } else {
601
- grip.style.width = `${GRIP_HOVER_SIZE}px`;
602
- }
603
-
604
- this.activePopover.show();
622
+ // Show after storing state so callbacks (e.g. onGripClick → setGripsDisplay)
623
+ // see the updated popoverState.grip reference
624
+ this.popoverState.popover?.show();
605
625
  this.onGripClick?.(type, index);
606
626
  }
607
627
 
608
628
  private destroyPopover(): void {
609
- if (this.activePopover !== null) {
610
- const popover = this.activePopover;
629
+ if (this.popoverState.popover !== null) {
630
+ const popoverRef = this.popoverState.popover;
611
631
 
612
- this.activePopover = null;
613
- this.activePopoverGrip = null;
614
- popover.destroy();
632
+ this.popoverState = { popover: null, grip: null };
633
+ popoverRef.destroy();
615
634
  }
616
635
  }
617
-
618
- private buildColumnMenu(colIndex: number): PopoverItemParams[] {
619
- const headingItems: PopoverItemParams[] = colIndex === 0
620
- ? [
621
- {
622
- type: PopoverItemType.Html,
623
- element: createHeadingToggle({
624
- icon: IconHeaderColumn,
625
- label: 'Header column',
626
- isActive: this.isHeadingColumn(),
627
- onToggle: () => {
628
- this.onAction({ type: 'toggle-heading-column' });
629
- },
630
- }),
631
- },
632
- { type: PopoverItemType.Separator },
633
- ]
634
- : [];
635
-
636
- const baseItems: PopoverItemParams[] = [
637
- {
638
- icon: IconInsertLeft,
639
- title: 'Insert Column Left',
640
- closeOnActivate: true,
641
- onActivate: (): void => {
642
- this.onAction({ type: 'insert-col-left', index: colIndex });
643
- },
644
- },
645
- {
646
- icon: IconInsertRight,
647
- title: 'Insert Column Right',
648
- closeOnActivate: true,
649
- onActivate: (): void => {
650
- this.onAction({ type: 'insert-col-right', index: colIndex });
651
- },
652
- },
653
- ];
654
-
655
- const canDelete = this.getColumnCount() > 1;
656
- const deleteItems: PopoverItemParams[] = [
657
- { type: PopoverItemType.Separator },
658
- {
659
- icon: IconTrash,
660
- title: 'Delete',
661
- isDestructive: true,
662
- isDisabled: !canDelete,
663
- closeOnActivate: true,
664
- onActivate: (): void => {
665
- this.onAction({ type: 'delete-col', index: colIndex });
666
- },
667
- },
668
- ];
669
-
670
- return [...headingItems, ...baseItems, ...deleteItems];
671
- }
672
-
673
- private buildRowMenu(rowIndex: number): PopoverItemParams[] {
674
- const headingItems: PopoverItemParams[] = rowIndex === 0
675
- ? [
676
- {
677
- type: PopoverItemType.Html,
678
- element: createHeadingToggle({
679
- icon: IconHeaderRow,
680
- label: 'Header row',
681
- isActive: this.isHeadingRow(),
682
- onToggle: () => {
683
- this.onAction({ type: 'toggle-heading' });
684
- },
685
- }),
686
- },
687
- { type: PopoverItemType.Separator },
688
- ]
689
- : [];
690
-
691
- const baseItems: PopoverItemParams[] = [
692
- {
693
- icon: IconInsertAbove,
694
- title: 'Insert Row Above',
695
- closeOnActivate: true,
696
- onActivate: (): void => {
697
- this.onAction({ type: 'insert-row-above', index: rowIndex });
698
- },
699
- },
700
- {
701
- icon: IconInsertBelow,
702
- title: 'Insert Row Below',
703
- closeOnActivate: true,
704
- onActivate: (): void => {
705
- this.onAction({ type: 'insert-row-below', index: rowIndex });
706
- },
707
- },
708
- ];
709
-
710
- const canDelete = this.getRowCount() > 1;
711
- const deleteItems: PopoverItemParams[] = [
712
- { type: PopoverItemType.Separator },
713
- {
714
- icon: IconTrash,
715
- title: 'Delete',
716
- isDestructive: true,
717
- isDisabled: !canDelete,
718
- closeOnActivate: true,
719
- onActivate: (): void => {
720
- this.onAction({ type: 'delete-row', index: rowIndex });
721
- },
722
- },
723
- ];
724
-
725
- return [...headingItems, ...baseItems, ...deleteItems];
726
- }
727
636
  }
@@ -186,8 +186,8 @@ export class TableRowColDrag {
186
186
  cells.forEach(node => {
187
187
  const cellEl = node as HTMLElement;
188
188
 
189
- cellEl.style.backgroundColor = '#dbeafe';
190
- cellEl.style.opacity = '0.6';
189
+ cellEl.style.backgroundColor = '#f3f4f6';
190
+ cellEl.style.opacity = '0.7';
191
191
  this.dragOverlayCells.push(cellEl);
192
192
  });
193
193
  }
@@ -202,8 +202,8 @@ export class TableRowColDrag {
202
202
 
203
203
  const cellEl = cells[this.dragFromIndex] as HTMLElement;
204
204
 
205
- cellEl.style.backgroundColor = '#dbeafe';
206
- cellEl.style.opacity = '0.6';
205
+ cellEl.style.backgroundColor = '#f3f4f6';
206
+ cellEl.style.opacity = '0.7';
207
207
  this.dragOverlayCells.push(cellEl);
208
208
  });
209
209
  }
@@ -0,0 +1,225 @@
1
+ import type { I18n } from '../../../types/api';
2
+ import {
3
+ IconInsertAbove,
4
+ IconInsertBelow,
5
+ IconInsertLeft,
6
+ IconInsertRight,
7
+ IconTrash,
8
+ IconHeaderRow,
9
+ IconHeaderColumn,
10
+ } from '../../components/icons';
11
+ import { PopoverDesktop, PopoverItemType } from '../../components/utils/popover';
12
+
13
+ import { GRIP_HOVER_SIZE } from './table-grip-visuals';
14
+ import { createHeadingToggle } from './table-heading-toggle';
15
+ import type { RowColAction } from './table-row-col-controls';
16
+
17
+ import { PopoverEvent } from '@/types/utils/popover/popover-event';
18
+ import type { PopoverItemParams } from '@/types/utils/popover/popover-item';
19
+
20
+ /**
21
+ * State for the currently active grip popover.
22
+ */
23
+ export interface PopoverState {
24
+ popover: PopoverDesktop | null;
25
+ grip: HTMLElement | null;
26
+ }
27
+
28
+ /**
29
+ * Options for building popover menu items.
30
+ */
31
+ export interface PopoverMenuOptions {
32
+ getColumnCount: () => number;
33
+ getRowCount: () => number;
34
+ isHeadingRow: () => boolean;
35
+ isHeadingColumn: () => boolean;
36
+ onAction: (action: RowColAction) => void;
37
+ i18n: I18n;
38
+ }
39
+
40
+ /**
41
+ * Callbacks the popover needs from the controls class.
42
+ */
43
+ export interface OpenPopoverCallbacks {
44
+ clearHideTimeout: () => void;
45
+ hideAllGripsExcept: (grip: HTMLElement) => void;
46
+ applyActiveClasses: (grip: HTMLElement) => void;
47
+ applyVisibleClasses: (grip: HTMLElement) => void;
48
+ scheduleHideAll: () => void;
49
+ destroyPopover: () => void;
50
+ onGripPopoverClose?: () => void;
51
+ }
52
+
53
+ /**
54
+ * Build the popover menu items for a column grip.
55
+ */
56
+ export const buildColumnMenuItems = (colIndex: number, options: PopoverMenuOptions): PopoverItemParams[] => {
57
+ const headingItems: PopoverItemParams[] = colIndex === 0
58
+ ? [
59
+ {
60
+ type: PopoverItemType.Html,
61
+ element: createHeadingToggle({
62
+ icon: IconHeaderColumn,
63
+ label: options.i18n.t('tools.table.headerColumn'),
64
+ isActive: options.isHeadingColumn(),
65
+ onToggle: () => {
66
+ options.onAction({ type: 'toggle-heading-column' });
67
+ },
68
+ }),
69
+ },
70
+ { type: PopoverItemType.Separator },
71
+ ]
72
+ : [];
73
+
74
+ const baseItems: PopoverItemParams[] = [
75
+ {
76
+ icon: IconInsertLeft,
77
+ title: options.i18n.t('tools.table.insertColumnLeft'),
78
+ closeOnActivate: true,
79
+ onActivate: (): void => {
80
+ options.onAction({ type: 'insert-col-left', index: colIndex });
81
+ },
82
+ },
83
+ {
84
+ icon: IconInsertRight,
85
+ title: options.i18n.t('tools.table.insertColumnRight'),
86
+ closeOnActivate: true,
87
+ onActivate: (): void => {
88
+ options.onAction({ type: 'insert-col-right', index: colIndex });
89
+ },
90
+ },
91
+ ];
92
+
93
+ const canDelete = options.getColumnCount() > 1;
94
+ const deleteItems: PopoverItemParams[] = [
95
+ { type: PopoverItemType.Separator },
96
+ {
97
+ icon: IconTrash,
98
+ title: options.i18n.t('tools.table.deleteColumn'),
99
+ isDestructive: true,
100
+ isDisabled: !canDelete,
101
+ closeOnActivate: true,
102
+ onActivate: (): void => {
103
+ options.onAction({ type: 'delete-col', index: colIndex });
104
+ },
105
+ },
106
+ ];
107
+
108
+ return [...headingItems, ...baseItems, ...deleteItems];
109
+ };
110
+
111
+ /**
112
+ * Build the popover menu items for a row grip.
113
+ */
114
+ export const buildRowMenuItems = (rowIndex: number, options: PopoverMenuOptions): PopoverItemParams[] => {
115
+ const headingItems: PopoverItemParams[] = rowIndex === 0
116
+ ? [
117
+ {
118
+ type: PopoverItemType.Html,
119
+ element: createHeadingToggle({
120
+ icon: IconHeaderRow,
121
+ label: options.i18n.t('tools.table.headerRow'),
122
+ isActive: options.isHeadingRow(),
123
+ onToggle: () => {
124
+ options.onAction({ type: 'toggle-heading' });
125
+ },
126
+ }),
127
+ },
128
+ { type: PopoverItemType.Separator },
129
+ ]
130
+ : [];
131
+
132
+ const baseItems: PopoverItemParams[] = [
133
+ {
134
+ icon: IconInsertAbove,
135
+ title: options.i18n.t('tools.table.insertRowAbove'),
136
+ closeOnActivate: true,
137
+ onActivate: (): void => {
138
+ options.onAction({ type: 'insert-row-above', index: rowIndex });
139
+ },
140
+ },
141
+ {
142
+ icon: IconInsertBelow,
143
+ title: options.i18n.t('tools.table.insertRowBelow'),
144
+ closeOnActivate: true,
145
+ onActivate: (): void => {
146
+ options.onAction({ type: 'insert-row-below', index: rowIndex });
147
+ },
148
+ },
149
+ ];
150
+
151
+ const canDelete = options.getRowCount() > 1;
152
+ const deleteItems: PopoverItemParams[] = [
153
+ { type: PopoverItemType.Separator },
154
+ {
155
+ icon: IconTrash,
156
+ title: options.i18n.t('tools.table.deleteRow'),
157
+ isDestructive: true,
158
+ isDisabled: !canDelete,
159
+ closeOnActivate: true,
160
+ onActivate: (): void => {
161
+ options.onAction({ type: 'delete-row', index: rowIndex });
162
+ },
163
+ },
164
+ ];
165
+
166
+ return [...headingItems, ...baseItems, ...deleteItems];
167
+ };
168
+
169
+ /**
170
+ * Create a popover anchored to the given grip and prepare it for display.
171
+ * Returns the new state. The caller must call `popover.show()` after
172
+ * storing the state so that any callbacks fired during show see the
173
+ * updated popover reference.
174
+ */
175
+ export const createGripPopover = (
176
+ type: 'row' | 'col',
177
+ index: number,
178
+ grips: { col: HTMLElement[]; row: HTMLElement[] },
179
+ menuOptions: PopoverMenuOptions,
180
+ callbacks: OpenPopoverCallbacks
181
+ ): PopoverState => {
182
+ callbacks.destroyPopover();
183
+ callbacks.clearHideTimeout();
184
+
185
+ const grip = type === 'col'
186
+ ? grips.col[index]
187
+ : grips.row[index];
188
+
189
+ if (!grip) {
190
+ return { popover: null, grip: null };
191
+ }
192
+
193
+ const items = type === 'col'
194
+ ? buildColumnMenuItems(index, menuOptions)
195
+ : buildRowMenuItems(index, menuOptions);
196
+
197
+ const popover = new PopoverDesktop({
198
+ items,
199
+ trigger: grip,
200
+ flippable: true,
201
+ });
202
+
203
+ popover.on(PopoverEvent.Closed, () => {
204
+ // The caller's destroyPopover handles nulling the shared state and
205
+ // calling popover.destroy(). The re-entrant Closed event is caught
206
+ // by the guard inside destroyPopover (checks if popover is already null).
207
+ callbacks.destroyPopover();
208
+ callbacks.applyVisibleClasses(grip);
209
+ callbacks.scheduleHideAll();
210
+ callbacks.onGripPopoverClose?.();
211
+ });
212
+
213
+ // Hide all other grips and make the active one blue
214
+ callbacks.hideAllGripsExcept(grip);
215
+ callbacks.applyActiveClasses(grip);
216
+
217
+ // Expand the grip to hover size so it remains visible while popover is open
218
+ if (type === 'col') {
219
+ grip.style.height = `${GRIP_HOVER_SIZE}px`;
220
+ } else {
221
+ grip.style.width = `${GRIP_HOVER_SIZE}px`;
222
+ }
223
+
224
+ return { popover, grip };
225
+ };
@@ -37,6 +37,8 @@ export interface TableData extends BlockToolData {
37
37
  content: LegacyCellContent[][];
38
38
  /** Column widths in pixels (e.g., [200, 300, 250]). Omit for equal widths. */
39
39
  colWidths?: number[];
40
+ /** Original per-column width in pixels, set once at creation. New columns = initialColWidth / 2. */
41
+ initialColWidth?: number;
40
42
  }
41
43
 
42
44
  /**
@@ -2,6 +2,7 @@
2
2
  import { BlocksAPI } from '../components/modules/api/blocks';
3
3
  import { CaretAPI } from '../components/modules/api/caret';
4
4
  import { EventsAPI } from '../components/modules/api/events';
5
+ import { HistoryAPI } from '../components/modules/api/history';
5
6
  import { I18nAPI } from '../components/modules/api/i18n';
6
7
  import { API } from '../components/modules/api/index';
7
8
  import { InlineToolbarAPI } from '../components/modules/api/inlineToolbar';
@@ -45,6 +46,7 @@ export interface BlokModules {
45
46
  CaretAPI: CaretAPI,
46
47
  ToolsAPI: ToolsAPI,
47
48
  EventsAPI: EventsAPI,
49
+ HistoryAPI: HistoryAPI,
48
50
  I18nAPI: I18nAPI,
49
51
  API: API,
50
52
  InlineToolbarAPI: InlineToolbarAPI,