@developer_tribe/react-builder 1.2.27 → 1.2.29
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/assets/samples/getSamples.d.ts +0 -3
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +1 -2
- package/dist/build-components/CountDown/CountDownProps.generated.d.ts +2 -1
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +1 -2
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +1 -2
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +1 -2
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +1 -2
- package/dist/build-components/PaywallOptions/usePaywallOptionParamsFactory.d.ts +1 -1
- package/dist/build-components/PriceTag/PriceTag.d.ts +5 -0
- package/dist/build-components/PriceTag/PriceTagProps.generated.d.ts +63 -0
- package/dist/build-components/Pricing/Pricing.d.ts +5 -0
- package/dist/build-components/Pricing/PricingProps.generated.d.ts +59 -0
- package/dist/build-components/Promo/Promo.d.ts +5 -0
- package/dist/build-components/Promo/PromoProps.generated.d.ts +59 -0
- package/dist/build-components/Text/TextProps.generated.d.ts +1 -2
- package/dist/build-components/index.d.ts +4 -1
- package/dist/build-components/patterns.generated.d.ts +1405 -202
- package/dist/components/BuilderProvider.d.ts +5 -3
- package/dist/components/ParamsProvider.d.ts +16 -8
- package/dist/hooks/useSyncHtmlThemeClass.d.ts +1 -1
- package/dist/index.cjs.js +4 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.esm.js +4 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.web.cjs.js +4 -4
- package/dist/index.web.cjs.js.map +1 -1
- package/dist/index.web.esm.js +4 -4
- package/dist/index.web.esm.js.map +1 -1
- package/dist/logger.d.ts +18 -0
- package/dist/modals/InspectModal.d.ts +5 -0
- package/dist/modals/index.d.ts +1 -1
- package/dist/pages/ProjectPage.d.ts +3 -3
- package/dist/paywall/hooks/useCalculateLocalizedPrice.d.ts +4 -2
- package/dist/paywall/hooks/useDiscountRate.d.ts +3 -2
- package/dist/paywall/types/paywall-types.d.ts +7 -32
- package/dist/product-base/buildPaywallLocalizationParams.d.ts +16 -0
- package/dist/product-base/calculations.d.ts +29 -0
- package/dist/product-base/extractAndroidParams.d.ts +24 -0
- package/dist/product-base/extractIOSParams.d.ts +24 -0
- package/dist/product-base/index.d.ts +51 -0
- package/dist/product-base/periodLocalizationKeys.d.ts +44 -0
- package/dist/product-base/types.d.ts +155 -0
- package/dist/product-base/usePaywallLocalizationParams.d.ts +29 -0
- package/dist/store.d.ts +7 -1
- package/dist/styles.css +1 -1
- package/dist/types/PreviewConfig.d.ts +10 -16
- package/dist/utils/extractTextStyle/extractTextStyle.d.ts +2 -2
- package/dist/utils/extractTextStyle/extractTextStyleNative.d.ts +2 -2
- package/dist/utils/replaceLocalizationParams.d.ts +1 -1
- package/package.json +2 -2
- package/scripts/migrate-samples-to-current.ts +3 -3
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +28 -12
- package/src/DeviceMockFrame.tsx +15 -10
- package/src/assets/meta.json +1 -1
- package/src/assets/samples/carousel-sample.json +6 -5
- package/src/assets/samples/getSamples.ts +16 -49
- package/src/assets/samples/paywall-1.json +64 -22
- package/src/assets/samples/paywall-2.json +0 -15
- package/src/assets/samples/paywall-app-delete-offer.json +0 -15
- package/src/assets/samples/paywall-app-open-offer.json +0 -15
- package/src/assets/samples/paywall-back-offer.json +0 -15
- package/src/assets/samples/paywall-notification-offer.json +0 -15
- package/src/assets/samples/simple-1.json +1 -16
- package/src/assets/samples/simple-2.json +0 -15
- package/src/assets/samples/unmigrated-builder-1.1.1.json +0 -3
- package/src/assets/samples/unmigrated-builder1.json +0 -3
- package/src/assets/samples/unvalidated-builder1.json +0 -3
- package/src/assets/samples/unvalidated-crash1.json +0 -3
- package/src/assets/samples/unvalidated-crashcomponent1.json +0 -3
- package/src/assets/samples/vpn-onboard-1.json +1 -34
- package/src/assets/samples/vpn-onboard-2.json +1 -34
- package/src/assets/samples/vpn-onboard-3.json +1 -42
- package/src/assets/samples/vpn-onboard-4.json +0 -73
- package/src/assets/samples/vpn-onboard-5.json +0 -73
- package/src/assets/samples/vpn-onboard-6.json +0 -73
- package/src/assets/samples/vpn-onboard-7.json +529 -0
- package/src/attribute-analyser/style/native/useExtractImageStyle.ts +1 -4
- package/src/attribute-analyser/style/native/useExtractTextStyle.ts +3 -12
- package/src/attribute-analyser/style/native/useExtractViewStyle.ts +1 -4
- package/src/attribute-analyser/style/web/useExtractImageStyle.ts +1 -4
- package/src/attribute-analyser/style/web/useExtractTextStyle.ts +3 -12
- package/src/attribute-analyser/style/web/useExtractViewStyle.ts +1 -4
- package/src/attributes-editor/useAttributesEditorModel.ts +5 -52
- package/src/build-components/BIcon/BIconProps.generated.ts +1 -2
- package/src/build-components/CarouselDots/CarouselDots.tsx +6 -13
- package/src/build-components/CountDown/CountDownProps.generated.ts +2 -1
- package/src/build-components/NavigationBarColor/NavigationBarColor.tsx +2 -2
- package/src/build-components/OnboardButton/OnboardButton.tsx +1 -2
- package/src/build-components/OnboardDot/OnboardDot.tsx +6 -18
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +5 -3
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +1 -2
- package/src/build-components/OnboardFooter/pattern.json +1 -1
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +1 -2
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +1 -2
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +1 -2
- package/src/build-components/PaywallOptions/PaywallOptions.tsx +3 -3
- package/src/build-components/PaywallOptions/usePaywallOptionParamsFactory.ts +26 -13
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +51 -12
- package/src/build-components/PriceTag/PriceTag.tsx +25 -0
- package/src/build-components/PriceTag/PriceTagProps.generated.ts +83 -0
- package/src/build-components/PriceTag/pattern.json +53 -0
- package/src/build-components/Pricing/Pricing.tsx +13 -0
- package/src/build-components/Pricing/PricingProps.generated.ts +76 -0
- package/src/build-components/Pricing/pattern.json +25 -0
- package/src/build-components/Promo/Promo.tsx +13 -0
- package/src/build-components/Promo/PromoProps.generated.ts +76 -0
- package/src/build-components/Promo/pattern.json +25 -0
- package/src/build-components/RadioButton/RadioButton.tsx +3 -5
- package/src/build-components/RenderNode.generated.tsx +15 -0
- package/src/build-components/StatusBarColor/StatusBarColor.tsx +2 -2
- package/src/build-components/Text/Text.tsx +12 -5
- package/src/build-components/Text/TextProps.generated.ts +1 -2
- package/src/build-components/Text/pattern.json +3 -2
- package/src/build-components/index.ts +15 -0
- package/src/build-components/patterns.generated.ts +1454 -181
- package/src/components/BottomBar.tsx +42 -39
- package/src/components/BuilderProvider.tsx +41 -14
- package/src/components/LocalizationParamsProvider.tsx +1 -1
- package/src/components/ParamsProvider.tsx +36 -11
- package/src/hooks/useLocalize.ts +7 -4
- package/src/hooks/useParams.ts +1 -1
- package/src/hooks/useSyncHtmlThemeClass.ts +2 -2
- package/src/index.ts +54 -8
- package/src/logger.ts +39 -0
- package/src/modals/InspectModal.tsx +331 -0
- package/src/modals/ProductPresetsModal.tsx +7 -14
- package/src/modals/index.ts +1 -1
- package/src/pages/DebugJsonPage.tsx +9 -22
- package/src/pages/ProjectDebug.tsx +1 -1
- package/src/pages/ProjectPage.tsx +29 -11
- package/src/pages/tabs/SideTool.tsx +28 -104
- package/src/paywall/hooks/useCalculateLocalizedPrice.ts +8 -3
- package/src/paywall/hooks/useDiscountRate.ts +11 -3
- package/src/paywall/types/paywall-types.ts +7 -38
- package/src/product-base/buildPaywallLocalizationParams.ts +100 -0
- package/src/product-base/calculations.ts +93 -0
- package/src/product-base/extractAndroidParams.ts +207 -0
- package/src/product-base/extractIOSParams.ts +199 -0
- package/src/product-base/index.ts +64 -0
- package/src/product-base/mockProducts.json +489 -0
- package/src/product-base/periodLocalizationKeys.ts +114 -0
- package/src/product-base/types.ts +183 -0
- package/src/product-base/usePaywallLocalizationParams.ts +61 -0
- package/src/store.ts +18 -1
- package/src/styles/index.scss +1 -0
- package/src/styles/modals/_inspect-modal.scss +155 -0
- package/src/types/PreviewConfig.ts +157 -16
- package/src/utils/extractTextStyle/extractTextStyle.ts +14 -6
- package/src/utils/extractTextStyle/extractTextStyleNative.ts +8 -6
- package/src/utils/logRenderStore.ts +6 -10
- package/src/utils/parseColor.ts +0 -1
- package/src/utils/replaceLocalizationParams.ts +8 -4
- package/dist/modals/ScreenColorsModal.d.ts +0 -8
- package/src/assets/products.json +0 -98
- package/src/modals/ScreenColorsModal.tsx +0 -121
|
@@ -3,7 +3,7 @@ import { Icon } from './Icon.generated';
|
|
|
3
3
|
import type { IconsType } from '../types/Icons';
|
|
4
4
|
import { useRenderStore } from '../store';
|
|
5
5
|
import type { Localication } from '../types/PreviewConfig';
|
|
6
|
-
import { LocalicationModal, Modal
|
|
6
|
+
import { InspectModal, LocalicationModal, Modal } from '../modals';
|
|
7
7
|
import type { Node } from '../types/Node';
|
|
8
8
|
import type { Project } from '../types/Project';
|
|
9
9
|
import { DebugJsonPage } from '../pages/DebugJsonPage';
|
|
@@ -28,29 +28,45 @@ export function BottomBar({
|
|
|
28
28
|
const magicCursorIcon: IconsType = 'magicpen';
|
|
29
29
|
const debugIcon: IconsType = 'speedometer-03';
|
|
30
30
|
const localizationIcon: IconsType = 'globe-01';
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
const inspectIcon: IconsType = 'info-circle';
|
|
32
|
+
|
|
33
|
+
const {
|
|
34
|
+
appConfig,
|
|
35
|
+
setAppConfig,
|
|
36
|
+
theme,
|
|
37
|
+
setTheme,
|
|
38
|
+
defaultLanguage,
|
|
39
|
+
setDefaultLanguage,
|
|
40
|
+
previewMode,
|
|
41
|
+
setPreviewMode,
|
|
42
|
+
isRtl,
|
|
43
|
+
setIsRtl,
|
|
44
|
+
} = useRenderStore((s) => ({
|
|
45
|
+
appConfig: s.appConfig,
|
|
46
|
+
setAppConfig: s.setAppConfig,
|
|
47
|
+
theme: s.theme,
|
|
48
|
+
setTheme: s.setTheme,
|
|
49
|
+
defaultLanguage: s.defaultLanguage,
|
|
50
|
+
setDefaultLanguage: s.setDefaultLanguage,
|
|
51
|
+
previewMode: s.previewMode,
|
|
52
|
+
setPreviewMode: s.setPreviewMode,
|
|
53
|
+
isRtl: s.isRtl,
|
|
54
|
+
setIsRtl: s.setIsRtl,
|
|
55
|
+
}));
|
|
40
56
|
|
|
41
57
|
const [isDebugOpen, setIsDebugOpen] = useState(false);
|
|
42
58
|
const [isLocalizationOpen, setIsLocalizationOpen] = useState(false);
|
|
43
|
-
const [
|
|
59
|
+
const [isInspectOpen, setIsInspectOpen] = useState(false);
|
|
44
60
|
|
|
45
61
|
const languages = useMemo(() => ['en', 'tr', 'ar'], []);
|
|
46
|
-
const activeLanguage =
|
|
62
|
+
const activeLanguage = defaultLanguage;
|
|
47
63
|
|
|
48
64
|
const handleLocalicationChange = (next: Localication) => {
|
|
49
65
|
setAppConfig({ ...appConfig, localication: next });
|
|
50
66
|
};
|
|
51
67
|
|
|
52
|
-
const themeIsActive =
|
|
53
|
-
const rtlIsActive =
|
|
68
|
+
const themeIsActive = theme === 'dark';
|
|
69
|
+
const rtlIsActive = isRtl;
|
|
54
70
|
const previewIsActive = previewMode;
|
|
55
71
|
const themeIcon: IconsType = themeIsActive ? 'moon-bold' : 'sun';
|
|
56
72
|
|
|
@@ -62,12 +78,7 @@ export function BottomBar({
|
|
|
62
78
|
className={`rb-bottom-bar__button${themeIsActive ? ' is-active' : ''}`}
|
|
63
79
|
aria-label="Theme"
|
|
64
80
|
aria-pressed={themeIsActive}
|
|
65
|
-
onClick={() =>
|
|
66
|
-
setAppConfig({
|
|
67
|
-
...appConfig,
|
|
68
|
-
theme: appConfig.theme === 'dark' ? 'light' : 'dark',
|
|
69
|
-
})
|
|
70
|
-
}
|
|
81
|
+
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
|
71
82
|
>
|
|
72
83
|
<Icon iconType={themeIcon} size={20} color="currentColor" alt="" />
|
|
73
84
|
</button>
|
|
@@ -79,9 +90,7 @@ export function BottomBar({
|
|
|
79
90
|
}`}
|
|
80
91
|
aria-label="RTL"
|
|
81
92
|
aria-pressed={rtlIsActive}
|
|
82
|
-
onClick={() =>
|
|
83
|
-
setAppConfig({ ...appConfig, isRtl: !(appConfig.isRtl ?? false) })
|
|
84
|
-
}
|
|
93
|
+
onClick={() => setIsRtl(!isRtl)}
|
|
85
94
|
>
|
|
86
95
|
<Icon iconType={rtlIcon} size={18} color="currentColor" alt="" />
|
|
87
96
|
<span className="rb-bottom-bar__rtl-text">RTL</span>
|
|
@@ -133,12 +142,12 @@ export function BottomBar({
|
|
|
133
142
|
|
|
134
143
|
<button
|
|
135
144
|
type="button"
|
|
136
|
-
className={`rb-bottom-bar__button${
|
|
137
|
-
aria-label="
|
|
138
|
-
aria-pressed={
|
|
139
|
-
onClick={() =>
|
|
145
|
+
className={`rb-bottom-bar__button${isInspectOpen ? ' is-active' : ''}`}
|
|
146
|
+
aria-label="Inspect"
|
|
147
|
+
aria-pressed={isInspectOpen}
|
|
148
|
+
onClick={() => setIsInspectOpen(true)}
|
|
140
149
|
>
|
|
141
|
-
<Icon iconType={
|
|
150
|
+
<Icon iconType={inspectIcon} size={20} color="currentColor" alt="" />
|
|
142
151
|
</button>
|
|
143
152
|
|
|
144
153
|
<div className="rb-bottom-bar__spacer" />
|
|
@@ -151,9 +160,7 @@ export function BottomBar({
|
|
|
151
160
|
className={`rb-bottom-bar__lang${
|
|
152
161
|
activeLanguage === language ? ' is-active' : ''
|
|
153
162
|
}`}
|
|
154
|
-
onClick={() =>
|
|
155
|
-
setAppConfig({ ...appConfig, defaultLanguage: language })
|
|
156
|
-
}
|
|
163
|
+
onClick={() => setDefaultLanguage(language)}
|
|
157
164
|
>
|
|
158
165
|
{language}
|
|
159
166
|
</button>
|
|
@@ -169,14 +176,6 @@ export function BottomBar({
|
|
|
169
176
|
/>
|
|
170
177
|
)}
|
|
171
178
|
|
|
172
|
-
{isColorsOpen && (
|
|
173
|
-
<ScreenColorsModal
|
|
174
|
-
appConfig={appConfig}
|
|
175
|
-
onChange={setAppConfig}
|
|
176
|
-
onClose={() => setIsColorsOpen(false)}
|
|
177
|
-
/>
|
|
178
|
-
)}
|
|
179
|
-
|
|
180
179
|
{isDebugOpen && (
|
|
181
180
|
<Modal
|
|
182
181
|
onClose={() => setIsDebugOpen(false)}
|
|
@@ -198,6 +197,10 @@ export function BottomBar({
|
|
|
198
197
|
/>
|
|
199
198
|
</Modal>
|
|
200
199
|
)}
|
|
200
|
+
|
|
201
|
+
{isInspectOpen && (
|
|
202
|
+
<InspectModal onClose={() => setIsInspectOpen(false)} />
|
|
203
|
+
)}
|
|
201
204
|
</>
|
|
202
205
|
);
|
|
203
206
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
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
|
|
4
|
+
import {
|
|
5
|
+
type AppConfig,
|
|
6
|
+
type Theme,
|
|
7
|
+
defaultLocalization,
|
|
8
|
+
defaultTheme,
|
|
9
|
+
mergeLocalization,
|
|
10
|
+
} from '../types/PreviewConfig';
|
|
5
11
|
import type { Fonts } from '../types/Fonts';
|
|
6
12
|
import type { ProjectColors } from '../types/Project';
|
|
7
13
|
import { defaultProjectColors, mergeProjectColors } from '../utils';
|
|
@@ -9,13 +15,12 @@ import { defaultProjectColors, mergeProjectColors } from '../utils';
|
|
|
9
15
|
// NOTE: We keep this context intentionally tiny.
|
|
10
16
|
// IMPORTANT: This provider may be mounted once but consumed by multiple `build-components`
|
|
11
17
|
// on the same screen. Keep the value minimal + stable to avoid unnecessary rerenders.
|
|
12
|
-
// In React Native,
|
|
13
|
-
// and passed in via `params` from the host app.
|
|
18
|
+
// In React Native, pass real IAP products here; in the web builder they come from mock presets.
|
|
14
19
|
export type Products = Product;
|
|
15
20
|
|
|
16
21
|
export type BuilderProviderParams = {
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
mockProducts: Products[];
|
|
23
|
+
mockBenefits: PaywallBenefits;
|
|
19
24
|
/**
|
|
20
25
|
* Render platform for style extraction + meta filtering.
|
|
21
26
|
* - 'web' (default): returns CSS-friendly styles for DOM rendering.
|
|
@@ -28,6 +33,8 @@ export type BuilderProviderParams = {
|
|
|
28
33
|
* These are intentionally passed down via BuilderProvider so `build-components`
|
|
29
34
|
* never need to touch `useRenderStore`.
|
|
30
35
|
*/
|
|
36
|
+
theme?: Theme;
|
|
37
|
+
defaultLanguage?: string;
|
|
31
38
|
appConfig?: AppConfig;
|
|
32
39
|
projectColors?: ProjectColors;
|
|
33
40
|
fonts?: Fonts;
|
|
@@ -51,18 +58,34 @@ const builderContext = createContext<BuilderProviderParams | undefined>(
|
|
|
51
58
|
export function BuilderProvider({ params, children }: BuilderProviderProps) {
|
|
52
59
|
const value = useMemo<BuilderProviderParams>(
|
|
53
60
|
() => ({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
mockProducts: Array.isArray(params?.mockProducts)
|
|
62
|
+
? params.mockProducts
|
|
63
|
+
: [],
|
|
64
|
+
mockBenefits:
|
|
65
|
+
params?.mockBenefits && typeof params.mockBenefits === 'object'
|
|
66
|
+
? (params.mockBenefits as PaywallBenefits)
|
|
58
67
|
: {},
|
|
59
68
|
onPaywallSubscribe:
|
|
60
69
|
typeof params?.onPaywallSubscribe === 'function'
|
|
61
70
|
? params.onPaywallSubscribe
|
|
62
71
|
: undefined,
|
|
72
|
+
theme:
|
|
73
|
+
params?.theme === 'light' || params?.theme === 'dark'
|
|
74
|
+
? params.theme
|
|
75
|
+
: defaultTheme,
|
|
76
|
+
defaultLanguage:
|
|
77
|
+
typeof params?.defaultLanguage === 'string'
|
|
78
|
+
? params.defaultLanguage
|
|
79
|
+
: 'en',
|
|
63
80
|
appConfig:
|
|
64
81
|
params?.appConfig && typeof params.appConfig === 'object'
|
|
65
|
-
?
|
|
82
|
+
? {
|
|
83
|
+
...(params.appConfig as AppConfig),
|
|
84
|
+
localication: mergeLocalization(
|
|
85
|
+
defaultLocalization,
|
|
86
|
+
(params.appConfig as AppConfig).localication ?? {},
|
|
87
|
+
),
|
|
88
|
+
}
|
|
66
89
|
: undefined,
|
|
67
90
|
projectColors:
|
|
68
91
|
params?.projectColors && typeof params.projectColors === 'object'
|
|
@@ -78,10 +101,12 @@ export function BuilderProvider({ params, children }: BuilderProviderProps) {
|
|
|
78
101
|
: undefined,
|
|
79
102
|
}),
|
|
80
103
|
[
|
|
81
|
-
params?.
|
|
82
|
-
params?.
|
|
104
|
+
params?.mockBenefits,
|
|
105
|
+
params?.mockProducts,
|
|
83
106
|
params?.platform,
|
|
84
107
|
params?.onPaywallSubscribe,
|
|
108
|
+
params?.theme,
|
|
109
|
+
params?.defaultLanguage,
|
|
85
110
|
params?.appConfig,
|
|
86
111
|
params?.projectColors,
|
|
87
112
|
params?.fonts,
|
|
@@ -99,9 +124,11 @@ export function BuilderProvider({ params, children }: BuilderProviderProps) {
|
|
|
99
124
|
export function useBuilderParams(): Readonly<BuilderProviderParams> {
|
|
100
125
|
return (
|
|
101
126
|
useContext(builderContext) ?? {
|
|
102
|
-
|
|
103
|
-
|
|
127
|
+
mockProducts: [],
|
|
128
|
+
mockBenefits: {},
|
|
104
129
|
platform: 'web',
|
|
130
|
+
theme: defaultTheme,
|
|
131
|
+
defaultLanguage: 'en',
|
|
105
132
|
projectColors: defaultProjectColors,
|
|
106
133
|
}
|
|
107
134
|
);
|
|
@@ -15,7 +15,7 @@ export function LocalizationParamsProvider({
|
|
|
15
15
|
children,
|
|
16
16
|
}: LocalizationParamsProviderProps) {
|
|
17
17
|
return (
|
|
18
|
-
<ParamsProvider localizationParams={params}
|
|
18
|
+
<ParamsProvider localizationParams={params} nestedLocalizationParams={{}}>
|
|
19
19
|
{children}
|
|
20
20
|
</ParamsProvider>
|
|
21
21
|
);
|
|
@@ -1,44 +1,69 @@
|
|
|
1
|
-
import React, { createContext, useMemo } from 'react';
|
|
1
|
+
import React, { createContext, useEffect, useMemo } from 'react';
|
|
2
|
+
import type { ProductParams, SingleProductParams } from '../product-base/types';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
export type
|
|
4
|
+
/** Provider-level params not tied to a single product. */
|
|
5
|
+
export type ContextLocalizationParams = {
|
|
6
|
+
platform?: string;
|
|
7
|
+
[key: `benefit${number}`]: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type LocalizationParams = Partial<ProductParams> &
|
|
11
|
+
ContextLocalizationParams;
|
|
12
|
+
export type NestedLocalizationParams = Partial<SingleProductParams>;
|
|
13
|
+
|
|
14
|
+
export type OtherParams = {
|
|
15
|
+
singleProductIsSelected?: boolean;
|
|
16
|
+
};
|
|
5
17
|
|
|
6
18
|
export type ParamsContextValue = {
|
|
7
19
|
localizationParams: LocalizationParams;
|
|
20
|
+
nestedLocalizationParams: NestedLocalizationParams;
|
|
8
21
|
otherParams: OtherParams;
|
|
9
|
-
/**
|
|
10
|
-
* `true` when the value comes from an actual `<ParamsProvider />` in the tree.
|
|
11
|
-
* Used to detect nesting vs the default context value.
|
|
12
|
-
*/
|
|
13
|
-
isProvided: boolean;
|
|
14
22
|
};
|
|
15
23
|
|
|
16
24
|
export type ParamsProviderProps = {
|
|
17
25
|
localizationParams?: LocalizationParams;
|
|
26
|
+
nestedLocalizationParams?: NestedLocalizationParams;
|
|
18
27
|
otherParams?: OtherParams;
|
|
19
28
|
children: React.ReactNode;
|
|
20
29
|
};
|
|
21
30
|
|
|
22
31
|
export const ParamsContext = createContext<ParamsContextValue>({
|
|
23
32
|
localizationParams: {},
|
|
33
|
+
nestedLocalizationParams: {},
|
|
24
34
|
otherParams: {},
|
|
25
|
-
isProvided: false,
|
|
26
35
|
});
|
|
27
36
|
|
|
37
|
+
let _lastParamsSnapshot: ParamsContextValue = {
|
|
38
|
+
localizationParams: {},
|
|
39
|
+
nestedLocalizationParams: {},
|
|
40
|
+
otherParams: {},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** Read-only snapshot of the most recent ParamsProvider value (for debug UIs rendered outside the context tree). */
|
|
44
|
+
export function getLastParamsSnapshot(): Readonly<ParamsContextValue> {
|
|
45
|
+
return _lastParamsSnapshot;
|
|
46
|
+
}
|
|
47
|
+
|
|
28
48
|
export function ParamsProvider({
|
|
29
49
|
localizationParams,
|
|
50
|
+
nestedLocalizationParams,
|
|
30
51
|
otherParams,
|
|
31
52
|
children,
|
|
32
53
|
}: ParamsProviderProps) {
|
|
33
54
|
const value = useMemo<ParamsContextValue>(
|
|
34
55
|
() => ({
|
|
35
56
|
localizationParams: localizationParams ?? {},
|
|
57
|
+
nestedLocalizationParams: nestedLocalizationParams ?? {},
|
|
36
58
|
otherParams: otherParams ?? {},
|
|
37
|
-
isProvided: true,
|
|
38
59
|
}),
|
|
39
|
-
[localizationParams, otherParams],
|
|
60
|
+
[localizationParams, nestedLocalizationParams, otherParams],
|
|
40
61
|
);
|
|
41
62
|
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
_lastParamsSnapshot = value;
|
|
65
|
+
}, [value]);
|
|
66
|
+
|
|
42
67
|
return (
|
|
43
68
|
<ParamsContext.Provider value={value}>{children}</ParamsContext.Provider>
|
|
44
69
|
);
|
package/src/hooks/useLocalize.ts
CHANGED
|
@@ -8,15 +8,18 @@ import { replaceLocalizationParams } from '../utils/replaceLocalizationParams';
|
|
|
8
8
|
export type LocalizeFn = (keyOrText: string) => string;
|
|
9
9
|
|
|
10
10
|
export function useLocalize(options?: { appConfig?: AppConfig }): LocalizeFn {
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
appConfig: builderAppConfig,
|
|
13
|
+
defaultLanguage: builderDefaultLanguage,
|
|
14
|
+
} = useBuilderParams();
|
|
12
15
|
const appConfig = options?.appConfig ?? builderAppConfig ?? defaultAppConfig;
|
|
13
|
-
const
|
|
16
|
+
const defaultLanguage = builderDefaultLanguage ?? 'en';
|
|
17
|
+
const { localication } = appConfig;
|
|
14
18
|
const params = useLocalizationParams();
|
|
15
19
|
|
|
16
20
|
return useCallback(
|
|
17
21
|
(keyOrText: string) => {
|
|
18
|
-
const raw =
|
|
19
|
-
localication?.[defaultLanguage ?? 'en']?.[keyOrText] ?? keyOrText;
|
|
22
|
+
const raw = localication?.[defaultLanguage]?.[keyOrText] ?? keyOrText;
|
|
20
23
|
return replaceLocalizationParams(raw, params);
|
|
21
24
|
},
|
|
22
25
|
[defaultLanguage, localication, params],
|
package/src/hooks/useParams.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { useEffect } from 'react';
|
|
|
2
2
|
import { useRenderStore } from '../store';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Syncs the builder's `
|
|
5
|
+
* Syncs the builder's `theme` to the DOM so CSS can react to `.dark`.
|
|
6
6
|
*
|
|
7
7
|
* - Uses `html.dark` as the toggle (shadcn/tailwind convention).
|
|
8
8
|
* - Also toggles `html.light` so system dark can be overridden back to light.
|
|
9
9
|
*/
|
|
10
10
|
export function useSyncHtmlThemeClass() {
|
|
11
|
-
const theme = useRenderStore((s) => s.
|
|
11
|
+
const theme = useRenderStore((s) => s.theme);
|
|
12
12
|
|
|
13
13
|
useEffect(() => {
|
|
14
14
|
if (typeof document === 'undefined') return;
|
package/src/index.ts
CHANGED
|
@@ -15,8 +15,18 @@ export type { TargetedScreenSize } from './types/TargetedScreenSize';
|
|
|
15
15
|
export type { Node, NodeData, NodeDefaultAttribute } from './types/Node';
|
|
16
16
|
export type { Project, ProjectColors, ProjectMeta } from './types/Project';
|
|
17
17
|
export type { Device } from './types/Device';
|
|
18
|
-
export type {
|
|
19
|
-
|
|
18
|
+
export type {
|
|
19
|
+
AppConfig,
|
|
20
|
+
Theme,
|
|
21
|
+
Localication,
|
|
22
|
+
LocalizationKey,
|
|
23
|
+
} from './types/PreviewConfig';
|
|
24
|
+
export {
|
|
25
|
+
defaultAppConfig,
|
|
26
|
+
defaultTheme,
|
|
27
|
+
defaultLocalization,
|
|
28
|
+
mergeLocalization,
|
|
29
|
+
} from './types/PreviewConfig';
|
|
20
30
|
export type { Fonts, FontDefinition } from './types/Fonts';
|
|
21
31
|
export type {
|
|
22
32
|
PaywallBenefitValue,
|
|
@@ -25,13 +35,53 @@ export type {
|
|
|
25
35
|
PaywallModel,
|
|
26
36
|
} from './paywall/types/paywall-types';
|
|
27
37
|
|
|
28
|
-
// Paywall hooks (RN-safe
|
|
38
|
+
// Paywall hooks (RN-safe)
|
|
29
39
|
export {
|
|
30
40
|
useCalculateLocalizedPrice,
|
|
31
41
|
useDiscountRate,
|
|
32
42
|
useChangeDelayByPaywall,
|
|
33
43
|
} from './paywall/hooks';
|
|
34
44
|
|
|
45
|
+
// Product base — centralized product utilities (RN-safe)
|
|
46
|
+
export type {
|
|
47
|
+
Product,
|
|
48
|
+
PurchaseType,
|
|
49
|
+
ProductInput,
|
|
50
|
+
PricingPhase,
|
|
51
|
+
SubscriptionOffer,
|
|
52
|
+
IOSDiscount,
|
|
53
|
+
IOSIntroductoryPrice,
|
|
54
|
+
AndroidOfferDetails,
|
|
55
|
+
PeriodUnit,
|
|
56
|
+
IOSPeriodUnit,
|
|
57
|
+
RecurrenceMode,
|
|
58
|
+
} from './product-base';
|
|
59
|
+
export type { AndroidParams } from './product-base';
|
|
60
|
+
export type { IOSParams } from './product-base';
|
|
61
|
+
export type { ProductParams, SingleProductParams } from './product-base';
|
|
62
|
+
/** @deprecated Use ProductParams instead */
|
|
63
|
+
export type { ProductParams as PaywallLocalizationParams } from './product-base';
|
|
64
|
+
export type { PaywallLocalizationConfig } from './product-base';
|
|
65
|
+
export {
|
|
66
|
+
extractPrice,
|
|
67
|
+
calculateDiscount,
|
|
68
|
+
calculatePricePerMonth,
|
|
69
|
+
calculatePricePerYear,
|
|
70
|
+
} from './product-base';
|
|
71
|
+
export {
|
|
72
|
+
PERIOD_LOCALIZATION_KEYS,
|
|
73
|
+
getPeriodLocalizationKey,
|
|
74
|
+
parseBillingPeriod,
|
|
75
|
+
convertIOSPeriodUnit,
|
|
76
|
+
} from './product-base';
|
|
77
|
+
export { extractAndroidParams, extractIOSParams } from './product-base';
|
|
78
|
+
export {
|
|
79
|
+
buildPaywallLocalizationParams,
|
|
80
|
+
usePaywallLocalizationParams,
|
|
81
|
+
} from './product-base';
|
|
82
|
+
export type { MockProductPresets } from './product-base';
|
|
83
|
+
export { getMockProducts, getMockProductsByPreset } from './product-base';
|
|
84
|
+
|
|
35
85
|
// Context (RN-safe). In React Native, `products` should come from an IAP wrapper
|
|
36
86
|
// (e.g. `react-native-iap`) and be passed into `BuilderProvider` by the host app.
|
|
37
87
|
export {
|
|
@@ -84,11 +134,7 @@ export type * from './build-components';
|
|
|
84
134
|
export { default as useNode } from './build-components/useNode';
|
|
85
135
|
|
|
86
136
|
// Static sample data helpers (RN-safe)
|
|
87
|
-
export {
|
|
88
|
-
getSamples,
|
|
89
|
-
getBasicSamples,
|
|
90
|
-
getOnboardSamples,
|
|
91
|
-
} from './assets/samples/getSamples';
|
|
137
|
+
export { getSamples } from './assets/samples/getSamples';
|
|
92
138
|
export { getDefaultProject } from './utils/getDefaultProject';
|
|
93
139
|
export type { EventObjectGenerated } from './build-components/OnboardButton/OnboardButtonProps.generated';
|
|
94
140
|
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IAP logger shim — delegates to console.
|
|
3
|
+
*
|
|
4
|
+
* The core project replaces this with a richer logger (Bugsnag remote, etc.).
|
|
5
|
+
* This minimal version keeps product-base compilable in the builder context.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
type LogPayload = Record<string, unknown>;
|
|
9
|
+
type LogOptions = { remote?: boolean };
|
|
10
|
+
|
|
11
|
+
function noop() {}
|
|
12
|
+
|
|
13
|
+
export const iapLogger = {
|
|
14
|
+
error(
|
|
15
|
+
_tags: string[],
|
|
16
|
+
message: string,
|
|
17
|
+
payload?: LogPayload,
|
|
18
|
+
_opts?: LogOptions,
|
|
19
|
+
) {
|
|
20
|
+
console.error(`[iap] ${message}`, payload);
|
|
21
|
+
},
|
|
22
|
+
warn(
|
|
23
|
+
_tags: string[],
|
|
24
|
+
message: string,
|
|
25
|
+
payload?: LogPayload,
|
|
26
|
+
_opts?: LogOptions,
|
|
27
|
+
) {
|
|
28
|
+
console.warn(`[iap] ${message}`, payload);
|
|
29
|
+
},
|
|
30
|
+
info(
|
|
31
|
+
_tags: string[],
|
|
32
|
+
message: string,
|
|
33
|
+
payload?: LogPayload,
|
|
34
|
+
_opts?: LogOptions,
|
|
35
|
+
) {
|
|
36
|
+
console.info(`[iap] ${message}`, payload);
|
|
37
|
+
},
|
|
38
|
+
debug: noop,
|
|
39
|
+
};
|