@jackuait/blok 0.19.0 → 0.19.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 (35) hide show
  1. package/dist/blok.cjs +1 -1
  2. package/dist/blok.iife.js +2 -2
  3. package/dist/blok.mjs +2 -2
  4. package/dist/blok.umd.js +2 -2
  5. package/dist/chunks/{blok-BosfCfPX.cjs → blok-C8_pY9Bg.cjs} +3 -3
  6. package/dist/chunks/{blok-CXB-exXU.mjs → blok-DCc23rzA.mjs} +4 -5
  7. package/dist/chunks/{constants-BmCvHbkL.mjs → constants-C3-Lh6Fs.mjs} +1 -1
  8. package/dist/chunks/{constants-ChsAFZ8F.cjs → constants-R70ypRAK.cjs} +1 -1
  9. package/dist/chunks/{tools-DmEzyrn3.cjs → tools-DcbePIHF.cjs} +2 -2
  10. package/dist/chunks/{tools-BdoYHyV0.mjs → tools-fEI-EVng.mjs} +65 -34
  11. package/dist/full.cjs +1 -1
  12. package/dist/full.mjs +3 -3
  13. package/dist/react.cjs +1 -1
  14. package/dist/react.mjs +1 -1
  15. package/dist/tools.cjs +1 -1
  16. package/dist/tools.mjs +2 -2
  17. package/package.json +3 -3
  18. package/src/blok.ts +7 -3
  19. package/src/components/modules/api/blocks.ts +1 -1
  20. package/src/components/modules/blockManager/blockManager.ts +2 -2
  21. package/src/components/modules/yjs/serializer.ts +1 -1
  22. package/src/components/utils/data-model-transform.ts +15 -15
  23. package/src/components/utils/popover/popover-desktop.ts +6 -3
  24. package/src/components/utils/tooltip.ts +5 -38
  25. package/src/markdown/markdown-handler.ts +1 -2
  26. package/src/styles/audio.css +23 -3
  27. package/src/tools/audio/index.ts +76 -21
  28. package/src/tools/audio/ui.ts +6 -1
  29. package/types/api/tooltip.d.ts +40 -1
  30. package/types/data-formats/output-data.d.ts +5 -2
  31. package/types/index.d.ts +28 -5
  32. package/types/tools/database.d.ts +1 -1
  33. package/types/tools/header.d.ts +2 -1
  34. package/types/tools/list.d.ts +2 -1
  35. package/types/utils/popover/popover.d.ts +42 -1
@@ -1,5 +1,5 @@
1
1
  import { i as e, t } from "./chunk-5O_1xk2F.mjs";
2
- import { $ as n, $n as r, $r as i, $t as a, An as o, At as s, B as c, Bn as l, Bt as u, C as d, Cn as f, Cr as p, Ct as m, Dn as h, Dr as g, Dt as _, En as v, Er as y, Et as b, F as x, Fi as S, Fn as C, Ft as w, G as T, Gn as E, Gt as D, H as ee, Hn as O, Ht as k, I as A, In as j, Ir as M, It as te, J as ne, Jn as N, Jt as re, Kn as ie, Kt as ae, L as oe, Ln as se, Lr as ce, Lt as P, Mn as le, Mr as F, Mt as ue, Nn as de, Nr as fe, Nt as pe, Oi as me, On as I, Or as he, Ot as ge, P as _e, Pi as L, Pn as ve, Pt as ye, Q as be, Qn as xe, Qt as Se, R as Ce, Rn as we, Rt as Te, S as Ee, Sn as De, St as Oe, T as ke, Tn as Ae, Tr as je, Tt as Me, U as R, Un as Ne, Ut as Pe, Vn as Fe, Vt as Ie, W as Le, Wn as Re, Wt as ze, X as Be, Xn as Ve, Xt as He, Y as Ue, Yn as We, Yt as Ge, Z as Ke, Zn as qe, Zt as Je, _ as Ye, _n as Xe, _t as Ze, a as Qe, ar as $e, at as et, b as tt, bn as nt, bt as rt, c as it, ci as at, cn as ot, cr as st, ct as z, d as ct, dn as lt, dt as ut, en as dt, et as ft, f as pt, fn as mt, fr as ht, ft as gt, g as _t, gn as vt, gr as yt, gt as bt, h as xt, hn as St, ht as Ct, i as wt, in as Tt, ir as Et, it as Dt, jn as Ot, jt as kt, kn as At, kr as B, kt as jt, l as Mt, ln as Nt, lr as Pt, lt as Ft, mn as It, mr as Lt, mt as Rt, n as zt, nn as Bt, nr as Vt, nt as Ht, o as V, oi as Ut, on as Wt, or as Gt, ot as Kt, p as qt, pn as Jt, pr as Yt, pt as Xt, q as Zt, qt as Qt, r as $t, rr as en, rt as tn, s as nn, sn as rn, sr as an, st as on, t as sn, tr as cn, u as H, un as ln, ur as un, ut as dn, v as fn, vn as pn, vt as mn, wn as hn, wr as U, wt as gn, x as _n, xn as vn, xt as yn, y as bn, yn as xn, yr as Sn, yt as Cn, z as wn, zn as Tn, zt as En } from "./constants-BmCvHbkL.mjs";
2
+ import { $ as n, $n as r, $r as i, $t as a, An as o, At as s, B as c, Bn as l, Bt as u, C as d, Cn as f, Cr as p, Ct as m, Dn as h, Dr as g, Dt as _, En as v, Er as y, Et as b, F as x, Fi as S, Fn as C, Ft as w, G as T, Gn as E, Gt as D, H as ee, Hn as O, Ht as k, I as A, In as j, Ir as M, It as te, J as ne, Jn as N, Jt as re, Kn as ie, Kt as ae, L as oe, Ln as se, Lr as ce, Lt as P, Mn as le, Mr as F, Mt as ue, Nn as de, Nr as fe, Nt as pe, Oi as me, On as I, Or as he, Ot as ge, P as _e, Pi as L, Pn as ve, Pt as ye, Q as be, Qn as xe, Qt as Se, R as Ce, Rn as we, Rt as Te, S as Ee, Sn as De, St as Oe, T as ke, Tn as Ae, Tr as je, Tt as Me, U as R, Un as Ne, Ut as Pe, Vn as Fe, Vt as Ie, W as Le, Wn as Re, Wt as ze, X as Be, Xn as Ve, Xt as He, Y as Ue, Yn as We, Yt as Ge, Z as Ke, Zn as qe, Zt as Je, _ as Ye, _n as Xe, _t as Ze, a as Qe, ar as $e, at as et, b as tt, bn as nt, bt as rt, c as it, ci as at, cn as ot, cr as st, ct as z, d as ct, dn as lt, dt as ut, en as dt, et as ft, f as pt, fn as mt, fr as ht, ft as gt, g as _t, gn as vt, gr as yt, gt as bt, h as xt, hn as St, ht as Ct, i as wt, in as Tt, ir as Et, it as Dt, jn as Ot, jt as kt, kn as At, kr as B, kt as jt, l as Mt, ln as Nt, lr as Pt, lt as Ft, mn as It, mr as Lt, mt as Rt, n as zt, nn as Bt, nr as Vt, nt as Ht, o as V, oi as Ut, on as Wt, or as Gt, ot as Kt, p as qt, pn as Jt, pr as Yt, pt as Xt, q as Zt, qt as Qt, r as $t, rr as en, rt as tn, s as nn, sn as rn, sr as an, st as on, t as sn, tr as cn, u as H, un as ln, ur as un, ut as dn, v as fn, vn as pn, vt as mn, wn as hn, wr as U, wt as gn, x as _n, xn as vn, xt as yn, y as bn, yn as xn, yr as Sn, yt as Cn, z as wn, zn as Tn, zt as En } from "./constants-C3-Lh6Fs.mjs";
3
3
  import { t as W } from "./objectSpread2-jlBcdYeb.mjs";
4
4
  import { n as G } from "./tw-DmW6-pCY.mjs";
5
5
  import { n as Dn } from "./lightweight-i18n-DJpMke7a.mjs";
@@ -14268,8 +14268,10 @@ function lm(e, t) {
14268
14268
  function um(e) {
14269
14269
  let t = document.createElement("div");
14270
14270
  t.className = "blok-audio-caption-row", t.setAttribute("data-role", "audio-caption-row");
14271
- let n = cm("audio-caption", e.value, e.editable, e.placeholder);
14272
- return n.className = "blok-audio-caption", t.appendChild(n), t;
14271
+ let n = document.createElement("div");
14272
+ n.className = "blok-audio-caption-row__inner";
14273
+ let r = cm("audio-caption", e.value, e.editable, e.placeholder);
14274
+ return r.className = "blok-audio-caption", n.appendChild(r), t.appendChild(n), t;
14273
14275
  }
14274
14276
  //#endregion
14275
14277
  //#region src/tools/audio/controls.ts
@@ -14657,7 +14659,7 @@ var Lm = class {
14657
14659
  }, Rm = class {
14658
14660
  constructor(e) {
14659
14661
  var t, n, r;
14660
- this.root = null, this.uploadingEl = null, this.lastFileName = null, this.errorMessage = null, this.lastSource = null, this.controlsHandle = null, this.waveformHandle = null, this.destroyed = !1, this.api = e.api, this.block = e.block, this.config = (t = e.config) == null ? {} : t, this.readOnly = e.readOnly, this.data = W(W({}, e.data), {}, { url: (n = (r = e.data) == null ? void 0 : r.url) == null ? "" : n }), this.state = this.data.url ? "RENDERED" : "EMPTY", this.uploader = new Lm(this.config);
14662
+ this.root = null, this.uploadingEl = null, this.lastFileName = null, this.errorMessage = null, this.lastSource = null, this.controlsHandle = null, this.waveformHandle = null, this.destroyed = !1, this.captionExitTimer = null, this.api = e.api, this.block = e.block, this.config = (t = e.config) == null ? {} : t, this.readOnly = e.readOnly, this.data = W(W({}, e.data), {}, { url: (n = (r = e.data) == null ? void 0 : r.url) == null ? "" : n }), this.state = this.data.url ? "RENDERED" : "EMPTY", this.uploader = new Lm(this.config);
14661
14663
  }
14662
14664
  render() {
14663
14665
  let e = document.createElement("div");
@@ -14782,7 +14784,7 @@ var Lm = class {
14782
14784
  }
14783
14785
  removed() {
14784
14786
  var e, t;
14785
- this.destroyed = !0, (e = this.controlsHandle) == null || e.destroy(), this.controlsHandle = null, (t = this.waveformHandle) == null || t.destroy(), this.waveformHandle = null, this.data.url.startsWith("blob:") && URL.revokeObjectURL(this.data.url);
14787
+ this.destroyed = !0, this.captionExitTimer && (clearTimeout(this.captionExitTimer), this.captionExitTimer = null), (e = this.controlsHandle) == null || e.destroy(), this.controlsHandle = null, (t = this.waveformHandle) == null || t.destroy(), this.waveformHandle = null, this.data.url.startsWith("blob:") && URL.revokeObjectURL(this.data.url);
14786
14788
  }
14787
14789
  startUpload(e) {
14788
14790
  this.lastFileName = e.name, this.lastSource = {
@@ -14835,7 +14837,7 @@ var Lm = class {
14835
14837
  renderState() {
14836
14838
  var e, t;
14837
14839
  if (this.root) {
14838
- if ((e = this.controlsHandle) == null || e.destroy(), this.controlsHandle = null, (t = this.waveformHandle) == null || t.destroy(), this.waveformHandle = null, this.root.replaceChildren(), this.uploadingEl = null, this.syncRootAttributes(), this.state === "EMPTY") {
14840
+ if (this.captionExitTimer && (clearTimeout(this.captionExitTimer), this.captionExitTimer = null), (e = this.controlsHandle) == null || e.destroy(), this.controlsHandle = null, (t = this.waveformHandle) == null || t.destroy(), this.waveformHandle = null, this.root.replaceChildren(), this.uploadingEl = null, this.syncRootAttributes(), this.state === "EMPTY") {
14839
14841
  this.renderEmpty();
14840
14842
  return;
14841
14843
  }
@@ -14880,55 +14882,84 @@ var Lm = class {
14880
14882
  r.type = "button", r.className = "blok-audio-retry", r.setAttribute("data-action", "replace"), r.textContent = Z(this.api.i18n, "tools.audio.errorReplace", "Replace"), r.addEventListener("click", () => this.transitionToEmpty()), t.append(n, r), this.root.appendChild(t);
14881
14883
  }
14882
14884
  renderRendered() {
14883
- var e, t;
14885
+ var e;
14884
14886
  if (!this.root) return;
14885
- let n = Z(this.api.i18n, "tools.audio.titlePlaceholder", "Track title"), r = Z(this.api.i18n, "tools.audio.artistPlaceholder", "Artist"), { figure: i, audio: a, waveformMount: o, title: s, artist: c, body: l } = lm(this.data, {
14887
+ let t = Z(this.api.i18n, "tools.audio.titlePlaceholder", "Track title"), n = Z(this.api.i18n, "tools.audio.artistPlaceholder", "Artist"), { figure: r, audio: i, waveformMount: a, title: o, artist: s, body: c } = lm(this.data, {
14886
14888
  editable: !this.readOnly,
14887
- titlePlaceholder: n,
14888
- artistPlaceholder: r
14889
+ titlePlaceholder: t,
14890
+ artistPlaceholder: n
14889
14891
  });
14890
14892
  (e = this.data.peaks) != null && e.length && (this.waveformHandle = Am({
14891
- mount: o,
14892
- media: a,
14893
+ mount: a,
14894
+ media: i,
14893
14895
  peaks: this.data.peaks
14894
14896
  })), this.controlsHandle = pm({
14895
- media: a,
14896
- figure: i,
14897
+ media: i,
14898
+ figure: r,
14897
14899
  data: this.data,
14898
14900
  onLoopChange: (e) => {
14899
14901
  this.data.loop = e || void 0, this.block.dispatchChange();
14900
14902
  }
14901
- }), l.appendChild(this.controlsHandle.element);
14902
- let u = (t = this.config.captionPlaceholder) == null ? am : t;
14903
- if (this.data.captionVisible !== !1 || !this.readOnly) {
14904
- var d;
14905
- i.appendChild(um({
14906
- value: (d = this.data.caption) == null ? "" : d,
14907
- placeholder: u,
14908
- editable: !this.readOnly
14909
- }));
14910
- }
14911
- s.addEventListener("blur", () => {
14903
+ }), c.appendChild(this.controlsHandle.element), this.data.captionVisible !== !1 && r.appendChild(this.createCaptionRow()), o.addEventListener("blur", () => {
14912
14904
  var e;
14913
- let t = (e = s.textContent) == null ? "" : e;
14905
+ let t = (e = o.textContent) == null ? "" : e;
14914
14906
  t !== this.data.title && (this.data.title = t || void 0, this.block.dispatchChange());
14915
- }), c.addEventListener("blur", () => {
14907
+ }), s.addEventListener("blur", () => {
14916
14908
  var e;
14917
- let t = (e = c.textContent) == null ? "" : e;
14909
+ let t = (e = s.textContent) == null ? "" : e;
14918
14910
  t !== this.data.artist && (this.data.artist = t || void 0, this.block.dispatchChange());
14919
- });
14920
- let f = i.querySelector("[data-role=\"audio-caption\"]");
14921
- f && f.addEventListener("blur", () => {
14911
+ }), this.root.appendChild(r);
14912
+ }
14913
+ createCaptionRow() {
14914
+ var e, t;
14915
+ let n = (e = this.config.captionPlaceholder) == null ? am : e, r = um({
14916
+ value: (t = this.data.caption) == null ? "" : t,
14917
+ placeholder: n,
14918
+ editable: !this.readOnly
14919
+ }), i = r.querySelector("[data-role=\"audio-caption\"]");
14920
+ return i == null || i.addEventListener("blur", () => {
14922
14921
  var e;
14923
- let t = (e = f.textContent) == null ? "" : e;
14922
+ let t = (e = i.textContent) == null ? "" : e;
14924
14923
  t !== this.data.caption && (this.data.caption = t || void 0, this.block.dispatchChange());
14925
- }), this.root.appendChild(i);
14924
+ }), r;
14925
+ }
14926
+ prefersReducedMotion() {
14927
+ var e, t, n;
14928
+ return (e = (t = (n = globalThis).matchMedia) == null ? void 0 : t.call(n, "(prefers-reduced-motion: reduce)").matches) == null ? !1 : e;
14926
14929
  }
14927
14930
  setAlignment(e) {
14928
14931
  this.data.alignment !== e && (this.data.alignment = e, this.block.dispatchChange(), this.renderState());
14929
14932
  }
14930
14933
  toggleCaption() {
14931
- this.data.captionVisible = this.data.captionVisible === !1, this.block.dispatchChange(), this.renderState();
14934
+ var e;
14935
+ let t = this.data.captionVisible === !1;
14936
+ this.data.captionVisible = t, t || (this.data.caption = void 0), this.block.dispatchChange();
14937
+ let n = (e = this.root) == null ? void 0 : e.querySelector("[data-role=\"audio-figure\"]");
14938
+ if (!n || this.prefersReducedMotion()) {
14939
+ this.renderState();
14940
+ return;
14941
+ }
14942
+ this.syncRootAttributes(), t ? this.animateCaptionIn(n) : this.animateCaptionOut(n);
14943
+ }
14944
+ animateCaptionIn(e) {
14945
+ let t = e.querySelector("[data-role=\"audio-caption-row\"]");
14946
+ if (t) {
14947
+ this.captionExitTimer && (clearTimeout(this.captionExitTimer), this.captionExitTimer = null), t.classList.remove("is-collapsed");
14948
+ return;
14949
+ }
14950
+ let n = this.createCaptionRow();
14951
+ n.classList.add("is-collapsed"), e.appendChild(n), n.offsetHeight, n.classList.remove("is-collapsed");
14952
+ }
14953
+ animateCaptionOut(e) {
14954
+ let t = e.querySelector("[data-role=\"audio-caption-row\"]");
14955
+ if (!t) return;
14956
+ t.classList.add("is-collapsed");
14957
+ let n = () => {
14958
+ this.captionExitTimer && (clearTimeout(this.captionExitTimer), this.captionExitTimer = null), t.remove();
14959
+ };
14960
+ t.addEventListener("transitionend", (e) => {
14961
+ e.propertyName === "grid-template-rows" && n();
14962
+ }, { once: !0 }), this.captionExitTimer = setTimeout(n, 360);
14932
14963
  }
14933
14964
  toggleLoop() {
14934
14965
  this.data.loop = this.data.loop === !0 ? void 0 : !0, this.block.dispatchChange(), this.renderState();
package/dist/full.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/blok-BosfCfPX.cjs`),t=require(`./chunks/constants-ChsAFZ8F.cjs`),n=require(`./chunks/objectSpread2-iNkE6aJh.cjs`),r=require(`./chunks/tools-DmEzyrn3.cjs`);var i={paragraph:{class:r.k,inlineToolbar:!0,config:{preserveBlank:!0}},header:{class:r.O,inlineToolbar:!0},list:{class:r.D,inlineToolbar:!0}},a=n.t(n.t({},i),{},{bold:{class:r.l},italic:{class:r.c},marker:{class:r.o},underline:{class:r.a},strikethrough:{class:r.i},link:{class:r.s}});exports.Blok=e.t,exports.Bold=r.l,exports.DATA_ATTR=t.Pi,exports.Header=r.O,exports.Italic=r.c,exports.Link=r.s,exports.List=r.D,exports.Marker=r.o,exports.Paragraph=r.k,exports.Strikethrough=r.i,exports.Toggle=r.T,exports.Underline=r.a,exports.allTools=a,exports.defaultBlockTools=r.t,exports.defaultInlineTools=r.n,exports.defaultTools=i,exports.version=e.n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/blok-C8_pY9Bg.cjs`),t=require(`./chunks/constants-R70ypRAK.cjs`),n=require(`./chunks/objectSpread2-iNkE6aJh.cjs`),r=require(`./chunks/tools-DcbePIHF.cjs`);var i={paragraph:{class:r.k,inlineToolbar:!0,config:{preserveBlank:!0}},header:{class:r.O,inlineToolbar:!0},list:{class:r.D,inlineToolbar:!0}},a=n.t(n.t({},i),{},{bold:{class:r.l},italic:{class:r.c},marker:{class:r.o},underline:{class:r.a},strikethrough:{class:r.i},link:{class:r.s}});exports.Blok=e.t,exports.Bold=r.l,exports.DATA_ATTR=t.Pi,exports.Header=r.O,exports.Italic=r.c,exports.Link=r.s,exports.List=r.D,exports.Marker=r.o,exports.Paragraph=r.k,exports.Strikethrough=r.i,exports.Toggle=r.T,exports.Underline=r.a,exports.allTools=a,exports.defaultBlockTools=r.t,exports.defaultInlineTools=r.n,exports.defaultTools=i,exports.version=e.n;
package/dist/full.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { n as e, t } from "./chunks/blok-CXB-exXU.mjs";
2
- import { Pi as n } from "./chunks/constants-BmCvHbkL.mjs";
1
+ import { n as e, t } from "./chunks/blok-DCc23rzA.mjs";
2
+ import { Pi as n } from "./chunks/constants-C3-Lh6Fs.mjs";
3
3
  import { t as r } from "./chunks/objectSpread2-jlBcdYeb.mjs";
4
- import { D as i, O as a, T as o, a as s, c, i as l, k as u, l as d, n as f, o as p, s as m, t as h } from "./chunks/tools-BdoYHyV0.mjs";
4
+ import { D as i, O as a, T as o, a as s, c, i as l, k as u, l as d, n as f, o as p, s as m, t as h } from "./chunks/tools-fEI-EVng.mjs";
5
5
  //#region src/full.ts
6
6
  var g = {
7
7
  paragraph: {
package/dist/react.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunks/chunk-BL1yB9zm.cjs`);const e=require(`./chunks/blok-BosfCfPX.cjs`),t=require(`./chunks/objectSpread2-iNkE6aJh.cjs`);let n=require(`react`),r=require(`react/jsx-runtime`);var i=new WeakMap;function a(e,t){i.set(e,t)}function o(e){return i.get(e)}function s(e){i.delete(e)}function c(r,i){let[o,c]=(0,n.useState)(null),u=(0,n.useRef)(r);u.current=r;let d=(0,n.useRef)({editor:null,holder:null,destroyTimeout:null,isDestroyed:!1,depsToken:null}),f=(0,n.useMemo)(()=>({}),i==null?[]:i);(0,n.useEffect)(()=>{if(typeof window>`u`)return;let n=d.current;if(n.destroyTimeout!==null&&(clearTimeout(n.destroyTimeout),n.destroyTimeout=null),n.editor!==null&&!n.isDestroyed&&n.depsToken===f)return c(n.editor),()=>{l(n,c)};if(n.editor!==null&&!n.isDestroyed){s(n.editor);try{n.editor.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,c(null)}let r=document.createElement(`div`);n.holder=r,n.isDestroyed=!1,n.depsToken=f;let i=u.current,o=new e.t(t.t(t.t({},i),{},{holder:r,onReady:()=>{var e,t;(e=(t=u.current).onReady)==null||e.call(t)},onChange:(...e)=>{var t,n;(t=(n=u.current).onChange)==null||t.call(n,...e)}}));return n.editor=o,a(o,r),o.isReady.then(()=>{n.editor===o&&!n.isDestroyed&&c(o)}).catch(()=>{if(n.editor===o&&!n.isDestroyed){s(o);try{o.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,c(null)}}),()=>{l(n,c)}},[f]);let{readOnly:p}=r;(0,n.useEffect)(()=>{o!==null&&o.readOnly.set(p==null?!1:p)},[o,p]);let{autofocus:m}=r;return(0,n.useEffect)(()=>{o===null||!m||o.focus()},[o,m]),o}function l(e,t){e.destroyTimeout=setTimeout(()=>{if(e.editor!==null){s(e.editor);try{e.editor.destroy()}catch(e){}e.editor=null,e.holder=null,e.isDestroyed=!0,e.destroyTimeout=null,t(null)}},0)}var u=[`editor`],d=(0,n.forwardRef)(function(i,a){let{editor:s}=i,c=e.i(i,u),l=(0,n.useRef)(null);return(0,n.useEffect)(()=>{if(s===null||l.current===null)return;let e=o(s);if(e!==void 0)return l.current.appendChild(e),()=>{e.remove()}},[s]),(0,r.jsx)(`div`,t.t({ref:e=>{if(l.current=e,typeof a==`function`)a(e);else if(a!=null){let t=a;t.current=e}}},c))});exports.BlokContent=d,exports.useBlok=c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunks/chunk-BL1yB9zm.cjs`);const e=require(`./chunks/blok-C8_pY9Bg.cjs`),t=require(`./chunks/objectSpread2-iNkE6aJh.cjs`);let n=require(`react`),r=require(`react/jsx-runtime`);var i=new WeakMap;function a(e,t){i.set(e,t)}function o(e){return i.get(e)}function s(e){i.delete(e)}function c(r,i){let[o,c]=(0,n.useState)(null),u=(0,n.useRef)(r);u.current=r;let d=(0,n.useRef)({editor:null,holder:null,destroyTimeout:null,isDestroyed:!1,depsToken:null}),f=(0,n.useMemo)(()=>({}),i==null?[]:i);(0,n.useEffect)(()=>{if(typeof window>`u`)return;let n=d.current;if(n.destroyTimeout!==null&&(clearTimeout(n.destroyTimeout),n.destroyTimeout=null),n.editor!==null&&!n.isDestroyed&&n.depsToken===f)return c(n.editor),()=>{l(n,c)};if(n.editor!==null&&!n.isDestroyed){s(n.editor);try{n.editor.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,c(null)}let r=document.createElement(`div`);n.holder=r,n.isDestroyed=!1,n.depsToken=f;let i=u.current,o=new e.t(t.t(t.t({},i),{},{holder:r,onReady:()=>{var e,t;(e=(t=u.current).onReady)==null||e.call(t)},onChange:(...e)=>{var t,n;(t=(n=u.current).onChange)==null||t.call(n,...e)}}));return n.editor=o,a(o,r),o.isReady.then(()=>{n.editor===o&&!n.isDestroyed&&c(o)}).catch(()=>{if(n.editor===o&&!n.isDestroyed){s(o);try{o.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,c(null)}}),()=>{l(n,c)}},[f]);let{readOnly:p}=r;(0,n.useEffect)(()=>{o!==null&&o.readOnly.set(p==null?!1:p)},[o,p]);let{autofocus:m}=r;return(0,n.useEffect)(()=>{o===null||!m||o.focus()},[o,m]),o}function l(e,t){e.destroyTimeout=setTimeout(()=>{if(e.editor!==null){s(e.editor);try{e.editor.destroy()}catch(e){}e.editor=null,e.holder=null,e.isDestroyed=!0,e.destroyTimeout=null,t(null)}},0)}var u=[`editor`],d=(0,n.forwardRef)(function(i,a){let{editor:s}=i,c=e.i(i,u),l=(0,n.useRef)(null);return(0,n.useEffect)(()=>{if(s===null||l.current===null)return;let e=o(s);if(e!==void 0)return l.current.appendChild(e),()=>{e.remove()}},[s]),(0,r.jsx)(`div`,t.t({ref:e=>{if(l.current=e,typeof a==`function`)a(e);else if(a!=null){let t=a;t.current=e}}},c))});exports.BlokContent=d,exports.useBlok=c;
package/dist/react.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as e, t } from "./chunks/blok-CXB-exXU.mjs";
1
+ import { i as e, t } from "./chunks/blok-DCc23rzA.mjs";
2
2
  import { t as n } from "./chunks/objectSpread2-jlBcdYeb.mjs";
3
3
  import { forwardRef as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
4
4
  import { jsx as c } from "react/jsx-runtime";
package/dist/tools.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/constants-ChsAFZ8F.cjs`),t=require(`./chunks/tools-DmEzyrn3.cjs`);exports.Audio=t.g,exports.Bold=t.l,exports.Bookmark=t.u,exports.Callout=t.w,exports.Code=t.y,exports.Column=t.p,exports.ColumnList=t.m,exports.Columns=t.f,exports.Convert=e.m,exports.Database=t.C,exports.DatabaseRow=t.S,exports.Divider=t.x,exports.Embed=t.d,exports.File=t._,exports.Header=t.O,exports.Image=t.v,exports.InlineCode=t.r,exports.Italic=t.c,exports.Link=t.s,exports.List=t.D,exports.Marker=t.o,exports.Paragraph=t.k,exports.Quote=t.b,exports.Strikethrough=t.i,exports.Table=t.E,exports.Toggle=t.T,exports.Underline=t.a,exports.Video=t.h,exports.defaultBlockTools=t.t,exports.defaultInlineTools=t.n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/constants-R70ypRAK.cjs`),t=require(`./chunks/tools-DcbePIHF.cjs`);exports.Audio=t.g,exports.Bold=t.l,exports.Bookmark=t.u,exports.Callout=t.w,exports.Code=t.y,exports.Column=t.p,exports.ColumnList=t.m,exports.Columns=t.f,exports.Convert=e.m,exports.Database=t.C,exports.DatabaseRow=t.S,exports.Divider=t.x,exports.Embed=t.d,exports.File=t._,exports.Header=t.O,exports.Image=t.v,exports.InlineCode=t.r,exports.Italic=t.c,exports.Link=t.s,exports.List=t.D,exports.Marker=t.o,exports.Paragraph=t.k,exports.Quote=t.b,exports.Strikethrough=t.i,exports.Table=t.E,exports.Toggle=t.T,exports.Underline=t.a,exports.Video=t.h,exports.defaultBlockTools=t.t,exports.defaultInlineTools=t.n;
package/dist/tools.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { m as e } from "./chunks/constants-BmCvHbkL.mjs";
2
- import { C as t, D as n, E as r, O as i, S as a, T as o, _ as s, a as c, b as l, c as u, d, f, g as p, h as m, i as h, k as g, l as _, m as v, n as y, o as b, p as x, r as S, s as C, t as w, u as T, v as E, w as D, x as O, y as k } from "./chunks/tools-BdoYHyV0.mjs";
1
+ import { m as e } from "./chunks/constants-C3-Lh6Fs.mjs";
2
+ import { C as t, D as n, E as r, O as i, S as a, T as o, _ as s, a as c, b as l, c as u, d, f, g as p, h as m, i as h, k as g, l as _, m as v, n as y, o as b, p as x, r as S, s as C, t as w, u as T, v as E, w as D, x as O, y as k } from "./chunks/tools-fEI-EVng.mjs";
3
3
  export { p as Audio, _ as Bold, T as Bookmark, D as Callout, k as Code, x as Column, v as ColumnList, f as Columns, e as Convert, t as Database, a as DatabaseRow, O as Divider, d as Embed, s as File, i as Header, E as Image, S as InlineCode, u as Italic, C as Link, n as List, b as Marker, g as Paragraph, l as Quote, h as Strikethrough, r as Table, o as Toggle, c as Underline, m as Video, w as defaultBlockTools, y as defaultInlineTools };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackuait/blok",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
4
4
  "description": "Blok — headless, highly extensible rich text editor built for developers who need to implement a block-based editing experience (similar to Notion) without building it from scratch",
5
5
  "module": "dist/blok.mjs",
6
6
  "main": "./dist/blok.cjs",
@@ -149,8 +149,7 @@
149
149
  "mdast-util-gfm": "^3.1.0",
150
150
  "mdast-util-math": "^3.0.0",
151
151
  "micromark-extension-gfm": "^3.0.0",
152
- "micromark-extension-math": "^3.1.0",
153
- "nanoid": "5.1.9"
152
+ "micromark-extension-math": "^3.1.0"
154
153
  },
155
154
  "devDependencies": {
156
155
  "@aiden0z/pptx-renderer": "^1.1.0",
@@ -204,6 +203,7 @@
204
203
  "katex": "^0.16.44",
205
204
  "mermaid": "^11.15.0",
206
205
  "music-metadata": "^11.13.0",
206
+ "nanoid": "5.1.9",
207
207
  "playwright": "1.59.1",
208
208
  "postcss": "8.5.10",
209
209
  "prismjs": "^1.30.0",
package/src/blok.ts CHANGED
@@ -36,9 +36,11 @@ class Blok {
36
36
  private readonly initialConfiguration: BlokConfig|string|undefined;
37
37
 
38
38
  /**
39
- * Promise that resolves when core modules are ready and UI is rendered on the page
39
+ * Promise that resolves when core modules are ready and UI is rendered on the page.
40
+ * Resolves with the fully-initialized Blok instance, so awaiting it narrows a
41
+ * pre-ready reference (see {@link PendingBlok}) to the complete API surface.
40
42
  */
41
- public isReady: Promise<void>;
43
+ public isReady: Promise<Blok>;
42
44
 
43
45
  /**
44
46
  * Stores destroy method implementation.
@@ -218,7 +220,7 @@ class Blok {
218
220
 
219
221
  Object.setPrototypeOf(this, null);
220
222
 
221
- return;
223
+ return this;
222
224
  }
223
225
 
224
226
  this.exportAPI(blok);
@@ -276,6 +278,8 @@ class Blok {
276
278
  * @todo pass API as an argument. It will allow to use Blok's API when blok is ready
277
279
  */
278
280
  onReady();
281
+
282
+ return this;
279
283
  });
280
284
  }
281
285
 
@@ -416,7 +416,7 @@ export class BlocksAPI extends Module {
416
416
  return this.Blok.BlockManager.composeBlock({
417
417
  id,
418
418
  tool: type || (this.config.defaultBlock as string),
419
- data: data as BlockToolData,
419
+ data: data,
420
420
  tunes,
421
421
  parentId: parent,
422
422
  contentIds: content,
@@ -516,7 +516,7 @@ export class BlockManager extends Module {
516
516
  // Those nested inserts sync to Yjs. If fromJSON() ran after, it would wipe
517
517
  // them (fromJSON replaces the entire Yjs array). Running fromJSON first
518
518
  // ensures nested blocks created during rendered() persist in Yjs.
519
- const blockDataArray: OutputBlockData<string, Record<string, unknown>>[] = blocks.map(block => {
519
+ const blockDataArray: OutputBlockData[] = blocks.map(block => {
520
520
  const tunes = block.preservedTunes;
521
521
 
522
522
  return {
@@ -1410,7 +1410,7 @@ export class BlockManager extends Module {
1410
1410
  * @param blocks - the fully reconciled blocks about to be handed to Yjs
1411
1411
  */
1412
1412
  private assertInsertManyHierarchy(blocks: Block[]): void {
1413
- const snapshot: OutputBlockData<string, Record<string, unknown>>[] = blocks.map((block) => ({
1413
+ const snapshot: OutputBlockData[] = blocks.map((block) => ({
1414
1414
  id: block.id,
1415
1415
  type: block.name,
1416
1416
  data: {},
@@ -6,7 +6,7 @@ import type { OutputBlockData } from '../../../../types/data-formats/output-data
6
6
  * Type alias for OutputBlockData with concrete types for the Yjs serializer.
7
7
  * Uses Record<string, unknown> for data to avoid the default `any` type.
8
8
  */
9
- export type YjsOutputBlockData = OutputBlockData<string, Record<string, unknown>>;
9
+ export type YjsOutputBlockData = OutputBlockData;
10
10
 
11
11
  /**
12
12
  * Characters that mark potential undo checkpoint positions.
@@ -33,7 +33,7 @@ type LegacyListItem = LegacyListItemObject | OldChecklistItem | string;
33
33
  /**
34
34
  * Legacy list data structure for data model transformation.
35
35
  */
36
- interface LegacyListData {
36
+ type LegacyListData = {
37
37
  style: 'unordered' | 'ordered' | 'checklist';
38
38
  items: LegacyListItem[];
39
39
  start?: number;
@@ -45,7 +45,7 @@ interface LegacyListData {
45
45
  * Blok has no dedicated checklist tool — checklist is a style of the List tool —
46
46
  * so this is expanded into per-item flat `list` blocks with style 'checklist'.
47
47
  */
48
- interface LegacyChecklistData {
48
+ type LegacyChecklistData = {
49
49
  items: LegacyListItem[];
50
50
  }
51
51
 
@@ -54,7 +54,7 @@ interface LegacyChecklistData {
54
54
  * Old format: { type: "linkTool", data: { link, meta: { title, description, image: { url }, favicon, domain } } }
55
55
  * Maps to Blok's flat Bookmark data shape (see types BookmarkMeta).
56
56
  */
57
- interface LegacyLinkToolData {
57
+ type LegacyLinkToolData = {
58
58
  link: string;
59
59
  meta?: {
60
60
  title?: string;
@@ -70,7 +70,7 @@ interface LegacyLinkToolData {
70
70
  * Legacy toggle list data structure for data model transformation.
71
71
  * Old format: { title: string, isExpanded?: boolean, body: { blocks: [], time, version }, titleVariant?: number }
72
72
  */
73
- interface LegacyToggleListData {
73
+ type LegacyToggleListData = {
74
74
  title: string;
75
75
  isExpanded?: boolean;
76
76
  titleVariant?: number;
@@ -85,7 +85,7 @@ interface LegacyToggleListData {
85
85
  * Legacy callout data structure for data model transformation.
86
86
  * Old format: { title?: string, body: { blocks: [] } | null, variant, emoji, isEmojiVisible }
87
87
  */
88
- interface LegacyCalloutData {
88
+ type LegacyCalloutData = {
89
89
  title?: string;
90
90
  body?: {
91
91
  blocks?: OutputBlockData[];
@@ -311,7 +311,7 @@ const isLegacyToggleListBlock = (block: OutputBlockData): block is OutputBlockDa
311
311
  return false;
312
312
  }
313
313
 
314
- const data = block.data as Record<string, unknown>;
314
+ const data = block.data;
315
315
 
316
316
  return typeof data === 'object' && data !== null && 'title' in data;
317
317
  };
@@ -326,7 +326,7 @@ const isLegacyCalloutBlock = (block: OutputBlockData): block is OutputBlockData<
326
326
  return false;
327
327
  }
328
328
 
329
- const data = block.data as Record<string, unknown>;
329
+ const data = block.data;
330
330
 
331
331
  return typeof data === 'object' && data !== null && 'body' in data;
332
332
  };
@@ -761,7 +761,7 @@ const expandCalloutToHierarchical = (
761
761
  * can't silently lose information.
762
762
  */
763
763
  const expandImageToHierarchical = (block: OutputBlockData, warned: Set<string>): OutputBlockData => {
764
- const rawData = (block.data ?? {}) as Record<string, unknown>;
764
+ const rawData = (block.data ?? {});
765
765
  const {
766
766
  file,
767
767
  url: flatUrl,
@@ -858,7 +858,7 @@ const expandLinkToolToHierarchical = (
858
858
  const expandQuoteToHierarchical = (block: OutputBlockData, warned: Set<string>): OutputBlockData[] => {
859
859
  warnLossyQuoteFields(block, warned);
860
860
 
861
- const rawData = (block.data ?? {}) as Record<string, unknown>;
861
+ const rawData = (block.data ?? {});
862
862
  const { caption, alignment: _alignment, ...rest } = rawData;
863
863
 
864
864
  const quoteBlock: OutputBlockData = {
@@ -897,7 +897,7 @@ const expandQuoteToHierarchical = (block: OutputBlockData, warned: Set<string>):
897
897
  */
898
898
  const expandTableToHierarchical = (block: OutputBlockData): OutputBlockData[] => {
899
899
  const tableId = block.id ?? generateBlockId();
900
- const rawData = (block.data ?? {}) as Record<string, unknown>;
900
+ const rawData = (block.data ?? {});
901
901
  const { content: _content, withHeadings, withHeadingColumn, stretched, ...restData } = rawData;
902
902
  const rows = getTableContentRows(rawData) ?? [];
903
903
  const childBlocks: OutputBlockData[] = [];
@@ -977,7 +977,7 @@ const WARNING_EMOJI = '⚠️';
977
977
  */
978
978
  const expandWarningToHierarchical = (block: OutputBlockData): OutputBlockData[] => {
979
979
  const calloutId = block.id ?? generateBlockId();
980
- const data = (block.data ?? {}) as Record<string, unknown>;
980
+ const data = (block.data ?? {});
981
981
  const title = typeof data.title === 'string' ? data.title : '';
982
982
  const message = typeof data.message === 'string' ? data.message : '';
983
983
 
@@ -1021,7 +1021,7 @@ const expandWarningToHierarchical = (block: OutputBlockData): OutputBlockData[]
1021
1021
  * equivalent and is dropped + warned once per pass.
1022
1022
  */
1023
1023
  const expandAttachesToHierarchical = (block: OutputBlockData, warned: Set<string>): OutputBlockData => {
1024
- const data = (block.data ?? {}) as Record<string, unknown>;
1024
+ const data = (block.data ?? {});
1025
1025
  const file = (typeof data.file === 'object' && data.file !== null ? data.file : {}) as Record<string, unknown>;
1026
1026
  const url = typeof file.url === 'string' ? file.url : '';
1027
1027
  const title = typeof data.title === 'string' ? data.title : undefined;
@@ -1389,7 +1389,7 @@ const isFlatModelCalloutBlock = (block: OutputBlockData): boolean => {
1389
1389
  return false;
1390
1390
  }
1391
1391
 
1392
- const data = block.data as Record<string, unknown>;
1392
+ const data = block.data;
1393
1393
 
1394
1394
  return typeof data === 'object' && data !== null && !('body' in data);
1395
1395
  };
@@ -1404,7 +1404,7 @@ const processRootCalloutItem = (
1404
1404
  ): OutputBlockData => {
1405
1405
  markBlockAsProcessed(block.id, processedIds);
1406
1406
 
1407
- const data = block.data as Record<string, unknown>;
1407
+ const data = block.data;
1408
1408
 
1409
1409
  // Map backgroundColor preset → variant
1410
1410
  const backgroundColor = data.backgroundColor as string | null | undefined;
@@ -1907,7 +1907,7 @@ export const reclaimDetachedTableCells = (blocks: OutputBlockData[]): OutputBloc
1907
1907
  });
1908
1908
  });
1909
1909
 
1910
- return { ...block, data: { ...(block.data as Record<string, unknown>), content: newContent } } as OutputBlockData;
1910
+ return { ...block, data: { ...(block.data), content: newContent } } as OutputBlockData;
1911
1911
  }
1912
1912
 
1913
1913
  return block;
@@ -15,7 +15,7 @@ import { resolvePosition } from './popover-position';
15
15
  import { stripPopoverAttribute } from '../top-layer';
16
16
  import { twMerge } from '../tw';
17
17
 
18
- import type { PopoverParams } from '@/types/utils/popover/popover';
18
+ import type { PopoverParams, Flipper as FlipperHandle } from '@/types/utils/popover/popover';
19
19
  import { PopoverEvent } from '@/types/utils/popover/popover-event';
20
20
 
21
21
 
@@ -51,9 +51,12 @@ if (typeof document !== 'undefined' && !(document as unknown as Record<string, u
51
51
  */
52
52
  export class PopoverDesktop extends PopoverAbstract {
53
53
  /**
54
- * Flipper - module for keyboard iteration between elements
54
+ * Flipper - module for keyboard iteration between elements.
55
+ * Typed as the published structural handle so a reused flipper passed via
56
+ * params (also the handle type) assigns cleanly; `new Flipper()` is
57
+ * structurally assignable to it.
55
58
  */
56
- public flipper: Flipper | undefined;
59
+ public flipper: FlipperHandle | undefined;
57
60
 
58
61
  /**
59
62
  * Popover nesting level. 0 value means that it is a root popover
@@ -6,45 +6,12 @@ import {
6
6
  } from './top-layer';
7
7
  import { twJoin } from './tw';
8
8
 
9
- /**
10
- * Tooltip supported content
11
- */
12
- export type TooltipContent = HTMLElement | DocumentFragment | Node | string;
13
-
14
- /**
15
- * Base options interface for tooltips
16
- */
17
- export interface TooltipOptions {
18
- /**
19
- * Tooltip placement: top|bottom|left|right
20
- */
21
- placement?: string;
22
-
23
- /**
24
- * Tooltip top margin
25
- */
26
- marginTop?: number;
27
-
28
- /**
29
- * Tooltip left margin
30
- */
31
- marginLeft?: number;
32
-
33
- /**
34
- * Tooltip right margin
35
- */
36
- marginRight?: number;
9
+ // TooltipContent / TooltipOptions are declared in the published types
10
+ // (types/api/tooltip.d.ts) as the single source of truth, so the package's
11
+ // declaration surface stays self-contained and never re-exports raw src.
12
+ import type { TooltipContent, TooltipOptions } from '@/types/api/tooltip';
37
13
 
38
- /**
39
- * Tooltip bottom margin
40
- */
41
- marginBottom?: number;
42
-
43
- /**
44
- * Timout before showing
45
- */
46
- delay?: number;
47
- }
14
+ export type { TooltipContent, TooltipOptions };
48
15
 
49
16
  const DEFAULT_OFFSET = 10;
50
17
  const TOOLTIP_ROLE = 'tooltip';
@@ -1,4 +1,3 @@
1
- import type { BlockToolData } from '../../types';
2
1
  import type { BlokModules } from '../types-internal/blok-modules';
3
2
  import type { SanitizerConfigBuilder } from '../components/modules/paste/sanitizer-config';
4
3
  import type { ToolRegistry } from '../components/modules/paste/tool-registry';
@@ -93,7 +92,7 @@ export class MarkdownHandler extends BasePasteHandler implements PasteHandler {
93
92
  BlockManager.composeBlock({
94
93
  id,
95
94
  tool: type,
96
- data: blockData as BlockToolData,
95
+ data: blockData,
97
96
  parentId: parent,
98
97
  })
99
98
  );
@@ -385,20 +385,38 @@
385
385
  color: var(--blok-text-primary);
386
386
  }
387
387
 
388
- /* ----- caption row (full-width footer) -------------------- */
388
+ /* ----- caption row (full-width footer) --------------------
389
+ The row is a single-track grid wrapper so it can collapse to zero height
390
+ (grid-template-rows 1fr → 0fr) when the caption is toggled, while the inner
391
+ element holds the actual padding/border that fade out with it. */
389
392
  [data-blok-tool="audio"] .blok-audio-caption-row {
390
393
  grid-column: 1 / -1;
391
394
  grid-row: 2;
395
+ display: grid;
396
+ grid-template-rows: 1fr;
397
+ transition:
398
+ grid-template-rows var(--blok-duration-slow) var(--blok-ease-popover),
399
+ opacity var(--blok-duration-slow) var(--blok-ease-popover);
400
+ }
401
+ [data-blok-tool="audio"] .blok-audio-caption-row.is-collapsed {
402
+ grid-template-rows: 0fr;
403
+ opacity: 0;
404
+ }
405
+ /* overflow:hidden + min-height:0 lets the grid track collapse fully to 0; the
406
+ padding/border live on the caption child below so they get clipped too. */
407
+ [data-blok-tool="audio"] .blok-audio-caption-row__inner {
408
+ min-height: 0;
409
+ overflow: hidden;
392
410
  display: flex;
393
411
  align-items: flex-start;
394
412
  gap: var(--blok-space-2);
395
- padding-top: var(--blok-space-2-5);
396
- border-top: 1px solid var(--blok-border-subtle);
397
413
  }
398
414
  [data-blok-tool="audio"] .blok-audio-caption {
399
415
  flex: 1 1 auto;
400
416
  min-width: 0;
401
417
  display: block;
418
+ padding-top: var(--blok-space-2-5);
419
+ border-top: 1px solid var(--blok-border-subtle);
402
420
  font-size: var(--blok-font-size-ui-label);
403
421
  color: var(--blok-text-secondary);
404
422
  line-height: var(--blok-line-height-body);
@@ -528,4 +546,6 @@
528
546
  }
529
547
  /* The badge still appears while playing — it just holds steady. */
530
548
  [data-blok-tool="audio"] .blok-audio-eq { transition: none; }
549
+ /* Caption appears/disappears instantly (JS also takes the instant path). */
550
+ [data-blok-tool="audio"] .blok-audio-caption-row { transition: none; }
531
551
  }