@jackuait/blok 0.23.3 → 0.23.4

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.
@@ -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, Ai as o, An as s, Ar as c, At as l, B as u, Bn as d, Br as f, Bt as p, C as m, Ci as h, Cn as g, Cr as _, Ct as v, Dn as y, Dr as b, Dt as x, Ea as S, Ei as C, En as w, Er as T, Et as E, F as D, Fn as ee, Fr as O, Ft as k, G as A, Gn as te, Gr as j, Gt as M, H as N, Hn as ne, Hr as P, Ht as re, I as F, In as ie, Ir as ae, It as I, J as oe, Jn as L, Jr as se, Jt as ce, Kn as le, Kr as ue, Kt as de, L as R, Ln as fe, Lr as pe, Lt as me, Ma as z, Mn as he, Mr as ge, Mt as _e, Na as ve, Ni as ye, Nn as be, Nr as xe, Nt as Se, On as Ce, Or as we, Ot as Te, P as Ee, Pi as De, Pn as Oe, Pr as ke, Pt as Ae, Q as je, Qn as Me, Qr as Ne, Qt as Pe, R as Fe, Rn as Ie, Rr as Le, Rt as Re, S as ze, Si as Be, Sn as Ve, Sr as He, St as Ue, T as We, Ti as Ge, Tn as Ke, Tr as qe, Tt as Je, U as Ye, Un as Xe, Ur as Ze, Ut as Qe, Vn as $e, Vr as et, Vt as tt, W as B, Wn as nt, Wr as rt, Wt as it, X as at, Xn as ot, Xr as st, Xt as ct, Y as lt, Yn as ut, Yr as dt, Yt as ft, Z as pt, Zi as mt, Zn as ht, Zt as gt, _ as _t, _n as vt, _r as yt, _t as bt, a as xt, ai as St, ar as Ct, at as wt, b as Tt, bi as V, bn as Et, br as Dt, bt as Ot, c as kt, cn as At, cr as jt, ct as Mt, d as Nt, di as Pt, dn as Ft, dr as It, dt as Lt, ei as Rt, en as zt, er as Bt, et as Vt, f as Ht, fn as Ut, fr as Wt, ft as Gt, g as Kt, gi as qt, gn as Jt, gr as Yt, gt as Xt, h as Zt, hn as Qt, hr as $t, ht as en, i as tn, ia as nn, ii as rn, in as an, ir as on, it as sn, jn as cn, jr as ln, jt as un, ki as H, kn as dn, kr as fn, kt as pn, l as mn, li as hn, ln as gn, lr as _n, lt as vn, mn as yn, mr as bn, mt as xn, n as Sn, ni as Cn, nn as wn, nr as Tn, nt as En, o as Dn, oa as On, oi as kn, on as An, or as jn, ot as Mn, p as Nn, pi as Pn, pn as Fn, pr as In, pt as Ln, q as Rn, qr as zn, qt as Bn, r as Vn, ri as Hn, rr as Un, rt as Wn, s as Gn, si as Kn, sn as qn, sr as Jn, st as Yn, t as Xn, ti as Zn, tr as Qn, u as U, ui as $n, un as er, ur as tr, ut as nr, v as rr, vn as ir, vr as ar, vt as or, wi as sr, wn as cr, wr as lr, wt as ur, x as dr, xi as fr, xn as pr, xr as mr, xt as hr, y as gr, yn as _r, yr as vr, yt as yr, z as br, zn as xr, zr as Sr, zt as Cr } from "./constants-BJ79cqMa.mjs";
2
+ import { $ as n, $n as r, $r as i, $t as a, Ai as o, An as s, Ar as c, At as l, B as u, Bn as d, Br as f, Bt as p, C as m, Ci as h, Cn as g, Cr as _, Ct as v, Dn as y, Dr as b, Dt as x, Ea as S, Ei as C, En as w, Er as T, Et as E, F as D, Fn as ee, Fr as O, Ft as k, G as A, Gn as te, Gr as j, Gt as M, H as N, Hn as ne, Hr as P, Ht as re, I as F, In as ie, Ir as ae, It as I, J as oe, Jn as L, Jr as se, Jt as ce, Kn as le, Kr as ue, Kt as de, L as R, Ln as fe, Lr as pe, Lt as me, Ma as z, Mn as he, Mr as ge, Mt as _e, Na as ve, Ni as ye, Nn as be, Nr as xe, Nt as Se, On as Ce, Or as we, Ot as Te, P as Ee, Pi as De, Pn as Oe, Pr as ke, Pt as Ae, Q as je, Qn as Me, Qr as Ne, Qt as Pe, R as Fe, Rn as Ie, Rr as Le, Rt as Re, S as ze, Si as Be, Sn as Ve, Sr as He, St as Ue, T as We, Ti as Ge, Tn as Ke, Tr as qe, Tt as Je, U as Ye, Un as Xe, Ur as Ze, Ut as Qe, Vn as $e, Vr as et, Vt as tt, W as B, Wn as nt, Wr as rt, Wt as it, X as at, Xn as ot, Xr as st, Xt as ct, Y as lt, Yn as ut, Yr as dt, Yt as ft, Z as pt, Zi as mt, Zn as ht, Zt as gt, _ as _t, _n as vt, _r as yt, _t as bt, a as xt, ai as St, ar as Ct, at as wt, b as Tt, bi as V, bn as Et, br as Dt, bt as Ot, c as kt, cn as At, cr as jt, ct as Mt, d as Nt, di as Pt, dn as Ft, dr as It, dt as Lt, ei as Rt, en as zt, er as Bt, et as Vt, f as Ht, fn as Ut, fr as Wt, ft as Gt, g as Kt, gi as qt, gn as Jt, gr as Yt, gt as Xt, h as Zt, hn as Qt, hr as $t, ht as en, i as tn, ia as nn, ii as rn, in as an, ir as on, it as sn, jn as cn, jr as ln, jt as un, ki as H, kn as dn, kr as fn, kt as pn, l as mn, li as hn, ln as gn, lr as _n, lt as vn, mn as yn, mr as bn, mt as xn, n as Sn, ni as Cn, nn as wn, nr as Tn, nt as En, o as Dn, oa as On, oi as kn, on as An, or as jn, ot as Mn, p as Nn, pi as Pn, pn as Fn, pr as In, pt as Ln, q as Rn, qr as zn, qt as Bn, r as Vn, ri as Hn, rr as Un, rt as Wn, s as Gn, si as Kn, sn as qn, sr as Jn, st as Yn, t as Xn, ti as Zn, tr as Qn, u as U, ui as $n, un as er, ur as tr, ut as nr, v as rr, vn as ir, vr as ar, vt as or, wi as sr, wn as cr, wr as lr, wt as ur, x as dr, xi as fr, xn as pr, xr as mr, xt as hr, y as gr, yn as _r, yr as vr, yt as yr, z as br, zn as xr, zr as Sr, zt as Cr } from "./constants-DZtdGLlr.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 wr } from "./lightweight-i18n-Cj88c8gl.mjs";
package/dist/full.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/blok-J3Lfa_bK.cjs`),t=require(`./chunks/constants-BZUc1kAY.cjs`),n=require(`./chunks/objectSpread2-iNkE6aJh.cjs`),r=require(`./chunks/tools-OHDv2C7w.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.Ma,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-qwtrt5R3.cjs`),t=require(`./chunks/constants-Y3Af_xZ7.cjs`),n=require(`./chunks/objectSpread2-iNkE6aJh.cjs`),r=require(`./chunks/tools-BmSYWm8L.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.Ma,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-1H9roBGf.mjs";
2
- import { Ma as n } from "./chunks/constants-BJ79cqMa.mjs";
1
+ import { n as e, t } from "./chunks/blok-BydOC-jj.mjs";
2
+ import { Ma as n } from "./chunks/constants-DZtdGLlr.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-ByOjWADT.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-DOZaLyYm.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-J3Lfa_bK.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(e,t){if(e===t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;let n=Array.isArray(e),r=Array.isArray(t);if(n!==r)return!1;if(n&&r)return e.length===t.length?e.every((e,n)=>c(e,t[n])):!1;let i=e,a=t,o=Object.keys(i),s=Object.keys(a);return o.length===s.length?o.every(e=>Object.prototype.hasOwnProperty.call(a,e)&&c(i[e],a[e])):!1}function l(r,i){let[o,l]=(0,n.useState)(null),d=(0,n.useRef)(r);d.current=r;let f=(0,n.useRef)({editor:null,holder:null,destroyTimeout:null,isDestroyed:!1,depsToken:null}),p=(0,n.useMemo)(()=>({}),i==null?[]:i);(0,n.useEffect)(()=>{if(typeof window>`u`)return;let n=f.current;if(n.destroyTimeout!==null&&(clearTimeout(n.destroyTimeout),n.destroyTimeout=null),n.editor!==null&&!n.isDestroyed&&n.depsToken===p)return l(n.editor),()=>{u(n,l)};if(n.editor!==null&&!n.isDestroyed){s(n.editor);try{n.editor.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,l(null)}let r=document.createElement(`div`);n.holder=r,n.isDestroyed=!1,n.depsToken=p;let i=d.current,o=new e.t(t.t(t.t({},i),{},{holder:r,onReady:()=>{var e,t;(e=(t=d.current).onReady)==null||e.call(t)},onChange:(...e)=>{var t,n;(t=(n=d.current).onChange)==null||t.call(n,...e)}}));return n.editor=o,a(o,r),o.isReady.then(()=>{n.editor===o&&!n.isDestroyed&&l(o)}).catch(()=>{if(n.editor===o&&!n.isDestroyed){s(o);try{o.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,l(null)}}),()=>{u(n,l)}},[p]);let{readOnly:m}=r;(0,n.useEffect)(()=>{o!==null&&o.readOnly.set(m==null?!1:m)},[o,m]);let{autofocus:h}=r;(0,n.useEffect)(()=>{o===null||!h||o.focus()},[o,h]);let{theme:g}=r;(0,n.useEffect)(()=>{o===null||g===void 0||o.theme.set(g)},[o,g]);let{width:_}=r;(0,n.useEffect)(()=>{o===null||_===void 0||o.width.set(_)},[o,_]);let{placeholder:v}=r;(0,n.useEffect)(()=>{o===null||v===void 0||o.placeholder.set(v)},[o,v]);let{data:y}=r,b=(0,n.useRef)(r.data),x=(0,n.useRef)(null),S=(0,n.useRef)(Promise.resolve());return(0,n.useEffect)(()=>{if(!(o===null||y===void 0)){if(x.current!==o){x.current=o,b.current=y;return}c(y,b.current)||(b.current=y,S.current=S.current.catch(()=>void 0).then(()=>o.render(y)))}},[o,y]),o}function u(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 d=[`editor`],f=(0,n.forwardRef)(function(i,a){let{editor:s}=i,c=e.i(i,d),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))}),p=`autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.onBeforePaste.onReady.onChange.inlineToolbar.tunes.style.theme.onThemeChange.scrollToBlock.user.resolveUser.notifierPosition.notifier.width`.split(`.`),m=[`deps`,`onReady`],h=new Set(p),g=(0,n.forwardRef)(function(i,a){let{deps:o,onReady:s}=i,c=e.i(i,m),u={},d={};for(let e of Object.keys(c)){let t=c[e];h.has(e)?u[e]=t:d[e]=t}let p=l(u,o);(0,n.useImperativeHandle)(a,()=>p,[p]);let g=(0,n.useRef)(s);return g.current=s,(0,n.useEffect)(()=>{if(p!==null){var e;(e=g.current)==null||e.call(g,p)}},[p]),(0,r.jsx)(f,t.t({editor:p},d))});exports.BlokContent=f,exports.BlokEditor=g,exports.useBlok=l;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunks/chunk-BL1yB9zm.cjs`);const e=require(`./chunks/blok-qwtrt5R3.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(e,t){if(e===t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;let n=Array.isArray(e),r=Array.isArray(t);if(n!==r)return!1;if(n&&r)return e.length===t.length?e.every((e,n)=>c(e,t[n])):!1;let i=e,a=t,o=Object.keys(i),s=Object.keys(a);return o.length===s.length?o.every(e=>Object.prototype.hasOwnProperty.call(a,e)&&c(i[e],a[e])):!1}function l(r,i){let[o,l]=(0,n.useState)(null),d=(0,n.useRef)(r);d.current=r;let f=(0,n.useRef)({editor:null,holder:null,destroyTimeout:null,isDestroyed:!1,depsToken:null}),p=(0,n.useMemo)(()=>({}),i==null?[]:i),m=(0,n.useRef)(r.data),h=(0,n.useRef)(null),g=(0,n.useRef)(Promise.resolve());(0,n.useEffect)(()=>{if(typeof window>`u`)return;let n=f.current;if(n.destroyTimeout!==null&&(clearTimeout(n.destroyTimeout),n.destroyTimeout=null),n.editor!==null&&!n.isDestroyed&&n.depsToken===p)return l(n.editor),()=>{u(n,l)};if(n.editor!==null&&!n.isDestroyed){s(n.editor);try{n.editor.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,l(null)}let r=document.createElement(`div`);n.holder=r,n.isDestroyed=!1,n.depsToken=p;let i=d.current,o=t.t(t.t({},i),{},{holder:r,onReady:()=>{var e,t;(e=(t=d.current).onReady)==null||e.call(t)},onChange:(...e)=>{var t,n;(t=(n=d.current).onChange)==null||t.call(n,...e)}});i.onSave&&(o.onSave=(...e)=>{var t,n;m.current=e[0],(t=(n=d.current).onSave)==null||t.call(n,...e)});let c=new e.t(o);return n.editor=c,a(c,r),c.isReady.then(()=>{n.editor===c&&!n.isDestroyed&&l(c)}).catch(()=>{if(n.editor===c&&!n.isDestroyed){s(c);try{c.destroy()}catch(e){}n.editor=null,n.holder=null,n.isDestroyed=!0,l(null)}}),()=>{u(n,l)}},[p]);let{readOnly:_}=r;(0,n.useEffect)(()=>{o!==null&&o.readOnly.set(_==null?!1:_)},[o,_]);let{autofocus:v}=r;(0,n.useEffect)(()=>{o===null||!v||o.focus()},[o,v]);let{theme:y}=r;(0,n.useEffect)(()=>{o===null||y===void 0||o.theme.set(y)},[o,y]);let{width:b}=r;(0,n.useEffect)(()=>{o===null||b===void 0||o.width.set(b)},[o,b]);let{placeholder:x}=r;(0,n.useEffect)(()=>{o===null||x===void 0||o.placeholder.set(x)},[o,x]);let{data:S}=r;return(0,n.useEffect)(()=>{if(!(o===null||S===void 0)){if(h.current!==o){h.current=o,m.current=S;return}c(S,m.current)||(m.current=S,g.current=g.current.catch(()=>void 0).then(()=>o.render(S)))}},[o,S]),o}function u(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 d=[`editor`],f=(0,n.forwardRef)(function(i,a){let{editor:s}=i,c=e.i(i,d),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))}),p=`autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.onBeforePaste.onReady.onChange.onSave.inlineToolbar.tunes.style.theme.onThemeChange.scrollToBlock.user.resolveUser.notifierPosition.notifier.width`.split(`.`),m=[`deps`,`onReady`],h=new Set(p),g=(0,n.forwardRef)(function(i,a){let{deps:o,onReady:s}=i,c=e.i(i,m),u={},d={};for(let e of Object.keys(c)){let t=c[e];h.has(e)?u[e]=t:d[e]=t}let p=l(u,o);(0,n.useImperativeHandle)(a,()=>p,[p]);let g=(0,n.useRef)(s);return g.current=s,(0,n.useEffect)(()=>{if(p!==null){var e;(e=g.current)==null||e.call(g,p)}},[p]),(0,r.jsx)(f,t.t({editor:p},d))});exports.BlokContent=f,exports.BlokEditor=g,exports.useBlok=l;
package/dist/react.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as e, t } from "./chunks/blok-1H9roBGf.mjs";
1
+ import { i as e, t } from "./chunks/blok-BydOC-jj.mjs";
2
2
  import { t as n } from "./chunks/objectSpread2-jlBcdYeb.mjs";
3
3
  import { forwardRef as r, useEffect as i, useImperativeHandle as a, useMemo as o, useRef as s, useState as c } from "react";
4
4
  import { jsx as l } from "react/jsx-runtime";
@@ -35,7 +35,7 @@ function h(e, r) {
35
35
  destroyTimeout: null,
36
36
  isDestroyed: !1,
37
37
  depsToken: null
38
- }), h = o(() => ({}), r == null ? [] : r);
38
+ }), h = o(() => ({}), r == null ? [] : r), _ = s(e.data), v = s(null), y = s(Promise.resolve());
39
39
  i(() => {
40
40
  if (typeof window > "u") return;
41
41
  let e = f.current;
@@ -51,7 +51,7 @@ function h(e, r) {
51
51
  }
52
52
  let r = document.createElement("div");
53
53
  e.holder = r, e.isDestroyed = !1, e.depsToken = h;
54
- let i = u.current, a = new t(n(n({}, i), {}, {
54
+ let i = u.current, a = n(n({}, i), {}, {
55
55
  holder: r,
56
56
  onReady: () => {
57
57
  var e, t;
@@ -61,14 +61,19 @@ function h(e, r) {
61
61
  var t, n;
62
62
  (t = (n = u.current).onChange) == null || t.call(n, ...e);
63
63
  }
64
- }));
65
- return e.editor = a, d(a, r), a.isReady.then(() => {
66
- e.editor === a && !e.isDestroyed && l(a);
64
+ });
65
+ i.onSave && (a.onSave = (...e) => {
66
+ var t, n;
67
+ _.current = e[0], (t = (n = u.current).onSave) == null || t.call(n, ...e);
68
+ });
69
+ let o = new t(a);
70
+ return e.editor = o, d(o, r), o.isReady.then(() => {
71
+ e.editor === o && !e.isDestroyed && l(o);
67
72
  }).catch(() => {
68
- if (e.editor === a && !e.isDestroyed) {
69
- p(a);
73
+ if (e.editor === o && !e.isDestroyed) {
74
+ p(o);
70
75
  try {
71
- a.destroy();
76
+ o.destroy();
72
77
  } catch (e) {}
73
78
  e.editor = null, e.holder = null, e.isDestroyed = !0, l(null);
74
79
  }
@@ -76,36 +81,36 @@ function h(e, r) {
76
81
  g(e, l);
77
82
  };
78
83
  }, [h]);
79
- let { readOnly: _ } = e;
84
+ let { readOnly: b } = e;
80
85
  i(() => {
81
- a !== null && a.readOnly.set(_ == null ? !1 : _);
82
- }, [a, _]);
83
- let { autofocus: v } = e;
86
+ a !== null && a.readOnly.set(b == null ? !1 : b);
87
+ }, [a, b]);
88
+ let { autofocus: x } = e;
84
89
  i(() => {
85
- a === null || !v || a.focus();
86
- }, [a, v]);
87
- let { theme: y } = e;
90
+ a === null || !x || a.focus();
91
+ }, [a, x]);
92
+ let { theme: S } = e;
88
93
  i(() => {
89
- a === null || y === void 0 || a.theme.set(y);
90
- }, [a, y]);
91
- let { width: b } = e;
94
+ a === null || S === void 0 || a.theme.set(S);
95
+ }, [a, S]);
96
+ let { width: C } = e;
92
97
  i(() => {
93
- a === null || b === void 0 || a.width.set(b);
94
- }, [a, b]);
95
- let { placeholder: x } = e;
98
+ a === null || C === void 0 || a.width.set(C);
99
+ }, [a, C]);
100
+ let { placeholder: w } = e;
96
101
  i(() => {
97
- a === null || x === void 0 || a.placeholder.set(x);
98
- }, [a, x]);
99
- let { data: S } = e, C = s(e.data), w = s(null), T = s(Promise.resolve());
102
+ a === null || w === void 0 || a.placeholder.set(w);
103
+ }, [a, w]);
104
+ let { data: T } = e;
100
105
  return i(() => {
101
- if (!(a === null || S === void 0)) {
102
- if (w.current !== a) {
103
- w.current = a, C.current = S;
106
+ if (!(a === null || T === void 0)) {
107
+ if (v.current !== a) {
108
+ v.current = a, _.current = T;
104
109
  return;
105
110
  }
106
- m(S, C.current) || (C.current = S, T.current = T.current.catch(() => void 0).then(() => a.render(S)));
111
+ m(T, _.current) || (_.current = T, y.current = y.current.catch(() => void 0).then(() => a.render(T)));
107
112
  }
108
- }, [a, S]), a;
113
+ }, [a, T]), a;
109
114
  }
110
115
  function g(e, t) {
111
116
  e.destroyTimeout = setTimeout(() => {
@@ -135,7 +140,7 @@ var _ = ["editor"], v = r(function(t, r) {
135
140
  t.current = e;
136
141
  }
137
142
  } }, o));
138
- }), y = /* @__PURE__ */ "autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.onBeforePaste.onReady.onChange.inlineToolbar.tunes.style.theme.onThemeChange.scrollToBlock.user.resolveUser.notifierPosition.notifier.width".split("."), b = ["deps", "onReady"], x = new Set(y), S = r(function(t, r) {
143
+ }), y = /* @__PURE__ */ "autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.onBeforePaste.onReady.onChange.onSave.inlineToolbar.tunes.style.theme.onThemeChange.scrollToBlock.user.resolveUser.notifierPosition.notifier.width".split("."), b = ["deps", "onReady"], x = new Set(y), S = r(function(t, r) {
139
144
  let { deps: o, onReady: c } = t, u = e(t, b), d = {}, f = {};
140
145
  for (let e of Object.keys(u)) {
141
146
  let t = u[e];
package/dist/tools.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/constants-BZUc1kAY.cjs`),t=require(`./chunks/tools-OHDv2C7w.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-Y3Af_xZ7.cjs`),t=require(`./chunks/tools-BmSYWm8L.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-BJ79cqMa.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-ByOjWADT.mjs";
1
+ import { m as e } from "./chunks/constants-DZtdGLlr.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-DOZaLyYm.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.23.3",
3
+ "version": "0.23.4",
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",
@@ -42,6 +42,12 @@ export class ModificationsObserver extends Module {
42
42
  */
43
43
  private readonly batchTime = modificationsObserverBatchTimeout;
44
44
 
45
+ /**
46
+ * Set once the module is destroyed so an in-flight serialization (onSave)
47
+ * doesn't call back into a torn-down editor after its promise resolves.
48
+ */
49
+ private destroyed = false;
50
+
45
51
  /**
46
52
  * Prepare the module
47
53
  * @param options - options used by the modification observer module
@@ -103,7 +109,7 @@ export class ModificationsObserver extends Module {
103
109
  * @param event - some of our custom change events
104
110
  */
105
111
  private particularBlockChanged(event: BlockMutationEvent): void {
106
- if (this.disabled || !isFunction(this.config.onChange)) {
112
+ if (this.disabled || (!isFunction(this.config.onChange) && !isFunction(this.config.onSave))) {
107
113
  return;
108
114
  }
109
115
 
@@ -127,14 +133,45 @@ export class ModificationsObserver extends Module {
127
133
  ? queuedEvents[0]
128
134
  : queuedEvents;
129
135
 
130
- if (this.config.onChange) {
136
+ if (isFunction(this.config.onChange)) {
131
137
  this.config.onChange(this.Blok.API.methods, eventsToEmit);
132
138
  }
133
139
 
140
+ if (isFunction(this.config.onSave)) {
141
+ this.emitOnSave();
142
+ }
143
+
134
144
  this.batchingOnChangeQueue.clear();
135
145
  }, this.batchTime);
136
146
  }
137
147
 
148
+ /**
149
+ * Serializes the editor and delivers the full OutputData to the consumer's
150
+ * `onSave` callback. Invoked once per batched change window, so a burst of
151
+ * edits results in a single serialization. Skips delivery if the module was
152
+ * destroyed while the (async) serialization was in flight.
153
+ */
154
+ private emitOnSave(): void {
155
+ void this.Blok.Saver.save()
156
+ .then((data) => {
157
+ if (this.destroyed || data === undefined) {
158
+ return;
159
+ }
160
+
161
+ const { onSave } = this.config;
162
+
163
+ if (isFunction(onSave)) {
164
+ onSave(data, this.Blok.API.methods);
165
+ }
166
+ })
167
+ .catch(() => {
168
+ /**
169
+ * Serialization failed — the Saver already surfaces the error via its
170
+ * own channel, so swallow here to avoid an unhandled rejection.
171
+ */
172
+ });
173
+ }
174
+
138
175
  /**
139
176
  * Cleans up the module: disconnects the MutationObserver and cancels any
140
177
  * pending batching timeout. Called by the editor's destroy() chain so that
@@ -144,6 +181,7 @@ export class ModificationsObserver extends Module {
144
181
  */
145
182
  public destroy(): void {
146
183
  this.disabled = true;
184
+ this.destroyed = true;
147
185
  this.mutationObserver.disconnect();
148
186
 
149
187
  if (this.batchingTimeout !== null) {
@@ -24,9 +24,17 @@ import type { UseBlokConfig } from './types';
24
24
  * mount, changing it to new *content* re-renders the editor via `render()` — no
25
25
  * recreation. Updates are deep-equal–deduped (a new reference with identical
26
26
  * content is a no-op, so it won't clobber the caret) and serialized (rapid
27
- * changes can't overlap). Read content via `onChange` or the ref
28
- * (`ref.current.save()`). For ad-hoc reloads you can still call
27
+ * changes can't overlap). For ad-hoc reloads you can still call
29
28
  * `ref.current.render(newData)`.
29
+ *
30
+ * Pair `data` with `onSave` for a true controlled component: `onSave` is the
31
+ * output half, firing (debounced) with the full serialized `OutputData` on every
32
+ * content change — no manual `ref.current.save()` polling. Echoing that payload
33
+ * straight back via `onSave={setData}` is safe and caret-stable: the adapter
34
+ * records the editor's own emitted output as the content baseline, so the
35
+ * `onSave → setState → data` round-trip deep-equals that baseline and is deduped
36
+ * to a no-op (no re-render, no caret reset, no recursion). Genuine external `data`
37
+ * changes still re-render in place.
30
38
  */
31
39
  export interface BlokEditorProps
32
40
  extends Omit<UseBlokConfig, 'onReady'>,
@@ -30,6 +30,7 @@ export const USE_BLOK_CONFIG_KEYS = [
30
30
  'onBeforePaste',
31
31
  'onReady',
32
32
  'onChange',
33
+ 'onSave',
33
34
  'inlineToolbar',
34
35
  'tunes',
35
36
  'style',
@@ -13,6 +13,10 @@ import type { BlokConfig, Blok, EditorWidth } from '@/types';
13
13
  * - `placeholder` — calls `editor.placeholder.set(value)`
14
14
  * - `data` — re-renders via `editor.render(value)` when content changes
15
15
  * (deep-equal–deduped and serialized; seeds the initial content at creation)
16
+ *
17
+ * The `onSave` config (inherited from `BlokConfig`) is the controlled output
18
+ * half: it fires with the full serialized `OutputData` on every content change,
19
+ * so `data` + `onSave` form a controlled component without manual `save()` calls.
16
20
  */
17
21
  export interface UseBlokConfig extends Omit<BlokConfig, 'holder'> {
18
22
  /** Editor content width mode. Synced reactively after mount via `editor.width.set()`. */
@@ -43,6 +43,17 @@ export function useBlok(config: UseBlokConfig, deps?: DependencyList): Blok | nu
43
43
  // eslint-disable-next-line react-hooks/exhaustive-deps
44
44
  const depsToken = useMemo(() => ({}), deps ?? []);
45
45
 
46
+ // Tracks the data the editor currently reflects — set when content is seeded
47
+ // or rendered (the reactive `data` effect below) AND when the editor emits its
48
+ // own serialized content via `onSave`. The latter is what makes a controlled
49
+ // `onSave -> setData -> data` round-trip a no-op: the echoed payload deep-equals
50
+ // this baseline, so the data effect skips the redundant render() (which would
51
+ // otherwise reset the caret). Declared here so the `onSave` wrapper below can
52
+ // update it before the consumer's setState re-runs the data effect.
53
+ const lastRenderedDataRef = useRef(config.data);
54
+ const seededEditorRef = useRef<Blok | null>(null);
55
+ const renderChainRef = useRef<Promise<void>>(Promise.resolve());
56
+
46
57
  // Main lifecycle effect
47
58
  useEffect(() => {
48
59
  if (typeof window === 'undefined') {
@@ -99,6 +110,19 @@ export function useBlok(config: UseBlokConfig, deps?: DependencyList): Blok | nu
99
110
  },
100
111
  };
101
112
 
113
+ // Only attach onSave when the consumer opted in: its mere presence makes the
114
+ // core serialize on every change batch, so an absent prop must stay absent.
115
+ // The wrapper reads through the ref so the latest callback is always used.
116
+ if (currentConfig.onSave) {
117
+ blokConfig.onSave = (...args: Parameters<NonNullable<UseBlokConfig['onSave']>>): void => {
118
+ // Record the editor's own serialized output as the rendered baseline so a
119
+ // controlled consumer echoing it straight back into `data` is a no-op —
120
+ // no redundant render(), no caret reset, no round-trip recursion.
121
+ lastRenderedDataRef.current = args[0];
122
+ configRef.current.onSave?.(...args);
123
+ };
124
+ }
125
+
102
126
  const blok = new BlokRuntime(blokConfig) as unknown as Blok;
103
127
  state.editor = blok;
104
128
  setHolder(blok, holder);
@@ -178,13 +202,12 @@ export function useBlok(config: UseBlokConfig, deps?: DependencyList): Blok | nu
178
202
  //
179
203
  // `data` seeds the editor at construction. Afterwards, changing the prop to
180
204
  // new *content* re-renders the editor via the public render() API — no
181
- // recreation. Updates are deep-equal–deduped (so a new reference with the
182
- // same content is a no-op and won't clobber the caret) and serialized (so
183
- // rapid changes can't trigger overlapping render passes).
205
+ // recreation. Updates are deep-equal–deduped against the editor's current
206
+ // content baseline (`lastRenderedDataRef`, declared above and also updated by
207
+ // the `onSave` wrapper) so a new reference with the same content — including
208
+ // the editor's own serialized output echoed back — is a no-op and won't
209
+ // clobber the caret. Renders are serialized so rapid changes can't overlap.
184
210
  const { data } = config;
185
- const lastRenderedDataRef = useRef(config.data);
186
- const seededEditorRef = useRef<Blok | null>(null);
187
- const renderChainRef = useRef<Promise<void>>(Promise.resolve());
188
211
  useEffect(() => {
189
212
  if (editor === null || data === undefined) {
190
213
  return;
@@ -187,6 +187,23 @@ export interface BlokConfig {
187
187
  */
188
188
  onChange?(api: API, event: BlockMutationEvent | BlockMutationEvent[]): void;
189
189
 
190
+ /**
191
+ * Fires with the full serialized {@link OutputData} whenever the content
192
+ * changes. This is the "output half" of a controlled editor: pair it with the
193
+ * `data` config (or the React `data` prop) to mirror the editor state into your
194
+ * own store with a single callback instead of calling `saver.save()` by hand.
195
+ *
196
+ * Serialization is debounced through the same change-batching window as
197
+ * `onChange`, so a burst of edits produces a single `onSave` call. Only
198
+ * user-driven content changes trigger it — programmatic `render()` does not
199
+ * (the change observer is disabled during render), so a controlled
200
+ * `data → render → onSave → setData` round-trip won't recurse.
201
+ *
202
+ * @param data - the full serialized output of the editor
203
+ * @param api - blok.js api
204
+ */
205
+ onSave?(data: OutputData, api: API): void;
206
+
190
207
  /**
191
208
  * Defines default toolbar for all tools.
192
209
  */