@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.
- package/README.md +16 -169
- package/bin/blok.mjs +10 -0
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-Bu9S3SsR.mjs → blok-Buf0btS7.mjs} +2267 -2024
- package/dist/chunks/{i18next-loader-CKuXJ0Av.mjs → i18next-loader-CVf_ZfwA.mjs} +1 -1
- package/dist/chunks/{index-jtZaryNw.mjs → index-C6jsfLLp.mjs} +1 -1
- package/dist/chunks/{inline-tool-convert-CFjyrH30.mjs → inline-tool-convert-BKKEoOqB.mjs} +710 -570
- package/dist/chunks/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
- package/dist/chunks/{messages-CQj2JU2j.mjs → messages-7QoX8DkW.mjs} +23 -9
- package/dist/{messages-LvFKBBPa.mjs → chunks/messages-7W4d0DwD.mjs} +15 -1
- package/dist/{messages-Bn253WWC.mjs → chunks/messages-9SihnaXQ.mjs} +14 -0
- package/dist/{messages-Bf6Y3_GI.mjs → chunks/messages-B1Aww8q7.mjs} +16 -2
- package/dist/{messages-pA5TvcAj.mjs → chunks/messages-BB5z9Uba.mjs} +14 -0
- package/dist/chunks/{messages-wdqp4610.mjs → messages-BC86qLvI.mjs} +17 -3
- package/dist/chunks/{messages-o24dK6CU.mjs → messages-BELRf6DU.mjs} +16 -2
- package/dist/chunks/{messages-CUZ1x1QD.mjs → messages-BFG6Wlgy.mjs} +16 -2
- package/dist/{messages-B5puUm7R.mjs → chunks/messages-BL0tXcDf.mjs} +15 -1
- package/dist/chunks/{messages-zS1AXZ0y.mjs → messages-BMXCuEKO.mjs} +19 -5
- package/dist/{messages-CyDU5lz9.mjs → chunks/messages-BMv4xwIr.mjs} +16 -2
- package/dist/chunks/{messages-BeUhMpsr.mjs → messages-BSbjsyHY.mjs} +25 -11
- package/dist/chunks/{messages-JGsXAReJ.mjs → messages-BU2nlrLK.mjs} +16 -2
- package/dist/chunks/{messages-srxrv8Yh.mjs → messages-BWF-zUpY.mjs} +17 -3
- package/dist/{messages-CXHd9SUK.mjs → chunks/messages-BYyy6Wqf.mjs} +14 -0
- package/dist/chunks/{messages-DOlC_Tty.mjs → messages-BdeLo0N9.mjs} +24 -10
- package/dist/chunks/{messages-B5jGUnOy.mjs → messages-Bmu_S7GM.mjs} +14 -0
- package/dist/chunks/{messages-BmKCChWZ.mjs → messages-BoJc_p1r.mjs} +14 -0
- package/dist/chunks/{messages-CvaqJFN-.mjs → messages-BogRq8lt.mjs} +15 -1
- package/dist/chunks/{messages-NP1myMGI.mjs → messages-BrPFGbM-.mjs} +14 -0
- package/dist/chunks/{messages-D00OjS2n.mjs → messages-C2htQ_3F.mjs} +24 -10
- package/dist/chunks/{messages-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
- package/dist/chunks/{messages-CkFT2gle.mjs → messages-C9eaarcK.mjs} +20 -6
- package/dist/chunks/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
- package/dist/chunks/messages-CKI54h6O.mjs +62 -0
- package/dist/{messages-CrsJ1TEJ.mjs → chunks/messages-CLhcMlTc.mjs} +15 -1
- package/dist/{messages-CnvW8Slp.mjs → chunks/messages-CMkNSDTo.mjs} +17 -3
- package/dist/{messages-BlpqL8vG.mjs → chunks/messages-CQwpzUFp.mjs} +19 -5
- package/dist/chunks/{messages-Cu08aLS3.mjs → messages-CVw84KdI.mjs} +21 -7
- package/dist/chunks/{messages-B9Oba7sq.mjs → messages-CY8_RyFE.mjs} +15 -1
- package/dist/chunks/{messages-B5hdXZwA.mjs → messages-CZygwLwM.mjs} +15 -1
- package/dist/chunks/{messages-CVeWVKsV.mjs → messages-CnwibSvh.mjs} +14 -0
- package/dist/chunks/{messages-DbVquYKN.mjs → messages-CqWJcCbY.mjs} +14 -0
- package/dist/{messages-Dg92dXZ5.mjs → chunks/messages-CvGLfqmV.mjs} +14 -0
- package/dist/{messages-AHESHJm_.mjs → chunks/messages-CzTufCHu.mjs} +14 -0
- package/dist/chunks/{messages-Cj-t1bdy.mjs → messages-CznZadDf.mjs} +15 -1
- package/dist/chunks/{messages-DMQIHGRj.mjs → messages-D-ZtY5v0.mjs} +14 -0
- package/dist/chunks/{messages-rRSHQDCX.mjs → messages-D1Hv8XGo.mjs} +14 -0
- package/dist/chunks/{messages-0tDXLuyH.mjs → messages-D5C3J9qr.mjs} +15 -1
- package/dist/chunks/{messages-RvMHb2Ht.mjs → messages-D5iv1Kox.mjs} +16 -2
- package/dist/{messages-zSzDzXej.mjs → chunks/messages-DBRw-7Zc.mjs} +16 -2
- package/dist/chunks/{messages-CeCjVKMW.mjs → messages-DBn76jVV.mjs} +16 -2
- package/dist/chunks/{messages-C7I_AVH2.mjs → messages-DJDG55Vq.mjs} +16 -2
- package/dist/{messages-DDLgIPDF.mjs → chunks/messages-DLfR5bMd.mjs} +16 -2
- package/dist/{messages-CbhuIWRJ.mjs → chunks/messages-DT4dP5uK.mjs} +15 -1
- package/dist/chunks/{messages-B66ZSDCJ.mjs → messages-DhLKYm2j.mjs} +15 -1
- package/dist/{messages-BPqWKx5Z.mjs → chunks/messages-Diu6jAaR.mjs} +17 -3
- package/dist/{messages-BA0rcTCY.mjs → chunks/messages-DnIhyAJk.mjs} +18 -4
- package/dist/chunks/{messages-DV6shA9b.mjs → messages-DnXLrlHh.mjs} +14 -0
- package/dist/chunks/{messages-DcKOuncK.mjs → messages-DprmQg6V.mjs} +16 -2
- package/dist/{messages-CJoBtXU6.mjs → chunks/messages-DqM1LFg5.mjs} +14 -0
- package/dist/chunks/{messages-Cyi2AMmz.mjs → messages-DvFLX36Q.mjs} +25 -11
- package/dist/chunks/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
- package/dist/chunks/{messages-GC2PhgV3.mjs → messages-Dzwxv9v1.mjs} +23 -9
- package/dist/chunks/{messages-Q4kc_ZtL.mjs → messages-JELdtT6E.mjs} +15 -1
- package/dist/{messages-DY94ykcE.mjs → chunks/messages-LPVfA-8K.mjs} +14 -0
- package/dist/{messages-Cr-RJ7YB.mjs → chunks/messages-O5tQus_0.mjs} +14 -0
- package/dist/chunks/{messages-CbMyJSzS.mjs → messages-Q7AO_FLv.mjs} +17 -3
- package/dist/chunks/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
- package/dist/{messages-CUy1vn-b.mjs → chunks/messages-Xq8UmkVs.mjs} +14 -0
- package/dist/chunks/{messages-BBJgd5jG.mjs → messages-Z9nEU2xK.mjs} +16 -2
- package/dist/chunks/{messages-Cm9aLHeX.mjs → messages-_ErNTNhk.mjs} +15 -1
- package/dist/chunks/{messages-JZUhXTuV.mjs → messages-_ncGrKHh.mjs} +16 -2
- package/dist/chunks/{messages-ftMcCEuO.mjs → messages-kep5wtm4.mjs} +15 -1
- package/dist/chunks/{messages-DteYq0rv.mjs → messages-uKX8WBaD.mjs} +16 -2
- package/dist/chunks/{messages-Bdv-IkfG.mjs → messages-w7v1GNaE.mjs} +15 -1
- package/dist/cli.mjs +50 -0
- package/dist/full.mjs +15 -15
- package/dist/locales.mjs +102 -88
- package/dist/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
- package/dist/{messages-CQj2JU2j.mjs → messages-7QoX8DkW.mjs} +23 -9
- package/dist/{chunks/messages-LvFKBBPa.mjs → messages-7W4d0DwD.mjs} +15 -1
- package/dist/{chunks/messages-Bn253WWC.mjs → messages-9SihnaXQ.mjs} +14 -0
- package/dist/{chunks/messages-Bf6Y3_GI.mjs → messages-B1Aww8q7.mjs} +16 -2
- package/dist/{chunks/messages-pA5TvcAj.mjs → messages-BB5z9Uba.mjs} +14 -0
- package/dist/{messages-wdqp4610.mjs → messages-BC86qLvI.mjs} +17 -3
- package/dist/{messages-o24dK6CU.mjs → messages-BELRf6DU.mjs} +16 -2
- package/dist/{messages-CUZ1x1QD.mjs → messages-BFG6Wlgy.mjs} +16 -2
- package/dist/{chunks/messages-B5puUm7R.mjs → messages-BL0tXcDf.mjs} +15 -1
- package/dist/{messages-zS1AXZ0y.mjs → messages-BMXCuEKO.mjs} +19 -5
- package/dist/{chunks/messages-CyDU5lz9.mjs → messages-BMv4xwIr.mjs} +16 -2
- package/dist/{messages-BeUhMpsr.mjs → messages-BSbjsyHY.mjs} +25 -11
- package/dist/{messages-JGsXAReJ.mjs → messages-BU2nlrLK.mjs} +16 -2
- package/dist/{messages-srxrv8Yh.mjs → messages-BWF-zUpY.mjs} +17 -3
- package/dist/{chunks/messages-CXHd9SUK.mjs → messages-BYyy6Wqf.mjs} +14 -0
- package/dist/{messages-DOlC_Tty.mjs → messages-BdeLo0N9.mjs} +24 -10
- package/dist/{messages-B5jGUnOy.mjs → messages-Bmu_S7GM.mjs} +14 -0
- package/dist/{messages-BmKCChWZ.mjs → messages-BoJc_p1r.mjs} +14 -0
- package/dist/{messages-CvaqJFN-.mjs → messages-BogRq8lt.mjs} +15 -1
- package/dist/{messages-NP1myMGI.mjs → messages-BrPFGbM-.mjs} +14 -0
- package/dist/{messages-D00OjS2n.mjs → messages-C2htQ_3F.mjs} +24 -10
- package/dist/{messages-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
- package/dist/{messages-CkFT2gle.mjs → messages-C9eaarcK.mjs} +20 -6
- package/dist/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
- package/dist/messages-CKI54h6O.mjs +62 -0
- package/dist/{chunks/messages-CrsJ1TEJ.mjs → messages-CLhcMlTc.mjs} +15 -1
- package/dist/{chunks/messages-CnvW8Slp.mjs → messages-CMkNSDTo.mjs} +17 -3
- package/dist/{chunks/messages-BlpqL8vG.mjs → messages-CQwpzUFp.mjs} +19 -5
- package/dist/{messages-Cu08aLS3.mjs → messages-CVw84KdI.mjs} +21 -7
- package/dist/{messages-B9Oba7sq.mjs → messages-CY8_RyFE.mjs} +15 -1
- package/dist/{messages-B5hdXZwA.mjs → messages-CZygwLwM.mjs} +15 -1
- package/dist/{messages-CVeWVKsV.mjs → messages-CnwibSvh.mjs} +14 -0
- package/dist/{messages-DbVquYKN.mjs → messages-CqWJcCbY.mjs} +14 -0
- package/dist/{chunks/messages-Dg92dXZ5.mjs → messages-CvGLfqmV.mjs} +14 -0
- package/dist/{chunks/messages-AHESHJm_.mjs → messages-CzTufCHu.mjs} +14 -0
- package/dist/{messages-Cj-t1bdy.mjs → messages-CznZadDf.mjs} +15 -1
- package/dist/{messages-DMQIHGRj.mjs → messages-D-ZtY5v0.mjs} +14 -0
- package/dist/{messages-rRSHQDCX.mjs → messages-D1Hv8XGo.mjs} +14 -0
- package/dist/{messages-0tDXLuyH.mjs → messages-D5C3J9qr.mjs} +15 -1
- package/dist/{messages-RvMHb2Ht.mjs → messages-D5iv1Kox.mjs} +16 -2
- package/dist/{chunks/messages-zSzDzXej.mjs → messages-DBRw-7Zc.mjs} +16 -2
- package/dist/{messages-CeCjVKMW.mjs → messages-DBn76jVV.mjs} +16 -2
- package/dist/{messages-C7I_AVH2.mjs → messages-DJDG55Vq.mjs} +16 -2
- package/dist/{chunks/messages-DDLgIPDF.mjs → messages-DLfR5bMd.mjs} +16 -2
- package/dist/{chunks/messages-CbhuIWRJ.mjs → messages-DT4dP5uK.mjs} +15 -1
- package/dist/{messages-B66ZSDCJ.mjs → messages-DhLKYm2j.mjs} +15 -1
- package/dist/{chunks/messages-BPqWKx5Z.mjs → messages-Diu6jAaR.mjs} +17 -3
- package/dist/{chunks/messages-BA0rcTCY.mjs → messages-DnIhyAJk.mjs} +18 -4
- package/dist/{messages-DV6shA9b.mjs → messages-DnXLrlHh.mjs} +14 -0
- package/dist/{messages-DcKOuncK.mjs → messages-DprmQg6V.mjs} +16 -2
- package/dist/{chunks/messages-CJoBtXU6.mjs → messages-DqM1LFg5.mjs} +14 -0
- package/dist/{messages-Cyi2AMmz.mjs → messages-DvFLX36Q.mjs} +25 -11
- package/dist/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
- package/dist/{messages-GC2PhgV3.mjs → messages-Dzwxv9v1.mjs} +23 -9
- package/dist/{messages-Q4kc_ZtL.mjs → messages-JELdtT6E.mjs} +15 -1
- package/dist/{chunks/messages-DY94ykcE.mjs → messages-LPVfA-8K.mjs} +14 -0
- package/dist/{chunks/messages-Cr-RJ7YB.mjs → messages-O5tQus_0.mjs} +14 -0
- package/dist/{messages-CbMyJSzS.mjs → messages-Q7AO_FLv.mjs} +17 -3
- package/dist/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
- package/dist/{chunks/messages-CUy1vn-b.mjs → messages-Xq8UmkVs.mjs} +14 -0
- package/dist/{messages-BBJgd5jG.mjs → messages-Z9nEU2xK.mjs} +16 -2
- package/dist/{messages-Cm9aLHeX.mjs → messages-_ErNTNhk.mjs} +15 -1
- package/dist/{messages-JZUhXTuV.mjs → messages-_ncGrKHh.mjs} +16 -2
- package/dist/{messages-ftMcCEuO.mjs → messages-kep5wtm4.mjs} +15 -1
- package/dist/{messages-DteYq0rv.mjs → messages-uKX8WBaD.mjs} +16 -2
- package/dist/{messages-Bdv-IkfG.mjs → messages-w7v1GNaE.mjs} +15 -1
- package/dist/tools.mjs +2005 -1267
- package/dist/vendor.LICENSE.txt +1 -1
- package/package.json +15 -14
- package/src/cli/commands/migration.ts +16 -0
- package/src/cli/commands/migrationContent.ts +6 -0
- package/src/cli/index.ts +47 -0
- package/src/cli/utils/output.ts +10 -0
- package/src/components/block-tunes/block-tune-delete.ts +3 -2
- package/src/components/blocks.ts +23 -6
- package/src/components/constants/data-attributes.ts +2 -0
- package/src/components/i18n/locales/am/messages.json +15 -1
- package/src/components/i18n/locales/ar/messages.json +14 -0
- package/src/components/i18n/locales/az/messages.json +14 -0
- package/src/components/i18n/locales/bg/messages.json +14 -0
- package/src/components/i18n/locales/bn/messages.json +25 -11
- package/src/components/i18n/locales/bs/messages.json +15 -1
- package/src/components/i18n/locales/cs/messages.json +14 -0
- package/src/components/i18n/locales/da/messages.json +14 -0
- package/src/components/i18n/locales/de/messages.json +14 -0
- package/src/components/i18n/locales/dv/messages.json +15 -1
- package/src/components/i18n/locales/el/messages.json +15 -1
- package/src/components/i18n/locales/en/messages.json +14 -0
- package/src/components/i18n/locales/es/messages.json +14 -0
- package/src/components/i18n/locales/et/messages.json +14 -0
- package/src/components/i18n/locales/fa/messages.json +15 -1
- package/src/components/i18n/locales/fi/messages.json +15 -1
- package/src/components/i18n/locales/fil/messages.json +20 -6
- package/src/components/i18n/locales/fr/messages.json +15 -1
- package/src/components/i18n/locales/gu/messages.json +15 -1
- package/src/components/i18n/locales/he/messages.json +14 -0
- package/src/components/i18n/locales/hi/messages.json +23 -9
- package/src/components/i18n/locales/hr/messages.json +14 -0
- package/src/components/i18n/locales/hu/messages.json +14 -0
- package/src/components/i18n/locales/hy/messages.json +16 -2
- package/src/components/i18n/locales/id/messages.json +19 -5
- package/src/components/i18n/locales/it/messages.json +14 -0
- package/src/components/i18n/locales/ja/messages.json +14 -0
- package/src/components/i18n/locales/ka/messages.json +15 -1
- package/src/components/i18n/locales/km/messages.json +16 -2
- package/src/components/i18n/locales/kn/messages.json +16 -2
- package/src/components/i18n/locales/ko/messages.json +14 -0
- package/src/components/i18n/locales/ku/messages.json +16 -2
- package/src/components/i18n/locales/lo/messages.json +15 -1
- package/src/components/i18n/locales/lt/messages.json +15 -1
- package/src/components/i18n/locales/lv/messages.json +15 -1
- package/src/components/i18n/locales/mk/messages.json +16 -2
- package/src/components/i18n/locales/ml/messages.json +16 -2
- package/src/components/i18n/locales/mn/messages.json +16 -2
- package/src/components/i18n/locales/mr/messages.json +24 -10
- package/src/components/i18n/locales/ms/messages.json +17 -3
- package/src/components/i18n/locales/my/messages.json +16 -2
- package/src/components/i18n/locales/ne/messages.json +24 -10
- package/src/components/i18n/locales/nl/messages.json +15 -1
- package/src/components/i18n/locales/no/messages.json +16 -2
- package/src/components/i18n/locales/pa/messages.json +15 -1
- package/src/components/i18n/locales/pl/messages.json +14 -0
- package/src/components/i18n/locales/ps/messages.json +17 -3
- package/src/components/i18n/locales/pt/messages.json +14 -0
- package/src/components/i18n/locales/ro/messages.json +15 -1
- package/src/components/i18n/locales/ru/messages.json +14 -0
- package/src/components/i18n/locales/sd/messages.json +16 -2
- package/src/components/i18n/locales/si/messages.json +23 -9
- package/src/components/i18n/locales/sk/messages.json +15 -1
- package/src/components/i18n/locales/sl/messages.json +16 -2
- package/src/components/i18n/locales/sq/messages.json +16 -2
- package/src/components/i18n/locales/sr/messages.json +16 -2
- package/src/components/i18n/locales/sv/messages.json +16 -2
- package/src/components/i18n/locales/sw/messages.json +16 -2
- package/src/components/i18n/locales/ta/messages.json +21 -7
- package/src/components/i18n/locales/te/messages.json +40 -26
- package/src/components/i18n/locales/th/messages.json +19 -5
- package/src/components/i18n/locales/tr/messages.json +15 -1
- package/src/components/i18n/locales/ug/messages.json +16 -2
- package/src/components/i18n/locales/uk/messages.json +15 -1
- package/src/components/i18n/locales/ur/messages.json +15 -1
- package/src/components/i18n/locales/vi/messages.json +25 -11
- package/src/components/i18n/locales/yi/messages.json +16 -2
- package/src/components/i18n/locales/zh/messages.json +15 -1
- package/src/components/icons/index.ts +104 -83
- package/src/components/modules/api/blocks.ts +35 -2
- package/src/components/modules/api/history.ts +64 -0
- package/src/components/modules/api/index.ts +2 -0
- package/src/components/modules/api/readonly.ts +11 -1
- package/src/components/modules/blockEvents/composers/markdownShortcuts.ts +12 -1
- package/src/components/modules/blockManager/blockManager.ts +7 -0
- package/src/components/modules/blockManager/operations.ts +3 -2
- package/src/components/modules/blockManager/types.ts +3 -1
- package/src/components/modules/blockManager/yjs-sync.ts +12 -2
- package/src/components/modules/index.ts +3 -0
- package/src/components/modules/normalizeInlineImages.ts +263 -0
- package/src/components/modules/readonly.ts +11 -0
- package/src/components/modules/rectangleSelection.ts +19 -3
- package/src/components/modules/saver.ts +7 -3
- package/src/components/modules/toolbar/blockSettings.ts +3 -3
- package/src/components/modules/toolbar/index.ts +72 -14
- package/src/components/modules/toolbar/plus-button.ts +24 -3
- package/src/components/modules/toolbar/settings-toggler.ts +3 -5
- package/src/components/modules/ui.ts +46 -68
- package/src/components/modules/uiControllers/controllers/blockHover.ts +49 -61
- package/src/components/modules/uiControllers/controllers/keyboard.ts +17 -11
- package/src/components/modules/uiControllers/handlers/click.ts +0 -12
- package/src/components/modules/yjs/index.ts +23 -0
- package/src/components/ui/toolbox.ts +41 -6
- package/src/components/utils/placeholder.ts +16 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +2 -1
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +6 -1
- package/src/components/utils/popover/index.ts +1 -0
- package/src/components/utils/popover/popover-abstract.ts +11 -1
- package/src/components/utils/popover/popover-desktop.ts +27 -8
- package/src/components/utils/popover/popover-registry.ts +188 -0
- package/src/components/utils/sanitizer.ts +23 -2
- package/src/components/utils/tooltip.ts +2 -24
- package/src/styles/main.css +22 -0
- package/src/tools/paragraph/index.ts +12 -4
- package/src/tools/table/data-normalizer.ts +1 -0
- package/src/tools/table/index.ts +283 -346
- package/src/tools/table/table-add-controls.ts +353 -47
- package/src/tools/table/table-cell-blocks.ts +95 -7
- package/src/tools/table/table-cell-selection.ts +648 -0
- package/src/tools/table/table-core.ts +21 -32
- package/src/tools/table/table-grip-visuals.ts +96 -0
- package/src/tools/table/table-heading-toggle.ts +127 -0
- package/src/tools/table/table-operations.ts +475 -0
- package/src/tools/table/table-resize.ts +27 -6
- package/src/tools/table/table-restrictions.ts +64 -0
- package/src/tools/table/table-row-col-action-handler.ts +190 -0
- package/src/tools/table/table-row-col-controls.ts +265 -211
- package/src/tools/table/table-row-col-drag.ts +4 -4
- package/src/tools/table/table-row-col-popover.ts +225 -0
- package/src/tools/table/types.ts +4 -0
- package/src/types-internal/blok-modules.d.ts +2 -0
- package/types/api/blocks.d.ts +8 -0
- package/types/api/history.d.ts +33 -0
- package/types/api/index.d.ts +1 -0
- package/types/api/readonly.d.ts +12 -2
- package/types/index.d.ts +10 -0
- package/types/tools/table.d.ts +67 -0
- package/types/tools-entry.d.ts +4 -0
- package/types/utils/popover/popover-item.d.ts +6 -0
- package/types/utils/popover/popover.d.ts +7 -0
- package/dist/chunks/messages-CySyfkMU.mjs +0 -48
- package/dist/messages-CySyfkMU.mjs +0 -48
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import type { API } from '../../../types';
|
|
2
|
+
|
|
3
|
+
import type { TableCellBlocks } from './table-cell-blocks';
|
|
4
|
+
import { CELL_BLOCKS_ATTR } from './table-cell-blocks';
|
|
5
|
+
import { BORDER_WIDTH, ROW_ATTR, CELL_ATTR } from './table-core';
|
|
6
|
+
import type { TableGrid } from './table-core';
|
|
7
|
+
import type { LegacyCellContent, TableData } from './types';
|
|
8
|
+
import { isCellWithBlocks } from './types';
|
|
9
|
+
|
|
10
|
+
// ─── Pure DOM helpers ───────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
export const readPixelWidths = (gridEl: HTMLElement): number[] => {
|
|
13
|
+
const firstRow = gridEl.querySelector(`[${ROW_ATTR}]`);
|
|
14
|
+
|
|
15
|
+
if (!firstRow) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const cells = firstRow.querySelectorAll(`[${CELL_ATTR}]`);
|
|
20
|
+
|
|
21
|
+
return Array.from(cells).map(cell =>
|
|
22
|
+
(cell as HTMLElement).getBoundingClientRect().width
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const applyPixelWidths = (gridEl: HTMLElement, widths: number[]): void => {
|
|
27
|
+
const totalWidth = widths.reduce((sum, w) => sum + w, 0);
|
|
28
|
+
const gridStyle: HTMLElement = gridEl;
|
|
29
|
+
|
|
30
|
+
gridStyle.style.width = `${totalWidth + BORDER_WIDTH}px`;
|
|
31
|
+
|
|
32
|
+
const rowEls = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
33
|
+
|
|
34
|
+
rowEls.forEach(row => {
|
|
35
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
36
|
+
|
|
37
|
+
cells.forEach((node, i) => {
|
|
38
|
+
if (i < widths.length) {
|
|
39
|
+
const cellEl = node as HTMLElement;
|
|
40
|
+
|
|
41
|
+
cellEl.style.width = `${widths[i]}px`;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const getCellPosition = (gridEl: HTMLElement, cell: HTMLElement): { row: number; col: number } | null => {
|
|
48
|
+
const rows = Array.from(gridEl.querySelectorAll(`[${ROW_ATTR}]`));
|
|
49
|
+
|
|
50
|
+
const rowIndex = rows.findIndex(row => {
|
|
51
|
+
const cells = Array.from(row.querySelectorAll(`[${CELL_ATTR}]`));
|
|
52
|
+
|
|
53
|
+
return cells.includes(cell);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (rowIndex === -1) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const cells = Array.from(rows[rowIndex].querySelectorAll(`[${CELL_ATTR}]`));
|
|
61
|
+
const colIndex = cells.indexOf(cell);
|
|
62
|
+
|
|
63
|
+
return { row: rowIndex, col: colIndex };
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ─── Cell emptiness ─────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
export const isCellEmpty = (cell: HTMLElement): boolean => {
|
|
69
|
+
const container = cell.querySelector(`[${CELL_BLOCKS_ATTR}]`);
|
|
70
|
+
|
|
71
|
+
if (!container) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (container.textContent ?? '').trim().length === 0;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const isRowEmpty = (gridEl: HTMLElement, rowIndex: number): boolean => {
|
|
79
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
80
|
+
const row = rows[rowIndex];
|
|
81
|
+
|
|
82
|
+
if (!row) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
87
|
+
|
|
88
|
+
return Array.from(cells).every(cell => isCellEmpty(cell as HTMLElement));
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const isColumnEmpty = (gridEl: HTMLElement, colIndex: number): boolean => {
|
|
92
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
93
|
+
|
|
94
|
+
return Array.from(rows).every(row => {
|
|
95
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
96
|
+
const cell = cells[colIndex] as HTMLElement | undefined;
|
|
97
|
+
|
|
98
|
+
return !cell || isCellEmpty(cell);
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// ─── Percent-mode width redistribution ──────────────────────────────
|
|
103
|
+
|
|
104
|
+
export const redistributePercentWidths = (gridEl: HTMLElement): void => {
|
|
105
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
106
|
+
const firstRow = rows[0];
|
|
107
|
+
|
|
108
|
+
if (!firstRow) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const firstRowCells = firstRow.querySelectorAll(`[${CELL_ATTR}]`);
|
|
113
|
+
const currentTotal = Array.from(firstRowCells).reduce(
|
|
114
|
+
(sum, cell) => sum + (parseFloat((cell as HTMLElement).style.width) || 0),
|
|
115
|
+
0,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (currentTotal <= 0) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const scale = 100 / currentTotal;
|
|
123
|
+
|
|
124
|
+
rows.forEach(row => {
|
|
125
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
126
|
+
|
|
127
|
+
cells.forEach(cell => {
|
|
128
|
+
const el = cell as HTMLElement;
|
|
129
|
+
const oldWidth = parseFloat(el.style.width) || 0;
|
|
130
|
+
|
|
131
|
+
el.style.width = `${Math.round(oldWidth * scale * 100) / 100}%`;
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// ─── Column width bookkeeping ───────────────────────────────────────
|
|
137
|
+
|
|
138
|
+
export const syncColWidthsAfterMove = (colWidths: number[] | undefined, fromIndex: number, toIndex: number): number[] | undefined => {
|
|
139
|
+
if (!colWidths) {
|
|
140
|
+
return colWidths;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const widths = [...colWidths];
|
|
144
|
+
const [moved] = widths.splice(fromIndex, 1);
|
|
145
|
+
|
|
146
|
+
widths.splice(toIndex, 0, moved);
|
|
147
|
+
|
|
148
|
+
return widths;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const syncColWidthsAfterDeleteColumn = (colWidths: number[] | undefined, index: number): number[] | undefined => {
|
|
152
|
+
if (!colWidths) {
|
|
153
|
+
return colWidths;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const widths = [...colWidths];
|
|
157
|
+
|
|
158
|
+
widths.splice(index, 1);
|
|
159
|
+
|
|
160
|
+
return widths.length > 0 ? widths : undefined;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const computeInsertColumnWidths = (
|
|
164
|
+
gridEl: HTMLElement,
|
|
165
|
+
index: number,
|
|
166
|
+
data: TableData,
|
|
167
|
+
grid: TableGrid,
|
|
168
|
+
): number[] => {
|
|
169
|
+
const colWidths = data.colWidths ?? readPixelWidths(gridEl);
|
|
170
|
+
|
|
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);
|
|
176
|
+
|
|
177
|
+
const newWidths = [...colWidths];
|
|
178
|
+
|
|
179
|
+
newWidths.splice(index, 0, halfWidth);
|
|
180
|
+
|
|
181
|
+
return newWidths;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export const computeHalfAvgWidth = (colWidths: number[]): number =>
|
|
185
|
+
Math.round(
|
|
186
|
+
(colWidths.reduce((sum, w) => sum + w, 0) / colWidths.length / 2) * 100
|
|
187
|
+
) / 100;
|
|
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
|
+
|
|
197
|
+
// ─── Block IDs from cells ───────────────────────────────────────────
|
|
198
|
+
|
|
199
|
+
export const getBlockIdsInRow = (element: HTMLElement | null, cellBlocks: TableCellBlocks | null, rowIndex: number): string[] => {
|
|
200
|
+
if (!element) {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const rows = element.querySelectorAll(`[${ROW_ATTR}]`);
|
|
205
|
+
const row = rows[rowIndex];
|
|
206
|
+
|
|
207
|
+
if (!row) {
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return cellBlocks?.getBlockIdsFromCells(row.querySelectorAll(`[${CELL_ATTR}]`)) ?? [];
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export const getBlockIdsInColumn = (element: HTMLElement | null, cellBlocks: TableCellBlocks | null, colIndex: number): string[] => {
|
|
215
|
+
if (!element) {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const rows = element.querySelectorAll(`[${ROW_ATTR}]`);
|
|
220
|
+
const cellsInColumn: Element[] = [];
|
|
221
|
+
|
|
222
|
+
rows.forEach(row => {
|
|
223
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
224
|
+
|
|
225
|
+
if (colIndex < cells.length) {
|
|
226
|
+
cellsInColumn.push(cells[colIndex]);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return cellBlocks?.getBlockIdsFromCells(cellsInColumn) ?? [];
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// ─── Row/column deletion with block cleanup ─────────────────────────
|
|
234
|
+
|
|
235
|
+
export const deleteRowWithBlockCleanup = (
|
|
236
|
+
gridEl: HTMLElement,
|
|
237
|
+
rowIndex: number,
|
|
238
|
+
grid: TableGrid,
|
|
239
|
+
cellBlocks: TableCellBlocks | null,
|
|
240
|
+
): void => {
|
|
241
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
242
|
+
const row = rows[rowIndex];
|
|
243
|
+
|
|
244
|
+
if (row && cellBlocks) {
|
|
245
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
246
|
+
|
|
247
|
+
cellBlocks.deleteBlocks(cellBlocks.getBlockIdsFromCells(cells));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
grid.deleteRow(gridEl, rowIndex);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export const deleteColumnWithBlockCleanup = (
|
|
254
|
+
gridEl: HTMLElement,
|
|
255
|
+
colIndex: number,
|
|
256
|
+
colWidths: number[] | undefined,
|
|
257
|
+
grid: TableGrid,
|
|
258
|
+
cellBlocks: TableCellBlocks | null,
|
|
259
|
+
): number[] | undefined => {
|
|
260
|
+
if (cellBlocks) {
|
|
261
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
262
|
+
const cellsInColumn: Element[] = [];
|
|
263
|
+
|
|
264
|
+
rows.forEach(row => {
|
|
265
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
266
|
+
|
|
267
|
+
if (colIndex < cells.length) {
|
|
268
|
+
cellsInColumn.push(cells[colIndex]);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
cellBlocks.deleteBlocks(cellBlocks.getBlockIdsFromCells(cellsInColumn));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
grid.deleteColumn(gridEl, colIndex);
|
|
276
|
+
|
|
277
|
+
return syncColWidthsAfterDeleteColumn(colWidths, colIndex);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// ─── Populate new cells ─────────────────────────────────────────────
|
|
281
|
+
|
|
282
|
+
export const populateNewCells = (gridEl: HTMLElement, cellBlocks: TableCellBlocks | null): void => {
|
|
283
|
+
const cells = gridEl.querySelectorAll(`[${CELL_ATTR}]`);
|
|
284
|
+
|
|
285
|
+
cells.forEach(cell => {
|
|
286
|
+
cellBlocks?.ensureCellHasBlock(cell as HTMLElement);
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
// ─── Readonly block mounting ────────────────────────────────────────
|
|
291
|
+
|
|
292
|
+
export const mountCellBlocksReadOnly = (
|
|
293
|
+
gridEl: HTMLElement,
|
|
294
|
+
content: LegacyCellContent[][],
|
|
295
|
+
api: API,
|
|
296
|
+
): void => {
|
|
297
|
+
const rowElements = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
298
|
+
|
|
299
|
+
content.forEach((rowData, rowIndex) => {
|
|
300
|
+
const row = rowElements[rowIndex];
|
|
301
|
+
|
|
302
|
+
if (!row) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const cells = row.querySelectorAll(`[${CELL_ATTR}]`);
|
|
307
|
+
|
|
308
|
+
rowData.forEach((cellContent, colIndex) => {
|
|
309
|
+
const cell = cells[colIndex] as HTMLElement | undefined;
|
|
310
|
+
|
|
311
|
+
if (!cell) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const container = cell.querySelector<HTMLElement>(`[${CELL_BLOCKS_ATTR}]`);
|
|
316
|
+
|
|
317
|
+
if (!container) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Skip legacy cells that already have blocks (idempotency guard)
|
|
322
|
+
const hasExistingBlocks = container.querySelectorAll('[data-blok-id]').length > 0;
|
|
323
|
+
|
|
324
|
+
if (!isCellWithBlocks(cellContent) && hasExistingBlocks) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (!isCellWithBlocks(cellContent)) {
|
|
329
|
+
// Handle legacy string content by creating a paragraph block
|
|
330
|
+
const legacyText = typeof cellContent === 'string' ? cellContent : '';
|
|
331
|
+
const insertedBlock = api.blocks.insert(
|
|
332
|
+
'paragraph',
|
|
333
|
+
{ text: legacyText },
|
|
334
|
+
{},
|
|
335
|
+
undefined,
|
|
336
|
+
true
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
insertedBlock?.holder && container.appendChild(insertedBlock.holder);
|
|
340
|
+
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
for (const blockId of cellContent.blocks) {
|
|
345
|
+
const index = api.blocks.getBlockIndex(blockId);
|
|
346
|
+
|
|
347
|
+
if (index === undefined) {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const block = api.blocks.getBlockByIndex(index);
|
|
352
|
+
|
|
353
|
+
if (!block) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
container.appendChild(block.holder);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// ─── Data normalization ─────────────────────────────────────────────
|
|
364
|
+
|
|
365
|
+
export const normalizeTableData = (
|
|
366
|
+
data: TableData | Record<string, never>,
|
|
367
|
+
config: { withHeadings?: boolean; stretched?: boolean },
|
|
368
|
+
): TableData => {
|
|
369
|
+
const isTableData = typeof data === 'object' && data !== null && 'content' in data;
|
|
370
|
+
|
|
371
|
+
if (!isTableData) {
|
|
372
|
+
return {
|
|
373
|
+
withHeadings: config.withHeadings ?? false,
|
|
374
|
+
withHeadingColumn: false,
|
|
375
|
+
stretched: config.stretched ?? false,
|
|
376
|
+
content: [],
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const tableData = data as TableData;
|
|
381
|
+
const cols = tableData.content?.[0]?.length;
|
|
382
|
+
const colWidths = tableData.colWidths;
|
|
383
|
+
const validWidths = colWidths && cols && colWidths.length === cols ? colWidths : undefined;
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
withHeadings: tableData.withHeadings ?? config.withHeadings ?? false,
|
|
387
|
+
withHeadingColumn: tableData.withHeadingColumn ?? false,
|
|
388
|
+
stretched: tableData.stretched ?? config.stretched ?? false,
|
|
389
|
+
content: tableData.content ?? [],
|
|
390
|
+
colWidths: validWidths,
|
|
391
|
+
initialColWidth: tableData.initialColWidth,
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// ─── Keyboard navigation ────────────────────────────────────────────
|
|
396
|
+
|
|
397
|
+
export const setupKeyboardNavigation = (
|
|
398
|
+
gridEl: HTMLElement,
|
|
399
|
+
cellBlocks: TableCellBlocks | null,
|
|
400
|
+
): void => {
|
|
401
|
+
gridEl.addEventListener('keydown', (event: KeyboardEvent) => {
|
|
402
|
+
const target = event.target as HTMLElement;
|
|
403
|
+
const cell = target.closest<HTMLElement>(`[${CELL_ATTR}]`);
|
|
404
|
+
|
|
405
|
+
if (!cell) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const position = getCellPosition(gridEl, cell);
|
|
410
|
+
|
|
411
|
+
if (position) {
|
|
412
|
+
cellBlocks?.handleKeyDown(event, position);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
export const SCROLL_OVERFLOW_CLASSES = ['overflow-x-auto', 'pt-[9px]', 'pl-[9px]'];
|
|
418
|
+
|
|
419
|
+
export const enableScrollOverflow = (element: HTMLDivElement | null): void => {
|
|
420
|
+
element?.classList.add(...SCROLL_OVERFLOW_CLASSES);
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
// ─── Heading styles ─────────────────────────────────────────────────
|
|
424
|
+
|
|
425
|
+
export const updateHeadingStyles = (element: HTMLDivElement | null, withHeadings: boolean): void => {
|
|
426
|
+
if (!element) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const gridEl = element.firstElementChild as HTMLElement;
|
|
431
|
+
|
|
432
|
+
if (!gridEl) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
437
|
+
|
|
438
|
+
rows.forEach(row => {
|
|
439
|
+
row.removeAttribute('data-blok-table-heading');
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
if (withHeadings && rows.length > 0) {
|
|
443
|
+
rows[0].setAttribute('data-blok-table-heading', '');
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
export const updateHeadingColumnStyles = (element: HTMLDivElement | null, withHeadingColumn: boolean): void => {
|
|
448
|
+
if (!element) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const gridEl = element.firstElementChild as HTMLElement;
|
|
453
|
+
|
|
454
|
+
if (!gridEl) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const allCells = gridEl.querySelectorAll(`[${CELL_ATTR}]`);
|
|
459
|
+
|
|
460
|
+
allCells.forEach(cell => {
|
|
461
|
+
cell.removeAttribute('data-blok-table-heading-col');
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
if (withHeadingColumn) {
|
|
465
|
+
const rows = gridEl.querySelectorAll(`[${ROW_ATTR}]`);
|
|
466
|
+
|
|
467
|
+
rows.forEach(row => {
|
|
468
|
+
const firstCell = row.querySelector(`[${CELL_ATTR}]`);
|
|
469
|
+
|
|
470
|
+
if (firstCell) {
|
|
471
|
+
firstCell.setAttribute('data-blok-table-heading-col', '');
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
};
|
|
@@ -17,11 +17,14 @@ export class TableResize {
|
|
|
17
17
|
private gridEl: HTMLElement;
|
|
18
18
|
private colWidths: number[];
|
|
19
19
|
private onChange: (widths: number[]) => void;
|
|
20
|
+
private onDragStart: (() => void) | null;
|
|
21
|
+
private onDrag: (() => void) | null;
|
|
20
22
|
private isDragging = false;
|
|
21
23
|
private dragStartX = 0;
|
|
22
24
|
private dragColIndex = -1;
|
|
23
25
|
private startColWidth = 0;
|
|
24
26
|
private handles: HTMLElement[] = [];
|
|
27
|
+
private needsInitialApply: boolean;
|
|
25
28
|
|
|
26
29
|
private boundPointerDown: (e: PointerEvent) => void;
|
|
27
30
|
private boundPointerMove: (e: PointerEvent) => void;
|
|
@@ -43,17 +46,24 @@ export class TableResize {
|
|
|
43
46
|
});
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
constructor(gridEl: HTMLElement, colWidths: number[], onChange: (widths: number[]) => void) {
|
|
49
|
+
constructor(gridEl: HTMLElement, colWidths: number[], onChange: (widths: number[]) => void, onDragStart?: () => void, onDrag?: () => void, skipInitialApply = false) {
|
|
47
50
|
this.gridEl = gridEl;
|
|
48
51
|
this.colWidths = [...colWidths];
|
|
49
52
|
this.onChange = onChange;
|
|
53
|
+
this.onDragStart = onDragStart ?? null;
|
|
54
|
+
this.onDrag = onDrag ?? null;
|
|
55
|
+
this.needsInitialApply = skipInitialApply;
|
|
50
56
|
|
|
51
57
|
this.boundPointerDown = this.onPointerDown.bind(this);
|
|
52
58
|
this.boundPointerMove = this.onPointerMove.bind(this);
|
|
53
59
|
this.boundPointerUp = this.onPointerUp.bind(this);
|
|
54
60
|
|
|
55
61
|
this.gridEl.style.position = 'relative';
|
|
56
|
-
|
|
62
|
+
|
|
63
|
+
if (!skipInitialApply) {
|
|
64
|
+
this.applyWidths();
|
|
65
|
+
}
|
|
66
|
+
|
|
57
67
|
this.createHandles();
|
|
58
68
|
|
|
59
69
|
this.gridEl.addEventListener('pointerdown', this.boundPointerDown);
|
|
@@ -96,17 +106,20 @@ export class TableResize {
|
|
|
96
106
|
handle.style.left = `${leftPx - HANDLE_HIT_WIDTH / 2}px`;
|
|
97
107
|
handle.style.cursor = 'col-resize';
|
|
98
108
|
handle.style.zIndex = '2';
|
|
109
|
+
handle.style.background = 'linear-gradient(to right, transparent 7px, #3b82f6 7px, #3b82f6 9px, transparent 9px)';
|
|
110
|
+
handle.style.opacity = '0';
|
|
111
|
+
handle.style.transition = 'opacity 150ms ease';
|
|
99
112
|
handle.setAttribute('contenteditable', 'false');
|
|
100
113
|
|
|
101
114
|
handle.addEventListener('mouseenter', () => {
|
|
102
115
|
if (!this.isDragging) {
|
|
103
|
-
handle.style.
|
|
116
|
+
handle.style.opacity = '1';
|
|
104
117
|
}
|
|
105
118
|
});
|
|
106
119
|
|
|
107
120
|
handle.addEventListener('mouseleave', () => {
|
|
108
121
|
if (!this.isDragging) {
|
|
109
|
-
handle.style.
|
|
122
|
+
handle.style.opacity = '0';
|
|
110
123
|
}
|
|
111
124
|
});
|
|
112
125
|
|
|
@@ -139,6 +152,12 @@ export class TableResize {
|
|
|
139
152
|
|
|
140
153
|
e.preventDefault();
|
|
141
154
|
|
|
155
|
+
if (this.needsInitialApply) {
|
|
156
|
+
this.applyWidths();
|
|
157
|
+
this.updateHandlePositions();
|
|
158
|
+
this.needsInitialApply = false;
|
|
159
|
+
}
|
|
160
|
+
|
|
142
161
|
const colStr = target.getAttribute('data-col');
|
|
143
162
|
|
|
144
163
|
if (colStr === null) {
|
|
@@ -150,9 +169,10 @@ export class TableResize {
|
|
|
150
169
|
this.dragStartX = e.clientX;
|
|
151
170
|
this.startColWidth = this.colWidths[this.dragColIndex];
|
|
152
171
|
|
|
172
|
+
this.onDragStart?.();
|
|
153
173
|
this.gridEl.style.userSelect = 'none';
|
|
154
174
|
|
|
155
|
-
target.style.
|
|
175
|
+
target.style.opacity = '1';
|
|
156
176
|
|
|
157
177
|
if (target.setPointerCapture) {
|
|
158
178
|
target.setPointerCapture(e.pointerId);
|
|
@@ -174,6 +194,7 @@ export class TableResize {
|
|
|
174
194
|
this.colWidths[this.dragColIndex] = newWidth;
|
|
175
195
|
this.applyWidths();
|
|
176
196
|
this.updateHandlePositions();
|
|
197
|
+
this.onDrag?.();
|
|
177
198
|
}
|
|
178
199
|
|
|
179
200
|
private onPointerUp(): void {
|
|
@@ -187,7 +208,7 @@ export class TableResize {
|
|
|
187
208
|
const activeHandle = this.handles[this.dragColIndex];
|
|
188
209
|
|
|
189
210
|
if (activeHandle) {
|
|
190
|
-
activeHandle.style.
|
|
211
|
+
activeHandle.style.opacity = '0';
|
|
191
212
|
}
|
|
192
213
|
|
|
193
214
|
document.removeEventListener('pointermove', this.boundPointerMove);
|
|
@@ -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
|
+
};
|