@jackuait/blok 0.4.1-beta.0 → 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-OwEtDFlk.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 +30 -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-D_baBvTG.mjs +0 -25795
- package/dist/blok.umd.js +0 -181
package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { PopoverItem } from '../popover-item';
|
|
2
|
+
import type { PopoverItemHtmlParams, PopoverItemRenderParamsMap, PopoverItemType } from '@/types/utils/popover/popover-item';
|
|
3
|
+
import { Dom } from '../../../../../dom';
|
|
4
|
+
import { css, cssInline } from './popover-item-html.const';
|
|
5
|
+
import { DATA_ATTR } from '../../../../../constants/data-attributes';
|
|
6
|
+
import { twMerge } from '../../../../tw';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Represents popover item with custom html content
|
|
10
|
+
*/
|
|
11
|
+
export class PopoverItemHtml extends PopoverItem {
|
|
12
|
+
/**
|
|
13
|
+
* Item html elements
|
|
14
|
+
*/
|
|
15
|
+
private nodes: { root: HTMLElement | null } = { root: null };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Whether the item is currently hidden
|
|
19
|
+
*/
|
|
20
|
+
private isHidden = false;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Whether this item is in an inline popover context
|
|
24
|
+
*/
|
|
25
|
+
private readonly isInline: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Constructs the instance
|
|
29
|
+
* @param params – instance parameters
|
|
30
|
+
* @param renderParams – popover item render params.
|
|
31
|
+
* The parameters that are not set by user via popover api but rather depend on technical implementation
|
|
32
|
+
*/
|
|
33
|
+
constructor(params: PopoverItemHtmlParams, renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Html]) {
|
|
34
|
+
super(params);
|
|
35
|
+
|
|
36
|
+
this.isInline = renderParams?.isInline ?? false;
|
|
37
|
+
|
|
38
|
+
this.nodes.root = this.createRootElement(params, renderParams);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns popover item root element
|
|
43
|
+
*/
|
|
44
|
+
public getElement(): HTMLElement {
|
|
45
|
+
return this.nodes.root as HTMLElement;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Toggles item hidden state
|
|
50
|
+
* @param isHidden - true if item should be hidden
|
|
51
|
+
*/
|
|
52
|
+
public toggleHidden(isHidden: boolean): void {
|
|
53
|
+
this.isHidden = isHidden;
|
|
54
|
+
this.updateRootClasses();
|
|
55
|
+
|
|
56
|
+
if (!this.nodes.root) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (isHidden) {
|
|
61
|
+
this.nodes.root.setAttribute(DATA_ATTR.hidden, 'true');
|
|
62
|
+
} else {
|
|
63
|
+
this.nodes.root.removeAttribute(DATA_ATTR.hidden);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Returns list of buttons and inputs inside custom content
|
|
69
|
+
*/
|
|
70
|
+
public getControls(): HTMLElement[] {
|
|
71
|
+
if (!this.nodes.root) {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const controls = this.nodes.root.querySelectorAll<HTMLElement>(
|
|
76
|
+
`button, ${Dom.allInputsSelector}`
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return Array.from(controls);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Updates the root element's class list based on current state
|
|
84
|
+
*/
|
|
85
|
+
private updateRootClasses(): void {
|
|
86
|
+
if (!this.nodes.root) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this.nodes.root.className = twMerge(
|
|
91
|
+
css.root,
|
|
92
|
+
this.isInline && cssInline.root,
|
|
93
|
+
this.isHidden && css.rootHidden
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Creates the root container element
|
|
99
|
+
* @param params - item params
|
|
100
|
+
* @param renderParams - render configuration
|
|
101
|
+
*/
|
|
102
|
+
private createRootElement(
|
|
103
|
+
params: PopoverItemHtmlParams,
|
|
104
|
+
renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Html]
|
|
105
|
+
): HTMLElement {
|
|
106
|
+
const root = document.createElement('div');
|
|
107
|
+
|
|
108
|
+
// Set initial classes
|
|
109
|
+
root.className = twMerge(
|
|
110
|
+
css.root,
|
|
111
|
+
this.isInline && cssInline.root
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// Set data attributes
|
|
115
|
+
root.setAttribute(DATA_ATTR.popoverItemHtml, '');
|
|
116
|
+
root.setAttribute('data-blok-testid', 'popover-item-html');
|
|
117
|
+
|
|
118
|
+
if (params.name) {
|
|
119
|
+
root.setAttribute('data-blok-item-name', params.name);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Append the custom element
|
|
123
|
+
root.appendChild(params.element);
|
|
124
|
+
|
|
125
|
+
// Add hint if configured
|
|
126
|
+
if (params.hint !== undefined && renderParams?.hint?.enabled !== false) {
|
|
127
|
+
this.addHint(root, {
|
|
128
|
+
...params.hint,
|
|
129
|
+
position: renderParams?.hint?.position || 'right',
|
|
130
|
+
alignment: renderParams?.hint?.alignment || 'center',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return root;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailwind CSS classes for popover separator component
|
|
3
|
+
*/
|
|
4
|
+
export const css = {
|
|
5
|
+
container: 'py-1 px-[3px]',
|
|
6
|
+
containerHidden: 'hidden',
|
|
7
|
+
line: 'h-px w-full bg-popover-border',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Tailwind CSS classes for inline popover separator
|
|
12
|
+
*/
|
|
13
|
+
export const cssInline = {
|
|
14
|
+
// Inline context: horizontal separator
|
|
15
|
+
container: 'px-1 py-0',
|
|
16
|
+
line: 'h-full w-px',
|
|
17
|
+
// Nested inline context: back to vertical separator
|
|
18
|
+
nestedContainer: 'py-1 px-[3px]',
|
|
19
|
+
nestedLine: 'w-full h-px',
|
|
20
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { twMerge } from '../../../../tw';
|
|
2
|
+
import { PopoverItem } from '../popover-item';
|
|
3
|
+
import type { PopoverItemRenderParamsMap, PopoverItemType } from '@/types/utils/popover/popover-item';
|
|
4
|
+
import { css, cssInline } from './popover-item-separator.const';
|
|
5
|
+
import { DATA_ATTR } from '../../../../../constants/data-attributes';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Represents popover separator node
|
|
9
|
+
*/
|
|
10
|
+
export class PopoverItemSeparator extends PopoverItem {
|
|
11
|
+
/**
|
|
12
|
+
* Html elements
|
|
13
|
+
*/
|
|
14
|
+
private nodes: { root: HTMLElement | null; line: HTMLElement | null } = { root: null, line: null };
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Whether this separator is in an inline popover context
|
|
18
|
+
*/
|
|
19
|
+
private readonly isInline: boolean;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whether this separator is in a nested inline popover context
|
|
23
|
+
*/
|
|
24
|
+
private readonly isNestedInline: boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Constructs the instance
|
|
28
|
+
* @param renderParams - optional render params for styling context
|
|
29
|
+
*/
|
|
30
|
+
constructor(renderParams?: PopoverItemRenderParamsMap[PopoverItemType.Separator]) {
|
|
31
|
+
super();
|
|
32
|
+
|
|
33
|
+
this.isInline = renderParams?.isInline ?? false;
|
|
34
|
+
this.isNestedInline = renderParams?.isNestedInline ?? false;
|
|
35
|
+
|
|
36
|
+
this.nodes.root = this.createRootElement();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns popover separator root element
|
|
41
|
+
*/
|
|
42
|
+
public getElement(): HTMLElement {
|
|
43
|
+
return this.nodes.root as HTMLElement;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Toggles item hidden state
|
|
48
|
+
* @param isHidden - true if item should be hidden
|
|
49
|
+
*/
|
|
50
|
+
public toggleHidden(isHidden: boolean): void {
|
|
51
|
+
if (!this.nodes.root) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const baseClass = this.getContainerClass(false);
|
|
56
|
+
const hiddenClass = this.getContainerClass(true);
|
|
57
|
+
|
|
58
|
+
this.nodes.root.className = isHidden ? hiddenClass : baseClass;
|
|
59
|
+
|
|
60
|
+
if (isHidden) {
|
|
61
|
+
this.nodes.root.setAttribute(DATA_ATTR.hidden, 'true');
|
|
62
|
+
} else {
|
|
63
|
+
this.nodes.root.removeAttribute(DATA_ATTR.hidden);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build container class based on context
|
|
69
|
+
*/
|
|
70
|
+
private getContainerClass(isHidden: boolean): string {
|
|
71
|
+
const baseClass = css.container;
|
|
72
|
+
|
|
73
|
+
if (this.isNestedInline) {
|
|
74
|
+
return twMerge(baseClass, cssInline.nestedContainer, isHidden && css.containerHidden);
|
|
75
|
+
}
|
|
76
|
+
if (this.isInline) {
|
|
77
|
+
return twMerge(baseClass, cssInline.container, isHidden && css.containerHidden);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return twMerge(baseClass, isHidden && css.containerHidden);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Build line class based on context
|
|
85
|
+
*/
|
|
86
|
+
private getLineClass(): string {
|
|
87
|
+
if (this.isNestedInline) {
|
|
88
|
+
return twMerge(css.line, cssInline.nestedLine);
|
|
89
|
+
}
|
|
90
|
+
if (this.isInline) {
|
|
91
|
+
return twMerge(css.line, cssInline.line);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return css.line;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Creates the root container element
|
|
99
|
+
*/
|
|
100
|
+
private createRootElement(): HTMLElement {
|
|
101
|
+
const container = document.createElement('div');
|
|
102
|
+
|
|
103
|
+
container.className = this.getContainerClass(false);
|
|
104
|
+
container.setAttribute(DATA_ATTR.popoverItemSeparator, '');
|
|
105
|
+
container.setAttribute('data-blok-testid', 'popover-item-separator');
|
|
106
|
+
|
|
107
|
+
const line = document.createElement('div');
|
|
108
|
+
|
|
109
|
+
line.className = this.getLineClass();
|
|
110
|
+
line.setAttribute(DATA_ATTR.popoverItemSeparatorLine, '');
|
|
111
|
+
|
|
112
|
+
container.appendChild(line);
|
|
113
|
+
this.nodes.line = line;
|
|
114
|
+
|
|
115
|
+
return container;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { hide, onHover } from '../../../../utils/tooltip';
|
|
2
|
+
import { type HintPosition, Hint } from '../hint';
|
|
3
|
+
import type { PopoverItemParams } from '@/types/utils/popover/popover-item';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Popover item abstract class
|
|
7
|
+
*/
|
|
8
|
+
export abstract class PopoverItem {
|
|
9
|
+
/**
|
|
10
|
+
* Constructs the instance
|
|
11
|
+
* @param params - instance parameters
|
|
12
|
+
*/
|
|
13
|
+
constructor(protected readonly params?: PopoverItemParams) {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Item name if exists
|
|
17
|
+
*/
|
|
18
|
+
public get name(): string | undefined {
|
|
19
|
+
if (this.params === undefined) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if ('name' in this.params) {
|
|
23
|
+
return this.params.name;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Destroys the instance
|
|
29
|
+
*/
|
|
30
|
+
public destroy(): void {
|
|
31
|
+
hide();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Called when children popover is opened (if exists)
|
|
36
|
+
*/
|
|
37
|
+
public onChildrenOpen(): void {
|
|
38
|
+
if (this.params === undefined) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if ('children' in this.params && typeof this.params.children?.onOpen === 'function') {
|
|
43
|
+
this.params.children.onOpen();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Called when children popover is closed (if exists)
|
|
49
|
+
*/
|
|
50
|
+
public onChildrenClose(): void {
|
|
51
|
+
if (this.params === undefined) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if ('children' in this.params && typeof this.params.children?.onClose === 'function') {
|
|
56
|
+
this.params.children.onClose();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Called on popover item click
|
|
62
|
+
*/
|
|
63
|
+
public handleClick(): void {
|
|
64
|
+
if (this.params === undefined) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!('onActivate' in this.params)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.params.onActivate?.(this.params);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Adds hint to the item element if hint data is provided
|
|
77
|
+
* @param itemElement - popover item root element to add hint to
|
|
78
|
+
* @param hintData - hint data
|
|
79
|
+
*/
|
|
80
|
+
protected addHint(itemElement: HTMLElement, hintData: { title: string, description?: string; position: HintPosition; alignment?: 'start' | 'center' }): void {
|
|
81
|
+
const content = new Hint(hintData);
|
|
82
|
+
|
|
83
|
+
onHover(itemElement, content.getElement(), {
|
|
84
|
+
placement: hintData.position,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns popover item root element
|
|
90
|
+
*/
|
|
91
|
+
public abstract getElement(): HTMLElement | null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Returns DOM element that should be mounted into the popover container.
|
|
95
|
+
* Default implementation returns the main element; subclasses may override
|
|
96
|
+
* when the mounted element differs from the focusable/root element.
|
|
97
|
+
*/
|
|
98
|
+
public getMountElement(): HTMLElement | null {
|
|
99
|
+
return this.getElement();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Toggles item hidden state
|
|
104
|
+
* @param isHidden - true if item should be hidden
|
|
105
|
+
*/
|
|
106
|
+
public abstract toggleHidden(isHidden: boolean): void;
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Returns item children that are represented as popover items
|
|
111
|
+
*/
|
|
112
|
+
public get children(): PopoverItemParams[] {
|
|
113
|
+
return this.params !== undefined && 'children' in this.params && this.params.children?.items !== undefined ? this.params.children.items : [];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns true if item has any type of children
|
|
118
|
+
*/
|
|
119
|
+
public get hasChildren(): boolean {
|
|
120
|
+
return this.children.length > 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns true if item children should be open instantly after popover is opened and not on item click/hover
|
|
125
|
+
*/
|
|
126
|
+
public get isChildrenOpen(): boolean {
|
|
127
|
+
return this.params !== undefined && 'children' in this.params && this.params.children?.isOpen === true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** * Returns true if the chevron icon should be hidden
|
|
131
|
+
*/
|
|
132
|
+
public get isChevronHidden(): boolean {
|
|
133
|
+
return this.params !== undefined && 'children' in this.params && this.params.children?.hideChevron === true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** * True if item children items should be navigatable via keyboard
|
|
137
|
+
*/
|
|
138
|
+
public get isChildrenFlippable(): boolean {
|
|
139
|
+
if (this.params === undefined) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!('children' in this.params)) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (this.params.children?.isFlippable === false) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Returns true if item has children that should be searchable
|
|
156
|
+
*/
|
|
157
|
+
public get isChildrenSearchable(): boolean {
|
|
158
|
+
return this.params !== undefined && 'children' in this.params && this.params.children?.searchable === true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* True if popover should close once item is activated
|
|
163
|
+
*/
|
|
164
|
+
public get closeOnActivate(): boolean | undefined {
|
|
165
|
+
return this.params !== undefined && 'closeOnActivate' in this.params && this.params.closeOnActivate;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* True if item is active
|
|
170
|
+
*/
|
|
171
|
+
public get isActive(): boolean {
|
|
172
|
+
if (this.params === undefined) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!('isActive' in this.params)) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (typeof this.params.isActive === 'function') {
|
|
181
|
+
return this.params.isActive();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return this.params.isActive === true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS class names to be used in popover search input class
|
|
3
|
+
*/
|
|
4
|
+
export const css = {
|
|
5
|
+
wrapper: 'bg-[#F8F8F8] border border-[rgba(226,226,229,0.20)] rounded p-0.5 grid grid-cols-[auto_auto_1fr] grid-rows-[auto]',
|
|
6
|
+
icon: 'w-toolbox-btn h-toolbox-btn flex items-center justify-center mr-2 [&_svg]:w-icon [&_svg]:h-icon [&_svg]:text-gray-text',
|
|
7
|
+
input: "text-sm outline-none font-medium font-inherit border-0 bg-transparent m-0 p-0 leading-[22px] min-w-[calc(100%-theme('spacing.6')-10px)] placeholder:text-gray-text placeholder:font-medium",
|
|
8
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Dom } from '../../../../dom';
|
|
2
|
+
import { Listeners } from '../../../listeners';
|
|
3
|
+
import { IconSearch } from '../../../../icons';
|
|
4
|
+
import type { SearchInputEventMap, SearchableItem } from './search-input.types';
|
|
5
|
+
import { SearchInputEvent, matchesSearchQuery } from './search-input.types';
|
|
6
|
+
import { css } from './search-input.const';
|
|
7
|
+
import { EventsDispatcher } from '../../../events';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Provides search input element and search logic
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export class SearchInput extends EventsDispatcher<SearchInputEventMap> {
|
|
14
|
+
/**
|
|
15
|
+
* Input wrapper element
|
|
16
|
+
*/
|
|
17
|
+
private wrapper: HTMLElement;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Editable input itself
|
|
21
|
+
*/
|
|
22
|
+
private input: HTMLInputElement;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The instance of the Listeners util
|
|
26
|
+
*/
|
|
27
|
+
private listeners: Listeners;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Items for local search
|
|
31
|
+
*/
|
|
32
|
+
private items: SearchableItem[];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Current search query
|
|
36
|
+
*/
|
|
37
|
+
private searchQuery = '';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param options - available config
|
|
41
|
+
* @param options.items - searchable items list
|
|
42
|
+
* @param options.placeholder - input placeholder
|
|
43
|
+
*/
|
|
44
|
+
constructor({ items, placeholder }: {
|
|
45
|
+
items: SearchableItem[];
|
|
46
|
+
placeholder?: string;
|
|
47
|
+
}) {
|
|
48
|
+
super();
|
|
49
|
+
|
|
50
|
+
this.listeners = new Listeners();
|
|
51
|
+
this.items = items;
|
|
52
|
+
|
|
53
|
+
/** Build ui */
|
|
54
|
+
this.wrapper = Dom.make('div', css.wrapper);
|
|
55
|
+
this.wrapper.setAttribute('data-blok-testid', 'popover-search-field');
|
|
56
|
+
|
|
57
|
+
const iconWrapper = Dom.make('div', css.icon, {
|
|
58
|
+
innerHTML: IconSearch,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
this.input = Dom.make('input', css.input, {
|
|
62
|
+
type: 'search',
|
|
63
|
+
placeholder,
|
|
64
|
+
/**
|
|
65
|
+
* Used to prevent focusing on the input by Tab key
|
|
66
|
+
* (Popover in the Toolbar lays below the blocks,
|
|
67
|
+
* so Tab in the last block will focus this hidden input if this property is not set)
|
|
68
|
+
*/
|
|
69
|
+
tabIndex: -1,
|
|
70
|
+
}) as HTMLInputElement;
|
|
71
|
+
this.input.setAttribute('data-blok-flipper-navigation-target', 'true');
|
|
72
|
+
this.input.setAttribute('data-blok-testid', 'popover-search-input');
|
|
73
|
+
|
|
74
|
+
this.wrapper.appendChild(iconWrapper);
|
|
75
|
+
this.wrapper.appendChild(this.input);
|
|
76
|
+
|
|
77
|
+
this.overrideValueProperty();
|
|
78
|
+
|
|
79
|
+
const eventsToHandle = ['input', 'keyup', 'search', 'change'] as const;
|
|
80
|
+
|
|
81
|
+
eventsToHandle.forEach((eventName) => {
|
|
82
|
+
this.listeners.on(this.input, eventName, this.handleValueChange);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Returns search field element
|
|
88
|
+
*/
|
|
89
|
+
public getElement(): HTMLElement {
|
|
90
|
+
return this.wrapper;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Sets focus to the input
|
|
95
|
+
*/
|
|
96
|
+
public focus(): void {
|
|
97
|
+
this.input.focus();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Clears search query and results
|
|
102
|
+
*/
|
|
103
|
+
public clear(): void {
|
|
104
|
+
this.input.value = '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Handles value changes for the input element
|
|
109
|
+
*/
|
|
110
|
+
private handleValueChange = (): void => {
|
|
111
|
+
this.applySearch(this.input.value);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Applies provided query to the search state and notifies listeners
|
|
116
|
+
* @param query - search query to apply
|
|
117
|
+
*/
|
|
118
|
+
private applySearch(query: string): void {
|
|
119
|
+
if (this.searchQuery === query) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.searchQuery = query;
|
|
124
|
+
|
|
125
|
+
this.emit(SearchInputEvent.Search, {
|
|
126
|
+
query,
|
|
127
|
+
items: this.foundItems,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Overrides value property setter to catch programmatic changes
|
|
133
|
+
*/
|
|
134
|
+
private overrideValueProperty(): void {
|
|
135
|
+
const prototype = Object.getPrototypeOf(this.input);
|
|
136
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'value');
|
|
137
|
+
|
|
138
|
+
if (descriptor?.set === undefined || descriptor.get === undefined) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const applySearch = this.applySearch.bind(this);
|
|
143
|
+
|
|
144
|
+
Object.defineProperty(this.input, 'value', {
|
|
145
|
+
configurable: descriptor.configurable ?? true,
|
|
146
|
+
enumerable: descriptor.enumerable ?? false,
|
|
147
|
+
get(): string {
|
|
148
|
+
return descriptor.get?.call(this) ?? '';
|
|
149
|
+
},
|
|
150
|
+
set(value: string): void {
|
|
151
|
+
descriptor.set?.call(this, value);
|
|
152
|
+
applySearch(value);
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Clears memory
|
|
159
|
+
*/
|
|
160
|
+
public destroy(): void {
|
|
161
|
+
this.listeners.removeAll();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Returns list of found items for the current search query
|
|
166
|
+
*/
|
|
167
|
+
private get foundItems(): SearchableItem[] {
|
|
168
|
+
return this.items.filter(item => this.checkItem(item));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Contains logic for checking whether passed item conforms the search query.
|
|
173
|
+
* @param item - item to be checked
|
|
174
|
+
*/
|
|
175
|
+
private checkItem(item: SearchableItem): boolean {
|
|
176
|
+
return matchesSearchQuery(item, this.searchQuery);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Item that could be searched
|
|
3
|
+
*/
|
|
4
|
+
export interface SearchableItem {
|
|
5
|
+
/**
|
|
6
|
+
* Items title (displayed, possibly translated)
|
|
7
|
+
*/
|
|
8
|
+
title?: string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* English title for fallback search (always matches English input)
|
|
12
|
+
*/
|
|
13
|
+
englishTitle?: string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Additional search terms/aliases (e.g., ['h1', 'title'])
|
|
17
|
+
*/
|
|
18
|
+
searchTerms?: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Checks if an item matches a search query.
|
|
23
|
+
* Matches against: displayed title, English title, and search term aliases.
|
|
24
|
+
* @param item - item to check
|
|
25
|
+
* @param query - search query (case-insensitive)
|
|
26
|
+
* @returns true if the item matches the query
|
|
27
|
+
*/
|
|
28
|
+
export const matchesSearchQuery = (item: SearchableItem, query: string): boolean => {
|
|
29
|
+
const lowerQuery = query.toLowerCase();
|
|
30
|
+
const title = item.title?.toLowerCase() ?? '';
|
|
31
|
+
const englishTitle = item.englishTitle?.toLowerCase() ?? '';
|
|
32
|
+
const searchTerms = item.searchTerms ?? [];
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
title.includes(lowerQuery) ||
|
|
36
|
+
englishTitle.includes(lowerQuery) ||
|
|
37
|
+
searchTerms.some(term => term.toLowerCase().includes(lowerQuery))
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Event that can be triggered by the Search Input
|
|
43
|
+
*/
|
|
44
|
+
export enum SearchInputEvent {
|
|
45
|
+
/**
|
|
46
|
+
* When search query is applied
|
|
47
|
+
*/
|
|
48
|
+
Search = 'search'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Events fired by the Search Input
|
|
53
|
+
*/
|
|
54
|
+
export interface SearchInputEventMap {
|
|
55
|
+
/**
|
|
56
|
+
* Fired when search query is applied
|
|
57
|
+
*/
|
|
58
|
+
[SearchInputEvent.Search]: { query: string; items: SearchableItem[]};
|
|
59
|
+
}
|