@revenuecat/purchases-ui-js 2.1.0 → 2.1.1
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/package/Package.stories.svelte +0 -1
- package/dist/components/package/Package.svelte +13 -1
- package/dist/components/paywall/Paywall.svelte +18 -1
- package/dist/components/paywall/Paywall.svelte.d.ts +2 -1
- package/dist/components/text/TextNode.stories.svelte +45 -1
- package/dist/components/text/TextNode.svelte +10 -1
- package/dist/index.d.ts +1 -1
- package/dist/stores/packageInfo.d.ts +5 -0
- package/dist/stores/packageInfo.js +13 -0
- package/dist/stores/paywall.d.ts +2 -1
- package/dist/stories/packageInfo-decorator.d.ts +3 -0
- package/dist/stories/packageInfo-decorator.js +9 -0
- package/dist/stories/paywall-decorator.js +1 -0
- package/dist/types/variables.d.ts +4 -0
- package/dist/utils/style-utils.d.ts +1 -0
- package/dist/utils/style-utils.js +8 -0
- package/dist/web-components/index.js +1083 -908
- package/package.json +19 -19
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import Package from "./Package.svelte";
|
|
3
3
|
import { componentDecorator } from "../../stories/component-decorator";
|
|
4
4
|
import { localizationDecorator } from "../../stories/localization-decorator";
|
|
5
|
-
import type { PackageProps } from "../../types/components/package";
|
|
6
5
|
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
7
6
|
|
|
8
7
|
const defaultLocale = "en_US";
|
|
@@ -8,10 +8,15 @@
|
|
|
8
8
|
} from "../../stores/variables";
|
|
9
9
|
import type { PackageProps } from "../../types/components/package";
|
|
10
10
|
import { derived } from "svelte/store";
|
|
11
|
+
import {
|
|
12
|
+
getPackageInfoContext,
|
|
13
|
+
setPackageInfoContext,
|
|
14
|
+
} from "../../stores/packageInfo";
|
|
11
15
|
|
|
12
16
|
const { stack, package_id }: PackageProps = $props();
|
|
13
17
|
|
|
14
|
-
const { selectedPackageId, variablesPerPackage } =
|
|
18
|
+
const { selectedPackageId, variablesPerPackage, infoPerPackage } =
|
|
19
|
+
getPaywallContext();
|
|
15
20
|
|
|
16
21
|
setSelectedStateContext(
|
|
17
22
|
derived(selectedPackageId, (value) => value === package_id),
|
|
@@ -27,6 +32,13 @@
|
|
|
27
32
|
(fallback) => $variablesPerPackage?.[package_id] ?? fallback,
|
|
28
33
|
);
|
|
29
34
|
setVariablesContext(variables);
|
|
35
|
+
|
|
36
|
+
const fallbackPackageInfo = getPackageInfoContext();
|
|
37
|
+
const packageInfo = derived(
|
|
38
|
+
fallbackPackageInfo,
|
|
39
|
+
(fallback) => $infoPerPackage?.[package_id] ?? fallback,
|
|
40
|
+
);
|
|
41
|
+
setPackageInfoContext(packageInfo);
|
|
30
42
|
</script>
|
|
31
43
|
|
|
32
44
|
<Stack {...stack} onclick={onPackageClick} />
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import type { SheetProps } from "../../types/components/sheet";
|
|
13
13
|
import type { PaywallData } from "../../types/paywall";
|
|
14
14
|
import type { UIConfig } from "../../types/ui-config";
|
|
15
|
-
import type { VariableDictionary } from "../../types/variables";
|
|
15
|
+
import type { PackageInfo, VariableDictionary } from "../../types/variables";
|
|
16
16
|
import { mapBackground } from "../../utils/background-utils";
|
|
17
17
|
import { css } from "../../utils/base-utils";
|
|
18
18
|
import { registerFonts } from "../../utils/font-utils";
|
|
@@ -21,11 +21,16 @@
|
|
|
21
21
|
import { derived, readable, writable } from "svelte/store";
|
|
22
22
|
import Stack from "../stack/Stack.svelte";
|
|
23
23
|
import Sheet from "./Sheet.svelte";
|
|
24
|
+
import {
|
|
25
|
+
type PackageInfoStore,
|
|
26
|
+
setPackageInfoContext,
|
|
27
|
+
} from "../../stores/packageInfo";
|
|
24
28
|
|
|
25
29
|
interface Props {
|
|
26
30
|
paywallData: PaywallData;
|
|
27
31
|
selectedLocale?: string;
|
|
28
32
|
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
33
|
+
infoPerPackage?: Record<string, PackageInfo>;
|
|
29
34
|
uiConfig: UIConfig;
|
|
30
35
|
preferredColorMode?: ColorMode;
|
|
31
36
|
onPurchaseClicked?: (selectedPackageId: string) => void;
|
|
@@ -41,6 +46,7 @@
|
|
|
41
46
|
paywallData,
|
|
42
47
|
selectedLocale,
|
|
43
48
|
variablesPerPackage = {},
|
|
49
|
+
infoPerPackage = {},
|
|
44
50
|
preferredColorMode,
|
|
45
51
|
onPurchaseClicked,
|
|
46
52
|
onBackClicked,
|
|
@@ -118,6 +124,7 @@
|
|
|
118
124
|
setPaywallContext({
|
|
119
125
|
selectedPackageId,
|
|
120
126
|
variablesPerPackage: readable(variablesPerPackage),
|
|
127
|
+
infoPerPackage: readable(infoPerPackage),
|
|
121
128
|
onPurchase,
|
|
122
129
|
onButtonAction,
|
|
123
130
|
uiConfig,
|
|
@@ -130,6 +137,13 @@
|
|
|
130
137
|
|
|
131
138
|
setVariablesContext(variables);
|
|
132
139
|
|
|
140
|
+
const packageInfo: PackageInfoStore = derived(
|
|
141
|
+
selectedPackageId,
|
|
142
|
+
(packageId) => infoPerPackage[packageId || ""],
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
setPackageInfoContext(packageInfo);
|
|
146
|
+
|
|
133
147
|
const style = $derived(
|
|
134
148
|
css({
|
|
135
149
|
...mapBackground(colorMode, null, base.background),
|
|
@@ -192,10 +206,12 @@
|
|
|
192
206
|
padding: 0;
|
|
193
207
|
font-family: sans-serif;
|
|
194
208
|
}
|
|
209
|
+
|
|
195
210
|
body {
|
|
196
211
|
line-height: 1.5;
|
|
197
212
|
-webkit-font-smoothing: antialiased;
|
|
198
213
|
}
|
|
214
|
+
|
|
199
215
|
img,
|
|
200
216
|
picture,
|
|
201
217
|
video,
|
|
@@ -211,6 +227,7 @@
|
|
|
211
227
|
select {
|
|
212
228
|
font: inherit;
|
|
213
229
|
}
|
|
230
|
+
|
|
214
231
|
p,
|
|
215
232
|
h1,
|
|
216
233
|
h2,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { ColorMode } from "../../types";
|
|
2
2
|
import type { PaywallData } from "../../types/paywall";
|
|
3
3
|
import type { UIConfig } from "../../types/ui-config";
|
|
4
|
-
import type { VariableDictionary } from "../../types/variables";
|
|
4
|
+
import type { PackageInfo, VariableDictionary } from "../../types/variables";
|
|
5
5
|
interface Props {
|
|
6
6
|
paywallData: PaywallData;
|
|
7
7
|
selectedLocale?: string;
|
|
8
8
|
variablesPerPackage?: Record<string, VariableDictionary>;
|
|
9
|
+
infoPerPackage?: Record<string, PackageInfo>;
|
|
9
10
|
uiConfig: UIConfig;
|
|
10
11
|
preferredColorMode?: ColorMode;
|
|
11
12
|
onPurchaseClicked?: (selectedPackageId: string) => void;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { localizationDecorator } from "../../stories/localization-decorator";
|
|
4
4
|
import { variablesDecorator } from "../../stories/variables-decorator";
|
|
5
5
|
import type { Localizations } from "../../types/localization";
|
|
6
|
-
import type { VariableDictionary } from "../../types/variables";
|
|
6
|
+
import type { PackageInfo, VariableDictionary } from "../../types/variables";
|
|
7
7
|
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
8
8
|
import { VARIABLES } from "../paywall/fixtures/variables";
|
|
9
9
|
import { DEFAULT_SPACING } from "../../utils/constants";
|
|
@@ -52,6 +52,18 @@
|
|
|
52
52
|
"product.price": "$39.99",
|
|
53
53
|
"product.price_per_period": "$39.99/yr",
|
|
54
54
|
} satisfies VariableDictionary;
|
|
55
|
+
|
|
56
|
+
const mockPackageInfoWithIntroOffer: PackageInfo = {
|
|
57
|
+
hasIntroOffer: true,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const mockPackageInfoWithTrial: PackageInfo = {
|
|
61
|
+
hasTrial: true,
|
|
62
|
+
};
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<script>
|
|
66
|
+
import { packageInfoDecorator } from "../../stories/packageInfo-decorator";
|
|
55
67
|
</script>
|
|
56
68
|
|
|
57
69
|
<Story name="Default" args={{ name: "hello world!" }} />
|
|
@@ -246,3 +258,35 @@
|
|
|
246
258
|
} satisfies Localizations,
|
|
247
259
|
}}
|
|
248
260
|
/>
|
|
261
|
+
|
|
262
|
+
<Story
|
|
263
|
+
name="With overrides for Intro Offers"
|
|
264
|
+
args={{
|
|
265
|
+
font_weight: "regular",
|
|
266
|
+
horizontal_alignment: "leading",
|
|
267
|
+
padding: { top: 16, trailing: 24, bottom: 16, leading: 24 },
|
|
268
|
+
margin: { top: 8, trailing: 0, bottom: 8, leading: 0 },
|
|
269
|
+
name: "hello world!",
|
|
270
|
+
overrides: [
|
|
271
|
+
{
|
|
272
|
+
conditions: [{ type: "intro_offer" }],
|
|
273
|
+
properties: { text_lid: "override_text_lid" },
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
text_lid,
|
|
277
|
+
}}
|
|
278
|
+
decorators={[
|
|
279
|
+
variablesDecorator(mockVariableDictionary),
|
|
280
|
+
packageInfoDecorator(mockPackageInfoWithIntroOffer),
|
|
281
|
+
]}
|
|
282
|
+
parameters={{
|
|
283
|
+
localizations: {
|
|
284
|
+
[defaultLocale]: {
|
|
285
|
+
[text_lid]:
|
|
286
|
+
"This is a text with variables: {{ product.store_product_name }} for {{ product.price }} per {{ product.price_per_period }} and a missing variable: {{ sub_period_abbreviated }}",
|
|
287
|
+
override_text_lid:
|
|
288
|
+
"This text is shown only when an intro offer is defined for the current package.",
|
|
289
|
+
},
|
|
290
|
+
} satisfies Localizations,
|
|
291
|
+
}}
|
|
292
|
+
/>
|
|
@@ -11,16 +11,25 @@
|
|
|
11
11
|
import { getSelectedStateContext } from "../../stores/selected";
|
|
12
12
|
import { getVariablesContext } from "../../stores/variables";
|
|
13
13
|
import type { TextNodeProps } from "../../types/components/text";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getActiveStateProps,
|
|
16
|
+
getIntroOfferStateProps,
|
|
17
|
+
} from "../../utils/style-utils";
|
|
15
18
|
import { replaceVariables } from "../../utils/variable-utils";
|
|
19
|
+
import { getPackageInfoContext } from "../../stores/packageInfo";
|
|
16
20
|
|
|
17
21
|
const props: TextNodeProps = $props();
|
|
18
22
|
|
|
19
23
|
const selectedState = getSelectedStateContext();
|
|
24
|
+
const packageInfo = getPackageInfoContext();
|
|
20
25
|
const actualProps = $derived.by(() => {
|
|
21
26
|
return {
|
|
22
27
|
...props,
|
|
23
28
|
...getActiveStateProps($selectedState, props.overrides),
|
|
29
|
+
...getIntroOfferStateProps(
|
|
30
|
+
!!$packageInfo?.hasIntroOffer,
|
|
31
|
+
props.overrides,
|
|
32
|
+
),
|
|
24
33
|
};
|
|
25
34
|
});
|
|
26
35
|
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,6 @@ export { default as Video } from "./components/video/Video.svelte";
|
|
|
11
11
|
export * from "./types";
|
|
12
12
|
export { type PaywallData } from "./types/paywall";
|
|
13
13
|
export { type UIConfig } from "./types/ui-config";
|
|
14
|
-
export { type VariableDictionary } from "./types/variables";
|
|
14
|
+
export { type VariableDictionary, type PackageInfo, } from "./types/variables";
|
|
15
15
|
export * from "./ui/globals";
|
|
16
16
|
export { default as Button } from "./ui/molecules/button.svelte";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PackageInfo } from "../types/variables";
|
|
2
|
+
import { type Readable } from "svelte/store";
|
|
3
|
+
export type PackageInfoStore = Readable<PackageInfo | undefined>;
|
|
4
|
+
export declare function setPackageInfoContext(variables: PackageInfoStore): void;
|
|
5
|
+
export declare function getPackageInfoContext(): PackageInfoStore;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getContext, setContext } from "svelte";
|
|
2
|
+
import {} from "svelte/store";
|
|
3
|
+
const key = Symbol("packageInfo");
|
|
4
|
+
export function setPackageInfoContext(variables) {
|
|
5
|
+
setContext(key, variables);
|
|
6
|
+
}
|
|
7
|
+
export function getPackageInfoContext() {
|
|
8
|
+
const context = getContext(key);
|
|
9
|
+
if (context === undefined) {
|
|
10
|
+
throw new Error("PackageInfo context not found");
|
|
11
|
+
}
|
|
12
|
+
return context;
|
|
13
|
+
}
|
package/dist/stores/paywall.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Action } from "../types/components/button";
|
|
2
2
|
import type { UIConfig } from "../types/ui-config";
|
|
3
|
-
import type { VariableDictionary } from "../types/variables";
|
|
3
|
+
import type { PackageInfo, VariableDictionary } from "../types/variables";
|
|
4
4
|
import { type Readable, type Writable } from "svelte/store";
|
|
5
5
|
type PaywallContext = Readonly<{
|
|
6
6
|
selectedPackageId: Writable<string | undefined>;
|
|
7
7
|
variablesPerPackage: Readable<Record<string, VariableDictionary> | undefined>;
|
|
8
|
+
infoPerPackage: Readable<Record<string, PackageInfo> | undefined>;
|
|
8
9
|
onPurchase: () => void;
|
|
9
10
|
onButtonAction: (action: Action, actionId?: string) => void;
|
|
10
11
|
uiConfig: UIConfig;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { PackageInfo } from "../types/variables";
|
|
2
|
+
import type { DecoratorFunction, Renderer } from "storybook/internal/csf";
|
|
3
|
+
export declare function packageInfoDecorator<TRenderer extends Renderer, TArgs>(packageInfo?: PackageInfo): DecoratorFunction<TRenderer, TArgs>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { readable } from "svelte/store";
|
|
2
|
+
import { setPackageInfoContext } from "../stores/packageInfo";
|
|
3
|
+
export function packageInfoDecorator(packageInfo) {
|
|
4
|
+
const store = readable(packageInfo);
|
|
5
|
+
return (Story) => {
|
|
6
|
+
setPackageInfoContext(store);
|
|
7
|
+
return Story();
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -16,6 +16,7 @@ export function paywallDecorator() {
|
|
|
16
16
|
setPaywallContext({
|
|
17
17
|
selectedPackageId,
|
|
18
18
|
variablesPerPackage: readable(undefined),
|
|
19
|
+
infoPerPackage: readable(undefined),
|
|
19
20
|
onPurchase: () => window.alert("Purchase clicked"),
|
|
20
21
|
onButtonAction: (action, actionId) => window.alert(`Button clicked: ${JSON.stringify({ action, actionId }, undefined, 2)}`),
|
|
21
22
|
uiConfig: emptyUiConfig,
|
|
@@ -10,4 +10,8 @@ export declare enum PackageIdentifier {
|
|
|
10
10
|
type VariableName = "product.price" | "product.price_per_period" | "product.price_per_period_abbreviated" | "product.price_per_day" | "product.price_per_week" | "product.price_per_month" | "product.price_per_year" | "product.period" | "product.period_abbreviated" | "product.periodly" | "product.period_in_days" | "product.period_in_weeks" | "product.period_in_months" | "product.period_in_years" | "product.period_with_unit" | "product.currency_code" | "product.currency_symbol" | "product.offer_price" | "product.offer_price_per_day" | "product.offer_price_per_week" | "product.offer_price_per_month" | "product.offer_price_per_year" | "product.offer_period" | "product.offer_period_abbreviated" | "product.offer_period_in_days" | "product.offer_period_in_weeks" | "product.offer_period_in_months" | "product.offer_period_in_years" | "product.offer_period_with_unit" | "product.offer_end_date" | "product.secondary_offer_price" | "product.secondary_offer_period" | "product.secondary_offer_period_abbreviated" | "product.relative_discount" | "product.store_product_name";
|
|
11
11
|
export type VariableDictionary = Record<VariableName, string>;
|
|
12
12
|
export type VariablesDictionary = Record<PackageIdentifier, VariableDictionary>;
|
|
13
|
+
export interface PackageInfo {
|
|
14
|
+
hasIntroOffer?: boolean;
|
|
15
|
+
hasTrial?: boolean;
|
|
16
|
+
}
|
|
13
17
|
export {};
|
|
@@ -8,3 +8,4 @@ import type { RootPaywall } from "../types/paywall.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function findSelectedPackageId({ stack, sticky_footer, }: RootPaywall): string | undefined;
|
|
10
10
|
export declare const getActiveStateProps: <T extends Component>(selectedState: boolean, overrides?: Overrides<T>) => Partial<T>;
|
|
11
|
+
export declare const getIntroOfferStateProps: <T extends Component>(hasIntroOffer: boolean, overrides?: Overrides<T>) => Partial<T>;
|
|
@@ -43,3 +43,11 @@ export const getActiveStateProps = (selectedState, overrides) => {
|
|
|
43
43
|
const override = overrides?.find((override) => override.conditions.find((condition) => condition.type === "selected"));
|
|
44
44
|
return override?.properties ?? {};
|
|
45
45
|
};
|
|
46
|
+
export const getIntroOfferStateProps = (hasIntroOffer, overrides) => {
|
|
47
|
+
if (!hasIntroOffer) {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
const override = overrides?.find((override) => override.conditions.find((condition) => condition.type === "intro_offer" ||
|
|
51
|
+
condition.type === "introductory_offer"));
|
|
52
|
+
return override?.properties ?? {};
|
|
53
|
+
};
|