@namiml/expo-sdk 3.4.1 → 3.4.2-dev.202606032130
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/index.cjs +40 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +42 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
- package/src/components/NamiView.tsx +20 -6
- package/src/components/PaywallScreen.tsx +14 -0
- package/src/components/containers/NamiContentContainer.tsx +11 -0
- package/src/components/containers/NamiResponsiveGrid.tsx +68 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { NAMI_SDK_PACKAGE_VERSION, registerPlatformAdapters, registerPurchaseAdapter, logger, Nami as Nami$1, PaywallState, initialState, getUrlParams, SMART_TEXT_PATTERN, VAR_REGEX, LIQUID_VARIABLE_REGEX, isAnonymousMode, NamiAPI, storageService, getDeviceScaleFactor, NamiEventEmitter, PAYWALL_ACTION_EVENT, NamiPaywallAction, NamiReservedActions, _internal, isNamiFlowCampaign, hasAllPaywalls, getPaywallDataFromLabel, getPaywall } from '@namiml/sdk-core';
|
|
1
|
+
import { NAMI_SDK_PACKAGE_VERSION, registerPlatformAdapters, registerPurchaseAdapter, logger, Nami as Nami$1, PaywallState, initialState, getUrlParams, SMART_TEXT_PATTERN, VAR_REGEX, LIQUID_VARIABLE_REGEX, isAnonymousMode, NamiAPI, storageService, getDeviceScaleFactor, NamiEventEmitter, PAYWALL_ACTION_EVENT, NamiPaywallAction, NamiReservedActions, _internal, isValidUrl, isNamiFlowCampaign, hasAllPaywalls, getPaywallDataFromLabel, getPaywall } from '@namiml/sdk-core';
|
|
2
2
|
export { NamiCampaignManager, NamiCustomerManager, NamiEntitlementManager, NamiFlowManager, NamiPaywallManager, NamiPurchaseManager } from '@namiml/sdk-core';
|
|
3
|
-
import { Platform, Dimensions, StyleSheet, View, ScrollView, ImageBackground, BackHandler, ActivityIndicator,
|
|
3
|
+
import { Platform, Dimensions, StyleSheet, View, ScrollView, ImageBackground, BackHandler, ActivityIndicator, StatusBar, Animated } from 'react-native';
|
|
4
4
|
import require$$0, { createContext, useRef, useState, useEffect, useMemo, useContext, useCallback, useLayoutEffect } from 'react';
|
|
5
|
+
import { useSafeAreaInsets, SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context';
|
|
5
6
|
|
|
6
7
|
class ExpoStorageAdapter {
|
|
7
8
|
constructor() {
|
|
@@ -2940,6 +2941,17 @@ function renderResolvedComponent(componentType, resolvedComponent, scaleFactor,
|
|
|
2940
2941
|
function splitContainerStyles(style) {
|
|
2941
2942
|
const { paddingLeft, paddingRight, paddingTop, paddingBottom, flexDirection, alignItems, justifyContent, ...rest } = style;
|
|
2942
2943
|
const outer = { ...rest };
|
|
2944
|
+
// The content container is always the page's vertical fill region: styles.outer
|
|
2945
|
+
// declares flex:1 and the body scrolls internally. A payload height of
|
|
2946
|
+
// 'fitContent' makes sizeStyles emit flexGrow:0, which would otherwise override
|
|
2947
|
+
// that fill and collapse the body to 0 height — the flex:1 ScrollView child
|
|
2948
|
+
// can't give an unbounded parent a height. Drop the flex-sizing keys so the
|
|
2949
|
+
// fill stays authoritative, matching the native renderers which always
|
|
2950
|
+
// fill-and-scroll this region regardless of the authored height.
|
|
2951
|
+
delete outer.flex;
|
|
2952
|
+
delete outer.flexGrow;
|
|
2953
|
+
delete outer.flexBasis;
|
|
2954
|
+
delete outer.flexShrink;
|
|
2943
2955
|
const inner = {
|
|
2944
2956
|
...(paddingLeft != null ? { paddingLeft } : {}),
|
|
2945
2957
|
...(paddingRight != null ? { paddingRight } : {}),
|
|
@@ -3141,7 +3153,19 @@ catch {
|
|
|
3141
3153
|
const fontGateCache = new Map();
|
|
3142
3154
|
const PaywallScreen = ({ paywall, onClose, onCommitted, holdInteractionUntilFocus = false, isActive = true, }) => {
|
|
3143
3155
|
const ctx = usePaywallContext();
|
|
3156
|
+
const insets = useSafeAreaInsets();
|
|
3144
3157
|
const focusReadyCtx = useFirstFocusReadyContext();
|
|
3158
|
+
// Push the measured top safe-area inset into paywall state so templates can
|
|
3159
|
+
// position chrome via ${state.safeAreaTop} (e.g. header topPadding,
|
|
3160
|
+
// background topMargin). Mirrors the native Android renderer, which measures
|
|
3161
|
+
// the display cutout and calls setSafeAreaTop. The full-bleed root lets the
|
|
3162
|
+
// background extend under the status bar; this offsets the content back into
|
|
3163
|
+
// the safe area. No safeAreaBottom equivalent exists in core/Android state.
|
|
3164
|
+
// Depend only on insets.top (stable per device/orientation) — depending on
|
|
3165
|
+
// ctx would re-run every render and loop through setState.
|
|
3166
|
+
useEffect(() => {
|
|
3167
|
+
ctx.setSafeAreaTop(insets.top);
|
|
3168
|
+
}, [insets.top]);
|
|
3145
3169
|
const scaleFactor = getDeviceScaleFactor(ctx.state.formFactor);
|
|
3146
3170
|
const userInteractionEnabled = ctx.state.userInteractionEnabled !== false;
|
|
3147
3171
|
const currentPageName = ctx.state.selectedPaywall === paywall
|
|
@@ -3329,8 +3353,13 @@ const NamiView = ({ placement, url, onClose, onSignIn, onDeepLink, onPurchase, o
|
|
|
3329
3353
|
return launchRequest;
|
|
3330
3354
|
if (url)
|
|
3331
3355
|
return { type: 'url', value: url };
|
|
3332
|
-
if (placement)
|
|
3333
|
-
|
|
3356
|
+
if (placement) {
|
|
3357
|
+
// A URL/deeplink campaign carries its URL in the value. If one is handed
|
|
3358
|
+
// in via the placement prop, classify it as a url launch so core takes
|
|
3359
|
+
// the URL-match branch — otherwise the label lookup misses, no paywall
|
|
3360
|
+
// resolves, and NamiView spins on the placeholder forever.
|
|
3361
|
+
return { type: isValidUrl(placement) ? 'url' : 'label', value: placement };
|
|
3362
|
+
}
|
|
3334
3363
|
return { type: undefined, value: '' };
|
|
3335
3364
|
}, [launchRequest, url, placement]);
|
|
3336
3365
|
const ctx = useMemo(() => ({
|
|
@@ -3742,12 +3771,19 @@ const NamiView = ({ placement, url, onClose, onSignIn, onDeepLink, onPurchase, o
|
|
|
3742
3771
|
setInitialScreenCommitted(true);
|
|
3743
3772
|
}, []);
|
|
3744
3773
|
if (isClosing) {
|
|
3745
|
-
return jsxRuntimeExports.jsx(
|
|
3774
|
+
return jsxRuntimeExports.jsx(View, { style: styles.root });
|
|
3746
3775
|
}
|
|
3747
3776
|
if (loading || !campaignData || (!isFlowCampaign && !paywallData) || (isFlowCampaign && !hasFlowScreen)) {
|
|
3748
3777
|
return jsxRuntimeExports.jsx(LaunchPlaceholder, { paywall: launchPlaceholderPaywall });
|
|
3749
3778
|
}
|
|
3750
|
-
return (
|
|
3779
|
+
return (
|
|
3780
|
+
// Full-bleed root so the paywall background extends under the status bar and
|
|
3781
|
+
// home indicator (edge-to-edge). Safe-area insets are applied only to the
|
|
3782
|
+
// chrome (header/footer) via useSafeAreaInsets, not the whole tree — the
|
|
3783
|
+
// previous core SafeAreaView inset every edge and let the #000 root show
|
|
3784
|
+
// through as letterbox bands. SafeAreaProvider guarantees an inset context
|
|
3785
|
+
// even if the host app didn't mount one (nested providers are supported).
|
|
3786
|
+
jsxRuntimeExports.jsxs(SafeAreaProvider, { initialMetrics: initialWindowMetrics, style: styles.root, children: [jsxRuntimeExports.jsx(StatusBar, { barStyle: "light-content", translucent: true, backgroundColor: "transparent" }), isFlowCampaign ? (jsxRuntimeExports.jsx(FlowRenderer, { paywalls: flowState.paywalls, currentIndex: flowState.index, animation: flowState.animation ?? undefined, onSettled: handleFlowAnimationSettled, onTransitionVisible: () => setPendingTransitionPaywall(null), onInitialCommitted: handleInitialCommitted, onClose: onClose, campaign: campaignData, context: ctx, flow: flowRef.current })) : (jsxRuntimeExports.jsx(PaywallProvider, { paywall: paywallData, context: ctx, campaign: campaignData, children: jsxRuntimeExports.jsx(PaywallScreen, { paywall: paywallData, onClose: requestClose, onCommitted: handleInitialCommitted, isActive: true }) })), !isClosing && showLaunchPlaceholder && jsxRuntimeExports.jsx(LaunchPlaceholder, { paywall: launchPlaceholderPaywall, overlay: true }), showTransitionPlaceholder && jsxRuntimeExports.jsx(LaunchPlaceholder, { paywall: pendingTransitionPaywall, overlay: true })] }));
|
|
3751
3787
|
};
|
|
3752
3788
|
const LaunchPlaceholder = ({ paywall, overlay = false }) => {
|
|
3753
3789
|
const initialPageName = paywall?.template?.initialState?.currentPage ?? 'page1';
|