@developer_tribe/react-builder 1.2.7 → 1.2.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/AttributesEditor.d.ts +2 -11
- package/dist/attribute-analyser/style/native/useExtractImageStyle.d.ts +10 -0
- package/dist/attribute-analyser/style/native/useExtractTextStyle.d.ts +9 -0
- package/dist/attribute-analyser/style/native/useExtractViewStyle.d.ts +8 -0
- package/dist/attribute-analyser/style/web/useExtractImageStyle.d.ts +4 -0
- package/dist/attribute-analyser/style/web/useExtractTextStyle.d.ts +4 -0
- package/dist/attribute-analyser/style/web/useExtractViewStyle.d.ts +4 -0
- package/dist/attributes-editor/AttributesEditorFields.d.ts +18 -0
- package/dist/attributes-editor/AttributesEditorView.d.ts +4 -0
- package/dist/attributes-editor/attributesEditorModelTypes.d.ts +67 -0
- package/dist/attributes-editor/attributesEditorUtils.d.ts +19 -0
- package/dist/attributes-editor/useAttributesEditorModel.d.ts +2 -0
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +41 -38
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +37 -34
- package/dist/build-components/Button/ButtonProps.generated.d.ts +39 -36
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +37 -34
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +37 -34
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +37 -34
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +36 -33
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +36 -33
- package/dist/build-components/Image/ImageProps.generated.d.ts +38 -33
- package/dist/build-components/Main/MainProps.generated.d.ts +36 -33
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +36 -33
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +38 -34
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +39 -36
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +43 -34
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +41 -38
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +36 -31
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +39 -33
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +38 -34
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +41 -38
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +41 -38
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +36 -33
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +41 -38
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +36 -33
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +36 -33
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +39 -36
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +36 -33
- package/dist/build-components/Text/TextProps.generated.d.ts +41 -38
- package/dist/build-components/View/ViewProps.generated.d.ts +36 -33
- package/dist/build-components/patterns.generated.d.ts +2673 -5787
- package/dist/components/BuilderProvider.d.ts +6 -0
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +5 -26
- package/dist/index.esm.js +5 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +6 -4
- package/dist/index.native.cjs.js.map +1 -1
- package/dist/index.native.d.ts +6 -3
- package/dist/index.native.esm.js +6 -4
- package/dist/index.native.esm.js.map +1 -1
- package/dist/migrations/migratePipe.d.ts +1 -1
- package/dist/migrations/migrations/1.1.2_extract_component_attributes_from_style.d.ts +2 -0
- package/dist/mockOS/components/PermissionModal.d.ts +1 -2
- package/dist/styles.css +1 -1
- package/dist/types/PreviewConfig.d.ts +1 -5
- package/dist/utils/extractImageStyle.d.ts +3 -0
- package/dist/utils/extractTextStyle/extractTextStyleNative.d.ts +17 -0
- package/dist/utils/extractTextStyle.d.ts +2 -0
- package/dist/utils/extractViewStyle/extractViewStyleNative.d.ts +12 -0
- package/dist/utils/extractViewStyle.d.ts +2 -0
- package/dist/utils/getMeta.d.ts +5 -0
- package/dist/utils/patterns.d.ts +14 -1
- package/package.json +2 -1
- package/scripts/prebuild/prebuild.js +14 -0
- package/scripts/prebuild/utils/createGeneratedProps.js +51 -3
- package/scripts/prebuild/utils/index.js +1 -0
- package/scripts/prebuild/utils/updateMetaJson.js +66 -0
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +37 -3
- package/scripts/prebuild/utils/validatePatternJson.js +27 -2
- package/scripts/public/scripts/build/index.js +20 -3
- package/scripts/public/scripts/build/info.json +6 -0
- package/scripts/public/scripts/build/utils/createComponentsIndex.js +9 -3
- package/scripts/public/scripts/build/utils/createRenderNodeGenerated.js +66 -8
- package/src/AttributesEditor.tsx +8 -944
- package/src/assets/meta.json +4 -0
- package/src/assets/samples/carousel-sample.json +1 -1
- package/src/assets/samples/getSamples.ts +2 -0
- package/src/assets/samples/paywall-1.json +11 -7
- package/src/assets/samples/simple-1.json +3 -3
- package/src/assets/samples/simple-2.json +3 -3
- package/src/assets/samples/unmigrated-builder-1.1.1.json +87 -0
- package/src/assets/samples/unmigrated-builder1.json +1 -1
- package/src/assets/samples/unvalidated-builder1.json +3 -3
- package/src/assets/samples/unvalidated-crash1.json +1 -1
- package/src/assets/samples/unvalidated-crashcomponent1.json +1 -1
- package/src/assets/samples/vpn-onboard-1.json +1 -1
- package/src/assets/samples/vpn-onboard-2.json +1 -1
- package/src/assets/samples/vpn-onboard-3.json +1 -1
- package/src/assets/samples/vpn-onboard-4.json +1 -1
- package/src/assets/samples/vpn-onboard-5.json +1 -1
- package/src/assets/samples/vpn-onboard-6.json +1 -1
- package/src/attribute-analyser/style/native/useExtractImageStyle.ts +46 -0
- package/src/attribute-analyser/style/native/useExtractTextStyle.ts +50 -0
- package/src/attribute-analyser/style/native/useExtractViewStyle.ts +32 -0
- package/src/attribute-analyser/style/web/useExtractImageStyle.ts +20 -0
- package/src/{hooks → attribute-analyser/style/web}/useExtractTextStyle.ts +7 -6
- package/src/{hooks → attribute-analyser/style/web}/useExtractViewStyle.ts +7 -6
- package/src/attributes-editor/AttributesEditorFields.tsx +248 -0
- package/src/attributes-editor/AttributesEditorView.tsx +360 -0
- package/src/attributes-editor/LayoutPreviewPicker.tsx +4 -3
- package/src/attributes-editor/attributesEditorModelTypes.ts +86 -0
- package/src/attributes-editor/attributesEditorUtils.ts +102 -0
- package/src/attributes-editor/useAttributesEditorModel.ts +477 -0
- package/src/build-components/BIcon/BIcon.tsx +4 -3
- package/src/build-components/BIcon/BIconProps.generated.ts +42 -38
- package/src/build-components/BIcon/pattern.json +5 -6
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +7 -4
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +38 -34
- package/src/build-components/BackgroundImage/pattern.json +9 -17
- package/src/build-components/Button/Button.tsx +7 -6
- package/src/build-components/Button/ButtonProps.generated.ts +40 -36
- package/src/build-components/Button/pattern.json +17 -15
- package/src/build-components/Carousel/Carousel.tsx +1 -1
- package/src/build-components/Carousel/CarouselProps.generated.ts +38 -34
- package/src/build-components/CarouselButtons/CarouselButtons.tsx +4 -6
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +41 -37
- package/src/build-components/CarouselButtons/pattern.json +2 -1
- package/src/build-components/CarouselDots/CarouselDots.tsx +2 -2
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +44 -40
- package/src/build-components/CarouselItem/CarouselItem.tsx +1 -1
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +37 -33
- package/src/build-components/CarouselProvider/CarouselProvider.tsx +1 -1
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +37 -33
- package/src/build-components/Image/Image.tsx +4 -3
- package/src/build-components/Image/ImageProps.generated.ts +39 -33
- package/src/build-components/Image/pattern.json +5 -11
- package/src/build-components/Main/Main.tsx +1 -1
- package/src/build-components/Main/MainProps.generated.ts +37 -33
- package/src/build-components/Main/pattern.json +2 -1
- package/src/build-components/Onboard/OnboardProps.generated.ts +37 -33
- package/src/build-components/OnboardButton/OnboardButton.tsx +8 -6
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +44 -39
- package/src/build-components/OnboardButton/pattern.json +9 -7
- package/src/build-components/OnboardButtons/OnboardButtons.tsx +31 -31
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +43 -39
- package/src/build-components/OnboardButtons/pattern.json +9 -7
- package/src/build-components/OnboardDot/OnboardDot.tsx +7 -5
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +55 -34
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +19 -23
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +42 -38
- package/src/build-components/OnboardFooter/pattern.json +16 -14
- package/src/build-components/OnboardImage/OnboardImage.tsx +8 -7
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +37 -31
- package/src/build-components/OnboardImage/pattern.json +2 -1
- package/src/build-components/OnboardItem/OnboardItem.tsx +1 -1
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +40 -33
- package/src/build-components/OnboardItem/pattern.json +2 -1
- package/src/build-components/OnboardProvider/OnboardProvider.tsx +1 -1
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +39 -34
- package/src/build-components/OnboardProvider/pattern.json +2 -1
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +42 -38
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +42 -38
- package/src/build-components/PaywallBackground/PaywallBackground.tsx +1 -1
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +37 -33
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +6 -5
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +42 -38
- package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +1 -1
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +37 -33
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +1 -1
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +37 -33
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +1 -1
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +40 -36
- package/src/build-components/RadioButton/RadioButton.tsx +5 -4
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +37 -33
- package/src/build-components/RadioButton/pattern.json +9 -7
- package/src/build-components/Text/Text.tsx +6 -8
- package/src/build-components/Text/TextProps.generated.ts +42 -38
- package/src/build-components/Text/pattern.json +15 -11
- package/src/build-components/View/View.tsx +1 -1
- package/src/build-components/View/ViewProps.generated.ts +37 -33
- package/src/build-components/View/pattern.json +71 -66
- package/src/build-components/patterns.generated.ts +3022 -5971
- package/src/components/AttributesEditorPanel.tsx +2 -2
- package/src/components/BuilderProvider.tsx +15 -1
- package/src/index.native.ts +7 -4
- package/src/index.ts +6 -77
- package/src/migrations/migratePipe.ts +7 -3
- package/src/migrations/migrations/1.1.2_extract_component_attributes_from_style.ts +211 -0
- package/src/mockOS/components/MockOSRouter.tsx +3 -1
- package/src/mockOS/components/PermissionModal.tsx +20 -160
- package/src/mockOS/components/SubscriptionModal.tsx +41 -278
- package/src/pages/ProjectPage.tsx +12 -6
- package/src/styles/components/_attributes-editor.scss +122 -0
- package/src/styles/components/_mockos-router.scss +388 -0
- package/src/styles/components/_onboard.scss +23 -0
- package/src/styles/index.scss +1 -0
- package/src/types/PreviewConfig.ts +1 -5
- package/src/utils/analyseNodeByPatterns.ts +39 -4
- package/src/utils/extractImageStyle.ts +34 -5
- package/src/utils/extractTextStyle/extractTextStyle.ts +7 -6
- package/src/utils/extractTextStyle/extractTextStyleNative.ts +106 -0
- package/src/utils/extractTextStyle.ts +2 -0
- package/src/utils/extractViewStyle/extractViewStyle.ts +2 -4
- package/src/utils/extractViewStyle/extractViewStyleNative.ts +111 -0
- package/src/utils/extractViewStyle.ts +2 -0
- package/src/utils/getMeta.ts +15 -0
- package/src/utils/patterns.ts +100 -3
- package/dist/hooks/useExtractImageStyle.d.ts +0 -3
- package/dist/hooks/useExtractTextStyle.d.ts +0 -3
- package/dist/hooks/useExtractViewStyle.d.ts +0 -3
- package/src/hooks/useExtractImageStyle.ts +0 -19
- package/src/migrations/migrations/1.1.0_normalize_style_attributes.ts +0 -80
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export type { ExtractTextStyleOptions } from './extractTextStyle/extractTextStyle';
|
|
2
2
|
export { extractTextStyle } from './extractTextStyle/extractTextStyle';
|
|
3
|
+
export type { ExtractTextStyleNativeOptions } from './extractTextStyle/extractTextStyleNative';
|
|
4
|
+
export { extractTextStyleNative } from './extractTextStyle/extractTextStyleNative';
|
|
@@ -17,12 +17,10 @@ export function extractViewStyle<T extends ViewPropsGenerated['attributes']>(
|
|
|
17
17
|
const styleBag = (attributes as any)?.style as
|
|
18
18
|
| Record<string, unknown>
|
|
19
19
|
| undefined;
|
|
20
|
-
const get =
|
|
21
|
-
key: K,
|
|
22
|
-
): ViewPropsGenerated['attributes'][K] | undefined => {
|
|
20
|
+
const get = (key: string): unknown => {
|
|
23
21
|
const direct = (attributes as any)?.[key];
|
|
24
22
|
if (direct !== undefined && direct !== null) return direct;
|
|
25
|
-
return styleBag?.[key
|
|
23
|
+
return styleBag?.[key];
|
|
26
24
|
};
|
|
27
25
|
|
|
28
26
|
const scrollable = (get('scrollable') as any) ?? false;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ViewPropsGenerated } from '../../build-components/View/ViewProps.generated';
|
|
2
|
+
import type { NodeData } from '../../types/Node';
|
|
3
|
+
import type { ProjectColors } from '../../types/Project';
|
|
4
|
+
import { parseSize } from '../../size-matters';
|
|
5
|
+
import { parseColor } from '../parseColor';
|
|
6
|
+
|
|
7
|
+
export type ExtractViewStyleNativeOptions = {
|
|
8
|
+
projectColors?: ProjectColors;
|
|
9
|
+
theme?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Extracts a React Native-friendly style object from node attributes.
|
|
14
|
+
* Unlike the web/CSS extractor, this avoids DOM-only props like overflowX/overflowY and maxWidth/maxHeight "100%" fallbacks.
|
|
15
|
+
*/
|
|
16
|
+
export function extractViewStyleNative<
|
|
17
|
+
T extends ViewPropsGenerated['attributes'],
|
|
18
|
+
>(node: NodeData<T>, options: ExtractViewStyleNativeOptions = {}) {
|
|
19
|
+
const attributes = node.attributes;
|
|
20
|
+
const styleBag = (attributes as any)?.style as
|
|
21
|
+
| Record<string, unknown>
|
|
22
|
+
| undefined;
|
|
23
|
+
const get = (key: string): unknown => {
|
|
24
|
+
const direct = (attributes as any)?.[key];
|
|
25
|
+
if (direct !== undefined && direct !== null) return direct;
|
|
26
|
+
return styleBag?.[key];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// RN default is already column, but we keep it explicit for predictable output.
|
|
30
|
+
const style: Record<string, unknown> = {
|
|
31
|
+
flexDirection: 'column',
|
|
32
|
+
};
|
|
33
|
+
if (!attributes) return style;
|
|
34
|
+
|
|
35
|
+
const isEmptySizeValue = (value: unknown) =>
|
|
36
|
+
value === undefined ||
|
|
37
|
+
value === null ||
|
|
38
|
+
(typeof value === 'string' && value.trim() === '');
|
|
39
|
+
|
|
40
|
+
// NOTE: "scrollable" is treated as non-style for RN; host apps should use ScrollView/FlatList.
|
|
41
|
+
// We intentionally do not map it to overflowX/Y.
|
|
42
|
+
|
|
43
|
+
const flexDirection = get('flexDirection');
|
|
44
|
+
if (flexDirection) style.flexDirection = flexDirection as any;
|
|
45
|
+
const alignItems = get('alignItems');
|
|
46
|
+
if (alignItems) style.alignItems = alignItems as any;
|
|
47
|
+
const justifyContent = get('justifyContent');
|
|
48
|
+
if (justifyContent) style.justifyContent = justifyContent as any;
|
|
49
|
+
|
|
50
|
+
const setParsedSize = (property: string, rawValue: unknown) => {
|
|
51
|
+
if (isEmptySizeValue(rawValue)) return;
|
|
52
|
+
const parsed = parseSize(rawValue as any);
|
|
53
|
+
// RN generally expects numbers (dp). We allow percentages for width/height-like props.
|
|
54
|
+
if (typeof parsed === 'number' || typeof parsed === 'string') {
|
|
55
|
+
(style as any)[property] = parsed;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// RN supports these "shorthand" props directly.
|
|
60
|
+
setParsedSize('padding', get('padding'));
|
|
61
|
+
setParsedSize('paddingHorizontal', get('paddingHorizontal'));
|
|
62
|
+
setParsedSize('paddingVertical', get('paddingVertical'));
|
|
63
|
+
setParsedSize('paddingTop', get('paddingTop'));
|
|
64
|
+
setParsedSize('paddingBottom', get('paddingBottom'));
|
|
65
|
+
setParsedSize('paddingLeft', get('paddingLeft'));
|
|
66
|
+
setParsedSize('paddingRight', get('paddingRight'));
|
|
67
|
+
|
|
68
|
+
setParsedSize('margin', get('margin'));
|
|
69
|
+
setParsedSize(
|
|
70
|
+
'marginHorizontal',
|
|
71
|
+
(attributes as any)?.marginHorizontal ?? styleBag?.marginHorizontal,
|
|
72
|
+
);
|
|
73
|
+
setParsedSize('marginVertical', get('marginVertical'));
|
|
74
|
+
setParsedSize('marginTop', get('marginTop'));
|
|
75
|
+
setParsedSize('marginBottom', get('marginBottom'));
|
|
76
|
+
setParsedSize('marginLeft', get('marginLeft'));
|
|
77
|
+
setParsedSize('marginRight', get('marginRight'));
|
|
78
|
+
|
|
79
|
+
const backgroundColor = get('backgroundColor') as any;
|
|
80
|
+
if (backgroundColor) {
|
|
81
|
+
(style as any).backgroundColor =
|
|
82
|
+
parseColor(backgroundColor, {
|
|
83
|
+
projectColors: options.projectColors,
|
|
84
|
+
theme: options.theme,
|
|
85
|
+
}) ?? backgroundColor;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
setParsedSize('borderRadius', get('borderRadius'));
|
|
89
|
+
setParsedSize('width', get('width'));
|
|
90
|
+
setParsedSize('minWidth', get('minWidth'));
|
|
91
|
+
setParsedSize('maxWidth', get('maxWidth'));
|
|
92
|
+
setParsedSize('height', get('height'));
|
|
93
|
+
setParsedSize('minHeight', get('minHeight'));
|
|
94
|
+
setParsedSize('maxHeight', get('maxHeight'));
|
|
95
|
+
|
|
96
|
+
const flex = get('flex') as any;
|
|
97
|
+
if (flex !== undefined) (style as any).flex = flex;
|
|
98
|
+
|
|
99
|
+
const position = get('position') as any;
|
|
100
|
+
if (position) (style as any).position = position;
|
|
101
|
+
|
|
102
|
+
setParsedSize('top', get('top'));
|
|
103
|
+
setParsedSize('bottom', get('bottom'));
|
|
104
|
+
setParsedSize('left', get('left'));
|
|
105
|
+
setParsedSize('right', get('right'));
|
|
106
|
+
|
|
107
|
+
const zIndex = get('zIndex') as any;
|
|
108
|
+
if (zIndex !== undefined) (style as any).zIndex = zIndex;
|
|
109
|
+
|
|
110
|
+
return style;
|
|
111
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export type { ExtractViewStyleOptions } from './extractViewStyle/extractViewStyle';
|
|
2
2
|
export { extractViewStyle } from './extractViewStyle/extractViewStyle';
|
|
3
|
+
export type { ExtractViewStyleNativeOptions } from './extractViewStyle/extractViewStyleNative';
|
|
4
|
+
export { extractViewStyleNative } from './extractViewStyle/extractViewStyleNative';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import metaJson from '../assets/meta.json';
|
|
2
|
+
|
|
3
|
+
export type BuilderMeta = {
|
|
4
|
+
supportedProjectVersion: string;
|
|
5
|
+
reactBuilderVersion: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const meta: BuilderMeta = {
|
|
9
|
+
supportedProjectVersion: metaJson.supportedProjectVersion,
|
|
10
|
+
reactBuilderVersion: metaJson.reactBuilderVersion,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function getMeta(): BuilderMeta {
|
|
14
|
+
return { ...meta };
|
|
15
|
+
}
|
package/src/utils/patterns.ts
CHANGED
|
@@ -60,8 +60,92 @@ type Pattern = {
|
|
|
60
60
|
|
|
61
61
|
const patterns: Pattern[] = generatedPatterns as unknown as Pattern[];
|
|
62
62
|
|
|
63
|
+
export type BuilderPlatform = 'web' | 'native';
|
|
64
|
+
|
|
65
|
+
function normalizePlatform(platform?: BuilderPlatform | null): BuilderPlatform {
|
|
66
|
+
return platform === 'native' ? 'native' : 'web';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Keys that conceptually behave like component props (behavior/flags) rather than
|
|
71
|
+
* style properties. These should NOT be normalized into `attributes.style`.
|
|
72
|
+
*/
|
|
73
|
+
export const NON_STYLE_ATTRIBUTE_KEYS = new Set<string>([
|
|
74
|
+
'scrollable',
|
|
75
|
+
'showEllipsis',
|
|
76
|
+
'adjustsFontSizeToFit',
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* schemaVersion=2 stores style-like keys inside `attributes.style`.
|
|
81
|
+
*
|
|
82
|
+
* We treat View+Text schema keys as style-like by default, but explicitly exclude
|
|
83
|
+
* known non-style props (behavior flags).
|
|
84
|
+
*/
|
|
85
|
+
export function getStyleAttributeKeySet(): Set<string> {
|
|
86
|
+
const viewSchema = getAttributeSchema('View') ?? {};
|
|
87
|
+
const textSchema = getAttributeSchema('Text') ?? {};
|
|
88
|
+
const viewStyle =
|
|
89
|
+
typeof (viewSchema as any)?.style === 'object' && (viewSchema as any)?.style
|
|
90
|
+
? Object.keys((viewSchema as any).style)
|
|
91
|
+
: Object.keys(viewSchema);
|
|
92
|
+
const textStyle =
|
|
93
|
+
typeof (textSchema as any)?.style === 'object' && (textSchema as any)?.style
|
|
94
|
+
? Object.keys((textSchema as any).style)
|
|
95
|
+
: Object.keys(textSchema);
|
|
96
|
+
const out = new Set<string>([...viewStyle, ...textStyle]);
|
|
97
|
+
for (const k of NON_STYLE_ATTRIBUTE_KEYS) out.delete(k);
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function adjustMetaForPlatform(
|
|
102
|
+
meta: Record<string, AttributeMeta> | undefined,
|
|
103
|
+
platform?: BuilderPlatform,
|
|
104
|
+
): Record<string, AttributeMeta> | undefined {
|
|
105
|
+
if (!meta) return undefined;
|
|
106
|
+
const p = normalizePlatform(platform);
|
|
107
|
+
|
|
108
|
+
// Values that are not directly style-friendly for the target platform should be shown under "other"
|
|
109
|
+
// (so they remain editable, but are clearly non-style / platform-specific behavior).
|
|
110
|
+
const moveToOtherAlways = new Set<string>(['scrollable']);
|
|
111
|
+
const moveToOtherOnWeb = new Set<string>([
|
|
112
|
+
// RN-only shorthands; on web they are translated to paddingLeft/Right, etc.
|
|
113
|
+
'paddingHorizontal',
|
|
114
|
+
'paddingVertical',
|
|
115
|
+
'marginHorizontal',
|
|
116
|
+
'marginVertical',
|
|
117
|
+
]);
|
|
118
|
+
const moveToOtherOnNative = new Set<string>([
|
|
119
|
+
// CSS-only layout convenience (not widely supported in RN style across versions).
|
|
120
|
+
'gap',
|
|
121
|
+
// Web-only text behaviors (implemented via DOM).
|
|
122
|
+
'showEllipsis',
|
|
123
|
+
'adjustsFontSizeToFit',
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
const shouldMove = (key: string) =>
|
|
127
|
+
moveToOtherAlways.has(key) ||
|
|
128
|
+
(p === 'web' ? moveToOtherOnWeb.has(key) : moveToOtherOnNative.has(key));
|
|
129
|
+
|
|
130
|
+
let changed = false;
|
|
131
|
+
const out: Record<string, AttributeMeta> = {};
|
|
132
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
133
|
+
if (!value || typeof value !== 'object') {
|
|
134
|
+
out[key] = value;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (shouldMove(key)) {
|
|
138
|
+
out[key] = { ...value, category: 'other', specialCategory: null };
|
|
139
|
+
changed = true;
|
|
140
|
+
} else {
|
|
141
|
+
out[key] = value;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return changed ? out : meta;
|
|
145
|
+
}
|
|
146
|
+
|
|
63
147
|
// Build a fast lookup map without normalization for direct access
|
|
64
|
-
const patternIndex: Map<string, Pattern> = new Map(
|
|
148
|
+
const patternIndex: Map<string, Pattern> = new Map<string, Pattern>(
|
|
65
149
|
patterns.map((p) => [p.pattern.type, p]),
|
|
66
150
|
);
|
|
67
151
|
|
|
@@ -79,7 +163,7 @@ function pascalToKebabCase(s: string): string {
|
|
|
79
163
|
.toLowerCase();
|
|
80
164
|
}
|
|
81
165
|
|
|
82
|
-
const typeAliases: Map<string, string> = new Map();
|
|
166
|
+
const typeAliases: Map<string, string> = new Map<string, string>();
|
|
83
167
|
for (const p of patterns) {
|
|
84
168
|
const canonical = p?.pattern?.type;
|
|
85
169
|
if (typeof canonical !== 'string' || !canonical) continue;
|
|
@@ -121,9 +205,22 @@ export function getAttributeSchema(
|
|
|
121
205
|
|
|
122
206
|
export function getAttributeMeta(
|
|
123
207
|
type?: string | null,
|
|
208
|
+
platform?: BuilderPlatform,
|
|
124
209
|
): Record<string, AttributeMeta> | undefined {
|
|
125
210
|
const p = getPatternByType(type);
|
|
126
|
-
|
|
211
|
+
const styles = p?.meta?.styles;
|
|
212
|
+
const attributes = p?.meta?.attributes;
|
|
213
|
+
|
|
214
|
+
// schemaVersion=2 prefers `meta.styles` but some repos split UI meta into:
|
|
215
|
+
// - meta.styles: style-tab fields
|
|
216
|
+
// - meta.attributes: non-style fields (container/other)
|
|
217
|
+
// Merge both to keep the editor + platform adjustments working.
|
|
218
|
+
const merged =
|
|
219
|
+
styles && attributes
|
|
220
|
+
? { ...attributes, ...styles }
|
|
221
|
+
: (styles ?? attributes);
|
|
222
|
+
|
|
223
|
+
return adjustMetaForPlatform(merged, platform);
|
|
127
224
|
}
|
|
128
225
|
|
|
129
226
|
/** Returns defaults block (if any) for a given component type */
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { NodeData } from '../types/Node';
|
|
2
|
-
import type { ImagePropsGenerated } from '../build-components/Image/ImageProps.generated';
|
|
3
|
-
export declare function useExtractImageStyle<T extends ImagePropsGenerated['attributes']>(node: NodeData<T>): import("react").CSSProperties;
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { NodeData } from '../types/Node';
|
|
2
|
-
import type { TextPropsGenerated } from '../build-components/Text/TextProps.generated';
|
|
3
|
-
export declare function useExtractTextStyle<T extends TextPropsGenerated['attributes']>(node: NodeData<T>): import("react").CSSProperties;
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { NodeData } from '../types/Node';
|
|
2
|
-
import type { ViewPropsGenerated } from '../build-components/View/ViewProps.generated';
|
|
3
|
-
export declare function useExtractViewStyle<T extends ViewPropsGenerated['attributes']>(node: NodeData<T>): import("react").CSSProperties;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import type { NodeData } from '../types/Node';
|
|
3
|
-
import type { ImagePropsGenerated } from '../build-components/Image/ImageProps.generated';
|
|
4
|
-
import { useBuilderParams } from '../components/BuilderProvider';
|
|
5
|
-
import { extractImageStyle } from '../utils/extractImageStyle';
|
|
6
|
-
import { defaultAppConfig } from '../types/PreviewConfig';
|
|
7
|
-
|
|
8
|
-
export function useExtractImageStyle<
|
|
9
|
-
T extends ImagePropsGenerated['attributes'],
|
|
10
|
-
>(node: NodeData<T>) {
|
|
11
|
-
const { appConfig, projectColors: builderProjectColors } = useBuilderParams();
|
|
12
|
-
const theme = appConfig?.theme ?? defaultAppConfig.theme;
|
|
13
|
-
const projectColors = builderProjectColors;
|
|
14
|
-
|
|
15
|
-
return useMemo(
|
|
16
|
-
() => extractImageStyle(node, { theme, projectColors }),
|
|
17
|
-
[node, theme, projectColors],
|
|
18
|
-
);
|
|
19
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import type { Project } from '../../types/Project';
|
|
2
|
-
import type { Node, NodeData, NodeDefaultAttribute } from '../../types/Node';
|
|
3
|
-
import {
|
|
4
|
-
isEmptyObject,
|
|
5
|
-
isNodeArray,
|
|
6
|
-
isNodeNullOrUndefined,
|
|
7
|
-
isNodeString,
|
|
8
|
-
} from '../../utils/nodeGuards';
|
|
9
|
-
import { getAttributeSchema } from '../../utils/patterns';
|
|
10
|
-
import type { Migration } from '../types';
|
|
11
|
-
|
|
12
|
-
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
13
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function buildStyleKeySet(): Set<string> {
|
|
17
|
-
const viewSchema = getAttributeSchema('View') ?? {};
|
|
18
|
-
const textSchema = getAttributeSchema('Text') ?? {};
|
|
19
|
-
return new Set([...Object.keys(viewSchema), ...Object.keys(textSchema)]);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function migrateNode(node: Node, styleKeys: Set<string>): Node {
|
|
23
|
-
if (
|
|
24
|
-
isNodeNullOrUndefined(node) ||
|
|
25
|
-
isNodeString(node) ||
|
|
26
|
-
isEmptyObject(node)
|
|
27
|
-
) {
|
|
28
|
-
return node;
|
|
29
|
-
}
|
|
30
|
-
if (isNodeArray(node)) {
|
|
31
|
-
return (node as Node[]).map((n) => migrateNode(n, styleKeys));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const record = node as NodeData<NodeDefaultAttribute>;
|
|
35
|
-
const nextChildren = migrateNode(record.children as Node, styleKeys);
|
|
36
|
-
|
|
37
|
-
if (!isPlainObject(record.attributes)) {
|
|
38
|
-
return { ...record, children: nextChildren };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const nextAttrs: Record<string, unknown> = { ...(record.attributes ?? {}) };
|
|
42
|
-
|
|
43
|
-
const prevStyle = isPlainObject(nextAttrs.style) ? nextAttrs.style : {};
|
|
44
|
-
const nextStyle: Record<string, unknown> = { ...prevStyle };
|
|
45
|
-
|
|
46
|
-
for (const [k, v] of Object.entries(nextAttrs)) {
|
|
47
|
-
if (k === 'style') continue;
|
|
48
|
-
if (!styleKeys.has(k)) continue;
|
|
49
|
-
|
|
50
|
-
// If already set in style, prefer style (drop legacy flat key).
|
|
51
|
-
if (!(k in nextStyle)) nextStyle[k] = v;
|
|
52
|
-
delete nextAttrs[k];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (Object.keys(nextStyle).length > 0) {
|
|
56
|
-
nextAttrs.style = nextStyle;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
...record,
|
|
61
|
-
children: nextChildren,
|
|
62
|
-
attributes: nextAttrs as NodeDefaultAttribute,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const migration_1_1_0_normalize_style_attributes: Migration = {
|
|
67
|
-
id: '1.1.0-normalize-style-attributes',
|
|
68
|
-
title: 'Normalize legacy style attributes into attributes.style',
|
|
69
|
-
fromVersion: '0.0.0',
|
|
70
|
-
toVersion: '1.1.0',
|
|
71
|
-
run: (project: Project): Project => {
|
|
72
|
-
const styleKeys = buildStyleKeySet();
|
|
73
|
-
const nextData = migrateNode(project.data as unknown as Node, styleKeys);
|
|
74
|
-
return {
|
|
75
|
-
...project,
|
|
76
|
-
version: '1.1.0',
|
|
77
|
-
data: nextData as any,
|
|
78
|
-
};
|
|
79
|
-
},
|
|
80
|
-
};
|