@developer_tribe/react-builder 1.2.1 → 1.2.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.
- package/dist/RenderPage.d.ts +3 -1
- package/dist/build-components/PaywallOptions/PaywallOptionButton.d.ts +1 -1
- package/dist/components/BuilderProvider.d.ts +17 -0
- package/dist/components/Checkbox.d.ts +1 -1
- package/dist/hooks/useExtractTextStyle.d.ts +3 -0
- package/dist/hooks/useExtractViewStyle.d.ts +3 -0
- package/dist/hooks/useLocalize.d.ts +4 -1
- package/dist/hooks/useSafeAreaViewStyle.d.ts +2 -1
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -6
- package/dist/index.esm.js +2 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +1 -28
- package/dist/index.native.cjs.js.map +1 -1
- package/dist/index.native.d.ts +1 -0
- package/dist/index.native.esm.js +1 -28
- package/dist/index.native.esm.js.map +1 -1
- package/dist/types/Node.d.ts +1 -0
- package/dist/utils/extractTextStyle/extractTextStyle.d.ts +13 -0
- package/dist/utils/extractTextStyle.d.ts +2 -10
- package/dist/utils/extractViewStyle/extractViewStyle.d.ts +8 -0
- package/dist/utils/extractViewStyle.d.ts +2 -9
- package/dist/utils/parseColor.d.ts +1 -2
- package/package.json +1 -1
- package/src/RenderPage.tsx +32 -20
- package/src/build-components/BIcon/BIcon.tsx +10 -17
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +10 -17
- package/src/build-components/Button/Button.tsx +23 -27
- package/src/build-components/Carousel/Carousel.tsx +10 -16
- package/src/build-components/CarouselButtons/CarouselButtons.tsx +4 -13
- package/src/build-components/CarouselDots/CarouselDots.tsx +5 -14
- package/src/build-components/CarouselItem/CarouselItem.tsx +4 -13
- package/src/build-components/CarouselProvider/CarouselProvider.tsx +3 -12
- package/src/build-components/Image/Image.tsx +11 -13
- package/src/build-components/Main/Main.tsx +12 -24
- package/src/build-components/OnboardButton/OnboardButton.tsx +8 -16
- package/src/build-components/OnboardButtons/OnboardButtons.tsx +9 -16
- package/src/build-components/OnboardDot/OnboardDot.tsx +25 -21
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +18 -22
- package/src/build-components/OnboardImage/OnboardImage.tsx +12 -14
- package/src/build-components/OnboardItem/OnboardItem.tsx +3 -12
- package/src/build-components/OnboardProvider/OnboardProvider.tsx +11 -18
- package/src/build-components/PaywallBackground/PaywallBackground.tsx +9 -15
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +10 -17
- package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +12 -18
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +16 -20
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +11 -17
- package/src/build-components/RadioButton/RadioButton.tsx +12 -21
- package/src/build-components/Text/Text.tsx +14 -25
- package/src/build-components/View/View.tsx +11 -17
- package/src/build-components/other.tsx +1 -1
- package/src/components/BuilderProvider.tsx +38 -0
- package/src/hooks/useExtractTextStyle.ts +26 -0
- package/src/hooks/useExtractViewStyle.ts +19 -0
- package/src/hooks/useLocalize.ts +7 -6
- package/src/hooks/useSafeAreaViewStyle.ts +4 -5
- package/src/index.native.ts +3 -0
- package/src/index.ts +10 -7
- package/src/pages/ProjectDebug.tsx +16 -15
- package/src/pages/ProjectPage.tsx +17 -5
- package/src/types/Node.ts +1 -0
- package/src/utils/extractTextStyle/extractTextStyle.ts +179 -0
- package/src/utils/extractTextStyle.ts +2 -160
- package/src/utils/extractViewStyle/extractViewStyle.ts +144 -0
- package/src/utils/extractViewStyle.ts +2 -145
- package/src/utils/parseColor.ts +4 -5
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useContext, useId, useMemo } from 'react';
|
|
2
2
|
import type { RadioButtonComponentProps } from './RadioButtonProps.generated';
|
|
3
3
|
import useNode from '../useNode';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { useBuilderParams } from '../../components/BuilderProvider';
|
|
5
|
+
import { useExtractViewStyle } from '../../hooks/useExtractViewStyle';
|
|
6
6
|
import { useLogRender } from '../../utils/useLogRender';
|
|
7
7
|
import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
|
|
8
8
|
import { useMergedStyle } from '../../utils/useMergedStyle';
|
|
@@ -82,32 +82,23 @@ function RadioButton({ node }: RadioButtonComponentProps) {
|
|
|
82
82
|
const attributeName = node.type ?? 'RadioButton';
|
|
83
83
|
const attributeKey = node.key ?? generatedId;
|
|
84
84
|
|
|
85
|
-
const { previewMode,
|
|
86
|
-
(s) => ({
|
|
87
|
-
previewMode: s.previewMode,
|
|
88
|
-
current: s.current,
|
|
89
|
-
appConfig: s.appConfig,
|
|
90
|
-
projectColors: s.projectColors,
|
|
91
|
-
}),
|
|
92
|
-
);
|
|
85
|
+
const { previewMode, selectedKey } = useBuilderParams();
|
|
93
86
|
|
|
94
|
-
const baseStyle =
|
|
95
|
-
() => extractViewStyle(node, { appConfig, projectColors }),
|
|
96
|
-
[node, appConfig, projectColors],
|
|
97
|
-
);
|
|
87
|
+
const baseStyle = useExtractViewStyle(node);
|
|
98
88
|
|
|
99
|
-
const isSelected = isNodeSelected({
|
|
89
|
+
const isSelected = isNodeSelected({
|
|
90
|
+
previewMode: !!previewMode,
|
|
91
|
+
current: selectedKey ? { key: selectedKey } : undefined,
|
|
92
|
+
node,
|
|
93
|
+
});
|
|
100
94
|
const style = useMergedStyle(
|
|
101
95
|
baseStyle,
|
|
102
96
|
isSelected ? SELECTED_OUTLINE_STYLE : undefined,
|
|
103
97
|
);
|
|
104
98
|
|
|
105
|
-
const selected = Boolean(
|
|
106
|
-
const color =
|
|
107
|
-
|
|
108
|
-
? ((node.attributes as any)?.color as string)
|
|
109
|
-
: undefined;
|
|
110
|
-
const size = parseNumberLike((node.attributes as any)?.size);
|
|
99
|
+
const selected = Boolean(node.attributes?.selected);
|
|
100
|
+
const color = node.attributes?.color;
|
|
101
|
+
const size = parseNumberLike(node.attributes?.size);
|
|
111
102
|
|
|
112
103
|
return (
|
|
113
104
|
<div
|
|
@@ -7,8 +7,8 @@ import React, {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import type { TextComponentProps } from './TextProps.generated';
|
|
9
9
|
import useNode from '../useNode';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { useBuilderParams } from '../../components/BuilderProvider';
|
|
11
|
+
import { useExtractTextStyle } from '../../hooks/useExtractTextStyle';
|
|
12
12
|
import { useLogRender } from '../../utils/useLogRender';
|
|
13
13
|
import { isNodeSelected, SELECTED_OUTLINE_STYLE } from '../../utils/selection';
|
|
14
14
|
import { useMergedStyle } from '../../utils/useMergedStyle';
|
|
@@ -18,41 +18,30 @@ function Text({ node }: TextComponentProps) {
|
|
|
18
18
|
useLogRender('Text');
|
|
19
19
|
node = useNode(node);
|
|
20
20
|
const generatedId = useId();
|
|
21
|
-
const attributeName =
|
|
21
|
+
const attributeName = node.sourceType ?? node.type ?? 'text';
|
|
22
22
|
const attributeKey = node.key ?? generatedId;
|
|
23
23
|
const textRef = useRef<HTMLParagraphElement | null>(null);
|
|
24
24
|
const [autoFontSizePx, setAutoFontSizePx] = useState<number | null>(null);
|
|
25
|
-
const { appConfig,
|
|
26
|
-
(s) => ({
|
|
27
|
-
appConfig: s.appConfig,
|
|
28
|
-
projectColors: s.projectColors,
|
|
29
|
-
previewMode: s.previewMode,
|
|
30
|
-
current: s.current,
|
|
31
|
-
}),
|
|
32
|
-
);
|
|
25
|
+
const { appConfig, previewMode, selectedKey } = useBuilderParams();
|
|
33
26
|
const keyOrText: string = node.children as string;
|
|
34
|
-
const textStyle =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
const textStyle = useExtractTextStyle(node);
|
|
28
|
+
const isSelected = isNodeSelected({
|
|
29
|
+
previewMode: !!previewMode,
|
|
30
|
+
current: selectedKey ? { key: selectedKey } : undefined,
|
|
31
|
+
node,
|
|
32
|
+
});
|
|
33
|
+
const localize = useLocalize({ appConfig });
|
|
40
34
|
|
|
41
35
|
const localizedText = useMemo(
|
|
42
36
|
() => localize(keyOrText),
|
|
43
37
|
[localize, keyOrText],
|
|
44
38
|
);
|
|
45
39
|
|
|
46
|
-
const attrs =
|
|
47
|
-
| (Record<string, unknown> & { style?: Record<string, unknown> })
|
|
48
|
-
| undefined;
|
|
40
|
+
const attrs = node.attributes;
|
|
49
41
|
const styleBag = attrs?.style;
|
|
50
|
-
const adjustsFontSizeToFit =
|
|
51
|
-
(attrs?.adjustsFontSizeToFit as boolean | undefined) ??
|
|
52
|
-
(styleBag?.adjustsFontSizeToFit as boolean | undefined) ??
|
|
53
|
-
false;
|
|
42
|
+
const adjustsFontSizeToFit = attrs?.adjustsFontSizeToFit ?? false;
|
|
54
43
|
const showEllipsis =
|
|
55
|
-
|
|
44
|
+
attrs?.showEllipsis ??
|
|
56
45
|
(styleBag?.showEllipsis as boolean | undefined) ??
|
|
57
46
|
false;
|
|
58
47
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import React, { useId
|
|
1
|
+
import React, { useId } from 'react';
|
|
2
2
|
import type { ViewComponentProps } from './ViewProps.generated';
|
|
3
3
|
import RenderNode from '../RenderNode.generated';
|
|
4
4
|
import { Node } from '../../types/Node';
|
|
5
5
|
import useNode from '../useNode';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { useBuilderParams } from '../../components/BuilderProvider';
|
|
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';
|
|
@@ -13,21 +13,15 @@ export function View({ node }: ViewComponentProps) {
|
|
|
13
13
|
useLogRender('View');
|
|
14
14
|
node = useNode(node);
|
|
15
15
|
const generatedId = useId();
|
|
16
|
-
const attributeName =
|
|
16
|
+
const attributeName = node.sourceType ?? node.type ?? 'view';
|
|
17
17
|
const attributeKey = node.key ?? generatedId;
|
|
18
|
-
const { previewMode,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
);
|
|
26
|
-
const baseStyle = useMemo(
|
|
27
|
-
() => extractViewStyle(node, { appConfig, projectColors }),
|
|
28
|
-
[node, appConfig, projectColors],
|
|
29
|
-
);
|
|
30
|
-
const isSelected = isNodeSelected({ previewMode, current, node });
|
|
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,
|
|
24
|
+
});
|
|
31
25
|
const viewStyle = useMergedStyle(
|
|
32
26
|
baseStyle,
|
|
33
27
|
isSelected ? SELECTED_OUTLINE_STYLE : undefined,
|
|
@@ -9,7 +9,7 @@ export function other(type: string, node: Node): React.ReactNode {
|
|
|
9
9
|
if (type === 'CrashComponent') {
|
|
10
10
|
const details =
|
|
11
11
|
node && typeof node === 'object' && !Array.isArray(node)
|
|
12
|
-
? (node as
|
|
12
|
+
? (node as { attributes?: unknown }).attributes
|
|
13
13
|
: undefined;
|
|
14
14
|
throw new Error(
|
|
15
15
|
`CrashComponent: intentional crash for testing${
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
2
|
import type { Product } from '../paywall/types/paywall-types';
|
|
3
3
|
import type { PaywallBenefits } from '../paywall/types/benefits';
|
|
4
|
+
import type { AppConfig } from '../types/PreviewConfig';
|
|
5
|
+
import type { Fonts } from '../types/Fonts';
|
|
6
|
+
import type { ProjectColors } from '../types/Project';
|
|
4
7
|
import { RenderErrorBoundary } from './RenderErrorBoundary';
|
|
5
8
|
|
|
6
9
|
// NOTE: We keep this context intentionally tiny.
|
|
@@ -15,6 +18,20 @@ export type BuilderProviderParams = {
|
|
|
15
18
|
benefits: PaywallBenefits;
|
|
16
19
|
onPaywallClose?: () => void;
|
|
17
20
|
onPaywallSubscribe?: (product?: Product) => void | boolean | Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Optional runtime config + styling inputs.
|
|
23
|
+
* These are intentionally passed down via BuilderProvider so `build-components`
|
|
24
|
+
* never need to touch `useRenderStore`.
|
|
25
|
+
*/
|
|
26
|
+
appConfig?: AppConfig;
|
|
27
|
+
projectColors?: ProjectColors;
|
|
28
|
+
fonts?: Fonts;
|
|
29
|
+
appFont?: string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Optional selection info (used by builder UI; ignored by host runtime).
|
|
32
|
+
*/
|
|
33
|
+
previewMode?: boolean;
|
|
34
|
+
selectedKey?: string;
|
|
18
35
|
};
|
|
19
36
|
|
|
20
37
|
type BuilderProviderProps = {
|
|
@@ -42,12 +59,33 @@ export function BuilderProvider({ params, children }: BuilderProviderProps) {
|
|
|
42
59
|
typeof params?.onPaywallSubscribe === 'function'
|
|
43
60
|
? params.onPaywallSubscribe
|
|
44
61
|
: undefined,
|
|
62
|
+
appConfig:
|
|
63
|
+
params?.appConfig && typeof params.appConfig === 'object'
|
|
64
|
+
? (params.appConfig as AppConfig)
|
|
65
|
+
: undefined,
|
|
66
|
+
projectColors:
|
|
67
|
+
params?.projectColors && typeof params.projectColors === 'object'
|
|
68
|
+
? (params.projectColors as ProjectColors)
|
|
69
|
+
: undefined,
|
|
70
|
+
fonts: Array.isArray(params?.fonts) ? (params.fonts as Fonts) : undefined,
|
|
71
|
+
appFont: params?.appFont,
|
|
72
|
+
previewMode: !!params?.previewMode,
|
|
73
|
+
selectedKey:
|
|
74
|
+
typeof params?.selectedKey === 'string'
|
|
75
|
+
? params.selectedKey
|
|
76
|
+
: undefined,
|
|
45
77
|
}),
|
|
46
78
|
[
|
|
47
79
|
params?.benefits,
|
|
48
80
|
params?.products,
|
|
49
81
|
params?.onPaywallClose,
|
|
50
82
|
params?.onPaywallSubscribe,
|
|
83
|
+
params?.appConfig,
|
|
84
|
+
params?.projectColors,
|
|
85
|
+
params?.fonts,
|
|
86
|
+
params?.appFont,
|
|
87
|
+
params?.previewMode,
|
|
88
|
+
params?.selectedKey,
|
|
51
89
|
],
|
|
52
90
|
);
|
|
53
91
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import type { NodeData } from '../types/Node';
|
|
3
|
+
import type { TextPropsGenerated } from '../build-components/Text/TextProps.generated';
|
|
4
|
+
import { defaultAppConfig } from '../types/PreviewConfig';
|
|
5
|
+
import { useBuilderParams } from '../components/BuilderProvider';
|
|
6
|
+
import { extractTextStyle } from '../utils/extractTextStyle';
|
|
7
|
+
|
|
8
|
+
export function useExtractTextStyle<T extends TextPropsGenerated['attributes']>(
|
|
9
|
+
node: NodeData<T>,
|
|
10
|
+
) {
|
|
11
|
+
const {
|
|
12
|
+
appConfig: builderAppConfig,
|
|
13
|
+
projectColors: builderProjectColors,
|
|
14
|
+
fonts: builderFonts,
|
|
15
|
+
} = useBuilderParams();
|
|
16
|
+
|
|
17
|
+
const appConfig = builderAppConfig ?? defaultAppConfig;
|
|
18
|
+
const projectColors = builderProjectColors;
|
|
19
|
+
const fonts = builderFonts;
|
|
20
|
+
|
|
21
|
+
return useMemo(
|
|
22
|
+
() => extractTextStyle(node, { appConfig, projectColors, fonts }),
|
|
23
|
+
// fonts is intentionally included: extractTextStyle resolves weights via font definitions.
|
|
24
|
+
[node, appConfig, projectColors, fonts],
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import type { NodeData } from '../types/Node';
|
|
3
|
+
import type { ViewPropsGenerated } from '../build-components/View/ViewProps.generated';
|
|
4
|
+
import { useBuilderParams } from '../components/BuilderProvider';
|
|
5
|
+
import { extractViewStyle } from '../utils/extractViewStyle';
|
|
6
|
+
import { defaultAppConfig } from '../types/PreviewConfig';
|
|
7
|
+
|
|
8
|
+
export function useExtractViewStyle<T extends ViewPropsGenerated['attributes']>(
|
|
9
|
+
node: NodeData<T>,
|
|
10
|
+
) {
|
|
11
|
+
const { appConfig, projectColors: builderProjectColors } = useBuilderParams();
|
|
12
|
+
const theme = appConfig?.theme ?? defaultAppConfig.theme;
|
|
13
|
+
const projectColors = builderProjectColors;
|
|
14
|
+
|
|
15
|
+
return useMemo(
|
|
16
|
+
() => extractViewStyle(node, { theme, projectColors }),
|
|
17
|
+
[node, theme, projectColors],
|
|
18
|
+
);
|
|
19
|
+
}
|
package/src/hooks/useLocalize.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import type { AppConfig } from '../types/PreviewConfig';
|
|
3
|
+
import { defaultAppConfig } from '../types/PreviewConfig';
|
|
4
|
+
import { useBuilderParams } from '../components/BuilderProvider';
|
|
3
5
|
import { useLocalizationParams } from './useLocalizationParams';
|
|
4
6
|
import { replaceLocalizationParams } from '../utils/replaceLocalizationParams';
|
|
5
7
|
|
|
6
8
|
export type LocalizeFn = (keyOrText: string) => string;
|
|
7
9
|
|
|
8
|
-
export function useLocalize(): LocalizeFn {
|
|
9
|
-
const {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}));
|
|
10
|
+
export function useLocalize(options?: { appConfig?: AppConfig }): LocalizeFn {
|
|
11
|
+
const { appConfig: builderAppConfig } = useBuilderParams();
|
|
12
|
+
const appConfig = options?.appConfig ?? builderAppConfig ?? defaultAppConfig;
|
|
13
|
+
const { defaultLanguage, localication } = appConfig;
|
|
13
14
|
const params = useLocalizationParams();
|
|
14
15
|
|
|
15
16
|
return useCallback(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import type { Device } from '../types/Device';
|
|
3
3
|
|
|
4
4
|
function addInset(
|
|
5
5
|
base: React.CSSProperties['paddingTop'],
|
|
@@ -28,19 +28,18 @@ function subtractInset(
|
|
|
28
28
|
export function useSafeAreaViewStyle(
|
|
29
29
|
baseStyle: React.CSSProperties,
|
|
30
30
|
enabled: boolean,
|
|
31
|
+
device?: Device,
|
|
31
32
|
) {
|
|
32
|
-
const device = useRenderStore((s) => s.device);
|
|
33
|
-
|
|
34
33
|
return useMemo(() => {
|
|
35
34
|
if (!enabled) return baseStyle;
|
|
36
35
|
|
|
37
|
-
const [insetTop, insetRight, insetBottom, insetLeft] = device
|
|
36
|
+
const [insetTop, insetRight, insetBottom, insetLeft] = device?.insets ?? [
|
|
38
37
|
0, 0, 0, 0,
|
|
39
38
|
];
|
|
40
39
|
|
|
41
40
|
// Match DeviceMockFrame fallbacks: status bar overlays content, so we treat it as top safe area.
|
|
42
41
|
const top =
|
|
43
|
-
insetTop || (device
|
|
42
|
+
insetTop || (device?.platform === 'ios' ? 20 : device?.platform ? 24 : 0);
|
|
44
43
|
|
|
45
44
|
// Bottom safe area is handled visually by the mock navigation bar area, which takes layout space.
|
|
46
45
|
// So we intentionally don't add bottom padding here to avoid double-spacing.
|
package/src/index.native.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import './styles/index.scss';
|
|
2
2
|
import AttributesEditor from './AttributesEditor';
|
|
3
|
+
|
|
4
|
+
// Example app (`example/`) uses these exports today:
|
|
5
|
+
// - `ProjectPage` (from `src/pages/ProjectPage.tsx`)
|
|
6
|
+
// - `getSamples` (from `src/assets/samples/getSamples.ts`)
|
|
7
|
+
// - types from `src/types/*` and `src/types/PreviewConfig.ts` (Project/ProjectColors/AppConfig/defaultAppConfig)
|
|
8
|
+
//
|
|
9
|
+
// React Native: a RN-safe entrypoint exists at `react-builder/native` (`src/index.native.ts`).
|
|
10
|
+
// More RN-focused exports/integration helpers are coming.
|
|
3
11
|
// NOTE: In React Native, `products` should be sourced from an IAP wrapper (e.g. `react-native-iap`)
|
|
4
12
|
// and passed into `BuilderProvider` from the host app.
|
|
5
13
|
export {
|
|
@@ -12,6 +20,8 @@ export { RenderErrorBoundary } from './components/RenderErrorBoundary';
|
|
|
12
20
|
export { useParams } from './hooks/useParams';
|
|
13
21
|
export { useLocalizationParams } from './hooks/useLocalizationParams';
|
|
14
22
|
export { useLocalize } from './hooks/useLocalize';
|
|
23
|
+
export { useExtractTextStyle } from './hooks/useExtractTextStyle';
|
|
24
|
+
export { useExtractViewStyle } from './hooks/useExtractViewStyle';
|
|
15
25
|
|
|
16
26
|
export type { TargetedScreenSize } from './types/TargetedScreenSize';
|
|
17
27
|
export type { Node, NodeData, NodeDefaultAttribute } from './types/Node';
|
|
@@ -25,11 +35,6 @@ export {
|
|
|
25
35
|
analyseNode,
|
|
26
36
|
} from './utils/analyseNode';
|
|
27
37
|
export { getSamples } from './assets/samples/getSamples';
|
|
28
|
-
export { getBasicSamples } from './assets/samples/getSamples';
|
|
29
|
-
export { getOnboardSamples } from './assets/samples/getSamples';
|
|
30
|
-
export { RenderPage } from './RenderPage';
|
|
31
|
-
export { DeviceMockFrame } from './DeviceMockFrame';
|
|
32
|
-
export { novaToJson } from './utils/novaToJson';
|
|
33
38
|
export type { AppConfig, Localication } from './types/PreviewConfig';
|
|
34
39
|
export { defaultAppConfig } from './types/PreviewConfig';
|
|
35
40
|
export { getDevices, getDefaultDevice } from './utils/getDevices';
|
|
@@ -50,7 +55,6 @@ export {
|
|
|
50
55
|
} from './utils/getImage';
|
|
51
56
|
export { ProjectPage } from './pages/ProjectPage';
|
|
52
57
|
export type { ProjectPageProps } from './pages/ProjectPage';
|
|
53
|
-
export { copyNode } from './utils/copyNode';
|
|
54
58
|
export { logger } from './utils/logger';
|
|
55
59
|
export type { LogLevel } from './types/Project';
|
|
56
60
|
export type {
|
|
@@ -59,7 +63,6 @@ export type {
|
|
|
59
63
|
Product as PaywallProduct,
|
|
60
64
|
PaywallModel,
|
|
61
65
|
} from './paywall/types/paywall-types';
|
|
62
|
-
|
|
63
66
|
// Paywall hooks
|
|
64
67
|
export {
|
|
65
68
|
usePaywallCounter,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type ReactNode, useMemo, useState } from 'react';
|
|
2
2
|
import { RenderPage } from '../RenderPage';
|
|
3
|
-
import { BuilderProvider } from '../components/BuilderProvider';
|
|
4
3
|
import { RenderErrorBoundary } from '../components/RenderErrorBoundary';
|
|
5
4
|
import type { Node } from '../types/Node';
|
|
6
5
|
import type { Product } from '../paywall/types/paywall-types';
|
|
@@ -267,20 +266,22 @@ export function ProjectDebug({
|
|
|
267
266
|
['--rb-canvas-bg' as any]: canvasBg ?? 'none',
|
|
268
267
|
}}
|
|
269
268
|
>
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
269
|
+
<RenderErrorBoundary
|
|
270
|
+
subtitle="caught by ProjectDebug preview"
|
|
271
|
+
onError={(e, componentStack) =>
|
|
272
|
+
setPreviewError({
|
|
273
|
+
message: e?.message ?? String(e),
|
|
274
|
+
stack: e?.stack,
|
|
275
|
+
componentStack,
|
|
276
|
+
})
|
|
277
|
+
}
|
|
278
|
+
>
|
|
279
|
+
<RenderPage
|
|
280
|
+
data={previewData}
|
|
281
|
+
name={name}
|
|
282
|
+
params={{ products, benefits }}
|
|
283
|
+
/>
|
|
284
|
+
</RenderErrorBoundary>
|
|
284
285
|
</section>
|
|
285
286
|
|
|
286
287
|
<section className="rb-project-debug__error" aria-label="Errors">
|
|
@@ -5,7 +5,6 @@ import { ToastContainer, toast } from 'react-toastify';
|
|
|
5
5
|
import { RenderPage } from '../RenderPage';
|
|
6
6
|
import { EditorHeader } from '../components/EditorHeader';
|
|
7
7
|
import { AttributesEditorPanel } from '../components/AttributesEditorPanel';
|
|
8
|
-
import { BuilderProvider } from '../components/BuilderProvider';
|
|
9
8
|
import { BuilderPanel } from './tabs/BuilderPanel';
|
|
10
9
|
import { BottomBar } from '../components/BottomBar';
|
|
11
10
|
import { AppConfig, defaultAppConfig } from '../types/PreviewConfig';
|
|
@@ -79,6 +78,7 @@ export function ProjectPage({
|
|
|
79
78
|
const resolvedProjectColors = projectColors ?? project.projectColors;
|
|
80
79
|
const isEmptyProjectData =
|
|
81
80
|
isNodeNullOrUndefined(project.data) || isEmptyObject(project.data);
|
|
81
|
+
// useRenderStore will be removed
|
|
82
82
|
const {
|
|
83
83
|
current,
|
|
84
84
|
setCurrent,
|
|
@@ -86,6 +86,7 @@ export function ProjectPage({
|
|
|
86
86
|
setProjectName,
|
|
87
87
|
products,
|
|
88
88
|
benefits,
|
|
89
|
+
previewMode,
|
|
89
90
|
} = useRenderStore((s) => ({
|
|
90
91
|
current: s.current,
|
|
91
92
|
setCurrent: s.setCurrent,
|
|
@@ -93,6 +94,7 @@ export function ProjectPage({
|
|
|
93
94
|
setProjectName: s.setProjectName,
|
|
94
95
|
products: s.products,
|
|
95
96
|
benefits: s.benefits,
|
|
97
|
+
previewMode: s.previewMode,
|
|
96
98
|
}));
|
|
97
99
|
const [editorData, setEditorData] = useState<Node>(() => {
|
|
98
100
|
if (!isEmptyProjectData) return null;
|
|
@@ -462,17 +464,27 @@ export function ProjectPage({
|
|
|
462
464
|
)}
|
|
463
465
|
{/* NOTE: In React Native, `products` should come from an IAP wrapper (e.g. `react-native-iap`). */}
|
|
464
466
|
{!showLoading && editorData && (
|
|
465
|
-
<
|
|
467
|
+
<RenderPage
|
|
468
|
+
data={editorData}
|
|
469
|
+
name={resolvedName}
|
|
466
470
|
params={{
|
|
467
471
|
products,
|
|
468
472
|
benefits:
|
|
469
473
|
benefits && typeof benefits === 'object'
|
|
470
474
|
? (benefits as PaywallBenefits)
|
|
471
475
|
: {},
|
|
476
|
+
// Theme/colors/fonts must be passed via BuilderProvider params so build-components never touch useRenderStore.
|
|
477
|
+
appConfig,
|
|
478
|
+
projectColors: resolvedProjectColors,
|
|
479
|
+
fonts: typography.fonts,
|
|
480
|
+
appFont: resolvedAppFont,
|
|
481
|
+
previewMode,
|
|
482
|
+
selectedKey:
|
|
483
|
+
current && typeof current === 'object' && 'key' in current
|
|
484
|
+
? ((current as any).key as string | undefined)
|
|
485
|
+
: undefined,
|
|
472
486
|
}}
|
|
473
|
-
|
|
474
|
-
<RenderPage data={editorData} name={resolvedName} />
|
|
475
|
-
</BuilderProvider>
|
|
487
|
+
/>
|
|
476
488
|
)}
|
|
477
489
|
</div>
|
|
478
490
|
{/* BOTOM BAR */}
|
package/src/types/Node.ts
CHANGED