@jackuait/blok 0.4.1-beta.1 → 0.4.1-beta.11
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 +138 -17
- package/codemod/README.md +45 -7
- package/codemod/migrate-editorjs-to-blok.js +960 -92
- package/codemod/test.js +780 -77
- package/dist/blok.mjs +5 -2
- package/dist/chunks/blok-oNSQ3HA6.mjs +13217 -0
- package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
- package/dist/chunks/i18next-loader-BdNRw4n4.mjs +43 -0
- package/dist/{index-CEXLTV6f.mjs → chunks/index-DHgXmfki.mjs} +2 -2
- package/dist/chunks/inline-tool-convert-CRqgjRim.mjs +1989 -0
- package/dist/chunks/messages-0tDXLuyH.mjs +48 -0
- package/dist/chunks/messages-2_xedlYw.mjs +48 -0
- package/dist/chunks/messages-AHESHJm_.mjs +48 -0
- package/dist/chunks/messages-B5hdXZwA.mjs +48 -0
- package/dist/chunks/messages-B5jGUnOy.mjs +48 -0
- package/dist/chunks/messages-B5puUm7R.mjs +48 -0
- package/dist/chunks/messages-B66ZSDCJ.mjs +48 -0
- package/dist/chunks/messages-B9Oba7sq.mjs +48 -0
- package/dist/chunks/messages-BA0rcTCY.mjs +48 -0
- package/dist/chunks/messages-BBJgd5jG.mjs +48 -0
- package/dist/chunks/messages-BPqWKx5Z.mjs +48 -0
- package/dist/chunks/messages-Bdv-IkfG.mjs +48 -0
- package/dist/chunks/messages-BeUhMpsr.mjs +48 -0
- package/dist/chunks/messages-Bf6Y3_GI.mjs +48 -0
- package/dist/chunks/messages-BiExzWJv.mjs +48 -0
- package/dist/chunks/messages-BlpqL8vG.mjs +48 -0
- package/dist/chunks/messages-BmKCChWZ.mjs +48 -0
- package/dist/chunks/messages-Bn253WWC.mjs +48 -0
- package/dist/chunks/messages-BrJHUxQL.mjs +48 -0
- package/dist/chunks/messages-C5b7hr_E.mjs +48 -0
- package/dist/chunks/messages-C7I_AVH2.mjs +48 -0
- package/dist/chunks/messages-CJoBtXU6.mjs +48 -0
- package/dist/chunks/messages-CQj2JU2j.mjs +48 -0
- package/dist/chunks/messages-CUZ1x1QD.mjs +48 -0
- package/dist/chunks/messages-CUy1vn-b.mjs +48 -0
- package/dist/chunks/messages-CVeWVKsV.mjs +48 -0
- package/dist/chunks/messages-CXHd9SUK.mjs +48 -0
- package/dist/chunks/messages-CbMyJSzS.mjs +48 -0
- package/dist/chunks/messages-CbhuIWRJ.mjs +48 -0
- package/dist/chunks/messages-CeCjVKMW.mjs +48 -0
- package/dist/chunks/messages-Cj-t1bdy.mjs +48 -0
- package/dist/chunks/messages-CkFT2gle.mjs +48 -0
- package/dist/chunks/messages-Cm9aLHeX.mjs +48 -0
- package/dist/chunks/messages-CnvW8Slp.mjs +48 -0
- package/dist/chunks/messages-Cr-RJ7YB.mjs +48 -0
- package/dist/chunks/messages-CrsJ1TEJ.mjs +48 -0
- package/dist/chunks/messages-Cu08aLS3.mjs +48 -0
- package/dist/chunks/messages-CvaqJFN-.mjs +48 -0
- package/dist/chunks/messages-CyDU5lz9.mjs +48 -0
- package/dist/chunks/messages-CySyfkMU.mjs +48 -0
- package/dist/chunks/messages-Cyi2AMmz.mjs +48 -0
- package/dist/chunks/messages-D00OjS2n.mjs +48 -0
- package/dist/chunks/messages-DDLgIPDF.mjs +48 -0
- package/dist/chunks/messages-DMQIHGRj.mjs +48 -0
- package/dist/chunks/messages-DOlC_Tty.mjs +48 -0
- package/dist/chunks/messages-DV6shA9b.mjs +48 -0
- package/dist/chunks/messages-DY94ykcE.mjs +48 -0
- package/dist/chunks/messages-DbVquYKN.mjs +48 -0
- package/dist/chunks/messages-DcKOuncK.mjs +48 -0
- package/dist/chunks/messages-Dg92dXZ5.mjs +48 -0
- package/dist/chunks/messages-DnbbyJT3.mjs +48 -0
- package/dist/chunks/messages-DteYq0rv.mjs +48 -0
- package/dist/chunks/messages-GC2PhgV3.mjs +48 -0
- package/dist/chunks/messages-JGsXAReJ.mjs +48 -0
- package/dist/chunks/messages-JZUhXTuV.mjs +48 -0
- package/dist/chunks/messages-LvFKBBPa.mjs +48 -0
- package/dist/chunks/messages-NP1myMGI.mjs +48 -0
- package/dist/chunks/messages-Q4kc_ZtL.mjs +48 -0
- package/dist/chunks/messages-RvMHb2Ht.mjs +48 -0
- package/dist/chunks/messages-ftMcCEuO.mjs +48 -0
- package/dist/chunks/messages-o24dK6CU.mjs +48 -0
- package/dist/chunks/messages-pA5TvcAj.mjs +48 -0
- package/dist/chunks/messages-rRSHQDCX.mjs +48 -0
- package/dist/chunks/messages-srxrv8Yh.mjs +48 -0
- package/dist/chunks/messages-wdqp4610.mjs +48 -0
- package/dist/chunks/messages-zS1AXZ0y.mjs +48 -0
- package/dist/chunks/messages-zSzDzXej.mjs +48 -0
- package/dist/full.mjs +50 -0
- package/dist/locales.mjs +228 -0
- package/dist/messages-0tDXLuyH.mjs +48 -0
- package/dist/messages-2_xedlYw.mjs +48 -0
- package/dist/messages-AHESHJm_.mjs +48 -0
- package/dist/messages-B5hdXZwA.mjs +48 -0
- package/dist/messages-B5jGUnOy.mjs +48 -0
- package/dist/messages-B5puUm7R.mjs +48 -0
- package/dist/messages-B66ZSDCJ.mjs +48 -0
- package/dist/messages-B9Oba7sq.mjs +48 -0
- package/dist/messages-BA0rcTCY.mjs +48 -0
- package/dist/messages-BBJgd5jG.mjs +48 -0
- package/dist/messages-BPqWKx5Z.mjs +48 -0
- package/dist/messages-Bdv-IkfG.mjs +48 -0
- package/dist/messages-BeUhMpsr.mjs +48 -0
- package/dist/messages-Bf6Y3_GI.mjs +48 -0
- package/dist/messages-BiExzWJv.mjs +48 -0
- package/dist/messages-BlpqL8vG.mjs +48 -0
- package/dist/messages-BmKCChWZ.mjs +48 -0
- package/dist/messages-Bn253WWC.mjs +48 -0
- package/dist/messages-BrJHUxQL.mjs +48 -0
- package/dist/messages-C5b7hr_E.mjs +48 -0
- package/dist/messages-C7I_AVH2.mjs +48 -0
- package/dist/messages-CJoBtXU6.mjs +48 -0
- package/dist/messages-CQj2JU2j.mjs +48 -0
- package/dist/messages-CUZ1x1QD.mjs +48 -0
- package/dist/messages-CUy1vn-b.mjs +48 -0
- package/dist/messages-CVeWVKsV.mjs +48 -0
- package/dist/messages-CXHd9SUK.mjs +48 -0
- package/dist/messages-CbMyJSzS.mjs +48 -0
- package/dist/messages-CbhuIWRJ.mjs +48 -0
- package/dist/messages-CeCjVKMW.mjs +48 -0
- package/dist/messages-Cj-t1bdy.mjs +48 -0
- package/dist/messages-CkFT2gle.mjs +48 -0
- package/dist/messages-Cm9aLHeX.mjs +48 -0
- package/dist/messages-CnvW8Slp.mjs +48 -0
- package/dist/messages-Cr-RJ7YB.mjs +48 -0
- package/dist/messages-CrsJ1TEJ.mjs +48 -0
- package/dist/messages-Cu08aLS3.mjs +48 -0
- package/dist/messages-CvaqJFN-.mjs +48 -0
- package/dist/messages-CyDU5lz9.mjs +48 -0
- package/dist/messages-CySyfkMU.mjs +48 -0
- package/dist/messages-Cyi2AMmz.mjs +48 -0
- package/dist/messages-D00OjS2n.mjs +48 -0
- package/dist/messages-DDLgIPDF.mjs +48 -0
- package/dist/messages-DMQIHGRj.mjs +48 -0
- package/dist/messages-DOlC_Tty.mjs +48 -0
- package/dist/messages-DV6shA9b.mjs +48 -0
- package/dist/messages-DY94ykcE.mjs +48 -0
- package/dist/messages-DbVquYKN.mjs +48 -0
- package/dist/messages-DcKOuncK.mjs +48 -0
- package/dist/messages-Dg92dXZ5.mjs +48 -0
- package/dist/messages-DnbbyJT3.mjs +48 -0
- package/dist/messages-DteYq0rv.mjs +48 -0
- package/dist/messages-GC2PhgV3.mjs +48 -0
- package/dist/messages-JGsXAReJ.mjs +48 -0
- package/dist/messages-JZUhXTuV.mjs +48 -0
- package/dist/messages-LvFKBBPa.mjs +48 -0
- package/dist/messages-NP1myMGI.mjs +48 -0
- package/dist/messages-Q4kc_ZtL.mjs +48 -0
- package/dist/messages-RvMHb2Ht.mjs +48 -0
- package/dist/messages-ftMcCEuO.mjs +48 -0
- package/dist/messages-o24dK6CU.mjs +48 -0
- package/dist/messages-pA5TvcAj.mjs +48 -0
- package/dist/messages-rRSHQDCX.mjs +48 -0
- package/dist/messages-srxrv8Yh.mjs +48 -0
- package/dist/messages-wdqp4610.mjs +48 -0
- package/dist/messages-zS1AXZ0y.mjs +48 -0
- package/dist/messages-zSzDzXej.mjs +48 -0
- package/dist/tools.mjs +3117 -0
- package/dist/vendor.LICENSE.txt +26 -225
- package/package.json +63 -24
- package/src/blok.ts +267 -0
- package/src/components/__module.ts +139 -0
- package/src/components/block/api.ts +155 -0
- package/src/components/block/index.ts +1428 -0
- package/src/components/block-tunes/block-tune-delete.ts +51 -0
- package/src/components/blocks.ts +352 -0
- package/src/components/constants/data-attributes.ts +344 -0
- package/src/components/constants.ts +76 -0
- package/src/components/core.ts +392 -0
- package/src/components/dom.ts +773 -0
- package/src/components/domIterator.ts +189 -0
- package/src/components/errors/critical.ts +5 -0
- package/src/components/events/BlockChanged.ts +16 -0
- package/src/components/events/BlockHovered.ts +21 -0
- package/src/components/events/BlockSettingsClosed.ts +12 -0
- package/src/components/events/BlockSettingsOpened.ts +12 -0
- package/src/components/events/BlokMobileLayoutToggled.ts +15 -0
- package/src/components/events/FakeCursorAboutToBeToggled.ts +17 -0
- package/src/components/events/FakeCursorHaveBeenSet.ts +17 -0
- package/src/components/events/HistoryStateChanged.ts +19 -0
- package/src/components/events/RedactorDomChanged.ts +14 -0
- package/src/components/events/index.ts +46 -0
- package/src/components/flipper.ts +497 -0
- package/src/components/i18n/i18next-loader.ts +84 -0
- package/src/components/i18n/lightweight-i18n.ts +86 -0
- package/src/components/i18n/locales/TRANSLATION_GUIDELINES.md +113 -0
- package/src/components/i18n/locales/am/messages.json +45 -0
- package/src/components/i18n/locales/ar/messages.json +45 -0
- package/src/components/i18n/locales/az/messages.json +45 -0
- package/src/components/i18n/locales/bg/messages.json +45 -0
- package/src/components/i18n/locales/bn/messages.json +45 -0
- package/src/components/i18n/locales/bs/messages.json +45 -0
- package/src/components/i18n/locales/cs/messages.json +45 -0
- package/src/components/i18n/locales/da/messages.json +45 -0
- package/src/components/i18n/locales/de/messages.json +45 -0
- package/src/components/i18n/locales/dv/messages.json +45 -0
- package/src/components/i18n/locales/el/messages.json +45 -0
- package/src/components/i18n/locales/en/messages.json +45 -0
- package/src/components/i18n/locales/es/messages.json +45 -0
- package/src/components/i18n/locales/et/messages.json +45 -0
- package/src/components/i18n/locales/fa/messages.json +45 -0
- package/src/components/i18n/locales/fi/messages.json +45 -0
- package/src/components/i18n/locales/fil/messages.json +45 -0
- package/src/components/i18n/locales/fr/messages.json +45 -0
- package/src/components/i18n/locales/gu/messages.json +45 -0
- package/src/components/i18n/locales/he/messages.json +45 -0
- package/src/components/i18n/locales/hi/messages.json +45 -0
- package/src/components/i18n/locales/hr/messages.json +45 -0
- package/src/components/i18n/locales/hu/messages.json +45 -0
- package/src/components/i18n/locales/hy/messages.json +45 -0
- package/src/components/i18n/locales/id/messages.json +45 -0
- package/src/components/i18n/locales/index.ts +231 -0
- package/src/components/i18n/locales/it/messages.json +45 -0
- package/src/components/i18n/locales/ja/messages.json +45 -0
- package/src/components/i18n/locales/ka/messages.json +45 -0
- package/src/components/i18n/locales/km/messages.json +45 -0
- package/src/components/i18n/locales/kn/messages.json +45 -0
- package/src/components/i18n/locales/ko/messages.json +45 -0
- package/src/components/i18n/locales/ku/messages.json +45 -0
- package/src/components/i18n/locales/lo/messages.json +45 -0
- package/src/components/i18n/locales/lt/messages.json +45 -0
- package/src/components/i18n/locales/lv/messages.json +45 -0
- package/src/components/i18n/locales/mk/messages.json +45 -0
- package/src/components/i18n/locales/ml/messages.json +45 -0
- package/src/components/i18n/locales/mn/messages.json +45 -0
- package/src/components/i18n/locales/mr/messages.json +45 -0
- package/src/components/i18n/locales/ms/messages.json +45 -0
- package/src/components/i18n/locales/my/messages.json +45 -0
- package/src/components/i18n/locales/ne/messages.json +45 -0
- package/src/components/i18n/locales/nl/messages.json +45 -0
- package/src/components/i18n/locales/no/messages.json +45 -0
- package/src/components/i18n/locales/pa/messages.json +45 -0
- package/src/components/i18n/locales/pl/messages.json +45 -0
- package/src/components/i18n/locales/ps/messages.json +45 -0
- package/src/components/i18n/locales/pt/messages.json +45 -0
- package/src/components/i18n/locales/ro/messages.json +45 -0
- package/src/components/i18n/locales/ru/messages.json +45 -0
- package/src/components/i18n/locales/sd/messages.json +45 -0
- package/src/components/i18n/locales/si/messages.json +45 -0
- package/src/components/i18n/locales/sk/messages.json +45 -0
- package/src/components/i18n/locales/sl/messages.json +45 -0
- package/src/components/i18n/locales/sq/messages.json +45 -0
- package/src/components/i18n/locales/sr/messages.json +45 -0
- package/src/components/i18n/locales/sv/messages.json +45 -0
- package/src/components/i18n/locales/sw/messages.json +45 -0
- package/src/components/i18n/locales/ta/messages.json +45 -0
- package/src/components/i18n/locales/te/messages.json +45 -0
- package/src/components/i18n/locales/th/messages.json +45 -0
- package/src/components/i18n/locales/tr/messages.json +45 -0
- package/src/components/i18n/locales/ug/messages.json +45 -0
- package/src/components/i18n/locales/uk/messages.json +45 -0
- package/src/components/i18n/locales/ur/messages.json +45 -0
- package/src/components/i18n/locales/vi/messages.json +45 -0
- package/src/components/i18n/locales/yi/messages.json +45 -0
- package/src/components/i18n/locales/zh/messages.json +45 -0
- package/src/components/icons/index.ts +242 -0
- package/src/components/inline-tools/inline-tool-bold.ts +2213 -0
- package/src/components/inline-tools/inline-tool-convert.ts +141 -0
- package/src/components/inline-tools/inline-tool-italic.ts +500 -0
- package/src/components/inline-tools/inline-tool-link.ts +539 -0
- package/src/components/modules/api/blocks.ts +377 -0
- package/src/components/modules/api/caret.ts +125 -0
- package/src/components/modules/api/events.ts +51 -0
- package/src/components/modules/api/history.ts +73 -0
- package/src/components/modules/api/i18n.ts +35 -0
- package/src/components/modules/api/index.ts +39 -0
- package/src/components/modules/api/inlineToolbar.ts +33 -0
- package/src/components/modules/api/listeners.ts +56 -0
- package/src/components/modules/api/notifier.ts +46 -0
- package/src/components/modules/api/readonly.ts +39 -0
- package/src/components/modules/api/sanitizer.ts +30 -0
- package/src/components/modules/api/saver.ts +52 -0
- package/src/components/modules/api/selection.ts +48 -0
- package/src/components/modules/api/styles.ts +72 -0
- package/src/components/modules/api/toolbar.ts +79 -0
- package/src/components/modules/api/tools.ts +16 -0
- package/src/components/modules/api/tooltip.ts +67 -0
- package/src/components/modules/api/ui.ts +36 -0
- package/src/components/modules/blockEvents.ts +1591 -0
- package/src/components/modules/blockManager.ts +1356 -0
- package/src/components/modules/blockSelection.ts +708 -0
- package/src/components/modules/caret.ts +853 -0
- package/src/components/modules/crossBlockSelection.ts +329 -0
- package/src/components/modules/dragManager.ts +1204 -0
- package/src/components/modules/history.ts +1098 -0
- package/src/components/modules/i18n.ts +332 -0
- package/src/components/modules/index.ts +139 -0
- package/src/components/modules/modificationsObserver.ts +147 -0
- package/src/components/modules/paste.ts +1092 -0
- package/src/components/modules/readonly.ts +136 -0
- package/src/components/modules/rectangleSelection.ts +711 -0
- package/src/components/modules/renderer.ts +155 -0
- package/src/components/modules/saver.ts +283 -0
- package/src/components/modules/toolbar/blockSettings.ts +781 -0
- package/src/components/modules/toolbar/index.ts +1315 -0
- package/src/components/modules/toolbar/inline.ts +956 -0
- package/src/components/modules/tools.ts +625 -0
- package/src/components/modules/ui.ts +1283 -0
- package/src/components/polyfills.ts +113 -0
- package/src/components/selection.ts +1179 -0
- package/src/components/tools/base.ts +301 -0
- package/src/components/tools/block.ts +339 -0
- package/src/components/tools/collection.ts +67 -0
- package/src/components/tools/factory.ts +138 -0
- package/src/components/tools/inline.ts +71 -0
- package/src/components/tools/tune.ts +33 -0
- package/src/components/ui/toolbox.ts +601 -0
- package/src/components/utils/announcer.ts +205 -0
- package/src/components/utils/api.ts +20 -0
- package/src/components/utils/bem.ts +26 -0
- package/src/components/utils/blocks.ts +284 -0
- package/src/components/utils/caret.ts +1067 -0
- package/src/components/utils/data-model-transform.ts +382 -0
- package/src/components/utils/events.ts +117 -0
- package/src/components/utils/keyboard.ts +60 -0
- package/src/components/utils/listeners.ts +296 -0
- package/src/components/utils/mutations.ts +39 -0
- package/src/components/utils/notifier/draw.ts +190 -0
- package/src/components/utils/notifier/index.ts +66 -0
- package/src/components/utils/notifier/types.ts +1 -0
- package/src/components/utils/notifier.ts +77 -0
- package/src/components/utils/placeholder.ts +140 -0
- package/src/components/utils/popover/components/hint/hint.const.ts +10 -0
- package/src/components/utils/popover/components/hint/hint.ts +46 -0
- package/src/components/utils/popover/components/hint/index.ts +6 -0
- package/src/components/utils/popover/components/popover-header/index.ts +2 -0
- package/src/components/utils/popover/components/popover-header/popover-header.const.ts +8 -0
- package/src/components/utils/popover/components/popover-header/popover-header.ts +80 -0
- package/src/components/utils/popover/components/popover-header/popover-header.types.ts +14 -0
- package/src/components/utils/popover/components/popover-item/index.ts +13 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +50 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +680 -0
- package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts +14 -0
- package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts +136 -0
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +20 -0
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts +117 -0
- package/src/components/utils/popover/components/popover-item/popover-item.ts +186 -0
- package/src/components/utils/popover/components/search-input/index.ts +2 -0
- package/src/components/utils/popover/components/search-input/search-input.const.ts +8 -0
- package/src/components/utils/popover/components/search-input/search-input.ts +178 -0
- package/src/components/utils/popover/components/search-input/search-input.types.ts +59 -0
- package/src/components/utils/popover/index.ts +13 -0
- package/src/components/utils/popover/popover-abstract.ts +457 -0
- package/src/components/utils/popover/popover-desktop.ts +676 -0
- package/src/components/utils/popover/popover-inline.ts +338 -0
- package/src/components/utils/popover/popover-mobile.ts +201 -0
- package/src/components/utils/popover/popover.const.ts +81 -0
- package/src/components/utils/popover/utils/popover-states-history.ts +72 -0
- package/src/components/utils/promise-queue.ts +43 -0
- package/src/components/utils/sanitizer.ts +537 -0
- package/src/components/utils/scroll-locker.ts +87 -0
- package/src/components/utils/shortcut.ts +231 -0
- package/src/components/utils/shortcuts.ts +113 -0
- package/src/components/utils/tools.ts +110 -0
- package/src/components/utils/tooltip.ts +591 -0
- package/src/components/utils/tw.ts +241 -0
- package/src/components/utils.ts +1081 -0
- package/src/env.d.ts +13 -0
- package/src/full.ts +69 -0
- package/src/locales.ts +51 -0
- package/src/stories/Block.stories.ts +498 -0
- package/src/stories/EditorModes.stories.ts +505 -0
- package/src/stories/Header.stories.ts +137 -0
- package/src/stories/InlineToolbar.stories.ts +498 -0
- package/src/stories/List.stories.ts +259 -0
- package/src/stories/Notifier.stories.ts +340 -0
- package/src/stories/Paragraph.stories.ts +112 -0
- package/src/stories/Placeholder.stories.ts +319 -0
- package/src/stories/Popover.stories.ts +844 -0
- package/src/stories/Selection.stories.ts +250 -0
- package/src/stories/StubBlock.stories.ts +156 -0
- package/src/stories/Toolbar.stories.ts +223 -0
- package/src/stories/Toolbox.stories.ts +166 -0
- package/src/stories/Tooltip.stories.ts +198 -0
- package/src/stories/helpers.ts +463 -0
- package/src/styles/main.css +123 -0
- package/src/tools/header/index.ts +646 -0
- package/src/tools/index.ts +45 -0
- package/src/tools/list/index.ts +1819 -0
- package/src/tools/paragraph/index.ts +412 -0
- package/src/tools/stub/index.ts +107 -0
- package/src/types-internal/blok-modules.d.ts +87 -0
- package/src/types-internal/html-janitor.d.ts +28 -0
- package/src/types-internal/module-config.d.ts +11 -0
- package/src/variants/all-locales.ts +155 -0
- package/src/variants/blok-maximum.ts +20 -0
- package/src/variants/blok-minimum.ts +243 -0
- package/types/api/blocks.d.ts +9 -1
- package/types/api/history.d.ts +7 -0
- package/types/api/i18n.d.ts +22 -3
- package/types/api/selection.d.ts +6 -0
- package/types/api/styles.d.ts +23 -10
- package/types/configs/blok-config.d.ts +29 -0
- package/types/configs/i18n-config.d.ts +52 -2
- package/types/configs/i18n-dictionary.d.ts +16 -90
- package/types/data-attributes.d.ts +170 -0
- package/types/data-formats/output-data.d.ts +15 -0
- package/types/full.d.ts +80 -0
- package/types/index.d.ts +29 -13
- package/types/locales.d.ts +59 -0
- package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
- package/types/tools/block-tool.d.ts +9 -0
- package/types/tools/header.d.ts +18 -0
- package/types/tools/index.d.ts +1 -0
- package/types/tools/list.d.ts +91 -0
- package/types/tools/paragraph.d.ts +71 -0
- package/types/tools/tool-settings.d.ts +92 -6
- package/types/tools/tool.d.ts +6 -0
- package/types/tools-entry.d.ts +49 -0
- package/types/utils/popover/popover-item.d.ts +18 -5
- package/types/utils/popover/popover.d.ts +7 -0
- package/dist/blok-C8XbyLHh.mjs +0 -25795
- package/dist/blok.umd.js +0 -181
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/html-vite';
|
|
2
|
+
import { userEvent, waitFor, expect } from 'storybook/test';
|
|
3
|
+
import type { OutputData } from '@/types';
|
|
4
|
+
import { createEditorContainer, simulateClick, waitForToolbar, TOOLBAR_TESTID, dispatchKeyboardEvent, focusSearchInput, waitForPointerEvents } from './helpers';
|
|
5
|
+
import type { EditorFactoryOptions } from './helpers';
|
|
6
|
+
import { Header } from '../tools/header';
|
|
7
|
+
|
|
8
|
+
interface PopoverArgs extends EditorFactoryOptions {
|
|
9
|
+
minHeight: number;
|
|
10
|
+
data: OutputData | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Constants
|
|
14
|
+
const BLOCK_TESTID = '[data-blok-testid="block-wrapper"]';
|
|
15
|
+
const ACTIONS_TESTID = '[data-blok-testid="toolbar-actions"]';
|
|
16
|
+
const PLUS_BUTTON_TESTID = '[data-blok-testid="plus-button"]';
|
|
17
|
+
const SETTINGS_BUTTON_TESTID = '[data-blok-testid="settings-toggler"]';
|
|
18
|
+
const BLOCK_TUNES_POPOVER_TESTID = '[data-blok-testid="block-tunes-popover"]';
|
|
19
|
+
const POPOVER_ITEM_TESTID = '[data-blok-testid="popover-item"]';
|
|
20
|
+
|
|
21
|
+
const POPOVER_OPENED_SELECTOR = '[data-blok-popover-opened="true"]';
|
|
22
|
+
const ITEM_FOCUSED_SELECTOR = '[data-blok-focused=\"true\"]';
|
|
23
|
+
const CONFIRMATION_SELECTOR = '[data-blok-popover-item-confirmation="true"]';
|
|
24
|
+
const NOTHING_FOUND_SELECTOR = '[data-blok-nothing-found-displayed="true"]';
|
|
25
|
+
const DELETE_BUTTON_SELECTOR = '[data-blok-item-name="delete"]';
|
|
26
|
+
const CONVERT_TO_SELECTOR = '[data-blok-item-name="convert-to"]';
|
|
27
|
+
const NESTED_POPOVER_SELECTOR = '[data-blok-nested="true"]';
|
|
28
|
+
|
|
29
|
+
const TIMEOUT_INIT = { timeout: 5000 };
|
|
30
|
+
const TIMEOUT_ACTION = { timeout: 5000 };
|
|
31
|
+
|
|
32
|
+
const sampleData: OutputData = {
|
|
33
|
+
time: Date.now(),
|
|
34
|
+
version: '1.0.0',
|
|
35
|
+
blocks: [
|
|
36
|
+
{
|
|
37
|
+
id: 'popover-block-1',
|
|
38
|
+
type: 'paragraph',
|
|
39
|
+
data: { text: 'Block for testing popover states and interactions.' },
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'popover-block-2',
|
|
43
|
+
type: 'paragraph',
|
|
44
|
+
data: { text: 'Second block for additional testing.' },
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const createEditor = (args: PopoverArgs): HTMLElement => createEditorContainer(args);
|
|
50
|
+
|
|
51
|
+
const meta: Meta<PopoverArgs> = {
|
|
52
|
+
title: 'Components/Popover',
|
|
53
|
+
tags: ['autodocs'],
|
|
54
|
+
args: {
|
|
55
|
+
minHeight: 350,
|
|
56
|
+
data: sampleData,
|
|
57
|
+
},
|
|
58
|
+
render: createEditor,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default meta;
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
type Story = StoryObj<PopoverArgs>;
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* NOTE: Toolbox opened state lives in EditorModes.stories.ts (ToolboxOpenedMode)
|
|
68
|
+
* This file focuses on popover-specific states: hover, focus, search, confirmation.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Default state: Popover is closed.
|
|
73
|
+
*/
|
|
74
|
+
export const Default: Story = {
|
|
75
|
+
args: {
|
|
76
|
+
data: sampleData,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Popover item hover state.
|
|
82
|
+
* Note: Waits for pointer-events to be enabled before hovering.
|
|
83
|
+
*/
|
|
84
|
+
export const ItemHoverState: Story = {
|
|
85
|
+
args: {
|
|
86
|
+
data: sampleData,
|
|
87
|
+
},
|
|
88
|
+
play: async ({ canvasElement, step }) => {
|
|
89
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
90
|
+
await waitFor(
|
|
91
|
+
() => {
|
|
92
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
93
|
+
|
|
94
|
+
expect(block).toBeInTheDocument();
|
|
95
|
+
},
|
|
96
|
+
TIMEOUT_INIT
|
|
97
|
+
);
|
|
98
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
99
|
+
await waitForToolbar(canvasElement);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await step('Click block to show toolbar', async () => {
|
|
103
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
104
|
+
|
|
105
|
+
if (block) {
|
|
106
|
+
simulateClick(block);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
await waitFor(
|
|
110
|
+
() => {
|
|
111
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
112
|
+
|
|
113
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
114
|
+
},
|
|
115
|
+
TIMEOUT_ACTION
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await step('Open toolbox and hover item', async () => {
|
|
120
|
+
const plusButton = canvasElement.querySelector(PLUS_BUTTON_TESTID);
|
|
121
|
+
|
|
122
|
+
if (plusButton) {
|
|
123
|
+
simulateClick(plusButton);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Wait for popover to open AND for pointer-events to be enabled
|
|
127
|
+
await waitForPointerEvents('[data-blok-popover-opened="true"] [data-blok-testid="popover-container"]');
|
|
128
|
+
|
|
129
|
+
// Small delay for CSS animation to complete
|
|
130
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
131
|
+
|
|
132
|
+
const popoverItem = document.querySelector(POPOVER_ITEM_TESTID);
|
|
133
|
+
|
|
134
|
+
if (popoverItem) {
|
|
135
|
+
// Add data-blok-force-hover attribute to show hover styles in headless browsers
|
|
136
|
+
// The CSS uses this attribute instead of :hover for testing compatibility
|
|
137
|
+
popoverItem.setAttribute('data-blok-force-hover', 'true');
|
|
138
|
+
await userEvent.hover(popoverItem);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Popover item focused state (keyboard navigation).
|
|
146
|
+
*/
|
|
147
|
+
export const ItemFocusedState: Story = {
|
|
148
|
+
args: {
|
|
149
|
+
data: sampleData,
|
|
150
|
+
},
|
|
151
|
+
play: async ({ canvasElement, step }) => {
|
|
152
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
153
|
+
await waitFor(
|
|
154
|
+
() => {
|
|
155
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
156
|
+
|
|
157
|
+
expect(block).toBeInTheDocument();
|
|
158
|
+
},
|
|
159
|
+
TIMEOUT_INIT
|
|
160
|
+
);
|
|
161
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
162
|
+
await waitForToolbar(canvasElement);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
await step('Click block to show toolbar', async () => {
|
|
166
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
167
|
+
|
|
168
|
+
if (block) {
|
|
169
|
+
simulateClick(block);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
await waitFor(
|
|
173
|
+
() => {
|
|
174
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
175
|
+
|
|
176
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
177
|
+
},
|
|
178
|
+
TIMEOUT_ACTION
|
|
179
|
+
);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
await step('Open toolbox and navigate with keyboard', async () => {
|
|
183
|
+
const plusButton = canvasElement.querySelector(PLUS_BUTTON_TESTID);
|
|
184
|
+
|
|
185
|
+
if (plusButton) {
|
|
186
|
+
await userEvent.click(plusButton);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
await waitFor(
|
|
190
|
+
() => {
|
|
191
|
+
// Popover is appended to document.body, not inside the canvas
|
|
192
|
+
const popover = document.querySelector(POPOVER_OPENED_SELECTOR);
|
|
193
|
+
|
|
194
|
+
expect(popover).toBeInTheDocument();
|
|
195
|
+
},
|
|
196
|
+
TIMEOUT_ACTION
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// Wait for popover to fully initialize before keyboard navigation
|
|
200
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
201
|
+
|
|
202
|
+
// Find a popover item or the popover container to dispatch from
|
|
203
|
+
const popoverItem = document.querySelector(POPOVER_ITEM_TESTID);
|
|
204
|
+
const popover = document.querySelector(POPOVER_OPENED_SELECTOR);
|
|
205
|
+
const targetElement = popoverItem ?? popover ?? document.body;
|
|
206
|
+
|
|
207
|
+
// Dispatch ArrowDown event from the popover element for flipper to catch
|
|
208
|
+
dispatchKeyboardEvent('ArrowDown', { target: targetElement });
|
|
209
|
+
|
|
210
|
+
await waitFor(
|
|
211
|
+
() => {
|
|
212
|
+
// Popover items are inside the popover which is in document.body
|
|
213
|
+
const focusedItem = document.querySelector(ITEM_FOCUSED_SELECTOR);
|
|
214
|
+
|
|
215
|
+
expect(focusedItem).toBeInTheDocument();
|
|
216
|
+
},
|
|
217
|
+
TIMEOUT_ACTION
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Block tunes popover with convert-to nested items.
|
|
225
|
+
*/
|
|
226
|
+
export const BlockTunesPopover: Story = {
|
|
227
|
+
args: {
|
|
228
|
+
data: sampleData,
|
|
229
|
+
},
|
|
230
|
+
play: async ({ canvasElement, step }) => {
|
|
231
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
232
|
+
await waitFor(
|
|
233
|
+
() => {
|
|
234
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
235
|
+
|
|
236
|
+
expect(block).toBeInTheDocument();
|
|
237
|
+
},
|
|
238
|
+
TIMEOUT_INIT
|
|
239
|
+
);
|
|
240
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
241
|
+
await waitForToolbar(canvasElement);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
await step('Click block to show toolbar', async () => {
|
|
245
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
246
|
+
|
|
247
|
+
if (block) {
|
|
248
|
+
simulateClick(block);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
await waitFor(
|
|
252
|
+
() => {
|
|
253
|
+
const actionsZone = canvasElement.querySelector(ACTIONS_TESTID);
|
|
254
|
+
|
|
255
|
+
expect(actionsZone).toBeInTheDocument();
|
|
256
|
+
},
|
|
257
|
+
TIMEOUT_ACTION
|
|
258
|
+
);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
await step('Open block tunes', async () => {
|
|
262
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
263
|
+
|
|
264
|
+
if (settingsButton) {
|
|
265
|
+
simulateClick(settingsButton);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
await waitFor(
|
|
269
|
+
() => {
|
|
270
|
+
// Block tunes popover is appended to document.body
|
|
271
|
+
const blockTunesPopover = document.querySelector(BLOCK_TUNES_POPOVER_TESTID);
|
|
272
|
+
|
|
273
|
+
expect(blockTunesPopover).toBeInTheDocument();
|
|
274
|
+
},
|
|
275
|
+
TIMEOUT_ACTION
|
|
276
|
+
);
|
|
277
|
+
});
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Popover confirmation state - demonstrates the visual appearance of an item in confirmation mode.
|
|
283
|
+
* Note: This manually applies confirmation styling since the default delete tune doesn't have confirmation.
|
|
284
|
+
*/
|
|
285
|
+
export const ConfirmationState: Story = {
|
|
286
|
+
args: {
|
|
287
|
+
data: sampleData,
|
|
288
|
+
},
|
|
289
|
+
play: async ({ canvasElement, step }) => {
|
|
290
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
291
|
+
await waitFor(
|
|
292
|
+
() => {
|
|
293
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
294
|
+
|
|
295
|
+
expect(block).toBeInTheDocument();
|
|
296
|
+
},
|
|
297
|
+
TIMEOUT_INIT
|
|
298
|
+
);
|
|
299
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
300
|
+
await waitForToolbar(canvasElement);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
await step('Click block to show toolbar', async () => {
|
|
304
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
305
|
+
|
|
306
|
+
if (block) {
|
|
307
|
+
simulateClick(block);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
await waitFor(
|
|
311
|
+
() => {
|
|
312
|
+
const actionsZone = canvasElement.querySelector(ACTIONS_TESTID);
|
|
313
|
+
|
|
314
|
+
expect(actionsZone).toBeInTheDocument();
|
|
315
|
+
},
|
|
316
|
+
TIMEOUT_ACTION
|
|
317
|
+
);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
await step('Open block tunes', async () => {
|
|
321
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
322
|
+
|
|
323
|
+
if (settingsButton) {
|
|
324
|
+
simulateClick(settingsButton);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
await waitFor(
|
|
328
|
+
() => {
|
|
329
|
+
// Block tunes popover is appended to document.body
|
|
330
|
+
const blockTunesPopover = document.querySelector(BLOCK_TUNES_POPOVER_TESTID);
|
|
331
|
+
|
|
332
|
+
expect(blockTunesPopover).toBeInTheDocument();
|
|
333
|
+
},
|
|
334
|
+
TIMEOUT_ACTION
|
|
335
|
+
);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
await step('Apply confirmation state styling to delete button', async () => {
|
|
339
|
+
// Wait for popover items to be fully rendered
|
|
340
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
341
|
+
|
|
342
|
+
// Delete button is inside the popover which is in document.body
|
|
343
|
+
const deleteButton = document.querySelector(DELETE_BUTTON_SELECTOR);
|
|
344
|
+
|
|
345
|
+
if (deleteButton) {
|
|
346
|
+
// Manually apply confirmation state styling for visual demonstration
|
|
347
|
+
// This matches the styling applied by popover-item-default.ts applyConfirmationState()
|
|
348
|
+
deleteButton.setAttribute('data-blok-popover-item-confirmation', 'true');
|
|
349
|
+
deleteButton.setAttribute('data-blok-popover-item-no-hover', 'true');
|
|
350
|
+
deleteButton.setAttribute('data-blok-popover-item-no-focus', 'true');
|
|
351
|
+
// eslint-disable-next-line internal-storybook/no-class-selectors
|
|
352
|
+
deleteButton.classList.add('!bg-item-confirm-bg', '!text-white');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
await waitFor(
|
|
356
|
+
() => {
|
|
357
|
+
// Confirmation button is inside the popover which is in document.body
|
|
358
|
+
const confirmButton = document.querySelector(CONFIRMATION_SELECTOR);
|
|
359
|
+
|
|
360
|
+
expect(confirmButton).toBeInTheDocument();
|
|
361
|
+
},
|
|
362
|
+
TIMEOUT_ACTION
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
// Add hover state to confirmation button for visual testing in headless browsers
|
|
366
|
+
const confirmButton = document.querySelector(CONFIRMATION_SELECTOR);
|
|
367
|
+
|
|
368
|
+
if (confirmButton) {
|
|
369
|
+
confirmButton.setAttribute('data-blok-force-hover', 'true');
|
|
370
|
+
await userEvent.hover(confirmButton);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Popover search/filter functionality (in block settings).
|
|
378
|
+
*/
|
|
379
|
+
export const SearchFiltering: Story = {
|
|
380
|
+
args: {
|
|
381
|
+
data: sampleData,
|
|
382
|
+
},
|
|
383
|
+
play: async ({ canvasElement, step }) => {
|
|
384
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
385
|
+
await waitFor(
|
|
386
|
+
() => {
|
|
387
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
388
|
+
|
|
389
|
+
expect(block).toBeInTheDocument();
|
|
390
|
+
},
|
|
391
|
+
TIMEOUT_INIT
|
|
392
|
+
);
|
|
393
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
394
|
+
await waitForToolbar(canvasElement);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
await step('Click block to show toolbar', async () => {
|
|
398
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
399
|
+
|
|
400
|
+
if (block) {
|
|
401
|
+
simulateClick(block);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
await waitFor(
|
|
405
|
+
() => {
|
|
406
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
407
|
+
|
|
408
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
409
|
+
},
|
|
410
|
+
TIMEOUT_ACTION
|
|
411
|
+
);
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
await step('Open block settings', async () => {
|
|
415
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
416
|
+
|
|
417
|
+
if (settingsButton) {
|
|
418
|
+
simulateClick(settingsButton);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
await waitFor(
|
|
422
|
+
() => {
|
|
423
|
+
// Block tunes popover is appended to document.body
|
|
424
|
+
const blockTunesPopover = document.querySelector(BLOCK_TUNES_POPOVER_TESTID);
|
|
425
|
+
|
|
426
|
+
expect(blockTunesPopover).toBeInTheDocument();
|
|
427
|
+
},
|
|
428
|
+
TIMEOUT_ACTION
|
|
429
|
+
);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
await step('Type to filter items', async () => {
|
|
433
|
+
// Wait for popover to be fully rendered
|
|
434
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
435
|
+
|
|
436
|
+
// Use helper to focus search input and type
|
|
437
|
+
focusSearchInput('delete');
|
|
438
|
+
|
|
439
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
440
|
+
|
|
441
|
+
// Verify the popover is still open and filtering worked
|
|
442
|
+
await waitFor(
|
|
443
|
+
() => {
|
|
444
|
+
const popover = document.querySelector(POPOVER_OPENED_SELECTOR);
|
|
445
|
+
|
|
446
|
+
expect(popover).toBeInTheDocument();
|
|
447
|
+
},
|
|
448
|
+
TIMEOUT_ACTION
|
|
449
|
+
);
|
|
450
|
+
});
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Popover nothing found message (in block settings).
|
|
456
|
+
*/
|
|
457
|
+
export const NothingFoundMessage: Story = {
|
|
458
|
+
args: {
|
|
459
|
+
data: sampleData,
|
|
460
|
+
},
|
|
461
|
+
play: async ({ canvasElement, step }) => {
|
|
462
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
463
|
+
await waitFor(
|
|
464
|
+
() => {
|
|
465
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
466
|
+
|
|
467
|
+
expect(block).toBeInTheDocument();
|
|
468
|
+
},
|
|
469
|
+
TIMEOUT_INIT
|
|
470
|
+
);
|
|
471
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
472
|
+
await waitForToolbar(canvasElement);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
await step('Click block to show toolbar', async () => {
|
|
476
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
477
|
+
|
|
478
|
+
if (block) {
|
|
479
|
+
simulateClick(block);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
await waitFor(
|
|
483
|
+
() => {
|
|
484
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
485
|
+
|
|
486
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
487
|
+
},
|
|
488
|
+
TIMEOUT_ACTION
|
|
489
|
+
);
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
await step('Open block settings', async () => {
|
|
493
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
494
|
+
|
|
495
|
+
if (settingsButton) {
|
|
496
|
+
await userEvent.click(settingsButton);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
await waitFor(
|
|
500
|
+
() => {
|
|
501
|
+
// Block tunes popover is appended to document.body
|
|
502
|
+
const blockTunesPopover = document.querySelector(BLOCK_TUNES_POPOVER_TESTID);
|
|
503
|
+
|
|
504
|
+
expect(blockTunesPopover).toBeInTheDocument();
|
|
505
|
+
},
|
|
506
|
+
TIMEOUT_ACTION
|
|
507
|
+
);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
await step('Search for non-existent item', async () => {
|
|
511
|
+
// Wait for popover to be fully rendered and search input to be available
|
|
512
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
513
|
+
|
|
514
|
+
// Find and focus the search input inside the popover
|
|
515
|
+
const searchInput = document.querySelector('[data-blok-testid="popover-search-input"]') as HTMLInputElement;
|
|
516
|
+
|
|
517
|
+
if (searchInput) {
|
|
518
|
+
searchInput.focus();
|
|
519
|
+
// Type directly into the input
|
|
520
|
+
searchInput.value = 'xyznonexistent';
|
|
521
|
+
// Trigger input event to notify the search handler
|
|
522
|
+
searchInput.dispatchEvent(new Event('input', { bubbles: true }));
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
await waitFor(
|
|
526
|
+
() => {
|
|
527
|
+
// Nothing found message is inside the popover which is in document.body
|
|
528
|
+
const nothingFound = document.querySelector(NOTHING_FOUND_SELECTOR);
|
|
529
|
+
|
|
530
|
+
expect(nothingFound).toBeInTheDocument();
|
|
531
|
+
},
|
|
532
|
+
TIMEOUT_ACTION
|
|
533
|
+
);
|
|
534
|
+
});
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Popover item in disabled state.
|
|
540
|
+
*/
|
|
541
|
+
export const DisabledItem: Story = {
|
|
542
|
+
args: {
|
|
543
|
+
data: sampleData,
|
|
544
|
+
},
|
|
545
|
+
play: async ({ canvasElement, step }) => {
|
|
546
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
547
|
+
await waitFor(
|
|
548
|
+
() => {
|
|
549
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
550
|
+
|
|
551
|
+
expect(block).toBeInTheDocument();
|
|
552
|
+
},
|
|
553
|
+
TIMEOUT_INIT
|
|
554
|
+
);
|
|
555
|
+
await waitForToolbar(canvasElement);
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
await step('Click block to show toolbar', async () => {
|
|
559
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
560
|
+
|
|
561
|
+
if (block) {
|
|
562
|
+
simulateClick(block);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
await waitFor(
|
|
566
|
+
() => {
|
|
567
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
568
|
+
|
|
569
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
570
|
+
},
|
|
571
|
+
TIMEOUT_ACTION
|
|
572
|
+
);
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
await step('Open toolbox and disable an item', async () => {
|
|
576
|
+
const plusButton = canvasElement.querySelector(PLUS_BUTTON_TESTID);
|
|
577
|
+
|
|
578
|
+
if (plusButton) {
|
|
579
|
+
simulateClick(plusButton);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
await waitFor(
|
|
583
|
+
() => {
|
|
584
|
+
const popover = document.querySelector(POPOVER_OPENED_SELECTOR);
|
|
585
|
+
|
|
586
|
+
expect(popover).toBeInTheDocument();
|
|
587
|
+
},
|
|
588
|
+
TIMEOUT_ACTION
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
// Wait for items to render then add disabled styling to first item
|
|
592
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
593
|
+
|
|
594
|
+
const popoverItem = document.querySelector(POPOVER_ITEM_TESTID);
|
|
595
|
+
|
|
596
|
+
if (popoverItem) {
|
|
597
|
+
// Add the proper disabled classes and attribute that match the real implementation
|
|
598
|
+
// The itemDisabled class from popover-item-default.const.ts is:
|
|
599
|
+
// 'cursor-default pointer-events-none text-text-secondary'
|
|
600
|
+
// eslint-disable-next-line internal-storybook/no-class-selectors
|
|
601
|
+
popoverItem.classList.add('cursor-default', 'pointer-events-none', 'text-text-secondary');
|
|
602
|
+
popoverItem.setAttribute('data-blok-disabled', 'true');
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
await waitFor(
|
|
606
|
+
() => {
|
|
607
|
+
const disabledItem = document.querySelector('[data-blok-disabled="true"]');
|
|
608
|
+
|
|
609
|
+
expect(disabledItem).toBeInTheDocument();
|
|
610
|
+
},
|
|
611
|
+
TIMEOUT_ACTION
|
|
612
|
+
);
|
|
613
|
+
});
|
|
614
|
+
},
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Mobile popover layout (full-width bottom sheet style).
|
|
619
|
+
*/
|
|
620
|
+
export const MobilePopover: Story = {
|
|
621
|
+
args: {
|
|
622
|
+
data: sampleData,
|
|
623
|
+
minHeight: 400,
|
|
624
|
+
},
|
|
625
|
+
parameters: {
|
|
626
|
+
viewport: {
|
|
627
|
+
defaultViewport: 'mobile1',
|
|
628
|
+
},
|
|
629
|
+
chromatic: {
|
|
630
|
+
viewports: [375],
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
play: async ({ canvasElement, step }) => {
|
|
634
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
635
|
+
await waitFor(
|
|
636
|
+
() => {
|
|
637
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
638
|
+
|
|
639
|
+
expect(block).toBeInTheDocument();
|
|
640
|
+
},
|
|
641
|
+
TIMEOUT_INIT
|
|
642
|
+
);
|
|
643
|
+
await waitForToolbar(canvasElement);
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
await step('Click block to show toolbar', async () => {
|
|
647
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
648
|
+
|
|
649
|
+
if (block) {
|
|
650
|
+
simulateClick(block);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
await waitFor(
|
|
654
|
+
() => {
|
|
655
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
656
|
+
|
|
657
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
658
|
+
},
|
|
659
|
+
TIMEOUT_ACTION
|
|
660
|
+
);
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
await step('Open toolbox in mobile view', async () => {
|
|
664
|
+
const plusButton = canvasElement.querySelector(PLUS_BUTTON_TESTID);
|
|
665
|
+
|
|
666
|
+
if (plusButton) {
|
|
667
|
+
simulateClick(plusButton);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
await waitFor(
|
|
671
|
+
() => {
|
|
672
|
+
const popover = document.querySelector(POPOVER_OPENED_SELECTOR);
|
|
673
|
+
|
|
674
|
+
expect(popover).toBeInTheDocument();
|
|
675
|
+
},
|
|
676
|
+
TIMEOUT_ACTION
|
|
677
|
+
);
|
|
678
|
+
});
|
|
679
|
+
},
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Mobile overlay backdrop (semi-transparent background).
|
|
684
|
+
*/
|
|
685
|
+
export const MobileOverlay: Story = {
|
|
686
|
+
args: {
|
|
687
|
+
data: sampleData,
|
|
688
|
+
minHeight: 400,
|
|
689
|
+
},
|
|
690
|
+
parameters: {
|
|
691
|
+
viewport: {
|
|
692
|
+
defaultViewport: 'mobile1',
|
|
693
|
+
},
|
|
694
|
+
chromatic: {
|
|
695
|
+
viewports: [375],
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
play: async ({ canvasElement, step }) => {
|
|
699
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
700
|
+
await waitFor(
|
|
701
|
+
() => {
|
|
702
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
703
|
+
|
|
704
|
+
expect(block).toBeInTheDocument();
|
|
705
|
+
},
|
|
706
|
+
TIMEOUT_INIT
|
|
707
|
+
);
|
|
708
|
+
await waitForToolbar(canvasElement);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
await step('Click block to show toolbar', async () => {
|
|
712
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
713
|
+
|
|
714
|
+
if (block) {
|
|
715
|
+
simulateClick(block);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
await waitFor(
|
|
719
|
+
() => {
|
|
720
|
+
const actionsZone = canvasElement.querySelector(ACTIONS_TESTID);
|
|
721
|
+
|
|
722
|
+
expect(actionsZone).toBeInTheDocument();
|
|
723
|
+
},
|
|
724
|
+
TIMEOUT_ACTION
|
|
725
|
+
);
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
await step('Open block tunes to show mobile overlay', async () => {
|
|
729
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
730
|
+
|
|
731
|
+
if (settingsButton) {
|
|
732
|
+
simulateClick(settingsButton);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
await waitFor(
|
|
736
|
+
() => {
|
|
737
|
+
const popover = document.querySelector(POPOVER_OPENED_SELECTOR);
|
|
738
|
+
|
|
739
|
+
expect(popover).toBeInTheDocument();
|
|
740
|
+
|
|
741
|
+
// On mobile, the overlay should be visible - check for overlay element
|
|
742
|
+
const popoverElements = document.querySelectorAll('[data-blok-popover-opened="true"]');
|
|
743
|
+
const hasOverlay = Array.from(popoverElements).some(p =>
|
|
744
|
+
p.querySelector('[data-blok-testid="popover-overlay"]')
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
// Overlay exists (visibility controlled by CSS media queries)
|
|
748
|
+
expect(hasOverlay || popover).toBeTruthy();
|
|
749
|
+
},
|
|
750
|
+
TIMEOUT_ACTION
|
|
751
|
+
);
|
|
752
|
+
});
|
|
753
|
+
},
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Block settings menu with convert-to dropdown open.
|
|
758
|
+
*/
|
|
759
|
+
export const BlockSettingsConvertToOpen: Story = {
|
|
760
|
+
args: {
|
|
761
|
+
data: sampleData,
|
|
762
|
+
tools: {
|
|
763
|
+
header: Header,
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
play: async ({ canvasElement, step }) => {
|
|
767
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
768
|
+
await waitFor(
|
|
769
|
+
() => {
|
|
770
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
771
|
+
|
|
772
|
+
expect(block).toBeInTheDocument();
|
|
773
|
+
},
|
|
774
|
+
TIMEOUT_INIT
|
|
775
|
+
);
|
|
776
|
+
await waitForToolbar(canvasElement);
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
await step('Click block to show toolbar', async () => {
|
|
780
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
781
|
+
|
|
782
|
+
if (block) {
|
|
783
|
+
simulateClick(block);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
await waitFor(
|
|
787
|
+
() => {
|
|
788
|
+
const actionsZone = canvasElement.querySelector(ACTIONS_TESTID);
|
|
789
|
+
|
|
790
|
+
expect(actionsZone).toBeInTheDocument();
|
|
791
|
+
},
|
|
792
|
+
TIMEOUT_ACTION
|
|
793
|
+
);
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
await step('Open block settings', async () => {
|
|
797
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
798
|
+
|
|
799
|
+
if (settingsButton) {
|
|
800
|
+
simulateClick(settingsButton);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
await waitFor(
|
|
804
|
+
() => {
|
|
805
|
+
const blockTunesPopover = document.querySelector(BLOCK_TUNES_POPOVER_TESTID);
|
|
806
|
+
|
|
807
|
+
expect(blockTunesPopover).toBeInTheDocument();
|
|
808
|
+
},
|
|
809
|
+
TIMEOUT_ACTION
|
|
810
|
+
);
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
await step('Click convert-to button to open nested popover', async () => {
|
|
814
|
+
// Wait for the convert-to button to appear (it's rendered async after block settings opens)
|
|
815
|
+
await waitFor(
|
|
816
|
+
() => {
|
|
817
|
+
const convertToButton = document.querySelector(CONVERT_TO_SELECTOR);
|
|
818
|
+
|
|
819
|
+
expect(convertToButton).toBeInTheDocument();
|
|
820
|
+
},
|
|
821
|
+
TIMEOUT_ACTION
|
|
822
|
+
);
|
|
823
|
+
|
|
824
|
+
const convertToButton = document.querySelector(CONVERT_TO_SELECTOR);
|
|
825
|
+
|
|
826
|
+
if (convertToButton) {
|
|
827
|
+
simulateClick(convertToButton);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Wait for the popover animation
|
|
831
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
832
|
+
|
|
833
|
+
await waitFor(
|
|
834
|
+
() => {
|
|
835
|
+
// The nested popover should be opened
|
|
836
|
+
const nestedPopover = document.querySelector(NESTED_POPOVER_SELECTOR + POPOVER_OPENED_SELECTOR);
|
|
837
|
+
|
|
838
|
+
expect(nestedPopover).toBeInTheDocument();
|
|
839
|
+
},
|
|
840
|
+
TIMEOUT_ACTION
|
|
841
|
+
);
|
|
842
|
+
});
|
|
843
|
+
},
|
|
844
|
+
};
|