@jackuait/blok 0.6.0-beta.4 → 0.6.0-beta.5
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/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-DK-97ZTf.mjs → blok-XA2L0_-K.mjs} +1216 -1178
- package/dist/chunks/{i18next-loader-CRollibS.mjs → i18next-loader-Ci2zhA-n.mjs} +1 -1
- package/dist/chunks/{index-jgHmMDND.mjs → index-R38OiQ_d.mjs} +1 -1
- package/dist/chunks/{inline-tool-convert-BIwvipPw.mjs → inline-tool-convert-e3PyuxB6.mjs} +88 -73
- package/dist/chunks/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
- package/dist/{messages-BPqWKx5Z.mjs → chunks/messages-49thXXGz.mjs} +16 -2
- 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-D00OjS2n.mjs → chunks/messages-B9fe4dQJ.mjs} +15 -1
- 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/chunks/{messages-CQj2JU2j.mjs → messages-BGxiFoZf.mjs} +15 -1
- package/dist/{messages-B5puUm7R.mjs → chunks/messages-BL0tXcDf.mjs} +15 -1
- package/dist/{messages-CyDU5lz9.mjs → chunks/messages-BMv4xwIr.mjs} +16 -2
- package/dist/chunks/{messages-CkFT2gle.mjs → messages-BNe6LuHW.mjs} +14 -0
- 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/{messages-Cyi2AMmz.mjs → chunks/messages-Bfiw5w_W.mjs} +16 -2
- 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-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
- package/dist/chunks/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
- package/dist/{messages-CrsJ1TEJ.mjs → chunks/messages-CLhcMlTc.mjs} +15 -1
- package/dist/{messages-CnvW8Slp.mjs → chunks/messages-CMkNSDTo.mjs} +17 -3
- 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/{messages-DOlC_Tty.mjs → chunks/messages-DChXyvh2.mjs} +15 -1
- 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-BlpqL8vG.mjs → chunks/messages-DjvaFRqx.mjs} +16 -2
- 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-CySyfkMU.mjs → messages-DsVNtdgM.mjs} +15 -1
- package/dist/chunks/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
- package/dist/chunks/{messages-Cu08aLS3.mjs → messages-EL5ARzmK.mjs} +16 -2
- 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-GC2PhgV3.mjs → messages-QtoE8uEv.mjs} +15 -1
- package/dist/chunks/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
- package/dist/chunks/{messages-zS1AXZ0y.mjs → messages-UX4gkere.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/{messages-BeUhMpsr.mjs → chunks/messages-wp_1b1hD.mjs} +15 -1
- package/dist/full.mjs +2 -2
- package/dist/locales.mjs +102 -88
- package/dist/{messages-C5b7hr_E.mjs → messages-1fC8IMyX.mjs} +16 -2
- package/dist/{chunks/messages-BPqWKx5Z.mjs → messages-49thXXGz.mjs} +16 -2
- 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-D00OjS2n.mjs → messages-B9fe4dQJ.mjs} +15 -1
- 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/{messages-CQj2JU2j.mjs → messages-BGxiFoZf.mjs} +15 -1
- package/dist/{chunks/messages-B5puUm7R.mjs → messages-BL0tXcDf.mjs} +15 -1
- package/dist/{chunks/messages-CyDU5lz9.mjs → messages-BMv4xwIr.mjs} +16 -2
- package/dist/{messages-CkFT2gle.mjs → messages-BNe6LuHW.mjs} +14 -0
- 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/{chunks/messages-Cyi2AMmz.mjs → messages-Bfiw5w_W.mjs} +16 -2
- 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-BiExzWJv.mjs → messages-C99mq906.mjs} +15 -1
- package/dist/{messages-BrJHUxQL.mjs → messages-CJdUsQ-c.mjs} +15 -1
- package/dist/{chunks/messages-CrsJ1TEJ.mjs → messages-CLhcMlTc.mjs} +15 -1
- package/dist/{chunks/messages-CnvW8Slp.mjs → messages-CMkNSDTo.mjs} +17 -3
- 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/{chunks/messages-DOlC_Tty.mjs → messages-DChXyvh2.mjs} +15 -1
- 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-BlpqL8vG.mjs → messages-DjvaFRqx.mjs} +16 -2
- 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-CySyfkMU.mjs → messages-DsVNtdgM.mjs} +15 -1
- package/dist/{messages-DnbbyJT3.mjs → messages-Dz9L52ol.mjs} +16 -2
- package/dist/{messages-Cu08aLS3.mjs → messages-EL5ARzmK.mjs} +16 -2
- 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-GC2PhgV3.mjs → messages-QtoE8uEv.mjs} +15 -1
- package/dist/{messages-2_xedlYw.mjs → messages-R3hUSvr3.mjs} +15 -1
- package/dist/{messages-zS1AXZ0y.mjs → messages-UX4gkere.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/{chunks/messages-BeUhMpsr.mjs → messages-wp_1b1hD.mjs} +15 -1
- package/dist/tools.mjs +854 -719
- package/package.json +5 -9
- 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 +15 -1
- 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 +14 -0
- 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 +15 -1
- 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 +16 -2
- 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 +15 -1
- package/src/components/i18n/locales/ms/messages.json +16 -2
- package/src/components/i18n/locales/my/messages.json +16 -2
- package/src/components/i18n/locales/ne/messages.json +15 -1
- 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 +15 -1
- 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 +16 -2
- package/src/components/i18n/locales/te/messages.json +15 -1
- package/src/components/i18n/locales/th/messages.json +15 -1
- 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 +16 -2
- package/src/components/i18n/locales/yi/messages.json +16 -2
- package/src/components/i18n/locales/zh/messages.json +15 -1
- package/src/components/modules/api/blocks.ts +17 -2
- package/src/components/modules/blockEvents/composers/markdownShortcuts.ts +12 -1
- package/src/components/modules/toolbar/index.ts +29 -7
- package/src/components/modules/ui.ts +46 -68
- package/src/components/modules/uiControllers/controllers/blockHover.ts +40 -61
- package/src/components/ui/toolbox.ts +41 -6
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +3 -1
- package/src/components/utils/popover/popover-desktop.ts +27 -8
- package/src/tools/table/index.ts +67 -70
- package/src/tools/table/table-add-controls.ts +25 -7
- package/src/tools/table/table-cell-blocks.ts +62 -0
- package/src/tools/table/table-cell-selection.ts +70 -46
- package/src/tools/table/table-core.ts +20 -15
- package/src/tools/table/table-grip-visuals.ts +4 -4
- package/src/tools/table/table-operations.ts +22 -12
- 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 +91 -182
- 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 +2 -0
- package/types/utils/popover/popover.d.ts +7 -0
|
@@ -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
|
|
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
|
|
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(`${
|
|
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
|
|
60
|
+
Object.assign(grip.style, { height: `${GRIP_HOVER_SIZE}px` });
|
|
61
61
|
} else {
|
|
62
|
-
grip.style
|
|
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
|
|
82
|
+
Object.assign(grip.style, { height: `${pillSize}px` });
|
|
83
83
|
} else {
|
|
84
|
-
grip.style
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
313
|
-
|
|
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
|
-
|
|
318
|
-
|
|
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
|
+
};
|