@bloklabs/vue 1.3.0 → 1.4.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 +67 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +145 -103
- package/package.json +24 -3
- package/src/BlokEditor.ts +3 -1
- package/src/index.ts +2 -0
- package/src/types.ts +6 -1
- package/src/useBlok.ts +87 -4
- package/src/useBlokReady.ts +70 -0
- package/types/index.d.ts +54 -1
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @bloklabs/vue
|
|
2
|
+
|
|
3
|
+
The Vue 3 block editor bindings for [Blok](https://blokeditor.com) — a headless, Notion-like rich text editor whose content is JSON blocks, not HTML.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @bloklabs/vue @bloklabs/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`@bloklabs/core` and `vue` are peer dependencies.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
`<BlokEditor>` is the all-in-one component: it mounts the editor, manages its lifecycle, and takes every editor config option as a prop.
|
|
16
|
+
|
|
17
|
+
```vue
|
|
18
|
+
<script setup lang="ts">
|
|
19
|
+
import { BlokEditor } from '@bloklabs/vue';
|
|
20
|
+
import { Header, Paragraph, List } from '@bloklabs/core/tools';
|
|
21
|
+
|
|
22
|
+
const tools = {
|
|
23
|
+
paragraph: Paragraph,
|
|
24
|
+
header: { class: Header, placeholder: 'Enter a heading' },
|
|
25
|
+
list: List,
|
|
26
|
+
};
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<BlokEditor :tools="tools" />
|
|
31
|
+
</template>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Saving
|
|
35
|
+
|
|
36
|
+
The `save` emit fires with the latest content on every change, so you never have to call `save()` by hand.
|
|
37
|
+
|
|
38
|
+
```vue
|
|
39
|
+
<script setup lang="ts">
|
|
40
|
+
import { ref } from 'vue';
|
|
41
|
+
import { BlokEditor } from '@bloklabs/vue';
|
|
42
|
+
import type { OutputData } from '@bloklabs/core';
|
|
43
|
+
|
|
44
|
+
const data = ref<OutputData>();
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<BlokEditor @save="(d: OutputData) => (data = d)" />
|
|
49
|
+
<pre>{{ data?.blocks }}</pre>
|
|
50
|
+
</template>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Also exported
|
|
54
|
+
|
|
55
|
+
- `useBlok(config, recreateKey?)` — the composable behind the component, returns a `Ref<Blok | null>`.
|
|
56
|
+
- `BlokContent` — the mount-point element, if you want to wire the composable yourself.
|
|
57
|
+
- `useBlocks(editor)` — a reactive snapshot of the block tree plus a manipulation API.
|
|
58
|
+
- `createVueBlock` — author block tools as Vue components.
|
|
59
|
+
- `provideBlok` / `useBlokDefaults` — share default editor config through provide/inject.
|
|
60
|
+
|
|
61
|
+
## Docs
|
|
62
|
+
|
|
63
|
+
- [Quick start](https://blokeditor.com/docs/quick-start?framework=vue)
|
|
64
|
+
- [`BlokEditor` reference](https://blokeditor.com/docs/blok-editor?framework=vue)
|
|
65
|
+
- [`useBlocks` reference](https://blokeditor.com/docs/use-blocks?framework=vue)
|
|
66
|
+
|
|
67
|
+
Licensed under Apache-2.0.
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@bloklabs/core"),n=require("@bloklabs/core/adapters");var r=new WeakMap;function i(e,t){r.set(e,t)}function a(e){return r.get(e)}function o(e){r.delete(e)}function s(e){"@babel/helpers - typeof";return s=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},s(e)}function c(e,t){if(s(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(s(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function l(e){var t=c(e,`string`);return s(t)==`symbol`?t:t+``}function u(e,t,n){return(t=l(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function d(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function f(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?d(Object(n),!0).forEach(function(t){u(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):d(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}var p=Symbol(`BLOK_DEFAULT_CONFIG`);function m(t){(0,e.provide)(p,t)}function h(){return(0,e.inject)(p,{})}function g(e,t){if(Object.keys(e).length===0)return t;let n=f({},e);for(let e of Object.keys(t)){let r=t[e];r!==void 0&&(n[e]=r)}return(e.tools!==void 0||t.tools!==void 0)&&(n.tools=f(f({},e.tools),t.tools)),n}var _=`__blokPortalRegistry`,v=()=>{let t=(0,e.reactive)(new Map);return{entries:t,register(n,r){t.set(n,(0,e.markRaw)(r))},unregister(e){t.delete(e)},setProps(e,n){let r=t.get(e);r!==void 0&&Object.assign(r.props,n)}}},y=new WeakMap;function b(e,t){y.set(e,t)}function x(e){return y.get(e)}function S(e){y.delete(e)}var C=(e,t)=>{if(typeof e!=`object`||!e)return e;let n={};for(let[i,a]of Object.entries(e)){var r;let e=typeof a==`function`?a:a==null?void 0:a.class;if(!(typeof e==`function`&&e.__isBlokVueBlock===!0)){n[i]=a;continue}let o=typeof a==`function`?{class:a}:f({},a);o.config=f(f({},(r=o.config)==null?{}:r),{},{[_]:t}),n[i]=o}return n};function w(r,a){let s=(0,e.shallowRef)(null),c=(0,e.inject)(p,{}),l=()=>g(c,(0,e.toValue)(r)),u={current:null,holder:null,lastRenderedData:l().data,seededEditor:null,renderChain:Promise.resolve()},d=()=>{let t=f({},g((0,e.toRaw)(c),(0,e.toRaw)((0,e.toValue)(r))));return delete t.holder,t.data!==void 0&&(t.data=(0,e.toRaw)(t.data)),t},m=()=>{if(u.current!==null){o(u.current),S(u.current);try{u.current.destroy()}catch(e){}}u.current=null,u.holder=null,s.value=null},h=()=>{let e=document.createElement(`div`);u.holder=e;let n=d(),r=v();n.tools!==void 0&&(n.tools=C(n.tools,r)),typeof n.onSave==`function`&&(n.onSave=(...e)=>{var t,n;u.lastRenderedData=e[0],(t=(n=l()).onSave)==null||t.call(n,...e)});let a=new t.Blok(f(f({},n),{},{holder:e}));u.current=a,i(a,e),b(a,r),a.isReady.then(()=>{u.current===a&&(s.value=a)}).catch(()=>{u.current===a&&m()})};(0,e.watch)([s,()=>(0,n.normalizeReadOnlyConfig)(l().readOnly).enabled],([e,t])=>{e&&e.readOnly.set(t)},{immediate:!0}),(0,e.watch)([s,()=>l().theme],([e,t])=>{e&&t!==void 0&&e.theme.set(t)},{immediate:!0}),(0,e.watch)([s,()=>l().width],([e,t])=>{e&&t!==void 0&&e.width.set(t)},{immediate:!0}),(0,e.watch)([s,()=>l().placeholder],([e,t])=>{e&&t!==void 0&&e.placeholder.set(t)},{immediate:!0});let _={value:void 0};return(0,e.watch)([s,()=>{var e;return(e=l().style)==null?void 0:e.tokens}],([e,t])=>{!e||t===void 0||(0,n.deepEqual)(t,_.value)||(_.value=f({},t),e.tokens.set(t))},{immediate:!0,deep:!0}),(0,e.watch)([s,()=>l().autofocus],([e,t])=>{e&&t&&e.focus()},{immediate:!0}),(0,e.watch)([s,()=>l().data],([t,r])=>{if(!(!t||r===void 0)){if(u.seededEditor!==t){u.seededEditor=t,u.lastRenderedData=r;return}(0,n.deepEqual)(r,u.lastRenderedData)||(u.lastRenderedData=r,u.renderChain=u.renderChain.catch(()=>void 0).then(()=>t.render((0,e.toRaw)(r))))}},{immediate:!0}),a!==void 0&&(0,e.watch)(()=>(0,e.toValue)(a),()=>{m(),h()}),(0,e.onMounted)(h),(0,e.onBeforeUnmount)(m),s}var T=`block changed`;function E(t){let r=(0,e.shallowRef)(0),i=()=>{let n=(0,e.toValue)(t);return n===null?null:(0,e.toRaw)(n)},a=()=>{r.value},o=(0,e.shallowRef)(n.EMPTY_API),s={editor:null,handler:null},c=()=>{s.editor!==null&&s.handler!==null&&s.editor.off(T,s.handler),s.editor=null,s.handler=null};return(0,e.watch)(()=>i(),e=>{if(c(),r.value+=1,e===null){o.value=n.EMPTY_API;return}let t=()=>{r.value+=1};e.on(T,t),s.editor=e,s.handler=t,o.value=(0,n.createBlocksApiForEditor)(e,a)},{immediate:!0}),(0,e.onScopeDispose)(c),{getById:e=>o.value.getById(e),getChildren:e=>o.value.getChildren(e),insert:e=>o.value.insert(e),insertMany:e=>o.value.insertMany(e),insertTree:e=>o.value.insertTree(e),insertMarkdown:(e,t)=>o.value.insertMarkdown(e,t),exportMarkdown:()=>o.value.exportMarkdown(),move:(e,t)=>o.value.move(e,t),nest:(e,t)=>o.value.nest(e,t),unnest:e=>o.value.unnest(e),remove:e=>o.value.remove(e),update:(e,t,n)=>o.value.update(e,t,n),convert:(e,t,n,r)=>o.value.convert(e,t,n,r),transact:e=>o.value.transact(e),transactWithoutCapture:e=>o.value.transactWithoutCapture(e),getBlocksCount:()=>o.value.getBlocksCount(),getCurrentBlockIndex:()=>o.value.getCurrentBlockIndex(),getBlockByIndex:e=>o.value.getBlockByIndex(e),getBlockByElement:e=>o.value.getBlockByElement(e),getBlockData:e=>o.value.getBlockData(e),getBlockIndex:e=>o.value.getBlockIndex(e),composeBlockData:e=>o.value.composeBlockData(e),renderFromHTML:e=>o.value.renderFromHTML(e),insertOutputData:(e,t)=>o.value.insertOutputData(e,t),splitBlock:(e,t,n,r,i)=>o.value.splitBlock(e,t,n,r,i),insertInsideParent:(e,t,n)=>o.value.insertInsideParent(e,t,n),render:e=>o.value.render(e),clear:()=>o.value.clear(),isSyncingFromYjs:()=>o.value.isSyncingFromYjs()}}var D=(0,e.defineComponent)({name:`BlockErrorBoundary`,setup(t,{slots:n}){return(0,e.onErrorCaptured)(()=>!1),()=>{var e;return(e=n.default)==null?void 0:e.call(n)}}}),O=(0,e.defineComponent)({name:`BlockPortalHost`,props:{registry:{type:Object,required:!0}},setup(t){return()=>(0,e.h)(e.Fragment,Array.from(t.registry.entries.entries()).map(([t,n])=>(0,e.h)(e.Teleport,{key:t,to:n.hostEl},[(0,e.h)(D,null,{default:()=>(0,e.h)(n.component,n.props)})])))}}),k=(0,e.defineComponent)({name:`BlokContent`,props:{editor:{type:Object,default:null}},setup(t){let n=(0,e.ref)(null),r=t=>{if(n.value===null||t===null)return;let r=a((0,e.toRaw)(t));r!==void 0&&n.value.appendChild(r)},i=t=>{var n;t!==null&&((n=a((0,e.toRaw)(t)))==null||n.remove())};return(0,e.onMounted)(()=>{r(t.editor)}),(0,e.watch)(()=>t.editor,(e,t)=>{i(t==null?null:t),r(e)}),(0,e.onBeforeUnmount)(()=>{i(t.editor)}),()=>{let r=t.editor,i=r===null?void 0:x((0,e.toRaw)(r));return(0,e.h)(`div`,{ref:n},i===void 0?[]:[(0,e.h)(O,{registry:i})])}}}),A=`autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.inlineToolbar.tunes.style.theme.scrollToBlock.user.resolveUser.notifierPosition.notifier.width.onBeforeRender.onBeforePaste.onEnter`.split(`.`),j=(0,e.defineComponent)({name:`BlokEditor`,inheritAttrs:!1,props:{autofocus:{type:Boolean,default:void 0},defaultBlock:{type:String,default:void 0},dataModel:{type:String,default:void 0},placeholder:{type:[String,Boolean],default:void 0},sanitizer:{type:Object,default:void 0},hideToolbar:{type:Boolean,default:void 0},maxHistoryLength:{type:Number,default:void 0},historyDebounceTime:{type:Number,default:void 0},newGroupDelay:{type:Number,default:void 0},globalUndoRedo:{type:Boolean,default:void 0},tools:{type:Object,default:void 0},data:{type:Object,default:void 0},minHeight:{type:Number,default:void 0},logLevel:{type:String,default:void 0},readOnly:{type:Boolean,default:void 0},i18n:{type:Object,default:void 0},link:{type:Object,default:void 0},linkPaste:{type:Object,default:void 0},inlineToolbar:{type:[Array,Boolean],default:void 0},tunes:{type:Array,default:void 0},style:{type:Object,default:void 0},theme:{type:String,default:void 0},scrollToBlock:{type:Object,default:void 0},user:{type:Object,default:void 0},resolveUser:{type:Function,default:void 0},notifierPosition:{type:String,default:void 0},notifier:{type:Function,default:void 0},width:{type:String,default:void 0},onBeforeRender:{type:Function,default:void 0},onBeforePaste:{type:Function,default:void 0},onEnter:{type:Function,default:void 0},recreateKey:{type:null}},emits:{ready:e=>!0,change:e=>!0,save:e=>!0,"update:data":e=>!0,"after-render":e=>!0,"theme-change":e=>!0,"blocks-rendered":e=>!0,"block-rendered":e=>!0},setup(t,{emit:n,expose:r,attrs:i}){let a=(0,e.getCurrentInstance)(),o=e=>{let t=a==null?void 0:a.vnode.props;return t!=null&&e in t},s=()=>{let e={};for(let n of A){let r=t[n];r!==void 0&&(e[n]=r)}return o(`onChange`)&&(e.onChange=(e,t)=>{n(`change`,{api:e,event:t})}),(o(`onSave`)||o(`onUpdate:data`))&&(e.onSave=e=>{n(`update:data`,e),n(`save`,e)}),o(`onAfterRender`)&&(e.onAfterRender=e=>{n(`after-render`,e)}),o(`onThemeChange`)&&(e.onThemeChange=e=>{n(`theme-change`,e)}),e},c=w(()=>s(),()=>t.recreateKey);(0,e.watch)(c,(e,t,r)=>{if(e===null)return;let i=[];if(o(`onBlocksRendered`)){let t=e=>n(`blocks-rendered`,e);e.on(`blocks:rendered`,t),i.push([`blocks:rendered`,t])}if(o(`onBlockRendered`)){let t=e=>n(`block-rendered`,e);e.on(`block:rendered`,t),i.push([`block:rendered`,t])}r(()=>{for(let[t,n]of i)e.off(t,n)})});let l={last:null};return(0,e.watch)(c,e=>{e!==null&&e!==l.last&&(l.last=e,n(`ready`,e))}),r({instance:(0,e.computed)(()=>c.value),save:()=>{var e;return(e=c.value)==null?void 0:e.save()},focus:e=>{var t;(t=c.value)==null||t.focus(e)},render:e=>{var t;return(t=c.value)==null?void 0:t.render(e)}}),()=>(0,e.h)(k,f({editor:c.value},i))}});function M(t){var r;let i=(0,e.defineComponent)({name:`VueBlock(${t.type})`,props:{ctx:{type:Object,required:!0}},setup(e){return t.setup(e.ctx)}});return r=class{static get toolbox(){return t.toolbox}static get isReadOnlySupported(){return!0}constructor(r){var i,a;this.hostEl=null,this.pendingDispatch=!1,this.commit=e=>{let r=(0,n.fillDefaults)(t.propSchema,f(f({},this.mirror),e));(0,n.deepEqual)(r,this.mirror)||(this.mirror=r,this.lastRendered=r,this.dataRef.value=r,this.flushDispatch())},this.blockApi=r.block;let o=(i=r.config)==null?{}:i;this.registry=o[_];let s=r.api;this.pointerDrag=()=>{var e;return(s==null||(e=s.blocks)==null?void 0:e.isPointerDragActive)===!0},this.mirror=(0,n.fillDefaults)(t.propSchema,(0,e.toRaw)((a=r.data)==null?{}:a)),this.lastRendered=this.mirror,this.dataRef=(0,e.shallowRef)(this.mirror),this.readOnlyRef=(0,e.shallowRef)(r.readOnly);let c=this.blockApi;this.childrenComponent=(0,e.defineComponent)({name:`VueBlockChildren(${t.type})`,setup(){let t=(0,e.ref)(null),r=()=>{t.value!==null&&(0,n.mountChildBlocks)(t.value,c.getChildren())};return(0,e.onMounted)(r),(0,e.onUpdated)(r),()=>(0,e.h)(`div`,{ref:t,[n.DATA_ATTR.nestedBlocks]:``})}})}render(){var e;let t=document.createElement(`div`);t.setAttribute(`data-blok-mutation-free`,`true`),this.hostEl=t;let n={data:this.dataRef,commit:this.commit,block:this.blockApi,readOnly:this.readOnlyRef,BlockChildren:this.childrenComponent};return(e=this.registry)==null||e.register(this.blockApi.id,{hostEl:t,component:i,props:{ctx:n}}),t}rendered(){var e;(e=t.onRendered)==null||e.call(t,this.blockApi)}save(){return this.mirror}async setData(r){var i=this;let a=(0,n.fillDefaults)(t.propSchema,(0,e.toRaw)(r==null?{}:r));return(0,n.deepEqual)(a,i.lastRendered)?!0:(i.mirror=a,i.lastRendered=a,i.dataRef.value=a,await(0,e.nextTick)(),!0)}setReadOnly(e){this.readOnlyRef.value=e}moved(){var e;(e=t.onMoved)==null||e.call(t,this.blockApi)}removed(){var e,n;(e=this.registry)==null||e.unregister(this.blockApi.id),(n=t.onRemoved)==null||n.call(t,this.blockApi)}destroy(){var e;(e=this.registry)==null||e.unregister(this.blockApi.id)}flushDispatch(){if(!this.pointerDrag()){this.pendingDispatch=!1,this.blockApi.dispatchChange();return}if(this.pendingDispatch)return;this.pendingDispatch=!0;let e=()=>{if(this.pointerDrag()){requestAnimationFrame(e);return}this.pendingDispatch=!1,this.blockApi.dispatchChange()};requestAnimationFrame(e)}},r.__isBlokVueBlock=!0,r}exports.BLOK_DEFAULT_CONFIG=p,exports.BlokContent=k,exports.BlokEditor=j,exports.createVueBlock=M,exports.provideBlok=m,exports.useBlocks=E,exports.useBlok=w,exports.useBlokDefaults=h;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@bloklabs/core"),n=require("@bloklabs/core/adapters");var r=new WeakMap;function i(e,t){r.set(e,t)}function a(e){return r.get(e)}function o(e){r.delete(e)}function s(e){"@babel/helpers - typeof";return s=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},s(e)}function c(e,t){if(s(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(s(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function l(e){var t=c(e,`string`);return s(t)==`symbol`?t:t+``}function u(e,t,n){return(t=l(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function d(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function f(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?d(Object(n),!0).forEach(function(t){u(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):d(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}var p=Symbol(`BLOK_DEFAULT_CONFIG`);function m(t){(0,e.provide)(p,t)}function h(){return(0,e.inject)(p,{})}function g(e,t){if(Object.keys(e).length===0)return t;let n=f({},e);for(let e of Object.keys(t)){let r=t[e];r!==void 0&&(n[e]=r)}return(e.tools!==void 0||t.tools!==void 0)&&(n.tools=f(f({},e.tools),t.tools)),n}var _=`__blokPortalRegistry`,v=()=>{let t=(0,e.reactive)(new Map);return{entries:t,register(n,r){t.set(n,(0,e.markRaw)(r))},unregister(e){t.delete(e)},setProps(e,n){let r=t.get(e);r!==void 0&&Object.assign(r.props,n)}}},y=new WeakMap;function b(e,t){y.set(e,t)}function x(e){return y.get(e)}function S(e){y.delete(e)}var C=(e,t)=>{if(typeof e!=`object`||!e)return e;let n={};for(let[i,a]of Object.entries(e)){var r;let e=typeof a==`function`?a:a==null?void 0:a.class;if(!(typeof e==`function`&&e.__isBlokVueBlock===!0)){n[i]=a;continue}let o=typeof a==`function`?{class:a}:f({},a);o.config=f(f({},(r=o.config)==null?{}:r),{},{[_]:t}),n[i]=o}return n};function w(r,a){let s=(0,e.shallowRef)(null),c=(0,e.inject)(p,{}),l=()=>g(c,(0,e.toValue)(r)),u={current:null,holder:null,lastRenderedData:l().data,seededEditor:null,renderChain:Promise.resolve()},d=()=>{let t=f({},g((0,e.toRaw)(c),(0,e.toRaw)((0,e.toValue)(r))));return delete t.holder,t.data!==void 0&&(t.data=(0,e.toRaw)(t.data)),t},m=()=>{if(u.current!==null){o(u.current),S(u.current);try{u.current.destroy()}catch(e){}}u.current=null,u.holder=null,s.value=null},h=()=>{let e=document.createElement(`div`);u.holder=e;let n=d(),r=v();n.tools!==void 0&&(n.tools=C(n.tools,r)),typeof n.onSave==`function`&&(n.onSave=(...e)=>{var t,n;u.lastRenderedData=e[0],(t=(n=l()).onSave)==null||t.call(n,...e)});let a=new t.Blok(f(f({},n),{},{holder:e}));u.current=a,i(a,e),b(a,r),a.isReady.then(()=>{u.current===a&&(s.value=a)}).catch(()=>{u.current===a&&m()})};(0,e.watch)([s,()=>(0,n.normalizeReadOnlyConfig)(l().readOnly).enabled,()=>(0,n.normalizeReadOnlyConfig)(l().readOnly).hideControls,()=>typeof l().readOnly==`object`],([e,t,n,r])=>{e&&(r?e.readOnly.set(t,{hideControls:n}):e.readOnly.set(t))},{immediate:!0}),(0,e.watch)([s,()=>l().hideToolbar],([e,t])=>{e&&e.toolbar.setHidden(!!t)},{immediate:!0}),(0,e.watch)([s,()=>l().theme],([e,t])=>{e&&t!==void 0&&e.theme.set(t)},{immediate:!0}),(0,e.watch)([s,()=>l().width],([e,t])=>{e&&t!==void 0&&e.width.set(t)},{immediate:!0}),(0,e.watch)([s,()=>l().placeholder],([e,t])=>{e&&t!==void 0&&e.placeholder.set(t)},{immediate:!0});let _={value:void 0};(0,e.watch)([s,()=>{var e;return(e=l().style)==null?void 0:e.tokens}],([e,t])=>{!e||t===void 0||(0,n.deepEqual)(t,_.value)||(_.value=f({},t),e.tokens.set(t))},{immediate:!0,deep:!0});let y={value:l().i18n};(0,e.watch)([s,()=>l().i18n],([e,t])=>{if(!e||t===void 0||(0,n.deepEqual)(t,y.value))return;y.value=f({},t);let{locale:r,messages:i,direction:a}=t;e.i18n.update(f(f(f({},r===void 0?{}:{locale:r}),i===void 0?{}:{messages:i}),a===void 0?{}:{direction:a}))},{immediate:!0,deep:!0});let x={editor:null,value:void 0};return(0,e.watch)([s,()=>l().inlineToolbar],([e,t])=>{if(!e||t===void 0||x.editor===e&&(0,n.deepEqual)(t,x.value))return;let r=Array.isArray(t)?[...t]:t;x.editor=e,x.value=r,e.tools.setInlineToolbar(r)},{immediate:!0,deep:!0}),(0,e.watch)([s,()=>l().autofocus],([e,t])=>{e&&t&&e.focus()},{immediate:!0}),(0,e.watch)([s,()=>l().data],([t,r])=>{if(!(!t||r===void 0)){if(u.seededEditor!==t){u.seededEditor=t,u.lastRenderedData=r;return}(0,n.deepEqual)(r,u.lastRenderedData)||(u.lastRenderedData=r,u.renderChain=u.renderChain.catch(()=>void 0).then(()=>t.render((0,e.toRaw)(r))))}},{immediate:!0}),a!==void 0&&(0,e.watch)(()=>(0,e.toValue)(a),()=>{m(),h()}),(0,e.onMounted)(h),(0,e.onBeforeUnmount)(m),s}var T=`block changed`;function E(t){let r=(0,e.shallowRef)(0),i=()=>{let n=(0,e.toValue)(t);return n===null?null:(0,e.toRaw)(n)},a=()=>{r.value},o=(0,e.shallowRef)(n.EMPTY_API),s={editor:null,handler:null},c=()=>{s.editor!==null&&s.handler!==null&&s.editor.off(T,s.handler),s.editor=null,s.handler=null};return(0,e.watch)(()=>i(),e=>{if(c(),r.value+=1,e===null){o.value=n.EMPTY_API;return}let t=()=>{r.value+=1};e.on(T,t),s.editor=e,s.handler=t,o.value=(0,n.createBlocksApiForEditor)(e,a)},{immediate:!0}),(0,e.onScopeDispose)(c),{getById:e=>o.value.getById(e),getChildren:e=>o.value.getChildren(e),insert:e=>o.value.insert(e),insertMany:e=>o.value.insertMany(e),insertTree:e=>o.value.insertTree(e),insertMarkdown:(e,t)=>o.value.insertMarkdown(e,t),exportMarkdown:()=>o.value.exportMarkdown(),move:(e,t)=>o.value.move(e,t),nest:(e,t)=>o.value.nest(e,t),unnest:e=>o.value.unnest(e),remove:e=>o.value.remove(e),update:(e,t,n)=>o.value.update(e,t,n),convert:(e,t,n,r)=>o.value.convert(e,t,n,r),transact:e=>o.value.transact(e),transactWithoutCapture:e=>o.value.transactWithoutCapture(e),getBlocksCount:()=>o.value.getBlocksCount(),getCurrentBlockIndex:()=>o.value.getCurrentBlockIndex(),getBlockByIndex:e=>o.value.getBlockByIndex(e),getBlockByElement:e=>o.value.getBlockByElement(e),getBlockData:e=>o.value.getBlockData(e),getBlockIndex:e=>o.value.getBlockIndex(e),composeBlockData:e=>o.value.composeBlockData(e),renderFromHTML:e=>o.value.renderFromHTML(e),insertOutputData:(e,t)=>o.value.insertOutputData(e,t),splitBlock:(e,t,n,r,i)=>o.value.splitBlock(e,t,n,r,i),insertInsideParent:(e,t,n)=>o.value.insertInsideParent(e,t,n),render:e=>o.value.render(e),clear:()=>o.value.clear(),isSyncingFromYjs:()=>o.value.isSyncingFromYjs()}}function D(n={}){let{within:r,settleOn:i}=n,a=(0,e.shallowRef)(!1),o=()=>{var n;let o=r===void 0||(n=(0,e.toValue)(r))==null?null:n;a.value=r!==void 0&&o===null?!1:t.Blok.readyState({within:o,settleOn:i}).ready};return(0,e.onScopeDispose)(t.Blok.subscribeReady(o)),(0,e.onMounted)(o),a}var O=(0,e.defineComponent)({name:`BlockErrorBoundary`,setup(t,{slots:n}){return(0,e.onErrorCaptured)(()=>!1),()=>{var e;return(e=n.default)==null?void 0:e.call(n)}}}),k=(0,e.defineComponent)({name:`BlockPortalHost`,props:{registry:{type:Object,required:!0}},setup(t){return()=>(0,e.h)(e.Fragment,Array.from(t.registry.entries.entries()).map(([t,n])=>(0,e.h)(e.Teleport,{key:t,to:n.hostEl},[(0,e.h)(O,null,{default:()=>(0,e.h)(n.component,n.props)})])))}}),A=(0,e.defineComponent)({name:`BlokContent`,props:{editor:{type:Object,default:null}},setup(t){let n=(0,e.ref)(null),r=t=>{if(n.value===null||t===null)return;let r=a((0,e.toRaw)(t));r!==void 0&&n.value.appendChild(r)},i=t=>{var n;t!==null&&((n=a((0,e.toRaw)(t)))==null||n.remove())};return(0,e.onMounted)(()=>{r(t.editor)}),(0,e.watch)(()=>t.editor,(e,t)=>{i(t==null?null:t),r(e)}),(0,e.onBeforeUnmount)(()=>{i(t.editor)}),()=>{let r=t.editor,i=r===null?void 0:x((0,e.toRaw)(r));return(0,e.h)(`div`,{ref:n},i===void 0?[]:[(0,e.h)(k,{registry:i})])}}}),j=`autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.inlineToolbar.tunes.style.theme.scrollToBlock.user.resolveUser.notifierPosition.notifier.width.onBeforeRender.onBeforePaste.onEnter`.split(`.`),M=(0,e.defineComponent)({name:`BlokEditor`,inheritAttrs:!1,props:{autofocus:{type:Boolean,default:void 0},defaultBlock:{type:String,default:void 0},dataModel:{type:String,default:void 0},placeholder:{type:[String,Boolean],default:void 0},sanitizer:{type:Object,default:void 0},hideToolbar:{type:Boolean,default:void 0},maxHistoryLength:{type:Number,default:void 0},historyDebounceTime:{type:Number,default:void 0},newGroupDelay:{type:Number,default:void 0},globalUndoRedo:{type:Boolean,default:void 0},tools:{type:Object,default:void 0},data:{type:Object,default:void 0},minHeight:{type:Number,default:void 0},logLevel:{type:String,default:void 0},readOnly:{type:[Boolean,Object],default:void 0},i18n:{type:Object,default:void 0},link:{type:Object,default:void 0},linkPaste:{type:Object,default:void 0},inlineToolbar:{type:[Array,Boolean],default:void 0},tunes:{type:Array,default:void 0},style:{type:Object,default:void 0},theme:{type:String,default:void 0},scrollToBlock:{type:Object,default:void 0},user:{type:Object,default:void 0},resolveUser:{type:Function,default:void 0},notifierPosition:{type:String,default:void 0},notifier:{type:Function,default:void 0},width:{type:String,default:void 0},onBeforeRender:{type:Function,default:void 0},onBeforePaste:{type:Function,default:void 0},onEnter:{type:Function,default:void 0},recreateKey:{type:null}},emits:{ready:e=>!0,change:e=>!0,save:e=>!0,"update:data":e=>!0,"after-render":e=>!0,"theme-change":e=>!0,"blocks-rendered":e=>!0,"block-rendered":e=>!0},setup(t,{emit:n,expose:r,attrs:i}){let a=(0,e.getCurrentInstance)(),o=e=>{let t=a==null?void 0:a.vnode.props;return t!=null&&e in t},s=()=>{let e={};for(let n of j){let r=t[n];r!==void 0&&(e[n]=r)}return o(`onChange`)&&(e.onChange=(e,t)=>{n(`change`,{api:e,event:t})}),(o(`onSave`)||o(`onUpdate:data`))&&(e.onSave=e=>{n(`update:data`,e),n(`save`,e)}),o(`onAfterRender`)&&(e.onAfterRender=e=>{n(`after-render`,e)}),o(`onThemeChange`)&&(e.onThemeChange=e=>{n(`theme-change`,e)}),e},c=w(()=>s(),()=>t.recreateKey);(0,e.watch)(c,(e,t,r)=>{if(e===null)return;let i=[];if(o(`onBlocksRendered`)){let t=e=>n(`blocks-rendered`,e);e.on(`blocks:rendered`,t),i.push([`blocks:rendered`,t])}if(o(`onBlockRendered`)){let t=e=>n(`block-rendered`,e);e.on(`block:rendered`,t),i.push([`block:rendered`,t])}r(()=>{for(let[t,n]of i)e.off(t,n)})});let l={last:null};return(0,e.watch)(c,e=>{e!==null&&e!==l.last&&(l.last=e,n(`ready`,e))}),r({instance:(0,e.computed)(()=>c.value),save:()=>{var e;return(e=c.value)==null?void 0:e.save()},focus:e=>{var t;(t=c.value)==null||t.focus(e)},render:e=>{var t;return(t=c.value)==null?void 0:t.render(e)}}),()=>(0,e.h)(A,f({editor:c.value},i))}});function N(t){var r;let i=(0,e.defineComponent)({name:`VueBlock(${t.type})`,props:{ctx:{type:Object,required:!0}},setup(e){return t.setup(e.ctx)}});return r=class{static get toolbox(){return t.toolbox}static get isReadOnlySupported(){return!0}constructor(r){var i,a;this.hostEl=null,this.pendingDispatch=!1,this.commit=e=>{let r=(0,n.fillDefaults)(t.propSchema,f(f({},this.mirror),e));(0,n.deepEqual)(r,this.mirror)||(this.mirror=r,this.lastRendered=r,this.dataRef.value=r,this.flushDispatch())},this.blockApi=r.block;let o=(i=r.config)==null?{}:i;this.registry=o[_];let s=r.api;this.pointerDrag=()=>{var e;return(s==null||(e=s.blocks)==null?void 0:e.isPointerDragActive)===!0},this.mirror=(0,n.fillDefaults)(t.propSchema,(0,e.toRaw)((a=r.data)==null?{}:a)),this.lastRendered=this.mirror,this.dataRef=(0,e.shallowRef)(this.mirror),this.readOnlyRef=(0,e.shallowRef)(r.readOnly);let c=this.blockApi;this.childrenComponent=(0,e.defineComponent)({name:`VueBlockChildren(${t.type})`,setup(){let t=(0,e.ref)(null),r=()=>{t.value!==null&&(0,n.mountChildBlocks)(t.value,c.getChildren())};return(0,e.onMounted)(r),(0,e.onUpdated)(r),()=>(0,e.h)(`div`,{ref:t,[n.DATA_ATTR.nestedBlocks]:``})}})}render(){var e;let t=document.createElement(`div`);t.setAttribute(`data-blok-mutation-free`,`true`),this.hostEl=t;let n={data:this.dataRef,commit:this.commit,block:this.blockApi,readOnly:this.readOnlyRef,BlockChildren:this.childrenComponent};return(e=this.registry)==null||e.register(this.blockApi.id,{hostEl:t,component:i,props:{ctx:n}}),t}rendered(){var e;(e=t.onRendered)==null||e.call(t,this.blockApi)}save(){return this.mirror}async setData(r){var i=this;let a=(0,n.fillDefaults)(t.propSchema,(0,e.toRaw)(r==null?{}:r));return(0,n.deepEqual)(a,i.lastRendered)?!0:(i.mirror=a,i.lastRendered=a,i.dataRef.value=a,await(0,e.nextTick)(),!0)}setReadOnly(e){this.readOnlyRef.value=e}moved(){var e;(e=t.onMoved)==null||e.call(t,this.blockApi)}removed(){var e,n;(e=this.registry)==null||e.unregister(this.blockApi.id),(n=t.onRemoved)==null||n.call(t,this.blockApi)}destroy(){var e;(e=this.registry)==null||e.unregister(this.blockApi.id)}flushDispatch(){if(!this.pointerDrag()){this.pendingDispatch=!1,this.blockApi.dispatchChange();return}if(this.pendingDispatch)return;this.pendingDispatch=!0;let e=()=>{if(this.pointerDrag()){requestAnimationFrame(e);return}this.pendingDispatch=!1,this.blockApi.dispatchChange()};requestAnimationFrame(e)}},r.__isBlokVueBlock=!0,r}exports.BLOK_DEFAULT_CONFIG=p,exports.BlokContent=A,exports.BlokEditor=M,exports.createVueBlock=N,exports.provideBlok=m,exports.useBlocks=E,exports.useBlok=w,exports.useBlokDefaults=h,exports.useBlokReady=D;
|
package/dist/index.mjs
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { Fragment as e, Teleport as t, computed as n, defineComponent as r, getCurrentInstance as i, h as a, inject as o, markRaw as s, nextTick as c, onBeforeUnmount as l, onErrorCaptured as u, onMounted as d, onScopeDispose as f, onUpdated as p, provide as m, reactive as
|
|
2
|
-
import { Blok as
|
|
3
|
-
import { DATA_ATTR as
|
|
1
|
+
import { Fragment as e, Teleport as t, computed as n, defineComponent as r, getCurrentInstance as i, h as a, inject as o, markRaw as s, nextTick as c, onBeforeUnmount as l, onErrorCaptured as u, onMounted as d, onScopeDispose as f, onUpdated as p, provide as m, reactive as h, ref as g, shallowRef as _, toRaw as v, toValue as y, watch as b } from "vue";
|
|
2
|
+
import { Blok as x } from "@bloklabs/core";
|
|
3
|
+
import { DATA_ATTR as S, EMPTY_API as C, createBlocksApiForEditor as w, deepEqual as T, fillDefaults as E, mountChildBlocks as D, normalizeReadOnlyConfig as O } from "@bloklabs/core/adapters";
|
|
4
4
|
//#region src/holder-map.ts
|
|
5
|
-
var
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
function A(e) {
|
|
10
|
-
return O.get(e);
|
|
5
|
+
var k = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
function A(e, t) {
|
|
7
|
+
k.set(e, t);
|
|
11
8
|
}
|
|
12
9
|
function j(e) {
|
|
13
|
-
|
|
10
|
+
return k.get(e);
|
|
11
|
+
}
|
|
12
|
+
function M(e) {
|
|
13
|
+
k.delete(e);
|
|
14
14
|
}
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/typeof.js
|
|
17
|
-
function
|
|
17
|
+
function N(e) {
|
|
18
18
|
"@babel/helpers - typeof";
|
|
19
|
-
return
|
|
19
|
+
return N = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) {
|
|
20
20
|
return typeof e;
|
|
21
21
|
} : function(e) {
|
|
22
22
|
return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
|
|
23
|
-
},
|
|
23
|
+
}, N(e);
|
|
24
24
|
}
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/toPrimitive.js
|
|
27
|
-
function
|
|
28
|
-
if (
|
|
27
|
+
function P(e, t) {
|
|
28
|
+
if (N(e) != "object" || !e) return e;
|
|
29
29
|
var n = e[Symbol.toPrimitive];
|
|
30
30
|
if (n !== void 0) {
|
|
31
31
|
var r = n.call(e, t || "default");
|
|
32
|
-
if (
|
|
32
|
+
if (N(r) != "object") return r;
|
|
33
33
|
throw TypeError("@@toPrimitive must return a primitive value.");
|
|
34
34
|
}
|
|
35
35
|
return (t === "string" ? String : Number)(e);
|
|
36
36
|
}
|
|
37
37
|
//#endregion
|
|
38
38
|
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/toPropertyKey.js
|
|
39
|
-
function
|
|
40
|
-
var t =
|
|
41
|
-
return
|
|
39
|
+
function F(e) {
|
|
40
|
+
var t = P(e, "string");
|
|
41
|
+
return N(t) == "symbol" ? t : t + "";
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
44
|
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/defineProperty.js
|
|
45
|
-
function
|
|
46
|
-
return (t =
|
|
45
|
+
function I(e, t, n) {
|
|
46
|
+
return (t = F(t)) in e ? Object.defineProperty(e, t, {
|
|
47
47
|
value: n,
|
|
48
48
|
enumerable: !0,
|
|
49
49
|
configurable: !0,
|
|
@@ -52,7 +52,7 @@ function F(e, t, n) {
|
|
|
52
52
|
}
|
|
53
53
|
//#endregion
|
|
54
54
|
//#region \0@oxc-project+runtime@0.139.0/helpers/esm/objectSpread2.js
|
|
55
|
-
function
|
|
55
|
+
function L(e, t) {
|
|
56
56
|
var n = Object.keys(e);
|
|
57
57
|
if (Object.getOwnPropertySymbols) {
|
|
58
58
|
var r = Object.getOwnPropertySymbols(e);
|
|
@@ -62,12 +62,12 @@ function I(e, t) {
|
|
|
62
62
|
}
|
|
63
63
|
return n;
|
|
64
64
|
}
|
|
65
|
-
function
|
|
65
|
+
function R(e) {
|
|
66
66
|
for (var t = 1; t < arguments.length; t++) {
|
|
67
67
|
var n = arguments[t] == null ? {} : arguments[t];
|
|
68
|
-
t % 2 ?
|
|
69
|
-
|
|
70
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) :
|
|
68
|
+
t % 2 ? L(Object(n), !0).forEach(function(t) {
|
|
69
|
+
I(e, t, n[t]);
|
|
70
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : L(Object(n)).forEach(function(t) {
|
|
71
71
|
Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t));
|
|
72
72
|
});
|
|
73
73
|
}
|
|
@@ -75,26 +75,26 @@ function L(e) {
|
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
77
|
//#region src/provide-blok.ts
|
|
78
|
-
var
|
|
79
|
-
function
|
|
80
|
-
m(
|
|
78
|
+
var z = Symbol("BLOK_DEFAULT_CONFIG");
|
|
79
|
+
function B(e) {
|
|
80
|
+
m(z, e);
|
|
81
81
|
}
|
|
82
|
-
function
|
|
83
|
-
return o(
|
|
82
|
+
function V() {
|
|
83
|
+
return o(z, {});
|
|
84
84
|
}
|
|
85
|
-
function
|
|
85
|
+
function H(e, t) {
|
|
86
86
|
if (Object.keys(e).length === 0) return t;
|
|
87
|
-
let n =
|
|
87
|
+
let n = R({}, e);
|
|
88
88
|
for (let e of Object.keys(t)) {
|
|
89
89
|
let r = t[e];
|
|
90
90
|
r !== void 0 && (n[e] = r);
|
|
91
91
|
}
|
|
92
|
-
return (e.tools !== void 0 || t.tools !== void 0) && (n.tools =
|
|
92
|
+
return (e.tools !== void 0 || t.tools !== void 0) && (n.tools = R(R({}, e.tools), t.tools)), n;
|
|
93
93
|
}
|
|
94
94
|
//#endregion
|
|
95
95
|
//#region src/block-portal-registry.ts
|
|
96
|
-
var
|
|
97
|
-
let e =
|
|
96
|
+
var U = "__blokPortalRegistry", W = () => {
|
|
97
|
+
let e = h(/* @__PURE__ */ new Map());
|
|
98
98
|
return {
|
|
99
99
|
entries: e,
|
|
100
100
|
register(t, n) {
|
|
@@ -108,19 +108,19 @@ var H = "__blokPortalRegistry", U = () => {
|
|
|
108
108
|
r !== void 0 && Object.assign(r.props, n);
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
|
-
},
|
|
112
|
-
function
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
function K(e) {
|
|
116
|
-
return W.get(e);
|
|
111
|
+
}, G = /* @__PURE__ */ new WeakMap();
|
|
112
|
+
function K(e, t) {
|
|
113
|
+
G.set(e, t);
|
|
117
114
|
}
|
|
118
115
|
function q(e) {
|
|
119
|
-
|
|
116
|
+
return G.get(e);
|
|
117
|
+
}
|
|
118
|
+
function J(e) {
|
|
119
|
+
G.delete(e);
|
|
120
120
|
}
|
|
121
121
|
//#endregion
|
|
122
122
|
//#region src/useBlok.ts
|
|
123
|
-
var
|
|
123
|
+
var Y = (e, t) => {
|
|
124
124
|
if (typeof e != "object" || !e) return e;
|
|
125
125
|
let n = {};
|
|
126
126
|
for (let [i, a] of Object.entries(e)) {
|
|
@@ -130,24 +130,24 @@ var J = (e, t) => {
|
|
|
130
130
|
n[i] = a;
|
|
131
131
|
continue;
|
|
132
132
|
}
|
|
133
|
-
let o = typeof a == "function" ? { class: a } :
|
|
134
|
-
o.config =
|
|
133
|
+
let o = typeof a == "function" ? { class: a } : R({}, a);
|
|
134
|
+
o.config = R(R({}, (r = o.config) == null ? {} : r), {}, { [U]: t }), n[i] = o;
|
|
135
135
|
}
|
|
136
136
|
return n;
|
|
137
137
|
};
|
|
138
|
-
function
|
|
139
|
-
let n =
|
|
138
|
+
function X(e, t) {
|
|
139
|
+
let n = _(null), r = o(z, {}), i = () => H(r, y(e)), a = {
|
|
140
140
|
current: null,
|
|
141
141
|
holder: null,
|
|
142
142
|
lastRenderedData: i().data,
|
|
143
143
|
seededEditor: null,
|
|
144
144
|
renderChain: Promise.resolve()
|
|
145
145
|
}, s = () => {
|
|
146
|
-
let t =
|
|
147
|
-
return delete t.holder, t.data !== void 0 && (t.data =
|
|
146
|
+
let t = R({}, H(v(r), v(y(e))));
|
|
147
|
+
return delete t.holder, t.data !== void 0 && (t.data = v(t.data)), t;
|
|
148
148
|
}, c = () => {
|
|
149
149
|
if (a.current !== null) {
|
|
150
|
-
|
|
150
|
+
M(a.current), J(a.current);
|
|
151
151
|
try {
|
|
152
152
|
a.current.destroy();
|
|
153
153
|
} catch (e) {}
|
|
@@ -156,74 +156,103 @@ function Y(e, t) {
|
|
|
156
156
|
}, u = () => {
|
|
157
157
|
let e = document.createElement("div");
|
|
158
158
|
a.holder = e;
|
|
159
|
-
let t = s(), r =
|
|
160
|
-
t.tools !== void 0 && (t.tools =
|
|
159
|
+
let t = s(), r = W();
|
|
160
|
+
t.tools !== void 0 && (t.tools = Y(t.tools, r)), typeof t.onSave == "function" && (t.onSave = (...e) => {
|
|
161
161
|
var t, n;
|
|
162
162
|
a.lastRenderedData = e[0], (t = (n = i()).onSave) == null || t.call(n, ...e);
|
|
163
163
|
});
|
|
164
|
-
let o = new
|
|
165
|
-
a.current = o,
|
|
164
|
+
let o = new x(R(R({}, t), {}, { holder: e }));
|
|
165
|
+
a.current = o, A(o, e), K(o, r), o.isReady.then(() => {
|
|
166
166
|
a.current === o && (n.value = o);
|
|
167
167
|
}).catch(() => {
|
|
168
168
|
a.current === o && c();
|
|
169
169
|
});
|
|
170
170
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
b([
|
|
172
|
+
n,
|
|
173
|
+
() => O(i().readOnly).enabled,
|
|
174
|
+
() => O(i().readOnly).hideControls,
|
|
175
|
+
() => typeof i().readOnly == "object"
|
|
176
|
+
], ([e, t, n, r]) => {
|
|
177
|
+
e && (r ? e.readOnly.set(t, { hideControls: n }) : e.readOnly.set(t));
|
|
178
|
+
}, { immediate: !0 }), b([n, () => i().hideToolbar], ([e, t]) => {
|
|
179
|
+
e && e.toolbar.setHidden(!!t);
|
|
180
|
+
}, { immediate: !0 }), b([n, () => i().theme], ([e, t]) => {
|
|
174
181
|
e && t !== void 0 && e.theme.set(t);
|
|
175
|
-
}, { immediate: !0 }),
|
|
182
|
+
}, { immediate: !0 }), b([n, () => i().width], ([e, t]) => {
|
|
176
183
|
e && t !== void 0 && e.width.set(t);
|
|
177
|
-
}, { immediate: !0 }),
|
|
184
|
+
}, { immediate: !0 }), b([n, () => i().placeholder], ([e, t]) => {
|
|
178
185
|
e && t !== void 0 && e.placeholder.set(t);
|
|
179
186
|
}, { immediate: !0 });
|
|
180
187
|
let f = { value: void 0 };
|
|
181
|
-
|
|
188
|
+
b([n, () => {
|
|
182
189
|
var e;
|
|
183
190
|
return (e = i().style) == null ? void 0 : e.tokens;
|
|
184
191
|
}], ([e, t]) => {
|
|
185
|
-
!e || t === void 0 ||
|
|
192
|
+
!e || t === void 0 || T(t, f.value) || (f.value = R({}, t), e.tokens.set(t));
|
|
186
193
|
}, {
|
|
187
194
|
immediate: !0,
|
|
188
195
|
deep: !0
|
|
189
|
-
})
|
|
196
|
+
});
|
|
197
|
+
let p = { value: i().i18n };
|
|
198
|
+
b([n, () => i().i18n], ([e, t]) => {
|
|
199
|
+
if (!e || t === void 0 || T(t, p.value)) return;
|
|
200
|
+
p.value = R({}, t);
|
|
201
|
+
let { locale: n, messages: r, direction: i } = t;
|
|
202
|
+
e.i18n.update(R(R(R({}, n === void 0 ? {} : { locale: n }), r === void 0 ? {} : { messages: r }), i === void 0 ? {} : { direction: i }));
|
|
203
|
+
}, {
|
|
204
|
+
immediate: !0,
|
|
205
|
+
deep: !0
|
|
206
|
+
});
|
|
207
|
+
let m = {
|
|
208
|
+
editor: null,
|
|
209
|
+
value: void 0
|
|
210
|
+
};
|
|
211
|
+
return b([n, () => i().inlineToolbar], ([e, t]) => {
|
|
212
|
+
if (!e || t === void 0 || m.editor === e && T(t, m.value)) return;
|
|
213
|
+
let n = Array.isArray(t) ? [...t] : t;
|
|
214
|
+
m.editor = e, m.value = n, e.tools.setInlineToolbar(n);
|
|
215
|
+
}, {
|
|
216
|
+
immediate: !0,
|
|
217
|
+
deep: !0
|
|
218
|
+
}), b([n, () => i().autofocus], ([e, t]) => {
|
|
190
219
|
e && t && e.focus();
|
|
191
|
-
}, { immediate: !0 }),
|
|
220
|
+
}, { immediate: !0 }), b([n, () => i().data], ([e, t]) => {
|
|
192
221
|
if (!(!e || t === void 0)) {
|
|
193
222
|
if (a.seededEditor !== e) {
|
|
194
223
|
a.seededEditor = e, a.lastRenderedData = t;
|
|
195
224
|
return;
|
|
196
225
|
}
|
|
197
|
-
|
|
226
|
+
T(t, a.lastRenderedData) || (a.lastRenderedData = t, a.renderChain = a.renderChain.catch(() => void 0).then(() => e.render(v(t))));
|
|
198
227
|
}
|
|
199
|
-
}, { immediate: !0 }), t !== void 0 &&
|
|
228
|
+
}, { immediate: !0 }), t !== void 0 && b(() => y(t), () => {
|
|
200
229
|
c(), u();
|
|
201
230
|
}), d(u), l(c), n;
|
|
202
231
|
}
|
|
203
232
|
//#endregion
|
|
204
233
|
//#region src/useBlocks.ts
|
|
205
|
-
var
|
|
206
|
-
function
|
|
207
|
-
let t =
|
|
208
|
-
let t =
|
|
209
|
-
return t === null ? null :
|
|
234
|
+
var Z = "block changed";
|
|
235
|
+
function Q(e) {
|
|
236
|
+
let t = _(0), n = () => {
|
|
237
|
+
let t = y(e);
|
|
238
|
+
return t === null ? null : v(t);
|
|
210
239
|
}, r = () => {
|
|
211
240
|
t.value;
|
|
212
|
-
}, i =
|
|
241
|
+
}, i = _(C), a = {
|
|
213
242
|
editor: null,
|
|
214
243
|
handler: null
|
|
215
244
|
}, o = () => {
|
|
216
|
-
a.editor !== null && a.handler !== null && a.editor.off(
|
|
245
|
+
a.editor !== null && a.handler !== null && a.editor.off(Z, a.handler), a.editor = null, a.handler = null;
|
|
217
246
|
};
|
|
218
|
-
return
|
|
247
|
+
return b(() => n(), (e) => {
|
|
219
248
|
if (o(), t.value += 1, e === null) {
|
|
220
|
-
i.value =
|
|
249
|
+
i.value = C;
|
|
221
250
|
return;
|
|
222
251
|
}
|
|
223
252
|
let n = () => {
|
|
224
253
|
t.value += 1;
|
|
225
254
|
};
|
|
226
|
-
e.on(
|
|
255
|
+
e.on(Z, n), a.editor = e, a.handler = n, i.value = w(e, r);
|
|
227
256
|
}, { immediate: !0 }), f(o), {
|
|
228
257
|
getById: (e) => i.value.getById(e),
|
|
229
258
|
getChildren: (e) => i.value.getChildren(e),
|
|
@@ -257,8 +286,21 @@ function Z(e) {
|
|
|
257
286
|
};
|
|
258
287
|
}
|
|
259
288
|
//#endregion
|
|
289
|
+
//#region src/useBlokReady.ts
|
|
290
|
+
function ee(e = {}) {
|
|
291
|
+
let { within: t, settleOn: n } = e, r = _(!1), i = () => {
|
|
292
|
+
var e;
|
|
293
|
+
let i = t === void 0 || (e = y(t)) == null ? null : e;
|
|
294
|
+
r.value = t !== void 0 && i === null ? !1 : x.readyState({
|
|
295
|
+
within: i,
|
|
296
|
+
settleOn: n
|
|
297
|
+
}).ready;
|
|
298
|
+
};
|
|
299
|
+
return f(x.subscribeReady(i)), d(i), r;
|
|
300
|
+
}
|
|
301
|
+
//#endregion
|
|
260
302
|
//#region src/BlockPortalHost.ts
|
|
261
|
-
var
|
|
303
|
+
var te = r({
|
|
262
304
|
name: "BlockErrorBoundary",
|
|
263
305
|
setup(e, { slots: t }) {
|
|
264
306
|
return u(() => !1), () => {
|
|
@@ -266,7 +308,7 @@ var Q = r({
|
|
|
266
308
|
return (e = t.default) == null ? void 0 : e.call(t);
|
|
267
309
|
};
|
|
268
310
|
}
|
|
269
|
-
}),
|
|
311
|
+
}), ne = r({
|
|
270
312
|
name: "BlockPortalHost",
|
|
271
313
|
props: { registry: {
|
|
272
314
|
type: Object,
|
|
@@ -276,7 +318,7 @@ var Q = r({
|
|
|
276
318
|
return () => a(e, Array.from(n.registry.entries.entries()).map(([e, n]) => a(t, {
|
|
277
319
|
key: e,
|
|
278
320
|
to: n.hostEl
|
|
279
|
-
}, [a(
|
|
321
|
+
}, [a(te, null, { default: () => a(n.component, n.props) })])));
|
|
280
322
|
}
|
|
281
323
|
}), $ = r({
|
|
282
324
|
name: "BlokContent",
|
|
@@ -285,26 +327,26 @@ var Q = r({
|
|
|
285
327
|
default: null
|
|
286
328
|
} },
|
|
287
329
|
setup(e) {
|
|
288
|
-
let t =
|
|
330
|
+
let t = g(null), n = (e) => {
|
|
289
331
|
if (t.value === null || e === null) return;
|
|
290
|
-
let n =
|
|
332
|
+
let n = j(v(e));
|
|
291
333
|
n !== void 0 && t.value.appendChild(n);
|
|
292
334
|
}, r = (e) => {
|
|
293
335
|
var t;
|
|
294
|
-
e !== null && ((t =
|
|
336
|
+
e !== null && ((t = j(v(e))) == null || t.remove());
|
|
295
337
|
};
|
|
296
338
|
return d(() => {
|
|
297
339
|
n(e.editor);
|
|
298
|
-
}),
|
|
340
|
+
}), b(() => e.editor, (e, t) => {
|
|
299
341
|
r(t == null ? null : t), n(e);
|
|
300
342
|
}), l(() => {
|
|
301
343
|
r(e.editor);
|
|
302
344
|
}), () => {
|
|
303
|
-
let n = e.editor, r = n === null ? void 0 :
|
|
304
|
-
return a("div", { ref: t }, r === void 0 ? [] : [a(
|
|
345
|
+
let n = e.editor, r = n === null ? void 0 : q(v(n));
|
|
346
|
+
return a("div", { ref: t }, r === void 0 ? [] : [a(ne, { registry: r })]);
|
|
305
347
|
};
|
|
306
348
|
}
|
|
307
|
-
}),
|
|
349
|
+
}), re = /* @__PURE__ */ "autofocus.defaultBlock.dataModel.placeholder.sanitizer.hideToolbar.maxHistoryLength.historyDebounceTime.newGroupDelay.globalUndoRedo.tools.data.minHeight.logLevel.readOnly.i18n.link.linkPaste.inlineToolbar.tunes.style.theme.scrollToBlock.user.resolveUser.notifierPosition.notifier.width.onBeforeRender.onBeforePaste.onEnter".split("."), ie = r({
|
|
308
350
|
name: "BlokEditor",
|
|
309
351
|
inheritAttrs: !1,
|
|
310
352
|
props: {
|
|
@@ -365,7 +407,7 @@ var Q = r({
|
|
|
365
407
|
default: void 0
|
|
366
408
|
},
|
|
367
409
|
readOnly: {
|
|
368
|
-
type: Boolean,
|
|
410
|
+
type: [Boolean, Object],
|
|
369
411
|
default: void 0
|
|
370
412
|
},
|
|
371
413
|
i18n: {
|
|
@@ -450,7 +492,7 @@ var Q = r({
|
|
|
450
492
|
return t != null && e in t;
|
|
451
493
|
}, l = () => {
|
|
452
494
|
let n = {};
|
|
453
|
-
for (let t of
|
|
495
|
+
for (let t of re) {
|
|
454
496
|
let r = e[t];
|
|
455
497
|
r !== void 0 && (n[t] = r);
|
|
456
498
|
}
|
|
@@ -466,8 +508,8 @@ var Q = r({
|
|
|
466
508
|
}), c("onThemeChange") && (n.onThemeChange = (e) => {
|
|
467
509
|
t("theme-change", e);
|
|
468
510
|
}), n;
|
|
469
|
-
}, u =
|
|
470
|
-
|
|
511
|
+
}, u = X(() => l(), () => e.recreateKey);
|
|
512
|
+
b(u, (e, n, r) => {
|
|
471
513
|
if (e === null) return;
|
|
472
514
|
let i = [];
|
|
473
515
|
if (c("onBlocksRendered")) {
|
|
@@ -483,7 +525,7 @@ var Q = r({
|
|
|
483
525
|
});
|
|
484
526
|
});
|
|
485
527
|
let d = { last: null };
|
|
486
|
-
return
|
|
528
|
+
return b(u, (e) => {
|
|
487
529
|
e !== null && e !== d.last && (d.last = e, t("ready", e));
|
|
488
530
|
}), r({
|
|
489
531
|
instance: n(() => u.value),
|
|
@@ -499,12 +541,12 @@ var Q = r({
|
|
|
499
541
|
var t;
|
|
500
542
|
return (t = u.value) == null ? void 0 : t.render(e);
|
|
501
543
|
}
|
|
502
|
-
}), () => a($,
|
|
544
|
+
}), () => a($, R({ editor: u.value }, o));
|
|
503
545
|
}
|
|
504
546
|
});
|
|
505
547
|
//#endregion
|
|
506
548
|
//#region src/createVueBlock.ts
|
|
507
|
-
function
|
|
549
|
+
function ae(e) {
|
|
508
550
|
var t;
|
|
509
551
|
let n = r({
|
|
510
552
|
name: `VueBlock(${e.type})`,
|
|
@@ -526,26 +568,26 @@ function ie(e) {
|
|
|
526
568
|
constructor(t) {
|
|
527
569
|
var n, i;
|
|
528
570
|
this.hostEl = null, this.pendingDispatch = !1, this.commit = (t) => {
|
|
529
|
-
let n =
|
|
530
|
-
|
|
571
|
+
let n = E(e.propSchema, R(R({}, this.mirror), t));
|
|
572
|
+
T(n, this.mirror) || (this.mirror = n, this.lastRendered = n, this.dataRef.value = n, this.flushDispatch());
|
|
531
573
|
}, this.blockApi = t.block;
|
|
532
574
|
let o = (n = t.config) == null ? {} : n;
|
|
533
|
-
this.registry = o[
|
|
575
|
+
this.registry = o[U];
|
|
534
576
|
let s = t.api;
|
|
535
577
|
this.pointerDrag = () => {
|
|
536
578
|
var e;
|
|
537
579
|
return (s == null || (e = s.blocks) == null ? void 0 : e.isPointerDragActive) === !0;
|
|
538
|
-
}, this.mirror =
|
|
580
|
+
}, this.mirror = E(e.propSchema, v((i = t.data) == null ? {} : i)), this.lastRendered = this.mirror, this.dataRef = _(this.mirror), this.readOnlyRef = _(t.readOnly);
|
|
539
581
|
let c = this.blockApi;
|
|
540
582
|
this.childrenComponent = r({
|
|
541
583
|
name: `VueBlockChildren(${e.type})`,
|
|
542
584
|
setup() {
|
|
543
|
-
let e =
|
|
544
|
-
e.value !== null &&
|
|
585
|
+
let e = g(null), t = () => {
|
|
586
|
+
e.value !== null && D(e.value, c.getChildren());
|
|
545
587
|
};
|
|
546
588
|
return d(t), p(t), () => a("div", {
|
|
547
589
|
ref: e,
|
|
548
|
-
[
|
|
590
|
+
[S.nestedBlocks]: ""
|
|
549
591
|
});
|
|
550
592
|
}
|
|
551
593
|
});
|
|
@@ -576,8 +618,8 @@ function ie(e) {
|
|
|
576
618
|
}
|
|
577
619
|
async setData(t) {
|
|
578
620
|
var n = this;
|
|
579
|
-
let r =
|
|
580
|
-
return
|
|
621
|
+
let r = E(e.propSchema, v(t == null ? {} : t));
|
|
622
|
+
return T(r, n.lastRendered) ? !0 : (n.mirror = r, n.lastRendered = r, n.dataRef.value = r, await c(), !0);
|
|
581
623
|
}
|
|
582
624
|
setReadOnly(e) {
|
|
583
625
|
this.readOnlyRef.value = e;
|
|
@@ -613,4 +655,4 @@ function ie(e) {
|
|
|
613
655
|
}, t.__isBlokVueBlock = !0, t;
|
|
614
656
|
}
|
|
615
657
|
//#endregion
|
|
616
|
-
export {
|
|
658
|
+
export { z as BLOK_DEFAULT_CONFIG, $ as BlokContent, ie as BlokEditor, ae as createVueBlock, B as provideBlok, Q as useBlocks, X as useBlok, V as useBlokDefaults, ee as useBlokReady };
|
package/package.json
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloklabs/vue",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Vue 3 bindings for the
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Vue block editor — official Vue 3 bindings for Blok, the headless Notion-like rich text editor. Composables and components that render blocks and save to JSON.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "JackUait",
|
|
7
|
+
"homepage": "https://blokeditor.com",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
10
|
"url": "git+https://github.com/JackUait/blok.git",
|
|
10
11
|
"directory": "packages/vue"
|
|
11
12
|
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/JackUait/blok/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"blok",
|
|
18
|
+
"vue",
|
|
19
|
+
"vue3",
|
|
20
|
+
"vue-component",
|
|
21
|
+
"block-editor",
|
|
22
|
+
"rich-text-editor",
|
|
23
|
+
"wysiwyg",
|
|
24
|
+
"editor",
|
|
25
|
+
"notion",
|
|
26
|
+
"notion-like",
|
|
27
|
+
"headless",
|
|
28
|
+
"block-based",
|
|
29
|
+
"contenteditable",
|
|
30
|
+
"json",
|
|
31
|
+
"typescript"
|
|
32
|
+
],
|
|
12
33
|
"type": "module",
|
|
13
34
|
"sideEffects": false,
|
|
14
35
|
"main": "./dist/index.cjs",
|
|
@@ -33,7 +54,7 @@
|
|
|
33
54
|
"build": "yarn run -T vite build --mode production"
|
|
34
55
|
},
|
|
35
56
|
"peerDependencies": {
|
|
36
|
-
"@bloklabs/core": "^1.
|
|
57
|
+
"@bloklabs/core": "^1.4.0",
|
|
37
58
|
"vue": "^3.5.0"
|
|
38
59
|
}
|
|
39
60
|
}
|
package/src/BlokEditor.ts
CHANGED
|
@@ -45,7 +45,9 @@ export const BlokEditor = defineComponent({
|
|
|
45
45
|
data: { type: Object as PropType<OutputData>, default: undefined },
|
|
46
46
|
minHeight: { type: Number, default: undefined },
|
|
47
47
|
logLevel: { type: String as PropType<BlokConfig['logLevel']>, default: undefined },
|
|
48
|
-
|
|
48
|
+
// [Boolean, Object]: the object form ({ hideControls }) must not be dropped
|
|
49
|
+
// or dev-warned — it always means read-only enabled (reactive contract).
|
|
50
|
+
readOnly: { type: [Boolean, Object] as PropType<BlokConfig['readOnly']>, default: undefined },
|
|
49
51
|
i18n: { type: Object as PropType<BlokConfig['i18n']>, default: undefined },
|
|
50
52
|
link: { type: Object as PropType<BlokConfig['link']>, default: undefined },
|
|
51
53
|
linkPaste: { type: Object as PropType<BlokConfig['linkPaste']>, default: undefined },
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { useBlok } from './useBlok';
|
|
2
2
|
export { useBlocks } from './useBlocks';
|
|
3
|
+
export { useBlokReady } from './useBlokReady';
|
|
3
4
|
export { BlokContent } from './BlokContent';
|
|
4
5
|
export { BlokEditor } from './BlokEditor';
|
|
5
6
|
export { provideBlok, useBlokDefaults, BLOK_DEFAULT_CONFIG } from './provide-blok';
|
|
6
7
|
export { createVueBlock } from './createVueBlock';
|
|
7
8
|
export type { UseBlokConfig, BlokContentProps } from './types';
|
|
9
|
+
export type { UseBlokReadyOptions } from './useBlokReady';
|
|
8
10
|
export type {
|
|
9
11
|
UseBlocksApi,
|
|
10
12
|
BlockNode,
|
package/src/types.ts
CHANGED
|
@@ -6,7 +6,12 @@ import type { BlokConfig, Blok, EditorWidth } from '@/types';
|
|
|
6
6
|
* reactive `width` prop.
|
|
7
7
|
*
|
|
8
8
|
* Reactive props (sync after mount without recreation):
|
|
9
|
-
* - `readOnly` — calls `editor.readOnly.set(
|
|
9
|
+
* - `readOnly` — calls `editor.readOnly.set(enabled, { hideControls })`; the
|
|
10
|
+
* object form's `hideControls` is live too (toggles in place — see
|
|
11
|
+
* `editor.readOnly.togglesInPlace`)
|
|
12
|
+
* - `hideToolbar` — calls `editor.toolbar.setHidden(value)` (undefined → false)
|
|
13
|
+
* - `inlineToolbar` — calls `editor.tools.setInlineToolbar(value)`
|
|
14
|
+
* (content-compared, so a fresh array with the same names is a no-op)
|
|
10
15
|
* - `autofocus` — calls `editor.focus()` when changed to true
|
|
11
16
|
* - `theme` — calls `editor.theme.set(value)`
|
|
12
17
|
* - `width` — calls `editor.width.set(value)`
|
package/src/useBlok.ts
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
type BlockPortalRegistry,
|
|
20
20
|
} from './block-portal-registry';
|
|
21
21
|
import { setRegistry, removeRegistry } from './registry-map';
|
|
22
|
-
import type { Blok, LooseOutputData, OutputData } from '@/types';
|
|
22
|
+
import type { Blok, BlokConfig, LooseOutputData, OutputData } from '@/types';
|
|
23
23
|
import type { UseBlokConfig } from './types';
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -199,11 +199,31 @@ export function useBlok(
|
|
|
199
199
|
// once the instance appears (the Vue analog of React's `editor` effect-dep).
|
|
200
200
|
// `theme`/`width`/`placeholder` guard on `=== undefined` (NOT falsiness) so a
|
|
201
201
|
// real `placeholder: false` (clear) still propagates.
|
|
202
|
+
// readOnly syncs the full normalized pair: `enabled` always, `hideControls`
|
|
203
|
+
// only for the object form (`readOnly.set` toggles IN PLACE — see
|
|
204
|
+
// `readOnly.togglesInPlace` — so no recreation is ever needed).
|
|
202
205
|
watch(
|
|
203
|
-
[
|
|
204
|
-
|
|
206
|
+
[
|
|
207
|
+
editor,
|
|
208
|
+
() => normalizeReadOnlyConfig(mergedConfig().readOnly).enabled,
|
|
209
|
+
() => normalizeReadOnlyConfig(mergedConfig().readOnly).hideControls,
|
|
210
|
+
() => typeof mergedConfig().readOnly === 'object',
|
|
211
|
+
],
|
|
212
|
+
([ed, readOnlyEnabled, hideControls, isObjectForm]) => {
|
|
205
213
|
if (ed) {
|
|
206
|
-
void ed.readOnly.set(readOnlyEnabled);
|
|
214
|
+
void (isObjectForm ? ed.readOnly.set(readOnlyEnabled, { hideControls }) : ed.readOnly.set(readOnlyEnabled));
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
{ immediate: true }
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// hideToolbar toggles the hover toolbar and its gutter in place. Coerces
|
|
221
|
+
// undefined to false (like readOnly) so clearing the option propagates.
|
|
222
|
+
watch(
|
|
223
|
+
[editor, () => mergedConfig().hideToolbar],
|
|
224
|
+
([ed, hideToolbar]) => {
|
|
225
|
+
if (ed) {
|
|
226
|
+
ed.toolbar.setHidden(Boolean(hideToolbar));
|
|
207
227
|
}
|
|
208
228
|
},
|
|
209
229
|
{ immediate: true }
|
|
@@ -258,6 +278,69 @@ export function useBlok(
|
|
|
258
278
|
{ immediate: true, deep: true }
|
|
259
279
|
);
|
|
260
280
|
|
|
281
|
+
// `config.i18n` was consumed once during boot, so a host driving a language
|
|
282
|
+
// switcher had to recreate the editor (losing caret, focus and undo stack)
|
|
283
|
+
// to relabel the UI. This drives the runtime `i18n.update` API instead.
|
|
284
|
+
// Deep-equal-deduped and `deep: true` for the same reasons as tokens.
|
|
285
|
+
// `defaultLocale` is not forwarded: it only affects the INITIAL locale
|
|
286
|
+
// resolution, so it is inert after mount.
|
|
287
|
+
/*
|
|
288
|
+
* Seeded with the mount-time value: construction already applied it, so the
|
|
289
|
+
* immediate run is a no-op and only genuine changes push.
|
|
290
|
+
*/
|
|
291
|
+
const appliedI18n: { value: BlokConfig['i18n'] | undefined } = { value: mergedConfig().i18n };
|
|
292
|
+
|
|
293
|
+
watch(
|
|
294
|
+
[editor, () => mergedConfig().i18n],
|
|
295
|
+
([ed, i18n]) => {
|
|
296
|
+
if (!ed || i18n === undefined || deepEqual(i18n, appliedI18n.value)) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
appliedI18n.value = { ...i18n };
|
|
301
|
+
|
|
302
|
+
const { locale, messages, direction } = i18n;
|
|
303
|
+
|
|
304
|
+
void ed.i18n.update({
|
|
305
|
+
...(locale === undefined ? {} : { locale }),
|
|
306
|
+
...(messages === undefined ? {} : { messages }),
|
|
307
|
+
...(direction === undefined ? {} : { direction }),
|
|
308
|
+
});
|
|
309
|
+
},
|
|
310
|
+
{ immediate: true, deep: true }
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
// inlineToolbar re-assigns inline tools in place. Content-compared (not
|
|
314
|
+
// identity-compared) because `boolean | string[]` configs are typically fresh
|
|
315
|
+
// array literals; the baseline is tracked per editor instance so a recreated
|
|
316
|
+
// editor gets the current value applied again. `deep: true` so mutating the
|
|
317
|
+
// same array still propagates (mirrors the tokens watch).
|
|
318
|
+
const appliedInlineToolbar: { editor: Blok | null; value: boolean | string[] | undefined } = {
|
|
319
|
+
editor: null,
|
|
320
|
+
value: undefined,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
watch(
|
|
324
|
+
[editor, () => mergedConfig().inlineToolbar],
|
|
325
|
+
([ed, inlineToolbar]) => {
|
|
326
|
+
if (!ed || inlineToolbar === undefined) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (appliedInlineToolbar.editor === ed && deepEqual(inlineToolbar, appliedInlineToolbar.value)) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// De-proxy: copy an array so no Vue reactive proxy reaches core.
|
|
335
|
+
const plain = Array.isArray(inlineToolbar) ? [...inlineToolbar] : inlineToolbar;
|
|
336
|
+
|
|
337
|
+
appliedInlineToolbar.editor = ed;
|
|
338
|
+
appliedInlineToolbar.value = plain;
|
|
339
|
+
ed.tools.setInlineToolbar(plain);
|
|
340
|
+
},
|
|
341
|
+
{ immediate: true, deep: true }
|
|
342
|
+
);
|
|
343
|
+
|
|
261
344
|
watch(
|
|
262
345
|
[editor, () => mergedConfig().autofocus],
|
|
263
346
|
([ed, autofocus]) => {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// packages/vue/src/useBlokReady.ts
|
|
2
|
+
import {
|
|
3
|
+
onMounted,
|
|
4
|
+
onScopeDispose,
|
|
5
|
+
shallowRef,
|
|
6
|
+
toValue,
|
|
7
|
+
type MaybeRefOrGetter,
|
|
8
|
+
type ShallowRef,
|
|
9
|
+
} from 'vue';
|
|
10
|
+
|
|
11
|
+
import { Blok as BlokRuntime } from '@bloklabs/core';
|
|
12
|
+
|
|
13
|
+
/** Options accepted by {@link useBlokReady}. */
|
|
14
|
+
export interface UseBlokReadyOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Restrict the wait to editors mounted inside this element. Accepts the
|
|
17
|
+
* template ref you already hold on the container (or a getter); it is
|
|
18
|
+
* re-read on every readiness change, so a ref that fills in on mount is
|
|
19
|
+
* picked up.
|
|
20
|
+
*
|
|
21
|
+
* Omit it to observe every editor on the page. Passing it while it still
|
|
22
|
+
* resolves to null reports NOT ready — an unresolved scope must never fall
|
|
23
|
+
* back to the page-global one.
|
|
24
|
+
*/
|
|
25
|
+
within?: MaybeRefOrGetter<Element | null | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* `'ready'` (default) settles when each editor has finished booting.
|
|
28
|
+
* `'rendered'` also waits for its content to be in the DOM and re-arms on
|
|
29
|
+
* every post-boot re-render.
|
|
30
|
+
*/
|
|
31
|
+
settleOn?: 'ready' | 'rendered';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Vue composable exposing the live readiness of the Blok editors in a DOM
|
|
36
|
+
* scope as a boolean ref.
|
|
37
|
+
*
|
|
38
|
+
* The readiness logic itself is framework-agnostic and lives in core
|
|
39
|
+
* (`Blok.readyState` / `Blok.subscribeReady`) — the SAME implementation behind
|
|
40
|
+
* React's `useBlokReady` and Angular's `injectBlokReady`, so the three adapters
|
|
41
|
+
* cannot drift. This composable supplies only Vue's reactivity wrapper: a
|
|
42
|
+
* `shallowRef` re-read on every registry change, with the subscription
|
|
43
|
+
* disposed by the surrounding effect scope.
|
|
44
|
+
*
|
|
45
|
+
* The ref starts `false` and takes its first real reading on mount, once the
|
|
46
|
+
* template ref has filled in. Over-waiting is safe; under-waiting is a bug.
|
|
47
|
+
* @param options - scope and readiness depth
|
|
48
|
+
*/
|
|
49
|
+
export function useBlokReady(options: UseBlokReadyOptions = {}): Readonly<ShallowRef<boolean>> {
|
|
50
|
+
const { within, settleOn } = options;
|
|
51
|
+
const ready = shallowRef(false);
|
|
52
|
+
|
|
53
|
+
const read = (): void => {
|
|
54
|
+
const scope = within === undefined ? null : (toValue(within) ?? null);
|
|
55
|
+
|
|
56
|
+
// A scope that was asked for but has not resolved yet is NOT the global
|
|
57
|
+
// scope — reporting ready here would gate on the wrong set of editors.
|
|
58
|
+
ready.value = within !== undefined && scope === null
|
|
59
|
+
? false
|
|
60
|
+
: BlokRuntime.readyState({
|
|
61
|
+
within: scope,
|
|
62
|
+
settleOn,
|
|
63
|
+
}).ready;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
onScopeDispose(BlokRuntime.subscribeReady(read));
|
|
67
|
+
onMounted(read);
|
|
68
|
+
|
|
69
|
+
return ready;
|
|
70
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -22,11 +22,22 @@ import type { MarkdownImportConfig } from '@bloklabs/core/markdown';
|
|
|
22
22
|
* plus a reactive `width` prop.
|
|
23
23
|
*
|
|
24
24
|
* Reactive props (sync after mount without recreation):
|
|
25
|
-
* - `readOnly` — calls `editor.readOnly.set(
|
|
25
|
+
* - `readOnly` — calls `editor.readOnly.set(enabled, { hideControls })`; the
|
|
26
|
+
* object form's `hideControls` is live too (toggles in place — see
|
|
27
|
+
* `editor.readOnly.togglesInPlace`)
|
|
28
|
+
* - `hideToolbar` — calls `editor.toolbar.setHidden(value)` (undefined → false)
|
|
29
|
+
* - `inlineToolbar` — calls `editor.tools.setInlineToolbar(value)`
|
|
30
|
+
* (content-compared, so a fresh array with the same names is a no-op)
|
|
26
31
|
* - `autofocus` — calls `editor.focus()` when changed to true
|
|
27
32
|
* - `theme` — calls `editor.theme.set(value)`
|
|
28
33
|
* - `width` — calls `editor.width.set(value)`
|
|
29
34
|
* - `placeholder` — calls `editor.placeholder.set(value)`
|
|
35
|
+
* - `style.tokens` — calls `editor.tokens.set(value)` (deep-equal–deduped;
|
|
36
|
+
* replace semantics, so pass the complete token set on each change)
|
|
37
|
+
* - `i18n` — calls `editor.i18n.update({ locale, messages, direction })`
|
|
38
|
+
* (deep-equal–deduped; relabels the editor chrome in place, so caret, focus
|
|
39
|
+
* and undo history survive a language switch). `defaultLocale` is not
|
|
40
|
+
* forwarded — it only affects the initial locale resolution.
|
|
30
41
|
* - `data` — re-renders via `editor.render(value)` when content changes
|
|
31
42
|
* (deep-equal–deduped and serialized; seeds the initial content at creation)
|
|
32
43
|
*
|
|
@@ -437,6 +448,48 @@ export interface UseBlocksApi {
|
|
|
437
448
|
*/
|
|
438
449
|
export declare function useBlocks(editor: MaybeRefOrGetter<Blok | null>): UseBlocksApi;
|
|
439
450
|
|
|
451
|
+
/** Options accepted by {@link useBlokReady}. */
|
|
452
|
+
export interface UseBlokReadyOptions {
|
|
453
|
+
/**
|
|
454
|
+
* Restrict the wait to editors mounted inside this element. Accepts the
|
|
455
|
+
* template ref you already hold on the container (or a getter); it is
|
|
456
|
+
* re-read on every readiness change, so a ref that fills in on mount is
|
|
457
|
+
* picked up.
|
|
458
|
+
*
|
|
459
|
+
* Omit it to observe every editor on the page. Passing it while it still
|
|
460
|
+
* resolves to null reports NOT ready — an unresolved scope must never fall
|
|
461
|
+
* back to the page-global one.
|
|
462
|
+
*/
|
|
463
|
+
within?: MaybeRefOrGetter<Element | null | undefined>;
|
|
464
|
+
/**
|
|
465
|
+
* `'ready'` (default) settles when each editor has finished booting.
|
|
466
|
+
* `'rendered'` also waits for its content to be in the DOM and re-arms on
|
|
467
|
+
* every post-boot re-render.
|
|
468
|
+
*/
|
|
469
|
+
settleOn?: 'ready' | 'rendered';
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Composable exposing the live readiness of the Blok editors in a DOM scope as
|
|
474
|
+
* a boolean ref. Mirrors React's `useBlokReady` and Angular's
|
|
475
|
+
* `injectBlokReady` — all three wrap the same core registry, so they cannot
|
|
476
|
+
* drift.
|
|
477
|
+
*
|
|
478
|
+
* The ref starts `false` and takes its first real reading on mount, once the
|
|
479
|
+
* template ref has filled in. Editors mounted later re-close the gate, and with
|
|
480
|
+
* `settleOn: 'rendered'` so does every re-render. A scope holding no editors is
|
|
481
|
+
* ready.
|
|
482
|
+
*
|
|
483
|
+
* @param options - scope and readiness depth
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```ts
|
|
487
|
+
* const list = ref<HTMLElement | null>(null);
|
|
488
|
+
* const ready = useBlokReady({ within: list, settleOn: 'rendered' });
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
export declare function useBlokReady(options?: UseBlokReadyOptions): Readonly<ShallowRef<boolean>>;
|
|
492
|
+
|
|
440
493
|
/** One field of a {@link CreateVueBlockSpec.propSchema}. */
|
|
441
494
|
export interface PropSchemaEntry {
|
|
442
495
|
default: unknown;
|