@jackuait/blok 0.4.1-beta.4 → 0.4.1-beta.6

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.
Files changed (400) hide show
  1. package/README.md +136 -17
  2. package/codemod/README.md +16 -0
  3. package/codemod/migrate-editorjs-to-blok.js +868 -92
  4. package/codemod/test.js +682 -77
  5. package/dist/blok.mjs +5 -2
  6. package/dist/chunks/blok-B5qs7C5l.mjs +12838 -0
  7. package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
  8. package/dist/chunks/i18next-loader-CTrK3HzG.mjs +43 -0
  9. package/dist/{index-XWGz4gev.mjs → chunks/index-DDpzQn-0.mjs} +2 -2
  10. package/dist/chunks/inline-tool-convert-RBcopmCh.mjs +1988 -0
  11. package/dist/chunks/messages-2434tVOK.mjs +47 -0
  12. package/dist/chunks/messages-3DcCwXMF.mjs +47 -0
  13. package/dist/chunks/messages-4kMwVAKY.mjs +47 -0
  14. package/dist/chunks/messages-57uL5htT.mjs +47 -0
  15. package/dist/chunks/messages-76-iJV9Q.mjs +47 -0
  16. package/dist/chunks/messages-8p86Eyf2.mjs +47 -0
  17. package/dist/chunks/messages-BBX0p0Pi.mjs +47 -0
  18. package/dist/chunks/messages-BCm2eudQ.mjs +47 -0
  19. package/dist/chunks/messages-BFiUomgG.mjs +47 -0
  20. package/dist/chunks/messages-BIPNHHAV.mjs +47 -0
  21. package/dist/chunks/messages-BUlwu9mo.mjs +47 -0
  22. package/dist/chunks/messages-BX-DPa-z.mjs +47 -0
  23. package/dist/chunks/messages-BextV3Qh.mjs +47 -0
  24. package/dist/chunks/messages-BiPSFlUG.mjs +47 -0
  25. package/dist/chunks/messages-BiXe9G-O.mjs +47 -0
  26. package/dist/chunks/messages-Bl5z_Igo.mjs +47 -0
  27. package/dist/chunks/messages-BnsE97ku.mjs +47 -0
  28. package/dist/chunks/messages-BoO8gsVD.mjs +47 -0
  29. package/dist/chunks/messages-BqWaOGMn.mjs +47 -0
  30. package/dist/chunks/messages-BqkL2_Ro.mjs +47 -0
  31. package/dist/chunks/messages-BvCkXKX-.mjs +47 -0
  32. package/dist/chunks/messages-C6tbPLoj.mjs +47 -0
  33. package/dist/chunks/messages-CA6T3-gQ.mjs +47 -0
  34. package/dist/chunks/messages-CFFPFdWP.mjs +47 -0
  35. package/dist/chunks/messages-CFrKE-TN.mjs +47 -0
  36. package/dist/chunks/messages-CHz8VlG-.mjs +47 -0
  37. package/dist/chunks/messages-CLixzySl.mjs +47 -0
  38. package/dist/chunks/messages-CV7OM_qk.mjs +47 -0
  39. package/dist/chunks/messages-CXHt3eCC.mjs +47 -0
  40. package/dist/chunks/messages-CbmsBrB0.mjs +47 -0
  41. package/dist/chunks/messages-Ceo1KtFx.mjs +47 -0
  42. package/dist/chunks/messages-Cm0LJLtB.mjs +47 -0
  43. package/dist/chunks/messages-CmymP_Ar.mjs +47 -0
  44. package/dist/chunks/messages-D0ohMB5H.mjs +47 -0
  45. package/dist/chunks/messages-D3GrDwXh.mjs +47 -0
  46. package/dist/chunks/messages-D3vTzIpL.mjs +47 -0
  47. package/dist/chunks/messages-D5WeksbV.mjs +47 -0
  48. package/dist/chunks/messages-DGaab4EP.mjs +47 -0
  49. package/dist/chunks/messages-DKha57ZU.mjs +47 -0
  50. package/dist/chunks/messages-DOaujgMW.mjs +47 -0
  51. package/dist/chunks/messages-DVbPLd_0.mjs +47 -0
  52. package/dist/chunks/messages-D_FCyfW6.mjs +47 -0
  53. package/dist/chunks/messages-Dd5iZN3c.mjs +47 -0
  54. package/dist/chunks/messages-DehM7135.mjs +47 -0
  55. package/dist/chunks/messages-Dg1OHftD.mjs +47 -0
  56. package/dist/chunks/messages-Di6Flq-b.mjs +47 -0
  57. package/dist/chunks/messages-Dqhhex6e.mjs +47 -0
  58. package/dist/chunks/messages-DueVe0F1.mjs +47 -0
  59. package/dist/chunks/messages-Dx3eFwI0.mjs +47 -0
  60. package/dist/chunks/messages-FOtiUoKl.mjs +47 -0
  61. package/dist/chunks/messages-FTOZNhRD.mjs +47 -0
  62. package/dist/chunks/messages-IQxGfQIV.mjs +47 -0
  63. package/dist/chunks/messages-JF2fzCkK.mjs +47 -0
  64. package/dist/chunks/messages-MOGl7I5v.mjs +47 -0
  65. package/dist/chunks/messages-QgYhPL-3.mjs +47 -0
  66. package/dist/chunks/messages-WYWIbQwo.mjs +47 -0
  67. package/dist/chunks/messages-a6A_LgDv.mjs +47 -0
  68. package/dist/chunks/messages-bSf31LJi.mjs +47 -0
  69. package/dist/chunks/messages-diGozhTn.mjs +47 -0
  70. package/dist/chunks/messages-er-kd-VO.mjs +47 -0
  71. package/dist/chunks/messages-ez3w5NBn.mjs +47 -0
  72. package/dist/chunks/messages-f3uXjegd.mjs +47 -0
  73. package/dist/chunks/messages-ohwI1UGv.mjs +47 -0
  74. package/dist/chunks/messages-p9BZJaFV.mjs +47 -0
  75. package/dist/chunks/messages-qIQ4L4rw.mjs +47 -0
  76. package/dist/chunks/messages-qWkXPggi.mjs +47 -0
  77. package/dist/chunks/messages-w5foGze_.mjs +47 -0
  78. package/dist/full.mjs +50 -0
  79. package/dist/locales.mjs +227 -0
  80. package/dist/messages-2434tVOK.mjs +47 -0
  81. package/dist/messages-3DcCwXMF.mjs +47 -0
  82. package/dist/messages-4kMwVAKY.mjs +47 -0
  83. package/dist/messages-57uL5htT.mjs +47 -0
  84. package/dist/messages-76-iJV9Q.mjs +47 -0
  85. package/dist/messages-8p86Eyf2.mjs +47 -0
  86. package/dist/messages-BBX0p0Pi.mjs +47 -0
  87. package/dist/messages-BCm2eudQ.mjs +47 -0
  88. package/dist/messages-BFiUomgG.mjs +47 -0
  89. package/dist/messages-BIPNHHAV.mjs +47 -0
  90. package/dist/messages-BUlwu9mo.mjs +47 -0
  91. package/dist/messages-BX-DPa-z.mjs +47 -0
  92. package/dist/messages-BextV3Qh.mjs +47 -0
  93. package/dist/messages-BiPSFlUG.mjs +47 -0
  94. package/dist/messages-BiXe9G-O.mjs +47 -0
  95. package/dist/messages-Bl5z_Igo.mjs +47 -0
  96. package/dist/messages-BnsE97ku.mjs +47 -0
  97. package/dist/messages-BoO8gsVD.mjs +47 -0
  98. package/dist/messages-BqWaOGMn.mjs +47 -0
  99. package/dist/messages-BqkL2_Ro.mjs +47 -0
  100. package/dist/messages-BvCkXKX-.mjs +47 -0
  101. package/dist/messages-C6tbPLoj.mjs +47 -0
  102. package/dist/messages-CA6T3-gQ.mjs +47 -0
  103. package/dist/messages-CFFPFdWP.mjs +47 -0
  104. package/dist/messages-CFrKE-TN.mjs +47 -0
  105. package/dist/messages-CHz8VlG-.mjs +47 -0
  106. package/dist/messages-CLixzySl.mjs +47 -0
  107. package/dist/messages-CV7OM_qk.mjs +47 -0
  108. package/dist/messages-CXHt3eCC.mjs +47 -0
  109. package/dist/messages-CbmsBrB0.mjs +47 -0
  110. package/dist/messages-Ceo1KtFx.mjs +47 -0
  111. package/dist/messages-Cm0LJLtB.mjs +47 -0
  112. package/dist/messages-CmymP_Ar.mjs +47 -0
  113. package/dist/messages-D0ohMB5H.mjs +47 -0
  114. package/dist/messages-D3GrDwXh.mjs +47 -0
  115. package/dist/messages-D3vTzIpL.mjs +47 -0
  116. package/dist/messages-D5WeksbV.mjs +47 -0
  117. package/dist/messages-DGaab4EP.mjs +47 -0
  118. package/dist/messages-DKha57ZU.mjs +47 -0
  119. package/dist/messages-DOaujgMW.mjs +47 -0
  120. package/dist/messages-DVbPLd_0.mjs +47 -0
  121. package/dist/messages-D_FCyfW6.mjs +47 -0
  122. package/dist/messages-Dd5iZN3c.mjs +47 -0
  123. package/dist/messages-DehM7135.mjs +47 -0
  124. package/dist/messages-Dg1OHftD.mjs +47 -0
  125. package/dist/messages-Di6Flq-b.mjs +47 -0
  126. package/dist/messages-Dqhhex6e.mjs +47 -0
  127. package/dist/messages-DueVe0F1.mjs +47 -0
  128. package/dist/messages-Dx3eFwI0.mjs +47 -0
  129. package/dist/messages-FOtiUoKl.mjs +47 -0
  130. package/dist/messages-FTOZNhRD.mjs +47 -0
  131. package/dist/messages-IQxGfQIV.mjs +47 -0
  132. package/dist/messages-JF2fzCkK.mjs +47 -0
  133. package/dist/messages-MOGl7I5v.mjs +47 -0
  134. package/dist/messages-QgYhPL-3.mjs +47 -0
  135. package/dist/messages-WYWIbQwo.mjs +47 -0
  136. package/dist/messages-a6A_LgDv.mjs +47 -0
  137. package/dist/messages-bSf31LJi.mjs +47 -0
  138. package/dist/messages-diGozhTn.mjs +47 -0
  139. package/dist/messages-er-kd-VO.mjs +47 -0
  140. package/dist/messages-ez3w5NBn.mjs +47 -0
  141. package/dist/messages-f3uXjegd.mjs +47 -0
  142. package/dist/messages-ohwI1UGv.mjs +47 -0
  143. package/dist/messages-p9BZJaFV.mjs +47 -0
  144. package/dist/messages-qIQ4L4rw.mjs +47 -0
  145. package/dist/messages-qWkXPggi.mjs +47 -0
  146. package/dist/messages-w5foGze_.mjs +47 -0
  147. package/dist/tools.mjs +3073 -0
  148. package/dist/vendor.LICENSE.txt +26 -225
  149. package/package.json +49 -23
  150. package/src/blok.ts +267 -0
  151. package/src/components/__module.ts +139 -0
  152. package/src/components/block/api.ts +155 -0
  153. package/src/components/block/index.ts +1427 -0
  154. package/src/components/block-tunes/block-tune-delete.ts +51 -0
  155. package/src/components/blocks.ts +338 -0
  156. package/src/components/constants/data-attributes.ts +342 -0
  157. package/src/components/constants.ts +76 -0
  158. package/src/components/core.ts +392 -0
  159. package/src/components/dom.ts +773 -0
  160. package/src/components/domIterator.ts +189 -0
  161. package/src/components/errors/critical.ts +5 -0
  162. package/src/components/events/BlockChanged.ts +16 -0
  163. package/src/components/events/BlockHovered.ts +21 -0
  164. package/src/components/events/BlockSettingsClosed.ts +12 -0
  165. package/src/components/events/BlockSettingsOpened.ts +12 -0
  166. package/src/components/events/BlokMobileLayoutToggled.ts +15 -0
  167. package/src/components/events/FakeCursorAboutToBeToggled.ts +17 -0
  168. package/src/components/events/FakeCursorHaveBeenSet.ts +17 -0
  169. package/src/components/events/HistoryStateChanged.ts +19 -0
  170. package/src/components/events/RedactorDomChanged.ts +14 -0
  171. package/src/components/events/index.ts +46 -0
  172. package/src/components/flipper.ts +481 -0
  173. package/src/components/i18n/i18next-loader.ts +84 -0
  174. package/src/components/i18n/lightweight-i18n.ts +86 -0
  175. package/src/components/i18n/locales/TRANSLATION_GUIDELINES.md +113 -0
  176. package/src/components/i18n/locales/am/messages.json +44 -0
  177. package/src/components/i18n/locales/ar/messages.json +44 -0
  178. package/src/components/i18n/locales/az/messages.json +44 -0
  179. package/src/components/i18n/locales/bg/messages.json +44 -0
  180. package/src/components/i18n/locales/bn/messages.json +44 -0
  181. package/src/components/i18n/locales/bs/messages.json +44 -0
  182. package/src/components/i18n/locales/cs/messages.json +44 -0
  183. package/src/components/i18n/locales/da/messages.json +44 -0
  184. package/src/components/i18n/locales/de/messages.json +44 -0
  185. package/src/components/i18n/locales/dv/messages.json +44 -0
  186. package/src/components/i18n/locales/el/messages.json +44 -0
  187. package/src/components/i18n/locales/en/messages.json +44 -0
  188. package/src/components/i18n/locales/es/messages.json +44 -0
  189. package/src/components/i18n/locales/et/messages.json +44 -0
  190. package/src/components/i18n/locales/fa/messages.json +44 -0
  191. package/src/components/i18n/locales/fi/messages.json +44 -0
  192. package/src/components/i18n/locales/fil/messages.json +44 -0
  193. package/src/components/i18n/locales/fr/messages.json +44 -0
  194. package/src/components/i18n/locales/gu/messages.json +44 -0
  195. package/src/components/i18n/locales/he/messages.json +44 -0
  196. package/src/components/i18n/locales/hi/messages.json +44 -0
  197. package/src/components/i18n/locales/hr/messages.json +44 -0
  198. package/src/components/i18n/locales/hu/messages.json +44 -0
  199. package/src/components/i18n/locales/hy/messages.json +44 -0
  200. package/src/components/i18n/locales/id/messages.json +44 -0
  201. package/src/components/i18n/locales/index.ts +225 -0
  202. package/src/components/i18n/locales/it/messages.json +44 -0
  203. package/src/components/i18n/locales/ja/messages.json +44 -0
  204. package/src/components/i18n/locales/ka/messages.json +44 -0
  205. package/src/components/i18n/locales/km/messages.json +44 -0
  206. package/src/components/i18n/locales/kn/messages.json +44 -0
  207. package/src/components/i18n/locales/ko/messages.json +44 -0
  208. package/src/components/i18n/locales/ku/messages.json +44 -0
  209. package/src/components/i18n/locales/lo/messages.json +44 -0
  210. package/src/components/i18n/locales/lt/messages.json +44 -0
  211. package/src/components/i18n/locales/lv/messages.json +44 -0
  212. package/src/components/i18n/locales/mk/messages.json +44 -0
  213. package/src/components/i18n/locales/ml/messages.json +44 -0
  214. package/src/components/i18n/locales/mn/messages.json +44 -0
  215. package/src/components/i18n/locales/mr/messages.json +44 -0
  216. package/src/components/i18n/locales/ms/messages.json +44 -0
  217. package/src/components/i18n/locales/my/messages.json +44 -0
  218. package/src/components/i18n/locales/ne/messages.json +44 -0
  219. package/src/components/i18n/locales/nl/messages.json +44 -0
  220. package/src/components/i18n/locales/no/messages.json +44 -0
  221. package/src/components/i18n/locales/pa/messages.json +44 -0
  222. package/src/components/i18n/locales/pl/messages.json +44 -0
  223. package/src/components/i18n/locales/ps/messages.json +44 -0
  224. package/src/components/i18n/locales/pt/messages.json +44 -0
  225. package/src/components/i18n/locales/ro/messages.json +44 -0
  226. package/src/components/i18n/locales/ru/messages.json +44 -0
  227. package/src/components/i18n/locales/sd/messages.json +44 -0
  228. package/src/components/i18n/locales/si/messages.json +44 -0
  229. package/src/components/i18n/locales/sk/messages.json +44 -0
  230. package/src/components/i18n/locales/sl/messages.json +44 -0
  231. package/src/components/i18n/locales/sq/messages.json +44 -0
  232. package/src/components/i18n/locales/sr/messages.json +44 -0
  233. package/src/components/i18n/locales/sv/messages.json +44 -0
  234. package/src/components/i18n/locales/sw/messages.json +44 -0
  235. package/src/components/i18n/locales/ta/messages.json +44 -0
  236. package/src/components/i18n/locales/te/messages.json +44 -0
  237. package/src/components/i18n/locales/th/messages.json +44 -0
  238. package/src/components/i18n/locales/tr/messages.json +44 -0
  239. package/src/components/i18n/locales/ug/messages.json +44 -0
  240. package/src/components/i18n/locales/uk/messages.json +44 -0
  241. package/src/components/i18n/locales/ur/messages.json +44 -0
  242. package/src/components/i18n/locales/vi/messages.json +44 -0
  243. package/src/components/i18n/locales/yi/messages.json +44 -0
  244. package/src/components/i18n/locales/zh/messages.json +44 -0
  245. package/src/components/icons/index.ts +242 -0
  246. package/src/components/inline-tools/inline-tool-bold.ts +2213 -0
  247. package/src/components/inline-tools/inline-tool-convert.ts +141 -0
  248. package/src/components/inline-tools/inline-tool-italic.ts +500 -0
  249. package/src/components/inline-tools/inline-tool-link.ts +539 -0
  250. package/src/components/modules/api/blocks.ts +363 -0
  251. package/src/components/modules/api/caret.ts +125 -0
  252. package/src/components/modules/api/events.ts +51 -0
  253. package/src/components/modules/api/history.ts +73 -0
  254. package/src/components/modules/api/i18n.ts +33 -0
  255. package/src/components/modules/api/index.ts +39 -0
  256. package/src/components/modules/api/inlineToolbar.ts +33 -0
  257. package/src/components/modules/api/listeners.ts +56 -0
  258. package/src/components/modules/api/notifier.ts +46 -0
  259. package/src/components/modules/api/readonly.ts +39 -0
  260. package/src/components/modules/api/sanitizer.ts +30 -0
  261. package/src/components/modules/api/saver.ts +52 -0
  262. package/src/components/modules/api/selection.ts +48 -0
  263. package/src/components/modules/api/styles.ts +72 -0
  264. package/src/components/modules/api/toolbar.ts +79 -0
  265. package/src/components/modules/api/tools.ts +16 -0
  266. package/src/components/modules/api/tooltip.ts +67 -0
  267. package/src/components/modules/api/ui.ts +36 -0
  268. package/src/components/modules/blockEvents.ts +1375 -0
  269. package/src/components/modules/blockManager.ts +1348 -0
  270. package/src/components/modules/blockSelection.ts +708 -0
  271. package/src/components/modules/caret.ts +853 -0
  272. package/src/components/modules/crossBlockSelection.ts +329 -0
  273. package/src/components/modules/dragManager.ts +1141 -0
  274. package/src/components/modules/history.ts +1098 -0
  275. package/src/components/modules/i18n.ts +325 -0
  276. package/src/components/modules/index.ts +139 -0
  277. package/src/components/modules/modificationsObserver.ts +147 -0
  278. package/src/components/modules/paste.ts +1092 -0
  279. package/src/components/modules/readonly.ts +136 -0
  280. package/src/components/modules/rectangleSelection.ts +668 -0
  281. package/src/components/modules/renderer.ts +155 -0
  282. package/src/components/modules/saver.ts +283 -0
  283. package/src/components/modules/toolbar/blockSettings.ts +776 -0
  284. package/src/components/modules/toolbar/index.ts +1311 -0
  285. package/src/components/modules/toolbar/inline.ts +956 -0
  286. package/src/components/modules/tools.ts +589 -0
  287. package/src/components/modules/ui.ts +1179 -0
  288. package/src/components/polyfills.ts +113 -0
  289. package/src/components/selection.ts +1189 -0
  290. package/src/components/tools/base.ts +274 -0
  291. package/src/components/tools/block.ts +291 -0
  292. package/src/components/tools/collection.ts +67 -0
  293. package/src/components/tools/factory.ts +85 -0
  294. package/src/components/tools/inline.ts +71 -0
  295. package/src/components/tools/tune.ts +33 -0
  296. package/src/components/ui/toolbox.ts +497 -0
  297. package/src/components/utils/announcer.ts +205 -0
  298. package/src/components/utils/api.ts +20 -0
  299. package/src/components/utils/bem.ts +26 -0
  300. package/src/components/utils/blocks.ts +284 -0
  301. package/src/components/utils/caret.ts +1067 -0
  302. package/src/components/utils/data-model-transform.ts +382 -0
  303. package/src/components/utils/events.ts +117 -0
  304. package/src/components/utils/keyboard.ts +60 -0
  305. package/src/components/utils/listeners.ts +296 -0
  306. package/src/components/utils/mutations.ts +39 -0
  307. package/src/components/utils/notifier/draw.ts +190 -0
  308. package/src/components/utils/notifier/index.ts +66 -0
  309. package/src/components/utils/notifier/types.ts +1 -0
  310. package/src/components/utils/notifier.ts +77 -0
  311. package/src/components/utils/placeholder.ts +140 -0
  312. package/src/components/utils/popover/components/hint/hint.const.ts +10 -0
  313. package/src/components/utils/popover/components/hint/hint.ts +46 -0
  314. package/src/components/utils/popover/components/hint/index.ts +6 -0
  315. package/src/components/utils/popover/components/popover-header/index.ts +2 -0
  316. package/src/components/utils/popover/components/popover-header/popover-header.const.ts +8 -0
  317. package/src/components/utils/popover/components/popover-header/popover-header.ts +80 -0
  318. package/src/components/utils/popover/components/popover-header/popover-header.types.ts +14 -0
  319. package/src/components/utils/popover/components/popover-item/index.ts +13 -0
  320. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +50 -0
  321. package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +666 -0
  322. package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts +14 -0
  323. package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts +136 -0
  324. package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +20 -0
  325. package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts +117 -0
  326. package/src/components/utils/popover/components/popover-item/popover-item.ts +187 -0
  327. package/src/components/utils/popover/components/search-input/index.ts +2 -0
  328. package/src/components/utils/popover/components/search-input/search-input.const.ts +8 -0
  329. package/src/components/utils/popover/components/search-input/search-input.ts +181 -0
  330. package/src/components/utils/popover/components/search-input/search-input.types.ts +30 -0
  331. package/src/components/utils/popover/index.ts +13 -0
  332. package/src/components/utils/popover/popover-abstract.ts +448 -0
  333. package/src/components/utils/popover/popover-desktop.ts +643 -0
  334. package/src/components/utils/popover/popover-inline.ts +338 -0
  335. package/src/components/utils/popover/popover-mobile.ts +201 -0
  336. package/src/components/utils/popover/popover.const.ts +81 -0
  337. package/src/components/utils/popover/utils/popover-states-history.ts +72 -0
  338. package/src/components/utils/promise-queue.ts +43 -0
  339. package/src/components/utils/sanitizer.ts +537 -0
  340. package/src/components/utils/scroll-locker.ts +87 -0
  341. package/src/components/utils/shortcut.ts +231 -0
  342. package/src/components/utils/shortcuts.ts +113 -0
  343. package/src/components/utils/tools.ts +105 -0
  344. package/src/components/utils/tooltip.ts +642 -0
  345. package/src/components/utils/tw.ts +241 -0
  346. package/src/components/utils.ts +1081 -0
  347. package/src/env.d.ts +13 -0
  348. package/src/full.ts +69 -0
  349. package/src/locales.ts +51 -0
  350. package/src/stories/Block.stories.ts +498 -0
  351. package/src/stories/EditorModes.stories.ts +505 -0
  352. package/src/stories/Header.stories.ts +137 -0
  353. package/src/stories/InlineToolbar.stories.ts +498 -0
  354. package/src/stories/List.stories.ts +259 -0
  355. package/src/stories/Notifier.stories.ts +340 -0
  356. package/src/stories/Paragraph.stories.ts +112 -0
  357. package/src/stories/Placeholder.stories.ts +319 -0
  358. package/src/stories/Popover.stories.ts +844 -0
  359. package/src/stories/Selection.stories.ts +250 -0
  360. package/src/stories/StubBlock.stories.ts +156 -0
  361. package/src/stories/Toolbar.stories.ts +223 -0
  362. package/src/stories/Toolbox.stories.ts +166 -0
  363. package/src/stories/Tooltip.stories.ts +198 -0
  364. package/src/stories/helpers.ts +463 -0
  365. package/src/styles/main.css +123 -0
  366. package/src/tools/header/index.ts +570 -0
  367. package/src/tools/index.ts +38 -0
  368. package/src/tools/list/index.ts +1803 -0
  369. package/src/tools/paragraph/index.ts +411 -0
  370. package/src/tools/stub/index.ts +107 -0
  371. package/src/types-internal/blok-modules.d.ts +87 -0
  372. package/src/types-internal/html-janitor.d.ts +28 -0
  373. package/src/types-internal/module-config.d.ts +11 -0
  374. package/src/variants/all-locales.ts +155 -0
  375. package/src/variants/blok-maximum.ts +20 -0
  376. package/src/variants/blok-minimum.ts +243 -0
  377. package/types/api/blocks.d.ts +1 -1
  378. package/types/api/i18n.d.ts +5 -3
  379. package/types/api/selection.d.ts +6 -0
  380. package/types/api/styles.d.ts +23 -10
  381. package/types/configs/blok-config.d.ts +29 -0
  382. package/types/configs/i18n-config.d.ts +52 -2
  383. package/types/configs/i18n-dictionary.d.ts +16 -90
  384. package/types/data-attributes.d.ts +169 -0
  385. package/types/data-formats/output-data.d.ts +15 -0
  386. package/types/full.d.ts +80 -0
  387. package/types/index.d.ts +9 -12
  388. package/types/locales.d.ts +59 -0
  389. package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
  390. package/types/tools/block-tool.d.ts +9 -0
  391. package/types/tools/header.d.ts +18 -0
  392. package/types/tools/index.d.ts +1 -0
  393. package/types/tools/list.d.ts +91 -0
  394. package/types/tools/paragraph.d.ts +71 -0
  395. package/types/tools/tool-settings.d.ts +16 -2
  396. package/types/tools/tool.d.ts +6 -0
  397. package/types/tools-entry.d.ts +49 -0
  398. package/types/utils/popover/popover-item.d.ts +6 -5
  399. package/dist/blok-B870U2fw.mjs +0 -25803
  400. package/dist/blok.umd.js +0 -181
@@ -0,0 +1,643 @@
1
+ import { Flipper } from '../../flipper';
2
+ import { PopoverAbstract } from './popover-abstract';
3
+ import type { PopoverItem, PopoverItemRenderParamsMap } from './components/popover-item';
4
+ import { PopoverItemSeparator, css as popoverItemCls } from './components/popover-item';
5
+ import type { PopoverParams } from '@/types/utils/popover/popover';
6
+ import { PopoverEvent } from '@/types/utils/popover/popover-event';
7
+ import { keyCodes } from '../../utils';
8
+ import { CSSVariables } from './popover.const';
9
+ import { DATA_ATTR } from '../../constants/data-attributes';
10
+ import type { SearchableItem } from './components/search-input';
11
+ import { SearchInput, SearchInputEvent } from './components/search-input';
12
+ import { PopoverItemDefault } from './components/popover-item';
13
+ import { PopoverItemHtml } from './components/popover-item/popover-item-html/popover-item-html';
14
+
15
+ /**
16
+ * Desktop popover.
17
+ * On desktop devices popover behaves like a floating element. Nested popover appears at right or left side.
18
+ * @internal
19
+ * @todo support rtl for nested popovers and search
20
+ */
21
+ export class PopoverDesktop extends PopoverAbstract {
22
+ /**
23
+ * Flipper - module for keyboard iteration between elements
24
+ */
25
+ public flipper: Flipper | undefined;
26
+
27
+ /**
28
+ * Popover nesting level. 0 value means that it is a root popover
29
+ */
30
+ public nestingLevel = 0;
31
+
32
+ /**
33
+ * Reference to nested popover if exists.
34
+ * Undefined by default, PopoverDesktop when exists and null after destroyed.
35
+ */
36
+ protected nestedPopover: PopoverDesktop | undefined | null;
37
+
38
+ /**
39
+ * Item nested popover is displayed for
40
+ */
41
+ protected nestedPopoverTriggerItem: PopoverItem | null = null;
42
+
43
+ /**
44
+ * Last hovered item inside popover.
45
+ * Is used to determine if cursor is moving inside one item or already moved away to another one.
46
+ * Helps prevent reopening nested popover while cursor is moving inside one item area.
47
+ */
48
+ private previouslyHoveredItem: PopoverItem | null = null;
49
+
50
+ /**
51
+ * Element of the page that creates 'scope' of the popover.
52
+ * If possible, popover will not cross specified element's borders when opening.
53
+ */
54
+ private scopeElement: HTMLElement = document.body;
55
+
56
+ /**
57
+ * Element relative to which the popover should be positioned
58
+ */
59
+ private trigger: HTMLElement | undefined;
60
+
61
+ /**
62
+ * Popover size cache
63
+ */
64
+ private _size: { height: number; width: number } | undefined;
65
+
66
+ /**
67
+ * Construct the instance
68
+ * @param params - popover params
69
+ * @param itemsRenderParams – popover item render params.
70
+ * The parameters that are not set by user via popover api but rather depend on technical implementation
71
+ */
72
+ constructor(params: PopoverParams, itemsRenderParams?: PopoverItemRenderParamsMap) {
73
+ super(params, itemsRenderParams);
74
+
75
+ if (params.trigger) {
76
+ this.trigger = params.trigger;
77
+ }
78
+
79
+ if (params.nestingLevel !== undefined) {
80
+ this.nestingLevel = params.nestingLevel;
81
+ }
82
+
83
+ if (this.nestingLevel > 0) {
84
+ this.nodes.popover.setAttribute(DATA_ATTR.nested, 'true');
85
+ }
86
+
87
+ if (params.scopeElement !== undefined) {
88
+ this.scopeElement = params.scopeElement;
89
+ }
90
+
91
+ if (this.nodes.popoverContainer !== null) {
92
+ this.listeners.on(this.nodes.popoverContainer, 'mouseover', (event: Event) => this.handleHover(event));
93
+ }
94
+
95
+ if (params.searchable) {
96
+ this.addSearch();
97
+ }
98
+
99
+ if (params.flippable === false) {
100
+ return;
101
+ }
102
+
103
+ if (params.flipper !== undefined) {
104
+ params.flipper.deactivate();
105
+ params.flipper.removeOnFlip(this.onFlip);
106
+ this.flipper = params.flipper;
107
+ } else {
108
+ this.flipper = new Flipper({
109
+ items: this.flippableElements,
110
+ focusedItemClass: popoverItemCls.focused,
111
+ allowedKeys: [
112
+ keyCodes.TAB,
113
+ keyCodes.UP,
114
+ keyCodes.DOWN,
115
+ keyCodes.ENTER,
116
+ keyCodes.RIGHT,
117
+ keyCodes.LEFT,
118
+ ],
119
+ onArrowLeft: params.onNavigateBack,
120
+ });
121
+ }
122
+
123
+ this.flipper?.onFlip(this.onFlip);
124
+ }
125
+
126
+ /**
127
+ * Returns true if some item inside popover is focused
128
+ */
129
+ public hasFocus(): boolean {
130
+ if (this.flipper === undefined) {
131
+ return false;
132
+ }
133
+
134
+ return this.flipper.hasFocus();
135
+ }
136
+
137
+ /**
138
+ * Scroll position inside items container of the popover
139
+ */
140
+ public get scrollTop(): number {
141
+ if (this.nodes.items === null) {
142
+ return 0;
143
+ }
144
+
145
+ return this.nodes.items.scrollTop;
146
+ }
147
+
148
+ /**
149
+ * Returns visible element offset top
150
+ */
151
+ public get offsetTop(): number {
152
+ if (this.nodes.popoverContainer === null) {
153
+ return 0;
154
+ }
155
+
156
+ return this.nodes.popoverContainer.offsetTop;
157
+ }
158
+
159
+ /**
160
+ * Open popover
161
+ */
162
+ public show(): void {
163
+ const mountTarget = this.getMountElement();
164
+
165
+ if (this.trigger && mountTarget) {
166
+ document.body.appendChild(mountTarget);
167
+ }
168
+
169
+ if (this.trigger) {
170
+ const { top, left } = this.calculatePosition();
171
+ this.nodes.popover.style.position = 'absolute';
172
+ this.nodes.popover.style.top = `${top}px`;
173
+ this.nodes.popover.style.left = `${left}px`;
174
+ this.nodes.popover.style.setProperty(CSSVariables.PopoverTop, '0px');
175
+ this.nodes.popover.style.setProperty(CSSVariables.PopoverLeft, '0px');
176
+ }
177
+
178
+ this.nodes.popover.style.setProperty(CSSVariables.PopoverHeight, this.size.height + 'px');
179
+
180
+ if (!this.trigger && !this.shouldOpenBottom) {
181
+ this.setOpenTop(true);
182
+ // Apply open-top positioning (moved from popover.css)
183
+ this.nodes.popover.style.setProperty(CSSVariables.PopoverTop, 'calc(-1 * (0.5rem + var(--popover-height)))');
184
+ }
185
+
186
+ if (!this.trigger && !this.shouldOpenRight) {
187
+ this.setOpenLeft(true);
188
+ // Apply open-left positioning (moved from popover.css)
189
+ this.nodes.popover.style.setProperty(CSSVariables.PopoverLeft, 'calc(-1 * var(--width) + 100%)');
190
+ }
191
+
192
+ super.show();
193
+ this.flipper?.activate(this.flippableElements);
194
+
195
+ // Focus the first item: search field if present, otherwise first menu item
196
+ requestAnimationFrame(() => {
197
+ this.focusInitialElement();
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Focuses the initial element when popover is shown.
203
+ * Focuses search field if present, otherwise first menu item.
204
+ */
205
+ private focusInitialElement(): void {
206
+ if (this.search) {
207
+ this.search.focus();
208
+
209
+ return;
210
+ }
211
+
212
+ this.flipper?.focusFirst();
213
+ }
214
+
215
+ /**
216
+ * Calculates position for the popover
217
+ */
218
+ private calculatePosition(): { top: number; left: number } {
219
+ if (!this.trigger) {
220
+ return {
221
+ top: 0,
222
+ left: 0,
223
+ };
224
+ }
225
+
226
+ const triggerRect = this.trigger.getBoundingClientRect();
227
+ const popoverRect = this.size;
228
+ const windowWidth = window.innerWidth;
229
+ const windowHeight = window.innerHeight;
230
+ const offset = 8;
231
+
232
+ const initialTop = triggerRect.bottom + offset + window.scrollY;
233
+ const shouldFlipTop = (triggerRect.bottom + offset + popoverRect.height > windowHeight + window.scrollY) &&
234
+ (triggerRect.top - offset - popoverRect.height > window.scrollY);
235
+ const top = shouldFlipTop ? triggerRect.top - offset - popoverRect.height + window.scrollY : initialTop;
236
+
237
+ const initialLeft = triggerRect.left + window.scrollX;
238
+ const shouldFlipLeft = initialLeft + popoverRect.width > windowWidth + window.scrollX;
239
+ const left = shouldFlipLeft ? Math.max(0, triggerRect.right - popoverRect.width + window.scrollX) : initialLeft;
240
+
241
+ return {
242
+ top,
243
+ left,
244
+ };
245
+ }
246
+
247
+ /**
248
+ * Closes popover
249
+ */
250
+ public hide = (): void => {
251
+ super.hide();
252
+
253
+ this.destroyNestedPopoverIfExists();
254
+
255
+ this.flipper?.deactivate();
256
+
257
+ this.previouslyHoveredItem = null;
258
+ };
259
+
260
+ /**
261
+ * Clears memory
262
+ */
263
+ public destroy(): void {
264
+ this.hide();
265
+ super.destroy();
266
+ }
267
+
268
+ /**
269
+ * Checks if popover contains the node.
270
+ * Overridden to check nested popover as well.
271
+ * @param node - node to check
272
+ */
273
+ public override hasNode(node: Node): boolean {
274
+ if (super.hasNode(node)) {
275
+ return true;
276
+ }
277
+
278
+ if (this.nestedPopover !== undefined && this.nestedPopover !== null) {
279
+ return this.nestedPopover.hasNode(node);
280
+ }
281
+
282
+ return false;
283
+ }
284
+
285
+ /**
286
+ * Handles displaying nested items for the item.
287
+ * @param item – item to show nested popover for
288
+ */
289
+ protected override showNestedItems(item: PopoverItem): void {
290
+ if (this.nestedPopover !== null && this.nestedPopover !== undefined) {
291
+ return;
292
+ }
293
+
294
+ this.nestedPopoverTriggerItem = item;
295
+
296
+ this.showNestedPopoverForItem(item);
297
+ }
298
+
299
+ /**
300
+ * Handles hover events inside popover items container
301
+ * @param event - hover event data
302
+ */
303
+ protected handleHover(event: Event): void {
304
+ const item = this.getTargetItem(event);
305
+
306
+ if (item === undefined) {
307
+ return;
308
+ }
309
+
310
+ if (this.previouslyHoveredItem === item) {
311
+ return;
312
+ }
313
+
314
+ this.destroyNestedPopoverIfExists();
315
+
316
+ this.previouslyHoveredItem = item;
317
+
318
+ if (!item.hasChildren) {
319
+ return;
320
+ }
321
+
322
+ this.showNestedPopoverForItem(item);
323
+ }
324
+
325
+ /**
326
+ * Sets CSS variable with position of item near which nested popover should be displayed.
327
+ * Is used for correct positioning of the nested popover
328
+ * @param nestedPopoverEl - nested popover element
329
+ * @param item – item near which nested popover should be displayed
330
+ */
331
+ protected setTriggerItemPosition(nestedPopoverEl: HTMLElement, item: PopoverItem): void {
332
+ const itemEl = item.getElement();
333
+ const itemOffsetTop = (itemEl ? itemEl.offsetTop : 0) - this.scrollTop;
334
+ const topOffset = this.offsetTop + itemOffsetTop;
335
+
336
+ const actualPopoverEl = nestedPopoverEl.querySelector(`[${DATA_ATTR.popover}]`) as HTMLElement | null ?? nestedPopoverEl;
337
+
338
+ actualPopoverEl.style.setProperty(CSSVariables.TriggerItemTop, topOffset + 'px');
339
+ }
340
+
341
+ /**
342
+ * Destroys existing nested popover
343
+ */
344
+ protected destroyNestedPopoverIfExists(): void {
345
+ if (this.nestedPopover === undefined || this.nestedPopover === null) {
346
+ return;
347
+ }
348
+
349
+ const triggerItemElement = this.nestedPopoverTriggerItem?.getElement();
350
+
351
+ this.nestedPopover.off(PopoverEvent.ClosedOnActivate, this.hide);
352
+ this.nestedPopover.hide();
353
+ this.nestedPopover.destroy();
354
+ this.nestedPopover.getElement().remove();
355
+ this.nestedPopover = null;
356
+ this.flipper?.activate(this.flippableElements);
357
+ // Focus the trigger item synchronously to ensure keyboard events work immediately
358
+ this.focusAfterNestedPopoverClose(triggerItemElement);
359
+
360
+ this.nestedPopoverTriggerItem?.onChildrenClose();
361
+ // Reset trigger item so clicking the same item again will open the nested popover
362
+ this.nestedPopoverTriggerItem = null;
363
+ }
364
+
365
+ /**
366
+ * Focuses the appropriate item after nested popover closes.
367
+ * Focuses the item that opened the nested popover, or falls back to first item.
368
+ * @param triggerItemElement - element that triggered the nested popover
369
+ */
370
+ private focusAfterNestedPopoverClose(triggerItemElement: HTMLElement | null | undefined): void {
371
+ if (!triggerItemElement || !this.flipper) {
372
+ this.flipper?.focusFirst();
373
+
374
+ return;
375
+ }
376
+
377
+ const triggerIndex = this.flippableElements.indexOf(triggerItemElement);
378
+
379
+ if (triggerIndex !== -1) {
380
+ // Don't skip next Tab - user expects Tab to move to next item after closing nested popover
381
+ this.flipper.focusItem(triggerIndex, { skipNextTab: false });
382
+
383
+ return;
384
+ }
385
+
386
+ this.flipper.focusFirst();
387
+ }
388
+
389
+ /**
390
+ * Creates and displays nested popover for specified item.
391
+ * Is used only on desktop
392
+ * @param item - item to display nested popover by
393
+ */
394
+ protected showNestedPopoverForItem(item: PopoverItem): PopoverDesktop {
395
+ this.nestedPopover = new PopoverDesktop({
396
+ searchable: item.isChildrenSearchable,
397
+ items: item.children,
398
+ nestingLevel: this.nestingLevel + 1,
399
+ flippable: item.isChildrenFlippable,
400
+ messages: this.messages,
401
+ onNavigateBack: this.destroyNestedPopoverIfExists.bind(this),
402
+ });
403
+
404
+ item.onChildrenOpen();
405
+
406
+ /**
407
+ * Close nested popover when item with 'closeOnActivate' property set was clicked
408
+ * parent popover should also be closed
409
+ */
410
+ this.nestedPopover.on(PopoverEvent.ClosedOnActivate, this.hide);
411
+
412
+ const nestedPopoverEl = this.nestedPopover.getMountElement();
413
+ const actualNestedPopoverEl = this.nestedPopover.getElement();
414
+
415
+ this.nodes.popover.appendChild(nestedPopoverEl);
416
+
417
+ this.setTriggerItemPosition(nestedPopoverEl, item);
418
+
419
+ /* We need nesting level value in CSS to calculate offset left for nested popover */
420
+ /* Set on the actual popover element so it's available for --popover-left calculation */
421
+ actualNestedPopoverEl.style.setProperty(CSSVariables.NestingLevel, this.nestedPopover.nestingLevel.toString());
422
+
423
+ // Apply nested popover positioning (moved from popover.css)
424
+ this.applyNestedPopoverPositioning(nestedPopoverEl);
425
+
426
+ this.nestedPopover.show();
427
+ this.flipper?.deactivate();
428
+
429
+ return this.nestedPopover;
430
+ }
431
+
432
+ /**
433
+ * Applies positioning styles to nested popover container.
434
+ * This replaces CSS selectors like [data-blok-nested] [data-blok-popover-container]
435
+ * @param nestedPopoverEl - the nested popover element (mount element)
436
+ */
437
+ private applyNestedPopoverPositioning(nestedPopoverEl: HTMLElement): void {
438
+ const nestedContainer = nestedPopoverEl.querySelector(`[${DATA_ATTR.popoverContainer}]`) as HTMLElement | null;
439
+
440
+ if (!nestedContainer) {
441
+ return;
442
+ }
443
+
444
+ const actualPopoverEl = nestedPopoverEl.querySelector(`[${DATA_ATTR.popover}]`) as HTMLElement | null ?? nestedPopoverEl;
445
+
446
+ // Check if parent popover has openTop or openLeft state
447
+ const isParentOpenTop = this.nodes.popover.hasAttribute(DATA_ATTR.popoverOpenTop);
448
+ const isParentOpenLeft = this.nodes.popover.hasAttribute(DATA_ATTR.popoverOpenLeft);
449
+
450
+ // Apply position: absolute for nested container
451
+ nestedContainer.style.position = 'absolute';
452
+
453
+ // Calculate --popover-left based on nesting level and parent open direction
454
+ // Set on the actual popover element to override its default value
455
+ if (isParentOpenLeft) {
456
+ // Position to the left
457
+ actualPopoverEl.style.setProperty(CSSVariables.PopoverLeft, 'calc(-1 * (var(--nesting-level) + 1) * var(--width) + 100%)');
458
+ } else {
459
+ // Position to the right
460
+ actualPopoverEl.style.setProperty(CSSVariables.PopoverLeft, 'calc(var(--nesting-level) * (var(--width) - var(--nested-popover-overlap)))');
461
+ }
462
+
463
+ // Calculate top position based on parent open direction
464
+ if (isParentOpenTop) {
465
+ // Open upward
466
+ nestedContainer.style.top = 'calc(var(--trigger-item-top) - var(--popover-height) + var(--item-height) + 0.5rem + var(--nested-popover-overlap))';
467
+ } else {
468
+ // Open downward
469
+ nestedContainer.style.top = 'calc(var(--trigger-item-top) - var(--nested-popover-overlap))';
470
+ }
471
+ }
472
+
473
+ /**
474
+ * Checks if popover should be opened bottom.
475
+ * It should happen when there is enough space below or not enough space above
476
+ */
477
+ private get shouldOpenBottom(): boolean {
478
+ if (this.nodes.popover === undefined || this.nodes.popover === null) {
479
+ return false;
480
+ }
481
+ const popoverRect = this.nodes.popoverContainer.getBoundingClientRect();
482
+ const scopeElementRect = this.scopeElement.getBoundingClientRect();
483
+ const popoverHeight = this.size.height;
484
+ const popoverPotentialBottomEdge = popoverRect.top + popoverHeight;
485
+ const popoverPotentialTopEdge = popoverRect.top - popoverHeight;
486
+ const bottomEdgeForComparison = Math.min(window.innerHeight, scopeElementRect.bottom);
487
+
488
+ return popoverPotentialTopEdge < scopeElementRect.top || popoverPotentialBottomEdge <= bottomEdgeForComparison;
489
+ }
490
+
491
+ /**
492
+ * Checks if popover should be opened left.
493
+ * It should happen when there is enough space in the right or not enough space in the left
494
+ */
495
+ private get shouldOpenRight(): boolean {
496
+ if (this.nodes.popover === undefined || this.nodes.popover === null) {
497
+ return false;
498
+ }
499
+
500
+ const popoverRect = this.nodes.popover.getBoundingClientRect();
501
+ const scopeElementRect = this.scopeElement.getBoundingClientRect();
502
+ const popoverWidth = this.size.width;
503
+ const popoverPotentialRightEdge = popoverRect.right + popoverWidth;
504
+ const popoverPotentialLeftEdge = popoverRect.left - popoverWidth;
505
+ const rightEdgeForComparison = Math.min(window.innerWidth, scopeElementRect.right);
506
+
507
+ return popoverPotentialLeftEdge < scopeElementRect.left || popoverPotentialRightEdge <= rightEdgeForComparison;
508
+ }
509
+
510
+ /**
511
+ * Helps to calculate size of popover that is only resolved when popover is displayed on screen.
512
+ * Renders invisible clone of popover to get actual values.
513
+ */
514
+ public get size(): { height: number; width: number } {
515
+ if (this._size) {
516
+ return this._size;
517
+ }
518
+
519
+ const size = {
520
+ height: 0,
521
+ width: 0,
522
+ };
523
+
524
+ if (this.nodes.popover === null) {
525
+ return size;
526
+ }
527
+
528
+ const popoverClone = this.nodes.popover.cloneNode(true) as HTMLElement;
529
+
530
+ popoverClone.style.visibility = 'hidden';
531
+ popoverClone.style.position = 'absolute';
532
+ popoverClone.style.top = '-1000px';
533
+
534
+ popoverClone.setAttribute(DATA_ATTR.popoverOpened, 'true');
535
+ popoverClone.querySelector(`[${DATA_ATTR.nested}]`)?.remove();
536
+ document.body.appendChild(popoverClone);
537
+
538
+ const container = popoverClone.querySelector(`[${DATA_ATTR.popoverContainer}]`) as HTMLElement;
539
+
540
+ size.height = container.offsetHeight;
541
+ size.width = container.offsetWidth;
542
+ popoverClone.remove();
543
+
544
+ this._size = size;
545
+
546
+ return size;
547
+ }
548
+
549
+ /**
550
+ * Returns list of elements available for keyboard navigation.
551
+ */
552
+ protected get flippableElements(): HTMLElement[] {
553
+ const result = this.items.flatMap(item => {
554
+ return this.getFlippableElementsForItem(item);
555
+ }).filter((item): item is HTMLElement => item !== undefined && item !== null);
556
+
557
+ return result;
558
+ }
559
+
560
+ /**
561
+ * Gets flippable elements for a single item.
562
+ * @param item - popover item to get elements from
563
+ * @returns array of HTML elements for keyboard navigation
564
+ */
565
+ private getFlippableElementsForItem(item: PopoverItem): HTMLElement[] {
566
+ if (item instanceof PopoverItemHtml) {
567
+ const element = item.getElement();
568
+
569
+ return element ? [element] : [];
570
+ }
571
+
572
+ if (!(item instanceof PopoverItemDefault)) {
573
+ return [];
574
+ }
575
+
576
+ if (item.isDisabled) {
577
+ return [];
578
+ }
579
+
580
+ const element = item.getElement();
581
+
582
+ return element ? [ element ] : [];
583
+ }
584
+
585
+ /**
586
+ * Called on flipper navigation
587
+ */
588
+ private onFlip = (): void => {
589
+ const focusedItem = this.itemsDefault.find(item => item.isFocused);
590
+
591
+ focusedItem?.onFocus();
592
+ };
593
+
594
+ /**
595
+ * Adds search to the popover
596
+ */
597
+ private addSearch(): void {
598
+ this.search = new SearchInput({
599
+ items: this.itemsDefault,
600
+ placeholder: this.messages.search,
601
+ });
602
+
603
+ this.search.on(SearchInputEvent.Search, this.onSearch);
604
+
605
+ const searchElement = this.search.getElement();
606
+
607
+ searchElement.classList.add('mb-1.5');
608
+
609
+ this.nodes.popoverContainer.insertBefore(searchElement, this.nodes.popoverContainer.firstChild);
610
+ }
611
+
612
+ /**
613
+ * Handles input inside search field
614
+ * @param data - search input event data
615
+ * @param data.query - search query text
616
+ * @param data.items - search results
617
+ */
618
+ private onSearch = (data: { query: string, items: SearchableItem[] }): void => {
619
+ const isEmptyQuery = data.query === '';
620
+ const isNothingFound = data.items.length === 0;
621
+
622
+ this.items
623
+ .forEach((item) => {
624
+ const isDefaultItem = item instanceof PopoverItemDefault;
625
+ const isSeparatorOrHtml = item instanceof PopoverItemSeparator || item instanceof PopoverItemHtml;
626
+ const isHidden = isDefaultItem
627
+ ? !data.items.includes(item)
628
+ : isSeparatorOrHtml && (isNothingFound || !isEmptyQuery);
629
+
630
+ item.toggleHidden(isHidden);
631
+ });
632
+ this.toggleNothingFoundMessage(isNothingFound);
633
+
634
+ /** List of elements available for keyboard navigation considering search query applied */
635
+ const flippableElements = data.query === '' ? this.flippableElements : data.items.map(item => (item as PopoverItem).getElement());
636
+
637
+ if (this.flipper?.isActivated) {
638
+ /** Update flipper items with only visible */
639
+ this.flipper.deactivate();
640
+ this.flipper.activate(flippableElements as HTMLElement[]);
641
+ }
642
+ };
643
+ }