@jackuait/blok 0.13.2 → 0.14.0
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/dist/blok.cjs +1 -1
- package/dist/blok.iife.js +30 -30
- package/dist/blok.mjs +2 -2
- package/dist/chunks/blok-Da-GaWJ8.cjs +17 -0
- package/dist/chunks/{blok-Du6vYONn.mjs → blok-PpFnlqXZ.mjs} +2722 -2322
- package/dist/chunks/constants-C-OQpSwB.cjs +457 -0
- package/dist/chunks/{constants-DUuYY64n.mjs → constants-DdfiMdC1.mjs} +390 -299
- package/dist/chunks/{i18next-loader-GIrBCFrC.mjs → i18next-loader-BEWWek8j.mjs} +1 -1
- package/dist/chunks/{i18next-loader-DC1uN-wc.cjs → i18next-loader-BRLYf-CW.cjs} +1 -1
- package/dist/chunks/{lightweight-i18n-DF9Pupws.mjs → lightweight-i18n-GbzxWVgl.mjs} +9 -0
- package/dist/chunks/lightweight-i18n-lNYVKCfj.cjs +1 -0
- package/dist/chunks/messages-085GG-gT.cjs +1 -0
- package/dist/{messages-3j4yi-DF.mjs → chunks/messages-46QopBh4.mjs} +9 -0
- package/dist/chunks/messages-5kQujjf1.cjs +1 -0
- package/dist/chunks/{messages-CTWXEx_o.mjs → messages-6r3Lrqpf.mjs} +9 -0
- package/dist/chunks/messages-8vjbwhvK.cjs +1 -0
- package/dist/chunks/messages-ACbZDExx.cjs +1 -0
- package/dist/chunks/messages-B05XREvI.cjs +1 -0
- package/dist/chunks/{messages-CQg2_vmm.mjs → messages-B0y97-C9.mjs} +9 -0
- package/dist/chunks/{messages-ZHNvKiIX.mjs → messages-B26pkAIj.mjs} +9 -0
- package/dist/chunks/messages-B2J7kDKI.cjs +1 -0
- package/dist/chunks/messages-B3jMjjFG.cjs +1 -0
- package/dist/chunks/messages-B4_c-uS0.cjs +1 -0
- package/dist/chunks/messages-B6zoVYEd.cjs +1 -0
- package/dist/chunks/{messages-DI9Ifrgt.mjs → messages-B73uch0z.mjs} +9 -0
- package/dist/chunks/{messages-AgmrT2Id.mjs → messages-B74xK8Ux.mjs} +9 -0
- package/dist/chunks/messages-B7efcz_S2.cjs +1 -0
- package/dist/chunks/{messages-sqdfYuVj2.mjs → messages-B9u3UJRu2.mjs} +9 -0
- package/dist/chunks/messages-BB9huoLU.cjs +1 -0
- package/dist/{messages-Cx7sqvx02.mjs → chunks/messages-BEzCtzW3.mjs} +9 -0
- package/dist/chunks/messages-BGQdk2zV2.cjs +1 -0
- package/dist/chunks/messages-BGmUrVtN2.cjs +1 -0
- package/dist/chunks/messages-BH-3FR4b2.cjs +1 -0
- package/dist/chunks/{messages-BZ4d5yNH.mjs → messages-BHqAQF6C.mjs} +9 -0
- package/dist/{messages-DzkZ434Z.mjs → chunks/messages-BI_-Ub99.mjs} +9 -0
- package/dist/chunks/messages-BNa6_BYq2.cjs +1 -0
- package/dist/chunks/{messages-BvupGuDw2.mjs → messages-BOMNOs8T2.mjs} +9 -0
- package/dist/chunks/{messages-fSeXd6-z.mjs → messages-BPYPnKHy.mjs} +9 -0
- package/dist/{messages-B3PWaMcw.mjs → chunks/messages-BQmUOeft.mjs} +9 -0
- package/dist/chunks/messages-BRfutnCs.cjs +1 -0
- package/dist/chunks/messages-BT_0dgL1.cjs +1 -0
- package/dist/chunks/{messages-BWGqOZ9J.mjs → messages-BWSXW4jk.mjs} +9 -0
- package/dist/chunks/messages-BWpKvkND2.cjs +1 -0
- package/dist/chunks/messages-BY6gCAsA2.cjs +1 -0
- package/dist/{messages-BDwU9rYR2.mjs → chunks/messages-BbfZo0kw2.mjs} +9 -0
- package/dist/{messages-gQ5PFa2t2.mjs → chunks/messages-BfqzgRP72.mjs} +9 -0
- package/dist/chunks/messages-Bk2Xs7_v.cjs +1 -0
- package/dist/{messages-CmN2OfuB.mjs → chunks/messages-BmkavfpK.mjs} +9 -0
- package/dist/chunks/{messages-B1k4DgVe.mjs → messages-BmzMikmq.mjs} +9 -0
- package/dist/chunks/messages-BniEGAW32.cjs +1 -0
- package/dist/chunks/{messages-BP77P9ER.mjs → messages-BplwYBhA.mjs} +9 -0
- package/dist/chunks/{messages-B1xgsCNQ.cjs → messages-BqJ-xe8R.cjs} +1 -1
- package/dist/chunks/messages-Bry43U_U.cjs +1 -0
- package/dist/{messages-DFfhoDWZ2.mjs → chunks/messages-BuzGjYKw.mjs} +9 -0
- package/dist/chunks/messages-ByT63R7v2.cjs +1 -0
- package/dist/{messages-C_gdsU952.mjs → chunks/messages-C0S7KViA2.mjs} +9 -0
- package/dist/chunks/{messages-DzY53I67.mjs → messages-C0Tt7Odx.mjs} +9 -0
- package/dist/{messages-B8Tq9Txy.mjs → chunks/messages-C3A1iLjY.mjs} +9 -0
- package/dist/chunks/{messages-B6You-RA.mjs → messages-C3gh1rpr.mjs} +9 -0
- package/dist/chunks/{messages-CXxz5HYQ.mjs → messages-C7JE4SUS.mjs} +9 -0
- package/dist/chunks/messages-C9IWDnCh2.cjs +1 -0
- package/dist/chunks/messages-CBc3S61g2.cjs +1 -0
- package/dist/chunks/{messages-DefZ3ihx.mjs → messages-CHpkDOiI.mjs} +9 -0
- package/dist/{messages-BcD7xtJA.mjs → chunks/messages-CImQCp-z2.mjs} +9 -0
- package/dist/chunks/messages-CJ--z80t2.cjs +1 -0
- package/dist/chunks/messages-CNH8YFuv.cjs +1 -0
- package/dist/chunks/{messages-bjSJwsXK2.mjs → messages-CQ2KWTbV2.mjs} +9 -0
- package/dist/{messages-C8RMjnBe.mjs → chunks/messages-CWAukiLC.mjs} +9 -0
- package/dist/{messages-B3oFjWq3.mjs → chunks/messages-C_BUhMkZ.mjs} +9 -0
- package/dist/chunks/{messages-BvuEffoe.mjs → messages-CcBT1o1B.mjs} +9 -0
- package/dist/chunks/messages-CdqejEof.cjs +1 -0
- package/dist/chunks/messages-Chdejshy2.cjs +1 -0
- package/dist/{messages-D-rvoUSJ.mjs → chunks/messages-CijMg_B_.mjs} +9 -0
- package/dist/{messages-JKXCsFKZ.mjs → chunks/messages-Ciz80Z2u2.mjs} +9 -0
- package/dist/{messages-Dq2WEsEu.mjs → chunks/messages-CjuGKMoT.mjs} +9 -0
- package/dist/chunks/{messages-BxKobpJ22.mjs → messages-ClOfUECP2.mjs} +9 -0
- package/dist/chunks/messages-CrF-Q_ML.cjs +1 -0
- package/dist/chunks/messages-Cww_rBCM.cjs +1 -0
- package/dist/chunks/messages-CxPVYl2H2.cjs +1 -0
- package/dist/chunks/{messages-BA2sVGrR2.mjs → messages-Cyiqo_dk2.mjs} +9 -0
- package/dist/{messages-D788KtGe.mjs → chunks/messages-D-u_SWhb.mjs} +9 -0
- package/dist/chunks/messages-D0H-D5FQ2.cjs +1 -0
- package/dist/chunks/messages-D195RH3A.cjs +1 -0
- package/dist/chunks/{messages-Dd4nzvLj2.mjs → messages-D5-DG-_u2.mjs} +9 -0
- package/dist/chunks/messages-D6kDQgDP2.cjs +1 -0
- package/dist/{messages-CAGQtm7T.mjs → chunks/messages-D8-hiQgf.mjs} +9 -0
- package/dist/{messages-ftPYsH6d2.mjs → chunks/messages-D8nb9CKr2.mjs} +9 -0
- package/dist/{messages-DPqFBtJR.mjs → chunks/messages-DAd5yWtH2.mjs} +9 -0
- package/dist/chunks/messages-DAdsFLpE.cjs +1 -0
- package/dist/chunks/messages-DCUsbiUQ.cjs +1 -0
- package/dist/{messages-AycxTjmw.mjs → chunks/messages-DCVZaAT9.mjs} +9 -0
- package/dist/chunks/messages-DHXttezt2.cjs +1 -0
- package/dist/chunks/messages-DIgxCixa.cjs +1 -0
- package/dist/chunks/messages-DJ0Wr-Bt2.cjs +1 -0
- package/dist/chunks/messages-DJBdlmxR.cjs +1 -0
- package/dist/chunks/{messages-5AxgjKgf2.mjs → messages-DJm-uLwr2.mjs} +9 -0
- package/dist/chunks/{messages-BVarbXYD2.mjs → messages-DKF4qWhw2.mjs} +9 -0
- package/dist/chunks/messages-DLAWSVlE.cjs +1 -0
- package/dist/{messages-Bj03XD-02.mjs → chunks/messages-DLI8m6z_2.mjs} +9 -0
- package/dist/{messages-CTzO11jz.mjs → chunks/messages-DNiWBVQr.mjs} +9 -0
- package/dist/chunks/messages-DNsgR3ZH.cjs +1 -0
- package/dist/{messages-CgaGkQi32.mjs → chunks/messages-DPI5-TrO2.mjs} +9 -0
- package/dist/chunks/{messages-CyCl8la6.mjs → messages-DQ1z_srP.mjs} +9 -0
- package/dist/chunks/{messages-C4bHKGnB2.mjs → messages-DSxYO-_j2.mjs} +9 -0
- package/dist/chunks/messages-DTrrEqf02.cjs +1 -0
- package/dist/chunks/{messages-D7YPlNAK.mjs → messages-DYLfoakZ.mjs} +9 -0
- package/dist/chunks/messages-DZCWq8nI2.cjs +1 -0
- package/dist/{messages-PQVh93mt.mjs → chunks/messages-D_JT9POv.mjs} +9 -0
- package/dist/chunks/{messages-Uc3Uc2862.mjs → messages-DaTniq4w2.mjs} +9 -0
- package/dist/{messages-DiL61awK.mjs → chunks/messages-De2tXe0o.mjs} +9 -0
- package/dist/chunks/{messages-l5xHQb_m.mjs → messages-DiwyN3uU.mjs} +9 -0
- package/dist/chunks/messages-DkQGwmom.cjs +1 -0
- package/dist/chunks/{messages-B6t1xShv.mjs → messages-Dl-C7Pdf.mjs} +9 -0
- package/dist/chunks/{messages-bSVgJ1cu.mjs → messages-DlDyYt5x.mjs} +9 -0
- package/dist/chunks/messages-Dmhwr_Ow2.cjs +1 -0
- package/dist/chunks/messages-DrQQ1Hky.cjs +1 -0
- package/dist/chunks/messages-DtQ_pCWn.cjs +1 -0
- package/dist/{messages-uy3FE24_2.mjs → chunks/messages-Du-inLpi2.mjs} +9 -0
- package/dist/{messages-DqXJJPx9.mjs → chunks/messages-Duu9LiF32.mjs} +9 -0
- package/dist/chunks/messages-DxCc14pu2.cjs +1 -0
- package/dist/chunks/{messages-DNqFlfOd.mjs → messages-Dz3cVqxu.mjs} +9 -0
- package/dist/chunks/messages-EJkYSgsP.cjs +1 -0
- package/dist/chunks/messages-F3QeKduK.cjs +1 -0
- package/dist/chunks/messages-HfCZ1oPV.cjs +1 -0
- package/dist/chunks/{messages-BVZONUH9.mjs → messages-Ji3WDjrp.mjs} +9 -0
- package/dist/chunks/messages-MTnjMh07.cjs +1 -0
- package/dist/{messages-DL7JAwpC.mjs → chunks/messages-NU3n_1t9.mjs} +9 -0
- package/dist/chunks/messages-NpCBoXqi.cjs +1 -0
- package/dist/chunks/messages-PMZIH3mH.cjs +1 -0
- package/dist/{messages-7fwJIrld2.mjs → chunks/messages-TFu4tdzc2.mjs} +9 -0
- package/dist/{messages-BSHFypGE2.mjs → chunks/messages-Ti4ZdnqM2.mjs} +9 -0
- package/dist/chunks/messages-UOTfsDv3.cjs +1 -0
- package/dist/chunks/messages-WDBEGpNu.cjs +1 -0
- package/dist/chunks/messages-Zg6PFQ87.cjs +1 -0
- package/dist/chunks/messages-bdVhFVzt2.cjs +1 -0
- package/dist/chunks/messages-dnnjc_oR2.cjs +1 -0
- package/dist/{messages-BmWP4vpV2.mjs → chunks/messages-fI_5bRwV2.mjs} +9 -0
- package/dist/{messages-CIjSE2_O2.mjs → chunks/messages-g80Luov_2.mjs} +9 -0
- package/dist/chunks/messages-hlzAtKI5.cjs +1 -0
- package/dist/chunks/messages-kuh4lSUE2.cjs +1 -0
- package/dist/chunks/messages-m20Eebmt2.cjs +1 -0
- package/dist/chunks/messages-o1__8Rul.cjs +1 -0
- package/dist/chunks/messages-pBYvH88_.cjs +1 -0
- package/dist/chunks/{messages-CMRjQYxi2.mjs → messages-u1hpTCvK2.mjs} +9 -0
- package/dist/chunks/{messages-BoCUgrkI.mjs → messages-vq5ZvFTF.mjs} +9 -0
- package/dist/chunks/tools-DeTgjuIK.cjs +116 -0
- package/dist/chunks/{tools-Tt-NXbRZ.mjs → tools-omGeunql.mjs} +1818 -1686
- package/dist/full.cjs +1 -1
- package/dist/full.mjs +8 -8
- package/dist/locales.mjs +76 -67
- package/dist/{chunks/messages-DHdoaaFq2.mjs → messages-2hSOMnir2.mjs} +9 -0
- package/dist/{chunks/messages-DlcI-0Sy.mjs → messages-3VCxXECx.mjs} +9 -0
- package/dist/{messages-CxX23Jsk2.mjs → messages-8xGEIh_m2.mjs} +9 -0
- package/dist/{chunks/messages-DmErSGPk2.mjs → messages-B-QcHnuI2.mjs} +9 -0
- package/dist/{messages-BKCuCTFM.mjs → messages-B8zoeMf9.mjs} +9 -0
- package/dist/{chunks/messages-BmdkDNYv.mjs → messages-B9CF0GcE.mjs} +9 -0
- package/dist/{messages-1ufJbdRv2.mjs → messages-B9W0pRCr2.mjs} +9 -0
- package/dist/{messages-DQik3_xv2.mjs → messages-BFM2ljkf2.mjs} +9 -0
- package/dist/{chunks/messages-BNxTGhHu.mjs → messages-BLm4FSbz2.mjs} +9 -0
- package/dist/{chunks/messages-GHsufIGi2.mjs → messages-BLpeYPKv2.mjs} +9 -0
- package/dist/{messages-D_WzyzUt.mjs → messages-BM73sjxy.mjs} +9 -0
- package/dist/{messages-CX8egsiA2.mjs → messages-BOpqKi6Y2.mjs} +9 -0
- package/dist/{chunks/messages-eyGOcbhV.mjs → messages-BUGdUeTK.mjs} +9 -0
- package/dist/{chunks/messages-DhZwMl9x2.mjs → messages-BZm7MzSJ2.mjs} +9 -0
- package/dist/{messages-C31VIrlL.mjs → messages-BtBhP1sv.mjs} +9 -0
- package/dist/{messages-D1Fjr4OK2.mjs → messages-BthFu3bN2.mjs} +9 -0
- package/dist/{chunks/messages-COMdnGQV2.mjs → messages-BurjwjCQ2.mjs} +9 -0
- package/dist/{messages-DTkd9ND8.mjs → messages-ByIHkus-.mjs} +9 -0
- package/dist/{messages-C9GFRcVj.mjs → messages-ByVKFMH3.mjs} +9 -0
- package/dist/{chunks/messages-B5CFhyI8.mjs → messages-C6FDRqcf.mjs} +9 -0
- package/dist/{chunks/messages-OSIAf0Wk2.mjs → messages-C9dJ_N542.mjs} +9 -0
- package/dist/{messages-CRR1VRO6.mjs → messages-CCw8aJgW.mjs} +9 -0
- package/dist/{chunks/messages-AtUsRyWK2.mjs → messages-CO3NEwf22.mjs} +9 -0
- package/dist/{chunks/messages-CcboYTP8.mjs → messages-CPB2xkpC.mjs} +9 -0
- package/dist/{messages-CITYhXUz.mjs → messages-CPDsEORY.mjs} +9 -0
- package/dist/{chunks/messages-B2zrJyAc2.mjs → messages-CYyPOGy7.mjs} +9 -0
- package/dist/{chunks/messages-C03LZxma.mjs → messages-CZAODRjY.mjs} +9 -0
- package/dist/{messages-Duk7VVeY.mjs → messages-C_rns7Ku.mjs} +9 -0
- package/dist/{chunks/messages-CdWXgq_r.mjs → messages-CaUUIQvU.mjs} +9 -0
- package/dist/{messages-Cp0fjsey.mjs → messages-Cc-A7Vip.mjs} +9 -0
- package/dist/{chunks/messages-B7KbtBAE.mjs → messages-Ccf81JsG.mjs} +9 -0
- package/dist/{chunks/messages-rEsI_fAk.mjs → messages-CerTDuSC.mjs} +9 -0
- package/dist/{messages-BkTBwYet.mjs → messages-CgmDwRRE.mjs} +9 -0
- package/dist/{chunks/messages-DsyO86r3.mjs → messages-Cn3PWtLp.mjs} +9 -0
- package/dist/{chunks/messages-CWTFEPbA2.mjs → messages-Cu1rTEkB.mjs} +9 -0
- package/dist/{messages-oIa8wahx.mjs → messages-CxEHfUNH.mjs} +9 -0
- package/dist/{messages-C_mN4lx0.mjs → messages-D1B41i8X.mjs} +9 -0
- package/dist/{messages-NVepzgE3.mjs → messages-D6954zcl.mjs} +9 -0
- package/dist/{messages-C2TRJroV2.mjs → messages-DBwWssfL2.mjs} +9 -0
- package/dist/{messages-Cdgz3urh.mjs → messages-DFHRMYke.mjs} +9 -0
- package/dist/{messages-DXCyNanc2.mjs → messages-DJVrq0Xa2.mjs} +9 -0
- package/dist/{chunks/messages-OYoN_rp1.mjs → messages-DMJz28kt.mjs} +9 -0
- package/dist/{chunks/messages-B_U10evN2.mjs → messages-DOnOpXFJ2.mjs} +9 -0
- package/dist/{messages-5USazVPA2.mjs → messages-DR1Tf-Kj2.mjs} +9 -0
- package/dist/{chunks/messages-C4sIqArW2.mjs → messages-DSUXwuzH2.mjs} +9 -0
- package/dist/{chunks/messages-DGHTTk1S2.mjs → messages-DTNO7tw1.mjs} +9 -0
- package/dist/{messages-Ddz6eH0-2.mjs → messages-DWBtyom42.mjs} +9 -0
- package/dist/{messages-DKsyrVp5.mjs → messages-DZQALZIU.mjs} +9 -0
- package/dist/{chunks/messages-V8K7-1l2.mjs → messages-D_i86vbQ.mjs} +9 -0
- package/dist/{chunks/messages-BmiN0JGP2.mjs → messages-Da1VKvvf2.mjs} +9 -0
- package/dist/{messages-D5qgCWmB2.mjs → messages-Ddimgqvp2.mjs} +9 -0
- package/dist/{chunks/messages-MPF8o3EP.mjs → messages-DdmXBLUC.mjs} +9 -0
- package/dist/{messages-D4U4wkYM.mjs → messages-Devcsnrv.mjs} +9 -0
- package/dist/{chunks/messages-DiGsu5XN.mjs → messages-DhS-j4Hp.mjs} +9 -0
- package/dist/{messages-BGzpwNrz.mjs → messages-DrRVvVPI.mjs} +9 -0
- package/dist/{chunks/messages-Z9mDYT3w.mjs → messages-Ds4gQbVR2.mjs} +9 -0
- package/dist/{chunks/messages-vQ5kblO8.mjs → messages-DxkB7LL6.mjs} +9 -0
- package/dist/{chunks/messages-LTkIIrSe2.mjs → messages-GgHHrLBU2.mjs} +9 -0
- package/dist/{messages-CntTlSE22.mjs → messages-IycPaZe22.mjs} +9 -0
- package/dist/{messages-BtDz-sw92.mjs → messages-ST8f_nDx2.mjs} +9 -0
- package/dist/{messages-CgVEHCQ-.mjs → messages-SV8lf6F0.mjs} +9 -0
- package/dist/{messages-Bt4TLGth.mjs → messages-lVrQmsky.mjs} +9 -0
- package/dist/{messages-rpO1POP02.mjs → messages-lcoIGSX82.mjs} +9 -0
- package/dist/{chunks/messages-BuYnNUtU2.mjs → messages-mqRVfUUq.mjs} +9 -0
- package/dist/{chunks/messages-C24IC_eR.mjs → messages-qWFvoPY1.mjs} +9 -0
- package/dist/{messages-CacRpQpm.mjs → messages-yte1QPX5.mjs} +9 -0
- package/dist/{messages-DNlrcG5Z.mjs → messages-zyiti_A8.mjs} +9 -0
- package/dist/react.cjs +1 -1
- package/dist/react.mjs +1 -1
- package/dist/tools.cjs +1 -1
- package/dist/tools.mjs +3 -3
- package/package.json +1 -1
- package/src/components/blocks.ts +30 -7
- package/src/components/i18n/locales/am/messages.json +9 -0
- package/src/components/i18n/locales/ar/messages.json +9 -0
- package/src/components/i18n/locales/az/messages.json +9 -0
- package/src/components/i18n/locales/bg/messages.json +9 -0
- package/src/components/i18n/locales/bn/messages.json +9 -0
- package/src/components/i18n/locales/bs/messages.json +9 -0
- package/src/components/i18n/locales/cs/messages.json +9 -0
- package/src/components/i18n/locales/da/messages.json +9 -0
- package/src/components/i18n/locales/de/messages.json +9 -0
- package/src/components/i18n/locales/dv/messages.json +9 -0
- package/src/components/i18n/locales/el/messages.json +9 -0
- package/src/components/i18n/locales/en/messages.json +9 -0
- package/src/components/i18n/locales/es/messages.json +9 -0
- package/src/components/i18n/locales/et/messages.json +9 -0
- package/src/components/i18n/locales/fa/messages.json +9 -0
- package/src/components/i18n/locales/fi/messages.json +9 -0
- package/src/components/i18n/locales/fil/messages.json +9 -0
- package/src/components/i18n/locales/fr/messages.json +9 -0
- package/src/components/i18n/locales/gu/messages.json +9 -0
- package/src/components/i18n/locales/he/messages.json +9 -0
- package/src/components/i18n/locales/hi/messages.json +9 -0
- package/src/components/i18n/locales/hr/messages.json +9 -0
- package/src/components/i18n/locales/hu/messages.json +9 -0
- package/src/components/i18n/locales/hy/messages.json +9 -0
- package/src/components/i18n/locales/id/messages.json +9 -0
- package/src/components/i18n/locales/it/messages.json +9 -0
- package/src/components/i18n/locales/ja/messages.json +9 -0
- package/src/components/i18n/locales/ka/messages.json +9 -0
- package/src/components/i18n/locales/km/messages.json +9 -0
- package/src/components/i18n/locales/kn/messages.json +9 -0
- package/src/components/i18n/locales/ko/messages.json +9 -0
- package/src/components/i18n/locales/ku/messages.json +9 -0
- package/src/components/i18n/locales/lo/messages.json +9 -0
- package/src/components/i18n/locales/lt/messages.json +9 -0
- package/src/components/i18n/locales/lv/messages.json +9 -0
- package/src/components/i18n/locales/mk/messages.json +9 -0
- package/src/components/i18n/locales/ml/messages.json +9 -0
- package/src/components/i18n/locales/mn/messages.json +9 -0
- package/src/components/i18n/locales/mr/messages.json +9 -0
- package/src/components/i18n/locales/ms/messages.json +9 -0
- package/src/components/i18n/locales/my/messages.json +9 -0
- package/src/components/i18n/locales/ne/messages.json +9 -0
- package/src/components/i18n/locales/nl/messages.json +9 -0
- package/src/components/i18n/locales/no/messages.json +9 -0
- package/src/components/i18n/locales/pa/messages.json +9 -0
- package/src/components/i18n/locales/pl/messages.json +9 -0
- package/src/components/i18n/locales/ps/messages.json +9 -0
- package/src/components/i18n/locales/pt/messages.json +9 -0
- package/src/components/i18n/locales/ro/messages.json +9 -0
- package/src/components/i18n/locales/ru/messages.json +9 -0
- package/src/components/i18n/locales/sd/messages.json +9 -0
- package/src/components/i18n/locales/si/messages.json +9 -0
- package/src/components/i18n/locales/sk/messages.json +9 -0
- package/src/components/i18n/locales/sl/messages.json +9 -0
- package/src/components/i18n/locales/sq/messages.json +9 -0
- package/src/components/i18n/locales/sr/messages.json +9 -0
- package/src/components/i18n/locales/sv/messages.json +9 -0
- package/src/components/i18n/locales/sw/messages.json +9 -0
- package/src/components/i18n/locales/ta/messages.json +9 -0
- package/src/components/i18n/locales/te/messages.json +9 -0
- package/src/components/i18n/locales/th/messages.json +9 -0
- package/src/components/i18n/locales/tr/messages.json +9 -0
- package/src/components/i18n/locales/ug/messages.json +9 -0
- package/src/components/i18n/locales/uk/messages.json +9 -0
- package/src/components/i18n/locales/ur/messages.json +9 -0
- package/src/components/i18n/locales/vi/messages.json +9 -0
- package/src/components/i18n/locales/yi/messages.json +9 -0
- package/src/components/i18n/locales/zh/messages.json +9 -0
- package/src/components/icons/index.ts +24 -0
- package/src/components/modules/blockEvents/composers/keyboardNavigation.ts +67 -6
- package/src/components/modules/blockManager/hierarchy.ts +150 -8
- package/src/components/modules/blockManager/operations.ts +207 -8
- package/src/components/modules/blockManager/yjs-sync.ts +36 -1
- package/src/components/modules/caret.ts +205 -31
- package/src/components/modules/drag/DragController.ts +219 -2
- package/src/components/modules/drag/a11y/DragA11y.ts +9 -1
- package/src/components/modules/drag/state/DragStateMachine.ts +1 -1
- package/src/components/modules/drag/target/DropTargetDetector.ts +513 -3
- package/src/components/modules/drag/utils/drag.constants.ts +9 -0
- package/src/components/modules/toolbar/blockSettings.ts +75 -5
- package/src/components/modules/toolbar/index.ts +12 -1
- package/src/components/modules/uiControllers/controllers/blockHover.ts +24 -2
- package/src/components/modules/uiControllers/controllers/selection.ts +50 -0
- package/src/components/utils/blocks.ts +21 -7
- package/src/styles/colors.css +3 -0
- package/src/styles/columns.css +105 -0
- package/src/styles/main.css +48 -3
- package/src/styles/popover-animation.css +8 -0
- package/src/tools/column/index.ts +189 -0
- package/src/tools/column/types.ts +26 -0
- package/src/tools/column-drop.ts +273 -0
- package/src/tools/column-list/index.ts +142 -0
- package/src/tools/column-list/types.ts +17 -0
- package/src/tools/columns-shared.ts +343 -0
- package/src/tools/divider/index.ts +1 -0
- package/src/tools/index.ts +4 -0
- package/src/tools/nested-blocks.ts +23 -2
- package/src/tools/table/table-restrictions.ts +1 -1
- package/types/tools/column-list.d.ts +15 -0
- package/types/tools/column.d.ts +13 -0
- package/types/tools-entry.d.ts +8 -0
- package/dist/chunks/blok-Xu27QC2G.cjs +0 -17
- package/dist/chunks/constants-DDTVRO2H.cjs +0 -457
- package/dist/chunks/lightweight-i18n-Bbl1cNYK.cjs +0 -1
- package/dist/chunks/messages-1qYt6EhZ2.cjs +0 -1
- package/dist/chunks/messages-2fxvN3Nb.cjs +0 -1
- package/dist/chunks/messages-B1Vs2HmR.cjs +0 -1
- package/dist/chunks/messages-B780gS332.cjs +0 -1
- package/dist/chunks/messages-B7T5Notn.cjs +0 -1
- package/dist/chunks/messages-BE9aZQ1Q.cjs +0 -1
- package/dist/chunks/messages-BIQpTYfm.cjs +0 -1
- package/dist/chunks/messages-BIRvUJ0t.cjs +0 -1
- package/dist/chunks/messages-BIodfkjv.cjs +0 -1
- package/dist/chunks/messages-BL-zBcuM.cjs +0 -1
- package/dist/chunks/messages-BQr0zpmu2.cjs +0 -1
- package/dist/chunks/messages-BTHi6rVW2.cjs +0 -1
- package/dist/chunks/messages-BZOAdcmO2.cjs +0 -1
- package/dist/chunks/messages-BbsGeVs_2.cjs +0 -1
- package/dist/chunks/messages-Bc1NYJVS.cjs +0 -1
- package/dist/chunks/messages-BdORNG8X.cjs +0 -1
- package/dist/chunks/messages-Bg2kheTv.cjs +0 -1
- package/dist/chunks/messages-Bj1eQtQw.cjs +0 -1
- package/dist/chunks/messages-BkJJCHNK.cjs +0 -1
- package/dist/chunks/messages-BkdGQfIX.cjs +0 -1
- package/dist/chunks/messages-BkgsB-cj2.cjs +0 -1
- package/dist/chunks/messages-Bn0vGFEP.cjs +0 -1
- package/dist/chunks/messages-BoIUXwWe.cjs +0 -1
- package/dist/chunks/messages-BpDEh8rW.cjs +0 -1
- package/dist/chunks/messages-BwknPZJ8.cjs +0 -1
- package/dist/chunks/messages-ByicRCge2.cjs +0 -1
- package/dist/chunks/messages-C2oBmyTn.cjs +0 -1
- package/dist/chunks/messages-C9wBMmxr2.cjs +0 -1
- package/dist/chunks/messages-CDK5-8vW.cjs +0 -1
- package/dist/chunks/messages-CKHbPcfh.cjs +0 -1
- package/dist/chunks/messages-CNFfwTfw.cjs +0 -1
- package/dist/chunks/messages-CNiuofck2.cjs +0 -1
- package/dist/chunks/messages-CWszAGkF.cjs +0 -1
- package/dist/chunks/messages-CWzQNagc2.cjs +0 -1
- package/dist/chunks/messages-CYf1gv722.cjs +0 -1
- package/dist/chunks/messages-CfcCwbQo.cjs +0 -1
- package/dist/chunks/messages-CkvqOnAR.cjs +0 -1
- package/dist/chunks/messages-Cnrug7nz2.cjs +0 -1
- package/dist/chunks/messages-Cr51zCHy.cjs +0 -1
- package/dist/chunks/messages-CsLvvl2F2.cjs +0 -1
- package/dist/chunks/messages-CuO-Rx4g.cjs +0 -1
- package/dist/chunks/messages-Cv4I3k1W2.cjs +0 -1
- package/dist/chunks/messages-CwHRv6g8.cjs +0 -1
- package/dist/chunks/messages-CzXnHfGb2.cjs +0 -1
- package/dist/chunks/messages-D2QxLx1a.cjs +0 -1
- package/dist/chunks/messages-D4LUPpX_.cjs +0 -1
- package/dist/chunks/messages-DJFL-bxd2.cjs +0 -1
- package/dist/chunks/messages-DLEeNpMi2.cjs +0 -1
- package/dist/chunks/messages-DTNU_cq0.cjs +0 -1
- package/dist/chunks/messages-DVKsYqpJ.cjs +0 -1
- package/dist/chunks/messages-DXlfz-nC.cjs +0 -1
- package/dist/chunks/messages-DbA_Zja3.cjs +0 -1
- package/dist/chunks/messages-Dc2TTEx_2.cjs +0 -1
- package/dist/chunks/messages-DeDMMmRC.cjs +0 -1
- package/dist/chunks/messages-DlQNXqzr.cjs +0 -1
- package/dist/chunks/messages-DqMqZLcn.cjs +0 -1
- package/dist/chunks/messages-DqqDuEE22.cjs +0 -1
- package/dist/chunks/messages-DzppdmWe.cjs +0 -1
- package/dist/chunks/messages-HzLF-BQL2.cjs +0 -1
- package/dist/chunks/messages-Jb9n97oP2.cjs +0 -1
- package/dist/chunks/messages-K_vSdSoF2.cjs +0 -1
- package/dist/chunks/messages-Nh7wrRdm.cjs +0 -1
- package/dist/chunks/messages-QHS-Ydg_.cjs +0 -1
- package/dist/chunks/messages-SpiG5vT-2.cjs +0 -1
- package/dist/chunks/messages-XFaJzdhP2.cjs +0 -1
- package/dist/chunks/messages-y03BGg692.cjs +0 -1
- package/dist/chunks/tools-DOuVjow8.cjs +0 -116
|
@@ -1197,7 +1197,18 @@ export class Toolbar extends Module<ToolbarNodes> {
|
|
|
1197
1197
|
const currentBlock = this.Blok.BlockManager.currentBlock;
|
|
1198
1198
|
|
|
1199
1199
|
if (currentBlock && currentBlock.inputs.length > 0) {
|
|
1200
|
-
|
|
1200
|
+
// If a freshly inserted tool already placed the caret inside its own
|
|
1201
|
+
// subtree (e.g. a column_list focusing its FIRST column), keep it.
|
|
1202
|
+
// Restore focus only when it has actually fallen outside the block —
|
|
1203
|
+
// to document.body on non-keyboard close paths — which is what this
|
|
1204
|
+
// branch defends against. Restoring to END would otherwise jump a
|
|
1205
|
+
// multi-input container like columns to its LAST input.
|
|
1206
|
+
const active = document.activeElement;
|
|
1207
|
+
const focusAlreadyInBlock = active instanceof Node && currentBlock.holder.contains(active);
|
|
1208
|
+
|
|
1209
|
+
if (!focusAlreadyInBlock) {
|
|
1210
|
+
this.Blok.Caret.setToBlock(currentBlock, this.Blok.Caret.positions.END);
|
|
1211
|
+
}
|
|
1201
1212
|
}
|
|
1202
1213
|
});
|
|
1203
1214
|
|
|
@@ -137,6 +137,15 @@ export class BlockHoverController extends Controller {
|
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Columns are structural containers, not selectable blocks. Skip the
|
|
142
|
+
* event so neither the column nor its column_list ever gets a toolbar —
|
|
143
|
+
* only the blocks inside a column are selectable (Notion-style).
|
|
144
|
+
*/
|
|
145
|
+
if (BlockHoverController.isColumnContainer(block)) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
140
149
|
/**
|
|
141
150
|
* For multi-block selection, still emit 'block-hovered' event so toolbar can follow the hovered block.
|
|
142
151
|
* The toolbar module will handle the logic of whether to move or not.
|
|
@@ -189,6 +198,17 @@ export class BlockHoverController extends Controller {
|
|
|
189
198
|
});
|
|
190
199
|
}
|
|
191
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Columns are structural containers, not independent blocks: neither a
|
|
203
|
+
* `column` nor its `column_list` may own a drag handle, settings menu, or
|
|
204
|
+
* "convert to" option. Only the blocks inside a column are selectable.
|
|
205
|
+
* @param block - a hovered or candidate block
|
|
206
|
+
* @returns true when the block is a column layout container
|
|
207
|
+
*/
|
|
208
|
+
private static isColumnContainer(block: Block): boolean {
|
|
209
|
+
return block.name === 'column' || block.name === 'column_list';
|
|
210
|
+
}
|
|
211
|
+
|
|
192
212
|
/**
|
|
193
213
|
* Emits a BlockHovered event for the nearest block, but only if the cursor
|
|
194
214
|
* is within the extended hover zone (HOVER_ZONE_SIZE px from content edges).
|
|
@@ -198,7 +218,8 @@ export class BlockHoverController extends Controller {
|
|
|
198
218
|
private emitNearestBlockHoveredInZone(clientX: number, clientY: number): void {
|
|
199
219
|
const blocks = this.Blok.BlockManager.blocks;
|
|
200
220
|
const topLevelBlocks = blocks.filter(block =>
|
|
201
|
-
|
|
221
|
+
!BlockHoverController.isColumnContainer(block)
|
|
222
|
+
&& block.holder.closest('[data-blok-table-cell-blocks], [data-blok-toggle-children]') === null
|
|
202
223
|
);
|
|
203
224
|
|
|
204
225
|
if (topLevelBlocks.length === 0) {
|
|
@@ -246,7 +267,8 @@ export class BlockHoverController extends Controller {
|
|
|
246
267
|
* This matches the direct-hit path which also resolves nested blocks to their parent.
|
|
247
268
|
*/
|
|
248
269
|
const topLevelBlocks = blocks.filter(block =>
|
|
249
|
-
|
|
270
|
+
!BlockHoverController.isColumnContainer(block)
|
|
271
|
+
&& block.holder.closest('[data-blok-table-cell-blocks], [data-blok-toggle-children]') === null
|
|
250
272
|
);
|
|
251
273
|
|
|
252
274
|
if (topLevelBlocks.length === 0) {
|
|
@@ -33,11 +33,51 @@ export class SelectionController extends Controller {
|
|
|
33
33
|
this.wrapperElement = element;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Whether a pointer is currently pressed (an in-progress drag selection).
|
|
38
|
+
* While true, the inline toolbar is kept hidden so it doesn't pop up mid-drag;
|
|
39
|
+
* it appears the moment the pointer is released.
|
|
40
|
+
*/
|
|
41
|
+
private isPointerDown = false;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Remember that a drag may be starting so the inline toolbar stays hidden
|
|
45
|
+
* until the pointer is released.
|
|
46
|
+
*/
|
|
47
|
+
private handlePointerDown = (): void => {
|
|
48
|
+
this.isPointerDown = true;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Show the inline toolbar the moment a pointer drag-selection is released.
|
|
53
|
+
*
|
|
54
|
+
* While the pointer is down the debounced selectionchange handler suppresses
|
|
55
|
+
* the toolbar (see handleSelectionChange), so it never flickers mid-drag.
|
|
56
|
+
* Clearing the flag and running the handler synchronously here makes the
|
|
57
|
+
* toolbar appear instantly on release.
|
|
58
|
+
*/
|
|
59
|
+
private handlePointerUp = (): void => {
|
|
60
|
+
this.isPointerDown = false;
|
|
61
|
+
this.handleSelectionChange();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A cancelled pointer interaction (e.g. the gesture is taken over by the
|
|
66
|
+
* browser) never fires pointerup, so clear the flag to avoid stranding the
|
|
67
|
+
* toolbar in a permanently-suppressed state.
|
|
68
|
+
*/
|
|
69
|
+
private handlePointerCancel = (): void => {
|
|
70
|
+
this.isPointerDown = false;
|
|
71
|
+
};
|
|
72
|
+
|
|
36
73
|
/**
|
|
37
74
|
* Enable selection change listeners
|
|
38
75
|
*/
|
|
39
76
|
public override enable(): void {
|
|
40
77
|
this.listeners.on(document, 'selectionchange', this.selectionChangeDebounced);
|
|
78
|
+
this.listeners.on(document, 'pointerdown', this.handlePointerDown);
|
|
79
|
+
this.listeners.on(document, 'pointerup', this.handlePointerUp);
|
|
80
|
+
this.listeners.on(document, 'pointercancel', this.handlePointerCancel);
|
|
41
81
|
}
|
|
42
82
|
|
|
43
83
|
/**
|
|
@@ -137,6 +177,16 @@ export class SelectionController extends Controller {
|
|
|
137
177
|
this.Blok.BlockManager.setCurrentBlockByChildNode(focusedElement);
|
|
138
178
|
}
|
|
139
179
|
|
|
180
|
+
/**
|
|
181
|
+
* While the pointer is held down the user is still dragging out the
|
|
182
|
+
* selection. Keep the toolbar hidden until they release (handlePointerUp),
|
|
183
|
+
* so it appears in one motion at the final selection rather than popping up
|
|
184
|
+
* mid-drag.
|
|
185
|
+
*/
|
|
186
|
+
if (this.isPointerDown) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
140
190
|
void this.Blok.InlineToolbar.tryToShow(true);
|
|
141
191
|
}
|
|
142
192
|
|
|
@@ -191,20 +191,34 @@ export const getConvertibleToolsForBlocks = async (blocks: BlockAPI[], allBlockT
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
/**
|
|
194
|
-
*
|
|
194
|
+
* Only the "roots" of the selection constrain the conversion targets:
|
|
195
|
+
*
|
|
196
|
+
* - A block nested under another selected block rides with its container
|
|
197
|
+
* (e.g. the contents of a selected column_list) and must NOT be converted
|
|
198
|
+
* on its own — so it's ignored here.
|
|
199
|
+
* - A block whose tool has no «export» rule (e.g. container blocks like
|
|
200
|
+
* column_list/column) cannot convert and is left untouched — ignored too,
|
|
201
|
+
* NOT used to suppress every target for the whole selection.
|
|
195
202
|
*/
|
|
196
|
-
|
|
203
|
+
const selectedIds = new Set(blocks.map((block) => block.id));
|
|
204
|
+
const convertibleBlocks = blocks.filter((block) => {
|
|
205
|
+
if (block.parentId !== null && selectedIds.has(block.parentId)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
|
|
197
209
|
const blockTool = allBlockTools.find((tool) => tool.name === block.name);
|
|
198
210
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
211
|
+
return blockTool === undefined || isToolConvertable(blockTool, 'export');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (convertibleBlocks.length === 0) {
|
|
215
|
+
return [];
|
|
202
216
|
}
|
|
203
217
|
|
|
204
218
|
/**
|
|
205
|
-
* Get the set of tool names that
|
|
219
|
+
* Get the set of tool names that the convertible blocks currently use
|
|
206
220
|
*/
|
|
207
|
-
const blockToolNames = new Set(
|
|
221
|
+
const blockToolNames = new Set(convertibleBlocks.map((block) => block.name));
|
|
208
222
|
|
|
209
223
|
/**
|
|
210
224
|
* Filter tools that have import conversion config and valid toolbox
|
package/src/styles/colors.css
CHANGED
|
@@ -241,6 +241,9 @@
|
|
|
241
241
|
/* Small UI surfaces that can't reach a var via Tailwind arbitrary syntax. */
|
|
242
242
|
--blok-button-focus-bg-hover: #fbfcfe;
|
|
243
243
|
--blok-dnd-drop-indicator-bg: #d4e3fc;
|
|
244
|
+
/* Drop-line geometry shared by the horizontal (top/bottom) and vertical
|
|
245
|
+
(left/right) indicators so both bars render identically. */
|
|
246
|
+
--blok-dnd-drop-indicator-thickness: 6px;
|
|
244
247
|
|
|
245
248
|
/* Direct-usage surface tokens extracted in B1.6. Light-theme values match
|
|
246
249
|
the dark overrides below; they are rarely applied outside the dark theme. */
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Columns layout tool — responsive stacking.
|
|
3
|
+
*
|
|
4
|
+
* The flex children of a column_list are the block-holder wrappers
|
|
5
|
+
* ([data-blok-element]), not the [data-blok-column] elements the Column tool
|
|
6
|
+
* renders. Target the holders directly so flex-wrap forces vertical stacking
|
|
7
|
+
* on narrow viewports and restores side-by-side distribution above the
|
|
8
|
+
* project's mobile breakpoint (651px, matching the `not-mobile` variant).
|
|
9
|
+
*/
|
|
10
|
+
[data-blok-columns] > [data-blok-element] {
|
|
11
|
+
flex-basis: 100%;
|
|
12
|
+
flex-shrink: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@media (min-width: 651px) {
|
|
16
|
+
[data-blok-columns] > [data-blok-element] {
|
|
17
|
+
flex-basis: 0;
|
|
18
|
+
flex-shrink: 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* New-column entry animation (Notion-style): a freshly added column slides in by
|
|
24
|
+
* growing its flex share from 0 while fading in, so the existing columns reflow
|
|
25
|
+
* to make room. The trigger attribute is set on the column holder when the
|
|
26
|
+
* column is created and stripped on animationend — see playColumnEnterAnimation.
|
|
27
|
+
*/
|
|
28
|
+
@keyframes blok-column-enter {
|
|
29
|
+
from {
|
|
30
|
+
flex-grow: 0;
|
|
31
|
+
opacity: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
to {
|
|
35
|
+
flex-grow: 1;
|
|
36
|
+
opacity: 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
[data-blok-columns] > [data-blok-element][data-blok-column-enter] {
|
|
41
|
+
animation: blok-column-enter 200ms ease-out;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@media (prefers-reduced-motion: reduce) {
|
|
45
|
+
[data-blok-columns] > [data-blok-element][data-blok-column-enter] {
|
|
46
|
+
animation: none;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
* Resize separator — a fixed-width flex item that forms the gutter between two
|
|
52
|
+
* columns. The visible bar is hidden until the gutter is hovered or dragged,
|
|
53
|
+
* matching Notion. The bar is wider than its hit feel via the full-width
|
|
54
|
+
* col-resize cursor zone.
|
|
55
|
+
*/
|
|
56
|
+
[data-blok-column-resizer] {
|
|
57
|
+
flex: 0 0 1.5rem;
|
|
58
|
+
align-self: stretch;
|
|
59
|
+
position: relative;
|
|
60
|
+
cursor: col-resize;
|
|
61
|
+
touch-action: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
[data-blok-column-resizer]::before {
|
|
65
|
+
content: '';
|
|
66
|
+
position: absolute;
|
|
67
|
+
inset-block: 0.25rem;
|
|
68
|
+
left: 50%;
|
|
69
|
+
width: 3px;
|
|
70
|
+
border-radius: 9999px;
|
|
71
|
+
/* Theme-aware so the handle stays visible on both light and dark surfaces. */
|
|
72
|
+
background-color: var(--blok-border-strong);
|
|
73
|
+
transform: translateX(-50%);
|
|
74
|
+
opacity: 0;
|
|
75
|
+
transition: opacity 120ms ease, background-color 120ms ease;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[data-blok-column-resizer]:hover::before,
|
|
79
|
+
[data-blok-column-resizer][data-dragging]::before {
|
|
80
|
+
opacity: 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Accent the handle while actively dragging for clear feedback. */
|
|
84
|
+
[data-blok-column-resizer][data-dragging]::before {
|
|
85
|
+
background-color: var(--blok-active-icon);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* While a block is being dragged, suppress the gutter handle entirely. Otherwise
|
|
90
|
+
* the cursor passing over a separator triggers :hover and reveals the gray handle
|
|
91
|
+
* bar right next to the blue drop indicator — reading as two drop targets in the
|
|
92
|
+
* gutter. Higher specificity than the :hover rule (three attributes), so it wins
|
|
93
|
+
* without !important. A real resize drag sets [data-dragging] on the resizer, not
|
|
94
|
+
* data-blok-dragging on the interface, so this never hides the active resize.
|
|
95
|
+
*/
|
|
96
|
+
[data-blok-interface][data-blok-dragging="true"] [data-blok-column-resizer]::before {
|
|
97
|
+
opacity: 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Columns stack vertically below the breakpoint, so the gutter handle hides. */
|
|
101
|
+
@media (max-width: 650px) {
|
|
102
|
+
[data-blok-column-resizer] {
|
|
103
|
+
display: none;
|
|
104
|
+
}
|
|
105
|
+
}
|
package/src/styles/main.css
CHANGED
|
@@ -170,11 +170,29 @@
|
|
|
170
170
|
@apply relative;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
/*
|
|
174
|
+
* Shared drop-line look for every orientation. The bar is a rounded rule whose
|
|
175
|
+
* colour and thickness come from the design tokens, so the horizontal
|
|
176
|
+
* (top/bottom) and vertical (left/right) indicators are visually identical;
|
|
177
|
+
* each orientation rule below only sets which axis the thickness applies to and
|
|
178
|
+
* where the bar is pinned.
|
|
179
|
+
*/
|
|
173
180
|
[data-drop-indicator]::before {
|
|
174
|
-
@apply content-[''] absolute
|
|
181
|
+
@apply content-[''] absolute rounded-xs pointer-events-none z-10;
|
|
175
182
|
background-color: var(--blok-dnd-drop-indicator-bg);
|
|
176
|
-
|
|
177
|
-
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Horizontal drop indicator: a rule across the top or bottom edge of the block.
|
|
187
|
+
*/
|
|
188
|
+
[data-drop-indicator="top"]::before,
|
|
189
|
+
[data-drop-indicator="bottom"]::before {
|
|
190
|
+
height: var(--blok-dnd-drop-indicator-thickness);
|
|
191
|
+
/* Confine the line to the content box: the holder spans the editor gutters,
|
|
192
|
+
* so the side offsets pull the line in to the visible content width. The
|
|
193
|
+
* depth indent (list nesting) is added on top of the content-left offset. */
|
|
194
|
+
left: calc(var(--drop-indicator-side-left, 0px) + var(--drop-indicator-depth, 0) * var(--blok-space-3));
|
|
195
|
+
right: var(--drop-indicator-side-right, 0px);
|
|
178
196
|
}
|
|
179
197
|
|
|
180
198
|
[data-drop-indicator="bottom"]::before {
|
|
@@ -187,6 +205,32 @@
|
|
|
187
205
|
transform: translateY(-50%);
|
|
188
206
|
}
|
|
189
207
|
|
|
208
|
+
/*
|
|
209
|
+
* Vertical drop indicator: a bar on the left or right edge of the holder,
|
|
210
|
+
* signalling a column-layout drop. Same look as the horizontal rule, only the
|
|
211
|
+
* thickness applies to the width and the bar is pinned to a side edge.
|
|
212
|
+
*/
|
|
213
|
+
[data-drop-indicator="left"]::before,
|
|
214
|
+
[data-drop-indicator="right"]::before {
|
|
215
|
+
width: var(--blok-dnd-drop-indicator-thickness);
|
|
216
|
+
/* Span the full column-row height when the target sits in a column_list: the
|
|
217
|
+
* controller sets these to the row's top/bottom offset (negative, so the bar
|
|
218
|
+
* grows past the single block). Default 0/0 → the bar matches the block. */
|
|
219
|
+
top: var(--drop-indicator-side-top, 0);
|
|
220
|
+
bottom: var(--drop-indicator-side-bottom, 0);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
[data-drop-indicator="left"]::before {
|
|
224
|
+
/* Pull the bar out into the gutter so it sits clear of the content edge. */
|
|
225
|
+
left: calc(var(--drop-indicator-side-left, 0px) - var(--blok-space-2));
|
|
226
|
+
transform: translateX(-50%);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
[data-drop-indicator="right"]::before {
|
|
230
|
+
right: calc(var(--drop-indicator-side-right, 0px) - var(--blok-space-2));
|
|
231
|
+
transform: translateX(50%);
|
|
232
|
+
}
|
|
233
|
+
|
|
190
234
|
/* Spring-loaded: flash selection highlight on toggle after it auto-expands */
|
|
191
235
|
[data-blok-spring-loaded] [data-blok-element-content] {
|
|
192
236
|
animation: spring-loaded-flash 700ms ease-out forwards;
|
|
@@ -296,6 +340,7 @@
|
|
|
296
340
|
@import './emoji-picker.css';
|
|
297
341
|
@import './database.css';
|
|
298
342
|
@import './image.css';
|
|
343
|
+
@import './columns.css';
|
|
299
344
|
|
|
300
345
|
/*
|
|
301
346
|
Image tool — selectors audited by unit tests (no backdrop-filter regression,
|
|
@@ -26,6 +26,14 @@
|
|
|
26
26
|
transform: scale(0.98);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/* Inline toolbar appears instantly — no entrance animation.
|
|
30
|
+
Direct child only, so nested inline popovers keep their animation. */
|
|
31
|
+
[data-blok-popover-inline] > [data-blok-popover-container],
|
|
32
|
+
[data-blok-popover-inline]:not([data-blok-popover-opened='true']) > [data-blok-popover-container] {
|
|
33
|
+
transition: none;
|
|
34
|
+
transform: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
@media (prefers-reduced-motion: reduce) {
|
|
30
38
|
[data-blok-popover-container] {
|
|
31
39
|
transition: none;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
API,
|
|
3
|
+
BlockTool,
|
|
4
|
+
BlockToolConstructorOptions,
|
|
5
|
+
} from '../../../types';
|
|
6
|
+
import { COLUMN_ATTR, unwrapColumnListIfCollapsed } from '../columns-shared';
|
|
7
|
+
import { mountChildBlocks } from '../nested-blocks';
|
|
8
|
+
import { DATA_ATTR } from '../../components/constants/data-attributes';
|
|
9
|
+
import { twMerge } from '../../components/utils/tw';
|
|
10
|
+
import type { ColumnData } from './types';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Column block — a single vertical column inside a column_list.
|
|
14
|
+
* Hosts arbitrary user blocks as nested children and seeds an empty
|
|
15
|
+
* paragraph when created so it is never empty.
|
|
16
|
+
*/
|
|
17
|
+
export class Column implements BlockTool {
|
|
18
|
+
private readonly api: API;
|
|
19
|
+
private _data: ColumnData;
|
|
20
|
+
private readonly blockId: string;
|
|
21
|
+
private readonly block: BlockToolConstructorOptions<ColumnData>['block'];
|
|
22
|
+
private childContainer: HTMLElement | null = null;
|
|
23
|
+
// Latched once the column has ever held content (mounted children or a seed).
|
|
24
|
+
// Distinguishes a fresh empty column (first render → seed) from one emptied
|
|
25
|
+
// later by a drag-out (re-render → self-delete).
|
|
26
|
+
private populated = false;
|
|
27
|
+
|
|
28
|
+
constructor({ data, api, block }: BlockToolConstructorOptions<ColumnData>) {
|
|
29
|
+
this.api = api;
|
|
30
|
+
this._data = { ...data };
|
|
31
|
+
this.blockId = block.id;
|
|
32
|
+
this.block = block;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public render(): HTMLElement {
|
|
36
|
+
const wrapper = document.createElement('div');
|
|
37
|
+
|
|
38
|
+
// `break-words` lets long unbreakable words reflow so a column can be
|
|
39
|
+
// resized arbitrarily thin instead of being held open at its min-content
|
|
40
|
+
// width. overflow-wrap is inherited, so descendant text picks it up.
|
|
41
|
+
wrapper.className = twMerge('flex', 'flex-col', 'min-w-0', 'break-words');
|
|
42
|
+
wrapper.setAttribute(COLUMN_ATTR, '');
|
|
43
|
+
|
|
44
|
+
const childContainer = document.createElement('div');
|
|
45
|
+
|
|
46
|
+
childContainer.setAttribute(DATA_ATTR.nestedBlocks, '');
|
|
47
|
+
wrapper.appendChild(childContainer);
|
|
48
|
+
|
|
49
|
+
this.childContainer = childContainer;
|
|
50
|
+
|
|
51
|
+
return wrapper;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public rendered(): void {
|
|
55
|
+
if (this.childContainer === null) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// The flex item is the block holder, not the rendered wrapper, and the
|
|
60
|
+
// holder only exists once the block is composed (post-render). Grow it so
|
|
61
|
+
// sibling columns split the row evenly; widthRatio biases the split.
|
|
62
|
+
this.block.holder.style.flexGrow = String(this._data.widthRatio ?? 1);
|
|
63
|
+
// A flex item defaults to min-width:auto (its min-content), which would
|
|
64
|
+
// floor the column at the width of its widest content. Allow it to shrink
|
|
65
|
+
// freely so the resizer has no min-width restriction.
|
|
66
|
+
this.block.holder.style.minWidth = '0';
|
|
67
|
+
|
|
68
|
+
const children = this.api.blocks.getChildren(this.blockId);
|
|
69
|
+
|
|
70
|
+
if (children.length > 0) {
|
|
71
|
+
this.populated = true;
|
|
72
|
+
mountChildBlocks(this.childContainer, children);
|
|
73
|
+
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Empty AFTER having held content: the column's last block was dragged out,
|
|
78
|
+
// which re-fires rendered(). A column is pure layout, never standalone — so
|
|
79
|
+
// it removes itself rather than lingering as a dead, uninteractable box.
|
|
80
|
+
if (this.populated) {
|
|
81
|
+
this.deleteSelf();
|
|
82
|
+
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Empty on the FIRST render. noSeed is a one-shot creation hint: a column-list
|
|
87
|
+
// wrap / add-column fills the column explicitly right afterwards, so suppress
|
|
88
|
+
// the seed this once and let the follow-up render mount the moved-in blocks.
|
|
89
|
+
if (this._data.noSeed === true) {
|
|
90
|
+
this._data.noSeed = false;
|
|
91
|
+
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// A fresh, unseeded column (e.g. a slash-menu preset): seed it so it is
|
|
96
|
+
// never empty.
|
|
97
|
+
this.seedParagraph();
|
|
98
|
+
this.populated = true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Remove this now-childless column from its column_list. Deferred to a
|
|
103
|
+
* microtask because rendered() runs inside the drop's affected-parents loop;
|
|
104
|
+
* an index-based delete fired synchronously would splice the flat array
|
|
105
|
+
* mid-iteration. Re-check emptiness at fire time so a column refilled before
|
|
106
|
+
* the microtask runs is spared. Deleting the column triggers its own removed()
|
|
107
|
+
* hook, which unwraps the column_list if this leaves a single survivor.
|
|
108
|
+
*/
|
|
109
|
+
private deleteSelf(): void {
|
|
110
|
+
queueMicrotask(() => {
|
|
111
|
+
if (this.api.blocks.getChildren(this.blockId).length > 0) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const index = this.api.blocks.getBlockIndex(this.blockId);
|
|
116
|
+
|
|
117
|
+
if (index !== undefined) {
|
|
118
|
+
void this.api.blocks.delete(index);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Seed the empty column with a paragraph. The first seeded column of a freshly
|
|
125
|
+
* created column_list claims the caret; siblings carry noFocus so the
|
|
126
|
+
* asynchronous last column never steals it (see {@link ColumnData}).
|
|
127
|
+
*/
|
|
128
|
+
private seedParagraph(): void {
|
|
129
|
+
const blockIndex = this.api.blocks.getBlockIndex(this.blockId);
|
|
130
|
+
|
|
131
|
+
if (blockIndex === undefined || this.childContainer === null) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const paragraph = this.api.blocks.insertInsideParent(this.blockId, blockIndex + 1);
|
|
136
|
+
|
|
137
|
+
this.childContainer.appendChild(paragraph.holder);
|
|
138
|
+
|
|
139
|
+
if (this._data.noFocus !== true) {
|
|
140
|
+
this.api.caret.setToBlock(paragraph.id, 'start');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public save(): ColumnData {
|
|
145
|
+
// The resizer mutates the holder's flex-grow live, so the holder is the
|
|
146
|
+
// source of truth once rendered. Fall back to the seeded data before the
|
|
147
|
+
// holder exists. An even-split grow of 1 is the default — omit it.
|
|
148
|
+
const liveGrow = this.block.holder?.style.flexGrow;
|
|
149
|
+
const ratio = liveGrow !== undefined && liveGrow !== ''
|
|
150
|
+
? Number(liveGrow)
|
|
151
|
+
: this._data.widthRatio;
|
|
152
|
+
|
|
153
|
+
return ratio !== undefined && ratio !== 1
|
|
154
|
+
? { widthRatio: ratio }
|
|
155
|
+
: {};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public validate(_data: ColumnData): boolean {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public removed(): void {
|
|
163
|
+
// removed() runs INSIDE blocksStore.remove, BEFORE this block is spliced
|
|
164
|
+
// out of the flat array. The unwrap below issues index-based deletes
|
|
165
|
+
// (deleteById) of the surviving column + the column_list; running them now
|
|
166
|
+
// would splice the array mid-removal, shifting indices so the outer splice
|
|
167
|
+
// hits the wrong slot — the storm that drops innocent blocks when an empty
|
|
168
|
+
// column collapses. Defer to a microtask so the triggering removal finishes
|
|
169
|
+
// its splice first and every nested delete runs on a stable array.
|
|
170
|
+
//
|
|
171
|
+
// Read the LIVE parent id (off the block) at fire time, not the id captured
|
|
172
|
+
// at construction: a column detached to root before deletion must skip.
|
|
173
|
+
queueMicrotask(() => {
|
|
174
|
+
const parentId = this.block.parentId;
|
|
175
|
+
|
|
176
|
+
if (parentId !== null) {
|
|
177
|
+
// Pass blockId as excludeId so a not-yet-spliced self is excluded from
|
|
178
|
+
// the surviving-column count.
|
|
179
|
+
void unwrapColumnListIfCollapsed(this.api, parentId, this.blockId);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public static get isReadOnlySupported(): boolean {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export type { ColumnData };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BlockToolData } from '../../../types';
|
|
2
|
+
|
|
3
|
+
export interface ColumnData extends BlockToolData {
|
|
4
|
+
/**
|
|
5
|
+
* Width of this column relative to its siblings, applied as flex-grow.
|
|
6
|
+
* Omitted means equal width (flex-grow: 1). Set by the resize sub-project.
|
|
7
|
+
*/
|
|
8
|
+
widthRatio?: number;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Transient flag set when a column is created programmatically (e.g. by a
|
|
12
|
+
* drag-beside drop) and will be populated by reparenting existing blocks.
|
|
13
|
+
* Suppresses the empty-paragraph seed in rendered(). Never persisted — not
|
|
14
|
+
* returned from save().
|
|
15
|
+
*/
|
|
16
|
+
noSeed?: boolean;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Transient flag: seed the empty paragraph but do NOT move the caret into it.
|
|
20
|
+
* Columns render asynchronously, so when a column_list seeds several columns
|
|
21
|
+
* the LAST one's self-focus would otherwise win the race. Setting this on
|
|
22
|
+
* every column except the first lets only the first column claim the caret.
|
|
23
|
+
* Never persisted — not returned from save().
|
|
24
|
+
*/
|
|
25
|
+
noFocus?: boolean;
|
|
26
|
+
}
|