@revenuecat/purchases-ui-js 3.11.4 → 3.12.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 +1 -1
- package/dist/components/options/InputOption.svelte +10 -1
- package/dist/components/options/InputOptionTestWrapper.svelte +47 -0
- package/dist/components/options/InputOptionTestWrapper.svelte.d.ts +12 -0
- package/dist/components/package/Package.svelte +3 -3
- package/dist/components/paywall/Paywall.svelte +11 -8
- package/dist/components/paywall/Paywall.svelte.d.ts +1 -1
- package/dist/components/purchase-button/PurchaseButton.svelte +1 -1
- package/dist/components/stack/Stack.stories.svelte +88 -0
- package/dist/components/stack/Stack.svelte +4 -1
- package/dist/components/workflows/Screen.svelte +5 -1
- package/dist/components/workflows/Screen.svelte.d.ts +1 -1
- package/dist/stores/paywall.d.ts +1 -1
- package/dist/types/paywall-component-interaction.d.ts +14 -14
- package/package.json +1 -1
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
componentType: "package_selection_sheet",
|
|
128
128
|
componentName: action.sheet?.name ?? props.name,
|
|
129
129
|
componentValue: "open",
|
|
130
|
-
|
|
130
|
+
currentPackageId: $selectedPackageId,
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
const onclick = () => {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
const props: InputOptionProps = $props();
|
|
11
11
|
const { stack, option_id } = props;
|
|
12
12
|
|
|
13
|
-
const { onButtonAction } = getPaywallContext();
|
|
13
|
+
const { onButtonAction, onInputChanged } = getPaywallContext();
|
|
14
14
|
const inputChoiceContext = getInputChoiceContext();
|
|
15
15
|
|
|
16
16
|
// Derive selected state from context (similar to Package)
|
|
@@ -41,6 +41,15 @@
|
|
|
41
41
|
// Update selection state
|
|
42
42
|
inputChoiceContext?.selectOption(option_id);
|
|
43
43
|
|
|
44
|
+
// Notify host (e.g. workflows) so selections can be persisted when every option shares
|
|
45
|
+
// the same workflow `on_press` id (e.g. `btn_*`); `onActionTriggered` alone is ambiguous.
|
|
46
|
+
// The trailing actionId lets hosts skip this callback when their own action path
|
|
47
|
+
// already persists the selection (e.g. a legacy input_option_* action handler).
|
|
48
|
+
const fieldId = inputChoiceContext?.fieldId;
|
|
49
|
+
if (fieldId) {
|
|
50
|
+
onInputChanged?.(fieldId, option_id, actionId);
|
|
51
|
+
}
|
|
52
|
+
|
|
44
53
|
// Trigger navigation
|
|
45
54
|
onButtonAction({ type: "workflow" }, actionId);
|
|
46
55
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setPaywallContext } from "../../stores/paywall";
|
|
3
|
+
import {
|
|
4
|
+
createInputChoiceContext,
|
|
5
|
+
setInputChoiceContext,
|
|
6
|
+
} from "../../stores/inputChoice";
|
|
7
|
+
import { readable, writable } from "svelte/store";
|
|
8
|
+
import InputOption from "./InputOption.svelte";
|
|
9
|
+
import type { InputOptionProps } from "../../types/components/options";
|
|
10
|
+
|
|
11
|
+
interface Props extends InputOptionProps {
|
|
12
|
+
fieldId?: string;
|
|
13
|
+
selectionMode?: "single" | "multiple";
|
|
14
|
+
onButtonAction?: (action: { type: string }, actionId?: string) => void;
|
|
15
|
+
onInputChanged?: (
|
|
16
|
+
fieldId: string,
|
|
17
|
+
value: string,
|
|
18
|
+
actionId?: string,
|
|
19
|
+
) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
fieldId,
|
|
24
|
+
selectionMode = "single",
|
|
25
|
+
onButtonAction = () => {},
|
|
26
|
+
onInputChanged,
|
|
27
|
+
...optionProps
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
|
|
30
|
+
if (fieldId !== undefined) {
|
|
31
|
+
setInputChoiceContext(createInputChoiceContext(fieldId, selectionMode));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setPaywallContext({
|
|
35
|
+
selectedPackageId: writable(undefined),
|
|
36
|
+
variablesPerPackage: readable(undefined),
|
|
37
|
+
baseVariables: readable(undefined),
|
|
38
|
+
infoPerPackage: readable(undefined),
|
|
39
|
+
onPurchase: () => {},
|
|
40
|
+
onButtonAction: onButtonAction as never,
|
|
41
|
+
onInputChanged,
|
|
42
|
+
uiConfig: {} as never,
|
|
43
|
+
hideBackButtons: false,
|
|
44
|
+
});
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<InputOption {...optionProps} />
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InputOptionProps } from "../../types/components/options";
|
|
2
|
+
interface Props extends InputOptionProps {
|
|
3
|
+
fieldId?: string;
|
|
4
|
+
selectionMode?: "single" | "multiple";
|
|
5
|
+
onButtonAction?: (action: {
|
|
6
|
+
type: string;
|
|
7
|
+
}, actionId?: string) => void;
|
|
8
|
+
onInputChanged?: (fieldId: string, value: string, actionId?: string) => void;
|
|
9
|
+
}
|
|
10
|
+
declare const InputOptionTestWrapper: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type InputOptionTestWrapper = ReturnType<typeof InputOptionTestWrapper>;
|
|
12
|
+
export default InputOptionTestWrapper;
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
componentType: "package",
|
|
56
56
|
componentName: name,
|
|
57
57
|
componentValue: package_id,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
originPackageId,
|
|
59
|
+
destinationPackageId: package_id,
|
|
60
|
+
defaultPackageId,
|
|
61
61
|
});
|
|
62
62
|
};
|
|
63
63
|
|
|
@@ -82,7 +82,11 @@
|
|
|
82
82
|
onError?: (error: unknown) => void;
|
|
83
83
|
hideBackButtons?: boolean;
|
|
84
84
|
walletButtonRender?: WalletButtonRender;
|
|
85
|
-
onInputChanged?: (
|
|
85
|
+
onInputChanged?: (
|
|
86
|
+
fieldId: string,
|
|
87
|
+
value: string,
|
|
88
|
+
actionId?: string,
|
|
89
|
+
) => void;
|
|
86
90
|
maxContentWidth?: string;
|
|
87
91
|
initialInputSelections?: InitialInputSelections;
|
|
88
92
|
/**
|
|
@@ -165,7 +169,7 @@
|
|
|
165
169
|
|
|
166
170
|
let sheet = $state<{
|
|
167
171
|
props: SheetProps;
|
|
168
|
-
|
|
172
|
+
rootSelectedPackageId?: string;
|
|
169
173
|
}>();
|
|
170
174
|
|
|
171
175
|
const onButtonAction = (action: Action, actionId?: string) => {
|
|
@@ -214,20 +218,19 @@
|
|
|
214
218
|
if (action.sheet) {
|
|
215
219
|
sheet = {
|
|
216
220
|
props: action.sheet,
|
|
217
|
-
|
|
221
|
+
rootSelectedPackageId: $selectedPackageId,
|
|
218
222
|
};
|
|
219
223
|
} else {
|
|
220
224
|
if (sheet) {
|
|
221
|
-
const
|
|
222
|
-
sheet.rootSelectedPackageIdentifier;
|
|
225
|
+
const resultingPackageId = sheet.rootSelectedPackageId;
|
|
223
226
|
emitComponentInteraction({
|
|
224
227
|
componentType: "package_selection_sheet",
|
|
225
228
|
componentName: sheet.props.name,
|
|
226
229
|
componentValue: "close",
|
|
227
|
-
|
|
228
|
-
|
|
230
|
+
currentPackageId: $selectedPackageId,
|
|
231
|
+
resultingPackageId,
|
|
229
232
|
});
|
|
230
|
-
selectedPackageId.set(
|
|
233
|
+
selectedPackageId.set(resultingPackageId);
|
|
231
234
|
}
|
|
232
235
|
sheet = undefined;
|
|
233
236
|
}
|
|
@@ -39,7 +39,7 @@ interface Props {
|
|
|
39
39
|
onError?: (error: unknown) => void;
|
|
40
40
|
hideBackButtons?: boolean;
|
|
41
41
|
walletButtonRender?: WalletButtonRender;
|
|
42
|
-
onInputChanged?: (fieldId: string, value: string) => void;
|
|
42
|
+
onInputChanged?: (fieldId: string, value: string, actionId?: string) => void;
|
|
43
43
|
maxContentWidth?: string;
|
|
44
44
|
initialInputSelections?: InitialInputSelections;
|
|
45
45
|
/**
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { localizations } from "../../stories/fixtures";
|
|
6
6
|
import { localizationDecorator } from "../../stories/localization-decorator";
|
|
7
7
|
import type { StackProps } from "../../types/components/stack";
|
|
8
|
+
import type { Component } from "../../types/component";
|
|
8
9
|
import { DEFAULT_TEXT_COLOR } from "../../utils/constants";
|
|
9
10
|
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
10
11
|
|
|
@@ -58,6 +59,53 @@
|
|
|
58
59
|
},
|
|
59
60
|
] as unknown as TextNodeProps[];
|
|
60
61
|
|
|
62
|
+
/** Z-layer: full-bleed image (layer 0), text label (layer 1). */
|
|
63
|
+
const zlayerImageUnderText: Component[] = [
|
|
64
|
+
{
|
|
65
|
+
type: "image",
|
|
66
|
+
id: "zlayer-bg",
|
|
67
|
+
name: "Background image",
|
|
68
|
+
size: { width: { type: "fill" }, height: { type: "fill" } },
|
|
69
|
+
fit_mode: "fill",
|
|
70
|
+
source: {
|
|
71
|
+
light: {
|
|
72
|
+
width: 600,
|
|
73
|
+
height: 400,
|
|
74
|
+
original:
|
|
75
|
+
"https://placehold.co/600x400/1e293b/94a3b8?text=Layer+0+%28back%29",
|
|
76
|
+
heic: "https://placehold.co/600x400",
|
|
77
|
+
heic_low_res: "https://placehold.co/600x400",
|
|
78
|
+
webp: "https://placehold.co/600x400",
|
|
79
|
+
webp_low_res: "https://placehold.co/600x400",
|
|
80
|
+
},
|
|
81
|
+
dark: null,
|
|
82
|
+
},
|
|
83
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
84
|
+
padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: "text",
|
|
88
|
+
id: "zlayer-top",
|
|
89
|
+
name: "Top label",
|
|
90
|
+
text_lid: "id1",
|
|
91
|
+
color: {
|
|
92
|
+
light: { type: "hex", value: "#f8fafc" },
|
|
93
|
+
dark: { type: "hex", value: "#f8fafc" },
|
|
94
|
+
},
|
|
95
|
+
font_name: null,
|
|
96
|
+
font_size: "heading_m",
|
|
97
|
+
font_weight: "semibold",
|
|
98
|
+
horizontal_alignment: "center",
|
|
99
|
+
background_color: {
|
|
100
|
+
light: { type: "hex", value: "#0f172acc" },
|
|
101
|
+
dark: { type: "hex", value: "#0f172acc" },
|
|
102
|
+
},
|
|
103
|
+
margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
|
|
104
|
+
padding: { top: 12, bottom: 12, leading: 16, trailing: 16 },
|
|
105
|
+
size: { width: { type: "fit" }, height: { type: "fit" } },
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
|
|
61
109
|
const { Story } = defineMeta({
|
|
62
110
|
title: "Components/Stack",
|
|
63
111
|
component: Stack,
|
|
@@ -140,6 +188,46 @@
|
|
|
140
188
|
}}
|
|
141
189
|
/>
|
|
142
190
|
|
|
191
|
+
<Story
|
|
192
|
+
name="Z layer — image under text"
|
|
193
|
+
args={{
|
|
194
|
+
components: zlayerImageUnderText,
|
|
195
|
+
size: {
|
|
196
|
+
width: { type: "fixed", value: 320 },
|
|
197
|
+
height: { type: "fixed", value: 220 },
|
|
198
|
+
},
|
|
199
|
+
dimension: {
|
|
200
|
+
type: "zlayer",
|
|
201
|
+
alignment: "center",
|
|
202
|
+
},
|
|
203
|
+
background: {
|
|
204
|
+
type: "color",
|
|
205
|
+
value: {
|
|
206
|
+
light: { type: "hex", value: "#0f172a" },
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
border: {
|
|
210
|
+
width: 1,
|
|
211
|
+
color: {
|
|
212
|
+
light: { type: "hex", value: "#334155" },
|
|
213
|
+
dark: { type: "hex", value: "#334155" },
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
shape: {
|
|
217
|
+
type: "rectangle",
|
|
218
|
+
corners: {
|
|
219
|
+
top_leading: 12,
|
|
220
|
+
top_trailing: 12,
|
|
221
|
+
bottom_leading: 12,
|
|
222
|
+
bottom_trailing: 12,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
}}
|
|
226
|
+
parameters={{
|
|
227
|
+
chromatic: { disable: true },
|
|
228
|
+
}}
|
|
229
|
+
/>
|
|
230
|
+
|
|
143
231
|
<Story
|
|
144
232
|
name="Space Around"
|
|
145
233
|
args={{
|
|
@@ -114,7 +114,10 @@
|
|
|
114
114
|
{/if}
|
|
115
115
|
|
|
116
116
|
{#if dimension.type === "zlayer"}
|
|
117
|
-
|
|
117
|
+
<!-- isolate: layer z-index values only sort within this stack, not the host page -->
|
|
118
|
+
<div
|
|
119
|
+
style="position: relative; width: 100%; height: 100%; isolation: isolate;"
|
|
120
|
+
>
|
|
118
121
|
{#each components as component, index}
|
|
119
122
|
<div style={getLayerStyle(index)}>
|
|
120
123
|
<Node nodeData={component} />
|
|
@@ -23,7 +23,11 @@
|
|
|
23
23
|
maxContentWidth?: string;
|
|
24
24
|
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
25
25
|
initialInputSelections?: InitialInputSelections;
|
|
26
|
-
onInputChanged?: (
|
|
26
|
+
onInputChanged?: (
|
|
27
|
+
fieldId: string,
|
|
28
|
+
value: string,
|
|
29
|
+
actionId?: string,
|
|
30
|
+
) => void;
|
|
27
31
|
onCompleteWorkflowNavigate?: (
|
|
28
32
|
args: CompleteWorkflowNavigateArgs,
|
|
29
33
|
) => void | Promise<void>;
|
|
@@ -18,7 +18,7 @@ interface Props {
|
|
|
18
18
|
maxContentWidth?: string;
|
|
19
19
|
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
20
20
|
initialInputSelections?: InitialInputSelections;
|
|
21
|
-
onInputChanged?: (fieldId: string, value: string) => void;
|
|
21
|
+
onInputChanged?: (fieldId: string, value: string, actionId?: string) => void;
|
|
22
22
|
onCompleteWorkflowNavigate?: (args: CompleteWorkflowNavigateArgs) => void | Promise<void>;
|
|
23
23
|
walletButtonRender?: WalletButtonRender;
|
|
24
24
|
}
|
package/dist/stores/paywall.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ type PaywallContext = Readonly<{
|
|
|
20
20
|
onPurchase: (actionId?: string) => void;
|
|
21
21
|
emitComponentInteraction: (data: ComponentInteractionData) => void;
|
|
22
22
|
onNavigateToUrl?: (url: string) => void;
|
|
23
|
-
onInputChanged?: (fieldId: string, value: string) => void;
|
|
23
|
+
onInputChanged?: (fieldId: string, value: string, actionId?: string) => void;
|
|
24
24
|
walletButtonRender?: WalletButtonRender;
|
|
25
25
|
onWalletButtonReady?: (walletButtonAvailable?: boolean) => void;
|
|
26
26
|
onButtonAction: (action: Action, actionId?: string) => void;
|
|
@@ -12,9 +12,9 @@ interface IndexedTransition {
|
|
|
12
12
|
defaultIndex: number;
|
|
13
13
|
}
|
|
14
14
|
interface PackageTransition {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
originPackageId?: string;
|
|
16
|
+
destinationPackageId: string;
|
|
17
|
+
defaultPackageId?: string;
|
|
18
18
|
}
|
|
19
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";
|
|
20
20
|
export type TabInteractionData = ComponentInteractionBase<"tab"> & IndexedTransition;
|
|
@@ -27,22 +27,22 @@ export type TextInteractionData = ComponentInteractionBase<"text", "navigate_to_
|
|
|
27
27
|
componentURL: string;
|
|
28
28
|
};
|
|
29
29
|
export type PackageInteractionData = ComponentInteractionBase<"package"> & PackageTransition & {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
originProductId?: string;
|
|
31
|
+
destinationProductId?: string;
|
|
32
|
+
defaultProductId?: string;
|
|
33
33
|
};
|
|
34
34
|
export type PurchaseButtonInteractionData = ComponentInteractionBase<"purchase_button", PurchaseButtonMethod["type"]> & {
|
|
35
35
|
componentURL?: string;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
currentPackageId: string;
|
|
37
|
+
currentProductId?: string;
|
|
38
|
+
resultingPackageId?: string;
|
|
39
|
+
resultingProductId?: string;
|
|
40
40
|
};
|
|
41
41
|
export type PackageSelectionSheetInteractionData = ComponentInteractionBase<"package_selection_sheet"> & {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
currentPackageId?: string;
|
|
43
|
+
resultingPackageId?: string;
|
|
44
|
+
currentProductId?: string;
|
|
45
|
+
resultingProductId?: string;
|
|
46
46
|
};
|
|
47
47
|
export type ComponentInteractionData = TabInteractionData | SwitchInteractionData | CarouselInteractionData | ButtonInteractionData | TextInteractionData | PackageInteractionData | PurchaseButtonInteractionData | PackageSelectionSheetInteractionData;
|
|
48
48
|
export type ComponentInteractionType = ComponentInteractionData["componentType"];
|