@jackuait/blok 0.7.2 → 0.7.3-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/dist/blok.mjs +3 -3
  2. package/dist/chunks/{blok-3RuPZd3G.mjs → blok-Cv1zWiST.mjs} +2147 -2099
  3. package/dist/chunks/{constants-BkelccB1.mjs → constants-DWpV4hCh.mjs} +186 -58
  4. package/dist/chunks/{i18next-loader-qjweOJ-t.mjs → i18next-loader-D5HxE5ZQ.mjs} +1 -1
  5. package/dist/chunks/{lightweight-i18n-vbtPx5C4.mjs → lightweight-i18n-Safdy0ua.mjs} +0 -1
  6. package/dist/chunks/{messages-CjcSWeud.mjs → messages-1C3OS98e.mjs} +0 -1
  7. package/dist/chunks/{messages-3bOAVT3X2.mjs → messages-3ePgbbpx2.mjs} +0 -1
  8. package/dist/chunks/{messages-CG2xl0IV.mjs → messages-6EJxSImH.mjs} +0 -1
  9. package/dist/{messages-BjnJajTO2.mjs → chunks/messages-6z-ULVyk.mjs} +0 -1
  10. package/dist/{messages-B8jjwMLK.mjs → chunks/messages-BKtWlK39.mjs} +0 -1
  11. package/dist/chunks/{messages-CpnXbVOK2.mjs → messages-BM1Su_Uy2.mjs} +0 -1
  12. package/dist/{messages-DZo0x7Bd.mjs → chunks/messages-BUy3odZo.mjs} +0 -1
  13. package/dist/{messages-BflWzIcP2.mjs → chunks/messages-BZ45xBlV.mjs} +0 -1
  14. package/dist/chunks/{messages-Dr7yA3xM.mjs → messages-B_90PYaG.mjs} +0 -1
  15. package/dist/{messages-49ZJ_ISf.mjs → chunks/messages-B_nVGWdk.mjs} +0 -1
  16. package/dist/{messages-cOqXp22e.mjs → chunks/messages-BjkDJuqh.mjs} +0 -1
  17. package/dist/chunks/{messages-CvamFN6x.mjs → messages-BtNOlsMj.mjs} +0 -1
  18. package/dist/{messages-DmX52AQr.mjs → chunks/messages-C1iQkKu82.mjs} +0 -1
  19. package/dist/{messages-CaAdEXoh2.mjs → chunks/messages-C1lqY56F2.mjs} +0 -1
  20. package/dist/chunks/{messages-BoTtYEct2.mjs → messages-C232njMF2.mjs} +0 -1
  21. package/dist/chunks/{messages-DPe7kW6J.mjs → messages-C3AJz_i6.mjs} +0 -1
  22. package/dist/{messages-BEDVb3ZX.mjs → chunks/messages-C9XSSqS5.mjs} +0 -1
  23. package/dist/chunks/{messages-DriB5lEF.mjs → messages-CRxkRJRN.mjs} +0 -1
  24. package/dist/{messages-XwPD18Kk.mjs → chunks/messages-CVzvKl6U.mjs} +0 -1
  25. package/dist/chunks/{messages-B_Qcy8kr2.mjs → messages-Cb-x47kY2.mjs} +0 -1
  26. package/dist/{messages-DvTVsLOK2.mjs → chunks/messages-CejEH4FW2.mjs} +0 -1
  27. package/dist/{messages-CicggErN2.mjs → chunks/messages-CficsmSH2.mjs} +0 -1
  28. package/dist/chunks/{messages-CFr0Ha6p2.mjs → messages-ClOxDE0y2.mjs} +0 -1
  29. package/dist/chunks/{messages-BRrtoRdw2.mjs → messages-Cn5n0nHe2.mjs} +0 -1
  30. package/dist/{messages-DwPfgL_u.mjs → chunks/messages-CnzaTbel.mjs} +0 -1
  31. package/dist/chunks/{messages-CIGX0FfW.mjs → messages-Cq6wj6FG.mjs} +0 -1
  32. package/dist/chunks/{messages-Csq7JatN.mjs → messages-CteKp81J.mjs} +0 -1
  33. package/dist/{messages-Dr-YJYIK2.mjs → chunks/messages-CvLXClh9.mjs} +0 -1
  34. package/dist/chunks/{messages-43N0Vfg42.mjs → messages-CxTq0x772.mjs} +0 -1
  35. package/dist/chunks/{messages-DkSwQvmi2.mjs → messages-CzCqu58X2.mjs} +0 -1
  36. package/dist/{messages-CkVfziK_2.mjs → chunks/messages-D6SAC8Lc2.mjs} +0 -1
  37. package/dist/chunks/{messages-Doxcj7Qy.mjs → messages-D7aoKTPD.mjs} +0 -1
  38. package/dist/chunks/{messages-B0cg-ThO2.mjs → messages-D9nReG4C2.mjs} +0 -1
  39. package/dist/{messages-g58itYPI.mjs → chunks/messages-D9qyilS0.mjs} +0 -1
  40. package/dist/chunks/{messages-BQZtOYxr2.mjs → messages-DDRCk44J2.mjs} +0 -1
  41. package/dist/chunks/{messages-B87-89os.mjs → messages-DDr8J4FE.mjs} +0 -1
  42. package/dist/{messages-DzhR8Klk.mjs → chunks/messages-DJWRON2S.mjs} +0 -1
  43. package/dist/{messages-DBwaWI0X.mjs → chunks/messages-DK6pBwD2.mjs} +0 -1
  44. package/dist/chunks/{messages-BFiMCfDX2.mjs → messages-DNrK8lCg2.mjs} +0 -1
  45. package/dist/chunks/{messages-D7fI9Pj52.mjs → messages-DQ4VyVJf2.mjs} +0 -1
  46. package/dist/{messages-BHOI7R4K.mjs → chunks/messages-DacahKek.mjs} +0 -1
  47. package/dist/chunks/{messages-Bn6LwI4B.mjs → messages-DbS9Oibb.mjs} +0 -1
  48. package/dist/chunks/{messages-Dg6kSnxq.mjs → messages-DcPtg90i.mjs} +0 -1
  49. package/dist/{messages-BpA30dPf.mjs → chunks/messages-DfTU2I8J.mjs} +0 -1
  50. package/dist/{messages-BdA_xvxj.mjs → chunks/messages-Dhe8_mnQ.mjs} +0 -1
  51. package/dist/{messages-CCKZS2f4.mjs → chunks/messages-DjOY_EqX.mjs} +0 -1
  52. package/dist/chunks/{messages-DRYKKPk8.mjs → messages-DnPkoMz1.mjs} +0 -1
  53. package/dist/chunks/{messages-B_uTiuQ-.mjs → messages-DoDbCS02.mjs} +0 -1
  54. package/dist/chunks/{messages-CRMdL0jG.mjs → messages-DotEkUpQ.mjs} +0 -1
  55. package/dist/chunks/{messages-DV5c_ZRQ.mjs → messages-Dxrg70jo.mjs} +0 -1
  56. package/dist/chunks/{messages-CwRhVVui.mjs → messages-DziA-L3p.mjs} +0 -1
  57. package/dist/{messages-CkAWTSc4.mjs → chunks/messages-IJhiftj5.mjs} +0 -1
  58. package/dist/chunks/{messages-yuqArCc6.mjs → messages-JRavIeeW.mjs} +0 -1
  59. package/dist/{messages-CERs9LC9.mjs → chunks/messages-Ul43l29K2.mjs} +0 -1
  60. package/dist/chunks/{messages-BU_YdaAf.mjs → messages-Yk__PXZQ.mjs} +0 -1
  61. package/dist/{messages-BX2KVzJp2.mjs → chunks/messages-h474TGR72.mjs} +0 -1
  62. package/dist/chunks/{messages-M8noQ6Kp2.mjs → messages-hngFJrES2.mjs} +0 -1
  63. package/dist/chunks/{messages-D0v0Xa_i2.mjs → messages-kHTrX3wo2.mjs} +0 -1
  64. package/dist/chunks/{messages-DqGQvcXv2.mjs → messages-m6bLP64R2.mjs} +0 -1
  65. package/dist/chunks/{messages-ClDJuy8K2.mjs → messages-nE9Ko73n2.mjs} +0 -1
  66. package/dist/chunks/{messages-C0ZWDShx2.mjs → messages-ni0ahgYk2.mjs} +0 -1
  67. package/dist/chunks/{messages-B7LU-b6n2.mjs → messages-pKUiAqlX2.mjs} +0 -1
  68. package/dist/{messages-BSlQrYwp.mjs → chunks/messages-rJdSnvyi.mjs} +0 -1
  69. package/dist/{messages-BrPEPj382.mjs → chunks/messages-tBHnC2Rj2.mjs} +0 -1
  70. package/dist/chunks/{messages-Cimsel4e.mjs → messages-tg78NAmW.mjs} +0 -1
  71. package/dist/{messages-CCm71gq3.mjs → chunks/messages-uLIUXFmU.mjs} +0 -1
  72. package/dist/{messages-BfgHOkAy.mjs → chunks/messages-yJmwc3zD.mjs} +0 -1
  73. package/dist/chunks/{tools-rsbC2UUN.mjs → tools-CUIpIxxP.mjs} +645 -641
  74. package/dist/full.mjs +3 -3
  75. package/dist/locales.mjs +67 -68
  76. package/dist/{chunks/messages-BhZcNoIQ.mjs → messages--XEfVx572.mjs} +0 -1
  77. package/dist/{messages-BTNuOkhL.mjs → messages-3aRjZXpv.mjs} +0 -1
  78. package/dist/{chunks/messages-JyZvGvrN.mjs → messages-6G0Eia-2.mjs} +0 -1
  79. package/dist/{messages-C3tLCwJp2.mjs → messages-B2bHgIcC2.mjs} +0 -1
  80. package/dist/{messages-aNMLsF8T2.mjs → messages-B8M4YRFO2.mjs} +0 -1
  81. package/dist/{messages-Bt_9ptDu.mjs → messages-B9qltgXa.mjs} +0 -1
  82. package/dist/{messages-CLQvtc_8.mjs → messages-BBgyeB_N.mjs} +0 -1
  83. package/dist/{messages-BigRnQS92.mjs → messages-BENRci-_2.mjs} +0 -1
  84. package/dist/{chunks/messages-DihczS7L.mjs → messages-BOxe7ewT.mjs} +0 -1
  85. package/dist/{chunks/messages-CA-jms9R.mjs → messages-BP8ZuVaD.mjs} +0 -1
  86. package/dist/{messages-DYlxQEIv.mjs → messages-BQJzUYP-.mjs} +0 -1
  87. package/dist/{chunks/messages-Cn1AC0Qk.mjs → messages-BU9luYgO.mjs} +0 -1
  88. package/dist/{messages-CYLYnOV82.mjs → messages-BZgGD0zf2.mjs} +0 -1
  89. package/dist/{messages-MBBSKGjJ2.mjs → messages-BbLCMWln2.mjs} +0 -1
  90. package/dist/{chunks/messages-elZUbCrN.mjs → messages-BdJ1lCo_.mjs} +0 -1
  91. package/dist/{chunks/messages-D3JVx_CH2.mjs → messages-Be1CCcsp2.mjs} +0 -1
  92. package/dist/{messages-D5KmRsUV2.mjs → messages-BlnZ8CkJ2.mjs} +0 -1
  93. package/dist/{messages-DDGzypb4.mjs → messages-Bsz7Qgj_.mjs} +0 -1
  94. package/dist/{messages-DdUpYaJ1.mjs → messages-Bw-GC0m5.mjs} +0 -1
  95. package/dist/{chunks/messages-FB_MePlt.mjs → messages-BwdowdYD.mjs} +0 -1
  96. package/dist/{chunks/messages-kC92TJI72.mjs → messages-BxQ1gzJF2.mjs} +0 -1
  97. package/dist/{messages-C45IBZtA2.mjs → messages-BztXgybv2.mjs} +0 -1
  98. package/dist/{chunks/messages-M0HT-kBW.mjs → messages-C0gyqo4h2.mjs} +0 -1
  99. package/dist/{messages-DhdWq5oQ2.mjs → messages-C7R0m6oE2.mjs} +0 -1
  100. package/dist/{chunks/messages-CtufKbaD.mjs → messages-C8iAUPzI.mjs} +0 -1
  101. package/dist/{messages-BaGwIHPb2.mjs → messages-CAffVeAE2.mjs} +0 -1
  102. package/dist/{messages-vssmW7KO.mjs → messages-CB0RKGVM.mjs} +0 -1
  103. package/dist/{messages-CPx1R-PH.mjs → messages-CE305J0p.mjs} +0 -1
  104. package/dist/{chunks/messages-Byp0YFMg.mjs → messages-CEhkWwqI.mjs} +0 -1
  105. package/dist/{messages-D0i5Vdyy2.mjs → messages-CJYE0_hr2.mjs} +0 -1
  106. package/dist/{messages-CYFdbooL2.mjs → messages-COU4L-pL2.mjs} +0 -1
  107. package/dist/{messages-BRPH_a6a.mjs → messages-CRMZ79Xf.mjs} +0 -1
  108. package/dist/{messages-CA0hwajz.mjs → messages-CVBsztOg.mjs} +0 -1
  109. package/dist/{messages-YfjdnhUF.mjs → messages-C_4VGaBC.mjs} +0 -1
  110. package/dist/{chunks/messages-D4jR5Oc-.mjs → messages-C_RPN2GV.mjs} +0 -1
  111. package/dist/{messages-CsM2iz1H2.mjs → messages-CaJRIGUu2.mjs} +0 -1
  112. package/dist/{messages-BeJaje7e2.mjs → messages-Cb5JJ8C_2.mjs} +0 -1
  113. package/dist/{chunks/messages-KdvbGwLH.mjs → messages-Cgy54529.mjs} +0 -1
  114. package/dist/{chunks/messages-CRdl14uE.mjs → messages-CkmVEyEQ2.mjs} +0 -1
  115. package/dist/{chunks/messages-CzCezryo.mjs → messages-CzSLUJQt.mjs} +0 -1
  116. package/dist/{chunks/messages-BWbZYIs12.mjs → messages-D6Sr5cUE.mjs} +0 -1
  117. package/dist/{messages-C0cXOCHN2.mjs → messages-DAssrN5L2.mjs} +0 -1
  118. package/dist/{messages-CYZVFnaF.mjs → messages-DB9U3VIh.mjs} +0 -1
  119. package/dist/{messages-DxKIxLKw.mjs → messages-DCOKudVN.mjs} +0 -1
  120. package/dist/{chunks/messages-DLrmLkco2.mjs → messages-DGZQXeav2.mjs} +0 -1
  121. package/dist/{chunks/messages-CqsES1wk2.mjs → messages-DZbsds_k2.mjs} +0 -1
  122. package/dist/{messages-RNusm48G2.mjs → messages-DkkrjINb2.mjs} +0 -1
  123. package/dist/{messages-DQGzw4IC.mjs → messages-DlrZrm3s.mjs} +0 -1
  124. package/dist/{messages-D-12TeCM2.mjs → messages-DpY9s4Qi2.mjs} +0 -1
  125. package/dist/{chunks/messages-BrvAiuWT.mjs → messages-DrouoDgp.mjs} +0 -1
  126. package/dist/{messages-DWZyaZNA.mjs → messages-GrVSCmXW.mjs} +0 -1
  127. package/dist/{chunks/messages-BLxyso1L.mjs → messages-K7ROT6ea.mjs} +0 -1
  128. package/dist/{chunks/messages-B3StvafX.mjs → messages-Kye1BINC.mjs} +0 -1
  129. package/dist/{chunks/messages-BdWTM73p.mjs → messages-MaHxNgKA.mjs} +0 -1
  130. package/dist/{messages-2iHnlF0U.mjs → messages-TseLyyoU.mjs} +0 -1
  131. package/dist/{chunks/messages-iWMOMK822.mjs → messages-e-KHuxtY2.mjs} +0 -1
  132. package/dist/{messages-DgstU8GH.mjs → messages-eCyczLYY.mjs} +0 -1
  133. package/dist/{messages-BFT0F9pw.mjs → messages-gldjQk7M.mjs} +0 -1
  134. package/dist/{chunks/messages-v1HkA3kF2.mjs → messages-huTzItxA.mjs} +0 -1
  135. package/dist/{messages-BEEr6Vh82.mjs → messages-m1uf_AMy2.mjs} +0 -1
  136. package/dist/{messages-Dc1yFFBM.mjs → messages-mVFAkdcY.mjs} +0 -1
  137. package/dist/{chunks/messages-tfyq1JIh2.mjs → messages-oH0ADQ362.mjs} +0 -1
  138. package/dist/{chunks/messages-Cuk0QaLM.mjs → messages-pgqtPci-.mjs} +0 -1
  139. package/dist/{messages-DuubRyFf.mjs → messages-q7HzQPVt.mjs} +0 -1
  140. package/dist/{messages-vfkwiKQo.mjs → messages-ruU_e2LK.mjs} +0 -1
  141. package/dist/{chunks/messages-Dgfbmyf-.mjs → messages-voUPclMU.mjs} +0 -1
  142. package/dist/{chunks/messages-DGodJU2R.mjs → messages-wRvz0vQ3.mjs} +0 -1
  143. package/dist/react.mjs +2 -2
  144. package/dist/tools.mjs +2 -2
  145. package/package.json +1 -1
  146. package/src/blok.ts +0 -1
  147. package/src/components/constants/data-attributes.ts +2 -0
  148. package/src/components/core.ts +1 -1
  149. package/src/components/i18n/locales/am/messages.json +0 -1
  150. package/src/components/i18n/locales/ar/messages.json +0 -1
  151. package/src/components/i18n/locales/az/messages.json +0 -1
  152. package/src/components/i18n/locales/bg/messages.json +0 -1
  153. package/src/components/i18n/locales/bn/messages.json +0 -1
  154. package/src/components/i18n/locales/bs/messages.json +0 -1
  155. package/src/components/i18n/locales/cs/messages.json +0 -1
  156. package/src/components/i18n/locales/da/messages.json +0 -1
  157. package/src/components/i18n/locales/de/messages.json +0 -1
  158. package/src/components/i18n/locales/dv/messages.json +0 -1
  159. package/src/components/i18n/locales/el/messages.json +0 -1
  160. package/src/components/i18n/locales/en/messages.json +0 -1
  161. package/src/components/i18n/locales/es/messages.json +0 -1
  162. package/src/components/i18n/locales/et/messages.json +0 -1
  163. package/src/components/i18n/locales/fa/messages.json +0 -1
  164. package/src/components/i18n/locales/fi/messages.json +0 -1
  165. package/src/components/i18n/locales/fil/messages.json +0 -1
  166. package/src/components/i18n/locales/fr/messages.json +1 -2
  167. package/src/components/i18n/locales/gu/messages.json +0 -1
  168. package/src/components/i18n/locales/he/messages.json +0 -1
  169. package/src/components/i18n/locales/hi/messages.json +0 -1
  170. package/src/components/i18n/locales/hr/messages.json +0 -1
  171. package/src/components/i18n/locales/hu/messages.json +0 -1
  172. package/src/components/i18n/locales/hy/messages.json +0 -1
  173. package/src/components/i18n/locales/id/messages.json +0 -1
  174. package/src/components/i18n/locales/it/messages.json +0 -1
  175. package/src/components/i18n/locales/ja/messages.json +0 -1
  176. package/src/components/i18n/locales/ka/messages.json +0 -1
  177. package/src/components/i18n/locales/km/messages.json +0 -1
  178. package/src/components/i18n/locales/kn/messages.json +0 -1
  179. package/src/components/i18n/locales/ko/messages.json +0 -1
  180. package/src/components/i18n/locales/ku/messages.json +0 -1
  181. package/src/components/i18n/locales/lo/messages.json +0 -1
  182. package/src/components/i18n/locales/lt/messages.json +0 -1
  183. package/src/components/i18n/locales/lv/messages.json +0 -1
  184. package/src/components/i18n/locales/mk/messages.json +0 -1
  185. package/src/components/i18n/locales/ml/messages.json +0 -1
  186. package/src/components/i18n/locales/mn/messages.json +0 -1
  187. package/src/components/i18n/locales/mr/messages.json +0 -1
  188. package/src/components/i18n/locales/ms/messages.json +0 -1
  189. package/src/components/i18n/locales/my/messages.json +0 -1
  190. package/src/components/i18n/locales/ne/messages.json +0 -1
  191. package/src/components/i18n/locales/nl/messages.json +0 -1
  192. package/src/components/i18n/locales/no/messages.json +0 -1
  193. package/src/components/i18n/locales/pa/messages.json +0 -1
  194. package/src/components/i18n/locales/pl/messages.json +0 -1
  195. package/src/components/i18n/locales/ps/messages.json +0 -1
  196. package/src/components/i18n/locales/pt/messages.json +0 -1
  197. package/src/components/i18n/locales/ro/messages.json +0 -1
  198. package/src/components/i18n/locales/ru/messages.json +0 -1
  199. package/src/components/i18n/locales/sd/messages.json +0 -1
  200. package/src/components/i18n/locales/si/messages.json +0 -1
  201. package/src/components/i18n/locales/sk/messages.json +0 -1
  202. package/src/components/i18n/locales/sl/messages.json +0 -1
  203. package/src/components/i18n/locales/sq/messages.json +0 -1
  204. package/src/components/i18n/locales/sr/messages.json +0 -1
  205. package/src/components/i18n/locales/sv/messages.json +0 -1
  206. package/src/components/i18n/locales/sw/messages.json +0 -1
  207. package/src/components/i18n/locales/ta/messages.json +0 -1
  208. package/src/components/i18n/locales/te/messages.json +0 -1
  209. package/src/components/i18n/locales/th/messages.json +0 -1
  210. package/src/components/i18n/locales/tr/messages.json +0 -1
  211. package/src/components/i18n/locales/ug/messages.json +0 -1
  212. package/src/components/i18n/locales/uk/messages.json +0 -1
  213. package/src/components/i18n/locales/ur/messages.json +0 -1
  214. package/src/components/i18n/locales/vi/messages.json +0 -1
  215. package/src/components/i18n/locales/yi/messages.json +0 -1
  216. package/src/components/i18n/locales/zh/messages.json +0 -1
  217. package/src/components/icons/index.ts +0 -16
  218. package/src/components/modules/api/index.ts +1 -1
  219. package/src/components/modules/api/theme.ts +17 -0
  220. package/src/components/modules/index.ts +8 -6
  221. package/src/components/modules/themeManager.ts +160 -0
  222. package/src/components/modules/toolbar/blockSettings.ts +12 -0
  223. package/src/components/modules/toolbar/index.ts +27 -1
  224. package/src/components/ui/toolbox.ts +3 -1
  225. package/src/components/utils/data-model-transform.ts +149 -5
  226. package/src/components/utils/popover/popover-desktop.ts +329 -44
  227. package/src/styles/main.css +1 -1
  228. package/src/tools/toggle/index.ts +14 -0
  229. package/src/types-internal/blok-modules.d.ts +6 -4
  230. package/types/api/index.d.ts +2 -1
  231. package/types/api/theme.d.ts +29 -0
  232. package/types/configs/blok-config.d.ts +10 -20
  233. package/types/index.d.ts +8 -4
  234. package/types/utils/popover/popover.d.ts +7 -0
  235. package/src/components/block-tunes/block-tune-width.ts +0 -39
  236. package/src/components/modules/api/width.ts +0 -17
  237. package/src/components/modules/widthManager.ts +0 -69
  238. package/types/api/width.d.ts +0 -19
@@ -3,7 +3,8 @@ import { Flipper } from '../../flipper';
3
3
  import { keyCodes } from '../../utils';
4
4
 
5
5
  import type { PopoverItem, PopoverItemRenderParamsMap } from './components/popover-item';
6
- import { PopoverItemSeparator, css as popoverItemCls , PopoverItemDefault } from './components/popover-item';
6
+ import { PopoverItemSeparator, css as popoverItemCls, PopoverItemDefault, PopoverItemType } from './components/popover-item';
7
+ import type { PopoverItemParams } from '@/types/utils/popover/popover-item';
7
8
  import { PopoverItemHtml } from './components/popover-item/popover-item-html/popover-item-html';
8
9
  import type { SearchableItem } from './components/search-input';
9
10
  import { SearchInput, SearchInputEvent, scoreSearchMatch } from './components/search-input';
@@ -86,6 +87,20 @@ export class PopoverDesktop extends PopoverAbstract {
86
87
  */
87
88
  private originalItemOrder: Element[] | undefined;
88
89
 
90
+ /**
91
+ * Cache of promoted items built from nested children.
92
+ * Built once on first non-empty search, destroyed on clear/hide/destroy.
93
+ */
94
+ private promotedItemCache: {
95
+ items: PopoverItemDefault[];
96
+ parentChains: Map<PopoverItemDefault, string[]>;
97
+ } | null = null;
98
+
99
+ /**
100
+ * Temporary group separator elements injected during search.
101
+ */
102
+ private promotedSeparators: HTMLElement[] = [];
103
+
89
104
  /**
90
105
  * Construct the instance
91
106
  * @param params - popover params
@@ -222,7 +237,10 @@ export class PopoverDesktop extends PopoverAbstract {
222
237
  this.nodes.popover.style.setProperty(CSSVariables.PopoverHeight, measuredSize.height + 'px');
223
238
 
224
239
  if (this.params.width === undefined || this.params.width === 'auto') {
225
- this.nodes.popover.style.setProperty('--width', measuredSize.width + 'px');
240
+ const minWidth = this.params.minWidth !== undefined ? parseFloat(this.params.minWidth) : 0;
241
+ const width = Math.max(measuredSize.width, minWidth);
242
+
243
+ this.nodes.popover.style.setProperty('--width', width + 'px');
226
244
  }
227
245
 
228
246
  if (!this.trigger && !this.shouldOpenBottom) {
@@ -321,6 +339,7 @@ export class PopoverDesktop extends PopoverAbstract {
321
339
  * Closes popover
322
340
  */
323
341
  public hide = (): void => {
342
+ this.cleanupPromotedItems();
324
343
  super.hide();
325
344
 
326
345
  this.destroyNestedPopoverIfExists();
@@ -430,6 +449,31 @@ export class PopoverDesktop extends PopoverAbstract {
430
449
  this.previouslyHoveredItem = null;
431
450
  }
432
451
 
452
+ /**
453
+ * Retrieves popover item that is the target of the specified event.
454
+ * Overridden to include promoted items from recursive search.
455
+ * @param event - event to retrieve popover item from
456
+ */
457
+ protected override getTargetItem(event: Event): PopoverItemDefault | PopoverItemHtml | undefined {
458
+ const allItems = this.promotedItemCache !== null
459
+ ? [...this.items, ...this.promotedItemCache.items]
460
+ : this.items;
461
+
462
+ return allItems
463
+ .filter((item): item is PopoverItemDefault | PopoverItemHtml =>
464
+ item instanceof PopoverItemDefault || item instanceof PopoverItemHtml
465
+ )
466
+ .find(item => {
467
+ const itemEl = item.getElement();
468
+
469
+ if (itemEl === null) {
470
+ return false;
471
+ }
472
+
473
+ return event.composedPath().includes(itemEl);
474
+ });
475
+ }
476
+
433
477
  /**
434
478
  * Sets CSS variable with position of item near which nested popover should be displayed.
435
479
  * Is used for correct positioning of the nested popover
@@ -577,7 +621,7 @@ export class PopoverDesktop extends PopoverAbstract {
577
621
  const actualPopoverEl: HTMLElement = queriedPopoverEl instanceof HTMLElement ? queriedPopoverEl : nestedPopoverEl;
578
622
 
579
623
  // Check if parent popover has openTop or openLeft state
580
- const isParentOpenTop = this.nodes.popover.hasAttribute(DATA_ATTR.popoverOpenTop);
624
+ const _isParentOpenTop = this.nodes.popover.hasAttribute(DATA_ATTR.popoverOpenTop);
581
625
  const isParentOpenLeft = this.nodes.popover.hasAttribute(DATA_ATTR.popoverOpenLeft);
582
626
 
583
627
  // Apply position: absolute for nested container
@@ -598,14 +642,8 @@ export class PopoverDesktop extends PopoverAbstract {
598
642
  actualPopoverEl.style.setProperty(CSSVariables.PopoverLeft, `calc(var(--nesting-level) * (${parentWidth} - var(--nested-popover-overlap)))`);
599
643
  }
600
644
 
601
- // Calculate top position based on parent open direction
602
- if (isParentOpenTop) {
603
- // Open upward
604
- nestedContainer.style.top = 'calc(var(--trigger-item-top) - var(--popover-height) + var(--item-height) + 0.5rem + var(--nested-popover-overlap))';
605
- } else {
606
- // Open downward
607
- nestedContainer.style.top = 'calc(var(--trigger-item-top) - var(--nested-popover-overlap))';
608
- }
645
+ // Center nested popover vertically on the trigger item
646
+ nestedContainer.style.top = 'calc(var(--trigger-item-top) - var(--popover-height) / 2 + var(--item-height) / 2)';
609
647
  }
610
648
 
611
649
  /**
@@ -732,6 +770,153 @@ export class PopoverDesktop extends PopoverAbstract {
732
770
  focusedItem?.onFocus();
733
771
  };
734
772
 
773
+ /**
774
+ * Builds cache of PopoverItemDefault instances from nested children.
775
+ * Recursively walks the item tree to arbitrary depth.
776
+ * Each cached item is mapped to its parent chain for group labeling.
777
+ */
778
+ private buildPromotedItemCache(): { items: PopoverItemDefault[]; parentChains: Map<PopoverItemDefault, string[]> } {
779
+ const cache = {
780
+ items: [] as PopoverItemDefault[],
781
+ parentChains: new Map<PopoverItemDefault, string[]>(),
782
+ };
783
+
784
+ this.collectPromotedChildren(this.items, [], cache);
785
+
786
+ return cache;
787
+ }
788
+
789
+ /**
790
+ * Recursively collects default child items from items that have children.
791
+ * @param items - items to inspect for children
792
+ * @param parentChain - ancestor label chain accumulated so far
793
+ * @param cache - mutable cache to populate
794
+ */
795
+ private collectPromotedChildren(
796
+ items: PopoverItem[],
797
+ parentChain: string[],
798
+ cache: { items: PopoverItemDefault[]; parentChains: Map<PopoverItemDefault, string[]> }
799
+ ): void {
800
+ for (const item of items) {
801
+ if (!(item instanceof PopoverItemDefault) || !item.hasChildren) {
802
+ continue;
803
+ }
804
+
805
+ const label = item.title ?? item.name ?? '';
806
+ const newChain = [...parentChain, label];
807
+
808
+ this.collectDefaultChildren(item.children, newChain, cache);
809
+ }
810
+ }
811
+
812
+ /**
813
+ * Constructs PopoverItemDefault instances from raw params and adds them to the cache.
814
+ * @param childParams - raw child item params from a parent item
815
+ * @param parentChain - ancestor label chain for this group
816
+ * @param cache - mutable cache to populate
817
+ */
818
+ private collectDefaultChildren(
819
+ childParams: PopoverItemParams[],
820
+ parentChain: string[],
821
+ cache: { items: PopoverItemDefault[]; parentChains: Map<PopoverItemDefault, string[]> }
822
+ ): void {
823
+ for (const childParam of childParams) {
824
+ if (childParam.type !== undefined && childParam.type !== PopoverItemType.Default) {
825
+ continue;
826
+ }
827
+
828
+ const childInstance = new PopoverItemDefault(childParam);
829
+
830
+ if (childInstance.name !== undefined && this.isNamePermanentlyHidden(childInstance.name)) {
831
+ childInstance.destroy();
832
+ continue;
833
+ }
834
+
835
+ cache.items.push(childInstance);
836
+ cache.parentChains.set(childInstance, parentChain);
837
+
838
+ if (childInstance.hasChildren) {
839
+ this.collectPromotedChildren([childInstance], parentChain, cache);
840
+ }
841
+ }
842
+ }
843
+
844
+ /**
845
+ * Removes promoted items and group separators from DOM and destroys cached instances.
846
+ * Idempotent — safe to call when cache is already null.
847
+ */
848
+ private cleanupPromotedItems(): void {
849
+ for (const separator of this.promotedSeparators) {
850
+ separator.remove();
851
+ }
852
+ this.promotedSeparators = [];
853
+
854
+ if (this.promotedItemCache !== null) {
855
+ for (const item of this.promotedItemCache.items) {
856
+ item.getElement()?.remove();
857
+ item.destroy();
858
+ }
859
+ this.promotedItemCache = null;
860
+ }
861
+ }
862
+
863
+ /**
864
+ * Creates a group separator element for promoted search results.
865
+ * @param label - the parent chain label (e.g., "Convert to" or "Parent › Child")
866
+ */
867
+ private createGroupSeparator(label: string): HTMLElement {
868
+ const el = document.createElement('div');
869
+
870
+ el.setAttribute(DATA_ATTR.promotedGroupLabel, '');
871
+ el.setAttribute('role', 'separator');
872
+ el.className = 'px-3 pt-2.5 pb-1 text-[11px] font-medium uppercase tracking-wide text-gray-text/50 cursor-default';
873
+ el.textContent = label;
874
+
875
+ return el;
876
+ }
877
+
878
+ /**
879
+ * Appends DOM elements for a group of promoted items to the items container.
880
+ * @param groupItems - promoted items with their scores
881
+ */
882
+ private appendPromotedGroupElements(groupItems: Array<{ item: PopoverItemDefault; score: number }>): void {
883
+ for (const { item } of groupItems) {
884
+ const el = item.getElement();
885
+
886
+ if (el !== null) {
887
+ this.nodes.items?.appendChild(el);
888
+ }
889
+ }
890
+ }
891
+
892
+ /**
893
+ * Filters out top-level items whose title duplicates a promoted item's title.
894
+ * Prevents the same entry from appearing both at the top level and under a group
895
+ * like "Convert to" during search.
896
+ * @param topLevel - top-level items matching the search query
897
+ * @param promoted - promoted items from nested children
898
+ */
899
+ private deduplicateAgainstPromoted(
900
+ topLevel: PopoverItemDefault[],
901
+ promoted: Array<{ item: PopoverItemDefault }>
902
+ ): PopoverItemDefault[] {
903
+ const promotedTitles = new Set<string>();
904
+
905
+ for (const { item } of promoted) {
906
+ if (item.title !== undefined) {
907
+ promotedTitles.add(item.title.toLowerCase());
908
+ }
909
+ }
910
+
911
+ return topLevel.filter(item => {
912
+ if (!(item instanceof PopoverItemDefault) || item.title === undefined) {
913
+ return true;
914
+ }
915
+
916
+ return !promotedTitles.has(item.title.toLowerCase());
917
+ });
918
+ }
919
+
735
920
  /**
736
921
  * Adds search to the popover
737
922
  */
@@ -741,7 +926,42 @@ export class PopoverDesktop extends PopoverAbstract {
741
926
  placeholder: this.messages.search,
742
927
  });
743
928
 
744
- this.search.on(SearchInputEvent.Search, this.onSearch);
929
+ this.search.on(SearchInputEvent.Search, (searchData: { query: string; items: SearchableItem[] }) => {
930
+ const isEmptyQuery = searchData.query === '';
931
+
932
+ if (isEmptyQuery) {
933
+ this.cleanupPromotedItems();
934
+ this.onSearch({
935
+ query: searchData.query,
936
+ topLevelItems: searchData.items as unknown as PopoverItemDefault[],
937
+ promotedItems: [],
938
+ });
939
+
940
+ return;
941
+ }
942
+
943
+ // Build cache on first non-empty search
944
+ if (this.promotedItemCache === null) {
945
+ this.promotedItemCache = this.buildPromotedItemCache();
946
+ }
947
+
948
+ // Score promoted items against the query
949
+ const { parentChains } = this.promotedItemCache;
950
+ const promotedScored = this.promotedItemCache.items
951
+ .map(item => ({
952
+ item,
953
+ score: scoreSearchMatch(item, searchData.query),
954
+ chain: parentChains.get(item) ?? [],
955
+ }))
956
+ .filter(({ score }) => score > 0)
957
+ .sort((a, b) => b.score - a.score);
958
+
959
+ this.onSearch({
960
+ query: searchData.query,
961
+ topLevelItems: searchData.items as unknown as PopoverItemDefault[],
962
+ promotedItems: promotedScored,
963
+ });
964
+ });
745
965
 
746
966
  const searchElement = this.search.getElement();
747
967
 
@@ -757,45 +977,66 @@ export class PopoverDesktop extends PopoverAbstract {
757
977
  */
758
978
  public override filterItems(query: string): void {
759
979
  if (query === '') {
980
+ this.cleanupPromotedItems();
760
981
  this.onSearch({
761
982
  query,
762
- items: this.itemsDefault as unknown as SearchableItem[],
983
+ topLevelItems: this.itemsDefault,
984
+ promotedItems: [],
763
985
  });
764
986
 
765
987
  return;
766
988
  }
767
989
 
768
- const scoredItems = this.itemsDefault
990
+ // Build cache on first non-empty search
991
+ if (this.promotedItemCache === null) {
992
+ this.promotedItemCache = this.buildPromotedItemCache();
993
+ }
994
+
995
+ // Score top-level items
996
+ const topLevelScored = this.itemsDefault
769
997
  .map(item => ({ item, score: scoreSearchMatch(item, query) }))
770
998
  .filter(({ score }) => score > 0)
771
999
  .sort((a, b) => b.score - a.score);
772
1000
 
773
- const matchingItems = scoredItems.map(({ item }) => item);
1001
+ // Score promoted items from cache
1002
+ const { parentChains: chains } = this.promotedItemCache;
1003
+ const promotedScored = this.promotedItemCache.items
1004
+ .map(item => ({
1005
+ item,
1006
+ score: scoreSearchMatch(item, query),
1007
+ chain: chains.get(item) ?? [],
1008
+ }))
1009
+ .filter(({ score }) => score > 0)
1010
+ .sort((a, b) => b.score - a.score);
774
1011
 
775
1012
  this.onSearch({
776
1013
  query,
777
- items: matchingItems as unknown as SearchableItem[],
1014
+ topLevelItems: topLevelScored.map(({ item }) => item),
1015
+ promotedItems: promotedScored,
778
1016
  });
779
1017
  }
780
1018
 
781
1019
  /**
782
- * Handles input inside search field
783
- * @param data - search input event data
784
- * @param data.query - search query text
785
- * @param data.items - search results
1020
+ * Handles search results from both filterItems and SearchInput.
1021
+ * Renders top-level matches and promoted children with group separators.
786
1022
  */
787
- private onSearch = (data: { query: string, items: SearchableItem[] }): void => {
1023
+ private onSearch = (data: {
1024
+ query: string;
1025
+ topLevelItems: PopoverItemDefault[] | SearchableItem[];
1026
+ promotedItems: Array<{ item: PopoverItemDefault; score: number; chain: string[] }>;
1027
+ }): void => {
788
1028
  const isEmptyQuery = data.query === '';
789
- const isNothingFound = data.items.length === 0;
1029
+ const allTopLevel = data.topLevelItems as unknown as PopoverItemDefault[];
1030
+
1031
+ // Deduplicate: hide top-level items whose title matches a promoted item
1032
+ const matchingTopLevel = !isEmptyQuery && data.promotedItems.length > 0
1033
+ ? this.deduplicateAgainstPromoted(allTopLevel, data.promotedItems)
1034
+ : allTopLevel;
790
1035
 
791
- // Cast data.items to PopoverItemDefault[] since we know that's what filterItems passes
792
- const matchingItems = data.items as unknown as PopoverItemDefault[];
1036
+ const isNothingFound = matchingTopLevel.length === 0 && data.promotedItems.length === 0;
793
1037
 
794
1038
  /**
795
1039
  * When nothing is found, disable transitions so items hide instantly.
796
- * The "Nothing found" message fade-in provides the visual transition;
797
- * animating the last items' collapse simultaneously causes a jarring
798
- * height bounce in the popover container.
799
1040
  */
800
1041
  if (isNothingFound) {
801
1042
  this.items.forEach(item => {
@@ -808,48 +1049,92 @@ export class PopoverDesktop extends PopoverAbstract {
808
1049
  const isDefaultItem = item instanceof PopoverItemDefault;
809
1050
  const isSeparatorOrHtml = item instanceof PopoverItemSeparator || item instanceof PopoverItemHtml;
810
1051
  const isHidden = isDefaultItem
811
- ? !matchingItems.includes(item) || (item.name !== undefined && this.isNamePermanentlyHidden(item.name))
1052
+ ? !matchingTopLevel.includes(item) || (item.name !== undefined && this.isNamePermanentlyHidden(item.name))
812
1053
  : isSeparatorOrHtml && (isNothingFound || !isEmptyQuery);
813
1054
 
814
1055
  item.toggleHidden(isHidden);
815
1056
  });
816
1057
 
817
1058
  if (isNothingFound) {
818
- // Force reflow so the instant hide takes effect, then restore transitions
819
1059
  this.nodes.popoverContainer.offsetHeight;
820
1060
  this.items.forEach(item => {
821
1061
  item.getElement()?.style.removeProperty('transition-duration');
822
1062
  });
823
1063
  }
824
1064
 
825
- // Reorder DOM elements to reflect ranking
826
- if (!isEmptyQuery && matchingItems.length > 0) {
827
- this.reorderItemsByRank(matchingItems);
1065
+ // Reorder top-level DOM elements to reflect ranking
1066
+ if (!isEmptyQuery && matchingTopLevel.length > 0) {
1067
+ this.reorderItemsByRank(matchingTopLevel);
828
1068
  } else if (isEmptyQuery && this.originalItemOrder !== undefined) {
829
1069
  this.restoreOriginalItemOrder();
830
1070
  }
831
1071
 
1072
+ // Detach previous promoted elements from DOM (don't destroy cache)
1073
+ for (const separator of this.promotedSeparators) {
1074
+ separator.remove();
1075
+ }
1076
+ this.promotedSeparators = [];
1077
+
1078
+ if (this.promotedItemCache !== null) {
1079
+ for (const item of this.promotedItemCache.items) {
1080
+ item.getElement()?.remove();
1081
+ }
1082
+ }
1083
+
1084
+ // Render promoted items grouped by parent chain
1085
+ if (data.promotedItems.length > 0) {
1086
+ const groups = new Map<string, Array<{ item: PopoverItemDefault; score: number }>>();
1087
+
1088
+ for (const entry of data.promotedItems) {
1089
+ const label = entry.chain.join(' \u203A ');
1090
+ const existing = groups.get(label);
1091
+
1092
+ if (existing !== undefined) {
1093
+ existing.push({ item: entry.item, score: entry.score });
1094
+ } else {
1095
+ groups.set(label, [{ item: entry.item, score: entry.score }]);
1096
+ }
1097
+ }
1098
+
1099
+ // Sort groups by best score in each group
1100
+ const sortedGroups = [...groups.entries()].sort((a, b) => {
1101
+ const bestA = Math.max(...a[1].map(e => e.score));
1102
+ const bestB = Math.max(...b[1].map(e => e.score));
1103
+
1104
+ return bestB - bestA;
1105
+ });
1106
+
1107
+ for (const [label, groupItems] of sortedGroups) {
1108
+ const separator = this.createGroupSeparator(label);
1109
+
1110
+ this.promotedSeparators.push(separator);
1111
+ this.nodes.items?.appendChild(separator);
1112
+
1113
+ this.appendPromotedGroupElements(groupItems);
1114
+ }
1115
+ }
1116
+
832
1117
  this.toggleNothingFoundMessage(isNothingFound);
833
1118
 
834
- /** List of elements available for keyboard navigation considering search query applied */
835
- const flippableElements = isEmptyQuery ? this.flippableElements : data.items.map(item => (item as PopoverItem).getElement());
1119
+ // Build flippable elements list: top-level matches + promoted items
1120
+ const topLevelFlippable = isEmptyQuery
1121
+ ? this.flippableElements
1122
+ : matchingTopLevel.map(item => item.getElement());
1123
+
1124
+ const promotedFlippable = data.promotedItems.map(({ item }) => item.getElement());
1125
+
1126
+ const flippableElements = [
1127
+ ...topLevelFlippable,
1128
+ ...promotedFlippable,
1129
+ ].filter((el): el is HTMLElement => el !== null);
836
1130
 
837
1131
  if (!this.flipper?.isActivated) {
838
1132
  return;
839
1133
  }
840
1134
 
841
- /** Update flipper items with only visible */
842
1135
  this.flipper.deactivate();
843
- this.flipper.activate(flippableElements as HTMLElement[]);
1136
+ this.flipper.activate(flippableElements);
844
1137
 
845
- /**
846
- * Focus first item after filtering.
847
- * Always skip the first Tab press so it just "enters" the menu rather than
848
- * advancing to second item. This applies regardless of whether the query is
849
- * empty (initial "/" open) or non-empty (user is typing to filter), because
850
- * the user's keyboard focus is still in the search input - pressing Tab
851
- * should enter the list at item 0, not advance from 0 to 1.
852
- */
853
1138
  if (flippableElements.length > 0) {
854
1139
  this.flipper.focusItem(0, { skipNextTab: true });
855
1140
  }
@@ -642,7 +642,7 @@
642
642
 
643
643
  @layer utilities {
644
644
  .max-w-blok-content {
645
- max-width: var(--blok-content-width, var(--max-width-content));
645
+ max-width: var(--max-width-content);
646
646
  }
647
647
  }
648
648
 
@@ -74,6 +74,20 @@ export class ToggleItem implements BlockTool {
74
74
  return normalized;
75
75
  }
76
76
 
77
+ // Handle legacy toggleList format: { title, isExpanded }
78
+ if (typeof data === 'object' && data !== null && 'title' in data) {
79
+ const legacyData = data as Record<string, unknown>;
80
+ const normalized: ToggleItemData = {
81
+ text: typeof legacyData.title === 'string' ? legacyData.title : '',
82
+ };
83
+
84
+ if (typeof legacyData.isExpanded === 'boolean') {
85
+ normalized.isOpen = legacyData.isExpanded;
86
+ }
87
+
88
+ return normalized;
89
+ }
90
+
77
91
  return { text: '' };
78
92
  }
79
93
 
@@ -16,7 +16,8 @@ import { StylesAPI } from '../components/modules/api/styles';
16
16
  import { ToolbarAPI } from '../components/modules/api/toolbar';
17
17
  import { TooltipAPI } from '../components/modules/api/tooltip';
18
18
  import { UiAPI } from '../components/modules/api/ui';
19
- import { WidthAPI } from '../components/modules/api/width';
19
+
20
+ import { ThemeAPI } from '../components/modules/api/theme';
20
21
  /** ./toolbar */
21
22
  import { BlockSettings } from '../components/modules/toolbar/blockSettings';
22
23
  import { Toolbar } from '../components/modules/toolbar/index';
@@ -39,7 +40,8 @@ import { Tools } from '../components/modules/tools';
39
40
  import { UI } from '../components/modules/ui';
40
41
  import { ToolsAPI } from '../components/modules/api/tools';
41
42
  import { I18n } from '../components/modules/i18n';
42
- import { WidthManager } from '../components/modules/widthManager';
43
+
44
+ import { ThemeManager } from '../components/modules/themeManager';
43
45
  import { YjsManager } from '../components/modules/yjs';
44
46
 
45
47
  export interface BlokModules {
@@ -62,7 +64,7 @@ export interface BlokModules {
62
64
  ToolbarAPI: ToolbarAPI,
63
65
  TooltipAPI: TooltipAPI,
64
66
  UiAPI: UiAPI,
65
- WidthAPI: WidthAPI,
67
+ ThemeAPI: ThemeAPI,
66
68
 
67
69
  // Toolbar Modules
68
70
  BlockSettings: BlockSettings,
@@ -85,6 +87,6 @@ export interface BlokModules {
85
87
  Saver: Saver,
86
88
  Tools: Tools,
87
89
  UI: UI,
88
- WidthManager: WidthManager,
90
+ ThemeManager: ThemeManager,
89
91
  YjsManager: YjsManager,
90
92
  }
@@ -16,4 +16,5 @@ export * from './readonly';
16
16
  export * from './i18n';
17
17
  export * from './ui';
18
18
  export * from './tools';
19
- export * from './width';
19
+
20
+ export * from './theme';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Theme mode set by the user.
3
+ */
4
+ export type ThemeMode = 'dark' | 'light' | 'auto';
5
+
6
+ /**
7
+ * Resolved theme after evaluating OS preference (for 'auto' mode).
8
+ */
9
+ export type ResolvedTheme = 'dark' | 'light';
10
+
11
+ /**
12
+ * Describes the theme API.
13
+ */
14
+ export interface Theme {
15
+ /**
16
+ * Returns the current theme mode.
17
+ */
18
+ get(): ThemeMode;
19
+
20
+ /**
21
+ * Sets the theme mode.
22
+ */
23
+ set(mode: ThemeMode): void;
24
+
25
+ /**
26
+ * Returns the resolved theme ('dark' or 'light'), evaluating OS preference if mode is 'auto'.
27
+ */
28
+ getResolved(): ResolvedTheme;
29
+ }
@@ -1,3 +1,4 @@
1
+ import type { ThemeMode, ResolvedTheme } from '../api/theme';
1
2
  import {ToolConstructable, ToolSettings} from '../tools';
2
3
  import {API, LogLevels, OutputData} from '../index';
3
4
  import {SanitizerConfig} from './sanitizer-config';
@@ -162,28 +163,17 @@ export interface BlokConfig {
162
163
  }
163
164
 
164
165
  /**
165
- * Initial width mode. Defaults to 'narrow'.
166
+ * Color theme mode.
167
+ * - 'auto': follow OS preference via prefers-color-scheme (default)
168
+ * - 'light': force light theme
169
+ * - 'dark': force dark theme
166
170
  */
167
- defaultWidth?: 'narrow' | 'full';
171
+ theme?: ThemeMode;
168
172
 
169
173
  /**
170
- * CSS max-width value for narrow mode.
171
- * Any valid CSS length (e.g. '650px', '800px', '60ch').
172
- * Defaults to '650px'.
174
+ * Called when the resolved theme changes (e.g. OS preference switches in 'auto' mode).
175
+ * Does not fire on initialization only on subsequent changes.
176
+ * @param resolvedTheme - the resolved theme ('dark' or 'light')
173
177
  */
174
- narrowWidth?: string;
175
-
176
- /**
177
- * CSS max-width value for full width mode.
178
- * Any valid CSS length, or 'none' for no constraint.
179
- * Defaults to 'none'.
180
- */
181
- fullWidth?: string;
182
-
183
- /**
184
- * Called when the editor width mode changes.
185
- * @param mode - the new mode ('narrow' or 'full')
186
- * @param value - the resolved CSS max-width value
187
- */
188
- onWidthChange?: (mode: 'narrow' | 'full', value: string) => void;
178
+ onThemeChange?: (resolvedTheme: ResolvedTheme) => void;
189
179
  }
package/types/index.d.ts CHANGED
@@ -30,7 +30,9 @@ import {
30
30
  I18n,
31
31
  Ui,
32
32
  Tools,
33
- Width,
33
+ Theme,
34
+ ThemeMode,
35
+ ResolvedTheme,
34
36
  } from './api';
35
37
 
36
38
  import { OutputData } from './data-formats';
@@ -106,7 +108,9 @@ export {
106
108
  I18n,
107
109
  Ui,
108
110
  Tools,
109
- Width,
111
+ Theme,
112
+ ThemeMode,
113
+ ResolvedTheme,
110
114
  } from './api';
111
115
  export {
112
116
  BlockMutationType,
@@ -144,7 +148,7 @@ export interface API {
144
148
  i18n: I18n;
145
149
  readOnly: ReadOnly;
146
150
  ui: Ui;
147
- width: Width;
151
+ theme: Theme;
148
152
  rectangleSelection: {
149
153
  cancelActiveSelection: () => void;
150
154
  isRectActivated: () => boolean;
@@ -179,7 +183,7 @@ export class Blok {
179
183
  public inlineToolbar: InlineToolbar;
180
184
  public tooltip: Tooltip;
181
185
  public readOnly: ReadOnly;
182
- public width: Width;
186
+ public theme: Theme;
183
187
  constructor(configuration?: BlokConfig|string);
184
188
 
185
189
  /**