@developer_tribe/react-builder 1.0.2 → 1.0.4

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 (147) hide show
  1. package/dist/AttributesEditor.d.ts +3 -1
  2. package/dist/RenderPage.d.ts +2 -1
  3. package/dist/android.svg +43 -0
  4. package/dist/apple.svg +16 -0
  5. package/dist/attributes-editor/Field.d.ts +4 -2
  6. package/dist/attributes-editor/SizeField.d.ts +9 -0
  7. package/dist/attributes-editor/SpecialCategorySection.d.ts +2 -1
  8. package/dist/build-components/BackgroundImage/BackgroundImage.d.ts +5 -0
  9. package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +45 -0
  10. package/dist/build-components/Button/ButtonProps.generated.d.ts +8 -0
  11. package/dist/build-components/Carousel/CarouselProps.generated.d.ts +8 -0
  12. package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +8 -0
  13. package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +8 -0
  14. package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +8 -0
  15. package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +8 -0
  16. package/dist/build-components/Image/ImageProps.generated.d.ts +8 -0
  17. package/dist/build-components/Onboard/OnboardProps.generated.d.ts +8 -0
  18. package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +8 -1
  19. package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +8 -0
  20. package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +9 -3
  21. package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +8 -0
  22. package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +9 -1
  23. package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +8 -0
  24. package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +8 -1
  25. package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +8 -0
  26. package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +8 -0
  27. package/dist/build-components/Text/TextProps.generated.d.ts +8 -0
  28. package/dist/build-components/View/ViewProps.generated.d.ts +8 -0
  29. package/dist/build-components/index.d.ts +2 -1
  30. package/dist/build-components/patterns.generated.d.ts +1612 -46
  31. package/dist/components/AttributesEditorPanel.d.ts +3 -4
  32. package/dist/components/Builder.d.ts +2 -1
  33. package/dist/components/BuilderButton.d.ts +9 -0
  34. package/dist/components/JsonTextEditor.d.ts +9 -0
  35. package/dist/index.cjs.js +5 -5
  36. package/dist/index.cjs.js.map +1 -1
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.esm.js +5 -5
  39. package/dist/index.esm.js.map +1 -1
  40. package/dist/modals/ColorModal.d.ts +3 -1
  41. package/dist/pages/ProjectPage.d.ts +3 -3
  42. package/dist/pages/tabs/BuilderPanel.d.ts +8 -0
  43. package/dist/pages/tabs/SideTool.d.ts +8 -0
  44. package/dist/store.d.ts +9 -1
  45. package/dist/styles.css +1 -1
  46. package/dist/types/Project.d.ts +11 -0
  47. package/dist/utils/analyseNode.d.ts +1 -0
  48. package/dist/utils/extractImageStyle.d.ts +2 -1
  49. package/dist/utils/extractTextStyle.d.ts +8 -1
  50. package/dist/utils/extractViewStyle.d.ts +7 -1
  51. package/dist/utils/parseColor.d.ts +7 -0
  52. package/dist/utils/selection.d.ts +7 -0
  53. package/dist/utils/useMergedStyle.d.ts +2 -0
  54. package/package.json +2 -5
  55. package/src/.DS_Store +0 -0
  56. package/src/AttributesEditor.tsx +83 -16
  57. package/src/RenderPage.tsx +86 -4
  58. package/src/attributes-editor/Field.tsx +60 -165
  59. package/src/attributes-editor/SizeField.tsx +184 -0
  60. package/src/attributes-editor/SpecialCategorySection.tsx +12 -4
  61. package/src/build-components/BackgroundImage/BackgroundImage.tsx +77 -0
  62. package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +61 -0
  63. package/src/build-components/BackgroundImage/pattern.json +45 -0
  64. package/src/build-components/Button/Button.tsx +29 -4
  65. package/src/build-components/Button/ButtonProps.generated.ts +8 -0
  66. package/src/build-components/Carousel/Carousel.tsx +25 -3
  67. package/src/build-components/Carousel/CarouselProps.generated.ts +8 -0
  68. package/src/build-components/CarouselButtons/CarouselButtons.tsx +19 -4
  69. package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +8 -0
  70. package/src/build-components/CarouselDots/CarouselDots.tsx +13 -4
  71. package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +8 -0
  72. package/src/build-components/CarouselItem/CarouselItem.tsx +20 -4
  73. package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +8 -0
  74. package/src/build-components/CarouselProvider/CarouselProvider.tsx +14 -3
  75. package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +8 -0
  76. package/src/build-components/Image/Image.tsx +27 -9
  77. package/src/build-components/Image/ImageProps.generated.ts +8 -0
  78. package/src/build-components/Image/pattern.json +1 -9
  79. package/src/build-components/Onboard/Onboard.tsx +2 -2
  80. package/src/build-components/Onboard/OnboardProps.generated.ts +8 -0
  81. package/src/build-components/OnboardButton/OnboardButton.tsx +11 -7
  82. package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +8 -1
  83. package/src/build-components/OnboardButtons/OnboardButtons.tsx +17 -5
  84. package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +8 -0
  85. package/src/build-components/OnboardDot/OnboardDot.tsx +68 -39
  86. package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +9 -3
  87. package/src/build-components/OnboardDot/pattern.json +3 -19
  88. package/src/build-components/OnboardFooter/OnboardFooter.tsx +37 -14
  89. package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +8 -0
  90. package/src/build-components/OnboardImage/OnboardImage.tsx +28 -6
  91. package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +9 -1
  92. package/src/build-components/OnboardItem/OnboardItem.tsx +15 -14
  93. package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +8 -0
  94. package/src/build-components/OnboardProvider/OnboardProvider.tsx +35 -20
  95. package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +8 -1
  96. package/src/build-components/OnboardProvider/pattern.json +0 -8
  97. package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +8 -0
  98. package/src/build-components/OnboardSubtitle/pattern.json +1 -1
  99. package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +8 -0
  100. package/src/build-components/OnboardTitle/pattern.json +1 -1
  101. package/src/build-components/RenderNode.generated.tsx +3 -0
  102. package/src/build-components/Text/Text.tsx +28 -10
  103. package/src/build-components/Text/TextProps.generated.ts +8 -0
  104. package/src/build-components/View/View.tsx +25 -3
  105. package/src/build-components/View/ViewProps.generated.ts +8 -0
  106. package/src/build-components/View/pattern.json +67 -1
  107. package/src/build-components/index.ts +5 -0
  108. package/src/build-components/patterns.generated.ts +1620 -46
  109. package/src/components/AttributesEditorPanel.tsx +13 -6
  110. package/src/components/Builder.tsx +200 -56
  111. package/src/components/BuilderButton.tsx +127 -0
  112. package/src/components/DeviceNavigationBar.tsx +0 -1
  113. package/src/components/EditorHeader.tsx +11 -1
  114. package/src/components/JsonTextEditor.tsx +185 -0
  115. package/src/index.ts +2 -2
  116. package/src/mockOS/components/MockOSRouter.tsx +17 -3
  117. package/src/mockOS/context/MockOSContext.tsx +0 -5
  118. package/src/mockOS/managers/mockPermissionManager.ts +0 -4
  119. package/src/mockOS/managers/navigationManager.ts +1 -6
  120. package/src/modals/ColorModal.tsx +306 -71
  121. package/src/modals/LocalicationModal.tsx +4 -5
  122. package/src/modals/Modal.tsx +8 -1
  123. package/src/pages/ProjectPage.tsx +299 -55
  124. package/src/pages/tabs/{BuilderTab.tsx → BuilderPanel.tsx} +13 -9
  125. package/src/pages/tabs/SideTool.tsx +260 -0
  126. package/src/size-matters/index.ts +6 -0
  127. package/src/store.ts +18 -1
  128. package/src/styles/base/_global.scss +163 -7
  129. package/src/styles/components/_attributes-editor.scss +12 -0
  130. package/src/styles/components/_editor-shell.scss +25 -0
  131. package/src/styles/foundation/_sizes.scss +1 -1
  132. package/src/styles/layout/_builder.scss +66 -10
  133. package/src/styles/modals/_color-modal.scss +59 -1
  134. package/src/styles/utilities/_carousel.scss +9 -8
  135. package/src/types/Project.ts +14 -0
  136. package/src/utils/analyseNode.ts +98 -0
  137. package/src/utils/extractImageStyle.ts +3 -6
  138. package/src/utils/extractTextStyle.ts +19 -82
  139. package/src/utils/extractViewStyle.ts +41 -12
  140. package/src/utils/parseColor.ts +43 -0
  141. package/src/utils/selection.ts +24 -0
  142. package/src/utils/useMergedStyle.ts +16 -0
  143. package/dist/pages/tabs/BuilderTab.d.ts +0 -9
  144. package/dist/pages/tabs/DebugTab.d.ts +0 -7
  145. package/dist/pages/tabs/PreviewTab.d.ts +0 -3
  146. package/src/pages/tabs/DebugTab.tsx +0 -64
  147. package/src/pages/tabs/PreviewTab.tsx +0 -206
@@ -1,17 +1,42 @@
1
- import React, { useMemo } 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';
5
6
  import { extractViewStyle } from '../../utils/extractViewStyle';
7
+ import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
8
+ import { useMergedStyle } from '../../utils/useMergedStyle';
6
9
 
7
10
  function Button({ node }: ButtonComponentProps) {
8
11
  useLogRender('Button');
9
12
  node = useNode(node);
10
- const attributeKey = (node as any)?.sourceType ?? node.type ?? 'button';
11
- const style = useMemo(() => extractViewStyle(node), [node]);
13
+ const generatedId = useId();
14
+ const attributeName = (node as any)?.sourceType ?? node.type ?? 'button';
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 = isNodeSelected({ previewMode, current, node });
29
+ const style = useMergedStyle(
30
+ baseStyle,
31
+ isSelected ? SELECTED_OUTLINE_STYLE : undefined,
32
+ );
12
33
 
13
34
  return (
14
- <div attribute-key={attributeKey} style={style}>
35
+ <div
36
+ attribute-name={attributeName}
37
+ attribute-key={attributeKey}
38
+ style={style}
39
+ >
15
40
  {String(node?.type ?? 'button')}
16
41
  </div>
17
42
  );
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
  export type FontWeightOptionType =
20
21
  | 'normal'
21
22
  | 'bold'
@@ -54,6 +55,13 @@ export interface ButtonPropsGenerated {
54
55
  borderRadius?: string;
55
56
  width?: string;
56
57
  height?: string;
58
+ flex?: number;
59
+ position?: PositionOptionType;
60
+ top?: string;
61
+ bottom?: string;
62
+ left?: string;
63
+ right?: string;
64
+ zIndex?: number;
57
65
  color?: string;
58
66
  fontSize?: string;
59
67
  fontWeight?: FontWeightOptionType;
@@ -1,16 +1,37 @@
1
- import React, { useMemo } 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';
7
8
  import { extractViewStyle } from '../../utils/extractViewStyle';
9
+ import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
10
+ import { useMergedStyle } from '../../utils/useMergedStyle';
8
11
 
9
12
  function Carousel({ node }: CarouselComponentProps) {
10
13
  useLogRender('Carousel');
11
14
  node = useNode(node);
12
- const attributeKey = (node as any)?.sourceType ?? node.type ?? 'carousel';
13
- const style = useMemo(() => extractViewStyle(node), [node]);
15
+ const generatedId = useId();
16
+ const attributeName = (node as any)?.sourceType ?? node.type ?? 'carousel';
17
+ const attributeKey = node.key ?? generatedId;
18
+ const { previewMode, current, appConfig, projectColors } = useRenderStore(
19
+ (s) => ({
20
+ previewMode: s.previewMode,
21
+ current: s.current,
22
+ appConfig: s.appConfig,
23
+ projectColors: s.projectColors,
24
+ }),
25
+ );
26
+ const baseStyle = useMemo(
27
+ () => extractViewStyle(node, { appConfig, projectColors }),
28
+ [node, appConfig, projectColors],
29
+ );
30
+ const isSelected = isNodeSelected({ previewMode, current, node });
31
+ const style = useMergedStyle(
32
+ baseStyle,
33
+ isSelected ? SELECTED_OUTLINE_STYLE : undefined,
34
+ );
14
35
  // Ensure children are carouselItems
15
36
  const renderChildren = () => {
16
37
  if (Array.isArray(node.children)) {
@@ -27,6 +48,7 @@ function Carousel({ node }: CarouselComponentProps) {
27
48
  //TODO: add to md file for agents
28
49
  return (
29
50
  <div
51
+ attribute-name={attributeName}
30
52
  attribute-key={attributeKey}
31
53
  className="embla__container"
32
54
  style={style}
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
 
20
21
  export interface CarouselPropsGenerated {
21
22
  child: string;
@@ -42,6 +43,13 @@ export interface CarouselPropsGenerated {
42
43
  borderRadius?: string;
43
44
  width?: string;
44
45
  height?: string;
46
+ flex?: number;
47
+ position?: PositionOptionType;
48
+ top?: string;
49
+ bottom?: string;
50
+ left?: string;
51
+ right?: string;
52
+ zIndex?: number;
45
53
  };
46
54
  }
47
55
 
@@ -1,16 +1,26 @@
1
- import React, { useContext, useMemo } 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
6
  import { extractViewStyle } from '../../utils/extractViewStyle';
7
+ import { useRenderStore } from '../../store';
7
8
 
8
9
  function CarouselButtons({ node }: CarouselButtonsComponentProps) {
9
10
  useLogRender('CarouselButtons');
10
11
  node = useNode(node);
11
- const attributeKey =
12
+ const generatedId = useId();
13
+ const attributeName =
12
14
  (node as any)?.sourceType ?? node.type ?? 'carouselButtons';
13
- const style = useMemo(() => extractViewStyle(node), [node]);
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
+ );
14
24
  const emblaApi = useContext(carouselContext);
15
25
  const buttonTypes = node.attributes?.buttonType || [
16
26
  'previous_button',
@@ -18,7 +28,12 @@ function CarouselButtons({ node }: CarouselButtonsComponentProps) {
18
28
  ];
19
29
 
20
30
  return (
21
- <div attribute-key={attributeKey} className="embla__buttons" style={style}>
31
+ <div
32
+ attribute-name={attributeName}
33
+ attribute-key={attributeKey}
34
+ className="embla__buttons"
35
+ style={style}
36
+ >
22
37
  {buttonTypes.includes('previous_button') && (
23
38
  <button
24
39
  onClick={() => emblaApi?.scrollPrev()}
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
  export type ButtonTypeOptionType =
20
21
  | 'previous_button'
21
22
  | 'next_button'
@@ -46,6 +47,13 @@ export interface CarouselButtonsPropsGenerated {
46
47
  borderRadius?: string;
47
48
  width?: string;
48
49
  height?: string;
50
+ flex?: number;
51
+ position?: PositionOptionType;
52
+ top?: string;
53
+ bottom?: string;
54
+ left?: string;
55
+ right?: string;
56
+ zIndex?: number;
49
57
  buttonType?: ButtonTypeOptionType;
50
58
  skipNumber?: number;
51
59
  };
@@ -1,23 +1,31 @@
1
- import React, { useContext, useEffect, useMemo, 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
4
  import { onboardContext } from '../OnboardProvider/OnboardProvider';
5
5
  import useNode from '../useNode';
6
6
  import { useLogRender } from '../../utils/useLogRender';
7
7
  import { extractViewStyle } from '../../utils/extractViewStyle';
8
+ import { useRenderStore } from '../../store';
8
9
 
9
10
  function CarouselDots({ node }: CarouselDotsComponentProps) {
10
11
  useLogRender('CarouselDots');
11
12
 
12
13
  node = useNode(node);
13
14
 
14
- const attributeKey = (node as any)?.sourceType ?? node.type ?? 'carouselDots';
15
+ const generatedId = useId();
16
+ const attributeName =
17
+ (node as any)?.sourceType ?? node.type ?? 'carouselDots';
18
+ const attributeKey = node.key ?? generatedId;
15
19
 
16
20
  const dotType = node.attributes?.dotType || 'normal_dot';
21
+ const { appConfig, projectColors } = useRenderStore((s) => ({
22
+ appConfig: s.appConfig,
23
+ projectColors: s.projectColors,
24
+ }));
17
25
 
18
26
  const style = useMemo(() => {
19
- return extractViewStyle(node);
20
- }, [node]);
27
+ return extractViewStyle(node, { appConfig, projectColors });
28
+ }, [node, appConfig, projectColors]);
21
29
 
22
30
  // Use the appropriate context based on sourceType
23
31
  const isOnboard = (node as any)?.sourceType === 'OnboardDot';
@@ -51,6 +59,7 @@ function CarouselDots({ node }: CarouselDotsComponentProps) {
51
59
 
52
60
  return (
53
61
  <div
62
+ attribute-name={attributeName}
54
63
  attribute-key={attributeKey}
55
64
  className={`embla__dots embla__dots--${dotType}`}
56
65
  style={style}
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
  export type DotTypeOptionType =
20
21
  | 'expanding_dot'
21
22
  | 'normal_dot'
@@ -49,6 +50,13 @@ export interface CarouselDotsPropsGenerated {
49
50
  borderRadius?: string;
50
51
  width?: string;
51
52
  height?: string;
53
+ flex?: number;
54
+ position?: PositionOptionType;
55
+ top?: string;
56
+ bottom?: string;
57
+ left?: string;
58
+ right?: string;
59
+ zIndex?: number;
52
60
  dotType?: DotTypeOptionType;
53
61
  };
54
62
  }
@@ -1,17 +1,33 @@
1
- import React, { useMemo } 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
6
  import { extractViewStyle } from '../../utils/extractViewStyle';
7
+ import { useRenderStore } from '../../store';
7
8
 
8
9
  export function CarouselItem({ node }: CarouselItemComponentProps) {
9
10
  useLogRender('CarouselItem');
10
11
  node = useNode(node);
11
- const attributeKey = (node as any)?.sourceType ?? node.type ?? 'carouselItem';
12
- const style = useMemo(() => extractViewStyle(node), [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
+ );
13
24
  return (
14
- <div className="embla__slide" attribute-key={attributeKey} style={style}>
25
+ <div
26
+ className="embla__slide"
27
+ attribute-name={attributeName}
28
+ attribute-key={attributeKey}
29
+ style={style}
30
+ >
15
31
  {node.children && <RenderNode node={node.children} />}
16
32
  </div>
17
33
  );
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
 
20
21
  export interface CarouselItemPropsGenerated {
21
22
  child: string;
@@ -42,6 +43,13 @@ export interface CarouselItemPropsGenerated {
42
43
  borderRadius?: string;
43
44
  width?: string;
44
45
  height?: string;
46
+ flex?: number;
47
+ position?: PositionOptionType;
48
+ top?: string;
49
+ bottom?: string;
50
+ left?: string;
51
+ right?: string;
52
+ zIndex?: number;
45
53
  };
46
54
  }
47
55
 
@@ -1,20 +1,31 @@
1
- import React, { createContext, useMemo } from 'react';
1
+ import React, { createContext, useId, useMemo } from 'react';
2
2
  import type { CarouselProviderComponentProps } from './CarouselProviderProps.generated';
3
3
  import { RenderNode } from '../..';
4
4
  import useEmblaCarousel from 'embla-carousel-react';
5
5
  import useNode from '../useNode';
6
6
  import { extractViewStyle } from '../../utils/extractViewStyle';
7
+ import { useRenderStore } from '../../store';
7
8
 
8
9
  export const carouselContext = createContext<any>(undefined);
9
10
  function CarouselProvider({ node }: CarouselProviderComponentProps) {
10
11
  node = useNode(node);
11
12
  const [emblaRef, emblaApi] = useEmblaCarousel(node.attributes as any);
12
- const attributeKey =
13
+ const generatedId = useId();
14
+ const attributeName =
13
15
  (node as any)?.sourceType ?? node.type ?? 'carouselProvider';
14
- const viewStyle = useMemo(() => extractViewStyle(node), [node]);
16
+ const attributeKey = node.key ?? generatedId;
17
+ const { appConfig, projectColors } = useRenderStore((s) => ({
18
+ appConfig: s.appConfig,
19
+ projectColors: s.projectColors,
20
+ }));
21
+ const viewStyle = useMemo(
22
+ () => extractViewStyle(node, { appConfig, projectColors }),
23
+ [node, appConfig, projectColors],
24
+ );
15
25
  return (
16
26
  <carouselContext.Provider value={emblaApi}>
17
27
  <div
28
+ attribute-name={attributeName}
18
29
  attribute-key={attributeKey}
19
30
  className="carousel-provider"
20
31
  style={viewStyle}
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
 
20
21
  export interface CarouselProviderPropsGenerated {
21
22
  child: string;
@@ -42,6 +43,13 @@ export interface CarouselProviderPropsGenerated {
42
43
  borderRadius?: string;
43
44
  width?: string;
44
45
  height?: string;
46
+ flex?: number;
47
+ position?: PositionOptionType;
48
+ top?: string;
49
+ bottom?: string;
50
+ left?: string;
51
+ right?: string;
52
+ zIndex?: number;
45
53
  };
46
54
  }
47
55
 
@@ -1,24 +1,42 @@
1
- import React, { useMemo } from 'react';
1
+ import React, { useId, useMemo } from 'react';
2
2
  import type { ImageComponentProps } from './ImageProps.generated';
3
3
  import useNode from '../useNode';
4
+ import { useRenderStore } from '../../store';
4
5
  import { extractImageStyle } from '../../utils/extractImageStyle';
5
- import { extractViewStyle } from '../../utils/extractViewStyle';
6
6
  import { useLogRender } from '../../utils/useLogRender';
7
+ import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
8
+ import { useMergedStyle } from '../../utils/useMergedStyle';
7
9
 
8
10
  function Image({ node }: ImageComponentProps) {
9
11
  useLogRender('Image');
10
12
  node = useNode(node);
11
- const attributeKey = (node as any)?.sourceType ?? node.type ?? 'image';
12
- const viewStyle = useMemo(() => extractViewStyle(node), [node]);
13
- const imageStyle = extractImageStyle(node);
14
- const style = { ...viewStyle, ...imageStyle };
13
+ const generatedId = useId();
14
+ const attributeName = (node as any)?.sourceType ?? node.type ?? 'image';
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 imageStyle = useMemo(
25
+ () => extractImageStyle(node, { appConfig, projectColors }),
26
+ [node, appConfig, projectColors],
27
+ );
28
+ const isSelected = isNodeSelected({ previewMode, current, node });
29
+ const style = useMergedStyle(
30
+ imageStyle,
31
+ isSelected ? SELECTED_OUTLINE_STYLE : undefined,
32
+ );
33
+
15
34
  return (
16
35
  <img
17
- key={node.key}
36
+ key={node.key + (node.attributes?.src ?? '-')}
37
+ attribute-name={attributeName}
18
38
  attribute-key={attributeKey}
19
39
  src={node.attributes?.src}
20
- width={node.attributes?.width}
21
- height={node.attributes?.height}
22
40
  style={style}
23
41
  alt=""
24
42
  />
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
  export type ResizeModeOptionType = 'cover' | 'contain' | 'stretch' | 'center';
20
21
 
21
22
  export interface ImagePropsGenerated {
@@ -43,6 +44,13 @@ export interface ImagePropsGenerated {
43
44
  borderRadius?: string;
44
45
  width?: string;
45
46
  height?: string;
47
+ flex?: number;
48
+ position?: PositionOptionType;
49
+ top?: string;
50
+ bottom?: string;
51
+ left?: string;
52
+ right?: string;
53
+ zIndex?: number;
46
54
  src?: string;
47
55
  resizeMode?: ResizeModeOptionType;
48
56
  };
@@ -9,8 +9,7 @@
9
9
  "src": "string",
10
10
  "width": "size",
11
11
  "height": "size",
12
- "resizeMode": ["cover", "contain", "stretch", "center"],
13
- "borderRadius": "size"
12
+ "resizeMode": ["cover", "contain", "stretch", "center"]
14
13
  }
15
14
  },
16
15
  "meta": {
@@ -45,13 +44,6 @@
45
44
  "category": "style",
46
45
  "specialCategory": null,
47
46
  "sort": 4
48
- },
49
- "borderRadius": {
50
- "label": "Border Radius",
51
- "description": "Corner rounding.",
52
- "category": "style",
53
- "specialCategory": null,
54
- "sort": 5
55
47
  }
56
48
  }
57
49
  }
@@ -7,10 +7,10 @@ import { useLogRender } from '../../utils/useLogRender';
7
7
  function Onboard({ node }: OnboardComponentProps) {
8
8
  useLogRender('Onboard');
9
9
  node = useNode(node);
10
- const attributeKey = node.type ?? 'Onboard';
10
+ const attributeName = node.type ?? 'Onboard';
11
11
  return (
12
12
  <Carousel
13
- node={{ ...node, type: 'carousel', sourceType: attributeKey } as any}
13
+ node={{ ...node, type: 'carousel', sourceType: attributeName } as any}
14
14
  />
15
15
  );
16
16
  }
@@ -16,6 +16,7 @@ export type JustifyContentOptionType =
16
16
  | 'space-between'
17
17
  | 'space-around'
18
18
  | 'space-evenly';
19
+ export type PositionOptionType = 'relative' | 'absolute';
19
20
 
20
21
  export interface OnboardPropsGenerated {
21
22
  child: string;
@@ -42,6 +43,13 @@ export interface OnboardPropsGenerated {
42
43
  borderRadius?: string;
43
44
  width?: string;
44
45
  height?: string;
46
+ flex?: number;
47
+ position?: PositionOptionType;
48
+ top?: string;
49
+ bottom?: string;
50
+ left?: string;
51
+ right?: string;
52
+ zIndex?: number;
45
53
  };
46
54
  }
47
55
 
@@ -1,4 +1,4 @@
1
- import React, { useContext, useMemo, useRef } from 'react';
1
+ import React, { useContext, useId, useMemo, useRef } from 'react';
2
2
  import type {
3
3
  EventObjectGenerated,
4
4
  OnboardButtonComponentProps,
@@ -13,16 +13,19 @@ import { useMockOSContext, useMockPermission } from '../../mockOS';
13
13
  function OnboardButton({ node }: OnboardButtonComponentProps) {
14
14
  useLogRender('OnboardButton');
15
15
  node = useNode(node);
16
- const attributeKey =
16
+ const attributeName =
17
17
  (node as any)?.sourceType ?? node.type ?? 'OnboardButton';
18
18
  const { emblaApi } = useContext(onboardContext) ?? {};
19
- const { appConfig } = useRenderStore((s) => ({
19
+ const { appConfig, projectColors } = useRenderStore((s) => ({
20
20
  appConfig: s.appConfig,
21
+ projectColors: s.projectColors,
21
22
  }));
22
23
 
23
24
  const context = useMockOSContext();
24
25
  const mockPermissionManager = useMockPermission(context);
25
26
  const handledEventsRef = useRef<EventObjectGenerated[]>([]);
27
+ const generatedId = useId();
28
+ const attributeKey = node.key ?? generatedId;
26
29
 
27
30
  const labelRaw = node.attributes?.labelKey ?? '';
28
31
  const label =
@@ -33,7 +36,10 @@ function OnboardButton({ node }: OnboardButtonComponentProps) {
33
36
  const flex = node.attributes?.flex ?? 1;
34
37
  const textColor = node.attributes?.button_text_color ?? '#FFFFFF';
35
38
  const backgroundColor = node.attributes?.button_background_color ?? '#0066FF';
36
- const viewStyle = useMemo(() => extractViewStyle(node), [node]);
39
+ const viewStyle = useMemo(
40
+ () => extractViewStyle(node, { appConfig, projectColors }),
41
+ [node, appConfig, projectColors],
42
+ );
37
43
 
38
44
  const handleClick = () => {
39
45
  //TODO: any ??
@@ -51,7 +57,6 @@ function OnboardButton({ node }: OnboardButtonComponentProps) {
51
57
  mockPermissionManager.requestPermission(permission);
52
58
  handledEventsRef.current.push(e);
53
59
  //TODO: cause user to click second time
54
- return;
55
60
  } else if (e.type === 'Navigate') {
56
61
  const eventTargetIndex = e.targetIndex;
57
62
  if (typeof eventTargetIndex === 'number') {
@@ -59,7 +64,6 @@ function OnboardButton({ node }: OnboardButtonComponentProps) {
59
64
  navigateHandled = true;
60
65
  handledEventsRef.current.push(e);
61
66
  //TODO: cause user to click second time
62
- return;
63
67
  } else if (e.navigate_to) {
64
68
  const eventTarget = e.navigate_to;
65
69
  if (typeof eventTarget === 'string') {
@@ -72,7 +76,6 @@ function OnboardButton({ node }: OnboardButtonComponentProps) {
72
76
  alert('Mock OS context not available for navigation.');
73
77
  }
74
78
  }
75
- return;
76
79
  }
77
80
  }
78
81
  }
@@ -81,6 +84,7 @@ function OnboardButton({ node }: OnboardButtonComponentProps) {
81
84
 
82
85
  return (
83
86
  <button
87
+ attribute-name={attributeName}
84
88
  attribute-key={attributeKey}
85
89
  className="onboard__button"
86
90
  onClick={handleClick}
@@ -18,6 +18,7 @@ export type JustifyContentOptionType =
18
18
  | 'space-between'
19
19
  | 'space-around'
20
20
  | 'space-evenly';
21
+ export type PositionOptionType = 'relative' | 'absolute';
21
22
  export type AnimationOptionType =
22
23
  | 'simple-animation'
23
24
  | 'line-animation'
@@ -57,12 +58,18 @@ export interface OnboardButtonPropsGenerated {
57
58
  borderRadius?: string;
58
59
  width?: string;
59
60
  height?: string;
61
+ flex?: number;
62
+ position?: PositionOptionType;
63
+ top?: string;
64
+ bottom?: string;
65
+ left?: string;
66
+ right?: string;
67
+ zIndex?: number;
60
68
  labelKey?: string;
61
69
  button_text_color?: string;
62
70
  animation?: AnimationOptionType;
63
71
  animation_color?: string;
64
72
  button_background_color?: string;
65
- flex?: number;
66
73
  events?: EventObjectGenerated[];
67
74
  };
68
75
  }