@webiny/website-builder-vue 6.4.0-beta.5 → 6.4.0-beta.6
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/LICENSE +21 -0
- package/README.md +11 -0
- package/components/ConnectToEditor.d.ts +35 -0
- package/components/ConnectToEditor.js +40 -0
- package/components/ConnectToEditor.js.map +1 -0
- package/components/DocumentFragment.d.ts +67 -0
- package/components/DocumentFragment.js +24 -0
- package/components/DocumentFragment.js.map +1 -0
- package/components/DocumentRenderer.d.ts +59 -0
- package/components/DocumentRenderer.js +68 -0
- package/components/DocumentRenderer.js.map +1 -0
- package/components/DocumentStoreProvider.d.ts +37 -0
- package/components/DocumentStoreProvider.js +32 -0
- package/components/DocumentStoreProvider.js.map +1 -0
- package/components/EditingElementRenderer/EditingElementRenderer.d.ts +22 -0
- package/components/EditingElementRenderer/EditingElementRenderer.js +53 -0
- package/components/EditingElementRenderer/EditingElementRenderer.js.map +1 -0
- package/components/EditingElementRenderer/EditingElementRenderer.presenter.d.ts +15 -0
- package/components/EditingElementRenderer/EditingElementRenderer.presenter.js +37 -0
- package/components/EditingElementRenderer/EditingElementRenderer.presenter.js.map +1 -0
- package/components/EditingElementRenderer/index.js +2 -0
- package/components/ElementIndexProvider.d.ts +19 -0
- package/components/ElementIndexProvider.js +19 -0
- package/components/ElementIndexProvider.js.map +1 -0
- package/components/ElementRenderer.d.ts +19 -0
- package/components/ElementRenderer.js +33 -0
- package/components/ElementRenderer.js.map +1 -0
- package/components/ElementSlot.d.ts +39 -0
- package/components/ElementSlot.js +36 -0
- package/components/ElementSlot.js.map +1 -0
- package/components/ElementSlotDepthProvider.d.ts +19 -0
- package/components/ElementSlotDepthProvider.js +19 -0
- package/components/ElementSlotDepthProvider.js.map +1 -0
- package/components/FragmentsProvider.d.ts +46 -0
- package/components/FragmentsProvider.js +40 -0
- package/components/FragmentsProvider.js.map +1 -0
- package/components/LiveElementRenderer.d.ts +24 -0
- package/components/LiveElementRenderer.js +74 -0
- package/components/LiveElementRenderer.js.map +1 -0
- package/components/LiveElementSlot.d.ts +21 -0
- package/components/LiveElementSlot.js +36 -0
- package/components/LiveElementSlot.js.map +1 -0
- package/components/PreviewElementSlot.d.ts +38 -0
- package/components/PreviewElementSlot.js +45 -0
- package/components/PreviewElementSlot.js.map +1 -0
- package/{src/components/index.ts → components/index.d.ts} +2 -11
- package/components/index.js +8 -0
- package/composables/useBindingsForElement.d.ts +825 -0
- package/composables/useBindingsForElement.js +24 -0
- package/composables/useBindingsForElement.js.map +1 -0
- package/composables/useDocumentState.d.ts +5 -0
- package/composables/useDocumentState.js +11 -0
- package/composables/useDocumentState.js.map +1 -0
- package/composables/useObservable.d.ts +13 -0
- package/composables/useObservable.js +14 -0
- package/composables/useObservable.js.map +1 -0
- package/{src/composables/useSelectFromState.ts → composables/useSelectFromState.d.ts} +2 -10
- package/composables/useSelectFromState.js +9 -0
- package/composables/useSelectFromState.js.map +1 -0
- package/composables/useViewport.d.ts +7 -0
- package/composables/useViewport.js +18 -0
- package/composables/useViewport.js.map +1 -0
- package/createComponent.d.ts +21 -0
- package/createComponent.js +31 -0
- package/createComponent.js.map +1 -0
- package/editorComponents/Box.d.ts +7 -0
- package/editorComponents/Box.js +4 -0
- package/editorComponents/Box.js.map +1 -0
- package/editorComponents/Box.manifest.d.ts +1 -0
- package/{src/editorComponents/Box.manifest.ts → editorComponents/Box.manifest.js} +6 -4
- package/editorComponents/Box.manifest.js.map +1 -0
- package/editorComponents/Fragment.d.ts +13 -0
- package/editorComponents/Fragment.js +39 -0
- package/editorComponents/Fragment.js.map +1 -0
- package/editorComponents/Fragment.manifest.d.ts +1 -0
- package/{src/editorComponents/Fragment.manifest.ts → editorComponents/Fragment.manifest.js} +6 -4
- package/editorComponents/Fragment.manifest.js.map +1 -0
- package/editorComponents/Grid.d.ts +24 -0
- package/editorComponents/Grid.js +33 -0
- package/editorComponents/Grid.js.map +1 -0
- package/editorComponents/Grid.manifest.d.ts +1 -0
- package/{src/editorComponents/Grid.manifest.ts → editorComponents/Grid.manifest.js} +58 -55
- package/editorComponents/Grid.manifest.js.map +1 -0
- package/editorComponents/GridColumn.d.ts +5 -0
- package/editorComponents/GridColumn.js +4 -0
- package/editorComponents/GridColumn.js.map +1 -0
- package/editorComponents/GridColumn.manifest.d.ts +1 -0
- package/{src/editorComponents/GridColumn.manifest.ts → editorComponents/GridColumn.manifest.js} +9 -5
- package/editorComponents/GridColumn.manifest.js.map +1 -0
- package/editorComponents/Image.d.ts +37 -0
- package/editorComponents/Image.js +115 -0
- package/editorComponents/Image.js.map +1 -0
- package/editorComponents/Image.manifest.d.ts +1 -0
- package/{src/editorComponents/Image.manifest.ts → editorComponents/Image.manifest.js} +17 -12
- package/editorComponents/Image.manifest.js.map +1 -0
- package/editorComponents/Lexical.d.ts +18 -0
- package/editorComponents/Lexical.js +15 -0
- package/editorComponents/Lexical.js.map +1 -0
- package/editorComponents/Lexical.manifest.d.ts +1 -0
- package/editorComponents/Lexical.manifest.js +24 -0
- package/editorComponents/Lexical.manifest.js.map +1 -0
- package/editorComponents/Root.d.ts +7 -0
- package/editorComponents/Root.js +4 -0
- package/editorComponents/Root.js.map +1 -0
- package/editorComponents/Root.manifest.d.ts +1 -0
- package/{src/editorComponents/Root.manifest.ts → editorComponents/Root.manifest.js} +5 -3
- package/editorComponents/Root.manifest.js.map +1 -0
- package/{src/editorComponents/index.ts → editorComponents/index.d.ts} +1 -3
- package/editorComponents/index.js +20 -0
- package/editorComponents/index.js.map +1 -0
- package/index.d.ts +10 -0
- package/index.js +9 -4
- package/package.json +10 -8
- package/{src/types.ts → types.d.ts} +11 -32
- package/types.js +0 -0
- package/src/components/ConnectToEditor.ts +0 -46
- package/src/components/DocumentFragment.ts +0 -43
- package/src/components/DocumentRenderer.ts +0 -102
- package/src/components/DocumentStoreProvider.ts +0 -53
- package/src/components/EditingElementRenderer/EditingElementRenderer.presenter.ts +0 -59
- package/src/components/EditingElementRenderer/EditingElementRenderer.ts +0 -70
- package/src/components/ElementIndexProvider.ts +0 -24
- package/src/components/ElementRenderer.ts +0 -42
- package/src/components/ElementSlot.ts +0 -34
- package/src/components/ElementSlotDepthProvider.ts +0 -24
- package/src/components/FragmentsProvider.ts +0 -87
- package/src/components/LiveElementRenderer.ts +0 -102
- package/src/components/LiveElementSlot.ts +0 -46
- package/src/components/PreviewElementSlot.ts +0 -43
- package/src/composables/useBindingsForElement.ts +0 -40
- package/src/composables/useDocumentState.ts +0 -13
- package/src/composables/useObservable.ts +0 -30
- package/src/composables/useViewport.ts +0 -27
- package/src/createComponent.ts +0 -55
- package/src/editorComponents/Box.ts +0 -8
- package/src/editorComponents/Fragment.ts +0 -57
- package/src/editorComponents/Grid.ts +0 -72
- package/src/editorComponents/GridColumn.ts +0 -6
- package/src/editorComponents/Image.ts +0 -144
- package/src/editorComponents/Lexical.manifest.ts +0 -24
- package/src/editorComponents/Lexical.ts +0 -23
- package/src/editorComponents/Root.ts +0 -8
- package/src/index.ts +0 -52
- package/tsconfig.build.json +0 -16
- package/tsconfig.json +0 -16
- package/webiny.config.js +0 -8
- /package/{src/components/EditingElementRenderer/index.ts → components/EditingElementRenderer/index.d.ts} +0 -0
- /package/{src/lexical.css → lexical.css} +0 -0
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineComponent,
|
|
3
|
-
provide,
|
|
4
|
-
inject,
|
|
5
|
-
watch,
|
|
6
|
-
type InjectionKey,
|
|
7
|
-
type PropType,
|
|
8
|
-
type Slot
|
|
9
|
-
} from "vue";
|
|
10
|
-
import { contentSdk } from "@webiny/website-builder-sdk";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* A fragment that renders a pre-defined Vue subtree (fixed).
|
|
14
|
-
* `element` is a Vue slot function returned by useSlots() — e.g. the result
|
|
15
|
-
* of `<template #fragment:header>…</template>` in the consumer.
|
|
16
|
-
*/
|
|
17
|
-
type FixedFragment = {
|
|
18
|
-
type: "fixed";
|
|
19
|
-
name: string;
|
|
20
|
-
element: Slot;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* A fragment that inserts a named editor component with given inputs.
|
|
25
|
-
*/
|
|
26
|
-
type ComponentFragment = {
|
|
27
|
-
type: "component";
|
|
28
|
-
component: string;
|
|
29
|
-
inputs: Record<string, unknown>;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export type DocumentFragmentConfig = FixedFragment | ComponentFragment;
|
|
33
|
-
export type DocumentFragments = DocumentFragmentConfig[];
|
|
34
|
-
|
|
35
|
-
const FRAGMENTS_KEY: InjectionKey<() => DocumentFragments> = Symbol("WebinyDocumentFragments");
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Provides the fragments array to all descendants and notifies the editing
|
|
39
|
-
* SDK whenever the fragment list changes.
|
|
40
|
-
*/
|
|
41
|
-
export const FragmentsProvider = defineComponent({
|
|
42
|
-
name: "WebinyFragmentsProvider",
|
|
43
|
-
|
|
44
|
-
props: {
|
|
45
|
-
fragments: {
|
|
46
|
-
type: Array as PropType<DocumentFragments>,
|
|
47
|
-
default: () => []
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
setup(props, { slots }) {
|
|
52
|
-
// Notify the editing SDK when fragments change.
|
|
53
|
-
watch(
|
|
54
|
-
() => props.fragments.length,
|
|
55
|
-
() => {
|
|
56
|
-
if (!contentSdk.isEditing()) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const data = props.fragments.map(f => {
|
|
61
|
-
if (f.type === "fixed") {
|
|
62
|
-
return { type: "fixed", name: f.name };
|
|
63
|
-
}
|
|
64
|
-
return { type: "component", component: f.component, inputs: f.inputs };
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
contentSdk.getEditingSdk()?.messenger.send("document.fragments", {
|
|
68
|
-
fragments: data
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
// Provide as a getter so consumers always receive the latest array.
|
|
74
|
-
provide(FRAGMENTS_KEY, () => props.fragments);
|
|
75
|
-
|
|
76
|
-
return () => slots.default?.();
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Composable – returns the current DocumentFragments array.
|
|
82
|
-
* Returns an empty array when called outside a FragmentsProvider.
|
|
83
|
-
*/
|
|
84
|
-
export const useDocumentFragments = (): DocumentFragments => {
|
|
85
|
-
const get = inject(FRAGMENTS_KEY, () => [] as DocumentFragments);
|
|
86
|
-
return get();
|
|
87
|
-
};
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { defineComponent, ref, computed, watch, onMounted, h, Fragment, type PropType } from "vue";
|
|
2
|
-
import { contentSdk, type DocumentElement, type ComponentInput } from "@webiny/website-builder-sdk";
|
|
3
|
-
import { ElementSlot } from "./ElementSlot.js";
|
|
4
|
-
import { useViewport } from "~/composables/useViewport.js";
|
|
5
|
-
import { useBindingsForElement } from "~/composables/useBindingsForElement.js";
|
|
6
|
-
import { useDocumentState } from "~/composables/useDocumentState.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Resolves a single document element into its rendered Vue subtree.
|
|
10
|
-
*
|
|
11
|
-
* Steps:
|
|
12
|
-
* 1. Determines the current breakpoint (starts at "desktop" for SSR safety).
|
|
13
|
-
* 2. Fetches merged bindings for the element at that breakpoint.
|
|
14
|
-
* 3. Calls contentSdk.resolveElement() to get the list of component instances.
|
|
15
|
-
* 4. Renders each instance, optionally wrapping it in a style div.
|
|
16
|
-
*/
|
|
17
|
-
export const LiveElementRenderer = defineComponent({
|
|
18
|
-
name: "WebinyLiveElementRenderer",
|
|
19
|
-
|
|
20
|
-
props: {
|
|
21
|
-
element: { type: Object as PropType<DocumentElement>, required: true }
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
setup(props) {
|
|
25
|
-
const viewport = useViewport();
|
|
26
|
-
|
|
27
|
-
// Start with "desktop" on both server and initial client render (SSR-safe).
|
|
28
|
-
const breakpoint = ref<string>("desktop");
|
|
29
|
-
|
|
30
|
-
onMounted(() => {
|
|
31
|
-
if (viewport.value?.breakpoint) {
|
|
32
|
-
breakpoint.value = viewport.value.breakpoint;
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
watch(
|
|
37
|
-
() => viewport.value?.breakpoint,
|
|
38
|
-
newBp => {
|
|
39
|
-
if (newBp && newBp !== breakpoint.value) {
|
|
40
|
-
breakpoint.value = newBp;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const elementId = computed(() => props.element?.id ?? "");
|
|
46
|
-
const elementBindings = useBindingsForElement(elementId.value, breakpoint);
|
|
47
|
-
const state = useDocumentState();
|
|
48
|
-
|
|
49
|
-
return () => {
|
|
50
|
-
const { element } = props;
|
|
51
|
-
if (!element?.component) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const onResolved = (value: unknown, input: ComponentInput) => {
|
|
56
|
-
if (input.type === "slot") {
|
|
57
|
-
const elements = (input as { list?: boolean }).list
|
|
58
|
-
? (value as string[])
|
|
59
|
-
: [value as string];
|
|
60
|
-
return h(ElementSlot, {
|
|
61
|
-
parentId: element.id,
|
|
62
|
-
slot: input.name,
|
|
63
|
-
elements
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return value;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const instances = contentSdk.resolveElement({
|
|
70
|
-
element,
|
|
71
|
-
state: state.value,
|
|
72
|
-
elementBindings: elementBindings.value,
|
|
73
|
-
onResolved
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
if (!instances) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const vnodes = instances.map((resolved, index) => {
|
|
81
|
-
const { component: Component, inputs, styles, manifest } = resolved;
|
|
82
|
-
const autoApplyStyles = manifest.autoApplyStyles !== false;
|
|
83
|
-
|
|
84
|
-
const userVNode = h(Component, {
|
|
85
|
-
key: `${element.id}-${index}`,
|
|
86
|
-
inputs,
|
|
87
|
-
styles,
|
|
88
|
-
element,
|
|
89
|
-
breakpoint: breakpoint.value
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
if (!autoApplyStyles) {
|
|
93
|
-
return userVNode;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return h("div", { key: `wrapper-${index}`, style: styles }, [userVNode]);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
return h(Fragment, null, vnodes);
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { defineComponent, h, type PropType } from "vue";
|
|
2
|
-
import { ElementSlotDepthProvider, useElementSlotDepth } from "./ElementSlotDepthProvider.js";
|
|
3
|
-
import { ElementIndexProvider } from "./ElementIndexProvider.js";
|
|
4
|
-
import { setLiveElementSlot } from "./PreviewElementSlot.js";
|
|
5
|
-
|
|
6
|
-
// Forward-declared to resolve the circular ElementRenderer ↔ LiveElementSlot cycle.
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
-
let ElementRenderer: any;
|
|
9
|
-
export const setElementRenderer = (c: unknown) => {
|
|
10
|
-
ElementRenderer = c;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Renders a flat list of element IDs as sibling ElementRenderer instances,
|
|
15
|
-
* each wrapped in an index-provider and nested inside an incremented depth.
|
|
16
|
-
*/
|
|
17
|
-
export const LiveElementSlot = defineComponent({
|
|
18
|
-
name: "WebinyLiveElementSlot",
|
|
19
|
-
|
|
20
|
-
props: {
|
|
21
|
-
elements: { type: Array as PropType<string[]>, default: () => [] }
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
setup(props) {
|
|
25
|
-
const depth = useElementSlotDepth();
|
|
26
|
-
|
|
27
|
-
return () =>
|
|
28
|
-
h(
|
|
29
|
-
ElementSlotDepthProvider,
|
|
30
|
-
{ depth: depth + 1 },
|
|
31
|
-
{
|
|
32
|
-
default: () =>
|
|
33
|
-
props.elements.map((id, index) =>
|
|
34
|
-
h(
|
|
35
|
-
ElementIndexProvider,
|
|
36
|
-
{ key: id, index },
|
|
37
|
-
{ default: () => h(ElementRenderer, { id }) }
|
|
38
|
-
)
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// Break the circular dependency: PreviewElementSlot needs LiveElementSlot.
|
|
46
|
-
setLiveElementSlot(LiveElementSlot);
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { defineComponent, h, type PropType } from "vue";
|
|
2
|
-
import { useElementSlotDepth } from "./ElementSlotDepthProvider.js";
|
|
3
|
-
|
|
4
|
-
// Forward-declare to avoid circular dep at module init time.
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
-
let LiveElementSlot: any;
|
|
7
|
-
export const setLiveElementSlot = (c: unknown) => {
|
|
8
|
-
LiveElementSlot = c;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* In editing mode, renders an empty placeholder div when the slot has no
|
|
13
|
-
* children (so the editor can show a drop zone). Otherwise delegates to
|
|
14
|
-
* LiveElementSlot.
|
|
15
|
-
*/
|
|
16
|
-
export const PreviewElementSlot = defineComponent({
|
|
17
|
-
name: "WebinyPreviewElementSlot",
|
|
18
|
-
|
|
19
|
-
props: {
|
|
20
|
-
parentId: { type: String, required: true },
|
|
21
|
-
slot: { type: String, required: true },
|
|
22
|
-
elements: { type: Array as PropType<string[]>, default: () => [] }
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
setup(props) {
|
|
26
|
-
const depth = useElementSlotDepth();
|
|
27
|
-
|
|
28
|
-
return () => {
|
|
29
|
-
if (!props.elements.length) {
|
|
30
|
-
return h("div", {
|
|
31
|
-
style: { height: "100px", width: "100% !important" },
|
|
32
|
-
"data-role": "element-slot",
|
|
33
|
-
"data-parent-id": props.parentId,
|
|
34
|
-
"data-parent-slot": props.slot,
|
|
35
|
-
"data-depth": depth,
|
|
36
|
-
"data-empty": true
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return h(LiveElementSlot, { elements: props.elements });
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { computed, type Ref } from "vue";
|
|
2
|
-
import { toJS } from "mobx";
|
|
3
|
-
import { BindingsProcessor } from "@webiny/website-builder-sdk";
|
|
4
|
-
import { useViewport } from "./useViewport.js";
|
|
5
|
-
import { useObservable } from "./useObservable.js";
|
|
6
|
-
import { useDocumentStore } from "~/components/DocumentStoreProvider.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Returns a Vue computed ref containing the merged bindings (inputs + styles)
|
|
10
|
-
* for the given element ID at the current breakpoint.
|
|
11
|
-
*
|
|
12
|
-
* Re-evaluates automatically when:
|
|
13
|
-
* - the MobX document store changes (via useObservable)
|
|
14
|
-
* - the breakpoint ref changes
|
|
15
|
-
* - the viewport breakpoints change
|
|
16
|
-
*/
|
|
17
|
-
export const useBindingsForElement = (elementId: string, breakpoint: Ref<string>) => {
|
|
18
|
-
const documentStore = useDocumentStore();
|
|
19
|
-
const viewport = useViewport();
|
|
20
|
-
|
|
21
|
-
// Observe this element's bindings directly inside the MobX autorun so that
|
|
22
|
-
// deep mutations from applyPatch (e.g. adding a child element) trigger a
|
|
23
|
-
// re-render without needing the top-level document reference to change.
|
|
24
|
-
// toJS() inside the autorun causes MobX to track all sub-properties.
|
|
25
|
-
const elementBindings = useObservable(() => {
|
|
26
|
-
const doc = documentStore.getDocument();
|
|
27
|
-
if (!doc) {
|
|
28
|
-
return undefined;
|
|
29
|
-
}
|
|
30
|
-
return toJS(doc.bindings[elementId]);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
return computed(() => {
|
|
34
|
-
const bindings = elementBindings.value ?? {};
|
|
35
|
-
const breakpoints =
|
|
36
|
-
viewport.value?.breakpoints?.map((bp: { name: string }) => bp.name) ?? [];
|
|
37
|
-
const processor = new BindingsProcessor(breakpoints);
|
|
38
|
-
return processor.getBindings(bindings, breakpoint.value);
|
|
39
|
-
});
|
|
40
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { computed } from "vue";
|
|
2
|
-
import { useObservable } from "./useObservable.js";
|
|
3
|
-
import { useDocumentStore } from "~/components/DocumentStoreProvider.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns a Vue computed ref containing the document's `state` object.
|
|
7
|
-
* Re-evaluates whenever the MobX document store changes.
|
|
8
|
-
*/
|
|
9
|
-
export const useDocumentState = () => {
|
|
10
|
-
const documentStore = useDocumentStore();
|
|
11
|
-
const document = useObservable(() => documentStore.getDocument());
|
|
12
|
-
return computed(() => document.value?.state ?? {});
|
|
13
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { shallowRef, onUnmounted, triggerRef, getCurrentInstance, type Ref } from "vue";
|
|
2
|
-
import { autorun } from "mobx";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Bridges a MobX observable into a Vue shallow ref.
|
|
6
|
-
*
|
|
7
|
-
* The supplied `fn` is run inside a MobX `autorun`. Every time a MobX
|
|
8
|
-
* observable accessed by `fn` changes, the ref is updated and Vue is told
|
|
9
|
-
* to treat it as "dirty" so that all computed values and templates that
|
|
10
|
-
* depend on it re-evaluate.
|
|
11
|
-
*
|
|
12
|
-
* Must be called inside a component setup() (or equivalent) so that
|
|
13
|
-
* `onUnmounted` can clean up the MobX reaction automatically.
|
|
14
|
-
*/
|
|
15
|
-
export function useObservable<T>(fn: () => T): Ref<T> {
|
|
16
|
-
const value = shallowRef<T>(fn());
|
|
17
|
-
|
|
18
|
-
const disposer = autorun(() => {
|
|
19
|
-
value.value = fn();
|
|
20
|
-
// shallowRef won't trigger on the same object reference; triggerRef
|
|
21
|
-
// forces Vue to re-evaluate all dependents regardless.
|
|
22
|
-
triggerRef(value);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
if (getCurrentInstance()) {
|
|
26
|
-
onUnmounted(() => disposer());
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return value as Ref<T>;
|
|
30
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { shallowRef, triggerRef, onMounted, onUnmounted } from "vue";
|
|
2
|
-
import { viewportManager } from "@webiny/website-builder-sdk";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Returns a reactive ref that contains the current viewport info.
|
|
6
|
-
*
|
|
7
|
-
* Starts with the current value (or a sensible default on the server) and
|
|
8
|
-
* updates whenever the viewport manager fires a change-end event.
|
|
9
|
-
*/
|
|
10
|
-
export const useViewport = () => {
|
|
11
|
-
const viewport = shallowRef(viewportManager.getViewport());
|
|
12
|
-
let unsubscribe: (() => void) | undefined;
|
|
13
|
-
|
|
14
|
-
onMounted(() => {
|
|
15
|
-
// Sync the latest value after mount (in case a resize already happened).
|
|
16
|
-
viewport.value = viewportManager.getViewport();
|
|
17
|
-
|
|
18
|
-
unsubscribe = viewportManager.onViewportChangeEnd(newViewport => {
|
|
19
|
-
viewport.value = newViewport;
|
|
20
|
-
triggerRef(viewport);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
onUnmounted(() => unsubscribe?.());
|
|
25
|
-
|
|
26
|
-
return viewport;
|
|
27
|
-
};
|
package/src/createComponent.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Component,
|
|
3
|
-
ComponentInput,
|
|
4
|
-
ComponentManifest,
|
|
5
|
-
ComponentManifestInput,
|
|
6
|
-
InputFactory
|
|
7
|
-
} from "@webiny/website-builder-sdk";
|
|
8
|
-
import { createSlotInput } from "@webiny/website-builder-sdk";
|
|
9
|
-
import type { ExtractInputs } from "~/types.js";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Wraps a Vue component with a Webiny Website Builder manifest so it can be
|
|
13
|
-
* registered with the SDK and rendered inside a DocumentRenderer.
|
|
14
|
-
*
|
|
15
|
-
* Usage:
|
|
16
|
-
* ```ts
|
|
17
|
-
* import { createComponent, createTextInput } from "@webiny/website-builder-vue";
|
|
18
|
-
*
|
|
19
|
-
* const MyBanner = (props: ComponentProps<{ headline: string }>) =>
|
|
20
|
-
* h("div", props.inputs.headline);
|
|
21
|
-
*
|
|
22
|
-
* export const Banner = createComponent(MyBanner, {
|
|
23
|
-
* name: "My/Banner",
|
|
24
|
-
* label: "Banner",
|
|
25
|
-
* inputs: { headline: createTextInput({ label: "Headline" }) }
|
|
26
|
-
* });
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export function createComponent<
|
|
30
|
-
TComponent extends (props: any) => any,
|
|
31
|
-
TInputs extends ExtractInputs<Parameters<TComponent>[0]>
|
|
32
|
-
>(component: TComponent, manifest: ComponentManifestInput<TInputs>): Component {
|
|
33
|
-
const inputs: ComponentInput[] = [];
|
|
34
|
-
|
|
35
|
-
if (Array.isArray(manifest.inputs)) {
|
|
36
|
-
inputs.push(...manifest.inputs);
|
|
37
|
-
} else {
|
|
38
|
-
const inputsObject: Record<string, InputFactory<any>> = manifest.inputs ?? {};
|
|
39
|
-
Object.keys(inputsObject).forEach((name: string) => {
|
|
40
|
-
inputs.push({ ...inputsObject[name], name });
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (manifest.acceptsChildren) {
|
|
45
|
-
const hasChildren = inputs.some(input => input.name === "children");
|
|
46
|
-
if (!hasChildren) {
|
|
47
|
-
inputs.push(createSlotInput({ name: "children" }));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
component,
|
|
53
|
-
manifest: { ...manifest, tags: manifest.tags ?? [], inputs } as ComponentManifest
|
|
54
|
-
};
|
|
55
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { h } from "vue";
|
|
2
|
-
import { contentSdk } from "@webiny/website-builder-sdk";
|
|
3
|
-
import { useDocumentFragments } from "~/components/FragmentsProvider.js";
|
|
4
|
-
import type { ComponentProps } from "~/types.js";
|
|
5
|
-
import type { DocumentFragments } from "~/components/FragmentsProvider.js";
|
|
6
|
-
import type { DocumentFragmentConfig } from "~/components/FragmentsProvider.js";
|
|
7
|
-
|
|
8
|
-
type FragmentProps = ComponentProps<{ name: string }>;
|
|
9
|
-
|
|
10
|
-
const findFixed = (fragments: DocumentFragments, name: string) =>
|
|
11
|
-
fragments.find(f => f.type === "fixed" && f.name === name) as
|
|
12
|
-
| Extract<DocumentFragmentConfig, { type: "fixed" }>
|
|
13
|
-
| undefined;
|
|
14
|
-
|
|
15
|
-
const FragmentPlaceholder = (props: { name: string }) => {
|
|
16
|
-
const label = props.name ? h("strong", null, [` ${props.name} `]) : " ";
|
|
17
|
-
|
|
18
|
-
return h(
|
|
19
|
-
"div",
|
|
20
|
-
{
|
|
21
|
-
style: {
|
|
22
|
-
display: "flex",
|
|
23
|
-
height: "100px",
|
|
24
|
-
backgroundColor: "#f4f4f4",
|
|
25
|
-
justifyContent: "center",
|
|
26
|
-
alignItems: "center",
|
|
27
|
-
fill: "#ffffff"
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
["This is a placeholder for", label, "content coming from your frontend app."]
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Looks up a named fixed fragment provided by the consumer's DocumentRenderer
|
|
36
|
-
* and renders it in place. Shows a placeholder in editing mode when no
|
|
37
|
-
* matching fragment is found.
|
|
38
|
-
*/
|
|
39
|
-
export const FragmentComponent = (props: FragmentProps) => {
|
|
40
|
-
const isEditing = contentSdk.isEditing();
|
|
41
|
-
const fragments = useDocumentFragments();
|
|
42
|
-
const fragment = findFixed(fragments, props.inputs?.name);
|
|
43
|
-
|
|
44
|
-
if (!fragment && isEditing) {
|
|
45
|
-
return h(FragmentPlaceholder, { name: props.inputs?.name });
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (fragment) {
|
|
49
|
-
// `element` is a Vue slot function (() => VNode[]) or a VNode.
|
|
50
|
-
if (typeof fragment.element === "function") {
|
|
51
|
-
return h("div", null, fragment.element());
|
|
52
|
-
}
|
|
53
|
-
return fragment.element;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return null;
|
|
57
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { h } from "vue";
|
|
2
|
-
import type { ComponentProps } from "~/types.js";
|
|
3
|
-
import type { VNode } from "vue";
|
|
4
|
-
|
|
5
|
-
interface Column {
|
|
6
|
-
children: VNode | null;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
type GridProps = ComponentProps<{
|
|
10
|
-
gridLayout: string;
|
|
11
|
-
rowCount: number;
|
|
12
|
-
rowGap: number;
|
|
13
|
-
columnGap: number;
|
|
14
|
-
columns: Column[];
|
|
15
|
-
stackAtBreakpoint?: string;
|
|
16
|
-
reverseWhenStacked?: boolean;
|
|
17
|
-
}>;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Renders a flexible CSS grid with rows/columns derived from `gridLayout`
|
|
21
|
-
* (e.g. "6-6" = two equal columns, "4-8" = one-third + two-thirds, etc.).
|
|
22
|
-
*
|
|
23
|
-
* The children of each column are VNodes resolved by the SDK (ElementSlot).
|
|
24
|
-
*/
|
|
25
|
-
export const GridComponent = (props: GridProps) => {
|
|
26
|
-
const { inputs, styles, breakpoint } = props;
|
|
27
|
-
const {
|
|
28
|
-
gridLayout = "12",
|
|
29
|
-
columns = [],
|
|
30
|
-
columnGap,
|
|
31
|
-
stackAtBreakpoint,
|
|
32
|
-
reverseWhenStacked
|
|
33
|
-
} = inputs;
|
|
34
|
-
|
|
35
|
-
const rowConfig = gridLayout.split("-").map(s => parseInt(s));
|
|
36
|
-
const rows: Column[][] = [];
|
|
37
|
-
|
|
38
|
-
for (let i = 0; i < columns.length; i += rowConfig.length) {
|
|
39
|
-
rows.push(columns.slice(i, i + rowConfig.length));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const cellWidthReduction = columnGap ? columnGap - columnGap / rowConfig.length : 0;
|
|
43
|
-
const stackColumns = breakpoint === stackAtBreakpoint;
|
|
44
|
-
|
|
45
|
-
const gridStyles = { ...styles };
|
|
46
|
-
if (stackColumns) {
|
|
47
|
-
gridStyles.flexDirection = reverseWhenStacked ? "column-reverse" : "column";
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const cells = rows.flatMap(rowCols =>
|
|
51
|
-
rowCols.map((col, i) => {
|
|
52
|
-
const width = stackColumns
|
|
53
|
-
? "100%"
|
|
54
|
-
: `calc(${(rowConfig[i] / 12) * 100}% - ${cellWidthReduction}px)`;
|
|
55
|
-
|
|
56
|
-
return h(
|
|
57
|
-
"div",
|
|
58
|
-
{
|
|
59
|
-
key: i,
|
|
60
|
-
style: {
|
|
61
|
-
flex: `0 0 ${width}`,
|
|
62
|
-
maxWidth: width,
|
|
63
|
-
boxSizing: "border-box"
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
[col.children]
|
|
67
|
-
);
|
|
68
|
-
})
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
return h("div", { style: gridStyles }, cells);
|
|
72
|
-
};
|