@jackuait/blok 0.22.0 → 0.23.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/README.md +12 -1
- package/dist/blok.cjs +1 -1
- package/dist/blok.iife.js +1 -1
- package/dist/blok.mjs +2 -2
- package/dist/blok.umd.js +1 -1
- package/dist/chunks/{blok-S6c68iVJ.mjs → blok-BmckXjmW.mjs} +1 -1
- package/dist/chunks/{blok-Blnd71Ww.cjs → blok-D4WXeg3t.cjs} +1 -1
- package/dist/chunks/{constants-BIqDMhRj.cjs → constants-BbCnmzAr.cjs} +1 -1
- package/dist/chunks/{constants-BvxJIgSQ.mjs → constants-tXKHkDAG.mjs} +1 -1
- package/dist/chunks/{tools-B89FUeNz.mjs → tools-oXMAa9zD.mjs} +1 -1
- package/dist/chunks/{tools-DTjC0C5o.cjs → tools-tG5_UaWz.cjs} +1 -1
- package/dist/full.cjs +1 -1
- package/dist/full.mjs +3 -3
- package/dist/react.cjs +1 -1
- package/dist/react.mjs +69 -42
- package/dist/tools.cjs +1 -1
- package/dist/tools.mjs +2 -2
- package/package.json +1 -1
- package/src/react/BlokEditor.tsx +63 -0
- package/src/react/index.ts +2 -0
- package/src/react/types.ts +13 -3
- package/src/react/useBlok.ts +18 -0
- package/types/react.d.ts +38 -3
package/dist/full.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/blok-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/blok-D4WXeg3t.cjs`),t=require(`./chunks/constants-BbCnmzAr.cjs`),n=require(`./chunks/objectSpread2-iNkE6aJh.cjs`),r=require(`./chunks/tools-tG5_UaWz.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.ja,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-
|
|
2
|
-
import { ja as n } from "./chunks/constants-
|
|
1
|
+
import { n as e, t } from "./chunks/blok-BmckXjmW.mjs";
|
|
2
|
+
import { ja as n } from "./chunks/constants-tXKHkDAG.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-
|
|
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-oXMAa9zD.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-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunks/chunk-BL1yB9zm.cjs`);const e=require(`./chunks/blok-D4WXeg3t.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;(0,n.useEffect)(()=>{o===null||!m||o.focus()},[o,m]);let{theme:h}=r;(0,n.useEffect)(()=>{o===null||h===void 0||o.theme.set(h)},[o,h]);let{width:g}=r;return(0,n.useEffect)(()=>{o===null||g===void 0||o.width.set(g)},[o,g]),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))}),f=[`deps`,`className`,`onReady`,`data-testid`],p=(0,n.forwardRef)(function(t,i){let{deps:a,className:o,onReady:s,"data-testid":l}=t,u=c(e.i(t,f),a);(0,n.useImperativeHandle)(i,()=>u,[u]);let p=(0,n.useRef)(s);return p.current=s,(0,n.useEffect)(()=>{if(u!==null){var e;(e=p.current)==null||e.call(p,u)}},[u]),(0,r.jsx)(d,{editor:u,className:o,"data-testid":l})});exports.BlokContent=d,exports.BlokEditor=p,exports.useBlok=c;
|
package/dist/react.mjs
CHANGED
|
@@ -1,83 +1,91 @@
|
|
|
1
|
-
import { i as e, t } from "./chunks/blok-
|
|
1
|
+
import { i as e, t } from "./chunks/blok-BmckXjmW.mjs";
|
|
2
2
|
import { t as n } from "./chunks/objectSpread2-jlBcdYeb.mjs";
|
|
3
|
-
import { forwardRef as r, useEffect as i,
|
|
4
|
-
import { jsx as
|
|
3
|
+
import { forwardRef as r, useEffect as i, useImperativeHandle as a, useMemo as o, useRef as s, useState as c } from "react";
|
|
4
|
+
import { jsx as l } from "react/jsx-runtime";
|
|
5
5
|
//#region src/react/holder-map.ts
|
|
6
|
-
var
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
function d(e) {
|
|
11
|
-
return l.get(e);
|
|
6
|
+
var u = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
function d(e, t) {
|
|
8
|
+
u.set(e, t);
|
|
12
9
|
}
|
|
13
10
|
function f(e) {
|
|
14
|
-
|
|
11
|
+
return u.get(e);
|
|
12
|
+
}
|
|
13
|
+
function p(e) {
|
|
14
|
+
u.delete(e);
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/react/useBlok.ts
|
|
18
|
-
function
|
|
19
|
-
let [
|
|
20
|
-
|
|
21
|
-
let
|
|
18
|
+
function m(e, r) {
|
|
19
|
+
let [a, l] = c(null), u = s(e);
|
|
20
|
+
u.current = e;
|
|
21
|
+
let f = s({
|
|
22
22
|
editor: null,
|
|
23
23
|
holder: null,
|
|
24
24
|
destroyTimeout: null,
|
|
25
25
|
isDestroyed: !1,
|
|
26
26
|
depsToken: null
|
|
27
|
-
}),
|
|
27
|
+
}), m = o(() => ({}), r == null ? [] : r);
|
|
28
28
|
i(() => {
|
|
29
29
|
if (typeof window > "u") return;
|
|
30
|
-
let e =
|
|
31
|
-
if (e.destroyTimeout !== null && (clearTimeout(e.destroyTimeout), e.destroyTimeout = null), e.editor !== null && !e.isDestroyed && e.depsToken ===
|
|
32
|
-
|
|
30
|
+
let e = f.current;
|
|
31
|
+
if (e.destroyTimeout !== null && (clearTimeout(e.destroyTimeout), e.destroyTimeout = null), e.editor !== null && !e.isDestroyed && e.depsToken === m) return l(e.editor), () => {
|
|
32
|
+
h(e, l);
|
|
33
33
|
};
|
|
34
34
|
if (e.editor !== null && !e.isDestroyed) {
|
|
35
|
-
|
|
35
|
+
p(e.editor);
|
|
36
36
|
try {
|
|
37
37
|
e.editor.destroy();
|
|
38
38
|
} catch (e) {}
|
|
39
39
|
e.editor = null, e.holder = null, e.isDestroyed = !0, l(null);
|
|
40
40
|
}
|
|
41
41
|
let r = document.createElement("div");
|
|
42
|
-
e.holder = r, e.isDestroyed = !1, e.depsToken =
|
|
43
|
-
let i =
|
|
42
|
+
e.holder = r, e.isDestroyed = !1, e.depsToken = m;
|
|
43
|
+
let i = u.current, a = new t(n(n({}, i), {}, {
|
|
44
44
|
holder: r,
|
|
45
45
|
onReady: () => {
|
|
46
46
|
var e, t;
|
|
47
|
-
(e = (t =
|
|
47
|
+
(e = (t = u.current).onReady) == null || e.call(t);
|
|
48
48
|
},
|
|
49
49
|
onChange: (...e) => {
|
|
50
50
|
var t, n;
|
|
51
|
-
(t = (n =
|
|
51
|
+
(t = (n = u.current).onChange) == null || t.call(n, ...e);
|
|
52
52
|
}
|
|
53
53
|
}));
|
|
54
|
-
return e.editor = a,
|
|
54
|
+
return e.editor = a, d(a, r), a.isReady.then(() => {
|
|
55
55
|
e.editor === a && !e.isDestroyed && l(a);
|
|
56
56
|
}).catch(() => {
|
|
57
57
|
if (e.editor === a && !e.isDestroyed) {
|
|
58
|
-
|
|
58
|
+
p(a);
|
|
59
59
|
try {
|
|
60
60
|
a.destroy();
|
|
61
61
|
} catch (e) {}
|
|
62
62
|
e.editor = null, e.holder = null, e.isDestroyed = !0, l(null);
|
|
63
63
|
}
|
|
64
64
|
}), () => {
|
|
65
|
-
|
|
65
|
+
h(e, l);
|
|
66
66
|
};
|
|
67
|
-
}, [
|
|
67
|
+
}, [m]);
|
|
68
68
|
let { readOnly: g } = e;
|
|
69
69
|
i(() => {
|
|
70
|
-
|
|
71
|
-
}, [
|
|
70
|
+
a !== null && a.readOnly.set(g == null ? !1 : g);
|
|
71
|
+
}, [a, g]);
|
|
72
72
|
let { autofocus: _ } = e;
|
|
73
|
+
i(() => {
|
|
74
|
+
a === null || !_ || a.focus();
|
|
75
|
+
}, [a, _]);
|
|
76
|
+
let { theme: v } = e;
|
|
77
|
+
i(() => {
|
|
78
|
+
a === null || v === void 0 || a.theme.set(v);
|
|
79
|
+
}, [a, v]);
|
|
80
|
+
let { width: y } = e;
|
|
73
81
|
return i(() => {
|
|
74
|
-
|
|
75
|
-
}, [
|
|
82
|
+
a === null || y === void 0 || a.width.set(y);
|
|
83
|
+
}, [a, y]), a;
|
|
76
84
|
}
|
|
77
|
-
function
|
|
85
|
+
function h(e, t) {
|
|
78
86
|
e.destroyTimeout = setTimeout(() => {
|
|
79
87
|
if (e.editor !== null) {
|
|
80
|
-
|
|
88
|
+
p(e.editor);
|
|
81
89
|
try {
|
|
82
90
|
e.editor.destroy();
|
|
83
91
|
} catch (e) {}
|
|
@@ -87,21 +95,40 @@ function m(e, t) {
|
|
|
87
95
|
}
|
|
88
96
|
//#endregion
|
|
89
97
|
//#region src/react/BlokContent.tsx
|
|
90
|
-
var
|
|
91
|
-
let { editor: a } = t,
|
|
98
|
+
var g = ["editor"], _ = r(function(t, r) {
|
|
99
|
+
let { editor: a } = t, o = e(t, g), c = s(null);
|
|
92
100
|
return i(() => {
|
|
93
|
-
if (a === null ||
|
|
94
|
-
let e =
|
|
95
|
-
if (e !== void 0) return
|
|
101
|
+
if (a === null || c.current === null) return;
|
|
102
|
+
let e = f(a);
|
|
103
|
+
if (e !== void 0) return c.current.appendChild(e), () => {
|
|
96
104
|
e.remove();
|
|
97
105
|
};
|
|
98
|
-
}, [a]), /* @__PURE__ */
|
|
99
|
-
if (
|
|
106
|
+
}, [a]), /* @__PURE__ */ l("div", n({ ref: (e) => {
|
|
107
|
+
if (c.current = e, typeof r == "function") r(e);
|
|
100
108
|
else if (r != null) {
|
|
101
109
|
let t = r;
|
|
102
110
|
t.current = e;
|
|
103
111
|
}
|
|
104
|
-
} },
|
|
112
|
+
} }, o));
|
|
113
|
+
}), v = [
|
|
114
|
+
"deps",
|
|
115
|
+
"className",
|
|
116
|
+
"onReady",
|
|
117
|
+
"data-testid"
|
|
118
|
+
], y = r(function(t, n) {
|
|
119
|
+
let { deps: r, className: o, onReady: c, "data-testid": u } = t, d = m(e(t, v), r);
|
|
120
|
+
a(n, () => d, [d]);
|
|
121
|
+
let f = s(c);
|
|
122
|
+
return f.current = c, i(() => {
|
|
123
|
+
if (d !== null) {
|
|
124
|
+
var e;
|
|
125
|
+
(e = f.current) == null || e.call(f, d);
|
|
126
|
+
}
|
|
127
|
+
}, [d]), /* @__PURE__ */ l(_, {
|
|
128
|
+
editor: d,
|
|
129
|
+
className: o,
|
|
130
|
+
"data-testid": u
|
|
131
|
+
});
|
|
105
132
|
});
|
|
106
133
|
//#endregion
|
|
107
|
-
export {
|
|
134
|
+
export { _ as BlokContent, y as BlokEditor, m as useBlok };
|
package/dist/tools.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/constants-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunks/constants-BbCnmzAr.cjs`),t=require(`./chunks/tools-tG5_UaWz.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-
|
|
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-
|
|
1
|
+
import { m as e } from "./chunks/constants-tXKHkDAG.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-oXMAa9zD.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.
|
|
3
|
+
"version": "0.23.0",
|
|
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",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { forwardRef, useImperativeHandle, useEffect, useRef, type DependencyList } from 'react';
|
|
2
|
+
import { useBlok } from './useBlok';
|
|
3
|
+
import { BlokContent } from './BlokContent';
|
|
4
|
+
import type { Blok } from '@/types';
|
|
5
|
+
import type { UseBlokConfig } from './types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Props for the all-in-one BlokEditor component.
|
|
9
|
+
* Accepts every useBlok config prop (except `onReady`, re-typed below to receive
|
|
10
|
+
* the ready instance), plus container `className`/`data-testid` and an optional
|
|
11
|
+
* `deps` list. When any value in `deps` changes, the editor is destroyed and
|
|
12
|
+
* recreated (use this when `tools` or other structural config changes).
|
|
13
|
+
*
|
|
14
|
+
* `data` is uncontrolled (seed-only): it sets the INITIAL content. After mount the
|
|
15
|
+
* editor owns the document — passing a new `data` reference does NOT reload it.
|
|
16
|
+
* Read content via `onChange` or the ref (`ref.current.save()`); replace it
|
|
17
|
+
* imperatively via `ref.current.render(newData)`.
|
|
18
|
+
*/
|
|
19
|
+
export interface BlokEditorProps extends Omit<UseBlokConfig, 'onReady'> {
|
|
20
|
+
/** When any value changes, the editor is destroyed and recreated. */
|
|
21
|
+
deps?: DependencyList;
|
|
22
|
+
/** Class name applied to the editor container element. */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Test id forwarded to the editor container element (via data-testid). */
|
|
25
|
+
'data-testid'?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Called once the editor is ready, with the live Blok instance. Fires after the
|
|
28
|
+
* forwarded ref is committed, so `ref.current` is also populated at this point.
|
|
29
|
+
*/
|
|
30
|
+
onReady?: (editor: Blok) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The recommended way to embed Blok in React. Internally wires `useBlok` and
|
|
35
|
+
* `BlokContent`, and forwards a ref to the live `Blok` instance.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* const ref = useRef<Blok | null>(null);
|
|
40
|
+
* <BlokEditor ref={ref} tools={tools} data={data} theme={theme} onReady={(e) => e.focus()} />;
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export const BlokEditor = forwardRef<Blok | null, BlokEditorProps>(
|
|
44
|
+
function BlokEditor({ deps, className, onReady, 'data-testid': dataTestId, ...config }, ref) {
|
|
45
|
+
const editor = useBlok(config, deps);
|
|
46
|
+
|
|
47
|
+
useImperativeHandle<Blok | null, Blok | null>(ref, () => editor, [editor]);
|
|
48
|
+
|
|
49
|
+
// Own onReady here instead of forwarding it to the core config: the core
|
|
50
|
+
// onReady fires before useImperativeHandle commits the ref. This passive
|
|
51
|
+
// effect runs AFTER the commit, so both the instance argument and ref.current
|
|
52
|
+
// are reliably populated.
|
|
53
|
+
const onReadyRef = useRef(onReady);
|
|
54
|
+
onReadyRef.current = onReady;
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (editor !== null) {
|
|
57
|
+
onReadyRef.current?.(editor);
|
|
58
|
+
}
|
|
59
|
+
}, [editor]);
|
|
60
|
+
|
|
61
|
+
return <BlokContent editor={editor} className={className} data-testid={dataTestId} />;
|
|
62
|
+
}
|
|
63
|
+
);
|
package/src/react/index.ts
CHANGED
package/src/react/types.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import type { BlokConfig, Blok } from '@/types';
|
|
1
|
+
import type { BlokConfig, Blok, EditorWidth } from '@/types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Configuration for useBlok hook.
|
|
5
|
-
* Same as BlokConfig but without `holder`
|
|
5
|
+
* Same as BlokConfig but without `holder` (managed by BlokContent), plus a
|
|
6
|
+
* React-only reactive `width` prop.
|
|
7
|
+
*
|
|
8
|
+
* Reactive props (sync after mount without recreation):
|
|
9
|
+
* - `readOnly` — calls `editor.readOnly.set(value)`
|
|
10
|
+
* - `autofocus` — calls `editor.focus()` when changed to true
|
|
11
|
+
* - `theme` — calls `editor.theme.set(value)`
|
|
12
|
+
* - `width` — calls `editor.width.set(value)`
|
|
6
13
|
*/
|
|
7
|
-
export interface UseBlokConfig extends Omit<BlokConfig, 'holder'> {
|
|
14
|
+
export interface UseBlokConfig extends Omit<BlokConfig, 'holder'> {
|
|
15
|
+
/** Editor content width mode. Synced reactively after mount via `editor.width.set()`. */
|
|
16
|
+
width?: EditorWidth;
|
|
17
|
+
}
|
|
8
18
|
|
|
9
19
|
/**
|
|
10
20
|
* Props for the BlokContent component.
|
package/src/react/useBlok.ts
CHANGED
|
@@ -146,6 +146,24 @@ export function useBlok(config: UseBlokConfig, deps?: DependencyList): Blok | nu
|
|
|
146
146
|
editor.focus();
|
|
147
147
|
}, [editor, autofocus]);
|
|
148
148
|
|
|
149
|
+
// Reactive: theme
|
|
150
|
+
const { theme } = config;
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (editor === null || theme === undefined) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
editor.theme.set(theme);
|
|
156
|
+
}, [editor, theme]);
|
|
157
|
+
|
|
158
|
+
// Reactive: width
|
|
159
|
+
const { width } = config;
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (editor === null || width === undefined) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
editor.width.set(width);
|
|
165
|
+
}, [editor, width]);
|
|
166
|
+
|
|
149
167
|
return editor;
|
|
150
168
|
}
|
|
151
169
|
|
package/types/react.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import type { BlokConfig } from './index';
|
|
2
|
-
import type { Blok } from './index';
|
|
2
|
+
import type { Blok, EditorWidth } from './index';
|
|
3
3
|
import type React from 'react';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Configuration for the useBlok hook.
|
|
7
|
-
* Accepts all BlokConfig properties except `holder`,
|
|
7
|
+
* Accepts all BlokConfig properties except `holder`, plus a React-only `width` prop.
|
|
8
8
|
*
|
|
9
9
|
* Reactive props (sync after mount without recreation):
|
|
10
10
|
* - `readOnly` — calls `editor.readOnly.set(value)`
|
|
11
11
|
* - `autofocus` — calls `editor.focus()` when changed to true
|
|
12
|
+
* - `theme` — calls `editor.theme.set(value)`
|
|
13
|
+
* - `width` — calls `editor.width.set(value)`
|
|
12
14
|
*
|
|
13
15
|
* All other config is consumed once at editor creation.
|
|
14
16
|
*/
|
|
15
|
-
export interface UseBlokConfig extends Omit<BlokConfig, 'holder'> {
|
|
17
|
+
export interface UseBlokConfig extends Omit<BlokConfig, 'holder'> {
|
|
18
|
+
/** Editor content width mode. Synced reactively after mount. */
|
|
19
|
+
width?: EditorWidth;
|
|
20
|
+
}
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
23
|
* Props for the BlokContent component.
|
|
@@ -56,3 +61,33 @@ export function useBlok(
|
|
|
56
61
|
* ```
|
|
57
62
|
*/
|
|
58
63
|
export declare const BlokContent: React.ForwardRefExoticComponent<BlokContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Props for the BlokEditor component — all useBlok config (except `onReady`,
|
|
67
|
+
* re-typed to receive the ready instance) plus container `className`/`data-testid`
|
|
68
|
+
* and an optional `deps` list that forces recreation when changed.
|
|
69
|
+
*/
|
|
70
|
+
export interface BlokEditorProps extends Omit<UseBlokConfig, 'onReady'> {
|
|
71
|
+
/** When any value changes, the editor is destroyed and recreated. */
|
|
72
|
+
deps?: React.DependencyList;
|
|
73
|
+
/** Class name applied to the editor container element. */
|
|
74
|
+
className?: string;
|
|
75
|
+
/** Test id forwarded to the editor container element (via data-testid). */
|
|
76
|
+
'data-testid'?: string;
|
|
77
|
+
/** Called once the editor is ready, with the live Blok instance (ref is also committed). */
|
|
78
|
+
onReady?: (editor: Blok) => void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The recommended all-in-one React component. Wires useBlok + BlokContent and
|
|
83
|
+
* forwards a ref to the live Blok instance (null before the editor is ready).
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* const ref = useRef<Blok | null>(null);
|
|
88
|
+
* <BlokEditor ref={ref} tools={tools} data={data} theme="dark" />;
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare const BlokEditor: React.ForwardRefExoticComponent<
|
|
92
|
+
BlokEditorProps & React.RefAttributes<Blok | null>
|
|
93
|
+
>;
|