@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,296 @@
|
|
|
1
|
+
import { generateId } from '../utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Event listener information
|
|
5
|
+
* @interface ListenerData
|
|
6
|
+
*/
|
|
7
|
+
export interface ListenerData {
|
|
8
|
+
/**
|
|
9
|
+
* Listener unique identifier
|
|
10
|
+
*/
|
|
11
|
+
id: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Element where to listen to dispatched events
|
|
15
|
+
*/
|
|
16
|
+
element: EventTarget;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Event to listen
|
|
20
|
+
*/
|
|
21
|
+
eventType: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Event handler
|
|
25
|
+
* @param {Event} event - event object
|
|
26
|
+
*/
|
|
27
|
+
handler: (event: Event) => void;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
|
|
31
|
+
*/
|
|
32
|
+
options: boolean | AddEventListenerOptions;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface NormalizedListenerOptions {
|
|
36
|
+
capture: boolean;
|
|
37
|
+
once: boolean;
|
|
38
|
+
passive: boolean;
|
|
39
|
+
signal?: AbortSignal | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Blok Listeners helper
|
|
44
|
+
*
|
|
45
|
+
* Decorator for event listeners assignment
|
|
46
|
+
* @author Blok Team
|
|
47
|
+
* @version 2.0.0
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {Listeners} Listeners
|
|
52
|
+
* @property {ListenerData[]} allListeners - listeners store
|
|
53
|
+
*/
|
|
54
|
+
export class Listeners {
|
|
55
|
+
/**
|
|
56
|
+
* Stores all listeners data to find/remove/process it
|
|
57
|
+
* @type {ListenerData[]}
|
|
58
|
+
*/
|
|
59
|
+
private allListeners: ListenerData[] = [];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Assigns event listener on element and returns unique identifier
|
|
63
|
+
* @param {EventTarget} element - DOM element that needs to be listened
|
|
64
|
+
* @param {string} eventType - event type
|
|
65
|
+
* @param {Function} handler - method that will be fired on event
|
|
66
|
+
* @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once}
|
|
67
|
+
*/
|
|
68
|
+
public on(
|
|
69
|
+
element: EventTarget,
|
|
70
|
+
eventType: string,
|
|
71
|
+
handler: (event: Event) => void,
|
|
72
|
+
options: boolean | AddEventListenerOptions = false
|
|
73
|
+
): string | undefined {
|
|
74
|
+
const alreadyExist = this.findOne(element, eventType, handler, options);
|
|
75
|
+
|
|
76
|
+
if (alreadyExist) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const id = generateId('l');
|
|
81
|
+
const assignedEventData: ListenerData = {
|
|
82
|
+
id,
|
|
83
|
+
element,
|
|
84
|
+
eventType,
|
|
85
|
+
handler,
|
|
86
|
+
options,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
this.allListeners.push(assignedEventData);
|
|
90
|
+
element.addEventListener(eventType, handler, options);
|
|
91
|
+
|
|
92
|
+
return id;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Removes event listener from element
|
|
97
|
+
* @param {EventTarget} element - DOM element that we removing listener
|
|
98
|
+
* @param {string} eventType - event type
|
|
99
|
+
* @param {Function} handler - remove handler, if element listens several handlers on the same event type
|
|
100
|
+
* @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once}
|
|
101
|
+
*/
|
|
102
|
+
public off(
|
|
103
|
+
element: EventTarget,
|
|
104
|
+
eventType: string,
|
|
105
|
+
handler?: (event: Event) => void,
|
|
106
|
+
options?: boolean | AddEventListenerOptions
|
|
107
|
+
): void {
|
|
108
|
+
const existingListeners = this.findAll(element, eventType, handler, options);
|
|
109
|
+
|
|
110
|
+
existingListeners.forEach((listener, i) => {
|
|
111
|
+
const index = this.allListeners.indexOf(existingListeners[i]);
|
|
112
|
+
|
|
113
|
+
if (index > -1) {
|
|
114
|
+
this.allListeners.splice(index, 1);
|
|
115
|
+
|
|
116
|
+
listener.element.removeEventListener(listener.eventType, listener.handler, listener.options);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Removes listener by id
|
|
123
|
+
* @param {string} id - listener identifier
|
|
124
|
+
*/
|
|
125
|
+
public offById(id: string): void {
|
|
126
|
+
const listener = this.findById(id);
|
|
127
|
+
|
|
128
|
+
if (!listener) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
listener.element.removeEventListener(listener.eventType, listener.handler, listener.options);
|
|
133
|
+
const index = this.allListeners.indexOf(listener);
|
|
134
|
+
|
|
135
|
+
if (index > -1) {
|
|
136
|
+
this.allListeners.splice(index, 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Finds and returns first listener by passed params
|
|
142
|
+
* @param {EventTarget} element - event target
|
|
143
|
+
* @param {string} [eventType] - event type
|
|
144
|
+
* @param {Function} [handler] - event handler
|
|
145
|
+
* @param {boolean|AddEventListenerOptions} [options] - event options
|
|
146
|
+
* @returns {ListenerData|null}
|
|
147
|
+
*/
|
|
148
|
+
public findOne(
|
|
149
|
+
element: EventTarget,
|
|
150
|
+
eventType?: string,
|
|
151
|
+
handler?: (event: Event) => void,
|
|
152
|
+
options?: boolean | AddEventListenerOptions
|
|
153
|
+
): ListenerData | null {
|
|
154
|
+
const foundListeners = this.findAll(element, eventType, handler, options);
|
|
155
|
+
|
|
156
|
+
return foundListeners[0] ?? null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Return all stored listeners by passed params
|
|
161
|
+
* @param {EventTarget} element - event target
|
|
162
|
+
* @param {string} eventType - event type
|
|
163
|
+
* @param {Function} handler - event handler
|
|
164
|
+
* @param {boolean|AddEventListenerOptions} [options] - event options
|
|
165
|
+
* @returns {ListenerData[]}
|
|
166
|
+
*/
|
|
167
|
+
public findAll(
|
|
168
|
+
element: EventTarget,
|
|
169
|
+
eventType?: string,
|
|
170
|
+
handler?: (event: Event) => void,
|
|
171
|
+
options?: boolean | AddEventListenerOptions
|
|
172
|
+
): ListenerData[] {
|
|
173
|
+
if (!element) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const foundByEventTargets = this.findByEventTarget(element);
|
|
178
|
+
|
|
179
|
+
return foundByEventTargets.filter((listener) => {
|
|
180
|
+
const matchesEventType = eventType === undefined || listener.eventType === eventType;
|
|
181
|
+
const matchesHandler = handler === undefined || listener.handler === handler;
|
|
182
|
+
const matchesOptions = this.areOptionsEqual(listener.options, options);
|
|
183
|
+
|
|
184
|
+
return matchesEventType && matchesHandler && matchesOptions;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Removes all listeners
|
|
190
|
+
*/
|
|
191
|
+
public removeAll(): void {
|
|
192
|
+
this.allListeners.forEach((current) => {
|
|
193
|
+
current.element.removeEventListener(current.eventType, current.handler, current.options);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
this.allListeners = [];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Module cleanup on destruction
|
|
201
|
+
*/
|
|
202
|
+
public destroy(): void {
|
|
203
|
+
this.removeAll();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Search method: looks for listener by passed element
|
|
208
|
+
* @param {EventTarget} element - searching element
|
|
209
|
+
* @returns {Array} listeners that found on element
|
|
210
|
+
*/
|
|
211
|
+
private findByEventTarget(element: EventTarget): ListenerData[] {
|
|
212
|
+
return this.allListeners.filter((listener) => listener.element === element);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Search method: looks for listener by passed event type
|
|
217
|
+
* @param {string} eventType - event type
|
|
218
|
+
* @returns {ListenerData[]} listeners that found on element
|
|
219
|
+
*/
|
|
220
|
+
private findByType(eventType: string): ListenerData[] {
|
|
221
|
+
return this.allListeners.filter((listener) => listener.eventType === eventType);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Search method: looks for listener by passed handler
|
|
226
|
+
* @param {Function} handler - event handler
|
|
227
|
+
* @returns {ListenerData[]} listeners that found on element
|
|
228
|
+
*/
|
|
229
|
+
private findByHandler(handler: (event: Event) => void): ListenerData[] {
|
|
230
|
+
return this.allListeners.filter((listener) => listener.handler === handler);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Returns listener data found by id
|
|
235
|
+
* @param {string} id - listener identifier
|
|
236
|
+
* @returns {ListenerData}
|
|
237
|
+
*/
|
|
238
|
+
private findById(id: string): ListenerData | undefined {
|
|
239
|
+
return this.allListeners.find((listener) => listener.id === id);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Normalizes listener options to a comparable shape
|
|
244
|
+
* @param {boolean|AddEventListenerOptions} [options] - event options
|
|
245
|
+
* @returns {NormalizedListenerOptions}
|
|
246
|
+
*/
|
|
247
|
+
private normalizeListenerOptions(options?: boolean | AddEventListenerOptions): NormalizedListenerOptions {
|
|
248
|
+
if (typeof options === 'boolean') {
|
|
249
|
+
return {
|
|
250
|
+
capture: options,
|
|
251
|
+
once: false,
|
|
252
|
+
passive: false,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (!options) {
|
|
257
|
+
return {
|
|
258
|
+
capture: false,
|
|
259
|
+
once: false,
|
|
260
|
+
passive: false,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
capture: options.capture ?? false,
|
|
266
|
+
once: options.once ?? false,
|
|
267
|
+
passive: options.passive ?? false,
|
|
268
|
+
signal: options.signal,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Compares stored listener options with provided ones
|
|
274
|
+
* @param {boolean|AddEventListenerOptions} storedOptions - stored event options
|
|
275
|
+
* @param {boolean|AddEventListenerOptions} [providedOptions] - provided event options
|
|
276
|
+
* @returns {boolean}
|
|
277
|
+
*/
|
|
278
|
+
private areOptionsEqual(
|
|
279
|
+
storedOptions: boolean | AddEventListenerOptions,
|
|
280
|
+
providedOptions?: boolean | AddEventListenerOptions
|
|
281
|
+
): boolean {
|
|
282
|
+
if (providedOptions === undefined) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const storedNormalized = this.normalizeListenerOptions(storedOptions);
|
|
287
|
+
const providedNormalized = this.normalizeListenerOptions(providedOptions);
|
|
288
|
+
|
|
289
|
+
return (
|
|
290
|
+
storedNormalized.capture === providedNormalized.capture &&
|
|
291
|
+
storedNormalized.once === providedNormalized.once &&
|
|
292
|
+
storedNormalized.passive === providedNormalized.passive &&
|
|
293
|
+
storedNormalized.signal === providedNormalized.signal
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if passed mutation belongs to a passed element
|
|
3
|
+
* @param mutationRecord - mutation to check
|
|
4
|
+
* @param element - element that is expected to contain mutation
|
|
5
|
+
*/
|
|
6
|
+
export const isMutationBelongsToElement = (mutationRecord: MutationRecord, element: Element): boolean => {
|
|
7
|
+
const { type, target, addedNodes, removedNodes } = mutationRecord;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Skip own technical mutations, for example, data-blok-empty attribute changes
|
|
11
|
+
*/
|
|
12
|
+
if (mutationRecord.type === 'attributes' && mutationRecord.attributeName === 'data-blok-empty') {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Covers all types of mutations happened to the element or it's descendants with the only one exception - removing/adding the element itself;
|
|
18
|
+
*/
|
|
19
|
+
if (element.contains(target)) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* In case of removing/adding the element itself, mutation type will be 'childList' and 'removedNodes'/'addedNodes' will contain the element.
|
|
25
|
+
*/
|
|
26
|
+
if (type !== 'childList') {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const elementAddedItself = Array.from(addedNodes).some(node => node === element);
|
|
31
|
+
|
|
32
|
+
if (elementAddedItself) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const elementRemovedItself = Array.from(removedNodes).some(node => node === element);
|
|
37
|
+
|
|
38
|
+
return elementRemovedItself;
|
|
39
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { twMerge, twJoin } from '../tw';
|
|
2
|
+
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions } from './types';
|
|
3
|
+
|
|
4
|
+
export const CSS = {
|
|
5
|
+
wrapper: twJoin(
|
|
6
|
+
'fixed z-[2] bottom-5 left-5',
|
|
7
|
+
'font-[-apple-system,BlinkMacSystemFont,"Segoe_UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira_Sans","Droid_Sans","Helvetica_Neue",sans-serif]'
|
|
8
|
+
),
|
|
9
|
+
notification: twJoin(
|
|
10
|
+
'relative w-[230px] mt-[15px] py-[13px] px-4',
|
|
11
|
+
'bg-white shadow-[0_11px_17px_0_rgba(23,32,61,0.13)] rounded-[5px]',
|
|
12
|
+
'text-sm leading-[1.4em] break-words',
|
|
13
|
+
'before:content-[""] before:absolute before:block before:top-0 before:left-0',
|
|
14
|
+
'before:w-[3px] before:h-[calc(100%-6px)] before:m-[3px] before:rounded-[5px] before:bg-transparent'
|
|
15
|
+
),
|
|
16
|
+
crossBtn: twJoin(
|
|
17
|
+
'absolute top-[7px] right-[15px] w-2.5 h-2.5 p-[5px] opacity-55 cursor-pointer',
|
|
18
|
+
'before:content-[""] before:absolute before:left-[9px] before:top-[5px] before:h-3 before:w-0.5 before:bg-[#575d67] before:rotate-[-45deg]',
|
|
19
|
+
'after:content-[""] after:absolute after:left-[9px] after:top-[5px] after:h-3 after:w-0.5 after:bg-[#575d67] after:rotate-45',
|
|
20
|
+
'hover:opacity-100'
|
|
21
|
+
),
|
|
22
|
+
btnsWrapper: 'flex flex-row flex-nowrap mt-[5px]',
|
|
23
|
+
btn: 'border-none rounded-[3px] text-[13px] py-[5px] px-2.5 cursor-pointer last:ml-2.5',
|
|
24
|
+
okBtn: 'bg-[#34c992] shadow-[0_1px_1px_0_rgba(18,49,35,0.05)] text-white hover:bg-[#2db583]',
|
|
25
|
+
cancelBtn: 'bg-[#f2f5f7] shadow-[0_2px_1px_0_rgba(16,19,29,0)] text-[#656b7c] hover:bg-[#e9ecee]',
|
|
26
|
+
input: twJoin(
|
|
27
|
+
'max-w-[130px] py-[5px] px-2.5 bg-[#f7f7f7] border-0 rounded-[3px]',
|
|
28
|
+
'text-[13px] text-[#656b7c] outline-none',
|
|
29
|
+
'placeholder:text-[#656b7c] focus:placeholder:text-[rgba(101,107,124,0.3)]'
|
|
30
|
+
),
|
|
31
|
+
successNotification: twJoin(
|
|
32
|
+
'!bg-[#fafffe]',
|
|
33
|
+
'before:!bg-[#41ffb1]'
|
|
34
|
+
),
|
|
35
|
+
errorNotification: twJoin(
|
|
36
|
+
'!bg-[#fffbfb]',
|
|
37
|
+
'before:!bg-[#fb5d5d]'
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {NotifierOptions} options - options for the notification
|
|
43
|
+
* @returns {HTMLElement} - the notification element
|
|
44
|
+
*/
|
|
45
|
+
export const alert = (options: NotifierOptions): HTMLElement => {
|
|
46
|
+
const notify = document.createElement('DIV');
|
|
47
|
+
const cross = document.createElement('DIV');
|
|
48
|
+
const message = options.message;
|
|
49
|
+
const style = options.style;
|
|
50
|
+
|
|
51
|
+
const getStyleClasses = (): string => {
|
|
52
|
+
if (style === 'success') {
|
|
53
|
+
return CSS.successNotification;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (style === 'error') {
|
|
57
|
+
return CSS.errorNotification;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return '';
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
notify.className = twMerge(CSS.notification, getStyleClasses());
|
|
64
|
+
|
|
65
|
+
if (style) {
|
|
66
|
+
notify.setAttribute('data-blok-testid', `notification-${style}`);
|
|
67
|
+
} else {
|
|
68
|
+
notify.setAttribute('data-blok-testid', 'notification');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
notify.innerHTML = message;
|
|
72
|
+
|
|
73
|
+
cross.className = CSS.crossBtn;
|
|
74
|
+
cross.setAttribute('data-blok-testid', 'notification-cross');
|
|
75
|
+
cross.addEventListener('click', () => notify.remove());
|
|
76
|
+
|
|
77
|
+
notify.appendChild(cross);
|
|
78
|
+
|
|
79
|
+
return notify;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {ConfirmNotifierOptions} options - options for the confirmation notification
|
|
84
|
+
* @returns {HTMLElement} - the notification element
|
|
85
|
+
*/
|
|
86
|
+
export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
87
|
+
const notify = alert(options);
|
|
88
|
+
const btnsWrapper = document.createElement('div');
|
|
89
|
+
const okBtn = document.createElement('button');
|
|
90
|
+
const cancelBtn = document.createElement('button');
|
|
91
|
+
const crossBtn = notify.querySelector('[data-blok-testid="notification-cross"]');
|
|
92
|
+
const cancelHandler = options.cancelHandler;
|
|
93
|
+
const okHandler = options.okHandler;
|
|
94
|
+
|
|
95
|
+
btnsWrapper.className = CSS.btnsWrapper;
|
|
96
|
+
btnsWrapper.setAttribute('data-blok-testid', 'notification-buttons-wrapper');
|
|
97
|
+
|
|
98
|
+
okBtn.innerHTML = options.okText || 'Confirm';
|
|
99
|
+
cancelBtn.innerHTML = options.cancelText || 'Cancel';
|
|
100
|
+
|
|
101
|
+
okBtn.className = twJoin(CSS.btn, CSS.okBtn);
|
|
102
|
+
cancelBtn.className = twJoin(CSS.btn, CSS.cancelBtn);
|
|
103
|
+
|
|
104
|
+
okBtn.setAttribute('data-blok-testid', 'notification-confirm-button');
|
|
105
|
+
cancelBtn.setAttribute('data-blok-testid', 'notification-cancel-button');
|
|
106
|
+
|
|
107
|
+
if (cancelHandler && typeof cancelHandler === 'function') {
|
|
108
|
+
cancelBtn.addEventListener('click', cancelHandler);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (cancelHandler && typeof cancelHandler === 'function' && crossBtn) {
|
|
112
|
+
crossBtn.addEventListener('click', cancelHandler);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (okHandler && typeof okHandler === 'function') {
|
|
116
|
+
okBtn.addEventListener('click', okHandler);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
okBtn.addEventListener('click', () => notify.remove());
|
|
120
|
+
cancelBtn.addEventListener('click', () => notify.remove());
|
|
121
|
+
|
|
122
|
+
btnsWrapper.appendChild(okBtn);
|
|
123
|
+
btnsWrapper.appendChild(cancelBtn);
|
|
124
|
+
|
|
125
|
+
notify.appendChild(btnsWrapper);
|
|
126
|
+
|
|
127
|
+
return notify;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {PromptNotifierOptions} options - options for the prompt notification
|
|
132
|
+
* @returns {HTMLElement} - the notification element
|
|
133
|
+
*/
|
|
134
|
+
export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
135
|
+
const notify = alert(options);
|
|
136
|
+
const btnsWrapper = document.createElement('div');
|
|
137
|
+
const okBtn = document.createElement('button');
|
|
138
|
+
const input = document.createElement('input');
|
|
139
|
+
const crossBtn = notify.querySelector('[data-blok-testid="notification-cross"]');
|
|
140
|
+
const cancelHandler = options.cancelHandler;
|
|
141
|
+
const okHandler = options.okHandler;
|
|
142
|
+
|
|
143
|
+
btnsWrapper.className = CSS.btnsWrapper;
|
|
144
|
+
|
|
145
|
+
okBtn.innerHTML = options.okText || 'Ok';
|
|
146
|
+
okBtn.className = twJoin(CSS.btn, CSS.okBtn);
|
|
147
|
+
|
|
148
|
+
input.className = CSS.input;
|
|
149
|
+
input.setAttribute('data-blok-testid', 'notification-input');
|
|
150
|
+
|
|
151
|
+
if (options.placeholder) {
|
|
152
|
+
input.setAttribute('placeholder', options.placeholder);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (options.default) {
|
|
156
|
+
input.value = options.default;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (options.inputType) {
|
|
160
|
+
input.type = options.inputType;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (cancelHandler && typeof cancelHandler === 'function' && crossBtn) {
|
|
164
|
+
crossBtn.addEventListener('click', cancelHandler);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (okHandler && typeof okHandler === 'function') {
|
|
168
|
+
okBtn.addEventListener('click', () => {
|
|
169
|
+
okHandler(input.value);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
okBtn.addEventListener('click', () => notify.remove());
|
|
174
|
+
|
|
175
|
+
btnsWrapper.appendChild(input);
|
|
176
|
+
btnsWrapper.appendChild(okBtn);
|
|
177
|
+
|
|
178
|
+
notify.appendChild(btnsWrapper);
|
|
179
|
+
|
|
180
|
+
return notify;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export const getWrapper = (): HTMLElement => {
|
|
184
|
+
const wrapper = document.createElement('DIV');
|
|
185
|
+
|
|
186
|
+
wrapper.className = CSS.wrapper;
|
|
187
|
+
wrapper.setAttribute('data-blok-testid', 'notifier-container');
|
|
188
|
+
|
|
189
|
+
return wrapper;
|
|
190
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { alert, confirm, getWrapper, prompt } from './draw';
|
|
2
|
+
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions } from './types';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TIME = 8000;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Prepare wrapper for notifications
|
|
8
|
+
* @returns {HTMLElement}
|
|
9
|
+
*/
|
|
10
|
+
const prepare_ = (): HTMLElement => {
|
|
11
|
+
const existingWrapper = document.querySelector('[data-blok-testid="notifier-container"]') as HTMLElement;
|
|
12
|
+
|
|
13
|
+
if (existingWrapper) {
|
|
14
|
+
return existingWrapper;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const wrapper = getWrapper();
|
|
18
|
+
|
|
19
|
+
document.body.appendChild(wrapper);
|
|
20
|
+
|
|
21
|
+
return wrapper;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Show new notification
|
|
26
|
+
* @param {NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions} options - notification options
|
|
27
|
+
*/
|
|
28
|
+
export const show = (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void => {
|
|
29
|
+
if (!options.message) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const wrapper = prepare_();
|
|
34
|
+
|
|
35
|
+
const time = options.time || DEFAULT_TIME;
|
|
36
|
+
|
|
37
|
+
const notify: HTMLElement = (() => {
|
|
38
|
+
switch (options.type) {
|
|
39
|
+
case 'confirm':
|
|
40
|
+
return confirm(options as ConfirmNotifierOptions);
|
|
41
|
+
|
|
42
|
+
case 'prompt':
|
|
43
|
+
return prompt(options as PromptNotifierOptions);
|
|
44
|
+
|
|
45
|
+
default: {
|
|
46
|
+
const alertElement = alert(options);
|
|
47
|
+
|
|
48
|
+
window.setTimeout(() => {
|
|
49
|
+
alertElement.remove();
|
|
50
|
+
}, time);
|
|
51
|
+
|
|
52
|
+
return alertElement;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
})();
|
|
56
|
+
|
|
57
|
+
if (wrapper && notify) {
|
|
58
|
+
wrapper.appendChild(notify);
|
|
59
|
+
notify.className = `${notify.className} animate-notify-bounce-in`;
|
|
60
|
+
notify.setAttribute('data-blok-bounce-in', 'true');
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const Notifier = {
|
|
65
|
+
show,
|
|
66
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from '@/types/configs/notifier';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Use local module for notifications
|
|
3
|
+
*/
|
|
4
|
+
import type { ConfirmNotifierOptions, NotifierOptions, PromptNotifierOptions } from './notifier/types';
|
|
5
|
+
|
|
6
|
+
type NotifierModule = {
|
|
7
|
+
show: (options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Util for showing notifications
|
|
12
|
+
*/
|
|
13
|
+
export class Notifier {
|
|
14
|
+
/**
|
|
15
|
+
* Cached notifier module instance
|
|
16
|
+
*/
|
|
17
|
+
private notifierModule: NotifierModule | null = null;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Promise used to avoid multiple parallel loads of the notifier module
|
|
21
|
+
*/
|
|
22
|
+
private loadingPromise: Promise<NotifierModule> | null = null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Lazily load notifier only when necessary.
|
|
26
|
+
* @returns {Promise<NotifierModule>} loaded notifier module
|
|
27
|
+
*/
|
|
28
|
+
private loadNotifierModule(): Promise<NotifierModule> {
|
|
29
|
+
if (this.notifierModule !== null) {
|
|
30
|
+
return Promise.resolve(this.notifierModule);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (this.loadingPromise === null) {
|
|
34
|
+
this.loadingPromise = import('./notifier/index')
|
|
35
|
+
.then((module) => {
|
|
36
|
+
const resolvedModule = module as unknown;
|
|
37
|
+
|
|
38
|
+
if (!this.isNotifierModule(resolvedModule)) {
|
|
39
|
+
throw new Error('notifier module does not expose a "show" method.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.notifierModule = resolvedModule;
|
|
43
|
+
|
|
44
|
+
return resolvedModule;
|
|
45
|
+
})
|
|
46
|
+
.catch((error) => {
|
|
47
|
+
this.loadingPromise = null;
|
|
48
|
+
|
|
49
|
+
throw error;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return this.loadingPromise;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Show web notification
|
|
58
|
+
* @param {NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions} options - notification options
|
|
59
|
+
*/
|
|
60
|
+
public show(options: NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions): void {
|
|
61
|
+
void this.loadNotifierModule()
|
|
62
|
+
.then((notifier) => {
|
|
63
|
+
notifier.show(options);
|
|
64
|
+
})
|
|
65
|
+
.catch((error) => {
|
|
66
|
+
console.error('[Blok] Failed to display notification. Reason:', error);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Narrow unknown module to notifier module shape
|
|
72
|
+
* @param {unknown} candidate - module to verify
|
|
73
|
+
*/
|
|
74
|
+
private isNotifierModule(candidate: unknown): candidate is NotifierModule {
|
|
75
|
+
return typeof candidate === 'object' && candidate !== null && 'show' in candidate && typeof (candidate as { show?: unknown }).show === 'function';
|
|
76
|
+
}
|
|
77
|
+
}
|