@developer_tribe/react-builder 1.0.8 → 1.0.9
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/build-components/BIcon/BIconProps.generated.d.ts +3 -0
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +1 -0
- package/dist/build-components/Button/ButtonProps.generated.d.ts +1 -0
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +5 -0
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +1 -0
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +1 -0
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +1 -0
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +1 -0
- package/dist/build-components/Image/ImageProps.generated.d.ts +1 -0
- package/dist/build-components/Main/MainProps.generated.d.ts +1 -1
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +1 -0
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +1 -0
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +1 -0
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +1 -0
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +3 -0
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +1 -0
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +1 -0
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +3 -0
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +3 -0
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +3 -0
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +1 -1
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +3 -1
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +1 -1
- package/dist/build-components/PaywallProvider/PaywallContext.d.ts +12 -0
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +1 -1
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +1 -0
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +1 -1
- package/dist/build-components/Text/TextProps.generated.d.ts +3 -0
- package/dist/build-components/View/ViewProps.generated.d.ts +1 -0
- package/dist/build-components/patterns.generated.d.ts +372 -374
- package/dist/components/BuilderProvider.d.ts +2 -0
- package/dist/components/ParamsProvider.d.ts +5 -0
- package/dist/components/RenderErrorBoundary.d.ts +28 -0
- package/dist/hooks/useSyncHtmlThemeClass.d.ts +7 -0
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +3 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +4 -4
- package/dist/index.native.cjs.js.map +1 -1
- package/dist/index.native.d.ts +1 -0
- package/dist/index.native.esm.js +4 -4
- package/dist/index.native.esm.js.map +1 -1
- package/dist/migrations/migratePipe.d.ts +14 -0
- package/dist/migrations/migrations/1.1.0_normalize_style_attributes.d.ts +2 -0
- package/dist/migrations/semver.d.ts +8 -0
- package/dist/migrations/types.d.ts +8 -0
- package/dist/mockOS/components/SubscriptionModal.d.ts +7 -0
- package/dist/mockOS/context/MockOSContextBase.d.ts +1 -0
- package/dist/mockOS/hooks/useMockIap.d.ts +3 -0
- package/dist/mockOS/index.d.ts +4 -0
- package/dist/mockOS/managers/mockOSIapManager.d.ts +6 -0
- package/dist/mockOS/managers/subscriptionManager.d.ts +10 -0
- package/dist/pages/ProjectDebug.d.ts +14 -0
- package/dist/pages/ProjectMigrationPage.d.ts +23 -0
- package/dist/pages/ProjectValidationPage.d.ts +15 -0
- package/dist/styles.css +1 -1
- package/dist/types/Device.d.ts +5 -0
- package/dist/utils/__special_exceptions.d.ts +7 -0
- package/dist/utils/getImage.d.ts +23 -0
- package/dist/utils/pasteNode.d.ts +15 -0
- package/dist/utils/patterns.d.ts +1 -2
- package/package.json +6 -2
- package/scripts/migrate-patterns-to-v2.mjs +131 -0
- package/scripts/migrate-samples-to-current.ts +79 -0
- package/scripts/prebuild/utils/createGeneratedProps.js +4 -5
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +32 -21
- package/scripts/prebuild/utils/validatePatternJson.js +12 -10
- package/src/.DS_Store +0 -0
- package/src/AttributesEditor.tsx +41 -11
- package/src/RenderPage.tsx +55 -0
- package/src/assets/.DS_Store +0 -0
- package/src/assets/devices.json +91 -0
- package/src/assets/samples/carousel-sample.json +141 -29
- package/src/assets/samples/getSamples.ts +9 -0
- package/src/assets/samples/paywall-1.json +119 -71
- package/src/assets/samples/simple-1.json +28 -16
- package/src/assets/samples/simple-2.json +157 -82
- package/src/assets/samples/unmigrated-builder1.json +42 -0
- package/src/assets/samples/unvalidated-builder1.json +49 -0
- package/src/assets/samples/unvalidated-crash1.json +19 -0
- package/src/assets/samples/unvalidated-crashcomponent1.json +16 -0
- package/src/assets/samples/vpn-onboard-1.json +91 -51
- package/src/assets/samples/vpn-onboard-2.json +318 -278
- package/src/assets/samples/vpn-onboard-3.json +286 -252
- package/src/assets/samples/vpn-onboard-4.json +286 -252
- package/src/assets/samples/vpn-onboard-5.json +434 -374
- package/src/assets/samples/vpn-onboard-6.json +290 -250
- package/src/attributes-editor/Field.tsx +1 -1
- package/src/attributes-editor/LayoutPreviewPicker.tsx +5 -2
- package/src/build-components/BIcon/BIconProps.generated.ts +3 -0
- package/src/build-components/BIcon/pattern.json +12 -9
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +3 -1
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +1 -0
- package/src/build-components/BackgroundImage/pattern.json +25 -16
- package/src/build-components/Button/Button.tsx +26 -3
- package/src/build-components/Button/ButtonProps.generated.ts +1 -0
- package/src/build-components/Button/pattern.json +10 -6
- package/src/build-components/Carousel/CarouselProps.generated.ts +5 -0
- package/src/build-components/Carousel/pattern.json +19 -8
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +1 -0
- package/src/build-components/CarouselButtons/pattern.json +11 -5
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +1 -0
- package/src/build-components/CarouselDots/pattern.json +5 -4
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +1 -0
- package/src/build-components/CarouselItem/pattern.json +5 -4
- package/src/build-components/CarouselProvider/CarouselProvider.tsx +44 -2
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +1 -0
- package/src/build-components/Image/Image.tsx +2 -1
- package/src/build-components/Image/ImageProps.generated.ts +1 -0
- package/src/build-components/Image/pattern.json +11 -5
- package/src/build-components/Main/MainProps.generated.ts +1 -1
- package/src/build-components/Main/pattern.json +12 -9
- package/src/build-components/Onboard/OnboardProps.generated.ts +1 -0
- package/src/build-components/Onboard/pattern.json +14 -9
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +1 -0
- package/src/build-components/OnboardButton/pattern.json +5 -4
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +1 -0
- package/src/build-components/OnboardButtons/pattern.json +5 -4
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +1 -0
- package/src/build-components/OnboardDot/pattern.json +5 -4
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +3 -0
- package/src/build-components/OnboardFooter/pattern.json +8 -5
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +1 -0
- package/src/build-components/OnboardImage/pattern.json +7 -4
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +1 -0
- package/src/build-components/OnboardItem/pattern.json +18 -9
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +3 -0
- package/src/build-components/OnboardProvider/pattern.json +21 -6
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +3 -0
- package/src/build-components/OnboardSubtitle/pattern.json +10 -6
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +3 -0
- package/src/build-components/OnboardTitle/pattern.json +11 -7
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +1 -1
- package/src/build-components/PaywallBackground/pattern.json +5 -4
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +6 -1
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +3 -1
- package/src/build-components/PaywallCloseButton/pattern.json +15 -12
- package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +0 -1
- package/src/build-components/PaywallOptions/PaywallOptions.tsx +3 -2
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +1 -1
- package/src/build-components/PaywallOptions/pattern.json +14 -11
- package/src/build-components/PaywallProvider/PaywallContext.ts +25 -0
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +102 -5
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +1 -1
- package/src/build-components/PaywallProvider/pattern.json +11 -8
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +7 -0
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +1 -0
- package/src/build-components/PaywallSubscribeButton/pattern.json +16 -13
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +1 -1
- package/src/build-components/RadioButton/pattern.json +5 -4
- package/src/build-components/Text/Text.tsx +107 -4
- package/src/build-components/Text/TextProps.generated.ts +3 -0
- package/src/build-components/Text/pattern.json +19 -4
- package/src/build-components/View/ViewProps.generated.ts +1 -0
- package/src/build-components/View/pattern.json +28 -13
- package/src/build-components/other.tsx +15 -0
- package/src/build-components/patterns.generated.ts +340 -235
- package/src/build-components/useNode.ts +22 -3
- package/src/components/Builder.tsx +20 -6
- package/src/components/BuilderButton.tsx +75 -38
- package/src/components/BuilderProvider.tsx +22 -2
- package/src/components/DeviceButton.tsx +12 -5
- package/src/components/EditorHeader.tsx +296 -38
- package/src/components/ParamsProvider.tsx +7 -0
- package/src/components/RenderErrorBoundary.tsx +200 -0
- package/src/hooks/useParams.ts +5 -1
- package/src/hooks/useSyncHtmlThemeClass.ts +19 -0
- package/src/index.native.ts +7 -0
- package/src/index.ts +8 -0
- package/src/migrations/migratePipe.ts +59 -0
- package/src/migrations/migrations/1.1.0_normalize_style_attributes.ts +80 -0
- package/src/migrations/semver.ts +24 -0
- package/src/migrations/types.ts +9 -0
- package/src/mockOS/components/PermissionModal.tsx +3 -2
- package/src/mockOS/components/SubscriptionModal.tsx +400 -0
- package/src/mockOS/context/MockOSContext.tsx +61 -10
- package/src/mockOS/context/MockOSContextBase.ts +1 -0
- package/src/mockOS/hooks/useMockIap.ts +11 -0
- package/src/mockOS/index.ts +7 -0
- package/src/mockOS/managers/mockOSIapManager.ts +10 -0
- package/src/mockOS/managers/subscriptionManager.ts +36 -0
- package/src/modals/IconPickerModal.tsx +1 -1
- package/src/pages/ProjectDebug.tsx +331 -0
- package/src/pages/ProjectMigrationPage.tsx +92 -0
- package/src/pages/ProjectPage.tsx +313 -161
- package/src/pages/ProjectValidationPage.tsx +54 -0
- package/src/styles/base/_global.scss +58 -11
- package/src/styles/components/_attributes-editor.scss +1 -1
- package/src/styles/components/_bottom-bar.scss +7 -4
- package/src/styles/components/_editor-shell.scss +126 -4
- package/src/styles/components/_mockos-router.scss +3 -2
- package/src/styles/components/_ui-components.scss +10 -5
- package/src/styles/foundation/_colors.scss +78 -11
- package/src/styles/foundation/_mixins.scss +4 -1
- package/src/styles/foundation/_sizes.scss +4 -2
- package/src/styles/index.scss +1 -0
- package/src/styles/layout/_builder.scss +61 -0
- package/src/styles/layout/_project-validation.scss +214 -0
- package/src/styles/modals/_add-component.scss +4 -2
- package/src/styles/modals/_color-modal.scss +4 -2
- package/src/styles/modals/_modal-shell.scss +3 -1
- package/src/types/Device.ts +5 -0
- package/src/utils/__special_exceptions.ts +88 -0
- package/src/utils/analyseNode.ts +8 -2
- package/src/utils/analyseNodeByPatterns.ts +43 -9
- package/src/utils/extractTextStyle.ts +19 -6
- package/src/utils/extractViewStyle.ts +68 -59
- package/src/utils/getImage.ts +76 -0
- package/src/utils/novaToJson.ts +2 -1
- package/src/utils/pasteNode.ts +172 -0
- package/src/utils/patterns.ts +4 -3
- package/dist/android.svg +0 -43
- package/dist/apple.svg +0 -16
- package/dist/background.jpg +0 -0
|
@@ -15,7 +15,18 @@ export function extractViewStyle<T extends ViewPropsGenerated['attributes']>(
|
|
|
15
15
|
options: ExtractViewStyleOptions = {},
|
|
16
16
|
) {
|
|
17
17
|
const attributes = node.attributes;
|
|
18
|
-
const
|
|
18
|
+
const styleBag = (attributes as any)?.style as
|
|
19
|
+
| Record<string, unknown>
|
|
20
|
+
| undefined;
|
|
21
|
+
const get = <K extends keyof ViewPropsGenerated['attributes']>(
|
|
22
|
+
key: K,
|
|
23
|
+
): ViewPropsGenerated['attributes'][K] | undefined => {
|
|
24
|
+
const direct = (attributes as any)?.[key];
|
|
25
|
+
if (direct !== undefined && direct !== null) return direct;
|
|
26
|
+
return styleBag?.[key as unknown as string] as any;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const scrollable = (get('scrollable') as any) ?? false;
|
|
19
30
|
const style: React.CSSProperties = {
|
|
20
31
|
display: 'flex',
|
|
21
32
|
flexDirection: 'column',
|
|
@@ -29,7 +40,7 @@ export function extractViewStyle<T extends ViewPropsGenerated['attributes']>(
|
|
|
29
40
|
// Important for flex children: allow the element to shrink so overflow scroll can work.
|
|
30
41
|
style.minWidth = 0;
|
|
31
42
|
style.minHeight = 0;
|
|
32
|
-
if (
|
|
43
|
+
if (get('flexDirection') === 'row') {
|
|
33
44
|
style.overflowX = 'auto';
|
|
34
45
|
style.overflowY = 'hidden';
|
|
35
46
|
style.maxWidth = '100%';
|
|
@@ -41,13 +52,15 @@ export function extractViewStyle<T extends ViewPropsGenerated['attributes']>(
|
|
|
41
52
|
style.maxWidth = '100%';
|
|
42
53
|
}
|
|
43
54
|
}
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
const flexDirection = get('flexDirection');
|
|
56
|
+
if (flexDirection) style.flexDirection = flexDirection as any;
|
|
57
|
+
const alignItems = get('alignItems');
|
|
58
|
+
if (alignItems)
|
|
59
|
+
style.alignItems = alignItems as React.CSSProperties['alignItems'];
|
|
60
|
+
const justifyContent = get('justifyContent');
|
|
61
|
+
if (justifyContent)
|
|
49
62
|
style.justifyContent =
|
|
50
|
-
|
|
63
|
+
justifyContent as React.CSSProperties['justifyContent'];
|
|
51
64
|
const setParsedSize = <K extends keyof React.CSSProperties>(
|
|
52
65
|
property: K,
|
|
53
66
|
rawValue: string | number | undefined,
|
|
@@ -57,80 +70,76 @@ export function extractViewStyle<T extends ViewPropsGenerated['attributes']>(
|
|
|
57
70
|
style[property] = parsed as React.CSSProperties[K];
|
|
58
71
|
};
|
|
59
72
|
|
|
60
|
-
setParsedSize('gap',
|
|
61
|
-
setParsedSize('padding',
|
|
62
|
-
setParsedSize('margin',
|
|
73
|
+
setParsedSize('gap', get('gap') as any);
|
|
74
|
+
setParsedSize('padding', get('padding') as any);
|
|
75
|
+
setParsedSize('margin', get('margin') as any);
|
|
63
76
|
|
|
64
|
-
|
|
65
|
-
|
|
77
|
+
const paddingHorizontal = get('paddingHorizontal') as any;
|
|
78
|
+
if (!isEmptySizeValue(paddingHorizontal)) {
|
|
79
|
+
const parsed = parseSize(paddingHorizontal);
|
|
66
80
|
style.paddingLeft = parsed as React.CSSProperties['paddingLeft'];
|
|
67
81
|
style.paddingRight = parsed as React.CSSProperties['paddingRight'];
|
|
68
82
|
}
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
const paddingVertical = get('paddingVertical') as any;
|
|
84
|
+
if (!isEmptySizeValue(paddingVertical)) {
|
|
85
|
+
const parsed = parseSize(paddingVertical);
|
|
71
86
|
style.paddingTop = parsed as React.CSSProperties['paddingTop'];
|
|
72
87
|
style.paddingBottom = parsed as React.CSSProperties['paddingBottom'];
|
|
73
88
|
}
|
|
74
89
|
|
|
75
90
|
// Explicit per-side paddings should override paddingHorizontal/paddingVertical.
|
|
76
|
-
setParsedSize('paddingTop',
|
|
77
|
-
setParsedSize('paddingBottom',
|
|
78
|
-
setParsedSize('paddingLeft',
|
|
79
|
-
setParsedSize('paddingRight',
|
|
91
|
+
setParsedSize('paddingTop', get('paddingTop') as any);
|
|
92
|
+
setParsedSize('paddingBottom', get('paddingBottom') as any);
|
|
93
|
+
setParsedSize('paddingLeft', get('paddingLeft') as any);
|
|
94
|
+
setParsedSize('paddingRight', get('paddingRight') as any);
|
|
80
95
|
|
|
81
|
-
const marginHorizontalRaw =
|
|
82
|
-
|
|
96
|
+
const marginHorizontalRaw =
|
|
97
|
+
((attributes as Record<string, unknown>).marginHorizontal as
|
|
98
|
+
| string
|
|
99
|
+
| number
|
|
100
|
+
| undefined) ?? (styleBag?.marginHorizontal as any);
|
|
83
101
|
if (!isEmptySizeValue(marginHorizontalRaw)) {
|
|
84
102
|
const parsed = parseSize(marginHorizontalRaw);
|
|
85
103
|
style.marginLeft = parsed as React.CSSProperties['marginLeft'];
|
|
86
104
|
style.marginRight = parsed as React.CSSProperties['marginRight'];
|
|
87
105
|
}
|
|
88
106
|
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
const marginVertical = get('marginVertical') as any;
|
|
108
|
+
if (!isEmptySizeValue(marginVertical)) {
|
|
109
|
+
const parsed = parseSize(marginVertical);
|
|
91
110
|
style.marginTop = parsed as React.CSSProperties['marginTop'];
|
|
92
111
|
style.marginBottom = parsed as React.CSSProperties['marginBottom'];
|
|
93
112
|
}
|
|
94
113
|
|
|
95
|
-
setParsedSize('marginTop',
|
|
96
|
-
setParsedSize('marginBottom',
|
|
97
|
-
setParsedSize('marginLeft',
|
|
98
|
-
setParsedSize('marginRight',
|
|
99
|
-
|
|
114
|
+
setParsedSize('marginTop', get('marginTop') as any);
|
|
115
|
+
setParsedSize('marginBottom', get('marginBottom') as any);
|
|
116
|
+
setParsedSize('marginLeft', get('marginLeft') as any);
|
|
117
|
+
setParsedSize('marginRight', get('marginRight') as any);
|
|
118
|
+
const backgroundColor = get('backgroundColor') as any;
|
|
119
|
+
if (backgroundColor) {
|
|
100
120
|
style.backgroundColor =
|
|
101
|
-
parseColor(
|
|
121
|
+
parseColor(backgroundColor, {
|
|
102
122
|
projectColors: options.projectColors,
|
|
103
123
|
appConfig: options.appConfig,
|
|
104
|
-
}) ??
|
|
124
|
+
}) ?? backgroundColor;
|
|
105
125
|
}
|
|
106
|
-
setParsedSize('borderRadius',
|
|
107
|
-
setParsedSize('width',
|
|
108
|
-
setParsedSize(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
112
|
-
setParsedSize(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
setParsedSize(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
);
|
|
125
|
-
if (attributes.flex !== undefined)
|
|
126
|
-
style.flex = attributes.flex as React.CSSProperties['flex'];
|
|
127
|
-
if (attributes.position)
|
|
128
|
-
style.position = attributes.position as React.CSSProperties['position'];
|
|
129
|
-
setParsedSize('top', attributes.top);
|
|
130
|
-
setParsedSize('bottom', attributes.bottom);
|
|
131
|
-
setParsedSize('left', attributes.left);
|
|
132
|
-
setParsedSize('right', attributes.right);
|
|
133
|
-
if (attributes.zIndex !== undefined)
|
|
134
|
-
style.zIndex = attributes.zIndex as React.CSSProperties['zIndex'];
|
|
126
|
+
setParsedSize('borderRadius', get('borderRadius') as any);
|
|
127
|
+
setParsedSize('width', get('width') as any);
|
|
128
|
+
setParsedSize('minWidth', get('minWidth') as any);
|
|
129
|
+
setParsedSize('maxWidth', get('maxWidth') as any);
|
|
130
|
+
setParsedSize('height', get('height') as any);
|
|
131
|
+
setParsedSize('minHeight', get('minHeight') as any);
|
|
132
|
+
setParsedSize('maxHeight', get('maxHeight') as any);
|
|
133
|
+
const flex = get('flex') as any;
|
|
134
|
+
if (flex !== undefined) style.flex = flex as React.CSSProperties['flex'];
|
|
135
|
+
const position = get('position') as any;
|
|
136
|
+
if (position) style.position = position as React.CSSProperties['position'];
|
|
137
|
+
setParsedSize('top', get('top') as any);
|
|
138
|
+
setParsedSize('bottom', get('bottom') as any);
|
|
139
|
+
setParsedSize('left', get('left') as any);
|
|
140
|
+
setParsedSize('right', get('right') as any);
|
|
141
|
+
const zIndex = get('zIndex') as any;
|
|
142
|
+
if (zIndex !== undefined)
|
|
143
|
+
style.zIndex = zIndex as React.CSSProperties['zIndex'];
|
|
135
144
|
return style;
|
|
136
145
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export const TRIBE_ASSETS_BASE_URL =
|
|
2
|
+
'https://tribemarketing.s3.eu-central-1.amazonaws.com/tribehub-assets/';
|
|
3
|
+
|
|
4
|
+
export enum TribeAssetName {
|
|
5
|
+
Android = 'android.svg',
|
|
6
|
+
Apple = 'apple.svg',
|
|
7
|
+
Background = 'background.jpg',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function normalizeAssetName(name: string): string {
|
|
11
|
+
const trimmed = name.trim().replace(/^\/+/, '');
|
|
12
|
+
|
|
13
|
+
// Common typos / aliases
|
|
14
|
+
if (trimmed === 'backgorund.jpg') return 'background.jpg';
|
|
15
|
+
if (trimmed === 'ios.svg') return 'apple.svg';
|
|
16
|
+
|
|
17
|
+
return trimmed;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function encodePath(path: string): string {
|
|
21
|
+
// Encode each segment but keep `/` separators intact.
|
|
22
|
+
return path
|
|
23
|
+
.split('/')
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.map((seg) => encodeURIComponent(seg))
|
|
26
|
+
.join('/');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns a full CDN URL for a given asset name/path.
|
|
31
|
+
*
|
|
32
|
+
* Examples:
|
|
33
|
+
* - getImage(TribeAssetName.Android)
|
|
34
|
+
* - getImage(TribeAssetName.Apple) // also accepts 'ios.svg' via parseTribeAssetName/resolveImageSrc
|
|
35
|
+
* - getImage(TribeAssetName.Background) // also accepts 'backgorund.jpg' via parseTribeAssetName/resolveImageSrc
|
|
36
|
+
*/
|
|
37
|
+
export function getImage(name: TribeAssetName): string {
|
|
38
|
+
const normalized = normalizeAssetName(name);
|
|
39
|
+
const base = TRIBE_ASSETS_BASE_URL.endsWith('/')
|
|
40
|
+
? TRIBE_ASSETS_BASE_URL
|
|
41
|
+
: `${TRIBE_ASSETS_BASE_URL}/`;
|
|
42
|
+
|
|
43
|
+
return `${base}${encodePath(normalized)}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function parseTribeAssetName(name: string): TribeAssetName | null {
|
|
47
|
+
const normalized = normalizeAssetName(name);
|
|
48
|
+
switch (normalized) {
|
|
49
|
+
case TribeAssetName.Android:
|
|
50
|
+
return TribeAssetName.Android;
|
|
51
|
+
case TribeAssetName.Apple:
|
|
52
|
+
return TribeAssetName.Apple;
|
|
53
|
+
case TribeAssetName.Background:
|
|
54
|
+
return TribeAssetName.Background;
|
|
55
|
+
default:
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function isAbsoluteUrl(src: string): boolean {
|
|
61
|
+
// Covers http(s), data, blob, and protocol-relative URLs.
|
|
62
|
+
return /^(https?:)?\/\//.test(src) || /^(data|blob):/.test(src);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Resolves a `src` value into a usable URL:
|
|
67
|
+
* - Absolute URLs are returned unchanged
|
|
68
|
+
* - Known tribe asset names (or aliases) are converted via `getImage`
|
|
69
|
+
* - Unknown relative strings are returned unchanged
|
|
70
|
+
*/
|
|
71
|
+
export function resolveImageSrc(src?: string | null): string | undefined {
|
|
72
|
+
if (!src) return undefined;
|
|
73
|
+
if (isAbsoluteUrl(src)) return src;
|
|
74
|
+
const parsed = parseTribeAssetName(src);
|
|
75
|
+
return parsed ? getImage(parsed) : src;
|
|
76
|
+
}
|
package/src/utils/novaToJson.ts
CHANGED
|
@@ -539,7 +539,8 @@ function mapFooterFromGeneralComponents(generalComponents: any[]): Node | null {
|
|
|
539
539
|
|
|
540
540
|
const attributes: Record<string, unknown> = { gap: 8 };
|
|
541
541
|
if (baseTextKey) attributes.textLocalizationKey = baseTextKey;
|
|
542
|
-
|
|
542
|
+
// OnboardFooter extends Text, so the canonical text color attribute is `color`.
|
|
543
|
+
if (baseTextColor) attributes.color = baseTextColor;
|
|
543
544
|
const first = linkedWords[0];
|
|
544
545
|
const second = linkedWords[1];
|
|
545
546
|
if (first) {
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { Node, NodeData } from '../types/Node';
|
|
2
|
+
import {
|
|
3
|
+
isNodeArray,
|
|
4
|
+
isNodeNullOrUndefined,
|
|
5
|
+
isNodeString,
|
|
6
|
+
} from './analyseNode';
|
|
7
|
+
import { getPatternByType } from './patterns';
|
|
8
|
+
|
|
9
|
+
export type PasteIntoChildrenResult =
|
|
10
|
+
| {
|
|
11
|
+
ok: true;
|
|
12
|
+
nextRoot: Node;
|
|
13
|
+
pastedNode: Node;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
ok: false;
|
|
17
|
+
nextRoot: Node;
|
|
18
|
+
reason: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function isNodeData(node: Node): node is NodeData {
|
|
22
|
+
return (
|
|
23
|
+
node !== null &&
|
|
24
|
+
node !== undefined &&
|
|
25
|
+
typeof node === 'object' &&
|
|
26
|
+
!Array.isArray(node)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function appendChild(children: Node, childToAppend: Node): Node {
|
|
31
|
+
if (Array.isArray(children)) {
|
|
32
|
+
return [...children, childToAppend];
|
|
33
|
+
}
|
|
34
|
+
if (
|
|
35
|
+
children === null ||
|
|
36
|
+
children === undefined ||
|
|
37
|
+
typeof children === 'string'
|
|
38
|
+
) {
|
|
39
|
+
return [childToAppend];
|
|
40
|
+
}
|
|
41
|
+
return [children as Node, childToAppend];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function replaceNode(root: Node, target: Node, next: Node): Node {
|
|
45
|
+
if (root === target) return next;
|
|
46
|
+
if (root === null || root === undefined) return root;
|
|
47
|
+
if (typeof root === 'string') return root;
|
|
48
|
+
if (Array.isArray(root)) {
|
|
49
|
+
let changed = false;
|
|
50
|
+
const arr = root.map((item) => {
|
|
51
|
+
const r = replaceNode(item, target, next);
|
|
52
|
+
if (r !== item) changed = true;
|
|
53
|
+
return r;
|
|
54
|
+
});
|
|
55
|
+
return changed ? arr : root;
|
|
56
|
+
}
|
|
57
|
+
const data = root as NodeData;
|
|
58
|
+
const prev = data.children as Node;
|
|
59
|
+
if (!prev) return root;
|
|
60
|
+
const replaced = Array.isArray(prev)
|
|
61
|
+
? (prev as Node[]).map((c) => replaceNode(c, target, next))
|
|
62
|
+
: replaceNode(prev as Node, target, next);
|
|
63
|
+
if (replaced !== prev) {
|
|
64
|
+
return { ...data, children: replaced } as Node;
|
|
65
|
+
}
|
|
66
|
+
return root;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function canPasteIntoChildren(
|
|
70
|
+
target: Node,
|
|
71
|
+
pastedNode: Node,
|
|
72
|
+
): {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
reason?: string;
|
|
75
|
+
} {
|
|
76
|
+
if (isNodeNullOrUndefined(target)) {
|
|
77
|
+
return { ok: false, reason: 'Select a node to paste into.' };
|
|
78
|
+
}
|
|
79
|
+
if (isNodeString(target)) {
|
|
80
|
+
return { ok: false, reason: 'Select a component node to paste into.' };
|
|
81
|
+
}
|
|
82
|
+
if (!isNodeData(pastedNode)) {
|
|
83
|
+
return { ok: false, reason: 'Only component nodes can be pasted.' };
|
|
84
|
+
}
|
|
85
|
+
const childType = pastedNode.type;
|
|
86
|
+
if (!childType) {
|
|
87
|
+
return { ok: false, reason: 'Pasted node has no type.' };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Collections behave like generic containers.
|
|
91
|
+
if (isNodeArray(target)) return { ok: true };
|
|
92
|
+
|
|
93
|
+
if (!isNodeData(target)) {
|
|
94
|
+
return { ok: false, reason: 'Select a component node to paste into.' };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const parentType = target.type;
|
|
98
|
+
if (!parentType) {
|
|
99
|
+
return { ok: false, reason: 'Target node has no type.' };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Special rule: limit OnboardButtons to OnboardButton only
|
|
103
|
+
if (parentType === 'OnboardButtons' && childType !== 'OnboardButton') {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
reason: 'OnboardButtons can only contain OnboardButton.',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const childrenSchema = getPatternByType(parentType)?.pattern
|
|
111
|
+
?.children as unknown;
|
|
112
|
+
if (!childrenSchema) {
|
|
113
|
+
return { ok: false, reason: `${parentType} does not accept children.` };
|
|
114
|
+
}
|
|
115
|
+
if (childrenSchema === 'never' || childrenSchema === 'string') {
|
|
116
|
+
return { ok: false, reason: `${parentType} does not accept child nodes.` };
|
|
117
|
+
}
|
|
118
|
+
if (
|
|
119
|
+
childrenSchema === 'node' ||
|
|
120
|
+
(Array.isArray(childrenSchema) &&
|
|
121
|
+
(childrenSchema as unknown[]).includes('node'))
|
|
122
|
+
) {
|
|
123
|
+
return { ok: true };
|
|
124
|
+
}
|
|
125
|
+
if (typeof childrenSchema === 'string') {
|
|
126
|
+
return childType === childrenSchema
|
|
127
|
+
? { ok: true }
|
|
128
|
+
: {
|
|
129
|
+
ok: false,
|
|
130
|
+
reason: `${parentType} only accepts ${childrenSchema} children.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return { ok: false, reason: `${parentType} does not accept this child.` };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function pasteIntoChildren(
|
|
137
|
+
root: Node,
|
|
138
|
+
target: Node,
|
|
139
|
+
pastedNode: Node,
|
|
140
|
+
): PasteIntoChildrenResult {
|
|
141
|
+
const can = canPasteIntoChildren(target, pastedNode);
|
|
142
|
+
if (!can.ok) {
|
|
143
|
+
return {
|
|
144
|
+
ok: false,
|
|
145
|
+
nextRoot: root,
|
|
146
|
+
reason: can.reason ?? 'Cannot paste into this node.',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Paste into collection (root arrays / array nodes).
|
|
151
|
+
if (isNodeArray(target)) {
|
|
152
|
+
const nextList = [...(target as Node[]), pastedNode];
|
|
153
|
+
const nextRoot = replaceNode(root, target, nextList);
|
|
154
|
+
return { ok: true, nextRoot, pastedNode };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Paste into component node children.
|
|
158
|
+
if (!isNodeData(target)) {
|
|
159
|
+
return {
|
|
160
|
+
ok: false,
|
|
161
|
+
nextRoot: root,
|
|
162
|
+
reason: 'Select a component node to paste into.',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const nextTarget: NodeData = {
|
|
167
|
+
...(target as NodeData),
|
|
168
|
+
children: appendChild((target as NodeData).children as Node, pastedNode),
|
|
169
|
+
};
|
|
170
|
+
const nextRoot = replaceNode(root, target, nextTarget as Node);
|
|
171
|
+
return { ok: true, nextRoot, pastedNode };
|
|
172
|
+
}
|
package/src/utils/patterns.ts
CHANGED
|
@@ -29,6 +29,9 @@ export type SpecialCategoryMeta = {
|
|
|
29
29
|
type PatternMeta = {
|
|
30
30
|
label?: string;
|
|
31
31
|
description?: string;
|
|
32
|
+
// schemaVersion >= 2 uses `styles` (formerly `attributes`)
|
|
33
|
+
styles?: Record<string, AttributeMeta>;
|
|
34
|
+
// backwards-compat for schemaVersion 1 patterns
|
|
32
35
|
attributes?: Record<string, AttributeMeta>;
|
|
33
36
|
specialCategories?: Record<string, SpecialCategoryMeta>;
|
|
34
37
|
desiredParent?: string[];
|
|
@@ -40,8 +43,6 @@ type PatternMeta = {
|
|
|
40
43
|
|
|
41
44
|
type Pattern = {
|
|
42
45
|
schemaVersion: number;
|
|
43
|
-
allowUnknownAttributes: boolean;
|
|
44
|
-
extends: string;
|
|
45
46
|
pattern: {
|
|
46
47
|
type: string;
|
|
47
48
|
children: unknown;
|
|
@@ -122,7 +123,7 @@ export function getAttributeMeta(
|
|
|
122
123
|
type?: string | null,
|
|
123
124
|
): Record<string, AttributeMeta> | undefined {
|
|
124
125
|
const p = getPatternByType(type);
|
|
125
|
-
return p?.meta?.attributes;
|
|
126
|
+
return p?.meta?.styles ?? p?.meta?.attributes;
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
/** Returns defaults block (if any) for a given component type */
|
package/dist/android.svg
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
4
|
-
viewBox="0 0 502.857 502.857" xml:space="preserve">
|
|
5
|
-
<g>
|
|
6
|
-
<path style="fill:#57C927;" d="M115.428,155.433v217.664c0,17,10.208,30.336,27.704,30.336h22.84c-0.784,0-2.544,5.768-2.544,8.6
|
|
7
|
-
v61.648c0,16.112,15.448,29.176,32,29.176c16.56,0,32-13.064,32-29.176v-61.648c0-2.832-3.088-8.6-3.848-8.6h55.712
|
|
8
|
-
c-0.76,0-3.864,5.768-3.864,8.6v61.648c0,16.112,15.416,29.176,31.968,29.176c16.592,0,32.032-13.064,32.032-29.176v-61.648
|
|
9
|
-
c0-2.832-1.752-8.6-2.536-8.6h22.872c17.496,0,27.664-13.336,27.664-30.336V155.433H113.596H115.428z"/>
|
|
10
|
-
<path style="fill:#57C927;" d="M59.428,158.977c-16.568,0-32,13.072-32,29.176v124.92c0,16.112,15.432,29.176,32,29.176
|
|
11
|
-
c16.56,0,32-13.064,32-29.176V188.161C91.428,172.049,75.988,158.977,59.428,158.977z"/>
|
|
12
|
-
<path style="fill:#57C927;" d="M320.3,42.057l5.584-8.192l5.592-8.096l12.456-18.2c1.56-2.256,0.912-5.264-1.384-6.744
|
|
13
|
-
c-2.272-1.512-5.416-0.88-6.904,1.36l-19.016,27.704l-5.72,8.344c-18.072-6.832-38.208-10.64-59.48-10.64
|
|
14
|
-
c-21.224,0-41.4,3.816-59.472,10.64l-5.688-8.336l-5.624-8.184l-13.36-19.512c-1.544-2.248-4.648-2.84-6.952-1.36
|
|
15
|
-
c-2.28,1.488-2.912,4.496-1.392,6.744l12.448,18.208l5.592,8.104l5.616,8.168c-42.432,19.24-71.144,57.368-71.144,97.368h279.96
|
|
16
|
-
C391.412,99.433,362.708,61.305,320.3,42.057z M191.436,100.593c-8.312,0-15.008-6.536-15.008-14.608s6.696-14.576,15.008-14.576
|
|
17
|
-
c8.288,0,15,6.504,15,14.576S199.732,100.593,191.436,100.593z M311.436,100.593c-8.304,0-15.016-6.536-15.016-14.608
|
|
18
|
-
s6.712-14.576,15.016-14.576c8.288,0,15,6.504,15,14.576S319.724,100.593,311.436,100.593z"/>
|
|
19
|
-
</g>
|
|
20
|
-
<path style="fill:#1CB71C;" d="M60.852,224.193c-12.472,0-25.424-11.768-33.424-30.432v119.32c0,16.112,15.432,29.176,32,29.176
|
|
21
|
-
c16.56,0,32-13.064,32-29.176V199.985C83.428,214.977,71.86,224.193,60.852,224.193z"/>
|
|
22
|
-
<path style="fill:#57C927;" d="M443.428,158.977c-16.568,0-32,13.072-32,29.176v124.92c0,16.112,15.432,29.176,32,29.176
|
|
23
|
-
c16.56,0,32-13.064,32-29.176V188.161C475.428,172.049,459.988,158.977,443.428,158.977z"/>
|
|
24
|
-
<g>
|
|
25
|
-
<path style="fill:#1CB71C;" d="M444.852,224.193c-12.472,0-25.424-11.768-33.424-30.432v119.32c0,16.112,15.432,29.176,32,29.176
|
|
26
|
-
c16.56,0,32-13.064,32-29.176V199.985C467.428,214.977,455.86,224.193,444.852,224.193z"/>
|
|
27
|
-
<path style="fill:#1CB71C;" d="M251.428,179.337c-63.28,0-120-7.32-136-17.712v211.472c0,17,10.208,30.336,27.704,30.336h22.84
|
|
28
|
-
c-0.784,0-2.544,5.768-2.544,8.6v61.648c0,16.112,15.448,29.176,32,29.176c16.56,0,32-13.064,32-29.176v-61.648
|
|
29
|
-
c0-2.832-3.088-8.6-3.848-8.6h55.712c-0.76,0-3.864,5.768-3.864,8.6v61.648c0,16.112,15.416,29.176,31.968,29.176
|
|
30
|
-
c16.592,0,32.032-13.064,32.032-29.176v-61.648c0-2.832-1.752-8.6-2.536-8.6h22.872c17.496,0,27.664-13.336,27.664-30.336v-211.48
|
|
31
|
-
C371.428,172.009,314.716,179.337,251.428,179.337z"/>
|
|
32
|
-
<path style="fill:#1CB71C;" d="M326.436,85.977c0,8.072-6.712,14.608-15,14.608c-8.304,0-15.016-6.536-15.016-14.608
|
|
33
|
-
c0-4.376,2.008-8.24,5.136-10.912c-15.816-2.64-32.64-4.088-50.128-4.088s-34.304,1.448-50.128,4.088
|
|
34
|
-
c3.136,2.664,5.144,6.536,5.144,10.912c0,8.072-6.712,14.608-15,14.608c-8.312,0-15.008-6.536-15.008-14.608
|
|
35
|
-
c0-2.064,0.456-4.024,1.248-5.808c-23.984,6.304-44.592,15.504-60.144,26.808c-3.92,10.296-6.088,24.456-6.088,32.456h279.96
|
|
36
|
-
c0-8-2.168-22.152-6.08-32.44c-15.544-11.32-36.16-20.536-60.128-26.84C325.988,81.937,326.436,83.921,326.436,85.977z"/>
|
|
37
|
-
</g>
|
|
38
|
-
<path style="fill:#049E42;" d="M251.428,262.817c-53.896,0-104-10.632-136-28.056v138.336c0,17,10.208,30.336,27.704,30.336h22.84
|
|
39
|
-
c-0.784,0-2.544,5.768-2.544,8.6v61.648c0,16.112,15.448,29.176,32,29.176c16.56,0,32-13.064,32-29.176v-61.648
|
|
40
|
-
c0-2.832-3.088-8.6-3.848-8.6h55.712c-0.76,0-3.864,5.768-3.864,8.6v61.648c0,16.112,15.416,29.176,31.968,29.176
|
|
41
|
-
c16.592,0,32.032-13.064,32.032-29.176v-61.648c0-2.832-1.752-8.6-2.536-8.6h22.872c17.496,0,27.664-13.336,27.664-30.336V234.761
|
|
42
|
-
C355.428,252.193,305.324,262.817,251.428,262.817z"/>
|
|
43
|
-
</svg>
|
package/dist/apple.svg
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
4
|
-
viewBox="0 0 496.412 496.412" xml:space="preserve">
|
|
5
|
-
<path d="M317.222,80.584C333.414,59.696,345.686,30.152,341.246,0c-26.472,1.84-57.384,18.768-75.432,40.832
|
|
6
|
-
c-16.456,20-29.976,49.728-24.688,78.608C270.054,120.344,299.91,103.008,317.222,80.584z"/>
|
|
7
|
-
<path style="fill:#1B546B;" d="M445.838,166.544c-25.4-31.872-61.12-50.344-94.848-50.344c-44.512,0-63.352,21.312-94.264,21.312
|
|
8
|
-
c-31.896,0-56.12-21.248-94.624-21.248c-37.832,0-78.112,23.12-103.64,62.64C22.574,234.576,28.694,339.2,86.894,428.336
|
|
9
|
-
c20.808,31.904,48.592,67.744,84.952,68.072c32.36,0.32,41.488-20.752,85.336-20.992c43.832-0.256,52.16,21.264,84.456,20.896
|
|
10
|
-
c36.384-0.288,65.712-40.016,86.512-71.92c14.912-22.848,20.48-34.376,32.056-60.184
|
|
11
|
-
C376.014,332.184,362.518,212.488,445.838,166.544z"/>
|
|
12
|
-
<path d="M394.774,228.08c-63.632,51.52-153.592,83.712-253.44,83.712c-35.776,0-70.288-4.144-102.768-11.808
|
|
13
|
-
c5.496,41.808,21.16,86.736,48.336,128.344c20.808,31.904,48.592,67.744,84.952,68.072c32.36,0.32,41.488-20.752,85.336-20.992
|
|
14
|
-
c43.832-0.256,52.16,21.264,84.456,20.896c36.384-0.288,65.712-40.016,86.512-71.92c14.912-22.848,20.48-34.376,32.056-60.184
|
|
15
|
-
C402.966,342.44,378.454,280.176,394.774,228.08z"/>
|
|
16
|
-
</svg>
|
package/dist/background.jpg
DELETED
|
Binary file
|