@developer_tribe/react-builder 1.2.6 → 1.2.8
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 +47 -44
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +38 -35
- package/dist/build-components/Button/ButtonProps.generated.d.ts +40 -37
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +37 -34
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +39 -36
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +38 -35
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +37 -34
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +37 -34
- package/dist/build-components/Image/ImageProps.generated.d.ts +38 -35
- package/dist/build-components/Main/MainProps.generated.d.ts +38 -35
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +37 -34
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +43 -40
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +44 -41
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +41 -38
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +51 -48
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +40 -37
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +38 -35
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +38 -35
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +44 -41
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +44 -41
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +37 -34
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +47 -44
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +37 -34
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +37 -34
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +40 -37
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +40 -37
- package/dist/build-components/Text/TextProps.generated.d.ts +44 -41
- package/dist/build-components/View/ViewProps.generated.d.ts +37 -34
- package/dist/build-components/patterns.generated.d.ts +21 -21
- package/dist/components/BuilderProvider.d.ts +6 -0
- package/dist/hooks/useExtractImageStyle.d.ts +3 -1
- package/dist/hooks/useExtractTextStyle.d.ts +1 -1
- package/dist/hooks/useExtractViewStyle.d.ts +1 -1
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +3 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +2 -2
- package/dist/index.native.cjs.js.map +1 -1
- package/dist/index.native.d.ts +4 -0
- package/dist/index.native.esm.js +2 -2
- package/dist/index.native.esm.js.map +1 -1
- 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/patterns.d.ts +2 -1
- package/package.json +5 -1
- package/scripts/prebuild/utils/createGeneratedProps.js +45 -3
- package/src/attributes-editor/LayoutPreviewPicker.tsx +4 -3
- package/src/build-components/BIcon/BIcon.tsx +3 -2
- package/src/build-components/BIcon/BIconProps.generated.ts +48 -44
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +5 -3
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +39 -35
- package/src/build-components/BackgroundImage/pattern.json +9 -17
- package/src/build-components/Button/Button.tsx +5 -4
- package/src/build-components/Button/ButtonProps.generated.ts +41 -37
- package/src/build-components/Carousel/CarouselProps.generated.ts +38 -34
- package/src/build-components/CarouselButtons/CarouselButtons.tsx +3 -2
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +40 -36
- package/src/build-components/CarouselDots/CarouselDots.tsx +1 -1
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +39 -35
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +38 -34
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +38 -34
- package/src/build-components/Image/Image.tsx +3 -2
- package/src/build-components/Image/ImageProps.generated.ts +39 -35
- package/src/build-components/Image/pattern.json +9 -16
- package/src/build-components/Main/Main.tsx +1 -1
- package/src/build-components/Main/MainProps.generated.ts +39 -35
- package/src/build-components/Onboard/OnboardProps.generated.ts +38 -34
- package/src/build-components/OnboardButton/OnboardButton.tsx +6 -5
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +44 -40
- package/src/build-components/OnboardButtons/OnboardButtons.tsx +4 -4
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +45 -41
- package/src/build-components/OnboardDot/OnboardDot.tsx +5 -4
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +42 -38
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +16 -21
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +52 -48
- package/src/build-components/OnboardImage/OnboardImage.tsx +7 -6
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +41 -37
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +39 -35
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +39 -35
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +45 -41
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +45 -41
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +38 -34
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +4 -4
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +48 -44
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +38 -34
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +38 -34
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +41 -37
- package/src/build-components/RadioButton/RadioButton.tsx +4 -3
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +41 -37
- package/src/build-components/Text/Text.tsx +3 -5
- package/src/build-components/Text/TextProps.generated.ts +45 -41
- package/src/build-components/View/ViewProps.generated.ts +38 -34
- package/src/build-components/patterns.generated.ts +21 -21
- package/src/components/BuilderProvider.tsx +15 -1
- package/src/hooks/useExtractImageStyle.ts +15 -4
- package/src/hooks/useExtractTextStyle.ts +11 -3
- package/src/hooks/useExtractViewStyle.ts +15 -4
- package/src/index.native.ts +6 -0
- package/src/index.ts +2 -0
- package/src/utils/extractImageStyle.ts +34 -5
- package/src/utils/extractTextStyle/extractTextStyle.ts +3 -5
- 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/patterns.ts +55 -1
package/src/index.native.ts
CHANGED
|
@@ -49,6 +49,11 @@ export { useExtractTextStyle } from './hooks/useExtractTextStyle';
|
|
|
49
49
|
export { useExtractViewStyle } from './hooks/useExtractViewStyle';
|
|
50
50
|
export { useExtractImageStyle } from './hooks/useExtractImageStyle';
|
|
51
51
|
|
|
52
|
+
// Native style extractors (RN-friendly style objects)
|
|
53
|
+
export { extractViewStyleNative } from './utils/extractViewStyle';
|
|
54
|
+
export { extractTextStyleNative } from './utils/extractTextStyle';
|
|
55
|
+
export { extractImageStyleNative } from './utils/extractImageStyle';
|
|
56
|
+
|
|
52
57
|
// Pure utilities (RN-safe)
|
|
53
58
|
export {
|
|
54
59
|
isNodeNullOrUndefined,
|
|
@@ -87,3 +92,4 @@ export {
|
|
|
87
92
|
getBasicSamples,
|
|
88
93
|
getOnboardSamples,
|
|
89
94
|
} from './assets/samples/getSamples';
|
|
95
|
+
export type { EventObjectGenerated } from './build-components/OnboardButton/OnboardButtonProps.generated';
|
package/src/index.ts
CHANGED
|
@@ -7,3 +7,5 @@ export { defaultAppConfig } from './types/PreviewConfig';
|
|
|
7
7
|
|
|
8
8
|
export type { AppConfig } from './types/PreviewConfig';
|
|
9
9
|
export type { Project, ProjectColors } from './types/Project';
|
|
10
|
+
//NOTE: TECH-DEBT: This is a temporary solution to export the native index. We should find a better way to do this.
|
|
11
|
+
export * from './index.native';
|
|
@@ -1,21 +1,50 @@
|
|
|
1
1
|
import { ImagePropsGenerated } from '../build-components/Image/ImageProps.generated';
|
|
2
2
|
import type { NodeData } from '../types/Node';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
extractViewStyle,
|
|
5
|
+
extractViewStyleNative,
|
|
6
|
+
ExtractViewStyleOptions,
|
|
7
|
+
} from './extractViewStyle';
|
|
4
8
|
|
|
5
9
|
export function extractImageStyle<T extends ImagePropsGenerated['attributes']>(
|
|
6
10
|
node: NodeData<T>,
|
|
7
11
|
options: ExtractViewStyleOptions = {},
|
|
8
12
|
) {
|
|
9
13
|
const attributes = node.attributes;
|
|
14
|
+
const styleBag = (attributes as any)?.style as
|
|
15
|
+
| Record<string, unknown>
|
|
16
|
+
| undefined;
|
|
10
17
|
const style: React.CSSProperties = {};
|
|
11
18
|
|
|
12
19
|
if (!attributes) return style;
|
|
13
20
|
|
|
14
21
|
// Map resizeMode to CSS object-fit
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
else if (
|
|
22
|
+
const resizeMode = ((attributes as any)?.resizeMode ??
|
|
23
|
+
styleBag?.resizeMode) as any;
|
|
24
|
+
if (resizeMode === 'cover') style.objectFit = 'cover';
|
|
25
|
+
else if (resizeMode === 'contain') style.objectFit = 'contain';
|
|
26
|
+
else if (resizeMode === 'stretch') style.objectFit = 'fill';
|
|
27
|
+
else if (resizeMode === 'center') style.objectFit = 'none';
|
|
19
28
|
|
|
20
29
|
return { ...extractViewStyle(node, options), ...style };
|
|
21
30
|
}
|
|
31
|
+
|
|
32
|
+
export function extractImageStyleNative<
|
|
33
|
+
T extends ImagePropsGenerated['attributes'],
|
|
34
|
+
>(node: NodeData<T>, options: ExtractViewStyleOptions = {}) {
|
|
35
|
+
const attributes = node.attributes;
|
|
36
|
+
const styleBag = (attributes as any)?.style as
|
|
37
|
+
| Record<string, unknown>
|
|
38
|
+
| undefined;
|
|
39
|
+
if (!attributes) return {};
|
|
40
|
+
|
|
41
|
+
const resizeMode = ((attributes as any)?.resizeMode ??
|
|
42
|
+
styleBag?.resizeMode) as any;
|
|
43
|
+
|
|
44
|
+
// In RN, resizeMode is usually an Image prop, but many codebases also accept it on ImageStyle.
|
|
45
|
+
// We return it here so consumers can pass it through as they prefer.
|
|
46
|
+
const nativeStyle: Record<string, unknown> = {};
|
|
47
|
+
if (resizeMode) nativeStyle.resizeMode = resizeMode;
|
|
48
|
+
|
|
49
|
+
return { ...extractViewStyleNative(node, options as any), ...nativeStyle };
|
|
50
|
+
}
|
|
@@ -93,12 +93,10 @@ export function extractTextStyle<T extends TextPropsGenerated['attributes']>(
|
|
|
93
93
|
const styleBag = (attributes as any)?.style as
|
|
94
94
|
| Record<string, unknown>
|
|
95
95
|
| undefined;
|
|
96
|
-
const get =
|
|
97
|
-
key: K,
|
|
98
|
-
): TextPropsGenerated['attributes'][K] | undefined => {
|
|
96
|
+
const get = (key: string): unknown => {
|
|
99
97
|
const direct = (attributes as any)?.[key];
|
|
100
98
|
if (direct !== undefined && direct !== null) return direct;
|
|
101
|
-
return styleBag?.[key
|
|
99
|
+
return styleBag?.[key];
|
|
102
100
|
};
|
|
103
101
|
const resolvedAppConfig = options.appConfig ?? defaultAppConfig;
|
|
104
102
|
const { screenStyle, theme } = resolvedAppConfig;
|
|
@@ -162,7 +160,7 @@ export function extractTextStyle<T extends TextPropsGenerated['attributes']>(
|
|
|
162
160
|
// If no fontFamily is set, keep previous behavior.
|
|
163
161
|
if (!normalizedFontFamily && normalizedFontWeight)
|
|
164
162
|
style.fontWeight = normalizedFontWeight;
|
|
165
|
-
const resolvedTextColor = parseColor(get('color'), {
|
|
163
|
+
const resolvedTextColor = parseColor(get('color') as any, {
|
|
166
164
|
projectColors: options.projectColors,
|
|
167
165
|
theme,
|
|
168
166
|
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { NodeData } from '../../types/Node';
|
|
2
|
+
import type { TextPropsGenerated } from '../../build-components/Text/TextProps.generated';
|
|
3
|
+
import type { AppConfig } from '../../types/PreviewConfig';
|
|
4
|
+
import { defaultAppConfig } from '../../types/PreviewConfig';
|
|
5
|
+
import type { ProjectColors } from '../../types/Project';
|
|
6
|
+
import type { Fonts } from '../../types/Fonts';
|
|
7
|
+
import { fs, parseSize } from '../../size-matters';
|
|
8
|
+
import { parseColor } from '../parseColor';
|
|
9
|
+
import { extractViewStyleNative } from '../extractViewStyle';
|
|
10
|
+
import { normalizeFontWeight } from '../fontWeight';
|
|
11
|
+
import {
|
|
12
|
+
findFontDefinition,
|
|
13
|
+
resolveClosestFontWeightKey,
|
|
14
|
+
} from '../loadFontFamily';
|
|
15
|
+
|
|
16
|
+
export type ExtractTextStyleNativeOptions = {
|
|
17
|
+
appConfig?: AppConfig;
|
|
18
|
+
projectColors?: ProjectColors;
|
|
19
|
+
fonts?: Fonts;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function weightToNumericKey(weight: unknown): string | undefined {
|
|
23
|
+
const normalized = normalizeFontWeight(weight);
|
|
24
|
+
if (!normalized) return undefined;
|
|
25
|
+
if (normalized === 'normal') return '400';
|
|
26
|
+
if (normalized === 'bold') return '700';
|
|
27
|
+
return normalized;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* React Native-friendly text style extraction.
|
|
32
|
+
* - Avoids web-only quoting of fontFamily.
|
|
33
|
+
* - Returns numeric fontSize (dp) when possible.
|
|
34
|
+
* - Merges with extractViewStyleNative so padding/margin/etc still work in RN.
|
|
35
|
+
*/
|
|
36
|
+
export function extractTextStyleNative<
|
|
37
|
+
T extends TextPropsGenerated['attributes'],
|
|
38
|
+
>(node: NodeData<T>, options: ExtractTextStyleNativeOptions = {}) {
|
|
39
|
+
const attributes = node.attributes;
|
|
40
|
+
const styleBag = (attributes as any)?.style as
|
|
41
|
+
| Record<string, unknown>
|
|
42
|
+
| undefined;
|
|
43
|
+
const get = (key: string): unknown => {
|
|
44
|
+
const direct = (attributes as any)?.[key];
|
|
45
|
+
if (direct !== undefined && direct !== null) return direct;
|
|
46
|
+
return styleBag?.[key];
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const resolvedAppConfig = options.appConfig ?? defaultAppConfig;
|
|
50
|
+
const { screenStyle, theme } = resolvedAppConfig;
|
|
51
|
+
const fallbackColor =
|
|
52
|
+
theme === 'light' ? screenStyle.light.color : screenStyle.dark.color;
|
|
53
|
+
|
|
54
|
+
const style: Record<string, unknown> = {};
|
|
55
|
+
if (!attributes) {
|
|
56
|
+
style.fontSize = fs(14);
|
|
57
|
+
style.color = fallbackColor;
|
|
58
|
+
return style;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const rawFontSize = get('fontSize') as any;
|
|
62
|
+
const parsedFontSize = parseSize(rawFontSize);
|
|
63
|
+
if (typeof parsedFontSize === 'number') style.fontSize = parsedFontSize;
|
|
64
|
+
else style.fontSize = fs(14);
|
|
65
|
+
|
|
66
|
+
const fontFamily = get('fontFamily') as any;
|
|
67
|
+
const fontWeight = get('fontWeight') as any;
|
|
68
|
+
const requestedWeight = weightToNumericKey(fontWeight);
|
|
69
|
+
const normalizedFontFamily =
|
|
70
|
+
typeof fontFamily === 'string' && fontFamily.trim().length > 0
|
|
71
|
+
? fontFamily.trim()
|
|
72
|
+
: undefined;
|
|
73
|
+
|
|
74
|
+
if (normalizedFontFamily) {
|
|
75
|
+
const def = findFontDefinition(options.fonts ?? [], normalizedFontFamily);
|
|
76
|
+
const resolvedWeightKey =
|
|
77
|
+
def?.family && typeof def.family === 'object'
|
|
78
|
+
? resolveClosestFontWeightKey(
|
|
79
|
+
def.family as Record<string, string>,
|
|
80
|
+
requestedWeight,
|
|
81
|
+
)
|
|
82
|
+
: requestedWeight;
|
|
83
|
+
|
|
84
|
+
style.fontFamily = normalizedFontFamily;
|
|
85
|
+
if (resolvedWeightKey) style.fontWeight = resolvedWeightKey;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const normalizedFontWeight = normalizeFontWeight(fontWeight);
|
|
89
|
+
if (!normalizedFontFamily && normalizedFontWeight)
|
|
90
|
+
style.fontWeight = normalizedFontWeight;
|
|
91
|
+
|
|
92
|
+
const resolvedTextColor = parseColor(get('color') as any, {
|
|
93
|
+
projectColors: options.projectColors,
|
|
94
|
+
theme,
|
|
95
|
+
});
|
|
96
|
+
style.color = resolvedTextColor ?? fallbackColor;
|
|
97
|
+
|
|
98
|
+
const textAlign = get('textAlign');
|
|
99
|
+
if (textAlign) style.textAlign = textAlign as any;
|
|
100
|
+
|
|
101
|
+
const viewStyle = extractViewStyleNative(node, {
|
|
102
|
+
projectColors: options.projectColors,
|
|
103
|
+
theme,
|
|
104
|
+
});
|
|
105
|
+
return { ...viewStyle, ...style };
|
|
106
|
+
}
|
|
@@ -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';
|
package/src/utils/patterns.ts
CHANGED
|
@@ -60,6 +60,58 @@ 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
|
+
function adjustMetaForPlatform(
|
|
70
|
+
meta: Record<string, AttributeMeta> | undefined,
|
|
71
|
+
platform?: BuilderPlatform,
|
|
72
|
+
): Record<string, AttributeMeta> | undefined {
|
|
73
|
+
if (!meta) return undefined;
|
|
74
|
+
const p = normalizePlatform(platform);
|
|
75
|
+
|
|
76
|
+
// Values that are not directly style-friendly for the target platform should be shown under "other"
|
|
77
|
+
// (so they remain editable, but are clearly non-style / platform-specific behavior).
|
|
78
|
+
const moveToOtherAlways = new Set<string>(['scrollable']);
|
|
79
|
+
const moveToOtherOnWeb = new Set<string>([
|
|
80
|
+
// RN-only shorthands; on web they are translated to paddingLeft/Right, etc.
|
|
81
|
+
'paddingHorizontal',
|
|
82
|
+
'paddingVertical',
|
|
83
|
+
'marginHorizontal',
|
|
84
|
+
'marginVertical',
|
|
85
|
+
]);
|
|
86
|
+
const moveToOtherOnNative = new Set<string>([
|
|
87
|
+
// CSS-only layout convenience (not widely supported in RN style across versions).
|
|
88
|
+
'gap',
|
|
89
|
+
// Web-only text behaviors (implemented via DOM).
|
|
90
|
+
'showEllipsis',
|
|
91
|
+
'adjustsFontSizeToFit',
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
const shouldMove = (key: string) =>
|
|
95
|
+
moveToOtherAlways.has(key) ||
|
|
96
|
+
(p === 'web' ? moveToOtherOnWeb.has(key) : moveToOtherOnNative.has(key));
|
|
97
|
+
|
|
98
|
+
let changed = false;
|
|
99
|
+
const out: Record<string, AttributeMeta> = {};
|
|
100
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
101
|
+
if (!value || typeof value !== 'object') {
|
|
102
|
+
out[key] = value;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (shouldMove(key)) {
|
|
106
|
+
out[key] = { ...value, category: 'other', specialCategory: null };
|
|
107
|
+
changed = true;
|
|
108
|
+
} else {
|
|
109
|
+
out[key] = value;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return changed ? out : meta;
|
|
113
|
+
}
|
|
114
|
+
|
|
63
115
|
// Build a fast lookup map without normalization for direct access
|
|
64
116
|
const patternIndex: Map<string, Pattern> = new Map(
|
|
65
117
|
patterns.map((p) => [p.pattern.type, p]),
|
|
@@ -121,9 +173,11 @@ export function getAttributeSchema(
|
|
|
121
173
|
|
|
122
174
|
export function getAttributeMeta(
|
|
123
175
|
type?: string | null,
|
|
176
|
+
platform?: BuilderPlatform,
|
|
124
177
|
): Record<string, AttributeMeta> | undefined {
|
|
125
178
|
const p = getPatternByType(type);
|
|
126
|
-
|
|
179
|
+
const meta = p?.meta?.styles ?? p?.meta?.attributes;
|
|
180
|
+
return adjustMetaForPlatform(meta, platform);
|
|
127
181
|
}
|
|
128
182
|
|
|
129
183
|
/** Returns defaults block (if any) for a given component type */
|