@developer_tribe/react-builder 1.0.1 → 1.0.3

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 (218) hide show
  1. package/dist/AttributesEditor.d.ts +3 -1
  2. package/dist/DeviceMockFrame.d.ts +2 -1
  3. package/dist/RenderPage.d.ts +5 -3
  4. package/dist/attributes-editor/Field.d.ts +17 -0
  5. package/dist/attributes-editor/FieldInfoTooltip.d.ts +7 -0
  6. package/dist/attributes-editor/LayoutPreviewPicker.d.ts +12 -0
  7. package/dist/attributes-editor/SpecialCategorySection.d.ts +20 -0
  8. package/dist/attributes-editor/types.d.ts +14 -0
  9. package/dist/background.jpg +0 -0
  10. package/dist/build-components/BackgroundImage/BackgroundImage.d.ts +5 -0
  11. package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +44 -0
  12. package/dist/build-components/Button/Button.d.ts +1 -1
  13. package/dist/build-components/Button/ButtonProps.generated.d.ts +33 -1
  14. package/dist/build-components/Carousel/CarouselProps.generated.d.ts +34 -1
  15. package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +32 -0
  16. package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +32 -0
  17. package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +34 -1
  18. package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +34 -1
  19. package/dist/build-components/Image/ImageProps.generated.d.ts +32 -3
  20. package/dist/build-components/Onboard/OnboardProps.generated.d.ts +34 -1
  21. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +32 -0
  22. package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +32 -0
  23. package/dist/build-components/OnboardDot/OnboardDot.d.ts +1 -1
  24. package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +29 -0
  25. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +11 -5
  26. package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +32 -3
  27. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +31 -3
  28. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +32 -5
  29. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +11 -5
  30. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +11 -5
  31. package/dist/build-components/Text/TextProps.generated.d.ts +11 -5
  32. package/dist/build-components/View/ViewProps.generated.d.ts +10 -4
  33. package/dist/build-components/index.d.ts +2 -1
  34. package/dist/build-components/patterns.generated.d.ts +6288 -136
  35. package/dist/components/AttributesEditorPanel.d.ts +3 -4
  36. package/dist/components/Breadcrumb.d.ts +3 -1
  37. package/dist/components/Builder.d.ts +2 -1
  38. package/dist/components/BuilderButton.d.ts +9 -0
  39. package/dist/components/Checkbox.d.ts +17 -0
  40. package/dist/components/DeviceButton.d.ts +8 -0
  41. package/dist/components/DeviceNavigationBar.d.ts +10 -0
  42. package/dist/components/DeviceStatusBar.d.ts +9 -0
  43. package/dist/components/EditorHeader.d.ts +3 -8
  44. package/dist/index.cjs.js +5 -5
  45. package/dist/index.cjs.js.map +1 -1
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.esm.js +5 -5
  48. package/dist/index.esm.js.map +1 -1
  49. package/dist/mockOS/components/MockLaunchScreenComponent.d.ts +6 -0
  50. package/dist/mockOS/components/MockOSRouter.d.ts +8 -0
  51. package/dist/mockOS/components/PermissionModal.d.ts +9 -0
  52. package/dist/mockOS/context/MockOSContext.d.ts +36 -0
  53. package/dist/mockOS/hooks/useMockNavigation.d.ts +3 -0
  54. package/dist/mockOS/hooks/useMockPermission.d.ts +3 -0
  55. package/dist/mockOS/index.d.ts +9 -0
  56. package/dist/mockOS/managers/mockPermissionManager.d.ts +10 -0
  57. package/dist/mockOS/managers/navigationManager.d.ts +17 -0
  58. package/dist/modals/AddComponentModal.d.ts +8 -0
  59. package/dist/modals/ColorModal.d.ts +11 -0
  60. package/dist/modals/DeviceSelectorModal.d.ts +9 -0
  61. package/dist/modals/LocalicationModal.d.ts +8 -0
  62. package/dist/modals/Modal.d.ts +12 -0
  63. package/dist/modals/index.d.ts +5 -0
  64. package/dist/pages/ProjectPage.d.ts +3 -3
  65. package/dist/pages/tabs/BuilderPanel.d.ts +8 -0
  66. package/dist/pages/tabs/{DebugTab.d.ts → SideTool.d.ts} +2 -2
  67. package/dist/store.d.ts +7 -3
  68. package/dist/styles.css +1 -1
  69. package/dist/types/Project.d.ts +11 -0
  70. package/dist/utils/analyseNode.d.ts +1 -0
  71. package/dist/utils/extractTextStyle.d.ts +8 -1
  72. package/dist/utils/extractViewStyle.d.ts +8 -1
  73. package/dist/utils/parseColor.d.ts +7 -0
  74. package/dist/utils/patterns.d.ts +24 -0
  75. package/package.json +2 -1
  76. package/scripts/prebuild/utils/createGeneratedProps.js +11 -3
  77. package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +45 -6
  78. package/scripts/prebuild/utils/validatePatternJson.js +13 -5
  79. package/src/AttributesEditor.tsx +493 -310
  80. package/src/DeviceMockFrame.tsx +21 -37
  81. package/src/RenderPage.tsx +86 -7
  82. package/src/assets/images/android.svg +42 -42
  83. package/src/assets/images/apple.svg +15 -15
  84. package/src/attributes-editor/Field.tsx +669 -0
  85. package/src/attributes-editor/FieldInfoTooltip.tsx +49 -0
  86. package/src/attributes-editor/LayoutPreviewPicker.tsx +199 -0
  87. package/src/attributes-editor/SpecialCategorySection.tsx +285 -0
  88. package/src/attributes-editor/types.ts +30 -0
  89. package/src/build-components/BackgroundImage/BackgroundImage.tsx +87 -0
  90. package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +60 -0
  91. package/src/build-components/BackgroundImage/pattern.json +45 -0
  92. package/src/build-components/Button/Button.tsx +37 -2
  93. package/src/build-components/Button/ButtonProps.generated.ts +44 -1
  94. package/src/build-components/Button/pattern.json +31 -2
  95. package/src/build-components/Carousel/Carousel.tsx +39 -2
  96. package/src/build-components/Carousel/CarouselProps.generated.ts +46 -1
  97. package/src/build-components/Carousel/pattern.json +10 -0
  98. package/src/build-components/CarouselButtons/CarouselButtons.tsx +21 -2
  99. package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +43 -0
  100. package/src/build-components/CarouselButtons/pattern.json +22 -0
  101. package/src/build-components/CarouselDots/CarouselDots.tsx +49 -8
  102. package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +43 -0
  103. package/src/build-components/CarouselDots/pattern.json +15 -0
  104. package/src/build-components/CarouselItem/CarouselItem.tsx +21 -2
  105. package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +46 -1
  106. package/src/build-components/CarouselItem/pattern.json +7 -0
  107. package/src/build-components/CarouselProvider/CarouselProvider.tsx +21 -2
  108. package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +46 -1
  109. package/src/build-components/CarouselProvider/pattern.json +7 -0
  110. package/src/build-components/Image/Image.tsx +33 -2
  111. package/src/build-components/Image/ImageProps.generated.ts +43 -3
  112. package/src/build-components/Image/pattern.json +46 -3
  113. package/src/build-components/Onboard/Onboard.tsx +6 -1
  114. package/src/build-components/Onboard/OnboardProps.generated.ts +46 -1
  115. package/src/build-components/Onboard/pattern.json +11 -0
  116. package/src/build-components/OnboardButton/OnboardButton.tsx +54 -6
  117. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +43 -0
  118. package/src/build-components/OnboardButton/pattern.json +71 -5
  119. package/src/build-components/OnboardButtons/OnboardButtons.tsx +33 -11
  120. package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +43 -0
  121. package/src/build-components/OnboardButtons/pattern.json +70 -4
  122. package/src/build-components/OnboardDot/OnboardDot.tsx +113 -4
  123. package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +29 -0
  124. package/src/build-components/OnboardDot/pattern.json +55 -2
  125. package/src/build-components/OnboardFooter/OnboardFooter.tsx +20 -4
  126. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +11 -5
  127. package/src/build-components/OnboardFooter/pattern.json +58 -2
  128. package/src/build-components/OnboardImage/OnboardImage.tsx +49 -5
  129. package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +43 -3
  130. package/src/build-components/OnboardImage/pattern.json +21 -0
  131. package/src/build-components/OnboardItem/OnboardItem.tsx +17 -1
  132. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +42 -3
  133. package/src/build-components/OnboardItem/pattern.json +38 -2
  134. package/src/build-components/OnboardProvider/OnboardProvider.tsx +52 -18
  135. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +44 -5
  136. package/src/build-components/OnboardProvider/pattern.json +44 -5
  137. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +11 -5
  138. package/src/build-components/OnboardSubtitle/pattern.json +7 -1
  139. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +11 -5
  140. package/src/build-components/OnboardTitle/pattern.json +7 -1
  141. package/src/build-components/RenderNode.generated.tsx +3 -0
  142. package/src/build-components/Text/Text.tsx +34 -6
  143. package/src/build-components/Text/TextProps.generated.ts +11 -5
  144. package/src/build-components/Text/pattern.json +38 -2
  145. package/src/build-components/View/View.tsx +33 -6
  146. package/src/build-components/View/ViewProps.generated.ts +10 -4
  147. package/src/build-components/View/pattern.json +285 -19
  148. package/src/build-components/index.ts +5 -0
  149. package/src/build-components/patterns.generated.ts +6346 -143
  150. package/src/components/AttributesEditorPanel.tsx +17 -64
  151. package/src/components/Breadcrumb.tsx +37 -5
  152. package/src/components/Builder.tsx +311 -108
  153. package/src/components/BuilderButton.tsx +127 -0
  154. package/src/components/Checkbox.tsx +81 -0
  155. package/src/components/DeviceButton.tsx +39 -0
  156. package/src/components/DeviceNavigationBar.tsx +201 -0
  157. package/src/components/DeviceStatusBar.tsx +85 -0
  158. package/src/components/EditorHeader.tsx +26 -74
  159. package/src/index.ts +2 -2
  160. package/src/mockOS/components/MockLaunchScreenComponent.tsx +43 -0
  161. package/src/mockOS/components/MockOSRouter.tsx +123 -0
  162. package/src/mockOS/components/PermissionModal.tsx +270 -0
  163. package/src/mockOS/context/MockOSContext.tsx +179 -0
  164. package/src/mockOS/hooks/useMockNavigation.ts +11 -0
  165. package/src/mockOS/hooks/useMockPermission.ts +11 -0
  166. package/src/mockOS/index.ts +26 -0
  167. package/src/mockOS/managers/mockPermissionManager.ts +54 -0
  168. package/src/mockOS/managers/navigationManager.ts +91 -0
  169. package/src/modals/AddComponentModal.tsx +313 -0
  170. package/src/modals/ColorModal.tsx +425 -0
  171. package/src/modals/DeviceSelectorModal.tsx +57 -0
  172. package/src/modals/LocalicationModal.tsx +54 -0
  173. package/src/modals/Modal.tsx +57 -0
  174. package/src/modals/index.ts +5 -0
  175. package/src/pages/ProjectPage.tsx +307 -71
  176. package/src/pages/tabs/{BuilderTab.tsx → BuilderPanel.tsx} +13 -9
  177. package/src/pages/tabs/SideTool.tsx +259 -0
  178. package/src/size-matters/index.ts +27 -5
  179. package/src/store.ts +13 -5
  180. package/src/styles/base/_global.scss +404 -0
  181. package/src/styles/components/_attributes-editor.scss +273 -0
  182. package/src/styles/components/_editor-shell.scss +212 -0
  183. package/src/styles/components/_mockos-router.scss +140 -0
  184. package/src/styles/components/_ui-components.scss +183 -0
  185. package/src/styles/foundation/_colors.scss +8 -0
  186. package/src/styles/{_mixins.scss → foundation/_mixins.scss} +5 -4
  187. package/src/styles/{_reset.scss → foundation/_reset.scss} +5 -2
  188. package/src/styles/foundation/_sizes.scss +37 -0
  189. package/src/styles/foundation/_typography.scss +4 -0
  190. package/src/styles/foundation/_variables.scss +3 -0
  191. package/src/styles/index.scss +22 -136
  192. package/src/styles/layout/_builder.scss +124 -0
  193. package/src/styles/layout/_pages.scss +3 -0
  194. package/src/styles/modals/_add-component.scss +122 -0
  195. package/src/styles/modals/_color-modal.scss +159 -0
  196. package/src/styles/modals/_device-selector.scss +18 -0
  197. package/src/styles/modals/_localication-modal.scss +68 -0
  198. package/src/styles/modals/_modal-shell.scss +46 -0
  199. package/src/styles/utilities/_carousel.scss +125 -0
  200. package/src/types/Project.ts +14 -0
  201. package/src/types/images.d.ts +8 -0
  202. package/src/utils/analyseNode.ts +98 -0
  203. package/src/utils/extractTextStyle.ts +28 -10
  204. package/src/utils/extractViewStyle.ts +77 -9
  205. package/src/utils/parseColor.ts +43 -0
  206. package/src/utils/patterns.ts +33 -0
  207. package/dist/build-components/OnboardDot/OnboardExpandingDotProps.generated.d.ts +0 -10
  208. package/dist/pages/tabs/BuilderTab.d.ts +0 -9
  209. package/dist/pages/tabs/PreviewTab.d.ts +0 -3
  210. package/src/build-components/OnboardDot/OnboardExpandingDotProps.generated.ts +0 -20
  211. package/src/pages/tabs/DebugTab.tsx +0 -23
  212. package/src/pages/tabs/PreviewTab.tsx +0 -194
  213. package/src/styles/_variables.scss +0 -27
  214. package/src/styles/builder.scss +0 -60
  215. package/src/styles/components.scss +0 -88
  216. package/src/styles/editor.scss +0 -174
  217. package/src/styles/global.scss +0 -200
  218. package/src/styles/pages.scss +0 -2
@@ -1,12 +1,47 @@
1
- import React from 'react';
1
+ import React, { useId, useMemo } from 'react';
2
2
  import type { ButtonComponentProps } from './ButtonProps.generated';
3
3
  import useNode from '../useNode';
4
+ import { useRenderStore } from '../../store';
4
5
  import { useLogRender } from '../../utils/useLogRender';
6
+ import { extractViewStyle } from '../../utils/extractViewStyle';
5
7
 
6
8
  function Button({ node }: ButtonComponentProps) {
7
9
  useLogRender('Button');
8
10
  node = useNode(node);
9
- return String(node?.type ?? 'button');
11
+ const generatedId = useId();
12
+ const attributeName = (node as any)?.sourceType ?? node.type ?? 'button';
13
+ const attributeKey = node.key ?? generatedId;
14
+ const { previewMode, current, appConfig, projectColors } = useRenderStore(
15
+ (s) => ({
16
+ previewMode: s.previewMode,
17
+ current: s.current,
18
+ appConfig: s.appConfig,
19
+ projectColors: s.projectColors,
20
+ }),
21
+ );
22
+ const baseStyle = useMemo(
23
+ () => extractViewStyle(node, { appConfig, projectColors }),
24
+ [node, appConfig, projectColors],
25
+ );
26
+ const isSelected =
27
+ previewMode &&
28
+ !!current &&
29
+ (current as any)?.key &&
30
+ (node as any)?.key &&
31
+ (current as any).key === (node as any).key;
32
+ const style = isSelected
33
+ ? { ...baseStyle, outline: '2px solid #2684FF' }
34
+ : baseStyle;
35
+
36
+ return (
37
+ <div
38
+ attribute-name={attributeName}
39
+ attribute-key={attributeKey}
40
+ style={style}
41
+ >
42
+ {String(node?.type ?? 'button')}
43
+ </div>
44
+ );
10
45
  }
11
46
 
12
47
  export default React.memo(Button);
@@ -2,6 +2,21 @@
2
2
 
3
3
  import type { NodeData } from '../../types/Node';
4
4
 
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type AlignItemsOptionType =
7
+ | 'flex-start'
8
+ | 'center'
9
+ | 'flex-end'
10
+ | 'stretch'
11
+ | 'baseline';
12
+ export type JustifyContentOptionType =
13
+ | 'flex-start'
14
+ | 'center'
15
+ | 'flex-end'
16
+ | 'space-between'
17
+ | 'space-around'
18
+ | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
5
20
  export type FontWeightOptionType =
6
21
  | 'normal'
7
22
  | 'bold'
@@ -18,8 +33,36 @@ export type FontWeightOptionType =
18
33
  export interface ButtonPropsGenerated {
19
34
  child: string;
20
35
  attributes: {
36
+ scrollable?: boolean;
37
+ flexDirection?: FlexDirectionOptionType;
38
+ alignItems?: AlignItemsOptionType;
39
+ justifyContent?: JustifyContentOptionType;
40
+ gap?: string;
41
+ padding?: string;
42
+ paddingHorizontal?: string;
43
+ paddingVertical?: string;
44
+ paddingTop?: string;
45
+ paddingBottom?: string;
46
+ paddingLeft?: string;
47
+ paddingRight?: string;
48
+ margin?: string;
49
+ marginVertical?: string;
50
+ marginTop?: string;
51
+ marginBottom?: string;
52
+ marginLeft?: string;
53
+ marginRight?: string;
54
+ backgroundColor?: string;
55
+ borderRadius?: string;
56
+ width?: string;
57
+ height?: string;
58
+ position?: PositionOptionType;
59
+ top?: string;
60
+ bottom?: string;
61
+ left?: string;
62
+ right?: string;
63
+ zIndex?: number;
21
64
  color?: string;
22
- fontSize?: number;
65
+ fontSize?: string;
23
66
  fontWeight?: FontWeightOptionType;
24
67
  };
25
68
  }
@@ -4,9 +4,10 @@
4
4
  "pattern": {
5
5
  "type": "button",
6
6
  "children": "string",
7
+ "extends": "View",
7
8
  "attributes": {
8
- "color": "string",
9
- "fontSize": "number",
9
+ "color": "color",
10
+ "fontSize": "size",
10
11
  "fontWeight": [
11
12
  "normal",
12
13
  "bold",
@@ -21,5 +22,33 @@
21
22
  "900"
22
23
  ]
23
24
  }
25
+ },
26
+ "meta": {
27
+ "desiredParent": ["all"],
28
+ "label": "Button",
29
+ "description": "Simple action button.",
30
+ "attributes": {
31
+ "color": {
32
+ "label": "Color",
33
+ "description": "Text color of the button.",
34
+ "category": "style",
35
+ "specialCategory": null,
36
+ "sort": 1
37
+ },
38
+ "fontSize": {
39
+ "label": "Font Size",
40
+ "description": "Text size of the button.",
41
+ "category": "style",
42
+ "specialCategory": null,
43
+ "sort": 2
44
+ },
45
+ "fontWeight": {
46
+ "label": "Font Weight",
47
+ "description": "Text weight of the button.",
48
+ "category": "style",
49
+ "specialCategory": null,
50
+ "sort": 3
51
+ }
52
+ }
24
53
  }
25
54
  }
@@ -1,13 +1,39 @@
1
- import React from 'react';
1
+ import React, { useId, useMemo } from 'react';
2
2
  import type { CarouselComponentProps } from './CarouselProps.generated';
3
3
  import RenderNode from '../RenderNode.generated';
4
4
  import { isCarouselItem } from '../../utils/isCarousel';
5
5
  import useNode from '../useNode';
6
+ import { useRenderStore } from '../../store';
6
7
  import { useLogRender } from '../../utils/useLogRender';
8
+ import { extractViewStyle } from '../../utils/extractViewStyle';
7
9
 
8
10
  function Carousel({ node }: CarouselComponentProps) {
9
11
  useLogRender('Carousel');
10
12
  node = useNode(node);
13
+ const generatedId = useId();
14
+ const attributeName = (node as any)?.sourceType ?? node.type ?? 'carousel';
15
+ const attributeKey = node.key ?? generatedId;
16
+ const { previewMode, current, appConfig, projectColors } = useRenderStore(
17
+ (s) => ({
18
+ previewMode: s.previewMode,
19
+ current: s.current,
20
+ appConfig: s.appConfig,
21
+ projectColors: s.projectColors,
22
+ }),
23
+ );
24
+ const baseStyle = useMemo(
25
+ () => extractViewStyle(node, { appConfig, projectColors }),
26
+ [node, appConfig, projectColors],
27
+ );
28
+ const isSelected =
29
+ previewMode &&
30
+ !!current &&
31
+ (current as any)?.key &&
32
+ (node as any)?.key &&
33
+ (current as any).key === (node as any).key;
34
+ const style = isSelected
35
+ ? { ...baseStyle, outline: '2px solid #2684FF' }
36
+ : baseStyle;
11
37
  // Ensure children are carouselItems
12
38
  const renderChildren = () => {
13
39
  if (Array.isArray(node.children)) {
@@ -20,7 +46,18 @@ function Carousel({ node }: CarouselComponentProps) {
20
46
  ) : null;
21
47
  };
22
48
 
23
- return <div className="embla__container">{renderChildren()}</div>;
49
+ //NOTE: I don't know how to force declare attribute-key. It must be added/checked manually.
50
+ //TODO: add to md file for agents
51
+ return (
52
+ <div
53
+ attribute-name={attributeName}
54
+ attribute-key={attributeKey}
55
+ className="embla__container"
56
+ style={style}
57
+ >
58
+ {renderChildren()}
59
+ </div>
60
+ );
24
61
  }
25
62
 
26
63
  export default React.memo(Carousel);
@@ -2,9 +2,54 @@
2
2
 
3
3
  import type { NodeData } from '../../types/Node';
4
4
 
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type AlignItemsOptionType =
7
+ | 'flex-start'
8
+ | 'center'
9
+ | 'flex-end'
10
+ | 'stretch'
11
+ | 'baseline';
12
+ export type JustifyContentOptionType =
13
+ | 'flex-start'
14
+ | 'center'
15
+ | 'flex-end'
16
+ | 'space-between'
17
+ | 'space-around'
18
+ | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
20
+
5
21
  export interface CarouselPropsGenerated {
6
22
  child: string;
7
- attributes: {};
23
+ attributes: {
24
+ scrollable?: boolean;
25
+ flexDirection?: FlexDirectionOptionType;
26
+ alignItems?: AlignItemsOptionType;
27
+ justifyContent?: JustifyContentOptionType;
28
+ gap?: string;
29
+ padding?: string;
30
+ paddingHorizontal?: string;
31
+ paddingVertical?: string;
32
+ paddingTop?: string;
33
+ paddingBottom?: string;
34
+ paddingLeft?: string;
35
+ paddingRight?: string;
36
+ margin?: string;
37
+ marginVertical?: string;
38
+ marginTop?: string;
39
+ marginBottom?: string;
40
+ marginLeft?: string;
41
+ marginRight?: string;
42
+ backgroundColor?: string;
43
+ borderRadius?: string;
44
+ width?: string;
45
+ height?: string;
46
+ position?: PositionOptionType;
47
+ top?: string;
48
+ bottom?: string;
49
+ left?: string;
50
+ right?: string;
51
+ zIndex?: number;
52
+ };
8
53
  }
9
54
 
10
55
  export interface CarouselComponentProps {
@@ -2,8 +2,18 @@
2
2
  "schemaVersion": 1,
3
3
  "allowUnknownAttributes": false,
4
4
  "pattern": {
5
+ "extends": "View",
5
6
  "type": "carousel",
6
7
  "children": "carouselItem",
8
+ "attributes": {},
9
+ "defaults": {
10
+ "flexDirection": "row"
11
+ }
12
+ },
13
+ "meta": {
14
+ "desiredParent": ["=CarouselProvider"],
15
+ "label": "Carousel",
16
+ "description": "Container for carousel items.",
7
17
  "attributes": {}
8
18
  }
9
19
  }
@@ -1,12 +1,26 @@
1
- import React, { useContext } from 'react';
1
+ import React, { useContext, useId, useMemo } from 'react';
2
2
  import type { CarouselButtonsComponentProps } from './CarouselButtonsProps.generated';
3
3
  import { carouselContext } from '../CarouselProvider/CarouselProvider';
4
4
  import useNode from '../useNode';
5
5
  import { useLogRender } from '../../utils/useLogRender';
6
+ import { extractViewStyle } from '../../utils/extractViewStyle';
7
+ import { useRenderStore } from '../../store';
6
8
 
7
9
  function CarouselButtons({ node }: CarouselButtonsComponentProps) {
8
10
  useLogRender('CarouselButtons');
9
11
  node = useNode(node);
12
+ const generatedId = useId();
13
+ const attributeName =
14
+ (node as any)?.sourceType ?? node.type ?? 'carouselButtons';
15
+ const attributeKey = node.key ?? generatedId;
16
+ const { appConfig, projectColors } = useRenderStore((s) => ({
17
+ appConfig: s.appConfig,
18
+ projectColors: s.projectColors,
19
+ }));
20
+ const style = useMemo(
21
+ () => extractViewStyle(node, { appConfig, projectColors }),
22
+ [node, appConfig, projectColors],
23
+ );
10
24
  const emblaApi = useContext(carouselContext);
11
25
  const buttonTypes = node.attributes?.buttonType || [
12
26
  'previous_button',
@@ -14,7 +28,12 @@ function CarouselButtons({ node }: CarouselButtonsComponentProps) {
14
28
  ];
15
29
 
16
30
  return (
17
- <div className="embla__buttons">
31
+ <div
32
+ attribute-name={attributeName}
33
+ attribute-key={attributeKey}
34
+ className="embla__buttons"
35
+ style={style}
36
+ >
18
37
  {buttonTypes.includes('previous_button') && (
19
38
  <button
20
39
  onClick={() => emblaApi?.scrollPrev()}
@@ -2,6 +2,21 @@
2
2
 
3
3
  import type { NodeData } from '../../types/Node';
4
4
 
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type AlignItemsOptionType =
7
+ | 'flex-start'
8
+ | 'center'
9
+ | 'flex-end'
10
+ | 'stretch'
11
+ | 'baseline';
12
+ export type JustifyContentOptionType =
13
+ | 'flex-start'
14
+ | 'center'
15
+ | 'flex-end'
16
+ | 'space-between'
17
+ | 'space-around'
18
+ | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
5
20
  export type ButtonTypeOptionType =
6
21
  | 'previous_button'
7
22
  | 'next_button'
@@ -10,6 +25,34 @@ export type ButtonTypeOptionType =
10
25
  export interface CarouselButtonsPropsGenerated {
11
26
  child: string;
12
27
  attributes: {
28
+ scrollable?: boolean;
29
+ flexDirection?: FlexDirectionOptionType;
30
+ alignItems?: AlignItemsOptionType;
31
+ justifyContent?: JustifyContentOptionType;
32
+ gap?: string;
33
+ padding?: string;
34
+ paddingHorizontal?: string;
35
+ paddingVertical?: string;
36
+ paddingTop?: string;
37
+ paddingBottom?: string;
38
+ paddingLeft?: string;
39
+ paddingRight?: string;
40
+ margin?: string;
41
+ marginVertical?: string;
42
+ marginTop?: string;
43
+ marginBottom?: string;
44
+ marginLeft?: string;
45
+ marginRight?: string;
46
+ backgroundColor?: string;
47
+ borderRadius?: string;
48
+ width?: string;
49
+ height?: string;
50
+ position?: PositionOptionType;
51
+ top?: string;
52
+ bottom?: string;
53
+ left?: string;
54
+ right?: string;
55
+ zIndex?: number;
13
56
  buttonType?: ButtonTypeOptionType;
14
57
  skipNumber?: number;
15
58
  };
@@ -4,9 +4,31 @@
4
4
  "pattern": {
5
5
  "type": "carouselButtons",
6
6
  "children": "never",
7
+ "extends": "View",
7
8
  "attributes": {
8
9
  "buttonType": ["previous_button", "next_button", "skip_button"],
9
10
  "skipNumber": "number"
10
11
  }
12
+ },
13
+ "meta": {
14
+ "desiredParent": [">OnboardProvider", ">CarouselProvider"],
15
+ "label": "Carousel Buttons",
16
+ "description": "Renders built-in carousel buttons.",
17
+ "attributes": {
18
+ "buttonType": {
19
+ "label": "Button Type",
20
+ "description": "Which carousel button to show.",
21
+ "category": "other",
22
+ "specialCategory": null,
23
+ "sort": 1
24
+ },
25
+ "skipNumber": {
26
+ "label": "Skip Number",
27
+ "description": "Index to skip to when tapped.",
28
+ "category": "other",
29
+ "specialCategory": null,
30
+ "sort": 2
31
+ }
32
+ }
11
33
  }
12
34
  }
@@ -1,28 +1,69 @@
1
- import React, { useContext, useEffect, useState } from 'react';
1
+ import React, { useContext, useEffect, useId, useMemo, useState } from 'react';
2
2
  import type { CarouselDotsComponentProps } from './CarouselDotsProps.generated';
3
3
  import { carouselContext } from '../CarouselProvider/CarouselProvider';
4
+ import { onboardContext } from '../OnboardProvider/OnboardProvider';
4
5
  import useNode from '../useNode';
5
6
  import { useLogRender } from '../../utils/useLogRender';
7
+ import { extractViewStyle } from '../../utils/extractViewStyle';
8
+ import { useRenderStore } from '../../store';
6
9
 
7
10
  function CarouselDots({ node }: CarouselDotsComponentProps) {
8
11
  useLogRender('CarouselDots');
12
+
9
13
  node = useNode(node);
14
+
15
+ const generatedId = useId();
16
+ const attributeName =
17
+ (node as any)?.sourceType ?? node.type ?? 'carouselDots';
18
+ const attributeKey = node.key ?? generatedId;
19
+
10
20
  const dotType = node.attributes?.dotType || 'normal_dot';
11
- const emblaApi = useContext(carouselContext);
21
+ const { appConfig, projectColors } = useRenderStore((s) => ({
22
+ appConfig: s.appConfig,
23
+ projectColors: s.projectColors,
24
+ }));
25
+
26
+ const style = useMemo(() => {
27
+ return extractViewStyle(node, { appConfig, projectColors });
28
+ }, [node, appConfig, projectColors]);
29
+
30
+ // Use the appropriate context based on sourceType
31
+ const isOnboard = (node as any)?.sourceType === 'OnboardDot';
32
+ const carouselApi = useContext(carouselContext);
33
+ const onboardApi = useContext(onboardContext);
34
+ const emblaApi = isOnboard ? onboardApi?.emblaApi : carouselApi;
35
+
12
36
  const [selectedIndex, setSelectedIndex] = useState(0);
13
37
  const [scrollSnaps, setScrollSnaps] = useState<number[]>([]);
14
38
 
15
39
  useEffect(() => {
16
40
  if (!emblaApi) return;
17
- setScrollSnaps(emblaApi.scrollSnapList());
18
- setSelectedIndex(emblaApi.selectedScrollSnap());
19
- emblaApi.on('select', () => {
20
- setSelectedIndex(emblaApi.selectedScrollSnap());
21
- });
41
+ const snaps = emblaApi.scrollSnapList();
42
+ const selected = emblaApi.selectedScrollSnap();
43
+ setScrollSnaps(snaps);
44
+ setSelectedIndex(selected);
45
+
46
+ const onSelect = () => {
47
+ const sel = emblaApi.selectedScrollSnap();
48
+ setSelectedIndex(sel);
49
+ };
50
+ emblaApi.on('select', onSelect);
51
+
52
+ // Potential cleanup if necessary
53
+ return () => {
54
+ if (emblaApi && emblaApi.off) {
55
+ emblaApi.off('select', onSelect);
56
+ }
57
+ };
22
58
  }, [emblaApi]);
23
59
 
24
60
  return (
25
- <div className={`embla__dots embla__dots--${dotType}`}>
61
+ <div
62
+ attribute-name={attributeName}
63
+ attribute-key={attributeKey}
64
+ className={`embla__dots embla__dots--${dotType}`}
65
+ style={style}
66
+ >
26
67
  {scrollSnaps.map((snap, index) => (
27
68
  <button
28
69
  key={index}
@@ -2,6 +2,21 @@
2
2
 
3
3
  import type { NodeData } from '../../types/Node';
4
4
 
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type AlignItemsOptionType =
7
+ | 'flex-start'
8
+ | 'center'
9
+ | 'flex-end'
10
+ | 'stretch'
11
+ | 'baseline';
12
+ export type JustifyContentOptionType =
13
+ | 'flex-start'
14
+ | 'center'
15
+ | 'flex-end'
16
+ | 'space-between'
17
+ | 'space-around'
18
+ | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
5
20
  export type DotTypeOptionType =
6
21
  | 'expanding_dot'
7
22
  | 'normal_dot'
@@ -13,6 +28,34 @@ export type DotTypeOptionType =
13
28
  export interface CarouselDotsPropsGenerated {
14
29
  child: string;
15
30
  attributes: {
31
+ scrollable?: boolean;
32
+ flexDirection?: FlexDirectionOptionType;
33
+ alignItems?: AlignItemsOptionType;
34
+ justifyContent?: JustifyContentOptionType;
35
+ gap?: string;
36
+ padding?: string;
37
+ paddingHorizontal?: string;
38
+ paddingVertical?: string;
39
+ paddingTop?: string;
40
+ paddingBottom?: string;
41
+ paddingLeft?: string;
42
+ paddingRight?: string;
43
+ margin?: string;
44
+ marginVertical?: string;
45
+ marginTop?: string;
46
+ marginBottom?: string;
47
+ marginLeft?: string;
48
+ marginRight?: string;
49
+ backgroundColor?: string;
50
+ borderRadius?: string;
51
+ width?: string;
52
+ height?: string;
53
+ position?: PositionOptionType;
54
+ top?: string;
55
+ bottom?: string;
56
+ left?: string;
57
+ right?: string;
58
+ zIndex?: number;
16
59
  dotType?: DotTypeOptionType;
17
60
  };
18
61
  }
@@ -4,6 +4,7 @@
4
4
  "pattern": {
5
5
  "type": "carouselDots",
6
6
  "children": "never",
7
+ "extends": "View",
7
8
  "attributes": {
8
9
  "dotType": [
9
10
  "expanding_dot",
@@ -14,5 +15,19 @@
14
15
  "liquid_like"
15
16
  ]
16
17
  }
18
+ },
19
+ "meta": {
20
+ "desiredParent": [">CarouselProvider"],
21
+ "label": "Carousel Dots",
22
+ "description": "Renders page indicator dots.",
23
+ "attributes": {
24
+ "dotType": {
25
+ "label": "Dot Type",
26
+ "description": "Style used for the dots.",
27
+ "category": "style",
28
+ "specialCategory": null,
29
+ "sort": 1
30
+ }
31
+ }
17
32
  }
18
33
  }
@@ -1,14 +1,33 @@
1
- import React from 'react';
1
+ import React, { useId, useMemo } from 'react';
2
2
  import type { CarouselItemComponentProps } from './CarouselItemProps.generated';
3
3
  import { RenderNode } from '../..';
4
4
  import useNode from '../useNode';
5
5
  import { useLogRender } from '../../utils/useLogRender';
6
+ import { extractViewStyle } from '../../utils/extractViewStyle';
7
+ import { useRenderStore } from '../../store';
6
8
 
7
9
  export function CarouselItem({ node }: CarouselItemComponentProps) {
8
10
  useLogRender('CarouselItem');
9
11
  node = useNode(node);
12
+ const generatedId = useId();
13
+ const attributeName =
14
+ (node as any)?.sourceType ?? node.type ?? 'carouselItem';
15
+ const attributeKey = node.key ?? generatedId;
16
+ const { appConfig, projectColors } = useRenderStore((s) => ({
17
+ appConfig: s.appConfig,
18
+ projectColors: s.projectColors,
19
+ }));
20
+ const style = useMemo(
21
+ () => extractViewStyle(node, { appConfig, projectColors }),
22
+ [node, appConfig, projectColors],
23
+ );
10
24
  return (
11
- <div className="embla__slide" {...node.attributes}>
25
+ <div
26
+ className="embla__slide"
27
+ attribute-name={attributeName}
28
+ attribute-key={attributeKey}
29
+ style={style}
30
+ >
12
31
  {node.children && <RenderNode node={node.children} />}
13
32
  </div>
14
33
  );
@@ -2,9 +2,54 @@
2
2
 
3
3
  import type { NodeData } from '../../types/Node';
4
4
 
5
+ export type FlexDirectionOptionType = 'row' | 'column';
6
+ export type AlignItemsOptionType =
7
+ | 'flex-start'
8
+ | 'center'
9
+ | 'flex-end'
10
+ | 'stretch'
11
+ | 'baseline';
12
+ export type JustifyContentOptionType =
13
+ | 'flex-start'
14
+ | 'center'
15
+ | 'flex-end'
16
+ | 'space-between'
17
+ | 'space-around'
18
+ | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
20
+
5
21
  export interface CarouselItemPropsGenerated {
6
22
  child: string;
7
- attributes: {};
23
+ attributes: {
24
+ scrollable?: boolean;
25
+ flexDirection?: FlexDirectionOptionType;
26
+ alignItems?: AlignItemsOptionType;
27
+ justifyContent?: JustifyContentOptionType;
28
+ gap?: string;
29
+ padding?: string;
30
+ paddingHorizontal?: string;
31
+ paddingVertical?: string;
32
+ paddingTop?: string;
33
+ paddingBottom?: string;
34
+ paddingLeft?: string;
35
+ paddingRight?: string;
36
+ margin?: string;
37
+ marginVertical?: string;
38
+ marginTop?: string;
39
+ marginBottom?: string;
40
+ marginLeft?: string;
41
+ marginRight?: string;
42
+ backgroundColor?: string;
43
+ borderRadius?: string;
44
+ width?: string;
45
+ height?: string;
46
+ position?: PositionOptionType;
47
+ top?: string;
48
+ bottom?: string;
49
+ left?: string;
50
+ right?: string;
51
+ zIndex?: number;
52
+ };
8
53
  }
9
54
 
10
55
  export interface CarouselItemComponentProps {