@revenuecat/purchases-ui-js 0.0.15 → 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 +5 -4
  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 +5 -2
  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 +62 -21
  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 -0
  44. package/dist/stories/fixtures.js +4716 -33
  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 +36 -4
  50. package/dist/utils/style-utils.js +82 -13
  51. package/package.json +27 -25
@@ -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,17 +1,15 @@
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
- [key: string]: any;
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;
11
11
  name: string;
12
12
  }
13
- export interface Text extends PaywallComponent {
14
- }
15
13
  export interface Stack extends PaywallComponent {
16
14
  spacing: number;
17
15
  components: PaywallComponent[];
@@ -40,16 +38,16 @@ export interface ComponentConfig {
40
38
  background?: BaseNodeBackgroundType;
41
39
  stack: Stack;
42
40
  sticky_footer?: {
43
- stack: {
44
- type: "stack";
45
- components: PaywallComponent[];
46
- };
41
+ stack: Stack;
42
+ id: string;
43
+ name: string;
44
+ type: "footer";
47
45
  } | null;
48
46
  };
49
47
  }
50
48
  export interface ComponentLocalizations extends Extra {
51
- en_US: {
52
- [key: string]: string;
49
+ [locale: string]: {
50
+ [label_id: string]: string;
53
51
  };
54
52
  }
55
53
  export interface PaywallData extends Extra {
@@ -69,7 +67,6 @@ export type ComponentState = {
69
67
  interface SharedComponentProps extends PaywallComponent, ActionsProps, PurchaseStateProps {
70
68
  labels: ComponentLocalizations;
71
69
  id: string;
72
- colorMode: ColorMode;
73
70
  name: string;
74
71
  variableDictionary?: VariableDictionary;
75
72
  componentState?: ComponentState;
@@ -130,9 +127,7 @@ export interface StackProps extends SharedComponentProps {
130
127
  spacing?: number;
131
128
  type: "stack";
132
129
  overrides?: {
133
- states: {
134
- [state: string]: StackProps;
135
- };
130
+ [state: string]: StackProps;
136
131
  };
137
132
  }
138
133
  export interface TextNodeProps extends SharedComponentProps {
@@ -142,7 +137,7 @@ export interface TextNodeProps extends SharedComponentProps {
142
137
  font_name?: string;
143
138
  font_size: keyof typeof FontSizeTags;
144
139
  font_weight: keyof typeof FontWeights;
145
- horizontal_alignment: TextAlignment;
140
+ horizontal_alignment: keyof typeof TextAlignments;
146
141
  margin: Spacing;
147
142
  padding: Spacing;
148
143
  text_lid: string;
@@ -150,9 +145,7 @@ export interface TextNodeProps extends SharedComponentProps {
150
145
  size: SizeType;
151
146
  variableDictionary?: VariableDictionary;
152
147
  overrides?: {
153
- states: {
154
- [state: string]: TextNodeProps;
155
- };
148
+ [state: string]: TextNodeProps;
156
149
  };
157
150
  }
158
151
  type ImageSourceDictionaryType = Record<"original" | "heic" | "heic_low_res" | "webp" | "webp_low_res", string>;
@@ -174,9 +167,57 @@ export interface ImageProps extends SharedComponentProps {
174
167
  max_height?: number;
175
168
  override_source_lid?: string;
176
169
  overrides?: {
177
- states: {
178
- [state: string]: ImageProps;
170
+ [state: string]: ImageProps;
171
+ };
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;
179
206
  };
207
+ color: ColorType;
180
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;
181
222
  }
182
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,6 +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 e2eTestTemplate: PaywallData;
12
+ export declare const zStackTemplate: PaywallData;
11
13
  export declare const labelsData: {
12
14
  en_US: {
13
15
  id1: string;
@@ -15,3 +17,6 @@ export declare const labelsData: {
15
17
  id3: string;
16
18
  };
17
19
  };
20
+ export declare const colorModeOverrideTemplate: PaywallData;
21
+ export declare const paywallWithFooter: PaywallData;
22
+ export declare const errorPaywallData: PaywallData;