@developer_tribe/react-builder 0.1.15 → 0.1.17
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/dist/assets/samples/getSamples.d.ts +2 -0
- package/dist/build-components/OnboardFooter/OnboardFooter.d.ts +1 -1
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +8 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1 -1
- package/package.json +1 -1
- package/src/AttributesEditor.tsx +17 -0
- package/src/RenderPage.tsx +12 -6
- package/src/assets/samples/getSamples.ts +13 -0
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +58 -2
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +8 -0
- package/src/build-components/OnboardFooter/pattern.json +9 -1
- package/src/build-components/OnboardProvider/OnboardProvider.tsx +0 -3
- package/src/index.ts +2 -0
- package/src/styles/index.scss +14 -0
- package/src/utils/novaToJson.ts +41 -10
package/src/AttributesEditor.tsx
CHANGED
|
@@ -56,6 +56,23 @@ function Field({
|
|
|
56
56
|
/>
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
|
+
if (type === 'string[]') {
|
|
60
|
+
const textValue = Array.isArray(value) ? value.join('\n') : '';
|
|
61
|
+
return (
|
|
62
|
+
<textarea
|
|
63
|
+
rows={4}
|
|
64
|
+
value={textValue}
|
|
65
|
+
onChange={(e) => {
|
|
66
|
+
const lines = e.target.value
|
|
67
|
+
.split('\n')
|
|
68
|
+
.map((s) => s.trim())
|
|
69
|
+
.filter((s) => s.length > 0);
|
|
70
|
+
onChange(lines.length > 0 ? lines : undefined);
|
|
71
|
+
}}
|
|
72
|
+
className="input"
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
59
76
|
return (
|
|
60
77
|
<input
|
|
61
78
|
type="text"
|
package/src/RenderPage.tsx
CHANGED
|
@@ -25,17 +25,23 @@ export function RenderPage({
|
|
|
25
25
|
localication,
|
|
26
26
|
defaultLanguage,
|
|
27
27
|
}: RenderPageProps) {
|
|
28
|
+
const screenPreviewHeight = 800;
|
|
29
|
+
// The calculation is correct for maintaining the aspect ratio of the target screen size.
|
|
30
|
+
// It scales the width proportionally to a fixed preview height.
|
|
31
|
+
// width = (previewHeight * targetWidth) / targetHeight
|
|
32
|
+
const height = screenPreviewHeight;
|
|
33
|
+
const width = (height * screenSize.width) / screenSize.height;
|
|
28
34
|
return (
|
|
29
35
|
<div className="stage-wrapper" style={{ overflow: 'auto' }}>
|
|
30
36
|
<div
|
|
31
37
|
className="stage"
|
|
32
38
|
style={{
|
|
33
|
-
width:
|
|
34
|
-
height:
|
|
35
|
-
minWidth:
|
|
36
|
-
maxWidth:
|
|
37
|
-
minHeight:
|
|
38
|
-
maxHeight:
|
|
39
|
+
width: width,
|
|
40
|
+
height: height,
|
|
41
|
+
minWidth: width,
|
|
42
|
+
maxWidth: width,
|
|
43
|
+
minHeight: height,
|
|
44
|
+
maxHeight: height,
|
|
39
45
|
overflow: 'hidden',
|
|
40
46
|
position: 'relative',
|
|
41
47
|
padding: 4,
|
|
@@ -26,3 +26,16 @@ export function getSamples(): Project[] {
|
|
|
26
26
|
...legacySamples,
|
|
27
27
|
];
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
export function getBasicSamples(): Project[] {
|
|
31
|
+
return [simple1 as Project, simple2 as Project, carouselSample as Project];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getOnboardSamples(): Project[] {
|
|
35
|
+
return [
|
|
36
|
+
vpnOnboard1 as Project,
|
|
37
|
+
vpnOnboard2 as Project,
|
|
38
|
+
vpnOnboard3 as Project,
|
|
39
|
+
vpnOnboard4 as Project,
|
|
40
|
+
];
|
|
41
|
+
}
|
|
@@ -1,8 +1,64 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
2
|
import type { OnboardFooterComponentProps } from './OnboardFooterProps.generated';
|
|
3
|
+
import { mainNodeContext } from '../../RenderMainNode';
|
|
3
4
|
|
|
4
5
|
function OnboardFooter({ node }: OnboardFooterComponentProps) {
|
|
5
|
-
|
|
6
|
+
const { localication, defaultLanguage } = useContext(mainNodeContext) ?? {};
|
|
7
|
+
const t = (key?: string) =>
|
|
8
|
+
key ? (localication?.[defaultLanguage ?? 'en']?.[key] ?? key) : '';
|
|
9
|
+
|
|
10
|
+
const text = t(node?.attributes?.textLocalizationKey);
|
|
11
|
+
const style: React.CSSProperties = {
|
|
12
|
+
display: 'flex',
|
|
13
|
+
flexDirection: (node?.attributes?.flexDirection as any) ?? 'column',
|
|
14
|
+
gap: typeof node?.attributes?.gap === 'number' ? node.attributes.gap : 0,
|
|
15
|
+
padding:
|
|
16
|
+
typeof node?.attributes?.padding === 'number'
|
|
17
|
+
? node.attributes.padding
|
|
18
|
+
: undefined,
|
|
19
|
+
margin:
|
|
20
|
+
typeof node?.attributes?.margin === 'number'
|
|
21
|
+
? node.attributes.margin
|
|
22
|
+
: undefined,
|
|
23
|
+
backgroundColor: node?.attributes?.backgroundColor,
|
|
24
|
+
borderRadius:
|
|
25
|
+
typeof node?.attributes?.borderRadius === 'number'
|
|
26
|
+
? node.attributes.borderRadius
|
|
27
|
+
: undefined,
|
|
28
|
+
width:
|
|
29
|
+
typeof node?.attributes?.width === 'number'
|
|
30
|
+
? node.attributes.width
|
|
31
|
+
: undefined,
|
|
32
|
+
height:
|
|
33
|
+
typeof node?.attributes?.height === 'number'
|
|
34
|
+
? node.attributes.height
|
|
35
|
+
: undefined,
|
|
36
|
+
alignItems: node?.attributes?.alignItems as any,
|
|
37
|
+
justifyContent: node?.attributes?.justifyContent as any,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const linkStyle = (color?: string): React.CSSProperties => ({
|
|
41
|
+
color,
|
|
42
|
+
cursor: color ? 'pointer' : undefined,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div className="primitive primitive-footer" style={style}>
|
|
47
|
+
{!!text && <p style={{ color: node?.attributes?.textColor }}>{text}</p>}
|
|
48
|
+
<div style={{ display: 'flex', gap: 8 }}>
|
|
49
|
+
{node?.attributes?.linkedWordFirstLocalizationKey && (
|
|
50
|
+
<span style={linkStyle(node?.attributes?.linkedWordFirstColor)}>
|
|
51
|
+
{t(node?.attributes?.linkedWordFirstLocalizationKey)}
|
|
52
|
+
</span>
|
|
53
|
+
)}
|
|
54
|
+
{node?.attributes?.linkedWordSecondLocalizationKey && (
|
|
55
|
+
<span style={linkStyle(node?.attributes?.linkedWordSecondColor)}>
|
|
56
|
+
{t(node?.attributes?.linkedWordSecondLocalizationKey)}
|
|
57
|
+
</span>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
6
62
|
}
|
|
7
63
|
|
|
8
64
|
export default React.memo(OnboardFooter);
|
|
@@ -22,6 +22,14 @@ export interface OnboardFooterPropsGenerated {
|
|
|
22
22
|
borderRadius?: number;
|
|
23
23
|
width?: number;
|
|
24
24
|
height?: number;
|
|
25
|
+
textLocalizationKey?: string;
|
|
26
|
+
textColor?: string;
|
|
27
|
+
linkedWordFirstLocalizationKey?: string;
|
|
28
|
+
linkedWordFirstColor?: string;
|
|
29
|
+
linkedWordFirstPage?: string;
|
|
30
|
+
linkedWordSecondLocalizationKey?: string;
|
|
31
|
+
linkedWordSecondColor?: string;
|
|
32
|
+
linkedWordSecondPage?: string;
|
|
25
33
|
};
|
|
26
34
|
}
|
|
27
35
|
|
|
@@ -22,7 +22,15 @@
|
|
|
22
22
|
"backgroundColor": "string",
|
|
23
23
|
"borderRadius": "number",
|
|
24
24
|
"width": "number",
|
|
25
|
-
"height": "number"
|
|
25
|
+
"height": "number",
|
|
26
|
+
"textLocalizationKey": "string",
|
|
27
|
+
"textColor": "string",
|
|
28
|
+
"linkedWordFirstLocalizationKey": "string",
|
|
29
|
+
"linkedWordFirstColor": "string",
|
|
30
|
+
"linkedWordFirstPage": "string",
|
|
31
|
+
"linkedWordSecondLocalizationKey": "string",
|
|
32
|
+
"linkedWordSecondColor": "string",
|
|
33
|
+
"linkedWordSecondPage": "string"
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
}
|
|
@@ -13,9 +13,6 @@ function OnboardProvider({ node }: OnboardProviderComponentProps) {
|
|
|
13
13
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
14
14
|
|
|
15
15
|
const children = useMemo(() => {
|
|
16
|
-
console.log('node', node);
|
|
17
|
-
console.log('node.children', node.children);
|
|
18
|
-
|
|
19
16
|
const onboardChild: NodeData = (node.children as NodeData[]).filter(
|
|
20
17
|
(c) => c.type === 'Onboard',
|
|
21
18
|
)[0];
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,8 @@ export {
|
|
|
12
12
|
analyseNode,
|
|
13
13
|
} from './utils/analyseNode';
|
|
14
14
|
export { getSamples } from './assets/samples/getSamples';
|
|
15
|
+
export { getBasicSamples } from './assets/samples/getSamples';
|
|
16
|
+
export { getOnboardSamples } from './assets/samples/getSamples';
|
|
15
17
|
export { PreviewConfig } from './types/PreviewConfig';
|
|
16
18
|
export { RenderPage } from './RenderPage';
|
|
17
19
|
export { RenderMainNode } from './RenderMainNode';
|
package/src/styles/index.scss
CHANGED
|
@@ -112,3 +112,17 @@
|
|
|
112
112
|
.embla__dot--selected:after {
|
|
113
113
|
box-shadow: inset 0 0 0 0.2rem var(--text-body);
|
|
114
114
|
}
|
|
115
|
+
.carousel-provider {
|
|
116
|
+
height: 100%;
|
|
117
|
+
}
|
|
118
|
+
.embla {
|
|
119
|
+
height: 100%;
|
|
120
|
+
}
|
|
121
|
+
.embla__viewport {
|
|
122
|
+
height: 100%;
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-direction: column;
|
|
125
|
+
}
|
|
126
|
+
.embla__container {
|
|
127
|
+
flex: 1;
|
|
128
|
+
}
|
package/src/utils/novaToJson.ts
CHANGED
|
@@ -229,25 +229,56 @@ function mapFooterFromGeneralComponents(generalComponents: any[]): Node | null {
|
|
|
229
229
|
const footer = generalComponents.find((gc) => gc?.layout === 'footer-layout');
|
|
230
230
|
if (!footer) return null;
|
|
231
231
|
const texts = (footer?.attributes?.texts || []) as any[];
|
|
232
|
-
const
|
|
232
|
+
const linkedWords: { text_key?: string; color?: string; page?: string }[] =
|
|
233
|
+
[];
|
|
234
|
+
let baseTextKey: string | undefined;
|
|
235
|
+
let baseTextColor: string | undefined;
|
|
233
236
|
|
|
234
237
|
for (const t of texts) {
|
|
235
238
|
if (t?.layout === 'Text') {
|
|
236
239
|
const textKey = t?.attributes?.text_localization_key || '';
|
|
237
240
|
const color = t?.attributes?.text_color || undefined;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
if (!baseTextKey) baseTextKey = textKey;
|
|
242
|
+
if (!baseTextColor && typeof color === 'string') baseTextColor = color;
|
|
243
|
+
|
|
244
|
+
// Extract linked words if present
|
|
245
|
+
const lws = (t?.attributes?.linkedwords || []) as any[];
|
|
246
|
+
for (const w of lws) {
|
|
247
|
+
if (w?.layout === 'LinkedWords') {
|
|
248
|
+
const text_key = w?.attributes?.linked_word_localization_key as
|
|
249
|
+
| string
|
|
250
|
+
| undefined;
|
|
251
|
+
const lwColor = w?.attributes?.linked_word_color as
|
|
252
|
+
| string
|
|
253
|
+
| undefined;
|
|
254
|
+
const page = w?.attributes?.page as string | undefined;
|
|
255
|
+
linkedWords.push({ text_key, color: lwColor, page });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
243
258
|
}
|
|
244
259
|
}
|
|
245
260
|
|
|
246
|
-
|
|
261
|
+
const attributes: Record<string, unknown> = { gap: 8 };
|
|
262
|
+
if (baseTextKey) attributes.textLocalizationKey = baseTextKey;
|
|
263
|
+
if (baseTextColor) attributes.textColor = baseTextColor;
|
|
264
|
+
const first = linkedWords[0];
|
|
265
|
+
const second = linkedWords[1];
|
|
266
|
+
if (first) {
|
|
267
|
+
if (first.text_key)
|
|
268
|
+
attributes.linkedWordFirstLocalizationKey = first.text_key;
|
|
269
|
+
if (first.color) attributes.linkedWordFirstColor = first.color;
|
|
270
|
+
if (first.page) attributes.linkedWordFirstPage = first.page;
|
|
271
|
+
}
|
|
272
|
+
if (second) {
|
|
273
|
+
if (second.text_key)
|
|
274
|
+
attributes.linkedWordSecondLocalizationKey = second.text_key;
|
|
275
|
+
if (second.color) attributes.linkedWordSecondColor = second.color;
|
|
276
|
+
if (second.page) attributes.linkedWordSecondPage = second.page;
|
|
277
|
+
}
|
|
247
278
|
|
|
248
279
|
return {
|
|
249
|
-
type: '
|
|
250
|
-
attributes
|
|
251
|
-
children,
|
|
280
|
+
type: 'OnboardFooter',
|
|
281
|
+
attributes,
|
|
282
|
+
children: undefined as unknown as Node,
|
|
252
283
|
} as NodeData;
|
|
253
284
|
}
|