@developer_tribe/react-builder 1.2.2 → 1.2.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 (64) hide show
  1. package/dist/RenderPage.d.ts +3 -1
  2. package/dist/build-components/PaywallOptions/PaywallOptionButton.d.ts +1 -1
  3. package/dist/components/BuilderProvider.d.ts +17 -0
  4. package/dist/components/Checkbox.d.ts +1 -1
  5. package/dist/components/RenderErrorBoundary.d.ts +1 -1
  6. package/dist/hooks/useExtractImageStyle.d.ts +3 -0
  7. package/dist/hooks/useExtractTextStyle.d.ts +1 -7
  8. package/dist/hooks/useExtractViewStyle.d.ts +1 -7
  9. package/dist/hooks/useLocalize.d.ts +4 -1
  10. package/dist/hooks/useSafeAreaViewStyle.d.ts +2 -1
  11. package/dist/index.cjs.js +5 -5
  12. package/dist/index.cjs.js.map +1 -1
  13. package/dist/index.d.ts +1 -6
  14. package/dist/index.esm.js +2 -2
  15. package/dist/index.esm.js.map +1 -1
  16. package/dist/index.native.cjs.js +1 -28
  17. package/dist/index.native.cjs.js.map +1 -1
  18. package/dist/index.native.esm.js +1 -28
  19. package/dist/index.native.esm.js.map +1 -1
  20. package/dist/types/Node.d.ts +1 -0
  21. package/dist/utils/extractTextStyle/extractTextStyle.d.ts +4 -0
  22. package/dist/utils/extractViewStyle/extractViewStyle.d.ts +1 -2
  23. package/dist/utils/parseColor.d.ts +1 -2
  24. package/package.json +1 -1
  25. package/src/RenderPage.tsx +35 -20
  26. package/src/build-components/BIcon/BIcon.tsx +8 -14
  27. package/src/build-components/BackgroundImage/BackgroundImage.tsx +9 -13
  28. package/src/build-components/Button/Button.tsx +11 -20
  29. package/src/build-components/Carousel/Carousel.tsx +8 -14
  30. package/src/build-components/CarouselButtons/CarouselButtons.tsx +2 -8
  31. package/src/build-components/CarouselDots/CarouselDots.tsx +3 -10
  32. package/src/build-components/CarouselItem/CarouselItem.tsx +2 -8
  33. package/src/build-components/CarouselProvider/CarouselProvider.tsx +2 -8
  34. package/src/build-components/Image/Image.tsx +11 -17
  35. package/src/build-components/Main/Main.tsx +10 -18
  36. package/src/build-components/OnboardButton/OnboardButton.tsx +7 -15
  37. package/src/build-components/OnboardButtons/OnboardButtons.tsx +7 -14
  38. package/src/build-components/OnboardDot/OnboardDot.tsx +23 -23
  39. package/src/build-components/OnboardFooter/OnboardFooter.tsx +16 -20
  40. package/src/build-components/OnboardImage/OnboardImage.tsx +10 -12
  41. package/src/build-components/OnboardItem/OnboardItem.tsx +2 -10
  42. package/src/build-components/OnboardProvider/OnboardProvider.tsx +2 -12
  43. package/src/build-components/PaywallBackground/PaywallBackground.tsx +8 -11
  44. package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +9 -16
  45. package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +11 -14
  46. package/src/build-components/PaywallProvider/PaywallProvider.tsx +15 -19
  47. package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +10 -16
  48. package/src/build-components/RadioButton/RadioButton.tsx +11 -20
  49. package/src/build-components/Text/Text.tsx +13 -21
  50. package/src/build-components/View/View.tsx +9 -12
  51. package/src/build-components/other.tsx +1 -1
  52. package/src/components/BuilderProvider.tsx +39 -6
  53. package/src/hooks/useExtractImageStyle.ts +19 -0
  54. package/src/hooks/useExtractTextStyle.ts +12 -16
  55. package/src/hooks/useExtractViewStyle.ts +7 -16
  56. package/src/hooks/useLocalize.ts +7 -6
  57. package/src/hooks/useSafeAreaViewStyle.ts +4 -5
  58. package/src/index.ts +9 -7
  59. package/src/pages/ProjectDebug.tsx +16 -15
  60. package/src/pages/ProjectPage.tsx +17 -5
  61. package/src/types/Node.ts +1 -0
  62. package/src/utils/extractTextStyle/extractTextStyle.ts +32 -13
  63. package/src/utils/extractViewStyle/extractViewStyle.ts +2 -3
  64. package/src/utils/parseColor.ts +4 -5
@@ -2,6 +2,7 @@ export type NodeDefaultAttribute = Record<string, unknown>;
2
2
  export type Node<T = NodeDefaultAttribute> = null | undefined | string | {} | Node<T>[] | NodeData<T>;
3
3
  export interface NodeData<T = Record<string, unknown>> {
4
4
  type: string;
5
+ sourceType?: string;
5
6
  children: Node<Record<string, unknown>>;
6
7
  attributes?: T;
7
8
  key?: string;
@@ -2,8 +2,12 @@ import type { NodeData } from '../../types/Node';
2
2
  import type { TextPropsGenerated } from '../../build-components/Text/TextProps.generated';
3
3
  import type { AppConfig } from '../../types/PreviewConfig';
4
4
  import type { ProjectColors } from '../../types/Project';
5
+ import type { Fonts } from '../../types/Fonts';
5
6
  export type ExtractTextStyleOptions = {
6
7
  appConfig?: AppConfig;
7
8
  projectColors?: ProjectColors;
9
+ fonts?: Fonts;
10
+ onFontLoaded?: (fontFamily: string) => void;
11
+ onError?: (error: string) => void;
8
12
  };
9
13
  export declare function extractTextStyle<T extends TextPropsGenerated['attributes']>(node: NodeData<T>, options?: ExtractTextStyleOptions): import("react").CSSProperties;
@@ -1,9 +1,8 @@
1
1
  import { ViewPropsGenerated } from '../../build-components/View/ViewProps.generated';
2
2
  import type { NodeData } from '../../types/Node';
3
- import type { AppConfig } from '../../types/PreviewConfig';
4
3
  import type { ProjectColors } from '../../types/Project';
5
4
  export type ExtractViewStyleOptions = {
6
- appConfig?: AppConfig;
7
5
  projectColors?: ProjectColors;
6
+ theme?: string;
8
7
  };
9
8
  export declare function extractViewStyle<T extends ViewPropsGenerated['attributes']>(node: NodeData<T>, options?: ExtractViewStyleOptions): import("react").CSSProperties;
@@ -1,7 +1,6 @@
1
- import type { AppConfig } from '../types/PreviewConfig';
2
1
  import type { ProjectColors } from '../types/Project';
3
2
  export type ParseColorOptions = {
4
3
  projectColors?: ProjectColors;
5
- appConfig?: AppConfig;
4
+ theme?: string;
6
5
  };
7
6
  export declare function parseColor(value?: string, options?: ParseColorOptions): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@developer_tribe/react-builder",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "restricted": true,
@@ -5,6 +5,11 @@ import { RenderNode } from './build-components';
5
5
  import { useRenderStore } from './store';
6
6
  import { useLogRender } from './utils/useLogRender';
7
7
  import { findNodeByKeyNested } from './utils/findNodeByKeyNested';
8
+ import {
9
+ BuilderProvider,
10
+ type BuilderProviderParams,
11
+ } from './components/BuilderProvider';
12
+ import { RenderErrorBoundary } from './components/RenderErrorBoundary';
8
13
  import type { NodeData } from './types/Node';
9
14
  export type ScreenStyle = {
10
15
  light: { backgroundColor: string; color: string; seperatorColor?: string };
@@ -14,6 +19,7 @@ interface RenderPageProps {
14
19
  data: Node;
15
20
  name: string;
16
21
  onSelectNode?: (node: Node | null) => void;
22
+ params: BuilderProviderParams;
17
23
  }
18
24
 
19
25
  function isNodeDataLike(value: unknown): value is NodeData {
@@ -59,7 +65,12 @@ function isEmptyPreview(node: Node): boolean {
59
65
  return false;
60
66
  }
61
67
 
62
- export function RenderPage({ data, name, onSelectNode }: RenderPageProps) {
68
+ export function RenderPage({
69
+ data,
70
+ name,
71
+ onSelectNode,
72
+ params,
73
+ }: RenderPageProps) {
63
74
  useLogRender('RenderPage');
64
75
  const { previewMode, forceRender, setCurrent, appFont } = useRenderStore(
65
76
  (s) => ({
@@ -109,26 +120,30 @@ export function RenderPage({ data, name, onSelectNode }: RenderPageProps) {
109
120
  }, [previewMode, data, onSelectNode, setCurrent, forceRender]); // forceRender: retrigger effect when we want to force a refresh (e.g. route change)
110
121
 
111
122
  return (
112
- <DeviceMockFrame appName={name}>
113
- <div
114
- className="screen-preview"
115
- ref={previewRootRef}
116
- style={{
117
- fontFamily: appFont ? `"${appFont}"` : undefined,
118
- }}
119
- >
120
- <RenderNode node={data} />
121
- {showEmptyState && (
122
- <div className="rb-empty-preview" aria-hidden="true">
123
- <div className="rb-empty-preview__card">
124
- <div className="rb-empty-preview__title">Empty screen</div>
125
- <div className="rb-empty-preview__hint">
126
- Add a component to start
123
+ <RenderErrorBoundary subtitle="caught by RenderPage">
124
+ <BuilderProvider params={params}>
125
+ <DeviceMockFrame appName={name}>
126
+ <div
127
+ className="screen-preview"
128
+ ref={previewRootRef}
129
+ style={{
130
+ fontFamily: appFont ? `"${appFont}"` : undefined,
131
+ }}
132
+ >
133
+ <RenderNode node={data} />
134
+ {showEmptyState && (
135
+ <div className="rb-empty-preview" aria-hidden="true">
136
+ <div className="rb-empty-preview__card">
137
+ <div className="rb-empty-preview__title">Empty screen</div>
138
+ <div className="rb-empty-preview__hint">
139
+ Add a component to start
140
+ </div>
141
+ </div>
127
142
  </div>
128
- </div>
143
+ )}
129
144
  </div>
130
- )}
131
- </div>
132
- </DeviceMockFrame>
145
+ </DeviceMockFrame>
146
+ </BuilderProvider>
147
+ </RenderErrorBoundary>
133
148
  );
134
149
  }
@@ -1,7 +1,7 @@
1
1
  import React, { useId, useMemo } from 'react';
2
2
  import type { BIconComponentProps } from './BIconProps.generated';
3
3
  import useNode from '../useNode';
4
- import { useRenderStore } from '../../store';
4
+ import { useBuilderParams } from '../../components/BuilderProvider';
5
5
  import { useLogRender } from '../../utils/useLogRender';
6
6
  import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
7
7
  import { useMergedStyle } from '../../utils/useMergedStyle';
@@ -13,23 +13,17 @@ function BIcon({ node }: BIconComponentProps) {
13
13
  useLogRender('BIcon');
14
14
  node = useNode(node);
15
15
  const generatedId = useId();
16
- const attributeName = (node as any)?.sourceType ?? node.type ?? 'BIcon';
16
+ const attributeName = node.sourceType ?? node.type ?? 'BIcon';
17
17
  const attributeKey = node.key ?? generatedId;
18
18
 
19
- const { previewMode, current, appConfig, projectColors } = useRenderStore(
20
- (s) => ({
21
- previewMode: s.previewMode,
22
- current: s.current,
23
- appConfig: s.appConfig,
24
- projectColors: s.projectColors,
25
- }),
26
- );
19
+ const { previewMode, selectedKey } = useBuilderParams();
27
20
 
28
- const baseStyle = useExtractTextStyle(node as any, {
29
- appConfig,
30
- projectColors,
21
+ const baseStyle = useExtractTextStyle(node);
22
+ const isSelected = isNodeSelected({
23
+ previewMode: !!previewMode,
24
+ current: selectedKey ? { key: selectedKey } : undefined,
25
+ node,
31
26
  });
32
- const isSelected = isNodeSelected({ previewMode, current, node });
33
27
  const style = useMergedStyle(
34
28
  baseStyle,
35
29
  isSelected ? SELECTED_OUTLINE_STYLE : undefined,
@@ -1,7 +1,7 @@
1
1
  import React, { useId, useMemo } from 'react';
2
2
  import type { BackgroundImageComponentProps } from './BackgroundImageProps.generated';
3
3
  import useNode from '../useNode';
4
- import { useRenderStore } from '../../store';
4
+ import { useBuilderParams } from '../../components/BuilderProvider';
5
5
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
6
6
  import { resolveImageSrc } from '../../utils/getImage';
7
7
  import { useLogRender } from '../../utils/useLogRender';
@@ -12,20 +12,12 @@ function BackgroundImage({ node }: BackgroundImageComponentProps) {
12
12
  useLogRender('BackgroundImage');
13
13
  node = useNode(node);
14
14
  const generatedId = useId();
15
- const attributeName =
16
- (node as any)?.sourceType ?? node.type ?? 'background-image';
15
+ const attributeName = node.sourceType ?? node.type ?? 'background-image';
17
16
  const attributeKey = node.key ?? generatedId;
18
17
 
19
- const { previewMode, current, appConfig, projectColors } = useRenderStore(
20
- (s) => ({
21
- previewMode: s.previewMode,
22
- current: s.current,
23
- appConfig: s.appConfig,
24
- projectColors: s.projectColors,
25
- }),
26
- );
18
+ const { previewMode, selectedKey } = useBuilderParams();
27
19
 
28
- const baseStyle = useExtractViewStyle(node, { appConfig, projectColors });
20
+ const baseStyle = useExtractViewStyle(node);
29
21
  const backgroundStyle = useMemo(() => {
30
22
  const attrs = node.attributes;
31
23
  const style: React.CSSProperties = {
@@ -57,7 +49,11 @@ function BackgroundImage({ node }: BackgroundImageComponentProps) {
57
49
 
58
50
  return style;
59
51
  }, [node]);
60
- const isSelected = isNodeSelected({ previewMode, current, node });
52
+ const isSelected = isNodeSelected({
53
+ previewMode: !!previewMode,
54
+ current: selectedKey ? { key: selectedKey } : undefined,
55
+ node,
56
+ });
61
57
  const mergedStyle = useMergedStyle(baseStyle, backgroundStyle);
62
58
  const style = useMergedStyle(
63
59
  mergedStyle,
@@ -1,7 +1,7 @@
1
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
+ import { useBuilderParams } from '../../components/BuilderProvider';
5
5
  import { useLogRender } from '../../utils/useLogRender';
6
6
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
7
7
  import { useExtractTextStyle } from '../../hooks/useExtractTextStyle';
@@ -13,25 +13,12 @@ function Button({ node }: ButtonComponentProps) {
13
13
  useLogRender('Button');
14
14
  node = useNode(node);
15
15
  const generatedId = useId();
16
- const attributeName = (node as any)?.sourceType ?? node.type ?? 'button';
16
+ const attributeName = node.sourceType ?? node.type ?? 'button';
17
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 localize = useLocalize();
27
- const baseStyle = useExtractViewStyle(node as any, {
28
- appConfig,
29
- projectColors,
30
- });
31
- const combinedTextStyle = useExtractTextStyle(node as any, {
32
- appConfig,
33
- projectColors,
34
- });
18
+ const { previewMode, selectedKey, appConfig } = useBuilderParams();
19
+ const localize = useLocalize({ appConfig });
20
+ const baseStyle = useExtractViewStyle(node);
21
+ const combinedTextStyle = useExtractTextStyle(node);
35
22
  const textStyle = useMemo(() => {
36
23
  return {
37
24
  color: combinedTextStyle.color,
@@ -58,7 +45,11 @@ function Button({ node }: ButtonComponentProps) {
58
45
  : { backgroundColor: 'transparent' }),
59
46
  } as React.CSSProperties;
60
47
  }, [node?.attributes?.backgroundColor]);
61
- const isSelected = isNodeSelected({ previewMode, current, node });
48
+ const isSelected = isNodeSelected({
49
+ previewMode: !!previewMode,
50
+ current: selectedKey ? { key: selectedKey } : undefined,
51
+ node,
52
+ });
62
53
  const withButtonDefaults = useMergedStyle(baseStyle, buttonDefaults);
63
54
  const style = useMergedStyle(
64
55
  withButtonDefaults,
@@ -3,7 +3,7 @@ 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
+ import { useBuilderParams } from '../../components/BuilderProvider';
7
7
  import { useLogRender } from '../../utils/useLogRender';
8
8
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
9
9
  import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
@@ -13,21 +13,15 @@ function Carousel({ node }: CarouselComponentProps) {
13
13
  useLogRender('Carousel');
14
14
  node = useNode(node);
15
15
  const generatedId = useId();
16
- const attributeName = (node as any)?.sourceType ?? node.type ?? 'carousel';
16
+ const attributeName = node.sourceType ?? node.type ?? 'carousel';
17
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 = useExtractViewStyle(node as any, {
27
- appConfig,
28
- projectColors,
18
+ const { previewMode, selectedKey } = useBuilderParams();
19
+ const baseStyle = useExtractViewStyle(node);
20
+ const isSelected = isNodeSelected({
21
+ previewMode: !!previewMode,
22
+ current: selectedKey ? { key: selectedKey } : undefined,
23
+ node,
29
24
  });
30
- const isSelected = isNodeSelected({ previewMode, current, node });
31
25
  const style = useMergedStyle(
32
26
  baseStyle,
33
27
  isSelected ? SELECTED_OUTLINE_STYLE : undefined,
@@ -4,20 +4,14 @@ import { carouselContext } from '../CarouselProvider/CarouselProvider';
4
4
  import useNode from '../useNode';
5
5
  import { useLogRender } from '../../utils/useLogRender';
6
6
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
7
- import { useRenderStore } from '../../store';
8
7
 
9
8
  function CarouselButtons({ node }: CarouselButtonsComponentProps) {
10
9
  useLogRender('CarouselButtons');
11
10
  node = useNode(node);
12
11
  const generatedId = useId();
13
- const attributeName =
14
- (node as any)?.sourceType ?? node.type ?? 'carouselButtons';
12
+ const attributeName = node.sourceType ?? node.type ?? 'carouselButtons';
15
13
  const attributeKey = node.key ?? generatedId;
16
- const { appConfig, projectColors } = useRenderStore((s) => ({
17
- appConfig: s.appConfig,
18
- projectColors: s.projectColors,
19
- }));
20
- const style = useExtractViewStyle(node as any, { appConfig, projectColors });
14
+ const style = useExtractViewStyle(node);
21
15
  const emblaApi = useContext(carouselContext);
22
16
  const buttonTypes = node.attributes?.buttonType || [
23
17
  'previous_button',
@@ -5,7 +5,6 @@ import { onboardContext } from '../OnboardProvider/OnboardProvider';
5
5
  import useNode from '../useNode';
6
6
  import { useLogRender } from '../../utils/useLogRender';
7
7
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
8
- import { useRenderStore } from '../../store';
9
8
 
10
9
  function CarouselDots({ node }: CarouselDotsComponentProps) {
11
10
  useLogRender('CarouselDots');
@@ -13,20 +12,14 @@ function CarouselDots({ node }: CarouselDotsComponentProps) {
13
12
  node = useNode(node);
14
13
 
15
14
  const generatedId = useId();
16
- const attributeName =
17
- (node as any)?.sourceType ?? node.type ?? 'carouselDots';
15
+ const attributeName = node.sourceType ?? node.type ?? 'carouselDots';
18
16
  const attributeKey = node.key ?? generatedId;
19
17
 
20
18
  const dotType = node.attributes?.dotType || 'normal_dot';
21
- const { appConfig, projectColors } = useRenderStore((s) => ({
22
- appConfig: s.appConfig,
23
- projectColors: s.projectColors,
24
- }));
25
-
26
- const style = useExtractViewStyle(node as any, { appConfig, projectColors });
19
+ const style = useExtractViewStyle(node);
27
20
 
28
21
  // Use the appropriate context based on sourceType
29
- const isOnboard = (node as any)?.sourceType === 'OnboardDot';
22
+ const isOnboard = node.sourceType === 'OnboardDot';
30
23
  const carouselApi = useContext(carouselContext);
31
24
  const onboardApi = useContext(onboardContext);
32
25
  const emblaApi = isOnboard ? onboardApi?.emblaApi : carouselApi;
@@ -4,20 +4,14 @@ import RenderNode from '../RenderNode.generated';
4
4
  import useNode from '../useNode';
5
5
  import { useLogRender } from '../../utils/useLogRender';
6
6
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
7
- import { useRenderStore } from '../../store';
8
7
 
9
8
  export function CarouselItem({ node }: CarouselItemComponentProps) {
10
9
  useLogRender('CarouselItem');
11
10
  node = useNode(node);
12
11
  const generatedId = useId();
13
- const attributeName =
14
- (node as any)?.sourceType ?? node.type ?? 'carouselItem';
12
+ const attributeName = node.sourceType ?? node.type ?? 'carouselItem';
15
13
  const attributeKey = node.key ?? generatedId;
16
- const { appConfig, projectColors } = useRenderStore((s) => ({
17
- appConfig: s.appConfig,
18
- projectColors: s.projectColors,
19
- }));
20
- const style = useExtractViewStyle(node as any, { appConfig, projectColors });
14
+ const style = useExtractViewStyle(node);
21
15
  return (
22
16
  <div
23
17
  className="embla__slide"
@@ -4,7 +4,6 @@ import RenderNode from '../RenderNode.generated';
4
4
  import useEmblaCarousel from 'embla-carousel-react';
5
5
  import useNode from '../useNode';
6
6
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
7
- import { useRenderStore } from '../../store';
8
7
  import { isCarousel } from '../../utils/isCarousel';
9
8
  import type { Node, NodeData } from '../../types/Node';
10
9
 
@@ -13,14 +12,9 @@ function CarouselProvider({ node }: CarouselProviderComponentProps) {
13
12
  node = useNode(node);
14
13
  const [emblaRef, emblaApi] = useEmblaCarousel(node.attributes as any);
15
14
  const generatedId = useId();
16
- const attributeName =
17
- (node as any)?.sourceType ?? node.type ?? 'carouselProvider';
15
+ const attributeName = node.sourceType ?? node.type ?? 'carouselProvider';
18
16
  const attributeKey = node.key ?? generatedId;
19
- const { appConfig, projectColors } = useRenderStore((s) => ({
20
- appConfig: s.appConfig,
21
- projectColors: s.projectColors,
22
- }));
23
- const viewStyle = useExtractViewStyle(node, { appConfig, projectColors });
17
+ const viewStyle = useExtractViewStyle(node);
24
18
 
25
19
  const { carouselChild, otherChildren } = useMemo(() => {
26
20
  const children = node.children as Node;
@@ -1,32 +1,26 @@
1
- import React, { useId, useMemo } from 'react';
1
+ import React, { useId } from 'react';
2
2
  import type { ImageComponentProps } from './ImageProps.generated';
3
3
  import useNode from '../useNode';
4
- import { useRenderStore } from '../../store';
5
- import { extractImageStyle } from '../../utils/extractImageStyle';
4
+ import { useBuilderParams } from '../../components/BuilderProvider';
6
5
  import { resolveImageSrc } from '../../utils/getImage';
7
6
  import { useLogRender } from '../../utils/useLogRender';
8
7
  import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
9
8
  import { useMergedStyle } from '../../utils/useMergedStyle';
9
+ import { useExtractImageStyle } from '../../hooks/useExtractImageStyle';
10
10
 
11
11
  function Image({ node }: ImageComponentProps) {
12
12
  useLogRender('Image');
13
13
  node = useNode(node);
14
14
  const generatedId = useId();
15
- const attributeName = (node as any)?.sourceType ?? node.type ?? 'image';
15
+ const attributeName = node.sourceType ?? node.type ?? 'image';
16
16
  const attributeKey = node.key ?? generatedId;
17
- const { previewMode, current, appConfig, projectColors } = useRenderStore(
18
- (s) => ({
19
- previewMode: s.previewMode,
20
- current: s.current,
21
- appConfig: s.appConfig,
22
- projectColors: s.projectColors,
23
- }),
24
- );
25
- const imageStyle = useMemo(
26
- () => extractImageStyle(node, { appConfig, projectColors }),
27
- [node, appConfig, projectColors],
28
- );
29
- const isSelected = isNodeSelected({ previewMode, current, node });
17
+ const { previewMode, selectedKey } = useBuilderParams();
18
+ const imageStyle = useExtractImageStyle(node);
19
+ const isSelected = isNodeSelected({
20
+ previewMode: !!previewMode,
21
+ current: selectedKey ? { key: selectedKey } : undefined,
22
+ node,
23
+ });
30
24
  const style = useMergedStyle(
31
25
  imageStyle,
32
26
  isSelected ? SELECTED_OUTLINE_STYLE : undefined,
@@ -3,41 +3,33 @@ import type { MainComponentProps } from './MainProps.generated';
3
3
  import RenderNode from '../RenderNode.generated';
4
4
  import type { Node } from '../../types/Node';
5
5
  import useNode from '../useNode';
6
- import { useRenderStore } from '../../store';
6
+ import { useBuilderParams } from '../../components/BuilderProvider';
7
7
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
8
8
  import { useLogRender } from '../../utils/useLogRender';
9
9
  import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
10
10
  import { useMergedStyle } from '../../utils/useMergedStyle';
11
11
  import { useSafeAreaViewStyle } from '../../hooks/useSafeAreaViewStyle';
12
- import type { NodeData } from '../../types/Node';
13
- import { ViewPropsGenerated } from '../View/ViewProps.generated';
14
12
 
15
13
  function Main({ node }: MainComponentProps) {
16
14
  useLogRender('Main');
17
15
  node = useNode(node);
18
16
 
19
17
  const generatedId = useId();
20
- const attributeName = (node as any)?.sourceType ?? node.type ?? 'Main';
18
+ const attributeName = node.sourceType ?? node.type ?? 'Main';
21
19
  const attributeKey = node.key ?? generatedId;
22
20
 
23
- const { previewMode, current, appConfig, projectColors } = useRenderStore(
24
- (s) => ({
25
- previewMode: s.previewMode,
26
- current: s.current,
27
- appConfig: s.appConfig,
28
- projectColors: s.projectColors,
29
- }),
30
- );
21
+ const { previewMode, selectedKey } = useBuilderParams();
31
22
 
32
- const baseStyle = useExtractViewStyle(
33
- node as NodeData<ViewPropsGenerated['attributes']>,
34
- { appConfig, projectColors },
35
- );
23
+ const baseStyle = useExtractViewStyle(node);
36
24
 
37
- const useSafeAreaView = (node.attributes as any)?.useSafeAreaView ?? true;
25
+ const useSafeAreaView = node.attributes?.useSafeAreaView ?? true;
38
26
  const layoutStyle = useSafeAreaViewStyle(baseStyle, useSafeAreaView);
39
27
 
40
- const isSelected = isNodeSelected({ previewMode, current, node });
28
+ const isSelected = isNodeSelected({
29
+ previewMode: !!previewMode,
30
+ current: selectedKey ? { key: selectedKey } : undefined,
31
+ node,
32
+ });
41
33
  const style = useMergedStyle(
42
34
  layoutStyle,
43
35
  isSelected ? SELECTED_OUTLINE_STYLE : undefined,
@@ -5,21 +5,18 @@ import type {
5
5
  } from './OnboardButtonProps.generated';
6
6
  import { onboardContext } from '../OnboardProvider/OnboardProvider';
7
7
  import useNode from '../useNode';
8
- import { useRenderStore } from '../../store';
8
+ import { useBuilderParams } from '../../components/BuilderProvider';
9
9
  import { useLogRender } from '../../utils/useLogRender';
10
10
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
11
11
  import { useMockOSContext, useMockPermission } from '../../mockOS';
12
+ import { useLocalize } from '../../hooks/useLocalize';
12
13
 
13
14
  function OnboardButton({ node }: OnboardButtonComponentProps) {
14
15
  useLogRender('OnboardButton');
15
16
  node = useNode(node);
16
- const attributeName =
17
- (node as any)?.sourceType ?? node.type ?? 'OnboardButton';
17
+ const attributeName = node.sourceType ?? node.type ?? 'OnboardButton';
18
18
  const { emblaApi } = useContext(onboardContext) ?? {};
19
- const { appConfig, projectColors } = useRenderStore((s) => ({
20
- appConfig: s.appConfig,
21
- projectColors: s.projectColors,
22
- }));
19
+ const { appConfig } = useBuilderParams();
23
20
 
24
21
  const context = useMockOSContext();
25
22
  const mockPermissionManager = useMockPermission(context);
@@ -28,18 +25,13 @@ function OnboardButton({ node }: OnboardButtonComponentProps) {
28
25
  const attributeKey = node.key ?? generatedId;
29
26
 
30
27
  const labelRaw = node.attributes?.labelKey ?? '';
31
- const label =
32
- (appConfig.localication?.[appConfig.defaultLanguage ?? 'en']?.[
33
- labelRaw
34
- ] as string) ?? labelRaw;
28
+ const localize = useLocalize({ appConfig });
29
+ const label = localize(labelRaw);
35
30
 
36
31
  const flex = node.attributes?.flex ?? 1;
37
32
  const textColor = node.attributes?.button_text_color ?? '#FFFFFF';
38
33
  const backgroundColor = node.attributes?.button_background_color ?? '#0066FF';
39
- const viewStyle = useExtractViewStyle(node as any, {
40
- appConfig,
41
- projectColors,
42
- });
34
+ const viewStyle = useExtractViewStyle(node);
43
35
 
44
36
  const handleClick = () => {
45
37
  //TODO: any ??
@@ -4,23 +4,19 @@ import type { OnboardButtonsComponentProps } from './OnboardButtonsProps.generat
4
4
  import { onboardContext } from '../OnboardProvider/OnboardProvider';
5
5
  import RenderNode from '../RenderNode.generated';
6
6
  import useNode from '../useNode';
7
- import { useRenderStore } from '../../store';
7
+ import { useBuilderParams } from '../../components/BuilderProvider';
8
8
  import { useLogRender } from '../../utils/useLogRender';
9
9
  import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
10
10
 
11
11
  function OnboardButtons({ node }: OnboardButtonsComponentProps) {
12
12
  useLogRender('OnboardButtons');
13
13
  node = useNode(node);
14
- const attributeName =
15
- (node as any)?.sourceType ?? node.type ?? 'OnboardButtons';
16
- const { appConfig, projectColors } = useRenderStore((s) => ({
17
- appConfig: s.appConfig,
18
- projectColors: s.projectColors,
19
- }));
14
+ const attributeName = node.sourceType ?? node.type ?? 'OnboardButtons';
15
+ const { appConfig } = useBuilderParams();
20
16
  const seperatorColorDefault =
21
- appConfig.theme === 'light'
22
- ? appConfig.screenStyle.light.seperatorColor
23
- : appConfig.screenStyle.dark.seperatorColor;
17
+ appConfig?.theme === 'light'
18
+ ? appConfig?.screenStyle?.light?.seperatorColor
19
+ : appConfig?.screenStyle?.dark?.seperatorColor;
24
20
  const ctx = useContext(onboardContext) ?? {};
25
21
  const [selectedIndex, setSelectedIndex] = useState(ctx.selectedIndex ?? 0);
26
22
 
@@ -44,10 +40,7 @@ function OnboardButtons({ node }: OnboardButtonsComponentProps) {
44
40
  return <RenderNode node={node.children as Node} />;
45
41
  };
46
42
 
47
- const viewStyle = useExtractViewStyle(node as any, {
48
- appConfig,
49
- projectColors,
50
- });
43
+ const viewStyle = useExtractViewStyle(node);
51
44
 
52
45
  // NOTE: Hooks must not be called conditionally.
53
46
  // Generate the id before any early returns so the hook order stays stable.