@jackuait/blok 0.7.0-beta.1 → 0.7.0-beta.3
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 +20 -4
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-ob9Fwr1L.mjs → blok-BlyYiZTm.mjs} +1840 -1654
- package/dist/chunks/{inline-tool-convert-CvFW2iie.mjs → constants-DEy4jBO5.mjs} +316 -297
- package/dist/chunks/{i18next-loader-Bu3vFvye.mjs → i18next-loader-Cfbv-x6v.mjs} +1 -1
- package/dist/chunks/index-Cu1w-sLZ.mjs +130 -0
- package/dist/chunks/{messages-D2NOpHn9.mjs → messages-0Pxnqd4N.mjs} +7 -0
- package/dist/chunks/{messages-GSByFygY.mjs → messages-0ZXYUq7S.mjs} +7 -0
- package/dist/{messages-BUl_Rcnj.mjs → chunks/messages-2OD2uUDS.mjs} +9 -2
- package/dist/{messages-CgTq3QhU.mjs → chunks/messages-7cEMfYzh.mjs} +7 -0
- package/dist/{messages-DlJbPF2T.mjs → chunks/messages-8mwfda1Q.mjs} +7 -0
- package/dist/{messages-D9ndgBnU.mjs → chunks/messages-B-FqWsBM.mjs} +7 -0
- package/dist/{messages-B217znr-.mjs → chunks/messages-B1jzqWiQ.mjs} +7 -0
- package/dist/{messages-BcpCubnC.mjs → chunks/messages-B5wk4Ezz.mjs} +7 -0
- package/dist/chunks/{messages-DRXWF0PV.mjs → messages-BAZ5Ld8x.mjs} +7 -0
- package/dist/{messages-CRJ_mchV.mjs → chunks/messages-BBhGp198.mjs} +7 -0
- package/dist/chunks/{messages-yHcs38yI.mjs → messages-BC9IjIb7.mjs} +7 -0
- package/dist/chunks/{messages-Cr94GzbX.mjs → messages-BFEmpeV-.mjs} +7 -0
- package/dist/chunks/{messages-ucTVgS5G.mjs → messages-BGqzTZy0.mjs} +7 -0
- package/dist/{messages-begYOTgC.mjs → chunks/messages-BICs1abK.mjs} +7 -0
- package/dist/chunks/{messages-DVQvl8Qj.mjs → messages-BJX6rOnd.mjs} +7 -0
- package/dist/chunks/{messages-Chb7k3Rg.mjs → messages-BL2bXRhN.mjs} +7 -0
- package/dist/{messages-Phkd7XmE.mjs → chunks/messages-BMs5qdlH.mjs} +7 -0
- package/dist/chunks/{messages-Cjjo7yHR.mjs → messages-BRsjUNwB.mjs} +7 -0
- package/dist/chunks/{messages-D4qqwVgQ.mjs → messages-BSqV8OUR.mjs} +7 -0
- package/dist/chunks/{messages-DviiFSv2.mjs → messages-BTqu3DfG.mjs} +7 -0
- package/dist/chunks/{messages-0AbcLMLm.mjs → messages-BXnDEsur.mjs} +7 -0
- package/dist/{messages-CmR9ftc_.mjs → chunks/messages-BYcre4-6.mjs} +7 -0
- package/dist/{messages-wmi-iFkH.mjs → chunks/messages-BZ9LRJf-.mjs} +7 -0
- package/dist/chunks/{messages-D00x4S8o.mjs → messages-BgypBy7y.mjs} +7 -0
- package/dist/{messages-96kNZDll.mjs → chunks/messages-BsuGf70G.mjs} +7 -0
- package/dist/chunks/{messages-v3GipbFl.mjs → messages-BwaoF4lQ.mjs} +7 -0
- package/dist/{messages-DDTQgImT.mjs → chunks/messages-C1l8_7-y.mjs} +7 -0
- package/dist/{messages-B1FZ8lxU.mjs → chunks/messages-C5NA_r9v.mjs} +7 -0
- package/dist/{messages-Cs8zmZ3L.mjs → chunks/messages-C6zgZ5pA.mjs} +7 -0
- package/dist/chunks/{messages-ZjUAIWb1.mjs → messages-CAo5ghFI.mjs} +7 -0
- package/dist/{messages-D5S1Dnpm.mjs → chunks/messages-CH9qlJ9I.mjs} +7 -0
- package/dist/{messages-D7u2bmP2.mjs → chunks/messages-CI0HqAeS.mjs} +7 -0
- package/dist/{messages-DH_jBeED.mjs → chunks/messages-CJJtms9k.mjs} +7 -0
- package/dist/{messages-CDBLbUOQ.mjs → chunks/messages-CM2hJqk6.mjs} +7 -0
- package/dist/chunks/{messages-8IPXkrDl.mjs → messages-CRMiDPIQ.mjs} +7 -0
- package/dist/chunks/{messages-Dzzn6XoD.mjs → messages-CWsZuBj1.mjs} +7 -0
- package/dist/chunks/{messages-CW4c4cRk.mjs → messages-C_gLHo6A.mjs} +7 -0
- package/dist/{messages-CH4hrauY.mjs → chunks/messages-Cbu-NUDn.mjs} +7 -0
- package/dist/{messages-RonBBCnh.mjs → chunks/messages-Cjb_MCeh.mjs} +7 -0
- package/dist/chunks/{messages-BJ6zrz2j.mjs → messages-ClXYO9Wn.mjs} +7 -0
- package/dist/chunks/{messages-CrCYPCk3.mjs → messages-CsH20vhP.mjs} +7 -0
- package/dist/{messages-CzK0LEhb.mjs → chunks/messages-CsjAGhzA.mjs} +7 -0
- package/dist/chunks/{messages-BZlmVRwn.mjs → messages-Cx7VKFOE.mjs} +7 -0
- package/dist/chunks/{messages-0E0AkrNu.mjs → messages-D3JeBwxo.mjs} +7 -0
- package/dist/chunks/{messages-D85FqxgY.mjs → messages-D541fieJ.mjs} +7 -0
- package/dist/{messages-4v4MuVEc.mjs → chunks/messages-D7XPdglc.mjs} +7 -0
- package/dist/{messages-BC8IN4Bf.mjs → chunks/messages-DBhylfvt.mjs} +7 -0
- package/dist/chunks/{messages-B8WNljW3.mjs → messages-DCA120lW.mjs} +7 -0
- package/dist/chunks/{messages-Cr49Nt3U.mjs → messages-DCf_xZMN.mjs} +7 -0
- package/dist/chunks/{messages-VDriF5Qy.mjs → messages-DDwXKCpe.mjs} +7 -0
- package/dist/{messages-b1EdvUm0.mjs → chunks/messages-DNKDlxcy.mjs} +7 -0
- package/dist/{messages-L_kl2Qvh.mjs → chunks/messages-DPvEjrGK.mjs} +7 -0
- package/dist/chunks/{messages-62v-CLC-.mjs → messages-DQ-AkNxA.mjs} +7 -0
- package/dist/chunks/{messages-DdK-nFGm.mjs → messages-DVuvkNap.mjs} +7 -0
- package/dist/{messages-DnVlmiNT.mjs → chunks/messages-DaglyqUT.mjs} +7 -0
- package/dist/{messages-Bm-E4iRC.mjs → chunks/messages-Di0bAfwA.mjs} +7 -0
- package/dist/{messages-D1mn7Zd5.mjs → chunks/messages-DuLct0Yr.mjs} +7 -0
- package/dist/{messages-8DeO60Oo.mjs → chunks/messages-DzEYYhZh.mjs} +7 -0
- package/dist/chunks/{messages-CfiyT2Wi.mjs → messages-DznNGAB2.mjs} +7 -0
- package/dist/chunks/{messages-DXktiao_.mjs → messages-DzoIzyu8.mjs} +7 -0
- package/dist/{messages-C_4otP7U.mjs → chunks/messages-QYOGmket.mjs} +7 -0
- package/dist/chunks/{messages-nefz1S71.mjs → messages-cEjGDAgI.mjs} +7 -0
- package/dist/chunks/{messages-jrncnb-H.mjs → messages-ddhvrdpE.mjs} +7 -0
- package/dist/chunks/{messages-DzqM3Fel.mjs → messages-mwfNK5nZ.mjs} +7 -0
- package/dist/chunks/{messages-Cl6ayUaq.mjs → messages-nG_vNDte.mjs} +7 -0
- package/dist/{messages-C4jL-90N.mjs → chunks/messages-tDq3Owh7.mjs} +7 -0
- package/dist/{messages-BI43k_BD.mjs → chunks/messages-x6VJVZKx.mjs} +7 -0
- package/dist/full.mjs +2 -2
- package/dist/locales.mjs +87 -80
- package/dist/{messages-D2NOpHn9.mjs → messages-0Pxnqd4N.mjs} +7 -0
- package/dist/{messages-GSByFygY.mjs → messages-0ZXYUq7S.mjs} +7 -0
- package/dist/{chunks/messages-BUl_Rcnj.mjs → messages-2OD2uUDS.mjs} +9 -2
- package/dist/{chunks/messages-CgTq3QhU.mjs → messages-7cEMfYzh.mjs} +7 -0
- package/dist/{chunks/messages-DlJbPF2T.mjs → messages-8mwfda1Q.mjs} +7 -0
- package/dist/{chunks/messages-D9ndgBnU.mjs → messages-B-FqWsBM.mjs} +7 -0
- package/dist/{chunks/messages-B217znr-.mjs → messages-B1jzqWiQ.mjs} +7 -0
- package/dist/{chunks/messages-BcpCubnC.mjs → messages-B5wk4Ezz.mjs} +7 -0
- package/dist/{messages-DRXWF0PV.mjs → messages-BAZ5Ld8x.mjs} +7 -0
- package/dist/{chunks/messages-CRJ_mchV.mjs → messages-BBhGp198.mjs} +7 -0
- package/dist/{messages-yHcs38yI.mjs → messages-BC9IjIb7.mjs} +7 -0
- package/dist/{messages-Cr94GzbX.mjs → messages-BFEmpeV-.mjs} +7 -0
- package/dist/{messages-ucTVgS5G.mjs → messages-BGqzTZy0.mjs} +7 -0
- package/dist/{chunks/messages-begYOTgC.mjs → messages-BICs1abK.mjs} +7 -0
- package/dist/{messages-DVQvl8Qj.mjs → messages-BJX6rOnd.mjs} +7 -0
- package/dist/{messages-Chb7k3Rg.mjs → messages-BL2bXRhN.mjs} +7 -0
- package/dist/{chunks/messages-Phkd7XmE.mjs → messages-BMs5qdlH.mjs} +7 -0
- package/dist/{messages-Cjjo7yHR.mjs → messages-BRsjUNwB.mjs} +7 -0
- package/dist/{messages-D4qqwVgQ.mjs → messages-BSqV8OUR.mjs} +7 -0
- package/dist/{messages-DviiFSv2.mjs → messages-BTqu3DfG.mjs} +7 -0
- package/dist/{messages-0AbcLMLm.mjs → messages-BXnDEsur.mjs} +7 -0
- package/dist/{chunks/messages-CmR9ftc_.mjs → messages-BYcre4-6.mjs} +7 -0
- package/dist/{chunks/messages-wmi-iFkH.mjs → messages-BZ9LRJf-.mjs} +7 -0
- package/dist/{messages-D00x4S8o.mjs → messages-BgypBy7y.mjs} +7 -0
- package/dist/{chunks/messages-96kNZDll.mjs → messages-BsuGf70G.mjs} +7 -0
- package/dist/{messages-v3GipbFl.mjs → messages-BwaoF4lQ.mjs} +7 -0
- package/dist/{chunks/messages-DDTQgImT.mjs → messages-C1l8_7-y.mjs} +7 -0
- package/dist/{chunks/messages-B1FZ8lxU.mjs → messages-C5NA_r9v.mjs} +7 -0
- package/dist/{chunks/messages-Cs8zmZ3L.mjs → messages-C6zgZ5pA.mjs} +7 -0
- package/dist/{messages-ZjUAIWb1.mjs → messages-CAo5ghFI.mjs} +7 -0
- package/dist/{chunks/messages-D5S1Dnpm.mjs → messages-CH9qlJ9I.mjs} +7 -0
- package/dist/{chunks/messages-D7u2bmP2.mjs → messages-CI0HqAeS.mjs} +7 -0
- package/dist/{chunks/messages-DH_jBeED.mjs → messages-CJJtms9k.mjs} +7 -0
- package/dist/{chunks/messages-CDBLbUOQ.mjs → messages-CM2hJqk6.mjs} +7 -0
- package/dist/{messages-8IPXkrDl.mjs → messages-CRMiDPIQ.mjs} +7 -0
- package/dist/{messages-Dzzn6XoD.mjs → messages-CWsZuBj1.mjs} +7 -0
- package/dist/{messages-CW4c4cRk.mjs → messages-C_gLHo6A.mjs} +7 -0
- package/dist/{chunks/messages-CH4hrauY.mjs → messages-Cbu-NUDn.mjs} +7 -0
- package/dist/{chunks/messages-RonBBCnh.mjs → messages-Cjb_MCeh.mjs} +7 -0
- package/dist/{messages-BJ6zrz2j.mjs → messages-ClXYO9Wn.mjs} +7 -0
- package/dist/{messages-CrCYPCk3.mjs → messages-CsH20vhP.mjs} +7 -0
- package/dist/{chunks/messages-CzK0LEhb.mjs → messages-CsjAGhzA.mjs} +7 -0
- package/dist/{messages-BZlmVRwn.mjs → messages-Cx7VKFOE.mjs} +7 -0
- package/dist/{messages-0E0AkrNu.mjs → messages-D3JeBwxo.mjs} +7 -0
- package/dist/{messages-D85FqxgY.mjs → messages-D541fieJ.mjs} +7 -0
- package/dist/{chunks/messages-4v4MuVEc.mjs → messages-D7XPdglc.mjs} +7 -0
- package/dist/{chunks/messages-BC8IN4Bf.mjs → messages-DBhylfvt.mjs} +7 -0
- package/dist/{messages-B8WNljW3.mjs → messages-DCA120lW.mjs} +7 -0
- package/dist/{messages-Cr49Nt3U.mjs → messages-DCf_xZMN.mjs} +7 -0
- package/dist/{messages-VDriF5Qy.mjs → messages-DDwXKCpe.mjs} +7 -0
- package/dist/{chunks/messages-b1EdvUm0.mjs → messages-DNKDlxcy.mjs} +7 -0
- package/dist/{chunks/messages-L_kl2Qvh.mjs → messages-DPvEjrGK.mjs} +7 -0
- package/dist/{messages-62v-CLC-.mjs → messages-DQ-AkNxA.mjs} +7 -0
- package/dist/{messages-DdK-nFGm.mjs → messages-DVuvkNap.mjs} +7 -0
- package/dist/{chunks/messages-DnVlmiNT.mjs → messages-DaglyqUT.mjs} +7 -0
- package/dist/{chunks/messages-Bm-E4iRC.mjs → messages-Di0bAfwA.mjs} +7 -0
- package/dist/{chunks/messages-D1mn7Zd5.mjs → messages-DuLct0Yr.mjs} +7 -0
- package/dist/{chunks/messages-8DeO60Oo.mjs → messages-DzEYYhZh.mjs} +7 -0
- package/dist/{messages-CfiyT2Wi.mjs → messages-DznNGAB2.mjs} +7 -0
- package/dist/{messages-DXktiao_.mjs → messages-DzoIzyu8.mjs} +7 -0
- package/dist/{chunks/messages-C_4otP7U.mjs → messages-QYOGmket.mjs} +7 -0
- package/dist/{messages-nefz1S71.mjs → messages-cEjGDAgI.mjs} +7 -0
- package/dist/{messages-jrncnb-H.mjs → messages-ddhvrdpE.mjs} +7 -0
- package/dist/{messages-DzqM3Fel.mjs → messages-mwfNK5nZ.mjs} +7 -0
- package/dist/{messages-Cl6ayUaq.mjs → messages-nG_vNDte.mjs} +7 -0
- package/dist/{chunks/messages-C4jL-90N.mjs → messages-tDq3Owh7.mjs} +7 -0
- package/dist/{chunks/messages-BI43k_BD.mjs → messages-x6VJVZKx.mjs} +7 -0
- package/dist/tools.mjs +443 -338
- package/package.json +1 -1
- package/src/components/i18n/locales/am/messages.json +7 -0
- package/src/components/i18n/locales/ar/messages.json +7 -0
- package/src/components/i18n/locales/az/messages.json +7 -0
- package/src/components/i18n/locales/bg/messages.json +7 -0
- package/src/components/i18n/locales/bn/messages.json +7 -0
- package/src/components/i18n/locales/bs/messages.json +7 -0
- package/src/components/i18n/locales/cs/messages.json +7 -0
- package/src/components/i18n/locales/da/messages.json +7 -0
- package/src/components/i18n/locales/de/messages.json +7 -0
- package/src/components/i18n/locales/dv/messages.json +7 -0
- package/src/components/i18n/locales/el/messages.json +7 -0
- package/src/components/i18n/locales/en/messages.json +7 -0
- package/src/components/i18n/locales/es/messages.json +7 -0
- package/src/components/i18n/locales/et/messages.json +7 -0
- package/src/components/i18n/locales/fa/messages.json +7 -0
- package/src/components/i18n/locales/fi/messages.json +7 -0
- package/src/components/i18n/locales/fil/messages.json +7 -0
- package/src/components/i18n/locales/fr/messages.json +7 -0
- package/src/components/i18n/locales/gu/messages.json +7 -0
- package/src/components/i18n/locales/he/messages.json +7 -0
- package/src/components/i18n/locales/hi/messages.json +7 -0
- package/src/components/i18n/locales/hr/messages.json +7 -0
- package/src/components/i18n/locales/hu/messages.json +7 -0
- package/src/components/i18n/locales/hy/messages.json +7 -0
- package/src/components/i18n/locales/id/messages.json +7 -0
- package/src/components/i18n/locales/it/messages.json +7 -0
- package/src/components/i18n/locales/ja/messages.json +7 -0
- package/src/components/i18n/locales/ka/messages.json +7 -0
- package/src/components/i18n/locales/km/messages.json +7 -0
- package/src/components/i18n/locales/kn/messages.json +7 -0
- package/src/components/i18n/locales/ko/messages.json +7 -0
- package/src/components/i18n/locales/ku/messages.json +7 -0
- package/src/components/i18n/locales/lo/messages.json +7 -0
- package/src/components/i18n/locales/lt/messages.json +7 -0
- package/src/components/i18n/locales/lv/messages.json +7 -0
- package/src/components/i18n/locales/mk/messages.json +7 -0
- package/src/components/i18n/locales/ml/messages.json +7 -0
- package/src/components/i18n/locales/mn/messages.json +7 -0
- package/src/components/i18n/locales/mr/messages.json +7 -0
- package/src/components/i18n/locales/ms/messages.json +7 -0
- package/src/components/i18n/locales/my/messages.json +7 -0
- package/src/components/i18n/locales/ne/messages.json +7 -0
- package/src/components/i18n/locales/nl/messages.json +7 -0
- package/src/components/i18n/locales/no/messages.json +7 -0
- package/src/components/i18n/locales/pa/messages.json +7 -0
- package/src/components/i18n/locales/pl/messages.json +7 -0
- package/src/components/i18n/locales/ps/messages.json +7 -0
- package/src/components/i18n/locales/pt/messages.json +7 -0
- package/src/components/i18n/locales/ro/messages.json +7 -0
- package/src/components/i18n/locales/ru/messages.json +7 -0
- package/src/components/i18n/locales/sd/messages.json +7 -0
- package/src/components/i18n/locales/si/messages.json +7 -0
- package/src/components/i18n/locales/sk/messages.json +7 -0
- package/src/components/i18n/locales/sl/messages.json +7 -0
- package/src/components/i18n/locales/sq/messages.json +7 -0
- package/src/components/i18n/locales/sr/messages.json +7 -0
- package/src/components/i18n/locales/sv/messages.json +7 -0
- package/src/components/i18n/locales/sw/messages.json +7 -0
- package/src/components/i18n/locales/ta/messages.json +7 -0
- package/src/components/i18n/locales/te/messages.json +7 -0
- package/src/components/i18n/locales/th/messages.json +7 -0
- package/src/components/i18n/locales/tr/messages.json +7 -0
- package/src/components/i18n/locales/ug/messages.json +7 -0
- package/src/components/i18n/locales/uk/messages.json +7 -0
- package/src/components/i18n/locales/ur/messages.json +7 -0
- package/src/components/i18n/locales/vi/messages.json +7 -0
- package/src/components/i18n/locales/yi/messages.json +7 -0
- package/src/components/i18n/locales/zh/messages.json +7 -0
- package/src/components/modules/blockEvents/composers/keyboardNavigation.ts +44 -2
- package/src/components/modules/blockEvents/index.ts +1 -3
- package/src/components/modules/blockManager/blockManager.ts +16 -0
- package/src/components/modules/blockManager/operations.ts +106 -9
- package/src/components/modules/blockSelection.ts +2 -0
- package/src/components/modules/caret.ts +49 -4
- package/src/components/modules/drag/DragController.ts +34 -2
- package/src/components/modules/paste/handlers/blok-data-handler.ts +50 -3
- package/src/components/modules/toolbar/index.ts +11 -16
- package/src/components/modules/ui.ts +22 -0
- package/src/components/ui/toolbox.ts +19 -3
- package/src/components/utils/notifier/draw.ts +116 -14
- package/src/components/utils/notifier/index.ts +31 -4
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +2 -2
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +6 -7
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +2 -2
- package/src/components/utils/popover/popover-abstract.ts +2 -0
- package/src/components/utils/popover/popover-desktop.ts +39 -2
- package/src/stories/Block.stories.ts +21 -0
- package/src/stories/EditorModes.stories.ts +19 -0
- package/src/stories/InlineToolbar.stories.ts +41 -9
- package/src/stories/MarkerColors.stories.ts +48 -52
- package/src/stories/Notifier.stories.ts +19 -1
- package/src/stories/Placeholder.stories.ts +12 -0
- package/src/stories/Popover.stories.ts +26 -0
- package/src/stories/Selection.stories.ts +6 -0
- package/src/stories/Table.stories.ts +12 -0
- package/src/stories/Toolbar.stories.ts +9 -0
- package/src/stories/Toolbox.stories.ts +4 -0
- package/src/stories/Tooltip.stories.ts +6 -0
- package/src/stories/helpers.ts +63 -8
- package/src/styles/main.css +46 -0
- package/src/tools/header/index.ts +121 -22
- package/src/tools/table/index.ts +2 -3
- package/src/tools/table/table-add-controls.ts +29 -1
- package/src/tools/table/table-cell-blocks.ts +93 -0
- package/src/tools/toggle/constants.ts +2 -2
- package/src/tools/toggle/dom-builder.ts +32 -4
- package/src/tools/toggle/index.ts +26 -4
- package/src/tools/toggle/toggle-keyboard.ts +19 -2
- package/src/tools/toggle/toggle-lifecycle.ts +1 -0
- package/src/tools/toggle/toggle-shortcuts.ts +18 -8
- package/types/utils/popover/popover.d.ts +8 -0
- package/dist/chunks/index-CZmRzRIX.mjs +0 -78
|
@@ -81,6 +81,9 @@ export const PlaceholderOnlyOnFocus: Story = {
|
|
|
81
81
|
placeholder: DEFAULT_PLACEHOLDER,
|
|
82
82
|
data: undefined,
|
|
83
83
|
},
|
|
84
|
+
parameters: {
|
|
85
|
+
chromatic: { delay: 500 },
|
|
86
|
+
},
|
|
84
87
|
play: async ({ canvasElement, step }) => {
|
|
85
88
|
await step('Wait for editor to initialize', async () => {
|
|
86
89
|
await waitFor(
|
|
@@ -153,6 +156,9 @@ export const TypeAndClearPlaceholder: Story = {
|
|
|
153
156
|
placeholder: DEFAULT_PLACEHOLDER,
|
|
154
157
|
data: undefined,
|
|
155
158
|
},
|
|
159
|
+
parameters: {
|
|
160
|
+
chromatic: { delay: 500 },
|
|
161
|
+
},
|
|
156
162
|
play: async ({ canvasElement, step }) => {
|
|
157
163
|
await step('Wait for editor to initialize', async () => {
|
|
158
164
|
await waitFor(
|
|
@@ -229,6 +235,9 @@ export const MultipleBlocksPlaceholder: Story = {
|
|
|
229
235
|
],
|
|
230
236
|
},
|
|
231
237
|
},
|
|
238
|
+
parameters: {
|
|
239
|
+
chromatic: { delay: 500 },
|
|
240
|
+
},
|
|
232
241
|
play: async ({ canvasElement, step }) => {
|
|
233
242
|
await step('Wait for editor to initialize', async () => {
|
|
234
243
|
await waitFor(
|
|
@@ -274,6 +283,9 @@ export const PlaceholderWithToolboxOpen: Story = {
|
|
|
274
283
|
placeholder: DEFAULT_PLACEHOLDER,
|
|
275
284
|
data: undefined,
|
|
276
285
|
},
|
|
286
|
+
parameters: {
|
|
287
|
+
chromatic: { delay: 500 },
|
|
288
|
+
},
|
|
277
289
|
play: async ({ canvasElement, step }) => {
|
|
278
290
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
279
291
|
await waitFor(
|
|
@@ -56,6 +56,7 @@ const meta: Meta<PopoverArgs> = {
|
|
|
56
56
|
tags: ['autodocs'],
|
|
57
57
|
args: {
|
|
58
58
|
minHeight: 350,
|
|
59
|
+
width: 450,
|
|
59
60
|
data: sampleData,
|
|
60
61
|
},
|
|
61
62
|
render: createEditor,
|
|
@@ -88,6 +89,9 @@ export const ItemHoverState: Story = {
|
|
|
88
89
|
args: {
|
|
89
90
|
data: sampleData,
|
|
90
91
|
},
|
|
92
|
+
parameters: {
|
|
93
|
+
chromatic: { delay: 500 },
|
|
94
|
+
},
|
|
91
95
|
play: async ({ canvasElement, step }) => {
|
|
92
96
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
93
97
|
await waitFor(
|
|
@@ -151,6 +155,9 @@ export const ItemFocusedState: Story = {
|
|
|
151
155
|
args: {
|
|
152
156
|
data: sampleData,
|
|
153
157
|
},
|
|
158
|
+
parameters: {
|
|
159
|
+
chromatic: { delay: 500 },
|
|
160
|
+
},
|
|
154
161
|
play: async ({ canvasElement, step }) => {
|
|
155
162
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
156
163
|
await waitFor(
|
|
@@ -230,6 +237,9 @@ export const BlockTunesPopover: Story = {
|
|
|
230
237
|
args: {
|
|
231
238
|
data: sampleData,
|
|
232
239
|
},
|
|
240
|
+
parameters: {
|
|
241
|
+
chromatic: { delay: 500 },
|
|
242
|
+
},
|
|
233
243
|
play: async ({ canvasElement, step }) => {
|
|
234
244
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
235
245
|
await waitFor(
|
|
@@ -289,6 +299,9 @@ export const ConfirmationState: Story = {
|
|
|
289
299
|
args: {
|
|
290
300
|
data: sampleData,
|
|
291
301
|
},
|
|
302
|
+
parameters: {
|
|
303
|
+
chromatic: { delay: 500 },
|
|
304
|
+
},
|
|
292
305
|
play: async ({ canvasElement, step }) => {
|
|
293
306
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
294
307
|
await waitFor(
|
|
@@ -382,6 +395,9 @@ export const SearchFiltering: Story = {
|
|
|
382
395
|
args: {
|
|
383
396
|
data: sampleData,
|
|
384
397
|
},
|
|
398
|
+
parameters: {
|
|
399
|
+
chromatic: { delay: 500 },
|
|
400
|
+
},
|
|
385
401
|
play: async ({ canvasElement, step }) => {
|
|
386
402
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
387
403
|
await waitFor(
|
|
@@ -460,6 +476,9 @@ export const DisabledItem: Story = {
|
|
|
460
476
|
args: {
|
|
461
477
|
data: sampleData,
|
|
462
478
|
},
|
|
479
|
+
parameters: {
|
|
480
|
+
chromatic: { delay: 500 },
|
|
481
|
+
},
|
|
463
482
|
play: async ({ canvasElement, step }) => {
|
|
464
483
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
465
484
|
await waitFor(
|
|
@@ -538,6 +557,7 @@ export const MobilePopover: Story = {
|
|
|
538
557
|
args: {
|
|
539
558
|
data: sampleData,
|
|
540
559
|
minHeight: 400,
|
|
560
|
+
width: 0,
|
|
541
561
|
},
|
|
542
562
|
parameters: {
|
|
543
563
|
viewport: {
|
|
@@ -545,6 +565,7 @@ export const MobilePopover: Story = {
|
|
|
545
565
|
},
|
|
546
566
|
chromatic: {
|
|
547
567
|
viewports: [375],
|
|
568
|
+
delay: 500,
|
|
548
569
|
},
|
|
549
570
|
},
|
|
550
571
|
play: async ({ canvasElement, step }) => {
|
|
@@ -603,6 +624,7 @@ export const MobileOverlay: Story = {
|
|
|
603
624
|
args: {
|
|
604
625
|
data: sampleData,
|
|
605
626
|
minHeight: 400,
|
|
627
|
+
width: 0,
|
|
606
628
|
},
|
|
607
629
|
parameters: {
|
|
608
630
|
viewport: {
|
|
@@ -610,6 +632,7 @@ export const MobileOverlay: Story = {
|
|
|
610
632
|
},
|
|
611
633
|
chromatic: {
|
|
612
634
|
viewports: [375],
|
|
635
|
+
delay: 500,
|
|
613
636
|
},
|
|
614
637
|
},
|
|
615
638
|
play: async ({ canvasElement, step }) => {
|
|
@@ -680,6 +703,9 @@ export const BlockSettingsConvertToOpen: Story = {
|
|
|
680
703
|
header: Header,
|
|
681
704
|
},
|
|
682
705
|
},
|
|
706
|
+
parameters: {
|
|
707
|
+
chromatic: { delay: 500 },
|
|
708
|
+
},
|
|
683
709
|
play: async ({ canvasElement, step }) => {
|
|
684
710
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
685
711
|
await waitFor(
|
|
@@ -82,6 +82,9 @@ export const MultiStringSelectionWithLinkInput: Story = {
|
|
|
82
82
|
args: {
|
|
83
83
|
data: multiLineData,
|
|
84
84
|
},
|
|
85
|
+
parameters: {
|
|
86
|
+
chromatic: { delay: 500 },
|
|
87
|
+
},
|
|
85
88
|
play: async ({ canvasElement, step }) => {
|
|
86
89
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
87
90
|
await waitFor(
|
|
@@ -169,6 +172,9 @@ export const CrossBlockSelectionWithLinkInput: Story = {
|
|
|
169
172
|
args: {
|
|
170
173
|
data: multiBlockData,
|
|
171
174
|
},
|
|
175
|
+
parameters: {
|
|
176
|
+
chromatic: { delay: 500 },
|
|
177
|
+
},
|
|
172
178
|
play: async ({ canvasElement, step }) => {
|
|
173
179
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
174
180
|
await waitFor(
|
|
@@ -596,6 +596,7 @@ export const ColumnGripsVisible: Story = {
|
|
|
596
596
|
],
|
|
597
597
|
},
|
|
598
598
|
},
|
|
599
|
+
parameters: { chromatic: { delay: 500 } },
|
|
599
600
|
play: async ({ canvasElement, step }) => {
|
|
600
601
|
await step('Wait for table', async () => {
|
|
601
602
|
await waitForTable(canvasElement);
|
|
@@ -643,6 +644,7 @@ export const RowGripsVisible: Story = {
|
|
|
643
644
|
],
|
|
644
645
|
},
|
|
645
646
|
},
|
|
647
|
+
parameters: { chromatic: { delay: 500 } },
|
|
646
648
|
play: async ({ canvasElement, step }) => {
|
|
647
649
|
await step('Wait for table', async () => {
|
|
648
650
|
await waitForTable(canvasElement);
|
|
@@ -689,6 +691,7 @@ export const ColumnGripActive: Story = {
|
|
|
689
691
|
],
|
|
690
692
|
},
|
|
691
693
|
},
|
|
694
|
+
parameters: { chromatic: { delay: 500 } },
|
|
692
695
|
play: async ({ canvasElement, step }) => {
|
|
693
696
|
await step('Wait for table', async () => {
|
|
694
697
|
await waitForTable(canvasElement);
|
|
@@ -736,6 +739,7 @@ export const RowGripActive: Story = {
|
|
|
736
739
|
],
|
|
737
740
|
},
|
|
738
741
|
},
|
|
742
|
+
parameters: { chromatic: { delay: 500 } },
|
|
739
743
|
play: async ({ canvasElement, step }) => {
|
|
740
744
|
await step('Wait for table', async () => {
|
|
741
745
|
await waitForTable(canvasElement);
|
|
@@ -786,6 +790,7 @@ export const CellFocused: Story = {
|
|
|
786
790
|
],
|
|
787
791
|
},
|
|
788
792
|
},
|
|
793
|
+
parameters: { chromatic: { delay: 500 } },
|
|
789
794
|
play: async ({ canvasElement, step }) => {
|
|
790
795
|
await step('Wait for table and toolbar', async () => {
|
|
791
796
|
await waitForTable(canvasElement);
|
|
@@ -841,6 +846,7 @@ export const MultiCellSelection: Story = {
|
|
|
841
846
|
],
|
|
842
847
|
},
|
|
843
848
|
},
|
|
849
|
+
parameters: { chromatic: { delay: 500 } },
|
|
844
850
|
play: async ({ canvasElement, step }) => {
|
|
845
851
|
await step('Wait for table', async () => {
|
|
846
852
|
await waitForTable(canvasElement);
|
|
@@ -881,6 +887,7 @@ export const SelectionPillExpanded: Story = {
|
|
|
881
887
|
],
|
|
882
888
|
},
|
|
883
889
|
},
|
|
890
|
+
parameters: { chromatic: { delay: 500 } },
|
|
884
891
|
play: async ({ canvasElement, step }) => {
|
|
885
892
|
await step('Wait for table', async () => {
|
|
886
893
|
await waitForTable(canvasElement);
|
|
@@ -972,6 +979,7 @@ export const ScrollOverflow: Story = {
|
|
|
972
979
|
],
|
|
973
980
|
},
|
|
974
981
|
},
|
|
982
|
+
parameters: { chromatic: { delay: 500 } },
|
|
975
983
|
play: async ({ canvasElement, step }) => {
|
|
976
984
|
await step('Wait for table', async () => {
|
|
977
985
|
await waitForTable(canvasElement);
|
|
@@ -1476,6 +1484,7 @@ export const AddButtonsVisible: Story = {
|
|
|
1476
1484
|
],
|
|
1477
1485
|
},
|
|
1478
1486
|
},
|
|
1487
|
+
parameters: { chromatic: { delay: 500 } },
|
|
1479
1488
|
play: async ({ canvasElement, step }) => {
|
|
1480
1489
|
await step('Wait for table', async () => {
|
|
1481
1490
|
await waitForTable(canvasElement);
|
|
@@ -1523,6 +1532,7 @@ export const ResizeHandlesVisible: Story = {
|
|
|
1523
1532
|
],
|
|
1524
1533
|
},
|
|
1525
1534
|
},
|
|
1535
|
+
parameters: { chromatic: { delay: 500 } },
|
|
1526
1536
|
play: async ({ canvasElement, step }) => {
|
|
1527
1537
|
await step('Wait for table', async () => {
|
|
1528
1538
|
await waitForTable(canvasElement);
|
|
@@ -1578,6 +1588,7 @@ export const RowDragInProgress: Story = {
|
|
|
1578
1588
|
],
|
|
1579
1589
|
},
|
|
1580
1590
|
},
|
|
1591
|
+
parameters: { chromatic: { delay: 500 } },
|
|
1581
1592
|
play: async ({ canvasElement, step }) => {
|
|
1582
1593
|
await step('Wait for table', async () => {
|
|
1583
1594
|
await waitForTable(canvasElement);
|
|
@@ -1629,6 +1640,7 @@ export const ColumnDragInProgress: Story = {
|
|
|
1629
1640
|
],
|
|
1630
1641
|
},
|
|
1631
1642
|
},
|
|
1643
|
+
parameters: { chromatic: { delay: 500 } },
|
|
1632
1644
|
play: async ({ canvasElement, step }) => {
|
|
1633
1645
|
await step('Wait for table', async () => {
|
|
1634
1646
|
await waitForTable(canvasElement);
|
|
@@ -75,6 +75,9 @@ export const ToolbarVisible: Story = {
|
|
|
75
75
|
args: {
|
|
76
76
|
data: sampleData,
|
|
77
77
|
},
|
|
78
|
+
parameters: {
|
|
79
|
+
chromatic: { delay: 500 },
|
|
80
|
+
},
|
|
78
81
|
play: async ({ canvasElement, step }) => {
|
|
79
82
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
80
83
|
await waitFor(
|
|
@@ -127,6 +130,9 @@ export const PlusButtonHover: Story = {
|
|
|
127
130
|
args: {
|
|
128
131
|
data: sampleData,
|
|
129
132
|
},
|
|
133
|
+
parameters: {
|
|
134
|
+
chromatic: { delay: 500 },
|
|
135
|
+
},
|
|
130
136
|
play: async ({ canvasElement, step }) => {
|
|
131
137
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
132
138
|
await waitFor(
|
|
@@ -181,6 +187,9 @@ export const SettingsButtonHover: Story = {
|
|
|
181
187
|
args: {
|
|
182
188
|
data: sampleData,
|
|
183
189
|
},
|
|
190
|
+
parameters: {
|
|
191
|
+
chromatic: { delay: 500 },
|
|
192
|
+
},
|
|
184
193
|
play: async ({ canvasElement, step }) => {
|
|
185
194
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
186
195
|
await waitFor(
|
|
@@ -62,6 +62,7 @@ const meta: Meta<ToolboxArgs> = {
|
|
|
62
62
|
tags: ['autodocs'],
|
|
63
63
|
args: {
|
|
64
64
|
minHeight: 300,
|
|
65
|
+
width: 450,
|
|
65
66
|
data: sampleData,
|
|
66
67
|
},
|
|
67
68
|
render: createEditor,
|
|
@@ -112,6 +113,9 @@ export const CustomIconsForAllTools: Story = {
|
|
|
112
113
|
} as ToolSettings,
|
|
113
114
|
},
|
|
114
115
|
},
|
|
116
|
+
parameters: {
|
|
117
|
+
chromatic: { delay: 500 },
|
|
118
|
+
},
|
|
115
119
|
play: async ({ canvasElement, step }) => {
|
|
116
120
|
await step('Wait for editor and toolbar to initialize', async () => {
|
|
117
121
|
await waitFor(
|
|
@@ -122,6 +122,9 @@ export const TooltipStates: Story = {
|
|
|
122
122
|
delay: 0,
|
|
123
123
|
},
|
|
124
124
|
render: createAllStatesDemo,
|
|
125
|
+
parameters: {
|
|
126
|
+
chromatic: { delay: 500 },
|
|
127
|
+
},
|
|
125
128
|
play: async ({ canvasElement, step }) => {
|
|
126
129
|
const placements: TooltipArgs['placement'][] = ['bottom', 'top', 'left', 'right'];
|
|
127
130
|
const triggerDefault = canvasElement.querySelector('[data-blok-testid="tooltip-trigger-default"]') as HTMLElement;
|
|
@@ -172,6 +175,9 @@ export const WithHTMLContent: Story = {
|
|
|
172
175
|
content: '<strong>Bold</strong> tooltip',
|
|
173
176
|
delay: 0,
|
|
174
177
|
},
|
|
178
|
+
parameters: {
|
|
179
|
+
chromatic: { delay: 500 },
|
|
180
|
+
},
|
|
175
181
|
play: async ({ canvasElement, step }) => {
|
|
176
182
|
await step('Show tooltip with HTML content', async () => {
|
|
177
183
|
const trigger = canvasElement.querySelector('[data-blok-testid="tooltip-trigger"]') as HTMLElement;
|
package/src/stories/helpers.ts
CHANGED
|
@@ -354,17 +354,23 @@ export const triggerSelectAll = (element: Element): void => {
|
|
|
354
354
|
|
|
355
355
|
/**
|
|
356
356
|
* Selects text within a block, handling DOM normalization (e.g., <b> → <strong>).
|
|
357
|
-
*
|
|
357
|
+
* Simulates a click on the contenteditable, creates a proper selection, and waits
|
|
358
|
+
* for the debounced selection handler to fire.
|
|
359
|
+
*
|
|
360
|
+
* In headless Chromium (CI), programmatic selections can become collapsed before the
|
|
361
|
+
* 180ms debounced selectionchange handler fires. The simulateClick + focus + explicit
|
|
362
|
+
* delay pattern ensures the selection persists reliably.
|
|
363
|
+
*
|
|
358
364
|
* @param block - The block wrapper element containing the contenteditable
|
|
359
365
|
* @param selector - CSS selector for the element to select (e.g., 'strong', 'em', 'a')
|
|
360
366
|
* @param contentEditableSelector - Selector for the contenteditable element
|
|
361
367
|
* @returns True if selection was created successfully
|
|
362
368
|
*/
|
|
363
|
-
export const selectTextInBlock = (
|
|
369
|
+
export const selectTextInBlock = async (
|
|
364
370
|
block: Element,
|
|
365
371
|
selector: string,
|
|
366
372
|
contentEditableSelector = '[contenteditable="true"]'
|
|
367
|
-
): boolean => {
|
|
373
|
+
): Promise<boolean> => {
|
|
368
374
|
const contentEditable = block.querySelector(contentEditableSelector);
|
|
369
375
|
const targetElement = block.querySelector(selector);
|
|
370
376
|
|
|
@@ -372,10 +378,8 @@ export const selectTextInBlock = (
|
|
|
372
378
|
return false;
|
|
373
379
|
}
|
|
374
380
|
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
contentEditable.focus();
|
|
378
|
-
}
|
|
381
|
+
// Simulate a full click sequence to establish proper focus context
|
|
382
|
+
simulateClick(contentEditable);
|
|
379
383
|
|
|
380
384
|
// Create and apply the selection
|
|
381
385
|
const range = document.createRange();
|
|
@@ -387,9 +391,17 @@ export const selectTextInBlock = (
|
|
|
387
391
|
selection?.removeAllRanges();
|
|
388
392
|
selection?.addRange(range);
|
|
389
393
|
|
|
390
|
-
//
|
|
394
|
+
// Re-focus to ensure selection is active after range is set
|
|
395
|
+
if (contentEditable instanceof HTMLElement) {
|
|
396
|
+
contentEditable.focus();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Dispatch selectionchange event to trigger the debounced handler
|
|
391
400
|
document.dispatchEvent(new Event('selectionchange'));
|
|
392
401
|
|
|
402
|
+
// Wait for the debounced selection handler (180ms) plus popover creation time
|
|
403
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
404
|
+
|
|
393
405
|
return true;
|
|
394
406
|
};
|
|
395
407
|
|
|
@@ -464,3 +476,46 @@ export const waitForPointerEvents = (selector: string, timeout = 3000): Promise<
|
|
|
464
476
|
check();
|
|
465
477
|
});
|
|
466
478
|
};
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Waits for the inline toolbar to be fully opened (with popover content).
|
|
482
|
+
* Unlike simply checking for the toolbar wrapper element, this verifies that
|
|
483
|
+
* the popover container has been created inside the toolbar, which only happens
|
|
484
|
+
* after the `open()` method runs successfully.
|
|
485
|
+
*
|
|
486
|
+
* @param selector - CSS selector for the inline toolbar wrapper (default: data-blok-testid="inline-toolbar")
|
|
487
|
+
* @param timeout - Maximum time to wait in ms (default: 5000)
|
|
488
|
+
*/
|
|
489
|
+
export const waitForInlineToolbarOpen = (
|
|
490
|
+
selector = '[data-blok-testid="inline-toolbar"]',
|
|
491
|
+
timeout = 5000
|
|
492
|
+
): Promise<Element> => {
|
|
493
|
+
return new Promise((resolve, reject) => {
|
|
494
|
+
const startTime = Date.now();
|
|
495
|
+
const checkInterval = 50;
|
|
496
|
+
|
|
497
|
+
const check = (): void => {
|
|
498
|
+
const toolbar = document.querySelector(selector);
|
|
499
|
+
const popover = toolbar?.querySelector('[data-blok-testid="popover-container"]');
|
|
500
|
+
|
|
501
|
+
if (toolbar && popover) {
|
|
502
|
+
resolve(toolbar);
|
|
503
|
+
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (Date.now() - startTime >= timeout) {
|
|
508
|
+
reject(new Error(
|
|
509
|
+
`Inline toolbar popover not found within ${timeout}ms. ` +
|
|
510
|
+
`Wrapper exists: ${toolbar !== null}, Popover exists: ${popover !== null}`
|
|
511
|
+
));
|
|
512
|
+
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
setTimeout(check, checkInterval);
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
check();
|
|
520
|
+
});
|
|
521
|
+
};
|
package/src/styles/main.css
CHANGED
|
@@ -108,6 +108,9 @@
|
|
|
108
108
|
--animate-wobble: wobble 400ms;
|
|
109
109
|
--animate-rotation: rotation 1.2s infinite linear;
|
|
110
110
|
--animate-notify-bounce-in: notifyBounceIn 600ms 1;
|
|
111
|
+
--animate-notify-slide-in: notifySlideIn 400ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
112
|
+
--animate-notify-slide-out: notifySlideOut 250ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
113
|
+
--animate-notify-progress: notifyProgress linear forwards;
|
|
111
114
|
|
|
112
115
|
/* Keyframes */
|
|
113
116
|
@keyframes fade-in {
|
|
@@ -166,6 +169,22 @@
|
|
|
166
169
|
70% { transform: scale(0.9); }
|
|
167
170
|
100% { transform: scale(1); }
|
|
168
171
|
}
|
|
172
|
+
|
|
173
|
+
@keyframes notifySlideIn {
|
|
174
|
+
0% { opacity: 0; transform: translateY(16px); }
|
|
175
|
+
70% { opacity: 1; transform: translateY(-2px); }
|
|
176
|
+
100% { opacity: 1; transform: translateY(0); }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@keyframes notifySlideOut {
|
|
180
|
+
0% { opacity: 1; transform: translateY(0); }
|
|
181
|
+
100% { opacity: 0; transform: translateY(8px); }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@keyframes notifyProgress {
|
|
185
|
+
0% { width: 100%; }
|
|
186
|
+
100% { width: 0%; }
|
|
187
|
+
}
|
|
169
188
|
}
|
|
170
189
|
|
|
171
190
|
/*
|
|
@@ -308,6 +327,19 @@
|
|
|
308
327
|
@apply p-0 m-0 min-h-[1.6em];
|
|
309
328
|
}
|
|
310
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Exclude bare 'color' from transition-property inside table cells.
|
|
332
|
+
* StyleManager applies transition-colors (which includes 'color') for smooth
|
|
333
|
+
* selection-state changes, but inside table cells inherited text-color changes
|
|
334
|
+
* trigger a 150ms flash from black → target. Keep all other transition
|
|
335
|
+
* properties so background-color selection highlighting still animates.
|
|
336
|
+
*/
|
|
337
|
+
[data-blok-table-cell] [data-blok-element-content] {
|
|
338
|
+
transition-property: background-color, border-color, outline-color,
|
|
339
|
+
text-decoration-color, fill, stroke, --tw-gradient-from,
|
|
340
|
+
--tw-gradient-via, --tw-gradient-to;
|
|
341
|
+
}
|
|
342
|
+
|
|
311
343
|
/**
|
|
312
344
|
* Table heading styles
|
|
313
345
|
* Applied to first row (heading row) and first column (heading column) cells
|
|
@@ -324,3 +356,17 @@
|
|
|
324
356
|
[data-blok-table-haze][data-blok-table-haze-visible] {
|
|
325
357
|
@apply opacity-100;
|
|
326
358
|
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Slash search input appearance
|
|
362
|
+
* When the user types "/" to open the toolbox, the contenteditable
|
|
363
|
+
* transforms to look like a search input with a placeholder.
|
|
364
|
+
*/
|
|
365
|
+
[data-blok-slash-search] {
|
|
366
|
+
@apply bg-[#F8F8F8] rounded-lg transition-colors duration-150 max-w-[240px];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
[data-blok-slash-search]::after {
|
|
370
|
+
content: attr(data-blok-slash-search);
|
|
371
|
+
@apply text-gray-text font-medium text-base pointer-events-none;
|
|
372
|
+
}
|
|
@@ -23,7 +23,8 @@ import { IconH1, IconH2, IconH3, IconH4, IconH5, IconH6, IconHeading, IconToggle
|
|
|
23
23
|
import { PLACEHOLDER_CLASSES, setupPlaceholder } from '../../components/utils/placeholder';
|
|
24
24
|
import { translateToolTitle } from '../../components/utils/tools';
|
|
25
25
|
import { twMerge } from '../../components/utils/tw';
|
|
26
|
-
import { ARROW_ICON,
|
|
26
|
+
import { ARROW_ICON, TOGGLE_ATTR, TOGGLE_WRAPPER_STYLES } from '../toggle/constants';
|
|
27
|
+
import { buildArrow } from '../toggle/dom-builder';
|
|
27
28
|
import { updateArrowState, updateChildrenVisibility } from '../toggle/toggle-lifecycle';
|
|
28
29
|
|
|
29
30
|
/**
|
|
@@ -216,6 +217,22 @@ export class Header implements BlockTool {
|
|
|
216
217
|
normalized.isToggleable = true;
|
|
217
218
|
}
|
|
218
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Sanitize text to remove any previously saved arrow HTML (backwards compatibility)
|
|
222
|
+
*/
|
|
223
|
+
if (normalized.text) {
|
|
224
|
+
const temp = document.createElement('div');
|
|
225
|
+
|
|
226
|
+
temp.innerHTML = normalized.text;
|
|
227
|
+
|
|
228
|
+
const arrowEl = temp.querySelector(`[${TOGGLE_ATTR.toggleArrow}]`);
|
|
229
|
+
|
|
230
|
+
if (arrowEl) {
|
|
231
|
+
arrowEl.remove();
|
|
232
|
+
normalized.text = temp.innerHTML;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
219
236
|
return normalized;
|
|
220
237
|
}
|
|
221
238
|
|
|
@@ -238,6 +255,42 @@ export class Header implements BlockTool {
|
|
|
238
255
|
}
|
|
239
256
|
}
|
|
240
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Expand the toggle heading (no-op if not toggleable or already expanded).
|
|
260
|
+
* Can be called externally via block.call('expand').
|
|
261
|
+
*/
|
|
262
|
+
public expand(): void {
|
|
263
|
+
if (!this._data.isToggleable || this._isOpen) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
this._isOpen = true;
|
|
268
|
+
|
|
269
|
+
if (this._arrowElement && this._element) {
|
|
270
|
+
updateArrowState(this._arrowElement, this._element, this._isOpen);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
this.updateChildrenVisibility();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Collapse the toggle heading (no-op if not toggleable or already collapsed).
|
|
278
|
+
* Can be called externally via block.call('collapse').
|
|
279
|
+
*/
|
|
280
|
+
public collapse(): void {
|
|
281
|
+
if (!this._data.isToggleable || !this._isOpen) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this._isOpen = false;
|
|
286
|
+
|
|
287
|
+
if (this._arrowElement && this._element) {
|
|
288
|
+
updateArrowState(this._arrowElement, this._element, this._isOpen);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
this.updateChildrenVisibility();
|
|
292
|
+
}
|
|
293
|
+
|
|
241
294
|
/**
|
|
242
295
|
* Returns header block tunes config
|
|
243
296
|
*
|
|
@@ -357,7 +410,34 @@ export class Header implements BlockTool {
|
|
|
357
410
|
* @param data - saved data to merge with current block
|
|
358
411
|
*/
|
|
359
412
|
public merge(data: HeaderData): void {
|
|
360
|
-
|
|
413
|
+
/**
|
|
414
|
+
* Strip any arrow HTML from incoming data to prevent injection of toggle markup
|
|
415
|
+
*/
|
|
416
|
+
const tempDiv = document.createElement('div');
|
|
417
|
+
tempDiv.innerHTML = data.text;
|
|
418
|
+
const arrowInData = tempDiv.querySelector(`[${TOGGLE_ATTR.toggleArrow}]`);
|
|
419
|
+
|
|
420
|
+
if (arrowInData) {
|
|
421
|
+
arrowInData.remove();
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const cleanText = tempDiv.innerHTML;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Strip arrow from current element, append text, then re-add arrow.
|
|
428
|
+
* This ensures text is appended to the content, not interleaved with toggle markup.
|
|
429
|
+
*/
|
|
430
|
+
const arrowEl = this._element.querySelector(`[${TOGGLE_ATTR.toggleArrow}]`);
|
|
431
|
+
|
|
432
|
+
if (arrowEl) {
|
|
433
|
+
arrowEl.remove();
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
this._element.insertAdjacentHTML('beforeend', cleanText);
|
|
437
|
+
|
|
438
|
+
if (arrowEl && this._data.isToggleable) {
|
|
439
|
+
this._element.prepend(arrowEl);
|
|
440
|
+
}
|
|
361
441
|
}
|
|
362
442
|
|
|
363
443
|
/**
|
|
@@ -378,8 +458,20 @@ export class Header implements BlockTool {
|
|
|
378
458
|
* @returns saved data
|
|
379
459
|
*/
|
|
380
460
|
public save(toolsContent: HTMLHeadingElement): HeaderData {
|
|
461
|
+
/**
|
|
462
|
+
* Clone the element and strip the arrow from the clone to read innerHTML
|
|
463
|
+
* without mutating the live DOM — DOM mutations during save would trigger
|
|
464
|
+
* the MutationObserver → didMutated → syncBlockDataToYjs → save() loop.
|
|
465
|
+
*/
|
|
466
|
+
const clone = toolsContent.cloneNode(true) as HTMLHeadingElement;
|
|
467
|
+
const arrowEl = clone.querySelector(`[${TOGGLE_ATTR.toggleArrow}]`);
|
|
468
|
+
|
|
469
|
+
if (arrowEl) {
|
|
470
|
+
arrowEl.remove();
|
|
471
|
+
}
|
|
472
|
+
|
|
381
473
|
const data: HeaderData = {
|
|
382
|
-
text:
|
|
474
|
+
text: clone.innerHTML,
|
|
383
475
|
level: this.currentLevel.number,
|
|
384
476
|
};
|
|
385
477
|
|
|
@@ -426,7 +518,24 @@ export class Header implements BlockTool {
|
|
|
426
518
|
* @returns Current data
|
|
427
519
|
*/
|
|
428
520
|
public get data(): HeaderData {
|
|
521
|
+
/**
|
|
522
|
+
* Strip arrow element before reading innerHTML to avoid capturing toggle markup
|
|
523
|
+
*/
|
|
524
|
+
const arrowEl = this._element.querySelector(`[${TOGGLE_ATTR.toggleArrow}]`);
|
|
525
|
+
|
|
526
|
+
if (arrowEl) {
|
|
527
|
+
arrowEl.remove();
|
|
528
|
+
}
|
|
529
|
+
|
|
429
530
|
this._data.text = this._element.innerHTML;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Re-add arrow after reading so the DOM is not mutated
|
|
534
|
+
*/
|
|
535
|
+
if (arrowEl && this._data.isToggleable) {
|
|
536
|
+
this._element.prepend(arrowEl);
|
|
537
|
+
}
|
|
538
|
+
|
|
430
539
|
this._data.level = this.currentLevel.number;
|
|
431
540
|
|
|
432
541
|
return this._data;
|
|
@@ -568,25 +677,7 @@ export class Header implements BlockTool {
|
|
|
568
677
|
* @returns The arrow element
|
|
569
678
|
*/
|
|
570
679
|
private buildArrow(): HTMLElement {
|
|
571
|
-
|
|
572
|
-
arrow.className = ARROW_STYLES;
|
|
573
|
-
arrow.setAttribute(TOGGLE_ATTR.toggleArrow, '');
|
|
574
|
-
arrow.setAttribute('role', 'button');
|
|
575
|
-
arrow.setAttribute('tabindex', '-1');
|
|
576
|
-
arrow.setAttribute('aria-label', 'Expand');
|
|
577
|
-
arrow.contentEditable = 'false';
|
|
578
|
-
arrow.innerHTML = ARROW_ICON;
|
|
579
|
-
|
|
580
|
-
if (this._isOpen) {
|
|
581
|
-
arrow.style.transform = 'rotate(90deg)';
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
arrow.addEventListener('click', (event: MouseEvent) => {
|
|
585
|
-
event.stopPropagation();
|
|
586
|
-
this.toggleOpen();
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
return arrow;
|
|
680
|
+
return buildArrow(this._isOpen, () => this.toggleOpen(), { contentEditableFalse: true });
|
|
590
681
|
}
|
|
591
682
|
|
|
592
683
|
/**
|
|
@@ -596,6 +687,14 @@ export class Header implements BlockTool {
|
|
|
596
687
|
private toggleIsToggleable(): void {
|
|
597
688
|
const wasToggleable = this._data.isToggleable === true;
|
|
598
689
|
|
|
690
|
+
/**
|
|
691
|
+
* If disabling toggle, ensure children are visible before removing toggle state
|
|
692
|
+
*/
|
|
693
|
+
if (wasToggleable) {
|
|
694
|
+
updateChildrenVisibility(this.api, this.blockId ?? '', true);
|
|
695
|
+
this._isOpen = false;
|
|
696
|
+
}
|
|
697
|
+
|
|
599
698
|
this.data = {
|
|
600
699
|
level: this._data.level,
|
|
601
700
|
text: this._data.text,
|