@lightspeed/crane 0.0.1-beta.23
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/bin/crane.js +3 -0
- package/dist/app.d.mts +130 -0
- package/dist/app.d.ts +130 -0
- package/dist/app.mjs +1 -0
- package/dist/cli.d.mts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.mjs +5 -0
- package/package.json +59 -0
- package/template/.eslintrc.cjs +3 -0
- package/template/_gitignore +25 -0
- package/template/crane.config.json +4 -0
- package/template/index.d.ts +1 -0
- package/template/package.json +14 -0
- package/template/sections/block-example/CustomBlock.vue +57 -0
- package/template/sections/block-example/client.ts +5 -0
- package/template/sections/block-example/server.ts +5 -0
- package/template/sections/block-example/settings/content.ts +41 -0
- package/template/sections/block-example/settings/design.ts +85 -0
- package/template/sections/block-example/settings/translations.ts +35 -0
- package/template/sections/block-example/type.ts +5 -0
- package/template/templates/template.json +159 -0
- package/template/tsconfig.json +24 -0
- package/types.d.ts +286 -0
package/bin/crane.js
ADDED
package/dist/app.d.mts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { App, Ref, Component } from 'vue';
|
|
2
|
+
|
|
3
|
+
interface AppBaseContext {
|
|
4
|
+
readonly appName: string;
|
|
5
|
+
readonly blockName: string;
|
|
6
|
+
readonly version: string;
|
|
7
|
+
readonly scriptUrl: string;
|
|
8
|
+
readonly imageBuckets: Record<string, string>;
|
|
9
|
+
readonly globalDesign: Record<string, Record<string, unknown>>;
|
|
10
|
+
}
|
|
11
|
+
interface AppBaseData<C, D> {
|
|
12
|
+
readonly content: C;
|
|
13
|
+
readonly design: D;
|
|
14
|
+
readonly defaults: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
interface AppBaseState<C, D> {
|
|
17
|
+
readonly context: AppBaseContext;
|
|
18
|
+
readonly data: AppBaseData<C, D>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface VueBaseProps<CONTENT, DESIGN> {
|
|
22
|
+
init: (app: App<Element>, contextValue: AppBaseContext, contentValue: CONTENT, designValue: DESIGN, defaultsValue: Record<string, unknown>) => void;
|
|
23
|
+
update: (app: App<Element>, contentValue: CONTENT, designValue: DESIGN) => void;
|
|
24
|
+
readonly context: Ref<AppBaseContext>;
|
|
25
|
+
readonly content: Ref<CONTENT>;
|
|
26
|
+
readonly design: Ref<DESIGN>;
|
|
27
|
+
readonly defaults: Ref<Record<string, unknown>>;
|
|
28
|
+
}
|
|
29
|
+
declare function useVueBaseProps<CONTENT, DESIGN>(): VueBaseProps<CONTENT, DESIGN>;
|
|
30
|
+
|
|
31
|
+
declare function useInputboxElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
32
|
+
hasContent: boolean;
|
|
33
|
+
value: string | undefined;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
declare function useTextareaElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
37
|
+
hasContent: boolean;
|
|
38
|
+
value: string | undefined;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
declare function useButtonElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
42
|
+
title: string | undefined;
|
|
43
|
+
link: string | undefined;
|
|
44
|
+
hasTitle: boolean;
|
|
45
|
+
hasLink: boolean;
|
|
46
|
+
performAction: () => void;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
declare function useImageElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
50
|
+
hasContent: boolean;
|
|
51
|
+
lowResolutionMobileImage: string;
|
|
52
|
+
highResolutionMobileImage: string;
|
|
53
|
+
lowResolutionDesktopImage: string;
|
|
54
|
+
highResolutionDesktopImage: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
declare function useToggleElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
58
|
+
hasContent: boolean;
|
|
59
|
+
value: boolean | undefined;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
declare function useSelectboxElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
63
|
+
hasContent: boolean;
|
|
64
|
+
value: undefined;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
declare function useTextElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
68
|
+
font: string | undefined;
|
|
69
|
+
size: number | GlobalTextSizeString | undefined;
|
|
70
|
+
bold: boolean | undefined;
|
|
71
|
+
italic: boolean | undefined;
|
|
72
|
+
color: Color | GlobalColorsString | undefined;
|
|
73
|
+
visible: boolean | undefined;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
declare function useButtonElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
77
|
+
appearance: ButtonAppearance | undefined;
|
|
78
|
+
font: string | undefined;
|
|
79
|
+
size: ButtonSize | undefined;
|
|
80
|
+
style: ButtonStyle | undefined;
|
|
81
|
+
color: Color | GlobalColorsString | undefined;
|
|
82
|
+
visible: boolean | undefined;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
declare function useImageElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
86
|
+
overlay: Overlay | undefined;
|
|
87
|
+
visible: boolean | undefined;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
declare function useToggleElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
91
|
+
enabled: boolean | undefined;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
declare function useSelectboxElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
95
|
+
value: string | undefined;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
declare function useBackgroundElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
99
|
+
background: Background | undefined;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
interface VueServerAppExtensions {
|
|
103
|
+
init?: (app: App<Element>) => void;
|
|
104
|
+
render?: <C, D>(app: App<Element>, context: AppBaseContext, data: AppBaseData<C, D>) => void;
|
|
105
|
+
}
|
|
106
|
+
interface VueRenderResult {
|
|
107
|
+
readonly html: string;
|
|
108
|
+
readonly state: unknown;
|
|
109
|
+
}
|
|
110
|
+
declare function createVueServerApp<C, D>(appComponent: Component, extensions?: VueServerAppExtensions): {
|
|
111
|
+
init: () => {
|
|
112
|
+
render: (context: AppBaseContext, data: AppBaseData<C, D>) => Promise<VueRenderResult>;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
interface VueClientAppExtensions {
|
|
117
|
+
init?: (app: App<Element>) => void;
|
|
118
|
+
mount?: <C, D, S extends AppBaseState<C, D>>(app: App<Element>, rootContainer: string, state: S) => void;
|
|
119
|
+
update?: <C, D, S extends AppBaseState<C, D>>(app: App<Element>, state: S) => void;
|
|
120
|
+
unmount?: (app: App<Element>) => void;
|
|
121
|
+
}
|
|
122
|
+
declare function createVueClientApp<C, D>(appComponent: Component, extensions?: VueClientAppExtensions): {
|
|
123
|
+
init: () => {
|
|
124
|
+
mount: <S extends AppBaseState<C, D>>(rootContainer: string, state: S) => void;
|
|
125
|
+
update: <S_1 extends AppBaseState<C, D>>(state: S_1) => void;
|
|
126
|
+
unmount: () => void;
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export { createVueClientApp, createVueServerApp, useBackgroundElementDesign, useButtonElementContent, useButtonElementDesign, useImageElementContent, useImageElementDesign, useInputboxElementContent, useSelectboxElementContent, useSelectboxElementDesign, useTextElementDesign, useTextareaElementContent, useToggleElementContent, useToggleElementDesign, useVueBaseProps };
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { App, Ref, Component } from 'vue';
|
|
2
|
+
|
|
3
|
+
interface AppBaseContext {
|
|
4
|
+
readonly appName: string;
|
|
5
|
+
readonly blockName: string;
|
|
6
|
+
readonly version: string;
|
|
7
|
+
readonly scriptUrl: string;
|
|
8
|
+
readonly imageBuckets: Record<string, string>;
|
|
9
|
+
readonly globalDesign: Record<string, Record<string, unknown>>;
|
|
10
|
+
}
|
|
11
|
+
interface AppBaseData<C, D> {
|
|
12
|
+
readonly content: C;
|
|
13
|
+
readonly design: D;
|
|
14
|
+
readonly defaults: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
interface AppBaseState<C, D> {
|
|
17
|
+
readonly context: AppBaseContext;
|
|
18
|
+
readonly data: AppBaseData<C, D>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface VueBaseProps<CONTENT, DESIGN> {
|
|
22
|
+
init: (app: App<Element>, contextValue: AppBaseContext, contentValue: CONTENT, designValue: DESIGN, defaultsValue: Record<string, unknown>) => void;
|
|
23
|
+
update: (app: App<Element>, contentValue: CONTENT, designValue: DESIGN) => void;
|
|
24
|
+
readonly context: Ref<AppBaseContext>;
|
|
25
|
+
readonly content: Ref<CONTENT>;
|
|
26
|
+
readonly design: Ref<DESIGN>;
|
|
27
|
+
readonly defaults: Ref<Record<string, unknown>>;
|
|
28
|
+
}
|
|
29
|
+
declare function useVueBaseProps<CONTENT, DESIGN>(): VueBaseProps<CONTENT, DESIGN>;
|
|
30
|
+
|
|
31
|
+
declare function useInputboxElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
32
|
+
hasContent: boolean;
|
|
33
|
+
value: string | undefined;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
declare function useTextareaElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
37
|
+
hasContent: boolean;
|
|
38
|
+
value: string | undefined;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
declare function useButtonElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
42
|
+
title: string | undefined;
|
|
43
|
+
link: string | undefined;
|
|
44
|
+
hasTitle: boolean;
|
|
45
|
+
hasLink: boolean;
|
|
46
|
+
performAction: () => void;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
declare function useImageElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
50
|
+
hasContent: boolean;
|
|
51
|
+
lowResolutionMobileImage: string;
|
|
52
|
+
highResolutionMobileImage: string;
|
|
53
|
+
lowResolutionDesktopImage: string;
|
|
54
|
+
highResolutionDesktopImage: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
declare function useToggleElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
58
|
+
hasContent: boolean;
|
|
59
|
+
value: boolean | undefined;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
declare function useSelectboxElementContent<CONTENT>(elementName: keyof CONTENT): {
|
|
63
|
+
hasContent: boolean;
|
|
64
|
+
value: undefined;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
declare function useTextElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
68
|
+
font: string | undefined;
|
|
69
|
+
size: number | GlobalTextSizeString | undefined;
|
|
70
|
+
bold: boolean | undefined;
|
|
71
|
+
italic: boolean | undefined;
|
|
72
|
+
color: Color | GlobalColorsString | undefined;
|
|
73
|
+
visible: boolean | undefined;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
declare function useButtonElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
77
|
+
appearance: ButtonAppearance | undefined;
|
|
78
|
+
font: string | undefined;
|
|
79
|
+
size: ButtonSize | undefined;
|
|
80
|
+
style: ButtonStyle | undefined;
|
|
81
|
+
color: Color | GlobalColorsString | undefined;
|
|
82
|
+
visible: boolean | undefined;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
declare function useImageElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
86
|
+
overlay: Overlay | undefined;
|
|
87
|
+
visible: boolean | undefined;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
declare function useToggleElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
91
|
+
enabled: boolean | undefined;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
declare function useSelectboxElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
95
|
+
value: string | undefined;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
declare function useBackgroundElementDesign<DESIGN>(elementName: keyof DESIGN): {
|
|
99
|
+
background: Background | undefined;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
interface VueServerAppExtensions {
|
|
103
|
+
init?: (app: App<Element>) => void;
|
|
104
|
+
render?: <C, D>(app: App<Element>, context: AppBaseContext, data: AppBaseData<C, D>) => void;
|
|
105
|
+
}
|
|
106
|
+
interface VueRenderResult {
|
|
107
|
+
readonly html: string;
|
|
108
|
+
readonly state: unknown;
|
|
109
|
+
}
|
|
110
|
+
declare function createVueServerApp<C, D>(appComponent: Component, extensions?: VueServerAppExtensions): {
|
|
111
|
+
init: () => {
|
|
112
|
+
render: (context: AppBaseContext, data: AppBaseData<C, D>) => Promise<VueRenderResult>;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
interface VueClientAppExtensions {
|
|
117
|
+
init?: (app: App<Element>) => void;
|
|
118
|
+
mount?: <C, D, S extends AppBaseState<C, D>>(app: App<Element>, rootContainer: string, state: S) => void;
|
|
119
|
+
update?: <C, D, S extends AppBaseState<C, D>>(app: App<Element>, state: S) => void;
|
|
120
|
+
unmount?: (app: App<Element>) => void;
|
|
121
|
+
}
|
|
122
|
+
declare function createVueClientApp<C, D>(appComponent: Component, extensions?: VueClientAppExtensions): {
|
|
123
|
+
init: () => {
|
|
124
|
+
mount: <S extends AppBaseState<C, D>>(rootContainer: string, state: S) => void;
|
|
125
|
+
update: <S_1 extends AppBaseState<C, D>>(state: S_1) => void;
|
|
126
|
+
unmount: () => void;
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export { createVueClientApp, createVueServerApp, useBackgroundElementDesign, useButtonElementContent, useButtonElementDesign, useImageElementContent, useImageElementDesign, useInputboxElementContent, useSelectboxElementContent, useSelectboxElementDesign, useTextElementDesign, useTextareaElementContent, useToggleElementContent, useToggleElementDesign, useVueBaseProps };
|
package/dist/app.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getCurrentInstance as k,ref as b,computed as o,reactive as d,createSSRApp as E}from"vue";import{renderToString as C}from"vue/server-renderer";const m=new Map;function c(){const n=(r,a,i,u,g)=>{m.set(r._uid,{context:b(a),content:b(i),design:b(u),defaults:b(g)})},t=(r,a,i)=>{const u=m.get(r._uid);u!==void 0&&(u.content.value=a,u.design.value=i)},e=k()?.appContext.app._uid??-1,l=m.get(e);return{init:n,update:t,context:l?.context,content:l?.content,design:l?.design,defaults:l?.defaults}}function x(n){const t=c(),e=o(()=>{const a=t.content.value[n];if(a!==void 0){if(typeof a=="string")return a;throw new Error(`Element ${n} is not inputbox`)}}),l=o(()=>e.value!==void 0),r=o(()=>e.value);return d({hasContent:l,value:r})}function h(n){const t=c(),e=o(()=>{const a=t.content.value[n];if(a!==void 0){if(typeof a=="string")return a;throw new Error(`Element ${n} is not textarea`)}}),l=o(()=>e.value!==void 0),r=o(()=>e.value);return d({hasContent:l,value:r})}function I(n){return"title"in n&&"type"in n}function $(n){const t=c(),e=o(()=>{const u=t.content.value[n];if(u!==void 0){if(I(u))return u;throw new Error(`Element ${n} is not action link`)}}),l=o(()=>e.value?.title),r=o(()=>e.value?.link),a=o(()=>!!l.value),i=o(()=>!!r.value);return d({title:l,link:r,hasTitle:a,hasLink:i,performAction:()=>{if(e.value!==void 0)switch(e.value.type){case"HYPER_LINK":e.value.link&&window.open(e.value.link,"_blank");break;case"GO_TO_STORE_LINK":window.open("/products");break;case"MAIL_LINK":e.value.email&&window.open(`mailto:${e.value.email}`,"_self");break;case"TEL_LINK":e.value.phone&&window.open(`tel:${e.value.phone}`,"_self");break;case"SCROLL_TO_TILE":{if(typeof document>"u")return;const u=e.value.tileId;document.getElementById(`tile-${u}`)?.scrollIntoView();break}default:throw new Error("Unknown ButtonType: ")}}})}function _(n){return"bucket"in n&&"borderInfo"in n&&"set"in n}function T(n){const t=c(),e=o(()=>{const s=t.content.value[n];if(s!==void 0){if(_(s))return s;throw new Error(`Element ${n} is not image`)}}),l=o(()=>e.value===void 0?"":t.context.value.imageBuckets?.[e.value?.bucket]),r=o(()=>e.value!==void 0),a=o(()=>`${l.value}/${e.value?.set?.["cropped-webp-100x200"]?.url}`),i=o(()=>`${l.value}/${e.value?.set?.["cropped-webp-1000x2000"]?.url}`),u=o(()=>`${l.value}/${e.value?.set?.["webp-200x200"]?.url}`),g=o(()=>`${l.value}/${e.value?.set?.["webp-2000x2000"]?.url}`);return d({hasContent:r,lowResolutionMobileImage:a,highResolutionMobileImage:i,lowResolutionDesktopImage:u,highResolutionDesktopImage:g})}function z(n){return"enabled"in n}function D(n){const t=c(),e=o(()=>{const a=t.content.value[n];if(a!==void 0){if(z(a))return a;throw new Error(`Element ${n} is not toggle`)}}),l=o(()=>e.value!==void 0),r=o(()=>e.value?.enabled);return d({hasContent:l,value:r})}function L(n){const t=c(),e=o(()=>{const a=t.content.value[n];if(a!==void 0){if(typeof a=="string")return a;throw new Error(`Element ${n} is not selectbox`)}}),l=o(()=>e.value!==void 0),r=o(()=>e.value);return d({hasContent:l,value:r})}function y(n,t){if(t===void 0)return;if(!t.startsWith("global."))return t;const e=t.split(".").at(2);if(e!==void 0)return n.fontFamily[e]}function S(n,t){if(t===void 0)return;if(typeof t!="string"||!t.startsWith("global."))return t;const e=t.split(".").at(2);if(e!==void 0)return n.textSize[e]}function f(n,t){if(t===void 0)return;if(typeof t!="string"||!t.startsWith("global."))return t;const e=t.split(".").at(2);if(e!==void 0)return n.color[e]}function R(n){const t=c(),e=o(()=>{const s=t.design.value[n],v=t.defaults.value[n],p=t.context.value.globalDesign;return{font:s?.font??y(p,v?.font),size:s?.size??S(p,v?.size),bold:s?.bold??v?.bold,italic:s?.italic??v?.italic,color:s?.color??f(p,v?.color),visible:s?.visible??v?.visible??!1}}),l=o(()=>e.value?.font),r=o(()=>e.value?.size),a=o(()=>e.value?.bold),i=o(()=>e.value?.italic),u=o(()=>e.value?.color),g=o(()=>e.value?.visible);return d({font:l,size:r,bold:a,italic:i,color:u,visible:g})}function B(n){const t=c(),e=o(()=>{const s=t.design.value[n],v=t.defaults.value[n],p=t.context.value.globalDesign;return{appearance:s?.appearance??v?.appearance,font:s?.font??y(p,v?.font),size:s?.size??v?.size,style:s?.style??v?.style,color:s?.color??f(p,v?.color),visible:s?.visible??v?.visible??!1}}),l=o(()=>e.value?.appearance),r=o(()=>e.value?.font),a=o(()=>e.value?.size),i=o(()=>e.value?.style),u=o(()=>e.value?.color),g=o(()=>e.value?.visible);return d({appearance:l,font:r,size:a,style:i,color:u,visible:g})}function A(n){const t=c(),e=o(()=>{const a=t.design.value[n],i=t.defaults.value[n],u=t.context.value.globalDesign;return{overlay:{type:a?.overlay?.type??i?.overlay?.type,solid:{color:a?.overlay?.solid?.color??f(u,i?.overlay?.solid?.color)},gradient:{fromColor:a?.overlay?.gradient?.fromColor??f(u,i?.overlay?.gradient?.fromColor),toColor:a?.overlay?.gradient?.toColor??f(u,i?.overlay?.gradient?.toColor)}},visible:a?.visible??i?.visible??!1}}),l=o(()=>e.value?.overlay),r=o(()=>e.value?.visible);return d({overlay:l,visible:r})}function O(n){const t=c(),e=o(()=>{const r=t.design.value[n],a=t.defaults.value[n];return{enabled:r?.enabled??a?.enabled}}),l=o(()=>e.value?.enabled);return d({enabled:l})}function G(n){const t=c(),e=o(()=>{const r=t.design.value[n],a=t.defaults.value[n];return{value:r?.value??a?.value}}),l=o(()=>e.value?.value);return d({value:l})}function K(n){const t=c(),e=o(()=>{const r=t.design.value[n],a=t.defaults.value[n],i=t.context.value.globalDesign;return{background:{type:r?.background?.type??a?.background?.type,solid:{color:r?.background?.solid?.color??f(i,a?.background?.solid?.color)},gradient:{fromColor:r?.background?.gradient?.fromColor??f(i,a?.background?.gradient?.fromColor),toColor:r?.background?.gradient?.toColor??f(i,a?.background?.gradient?.toColor)}}}}),l=o(()=>e.value?.background);return d({background:l})}function w(n){return{app:E(n)}}function M(n,t){return{init:()=>{const{app:e}=w(n);return t?.init?.(e),{render:async(l,r)=>(c().init(e,l,r.content,r.design,r.defaults),t?.render?.(e,l,r),{html:await C(e,{context:l}),state:{context:l,data:r}})}}}}function N(n,t){return{init:()=>{const{app:e}=w(n);return t?.init?.(e),{mount:(l,r)=>{c().init(e,r.context,r.data.content,r.data.design,r.data.defaults),t?.mount?.(e,l,r),e.mount(l)},update:l=>{c().update(e,l.data.content,l.data.design),t?.update?.(e,l)},unmount:()=>{t?.unmount?.(e),e.unmount()}}}}}export{N as createVueClientApp,M as createVueServerApp,K as useBackgroundElementDesign,$ as useButtonElementContent,B as useButtonElementDesign,T as useImageElementContent,A as useImageElementDesign,x as useInputboxElementContent,L as useSelectboxElementContent,G as useSelectboxElementDesign,R as useTextElementDesign,h as useTextareaElementContent,D as useToggleElementContent,O as useToggleElementDesign,c as useVueBaseProps};
|
package/dist/cli.d.mts
ADDED
package/dist/cli.d.ts
ADDED
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import D from"cac";import a from"node:fs";import l from"node:path";import{fileURLToPath as v}from"node:url";import{red as I,yellow as A,green as _}from"kolorist";import{resolve as i,dirname as U,sep as F}from"path";import{glob as d}from"glob";import{build as g,defineConfig as E}from"vite";import{builtinModules as S}from"module";import k from"@vitejs/plugin-vue";import $ from"vite-tsconfig-paths";import B from"vite-plugin-checker";import{viteExternalsPlugin as G}from"vite-plugin-externals";import{writeFileSync as x,createReadStream as h}from"fs";import{readFile as C}from"fs/promises";import z from"axios";import{inc as M}from"semver";import*as c from"process";import P from"tinycolor2";function N(t,e){a.statSync(t).isDirectory()?(a.mkdirSync(e,{recursive:!0}),a.readdirSync(t).forEach(n=>{const o=l.resolve(t,n),r=l.resolve(e,n);N(o,r)})):a.copyFileSync(t,e)}function j(t,e,n,o){const r=l.join(t,o?.[n]??n);N(l.join(e,n),r)}const f={error:t=>console.log(I(t)),warn:t=>console.log(A(t)),info:t=>console.log(_(t))};async function K(t){try{const e=t,n=process.cwd(),o=l.join(n,e),r=["templates"],s={_gitignore:".gitignore"};a.existsSync(o)||a.mkdirSync(o);const p=l.resolve(v(import.meta.url),"../..","template");a.readdirSync(p).filter(w=>w!=="package.json").filter(w=>!r.includes(w)).forEach(async w=>j(o,p,w,s));const u=JSON.parse(a.readFileSync(l.join(p,"package.json"),"utf-8"));u.name=t;const L=l.join(o,"package.json");a.writeFileSync(L,`${JSON.stringify(u,null,2)}
|
|
2
|
+
`),f.info(`App ${t} created`)}catch(e){f.error(`Error while creating app: ${e.message}`)}}async function X(t){try{const e=t,n=process.cwd(),o=l.join(n,"sections",e);a.existsSync(o)||a.mkdirSync(o);const r=l.resolve(v(import.meta.url),"../..","template/sections/block-example");a.readdirSync(r).forEach(async s=>j(o,r,s)),f.info(`Block ${t} created`)}catch(e){f.error(`Error while creating block: ${e.message}`)}}async function J(t){try{const e=process.cwd(),n=l.join(e,"templates"),o={"template.json":`${t}.json`};a.existsSync(n)||a.mkdirSync(n);const r=l.resolve(v(import.meta.url),"../..","template/templates");a.readdirSync(r).forEach(async s=>j(n,r,s,o)),f.info(`Template descriptor file [${t}.json] has been created`)}catch(e){f.error(`Error while creating template descriptors: ${e.message}`)}}function T(){const t=process.env.npm_lifecycle_event;return B({typescript:!0,vueTsc:!1,eslint:{lintCommand:`eslint --max-warnings=0 "./sections/**/*.{js,ts,vue}" --cache --cache-location "./build/eslintcache/${t}.json"`}})}function W(t,e){return{plugins:[k(),$(),T(),G({vue:"EcVue"})],define:{"process.env":{NODE_ENV:"production"}},resolve:{alias:{"@":"/src"}},build:{outDir:`./dist/${t}`,emptyOutDir:!1,rollupOptions:{preserveEntrySignatures:"strict",input:i(process.cwd(),e),output:{validate:!0,entryFileNames:"js/[name].js",chunkFileNames:"js/[name].js",assetFileNames:"assets/[name].[ext]"}}}}}function H(t,e){return{plugins:[k(),$()],define:{"process.env":{NODE_ENV:"production"}},resolve:{alias:{"@":"/src"}},ssr:{noExternal:!0},build:{ssr:!0,outDir:`./dist/${t}`,emptyOutDir:!0,rollupOptions:{external:[...S,...S.map(n=>`node:${n}`)],preserveEntrySignatures:"strict",input:i(process.cwd(),e),output:{validate:!0,entryFileNames:"js/[name].js"}}}}}function O(t,e){return{plugins:[$(),T()],resolve:{alias:{"@":"/src"}},build:{outDir:`./dist/${t}`,emptyOutDir:!1,rollupOptions:{preserveEntrySignatures:"strict",input:i(process.cwd(),e),output:{validate:!0,entryFileNames:"js/settings/[name].mjs"}}}}}async function V(){const t=await d("**/server.{js,ts}",{ignore:["node_modules/**","dist/**"]});return Promise.all(t.map(async e=>{const n=U(e).split(F).pop()??"default",o=await d(`**/${n}/client.{js,ts}`,{ignore:["node_modules/**","dist/**"]}),r=await d(`**/${n}/settings/content.{js,ts}`,{ignore:["node_modules/**","dist/**"]}),s=await d(`**/${n}/settings/design.{js,ts}`,{ignore:["node_modules/**","dist/**"]}),p=await d(`**/${n}/settings/translations.{js,ts}`,{ignore:["node_modules/**","dist/**"]});return{name:n,serverEntrypoint:e,clientEntrypoint:o.at(0),contentSettingsEntrypoint:r.at(0),designSettingsEntrypoint:s.at(0),translationsEntrypoint:p.at(0)}}))}async function Z(){try{const t=await V();for(const e of t){const{name:n,serverEntrypoint:o,clientEntrypoint:r,contentSettingsEntrypoint:s,designSettingsEntrypoint:p,translationsEntrypoint:u}=e;await g({configFile:!1,...E(H(n,o))}),r!==void 0&&await g({configFile:!1,...E(W(n,r))}),s!==void 0&&await g({configFile:!1,...E(O(n,s))}),p!==void 0&&await g({configFile:!1,...E(O(n,p))}),u!==void 0&&await g({configFile:!1,...E(O(n,u))})}f.info("Build successful. For deploy run: npm run deploy")}catch(t){f.error(`Error while building: ${t.message}`)}}function R(t){if(t!==void 0)return t.startsWith("global.")?{type:"GLOBAL_FONT",font:t}:{type:"PRESET_FONT",font:t}}function y(t){if(t===void 0)return;if(t.startsWith("global."))return{type:"GLOBAL_COLOR",raw:t};const e=P(t);return{type:"STRUCTURED_COLOR",raw:t,hex:e.toHex8String(),hsl:e.toHsl(),rgba:e.toRgb(),auto:!1}}function q(t){if(t!==void 0)return typeof t=="string"&&t.startsWith("global.")?{type:"GLOBAL_TEXT_SIZE",size:t}:{type:"NUMERIC_TEXT_SIZE",size:t}}const Q={COLOR:"COLOR",GRADIENT:"GRADIENT"};function Y(t){switch(t){case"COLOR":return"solid";case"GRADIENT":return"gradient";default:throw new Error(`Unknown background type: ${t}. Right options: ${Object.keys(Q)}`)}}function tt(t){const e=t.style,n=t.color,o=Array.isArray(n)?n:[n,n];return t.background={type:Y(e),solid:{color:y(o.at(0))},gradient:{fromColor:y(o.at(0)),toColor:y(o.at(1))}},t.style=void 0,t.color=void 0,t}const et={SOLID:"SOLID",OUTLINE:"OUTLINE",TEXT:"TEXT"};function nt(t){switch(t){case"SOLID":return"solid-button";case"OUTLINE":return"outline-button";case"TEXT":return"text-link";default:throw new Error(`Unknown button appearance: ${t}. Right options: ${Object.keys(et)}`)}}const ot={SMALL:"SMALL",MEDIUM:"MEDIUM",LARGE:"LARGE"};function rt(t){switch(t){case"SMALL":return"small";case"MEDIUM":return"medium";case"LARGE":return"large";default:throw new Error(`Unknown button size: ${t}. Right options: ${Object.keys(ot)}`)}}const st={ROUND_CORNER:"ROUND_CORNER",RECTANGLE:"RECTANGLE",PILL:"PILL"};function it(t){switch(t){case"ROUND_CORNER":return"round-corner";case"RECTANGLE":return"rectangle";case"PILL":return"pill";default:throw new Error(`Unknown button shape: ${t}. Right options: ${Object.keys(st)}`)}}function at(t){const e=t.appearance;e!==void 0&&(t.appearance=nt(e));const n=t.size;n!==void 0&&(t.size=rt(n));const o=t.shape;o!==void 0&&(t.style=it(o),t.shape=void 0);const r=t.font;t.font=R(r);const s=t.color;return t.color=y(s),t}const ct={COLOR:"COLOR",GRADIENT:"GRADIENT",NONE:"NONE"};function pt(t){switch(t){case"COLOR":return"solid";case"GRADIENT":return"gradient";case"NONE":return"none";default:throw new Error(`Unknown image overlay type: ${t}. Right options: ${Object.keys(ct)}`)}}function lt(t){const e=t.overlay,n=t.color,o=Array.isArray(n)?n:[n,n];return t.overlay={type:pt(e),solid:{color:y(o.at(0))},gradient:{fromColor:y(o.at(0)),toColor:y(o.at(1))}},t.color=void 0,t}function ut(t){const e=t.font;t.font=R(e);const n=t.color;t.color=y(n);const o=t.size;return t.size=q(o),t}function dt(t){Object.keys(t).forEach(e=>{const n=t[e],o=n.type;switch(o){case"TEXT":{n.defaults=ut(n.defaults);break}case"BUTTON":{n.defaults=at(n.defaults);break}case"IMAGE":{n.defaults=lt(n.defaults);break}case"BACKGROUND":{n.defaults=tt(n.defaults);break}case"TOGGLE":case"SELECTBOX":break;default:throw new Error(`Unknown design editor type: ${o}`)}})}const ft="https://blockbuster.ecwid.com";async function mt(){const t=await C(i(c.cwd(),"crane.config.json")),e=JSON.parse(t.toString());return{appClientId:e.app_client_id,appSecretKey:btoa(e.app_secret_key)}}async function yt(){const t=await C(i(c.cwd(),"package.json")),e=JSON.parse(t.toString()),n=M(e.version,"patch");return e.version=n,x(i(c.cwd(),"package.json"),`${JSON.stringify(e,null,2)}
|
|
3
|
+
`),e.version}async function wt(t,e){try{const n=(await import(i(c.cwd(),`dist/${t}/js/settings/content.mjs`))).default;return b(n,e),n}catch{throw new Error("Content settings is invalid or undefined")}}async function gt(t,e){try{const n=(await import(i(c.cwd(),`dist/${t}/js/settings/design.mjs`))).default;return dt(n),b(n,e),n}catch(n){throw new Error(`Design settings is invalid or undefined. Error ${n}`)}}async function Et(t){const e=(await import(i(c.cwd(),`dist/${t}/js/settings/translations.mjs`))).default;return vt(e)}function b(t,e){if(t&&typeof t=="object"){const n=t;for(let o in n){const r=n[o];typeof r=="string"&&r.startsWith("$")&&(n[o]=ht(e,r)),typeof r=="object"&&b(r,e)}}}function ht(t,e){if(!e)return;const n=t[e];return n===void 0?{en:e}:n}function vt(t){const e={};for(let n in t){const o=t[n];for(let r in o){const s=e[r],p=o[r];if(s===void 0){const u={};u[n]=p,e[r]=u}else s[n]=p}}return e}async function $t(){const t=await d("*/",{cwd:i(c.cwd(),"dist/")});return Promise.all(t.map(async e=>{const n=await Et(e),o=await wt(e,n),r=await gt(e,n);return{id:e,name:{en:e},contentEditors:o,designEditors:r}}))}async function jt(t,e,n,o){const r=(await d("server.js",{cwd:i(c.cwd(),`dist/${o}/js/`)})).at(0);r!==void 0&&await t.post("/api/v1/app/resource/upload",{file:h(i(c.cwd(),`dist/${o}/js/server.js`))},{params:{appClientId:e.appClientId,type:"server_js",version:n,block:o,fileName:r},headers:{"Content-Type":"multipart/form-data",Authorization:`Bearer ${e.appSecretKey}`}})}async function Ot(t,e,n,o){(await d("*.js",{cwd:i(c.cwd(),`dist/${o}/js/`),ignore:"**/server.js"})).forEach(async r=>{await t.post("/api/v1/app/resource/upload",{file:h(i(c.cwd(),`dist/${o}/js/${r}`))},{params:{appClientId:e.appClientId,type:"client_js",version:n,block:o,fileName:r},headers:{"Content-Type":"multipart/form-data",Authorization:`Bearer ${e.appSecretKey}`}})})}async function bt(t,e,n,o){(await d("*",{cwd:i(c.cwd(),`dist/${o}/assets/`)})).forEach(async r=>{await t.post("/api/v1/app/resource/upload",{file:h(i(c.cwd(),`dist/${o}/assets/${r}`))},{params:{appClientId:e.appClientId,type:"assets",version:n,block:o,fileName:r},headers:{"Content-Type":"multipart/form-data",Authorization:`Bearer ${e.appSecretKey}`}})})}async function St(t,e,n){(await d("package.json")).at(0)!==void 0&&await t.post("/api/v1/app/resource/upload",{file:h(i(c.cwd(),"package.json"))},{params:{appClientId:e.appClientId,type:"dependencies",version:n},headers:{"Content-Type":"multipart/form-data",Authorization:`Bearer ${e.appSecretKey}`}})}async function kt(t,e,n,o){o.forEach(async r=>{await jt(t,e,n,r.id),await Ot(t,e,n,r.id),await bt(t,e,n,r.id),await St(t,e,n)})}async function Ct(t,e,n,o){await t.post("/api/v1/app/manifest",{version:n,name:"Custom Block App",blocks:o},{params:{appClientId:e.appClientId},headers:{Authorization:`Bearer ${e.appSecretKey}`}})}async function Nt(t){try{const e=t??ft,n=z.create({baseURL:e}),o=await mt(),r=await yt(),s=await $t();await Ct(n,o,r,s),await kt(n,o,r,s);const p=s.map(u=>u.id);f.info(`Deploy to ${e} successful
|
|
4
|
+
Current app version: ${r}
|
|
5
|
+
Deployed blocks: ${p.join(", ")}`)}catch(e){f.error(`Error while deploying: ${e.message}`)}}const Tt="0.0.1-beta.22",m=D("crane");function Rt(){m.command("create-app <appName>","Create app with custom blocks").action(K),m.command("create-block <blockName>","Create custom block").action(X),m.command("create-template <templateName>","Create custom template descriptor").action(J),m.command("build","Build app with custom blocks").action(Z),m.command("deploy","Deploy app with custom blocks").option("--url <url>","Custom deploy url").action(t=>Nt(t.url)),m.help(),m.version(Tt),m.parse()}try{Rt()}catch{m.outputHelp(),process.exit(1)}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lightspeed/crane",
|
|
3
|
+
"version": "0.0.1-beta.23",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": "bin/crane.js",
|
|
6
|
+
"main": "./dist/app.mjs",
|
|
7
|
+
"types": "./dist/app.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/app.mjs",
|
|
11
|
+
"types": "./dist/app.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./types": {
|
|
14
|
+
"types": "./types.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"bin",
|
|
20
|
+
"dist",
|
|
21
|
+
"template",
|
|
22
|
+
"types.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"dev": "unbuild --stub",
|
|
26
|
+
"build": "unbuild",
|
|
27
|
+
"lint": "eslint \"./{src,test}/**/*.{js,ts}\""
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/fs-extra": "^11.0.1",
|
|
31
|
+
"@types/node": "^20.4.5",
|
|
32
|
+
"unbuild": "^2.0.0",
|
|
33
|
+
"vite-plugin-dts": "^3.4.0",
|
|
34
|
+
"vite-plugin-static-copy": "^0.17.0"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@lightspeed/eslint-config-crane": "0.0.1-beta.2",
|
|
38
|
+
"@vitejs/plugin-vue": "^4.1.0",
|
|
39
|
+
"axios": "^1.4.0",
|
|
40
|
+
"cac": "^6.7.14",
|
|
41
|
+
"eslint": "~8.15.0",
|
|
42
|
+
"fs-extra": "^11.1.1",
|
|
43
|
+
"glob": "^10.3.3",
|
|
44
|
+
"kolorist": "^1.8.0",
|
|
45
|
+
"prompts": "^2.4.2",
|
|
46
|
+
"semver": "^7.5.4",
|
|
47
|
+
"tinycolor2": "^1.6.0",
|
|
48
|
+
"typescript": "^5.3.0",
|
|
49
|
+
"vite": "^5.1.0",
|
|
50
|
+
"vite-plugin-checker": "^0.6.1",
|
|
51
|
+
"vite-plugin-externals": "^0.6.2",
|
|
52
|
+
"vite-tsconfig-paths": "^4.2.0",
|
|
53
|
+
"vue": "^3.4.0",
|
|
54
|
+
"vue-tsc": "^1.8.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"vue": "^3.4.0"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
crane.config.json
|
|
15
|
+
|
|
16
|
+
# Editor directories and files
|
|
17
|
+
.vscode/*
|
|
18
|
+
!.vscode/extensions.json
|
|
19
|
+
.idea
|
|
20
|
+
.DS_Store
|
|
21
|
+
*.suo
|
|
22
|
+
*.ntvs*
|
|
23
|
+
*.njsproj
|
|
24
|
+
*.sln
|
|
25
|
+
*.sw?
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="@lightspeed/crane/types" />
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__placeholder__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "crane build",
|
|
7
|
+
"deploy": "crane build && crane deploy"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@lightspeed/crane": "0.0.1-beta.23",
|
|
11
|
+
"@lightspeed/eslint-config-crane": "0.0.1-beta.2",
|
|
12
|
+
"vue": "^3.4.0"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
useInputboxElementContent,
|
|
4
|
+
useTextareaElementContent,
|
|
5
|
+
useButtonElementContent,
|
|
6
|
+
useImageElementContent,
|
|
7
|
+
useToggleElementContent,
|
|
8
|
+
useSelectboxElementContent,
|
|
9
|
+
} from '@lightspeed/crane';
|
|
10
|
+
import { Content } from './type';
|
|
11
|
+
|
|
12
|
+
const inputboxContent = useInputboxElementContent<Content>('inputbox');
|
|
13
|
+
const textareaContent = useTextareaElementContent<Content>('textarea');
|
|
14
|
+
const buttonContent = useButtonElementContent<Content>('button');
|
|
15
|
+
const imageContent = useImageElementContent<Content>('image');
|
|
16
|
+
const toggleContent = useToggleElementContent<Content>('toggle');
|
|
17
|
+
const selectboxContent = useSelectboxElementContent<Content>('selectbox');
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<div>
|
|
22
|
+
<div>
|
|
23
|
+
<h1 v-if="inputboxContent.hasContent">
|
|
24
|
+
{{ inputboxContent.value }}
|
|
25
|
+
</h1>
|
|
26
|
+
</div>
|
|
27
|
+
<div>
|
|
28
|
+
<h1 v-if="textareaContent.hasContent">
|
|
29
|
+
{{ textareaContent.value }}
|
|
30
|
+
</h1>
|
|
31
|
+
</div>
|
|
32
|
+
<div>
|
|
33
|
+
<button
|
|
34
|
+
v-if="buttonContent.hasTitle"
|
|
35
|
+
@click="buttonContent.performAction"
|
|
36
|
+
>
|
|
37
|
+
{{ buttonContent.title }}
|
|
38
|
+
</button>
|
|
39
|
+
</div>
|
|
40
|
+
<div>
|
|
41
|
+
<img
|
|
42
|
+
v-if="imageContent.hasContent"
|
|
43
|
+
:src="imageContent.highResolutionDesktopImage"
|
|
44
|
+
>
|
|
45
|
+
</div>
|
|
46
|
+
<div>
|
|
47
|
+
<input
|
|
48
|
+
type="checkbox"
|
|
49
|
+
disabled="true"
|
|
50
|
+
:checked="toggleContent.value"
|
|
51
|
+
>
|
|
52
|
+
</div>
|
|
53
|
+
<div>
|
|
54
|
+
<h1>{{ selectboxContent.value }}</h1>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
inputbox: {
|
|
3
|
+
type: 'INPUTBOX',
|
|
4
|
+
label: '$label.inputbox.label',
|
|
5
|
+
placeholder: '$label.inputbox.placeholder',
|
|
6
|
+
},
|
|
7
|
+
textarea: {
|
|
8
|
+
type: 'TEXTAREA',
|
|
9
|
+
label: '$label.textarea.label',
|
|
10
|
+
placeholder: '$label.textarea.placeholder',
|
|
11
|
+
},
|
|
12
|
+
button: {
|
|
13
|
+
type: 'BUTTON',
|
|
14
|
+
label: '$label.button.label',
|
|
15
|
+
},
|
|
16
|
+
image: {
|
|
17
|
+
type: 'IMAGE',
|
|
18
|
+
label: '$label.image.label',
|
|
19
|
+
},
|
|
20
|
+
toggle: {
|
|
21
|
+
type: 'TOGGLE',
|
|
22
|
+
label: '$label.toggle.label',
|
|
23
|
+
description: '$label.toggle.description',
|
|
24
|
+
},
|
|
25
|
+
selectbox: {
|
|
26
|
+
type: 'SELECTBOX',
|
|
27
|
+
label: '$label.selectbox.label',
|
|
28
|
+
placeholder: '$label.selectbox.placeholder',
|
|
29
|
+
description: '$label.selectbox.description',
|
|
30
|
+
options: [
|
|
31
|
+
{
|
|
32
|
+
value: 'one',
|
|
33
|
+
label: '$label.selectbox.one.label',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
value: 'two',
|
|
37
|
+
label: '$label.selectbox.two.label',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
} as const;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
inputbox: {
|
|
3
|
+
type: 'TEXT',
|
|
4
|
+
label: '$label.inputbox.label',
|
|
5
|
+
colors: ['#FFFFFF66', '#0000004D', '#00000099', '#64C7FF66', '#F9947266', '#C794CD66', '#FFD17466'],
|
|
6
|
+
sizes: [12, 13, 14, 15, 16, 17, 18, 20],
|
|
7
|
+
defaults: {
|
|
8
|
+
font: 'global.fontFamily.body',
|
|
9
|
+
size: 18,
|
|
10
|
+
bold: true,
|
|
11
|
+
italic: false,
|
|
12
|
+
color: '#333',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
textarea: {
|
|
16
|
+
type: 'TEXT',
|
|
17
|
+
label: '$label.textarea.label',
|
|
18
|
+
colors: ['#FFFFFF66', '#0000004D', '#00000099', '#64C7FF66', '#F9947266', '#C794CD66', '#FFD17466'],
|
|
19
|
+
sizes: [12, 13, 14, 15, 16, 17, 18, 20],
|
|
20
|
+
defaults: {
|
|
21
|
+
font: 'global.fontFamily.body',
|
|
22
|
+
size: 16,
|
|
23
|
+
bold: false,
|
|
24
|
+
italic: true,
|
|
25
|
+
color: '#333',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
button: {
|
|
29
|
+
type: 'BUTTON',
|
|
30
|
+
label: '$label.button.label',
|
|
31
|
+
colors: ['#FFFFFF66', '#0000004D', '#00000099', '#64C7FF66', '#F9947266', '#C794CD66', '#FFD17466'],
|
|
32
|
+
defaults: {
|
|
33
|
+
font: 'global.fontFamily.body',
|
|
34
|
+
size: 'MEDIUM',
|
|
35
|
+
appearance: 'OUTLINE',
|
|
36
|
+
shape: 'PILL',
|
|
37
|
+
color: '#333',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
image: {
|
|
41
|
+
type: 'IMAGE',
|
|
42
|
+
label: '$label.image.label',
|
|
43
|
+
colors: ['#FFFFFF66', '#0000004D', '#00000099', '#64C7FF66', '#F9947266', '#C794CD66', '#FFD17466'],
|
|
44
|
+
defaults: {
|
|
45
|
+
overlay: 'COLOR',
|
|
46
|
+
color: '#333',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
toggle: {
|
|
50
|
+
type: 'TOGGLE',
|
|
51
|
+
label: '$label.toggle.label',
|
|
52
|
+
description: '$label.toggle.description',
|
|
53
|
+
defaults: {
|
|
54
|
+
enabled: true,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
selectbox: {
|
|
58
|
+
type: 'SELECTBOX',
|
|
59
|
+
label: '$label.selectbox.label',
|
|
60
|
+
placeholder: '$label.selectbox.placeholder',
|
|
61
|
+
description: '$label.selectbox.description',
|
|
62
|
+
options: [
|
|
63
|
+
{
|
|
64
|
+
value: 'one',
|
|
65
|
+
label: '$label.selectbox.one.label',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
value: 'two',
|
|
69
|
+
label: '$label.selectbox.two.label',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
defaults: {
|
|
73
|
+
value: 'two',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
background: {
|
|
77
|
+
type: 'BACKGROUND',
|
|
78
|
+
label: '$label.background.label',
|
|
79
|
+
colors: ['#FFFFFF66', '#0000004D', '#00000099', '#64C7FF66', '#F9947266', '#C794CD66', '#FFD17466'],
|
|
80
|
+
defaults: {
|
|
81
|
+
style: 'COLOR',
|
|
82
|
+
color: 'global.color.background',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
} as const;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
en: {
|
|
3
|
+
'$label.inputbox.label': 'Inputbox',
|
|
4
|
+
'$label.inputbox.placeholder': 'Input text',
|
|
5
|
+
'$label.textarea.label': 'Textarea',
|
|
6
|
+
'$label.textarea.placeholder': 'Input text',
|
|
7
|
+
'$label.button.label': 'Button',
|
|
8
|
+
'$label.image.label': 'Image',
|
|
9
|
+
'$label.toggle.label': 'Toggle',
|
|
10
|
+
'$label.toggle.description': 'On/off toggle',
|
|
11
|
+
'$label.selectbox.label': 'Selectbox',
|
|
12
|
+
'$label.selectbox.placeholder': 'Choose',
|
|
13
|
+
'$label.selectbox.description': 'Selectbox description',
|
|
14
|
+
'$label.selectbox.one.label': 'One',
|
|
15
|
+
'$label.selectbox.two.label': 'Two',
|
|
16
|
+
'$label.background.label': 'Background',
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
ru: {
|
|
20
|
+
'$label.inputbox.label': 'Текст',
|
|
21
|
+
'$label.inputbox.placeholder': 'Введите текст',
|
|
22
|
+
'$label.textarea.label': 'Многострочный текст',
|
|
23
|
+
'$label.textarea.placeholder': 'Введите текст',
|
|
24
|
+
'$label.button.label': 'Кнопка',
|
|
25
|
+
'$label.image.label': 'Картинка',
|
|
26
|
+
'$label.toggle.label': 'Тоггл',
|
|
27
|
+
'$label.toggle.description': 'Включить/выключить тоггл',
|
|
28
|
+
'$label.selectbox.label': 'Селектбокс',
|
|
29
|
+
'$label.selectbox.placeholder': 'Выберите',
|
|
30
|
+
'$label.selectbox.description': 'Описание селектбокса',
|
|
31
|
+
'$label.selectbox.one.label': 'Один',
|
|
32
|
+
'$label.selectbox.two.label': 'Два',
|
|
33
|
+
'$label.background.label': 'Фон',
|
|
34
|
+
},
|
|
35
|
+
} as const;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "template.schema.json",
|
|
3
|
+
"metadata": {
|
|
4
|
+
"name": "Example Template :: Standard Preset",
|
|
5
|
+
"description": "Standard Preset for the Example template",
|
|
6
|
+
"url": {
|
|
7
|
+
"demo_website": "https://www.example.com",
|
|
8
|
+
"cover_image": "https://www.example.com/cover.jpg"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"sections": [
|
|
12
|
+
{
|
|
13
|
+
"type": "default",
|
|
14
|
+
"id": "header"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "default",
|
|
18
|
+
"id": "slider_001"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "custom",
|
|
22
|
+
"id": "example-block"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "custom",
|
|
26
|
+
"id": "example-block",
|
|
27
|
+
"content": {
|
|
28
|
+
"inputbox": {
|
|
29
|
+
"type": "INPUTBOX",
|
|
30
|
+
"label": "$label.example.label",
|
|
31
|
+
"placeholder": "$label.example.placeholder"
|
|
32
|
+
},
|
|
33
|
+
"textarea": {
|
|
34
|
+
"type": "TEXTAREA",
|
|
35
|
+
"label": "$label.example.label",
|
|
36
|
+
"placeholder": "$label.example.placeholder"
|
|
37
|
+
},
|
|
38
|
+
"button": {
|
|
39
|
+
"type": "BUTTON",
|
|
40
|
+
"label": "$label.example.label"
|
|
41
|
+
},
|
|
42
|
+
"image": {
|
|
43
|
+
"type": "IMAGE",
|
|
44
|
+
"label": "$label.example.label"
|
|
45
|
+
},
|
|
46
|
+
"toggle": {
|
|
47
|
+
"type": "TOGGLE",
|
|
48
|
+
"label": "$label.example.label",
|
|
49
|
+
"description": "$label.example.description"
|
|
50
|
+
},
|
|
51
|
+
"selectBox": {
|
|
52
|
+
"type": "SELECTBOX",
|
|
53
|
+
"label": "$label.example.label",
|
|
54
|
+
"placeholder": "$label.example.placeholder",
|
|
55
|
+
"description": "$label.example.description",
|
|
56
|
+
"options": [
|
|
57
|
+
{
|
|
58
|
+
"value": "one",
|
|
59
|
+
"label": "$label.example.one.label"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"value": "two",
|
|
63
|
+
"label": "$label.example.two.label"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"design": {
|
|
69
|
+
"inputbox": {
|
|
70
|
+
"type": "TEXT",
|
|
71
|
+
"label": "$label.example.label",
|
|
72
|
+
"colors": ["#FFFFFF66", "#0000004D", "#00000099", "#64C7FF66", "#F9947266", "#C794CD66", "#FFD17466"],
|
|
73
|
+
"sizes": [12, 13, 14, 15, 16, 17, 18, 20],
|
|
74
|
+
"defaults": {
|
|
75
|
+
"font": "global.fontFamily.body",
|
|
76
|
+
"size": 18,
|
|
77
|
+
"bold": true,
|
|
78
|
+
"italic": false,
|
|
79
|
+
"color": "#333"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"textarea": {
|
|
83
|
+
"type": "TEXT",
|
|
84
|
+
"label": "$label.example.label",
|
|
85
|
+
"colors": ["#FFFFFF66", "#0000004D", "#00000099", "#64C7FF66", "#F9947266", "#C794CD66", "#FFD17466"],
|
|
86
|
+
"sizes": [12, 13, 14, 15, 16, 17, 18, 20],
|
|
87
|
+
"defaults": {
|
|
88
|
+
"font": "global.fontFamily.body",
|
|
89
|
+
"size": 16,
|
|
90
|
+
"bold": false,
|
|
91
|
+
"italic": true,
|
|
92
|
+
"color": "#333"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"button": {
|
|
96
|
+
"type": "BUTTON",
|
|
97
|
+
"label": "$label.example.label",
|
|
98
|
+
"colors": ["#FFFFFF66", "#0000004D", "#00000099", "#64C7FF66", "#F9947266", "#C794CD66", "#FFD17466"],
|
|
99
|
+
"defaults": {
|
|
100
|
+
"font": "global.fontFamily.body",
|
|
101
|
+
"size": "MEDIUM",
|
|
102
|
+
"appearance": "OUTLINE",
|
|
103
|
+
"shape": "PILL",
|
|
104
|
+
"color": "#333"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"image": {
|
|
108
|
+
"type": "IMAGE",
|
|
109
|
+
"label": "$label.example.label",
|
|
110
|
+
"colors": ["#FFFFFF66", "#0000004D", "#00000099", "#64C7FF66", "#F9947266", "#C794CD66", "#FFD17466"],
|
|
111
|
+
"defaults": {
|
|
112
|
+
"overlay": "COLOR",
|
|
113
|
+
"color": "#333"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"toggle": {
|
|
117
|
+
"type": "TOGGLE",
|
|
118
|
+
"label": "$label.example.label",
|
|
119
|
+
"description": "$label.example.description",
|
|
120
|
+
"defaults": {
|
|
121
|
+
"enabled": true
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"selectbox": {
|
|
125
|
+
"type": "SELECTBOX",
|
|
126
|
+
"label": "$label.example.label",
|
|
127
|
+
"placeholder": "$label.example.placeholder",
|
|
128
|
+
"description": "$label.example.description",
|
|
129
|
+
"options": [
|
|
130
|
+
{
|
|
131
|
+
"value": "one",
|
|
132
|
+
"label": "$label.example.one.label"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"value": "two",
|
|
136
|
+
"label": "$label.example.two.label"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"defaults": {
|
|
140
|
+
"value": "two"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"background": {
|
|
144
|
+
"type": "BACKGROUND",
|
|
145
|
+
"label": "$label.example.label",
|
|
146
|
+
"colors": ["#FFFFFF66", "#0000004D", "#00000099", "#64C7FF66", "#F9947266", "#C794CD66", "#FFD17466"],
|
|
147
|
+
"defaults": {
|
|
148
|
+
"style": "COLOR",
|
|
149
|
+
"color": "global.color.background"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"type": "default",
|
|
156
|
+
"id": "footer"
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "esnext",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"allowImportingTsExtensions": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
|
|
16
|
+
"strict": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"noFallthroughCasesInSwitch": true,
|
|
20
|
+
"baseUrl": ".",
|
|
21
|
+
},
|
|
22
|
+
"include": ["**/*.ts", "**/*.d.ts", "**/*.tsx", "**/*.vue"],
|
|
23
|
+
}
|
|
24
|
+
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
declare module '*.vue' {
|
|
4
|
+
import type { DefineComponent } from 'vue';
|
|
5
|
+
|
|
6
|
+
const component: DefineComponent<{}, {}, any>;
|
|
7
|
+
export default component;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type ButtonType =
|
|
11
|
+
'SCROLL_TO_TILE'
|
|
12
|
+
| 'HYPER_LINK'
|
|
13
|
+
| 'MAIL_LINK'
|
|
14
|
+
| 'TEL_LINK'
|
|
15
|
+
| 'GO_TO_STORE_LINK';
|
|
16
|
+
|
|
17
|
+
interface ButtonContentData {
|
|
18
|
+
readonly title: string;
|
|
19
|
+
readonly type: ButtonType;
|
|
20
|
+
readonly link?: string;
|
|
21
|
+
readonly email?: string;
|
|
22
|
+
readonly phone?: string;
|
|
23
|
+
readonly tileId?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ImageInfoData {
|
|
27
|
+
readonly url: string;
|
|
28
|
+
readonly width: number;
|
|
29
|
+
readonly height: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface ImageBorderInfoData {
|
|
33
|
+
readonly homogeneity: boolean;
|
|
34
|
+
readonly color: {
|
|
35
|
+
readonly r: number;
|
|
36
|
+
readonly g: number;
|
|
37
|
+
readonly b: number;
|
|
38
|
+
readonly a: number;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ImageContentData {
|
|
43
|
+
readonly bucket: string;
|
|
44
|
+
readonly borderInfo: ImageBorderInfoData;
|
|
45
|
+
readonly set: Record<string, ImageInfoData>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface ToggleContentData {
|
|
49
|
+
readonly enabled: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type GlobalColorsString =
|
|
53
|
+
'global.color.title' |
|
|
54
|
+
'global.color.body' |
|
|
55
|
+
'global.color.button' |
|
|
56
|
+
'global.color.link' |
|
|
57
|
+
'global.color.background';
|
|
58
|
+
|
|
59
|
+
type GlobalFontsString =
|
|
60
|
+
'global.fontFamily.title' |
|
|
61
|
+
'global.fontFamily.body';
|
|
62
|
+
|
|
63
|
+
type GlobalTextSizeString =
|
|
64
|
+
'global.textSize.title' |
|
|
65
|
+
'global.textSize.subtitle' |
|
|
66
|
+
'global.textSize.body';
|
|
67
|
+
|
|
68
|
+
interface HSLColor {
|
|
69
|
+
h: number;
|
|
70
|
+
s: number;
|
|
71
|
+
l: number;
|
|
72
|
+
a: number;
|
|
73
|
+
}
|
|
74
|
+
interface RGBAColor {
|
|
75
|
+
r: number;
|
|
76
|
+
g: number;
|
|
77
|
+
b: number;
|
|
78
|
+
a: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface Color {
|
|
82
|
+
raw: string;
|
|
83
|
+
hex: string;
|
|
84
|
+
hsl: HSLColor;
|
|
85
|
+
rgba: RGBAColor;
|
|
86
|
+
auto?: boolean;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface SolidColor {
|
|
90
|
+
color: Color | GlobalColorsString | undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface GradientColor {
|
|
94
|
+
fromColor: Color | GlobalColorsString| undefined;
|
|
95
|
+
toColor: Color | GlobalColorsString| undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface TextDesignData {
|
|
99
|
+
font: string | GlobalFontsString | undefined;
|
|
100
|
+
size: number | GlobalTextSizeString | undefined;
|
|
101
|
+
bold: boolean | undefined;
|
|
102
|
+
italic: boolean | undefined;
|
|
103
|
+
color: Color | GlobalColorsString | undefined;
|
|
104
|
+
visible: boolean;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
type ButtonAppearance =
|
|
108
|
+
'solid-button'
|
|
109
|
+
| 'outline-button'
|
|
110
|
+
| 'text-link';
|
|
111
|
+
|
|
112
|
+
type ButtonSize =
|
|
113
|
+
'small'
|
|
114
|
+
| 'medium'
|
|
115
|
+
| 'large';
|
|
116
|
+
|
|
117
|
+
type ButtonStyle =
|
|
118
|
+
'round-corner'
|
|
119
|
+
| 'rectangle'
|
|
120
|
+
| 'pill';
|
|
121
|
+
|
|
122
|
+
interface ButtonDesignData {
|
|
123
|
+
appearance: ButtonAppearance | undefined;
|
|
124
|
+
font: string | GlobalFontsString | undefined;
|
|
125
|
+
size: ButtonSize | undefined;
|
|
126
|
+
style: ButtonStyle | undefined;
|
|
127
|
+
color: Color | GlobalColorsString | undefined;
|
|
128
|
+
visible: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type OverlayType =
|
|
132
|
+
'solid'
|
|
133
|
+
| 'gradient'
|
|
134
|
+
| 'none';
|
|
135
|
+
|
|
136
|
+
interface Overlay {
|
|
137
|
+
type: OverlayType | undefined;
|
|
138
|
+
solid: SolidColor | undefined;
|
|
139
|
+
gradient: GradientColor | undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
interface ImageDesignData {
|
|
143
|
+
overlay: Overlay | undefined;
|
|
144
|
+
visible: boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface SelectboxDesignData {
|
|
148
|
+
value: string | undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
interface ToggleDesignData {
|
|
152
|
+
enabled: boolean | undefined;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
type BackgroundType =
|
|
156
|
+
'solid'
|
|
157
|
+
| 'gradient';
|
|
158
|
+
|
|
159
|
+
interface Background {
|
|
160
|
+
type: BackgroundType | undefined;
|
|
161
|
+
solid: SolidColor | undefined;
|
|
162
|
+
gradient: GradientColor | undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface BackgroundDesignData {
|
|
166
|
+
background: Background | undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
type MapEditorContentTypes = {
|
|
170
|
+
readonly INPUTBOX: string;
|
|
171
|
+
readonly TEXTAREA: string;
|
|
172
|
+
readonly BUTTON: ButtonContentData;
|
|
173
|
+
readonly IMAGE: ImageContentData;
|
|
174
|
+
readonly TOGGLE: ToggleContentData;
|
|
175
|
+
readonly SELECTBOX: string;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
interface InputboxContentEditor {
|
|
179
|
+
readonly type: 'INPUTBOX';
|
|
180
|
+
readonly label: Record<string, string>;
|
|
181
|
+
readonly placeholder: Record<string, string>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface TextareaContentEditor {
|
|
185
|
+
readonly type: 'TEXTAREA';
|
|
186
|
+
readonly label: Record<string, string>;
|
|
187
|
+
readonly placeholder: Record<string, string>;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface ButtonContentEditor {
|
|
191
|
+
readonly type: 'BUTTON';
|
|
192
|
+
readonly label: Record<string, string>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
interface ImageContentEditor {
|
|
196
|
+
readonly type: 'IMAGE';
|
|
197
|
+
readonly label: Record<string, string>;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
interface ToggleContentEditor {
|
|
201
|
+
readonly type: 'TOGGLE';
|
|
202
|
+
readonly label: Record<string, string>;
|
|
203
|
+
readonly description?: Record<string, string>;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface SelectboxContentOption {
|
|
207
|
+
readonly value: string;
|
|
208
|
+
readonly label: Record<string, string>;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
interface SelectboxContentEditor {
|
|
212
|
+
readonly type: 'SELECTBOX';
|
|
213
|
+
readonly label: Record<string, string>;
|
|
214
|
+
readonly placeholder: Record<string, string>;
|
|
215
|
+
readonly description?: Record<string, string>;
|
|
216
|
+
readonly options: ReadonlyArray<SelectboxOption>;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
type ContentEditor =
|
|
220
|
+
TextContentEditor
|
|
221
|
+
| MultilineTextContentEditor
|
|
222
|
+
| ButtonContentEditor
|
|
223
|
+
| ImageContentEditor
|
|
224
|
+
| ToggleContentEditor
|
|
225
|
+
| SelectboxContentEditor;
|
|
226
|
+
|
|
227
|
+
type InferContentType<T extends Record<string, ContentEditor>> = {
|
|
228
|
+
readonly [P in keyof T]: MapEditorContentTypes[T[P]['type']]
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
type MapEditorDesignTypes = {
|
|
232
|
+
readonly TEXT: string;
|
|
233
|
+
readonly BUTTON: string;
|
|
234
|
+
readonly IMAGE: string;
|
|
235
|
+
readonly TOGGLE: string;
|
|
236
|
+
readonly SELECTBOX: string;
|
|
237
|
+
readonly BACKGROUND: string;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
interface TextDesignEditor {
|
|
241
|
+
readonly type: 'TEXT';
|
|
242
|
+
readonly label: string | Record<string, string>;
|
|
243
|
+
defaults: Record<string, unknown>;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface ButtonDesignEditor {
|
|
247
|
+
readonly type: 'BUTTON';
|
|
248
|
+
readonly label: string | Record<string, string>;
|
|
249
|
+
defaults: Record<string, unknown>;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface ImageDesignEditor {
|
|
253
|
+
readonly type: 'IMAGE';
|
|
254
|
+
readonly label: string | Record<string, string>;
|
|
255
|
+
defaults: Record<string, unknown>;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
interface ToggleDesignEditor {
|
|
259
|
+
readonly type: 'TOGGLE';
|
|
260
|
+
readonly label: string | Record<string, string>;
|
|
261
|
+
defaults: Record<string, unknown>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
interface SelectboxDesignEditor {
|
|
265
|
+
readonly type: 'SELECTBOX';
|
|
266
|
+
readonly label: string | Record<string, string>;
|
|
267
|
+
defaults: Record<string, unknown>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
interface BackgroundDesignEditor {
|
|
271
|
+
readonly type: 'BACKGROUND';
|
|
272
|
+
readonly label: string | Record<string, string>;
|
|
273
|
+
defaults: Record<string, unknown>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
type DesignEditor =
|
|
277
|
+
TextDesignEditor
|
|
278
|
+
| ButtonDesignEditor
|
|
279
|
+
| ImageDesignEditor
|
|
280
|
+
| ToggleDesignEditor
|
|
281
|
+
| SelectboxDesignEditor
|
|
282
|
+
| BackgroundDesignEditor;
|
|
283
|
+
|
|
284
|
+
type InferDesignType<T extends Record<string, DesignEditor>> = {
|
|
285
|
+
readonly [P in keyof T]: MapEditorDesignTypes[T[P]['type']]
|
|
286
|
+
}
|