@revenuecat/purchases-ui-js 0.0.16 → 0.0.17

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 (51) hide show
  1. package/dist/components/button/Button.svelte.d.ts +4 -2
  2. package/dist/components/button/ButtonNode.stories.svelte +2 -4
  3. package/dist/components/button/ButtonNode.svelte.d.ts +1 -0
  4. package/dist/components/footer/Footer.stories.svelte +46 -156
  5. package/dist/components/footer/Footer.stories.svelte.d.ts +1 -2
  6. package/dist/components/footer/Footer.svelte +9 -0
  7. package/dist/components/footer/Footer.svelte.d.ts +1 -0
  8. package/dist/components/image/Image.stories.svelte +9 -7
  9. package/dist/components/image/Image.svelte +18 -3
  10. package/dist/components/image/Image.svelte.d.ts +1 -0
  11. package/dist/components/image/image-utils.js +3 -3
  12. package/dist/components/package/Package.stories.svelte +0 -2
  13. package/dist/components/package/Package.svelte.d.ts +1 -0
  14. package/dist/components/paywall/Node.svelte +8 -1
  15. package/dist/components/paywall/Node.svelte.d.ts +4 -2
  16. package/dist/components/paywall/Paywall.stories.svelte +79 -15
  17. package/dist/components/paywall/Paywall.svelte +41 -22
  18. package/dist/components/paywall/Paywall.svelte.d.ts +4 -0
  19. package/dist/components/purchase-button/PurchaseButton.stories.svelte +0 -2
  20. package/dist/components/purchase-button/PurchaseButton.svelte.d.ts +1 -0
  21. package/dist/components/stack/Stack.stories.svelte +0 -2
  22. package/dist/components/stack/Stack.svelte +3 -0
  23. package/dist/components/stack/Stack.svelte.d.ts +1 -0
  24. package/dist/components/stack/stack-utils.js +3 -3
  25. package/dist/components/text/Text.svelte.d.ts +4 -2
  26. package/dist/components/text/TextNode.stories.svelte +1 -2
  27. package/dist/components/text/TextNode.svelte +5 -12
  28. package/dist/components/text/TextNode.svelte.d.ts +1 -0
  29. package/dist/components/text/text-utils.d.ts +3 -0
  30. package/dist/components/text/text-utils.js +9 -9
  31. package/dist/components/timeline/Timeline.stories.svelte +640 -0
  32. package/dist/components/timeline/Timeline.stories.svelte.d.ts +19 -0
  33. package/dist/components/timeline/Timeline.svelte +40 -0
  34. package/dist/components/timeline/Timeline.svelte.d.ts +4 -0
  35. package/dist/components/timeline/TimelineItem.svelte +100 -0
  36. package/dist/components/timeline/TimelineItem.svelte.d.ts +4 -0
  37. package/dist/components/timeline/timeline-utils.d.ts +25 -0
  38. package/dist/components/timeline/timeline-utils.js +93 -0
  39. package/dist/data/entities.d.ts +57 -8
  40. package/dist/data/state.d.ts +2 -0
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.js +1 -0
  43. package/dist/stories/fixtures.d.ts +5 -1
  44. package/dist/stories/fixtures.js +2958 -1
  45. package/dist/stories/meta-templates.d.ts +0 -1
  46. package/dist/stories/meta-templates.js +0 -5
  47. package/dist/types.d.ts +12 -4
  48. package/dist/types.js +7 -0
  49. package/dist/utils/style-utils.d.ts +34 -2
  50. package/dist/utils/style-utils.js +77 -8
  51. package/package.json +25 -24
@@ -0,0 +1,100 @@
1
+ <script lang="ts">
2
+ import {
3
+ getTimelineItemStyles,
4
+ getTimelineItemTextStyles,
5
+ } from "./timeline-utils";
6
+ import type { TimelineItemProps } from "../../data/entities";
7
+ import { stringifyStyles } from "../../utils/style-utils";
8
+
9
+ const props: TimelineItemProps = $props();
10
+ const styles = $derived(stringifyStyles(getTimelineItemStyles(props)));
11
+
12
+ const {
13
+ tagToRender: titleTagToRender,
14
+ textStyles: titleStyles,
15
+ textLabel: titleLabel,
16
+ } = $derived(getTimelineItemTextStyles(props, "title"));
17
+
18
+ const {
19
+ tagToRender: descriptionTagToRender,
20
+ textStyles: descriptionStyles,
21
+ textLabel: descriptionLabel,
22
+ } = $derived(getTimelineItemTextStyles(props, "description"));
23
+ // TODO: Object mapping icon name to icon component
24
+ </script>
25
+
26
+ <div class="timeline-item" style={styles}>
27
+ <div class="timeline-item-icon-container">
28
+ <div class="timeline-item-icon"></div>
29
+ </div>
30
+ <div class="timeline-item-content">
31
+ <svelte:element
32
+ this={titleTagToRender}
33
+ class="timeline-item-content-title"
34
+ style={titleStyles}>{titleLabel}</svelte:element
35
+ >
36
+ {#if descriptionLabel}
37
+ <svelte:element
38
+ this={descriptionTagToRender}
39
+ class="timeline-item-content-description"
40
+ style={descriptionStyles}>{descriptionLabel}</svelte:element
41
+ >
42
+ {/if}
43
+ </div>
44
+ </div>
45
+
46
+ <style>
47
+ .timeline-item {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: var(--item-spacing, 0px);
51
+ }
52
+
53
+ .timeline-item-icon-container {
54
+ position: relative;
55
+ border-radius: var(--icon-border-radius, 0px);
56
+ width: var(--icon-size, 16px);
57
+ height: var(--icon-size, 16px);
58
+ flex-shrink: 0;
59
+ background-color: var(--icon-background-color, #ffffff);
60
+ border: var(--icon-border, unset);
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ padding: var(--icon-padding, 0px);
65
+ }
66
+
67
+ .timeline-item-icon-container::before {
68
+ position: absolute;
69
+ content: "";
70
+ z-index: -1;
71
+ top: var(--connector-top, 0px);
72
+ height: var(--connector-height, 0px);
73
+ width: var(--connector-width, 0px);
74
+ background: var(--connector-color, transparent);
75
+ }
76
+
77
+ .timeline-item-icon {
78
+ width: var(--icon-width, 10px);
79
+ height: var(--icon-height, 10px);
80
+ color: var(--icon-color, #ffffff);
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ }
85
+
86
+ .timeline-item-content {
87
+ display: flex;
88
+ flex-direction: column;
89
+ justify-content: flex-start;
90
+ align-items: flex-start;
91
+ gap: var(--text-spacing, 0px);
92
+ height: fit-content;
93
+ }
94
+ .timeline-item-content-title,
95
+ .timeline-item-content-description {
96
+ margin: var(--text-margin, 0px);
97
+ padding: var(--text-padding, 0px);
98
+ font-family: var(--font-family, sans-serif);
99
+ }
100
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { TimelineItemProps } from "../../data/entities";
2
+ declare const TimelineItem: import("svelte").Component<TimelineItemProps, {}, "">;
3
+ type TimelineItem = ReturnType<typeof TimelineItem>;
4
+ export default TimelineItem;
@@ -0,0 +1,25 @@
1
+ import type { TimelineItemProps, TimelineProps } from "../../data/entities";
2
+ export declare function getTimelineStyles(props: TimelineProps): {
3
+ "--item-spacing": string;
4
+ "--width": string;
5
+ "--height": string;
6
+ "--flex": string;
7
+ };
8
+ export declare function getTimelineItemStyles(props: TimelineItemProps): {
9
+ "--icon-size": string;
10
+ "--icon-padding": string;
11
+ "--icon-color": string;
12
+ "--text-spacing": string;
13
+ "--icon-background-color": string;
14
+ "--icon-border": string;
15
+ "--icon-border-radius": string;
16
+ "--connector-color": string;
17
+ "--connector-width": string;
18
+ "--connector-top": string;
19
+ "--connector-height": string;
20
+ };
21
+ export declare function getTimelineItemTextStyles(props: TimelineItemProps, kind?: "title" | "description"): {
22
+ textStyles: string;
23
+ tagToRender: Partial<import("../../utils/style-utils").TextComponentTags>;
24
+ textLabel: string | undefined;
25
+ };
@@ -0,0 +1,93 @@
1
+ import { defaultColor, getTextComponentStyles, } from "../text/text-utils";
2
+ import { getBorderStyle, getColor, getCornerRadiusStyle, getLabelAndReplaceVariables, getSizeStyle, stringifyStyles, } from "../../utils/style-utils";
3
+ export function getTimelineStyles(props) {
4
+ const styles = {
5
+ "--item-spacing": `${props.item_spacing}px`,
6
+ "--width": "unset",
7
+ "--height": "unset",
8
+ "--flex": "0 1 auto",
9
+ };
10
+ Object.assign(styles, getSizeStyle(props.size));
11
+ return styles;
12
+ }
13
+ export function getTimelineItemStyles(props) {
14
+ const styles = {
15
+ "--icon-size": `${props.icon.width_and_height}px`,
16
+ "--icon-padding": `${props.icon.padding}px`,
17
+ "--icon-color": getColor({
18
+ colorMap: props.icon.color,
19
+ colorMode: props.purchaseState?.colorMode,
20
+ }),
21
+ "--text-spacing": `${props.text_spacing}px`,
22
+ "--icon-background-color": getColor({
23
+ colorMap: props.icon_background?.color,
24
+ colorMode: props.purchaseState.colorMode,
25
+ }),
26
+ "--icon-border": getBorderStyle(props.icon_background?.border, props.purchaseState?.colorMode),
27
+ "--icon-border-radius": props.icon_background?.shape?.type === "rectangle"
28
+ ? getCornerRadiusStyle(props.icon_background.shape.corners)
29
+ : "50%",
30
+ "--connector-color": getColor({
31
+ colorMap: props.connector?.color,
32
+ colorMode: props.purchaseState.colorMode,
33
+ }),
34
+ "--connector-width": `${props.connector?.width || 0}px`,
35
+ "--connector-top": "0px",
36
+ "--connector-height": `${props.item_spacing}px`,
37
+ };
38
+ if (props.connector) {
39
+ const hasMarginTop = props.connector.margin.top !== 0;
40
+ const hasMarginBottom = props.connector.margin.bottom !== 0;
41
+ const itemBackgroundSize = props.icon.padding + props.icon.width_and_height / 2;
42
+ if (!hasMarginTop && !hasMarginBottom) {
43
+ styles["--connector-height"] =
44
+ `${props.item_spacing + itemBackgroundSize * 2}px`;
45
+ styles["--connector-top"] = `50%`;
46
+ }
47
+ if (hasMarginTop && hasMarginBottom) {
48
+ styles["--connector-height"] =
49
+ `${props.item_spacing - props.connector.margin.top - props.connector.margin.bottom}px`;
50
+ styles["--connector-top"] =
51
+ `calc(100% + ${props.connector.margin.top}px)`;
52
+ }
53
+ if (!hasMarginTop && hasMarginBottom) {
54
+ styles["--connector-height"] =
55
+ `${props.item_spacing - props.connector.margin.bottom + itemBackgroundSize}px`;
56
+ styles["--connector-top"] = `50%`;
57
+ }
58
+ if (hasMarginTop && !hasMarginBottom) {
59
+ styles["--connector-height"] =
60
+ `${props.item_spacing + itemBackgroundSize}px`;
61
+ styles["--connector-top"] =
62
+ `calc(100% + ${props.connector.margin.top}px)`;
63
+ }
64
+ }
65
+ return styles;
66
+ }
67
+ export function getTimelineItemTextStyles(props, kind = "title") {
68
+ const textProps = {
69
+ color: props[kind]?.color || defaultColor,
70
+ font_size: props[kind]?.font_size || "body_m",
71
+ font_weight: props[kind]?.font_weight || "regular",
72
+ horizontal_alignment: props[kind]?.horizontal_alignment || "leading",
73
+ };
74
+ const { tagToRender, textStyles } = getTextComponentStyles({
75
+ ...props,
76
+ components: [],
77
+ ...textProps,
78
+ size: { width: { type: "fit" }, height: { type: "fit" } },
79
+ type: "text",
80
+ margin: { top: 0, bottom: 0, leading: 0, trailing: 0 },
81
+ padding: { top: 0, bottom: 0, leading: 0, trailing: 0 },
82
+ text_lid: "",
83
+ });
84
+ const stringifiedStyles = stringifyStyles(textStyles);
85
+ const textLabel = getLabelAndReplaceVariables({
86
+ text_lid: props[kind]?.text_lid,
87
+ locale: props.purchaseState.locale,
88
+ defaultLocale: props.purchaseState.defaultLocale,
89
+ labels: props.labels,
90
+ variableDictionary: props.variableDictionary,
91
+ });
92
+ return { textStyles: stringifiedStyles, tagToRender, textLabel };
93
+ }
@@ -1,10 +1,10 @@
1
- import type { BorderType, ColorMode, ColorType, CornerRadiusType, DimensionType, FitTypes, FontSizeTags, FontWeights, ShadowType, ShapeType, SizeType, Spacing, TextAlignment } from "../types";
1
+ import type { BorderType, CircleShape, ColorType, CornerRadiusType, DimensionType, FitTypes, FontSizeTags, FontWeights, RectangleShape, ShadowType, ShapeType, SizeType, Spacing, TextAlignments } from "../types";
2
2
  import type { PurchaseState } from "./state";
3
3
  import type { VariableDictionary } from "../utils/variable-utils";
4
4
  export interface Extra {
5
5
  [key: string]: unknown;
6
6
  }
7
- export type ComponentTypes = "stack" | "text" | "image" | "button" | "purchase_button" | "footer" | "package";
7
+ export type ComponentTypes = "stack" | "text" | "image" | "button" | "purchase_button" | "footer" | "package" | "timeline";
8
8
  export interface PaywallComponent extends Extra {
9
9
  type: ComponentTypes;
10
10
  id: string;
@@ -38,10 +38,10 @@ export interface ComponentConfig {
38
38
  background?: BaseNodeBackgroundType;
39
39
  stack: Stack;
40
40
  sticky_footer?: {
41
- stack: {
42
- type: "stack";
43
- components: PaywallComponent[];
44
- };
41
+ stack: Stack;
42
+ id: string;
43
+ name: string;
44
+ type: "footer";
45
45
  } | null;
46
46
  };
47
47
  }
@@ -67,7 +67,6 @@ export type ComponentState = {
67
67
  interface SharedComponentProps extends PaywallComponent, ActionsProps, PurchaseStateProps {
68
68
  labels: ComponentLocalizations;
69
69
  id: string;
70
- colorMode: ColorMode;
71
70
  name: string;
72
71
  variableDictionary?: VariableDictionary;
73
72
  componentState?: ComponentState;
@@ -138,7 +137,7 @@ export interface TextNodeProps extends SharedComponentProps {
138
137
  font_name?: string;
139
138
  font_size: keyof typeof FontSizeTags;
140
139
  font_weight: keyof typeof FontWeights;
141
- horizontal_alignment: TextAlignment;
140
+ horizontal_alignment: keyof typeof TextAlignments;
142
141
  margin: Spacing;
143
142
  padding: Spacing;
144
143
  text_lid: string;
@@ -171,4 +170,54 @@ export interface ImageProps extends SharedComponentProps {
171
170
  [state: string]: ImageProps;
172
171
  };
173
172
  }
173
+ export type ItemProps = {
174
+ title: {
175
+ text_lid: string;
176
+ color: ColorType;
177
+ font_name?: string;
178
+ font_weight?: keyof typeof FontWeights;
179
+ font_size?: keyof typeof FontSizeTags;
180
+ horizontal_alignment?: keyof typeof TextAlignments;
181
+ };
182
+ description?: {
183
+ text_lid: string;
184
+ color: ColorType;
185
+ font_name?: string;
186
+ font_weight?: keyof typeof FontWeights;
187
+ font_size?: keyof typeof FontSizeTags;
188
+ horizontal_alignment?: keyof typeof TextAlignments;
189
+ };
190
+ icon: {
191
+ name: string;
192
+ color: ColorType;
193
+ width_and_height: number;
194
+ padding: number;
195
+ };
196
+ icon_background?: {
197
+ shape: CircleShape | RectangleShape;
198
+ color: ColorType;
199
+ border?: BorderType;
200
+ };
201
+ connector?: {
202
+ width: number;
203
+ margin: {
204
+ top: number;
205
+ bottom: number;
206
+ };
207
+ color: ColorType;
208
+ };
209
+ };
210
+ export interface TimelineProps extends SharedComponentProps {
211
+ type: "timeline";
212
+ item_spacing: number;
213
+ text_spacing: number;
214
+ size: SizeType;
215
+ padding: Spacing;
216
+ margin: Spacing;
217
+ items: ItemProps[];
218
+ }
219
+ export interface TimelineItemProps extends ItemProps, SharedComponentProps {
220
+ text_spacing: number;
221
+ item_spacing: number;
222
+ }
174
223
  export {};
@@ -1,7 +1,9 @@
1
+ import type { ColorMode } from "../types";
1
2
  import type { VariableDictionary } from "../utils/variable-utils";
2
3
  export interface PurchaseState {
3
4
  selectedPackageId?: string;
4
5
  locale: string;
5
6
  defaultLocale: string;
6
7
  variablesPerPackage?: Record<string, VariableDictionary>;
8
+ colorMode: ColorMode;
7
9
  }
package/dist/index.d.ts CHANGED
@@ -9,3 +9,4 @@ export { default as PurchaseButton } from "./components/purchase-button/Purchase
9
9
  export { default as Package } from "./components/package/Package.svelte";
10
10
  export { default as Footer } from "./components/footer/Footer.svelte";
11
11
  export { type VariableDictionary } from "./utils/variable-utils";
12
+ export { default as Timeline } from "./components/timeline/Timeline.svelte";
package/dist/index.js CHANGED
@@ -10,3 +10,4 @@ export { default as PurchaseButton } from "./components/purchase-button/Purchase
10
10
  export { default as Package } from "./components/package/Package.svelte";
11
11
  export { default as Footer } from "./components/footer/Footer.svelte";
12
12
  export {} from "./utils/variable-utils";
13
+ export { default as Timeline } from "./components/timeline/Timeline.svelte";
@@ -8,7 +8,8 @@ export declare const gradientPaywallData: PaywallData;
8
8
  export declare const calmPaywallData: PaywallData;
9
9
  export declare const stateTemplate: PaywallData;
10
10
  export declare const posterMakerTemplate: PaywallData;
11
- export declare const testTemplate: PaywallData;
11
+ export declare const e2eTestTemplate: PaywallData;
12
+ export declare const zStackTemplate: PaywallData;
12
13
  export declare const labelsData: {
13
14
  en_US: {
14
15
  id1: string;
@@ -16,3 +17,6 @@ export declare const labelsData: {
16
17
  id3: string;
17
18
  };
18
19
  };
20
+ export declare const colorModeOverrideTemplate: PaywallData;
21
+ export declare const paywallWithFooter: PaywallData;
22
+ export declare const errorPaywallData: PaywallData;