@revenuecat/purchases-ui-js 0.0.13 → 0.0.15

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.
Files changed (35) hide show
  1. package/dist/components/button/Button.svelte +1 -1
  2. package/dist/components/button/ButtonNode.svelte +9 -3
  3. package/dist/components/footer/Footer.svelte +3 -3
  4. package/dist/components/image/Image.svelte +4 -2
  5. package/dist/components/image/image-utils.js +9 -5
  6. package/dist/components/package/Package.svelte +28 -8
  7. package/dist/components/paywall/Node.svelte +17 -2
  8. package/dist/components/paywall/Node.svelte.d.ts +2 -0
  9. package/dist/components/paywall/Paywall.stories.svelte +99 -1
  10. package/dist/components/paywall/Paywall.svelte +60 -3
  11. package/dist/components/paywall/Paywall.svelte.d.ts +2 -0
  12. package/dist/components/paywall/paywall-utils.d.ts +7 -0
  13. package/dist/components/paywall/paywall-utils.js +21 -0
  14. package/dist/components/purchase-button/PurchaseButton.svelte +9 -4
  15. package/dist/components/stack/Stack.svelte +9 -2
  16. package/dist/components/stack/stack-utils.d.ts +1 -1
  17. package/dist/components/stack/stack-utils.js +9 -4
  18. package/dist/components/text/Text.svelte +4 -3
  19. package/dist/components/text/TextNode.stories.svelte +118 -1
  20. package/dist/components/text/TextNode.svelte +35 -5
  21. package/dist/components/text/text-utils.d.ts +2 -0
  22. package/dist/components/text/text-utils.js +6 -5
  23. package/dist/data/entities.d.ts +40 -0
  24. package/dist/data/state.d.ts +2 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +1 -0
  27. package/dist/stories/fixtures.d.ts +4 -0
  28. package/dist/stories/fixtures.js +7840 -585
  29. package/dist/types.d.ts +9 -3
  30. package/dist/types.js +1 -1
  31. package/dist/utils/style-utils.d.ts +15 -8
  32. package/dist/utils/style-utils.js +61 -11
  33. package/dist/utils/variable-utils.d.ts +23 -3
  34. package/dist/utils/variable-utils.js +1 -1
  35. package/package.json +13 -3
package/dist/types.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  export type ColorMode = "light" | "dark";
2
+ export type ColorStop = {
3
+ color: string;
4
+ percent: number;
5
+ };
2
6
  type Color = {
3
- type: "hex" | "alias";
4
- value: string;
7
+ type: "hex" | "alias" | "linear" | "radial";
8
+ value?: string;
9
+ degrees?: number;
10
+ points?: ColorStop[];
5
11
  };
6
12
  export type ColorType = {
7
13
  dark?: Color;
@@ -25,7 +31,7 @@ export declare enum FontWeights {
25
31
  light = 300,
26
32
  regular = 400,
27
33
  medium = 500,
28
- semi_bold = 600,
34
+ semibold = 600,
29
35
  bold = 700,
30
36
  extra_bold = 800,
31
37
  black = 900
package/dist/types.js CHANGED
@@ -19,7 +19,7 @@ export var FontWeights;
19
19
  FontWeights[FontWeights["light"] = 300] = "light";
20
20
  FontWeights[FontWeights["regular"] = 400] = "regular";
21
21
  FontWeights[FontWeights["medium"] = 500] = "medium";
22
- FontWeights[FontWeights["semi_bold"] = 600] = "semi_bold";
22
+ FontWeights[FontWeights["semibold"] = 600] = "semibold";
23
23
  FontWeights[FontWeights["bold"] = 700] = "bold";
24
24
  FontWeights[FontWeights["extra_bold"] = 800] = "extra_bold";
25
25
  FontWeights[FontWeights["black"] = 900] = "black";
@@ -1,4 +1,4 @@
1
- import type { ComponentLocalizations, ImageMaskShapeType, PaywallData, TextNodeProps } from "../data/entities.js";
1
+ import type { ComponentLocalizations, ComponentState, ImageMaskShapeType, PaywallData, TextNodeProps } from "../data/entities.js";
2
2
  import { type BorderType, type ColorMode, type ColorType, type DimensionType, FontSizeTags, type ShadowType, type ShapeType, type SizeType, type Spacing } from "../types.js";
3
3
  export type TextComponentTags = "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
4
4
  /**
@@ -7,6 +7,16 @@ export type TextComponentTags = "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
7
7
  * @returns Corresponding HTML heading tag
8
8
  */
9
9
  export declare function getTextComponentTag(fontSize: keyof typeof FontSizeTags): TextComponentTags;
10
+ /**
11
+ * Gets color value based on color mode with fallback
12
+ * @param params - Object containing color map, mode and fallback color
13
+ * @returns Color value as string
14
+ */
15
+ export declare function getColor({ colorMap, colorMode, fallback, }: {
16
+ colorMap?: ColorType;
17
+ colorMode?: ColorMode;
18
+ fallback?: string;
19
+ }): string;
10
20
  /**
11
21
  * Generates comprehensive component styles including spacing, colors, borders and shadows
12
22
  * @param params - Component style configuration object
@@ -30,7 +40,7 @@ export declare function getComponentStyles({ backgroundColor, border, margin, pa
30
40
  "--padding-inline-end": string;
31
41
  "--padding-block-end": string;
32
42
  "--padding-inline-start": string;
33
- "--background-color": string;
43
+ "--background": string;
34
44
  "--text-color": string;
35
45
  "--border": string;
36
46
  "--border-radius": string;
@@ -77,14 +87,10 @@ export declare function getDimensionStyle(dimension: DimensionType): {
77
87
  /**
78
88
  * Generates text-related styles
79
89
  * @param props - Text component properties
90
+ * @param colorMode - The currently selected ColorMode (dark/light)
80
91
  * @returns CSS style object with text formatting properties
81
92
  */
82
- export declare function getTextStyles(props: TextNodeProps): {
83
- "--text-align": string;
84
- "--font-weight": number;
85
- "--font-size": string;
86
- "--font-family": string;
87
- };
93
+ export declare function getTextStyles(props: TextNodeProps, colorMode?: ColorMode): any;
88
94
  /**
89
95
  * Converts a style object to a CSS string
90
96
  * @param styles - Object containing CSS properties and values
@@ -108,3 +114,4 @@ export declare function getLabelById(label_id: string, locale: string, fallbackL
108
114
  * @returns the id of the first package marked as `is_selected_by_default` or undefined
109
115
  */
110
116
  export declare function findSelectedPackageId(paywallData: PaywallData): string | undefined;
117
+ export declare const getActiveStateProps: <T>(overrides?: Record<"states", Record<string, T>>, componentState?: ComponentState) => T;
@@ -28,8 +28,27 @@ export function getTextComponentTag(fontSize) {
28
28
  * @param params - Object containing color map, mode and fallback color
29
29
  * @returns Color value as string
30
30
  */
31
- function getColor({ colorMap, colorMode = "light", fallback = "FFFFFF", }) {
32
- return colorMap?.[colorMode]?.value || fallback;
31
+ export function getColor({ colorMap, colorMode = "light", fallback = "FFFFFF", }) {
32
+ if (!colorMap)
33
+ return fallback;
34
+ const color = colorMap[colorMode] || colorMap["light"];
35
+ let colorPoints = "";
36
+ switch (color.type) {
37
+ case "hex":
38
+ case "alias":
39
+ return color.value ?? fallback;
40
+ case "linear":
41
+ colorPoints = (color.points || [])
42
+ .map((point) => `${point.color} ${point.percent}%`)
43
+ .join(", ");
44
+ return `linear-gradient(${color.degrees}deg, ${colorPoints})`;
45
+ case "radial":
46
+ colorPoints = (color.points || [])
47
+ .map((point) => `${point.color} ${point.percent}%`)
48
+ .join(", ");
49
+ return `radial-gradient(${colorPoints})`;
50
+ }
51
+ return fallback;
33
52
  }
34
53
  /**
35
54
  * Generates CSS border style string
@@ -64,7 +83,7 @@ export function getComponentStyles({ backgroundColor, border, margin, padding, t
64
83
  "--padding-inline-end": "0px",
65
84
  "--padding-block-end": "0px",
66
85
  "--padding-inline-start": "0px",
67
- "--background-color": "transparent",
86
+ "--background": "transparent",
68
87
  "--text-color": "#000000",
69
88
  "--border": "none",
70
89
  "--border-radius": "0px",
@@ -77,7 +96,7 @@ export function getComponentStyles({ backgroundColor, border, margin, padding, t
77
96
  Object.assign(stylesObject, getSpacingStyle(margin, "margin"));
78
97
  }
79
98
  if (backgroundColor) {
80
- stylesObject["--background-color"] = getColor({
99
+ stylesObject["--background"] = getColor({
81
100
  colorMap: backgroundColor,
82
101
  colorMode,
83
102
  fallback: "transparent",
@@ -119,7 +138,6 @@ export function getSizeStyle(size) {
119
138
  return "fit-content";
120
139
  }
121
140
  if (size.type === "fill") {
122
- // return "100%";
123
141
  const userAgent = navigator.userAgent;
124
142
  const isFirefox = userAgent.match(/firefox|fxios/i);
125
143
  return isFirefox ? "-moz-available" : "-webkit-fill-available";
@@ -143,9 +161,9 @@ export function getSizeStyle(size) {
143
161
  */
144
162
  export function getGradientStyle(colorMode, gradientColors) {
145
163
  if (!gradientColors)
146
- return { "--background": "unset" };
164
+ return { "--background": "none" };
147
165
  return {
148
- "--background": `linear-gradient(${gradientColors.map((color) => color[colorMode]?.value).join(", ")})`,
166
+ "--background": `linear-gradient(${gradientColors.map((color) => color[colorMode]?.value || color["light"].value).join(", ")})`,
149
167
  };
150
168
  }
151
169
  /**
@@ -200,20 +218,29 @@ export function getDimensionStyle(dimension) {
200
218
  /**
201
219
  * Generates text-related styles
202
220
  * @param props - Text component properties
221
+ * @param colorMode - The currently selected ColorMode (dark/light)
203
222
  * @returns CSS style object with text formatting properties
204
223
  */
205
- export function getTextStyles(props) {
206
- const { font_size, horizontal_alignment, font_weight, font_name } = props;
224
+ export function getTextStyles(props, colorMode = "light") {
225
+ const { font_size, horizontal_alignment, font_weight, font_name, color } = props;
207
226
  const styles = {
208
227
  "--text-align": "initial",
209
228
  "--font-weight": 400,
210
229
  "--font-size": "initial",
211
230
  "--font-family": "sans-serif",
231
+ "--background-clip": "initial",
232
+ "--text-fill-color": "initial",
212
233
  };
213
234
  styles["--text-align"] = horizontal_alignment;
214
- styles["--font-weight"] = FontWeights[font_weight];
215
- styles["--font-size"] = FontSizes[font_size];
235
+ styles["--font-weight"] = FontWeights[font_weight] || FontWeights.regular;
236
+ styles["--font-size"] = FontSizes[font_size] || FontSizes.body_m;
216
237
  styles["--font-family"] = font_name || "sans-serif";
238
+ if (color &&
239
+ (color[colorMode]?.type === "linear" || color[colorMode]?.type === "radial")) {
240
+ styles["--background-clip"] = "text";
241
+ styles["--text-fill-color"] = "transparent";
242
+ styles["--background"] = getColor({ colorMap: color, colorMode });
243
+ }
217
244
  return styles;
218
245
  }
219
246
  /**
@@ -276,3 +303,26 @@ export function findSelectedPackageId(paywallData) {
276
303
  }
277
304
  return p.package_id;
278
305
  }
306
+ export const getActiveStateProps = (overrides, componentState) => {
307
+ if (!componentState)
308
+ return {};
309
+ const activeStateKeys = getComponentActiveStateKeys(componentState);
310
+ const activeStateProps = activeStateKeys.reduce((props, key) => {
311
+ if (overrides) {
312
+ const styles = overrides.states[key];
313
+ return { ...props, ...styles };
314
+ }
315
+ return props;
316
+ }, {});
317
+ return activeStateProps;
318
+ };
319
+ const getComponentActiveStateKeys = (componentState) => {
320
+ if (!componentState)
321
+ return [];
322
+ const stateKeys = Object.entries(componentState).reduce((activeStates, [stateKey, stateValue]) => {
323
+ if (stateValue)
324
+ activeStates.push(stateKey);
325
+ return activeStates;
326
+ }, []);
327
+ return stateKeys;
328
+ };
@@ -1,8 +1,28 @@
1
1
  export declare const VARIABLE_NAMES: string[];
2
- export type VariableDictionary = Record<string, string | number | undefined>;
2
+ export type VariableDictionary = {
3
+ product_name: string | number | undefined;
4
+ price: string | number | undefined;
5
+ price_per_period: string | number | undefined;
6
+ price_per_period_full: string | number | undefined;
7
+ total_price_and_per_month: string | number | undefined;
8
+ total_price_and_per_month_full: string | number | undefined;
9
+ sub_price_per_month: string | number | undefined;
10
+ sub_price_per_week: string | number | undefined;
11
+ sub_duration: string | number | undefined;
12
+ sub_duration_in_months: string | number | undefined;
13
+ sub_period: string | number | undefined;
14
+ sub_period_length: string | number | undefined;
15
+ sub_period_abbreviated: string | number | undefined;
16
+ sub_offer_duration: string | number | undefined;
17
+ sub_offer_duration_2: string | number | undefined;
18
+ sub_offer_price: string | number | undefined;
19
+ sub_offer_price_2: string | number | undefined;
20
+ sub_relative_discount: string | number | undefined;
21
+ [key: string]: string | number | undefined;
22
+ };
3
23
  export type ReplaceVariablesProps = {
4
24
  value?: string;
5
- dictionary?: VariableDictionary;
25
+ variableDictionary?: VariableDictionary;
6
26
  };
7
27
  /**
8
28
  * Returns a string with the variables replaced by values from the dictionary
@@ -10,4 +30,4 @@ export type ReplaceVariablesProps = {
10
30
  * @param dictionary Dictionary containing the values for the variables
11
31
  * @returns The string with values: "Try CatGPT Annual for only $59.99/yr ($4.99/mo)"
12
32
  */
13
- export declare const replaceVariables: ({ value, dictionary, }: ReplaceVariablesProps) => string | undefined;
33
+ export declare const replaceVariables: ({ value, variableDictionary: dictionary, }: ReplaceVariablesProps) => string | undefined;
@@ -24,7 +24,7 @@ export const VARIABLE_NAMES = [
24
24
  * @param dictionary Dictionary containing the values for the variables
25
25
  * @returns The string with values: "Try CatGPT Annual for only $59.99/yr ($4.99/mo)"
26
26
  */
27
- export const replaceVariables = ({ value = "", dictionary, }) => {
27
+ export const replaceVariables = ({ value = "", variableDictionary: dictionary, }) => {
28
28
  if (!dictionary)
29
29
  return value;
30
30
  return VARIABLE_NAMES.reduce((result, variableName) => {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@revenuecat/purchases-ui-js",
3
3
  "description": "Web components for Paywalls. Powered by RevenueCat",
4
4
  "private": false,
5
- "version": "0.0.13",
5
+ "version": "0.0.15",
6
6
  "author": {
7
7
  "name": "RevenueCat, Inc."
8
8
  },
@@ -35,7 +35,8 @@
35
35
  "prepare": "husky",
36
36
  "chromatic": "chromatic",
37
37
  "format": "prettier --write .",
38
- "typecheck": "tsc --noEmit"
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "vitest"
39
40
  },
40
41
  "files": [
41
42
  "dist",
@@ -60,6 +61,7 @@
60
61
  },
61
62
  "devDependencies": {
62
63
  "@chromatic-com/storybook": "^1.9.0",
64
+ "@eslint/js": "^9.16.0",
63
65
  "@storybook/addon-essentials": "^8.3.6",
64
66
  "@storybook/addon-interactions": "^8.3.6",
65
67
  "@storybook/addon-links": "^8.3.6",
@@ -72,7 +74,11 @@
72
74
  "@sveltejs/kit": "^2.0.0",
73
75
  "@sveltejs/package": "^2.0.0",
74
76
  "@sveltejs/vite-plugin-svelte": "^4.0.0",
77
+ "@typescript-eslint/parser": "^8.17.0",
75
78
  "chromatic": "^11.16.1",
79
+ "eslint": "^9.16.0",
80
+ "eslint-plugin-svelte": "^2.46.1",
81
+ "globals": "^15.13.0",
76
82
  "husky": "^9.1.6",
77
83
  "lint-staged": "^15.2.10",
78
84
  "prettier": "^3.3.3",
@@ -82,10 +88,14 @@
82
88
  "svelte": "^5.0.0",
83
89
  "svelte-check": "^4.0.0",
84
90
  "typescript": "^5.0.0",
91
+ "typescript-eslint": "^8.17.0",
85
92
  "vite": "^5.0.11"
86
93
  },
87
94
  "lint-staged": {
88
- "**/*": "prettier --write --ignore-unknown"
95
+ "**/*": [
96
+ "prettier --write --ignore-unknown",
97
+ "eslint --fix"
98
+ ]
89
99
  },
90
100
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
91
101
  }