@jackuait/blok 0.6.0-beta.0 → 0.6.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) 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-Bu9S3SsR.mjs → blok-Buf0btS7.mjs} +2267 -2024
  5. package/dist/chunks/{i18next-loader-CKuXJ0Av.mjs → i18next-loader-CVf_ZfwA.mjs} +1 -1
  6. package/dist/chunks/{index-jtZaryNw.mjs → index-C6jsfLLp.mjs} +1 -1
  7. package/dist/chunks/{inline-tool-convert-CFjyrH30.mjs → inline-tool-convert-BKKEoOqB.mjs} +710 -570
  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 +2005 -1267
  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/block-tunes/block-tune-delete.ts +3 -2
  153. package/src/components/blocks.ts +23 -6
  154. package/src/components/constants/data-attributes.ts +2 -0
  155. package/src/components/i18n/locales/am/messages.json +15 -1
  156. package/src/components/i18n/locales/ar/messages.json +14 -0
  157. package/src/components/i18n/locales/az/messages.json +14 -0
  158. package/src/components/i18n/locales/bg/messages.json +14 -0
  159. package/src/components/i18n/locales/bn/messages.json +25 -11
  160. package/src/components/i18n/locales/bs/messages.json +15 -1
  161. package/src/components/i18n/locales/cs/messages.json +14 -0
  162. package/src/components/i18n/locales/da/messages.json +14 -0
  163. package/src/components/i18n/locales/de/messages.json +14 -0
  164. package/src/components/i18n/locales/dv/messages.json +15 -1
  165. package/src/components/i18n/locales/el/messages.json +15 -1
  166. package/src/components/i18n/locales/en/messages.json +14 -0
  167. package/src/components/i18n/locales/es/messages.json +14 -0
  168. package/src/components/i18n/locales/et/messages.json +14 -0
  169. package/src/components/i18n/locales/fa/messages.json +15 -1
  170. package/src/components/i18n/locales/fi/messages.json +15 -1
  171. package/src/components/i18n/locales/fil/messages.json +20 -6
  172. package/src/components/i18n/locales/fr/messages.json +15 -1
  173. package/src/components/i18n/locales/gu/messages.json +15 -1
  174. package/src/components/i18n/locales/he/messages.json +14 -0
  175. package/src/components/i18n/locales/hi/messages.json +23 -9
  176. package/src/components/i18n/locales/hr/messages.json +14 -0
  177. package/src/components/i18n/locales/hu/messages.json +14 -0
  178. package/src/components/i18n/locales/hy/messages.json +16 -2
  179. package/src/components/i18n/locales/id/messages.json +19 -5
  180. package/src/components/i18n/locales/it/messages.json +14 -0
  181. package/src/components/i18n/locales/ja/messages.json +14 -0
  182. package/src/components/i18n/locales/ka/messages.json +15 -1
  183. package/src/components/i18n/locales/km/messages.json +16 -2
  184. package/src/components/i18n/locales/kn/messages.json +16 -2
  185. package/src/components/i18n/locales/ko/messages.json +14 -0
  186. package/src/components/i18n/locales/ku/messages.json +16 -2
  187. package/src/components/i18n/locales/lo/messages.json +15 -1
  188. package/src/components/i18n/locales/lt/messages.json +15 -1
  189. package/src/components/i18n/locales/lv/messages.json +15 -1
  190. package/src/components/i18n/locales/mk/messages.json +16 -2
  191. package/src/components/i18n/locales/ml/messages.json +16 -2
  192. package/src/components/i18n/locales/mn/messages.json +16 -2
  193. package/src/components/i18n/locales/mr/messages.json +24 -10
  194. package/src/components/i18n/locales/ms/messages.json +17 -3
  195. package/src/components/i18n/locales/my/messages.json +16 -2
  196. package/src/components/i18n/locales/ne/messages.json +24 -10
  197. package/src/components/i18n/locales/nl/messages.json +15 -1
  198. package/src/components/i18n/locales/no/messages.json +16 -2
  199. package/src/components/i18n/locales/pa/messages.json +15 -1
  200. package/src/components/i18n/locales/pl/messages.json +14 -0
  201. package/src/components/i18n/locales/ps/messages.json +17 -3
  202. package/src/components/i18n/locales/pt/messages.json +14 -0
  203. package/src/components/i18n/locales/ro/messages.json +15 -1
  204. package/src/components/i18n/locales/ru/messages.json +14 -0
  205. package/src/components/i18n/locales/sd/messages.json +16 -2
  206. package/src/components/i18n/locales/si/messages.json +23 -9
  207. package/src/components/i18n/locales/sk/messages.json +15 -1
  208. package/src/components/i18n/locales/sl/messages.json +16 -2
  209. package/src/components/i18n/locales/sq/messages.json +16 -2
  210. package/src/components/i18n/locales/sr/messages.json +16 -2
  211. package/src/components/i18n/locales/sv/messages.json +16 -2
  212. package/src/components/i18n/locales/sw/messages.json +16 -2
  213. package/src/components/i18n/locales/ta/messages.json +21 -7
  214. package/src/components/i18n/locales/te/messages.json +40 -26
  215. package/src/components/i18n/locales/th/messages.json +19 -5
  216. package/src/components/i18n/locales/tr/messages.json +15 -1
  217. package/src/components/i18n/locales/ug/messages.json +16 -2
  218. package/src/components/i18n/locales/uk/messages.json +15 -1
  219. package/src/components/i18n/locales/ur/messages.json +15 -1
  220. package/src/components/i18n/locales/vi/messages.json +25 -11
  221. package/src/components/i18n/locales/yi/messages.json +16 -2
  222. package/src/components/i18n/locales/zh/messages.json +15 -1
  223. package/src/components/icons/index.ts +104 -83
  224. package/src/components/modules/api/blocks.ts +35 -2
  225. package/src/components/modules/api/history.ts +64 -0
  226. package/src/components/modules/api/index.ts +2 -0
  227. package/src/components/modules/api/readonly.ts +11 -1
  228. package/src/components/modules/blockEvents/composers/markdownShortcuts.ts +12 -1
  229. package/src/components/modules/blockManager/blockManager.ts +7 -0
  230. package/src/components/modules/blockManager/operations.ts +3 -2
  231. package/src/components/modules/blockManager/types.ts +3 -1
  232. package/src/components/modules/blockManager/yjs-sync.ts +12 -2
  233. package/src/components/modules/index.ts +3 -0
  234. package/src/components/modules/normalizeInlineImages.ts +263 -0
  235. package/src/components/modules/readonly.ts +11 -0
  236. package/src/components/modules/rectangleSelection.ts +19 -3
  237. package/src/components/modules/saver.ts +7 -3
  238. package/src/components/modules/toolbar/blockSettings.ts +3 -3
  239. package/src/components/modules/toolbar/index.ts +72 -14
  240. package/src/components/modules/toolbar/plus-button.ts +24 -3
  241. package/src/components/modules/toolbar/settings-toggler.ts +3 -5
  242. package/src/components/modules/ui.ts +46 -68
  243. package/src/components/modules/uiControllers/controllers/blockHover.ts +49 -61
  244. package/src/components/modules/uiControllers/controllers/keyboard.ts +17 -11
  245. package/src/components/modules/uiControllers/handlers/click.ts +0 -12
  246. package/src/components/modules/yjs/index.ts +23 -0
  247. package/src/components/ui/toolbox.ts +41 -6
  248. package/src/components/utils/placeholder.ts +16 -0
  249. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +2 -1
  250. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +6 -1
  251. package/src/components/utils/popover/index.ts +1 -0
  252. package/src/components/utils/popover/popover-abstract.ts +11 -1
  253. package/src/components/utils/popover/popover-desktop.ts +27 -8
  254. package/src/components/utils/popover/popover-registry.ts +188 -0
  255. package/src/components/utils/sanitizer.ts +23 -2
  256. package/src/components/utils/tooltip.ts +2 -24
  257. package/src/styles/main.css +22 -0
  258. package/src/tools/paragraph/index.ts +12 -4
  259. package/src/tools/table/data-normalizer.ts +1 -0
  260. package/src/tools/table/index.ts +283 -346
  261. package/src/tools/table/table-add-controls.ts +353 -47
  262. package/src/tools/table/table-cell-blocks.ts +95 -7
  263. package/src/tools/table/table-cell-selection.ts +648 -0
  264. package/src/tools/table/table-core.ts +21 -32
  265. package/src/tools/table/table-grip-visuals.ts +96 -0
  266. package/src/tools/table/table-heading-toggle.ts +127 -0
  267. package/src/tools/table/table-operations.ts +475 -0
  268. package/src/tools/table/table-resize.ts +27 -6
  269. package/src/tools/table/table-restrictions.ts +64 -0
  270. package/src/tools/table/table-row-col-action-handler.ts +190 -0
  271. package/src/tools/table/table-row-col-controls.ts +265 -211
  272. package/src/tools/table/table-row-col-drag.ts +4 -4
  273. package/src/tools/table/table-row-col-popover.ts +225 -0
  274. package/src/tools/table/types.ts +4 -0
  275. package/src/types-internal/blok-modules.d.ts +2 -0
  276. package/types/api/blocks.d.ts +8 -0
  277. package/types/api/history.d.ts +33 -0
  278. package/types/api/index.d.ts +1 -0
  279. package/types/api/readonly.d.ts +12 -2
  280. package/types/index.d.ts +10 -0
  281. package/types/tools/table.d.ts +67 -0
  282. package/types/tools-entry.d.ts +4 -0
  283. package/types/utils/popover/popover-item.d.ts +6 -0
  284. package/types/utils/popover/popover.d.ts +7 -0
  285. package/dist/chunks/messages-CySyfkMU.mjs +0 -48
  286. package/dist/messages-CySyfkMU.mjs +0 -48
@@ -1,25 +1,17 @@
1
- import {
2
- IconInsertAbove,
3
- IconInsertBelow,
4
- IconInsertLeft,
5
- IconInsertRight,
6
- IconTrash,
7
- IconHeading,
8
- } from '../../components/icons';
9
- import { PopoverDesktop, PopoverItemType } from '../../components/utils/popover';
1
+ import type { I18n } from '../../../types/api';
10
2
  import { twMerge } from '../../components/utils/tw';
11
3
 
12
- import { CELL_ATTR, ROW_ATTR } from './table-core';
4
+ import { BORDER_WIDTH, CELL_ATTR, ROW_ATTR } from './table-core';
5
+ import { collapseGrip, createGripDotsSvg, expandGrip, GRIP_HOVER_SIZE } from './table-grip-visuals';
13
6
  import { getCumulativeColEdges, TableRowColDrag } from './table-row-col-drag';
14
-
15
- import { PopoverEvent } from '@/types/utils/popover/popover-event';
16
- 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';
17
9
 
18
10
  const GRIP_ATTR = 'data-blok-table-grip';
19
11
  const GRIP_COL_ATTR = 'data-blok-table-grip-col';
20
12
  const GRIP_ROW_ATTR = 'data-blok-table-grip-row';
21
13
  const HIDE_DELAY_MS = 150;
22
- const COL_PILL_WIDTH = 32;
14
+ const COL_PILL_WIDTH = 24;
23
15
  const COL_PILL_HEIGHT = 4;
24
16
  const ROW_PILL_WIDTH = 4;
25
17
  const ROW_PILL_HEIGHT = 20;
@@ -36,25 +28,35 @@ export type RowColAction =
36
28
  | { type: 'move-col'; fromIndex: number; toIndex: number }
37
29
  | { type: 'delete-row'; index: number }
38
30
  | { type: 'delete-col'; index: number }
39
- | { type: 'toggle-heading' };
31
+ | { type: 'toggle-heading' }
32
+ | { type: 'toggle-heading-column' };
40
33
 
41
34
  export interface TableRowColControlsOptions {
42
35
  grid: HTMLElement;
43
36
  getColumnCount: () => number;
44
37
  getRowCount: () => number;
45
38
  isHeadingRow: () => boolean;
39
+ isHeadingColumn: () => boolean;
46
40
  onAction: (action: RowColAction) => void;
47
41
  onDragStateChange?: (isDragging: boolean, dragType: 'row' | 'col' | null) => void;
42
+ onGripClick?: (type: 'row' | 'col', index: number) => void;
43
+ onGripPopoverClose?: () => void;
44
+ i18n: I18n;
48
45
  }
49
46
 
50
47
  const GRIP_CAPSULE_CLASSES = [
51
48
  'absolute',
52
49
  'z-[3]',
53
- 'rounded-full',
50
+ 'rounded',
54
51
  'cursor-grab',
55
52
  'select-none',
56
- 'transition-[opacity,background-color]',
53
+ 'transition-[opacity,background-color,width,height]',
57
54
  'duration-150',
55
+ 'group',
56
+ 'flex',
57
+ 'items-center',
58
+ 'justify-center',
59
+ 'overflow-hidden',
58
60
  ];
59
61
 
60
62
  const GRIP_IDLE_CLASSES = [
@@ -65,7 +67,13 @@ const GRIP_IDLE_CLASSES = [
65
67
 
66
68
  const GRIP_VISIBLE_CLASSES = [
67
69
  'bg-gray-300',
68
- 'hover:bg-gray-400',
70
+ 'opacity-100',
71
+ 'pointer-events-auto',
72
+ ];
73
+
74
+ const GRIP_ACTIVE_CLASSES = [
75
+ 'bg-blue-500',
76
+ 'text-white',
69
77
  'opacity-100',
70
78
  'pointer-events-auto',
71
79
  ];
@@ -78,28 +86,39 @@ export class TableRowColControls {
78
86
  private getColumnCount: () => number;
79
87
  private getRowCount: () => number;
80
88
  private isHeadingRow: () => boolean;
89
+ private isHeadingColumn: () => boolean;
81
90
  private onAction: (action: RowColAction) => void;
91
+ private onGripClick: ((type: 'row' | 'col', index: number) => void) | undefined;
92
+ private onGripPopoverClose: (() => void) | undefined;
93
+ private i18n: I18n;
82
94
 
83
95
  private colGrips: HTMLElement[] = [];
84
96
  private rowGrips: HTMLElement[] = [];
85
- private activePopover: PopoverDesktop | null = null;
97
+ private popoverState: PopoverState = { popover: null, grip: null };
98
+ private lockedGrip: HTMLElement | null = null;
99
+ private boundUnlockGrip: (e: PointerEvent) => void;
86
100
  private hideTimeout: ReturnType<typeof setTimeout> | null = null;
87
101
  private activeColGripIndex = -1;
88
102
  private activeRowGripIndex = -1;
103
+ private isInsideTable = false;
104
+ private rowResizeObserver: ResizeObserver | null = null;
89
105
 
90
106
  private drag: TableRowColDrag;
91
107
 
92
- private boundFocusIn: (e: FocusEvent) => void;
93
- private boundFocusOut: (e: FocusEvent) => void;
108
+ private boundMouseOver: (e: MouseEvent) => void;
109
+ private boundMouseLeave: (e: MouseEvent) => void;
94
110
  private boundPointerDown: (e: PointerEvent) => void;
95
- private boundDocPointerDown: ((e: PointerEvent) => void) | null = null;
96
111
 
97
112
  constructor(options: TableRowColControlsOptions) {
98
113
  this.grid = options.grid;
99
114
  this.getColumnCount = options.getColumnCount;
100
115
  this.getRowCount = options.getRowCount;
101
116
  this.isHeadingRow = options.isHeadingRow;
117
+ this.isHeadingColumn = options.isHeadingColumn;
102
118
  this.onAction = options.onAction;
119
+ this.onGripClick = options.onGripClick;
120
+ this.onGripPopoverClose = options.onGripPopoverClose;
121
+ this.i18n = options.i18n;
103
122
 
104
123
  this.drag = new TableRowColDrag({
105
124
  grid: this.grid,
@@ -110,14 +129,15 @@ export class TableRowColControls {
110
129
  },
111
130
  });
112
131
 
113
- this.boundFocusIn = this.handleFocusIn.bind(this);
114
- this.boundFocusOut = this.handleFocusOut.bind(this);
132
+ this.boundMouseOver = this.handleMouseOver.bind(this);
133
+ this.boundMouseLeave = this.handleMouseLeave.bind(this);
115
134
  this.boundPointerDown = this.handlePointerDown.bind(this);
135
+ this.boundUnlockGrip = this.handleUnlockGrip.bind(this);
116
136
 
117
137
  this.createGrips();
118
138
 
119
- this.grid.addEventListener('focusin', this.boundFocusIn);
120
- this.grid.addEventListener('focusout', this.boundFocusOut);
139
+ this.grid.addEventListener('mouseover', this.boundMouseOver);
140
+ this.grid.addEventListener('mouseleave', this.boundMouseLeave);
121
141
  }
122
142
 
123
143
  /**
@@ -126,14 +146,57 @@ export class TableRowColControls {
126
146
  public refresh(): void {
127
147
  this.destroyGrips();
128
148
  this.createGrips();
129
- this.showGripsForFocusedCell();
149
+ }
150
+
151
+ /**
152
+ * Set a specific grip to active (blue) state without opening the popover.
153
+ * Hides all other grips.
154
+ */
155
+ public setActiveGrip(type: 'row' | 'col', index: number): void {
156
+ const grip = type === 'col'
157
+ ? this.colGrips[index]
158
+ : this.rowGrips[index];
159
+
160
+ if (!grip) {
161
+ return;
162
+ }
163
+
164
+ this.unlockGrip();
165
+ this.clearHideTimeout();
166
+ this.hideAllGripsExcept(grip);
167
+ this.applyActiveClasses(grip);
168
+
169
+ if (type === 'col') {
170
+ grip.style.height = `${GRIP_HOVER_SIZE}px`;
171
+ } else {
172
+ grip.style.width = `${GRIP_HOVER_SIZE}px`;
173
+ }
174
+
175
+ this.lockedGrip = grip;
176
+
177
+ document.addEventListener('pointerdown', this.boundUnlockGrip);
178
+ }
179
+
180
+ private handleUnlockGrip(): void {
181
+ document.removeEventListener('pointerdown', this.boundUnlockGrip);
182
+
183
+ if (this.lockedGrip) {
184
+ this.applyIdleClasses(this.lockedGrip);
185
+ this.lockedGrip = null;
186
+ }
187
+ }
188
+
189
+ private unlockGrip(): void {
190
+ document.removeEventListener('pointerdown', this.boundUnlockGrip);
191
+ this.lockedGrip = null;
130
192
  }
131
193
 
132
194
  public destroy(): void {
133
195
  this.destroyPopover();
196
+ this.unlockGrip();
134
197
  this.drag.cleanup();
135
- this.grid.removeEventListener('focusin', this.boundFocusIn);
136
- this.grid.removeEventListener('focusout', this.boundFocusOut);
198
+ this.grid.removeEventListener('mouseover', this.boundMouseOver);
199
+ this.grid.removeEventListener('mouseleave', this.boundMouseLeave);
137
200
  this.clearHideTimeout();
138
201
  this.destroyGrips();
139
202
  }
@@ -157,15 +220,19 @@ export class TableRowColControls {
157
220
  });
158
221
 
159
222
  this.positionGrips();
223
+ this.observeRowHeights();
160
224
  }
161
225
 
162
226
  private destroyGrips(): void {
227
+ this.rowResizeObserver?.disconnect();
228
+ this.rowResizeObserver = null;
163
229
  this.colGrips.forEach(g => g.remove());
164
230
  this.rowGrips.forEach(g => g.remove());
165
231
  this.colGrips = [];
166
232
  this.rowGrips = [];
167
233
  this.activeColGripIndex = -1;
168
234
  this.activeRowGripIndex = -1;
235
+ this.isInsideTable = false;
169
236
  }
170
237
 
171
238
  private createGripElement(type: 'row' | 'col', index: number): HTMLElement {
@@ -176,23 +243,37 @@ export class TableRowColControls {
176
243
  grip.setAttribute(type === 'col' ? GRIP_COL_ATTR : GRIP_ROW_ATTR, String(index));
177
244
  grip.setAttribute('contenteditable', 'false');
178
245
 
179
- if (type === 'col') {
180
- grip.style.width = `${COL_PILL_WIDTH}px`;
181
- grip.style.height = `${COL_PILL_HEIGHT}px`;
182
- } else {
183
- grip.style.width = `${ROW_PILL_WIDTH}px`;
184
- grip.style.height = `${ROW_PILL_HEIGHT}px`;
185
- }
246
+ const idleWidth = type === 'col' ? COL_PILL_WIDTH : ROW_PILL_WIDTH;
247
+ const idleHeight = type === 'col' ? COL_PILL_HEIGHT : ROW_PILL_HEIGHT;
248
+ const pillSize = type === 'col' ? COL_PILL_HEIGHT : ROW_PILL_WIDTH;
249
+
250
+ grip.style.width = `${idleWidth}px`;
251
+ grip.style.height = `${idleHeight}px`;
252
+ grip.style.transform = 'translate(-50%, -50%)';
253
+ grip.style.outline = '2px solid white';
254
+
255
+ grip.appendChild(createGripDotsSvg(type === 'col' ? 'horizontal' : 'vertical'));
186
256
 
187
257
  grip.addEventListener('pointerdown', this.boundPointerDown);
258
+ grip.addEventListener('mouseenter', () => {
259
+ if (!this.isGripInteractionLocked()) {
260
+ expandGrip(grip, type);
261
+ }
262
+ });
263
+ grip.addEventListener('mouseleave', () => {
264
+ if (!this.isGripInteractionLocked()) {
265
+ collapseGrip(grip, type, pillSize);
266
+ }
267
+ });
188
268
 
189
269
  return grip;
190
270
  }
191
271
 
192
272
  /**
193
- * Position grips relative to their row/column
273
+ * Reposition grips to match current row/column layout.
274
+ * Called after resize or structural changes.
194
275
  */
195
- private positionGrips(): void {
276
+ public positionGrips(): void {
196
277
  const rows = this.grid.querySelectorAll(`[${ROW_ATTR}]`);
197
278
  const firstRow = rows[0];
198
279
 
@@ -210,8 +291,8 @@ export class TableRowColControls {
210
291
  const centerX = (edges[i] + edges[i + 1]) / 2;
211
292
  const style = grip.style;
212
293
 
213
- style.top = `${-(COL_PILL_HEIGHT / 2)}px`;
214
- style.left = `${centerX - COL_PILL_WIDTH / 2}px`;
294
+ style.top = `${-BORDER_WIDTH / 2}px`;
295
+ style.left = `${centerX}px`;
215
296
  });
216
297
 
217
298
  this.rowGrips.forEach((grip, i) => {
@@ -223,12 +304,37 @@ export class TableRowColControls {
223
304
  const centerY = rowEl.offsetTop + rowEl.offsetHeight / 2;
224
305
  const style = grip.style;
225
306
 
226
- style.left = `${-(ROW_PILL_WIDTH / 2)}px`;
227
- style.top = `${centerY - ROW_PILL_HEIGHT / 2}px`;
307
+ style.left = `${-BORDER_WIDTH / 2}px`;
308
+ style.top = `${centerY}px`;
309
+ });
310
+ }
311
+
312
+ /**
313
+ * Set up ResizeObserver to watch for row height changes and reposition grips.
314
+ */
315
+ private observeRowHeights(): void {
316
+ this.rowResizeObserver?.disconnect();
317
+
318
+ this.rowResizeObserver = new ResizeObserver(() => {
319
+ this.positionGrips();
320
+ });
321
+
322
+ const rows = this.grid.querySelectorAll(`[${ROW_ATTR}]`);
323
+
324
+ rows.forEach(row => {
325
+ this.rowResizeObserver?.observe(row as HTMLElement);
228
326
  });
229
327
  }
230
328
 
231
- private handleFocusIn(e: FocusEvent): void {
329
+ private isGripInteractionLocked(): boolean {
330
+ return this.popoverState.popover !== null || this.lockedGrip !== null;
331
+ }
332
+
333
+ private handleMouseOver(e: MouseEvent): void {
334
+ if (this.isGripInteractionLocked()) {
335
+ return;
336
+ }
337
+
232
338
  const target = e.target as HTMLElement;
233
339
  const cell = target.closest<HTMLElement>(`[${CELL_ATTR}]`);
234
340
 
@@ -246,10 +352,11 @@ export class TableRowColControls {
246
352
 
247
353
  this.showColGrip(position.col);
248
354
  this.showRowGrip(position.row);
355
+ this.isInsideTable = true;
249
356
  }
250
357
 
251
- private handleFocusOut(_e: FocusEvent): void {
252
- if (this.activePopover !== null) {
358
+ private handleMouseLeave(): void {
359
+ if (this.isGripInteractionLocked()) {
253
360
  return;
254
361
  }
255
362
 
@@ -280,21 +387,34 @@ export class TableRowColControls {
280
387
  return { row: rowIndex, col: colIndex };
281
388
  }
282
389
 
283
- private showGripsForFocusedCell(): void {
284
- const focused = this.grid.querySelector<HTMLElement>(`[${CELL_ATTR}]:focus`);
390
+ /**
391
+ * Show or hide all grip elements by toggling display.
392
+ * Used to hide grips during add-button drag operations.
393
+ * Preserves visibility of the grip with an active popover.
394
+ */
395
+ public setGripsDisplay(visible: boolean): void {
396
+ const display = visible ? '' : 'none';
285
397
 
286
- if (!focused) {
287
- return;
288
- }
398
+ [...this.colGrips, ...this.rowGrips].forEach(grip => {
399
+ const el: HTMLElement = grip;
289
400
 
290
- const position = this.getCellPosition(focused);
401
+ // Don't hide the grip that has an active popover
402
+ if (!visible && grip === this.popoverState.grip) {
403
+ return;
404
+ }
291
405
 
292
- if (!position) {
293
- return;
294
- }
406
+ el.style.display = display;
407
+ });
408
+ }
295
409
 
296
- this.showColGrip(position.col);
297
- this.showRowGrip(position.row);
410
+ /**
411
+ * Immediately hide all grips (no delay). Used when resize drag starts.
412
+ */
413
+ public hideAllGrips(): void {
414
+ this.clearHideTimeout();
415
+ this.hideColGrip();
416
+ this.hideRowGrip();
417
+ this.isInsideTable = false;
298
418
  }
299
419
 
300
420
  private showColGrip(index: number): void {
@@ -335,33 +455,80 @@ export class TableRowColControls {
335
455
 
336
456
  private applyVisibleClasses(grip: HTMLElement): void {
337
457
  const el = grip;
458
+ const isCol = el.hasAttribute(GRIP_COL_ATTR);
459
+ const type: 'col' | 'row' = isCol ? 'col' : 'row';
460
+ const pillSize = isCol ? COL_PILL_HEIGHT : ROW_PILL_WIDTH;
461
+
462
+ // Reset to pill size before making visible
463
+ collapseGrip(el, type, pillSize);
464
+
465
+ if (this.isInsideTable) {
466
+ el.style.transition = 'none';
467
+ }
338
468
 
339
469
  el.className = twMerge(GRIP_CAPSULE_CLASSES, GRIP_VISIBLE_CLASSES);
470
+ el.setAttribute('data-blok-table-grip-visible', '');
471
+
472
+ if (this.isInsideTable) {
473
+ void el.offsetHeight;
474
+ el.style.transition = '';
475
+ }
476
+
477
+ const svg = el.querySelector('svg');
478
+
479
+ if (svg) {
480
+ svg.classList.remove('text-white');
481
+ svg.classList.add('text-gray-400');
482
+ }
340
483
  }
341
484
 
342
- private applyIdleClasses(grip: HTMLElement): void {
343
- const el = grip;
485
+ private applyActiveClasses(grip: HTMLElement): void {
486
+ Object.assign(grip, { className: twMerge(GRIP_CAPSULE_CLASSES, GRIP_ACTIVE_CLASSES) });
487
+ grip.setAttribute('data-blok-table-grip-visible', '');
344
488
 
345
- el.className = twMerge(GRIP_CAPSULE_CLASSES, GRIP_IDLE_CLASSES);
489
+ const svg = grip.querySelector('svg');
490
+
491
+ if (svg) {
492
+ svg.classList.remove('text-gray-400', 'opacity-0');
493
+ svg.classList.add('text-white', 'opacity-100');
494
+ }
346
495
  }
347
496
 
348
- private handleDragStateChange(isDragging: boolean, dragType: 'row' | 'col' | null): void {
349
- if (isDragging) {
350
- const gripsToHide = dragType === 'row' ? this.colGrips : this.rowGrips;
497
+ private hideAllGripsExcept(activeGrip: HTMLElement): void {
498
+ [...this.colGrips, ...this.rowGrips].forEach(grip => {
499
+ if (grip !== activeGrip) {
500
+ this.applyIdleClasses(grip);
501
+ }
502
+ });
503
+ }
351
504
 
352
- gripsToHide.forEach(grip => {
353
- const el: HTMLElement = grip;
505
+ private applyIdleClasses(grip: HTMLElement): void {
506
+ const el = grip;
507
+ const isCol = el.hasAttribute(GRIP_COL_ATTR);
508
+ const type: 'col' | 'row' = isCol ? 'col' : 'row';
509
+ // With border-box, pillSize must account for the 12px padding (6px each side)
510
+ const HIT_AREA_PADDING = 12;
511
+ const pillSize = isCol ? (COL_PILL_HEIGHT + HIT_AREA_PADDING) : (ROW_PILL_WIDTH + HIT_AREA_PADDING);
512
+
513
+ if (this.isInsideTable) {
514
+ el.style.transition = 'none';
515
+ }
354
516
 
355
- el.style.display = 'none';
356
- });
517
+ collapseGrip(el, type, pillSize);
518
+ el.className = twMerge(GRIP_CAPSULE_CLASSES, GRIP_IDLE_CLASSES);
519
+ el.removeAttribute('data-blok-table-grip-visible');
357
520
 
358
- return;
521
+ if (this.isInsideTable) {
522
+ void el.offsetHeight;
523
+ el.style.transition = '';
359
524
  }
525
+ }
360
526
 
527
+ private handleDragStateChange(isDragging: boolean, _dragType: 'row' | 'col' | null): void {
361
528
  [...this.colGrips, ...this.rowGrips].forEach(grip => {
362
529
  const el: HTMLElement = grip;
363
530
 
364
- el.style.display = '';
531
+ el.style.display = isDragging ? 'none' : '';
365
532
  });
366
533
  }
367
534
 
@@ -369,6 +536,7 @@ export class TableRowColControls {
369
536
  this.hideTimeout = setTimeout(() => {
370
537
  this.hideColGrip();
371
538
  this.hideRowGrip();
539
+ this.isInsideTable = false;
372
540
  this.hideTimeout = null;
373
541
  }, HIDE_DELAY_MS);
374
542
  }
@@ -427,155 +595,41 @@ export class TableRowColControls {
427
595
  // ── Popover menus ────────────────────────────────────────────
428
596
 
429
597
  private openPopover(type: 'row' | 'col', index: number): void {
430
- this.destroyPopover();
431
- this.clearHideTimeout();
432
-
433
- const grip = type === 'col'
434
- ? this.colGrips[index]
435
- : this.rowGrips[index];
436
-
437
- if (!grip) {
438
- return;
439
- }
440
-
441
- const items = type === 'col'
442
- ? this.buildColumnMenu(index)
443
- : this.buildRowMenu(index);
444
-
445
- this.activePopover = new PopoverDesktop({
446
- items,
447
- trigger: grip,
448
- flippable: true,
449
- });
450
-
451
- this.activePopover.on(PopoverEvent.Closed, () => {
452
- this.destroyPopover();
453
- this.scheduleHideAll();
454
- });
455
-
456
- this.activePopover.show();
457
- this.addOutsideClickListener(grip);
458
- }
459
-
460
- private addOutsideClickListener(grip: HTMLElement): void {
461
- this.boundDocPointerDown = (e: PointerEvent): void => {
462
- const target = e.target as Node;
463
-
464
- if (grip.contains(target)) {
465
- return;
466
- }
467
-
468
- if (this.activePopover?.hasNode(target)) {
469
- return;
598
+ this.popoverState = createGripPopover(
599
+ type,
600
+ index,
601
+ { col: this.colGrips, row: this.rowGrips },
602
+ {
603
+ getColumnCount: this.getColumnCount,
604
+ getRowCount: this.getRowCount,
605
+ isHeadingRow: this.isHeadingRow,
606
+ isHeadingColumn: this.isHeadingColumn,
607
+ onAction: this.onAction,
608
+ i18n: this.i18n,
609
+ },
610
+ {
611
+ clearHideTimeout: () => this.clearHideTimeout(),
612
+ hideAllGripsExcept: (grip) => this.hideAllGripsExcept(grip),
613
+ applyActiveClasses: (grip) => this.applyActiveClasses(grip),
614
+ applyVisibleClasses: (grip) => this.applyVisibleClasses(grip),
615
+ scheduleHideAll: () => this.scheduleHideAll(),
616
+ destroyPopover: () => this.destroyPopover(),
617
+ onGripPopoverClose: this.onGripPopoverClose,
470
618
  }
619
+ );
471
620
 
472
- this.destroyPopover();
473
- };
474
-
475
- document.addEventListener('pointerdown', this.boundDocPointerDown);
476
- }
477
-
478
- private removeOutsideClickListener(): void {
479
- if (this.boundDocPointerDown !== null) {
480
- document.removeEventListener('pointerdown', this.boundDocPointerDown);
481
- this.boundDocPointerDown = null;
482
- }
621
+ // Show after storing state so callbacks (e.g. onGripClick → setGripsDisplay)
622
+ // see the updated popoverState.grip reference
623
+ this.popoverState.popover?.show();
624
+ this.onGripClick?.(type, index);
483
625
  }
484
626
 
485
627
  private destroyPopover(): void {
486
- if (this.activePopover !== null) {
487
- const popover = this.activePopover;
628
+ if (this.popoverState.popover !== null) {
629
+ const popoverRef = this.popoverState.popover;
488
630
 
489
- this.activePopover = null;
490
- this.removeOutsideClickListener();
491
- popover.destroy();
631
+ this.popoverState = { popover: null, grip: null };
632
+ popoverRef.destroy();
492
633
  }
493
634
  }
494
-
495
- private buildColumnMenu(colIndex: number): PopoverItemParams[] {
496
- return [
497
- {
498
- icon: IconInsertLeft,
499
- title: 'Insert Column Left',
500
- closeOnActivate: true,
501
- onActivate: (): void => {
502
- this.onAction({ type: 'insert-col-left', index: colIndex });
503
- },
504
- },
505
- {
506
- icon: IconInsertRight,
507
- title: 'Insert Column Right',
508
- closeOnActivate: true,
509
- onActivate: (): void => {
510
- this.onAction({ type: 'insert-col-right', index: colIndex });
511
- },
512
- },
513
- { type: PopoverItemType.Separator },
514
- {
515
- icon: IconTrash,
516
- title: 'Delete Column',
517
- confirmation: {
518
- title: 'Click to confirm',
519
- icon: IconTrash,
520
- onActivate: (): void => {
521
- this.onAction({ type: 'delete-col', index: colIndex });
522
- },
523
- },
524
- },
525
- ];
526
- }
527
-
528
- private buildRowMenu(rowIndex: number): PopoverItemParams[] {
529
- const baseItems: PopoverItemParams[] = [
530
- {
531
- icon: IconInsertAbove,
532
- title: 'Insert Row Above',
533
- closeOnActivate: true,
534
- onActivate: (): void => {
535
- this.onAction({ type: 'insert-row-above', index: rowIndex });
536
- },
537
- },
538
- {
539
- icon: IconInsertBelow,
540
- title: 'Insert Row Below',
541
- closeOnActivate: true,
542
- onActivate: (): void => {
543
- this.onAction({ type: 'insert-row-below', index: rowIndex });
544
- },
545
- },
546
- ];
547
-
548
- const headingItems: PopoverItemParams[] = rowIndex === 0
549
- ? [
550
- { type: PopoverItemType.Separator },
551
- {
552
- icon: IconHeading,
553
- title: 'Set as Heading',
554
- isActive: this.isHeadingRow(),
555
- toggle: true,
556
- closeOnActivate: true,
557
- onActivate: (): void => {
558
- this.onAction({ type: 'toggle-heading' });
559
- },
560
- },
561
- ]
562
- : [];
563
-
564
- const deleteItems: PopoverItemParams[] = [
565
- { type: PopoverItemType.Separator },
566
- {
567
- icon: IconTrash,
568
- title: 'Delete Row',
569
- confirmation: {
570
- title: 'Click to confirm',
571
- icon: IconTrash,
572
- onActivate: (): void => {
573
- this.onAction({ type: 'delete-row', index: rowIndex });
574
- },
575
- },
576
- },
577
- ];
578
-
579
- return [...baseItems, ...headingItems, ...deleteItems];
580
- }
581
635
  }
@@ -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
  }