@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.
Files changed (204) hide show
  1. package/dist/AttributesEditor.d.ts +2 -11
  2. package/dist/attribute-analyser/style/native/useExtractImageStyle.d.ts +10 -0
  3. package/dist/attribute-analyser/style/native/useExtractTextStyle.d.ts +9 -0
  4. package/dist/attribute-analyser/style/native/useExtractViewStyle.d.ts +8 -0
  5. package/dist/attribute-analyser/style/web/useExtractImageStyle.d.ts +4 -0
  6. package/dist/attribute-analyser/style/web/useExtractTextStyle.d.ts +4 -0
  7. package/dist/attribute-analyser/style/web/useExtractViewStyle.d.ts +4 -0
  8. package/dist/attributes-editor/AttributesEditorFields.d.ts +18 -0
  9. package/dist/attributes-editor/AttributesEditorView.d.ts +4 -0
  10. package/dist/attributes-editor/attributesEditorModelTypes.d.ts +67 -0
  11. package/dist/attributes-editor/attributesEditorUtils.d.ts +19 -0
  12. package/dist/attributes-editor/useAttributesEditorModel.d.ts +2 -0
  13. package/dist/build-components/BIcon/BIconProps.generated.d.ts +41 -38
  14. package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +37 -34
  15. package/dist/build-components/Button/ButtonProps.generated.d.ts +39 -36
  16. package/dist/build-components/Carousel/CarouselProps.generated.d.ts +37 -34
  17. package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +37 -34
  18. package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +37 -34
  19. package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +36 -33
  20. package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +36 -33
  21. package/dist/build-components/Image/ImageProps.generated.d.ts +38 -33
  22. package/dist/build-components/Main/MainProps.generated.d.ts +36 -33
  23. package/dist/build-components/Onboard/OnboardProps.generated.d.ts +36 -33
  24. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +38 -34
  25. package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +39 -36
  26. package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +43 -34
  27. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +41 -38
  28. package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +36 -31
  29. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +39 -33
  30. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +38 -34
  31. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +41 -38
  32. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +41 -38
  33. package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +36 -33
  34. package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +41 -38
  35. package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +36 -33
  36. package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +36 -33
  37. package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +39 -36
  38. package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +36 -33
  39. package/dist/build-components/Text/TextProps.generated.d.ts +41 -38
  40. package/dist/build-components/View/ViewProps.generated.d.ts +36 -33
  41. package/dist/build-components/patterns.generated.d.ts +2673 -5787
  42. package/dist/components/BuilderProvider.d.ts +6 -0
  43. package/dist/index.cjs.js +5 -5
  44. package/dist/index.cjs.js.map +1 -1
  45. package/dist/index.d.ts +5 -26
  46. package/dist/index.esm.js +5 -5
  47. package/dist/index.esm.js.map +1 -1
  48. package/dist/index.native.cjs.js +6 -4
  49. package/dist/index.native.cjs.js.map +1 -1
  50. package/dist/index.native.d.ts +6 -3
  51. package/dist/index.native.esm.js +6 -4
  52. package/dist/index.native.esm.js.map +1 -1
  53. package/dist/migrations/migratePipe.d.ts +1 -1
  54. package/dist/migrations/migrations/1.1.2_extract_component_attributes_from_style.d.ts +2 -0
  55. package/dist/mockOS/components/PermissionModal.d.ts +1 -2
  56. package/dist/styles.css +1 -1
  57. package/dist/types/PreviewConfig.d.ts +1 -5
  58. package/dist/utils/extractImageStyle.d.ts +3 -0
  59. package/dist/utils/extractTextStyle/extractTextStyleNative.d.ts +17 -0
  60. package/dist/utils/extractTextStyle.d.ts +2 -0
  61. package/dist/utils/extractViewStyle/extractViewStyleNative.d.ts +12 -0
  62. package/dist/utils/extractViewStyle.d.ts +2 -0
  63. package/dist/utils/getMeta.d.ts +5 -0
  64. package/dist/utils/patterns.d.ts +14 -1
  65. package/package.json +2 -1
  66. package/scripts/prebuild/prebuild.js +14 -0
  67. package/scripts/prebuild/utils/createGeneratedProps.js +51 -3
  68. package/scripts/prebuild/utils/index.js +1 -0
  69. package/scripts/prebuild/utils/updateMetaJson.js +66 -0
  70. package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +37 -3
  71. package/scripts/prebuild/utils/validatePatternJson.js +27 -2
  72. package/scripts/public/scripts/build/index.js +20 -3
  73. package/scripts/public/scripts/build/info.json +6 -0
  74. package/scripts/public/scripts/build/utils/createComponentsIndex.js +9 -3
  75. package/scripts/public/scripts/build/utils/createRenderNodeGenerated.js +66 -8
  76. package/src/AttributesEditor.tsx +8 -944
  77. package/src/assets/meta.json +4 -0
  78. package/src/assets/samples/carousel-sample.json +1 -1
  79. package/src/assets/samples/getSamples.ts +2 -0
  80. package/src/assets/samples/paywall-1.json +11 -7
  81. package/src/assets/samples/simple-1.json +3 -3
  82. package/src/assets/samples/simple-2.json +3 -3
  83. package/src/assets/samples/unmigrated-builder-1.1.1.json +87 -0
  84. package/src/assets/samples/unmigrated-builder1.json +1 -1
  85. package/src/assets/samples/unvalidated-builder1.json +3 -3
  86. package/src/assets/samples/unvalidated-crash1.json +1 -1
  87. package/src/assets/samples/unvalidated-crashcomponent1.json +1 -1
  88. package/src/assets/samples/vpn-onboard-1.json +1 -1
  89. package/src/assets/samples/vpn-onboard-2.json +1 -1
  90. package/src/assets/samples/vpn-onboard-3.json +1 -1
  91. package/src/assets/samples/vpn-onboard-4.json +1 -1
  92. package/src/assets/samples/vpn-onboard-5.json +1 -1
  93. package/src/assets/samples/vpn-onboard-6.json +1 -1
  94. package/src/attribute-analyser/style/native/useExtractImageStyle.ts +46 -0
  95. package/src/attribute-analyser/style/native/useExtractTextStyle.ts +50 -0
  96. package/src/attribute-analyser/style/native/useExtractViewStyle.ts +32 -0
  97. package/src/attribute-analyser/style/web/useExtractImageStyle.ts +20 -0
  98. package/src/{hooks → attribute-analyser/style/web}/useExtractTextStyle.ts +7 -6
  99. package/src/{hooks → attribute-analyser/style/web}/useExtractViewStyle.ts +7 -6
  100. package/src/attributes-editor/AttributesEditorFields.tsx +248 -0
  101. package/src/attributes-editor/AttributesEditorView.tsx +360 -0
  102. package/src/attributes-editor/LayoutPreviewPicker.tsx +4 -3
  103. package/src/attributes-editor/attributesEditorModelTypes.ts +86 -0
  104. package/src/attributes-editor/attributesEditorUtils.ts +102 -0
  105. package/src/attributes-editor/useAttributesEditorModel.ts +477 -0
  106. package/src/build-components/BIcon/BIcon.tsx +4 -3
  107. package/src/build-components/BIcon/BIconProps.generated.ts +42 -38
  108. package/src/build-components/BIcon/pattern.json +5 -6
  109. package/src/build-components/BackgroundImage/BackgroundImage.tsx +7 -4
  110. package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +38 -34
  111. package/src/build-components/BackgroundImage/pattern.json +9 -17
  112. package/src/build-components/Button/Button.tsx +7 -6
  113. package/src/build-components/Button/ButtonProps.generated.ts +40 -36
  114. package/src/build-components/Button/pattern.json +17 -15
  115. package/src/build-components/Carousel/Carousel.tsx +1 -1
  116. package/src/build-components/Carousel/CarouselProps.generated.ts +38 -34
  117. package/src/build-components/CarouselButtons/CarouselButtons.tsx +4 -6
  118. package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +41 -37
  119. package/src/build-components/CarouselButtons/pattern.json +2 -1
  120. package/src/build-components/CarouselDots/CarouselDots.tsx +2 -2
  121. package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +44 -40
  122. package/src/build-components/CarouselItem/CarouselItem.tsx +1 -1
  123. package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +37 -33
  124. package/src/build-components/CarouselProvider/CarouselProvider.tsx +1 -1
  125. package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +37 -33
  126. package/src/build-components/Image/Image.tsx +4 -3
  127. package/src/build-components/Image/ImageProps.generated.ts +39 -33
  128. package/src/build-components/Image/pattern.json +5 -11
  129. package/src/build-components/Main/Main.tsx +1 -1
  130. package/src/build-components/Main/MainProps.generated.ts +37 -33
  131. package/src/build-components/Main/pattern.json +2 -1
  132. package/src/build-components/Onboard/OnboardProps.generated.ts +37 -33
  133. package/src/build-components/OnboardButton/OnboardButton.tsx +8 -6
  134. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +44 -39
  135. package/src/build-components/OnboardButton/pattern.json +9 -7
  136. package/src/build-components/OnboardButtons/OnboardButtons.tsx +31 -31
  137. package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +43 -39
  138. package/src/build-components/OnboardButtons/pattern.json +9 -7
  139. package/src/build-components/OnboardDot/OnboardDot.tsx +7 -5
  140. package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +55 -34
  141. package/src/build-components/OnboardFooter/OnboardFooter.tsx +19 -23
  142. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +42 -38
  143. package/src/build-components/OnboardFooter/pattern.json +16 -14
  144. package/src/build-components/OnboardImage/OnboardImage.tsx +8 -7
  145. package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +37 -31
  146. package/src/build-components/OnboardImage/pattern.json +2 -1
  147. package/src/build-components/OnboardItem/OnboardItem.tsx +1 -1
  148. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +40 -33
  149. package/src/build-components/OnboardItem/pattern.json +2 -1
  150. package/src/build-components/OnboardProvider/OnboardProvider.tsx +1 -1
  151. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +39 -34
  152. package/src/build-components/OnboardProvider/pattern.json +2 -1
  153. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +42 -38
  154. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +42 -38
  155. package/src/build-components/PaywallBackground/PaywallBackground.tsx +1 -1
  156. package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +37 -33
  157. package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +6 -5
  158. package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +42 -38
  159. package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +1 -1
  160. package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +37 -33
  161. package/src/build-components/PaywallProvider/PaywallProvider.tsx +1 -1
  162. package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +37 -33
  163. package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +1 -1
  164. package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +40 -36
  165. package/src/build-components/RadioButton/RadioButton.tsx +5 -4
  166. package/src/build-components/RadioButton/RadioButtonProps.generated.ts +37 -33
  167. package/src/build-components/RadioButton/pattern.json +9 -7
  168. package/src/build-components/Text/Text.tsx +6 -8
  169. package/src/build-components/Text/TextProps.generated.ts +42 -38
  170. package/src/build-components/Text/pattern.json +15 -11
  171. package/src/build-components/View/View.tsx +1 -1
  172. package/src/build-components/View/ViewProps.generated.ts +37 -33
  173. package/src/build-components/View/pattern.json +71 -66
  174. package/src/build-components/patterns.generated.ts +3022 -5971
  175. package/src/components/AttributesEditorPanel.tsx +2 -2
  176. package/src/components/BuilderProvider.tsx +15 -1
  177. package/src/index.native.ts +7 -4
  178. package/src/index.ts +6 -77
  179. package/src/migrations/migratePipe.ts +7 -3
  180. package/src/migrations/migrations/1.1.2_extract_component_attributes_from_style.ts +211 -0
  181. package/src/mockOS/components/MockOSRouter.tsx +3 -1
  182. package/src/mockOS/components/PermissionModal.tsx +20 -160
  183. package/src/mockOS/components/SubscriptionModal.tsx +41 -278
  184. package/src/pages/ProjectPage.tsx +12 -6
  185. package/src/styles/components/_attributes-editor.scss +122 -0
  186. package/src/styles/components/_mockos-router.scss +388 -0
  187. package/src/styles/components/_onboard.scss +23 -0
  188. package/src/styles/index.scss +1 -0
  189. package/src/types/PreviewConfig.ts +1 -5
  190. package/src/utils/analyseNodeByPatterns.ts +39 -4
  191. package/src/utils/extractImageStyle.ts +34 -5
  192. package/src/utils/extractTextStyle/extractTextStyle.ts +7 -6
  193. package/src/utils/extractTextStyle/extractTextStyleNative.ts +106 -0
  194. package/src/utils/extractTextStyle.ts +2 -0
  195. package/src/utils/extractViewStyle/extractViewStyle.ts +2 -4
  196. package/src/utils/extractViewStyle/extractViewStyleNative.ts +111 -0
  197. package/src/utils/extractViewStyle.ts +2 -0
  198. package/src/utils/getMeta.ts +15 -0
  199. package/src/utils/patterns.ts +100 -3
  200. package/dist/hooks/useExtractImageStyle.d.ts +0 -3
  201. package/dist/hooks/useExtractTextStyle.d.ts +0 -3
  202. package/dist/hooks/useExtractViewStyle.d.ts +0 -3
  203. package/src/hooks/useExtractImageStyle.ts +0 -19
  204. 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 = <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';
@@ -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
+ }
@@ -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
- return p?.meta?.styles ?? p?.meta?.attributes;
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
- };