@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,3 +1,4 @@
1
+ import type { I18n } from '../../../types/api';
1
2
  import { IconCross } from '../../components/icons';
2
3
  import { PopoverDesktop } from '../../components/utils/popover';
3
4
  import { twMerge } from '../../components/utils/tw';
@@ -56,6 +57,7 @@ interface CellSelectionOptions {
56
57
  rectangleSelection?: { cancelActiveSelection: () => void };
57
58
  onSelectionActiveChange?: (hasSelection: boolean) => void;
58
59
  onClearContent?: (cells: HTMLElement[]) => void;
60
+ i18n: I18n;
59
61
  }
60
62
 
61
63
  export class TableCellSelection {
@@ -63,6 +65,7 @@ export class TableCellSelection {
63
65
  private rectangleSelection?: { cancelActiveSelection: () => void };
64
66
  private onSelectionActiveChange: ((hasSelection: boolean) => void) | undefined;
65
67
  private onClearContent: ((cells: HTMLElement[]) => void) | undefined;
68
+ private i18n: I18n;
66
69
  private anchorCell: CellCoord | null = null;
67
70
  private extentCell: CellCoord | null = null;
68
71
  private isSelecting = false;
@@ -77,12 +80,14 @@ export class TableCellSelection {
77
80
  private boundPointerUp: () => void;
78
81
  private boundClearSelection: (e: PointerEvent) => void;
79
82
  private boundCancelRectangle: (e: MouseEvent) => void;
83
+ private boundKeyDown: (e: KeyboardEvent) => void;
80
84
 
81
85
  constructor(options: CellSelectionOptions) {
82
86
  this.grid = options.grid;
83
87
  this.rectangleSelection = options.rectangleSelection;
84
88
  this.onSelectionActiveChange = options.onSelectionActiveChange;
85
89
  this.onClearContent = options.onClearContent;
90
+ this.i18n = options.i18n;
86
91
  this.grid.style.position = 'relative';
87
92
 
88
93
  this.boundPointerDown = this.handlePointerDown.bind(this);
@@ -90,8 +95,10 @@ export class TableCellSelection {
90
95
  this.boundPointerUp = this.handlePointerUp.bind(this);
91
96
  this.boundClearSelection = this.handleClearSelection.bind(this);
92
97
  this.boundCancelRectangle = this.handleCancelRectangle.bind(this);
98
+ this.boundKeyDown = this.handleKeyDown.bind(this);
93
99
 
94
100
  this.grid.addEventListener('pointerdown', this.boundPointerDown);
101
+ document.addEventListener('keydown', this.boundKeyDown);
95
102
  }
96
103
 
97
104
  public destroy(): void {
@@ -102,6 +109,7 @@ export class TableCellSelection {
102
109
  document.removeEventListener('pointerup', this.boundPointerUp);
103
110
  document.removeEventListener('pointerdown', this.boundClearSelection);
104
111
  document.removeEventListener('mousemove', this.boundCancelRectangle, true);
112
+ document.removeEventListener('keydown', this.boundKeyDown);
105
113
  }
106
114
 
107
115
  /**
@@ -276,6 +284,25 @@ export class TableCellSelection {
276
284
  this.clearSelection();
277
285
  }
278
286
 
287
+ private handleKeyDown(e: KeyboardEvent): void {
288
+ // Only trigger when selection is active
289
+ if (!this.hasSelection) {
290
+ return;
291
+ }
292
+
293
+ // Check for Delete or Backspace
294
+ if (e.key !== 'Delete' && e.key !== 'Backspace') {
295
+ return;
296
+ }
297
+
298
+ // Prevent default behavior
299
+ e.preventDefault();
300
+
301
+ // Clear content and dismiss selection
302
+ this.onClearContent?.([...this.selectedCells]);
303
+ this.clearSelection();
304
+ }
305
+
279
306
  private clearSelection(): void {
280
307
  const hadSelection = this.hasSelection;
281
308
 
@@ -348,26 +375,10 @@ export class TableCellSelection {
348
375
  const rows = this.grid.querySelectorAll(`[${ROW_ATTR}]`);
349
376
 
350
377
  // Mark selected cells
351
- for (let r = minRow; r <= maxRow; r++) {
352
- const row = rows[r];
353
-
354
- if (!row) {
355
- continue;
356
- }
357
-
358
- const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
359
-
360
- for (let c = minCol; c <= maxCol; c++) {
361
- const cell = cells[c] as HTMLElement | undefined;
362
-
363
- if (!cell) {
364
- continue;
365
- }
366
-
367
- cell.setAttribute(SELECTED_ATTR, '');
368
- this.selectedCells.push(cell);
369
- }
370
- }
378
+ this.selectedCells = this.collectCellsInRange(rows, minRow, maxRow, minCol, maxCol);
379
+ this.selectedCells.forEach(cell => {
380
+ cell.setAttribute(SELECTED_ATTR, '');
381
+ });
371
382
 
372
383
  // Calculate overlay position from bounding rects of corner cells
373
384
  const firstCell = rows[minRow]?.querySelectorAll(`[${CELL_ATTR}]`)[minCol] as HTMLElement | undefined;
@@ -388,16 +399,14 @@ export class TableCellSelection {
388
399
  const borderTop = parseFloat(gridStyle.borderTopWidth) || 0;
389
400
  const borderLeft = parseFloat(gridStyle.borderLeftWidth) || 0;
390
401
 
391
- let top = firstRect.top - gridRect.top - borderTop;
392
- let left = firstRect.left - gridRect.left - borderLeft;
393
402
  const width = lastRect.right - firstRect.left + 1;
394
403
  const height = lastRect.bottom - firstRect.top + 1;
395
404
 
396
405
  // Extend overlay 1px outward to cover adjacent borders:
397
406
  // grid border-top/border-left at row 0/col 0, or the previous
398
407
  // row's border-bottom / previous column's border-right otherwise.
399
- top -= 1;
400
- left -= 1;
408
+ const top = firstRect.top - gridRect.top - borderTop - 1;
409
+ const left = firstRect.left - gridRect.left - borderLeft - 1;
401
410
 
402
411
  // Create overlay once, reuse on subsequent paints
403
412
  if (!this.overlay) {
@@ -476,7 +485,7 @@ export class TableCellSelection {
476
485
  const items: PopoverItemParams[] = [
477
486
  {
478
487
  icon: IconCross,
479
- title: 'Clear',
488
+ title: this.i18n.t('tools.table.clearSelection'),
480
489
  closeOnActivate: true,
481
490
  onActivate: (): void => {
482
491
  this.onClearContent?.([...this.selectedCells]);
@@ -592,27 +601,8 @@ export class TableCellSelection {
592
601
  return;
593
602
  }
594
603
 
595
- // Clamp row
596
- let row: number;
597
-
598
- if (e.clientY < gridRect.top) {
599
- row = 0;
600
- } else if (e.clientY > gridRect.bottom) {
601
- row = rowCount - 1;
602
- } else {
603
- row = this.extentCell?.row ?? this.anchorCell.row;
604
- }
605
-
606
- // Clamp col
607
- let col: number;
608
-
609
- if (e.clientX < gridRect.left) {
610
- col = 0;
611
- } else if (e.clientX > gridRect.right) {
612
- col = colCount - 1;
613
- } else {
614
- col = this.extentCell?.col ?? this.anchorCell.col;
615
- }
604
+ const row = this.clampAxis(e.clientY, gridRect.top, gridRect.bottom, rowCount, this.extentCell?.row ?? this.anchorCell.row);
605
+ const col = this.clampAxis(e.clientX, gridRect.left, gridRect.right, colCount, this.extentCell?.col ?? this.anchorCell.col);
616
606
 
617
607
  const clamped = { row, col };
618
608
 
@@ -621,4 +611,38 @@ export class TableCellSelection {
621
611
  this.paintSelection();
622
612
  }
623
613
  }
614
+
615
+ private collectCellsInRange(
616
+ rows: NodeListOf<Element>,
617
+ minRow: number,
618
+ maxRow: number,
619
+ minCol: number,
620
+ maxCol: number,
621
+ ): HTMLElement[] {
622
+ return Array.from(rows)
623
+ .slice(minRow, maxRow + 1)
624
+ .flatMap(row => {
625
+ const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
626
+
627
+ return Array.from(cells)
628
+ .slice(minCol, maxCol + 1)
629
+ .filter((cell): cell is HTMLElement => cell instanceof HTMLElement);
630
+ });
631
+ }
632
+
633
+ /**
634
+ * Clamp a pointer coordinate to an axis range, returning the edge index
635
+ * when outside or the fallback when inside.
636
+ */
637
+ private clampAxis(pointer: number, min: number, max: number, count: number, fallback: number): number {
638
+ if (pointer < min) {
639
+ return 0;
640
+ }
641
+
642
+ if (pointer > max) {
643
+ return count - 1;
644
+ }
645
+
646
+ return fallback;
647
+ }
624
648
  }
@@ -20,6 +20,7 @@ const CELL_CLASSES = [
20
20
  'outline-none',
21
21
  'leading-normal',
22
22
  'text-sm',
23
+ 'cursor-text',
23
24
  ];
24
25
 
25
26
  /**
@@ -131,7 +132,7 @@ export class TableGrid {
131
132
  * those widths and the new column is added in px mode. This prevents
132
133
  * existing columns from shrinking when the table is in percent mode.
133
134
  */
134
- public addColumn(table: HTMLElement, index?: number, colWidths?: number[]): boolean {
135
+ public addColumn(table: HTMLElement, index?: number, colWidths?: number[], newColWidth?: number): boolean {
135
136
  const rows = table.querySelectorAll(`[${ROW_ATTR}]`);
136
137
  const oldColCount = this.getColumnCount(table);
137
138
  const hasValidColWidths = colWidths !== undefined && colWidths.length === oldColCount;
@@ -142,7 +143,7 @@ export class TableGrid {
142
143
  }
143
144
 
144
145
  if (usePx) {
145
- this.addColumnPx(rows, oldColCount, index);
146
+ this.addColumnPx(rows, oldColCount, index, newColWidth);
146
147
 
147
148
  return true;
148
149
  }
@@ -170,24 +171,15 @@ export class TableGrid {
170
171
  }
171
172
 
172
173
  /**
173
- * Add column in px mode: keep existing widths, add new column at half the average width
174
+ * Add column in px mode: keep existing widths, add new column at given width or half the average
174
175
  */
175
- private addColumnPx(rows: NodeListOf<Element>, oldColCount: number, index?: number): void {
176
- const firstRow = rows[0];
177
- const firstRowCells = firstRow?.querySelectorAll(`[${CELL_ATTR}]`);
178
- const totalWidth = Array.from(firstRowCells ?? []).reduce(
179
- (sum, node) => sum + (parseFloat((node as HTMLElement).style.width) || 0),
180
- 0
181
- );
182
-
183
- const newColWidth = oldColCount > 0
184
- ? Math.round((totalWidth / oldColCount / 2) * 100) / 100
185
- : 0;
176
+ private addColumnPx(rows: NodeListOf<Element>, oldColCount: number, index?: number, newColWidth?: number): void {
177
+ const computedWidth = newColWidth ?? this.computeHalfAvgPxWidth(rows, oldColCount);
186
178
 
187
179
  rows.forEach(row => {
188
180
  const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
189
181
  const isAppend = index === undefined || index >= cells.length;
190
- const cell = this.createCell(`${newColWidth}px`);
182
+ const cell = this.createCell(`${computedWidth}px`);
191
183
 
192
184
  if (!isAppend) {
193
185
  row.insertBefore(cell, cells[index]);
@@ -199,6 +191,19 @@ export class TableGrid {
199
191
  });
200
192
  }
201
193
 
194
+ private computeHalfAvgPxWidth(rows: NodeListOf<Element>, oldColCount: number): number {
195
+ const firstRow = rows[0];
196
+ const firstRowCells = firstRow?.querySelectorAll(`[${CELL_ATTR}]`);
197
+ const totalWidth = Array.from(firstRowCells ?? []).reduce(
198
+ (sum, node) => sum + (parseFloat((node as HTMLElement).style.width) || 0),
199
+ 0
200
+ );
201
+
202
+ return oldColCount > 0
203
+ ? Math.round((totalWidth / oldColCount / 2) * 100) / 100
204
+ : 0;
205
+ }
206
+
202
207
  /**
203
208
  * Add column in % mode: shrink existing columns slightly and add new column at half the average width
204
209
  */
@@ -57,9 +57,9 @@ export const createGripDotsSvg = (orientation: 'horizontal' | 'vertical'): SVGEl
57
57
  */
58
58
  export const expandGrip = (grip: HTMLElement, type: 'col' | 'row'): void => {
59
59
  if (type === 'col') {
60
- grip.style.height = `${GRIP_HOVER_SIZE}px`;
60
+ Object.assign(grip.style, { height: `${GRIP_HOVER_SIZE}px` });
61
61
  } else {
62
- grip.style.width = `${GRIP_HOVER_SIZE}px`;
62
+ Object.assign(grip.style, { width: `${GRIP_HOVER_SIZE}px` });
63
63
  }
64
64
 
65
65
  grip.classList.add('bg-gray-200');
@@ -79,9 +79,9 @@ export const expandGrip = (grip: HTMLElement, type: 'col' | 'row'): void => {
79
79
  */
80
80
  export const collapseGrip = (grip: HTMLElement, type: 'col' | 'row', pillSize: number): void => {
81
81
  if (type === 'col') {
82
- grip.style.height = `${pillSize}px`;
82
+ Object.assign(grip.style, { height: `${pillSize}px` });
83
83
  } else {
84
- grip.style.width = `${pillSize}px`;
84
+ Object.assign(grip.style, { width: `${pillSize}px` });
85
85
  }
86
86
 
87
87
  grip.classList.remove('bg-gray-200');
@@ -168,14 +168,15 @@ export const computeInsertColumnWidths = (
168
168
  ): number[] => {
169
169
  const colWidths = data.colWidths ?? readPixelWidths(gridEl);
170
170
 
171
- grid.addColumn(gridEl, index, colWidths);
171
+ const halfWidth = data.initialColWidth !== undefined
172
+ ? Math.round((data.initialColWidth / 2) * 100) / 100
173
+ : computeHalfAvgWidth(colWidths);
174
+
175
+ grid.addColumn(gridEl, index, colWidths, halfWidth);
172
176
 
173
- const halfAvgWidth = Math.round(
174
- (colWidths.reduce((sum, w) => sum + w, 0) / colWidths.length / 2) * 100
175
- ) / 100;
176
177
  const newWidths = [...colWidths];
177
178
 
178
- newWidths.splice(index, 0, halfAvgWidth);
179
+ newWidths.splice(index, 0, halfWidth);
179
180
 
180
181
  return newWidths;
181
182
  };
@@ -185,6 +186,14 @@ export const computeHalfAvgWidth = (colWidths: number[]): number =>
185
186
  (colWidths.reduce((sum, w) => sum + w, 0) / colWidths.length / 2) * 100
186
187
  ) / 100;
187
188
 
189
+ export const computeInitialColWidth = (colWidths: number[]): number => {
190
+ if (colWidths.length === 0) {
191
+ return 0;
192
+ }
193
+
194
+ return Math.round((colWidths.reduce((sum, w) => sum + w, 0) / colWidths.length) * 100) / 100;
195
+ };
196
+
188
197
  // ─── Block IDs from cells ───────────────────────────────────────────
189
198
 
190
199
  export const getBlockIdsInRow = (element: HTMLElement | null, cellBlocks: TableCellBlocks | null, rowIndex: number): string[] => {
@@ -309,15 +318,15 @@ export const mountCellBlocksReadOnly = (
309
318
  return;
310
319
  }
311
320
 
312
- if (!isCellWithBlocks(cellContent)) {
313
- // Handle legacy string content by creating a paragraph block
314
- // Check if container already has blocks to ensure idempotency
315
- const existingBlocks = container.querySelectorAll('[data-blok-id]');
321
+ // Skip legacy cells that already have blocks (idempotency guard)
322
+ const hasExistingBlocks = container.querySelectorAll('[data-blok-id]').length > 0;
316
323
 
317
- if (existingBlocks.length > 0) {
318
- return;
319
- }
324
+ if (!isCellWithBlocks(cellContent) && hasExistingBlocks) {
325
+ return;
326
+ }
320
327
 
328
+ if (!isCellWithBlocks(cellContent)) {
329
+ // Handle legacy string content by creating a paragraph block
321
330
  const legacyText = typeof cellContent === 'string' ? cellContent : '';
322
331
  const insertedBlock = api.blocks.insert(
323
332
  'paragraph',
@@ -379,6 +388,7 @@ export const normalizeTableData = (
379
388
  stretched: tableData.stretched ?? config.stretched ?? false,
380
389
  content: tableData.content ?? [],
381
390
  colWidths: validWidths,
391
+ initialColWidth: tableData.initialColWidth,
382
392
  };
383
393
  };
384
394
 
@@ -0,0 +1,64 @@
1
+ import type { API } from '../../../types';
2
+ import type { Block } from '../../components/block';
3
+
4
+ /**
5
+ * List of block tools that are restricted from being inserted into table cells.
6
+ * These tools create semantic or structural issues when nested in table cells.
7
+ */
8
+ export const RESTRICTED_TOOLS = ['header', 'table'];
9
+
10
+ /**
11
+ * Check if a block or element is inside a table cell.
12
+ * Uses the data-blok-table-cell-blocks attribute to detect cell containers.
13
+ *
14
+ * @param block - Block instance or HTMLElement to check
15
+ * @returns true if inside a table cell, false otherwise
16
+ */
17
+ export const isInsideTableCell = (block: Block | HTMLElement | null | undefined): boolean => {
18
+ if (!block) {
19
+ return false;
20
+ }
21
+
22
+ const element = block instanceof HTMLElement ? block : block.holder;
23
+
24
+ return element.closest('[data-blok-table-cell-blocks]') !== null;
25
+ };
26
+
27
+ /**
28
+ * Check if a tool name is restricted inside table cells.
29
+ *
30
+ * @param toolName - Name of the block tool to check
31
+ * @returns true if the tool is restricted in table cells, false otherwise
32
+ */
33
+ export const isRestrictedInTableCell = (toolName: string): boolean => {
34
+ return RESTRICTED_TOOLS.includes(toolName);
35
+ };
36
+
37
+ /**
38
+ * Convert a restricted block to a paragraph block, preserving text content.
39
+ * Replaces the original block in place.
40
+ *
41
+ * @param block - The block to convert
42
+ * @param api - Blok API instance
43
+ * @returns The newly created paragraph block
44
+ * @throws Error if block index cannot be found
45
+ */
46
+ export const convertToParagraph = (block: Block, api: API): Block => {
47
+ const text = block.holder.textContent || '';
48
+ const blockIndex = api.blocks.getBlockIndex(block.id);
49
+
50
+ if (blockIndex === undefined) {
51
+ throw new Error('Block index not found');
52
+ }
53
+
54
+ // Replace with paragraph, preserving text
55
+ return api.blocks.insert(
56
+ 'paragraph',
57
+ { text },
58
+ {},
59
+ blockIndex,
60
+ false, // don't focus
61
+ true, // replace existing
62
+ block.id
63
+ ) as unknown as Block;
64
+ };
@@ -0,0 +1,190 @@
1
+ import type { TableCellBlocks } from './table-cell-blocks';
2
+ import type { TableGrid } from './table-core';
3
+ import {
4
+ applyPixelWidths,
5
+ computeInsertColumnWidths,
6
+ deleteColumnWithBlockCleanup,
7
+ deleteRowWithBlockCleanup,
8
+ populateNewCells,
9
+ redistributePercentWidths,
10
+ syncColWidthsAfterMove,
11
+ } from './table-operations';
12
+ import type { RowColAction } from './table-row-col-controls';
13
+ import type { TableData } from './types';
14
+
15
+ /**
16
+ * Describes which row or column to highlight after an action completes.
17
+ */
18
+ export type PendingHighlight = { type: 'row' | 'col'; index: number };
19
+
20
+ interface ActionContext {
21
+ grid: TableGrid;
22
+ data: TableData;
23
+ cellBlocks: TableCellBlocks | null;
24
+ }
25
+
26
+ interface ActionResult {
27
+ pendingHighlight: PendingHighlight | null;
28
+ moveSelection: { type: 'row' | 'col'; index: number } | null;
29
+ colWidths: number[] | undefined;
30
+ withHeadings: boolean;
31
+ withHeadingColumn: boolean;
32
+ }
33
+
34
+ const handleInsertRow = (
35
+ gridEl: HTMLElement,
36
+ index: number,
37
+ ctx: ActionContext,
38
+ ): ActionResult => {
39
+ ctx.grid.addRow(gridEl, index);
40
+ populateNewCells(gridEl, ctx.cellBlocks);
41
+
42
+ return {
43
+ pendingHighlight: { type: 'row', index },
44
+ moveSelection: null,
45
+ colWidths: ctx.data.colWidths,
46
+ withHeadings: ctx.data.withHeadings,
47
+ withHeadingColumn: ctx.data.withHeadingColumn,
48
+ };
49
+ };
50
+
51
+ const handleInsertCol = (
52
+ gridEl: HTMLElement,
53
+ index: number,
54
+ ctx: ActionContext,
55
+ ): ActionResult => {
56
+ const colWidths = computeInsertColumnWidths(gridEl, index, ctx.data, ctx.grid);
57
+
58
+ populateNewCells(gridEl, ctx.cellBlocks);
59
+
60
+ return {
61
+ pendingHighlight: { type: 'col', index },
62
+ moveSelection: null,
63
+ colWidths,
64
+ withHeadings: ctx.data.withHeadings,
65
+ withHeadingColumn: ctx.data.withHeadingColumn,
66
+ };
67
+ };
68
+
69
+ const handleMoveRow = (
70
+ gridEl: HTMLElement,
71
+ fromIndex: number,
72
+ toIndex: number,
73
+ ctx: ActionContext,
74
+ ): ActionResult => {
75
+ ctx.grid.moveRow(gridEl, fromIndex, toIndex);
76
+
77
+ return {
78
+ pendingHighlight: null,
79
+ moveSelection: { type: 'row', index: toIndex },
80
+ colWidths: ctx.data.colWidths,
81
+ withHeadings: ctx.data.withHeadings,
82
+ withHeadingColumn: ctx.data.withHeadingColumn,
83
+ };
84
+ };
85
+
86
+ const handleMoveCol = (
87
+ gridEl: HTMLElement,
88
+ fromIndex: number,
89
+ toIndex: number,
90
+ ctx: ActionContext,
91
+ ): ActionResult => {
92
+ ctx.grid.moveColumn(gridEl, fromIndex, toIndex);
93
+
94
+ return {
95
+ pendingHighlight: null,
96
+ moveSelection: { type: 'col', index: toIndex },
97
+ colWidths: syncColWidthsAfterMove(ctx.data.colWidths, fromIndex, toIndex),
98
+ withHeadings: ctx.data.withHeadings,
99
+ withHeadingColumn: ctx.data.withHeadingColumn,
100
+ };
101
+ };
102
+
103
+ const handleDeleteRow = (
104
+ gridEl: HTMLElement,
105
+ index: number,
106
+ ctx: ActionContext,
107
+ ): ActionResult => {
108
+ deleteRowWithBlockCleanup(gridEl, index, ctx.grid, ctx.cellBlocks);
109
+ const newRowCount = ctx.grid.getRowCount(gridEl);
110
+ const neighborRow = index < newRowCount ? index : index - 1;
111
+
112
+ return {
113
+ pendingHighlight: { type: 'row', index: neighborRow },
114
+ moveSelection: null,
115
+ colWidths: ctx.data.colWidths,
116
+ withHeadings: ctx.data.withHeadings,
117
+ withHeadingColumn: ctx.data.withHeadingColumn,
118
+ };
119
+ };
120
+
121
+ const handleDeleteCol = (
122
+ gridEl: HTMLElement,
123
+ index: number,
124
+ ctx: ActionContext,
125
+ ): ActionResult => {
126
+ const colWidths = deleteColumnWithBlockCleanup(gridEl, index, ctx.data.colWidths, ctx.grid, ctx.cellBlocks);
127
+
128
+ if (colWidths) {
129
+ applyPixelWidths(gridEl, colWidths);
130
+ } else {
131
+ redistributePercentWidths(gridEl);
132
+ }
133
+
134
+ const newColCount = ctx.grid.getColumnCount(gridEl);
135
+ const neighborCol = index < newColCount ? index : index - 1;
136
+
137
+ return {
138
+ pendingHighlight: { type: 'col', index: neighborCol },
139
+ moveSelection: null,
140
+ colWidths,
141
+ withHeadings: ctx.data.withHeadings,
142
+ withHeadingColumn: ctx.data.withHeadingColumn,
143
+ };
144
+ };
145
+
146
+ /**
147
+ * Execute a row/column action on the table grid.
148
+ * Returns the updated colWidths, withHeadings, withHeadingColumn values
149
+ * along with pendingHighlight and moveSelection for the caller to apply.
150
+ */
151
+ export const executeRowColAction = (
152
+ gridEl: HTMLElement,
153
+ action: RowColAction,
154
+ ctx: ActionContext,
155
+ ): ActionResult => {
156
+ switch (action.type) {
157
+ case 'insert-row-above':
158
+ return handleInsertRow(gridEl, action.index, ctx);
159
+ case 'insert-row-below':
160
+ return handleInsertRow(gridEl, action.index + 1, ctx);
161
+ case 'insert-col-left':
162
+ return handleInsertCol(gridEl, action.index, ctx);
163
+ case 'insert-col-right':
164
+ return handleInsertCol(gridEl, action.index + 1, ctx);
165
+ case 'move-row':
166
+ return handleMoveRow(gridEl, action.fromIndex, action.toIndex, ctx);
167
+ case 'move-col':
168
+ return handleMoveCol(gridEl, action.fromIndex, action.toIndex, ctx);
169
+ case 'delete-row':
170
+ return handleDeleteRow(gridEl, action.index, ctx);
171
+ case 'delete-col':
172
+ return handleDeleteCol(gridEl, action.index, ctx);
173
+ case 'toggle-heading':
174
+ return {
175
+ pendingHighlight: { type: 'row', index: 0 },
176
+ moveSelection: null,
177
+ colWidths: ctx.data.colWidths,
178
+ withHeadings: !ctx.data.withHeadings,
179
+ withHeadingColumn: ctx.data.withHeadingColumn,
180
+ };
181
+ case 'toggle-heading-column':
182
+ return {
183
+ pendingHighlight: { type: 'col', index: 0 },
184
+ moveSelection: null,
185
+ colWidths: ctx.data.colWidths,
186
+ withHeadings: ctx.data.withHeadings,
187
+ withHeadingColumn: !ctx.data.withHeadingColumn,
188
+ };
189
+ }
190
+ };