@revenuecat/purchases-ui-js 4.6.0 → 4.7.0
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/components/button/ButtonNode.svelte +35 -15
- package/dist/components/paywall/Node.svelte +13 -4
- package/dist/components/paywall/Paywall.svelte +15 -0
- package/dist/components/paywall/Paywall.svelte.d.ts +7 -0
- package/dist/components/workflows/Screen.svelte +6 -0
- package/dist/components/workflows/Screen.svelte.d.ts +2 -0
- package/dist/components/workflows/Workflow.stories.svelte +53 -0
- package/dist/components/workflows/Workflow.stories.svelte.d.ts +19 -0
- package/dist/components/workflows/Workflow.svelte +130 -0
- package/dist/components/workflows/Workflow.svelte.d.ts +32 -0
- package/dist/components/workflows/fixtures/two-page-workflow.d.ts +12 -0
- package/dist/components/workflows/fixtures/two-page-workflow.js +378 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/types/component.d.ts +2 -1
- package/dist/types/components/button.d.ts +8 -1
- package/dist/types/components/fallback-header.d.ts +9 -0
- package/dist/types/components/fallback-header.js +1 -0
- package/dist/types/paywall-component-interaction.d.ts +1 -1
- package/dist/types/workflow-nav.d.ts +30 -0
- package/dist/types/workflow-nav.js +34 -0
- package/dist/types/workflow.d.ts +29 -0
- package/package.json +1 -1
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
import { readable } from "svelte/store";
|
|
14
14
|
|
|
15
15
|
const props: ButtonProps = $props();
|
|
16
|
+
type SheetAction = Extract<
|
|
17
|
+
ButtonProps["action"],
|
|
18
|
+
{ type: "navigate_to"; destination: "sheet" }
|
|
19
|
+
>;
|
|
16
20
|
|
|
17
21
|
const selectedState = getSelectedStateContext();
|
|
18
22
|
const { action } = $derived.by(() => {
|
|
@@ -63,6 +67,18 @@
|
|
|
63
67
|
componentName: props.name,
|
|
64
68
|
componentValue: "navigate_back",
|
|
65
69
|
};
|
|
70
|
+
case "navigate_to_page":
|
|
71
|
+
return {
|
|
72
|
+
componentType: "button",
|
|
73
|
+
componentName: props.name,
|
|
74
|
+
componentValue: "navigate_to_page",
|
|
75
|
+
};
|
|
76
|
+
case "close_workflow":
|
|
77
|
+
return {
|
|
78
|
+
componentType: "button",
|
|
79
|
+
componentName: props.name,
|
|
80
|
+
componentValue: "close_workflow",
|
|
81
|
+
};
|
|
66
82
|
case "restore_purchases":
|
|
67
83
|
return {
|
|
68
84
|
componentType: "button",
|
|
@@ -122,28 +138,28 @@
|
|
|
122
138
|
}
|
|
123
139
|
};
|
|
124
140
|
|
|
125
|
-
const getSheetOpenInteractionData =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
141
|
+
const getSheetOpenInteractionData = (
|
|
142
|
+
sheetAction: SheetAction,
|
|
143
|
+
): PackageSelectionSheetInteractionData => ({
|
|
144
|
+
componentType: "package_selection_sheet",
|
|
145
|
+
componentName: sheetAction.sheet?.name ?? props.name,
|
|
146
|
+
componentValue: "open",
|
|
147
|
+
currentPackageId: $selectedPackageId,
|
|
148
|
+
});
|
|
132
149
|
|
|
133
150
|
const onclick = () => {
|
|
134
151
|
if (isDisabled) return;
|
|
135
152
|
const actionId = props.triggers?.on_press;
|
|
136
|
-
|
|
137
|
-
action.
|
|
138
|
-
|
|
139
|
-
|
|
153
|
+
if (action.type === "navigate_to" && action.destination === "sheet") {
|
|
154
|
+
if (action.sheet != null) {
|
|
155
|
+
emitComponentInteraction(getSheetOpenInteractionData(action));
|
|
156
|
+
}
|
|
140
157
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} else if (!isSheetCloseAction) {
|
|
144
|
-
emitComponentInteraction(getButtonInteractionData());
|
|
158
|
+
onButtonAction(action, actionId);
|
|
159
|
+
return;
|
|
145
160
|
}
|
|
146
161
|
|
|
162
|
+
emitComponentInteraction(getButtonInteractionData());
|
|
147
163
|
onButtonAction(action, actionId);
|
|
148
164
|
};
|
|
149
165
|
|
|
@@ -157,6 +173,10 @@
|
|
|
157
173
|
return false;
|
|
158
174
|
case "navigate_back":
|
|
159
175
|
return !hideBackButtons;
|
|
176
|
+
case "navigate_to_page":
|
|
177
|
+
return true;
|
|
178
|
+
case "close_workflow":
|
|
179
|
+
return true;
|
|
160
180
|
case "navigate_to":
|
|
161
181
|
return action.destination !== "web_paywall_link";
|
|
162
182
|
default:
|
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
nodeData: Component;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
type RenderableComponent = Exclude<
|
|
37
|
+
Component,
|
|
38
|
+
{ type: "tab" | "fallback_header" }
|
|
39
|
+
>;
|
|
40
|
+
|
|
36
41
|
const ComponentTypes = {
|
|
37
42
|
button: ButtonNode,
|
|
38
43
|
carousel: Carousel,
|
|
@@ -60,11 +65,15 @@
|
|
|
60
65
|
video: Video,
|
|
61
66
|
wallet_button: WalletButton,
|
|
62
67
|
} satisfies {
|
|
63
|
-
[key in
|
|
64
|
-
Extract<
|
|
68
|
+
[key in RenderableComponent["type"]]: SvelteComponent<
|
|
69
|
+
Extract<RenderableComponent, { type: key }>
|
|
65
70
|
>;
|
|
66
71
|
};
|
|
67
72
|
|
|
73
|
+
const isRenderableComponent = (
|
|
74
|
+
component: Component,
|
|
75
|
+
): component is RenderableComponent => component.type in ComponentTypes;
|
|
76
|
+
|
|
68
77
|
/**
|
|
69
78
|
* This function returns the component class and the node data for a given paywall component.
|
|
70
79
|
* It first checks if the component type is supported and returns the corresponding component class.
|
|
@@ -79,7 +88,7 @@
|
|
|
79
88
|
) => [SvelteComponent<Component>, Component] | undefined = (
|
|
80
89
|
nodeData: Component,
|
|
81
90
|
) => {
|
|
82
|
-
if (
|
|
91
|
+
if (isRenderableComponent(nodeData)) {
|
|
83
92
|
return [
|
|
84
93
|
ComponentTypes[nodeData.type] as SvelteComponent<Component>,
|
|
85
94
|
nodeData,
|
|
@@ -91,7 +100,7 @@
|
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
const { fallback } = nodeData;
|
|
94
|
-
if (fallback &&
|
|
103
|
+
if (fallback && isRenderableComponent(fallback)) {
|
|
95
104
|
return [
|
|
96
105
|
ComponentTypes[fallback.type] as SvelteComponent<Component>,
|
|
97
106
|
fallback,
|
|
@@ -71,6 +71,13 @@
|
|
|
71
71
|
preferredColorMode?: ColorMode;
|
|
72
72
|
onPurchaseClicked?: (selectedPackageId: string, actionId: string) => void;
|
|
73
73
|
onBackClicked?: () => void;
|
|
74
|
+
/**
|
|
75
|
+
* Called when a `navigate_to_page` button is pressed and there is no
|
|
76
|
+
* active nav_host context to handle it internally.
|
|
77
|
+
*/
|
|
78
|
+
onNavigateToPage?: (pageId: string) => void;
|
|
79
|
+
/** Called when a `close_workflow` button is pressed to dismiss the paywall/workflow. */
|
|
80
|
+
onClose?: () => void;
|
|
74
81
|
onVisitCustomerCenterClicked?: () => void;
|
|
75
82
|
onRestorePurchasesClicked?: () => void;
|
|
76
83
|
onNavigateToUrlClicked?: (url: string) => void;
|
|
@@ -128,6 +135,8 @@
|
|
|
128
135
|
preferredColorMode,
|
|
129
136
|
onPurchaseClicked,
|
|
130
137
|
onBackClicked,
|
|
138
|
+
onNavigateToPage,
|
|
139
|
+
onClose,
|
|
131
140
|
onVisitCustomerCenterClicked,
|
|
132
141
|
onRestorePurchasesClicked,
|
|
133
142
|
onNavigateToUrlClicked,
|
|
@@ -239,6 +248,12 @@
|
|
|
239
248
|
case "navigate_back":
|
|
240
249
|
onBackClicked?.();
|
|
241
250
|
return;
|
|
251
|
+
case "navigate_to_page":
|
|
252
|
+
onNavigateToPage?.(action.page_id);
|
|
253
|
+
return;
|
|
254
|
+
case "close_workflow":
|
|
255
|
+
onClose?.();
|
|
256
|
+
return;
|
|
242
257
|
case "restore_purchases":
|
|
243
258
|
onRestorePurchasesClicked?.();
|
|
244
259
|
return;
|
|
@@ -28,6 +28,13 @@ interface Props {
|
|
|
28
28
|
preferredColorMode?: ColorMode;
|
|
29
29
|
onPurchaseClicked?: (selectedPackageId: string, actionId: string) => void;
|
|
30
30
|
onBackClicked?: () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Called when a `navigate_to_page` button is pressed and there is no
|
|
33
|
+
* active nav_host context to handle it internally.
|
|
34
|
+
*/
|
|
35
|
+
onNavigateToPage?: (pageId: string) => void;
|
|
36
|
+
/** Called when a `close_workflow` button is pressed to dismiss the paywall/workflow. */
|
|
37
|
+
onClose?: () => void;
|
|
31
38
|
onVisitCustomerCenterClicked?: () => void;
|
|
32
39
|
onRestorePurchasesClicked?: () => void;
|
|
33
40
|
onNavigateToUrlClicked?: (url: string) => void;
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
actionId: string,
|
|
22
22
|
) => void | Promise<void>;
|
|
23
23
|
onBackClicked?: () => void;
|
|
24
|
+
onNavigateToPage?: (pageId: string) => void;
|
|
25
|
+
onClose?: () => void;
|
|
24
26
|
containerId?: string;
|
|
25
27
|
maxContentWidth?: string;
|
|
26
28
|
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
@@ -49,6 +51,8 @@
|
|
|
49
51
|
onComponentInteraction,
|
|
50
52
|
onPurchaseClicked,
|
|
51
53
|
onBackClicked,
|
|
54
|
+
onNavigateToPage,
|
|
55
|
+
onClose,
|
|
52
56
|
containerId = "screen-container",
|
|
53
57
|
maxContentWidth,
|
|
54
58
|
variablesPerPackage,
|
|
@@ -77,6 +81,8 @@
|
|
|
77
81
|
{onCompleteWorkflowNavigate}
|
|
78
82
|
onVisitCustomerCenterClicked={() => {}}
|
|
79
83
|
{onBackClicked}
|
|
84
|
+
{onNavigateToPage}
|
|
85
|
+
{onClose}
|
|
80
86
|
onRestorePurchasesClicked={() => {}}
|
|
81
87
|
onActionTriggered={(actionId: string) => {
|
|
82
88
|
onActionTriggered?.(actionId);
|
|
@@ -16,6 +16,8 @@ interface Props {
|
|
|
16
16
|
onComponentInteraction?: OnComponentInteraction;
|
|
17
17
|
onPurchaseClicked?: (packageId: string, actionId: string) => void | Promise<void>;
|
|
18
18
|
onBackClicked?: () => void;
|
|
19
|
+
onNavigateToPage?: (pageId: string) => void;
|
|
20
|
+
onClose?: () => void;
|
|
19
21
|
containerId?: string;
|
|
20
22
|
maxContentWidth?: string;
|
|
21
23
|
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import type { ComponentProps } from "svelte";
|
|
4
|
+
|
|
5
|
+
import Workflow from "./Workflow.svelte";
|
|
6
|
+
import { uiConfigData } from "../../stories/fixtures";
|
|
7
|
+
import { TWO_PAGE_WORKFLOW } from "./fixtures/two-page-workflow";
|
|
8
|
+
|
|
9
|
+
const { Story } = defineMeta({
|
|
10
|
+
title: "Example/Workflow",
|
|
11
|
+
component: Workflow,
|
|
12
|
+
render: template,
|
|
13
|
+
args: {
|
|
14
|
+
workflow: TWO_PAGE_WORKFLOW,
|
|
15
|
+
uiConfig: uiConfigData,
|
|
16
|
+
onClose: () => alert("onClose — workflow dismissed"),
|
|
17
|
+
onExitBack: () => alert("onExitBack — backed out from root page"),
|
|
18
|
+
onPurchaseClicked: (packageId: string, actionId: string) =>
|
|
19
|
+
alert(`onPurchaseClicked — package: ${packageId}, action: ${actionId}`),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
{#snippet template(props: ComponentProps<typeof Workflow>)}
|
|
25
|
+
<div class="viewport-frame">
|
|
26
|
+
<div class="content-wrapper">
|
|
27
|
+
<Workflow {...props} />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
{/snippet}
|
|
31
|
+
|
|
32
|
+
<Story name="Two-page navigation" />
|
|
33
|
+
|
|
34
|
+
<style>
|
|
35
|
+
.viewport-frame {
|
|
36
|
+
position: fixed;
|
|
37
|
+
inset: 0;
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
background-color: var(--rc-purchases-ui-bg-color, Canvas);
|
|
41
|
+
color-scheme: light dark;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.content-wrapper {
|
|
46
|
+
width: 100%;
|
|
47
|
+
display: flex;
|
|
48
|
+
flex: 1 1 auto;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
min-height: 0;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Workflow from "./Workflow.svelte";
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Workflow: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Workflow = InstanceType<typeof Workflow>;
|
|
19
|
+
export default Workflow;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Screen from "./Screen.svelte";
|
|
3
|
+
import type { CompleteWorkflowNavigateArgs } from "../../types/components/button";
|
|
4
|
+
import type { ColorScheme } from "../../types/colors";
|
|
5
|
+
import type { InitialInputSelections } from "../../stores/inputValidation";
|
|
6
|
+
import type { OnComponentInteraction } from "../../types/paywall-component-interaction";
|
|
7
|
+
import type { VariableDictionary } from "../../types/variables";
|
|
8
|
+
import type { WalletButtonRender } from "../../types/wallet";
|
|
9
|
+
import type { UIConfig } from "../../types/ui-config";
|
|
10
|
+
import type { ReservedAttribute } from "../../types/components/input-text";
|
|
11
|
+
import type { WorkflowNavData } from "../../types/workflow-nav";
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
workflow: WorkflowNavData;
|
|
15
|
+
uiConfig: UIConfig;
|
|
16
|
+
selectedLocale?: string;
|
|
17
|
+
globalVariables?: VariableDictionary;
|
|
18
|
+
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
19
|
+
maxContentWidth?: string;
|
|
20
|
+
initialInputSelections?: InitialInputSelections;
|
|
21
|
+
containerId?: string;
|
|
22
|
+
walletButtonRender?: WalletButtonRender;
|
|
23
|
+
safeAreaFallbackColor?: ColorScheme | null;
|
|
24
|
+
onPurchaseClicked?: (
|
|
25
|
+
packageId: string,
|
|
26
|
+
actionId: string,
|
|
27
|
+
) => void | Promise<void>;
|
|
28
|
+
onActionTriggered?: (actionId: string) => void;
|
|
29
|
+
onInputChanged?: (
|
|
30
|
+
fieldId: string,
|
|
31
|
+
value: string,
|
|
32
|
+
actionId?: string,
|
|
33
|
+
) => void;
|
|
34
|
+
onReservedAttributeChanged?: (
|
|
35
|
+
reservedAttribute: ReservedAttribute,
|
|
36
|
+
value: string,
|
|
37
|
+
) => void;
|
|
38
|
+
onCompleteWorkflowNavigate?: (
|
|
39
|
+
args: CompleteWorkflowNavigateArgs,
|
|
40
|
+
) => void | Promise<void>;
|
|
41
|
+
onComponentInteraction?: OnComponentInteraction;
|
|
42
|
+
onClose?: () => void;
|
|
43
|
+
onExitBack?: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const {
|
|
47
|
+
workflow,
|
|
48
|
+
uiConfig,
|
|
49
|
+
selectedLocale,
|
|
50
|
+
globalVariables,
|
|
51
|
+
variablesPerPackage,
|
|
52
|
+
maxContentWidth,
|
|
53
|
+
initialInputSelections,
|
|
54
|
+
containerId,
|
|
55
|
+
walletButtonRender,
|
|
56
|
+
safeAreaFallbackColor,
|
|
57
|
+
onPurchaseClicked,
|
|
58
|
+
onActionTriggered,
|
|
59
|
+
onInputChanged,
|
|
60
|
+
onReservedAttributeChanged,
|
|
61
|
+
onCompleteWorkflowNavigate,
|
|
62
|
+
onComponentInteraction,
|
|
63
|
+
onClose,
|
|
64
|
+
onExitBack,
|
|
65
|
+
}: Props = $props();
|
|
66
|
+
|
|
67
|
+
// ── Nav stack ─────────────────────────────────────────────────────────────
|
|
68
|
+
// The stack always has at least the initial page. The current page is the
|
|
69
|
+
// last entry. navigate_to_page pushes, navigate_back pops.
|
|
70
|
+
//
|
|
71
|
+
// We key the reset off workflow.initial_page_id (a stable string) rather
|
|
72
|
+
// than workflow object identity, so hosts that recompute the prop object on
|
|
73
|
+
// unrelated reactive updates don't accidentally snap the user back to the
|
|
74
|
+
// first page mid-flow.
|
|
75
|
+
let navStack = $state<string[]>([]);
|
|
76
|
+
let trackedInitialPageId = $state<string>();
|
|
77
|
+
|
|
78
|
+
const currentPageId = $derived(
|
|
79
|
+
navStack[navStack.length - 1] ?? workflow.initial_page_id,
|
|
80
|
+
);
|
|
81
|
+
const currentScreen = $derived(workflow.pages[currentPageId]);
|
|
82
|
+
|
|
83
|
+
$effect.pre(() => {
|
|
84
|
+
if (trackedInitialPageId !== workflow.initial_page_id) {
|
|
85
|
+
trackedInitialPageId = workflow.initial_page_id;
|
|
86
|
+
navStack = [workflow.initial_page_id];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
function handleNavigateToPage(pageId: string) {
|
|
91
|
+
if (!workflow.pages[pageId]) {
|
|
92
|
+
console.warn(`[Workflow] navigate_to_page: unknown page_id "${pageId}"`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
navStack = [...navStack, pageId];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function handleBackClicked() {
|
|
99
|
+
if (navStack.length > 1) {
|
|
100
|
+
navStack = navStack.slice(0, -1);
|
|
101
|
+
} else {
|
|
102
|
+
// Already at root — bubble up to the host.
|
|
103
|
+
onExitBack?.();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
{#key currentPageId}
|
|
109
|
+
<Screen
|
|
110
|
+
paywallComponents={currentScreen}
|
|
111
|
+
{uiConfig}
|
|
112
|
+
{selectedLocale}
|
|
113
|
+
{globalVariables}
|
|
114
|
+
{variablesPerPackage}
|
|
115
|
+
{maxContentWidth}
|
|
116
|
+
{initialInputSelections}
|
|
117
|
+
{containerId}
|
|
118
|
+
{walletButtonRender}
|
|
119
|
+
{safeAreaFallbackColor}
|
|
120
|
+
{onPurchaseClicked}
|
|
121
|
+
{onActionTriggered}
|
|
122
|
+
{onInputChanged}
|
|
123
|
+
{onReservedAttributeChanged}
|
|
124
|
+
{onCompleteWorkflowNavigate}
|
|
125
|
+
{onComponentInteraction}
|
|
126
|
+
onNavigateToPage={handleNavigateToPage}
|
|
127
|
+
onBackClicked={handleBackClicked}
|
|
128
|
+
{onClose}
|
|
129
|
+
/>
|
|
130
|
+
{/key}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CompleteWorkflowNavigateArgs } from "../../types/components/button";
|
|
2
|
+
import type { ColorScheme } from "../../types/colors";
|
|
3
|
+
import type { InitialInputSelections } from "../../stores/inputValidation";
|
|
4
|
+
import type { OnComponentInteraction } from "../../types/paywall-component-interaction";
|
|
5
|
+
import type { VariableDictionary } from "../../types/variables";
|
|
6
|
+
import type { WalletButtonRender } from "../../types/wallet";
|
|
7
|
+
import type { UIConfig } from "../../types/ui-config";
|
|
8
|
+
import type { ReservedAttribute } from "../../types/components/input-text";
|
|
9
|
+
import type { WorkflowNavData } from "../../types/workflow-nav";
|
|
10
|
+
interface Props {
|
|
11
|
+
workflow: WorkflowNavData;
|
|
12
|
+
uiConfig: UIConfig;
|
|
13
|
+
selectedLocale?: string;
|
|
14
|
+
globalVariables?: VariableDictionary;
|
|
15
|
+
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
16
|
+
maxContentWidth?: string;
|
|
17
|
+
initialInputSelections?: InitialInputSelections;
|
|
18
|
+
containerId?: string;
|
|
19
|
+
walletButtonRender?: WalletButtonRender;
|
|
20
|
+
safeAreaFallbackColor?: ColorScheme | null;
|
|
21
|
+
onPurchaseClicked?: (packageId: string, actionId: string) => void | Promise<void>;
|
|
22
|
+
onActionTriggered?: (actionId: string) => void;
|
|
23
|
+
onInputChanged?: (fieldId: string, value: string, actionId?: string) => void;
|
|
24
|
+
onReservedAttributeChanged?: (reservedAttribute: ReservedAttribute, value: string) => void;
|
|
25
|
+
onCompleteWorkflowNavigate?: (args: CompleteWorkflowNavigateArgs) => void | Promise<void>;
|
|
26
|
+
onComponentInteraction?: OnComponentInteraction;
|
|
27
|
+
onClose?: () => void;
|
|
28
|
+
onExitBack?: () => void;
|
|
29
|
+
}
|
|
30
|
+
declare const Workflow: import("svelte").Component<Props, {}, "">;
|
|
31
|
+
type Workflow = ReturnType<typeof Workflow>;
|
|
32
|
+
export default Workflow;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { WorkflowNavData } from "../../../types/workflow-nav";
|
|
2
|
+
/**
|
|
3
|
+
* Two-page workflow fixture that exercises navigate_to_page, navigate_back,
|
|
4
|
+
* and close_workflow button actions via the Workflow component.
|
|
5
|
+
*
|
|
6
|
+
* Page layout:
|
|
7
|
+
* "rcpaywall_welcome" — welcome screen with a "Next →" navigate_to_page button
|
|
8
|
+
* "rcpaywall_details" — details screen with "← Back" and "✕ Close" buttons
|
|
9
|
+
*
|
|
10
|
+
* Page IDs match a paywall rc_public_id as they would in a real SDK response.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TWO_PAGE_WORKFLOW: WorkflowNavData;
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two-page workflow fixture that exercises navigate_to_page, navigate_back,
|
|
3
|
+
* and close_workflow button actions via the Workflow component.
|
|
4
|
+
*
|
|
5
|
+
* Page layout:
|
|
6
|
+
* "rcpaywall_welcome" — welcome screen with a "Next →" navigate_to_page button
|
|
7
|
+
* "rcpaywall_details" — details screen with "← Back" and "✕ Close" buttons
|
|
8
|
+
*
|
|
9
|
+
* Page IDs match a paywall rc_public_id as they would in a real SDK response.
|
|
10
|
+
*/
|
|
11
|
+
export const TWO_PAGE_WORKFLOW = {
|
|
12
|
+
initial_page_id: "rcpaywall_welcome",
|
|
13
|
+
pages: {
|
|
14
|
+
rcpaywall_welcome: {
|
|
15
|
+
id: "rcpaywall_welcome",
|
|
16
|
+
default_locale: "en_US",
|
|
17
|
+
name: "Welcome",
|
|
18
|
+
template_name: "stack",
|
|
19
|
+
revision: 1,
|
|
20
|
+
asset_base_url: "https://assets.pawwalls.com",
|
|
21
|
+
config: {},
|
|
22
|
+
localized_strings: {},
|
|
23
|
+
localized_strings_by_tier: {},
|
|
24
|
+
offering_id: null,
|
|
25
|
+
components_localizations: {
|
|
26
|
+
en_US: {
|
|
27
|
+
welcome_title: "Welcome",
|
|
28
|
+
welcome_body: "This is page 1 of 2. Tap the button below to navigate to page 2.",
|
|
29
|
+
next_btn: "Next →",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
components_config: {
|
|
33
|
+
base: {
|
|
34
|
+
background: {
|
|
35
|
+
type: "color",
|
|
36
|
+
value: {
|
|
37
|
+
light: { type: "hex", value: "#f0f4ffff" },
|
|
38
|
+
dark: { type: "hex", value: "#1a1f2eff" },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
stack: {
|
|
42
|
+
type: "stack",
|
|
43
|
+
id: "welcome_root",
|
|
44
|
+
name: "Root",
|
|
45
|
+
size: { width: { type: "fill" }, height: { type: "fill" } },
|
|
46
|
+
dimension: {
|
|
47
|
+
type: "vertical",
|
|
48
|
+
alignment: "center",
|
|
49
|
+
distribution: "start",
|
|
50
|
+
},
|
|
51
|
+
spacing: 0,
|
|
52
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
53
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
54
|
+
background: null,
|
|
55
|
+
background_color: null,
|
|
56
|
+
badge: null,
|
|
57
|
+
border: null,
|
|
58
|
+
shadow: null,
|
|
59
|
+
shape: null,
|
|
60
|
+
components: [
|
|
61
|
+
// ── Title ────────────────────────────────────────────────
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
id: "welcome_title",
|
|
65
|
+
name: "Title",
|
|
66
|
+
text_lid: "welcome_title",
|
|
67
|
+
font_size: "heading_xl",
|
|
68
|
+
font_weight: "bold",
|
|
69
|
+
horizontal_alignment: "center",
|
|
70
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
71
|
+
margin: { top: 80, bottom: 16, leading: 24, trailing: 24 },
|
|
72
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
73
|
+
color: {
|
|
74
|
+
light: { type: "hex", value: "#1a1f2eff" },
|
|
75
|
+
dark: { type: "hex", value: "#f0f4ffff" },
|
|
76
|
+
},
|
|
77
|
+
background_color: {
|
|
78
|
+
light: { type: "hex", value: "transparent" },
|
|
79
|
+
dark: { type: "hex", value: "transparent" },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
// ── Body ─────────────────────────────────────────────────
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
id: "welcome_body",
|
|
86
|
+
name: "Body",
|
|
87
|
+
text_lid: "welcome_body",
|
|
88
|
+
font_size: "body_m",
|
|
89
|
+
font_weight: "regular",
|
|
90
|
+
horizontal_alignment: "center",
|
|
91
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
92
|
+
margin: { top: 0, bottom: 48, leading: 24, trailing: 24 },
|
|
93
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
94
|
+
color: {
|
|
95
|
+
light: { type: "hex", value: "#555577ff" },
|
|
96
|
+
dark: { type: "hex", value: "#aaaaccff" },
|
|
97
|
+
},
|
|
98
|
+
background_color: {
|
|
99
|
+
light: { type: "hex", value: "transparent" },
|
|
100
|
+
dark: { type: "hex", value: "transparent" },
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
// ── navigate_to_page button ───────────────────────────
|
|
104
|
+
{
|
|
105
|
+
type: "button",
|
|
106
|
+
id: "next_btn",
|
|
107
|
+
name: "Next",
|
|
108
|
+
action: {
|
|
109
|
+
type: "navigate_to_page",
|
|
110
|
+
page_id: "rcpaywall_details",
|
|
111
|
+
},
|
|
112
|
+
stack: {
|
|
113
|
+
type: "stack",
|
|
114
|
+
id: "next_btn_stack",
|
|
115
|
+
name: "Next button stack",
|
|
116
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
117
|
+
dimension: {
|
|
118
|
+
type: "horizontal",
|
|
119
|
+
alignment: "center",
|
|
120
|
+
distribution: "center",
|
|
121
|
+
},
|
|
122
|
+
spacing: 0,
|
|
123
|
+
margin: { top: 0, bottom: 0, leading: 24, trailing: 24 },
|
|
124
|
+
padding: { top: 16, bottom: 16, leading: 24, trailing: 24 },
|
|
125
|
+
background: {
|
|
126
|
+
type: "color",
|
|
127
|
+
value: {
|
|
128
|
+
light: { type: "hex", value: "#3366ffff" },
|
|
129
|
+
dark: { type: "hex", value: "#4d7fffff" },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
background_color: null,
|
|
133
|
+
badge: null,
|
|
134
|
+
border: null,
|
|
135
|
+
shadow: null,
|
|
136
|
+
shape: { type: "pill" },
|
|
137
|
+
components: [
|
|
138
|
+
{
|
|
139
|
+
type: "text",
|
|
140
|
+
id: "next_btn_text",
|
|
141
|
+
name: "next_btn_text",
|
|
142
|
+
text_lid: "next_btn",
|
|
143
|
+
font_size: "body_m",
|
|
144
|
+
font_weight: "medium",
|
|
145
|
+
horizontal_alignment: "center",
|
|
146
|
+
size: { width: { type: "fit" }, height: { type: "fit" } },
|
|
147
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
148
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
149
|
+
color: {
|
|
150
|
+
light: { type: "hex", value: "#ffffffff" },
|
|
151
|
+
dark: { type: "hex", value: "#ffffffff" },
|
|
152
|
+
},
|
|
153
|
+
background_color: {
|
|
154
|
+
light: { type: "hex", value: "transparent" },
|
|
155
|
+
dark: { type: "hex", value: "transparent" },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
rcpaywall_details: {
|
|
167
|
+
id: "rcpaywall_details",
|
|
168
|
+
default_locale: "en_US",
|
|
169
|
+
name: "Details",
|
|
170
|
+
template_name: "stack",
|
|
171
|
+
revision: 1,
|
|
172
|
+
asset_base_url: "https://assets.pawwalls.com",
|
|
173
|
+
config: {},
|
|
174
|
+
localized_strings: {},
|
|
175
|
+
localized_strings_by_tier: {},
|
|
176
|
+
offering_id: null,
|
|
177
|
+
components_localizations: {
|
|
178
|
+
en_US: {
|
|
179
|
+
details_title: "Details",
|
|
180
|
+
details_body: "This is page 2 of 2. Use the buttons below to navigate back or close the workflow entirely.",
|
|
181
|
+
back_btn: "← Back",
|
|
182
|
+
close_btn: "✕ Close",
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
components_config: {
|
|
186
|
+
base: {
|
|
187
|
+
background: {
|
|
188
|
+
type: "color",
|
|
189
|
+
value: {
|
|
190
|
+
light: { type: "hex", value: "#fff4f0ff" },
|
|
191
|
+
dark: { type: "hex", value: "#2e1a1aff" },
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
stack: {
|
|
195
|
+
type: "stack",
|
|
196
|
+
id: "details_root",
|
|
197
|
+
name: "Root",
|
|
198
|
+
size: { width: { type: "fill" }, height: { type: "fill" } },
|
|
199
|
+
dimension: {
|
|
200
|
+
type: "vertical",
|
|
201
|
+
alignment: "center",
|
|
202
|
+
distribution: "start",
|
|
203
|
+
},
|
|
204
|
+
spacing: 0,
|
|
205
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
206
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
207
|
+
background: null,
|
|
208
|
+
background_color: null,
|
|
209
|
+
badge: null,
|
|
210
|
+
border: null,
|
|
211
|
+
shadow: null,
|
|
212
|
+
shape: null,
|
|
213
|
+
components: [
|
|
214
|
+
// ── Title ────────────────────────────────────────────────
|
|
215
|
+
{
|
|
216
|
+
type: "text",
|
|
217
|
+
id: "details_title",
|
|
218
|
+
name: "Title",
|
|
219
|
+
text_lid: "details_title",
|
|
220
|
+
font_size: "heading_xl",
|
|
221
|
+
font_weight: "bold",
|
|
222
|
+
horizontal_alignment: "center",
|
|
223
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
224
|
+
margin: { top: 80, bottom: 16, leading: 24, trailing: 24 },
|
|
225
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
226
|
+
color: {
|
|
227
|
+
light: { type: "hex", value: "#2e1a1aff" },
|
|
228
|
+
dark: { type: "hex", value: "#fff4f0ff" },
|
|
229
|
+
},
|
|
230
|
+
background_color: {
|
|
231
|
+
light: { type: "hex", value: "transparent" },
|
|
232
|
+
dark: { type: "hex", value: "transparent" },
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
// ── Body ─────────────────────────────────────────────────
|
|
236
|
+
{
|
|
237
|
+
type: "text",
|
|
238
|
+
id: "details_body",
|
|
239
|
+
name: "Body",
|
|
240
|
+
text_lid: "details_body",
|
|
241
|
+
font_size: "body_m",
|
|
242
|
+
font_weight: "regular",
|
|
243
|
+
horizontal_alignment: "center",
|
|
244
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
245
|
+
margin: { top: 0, bottom: 48, leading: 24, trailing: 24 },
|
|
246
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
247
|
+
color: {
|
|
248
|
+
light: { type: "hex", value: "#775555ff" },
|
|
249
|
+
dark: { type: "hex", value: "#ccaaaaff" },
|
|
250
|
+
},
|
|
251
|
+
background_color: {
|
|
252
|
+
light: { type: "hex", value: "transparent" },
|
|
253
|
+
dark: { type: "hex", value: "transparent" },
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
// ── navigate_back button ──────────────────────────────
|
|
257
|
+
{
|
|
258
|
+
type: "button",
|
|
259
|
+
id: "back_btn",
|
|
260
|
+
name: "Back",
|
|
261
|
+
action: { type: "navigate_back" },
|
|
262
|
+
stack: {
|
|
263
|
+
type: "stack",
|
|
264
|
+
id: "back_btn_stack",
|
|
265
|
+
name: "Back button stack",
|
|
266
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
267
|
+
dimension: {
|
|
268
|
+
type: "horizontal",
|
|
269
|
+
alignment: "center",
|
|
270
|
+
distribution: "center",
|
|
271
|
+
},
|
|
272
|
+
spacing: 0,
|
|
273
|
+
margin: { top: 0, bottom: 12, leading: 24, trailing: 24 },
|
|
274
|
+
padding: { top: 16, bottom: 16, leading: 24, trailing: 24 },
|
|
275
|
+
background: {
|
|
276
|
+
type: "color",
|
|
277
|
+
value: {
|
|
278
|
+
light: { type: "hex", value: "transparent" },
|
|
279
|
+
dark: { type: "hex", value: "transparent" },
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
background_color: null,
|
|
283
|
+
badge: null,
|
|
284
|
+
border: {
|
|
285
|
+
width: 1.5,
|
|
286
|
+
color: {
|
|
287
|
+
light: { type: "hex", value: "#3366ffff" },
|
|
288
|
+
dark: { type: "hex", value: "#4d7fffff" },
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
shadow: null,
|
|
292
|
+
shape: { type: "pill" },
|
|
293
|
+
components: [
|
|
294
|
+
{
|
|
295
|
+
type: "text",
|
|
296
|
+
id: "back_btn_text",
|
|
297
|
+
name: "back_btn_text",
|
|
298
|
+
text_lid: "back_btn",
|
|
299
|
+
font_size: "body_m",
|
|
300
|
+
font_weight: "medium",
|
|
301
|
+
horizontal_alignment: "center",
|
|
302
|
+
size: { width: { type: "fit" }, height: { type: "fit" } },
|
|
303
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
304
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
305
|
+
color: {
|
|
306
|
+
light: { type: "hex", value: "#3366ffff" },
|
|
307
|
+
dark: { type: "hex", value: "#4d7fffff" },
|
|
308
|
+
},
|
|
309
|
+
background_color: {
|
|
310
|
+
light: { type: "hex", value: "transparent" },
|
|
311
|
+
dark: { type: "hex", value: "transparent" },
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
// ── close button ──────────────────────────────────────
|
|
318
|
+
{
|
|
319
|
+
type: "button",
|
|
320
|
+
id: "close_btn",
|
|
321
|
+
name: "Close",
|
|
322
|
+
action: { type: "close_workflow" },
|
|
323
|
+
stack: {
|
|
324
|
+
type: "stack",
|
|
325
|
+
id: "close_btn_stack",
|
|
326
|
+
name: "Close button stack",
|
|
327
|
+
size: { width: { type: "fill" }, height: { type: "fit" } },
|
|
328
|
+
dimension: {
|
|
329
|
+
type: "horizontal",
|
|
330
|
+
alignment: "center",
|
|
331
|
+
distribution: "center",
|
|
332
|
+
},
|
|
333
|
+
spacing: 0,
|
|
334
|
+
margin: { top: 0, bottom: 40, leading: 24, trailing: 24 },
|
|
335
|
+
padding: { top: 16, bottom: 16, leading: 24, trailing: 24 },
|
|
336
|
+
background: {
|
|
337
|
+
type: "color",
|
|
338
|
+
value: {
|
|
339
|
+
light: { type: "hex", value: "#ff3b30ff" },
|
|
340
|
+
dark: { type: "hex", value: "#ff453aff" },
|
|
341
|
+
},
|
|
342
|
+
},
|
|
343
|
+
background_color: null,
|
|
344
|
+
badge: null,
|
|
345
|
+
border: null,
|
|
346
|
+
shadow: null,
|
|
347
|
+
shape: { type: "pill" },
|
|
348
|
+
components: [
|
|
349
|
+
{
|
|
350
|
+
type: "text",
|
|
351
|
+
id: "close_btn_text",
|
|
352
|
+
name: "close_btn_text",
|
|
353
|
+
text_lid: "close_btn",
|
|
354
|
+
font_size: "body_m",
|
|
355
|
+
font_weight: "medium",
|
|
356
|
+
horizontal_alignment: "center",
|
|
357
|
+
size: { width: { type: "fit" }, height: { type: "fit" } },
|
|
358
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
359
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
360
|
+
color: {
|
|
361
|
+
light: { type: "hex", value: "#ffffffff" },
|
|
362
|
+
dark: { type: "hex", value: "#ffffffff" },
|
|
363
|
+
},
|
|
364
|
+
background_color: {
|
|
365
|
+
light: { type: "hex", value: "transparent" },
|
|
366
|
+
dark: { type: "hex", value: "transparent" },
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
],
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
],
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -13,9 +13,12 @@ export { default as Stack } from "./components/stack/Stack.svelte";
|
|
|
13
13
|
export { default as Text } from "./components/text/Text.svelte";
|
|
14
14
|
export { default as Timeline } from "./components/timeline/Timeline.svelte";
|
|
15
15
|
export { default as Screen } from "./components/workflows/Screen.svelte";
|
|
16
|
+
export { default as Workflow } from "./components/workflows/Workflow.svelte";
|
|
16
17
|
export { default as Video } from "./components/video/Video.svelte";
|
|
17
18
|
export * from "./types";
|
|
18
19
|
export { type PaywallData } from "./types/paywall";
|
|
20
|
+
export { type WorkflowNavData, workflowDataToNavData, } from "./types/workflow-nav";
|
|
21
|
+
export { type WorkflowData, type WorkflowStep } from "./types/workflow";
|
|
19
22
|
export { type InitialInputSelections } from "./stores/inputValidation";
|
|
20
23
|
export { type UIConfig } from "./types/ui-config";
|
|
21
24
|
export { type WalletButtonRender, type WalletButtonTheme, } from "./types/wallet";
|
package/dist/index.js
CHANGED
|
@@ -14,9 +14,12 @@ export { default as Stack } from "./components/stack/Stack.svelte";
|
|
|
14
14
|
export { default as Text } from "./components/text/Text.svelte";
|
|
15
15
|
export { default as Timeline } from "./components/timeline/Timeline.svelte";
|
|
16
16
|
export { default as Screen } from "./components/workflows/Screen.svelte";
|
|
17
|
+
export { default as Workflow } from "./components/workflows/Workflow.svelte";
|
|
17
18
|
export { default as Video } from "./components/video/Video.svelte";
|
|
18
19
|
export * from "./types";
|
|
19
20
|
export {} from "./types/paywall";
|
|
21
|
+
export { workflowDataToNavData, } from "./types/workflow-nav";
|
|
22
|
+
export {} from "./types/workflow";
|
|
20
23
|
export {} from "./stores/inputValidation";
|
|
21
24
|
export {} from "./types/ui-config";
|
|
22
25
|
export {} from "./types/wallet";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ButtonProps } from "./components/button";
|
|
2
2
|
import type { CarouselProps } from "./components/carousel";
|
|
3
3
|
import type { CountdownProps } from "./components/countdown";
|
|
4
|
+
import type { FallbackHeaderProps } from "./components/fallback-header";
|
|
4
5
|
import type { FooterProps } from "./components/footer";
|
|
5
6
|
import type { IconProps } from "./components/icon";
|
|
6
7
|
import type { ImageProps } from "./components/image";
|
|
@@ -18,4 +19,4 @@ import type { WalletButtonProps } from "./components/wallet-button";
|
|
|
18
19
|
import type { SkeletonLoaderProps } from "./components/skeleton-loader-props";
|
|
19
20
|
import type { ExpressPurchaseButtonProps } from "./components/express-purchase-button-props";
|
|
20
21
|
import type { HeaderProps } from "./components/header";
|
|
21
|
-
export type Component = ButtonProps | CarouselProps | CountdownProps | ExpressPurchaseButtonProps | FooterProps | HeaderProps | IconProps | ImageProps | InputMultipleChoiceProps | InputOptionProps | InputSingleChoiceProps | InputTextProps | PackageProps | PurchaseButtonProps | RedemptionButtonProps | SkeletonLoaderProps | StackProps | TabControlButtonProps | TabControlToggleProps | TabControlProps | TabProps | TabsProps | TextNodeProps | TimelineProps | WalletButtonProps | VideoProps;
|
|
22
|
+
export type Component = ButtonProps | CarouselProps | CountdownProps | ExpressPurchaseButtonProps | FallbackHeaderProps | FooterProps | HeaderProps | IconProps | ImageProps | InputMultipleChoiceProps | InputOptionProps | InputSingleChoiceProps | InputTextProps | PackageProps | PurchaseButtonProps | RedemptionButtonProps | SkeletonLoaderProps | StackProps | TabControlButtonProps | TabControlToggleProps | TabControlProps | TabProps | TabsProps | TextNodeProps | TimelineProps | WalletButtonProps | VideoProps;
|
|
@@ -11,6 +11,13 @@ interface RestorePurchasesAction {
|
|
|
11
11
|
interface NavigateBackAction {
|
|
12
12
|
type: "navigate_back";
|
|
13
13
|
}
|
|
14
|
+
interface NavigateToPageAction {
|
|
15
|
+
type: "navigate_to_page";
|
|
16
|
+
page_id: string;
|
|
17
|
+
}
|
|
18
|
+
interface CloseAction {
|
|
19
|
+
type: "close_workflow";
|
|
20
|
+
}
|
|
14
21
|
interface NavigateToAction {
|
|
15
22
|
type: "navigate_to";
|
|
16
23
|
destination: "customer_center" | "offer_code" | "screen_redirect";
|
|
@@ -53,7 +60,7 @@ interface CompleteWorkflowAction {
|
|
|
53
60
|
};
|
|
54
61
|
url_query_params?: CompleteWorkflowUrlQueryParams;
|
|
55
62
|
}
|
|
56
|
-
export type Action = WorkflowAction | RestorePurchasesAction | NavigateBackAction | NavigateToAction | NavigateToSheetAction | NavigateToWebPurchase | NavigateToUrlAction | CompleteWorkflowAction;
|
|
63
|
+
export type Action = WorkflowAction | RestorePurchasesAction | NavigateBackAction | NavigateToPageAction | CloseAction | NavigateToAction | NavigateToSheetAction | NavigateToWebPurchase | NavigateToUrlAction | CompleteWorkflowAction;
|
|
57
64
|
export interface ButtonProps extends BaseComponent {
|
|
58
65
|
type: "button";
|
|
59
66
|
action: Action;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BaseComponent } from "../base";
|
|
2
|
+
/**
|
|
3
|
+
* Sentinel component type emitted by the backend when a component has no
|
|
4
|
+
* known renderer on this client. `Node` skips rendering and falls back to
|
|
5
|
+
* the component's `fallback` child (if present) instead.
|
|
6
|
+
*/
|
|
7
|
+
export interface FallbackHeaderProps extends BaseComponent {
|
|
8
|
+
type: "fallback_header";
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -16,7 +16,7 @@ interface PackageTransition {
|
|
|
16
16
|
destinationPackageId: string;
|
|
17
17
|
defaultPackageId?: string;
|
|
18
18
|
}
|
|
19
|
-
type ButtonInteractionValue = "workflow" | "navigate_to_url" | "navigate_back" | "restore_purchases" | "navigate_to_customer_center" | "screen_redirect" | "navigate_to_privacy_policy" | "navigate_to_terms" | "navigate_to_sheet" | "navigate_to_offer_code" | "navigate_to_web_paywall_link";
|
|
19
|
+
type ButtonInteractionValue = "workflow" | "navigate_to_url" | "navigate_back" | "navigate_to_page" | "close_workflow" | "restore_purchases" | "navigate_to_customer_center" | "screen_redirect" | "navigate_to_privacy_policy" | "navigate_to_terms" | "navigate_to_sheet" | "navigate_to_offer_code" | "navigate_to_web_paywall_link";
|
|
20
20
|
export type TabInteractionData = ComponentInteractionBase<"tab"> & IndexedTransition;
|
|
21
21
|
export type SwitchInteractionData = ComponentInteractionBase<"switch", "on" | "off">;
|
|
22
22
|
export type CarouselInteractionData = ComponentInteractionBase<"carousel"> & IndexedTransition;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { WorkflowData, WorkflowScreen } from "./workflow";
|
|
2
|
+
/**
|
|
3
|
+
* A self-contained multi-page workflow payload for use with the Workflow
|
|
4
|
+
* component. This mirrors the shape of rc-workflows' WorkflowData but only
|
|
5
|
+
* includes the fields needed for client-side page navigation — it does NOT
|
|
6
|
+
* include step trigger_actions or experiment logic, which remain rc-workflows
|
|
7
|
+
* concerns.
|
|
8
|
+
*/
|
|
9
|
+
export interface WorkflowNavData {
|
|
10
|
+
/** ID of the first page to display. Must be a key in `pages`. */
|
|
11
|
+
initial_page_id: string;
|
|
12
|
+
/**
|
|
13
|
+
* All pages in this workflow keyed by page ID (the screen's rc_public_id).
|
|
14
|
+
* `navigate_to_page` actions reference these IDs directly.
|
|
15
|
+
*/
|
|
16
|
+
pages: Record<string, WorkflowScreen>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Map a full `WorkflowData` SDK response to the `WorkflowNavData` shape
|
|
20
|
+
* consumed by the `Workflow` component.
|
|
21
|
+
*
|
|
22
|
+
* - `pages` is taken directly from `WorkflowData.screens` (already keyed by
|
|
23
|
+
* screen/paywall rc_public_id, which is what `navigate_to_page` page_ids
|
|
24
|
+
* reference).
|
|
25
|
+
* - `initial_page_id` is resolved by looking up the screen_id of the initial
|
|
26
|
+
* step, since `initial_step_id` is a step ID, not a screen ID.
|
|
27
|
+
*
|
|
28
|
+
* Returns `null` if the initial step or its screen cannot be resolved.
|
|
29
|
+
*/
|
|
30
|
+
export declare function workflowDataToNavData(data: WorkflowData): WorkflowNavData | null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a full `WorkflowData` SDK response to the `WorkflowNavData` shape
|
|
3
|
+
* consumed by the `Workflow` component.
|
|
4
|
+
*
|
|
5
|
+
* - `pages` is taken directly from `WorkflowData.screens` (already keyed by
|
|
6
|
+
* screen/paywall rc_public_id, which is what `navigate_to_page` page_ids
|
|
7
|
+
* reference).
|
|
8
|
+
* - `initial_page_id` is resolved by looking up the screen_id of the initial
|
|
9
|
+
* step, since `initial_step_id` is a step ID, not a screen ID.
|
|
10
|
+
*
|
|
11
|
+
* Returns `null` if the initial step or its screen cannot be resolved.
|
|
12
|
+
*/
|
|
13
|
+
export function workflowDataToNavData(data) {
|
|
14
|
+
const initialStep = data.steps[data.initial_step_id];
|
|
15
|
+
if (!initialStep) {
|
|
16
|
+
console.warn(`[workflowDataToNavData] initial_step_id "${data.initial_step_id}" not found in steps`);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const initialPageId = initialStep.screen_id;
|
|
20
|
+
if (!initialPageId) {
|
|
21
|
+
console.warn(`[workflowDataToNavData] initial step "${data.initial_step_id}" has no screen_id (logic/experiment step?)`);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (!data.screens[initialPageId]) {
|
|
25
|
+
console.warn(`[workflowDataToNavData] screen_id "${initialPageId}" not found in screens`);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
initial_page_id: initialPageId,
|
|
30
|
+
// Shared by reference intentionally — screens are never mutated after
|
|
31
|
+
// WorkflowData is received from the SDK, so a copy would be wasteful.
|
|
32
|
+
pages: data.screens,
|
|
33
|
+
};
|
|
34
|
+
}
|
package/dist/types/workflow.d.ts
CHANGED
|
@@ -13,3 +13,32 @@ export interface WorkflowScreen extends PaywallData {
|
|
|
13
13
|
revision: number;
|
|
14
14
|
template_name: string;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* A single step in a workflow, referencing a screen by ID.
|
|
18
|
+
* Aligns with the SDK response shape from khepri.
|
|
19
|
+
*/
|
|
20
|
+
export interface WorkflowStep {
|
|
21
|
+
id: string;
|
|
22
|
+
screen_id?: string;
|
|
23
|
+
type: string;
|
|
24
|
+
param_values: Record<string, unknown>;
|
|
25
|
+
trigger_actions: Record<string, unknown>;
|
|
26
|
+
triggers: Record<string, unknown>;
|
|
27
|
+
outputs: Record<string, unknown>;
|
|
28
|
+
metadata: Record<string, unknown> | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The full workflow payload returned by the RevenueCat SDK.
|
|
32
|
+
* Aligns with rc-workflows' WorkflowData type — rc-workflows imports
|
|
33
|
+
* WorkflowScreen from this package and can import WorkflowData here too.
|
|
34
|
+
*/
|
|
35
|
+
export interface WorkflowData {
|
|
36
|
+
id: string;
|
|
37
|
+
display_name: string;
|
|
38
|
+
initial_step_id: string;
|
|
39
|
+
steps: Record<string, WorkflowStep>;
|
|
40
|
+
screens: Record<string, WorkflowScreen>;
|
|
41
|
+
ui_config: Record<string, unknown>;
|
|
42
|
+
content_max_width: number | null;
|
|
43
|
+
metadata?: Record<string, unknown> | null;
|
|
44
|
+
}
|