@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.
Files changed (112) hide show
  1. package/dist/build-components/BIcon/BIconProps.generated.d.ts +47 -44
  2. package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +38 -35
  3. package/dist/build-components/Button/ButtonProps.generated.d.ts +40 -37
  4. package/dist/build-components/Carousel/CarouselProps.generated.d.ts +37 -34
  5. package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +39 -36
  6. package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +38 -35
  7. package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +37 -34
  8. package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +37 -34
  9. package/dist/build-components/Image/ImageProps.generated.d.ts +38 -35
  10. package/dist/build-components/Main/MainProps.generated.d.ts +38 -35
  11. package/dist/build-components/Onboard/OnboardProps.generated.d.ts +37 -34
  12. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +43 -40
  13. package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +44 -41
  14. package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +41 -38
  15. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +51 -48
  16. package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +40 -37
  17. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +38 -35
  18. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +38 -35
  19. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +44 -41
  20. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +44 -41
  21. package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +37 -34
  22. package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +47 -44
  23. package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +37 -34
  24. package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +37 -34
  25. package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +40 -37
  26. package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +40 -37
  27. package/dist/build-components/Text/TextProps.generated.d.ts +44 -41
  28. package/dist/build-components/View/ViewProps.generated.d.ts +37 -34
  29. package/dist/build-components/patterns.generated.d.ts +21 -21
  30. package/dist/components/BuilderProvider.d.ts +6 -0
  31. package/dist/hooks/useExtractImageStyle.d.ts +3 -1
  32. package/dist/hooks/useExtractTextStyle.d.ts +1 -1
  33. package/dist/hooks/useExtractViewStyle.d.ts +1 -1
  34. package/dist/index.cjs.js +5 -5
  35. package/dist/index.cjs.js.map +1 -1
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.esm.js +3 -3
  38. package/dist/index.esm.js.map +1 -1
  39. package/dist/index.native.cjs.js +2 -2
  40. package/dist/index.native.cjs.js.map +1 -1
  41. package/dist/index.native.d.ts +4 -0
  42. package/dist/index.native.esm.js +2 -2
  43. package/dist/index.native.esm.js.map +1 -1
  44. package/dist/utils/extractImageStyle.d.ts +3 -0
  45. package/dist/utils/extractTextStyle/extractTextStyleNative.d.ts +17 -0
  46. package/dist/utils/extractTextStyle.d.ts +2 -0
  47. package/dist/utils/extractViewStyle/extractViewStyleNative.d.ts +12 -0
  48. package/dist/utils/extractViewStyle.d.ts +2 -0
  49. package/dist/utils/patterns.d.ts +2 -1
  50. package/package.json +5 -1
  51. package/scripts/prebuild/utils/createGeneratedProps.js +45 -3
  52. package/src/attributes-editor/LayoutPreviewPicker.tsx +4 -3
  53. package/src/build-components/BIcon/BIcon.tsx +3 -2
  54. package/src/build-components/BIcon/BIconProps.generated.ts +48 -44
  55. package/src/build-components/BackgroundImage/BackgroundImage.tsx +5 -3
  56. package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +39 -35
  57. package/src/build-components/BackgroundImage/pattern.json +9 -17
  58. package/src/build-components/Button/Button.tsx +5 -4
  59. package/src/build-components/Button/ButtonProps.generated.ts +41 -37
  60. package/src/build-components/Carousel/CarouselProps.generated.ts +38 -34
  61. package/src/build-components/CarouselButtons/CarouselButtons.tsx +3 -2
  62. package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +40 -36
  63. package/src/build-components/CarouselDots/CarouselDots.tsx +1 -1
  64. package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +39 -35
  65. package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +38 -34
  66. package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +38 -34
  67. package/src/build-components/Image/Image.tsx +3 -2
  68. package/src/build-components/Image/ImageProps.generated.ts +39 -35
  69. package/src/build-components/Image/pattern.json +9 -16
  70. package/src/build-components/Main/Main.tsx +1 -1
  71. package/src/build-components/Main/MainProps.generated.ts +39 -35
  72. package/src/build-components/Onboard/OnboardProps.generated.ts +38 -34
  73. package/src/build-components/OnboardButton/OnboardButton.tsx +6 -5
  74. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +44 -40
  75. package/src/build-components/OnboardButtons/OnboardButtons.tsx +4 -4
  76. package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +45 -41
  77. package/src/build-components/OnboardDot/OnboardDot.tsx +5 -4
  78. package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +42 -38
  79. package/src/build-components/OnboardFooter/OnboardFooter.tsx +16 -21
  80. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +52 -48
  81. package/src/build-components/OnboardImage/OnboardImage.tsx +7 -6
  82. package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +41 -37
  83. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +39 -35
  84. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +39 -35
  85. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +45 -41
  86. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +45 -41
  87. package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +38 -34
  88. package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +4 -4
  89. package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +48 -44
  90. package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +38 -34
  91. package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +38 -34
  92. package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +41 -37
  93. package/src/build-components/RadioButton/RadioButton.tsx +4 -3
  94. package/src/build-components/RadioButton/RadioButtonProps.generated.ts +41 -37
  95. package/src/build-components/Text/Text.tsx +3 -5
  96. package/src/build-components/Text/TextProps.generated.ts +45 -41
  97. package/src/build-components/View/ViewProps.generated.ts +38 -34
  98. package/src/build-components/patterns.generated.ts +21 -21
  99. package/src/components/BuilderProvider.tsx +15 -1
  100. package/src/hooks/useExtractImageStyle.ts +15 -4
  101. package/src/hooks/useExtractTextStyle.ts +11 -3
  102. package/src/hooks/useExtractViewStyle.ts +15 -4
  103. package/src/index.native.ts +6 -0
  104. package/src/index.ts +2 -0
  105. package/src/utils/extractImageStyle.ts +34 -5
  106. package/src/utils/extractTextStyle/extractTextStyle.ts +3 -5
  107. package/src/utils/extractTextStyle/extractTextStyleNative.ts +106 -0
  108. package/src/utils/extractTextStyle.ts +2 -0
  109. package/src/utils/extractViewStyle/extractViewStyle.ts +2 -4
  110. package/src/utils/extractViewStyle/extractViewStyleNative.ts +111 -0
  111. package/src/utils/extractViewStyle.ts +2 -0
  112. package/src/utils/patterns.ts +55 -1
@@ -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 { extractViewStyle, ExtractViewStyleOptions } from './extractViewStyle';
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
- if (attributes.resizeMode === 'cover') style.objectFit = 'cover';
16
- else if (attributes.resizeMode === 'contain') style.objectFit = 'contain';
17
- else if (attributes.resizeMode === 'stretch') style.objectFit = 'fill';
18
- else if (attributes.resizeMode === 'center') style.objectFit = 'none';
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 = <K extends keyof TextPropsGenerated['attributes']>(
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 as unknown as string] as any;
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 = <K extends keyof ViewPropsGenerated['attributes']>(
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 as unknown as string] as any;
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';
@@ -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
- return p?.meta?.styles ?? p?.meta?.attributes;
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 */