@jackuait/blok 0.4.1 → 0.4.2
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 +136 -17
- package/codemod/README.md +16 -0
- package/codemod/migrate-editorjs-to-blok.js +859 -92
- package/codemod/test.js +682 -77
- package/dist/blok.mjs +5 -2
- package/dist/chunks/blok-BjgH1REI.mjs +12838 -0
- package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
- package/dist/chunks/i18next-loader-DfiUa_gd.mjs +43 -0
- package/dist/{index-CBkApZKo.mjs → chunks/index-5m5JWNey.mjs} +2 -2
- package/dist/chunks/inline-tool-convert-Bx5BVd8I.mjs +1988 -0
- package/dist/chunks/messages-2434tVOK.mjs +47 -0
- package/dist/chunks/messages-3DcCwXMF.mjs +47 -0
- package/dist/chunks/messages-4kMwVAKY.mjs +47 -0
- package/dist/chunks/messages-57uL5htT.mjs +47 -0
- package/dist/chunks/messages-76-iJV9Q.mjs +47 -0
- package/dist/chunks/messages-8p86Eyf2.mjs +47 -0
- package/dist/chunks/messages-BBX0p0Pi.mjs +47 -0
- package/dist/chunks/messages-BCm2eudQ.mjs +47 -0
- package/dist/chunks/messages-BFiUomgG.mjs +47 -0
- package/dist/chunks/messages-BIPNHHAV.mjs +47 -0
- package/dist/chunks/messages-BUlwu9mo.mjs +47 -0
- package/dist/chunks/messages-BX-DPa-z.mjs +47 -0
- package/dist/chunks/messages-BextV3Qh.mjs +47 -0
- package/dist/chunks/messages-BiPSFlUG.mjs +47 -0
- package/dist/chunks/messages-BiXe9G-O.mjs +47 -0
- package/dist/chunks/messages-Bl5z_Igo.mjs +47 -0
- package/dist/chunks/messages-BnsE97ku.mjs +47 -0
- package/dist/chunks/messages-BoO8gsVD.mjs +47 -0
- package/dist/chunks/messages-BqWaOGMn.mjs +47 -0
- package/dist/chunks/messages-BqkL2_Ro.mjs +47 -0
- package/dist/chunks/messages-BvCkXKX-.mjs +47 -0
- package/dist/chunks/messages-C6tbPLoj.mjs +47 -0
- package/dist/chunks/messages-CA6T3-gQ.mjs +47 -0
- package/dist/chunks/messages-CFFPFdWP.mjs +47 -0
- package/dist/chunks/messages-CFrKE-TN.mjs +47 -0
- package/dist/chunks/messages-CHz8VlG-.mjs +47 -0
- package/dist/chunks/messages-CLixzySl.mjs +47 -0
- package/dist/chunks/messages-CV7OM_qk.mjs +47 -0
- package/dist/chunks/messages-CXHt3eCC.mjs +47 -0
- package/dist/chunks/messages-CbmsBrB0.mjs +47 -0
- package/dist/chunks/messages-Ceo1KtFx.mjs +47 -0
- package/dist/chunks/messages-Cm0LJLtB.mjs +47 -0
- package/dist/chunks/messages-CmymP_Ar.mjs +47 -0
- package/dist/chunks/messages-D0ohMB5H.mjs +47 -0
- package/dist/chunks/messages-D3GrDwXh.mjs +47 -0
- package/dist/chunks/messages-D3vTzIpL.mjs +47 -0
- package/dist/chunks/messages-D5WeksbV.mjs +47 -0
- package/dist/chunks/messages-DGaab4EP.mjs +47 -0
- package/dist/chunks/messages-DKha57ZU.mjs +47 -0
- package/dist/chunks/messages-DOaujgMW.mjs +47 -0
- package/dist/chunks/messages-DVbPLd_0.mjs +47 -0
- package/dist/chunks/messages-D_FCyfW6.mjs +47 -0
- package/dist/chunks/messages-Dd5iZN3c.mjs +47 -0
- package/dist/chunks/messages-DehM7135.mjs +47 -0
- package/dist/chunks/messages-Dg1OHftD.mjs +47 -0
- package/dist/chunks/messages-Di6Flq-b.mjs +47 -0
- package/dist/chunks/messages-Dqhhex6e.mjs +47 -0
- package/dist/chunks/messages-DueVe0F1.mjs +47 -0
- package/dist/chunks/messages-Dx3eFwI0.mjs +47 -0
- package/dist/chunks/messages-FOtiUoKl.mjs +47 -0
- package/dist/chunks/messages-FTOZNhRD.mjs +47 -0
- package/dist/chunks/messages-IQxGfQIV.mjs +47 -0
- package/dist/chunks/messages-JF2fzCkK.mjs +47 -0
- package/dist/chunks/messages-MOGl7I5v.mjs +47 -0
- package/dist/chunks/messages-QgYhPL-3.mjs +47 -0
- package/dist/chunks/messages-WYWIbQwo.mjs +47 -0
- package/dist/chunks/messages-a6A_LgDv.mjs +47 -0
- package/dist/chunks/messages-bSf31LJi.mjs +47 -0
- package/dist/chunks/messages-diGozhTn.mjs +47 -0
- package/dist/chunks/messages-er-kd-VO.mjs +47 -0
- package/dist/chunks/messages-ez3w5NBn.mjs +47 -0
- package/dist/chunks/messages-f3uXjegd.mjs +47 -0
- package/dist/chunks/messages-ohwI1UGv.mjs +47 -0
- package/dist/chunks/messages-p9BZJaFV.mjs +47 -0
- package/dist/chunks/messages-qIQ4L4rw.mjs +47 -0
- package/dist/chunks/messages-qWkXPggi.mjs +47 -0
- package/dist/chunks/messages-w5foGze_.mjs +47 -0
- package/dist/full.mjs +50 -0
- package/dist/locales.mjs +227 -0
- package/dist/messages-2434tVOK.mjs +47 -0
- package/dist/messages-3DcCwXMF.mjs +47 -0
- package/dist/messages-4kMwVAKY.mjs +47 -0
- package/dist/messages-57uL5htT.mjs +47 -0
- package/dist/messages-76-iJV9Q.mjs +47 -0
- package/dist/messages-8p86Eyf2.mjs +47 -0
- package/dist/messages-BBX0p0Pi.mjs +47 -0
- package/dist/messages-BCm2eudQ.mjs +47 -0
- package/dist/messages-BFiUomgG.mjs +47 -0
- package/dist/messages-BIPNHHAV.mjs +47 -0
- package/dist/messages-BUlwu9mo.mjs +47 -0
- package/dist/messages-BX-DPa-z.mjs +47 -0
- package/dist/messages-BextV3Qh.mjs +47 -0
- package/dist/messages-BiPSFlUG.mjs +47 -0
- package/dist/messages-BiXe9G-O.mjs +47 -0
- package/dist/messages-Bl5z_Igo.mjs +47 -0
- package/dist/messages-BnsE97ku.mjs +47 -0
- package/dist/messages-BoO8gsVD.mjs +47 -0
- package/dist/messages-BqWaOGMn.mjs +47 -0
- package/dist/messages-BqkL2_Ro.mjs +47 -0
- package/dist/messages-BvCkXKX-.mjs +47 -0
- package/dist/messages-C6tbPLoj.mjs +47 -0
- package/dist/messages-CA6T3-gQ.mjs +47 -0
- package/dist/messages-CFFPFdWP.mjs +47 -0
- package/dist/messages-CFrKE-TN.mjs +47 -0
- package/dist/messages-CHz8VlG-.mjs +47 -0
- package/dist/messages-CLixzySl.mjs +47 -0
- package/dist/messages-CV7OM_qk.mjs +47 -0
- package/dist/messages-CXHt3eCC.mjs +47 -0
- package/dist/messages-CbmsBrB0.mjs +47 -0
- package/dist/messages-Ceo1KtFx.mjs +47 -0
- package/dist/messages-Cm0LJLtB.mjs +47 -0
- package/dist/messages-CmymP_Ar.mjs +47 -0
- package/dist/messages-D0ohMB5H.mjs +47 -0
- package/dist/messages-D3GrDwXh.mjs +47 -0
- package/dist/messages-D3vTzIpL.mjs +47 -0
- package/dist/messages-D5WeksbV.mjs +47 -0
- package/dist/messages-DGaab4EP.mjs +47 -0
- package/dist/messages-DKha57ZU.mjs +47 -0
- package/dist/messages-DOaujgMW.mjs +47 -0
- package/dist/messages-DVbPLd_0.mjs +47 -0
- package/dist/messages-D_FCyfW6.mjs +47 -0
- package/dist/messages-Dd5iZN3c.mjs +47 -0
- package/dist/messages-DehM7135.mjs +47 -0
- package/dist/messages-Dg1OHftD.mjs +47 -0
- package/dist/messages-Di6Flq-b.mjs +47 -0
- package/dist/messages-Dqhhex6e.mjs +47 -0
- package/dist/messages-DueVe0F1.mjs +47 -0
- package/dist/messages-Dx3eFwI0.mjs +47 -0
- package/dist/messages-FOtiUoKl.mjs +47 -0
- package/dist/messages-FTOZNhRD.mjs +47 -0
- package/dist/messages-IQxGfQIV.mjs +47 -0
- package/dist/messages-JF2fzCkK.mjs +47 -0
- package/dist/messages-MOGl7I5v.mjs +47 -0
- package/dist/messages-QgYhPL-3.mjs +47 -0
- package/dist/messages-WYWIbQwo.mjs +47 -0
- package/dist/messages-a6A_LgDv.mjs +47 -0
- package/dist/messages-bSf31LJi.mjs +47 -0
- package/dist/messages-diGozhTn.mjs +47 -0
- package/dist/messages-er-kd-VO.mjs +47 -0
- package/dist/messages-ez3w5NBn.mjs +47 -0
- package/dist/messages-f3uXjegd.mjs +47 -0
- package/dist/messages-ohwI1UGv.mjs +47 -0
- package/dist/messages-p9BZJaFV.mjs +47 -0
- package/dist/messages-qIQ4L4rw.mjs +47 -0
- package/dist/messages-qWkXPggi.mjs +47 -0
- package/dist/messages-w5foGze_.mjs +47 -0
- package/dist/tools.mjs +3073 -0
- package/dist/vendor.LICENSE.txt +59 -156
- package/package.json +47 -15
- 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 +1427 -0
- package/src/components/block-tunes/block-tune-delete.ts +51 -0
- package/src/components/blocks.ts +338 -0
- package/src/components/constants/data-attributes.ts +342 -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 +481 -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 +44 -0
- package/src/components/i18n/locales/ar/messages.json +44 -0
- package/src/components/i18n/locales/az/messages.json +44 -0
- package/src/components/i18n/locales/bg/messages.json +44 -0
- package/src/components/i18n/locales/bn/messages.json +44 -0
- package/src/components/i18n/locales/bs/messages.json +44 -0
- package/src/components/i18n/locales/cs/messages.json +44 -0
- package/src/components/i18n/locales/da/messages.json +44 -0
- package/src/components/i18n/locales/de/messages.json +44 -0
- package/src/components/i18n/locales/dv/messages.json +44 -0
- package/src/components/i18n/locales/el/messages.json +44 -0
- package/src/components/i18n/locales/en/messages.json +44 -0
- package/src/components/i18n/locales/es/messages.json +44 -0
- package/src/components/i18n/locales/et/messages.json +44 -0
- package/src/components/i18n/locales/fa/messages.json +44 -0
- package/src/components/i18n/locales/fi/messages.json +44 -0
- package/src/components/i18n/locales/fil/messages.json +44 -0
- package/src/components/i18n/locales/fr/messages.json +44 -0
- package/src/components/i18n/locales/gu/messages.json +44 -0
- package/src/components/i18n/locales/he/messages.json +44 -0
- package/src/components/i18n/locales/hi/messages.json +44 -0
- package/src/components/i18n/locales/hr/messages.json +44 -0
- package/src/components/i18n/locales/hu/messages.json +44 -0
- package/src/components/i18n/locales/hy/messages.json +44 -0
- package/src/components/i18n/locales/id/messages.json +44 -0
- package/src/components/i18n/locales/index.ts +225 -0
- package/src/components/i18n/locales/it/messages.json +44 -0
- package/src/components/i18n/locales/ja/messages.json +44 -0
- package/src/components/i18n/locales/ka/messages.json +44 -0
- package/src/components/i18n/locales/km/messages.json +44 -0
- package/src/components/i18n/locales/kn/messages.json +44 -0
- package/src/components/i18n/locales/ko/messages.json +44 -0
- package/src/components/i18n/locales/ku/messages.json +44 -0
- package/src/components/i18n/locales/lo/messages.json +44 -0
- package/src/components/i18n/locales/lt/messages.json +44 -0
- package/src/components/i18n/locales/lv/messages.json +44 -0
- package/src/components/i18n/locales/mk/messages.json +44 -0
- package/src/components/i18n/locales/ml/messages.json +44 -0
- package/src/components/i18n/locales/mn/messages.json +44 -0
- package/src/components/i18n/locales/mr/messages.json +44 -0
- package/src/components/i18n/locales/ms/messages.json +44 -0
- package/src/components/i18n/locales/my/messages.json +44 -0
- package/src/components/i18n/locales/ne/messages.json +44 -0
- package/src/components/i18n/locales/nl/messages.json +44 -0
- package/src/components/i18n/locales/no/messages.json +44 -0
- package/src/components/i18n/locales/pa/messages.json +44 -0
- package/src/components/i18n/locales/pl/messages.json +44 -0
- package/src/components/i18n/locales/ps/messages.json +44 -0
- package/src/components/i18n/locales/pt/messages.json +44 -0
- package/src/components/i18n/locales/ro/messages.json +44 -0
- package/src/components/i18n/locales/ru/messages.json +44 -0
- package/src/components/i18n/locales/sd/messages.json +44 -0
- package/src/components/i18n/locales/si/messages.json +44 -0
- package/src/components/i18n/locales/sk/messages.json +44 -0
- package/src/components/i18n/locales/sl/messages.json +44 -0
- package/src/components/i18n/locales/sq/messages.json +44 -0
- package/src/components/i18n/locales/sr/messages.json +44 -0
- package/src/components/i18n/locales/sv/messages.json +44 -0
- package/src/components/i18n/locales/sw/messages.json +44 -0
- package/src/components/i18n/locales/ta/messages.json +44 -0
- package/src/components/i18n/locales/te/messages.json +44 -0
- package/src/components/i18n/locales/th/messages.json +44 -0
- package/src/components/i18n/locales/tr/messages.json +44 -0
- package/src/components/i18n/locales/ug/messages.json +44 -0
- package/src/components/i18n/locales/uk/messages.json +44 -0
- package/src/components/i18n/locales/ur/messages.json +44 -0
- package/src/components/i18n/locales/vi/messages.json +44 -0
- package/src/components/i18n/locales/yi/messages.json +44 -0
- package/src/components/i18n/locales/zh/messages.json +44 -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 +363 -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 +33 -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 +1375 -0
- package/src/components/modules/blockManager.ts +1348 -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 +1141 -0
- package/src/components/modules/history.ts +1098 -0
- package/src/components/modules/i18n.ts +325 -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 +668 -0
- package/src/components/modules/renderer.ts +155 -0
- package/src/components/modules/saver.ts +283 -0
- package/src/components/modules/toolbar/blockSettings.ts +776 -0
- package/src/components/modules/toolbar/index.ts +1311 -0
- package/src/components/modules/toolbar/inline.ts +956 -0
- package/src/components/modules/tools.ts +589 -0
- package/src/components/modules/ui.ts +1179 -0
- package/src/components/polyfills.ts +113 -0
- package/src/components/selection.ts +1189 -0
- package/src/components/tools/base.ts +274 -0
- package/src/components/tools/block.ts +291 -0
- package/src/components/tools/collection.ts +67 -0
- package/src/components/tools/factory.ts +85 -0
- package/src/components/tools/inline.ts +71 -0
- package/src/components/tools/tune.ts +33 -0
- package/src/components/ui/toolbox.ts +497 -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 +666 -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 +187 -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 +181 -0
- package/src/components/utils/popover/components/search-input/search-input.types.ts +30 -0
- package/src/components/utils/popover/index.ts +13 -0
- package/src/components/utils/popover/popover-abstract.ts +448 -0
- package/src/components/utils/popover/popover-desktop.ts +643 -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 +105 -0
- package/src/components/utils/tooltip.ts +642 -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 +570 -0
- package/src/tools/index.ts +38 -0
- package/src/tools/list/index.ts +1803 -0
- package/src/tools/paragraph/index.ts +411 -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 +1 -1
- package/types/api/i18n.d.ts +5 -3
- package/types/api/selection.d.ts +6 -0
- package/types/api/styles.d.ts +0 -5
- package/types/configs/blok-config.d.ts +21 -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 +169 -0
- package/types/data-formats/output-data.d.ts +15 -0
- package/types/full.d.ts +80 -0
- package/types/index.d.ts +9 -24
- 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/list.d.ts +25 -18
- package/types/tools/tool-settings.d.ts +8 -1
- package/types/tools/tool.d.ts +6 -0
- package/types/tools-entry.d.ts +49 -0
- package/types/utils/popover/popover-item.d.ts +0 -5
- package/dist/blok-BwPfU8ro.mjs +0 -21510
- package/dist/blok.umd.js +0 -198
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/html-vite';
|
|
2
|
+
import { waitFor, expect } from 'storybook/test';
|
|
3
|
+
import type { OutputData } from '@/types';
|
|
4
|
+
import { createEditorContainer, simulateClick, waitForToolbar } from './helpers';
|
|
5
|
+
import type { EditorFactoryOptions } from './helpers';
|
|
6
|
+
|
|
7
|
+
interface SelectionArgs extends EditorFactoryOptions {
|
|
8
|
+
minHeight: number;
|
|
9
|
+
data: OutputData | undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Constants
|
|
13
|
+
const BLOCK_TESTID = '[data-blok-testid="block-wrapper"]';
|
|
14
|
+
const INLINE_TOOLBAR_TESTID = '[data-blok-testid="inline-toolbar"]';
|
|
15
|
+
const INLINE_TOOL_INPUT_TESTID = '[data-blok-testid="inline-tool-input"]';
|
|
16
|
+
const CONTENTEDITABLE_SELECTOR = '[contenteditable="true"]';
|
|
17
|
+
const LINK_TOOL_SELECTOR = '[data-blok-item-name="link"]';
|
|
18
|
+
|
|
19
|
+
const TIMEOUT_INIT = { timeout: 5000 };
|
|
20
|
+
const TIMEOUT_ACTION = { timeout: 5000 };
|
|
21
|
+
|
|
22
|
+
const multiLineData: OutputData = {
|
|
23
|
+
time: Date.now(),
|
|
24
|
+
version: '1.0.0',
|
|
25
|
+
blocks: [
|
|
26
|
+
{
|
|
27
|
+
id: 'multi-line-block',
|
|
28
|
+
type: 'paragraph',
|
|
29
|
+
data: {
|
|
30
|
+
text: 'This is the first line of text that spans multiple words. Here is the second sentence with more content. And finally a third sentence to make it longer.',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const multiBlockData: OutputData = {
|
|
37
|
+
time: Date.now(),
|
|
38
|
+
version: '1.0.0',
|
|
39
|
+
blocks: [
|
|
40
|
+
{
|
|
41
|
+
id: 'block-1',
|
|
42
|
+
type: 'paragraph',
|
|
43
|
+
data: { text: 'First paragraph with some text to select from here.' },
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'block-2',
|
|
47
|
+
type: 'paragraph',
|
|
48
|
+
data: { text: 'Second paragraph continues the selection across blocks.' },
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'block-3',
|
|
52
|
+
type: 'paragraph',
|
|
53
|
+
data: { text: 'Third paragraph ends the cross-block selection here.' },
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const createEditor = (args: SelectionArgs): HTMLElement => createEditorContainer(args);
|
|
59
|
+
|
|
60
|
+
const meta: Meta<SelectionArgs> = {
|
|
61
|
+
title: 'Components/Selection',
|
|
62
|
+
tags: ['autodocs'],
|
|
63
|
+
args: {
|
|
64
|
+
minHeight: 300,
|
|
65
|
+
data: multiLineData,
|
|
66
|
+
},
|
|
67
|
+
render: createEditor,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default meta;
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
type Story = StoryObj<SelectionArgs>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Selects text across multiple words/strings and opens the link input.
|
|
77
|
+
* This demonstrates the fake background selection behavior when focus moves to the link input.
|
|
78
|
+
*/
|
|
79
|
+
export const MultiStringSelectionWithLinkInput: Story = {
|
|
80
|
+
args: {
|
|
81
|
+
data: multiLineData,
|
|
82
|
+
},
|
|
83
|
+
play: async ({ canvasElement, step }) => {
|
|
84
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
85
|
+
await waitFor(
|
|
86
|
+
() => {
|
|
87
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
88
|
+
|
|
89
|
+
expect(block).toBeInTheDocument();
|
|
90
|
+
},
|
|
91
|
+
TIMEOUT_INIT
|
|
92
|
+
);
|
|
93
|
+
await waitForToolbar(canvasElement);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
await step('Select text spanning multiple words', async () => {
|
|
97
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
98
|
+
const contentEditable = block?.querySelector(CONTENTEDITABLE_SELECTOR);
|
|
99
|
+
|
|
100
|
+
if (contentEditable) {
|
|
101
|
+
simulateClick(contentEditable);
|
|
102
|
+
|
|
103
|
+
const range = document.createRange();
|
|
104
|
+
const textNode = contentEditable.firstChild;
|
|
105
|
+
|
|
106
|
+
if (textNode && textNode.nodeType === Node.TEXT_NODE) {
|
|
107
|
+
// Select "first line of text that spans multiple words" (characters 12-54)
|
|
108
|
+
range.setStart(textNode, 12);
|
|
109
|
+
range.setEnd(textNode, 54);
|
|
110
|
+
} else {
|
|
111
|
+
range.selectNodeContents(contentEditable);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const selection = window.getSelection();
|
|
115
|
+
|
|
116
|
+
selection?.removeAllRanges();
|
|
117
|
+
selection?.addRange(range);
|
|
118
|
+
|
|
119
|
+
(contentEditable as HTMLElement).focus();
|
|
120
|
+
document.dispatchEvent(new Event('selectionchange'));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Wait for debounced selection handler
|
|
124
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
125
|
+
|
|
126
|
+
await waitFor(
|
|
127
|
+
() => {
|
|
128
|
+
const inlineToolbar = document.querySelector(INLINE_TOOLBAR_TESTID);
|
|
129
|
+
|
|
130
|
+
expect(inlineToolbar).toBeInTheDocument();
|
|
131
|
+
},
|
|
132
|
+
TIMEOUT_ACTION
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await step('Click link tool to open input', async () => {
|
|
137
|
+
const linkTool = document.querySelector(LINK_TOOL_SELECTOR);
|
|
138
|
+
|
|
139
|
+
expect(linkTool).toBeInTheDocument();
|
|
140
|
+
|
|
141
|
+
if (linkTool) {
|
|
142
|
+
(linkTool as HTMLElement).click();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
await waitFor(
|
|
146
|
+
() => {
|
|
147
|
+
const linkInput = document.querySelector(INLINE_TOOL_INPUT_TESTID);
|
|
148
|
+
|
|
149
|
+
expect(linkInput).toBeInTheDocument();
|
|
150
|
+
|
|
151
|
+
// Verify fake background is applied to maintain visual selection
|
|
152
|
+
const fakeBackground = document.querySelector('[data-blok-fake-background="true"]');
|
|
153
|
+
|
|
154
|
+
expect(fakeBackground).toBeInTheDocument();
|
|
155
|
+
},
|
|
156
|
+
TIMEOUT_ACTION
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Selects text across multiple blocks/paragraphs and opens the link input.
|
|
164
|
+
* This demonstrates cross-block selection with fake background when focus moves to the link input.
|
|
165
|
+
*/
|
|
166
|
+
export const CrossBlockSelectionWithLinkInput: Story = {
|
|
167
|
+
args: {
|
|
168
|
+
data: multiBlockData,
|
|
169
|
+
},
|
|
170
|
+
play: async ({ canvasElement, step }) => {
|
|
171
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
172
|
+
await waitFor(
|
|
173
|
+
() => {
|
|
174
|
+
const blocks = canvasElement.querySelectorAll(BLOCK_TESTID);
|
|
175
|
+
|
|
176
|
+
expect(blocks.length).toBeGreaterThanOrEqual(3);
|
|
177
|
+
},
|
|
178
|
+
TIMEOUT_INIT
|
|
179
|
+
);
|
|
180
|
+
await waitForToolbar(canvasElement);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
await step('Select text across multiple blocks', async () => {
|
|
184
|
+
const blocks = canvasElement.querySelectorAll(BLOCK_TESTID);
|
|
185
|
+
const firstBlock = blocks[0];
|
|
186
|
+
const lastBlock = blocks[2];
|
|
187
|
+
|
|
188
|
+
const firstContentEditable = firstBlock?.querySelector(CONTENTEDITABLE_SELECTOR);
|
|
189
|
+
const lastContentEditable = lastBlock?.querySelector(CONTENTEDITABLE_SELECTOR);
|
|
190
|
+
|
|
191
|
+
if (firstContentEditable && lastContentEditable) {
|
|
192
|
+
simulateClick(firstContentEditable);
|
|
193
|
+
|
|
194
|
+
const range = document.createRange();
|
|
195
|
+
const firstTextNode = firstContentEditable.firstChild;
|
|
196
|
+
const lastTextNode = lastContentEditable.firstChild;
|
|
197
|
+
|
|
198
|
+
if (firstTextNode && lastTextNode) {
|
|
199
|
+
// Select from "some text" in first block to "cross-block" in third block
|
|
200
|
+
range.setStart(firstTextNode, 22);
|
|
201
|
+
range.setEnd(lastTextNode, 35);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const selection = window.getSelection();
|
|
205
|
+
|
|
206
|
+
selection?.removeAllRanges();
|
|
207
|
+
selection?.addRange(range);
|
|
208
|
+
|
|
209
|
+
(firstContentEditable as HTMLElement).focus();
|
|
210
|
+
document.dispatchEvent(new Event('selectionchange'));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Wait for debounced selection handler
|
|
214
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
215
|
+
|
|
216
|
+
await waitFor(
|
|
217
|
+
() => {
|
|
218
|
+
const inlineToolbar = document.querySelector(INLINE_TOOLBAR_TESTID);
|
|
219
|
+
|
|
220
|
+
expect(inlineToolbar).toBeInTheDocument();
|
|
221
|
+
},
|
|
222
|
+
TIMEOUT_ACTION
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
await step('Click link tool to open input', async () => {
|
|
227
|
+
const linkTool = document.querySelector(LINK_TOOL_SELECTOR);
|
|
228
|
+
|
|
229
|
+
expect(linkTool).toBeInTheDocument();
|
|
230
|
+
|
|
231
|
+
if (linkTool) {
|
|
232
|
+
(linkTool as HTMLElement).click();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
await waitFor(
|
|
236
|
+
() => {
|
|
237
|
+
const linkInput = document.querySelector(INLINE_TOOL_INPUT_TESTID);
|
|
238
|
+
|
|
239
|
+
expect(linkInput).toBeInTheDocument();
|
|
240
|
+
|
|
241
|
+
// Verify fake background is applied to maintain visual selection across blocks
|
|
242
|
+
const fakeBackgrounds = document.querySelectorAll('[data-blok-fake-background="true"]');
|
|
243
|
+
|
|
244
|
+
expect(fakeBackgrounds.length).toBeGreaterThan(0);
|
|
245
|
+
},
|
|
246
|
+
TIMEOUT_ACTION
|
|
247
|
+
);
|
|
248
|
+
});
|
|
249
|
+
},
|
|
250
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StubBlock.stories.ts - Stories for stub block component.
|
|
3
|
+
*
|
|
4
|
+
* The stub block is displayed when a block's tool is not found/registered.
|
|
5
|
+
* It shows an error state with the tool name and preserves the original data.
|
|
6
|
+
*/
|
|
7
|
+
import type { Meta, StoryObj } from '@storybook/html-vite';
|
|
8
|
+
import { waitFor, expect } from 'storybook/test';
|
|
9
|
+
import type { OutputData } from '@/types';
|
|
10
|
+
import { createEditorContainer } from './helpers';
|
|
11
|
+
import type { EditorFactoryOptions } from './helpers';
|
|
12
|
+
|
|
13
|
+
interface StubBlockArgs extends EditorFactoryOptions {
|
|
14
|
+
minHeight: number;
|
|
15
|
+
data: OutputData;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const TIMEOUT_INIT = { timeout: 5000 };
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sample data with a block type that has no registered tool
|
|
22
|
+
*/
|
|
23
|
+
const stubBlockData: OutputData = {
|
|
24
|
+
time: Date.now(),
|
|
25
|
+
version: '1.0.0',
|
|
26
|
+
blocks: [
|
|
27
|
+
{
|
|
28
|
+
id: 'stub-block-1',
|
|
29
|
+
type: 'paragraph',
|
|
30
|
+
data: { text: 'This is a regular paragraph block.' },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'stub-block-2',
|
|
34
|
+
type: 'unknownTool', // This tool doesn't exist - will show stub
|
|
35
|
+
data: { someData: 'preserved data for unknown tool' },
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'stub-block-3',
|
|
39
|
+
type: 'paragraph',
|
|
40
|
+
data: { text: 'Another regular paragraph after the stub.' },
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const createEditor = (args: StubBlockArgs): HTMLElement => createEditorContainer(args);
|
|
46
|
+
|
|
47
|
+
const meta: Meta<StubBlockArgs> = {
|
|
48
|
+
title: 'Components/Stub Block',
|
|
49
|
+
tags: ['autodocs'],
|
|
50
|
+
args: {
|
|
51
|
+
minHeight: 300,
|
|
52
|
+
data: stubBlockData,
|
|
53
|
+
},
|
|
54
|
+
render: createEditor,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default meta;
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
type Story = StoryObj<StubBlockArgs>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Stub block shown when tool is not registered.
|
|
64
|
+
* Displays warning icon, tool name, and error message.
|
|
65
|
+
*/
|
|
66
|
+
export const MissingTool: Story = {
|
|
67
|
+
args: {
|
|
68
|
+
data: stubBlockData,
|
|
69
|
+
},
|
|
70
|
+
play: async ({ canvasElement, step }) => {
|
|
71
|
+
await step('Wait for stub block to render', async () => {
|
|
72
|
+
await waitFor(
|
|
73
|
+
() => {
|
|
74
|
+
// Look for the stub block by its data attribute
|
|
75
|
+
const stubBlock = canvasElement.querySelector('[data-blok-stub]');
|
|
76
|
+
|
|
77
|
+
expect(stubBlock).toBeTruthy();
|
|
78
|
+
},
|
|
79
|
+
TIMEOUT_INIT
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
await step('Verify stub block structure', async () => {
|
|
84
|
+
const stubBlock = canvasElement.querySelector('[data-blok-stub]');
|
|
85
|
+
const title = stubBlock?.querySelector('[data-blok-stub-title]');
|
|
86
|
+
const subtitle = stubBlock?.querySelector('[data-blok-stub-subtitle]');
|
|
87
|
+
|
|
88
|
+
expect(title).toBeTruthy();
|
|
89
|
+
expect(subtitle).toBeTruthy();
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Multiple stub blocks for different missing tools.
|
|
96
|
+
*/
|
|
97
|
+
export const MultipleMissingTools: Story = {
|
|
98
|
+
args: {
|
|
99
|
+
data: {
|
|
100
|
+
time: Date.now(),
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
blocks: [
|
|
103
|
+
{
|
|
104
|
+
id: 'multi-stub-1',
|
|
105
|
+
type: 'customImage', // Missing tool
|
|
106
|
+
data: { url: 'https://example.com/image.jpg' },
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'multi-stub-2',
|
|
110
|
+
type: 'customVideo', // Missing tool
|
|
111
|
+
data: { videoId: 'abc123' },
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: 'multi-stub-3',
|
|
115
|
+
type: 'customEmbed', // Missing tool
|
|
116
|
+
data: { embedCode: '<iframe></iframe>' },
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
play: async ({ canvasElement, step }) => {
|
|
122
|
+
await step('Wait for all stub blocks to render', async () => {
|
|
123
|
+
await waitFor(
|
|
124
|
+
() => {
|
|
125
|
+
// Count stub wrapper elements by data attribute
|
|
126
|
+
const stubWrappers = canvasElement.querySelectorAll('[data-blok-stub]');
|
|
127
|
+
|
|
128
|
+
expect(stubWrappers.length).toBe(3);
|
|
129
|
+
},
|
|
130
|
+
TIMEOUT_INIT
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Stub block in read-only mode.
|
|
138
|
+
*/
|
|
139
|
+
export const StubInReadOnly: Story = {
|
|
140
|
+
args: {
|
|
141
|
+
data: stubBlockData,
|
|
142
|
+
readOnly: true,
|
|
143
|
+
},
|
|
144
|
+
play: async ({ canvasElement, step }) => {
|
|
145
|
+
await step('Wait for stub block in read-only mode', async () => {
|
|
146
|
+
await waitFor(
|
|
147
|
+
() => {
|
|
148
|
+
const stubBlock = canvasElement.querySelector('[data-blok-stub]');
|
|
149
|
+
|
|
150
|
+
expect(stubBlock).toBeTruthy();
|
|
151
|
+
},
|
|
152
|
+
TIMEOUT_INIT
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
};
|
|
@@ -0,0 +1,223 @@
|
|
|
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 } from './helpers';
|
|
5
|
+
import type { EditorFactoryOptions } from './helpers';
|
|
6
|
+
|
|
7
|
+
interface ToolbarArgs extends EditorFactoryOptions {
|
|
8
|
+
minHeight: number;
|
|
9
|
+
data: OutputData | undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Constants to avoid duplicate strings
|
|
13
|
+
const BLOCK_TESTID = '[data-blok-testid="block-wrapper"]';
|
|
14
|
+
const ACTIONS_TESTID = '[data-blok-testid="toolbar-actions"]';
|
|
15
|
+
const PLUS_BUTTON_TESTID = '[data-blok-testid="plus-button"]';
|
|
16
|
+
const SETTINGS_BUTTON_TESTID = '[data-blok-testid="settings-toggler"]';
|
|
17
|
+
|
|
18
|
+
const TIMEOUT_INIT = { timeout: 5000 };
|
|
19
|
+
const TIMEOUT_ACTION = { timeout: 5000 };
|
|
20
|
+
|
|
21
|
+
const sampleData: OutputData = {
|
|
22
|
+
time: Date.now(),
|
|
23
|
+
version: '1.0.0',
|
|
24
|
+
blocks: [
|
|
25
|
+
{
|
|
26
|
+
id: 'toolbar-block-1',
|
|
27
|
+
type: 'paragraph',
|
|
28
|
+
data: { text: 'First paragraph block for toolbar testing.' },
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'toolbar-block-2',
|
|
32
|
+
type: 'paragraph',
|
|
33
|
+
data: { text: 'Second paragraph block.' },
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'toolbar-block-3',
|
|
37
|
+
type: 'paragraph',
|
|
38
|
+
data: { text: 'Third paragraph block.' },
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const createEditor = (args: ToolbarArgs): HTMLElement => createEditorContainer(args);
|
|
44
|
+
|
|
45
|
+
const meta: Meta<ToolbarArgs> = {
|
|
46
|
+
title: 'Components/Toolbar',
|
|
47
|
+
tags: ['autodocs'],
|
|
48
|
+
args: {
|
|
49
|
+
minHeight: 300,
|
|
50
|
+
data: sampleData,
|
|
51
|
+
},
|
|
52
|
+
render: createEditor,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default meta;
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
type Story = StoryObj<ToolbarArgs>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Default state: Toolbar is hidden until a block is focused/hovered.
|
|
62
|
+
*/
|
|
63
|
+
export const Default: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
data: sampleData,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Toolbar visible with actions zone shown when block is hovered.
|
|
71
|
+
*/
|
|
72
|
+
export const ToolbarVisible: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
data: sampleData,
|
|
75
|
+
},
|
|
76
|
+
play: async ({ canvasElement, step }) => {
|
|
77
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
78
|
+
await waitFor(
|
|
79
|
+
() => {
|
|
80
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
81
|
+
|
|
82
|
+
expect(block).toBeInTheDocument();
|
|
83
|
+
},
|
|
84
|
+
TIMEOUT_INIT
|
|
85
|
+
);
|
|
86
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
87
|
+
await waitForToolbar(canvasElement);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
await step('Click on a block to show toolbar', async () => {
|
|
91
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
92
|
+
|
|
93
|
+
if (block) {
|
|
94
|
+
simulateClick(block);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await waitFor(
|
|
98
|
+
() => {
|
|
99
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
100
|
+
|
|
101
|
+
expect(toolbar).toBeInTheDocument();
|
|
102
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
103
|
+
},
|
|
104
|
+
TIMEOUT_ACTION
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await step('Verify actions zone is visible', async () => {
|
|
109
|
+
await waitFor(
|
|
110
|
+
() => {
|
|
111
|
+
const actionsZone = canvasElement.querySelector(ACTIONS_TESTID);
|
|
112
|
+
|
|
113
|
+
expect(actionsZone).toBeInTheDocument();
|
|
114
|
+
},
|
|
115
|
+
TIMEOUT_ACTION
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Plus button hover state.
|
|
123
|
+
*/
|
|
124
|
+
export const PlusButtonHover: Story = {
|
|
125
|
+
args: {
|
|
126
|
+
data: sampleData,
|
|
127
|
+
},
|
|
128
|
+
play: async ({ canvasElement, step }) => {
|
|
129
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
130
|
+
await waitFor(
|
|
131
|
+
() => {
|
|
132
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
133
|
+
|
|
134
|
+
expect(block).toBeInTheDocument();
|
|
135
|
+
},
|
|
136
|
+
TIMEOUT_INIT
|
|
137
|
+
);
|
|
138
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
139
|
+
await waitForToolbar(canvasElement);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
await step('Click on block to show toolbar', async () => {
|
|
143
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
144
|
+
|
|
145
|
+
if (block) {
|
|
146
|
+
simulateClick(block);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
await waitFor(
|
|
150
|
+
() => {
|
|
151
|
+
const toolbar = canvasElement.querySelector(TOOLBAR_TESTID);
|
|
152
|
+
|
|
153
|
+
expect(toolbar).toHaveAttribute('data-blok-opened', 'true');
|
|
154
|
+
},
|
|
155
|
+
TIMEOUT_ACTION
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
await step('Hover plus button', async () => {
|
|
160
|
+
const plusButton = canvasElement.querySelector(PLUS_BUTTON_TESTID);
|
|
161
|
+
|
|
162
|
+
if (plusButton) {
|
|
163
|
+
await userEvent.hover(plusButton);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/*
|
|
170
|
+
* NOTE: Toolbox opened state lives in EditorModes.stories.ts (ToolboxOpenedMode)
|
|
171
|
+
* Block tunes popover and delete confirmation live in Popover.stories.ts
|
|
172
|
+
* This file focuses on toolbar visibility, button states, and hover interactions.
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Settings button hover state (grab cursor).
|
|
177
|
+
*/
|
|
178
|
+
export const SettingsButtonHover: Story = {
|
|
179
|
+
args: {
|
|
180
|
+
data: sampleData,
|
|
181
|
+
},
|
|
182
|
+
play: async ({ canvasElement, step }) => {
|
|
183
|
+
await step('Wait for editor and toolbar to initialize', async () => {
|
|
184
|
+
await waitFor(
|
|
185
|
+
() => {
|
|
186
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
187
|
+
|
|
188
|
+
expect(block).toBeInTheDocument();
|
|
189
|
+
},
|
|
190
|
+
TIMEOUT_INIT
|
|
191
|
+
);
|
|
192
|
+
// Wait for toolbar to be created (happens in requestIdleCallback)
|
|
193
|
+
await waitForToolbar(canvasElement);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
await step('Click on block to show toolbar', async () => {
|
|
197
|
+
const block = canvasElement.querySelector(BLOCK_TESTID);
|
|
198
|
+
|
|
199
|
+
if (block) {
|
|
200
|
+
simulateClick(block);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
await waitFor(
|
|
204
|
+
() => {
|
|
205
|
+
const actionsZone = canvasElement.querySelector(ACTIONS_TESTID);
|
|
206
|
+
|
|
207
|
+
expect(actionsZone).toBeInTheDocument();
|
|
208
|
+
},
|
|
209
|
+
TIMEOUT_ACTION
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await step('Hover settings button', async () => {
|
|
214
|
+
const settingsButton = canvasElement.querySelector(SETTINGS_BUTTON_TESTID);
|
|
215
|
+
|
|
216
|
+
if (settingsButton) {
|
|
217
|
+
await userEvent.hover(settingsButton);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
|