@b10cks/vue 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -42
- package/dist/index.mjs.map +1 -1
- package/dist/vue/src/preview-bridge.d.ts +4 -4
- package/package.json +26 -26
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @b10cks/vue
|
|
2
|
+
|
|
3
|
+
Vue 3 SDK for integrating b10cks into your Vue applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @b10cks/vue @b10cks/client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Plugin Setup
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createApp } from 'vue'
|
|
17
|
+
import { B10cksVue } from '@b10cks/vue'
|
|
18
|
+
import app from './App.vue'
|
|
19
|
+
|
|
20
|
+
const app = createApp(App)
|
|
21
|
+
|
|
22
|
+
app.use(B10cksVue, {
|
|
23
|
+
accessToken: 'your-access-token',
|
|
24
|
+
apiUrl: 'https://api.b10cks.com/api',
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
app.mount('#app')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Directives
|
|
31
|
+
|
|
32
|
+
#### `v-editable`
|
|
33
|
+
|
|
34
|
+
Mark content as editable within the b10cks editor.
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<div v-editable="block">
|
|
38
|
+
Content here
|
|
39
|
+
</div>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### `v-editable-field`
|
|
43
|
+
|
|
44
|
+
Mark specific fields within editable blocks.
|
|
45
|
+
|
|
46
|
+
```vue
|
|
47
|
+
<div v-editable="block">
|
|
48
|
+
<h1 v-editable-field="{ id: block.id, field: 'title' }">Title</h1>
|
|
49
|
+
<p v-editable-field="{ id: block.id, field: 'description' }">Description</p>
|
|
50
|
+
</div>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Components
|
|
54
|
+
|
|
55
|
+
#### `B10cksComponent`
|
|
56
|
+
|
|
57
|
+
Render b10cks components directly in your Vue app.
|
|
58
|
+
|
|
59
|
+
```vue
|
|
60
|
+
<B10cksComponent :component="componentData" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## API Client
|
|
64
|
+
|
|
65
|
+
Access the underlying API client for direct API calls:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { ApiClient } from '@b10cks/client'
|
|
69
|
+
|
|
70
|
+
const client = new ApiClient(
|
|
71
|
+
{
|
|
72
|
+
baseUrl: 'https://api.b10cks.com/api',
|
|
73
|
+
token: 'your-token',
|
|
74
|
+
fetchClient: fetch,
|
|
75
|
+
},
|
|
76
|
+
new URL(window.location.href)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
const blocks = await client.get('blocks')
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue");class c{static instance;eventListeners={};isEnabled=!1;constructor(){this.isEnabled=this.isIframe()}init(){this.isEnabled&&window&&window.addEventListener("message",this.handleMessage)}static getInstance(){return c.instance||(c.instance=new c),c.instance}isInPreviewMode(){return this.isEnabled}isIframe(){return window&&window.self!==window.top}handleMessage=t=>{if(!t.data||typeof t.data!="object")return;const{type:s,payload:n}=t.data;this.notifyListeners(s,n)};notifyListeners(t,s){const n=this.eventListeners[t];n&&n.forEach(r=>r(s))}on(t,s){return this.isEnabled?(this.eventListeners[t]||(this.eventListeners[t]=[]),this.eventListeners[t].push(s),()=>{this.eventListeners[t]=this.eventListeners[t].filter(n=>n!==s)}):()=>{}}selectItem(t){this.isEnabled&&window.parent.postMessage({type:"SELECT_UPDATE",payload:{selectedItem:t}},"*")}updateField(t,s,n){this.isEnabled&&window.parent.postMessage({type:"FIELD_UPDATE",payload:{itemId:t,field:s,value:n}},"*")}destroy(){this.isEnabled&&(window.removeEventListener("message",this.handleMessage),this.isEnabled=!1),this.eventListeners={}}}const a=c.getInstance(),f={mounted(e,t,s){if(!a.isInPreviewMode())return;const{id:n}=t.value;if(!n){console.warn("v-editable directive requires a block with an id");return}e.classList.add("b10cks-preview");const r=i=>{i.preventDefault(),i.stopPropagation(),a.selectItem(n)},u=({selectedItem:i})=>{s.el&&(i===n?(s.el.classList.add("b10cks-selected"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue"),b={key:1},h=o.defineComponent({__name:"B10cksComponent",props:{block:{}},setup(e,{expose:t}){const s=e,n=o.useTemplateRef("blockRef");t({value:n});const r=o.shallowRef(null),u=o.computed(()=>s.block?.block||null);return o.watch(()=>u.value,async l=>{if(!l){r.value=null;return}const p=l.replace(/^([a-z])/,i=>i.toUpperCase()).replace(/([a-z])([A-Z])/g,"$1$2");try{r.value=o.defineAsyncComponent({loader:()=>import(`~/b10cks/${p}.vue`),timeout:3e3,onError:(i,d,v)=>{console.warn(`Failed to load block component for type "${l}":`,i),v()}})}catch(i){console.error(`Error resolving component for block type "${l}":`,i)}},{immediate:!0}),(l,p)=>r.value?(o.openBlock(),o.createBlock(o.resolveDynamicComponent(r.value),o.mergeProps({key:0,ref_key:"blockRef",ref:n},{...l.$props,...l.$attrs}),null,16)):(o.openBlock(),o.createElementBlock("div",b,'Component for block type "'+o.toDisplayString(u.value)+'" not found.',1))}});class c{static instance;eventListeners={};isEnabled=!1;constructor(){this.isEnabled=this.isIframe()}init(){this.isEnabled&&window&&window.addEventListener("message",this.handleMessage)}static getInstance(){return c.instance||(c.instance=new c),c.instance}isInPreviewMode(){return this.isEnabled}isIframe(){return window&&window.self!==window.top}handleMessage=t=>{if(!t.data||typeof t.data!="object")return;const{type:s,payload:n}=t.data;this.notifyListeners(s,n)};notifyListeners(t,s){const n=this.eventListeners[t];n&&n.forEach(r=>{r(s)})}on(t,s){return this.isEnabled?(this.eventListeners[t]||(this.eventListeners[t]=[]),this.eventListeners[t].push(s),()=>{this.eventListeners[t]=this.eventListeners[t].filter(n=>n!==s)}):()=>{}}selectItem(t){this.isEnabled&&window.parent.postMessage({type:"SELECT_UPDATE",payload:{selectedItem:t}},"*")}updateField(t,s,n){this.isEnabled&&window.parent.postMessage({type:"FIELD_UPDATE",payload:{itemId:t,field:s,value:n}},"*")}destroy(){this.isEnabled&&(window.removeEventListener("message",this.handleMessage),this.isEnabled=!1),this.eventListeners={}}}const a=c.getInstance(),f={mounted(e,t,s){if(!a.isInPreviewMode())return;const{id:n}=t.value;if(!n){console.warn("v-editable directive requires a block with an id");return}e.classList.add("b10cks-preview");const r=i=>{i.preventDefault(),i.stopPropagation(),a.selectItem(n)},u=({selectedItem:i})=>{s.el&&(i===n?(s.el.classList.add("b10cks-selected"),m(e)):s.el.classList.remove("b10cks-selected"))},l=({selectedItem:i})=>{s.el&&(i===n?s.el.classList.add("b10cks-hover"):s.el.classList.remove("b10cks-hover"))},p=({content:i})=>{if(i&&i.id===n){const d=s.ctx;d.parent.attrs.block=i,d.update(),d.props.block=i,d.update()}};e.addEventListener("click",r),a.on("SELECT_UPDATE",u),a.on("HOVER_UPDATE",l),a.on("CONTENT_UPDATE",p),e._editableCleanup=()=>{e.removeEventListener("click",r)}},updated(e,t,s){a.isInPreviewMode()&&t.value!==t.oldValue&&(e._editableCleanup&&e._editableCleanup(),f.mounted(e,t,s))},unmounted(e){a.isInPreviewMode()&&(e._editableCleanup&&(e._editableCleanup(),delete e._editableCleanup),e.classList.remove("b10cks-preview","b10cks-selected"))}};function m(e){e.scrollIntoView&&e.scrollIntoView({behavior:"smooth"})}if(a.isInPreviewMode()){const e=document.createElement("style");e.innerHTML=`
|
|
2
2
|
.b10cks-hover,
|
|
3
3
|
.b10cks-preview:hover {
|
|
4
4
|
outline: 2px dashed rgba(59, 130, 246, 0.5);
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
outline: 2px solid rgb(59, 130, 246) !important;
|
|
9
9
|
outline-offset: 2px;
|
|
10
10
|
}
|
|
11
|
-
`,document.head.appendChild(e)}const
|
|
11
|
+
`,document.head.appendChild(e)}const k={mounted(e,t){const{id:s,field:n}=t.value;a.isInPreviewMode()&&(e.setAttribute("contenteditable","true"),e.addEventListener("input",r=>{a.updateField(s,n,r.target.innerText)}))}},E={install(e,t){e.provide("b10cksVueOptions",t),e.directive("editable",f),e.directive("editable-field",k),e.component("B10cksComponent",h)}};exports.B10cksVue=E;exports.previewBridge=a;
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/preview-bridge.ts","../src/directives/v-editable.ts","../src/directives/v-editable-content.ts","../src/components/B10cksComponent.vue","../src/index.ts"],"sourcesContent":["export type ContentUpdateEvent = {\n content: Record<string, any>;\n};\n\nexport type SelectUpdateEvent = {\n selectedItem: string;\n};\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE';\n\nexport type EventPayloadMap = {\n 'CONTENT_UPDATE': ContentUpdateEvent;\n 'SELECT_UPDATE': SelectUpdateEvent;\n 'HOVER_UPDATE': SelectUpdateEvent;\n};\n\nexport type BridgeEvent = {\n type: EventType;\n payload: ContentUpdateEvent | SelectUpdateEvent;\n b10cksId?: string;\n};\n\ntype EventCallback<T> = (payload: T) => void;\n\nclass PreviewBridge {\n private static instance: PreviewBridge\n private eventListeners: {\n [key in EventType]?: Array<EventCallback<EventPayloadMap[key]>>;\n } = {}\n\n private isEnabled = false\n\n private constructor() {\n this.isEnabled = this.isIframe()\n }\n\n\n public init(): void {\n if (this.isEnabled && window) {\n window.addEventListener('message', this.handleMessage)\n }\n }\n\n public static getInstance(): PreviewBridge {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n public isInPreviewMode(): boolean {\n return this.isEnabled\n }\n\n private isIframe(): boolean {\n return window && window.self !== window.top\n }\n\n private handleMessage = (event: MessageEvent): void => {\n if (!event.data || typeof event.data !== 'object') return\n const { type, payload } = event.data as BridgeEvent\n\n this.notifyListeners(type as EventType, payload)\n }\n\n private notifyListeners<T extends EventType>(type: T, payload: EventPayloadMap[T]): void {\n const listeners = this.eventListeners[type] as Array<EventCallback<EventPayloadMap[T]>> | undefined\n\n if (listeners) {\n listeners.forEach(listener => listener(payload))\n }\n }\n\n public on<T extends EventType>(\n eventType: T,\n callback: EventCallback<EventPayloadMap[T]>\n ): () => void {\n if (!this.isEnabled) return () => {\n }\n\n if (!this.eventListeners[eventType]) {\n this.eventListeners[eventType] = []\n }\n\n (this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>).push(callback)\n\n return () => {\n this.eventListeners[eventType] = (this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>)\n .filter(listener => listener !== callback) as never\n }\n }\n\n public selectItem(selectedItem: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem }\n },\n '*'\n )\n }\n\n public updateField(itemId: string, field: string, value: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value }\n },\n '*'\n )\n }\n\n public destroy(): void {\n if (this.isEnabled) {\n window.removeEventListener('message', this.handleMessage)\n this.isEnabled = false\n }\n this.eventListeners = {}\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()","import type { DirectiveBinding, VNode } from 'vue'\nimport type { SelectUpdateEvent } from '../preview-bridge'\nimport { previewBridge } from '../preview-bridge'\n\ninterface EditableElement extends HTMLElement {\n _editableCleanup?: () => void\n}\n\nexport const EditableDirective = {\n mounted(el: EditableElement, binding: DirectiveBinding, node: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n const { id: itemId } = binding.value\n\n if (!itemId) {\n console.warn('v-editable directive requires a block with an id')\n return\n }\n\n el.classList.add('b10cks-preview')\n\n const handleClick = (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n previewBridge.selectItem(itemId)\n }\n\n const handleSelectionChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-selected')\n scrollIntoViewIfNeeded(el)\n } else {\n node.el.classList.remove('b10cks-selected')\n }\n }\n\n const handleHoverChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-hover')\n } else {\n node.el.classList.remove('b10cks-hover')\n }\n }\n\n const handleUpdate = ({ content }: { content: any }) => {\n if (content && content.id === itemId) {\n const ctx = (node as any).ctx\n ctx.parent.attrs.block = content\n ctx.update()\n ctx.props.block = content\n ctx.update()\n }\n }\n\n el.addEventListener('click', handleClick)\n previewBridge.on('SELECT_UPDATE', handleSelectionChange)\n previewBridge.on('HOVER_UPDATE', handleHoverChange)\n previewBridge.on('CONTENT_UPDATE', handleUpdate)\n\n el._editableCleanup = () => {\n el.removeEventListener('click', handleClick)\n }\n },\n\n updated(el: EditableElement, binding: DirectiveBinding, vnode: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (binding.value !== binding.oldValue) {\n if (el._editableCleanup) {\n el._editableCleanup()\n }\n\n EditableDirective.mounted(el, binding, vnode)\n }\n },\n\n unmounted(el: EditableElement) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (el._editableCleanup) {\n el._editableCleanup()\n delete el._editableCleanup\n }\n\n el.classList.remove('b10cks-preview', 'b10cks-selected')\n }\n}\n\nfunction scrollIntoViewIfNeeded(el: HTMLElement) {\n if (el.scrollIntoView) {\n el.scrollIntoView({ behavior: 'smooth' })\n }\n}\n\nif (previewBridge.isInPreviewMode()) {\n const style = document.createElement('style')\n style.innerHTML = `\n .b10cks-hover,\n .b10cks-preview:hover {\n outline: 2px dashed rgba(59, 130, 246, 0.5);\n outline-offset: 2px;\n }\n .b10cks-selected {\n outline: 2px solid rgb(59, 130, 246) !important;\n outline-offset: 2px;\n }\n `\n document.head.appendChild(style)\n}","import { previewBridge } from '../preview-bridge'\nimport type { Directive, DirectiveBinding } from 'vue'\n\nexport const EditableContentDirective: Directive<HTMLElement> = {\n mounted(el: HTMLElement, binding: DirectiveBinding) {\n const { id: itemId, field } = binding.value\n if (!previewBridge.isInPreviewMode()) return\n el.setAttribute('contenteditable', 'true')\n\n el.addEventListener('input', (event: Event) => {\n previewBridge.updateField(itemId, field, (event.target as HTMLInputElement).innerText)\n })\n }\n}\n","<script setup lang=\"ts\">\nimport { type Component, computed, watch, useTemplateRef, defineAsyncComponent, shallowRef, inject } from 'vue'\nimport type { IBContent } from '@b10cks/client'\n\nconst props = defineProps<{\n block: IBContent<string> & Record<string, never>,\n}>()\n\nconst blockRef = useTemplateRef('blockRef')\ndefineExpose({ value: blockRef })\n\nconst resolvedComponent = shallowRef<Component | null>(null)\nconst componentName = computed(() => props.block?.block || null)\n\nwatch(() => componentName.value,\n async (newComponentName: string | null) => {\n if (!newComponentName) {\n resolvedComponent.value = null\n return\n }\n\n const pascalCaseBlockType = newComponentName\n .replace(/^([a-z])/, (match: string) => match.toUpperCase())\n .replace(/([a-z])([A-Z])/g, '$1$2')\n\n try {\n resolvedComponent.value = defineAsyncComponent({\n loader: () => import(`~/b10cks/${pascalCaseBlockType}.vue`),\n timeout: 3000,\n onError: (error, retry, fail) => {\n console.warn(`Failed to load block component for type \"${newComponentName}\":`, error)\n fail()\n }\n })\n } catch (error) {\n console.error(`Error resolving component for block type \"${newComponentName}\":`, error)\n }\n },\n { immediate: true }\n)\n</script>\n<template>\n <component :is=\"resolvedComponent\" v-if=\"resolvedComponent\" ref=\"blockRef\" v-bind=\"{ ...$props, ...$attrs }\" />\n <div v-else>Component for block type \"{{ componentName }}\" not found.</div>\n</template>","import type { Plugin } from 'vue'\nimport type { B10cksVuePluginOptions } from './types'\n\nimport { EditableDirective } from './directives/v-editable'\nimport { EditableContentDirective } from './directives/v-editable-content'\nimport B10cksComponent from './components/B10cksComponent.vue'\n\nexport { previewBridge } from './preview-bridge'\n\nexport const B10cksVue: Plugin = {\n install(app, pluginOptions: B10cksVuePluginOptions) {\n app.provide('b10cksVueOptions', pluginOptions)\n\n app.directive('editable', EditableDirective)\n app.directive('editable-field', EditableContentDirective)\n app.component('B10cksComponent', B10cksComponent)\n }\n}"],"names":["PreviewBridge","event","type","payload","listeners","listener","eventType","callback","selectedItem","itemId","field","value","previewBridge","EditableDirective","el","binding","node","handleClick","e","handleSelectionChange","scrollIntoViewIfNeeded","handleHoverChange","handleUpdate","content","ctx","vnode","style","EditableContentDirective","props","__props","blockRef","useTemplateRef","__expose","resolvedComponent","shallowRef","componentName","computed","watch","newComponentName","pascalCaseBlockType","match","defineAsyncComponent","error","retry","fail","_createBlock","_resolveDynamicComponent","_mergeProps","$props","$attrs","_openBlock","_createElementBlock","_hoisted_1","_toDisplayString","B10cksVue","app","pluginOptions","B10cksComponent"],"mappings":"uGAwBA,MAAMA,CAAc,CAClB,OAAe,SACP,eAEJ,CAAA,EAEI,UAAY,GAEZ,aAAc,CACpB,KAAK,UAAY,KAAK,SAAA,CACxB,CAGO,MAAa,CACd,KAAK,WAAa,QACpB,OAAO,iBAAiB,UAAW,KAAK,aAAa,CAEzD,CAEA,OAAc,aAA6B,CACzC,OAAKA,EAAc,WACjBA,EAAc,SAAW,IAAIA,GAExBA,EAAc,QACvB,CAEO,iBAA2B,CAChC,OAAO,KAAK,SACd,CAEQ,UAAoB,CAC1B,OAAO,QAAU,OAAO,OAAS,OAAO,GAC1C,CAEQ,cAAiBC,GAA8B,CACrD,GAAI,CAACA,EAAM,MAAQ,OAAOA,EAAM,MAAS,SAAU,OACnD,KAAM,CAAE,KAAAC,EAAM,QAAAC,CAAA,EAAYF,EAAM,KAEhC,KAAK,gBAAgBC,EAAmBC,CAAO,CACjD,EAEQ,gBAAqCD,EAASC,EAAmC,CACvF,MAAMC,EAAY,KAAK,eAAeF,CAAI,EAEtCE,GACFA,EAAU,QAAQC,GAAYA,EAASF,CAAO,CAAC,CAEnD,CAEO,GACLG,EACAC,EACY,CACZ,OAAK,KAAK,WAGL,KAAK,eAAeD,CAAS,IAChC,KAAK,eAAeA,CAAS,EAAI,CAAA,GAGlC,KAAK,eAAeA,CAAS,EAA+C,KAAKC,CAAQ,EAEnF,IAAM,CACX,KAAK,eAAeD,CAAS,EAAK,KAAK,eAAeA,CAAS,EAC5D,OAAOD,GAAYA,IAAaE,CAAQ,CAC7C,GAZ4B,IAAM,CAClC,CAYF,CAEO,WAAWC,EAA4B,CACvC,KAAK,WAEV,OAAO,OAAO,YACZ,CACE,KAAM,gBACN,QAAS,CAAE,aAAAA,CAAA,CAAa,EAE1B,GAAA,CAEJ,CAEO,YAAYC,EAAgBC,EAAeC,EAAqB,CAChE,KAAK,WAEV,OAAO,OAAO,YACZ,CACE,KAAM,eACN,QAAS,CAAE,OAAAF,EAAQ,MAAAC,EAAO,MAAAC,CAAA,CAAM,EAElC,GAAA,CAEJ,CAEO,SAAgB,CACjB,KAAK,YACP,OAAO,oBAAoB,UAAW,KAAK,aAAa,EACxD,KAAK,UAAY,IAEnB,KAAK,eAAiB,CAAA,CACxB,CACF,CAEO,MAAMC,EAAgBZ,EAAc,YAAA,ECrH9Ba,EAAoB,CAC/B,QAAQC,EAAqBC,EAA2BC,EAAa,CACnE,GAAI,CAACJ,EAAc,kBAAmB,OACtC,KAAM,CAAE,GAAIH,CAAA,EAAWM,EAAQ,MAE/B,GAAI,CAACN,EAAQ,CACX,QAAQ,KAAK,kDAAkD,EAC/D,MACF,CAEAK,EAAG,UAAU,IAAI,gBAAgB,EAEjC,MAAMG,EAAeC,GAAkB,CACrCA,EAAE,eAAA,EACFA,EAAE,gBAAA,EACFN,EAAc,WAAWH,CAAM,CACjC,EAEMU,EAAwB,CAAC,CAAE,aAAAX,KAAsC,CAChEQ,EAAK,KAENR,IAAiBC,GACnBO,EAAK,GAAG,UAAU,IAAI,iBAAiB,EACvCI,EAAuBN,CAAE,GAEzBE,EAAK,GAAG,UAAU,OAAO,iBAAiB,EAE9C,EAEMK,EAAoB,CAAC,CAAE,aAAAb,KAAsC,CAC5DQ,EAAK,KAENR,IAAiBC,EACnBO,EAAK,GAAG,UAAU,IAAI,cAAc,EAEpCA,EAAK,GAAG,UAAU,OAAO,cAAc,EAE3C,EAEMM,EAAe,CAAC,CAAE,QAAAC,KAAgC,CACtD,GAAIA,GAAWA,EAAQ,KAAOd,EAAQ,CACpC,MAAMe,EAAOR,EAAa,IAC1BQ,EAAI,OAAO,MAAM,MAAQD,EACzBC,EAAI,OAAA,EACJA,EAAI,MAAM,MAAQD,EAClBC,EAAI,OAAA,CACN,CACF,EAEAV,EAAG,iBAAiB,QAASG,CAAW,EACxCL,EAAc,GAAG,gBAAiBO,CAAqB,EACvDP,EAAc,GAAG,eAAgBS,CAAiB,EAClDT,EAAc,GAAG,iBAAkBU,CAAY,EAE/CR,EAAG,iBAAmB,IAAM,CAC1BA,EAAG,oBAAoB,QAASG,CAAW,CAC7C,CACF,EAEA,QAAQH,EAAqBC,EAA2BU,EAAc,CAC/Db,EAAc,mBAEfG,EAAQ,QAAUA,EAAQ,WACxBD,EAAG,kBACLA,EAAG,iBAAA,EAGLD,EAAkB,QAAQC,EAAIC,EAASU,CAAK,EAEhD,EAEA,UAAUX,EAAqB,CACxBF,EAAc,oBAEfE,EAAG,mBACLA,EAAG,iBAAA,EACH,OAAOA,EAAG,kBAGZA,EAAG,UAAU,OAAO,iBAAkB,iBAAiB,EACzD,CACF,EAEA,SAASM,EAAuBN,EAAiB,CAC3CA,EAAG,gBACLA,EAAG,eAAe,CAAE,SAAU,QAAA,CAAU,CAE5C,CAEA,GAAIF,EAAc,kBAAmB,CACnC,MAAMc,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,UAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWlB,SAAS,KAAK,YAAYA,CAAK,CACjC,CC5GO,MAAMC,EAAmD,CAC9D,QAAQb,EAAiBC,EAA2B,CAClD,KAAM,CAAE,GAAIN,EAAQ,MAAAC,CAAA,EAAUK,EAAQ,MACjCH,EAAc,oBACnBE,EAAG,aAAa,kBAAmB,MAAM,EAEzCA,EAAG,iBAAiB,QAAUb,GAAiB,CAC7CW,EAAc,YAAYH,EAAQC,EAAQT,EAAM,OAA4B,SAAS,CACvF,CAAC,EACH,CACF,+FCTA,MAAM2B,EAAQC,EAIRC,EAAWC,EAAAA,eAAe,UAAU,EAC1CC,EAAa,CAAE,MAAOF,EAAU,EAEhC,MAAMG,EAAoBC,EAAAA,WAA6B,IAAI,EACrDC,EAAgBC,EAAAA,SAAS,IAAMR,EAAM,OAAO,OAAS,IAAI,EAE/DS,OAAAA,EAAAA,MAAM,IAAMF,EAAc,MACxB,MAAOG,GAAoC,CACzC,GAAI,CAACA,EAAkB,CACrBL,EAAkB,MAAQ,KAC1B,MACF,CAEA,MAAMM,EAAsBD,EACzB,QAAQ,WAAaE,GAAkBA,EAAM,YAAA,CAAa,EAC1D,QAAQ,kBAAmB,MAAM,EAEpC,GAAI,CACFP,EAAkB,MAAQQ,uBAAqB,CAC7C,OAAQ,IAAM,OAAO,YAAYF,CAAmB,QACpD,QAAS,IACT,QAAS,CAACG,EAAOC,EAAOC,IAAS,CAC/B,QAAQ,KAAK,4CAA4CN,CAAgB,KAAMI,CAAK,EACpFE,EAAA,CACF,CAAA,CACD,CACH,OAASF,EAAO,CACd,QAAQ,MAAM,6CAA6CJ,CAAgB,KAAMI,CAAK,CACxF,CACF,EACA,CAAE,UAAW,EAAA,CAAK,SAIuBT,EAAA,qBAAzCY,EAAAA,YAA+GC,EAAAA,wBAA/Fb,EAAA,KAAiB,EAAjCc,aAA+G,eAA/C,WAAJ,IAAIjB,CAAA,EAAwBkB,CAAAA,GAAAA,EAAAA,UAAWC,EAAAA,OAAM,EAAA,KAAA,EAAA,IACzGC,EAAAA,UAAA,EAAAC,qBAA2E,MAAAC,EAA/D,6BAA0BC,EAAAA,gBAAGlB,EAAA,KAAa,EAAG,eAAY,CAAA,MClC1DmB,EAAoB,CAC/B,QAAQC,EAAKC,EAAuC,CAClDD,EAAI,QAAQ,mBAAoBC,CAAa,EAE7CD,EAAI,UAAU,WAAY1C,CAAiB,EAC3C0C,EAAI,UAAU,iBAAkB5B,CAAwB,EACxD4B,EAAI,UAAU,kBAAmBE,CAAe,CAClD,CACF"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/components/B10cksComponent.vue","../src/preview-bridge.ts","../src/directives/v-editable.ts","../src/directives/v-editable-content.ts","../src/index.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { IBContent } from '@b10cks/client'\nimport {\n type Component,\n computed,\n defineAsyncComponent,\n shallowRef,\n useTemplateRef,\n watch,\n} from 'vue'\n\nconst props = defineProps<{\n block: IBContent<string> & Record<string, never>\n}>()\n\nconst blockRef = useTemplateRef('blockRef')\ndefineExpose({ value: blockRef })\n\nconst resolvedComponent = shallowRef<Component | null>(null)\nconst componentName = computed(() => props.block?.block || null)\n\nwatch(\n () => componentName.value,\n async (newComponentName: string | null) => {\n if (!newComponentName) {\n resolvedComponent.value = null\n return\n }\n\n const pascalCaseBlockType = newComponentName\n .replace(/^([a-z])/, (match: string) => match.toUpperCase())\n .replace(/([a-z])([A-Z])/g, '$1$2')\n\n try {\n resolvedComponent.value = defineAsyncComponent({\n loader: () => import(`~/b10cks/${pascalCaseBlockType}.vue`),\n timeout: 3000,\n onError: (error, _, fail) => {\n // biome-ignore lint/suspicious/noConsole: give developers feedback\n console.warn(`Failed to load block component for type \"${newComponentName}\":`, error)\n fail()\n },\n })\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: give developers feedback\n console.error(`Error resolving component for block type \"${newComponentName}\":`, error)\n }\n },\n { immediate: true }\n)\n</script>\n<template>\n <component\n :is=\"resolvedComponent\"\n v-if=\"resolvedComponent\"\n ref=\"blockRef\"\n v-bind=\"{ ...$props, ...$attrs }\"\n />\n <div v-else>Component for block type \"{{ componentName }}\" not found.</div>\n</template>\n","export type ContentUpdateEvent = {\n content: Record<string, unknown>\n}\n\nexport type SelectUpdateEvent = {\n selectedItem: string\n}\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE'\n\nexport type EventPayloadMap = {\n CONTENT_UPDATE: ContentUpdateEvent\n SELECT_UPDATE: SelectUpdateEvent\n HOVER_UPDATE: SelectUpdateEvent\n}\n\nexport type BridgeEvent = {\n type: EventType\n payload: ContentUpdateEvent | SelectUpdateEvent\n b10cksId?: string\n}\n\ntype EventCallback<T> = (payload: T) => void\n\nclass PreviewBridge {\n private static instance: PreviewBridge\n private eventListeners: {\n [key in EventType]?: Array<EventCallback<EventPayloadMap[key]>>\n } = {}\n\n private isEnabled = false\n\n private constructor() {\n this.isEnabled = this.isIframe()\n }\n\n public init(): void {\n if (this.isEnabled && window) {\n window.addEventListener('message', this.handleMessage)\n }\n }\n\n public static getInstance(): PreviewBridge {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n public isInPreviewMode(): boolean {\n return this.isEnabled\n }\n\n private isIframe(): boolean {\n return window && window.self !== window.top\n }\n\n private handleMessage = (event: MessageEvent): void => {\n if (!event.data || typeof event.data !== 'object') return\n const { type, payload } = event.data as BridgeEvent\n\n this.notifyListeners(type as EventType, payload)\n }\n\n private notifyListeners<T extends EventType>(type: T, payload: EventPayloadMap[T]): void {\n const listeners = this.eventListeners[type] as\n | Array<EventCallback<EventPayloadMap[T]>>\n | undefined\n\n if (listeners) {\n listeners.forEach((listener) => {\n listener(payload)\n })\n }\n }\n\n public on<T extends EventType>(\n eventType: T,\n callback: EventCallback<EventPayloadMap[T]>\n ): () => void {\n if (!this.isEnabled) return () => {}\n\n if (!this.eventListeners[eventType]) {\n this.eventListeners[eventType] = []\n }\n\n ;(this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>).push(callback)\n\n return () => {\n this.eventListeners[eventType] = (\n this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>\n ).filter((listener) => listener !== callback) as never\n }\n }\n\n public selectItem(selectedItem: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem },\n },\n '*'\n )\n }\n\n public updateField(itemId: string, field: string, value: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value },\n },\n '*'\n )\n }\n\n public destroy(): void {\n if (this.isEnabled) {\n window.removeEventListener('message', this.handleMessage)\n this.isEnabled = false\n }\n this.eventListeners = {}\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()\n","import type { DirectiveBinding, VNode } from 'vue'\n\nimport type { SelectUpdateEvent } from '../preview-bridge'\n\nimport { previewBridge } from '../preview-bridge'\n\ninterface EditableElement extends HTMLElement {\n _editableCleanup?: () => void\n}\n\nexport const EditableDirective = {\n mounted(el: EditableElement, binding: DirectiveBinding, node: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n const { id: itemId } = binding.value\n\n if (!itemId) {\n // biome-ignore lint/suspicious/noConsole: give developers feedback\n console.warn('v-editable directive requires a block with an id')\n return\n }\n\n el.classList.add('b10cks-preview')\n\n const handleClick = (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n previewBridge.selectItem(itemId)\n }\n\n const handleSelectionChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-selected')\n scrollIntoViewIfNeeded(el)\n } else {\n node.el.classList.remove('b10cks-selected')\n }\n }\n\n const handleHoverChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-hover')\n } else {\n node.el.classList.remove('b10cks-hover')\n }\n }\n\n const handleUpdate = ({ content }: { content: any }) => {\n if (content && content.id === itemId) {\n // biome-ignore lint/suspicious/noExplicitAny: use of any to access internal properties\n const ctx = (node as any).ctx\n ctx.parent.attrs.block = content\n ctx.update()\n ctx.props.block = content\n ctx.update()\n }\n }\n\n el.addEventListener('click', handleClick)\n previewBridge.on('SELECT_UPDATE', handleSelectionChange)\n previewBridge.on('HOVER_UPDATE', handleHoverChange)\n previewBridge.on('CONTENT_UPDATE', handleUpdate)\n\n el._editableCleanup = () => {\n el.removeEventListener('click', handleClick)\n }\n },\n\n updated(el: EditableElement, binding: DirectiveBinding, vnode: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (binding.value !== binding.oldValue) {\n if (el._editableCleanup) {\n el._editableCleanup()\n }\n\n EditableDirective.mounted(el, binding, vnode)\n }\n },\n\n unmounted(el: EditableElement) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (el._editableCleanup) {\n el._editableCleanup()\n delete el._editableCleanup\n }\n\n el.classList.remove('b10cks-preview', 'b10cks-selected')\n },\n}\n\nfunction scrollIntoViewIfNeeded(el: HTMLElement) {\n if (el.scrollIntoView) {\n el.scrollIntoView({ behavior: 'smooth' })\n }\n}\n\nif (previewBridge.isInPreviewMode()) {\n const style = document.createElement('style')\n style.innerHTML = `\n .b10cks-hover,\n .b10cks-preview:hover {\n outline: 2px dashed rgba(59, 130, 246, 0.5);\n outline-offset: 2px;\n }\n .b10cks-selected {\n outline: 2px solid rgb(59, 130, 246) !important;\n outline-offset: 2px;\n }\n `\n document.head.appendChild(style)\n}\n","import type { Directive, DirectiveBinding } from 'vue'\n\nimport { previewBridge } from '../preview-bridge'\n\nexport const EditableContentDirective: Directive<HTMLElement> = {\n mounted(el: HTMLElement, binding: DirectiveBinding) {\n const { id: itemId, field } = binding.value\n if (!previewBridge.isInPreviewMode()) return\n el.setAttribute('contenteditable', 'true')\n\n el.addEventListener('input', (event: Event) => {\n previewBridge.updateField(itemId, field, (event.target as HTMLInputElement).innerText)\n })\n },\n}\n","import type { Plugin } from 'vue'\n\nimport type { B10cksVuePluginOptions } from './types'\n\nimport B10cksComponent from './components/B10cksComponent.vue'\nimport { EditableDirective } from './directives/v-editable'\nimport { EditableContentDirective } from './directives/v-editable-content'\n\nexport { previewBridge } from './preview-bridge'\n\nexport const B10cksVue: Plugin = {\n install(app, pluginOptions: B10cksVuePluginOptions) {\n app.provide('b10cksVueOptions', pluginOptions)\n\n app.directive('editable', EditableDirective)\n app.directive('editable-field', EditableContentDirective)\n app.component('B10cksComponent', B10cksComponent)\n },\n}\n"],"names":["props","__props","blockRef","useTemplateRef","__expose","resolvedComponent","shallowRef","componentName","computed","watch","newComponentName","pascalCaseBlockType","match","defineAsyncComponent","error","_","fail","_createBlock","_resolveDynamicComponent","_mergeProps","$props","$attrs","_openBlock","_createElementBlock","_hoisted_1","_toDisplayString","PreviewBridge","event","type","payload","listeners","listener","eventType","callback","selectedItem","itemId","field","value","previewBridge","EditableDirective","el","binding","node","handleClick","e","handleSelectionChange","scrollIntoViewIfNeeded","handleHoverChange","handleUpdate","content","ctx","vnode","style","EditableContentDirective","B10cksVue","app","pluginOptions","B10cksComponent"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,41 @@
|
|
|
1
1
|
import { defineComponent as b, useTemplateRef as h, shallowRef as m, computed as k, watch as E, defineAsyncComponent as w, createBlock as L, createElementBlock as y, openBlock as p, resolveDynamicComponent as C, mergeProps as I, toDisplayString as g } from "vue";
|
|
2
|
+
const _ = { key: 1 }, M = /* @__PURE__ */ b({
|
|
3
|
+
__name: "B10cksComponent",
|
|
4
|
+
props: {
|
|
5
|
+
block: {}
|
|
6
|
+
},
|
|
7
|
+
setup(e, { expose: t }) {
|
|
8
|
+
const s = e, n = h("blockRef");
|
|
9
|
+
t({ value: n });
|
|
10
|
+
const o = m(null), d = k(() => s.block?.block || null);
|
|
11
|
+
return E(
|
|
12
|
+
() => d.value,
|
|
13
|
+
async (a) => {
|
|
14
|
+
if (!a) {
|
|
15
|
+
o.value = null;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const u = a.replace(/^([a-z])/, (i) => i.toUpperCase()).replace(/([a-z])([A-Z])/g, "$1$2");
|
|
19
|
+
try {
|
|
20
|
+
o.value = w({
|
|
21
|
+
loader: () => import(`~/b10cks/${u}.vue`),
|
|
22
|
+
timeout: 3e3,
|
|
23
|
+
onError: (i, c, v) => {
|
|
24
|
+
console.warn(`Failed to load block component for type "${a}":`, i), v();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
} catch (i) {
|
|
28
|
+
console.error(`Error resolving component for block type "${a}":`, i);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{ immediate: !0 }
|
|
32
|
+
), (a, u) => o.value ? (p(), L(C(o.value), I({
|
|
33
|
+
key: 0,
|
|
34
|
+
ref_key: "blockRef",
|
|
35
|
+
ref: n
|
|
36
|
+
}, { ...a.$props, ...a.$attrs }), null, 16)) : (p(), y("div", _, 'Component for block type "' + g(d.value) + '" not found.', 1));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
2
39
|
class l {
|
|
3
40
|
static instance;
|
|
4
41
|
eventListeners = {};
|
|
@@ -25,7 +62,9 @@ class l {
|
|
|
25
62
|
};
|
|
26
63
|
notifyListeners(t, s) {
|
|
27
64
|
const n = this.eventListeners[t];
|
|
28
|
-
n && n.forEach((o) =>
|
|
65
|
+
n && n.forEach((o) => {
|
|
66
|
+
o(s);
|
|
67
|
+
});
|
|
29
68
|
}
|
|
30
69
|
on(t, s) {
|
|
31
70
|
return this.isEnabled ? (this.eventListeners[t] || (this.eventListeners[t] = []), this.eventListeners[t].push(s), () => {
|
|
@@ -67,7 +106,7 @@ const r = l.getInstance(), f = {
|
|
|
67
106
|
const o = (i) => {
|
|
68
107
|
i.preventDefault(), i.stopPropagation(), r.selectItem(n);
|
|
69
108
|
}, d = ({ selectedItem: i }) => {
|
|
70
|
-
s.el && (i === n ? (s.el.classList.add("b10cks-selected"),
|
|
109
|
+
s.el && (i === n ? (s.el.classList.add("b10cks-selected"), D(e)) : s.el.classList.remove("b10cks-selected"));
|
|
71
110
|
}, a = ({ selectedItem: i }) => {
|
|
72
111
|
s.el && (i === n ? s.el.classList.add("b10cks-hover") : s.el.classList.remove("b10cks-hover"));
|
|
73
112
|
}, u = ({ content: i }) => {
|
|
@@ -87,7 +126,7 @@ const r = l.getInstance(), f = {
|
|
|
87
126
|
r.isInPreviewMode() && (e._editableCleanup && (e._editableCleanup(), delete e._editableCleanup), e.classList.remove("b10cks-preview", "b10cks-selected"));
|
|
88
127
|
}
|
|
89
128
|
};
|
|
90
|
-
function
|
|
129
|
+
function D(e) {
|
|
91
130
|
e.scrollIntoView && e.scrollIntoView({ behavior: "smooth" });
|
|
92
131
|
}
|
|
93
132
|
if (r.isInPreviewMode()) {
|
|
@@ -104,52 +143,16 @@ if (r.isInPreviewMode()) {
|
|
|
104
143
|
}
|
|
105
144
|
`, document.head.appendChild(e);
|
|
106
145
|
}
|
|
107
|
-
const
|
|
146
|
+
const P = {
|
|
108
147
|
mounted(e, t) {
|
|
109
148
|
const { id: s, field: n } = t.value;
|
|
110
149
|
r.isInPreviewMode() && (e.setAttribute("contenteditable", "true"), e.addEventListener("input", (o) => {
|
|
111
150
|
r.updateField(s, n, o.target.innerText);
|
|
112
151
|
}));
|
|
113
152
|
}
|
|
114
|
-
},
|
|
115
|
-
__name: "B10cksComponent",
|
|
116
|
-
props: {
|
|
117
|
-
block: {}
|
|
118
|
-
},
|
|
119
|
-
setup(e, { expose: t }) {
|
|
120
|
-
const s = e, n = h("blockRef");
|
|
121
|
-
t({ value: n });
|
|
122
|
-
const o = m(null), d = k(() => s.block?.block || null);
|
|
123
|
-
return E(
|
|
124
|
-
() => d.value,
|
|
125
|
-
async (a) => {
|
|
126
|
-
if (!a) {
|
|
127
|
-
o.value = null;
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
const u = a.replace(/^([a-z])/, (i) => i.toUpperCase()).replace(/([a-z])([A-Z])/g, "$1$2");
|
|
131
|
-
try {
|
|
132
|
-
o.value = w({
|
|
133
|
-
loader: () => import(`~/b10cks/${u}.vue`),
|
|
134
|
-
timeout: 3e3,
|
|
135
|
-
onError: (i, c, v) => {
|
|
136
|
-
console.warn(`Failed to load block component for type "${a}":`, i), v();
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
} catch (i) {
|
|
140
|
-
console.error(`Error resolving component for block type "${a}":`, i);
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
{ immediate: !0 }
|
|
144
|
-
), (a, u) => o.value ? (p(), L(C(o.value), I({
|
|
145
|
-
key: 0,
|
|
146
|
-
ref_key: "blockRef",
|
|
147
|
-
ref: n
|
|
148
|
-
}, { ...a.$props, ...a.$attrs }), null, 16)) : (p(), y("div", D, 'Component for block type "' + g(d.value) + '" not found.', 1));
|
|
149
|
-
}
|
|
150
|
-
}), x = {
|
|
153
|
+
}, x = {
|
|
151
154
|
install(e, t) {
|
|
152
|
-
e.provide("b10cksVueOptions", t), e.directive("editable", f), e.directive("editable-field",
|
|
155
|
+
e.provide("b10cksVueOptions", t), e.directive("editable", f), e.directive("editable-field", P), e.component("B10cksComponent", M);
|
|
153
156
|
}
|
|
154
157
|
};
|
|
155
158
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/preview-bridge.ts","../src/directives/v-editable.ts","../src/directives/v-editable-content.ts","../src/components/B10cksComponent.vue","../src/index.ts"],"sourcesContent":["export type ContentUpdateEvent = {\n content: Record<string, any>;\n};\n\nexport type SelectUpdateEvent = {\n selectedItem: string;\n};\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE';\n\nexport type EventPayloadMap = {\n 'CONTENT_UPDATE': ContentUpdateEvent;\n 'SELECT_UPDATE': SelectUpdateEvent;\n 'HOVER_UPDATE': SelectUpdateEvent;\n};\n\nexport type BridgeEvent = {\n type: EventType;\n payload: ContentUpdateEvent | SelectUpdateEvent;\n b10cksId?: string;\n};\n\ntype EventCallback<T> = (payload: T) => void;\n\nclass PreviewBridge {\n private static instance: PreviewBridge\n private eventListeners: {\n [key in EventType]?: Array<EventCallback<EventPayloadMap[key]>>;\n } = {}\n\n private isEnabled = false\n\n private constructor() {\n this.isEnabled = this.isIframe()\n }\n\n\n public init(): void {\n if (this.isEnabled && window) {\n window.addEventListener('message', this.handleMessage)\n }\n }\n\n public static getInstance(): PreviewBridge {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n public isInPreviewMode(): boolean {\n return this.isEnabled\n }\n\n private isIframe(): boolean {\n return window && window.self !== window.top\n }\n\n private handleMessage = (event: MessageEvent): void => {\n if (!event.data || typeof event.data !== 'object') return\n const { type, payload } = event.data as BridgeEvent\n\n this.notifyListeners(type as EventType, payload)\n }\n\n private notifyListeners<T extends EventType>(type: T, payload: EventPayloadMap[T]): void {\n const listeners = this.eventListeners[type] as Array<EventCallback<EventPayloadMap[T]>> | undefined\n\n if (listeners) {\n listeners.forEach(listener => listener(payload))\n }\n }\n\n public on<T extends EventType>(\n eventType: T,\n callback: EventCallback<EventPayloadMap[T]>\n ): () => void {\n if (!this.isEnabled) return () => {\n }\n\n if (!this.eventListeners[eventType]) {\n this.eventListeners[eventType] = []\n }\n\n (this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>).push(callback)\n\n return () => {\n this.eventListeners[eventType] = (this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>)\n .filter(listener => listener !== callback) as never\n }\n }\n\n public selectItem(selectedItem: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem }\n },\n '*'\n )\n }\n\n public updateField(itemId: string, field: string, value: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value }\n },\n '*'\n )\n }\n\n public destroy(): void {\n if (this.isEnabled) {\n window.removeEventListener('message', this.handleMessage)\n this.isEnabled = false\n }\n this.eventListeners = {}\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()","import type { DirectiveBinding, VNode } from 'vue'\nimport type { SelectUpdateEvent } from '../preview-bridge'\nimport { previewBridge } from '../preview-bridge'\n\ninterface EditableElement extends HTMLElement {\n _editableCleanup?: () => void\n}\n\nexport const EditableDirective = {\n mounted(el: EditableElement, binding: DirectiveBinding, node: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n const { id: itemId } = binding.value\n\n if (!itemId) {\n console.warn('v-editable directive requires a block with an id')\n return\n }\n\n el.classList.add('b10cks-preview')\n\n const handleClick = (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n previewBridge.selectItem(itemId)\n }\n\n const handleSelectionChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-selected')\n scrollIntoViewIfNeeded(el)\n } else {\n node.el.classList.remove('b10cks-selected')\n }\n }\n\n const handleHoverChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-hover')\n } else {\n node.el.classList.remove('b10cks-hover')\n }\n }\n\n const handleUpdate = ({ content }: { content: any }) => {\n if (content && content.id === itemId) {\n const ctx = (node as any).ctx\n ctx.parent.attrs.block = content\n ctx.update()\n ctx.props.block = content\n ctx.update()\n }\n }\n\n el.addEventListener('click', handleClick)\n previewBridge.on('SELECT_UPDATE', handleSelectionChange)\n previewBridge.on('HOVER_UPDATE', handleHoverChange)\n previewBridge.on('CONTENT_UPDATE', handleUpdate)\n\n el._editableCleanup = () => {\n el.removeEventListener('click', handleClick)\n }\n },\n\n updated(el: EditableElement, binding: DirectiveBinding, vnode: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (binding.value !== binding.oldValue) {\n if (el._editableCleanup) {\n el._editableCleanup()\n }\n\n EditableDirective.mounted(el, binding, vnode)\n }\n },\n\n unmounted(el: EditableElement) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (el._editableCleanup) {\n el._editableCleanup()\n delete el._editableCleanup\n }\n\n el.classList.remove('b10cks-preview', 'b10cks-selected')\n }\n}\n\nfunction scrollIntoViewIfNeeded(el: HTMLElement) {\n if (el.scrollIntoView) {\n el.scrollIntoView({ behavior: 'smooth' })\n }\n}\n\nif (previewBridge.isInPreviewMode()) {\n const style = document.createElement('style')\n style.innerHTML = `\n .b10cks-hover,\n .b10cks-preview:hover {\n outline: 2px dashed rgba(59, 130, 246, 0.5);\n outline-offset: 2px;\n }\n .b10cks-selected {\n outline: 2px solid rgb(59, 130, 246) !important;\n outline-offset: 2px;\n }\n `\n document.head.appendChild(style)\n}","import { previewBridge } from '../preview-bridge'\nimport type { Directive, DirectiveBinding } from 'vue'\n\nexport const EditableContentDirective: Directive<HTMLElement> = {\n mounted(el: HTMLElement, binding: DirectiveBinding) {\n const { id: itemId, field } = binding.value\n if (!previewBridge.isInPreviewMode()) return\n el.setAttribute('contenteditable', 'true')\n\n el.addEventListener('input', (event: Event) => {\n previewBridge.updateField(itemId, field, (event.target as HTMLInputElement).innerText)\n })\n }\n}\n","<script setup lang=\"ts\">\nimport { type Component, computed, watch, useTemplateRef, defineAsyncComponent, shallowRef, inject } from 'vue'\nimport type { IBContent } from '@b10cks/client'\n\nconst props = defineProps<{\n block: IBContent<string> & Record<string, never>,\n}>()\n\nconst blockRef = useTemplateRef('blockRef')\ndefineExpose({ value: blockRef })\n\nconst resolvedComponent = shallowRef<Component | null>(null)\nconst componentName = computed(() => props.block?.block || null)\n\nwatch(() => componentName.value,\n async (newComponentName: string | null) => {\n if (!newComponentName) {\n resolvedComponent.value = null\n return\n }\n\n const pascalCaseBlockType = newComponentName\n .replace(/^([a-z])/, (match: string) => match.toUpperCase())\n .replace(/([a-z])([A-Z])/g, '$1$2')\n\n try {\n resolvedComponent.value = defineAsyncComponent({\n loader: () => import(`~/b10cks/${pascalCaseBlockType}.vue`),\n timeout: 3000,\n onError: (error, retry, fail) => {\n console.warn(`Failed to load block component for type \"${newComponentName}\":`, error)\n fail()\n }\n })\n } catch (error) {\n console.error(`Error resolving component for block type \"${newComponentName}\":`, error)\n }\n },\n { immediate: true }\n)\n</script>\n<template>\n <component :is=\"resolvedComponent\" v-if=\"resolvedComponent\" ref=\"blockRef\" v-bind=\"{ ...$props, ...$attrs }\" />\n <div v-else>Component for block type \"{{ componentName }}\" not found.</div>\n</template>","import type { Plugin } from 'vue'\nimport type { B10cksVuePluginOptions } from './types'\n\nimport { EditableDirective } from './directives/v-editable'\nimport { EditableContentDirective } from './directives/v-editable-content'\nimport B10cksComponent from './components/B10cksComponent.vue'\n\nexport { previewBridge } from './preview-bridge'\n\nexport const B10cksVue: Plugin = {\n install(app, pluginOptions: B10cksVuePluginOptions) {\n app.provide('b10cksVueOptions', pluginOptions)\n\n app.directive('editable', EditableDirective)\n app.directive('editable-field', EditableContentDirective)\n app.component('B10cksComponent', B10cksComponent)\n }\n}"],"names":["PreviewBridge","event","type","payload","listeners","listener","eventType","callback","selectedItem","itemId","field","value","previewBridge","EditableDirective","el","binding","node","handleClick","e","handleSelectionChange","scrollIntoViewIfNeeded","handleHoverChange","handleUpdate","content","ctx","vnode","style","EditableContentDirective","props","__props","blockRef","useTemplateRef","__expose","resolvedComponent","shallowRef","componentName","computed","watch","newComponentName","pascalCaseBlockType","match","defineAsyncComponent","error","retry","fail","_createBlock","_resolveDynamicComponent","_mergeProps","$props","$attrs","_openBlock","_createElementBlock","_hoisted_1","_toDisplayString","B10cksVue","app","pluginOptions","B10cksComponent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/components/B10cksComponent.vue","../src/preview-bridge.ts","../src/directives/v-editable.ts","../src/directives/v-editable-content.ts","../src/index.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { IBContent } from '@b10cks/client'\nimport {\n type Component,\n computed,\n defineAsyncComponent,\n shallowRef,\n useTemplateRef,\n watch,\n} from 'vue'\n\nconst props = defineProps<{\n block: IBContent<string> & Record<string, never>\n}>()\n\nconst blockRef = useTemplateRef('blockRef')\ndefineExpose({ value: blockRef })\n\nconst resolvedComponent = shallowRef<Component | null>(null)\nconst componentName = computed(() => props.block?.block || null)\n\nwatch(\n () => componentName.value,\n async (newComponentName: string | null) => {\n if (!newComponentName) {\n resolvedComponent.value = null\n return\n }\n\n const pascalCaseBlockType = newComponentName\n .replace(/^([a-z])/, (match: string) => match.toUpperCase())\n .replace(/([a-z])([A-Z])/g, '$1$2')\n\n try {\n resolvedComponent.value = defineAsyncComponent({\n loader: () => import(`~/b10cks/${pascalCaseBlockType}.vue`),\n timeout: 3000,\n onError: (error, _, fail) => {\n // biome-ignore lint/suspicious/noConsole: give developers feedback\n console.warn(`Failed to load block component for type \"${newComponentName}\":`, error)\n fail()\n },\n })\n } catch (error) {\n // biome-ignore lint/suspicious/noConsole: give developers feedback\n console.error(`Error resolving component for block type \"${newComponentName}\":`, error)\n }\n },\n { immediate: true }\n)\n</script>\n<template>\n <component\n :is=\"resolvedComponent\"\n v-if=\"resolvedComponent\"\n ref=\"blockRef\"\n v-bind=\"{ ...$props, ...$attrs }\"\n />\n <div v-else>Component for block type \"{{ componentName }}\" not found.</div>\n</template>\n","export type ContentUpdateEvent = {\n content: Record<string, unknown>\n}\n\nexport type SelectUpdateEvent = {\n selectedItem: string\n}\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE'\n\nexport type EventPayloadMap = {\n CONTENT_UPDATE: ContentUpdateEvent\n SELECT_UPDATE: SelectUpdateEvent\n HOVER_UPDATE: SelectUpdateEvent\n}\n\nexport type BridgeEvent = {\n type: EventType\n payload: ContentUpdateEvent | SelectUpdateEvent\n b10cksId?: string\n}\n\ntype EventCallback<T> = (payload: T) => void\n\nclass PreviewBridge {\n private static instance: PreviewBridge\n private eventListeners: {\n [key in EventType]?: Array<EventCallback<EventPayloadMap[key]>>\n } = {}\n\n private isEnabled = false\n\n private constructor() {\n this.isEnabled = this.isIframe()\n }\n\n public init(): void {\n if (this.isEnabled && window) {\n window.addEventListener('message', this.handleMessage)\n }\n }\n\n public static getInstance(): PreviewBridge {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n public isInPreviewMode(): boolean {\n return this.isEnabled\n }\n\n private isIframe(): boolean {\n return window && window.self !== window.top\n }\n\n private handleMessage = (event: MessageEvent): void => {\n if (!event.data || typeof event.data !== 'object') return\n const { type, payload } = event.data as BridgeEvent\n\n this.notifyListeners(type as EventType, payload)\n }\n\n private notifyListeners<T extends EventType>(type: T, payload: EventPayloadMap[T]): void {\n const listeners = this.eventListeners[type] as\n | Array<EventCallback<EventPayloadMap[T]>>\n | undefined\n\n if (listeners) {\n listeners.forEach((listener) => {\n listener(payload)\n })\n }\n }\n\n public on<T extends EventType>(\n eventType: T,\n callback: EventCallback<EventPayloadMap[T]>\n ): () => void {\n if (!this.isEnabled) return () => {}\n\n if (!this.eventListeners[eventType]) {\n this.eventListeners[eventType] = []\n }\n\n ;(this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>).push(callback)\n\n return () => {\n this.eventListeners[eventType] = (\n this.eventListeners[eventType] as Array<EventCallback<EventPayloadMap[T]>>\n ).filter((listener) => listener !== callback) as never\n }\n }\n\n public selectItem(selectedItem: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem },\n },\n '*'\n )\n }\n\n public updateField(itemId: string, field: string, value: string): void {\n if (!this.isEnabled) return\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value },\n },\n '*'\n )\n }\n\n public destroy(): void {\n if (this.isEnabled) {\n window.removeEventListener('message', this.handleMessage)\n this.isEnabled = false\n }\n this.eventListeners = {}\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()\n","import type { DirectiveBinding, VNode } from 'vue'\n\nimport type { SelectUpdateEvent } from '../preview-bridge'\n\nimport { previewBridge } from '../preview-bridge'\n\ninterface EditableElement extends HTMLElement {\n _editableCleanup?: () => void\n}\n\nexport const EditableDirective = {\n mounted(el: EditableElement, binding: DirectiveBinding, node: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n const { id: itemId } = binding.value\n\n if (!itemId) {\n // biome-ignore lint/suspicious/noConsole: give developers feedback\n console.warn('v-editable directive requires a block with an id')\n return\n }\n\n el.classList.add('b10cks-preview')\n\n const handleClick = (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n previewBridge.selectItem(itemId)\n }\n\n const handleSelectionChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-selected')\n scrollIntoViewIfNeeded(el)\n } else {\n node.el.classList.remove('b10cks-selected')\n }\n }\n\n const handleHoverChange = ({ selectedItem }: SelectUpdateEvent) => {\n if (!node.el) return\n\n if (selectedItem === itemId) {\n node.el.classList.add('b10cks-hover')\n } else {\n node.el.classList.remove('b10cks-hover')\n }\n }\n\n const handleUpdate = ({ content }: { content: any }) => {\n if (content && content.id === itemId) {\n // biome-ignore lint/suspicious/noExplicitAny: use of any to access internal properties\n const ctx = (node as any).ctx\n ctx.parent.attrs.block = content\n ctx.update()\n ctx.props.block = content\n ctx.update()\n }\n }\n\n el.addEventListener('click', handleClick)\n previewBridge.on('SELECT_UPDATE', handleSelectionChange)\n previewBridge.on('HOVER_UPDATE', handleHoverChange)\n previewBridge.on('CONTENT_UPDATE', handleUpdate)\n\n el._editableCleanup = () => {\n el.removeEventListener('click', handleClick)\n }\n },\n\n updated(el: EditableElement, binding: DirectiveBinding, vnode: VNode) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (binding.value !== binding.oldValue) {\n if (el._editableCleanup) {\n el._editableCleanup()\n }\n\n EditableDirective.mounted(el, binding, vnode)\n }\n },\n\n unmounted(el: EditableElement) {\n if (!previewBridge.isInPreviewMode()) return\n\n if (el._editableCleanup) {\n el._editableCleanup()\n delete el._editableCleanup\n }\n\n el.classList.remove('b10cks-preview', 'b10cks-selected')\n },\n}\n\nfunction scrollIntoViewIfNeeded(el: HTMLElement) {\n if (el.scrollIntoView) {\n el.scrollIntoView({ behavior: 'smooth' })\n }\n}\n\nif (previewBridge.isInPreviewMode()) {\n const style = document.createElement('style')\n style.innerHTML = `\n .b10cks-hover,\n .b10cks-preview:hover {\n outline: 2px dashed rgba(59, 130, 246, 0.5);\n outline-offset: 2px;\n }\n .b10cks-selected {\n outline: 2px solid rgb(59, 130, 246) !important;\n outline-offset: 2px;\n }\n `\n document.head.appendChild(style)\n}\n","import type { Directive, DirectiveBinding } from 'vue'\n\nimport { previewBridge } from '../preview-bridge'\n\nexport const EditableContentDirective: Directive<HTMLElement> = {\n mounted(el: HTMLElement, binding: DirectiveBinding) {\n const { id: itemId, field } = binding.value\n if (!previewBridge.isInPreviewMode()) return\n el.setAttribute('contenteditable', 'true')\n\n el.addEventListener('input', (event: Event) => {\n previewBridge.updateField(itemId, field, (event.target as HTMLInputElement).innerText)\n })\n },\n}\n","import type { Plugin } from 'vue'\n\nimport type { B10cksVuePluginOptions } from './types'\n\nimport B10cksComponent from './components/B10cksComponent.vue'\nimport { EditableDirective } from './directives/v-editable'\nimport { EditableContentDirective } from './directives/v-editable-content'\n\nexport { previewBridge } from './preview-bridge'\n\nexport const B10cksVue: Plugin = {\n install(app, pluginOptions: B10cksVuePluginOptions) {\n app.provide('b10cksVueOptions', pluginOptions)\n\n app.directive('editable', EditableDirective)\n app.directive('editable-field', EditableContentDirective)\n app.component('B10cksComponent', B10cksComponent)\n },\n}\n"],"names":["props","__props","blockRef","useTemplateRef","__expose","resolvedComponent","shallowRef","componentName","computed","watch","newComponentName","pascalCaseBlockType","match","defineAsyncComponent","error","_","fail","_createBlock","_resolveDynamicComponent","_mergeProps","$props","$attrs","_openBlock","_createElementBlock","_hoisted_1","_toDisplayString","PreviewBridge","event","type","payload","listeners","listener","eventType","callback","selectedItem","itemId","field","value","previewBridge","EditableDirective","el","binding","node","handleClick","e","handleSelectionChange","scrollIntoViewIfNeeded","handleHoverChange","handleUpdate","content","ctx","vnode","style","EditableContentDirective","B10cksVue","app","pluginOptions","B10cksComponent"],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export type ContentUpdateEvent = {
|
|
2
|
-
content: Record<string,
|
|
2
|
+
content: Record<string, unknown>;
|
|
3
3
|
};
|
|
4
4
|
export type SelectUpdateEvent = {
|
|
5
5
|
selectedItem: string;
|
|
6
6
|
};
|
|
7
7
|
export type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE';
|
|
8
8
|
export type EventPayloadMap = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
CONTENT_UPDATE: ContentUpdateEvent;
|
|
10
|
+
SELECT_UPDATE: SelectUpdateEvent;
|
|
11
|
+
HOVER_UPDATE: SelectUpdateEvent;
|
|
12
12
|
};
|
|
13
13
|
export type BridgeEvent = {
|
|
14
14
|
type: EventType;
|
package/package.json
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@b10cks/vue",
|
|
3
|
+
"version": "0.10.2",
|
|
4
|
+
"description": "SDK to integrate b10cks into your vue applications",
|
|
3
5
|
"license": "MIT",
|
|
4
|
-
"version": "0.10.0",
|
|
5
6
|
"author": "Michael Wallner @ Coder's Cantina",
|
|
6
|
-
"
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/b10cks/sdk.git",
|
|
10
|
+
"directory": "packages/vue"
|
|
11
|
+
},
|
|
12
|
+
"source": "src/index.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
7
16
|
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"module": "./dist/index.mjs",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
8
20
|
"exports": {
|
|
9
21
|
".": {
|
|
10
22
|
"types": "./dist/index.d.ts",
|
|
@@ -12,17 +24,17 @@
|
|
|
12
24
|
"require": "./dist/index.js"
|
|
13
25
|
}
|
|
14
26
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@b10cks/client": "^0.10.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"vite": "^7.2.4",
|
|
36
|
+
"vite-plugin-dts": "^4.5.4",
|
|
37
|
+
"vue": "^3.5.25"
|
|
26
38
|
},
|
|
27
39
|
"peerDependencies": {
|
|
28
40
|
"vue": "^3.5.21"
|
|
@@ -32,23 +44,11 @@
|
|
|
32
44
|
"main"
|
|
33
45
|
]
|
|
34
46
|
},
|
|
35
|
-
"publishConfig": {
|
|
36
|
-
"access": "public"
|
|
37
|
-
},
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"typescript": "^5.9.0",
|
|
40
|
-
"vite": "^7.1.4",
|
|
41
|
-
"vite-plugin-dts": "^4.5.4",
|
|
42
|
-
"vue": "^3.4.0"
|
|
43
|
-
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"@b10cks/client": "^0.10.0"
|
|
46
|
-
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "vite build",
|
|
49
49
|
"dev": "vite build --watch",
|
|
50
50
|
"test": "vitest",
|
|
51
|
-
"lint": "
|
|
51
|
+
"lint": "biome lint --write",
|
|
52
52
|
"clean": "rm -rf dist"
|
|
53
53
|
}
|
|
54
54
|
}
|