@flyo/nitro-vue3 2.0.0 → 2.2.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 CHANGED
@@ -182,7 +182,49 @@ Every composable returns the same reactive shape:
182
182
 
183
183
  ## Live-edit support
184
184
 
185
- When your site is embedded in the Flyo preview iframe, `FlyoPage` automatically listens for `pageRefresh` messages and emits `update:page` so your component can reactively update without a full reload. Enable this by passing `liveEdit: true` to the plugin options.
185
+ When your site is embedded in the Flyo preview iframe, you can enable a full live-editing experience by passing `liveEdit: true` to the plugin options and using the `useFlyoLiveEdit` composable together with the `editable` helper.
186
+
187
+ ### `useFlyoLiveEdit()`
188
+
189
+ Call this composable **once** in your root layout or `App.vue`. It activates the bridge features from `@flyo/nitro-js-bridge` when `liveEdit` is enabled:
190
+
191
+ - **`reload()`** — reloads the page when Flyo sends a `pageRefresh` message.
192
+ - **`scrollTo()`** — scrolls to a specific block when Flyo sends a `scrollTo` message.
193
+ - **`highlightAndClick()`** — adds hover highlight and click-to-edit on every element with a `data-flyo-uid` attribute. A `MutationObserver` automatically wires up elements that are added after the initial render.
194
+
195
+ The composable is a no-op when `liveEdit` is `false`, so it is safe to include unconditionally.
196
+
197
+ ```vue
198
+ <!-- App.vue or your root layout component -->
199
+ <script setup>
200
+ import { useFlyoLiveEdit } from '@flyo/nitro-vue3'
201
+
202
+ useFlyoLiveEdit()
203
+ </script>
204
+
205
+ <template>
206
+ <router-view />
207
+ </template>
208
+ ```
209
+
210
+ ### `editable(block)`
211
+
212
+ Returns a `{ 'data-flyo-uid': block.uid }` attribute object for a given block, or an empty object if the block has no uid. Use `v-bind` to spread it onto the root element of your block component so `useFlyoLiveEdit` can discover it.
213
+
214
+ ```vue
215
+ <script setup>
216
+ import { editable } from '@flyo/nitro-vue3'
217
+
218
+ defineProps({ block: Object })
219
+ </script>
220
+
221
+ <template>
222
+ <section v-bind="editable(block)" class="bg-gray-200 p-8 rounded-lg text-center">
223
+ <h2 class="text-3xl font-bold mb-4">{{ block?.content?.title }}</h2>
224
+ <p class="text-lg mb-6">{{ block?.content?.teaser }}</p>
225
+ </section>
226
+ </template>
227
+ ```
186
228
 
187
229
  ---
188
230
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const u=require("@flyo/nitro-typescript"),e=require("vue");let m=null;const F=({apiToken:n,apiBasePath:t,defaultHeaders:o})=>{m=new u.Configuration({apiKey:n,...t&&{basePath:t},headers:o||{}})},f=()=>m,N={name:"FlyoBlock"},y=Object.assign(N,{props:{item:{type:Object,default:()=>{}}},setup(n){return(t,o)=>(e.openBlock(),e.createBlock(e.resolveDynamicComponent(n.item.component),{config:n.item.config,content:n.item.content,items:n.item.items,slots:n.item.slots},null,8,["config","content","items","slots"]))}}),J={name:"FlyoPage"},d=Object.assign(J,{props:{page:{type:[Object,Boolean],default:!1}},emits:["update:page"],setup(n,{emit:t}){const o=n,s=t,{liveEdit:a,liveEditOrigin:i}=e.inject("flyo"),p=r=>{const c=r.parent||r.opener;return r.self===c?!1:r.parent||r.opener},O=r=>{a&&process.client&&p(window)&&p(window).postMessage({action:"openEdit",data:JSON.parse(JSON.stringify({page:o.page,item:r}))},i)};return process.client&&p(window)&&window.addEventListener("message",r=>{if(r.origin!==i){console.log(`Message from ${r.origin} blocked. Expected ${i}.`);return}const c=r.data;c.action==="pageRefresh"&&s("update:page",c.data)}),(r,c)=>{const S=e.resolveComponent("FlyoBlock");return e.openBlock(),e.createElementBlock("div",null,[n.page?e.renderSlot(r.$slots,"default",e.normalizeProps(e.mergeProps({key:0},n.page)),()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.page.json,g=>(e.openBlock(),e.createBlock(S,{key:g.uid,item:g,onClick:()=>O(g)},null,8,["item","onClick"]))),128))]):e.createCommentVNode("",!0)])}}}),l=e.reactive({isLoading:null,response:null,error:null}),k=()=>{const n=async()=>{try{l.error=null,l.isLoading=!0,l.response=JSON.parse(JSON.stringify(await new u.ConfigApi(f()).config())),l.isLoading=!1}catch(t){l.isLoading=!1,l.response=null,l.error=JSON.parse(JSON.stringify(t))}return{response:l.response,error:l.error}};return{...e.toRefs(l),fetch:n}},h=n=>{const t=e.ref(!1),o=e.ref(null),s=e.ref(null);return{isLoading:t,response:o,error:s,fetch:async()=>{try{s.value=null,t.value=!0,o.value=JSON.parse(JSON.stringify(await new u.EntitiesApi(f()).entityByUniqueid({uniqueid:n}))),t.value=!1}catch(i){t.value=!1,o.value=null,s.value=JSON.parse(JSON.stringify(i))}return{response:e.unref(o),error:e.unref(s)}}}},E=n=>{const t=e.ref(!1),o=e.ref(null),s=e.ref(null);return{isLoading:t,response:o,error:s,fetch:async()=>{try{s.value=null,t.value=!0,o.value=JSON.parse(JSON.stringify(await new u.PagesApi(f()).page({slug:n}))),t.value=!1}catch(i){t.value=!1,o.value=null,s.value=JSON.parse(JSON.stringify(i))}return{response:e.unref(o),error:e.unref(s)}}}},B=()=>{const n=e.ref(!1),t=e.ref(null),o=e.ref(null);return{isLoading:n,response:t,error:o,fetch:async()=>{try{o.value=null,n.value=!0,t.value=JSON.parse(JSON.stringify(await new u.SitemapApi(f()).sitemap())),n.value=!1}catch(a){n.value=!1,t.value=null,o.value=JSON.parse(JSON.stringify(a))}return{response:e.unref(t),error:e.unref(o)}}}},v={install(n,t){F(t),n.component(y.name,y),n.component(d.name,d),n.provide("flyo",{liveEdit:t.liveEdit,liveEditOrigin:t.liveEditOrigin})}};exports.Block=y;exports.FlyoVue=v;exports.Page=d;exports.default=v;exports.getFlyoConfig=f;exports.useFlyoConfig=k;exports.useFlyoEntity=h;exports.useFlyoPage=E;exports.useFlyoSitemap=B;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const O=require("@flyo/nitro-typescript"),s=require("vue");let te=null;const de=({apiToken:t,apiBasePath:n,defaultHeaders:i})=>{te=new O.Configuration({apiKey:t,...n&&{basePath:n},headers:i||{}})},N=()=>te,ce={name:"FlyoBlock"},H=Object.assign(ce,{props:{item:{type:Object,default:()=>{}}},setup(t){return(n,i)=>(s.openBlock(),s.createBlock(s.resolveDynamicComponent(t.item.component),{config:t.item.config,content:t.item.content,items:t.item.items,slots:t.item.slots},null,8,["config","content","items","slots"]))}}),fe={name:"FlyoPage"},I=Object.assign(fe,{props:{page:{type:[Object,Boolean],default:!1}},emits:["update:page"],setup(t,{emit:n}){const i=t,r=n,{liveEdit:e,liveEditOrigin:o}=s.inject("flyo"),a=u=>{const d=u.parent||u.opener;return u.self===d?!1:u.parent||u.opener},f=u=>{e&&process.client&&a(window)&&a(window).postMessage({action:"openEdit",data:JSON.parse(JSON.stringify({page:i.page,item:u}))},o)};return process.client&&a(window)&&window.addEventListener("message",u=>{if(u.origin!==o){console.log(`Message from ${u.origin} blocked. Expected ${o}.`);return}const d=u.data;d.action==="pageRefresh"&&r("update:page",d.data)}),(u,d)=>{const y=s.resolveComponent("FlyoBlock");return s.openBlock(),s.createElementBlock("div",null,[t.page?s.renderSlot(u.$slots,"default",s.normalizeProps(s.mergeProps({key:0},t.page)),()=>[(s.openBlock(!0),s.createElementBlock(s.Fragment,null,s.renderList(t.page.json,v=>(s.openBlock(),s.createBlock(y,{key:v.uid,item:v,onClick:()=>f(v)},null,8,["item","onClick"]))),128))]):s.createCommentVNode("",!0)])}}}),c=s.reactive({isLoading:null,response:null,error:null}),ye=()=>{const t=async()=>{try{c.error=null,c.isLoading=!0,c.response=JSON.parse(JSON.stringify(await new O.ConfigApi(N()).config())),c.isLoading=!1}catch(n){c.isLoading=!1,c.response=null,c.error=JSON.parse(JSON.stringify(n))}return{response:c.response,error:c.error}};return{...s.toRefs(c),fetch:t}},pe=t=>{const n=s.ref(!1),i=s.ref(null),r=s.ref(null);return{isLoading:n,response:i,error:r,fetch:async()=>{try{r.value=null,n.value=!0,i.value=JSON.parse(JSON.stringify(await new O.EntitiesApi(N()).entityByUniqueid({uniqueid:t}))),n.value=!1}catch(o){n.value=!1,i.value=null,r.value=JSON.parse(JSON.stringify(o))}return{response:s.unref(i),error:s.unref(r)}}}};function B(){return typeof window>"u"?!1:window!==window.top}function me(){return typeof window>"u"?!1:B()?window.parent:window}function ve(t){var n=me();n&&n.postMessage({action:"openEdit",data:JSON.parse(JSON.stringify({item:{uid:t}}))},"https://flyo.cloud")}function ge(){typeof window>"u"||B()&&window.addEventListener("message",t=>{var n;((n=t.data)==null?void 0:n.action)==="pageRefresh"&&window.location.reload()})}function he(){typeof window>"u"||B()&&window.addEventListener("message",t=>{var n,i,r,e;if(((n=t.data)==null?void 0:n.action)==="scrollTo"){const o=(e=(r=(i=t.data)==null?void 0:i.data)==null?void 0:r.item)==null?void 0:e.uid;if(!o)return;const a=document.querySelector(`[data-flyo-uid="${CSS.escape(o)}"]`);a&&a.scrollIntoView({behavior:"smooth",block:"start"})}})}function we(t,n){const i=()=>ve(t);if(!B()||!n)return i;const r=n,e=document.createElement("button");e.type="button",e.setAttribute("aria-label","Edit block"),e.style.position="fixed",e.style.top="0px",e.style.left="0px",e.style.zIndex="9999",e.style.width="44px",e.style.height="44px",e.style.display="none",e.style.alignItems="center",e.style.justifyContent="center",e.style.border="0px solid #000",e.style.borderRadius="9999px",e.style.boxSizing="border-box",e.style.cursor="pointer",e.style.background="#FFD466",e.innerHTML='<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25z" fill="#111"/><path d="M20.71 7.04a1 1 0 0 0 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" fill="#111"/></svg>';const o=document.createElement("div");o.style.position="fixed",o.style.top="0px",o.style.left="0px",o.style.zIndex="9998",o.style.display="none",o.style.pointerEvents="none",o.style.background="transparent",o.style.border="none",e.addEventListener("click",i),document.body.appendChild(o),document.body.appendChild(e);const a=44,f=6,u=6,d=6,y=10,v=180,F=()=>window.innerWidth||document.documentElement.clientWidth,C=()=>window.innerHeight||document.documentElement.clientHeight,oe=l=>!(l.bottom<0||l.right<0||l.top>C()||l.left>F()||l.width===0&&l.height===0),$=(l,m)=>l>=d&&m>=d&&l+a<=F()-d&&m+a<=C()-d,W=(l,m)=>({x:Math.max(d,Math.min(l,F()-a-d)),y:Math.max(d,Math.min(m,C()-a-d))});function A(){const l=r.getBoundingClientRect(),m=l.width<a||l.height<a,L=Math.round(l.left),x=Math.round(l.top)-a-u,T=Math.round(l.left)+f,P=Math.round(l.top)+f;let M,S;if(m&&$(L,x))M=L,S=x;else if($(T,P))M=T,S=P;else if($(L,x))M=L,S=x;else{const _=W(L,x),q=W(T,P),ae=Math.abs(_.x-l.left)+Math.abs(_.y-l.top),ue=Math.abs(q.x-l.left)+Math.abs(q.y-l.top);({x:M,y:S}=ae<=ue?_:q)}e.style.left=`${M}px`,e.style.top=`${S}px`;const Z=Math.max(d,Math.round(l.left)-y),ee=Math.max(d,Math.round(l.top)-y),le=Math.min(F()-d,Math.round(l.right)+y),re=Math.min(C()-d,Math.round(l.bottom)+y);o.style.left=`${Z}px`,o.style.top=`${ee}px`,o.style.width=`${Math.max(0,le-Z)}px`,o.style.height=`${Math.max(0,re-ee)}px`}let g=!1,h=!1,w=!1,J=!1,E=null;const k=()=>{E!==null&&(clearTimeout(E),E=null)},j=()=>{k();try{const l=r.getBoundingClientRect();if(!oe(l)){b(!0);return}A(),e.style.display="flex",o.style.display="block",se()}catch{b(!0)}},b=(l=!1)=>{if(l){k(),e.style.display="none",o.style.display="none",R();return}k(),E=window.setTimeout(()=>{!g&&!h&&!w&&(e.style.display="none",o.style.display="none",R()),E=null},v)},z=()=>{e.style.display!=="none"&&A()},D=z;let p=null;const V=window.ResizeObserver,se=()=>{J||(J=!0,window.addEventListener("scroll",z,!0),window.addEventListener("resize",D),typeof V=="function"&&(p=new V(()=>{e.style.display!=="none"&&A()}),p==null||p.observe(r)))},R=()=>{if(J){J=!1,window.removeEventListener("scroll",z,!0),window.removeEventListener("resize",D);try{p==null||p.disconnect()}catch{}p=null}},U=()=>{g=!0,j()},K=()=>{g=!1,!h&&!w&&b()},G=()=>{h=!0,j()},Q=()=>{h=!1,!g&&!w&&b()},X=()=>{w=!0,j()},Y=()=>{w=!1,!g&&!h&&b()};r.addEventListener("mouseenter",U),r.addEventListener("mouseleave",K),e.addEventListener("mouseenter",G),e.addEventListener("mouseleave",Q),o.addEventListener("mouseenter",X),o.addEventListener("mouseleave",Y),e.addEventListener("click",i);function ie(){k(),R(),e.removeEventListener("click",i),r.removeEventListener("mouseenter",U),r.removeEventListener("mouseleave",K),e.removeEventListener("mouseenter",G),e.removeEventListener("mouseleave",Q),o.removeEventListener("mouseenter",X),o.removeEventListener("mouseleave",Y),e.parentElement===document.body&&document.body.removeChild(e),o.parentElement===document.body&&document.body.removeChild(o)}return ie}const Ee=t=>typeof(t==null?void 0:t.uid)=="string"&&t.uid.trim()!==""?{"data-flyo-uid":t.uid}:{},be=()=>{const{liveEdit:t}=s.inject("flyo");if(!t)return;let n=null;const i=[],r=()=>{i.forEach(e=>e()),i.length=0,document.querySelectorAll("[data-flyo-uid]").forEach(e=>{const o=e.getAttribute("data-flyo-uid");if(o&&e instanceof HTMLElement){const a=we(o,e);typeof a=="function"&&i.push(a)}})};s.onMounted(()=>{ge(),he(),r(),n=new MutationObserver(e=>{e.some(a=>Array.from(a.addedNodes).some(f=>{if(f.nodeType===Node.ELEMENT_NODE){const u=f;return u.hasAttribute("data-flyo-uid")||u.querySelector("[data-flyo-uid]")}return!1}))&&r()}),n.observe(document.body,{childList:!0,subtree:!0})}),s.onUnmounted(()=>{n&&n.disconnect(),i.forEach(e=>e()),i.length=0})},Le=t=>{const n=s.ref(!1),i=s.ref(null),r=s.ref(null);return{isLoading:n,response:i,error:r,fetch:async()=>{try{r.value=null,n.value=!0,i.value=JSON.parse(JSON.stringify(await new O.PagesApi(N()).page({slug:t}))),n.value=!1}catch(o){n.value=!1,i.value=null,r.value=JSON.parse(JSON.stringify(o))}return{response:s.unref(i),error:s.unref(r)}}}},xe=()=>{const t=s.ref(!1),n=s.ref(null),i=s.ref(null);return{isLoading:t,response:n,error:i,fetch:async()=>{try{i.value=null,t.value=!0,n.value=JSON.parse(JSON.stringify(await new O.SitemapApi(N()).sitemap())),t.value=!1}catch(e){t.value=!1,n.value=null,i.value=JSON.parse(JSON.stringify(e))}return{response:s.unref(n),error:s.unref(i)}}}},ne={install(t,n){de(n),t.component(H.name,H),t.component(I.name,I),t.provide("flyo",{liveEdit:n.liveEdit,liveEditOrigin:n.liveEditOrigin})}};exports.Block=H;exports.FlyoVue=ne;exports.Page=I;exports.default=ne;exports.editable=Ee;exports.getFlyoConfig=N;exports.useFlyoConfig=ye;exports.useFlyoEntity=pe;exports.useFlyoLiveEdit=be;exports.useFlyoPage=Le;exports.useFlyoSitemap=xe;
@@ -0,0 +1,76 @@
1
+ import type { App, Component, Ref } from 'vue'
2
+ import type {
3
+ Block as NitroBlock,
4
+ Configuration,
5
+ ConfigApi,
6
+ EntitiesApi,
7
+ PagesApi,
8
+ SitemapApi
9
+ } from '@flyo/nitro-typescript'
10
+
11
+ export interface FlyoVuePluginOptions {
12
+ apiToken: string
13
+ apiBasePath?: string
14
+ defaultHeaders?: Record<string, string>
15
+ liveEdit?: boolean
16
+ liveEditOrigin?: string
17
+ }
18
+
19
+ export interface FlyoFetchResult<T> {
20
+ response: T | null
21
+ error: unknown | null
22
+ }
23
+
24
+ export type FlyoConfigResponse = Awaited<ReturnType<ConfigApi['config']>>
25
+ export type FlyoPageResponse = Awaited<ReturnType<PagesApi['page']>>
26
+ export type FlyoEntityResponse = Awaited<ReturnType<EntitiesApi['entityByUniqueid']>>
27
+ export type FlyoSitemapResponse = Awaited<ReturnType<SitemapApi['sitemap']>>
28
+
29
+ export interface UseFlyoConfigReturn {
30
+ isLoading: Ref<boolean | null>
31
+ response: Ref<FlyoConfigResponse | null>
32
+ error: Ref<unknown | null>
33
+ fetch: () => Promise<FlyoFetchResult<FlyoConfigResponse>>
34
+ }
35
+
36
+ export interface UseFlyoPageReturn {
37
+ isLoading: Ref<boolean>
38
+ response: Ref<FlyoPageResponse | null>
39
+ error: Ref<unknown | null>
40
+ fetch: () => Promise<FlyoFetchResult<FlyoPageResponse>>
41
+ }
42
+
43
+ export interface UseFlyoEntityReturn {
44
+ isLoading: Ref<boolean>
45
+ response: Ref<FlyoEntityResponse | null>
46
+ error: Ref<unknown | null>
47
+ fetch: () => Promise<FlyoFetchResult<FlyoEntityResponse>>
48
+ }
49
+
50
+ export interface UseFlyoSitemapReturn {
51
+ isLoading: Ref<boolean>
52
+ response: Ref<FlyoSitemapResponse | null>
53
+ error: Ref<unknown | null>
54
+ fetch: () => Promise<FlyoFetchResult<FlyoSitemapResponse>>
55
+ }
56
+
57
+ export interface FlyoVuePlugin {
58
+ install: (app: App, options: FlyoVuePluginOptions) => void
59
+ }
60
+
61
+ declare const FlyoVue: FlyoVuePlugin
62
+ declare const Block: Component
63
+ declare const Page: Component
64
+
65
+ export default FlyoVue
66
+ export { FlyoVue, Block, Page }
67
+
68
+ export function getFlyoConfig(): Configuration | null
69
+
70
+ export function editable(block: NitroBlock): { 'data-flyo-uid'?: string }
71
+
72
+ export function useFlyoConfig(): UseFlyoConfigReturn
73
+ export function useFlyoLiveEdit(): void
74
+ export function useFlyoPage(slug: string): UseFlyoPageReturn
75
+ export function useFlyoEntity(uniqueid: string): UseFlyoEntityReturn
76
+ export function useFlyoSitemap(): UseFlyoSitemapReturn
package/dist/index.mjs CHANGED
@@ -1,15 +1,15 @@
1
- import { Configuration as h, ConfigApi as E, EntitiesApi as F, PagesApi as k, SitemapApi as w } from "@flyo/nitro-typescript";
2
- import { openBlock as f, createBlock as O, resolveDynamicComponent as C, inject as L, resolveComponent as B, createElementBlock as y, renderSlot as b, normalizeProps as j, mergeProps as P, Fragment as A, renderList as $, createCommentVNode as _, reactive as x, toRefs as M, ref as a, unref as i } from "vue";
3
- let S = null;
4
- const R = ({ apiToken: e, apiBasePath: n, defaultHeaders: t }) => {
5
- S = new h({
6
- apiKey: e,
1
+ import { Configuration as pe, ConfigApi as ye, EntitiesApi as me, PagesApi as ve, SitemapApi as ge } from "@flyo/nitro-typescript";
2
+ import { openBlock as k, createBlock as oe, resolveDynamicComponent as he, inject as se, resolveComponent as we, createElementBlock as ee, renderSlot as Ee, normalizeProps as be, mergeProps as Le, Fragment as xe, renderList as Me, createCommentVNode as Oe, reactive as Se, toRefs as Ne, ref as c, unref as v, onMounted as Ce, onUnmounted as Je } from "vue";
3
+ let ie = null;
4
+ const Fe = ({ apiToken: t, apiBasePath: n, defaultHeaders: s }) => {
5
+ ie = new pe({
6
+ apiKey: t,
7
7
  ...n && { basePath: n },
8
- headers: t || {}
8
+ headers: s || {}
9
9
  });
10
- }, p = () => S, W = {
10
+ }, $ = () => ie, ke = {
11
11
  name: "FlyoBlock"
12
- }, d = /* @__PURE__ */ Object.assign(W, {
12
+ }, te = /* @__PURE__ */ Object.assign(ke, {
13
13
  props: {
14
14
  item: {
15
15
  type: Object,
@@ -17,17 +17,17 @@ const R = ({ apiToken: e, apiBasePath: n, defaultHeaders: t }) => {
17
17
  }
18
18
  }
19
19
  },
20
- setup(e) {
21
- return (n, t) => (f(), O(C(e.item.component), {
22
- config: e.item.config,
23
- content: e.item.content,
24
- items: e.item.items,
25
- slots: e.item.slots
20
+ setup(t) {
21
+ return (n, s) => (k(), oe(he(t.item.component), {
22
+ config: t.item.config,
23
+ content: t.item.content,
24
+ items: t.item.items,
25
+ slots: t.item.slots
26
26
  }, null, 8, ["config", "content", "items", "slots"]));
27
27
  }
28
- }), q = {
28
+ }), $e = {
29
29
  name: "FlyoPage"
30
- }, v = /* @__PURE__ */ Object.assign(q, {
30
+ }, ne = /* @__PURE__ */ Object.assign($e, {
31
31
  props: {
32
32
  page: {
33
33
  type: [Object, Boolean],
@@ -35,129 +35,283 @@ const R = ({ apiToken: e, apiBasePath: n, defaultHeaders: t }) => {
35
35
  }
36
36
  },
37
37
  emits: ["update:page"],
38
- setup(e, { emit: n }) {
39
- const t = e, o = n, { liveEdit: c, liveEditOrigin: l } = L("flyo"), g = (s) => {
40
- const u = s.parent || s.opener;
41
- return s.self === u ? !1 : s.parent || s.opener;
42
- }, N = (s) => {
43
- c && process.client && g(window) && g(window).postMessage({
38
+ setup(t, { emit: n }) {
39
+ const s = t, l = n, { liveEdit: e, liveEditOrigin: o } = se("flyo"), r = (a) => {
40
+ const u = a.parent || a.opener;
41
+ return a.self === u ? !1 : a.parent || a.opener;
42
+ }, f = (a) => {
43
+ e && process.client && r(window) && r(window).postMessage({
44
44
  action: "openEdit",
45
45
  data: JSON.parse(JSON.stringify({
46
- page: t.page,
47
- item: s
46
+ page: s.page,
47
+ item: a
48
48
  }))
49
- }, l);
49
+ }, o);
50
50
  };
51
- return process.client && g(window) && window.addEventListener("message", (s) => {
52
- if (s.origin !== l) {
53
- console.log(`Message from ${s.origin} blocked. Expected ${l}.`);
51
+ return process.client && r(window) && window.addEventListener("message", (a) => {
52
+ if (a.origin !== o) {
53
+ console.log(`Message from ${a.origin} blocked. Expected ${o}.`);
54
54
  return;
55
55
  }
56
- const u = s.data;
57
- u.action === "pageRefresh" && o("update:page", u.data);
58
- }), (s, u) => {
59
- const J = B("FlyoBlock");
60
- return f(), y("div", null, [
61
- e.page ? b(s.$slots, "default", j(P({ key: 0 }, e.page)), () => [
62
- (f(!0), y(A, null, $(e.page.json, (m) => (f(), O(J, {
63
- key: m.uid,
64
- item: m,
65
- onClick: () => N(m)
56
+ const u = a.data;
57
+ u.action === "pageRefresh" && l("update:page", u.data);
58
+ }), (a, u) => {
59
+ const p = we("FlyoBlock");
60
+ return k(), ee("div", null, [
61
+ t.page ? Ee(a.$slots, "default", be(Le({ key: 0 }, t.page)), () => [
62
+ (k(!0), ee(xe, null, Me(t.page.json, (g) => (k(), oe(p, {
63
+ key: g.uid,
64
+ item: g,
65
+ onClick: () => f(g)
66
66
  }, null, 8, ["item", "onClick"]))), 128))
67
- ]) : _("", !0)
67
+ ]) : Oe("", !0)
68
68
  ]);
69
69
  };
70
70
  }
71
- }), r = x({
71
+ }), d = Se({
72
72
  isLoading: null,
73
73
  response: null,
74
74
  error: null
75
- }), K = () => {
76
- const e = async () => {
75
+ }), _e = () => {
76
+ const t = async () => {
77
77
  try {
78
- r.error = null, r.isLoading = !0, r.response = JSON.parse(JSON.stringify(await new E(p()).config())), r.isLoading = !1;
78
+ d.error = null, d.isLoading = !0, d.response = JSON.parse(JSON.stringify(await new ye($()).config())), d.isLoading = !1;
79
79
  } catch (n) {
80
- r.isLoading = !1, r.response = null, r.error = JSON.parse(JSON.stringify(n));
80
+ d.isLoading = !1, d.response = null, d.error = JSON.parse(JSON.stringify(n));
81
81
  }
82
82
  return {
83
- response: r.response,
84
- error: r.error
83
+ response: d.response,
84
+ error: d.error
85
85
  };
86
86
  };
87
87
  return {
88
- ...M(r),
89
- fetch: e
88
+ ...Ne(d),
89
+ fetch: t
90
90
  };
91
- }, U = (e) => {
92
- const n = a(!1), t = a(null), o = a(null);
91
+ }, qe = (t) => {
92
+ const n = c(!1), s = c(null), l = c(null);
93
93
  return {
94
94
  isLoading: n,
95
- response: t,
96
- error: o,
95
+ response: s,
96
+ error: l,
97
97
  fetch: async () => {
98
98
  try {
99
- o.value = null, n.value = !0, t.value = JSON.parse(JSON.stringify(await new F(p()).entityByUniqueid({ uniqueid: e }))), n.value = !1;
100
- } catch (l) {
101
- n.value = !1, t.value = null, o.value = JSON.parse(JSON.stringify(l));
99
+ l.value = null, n.value = !0, s.value = JSON.parse(JSON.stringify(await new me($()).entityByUniqueid({ uniqueid: t }))), n.value = !1;
100
+ } catch (o) {
101
+ n.value = !1, s.value = null, l.value = JSON.parse(JSON.stringify(o));
102
102
  }
103
103
  return {
104
- response: i(t),
105
- error: i(o)
104
+ response: v(s),
105
+ error: v(l)
106
106
  };
107
107
  }
108
108
  };
109
- }, G = (e) => {
110
- const n = a(!1), t = a(null), o = a(null);
109
+ };
110
+ function A() {
111
+ return typeof window > "u" ? !1 : window !== window.top;
112
+ }
113
+ function Ae() {
114
+ return typeof window > "u" ? !1 : A() ? window.parent : window;
115
+ }
116
+ function Be(t) {
117
+ var n = Ae();
118
+ n && n.postMessage({
119
+ action: "openEdit",
120
+ data: JSON.parse(JSON.stringify({ item: { uid: t } }))
121
+ }, "https://flyo.cloud");
122
+ }
123
+ function ze() {
124
+ typeof window > "u" || A() && window.addEventListener("message", (t) => {
125
+ var n;
126
+ ((n = t.data) == null ? void 0 : n.action) === "pageRefresh" && window.location.reload();
127
+ });
128
+ }
129
+ function Re() {
130
+ typeof window > "u" || A() && window.addEventListener("message", (t) => {
131
+ var n, s, l, e;
132
+ if (((n = t.data) == null ? void 0 : n.action) === "scrollTo") {
133
+ const o = (e = (l = (s = t.data) == null ? void 0 : s.data) == null ? void 0 : l.item) == null ? void 0 : e.uid;
134
+ if (!o)
135
+ return;
136
+ const r = document.querySelector(`[data-flyo-uid="${CSS.escape(o)}"]`);
137
+ r && r.scrollIntoView({ behavior: "smooth", block: "start" });
138
+ }
139
+ });
140
+ }
141
+ function je(t, n) {
142
+ const s = () => Be(t);
143
+ if (!A() || !n)
144
+ return s;
145
+ const l = n, e = document.createElement("button");
146
+ e.type = "button", e.setAttribute("aria-label", "Edit block"), e.style.position = "fixed", e.style.top = "0px", e.style.left = "0px", e.style.zIndex = "9999", e.style.width = "44px", e.style.height = "44px", e.style.display = "none", e.style.alignItems = "center", e.style.justifyContent = "center", e.style.border = "0px solid #000", e.style.borderRadius = "9999px", e.style.boxSizing = "border-box", e.style.cursor = "pointer", e.style.background = "#FFD466", e.innerHTML = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25z" fill="#111"/><path d="M20.71 7.04a1 1 0 0 0 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" fill="#111"/></svg>';
147
+ const o = document.createElement("div");
148
+ o.style.position = "fixed", o.style.top = "0px", o.style.left = "0px", o.style.zIndex = "9998", o.style.display = "none", o.style.pointerEvents = "none", o.style.background = "transparent", o.style.border = "none", e.addEventListener("click", s), document.body.appendChild(o), document.body.appendChild(e);
149
+ const r = 44, f = 6, a = 6, u = 6, p = 10, g = 180, N = () => window.innerWidth || document.documentElement.clientWidth, C = () => window.innerHeight || document.documentElement.clientHeight, le = (i) => !(i.bottom < 0 || i.right < 0 || i.top > C() || i.left > N() || i.width === 0 && i.height === 0), B = (i, m) => i >= u && m >= u && i + r <= N() - u && m + r <= C() - u, I = (i, m) => ({
150
+ x: Math.max(u, Math.min(i, N() - r - u)),
151
+ y: Math.max(u, Math.min(m, C() - r - u))
152
+ });
153
+ function z() {
154
+ const i = l.getBoundingClientRect(), m = i.width < r || i.height < r, x = Math.round(i.left), M = Math.round(i.top) - r - a, P = Math.round(i.left) + f, _ = Math.round(i.top) + f;
155
+ let O, S;
156
+ if (m && B(x, M))
157
+ O = x, S = M;
158
+ else if (B(P, _))
159
+ O = P, S = _;
160
+ else if (B(x, M))
161
+ O = x, S = M;
162
+ else {
163
+ const q = I(x, M), H = I(P, _), ce = Math.abs(q.x - i.left) + Math.abs(q.y - i.top), fe = Math.abs(H.x - i.left) + Math.abs(H.y - i.top);
164
+ ({ x: O, y: S } = ce <= fe ? q : H);
165
+ }
166
+ e.style.left = `${O}px`, e.style.top = `${S}px`;
167
+ const Y = Math.max(u, Math.round(i.left) - p), Z = Math.max(u, Math.round(i.top) - p), ue = Math.min(N() - u, Math.round(i.right) + p), de = Math.min(C() - u, Math.round(i.bottom) + p);
168
+ o.style.left = `${Y}px`, o.style.top = `${Z}px`, o.style.width = `${Math.max(0, ue - Y)}px`, o.style.height = `${Math.max(0, de - Z)}px`;
169
+ }
170
+ let h = !1, w = !1, E = !1, J = !1, b = null;
171
+ const F = () => {
172
+ b !== null && (clearTimeout(b), b = null);
173
+ }, R = () => {
174
+ F();
175
+ try {
176
+ const i = l.getBoundingClientRect();
177
+ if (!le(i)) {
178
+ L(!0);
179
+ return;
180
+ }
181
+ z(), e.style.display = "flex", o.style.display = "block", re();
182
+ } catch {
183
+ L(!0);
184
+ }
185
+ }, L = (i = !1) => {
186
+ if (i) {
187
+ F(), e.style.display = "none", o.style.display = "none", T();
188
+ return;
189
+ }
190
+ F(), b = window.setTimeout(() => {
191
+ !h && !w && !E && (e.style.display = "none", o.style.display = "none", T()), b = null;
192
+ }, g);
193
+ }, j = () => {
194
+ e.style.display !== "none" && z();
195
+ }, W = j;
196
+ let y = null;
197
+ const D = window.ResizeObserver, re = () => {
198
+ J || (J = !0, window.addEventListener("scroll", j, !0), window.addEventListener("resize", W), typeof D == "function" && (y = new D(() => {
199
+ e.style.display !== "none" && z();
200
+ }), y == null || y.observe(l)));
201
+ }, T = () => {
202
+ if (J) {
203
+ J = !1, window.removeEventListener("scroll", j, !0), window.removeEventListener("resize", W);
204
+ try {
205
+ y == null || y.disconnect();
206
+ } catch {
207
+ }
208
+ y = null;
209
+ }
210
+ }, U = () => {
211
+ h = !0, R();
212
+ }, V = () => {
213
+ h = !1, !w && !E && L();
214
+ }, K = () => {
215
+ w = !0, R();
216
+ }, G = () => {
217
+ w = !1, !h && !E && L();
218
+ }, Q = () => {
219
+ E = !0, R();
220
+ }, X = () => {
221
+ E = !1, !h && !w && L();
222
+ };
223
+ l.addEventListener("mouseenter", U), l.addEventListener("mouseleave", V), e.addEventListener("mouseenter", K), e.addEventListener("mouseleave", G), o.addEventListener("mouseenter", Q), o.addEventListener("mouseleave", X), e.addEventListener("click", s);
224
+ function ae() {
225
+ F(), T(), e.removeEventListener("click", s), l.removeEventListener("mouseenter", U), l.removeEventListener("mouseleave", V), e.removeEventListener("mouseenter", K), e.removeEventListener("mouseleave", G), o.removeEventListener("mouseenter", Q), o.removeEventListener("mouseleave", X), e.parentElement === document.body && document.body.removeChild(e), o.parentElement === document.body && document.body.removeChild(o);
226
+ }
227
+ return ae;
228
+ }
229
+ const He = (t) => typeof (t == null ? void 0 : t.uid) == "string" && t.uid.trim() !== "" ? { "data-flyo-uid": t.uid } : {}, Ie = () => {
230
+ const { liveEdit: t } = se("flyo");
231
+ if (!t)
232
+ return;
233
+ let n = null;
234
+ const s = [], l = () => {
235
+ s.forEach((e) => e()), s.length = 0, document.querySelectorAll("[data-flyo-uid]").forEach((e) => {
236
+ const o = e.getAttribute("data-flyo-uid");
237
+ if (o && e instanceof HTMLElement) {
238
+ const r = je(o, e);
239
+ typeof r == "function" && s.push(r);
240
+ }
241
+ });
242
+ };
243
+ Ce(() => {
244
+ ze(), Re(), l(), n = new MutationObserver((e) => {
245
+ e.some(
246
+ (r) => Array.from(r.addedNodes).some((f) => {
247
+ if (f.nodeType === Node.ELEMENT_NODE) {
248
+ const a = f;
249
+ return a.hasAttribute("data-flyo-uid") || a.querySelector("[data-flyo-uid]");
250
+ }
251
+ return !1;
252
+ })
253
+ ) && l();
254
+ }), n.observe(document.body, {
255
+ childList: !0,
256
+ subtree: !0
257
+ });
258
+ }), Je(() => {
259
+ n && n.disconnect(), s.forEach((e) => e()), s.length = 0;
260
+ });
261
+ }, We = (t) => {
262
+ const n = c(!1), s = c(null), l = c(null);
111
263
  return {
112
264
  isLoading: n,
113
- response: t,
114
- error: o,
265
+ response: s,
266
+ error: l,
115
267
  fetch: async () => {
116
268
  try {
117
- o.value = null, n.value = !0, t.value = JSON.parse(JSON.stringify(await new k(p()).page({ slug: e }))), n.value = !1;
118
- } catch (l) {
119
- n.value = !1, t.value = null, o.value = JSON.parse(JSON.stringify(l));
269
+ l.value = null, n.value = !0, s.value = JSON.parse(JSON.stringify(await new ve($()).page({ slug: t }))), n.value = !1;
270
+ } catch (o) {
271
+ n.value = !1, s.value = null, l.value = JSON.parse(JSON.stringify(o));
120
272
  }
121
273
  return {
122
- response: i(t),
123
- error: i(o)
274
+ response: v(s),
275
+ error: v(l)
124
276
  };
125
277
  }
126
278
  };
127
- }, H = () => {
128
- const e = a(!1), n = a(null), t = a(null);
279
+ }, De = () => {
280
+ const t = c(!1), n = c(null), s = c(null);
129
281
  return {
130
- isLoading: e,
282
+ isLoading: t,
131
283
  response: n,
132
- error: t,
284
+ error: s,
133
285
  fetch: async () => {
134
286
  try {
135
- t.value = null, e.value = !0, n.value = JSON.parse(JSON.stringify(await new w(p()).sitemap())), e.value = !1;
136
- } catch (c) {
137
- e.value = !1, n.value = null, t.value = JSON.parse(JSON.stringify(c));
287
+ s.value = null, t.value = !0, n.value = JSON.parse(JSON.stringify(await new ge($()).sitemap())), t.value = !1;
288
+ } catch (e) {
289
+ t.value = !1, n.value = null, s.value = JSON.parse(JSON.stringify(e));
138
290
  }
139
291
  return {
140
- response: i(n),
141
- error: i(t)
292
+ response: v(n),
293
+ error: v(s)
142
294
  };
143
295
  }
144
296
  };
145
- }, I = {
146
- install(e, n) {
147
- R(n), e.component(d.name, d), e.component(v.name, v), e.provide("flyo", {
297
+ }, Ue = {
298
+ install(t, n) {
299
+ Fe(n), t.component(te.name, te), t.component(ne.name, ne), t.provide("flyo", {
148
300
  liveEdit: n.liveEdit,
149
301
  liveEditOrigin: n.liveEditOrigin
150
302
  });
151
303
  }
152
304
  };
153
305
  export {
154
- d as Block,
155
- I as FlyoVue,
156
- v as Page,
157
- I as default,
158
- p as getFlyoConfig,
159
- K as useFlyoConfig,
160
- U as useFlyoEntity,
161
- G as useFlyoPage,
162
- H as useFlyoSitemap
306
+ te as Block,
307
+ Ue as FlyoVue,
308
+ ne as Page,
309
+ Ue as default,
310
+ He as editable,
311
+ $ as getFlyoConfig,
312
+ _e as useFlyoConfig,
313
+ qe as useFlyoEntity,
314
+ Ie as useFlyoLiveEdit,
315
+ We as useFlyoPage,
316
+ De as useFlyoSitemap
163
317
  };
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@flyo/nitro-vue3",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Vue3 Components for Flyo Nitro",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
7
8
  "exports": {
8
9
  ".": {
10
+ "types": "./dist/index.d.ts",
9
11
  "import": "./dist/index.mjs",
10
12
  "require": "./dist/index.cjs"
11
13
  }
@@ -18,7 +20,9 @@
18
20
  "dist"
19
21
  ],
20
22
  "scripts": {
21
- "build": "vite build",
23
+ "build": "vite build && npm run build:types",
24
+ "build:types": "node scripts/build-types.mjs",
25
+ "prepublishOnly": "npm run build",
22
26
  "test": "vitest run",
23
27
  "test:watch": "vitest",
24
28
  "release": "npm publish --access=public"
@@ -38,6 +42,7 @@
38
42
  "vitest": "^1.0.0"
39
43
  },
40
44
  "dependencies": {
45
+ "@flyo/nitro-js-bridge": "^1.3.0",
41
46
  "@flyo/nitro-typescript": "^1.4.0"
42
47
  }
43
48
  }