@revenuecat/purchases-ui-js 2.0.1 → 2.0.3

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 (138) hide show
  1. package/dist/components/button/ButtonNode.stories.svelte +66 -108
  2. package/dist/components/button/ButtonNode.svelte +3 -31
  3. package/dist/components/footer/Footer.stories.svelte +112 -106
  4. package/dist/components/footer/Footer.svelte +10 -6
  5. package/dist/components/icon/Icon.stories.svelte +100 -0
  6. package/dist/components/icon/Icon.stories.svelte.d.ts +19 -0
  7. package/dist/components/icon/Icon.svelte +73 -0
  8. package/dist/components/icon/Icon.svelte.d.ts +4 -0
  9. package/dist/components/image/ClipPath.svelte +49 -0
  10. package/dist/components/image/ClipPath.svelte.d.ts +9 -0
  11. package/dist/components/image/Image.stories.svelte +83 -199
  12. package/dist/components/image/Image.svelte +152 -137
  13. package/dist/components/image/Image.svelte.d.ts +1 -1
  14. package/dist/components/image/Overlay.svelte +36 -0
  15. package/dist/components/image/Overlay.svelte.d.ts +8 -0
  16. package/dist/components/package/Package.stories.svelte +12 -27
  17. package/dist/components/package/Package.svelte +10 -44
  18. package/dist/components/paywall/Node.svelte +45 -43
  19. package/dist/components/paywall/Node.svelte.d.ts +10 -12
  20. package/dist/components/paywall/Paywall.stories.svelte +36 -140
  21. package/dist/components/paywall/Paywall.svelte +38 -20
  22. package/dist/components/paywall/Paywall.svelte.d.ts +3 -2
  23. package/dist/components/paywall/fixtures/override-paywall.d.ts +2 -0
  24. package/dist/components/paywall/fixtures/override-paywall.js +1310 -0
  25. package/dist/components/paywall/fixtures/stack-paywall.d.ts +2 -0
  26. package/dist/components/paywall/fixtures/stack-paywall.js +5223 -0
  27. package/dist/components/paywall/fixtures/variables.d.ts +261 -0
  28. package/dist/components/paywall/fixtures/variables.js +262 -0
  29. package/dist/components/purchase-button/PurchaseButton.stories.svelte +10 -29
  30. package/dist/components/purchase-button/PurchaseButton.svelte +2 -34
  31. package/dist/components/stack/Stack.stories.svelte +2364 -1020
  32. package/dist/components/stack/Stack.svelte +108 -151
  33. package/dist/components/stack/Stack.svelte.d.ts +6 -2
  34. package/dist/components/stack/stack-utils.d.ts +10 -30
  35. package/dist/components/stack/stack-utils.js +77 -257
  36. package/dist/components/text/Text.svelte +3 -37
  37. package/dist/components/text/Text.svelte.d.ts +1 -2
  38. package/dist/components/text/TextNode.stories.svelte +10 -48
  39. package/dist/components/text/TextNode.svelte +25 -37
  40. package/dist/components/text/TextNode.svelte.d.ts +1 -1
  41. package/dist/components/text/text-utils.d.ts +4 -9
  42. package/dist/components/text/text-utils.js +32 -117
  43. package/dist/components/timeline/Timeline.stories.svelte +640 -256
  44. package/dist/components/timeline/Timeline.svelte +42 -30
  45. package/dist/components/timeline/Timeline.svelte.d.ts +1 -1
  46. package/dist/components/timeline/TimelineItem.svelte +80 -112
  47. package/dist/components/timeline/TimelineItem.svelte.d.ts +6 -2
  48. package/dist/components/timeline/timeline-utils.d.ts +24 -6
  49. package/dist/components/timeline/timeline-utils.js +21 -114
  50. package/dist/data/entities.d.ts +23 -169
  51. package/dist/index.d.ts +11 -10
  52. package/dist/index.js +11 -10
  53. package/dist/stores/color-mode.d.ts +1 -1
  54. package/dist/stores/localization.d.ts +1 -1
  55. package/dist/stores/localization.js +3 -2
  56. package/dist/stores/paywall.d.ts +7 -3
  57. package/dist/stores/selected.d.ts +5 -0
  58. package/dist/stores/selected.js +12 -0
  59. package/dist/stores/variables.d.ts +2 -3
  60. package/dist/stores/variables.js +0 -1
  61. package/dist/stories/component-decorator.d.ts +2 -0
  62. package/dist/stories/component-decorator.js +12 -0
  63. package/dist/stories/fixtures.d.ts +6 -4
  64. package/dist/stories/fixtures.js +6241 -5485
  65. package/dist/stories/localization-decorator.js +1 -1
  66. package/dist/stories/paywall-decorator.js +8 -1
  67. package/dist/stories/variables-decorator.d.ts +1 -1
  68. package/dist/stories/viewport-decorator.d.ts +2 -0
  69. package/dist/stories/viewport-decorator.js +8 -0
  70. package/dist/stories/viewport-wrapper.svelte +53 -0
  71. package/dist/stories/viewport-wrapper.svelte.d.ts +10 -0
  72. package/dist/stories/with-layout.d.ts +2 -10
  73. package/dist/stories/with-layout.js +3 -5
  74. package/dist/stories/with-layout.svelte +3 -3
  75. package/dist/types/alignment.d.ts +5 -3
  76. package/dist/types/background.d.ts +6 -5
  77. package/dist/types/base.d.ts +7 -0
  78. package/dist/types/colors.d.ts +4 -4
  79. package/dist/types/component.d.ts +10 -0
  80. package/dist/types/component.js +1 -0
  81. package/dist/types/components/button.d.ts +5 -2
  82. package/dist/types/components/footer.d.ts +3 -2
  83. package/dist/types/components/icon.d.ts +28 -0
  84. package/dist/types/components/icon.js +1 -0
  85. package/dist/types/components/image.d.ts +20 -0
  86. package/dist/types/components/image.js +1 -0
  87. package/dist/types/components/package.d.ts +3 -2
  88. package/dist/types/components/purchase-button.d.ts +3 -2
  89. package/dist/types/components/stack.d.ts +32 -0
  90. package/dist/types/components/stack.js +1 -0
  91. package/dist/types/components/text.d.ts +20 -0
  92. package/dist/types/components/text.js +1 -0
  93. package/dist/types/components/timeline.d.ts +35 -0
  94. package/dist/types/components/timeline.js +1 -0
  95. package/dist/types/localization.d.ts +2 -1
  96. package/dist/types/media.d.ts +4 -3
  97. package/dist/types/overrides.d.ts +48 -0
  98. package/dist/types/overrides.js +1 -0
  99. package/dist/types/variables.d.ts +13 -0
  100. package/dist/types/variables.js +10 -0
  101. package/dist/types.d.ts +17 -9
  102. package/dist/ui/atoms/typography.stories.svelte +3 -29
  103. package/dist/ui/atoms/typography.stories.svelte.d.ts +1 -1
  104. package/dist/ui/layout/main-block.svelte +2 -2
  105. package/dist/ui/molecules/button.stories.svelte +5 -10
  106. package/dist/ui/molecules/button.svelte +1 -1
  107. package/dist/ui/theme/colors.d.ts +0 -6
  108. package/dist/ui/theme/colors.js +1 -1
  109. package/dist/ui/theme/text.d.ts +3 -4
  110. package/dist/ui/theme/theme.d.ts +2 -2
  111. package/dist/ui/theme/theme.js +2 -2
  112. package/dist/ui/theme/utils.d.ts +2 -12
  113. package/dist/ui/theme/utils.js +5 -5
  114. package/dist/utils/background-utils.d.ts +4 -0
  115. package/dist/utils/background-utils.js +39 -0
  116. package/dist/utils/base-utils.d.ts +18 -0
  117. package/dist/utils/base-utils.js +124 -0
  118. package/dist/utils/constants.d.ts +2 -2
  119. package/dist/utils/constants.js +6 -1
  120. package/dist/utils/font-utils.d.ts +4 -0
  121. package/dist/utils/font-utils.js +47 -0
  122. package/dist/utils/style-utils.d.ts +7 -120
  123. package/dist/utils/style-utils.js +35 -314
  124. package/dist/utils/variable-utils.d.ts +1 -22
  125. package/dist/utils/variable-utils.js +28 -24
  126. package/dist/web-components/index.css +1 -1
  127. package/dist/web-components/index.js +1415 -987
  128. package/package.json +34 -24
  129. package/dist/components/button/button-utils.d.ts +0 -2
  130. package/dist/components/button/button-utils.js +0 -19
  131. package/dist/components/image/image-utils.d.ts +0 -19
  132. package/dist/components/image/image-utils.js +0 -33
  133. package/dist/components/purchase-button/purchase-button-utils.d.ts +0 -2
  134. package/dist/components/purchase-button/purchase-button-utils.js +0 -20
  135. package/dist/data/state.d.ts +0 -4
  136. package/dist/stories/meta-templates.d.ts +0 -12
  137. package/dist/stories/meta-templates.js +0 -155
  138. /package/dist/{data/state.js → types/base.js} +0 -0
@@ -1,263 +1,83 @@
1
- import { getTextComponentStyles } from "../text/text-utils";
2
- import { getActiveStateProps, getComponentStyles, getDimensionStyle, getInsetStyles, getSizeStyle, prefixObject, stringifyStyles, } from "../../utils/style-utils";
3
- /**
4
- * Generates comprehensive styles for stack components by combining component, dimension and size styles
5
- * @param props - Stack component properties including background, spacing, size, border etc.
6
- * @returns CSS style variables object with all stack-specific styles
7
- */
8
- export const getStackComponentStyles = (colorMode, props) => {
9
- const { background_color, margin, padding, spacing, size, border, shape, shadow, dimension, componentState, overrides, zStackChildStyles, } = props;
10
- const stackStyles = {
11
- "--flex": "0 1 auto",
12
- "--height": "initial",
13
- "--width": "initial",
14
- "--spacing": `${spacing || 0}px`,
15
- "--direction": "unset",
16
- "--alignment": "unset",
17
- "--distribution": "flex-start",
18
- "--margin-block-start": "0px",
19
- "--margin-inline-end": "0px",
20
- "--margin-block-end": "0px",
21
- "--margin-inline-start": "0px",
22
- "--padding-block-start": "0px",
23
- "--padding-inline-end": "0px",
24
- "--padding-block-end": "0px",
25
- "--padding-inline-start": "0px",
26
- "--background": "unset",
27
- "--text-color": "inherit",
28
- "--border": "none",
29
- "--border-end-start-radius": "0px",
30
- "--border-end-end-radius": "0px",
31
- "--border-start-start-radius": "0px",
32
- "--border-start-end-radius": "0px",
33
- "--shadow": "none",
34
- "--position": "relative",
35
- "--transform": "initial",
36
- "--inset": "initial",
37
- };
38
- const activeStateProps = getActiveStateProps(overrides, componentState);
39
- Object.assign(stackStyles, getComponentStyles({
40
- background_color,
41
- margin,
42
- padding,
43
- border,
44
- colorMode,
45
- shape,
46
- shadow,
47
- ...activeStateProps,
48
- }), getDimensionStyle({
49
- ...dimension,
50
- ...activeStateProps,
51
- }), getSizeStyle({ ...size, ...activeStateProps }));
52
- Object.assign(stackStyles, zStackChildStyles);
53
- const prefixedStyles = prefixObject(stackStyles, "stack");
54
- return stringifyStyles(prefixedStyles);
55
- };
56
- /**
57
- * Generates styles for badge component within a stack
58
- * @param props - Stack component properties containing badge configuration
59
- * @returns CSS style object with badge-specific styles including positioning, dimensions and appearance
60
- */
61
- export function getBadgeStyles(colorMode, props) {
62
- const { badge } = props;
63
- if (!badge)
64
- return "";
65
- const styles = {
66
- "--inset": "unset",
67
- "--transform": "unset",
68
- "--margin-block-start": "0px",
69
- "--margin-inline-end": "0px",
70
- "--margin-block-end": "0px",
71
- "--margin-inline-start": "0px",
72
- "--padding-block-start": "0px",
73
- "--padding-inline-end": "0px",
74
- "--padding-block-end": "0px",
75
- "--padding-inline-start": "0px",
76
- "--background": "unset",
77
- "--text-color": "inherit",
78
- "--border": "none",
79
- "--border-end-start-radius": "0px",
80
- "--border-end-end-radius": "0px",
81
- "--border-start-start-radius": "0px",
82
- "--border-start-end-radius": "0px",
83
- "--shadow": "none",
84
- "--badge-width": "unset",
85
- "--z-index": "unset",
86
- };
87
- // Calculating this as a zIndex alignment since it behaves in the same way
88
- // except there's no center alignment
89
- Object.assign(styles, getInsetStyles({
90
- type: "zlayer",
91
- alignment: badge.alignment,
92
- }), getComponentStyles({
93
- ...badge,
94
- background_color: badge.background_color,
95
- color: badge.color,
96
- colorMode,
97
- }));
98
- if (badge.style === "overlay") {
99
- // Disable vertical margin for nested & center aligned badges
100
- styles["--margin-block-start"] = "0px";
101
- styles["--margin-block-end"] = "0px";
102
- // Vertically center the badge to the edge of the stack
103
- styles["--transform"] = getBadgeTransformStyles(badge, 0, -(props.border?.width || 0));
1
+ import { px } from "../../utils/base-utils";
2
+ const ALIGNMENT_MAP = Object.freeze({
3
+ leading: "flex-start",
4
+ top: "flex-start",
5
+ center: "center",
6
+ trailing: "flex-end",
7
+ bottom: "flex-end",
8
+ });
9
+ const DISTRIBUTION_MAP = Object.freeze({
10
+ space_between: "space-between",
11
+ space_around: "space-around",
12
+ space_evenly: "space-evenly",
13
+ start: "flex-start",
14
+ center: "center",
15
+ end: "flex-end",
16
+ });
17
+ export function mapDimension(dimension) {
18
+ if (dimension.type === "zlayer") {
19
+ return {};
104
20
  }
105
- if (badge.style === "edge_to_edge") {
106
- styles["--margin-block-start"] = "0px";
107
- styles["--margin-block-end"] = "0px";
108
- styles["--margin-inline-start"] = "0px";
109
- styles["--margin-inline-end"] = "0px";
110
- // Shared props between top and bottom
111
- if (badge.alignment === "top" || badge.alignment === "bottom") {
112
- styles["--badge-width"] =
113
- `calc(100% + ${(props.border?.width || 0) * 2}px)`;
114
- styles["--z-index"] = "-1";
115
- const highestRadius = Math.max(props.shape?.corners?.top_leading || 0, props.shape?.corners?.top_trailing || 0);
116
- // one offs for top and bottom
117
- if (badge.alignment === "top") {
118
- styles["--padding-block-end"] =
119
- `${highestRadius + badge.padding.bottom}px`;
120
- styles["--transform"] = getBadgeTransformStyles(badge, highestRadius);
121
- }
122
- if (badge.alignment === "bottom") {
123
- styles["--padding-block-start"] =
124
- `${highestRadius + badge.padding.top}px`;
125
- styles["--transform"] = getBadgeTransformStyles(badge, -highestRadius);
126
- }
127
- }
128
- else {
129
- styles["--transform"] = getBadgeTransformStyles(badge);
130
- Object.assign(styles, getBadgeBorderRadiusStyles(props));
131
- }
132
- }
133
- const prefixedStyles = prefixObject(styles, "stack-badge");
134
- return stringifyStyles(prefixedStyles);
135
- }
136
- const oppositeCornerDictionary = {
137
- top_leading: "bottom_trailing",
138
- top_trailing: "bottom_leading",
139
- bottom_leading: "top_trailing",
140
- bottom_trailing: "top_leading",
141
- };
142
- const propToCssPropDictionary = {
143
- top_leading: "--border-start-start-radius",
144
- top_trailing: "--border-start-end-radius",
145
- bottom_leading: "--border-end-start-radius",
146
- bottom_trailing: "--border-end-end-radius",
147
- };
148
- function getBadgeBorderRadiusStyles(props) {
149
- const styles = {
150
- "--border-end-start-radius": "0px",
151
- "--border-end-end-radius": "0px",
152
- "--border-start-start-radius": "0px",
153
- "--border-start-end-radius": "0px",
21
+ const direction = dimension.type === "vertical" ? "column" : "row";
22
+ const justify = DISTRIBUTION_MAP[dimension.distribution] || "center";
23
+ const align = ALIGNMENT_MAP[dimension.alignment] || "center";
24
+ return {
25
+ "flex-direction": direction,
26
+ "justify-content": justify,
27
+ "align-items": align,
154
28
  };
155
- const { badge } = props;
156
- if (!badge)
157
- return styles;
158
- const borderWidth = props.border?.width || 0;
159
- const badgeAlignment = badge.alignment;
160
- // badge inner radius
161
- styles[propToCssPropDictionary[oppositeCornerDictionary[badgeAlignment]]] =
162
- `${badge.shape?.corners[oppositeCornerDictionary[badgeAlignment]]}px`;
163
- // badge outer radius
164
- styles[propToCssPropDictionary[badgeAlignment]] =
165
- `${props.shape?.corners[badgeAlignment] - borderWidth}px`;
166
- return styles;
167
29
  }
168
- /**
169
- * Generates CSS transform styles for badge positioning
170
- * @param badge - Badge configuration from StackProps
171
- * @param verticalOffset - Optional vertical offset in pixels for edge-to-edge badges
172
- * @returns CSS transform string for badge positioning
173
- */
174
- function getBadgeTransformStyles(badge, verticalOffset = 0, horizontalOffset = 0) {
175
- if (!badge)
176
- return "";
177
- if (badge.style === "overlay") {
178
- if (badge.alignment === "top_leading") {
179
- return `translate(${horizontalOffset}px, calc(-50% + ${verticalOffset}px))`;
180
- }
181
- if (badge.alignment === "top_trailing") {
182
- return `translate(calc(0% - ${horizontalOffset}px), calc(-50% + ${verticalOffset}px))`;
183
- }
184
- if (badge.alignment === "bottom_leading") {
185
- return `translate(${horizontalOffset}px, calc(50% + ${verticalOffset}px))`;
186
- }
187
- if (badge.alignment === "bottom_trailing") {
188
- return `translate(calc(0% - ${horizontalOffset}px), calc(50% + ${verticalOffset}px))`;
189
- }
190
- if (badge.alignment === "top") {
191
- return `translate(calc(-50% + ${horizontalOffset}px), calc(-50% + ${verticalOffset}px))`;
192
- }
193
- if (badge.alignment === "bottom") {
194
- return `translate(calc(50% + ${horizontalOffset}px), calc(50% + ${verticalOffset}px))`;
195
- }
30
+ const Z_ALIGNMENT_MAP = Object.freeze({
31
+ top_leading: { justifyContent: "flex-start", alignItems: "flex-start" },
32
+ top: { justifyContent: "center", alignItems: "flex-start" },
33
+ top_trailing: { justifyContent: "flex-end", alignItems: "flex-start" },
34
+ leading: { justifyContent: "flex-start", alignItems: "center" },
35
+ center: { justifyContent: "center", alignItems: "center" },
36
+ trailing: { justifyContent: "flex-end", alignItems: "center" },
37
+ bottom_leading: { justifyContent: "flex-start", alignItems: "flex-end" },
38
+ bottom: { justifyContent: "center", alignItems: "flex-end" },
39
+ bottom_trailing: { justifyContent: "flex-end", alignItems: "flex-end" },
40
+ });
41
+ export function mapLayerAlignment(alignment) {
42
+ return Z_ALIGNMENT_MAP[alignment];
43
+ }
44
+ export function mapBadge(badge, parentBorderWidth) {
45
+ if (badge == null) {
46
+ return {};
196
47
  }
197
- if (badge.style === "edge_to_edge") {
198
- if (badge.alignment === "top") {
199
- return `translate(calc(-50% + ${horizontalOffset}px), calc(-100% - ${verticalOffset}px + 16px))`;
200
- }
201
- else if (badge.alignment === "bottom") {
202
- return `translate(calc(50% + ${horizontalOffset}px), calc(100% + ${verticalOffset}px))`;
203
- }
48
+ const { style, alignment } = badge;
49
+ const isTop = alignment.startsWith("top");
50
+ const isLeading = alignment.endsWith("leading");
51
+ const isTrailing = alignment.endsWith("trailing");
52
+ const isCenter = !isLeading && !isTrailing;
53
+ const offset = parentBorderWidth ?? 0;
54
+ if (style === "overlay") {
55
+ const translateX = isCenter ? "translateX(-50%)" : "";
56
+ const translateY = isTop ? "translateY(-50%)" : "translateY(50%)";
57
+ return {
58
+ "z-index": 10,
59
+ position: "absolute",
60
+ width: "max-content",
61
+ top: isTop ? px(-offset / 2) : "initial",
62
+ bottom: !isTop ? px(-offset / 2) : "initial",
63
+ left: isLeading ? px(-offset) : isCenter ? "50%" : "initial",
64
+ right: isTrailing ? px(-offset) : "initial",
65
+ transform: `${translateX} ${translateY}`,
66
+ };
204
67
  }
205
- return "";
206
- }
207
- /**
208
- * Generates text styles and HTML tag for a stack's badge component
209
- * @param props - Stack component properties containing badge configuration
210
- * @returns Object containing:
211
- * - tagToRender: HTML tag to use for the badge text
212
- * - textStyles: CSS styles string for the badge text
213
- */
214
- export function getStackBadgeTextStyles(colorMode, props) {
215
- const { badge } = props;
216
- if (!badge)
217
- return { tagToRender: "", textStyles: "" };
218
- const { tagToRender, textStyles } = getTextComponentStyles(colorMode, {
219
- id: props.id,
220
- purchaseState: props.purchaseState,
221
- ...badge,
222
- components: [],
223
- type: "text",
224
- size: {
225
- width: { type: "fit" },
226
- height: { type: "fit" },
227
- },
228
- color: badge?.color,
229
- name: props.name,
230
- });
231
- const resetSpacing = {
232
- "--text-margin-block-start": "0px",
233
- "--text-margin-inline-end": "0px",
234
- "--text-margin-block-end": "0px",
235
- "--text-margin-inline-start": "0px",
236
- "--text-padding-block-start": "0px",
237
- "--text-padding-inline-end": "0px",
238
- "--text-padding-block-end": "0px",
239
- "--text-padding-inline-start": "0px",
240
- };
241
- const stylesObject = {
242
- ...textStyles,
243
- ...resetSpacing,
244
- };
245
- const stringifiedStyles = stringifyStyles(stylesObject);
246
- return {
247
- tagToRender,
248
- textStyles: stringifiedStyles,
249
- };
250
- }
251
- export function getZStackChildStyles(props) {
252
- const { dimension } = props;
253
- const baseStyles = {
254
- "--inset": "initial",
255
- "--transform": "initial",
256
- "--position": "relative",
257
- };
258
- if (dimension.type !== "zlayer")
259
- return;
260
- const insetStyles = getInsetStyles({ ...dimension, type: "zlayer" });
261
- Object.assign(baseStyles, { ...insetStyles, "--position": "absolute" });
262
- return baseStyles;
68
+ if (style === "nested") {
69
+ return {
70
+ "z-index": 10,
71
+ position: "absolute",
72
+ inset: 0,
73
+ display: "flex",
74
+ top: isTop ? px(offset) : "initial",
75
+ bottom: !isTop ? px(offset) : "initial",
76
+ left: isLeading ? px(offset) : isCenter ? "50%" : "initial",
77
+ right: isTrailing ? px(offset) : "initial",
78
+ transform: isCenter ? "translateX(-50%)" : "initial",
79
+ };
80
+ }
81
+ // Not supported yet.
82
+ return {};
263
83
  }
@@ -3,47 +3,13 @@
3
3
 
4
4
  interface TextProps {
5
5
  component?: string;
6
- styleVariables?: string;
7
- id?: string;
6
+ style?: string;
8
7
  children?: Snippet;
9
8
  }
10
9
 
11
- const {
12
- children,
13
- styleVariables = "",
14
- component = "p",
15
- id,
16
- }: TextProps = $props();
10
+ const { children, style = "", component = "p" }: TextProps = $props();
17
11
  </script>
18
12
 
19
- <svelte:element
20
- this={component}
21
- {id}
22
- style={styleVariables}
23
- class="rc-pw-text-block"
24
- >
13
+ <svelte:element this={component} {style}>
25
14
  {@render children?.()}
26
15
  </svelte:element>
27
-
28
- <style>
29
- .rc-pw-text-block {
30
- display: block;
31
- padding-block-start: var(--text-padding-block-start, initial);
32
- padding-inline-end: var(--text-padding-inline-end, initial);
33
- padding-block-end: var(--text-padding-block-end, initial);
34
- padding-inline-start: var(--text-padding-inline-start, initial);
35
- margin-block-start: var(--text-margin-block-start, initial);
36
- margin-inline-end: var(--text-margin-inline-end, initial);
37
- margin-block-end: var(--text-margin-block-end, initial);
38
- margin-inline-start: var(--text-margin-inline-start, initial);
39
- color: var(--text-text-color, #ffffff);
40
- background: var(--text-background, none);
41
- font-size: var(--text-font-size, 1rem);
42
- font-weight: var(--text-font-weight, normal);
43
- text-align: var(--text-text-align, center);
44
- font-family: var(--text-font-family, sans-serif);
45
- -webkit-background-clip: var(--text-background-clip, initial);
46
- background-clip: var(--text-background-clip, initial);
47
- -webkit-text-fill-color: var(--text-text-fill-color, initial);
48
- }
49
- </style>
@@ -1,8 +1,7 @@
1
1
  import type { Snippet } from "svelte";
2
2
  interface TextProps {
3
3
  component?: string;
4
- styleVariables?: string;
5
- id?: string;
4
+ style?: string;
6
5
  children?: Snippet;
7
6
  }
8
7
  declare const Text: import("svelte").Component<TextProps, {}, "">;
@@ -1,18 +1,11 @@
1
1
  <script module lang="ts">
2
2
  import TextNode from "./TextNode.svelte";
3
3
  import { localizationDecorator } from "../../stories/localization-decorator";
4
- import {
5
- fontSizeStoryMeta,
6
- fontWeightStoryMeta,
7
- getColorStoryMeta,
8
- getSpacingStoryMeta,
9
- getTextControlStoryMeta,
10
- horizontalAlignmentStoryMeta,
11
- } from "../../stories/meta-templates";
12
4
  import { variablesDecorator } from "../../stories/variables-decorator";
13
5
  import type { Localizations } from "../../types/localization";
14
- import type { VariableDictionary } from "../../utils/variable-utils";
6
+ import type { VariableDictionary } from "../../types/variables";
15
7
  import { defineMeta } from "@storybook/addon-svelte-csf";
8
+ import { VARIABLES } from "../paywall/fixtures/variables";
16
9
 
17
10
  /*
18
11
  * Documentation for this component can be found in https://www.notion.so/revenuecat/Text-e257cb046e104351861f8364ede617be?pvs=4
@@ -24,7 +17,6 @@
24
17
  const { Story } = defineMeta({
25
18
  title: "Components/Text",
26
19
  component: TextNode,
27
- tags: ["autodocs"],
28
20
  decorators: [
29
21
  (Story, context) => {
30
22
  const localizations = context.parameters.localizations as Localizations;
@@ -40,25 +32,6 @@
40
32
  width: { type: "fill" },
41
33
  height: { type: "fill" },
42
34
  },
43
- purchaseState: {},
44
- },
45
- argTypes: {
46
- name: getTextControlStoryMeta("Content of the text to render"),
47
- font_name: getTextControlStoryMeta(
48
- "Font family to be used, uses GoogleFonts API",
49
- ),
50
- font_weight: fontWeightStoryMeta,
51
- font_size: fontSizeStoryMeta,
52
- color: getColorStoryMeta("Text color object"),
53
- background_color: getColorStoryMeta("Background color object"),
54
- horizontal_alignment: horizontalAlignmentStoryMeta,
55
- padding: getSpacingStoryMeta("Padding values in pixels"),
56
- margin: getSpacingStoryMeta("Margin values in pixels"),
57
- variableDictionary: {
58
- description: "Dictionary containing the values for the variables",
59
- control: { type: "object" },
60
- defaultValue: {},
61
- },
62
35
  },
63
36
  parameters: {
64
37
  localizations: {
@@ -71,43 +44,37 @@
71
44
  });
72
45
 
73
46
  const mockVariableDictionary = {
74
- product_name: "CatGPT",
75
- price: "$39.99",
76
- price_per_period: "$39.99/yr",
77
- } as VariableDictionary;
47
+ ...VARIABLES.$rc_weekly,
48
+ "product.store_product_name": "CatGPT",
49
+ "product.price": "$39.99",
50
+ "product.price_per_period": "$39.99/yr",
51
+ } satisfies VariableDictionary;
78
52
  </script>
79
53
 
80
- <!-- Default story -->
81
54
  <Story name="Default" args={{ name: "hello world!" }} />
82
55
 
83
- <!-- Font Weight text story -->
84
56
  <Story
85
57
  name="Font Weight"
86
58
  args={{
87
59
  font_weight: "bold",
88
- text_style: "normal",
89
60
  horizontal_alignment: "leading",
90
61
  name: "hello world!",
91
62
  }}
92
63
  />
93
64
 
94
- <!-- Text Alignment text story -->
95
65
  <Story
96
66
  name="Text Alignment"
97
67
  args={{
98
68
  font_weight: "regular",
99
- text_style: "normal",
100
69
  horizontal_alignment: "center",
101
70
  name: "hello world!",
102
71
  }}
103
72
  />
104
73
 
105
- <!-- Color text story -->
106
74
  <Story
107
75
  name="Color"
108
76
  args={{
109
77
  font_weight: "regular",
110
- text_style: "normal",
111
78
  horizontal_alignment: "leading",
112
79
  color: {
113
80
  dark: { type: "hex", value: "#3471eb" },
@@ -121,12 +88,10 @@
121
88
  }}
122
89
  />
123
90
 
124
- <!-- Text with spacing story -->
125
91
  <Story
126
92
  name="With Spacing"
127
93
  args={{
128
94
  font_weight: "regular",
129
- text_style: "normal",
130
95
  horizontal_alignment: "leading",
131
96
  padding: { top: 16, trailing: 24, bottom: 16, leading: 24 },
132
97
  margin: { top: 8, trailing: 0, bottom: 8, leading: 0 },
@@ -134,12 +99,10 @@
134
99
  }}
135
100
  />
136
101
 
137
- <!-- Text with variable dictionary story -->
138
102
  <Story
139
103
  name="With variable dictionary"
140
104
  args={{
141
105
  font_weight: "regular",
142
- text_style: "normal",
143
106
  horizontal_alignment: "leading",
144
107
  padding: { top: 16, trailing: 24, bottom: 16, leading: 24 },
145
108
  margin: { top: 8, trailing: 0, bottom: 8, leading: 0 },
@@ -151,17 +114,16 @@
151
114
  localizations: {
152
115
  [defaultLocale]: {
153
116
  [text_lid]:
154
- "This is a text that contains variables: {{ product_name }} for {{ price }} per {{ price_per_period }}",
117
+ "This is a text that contains variables: {{ product.product_name }} for {{ product.price }} per {{ product.price_per_period }}",
155
118
  },
156
119
  } satisfies Localizations,
157
120
  }}
158
121
  />
159
- <!-- Text with missing variable in dictionary story -->
122
+
160
123
  <Story
161
124
  name="With missing variable in dictionary"
162
125
  args={{
163
126
  font_weight: "regular",
164
- text_style: "normal",
165
127
  horizontal_alignment: "leading",
166
128
  padding: { top: 16, trailing: 24, bottom: 16, leading: 24 },
167
129
  margin: { top: 8, trailing: 0, bottom: 8, leading: 0 },
@@ -173,7 +135,7 @@
173
135
  localizations: {
174
136
  [defaultLocale]: {
175
137
  [text_lid]:
176
- "This is a text with variables: {{ product_name }} for {{ price }} per {{ price_per_period }} and a missing variable: {{ sub_period_abbreviated }}",
138
+ "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 }}",
177
139
  },
178
140
  } satisfies Localizations,
179
141
  }}
@@ -1,67 +1,55 @@
1
1
  <script lang="ts">
2
2
  import {
3
3
  getHtmlFromMarkdown,
4
- getTextNodeStyles,
5
- getTextWrapperStyles,
4
+ getTextComponentStyles,
5
+ getTextWrapperInlineStyles,
6
6
  } from "./text-utils";
7
7
  import Text from "./Text.svelte";
8
- import type { TextNodeProps } from "../../data/entities";
9
8
  import { getColorModeContext } from "../../stores/color-mode";
10
9
  import { getLocalizationContext } from "../../stores/localization";
10
+ import { getSelectedStateContext } from "../../stores/selected";
11
11
  import { getVariablesContext } from "../../stores/variables";
12
+ import type { TextNodeProps } from "../../types/components/text";
13
+ import { getActiveStateProps } from "../../utils/style-utils";
12
14
  import { replaceVariables } from "../../utils/variable-utils";
13
15
 
14
- const {
15
- id,
16
- labels,
17
- text_lid,
18
- purchaseState,
19
- background_color,
20
- size,
21
- ...restProps
22
- }: TextNodeProps = $props();
16
+ const props: TextNodeProps = $props();
17
+
18
+ const selectedState = getSelectedStateContext();
19
+ const actualProps = $derived.by(() => {
20
+ return {
21
+ ...props,
22
+ ...getActiveStateProps($selectedState, props.overrides),
23
+ };
24
+ });
23
25
 
24
26
  const getColorMode = getColorModeContext();
25
27
  const colorMode = $derived(getColorMode());
26
28
 
27
29
  const { tagToRender, textStyles } = $derived(
28
- getTextNodeStyles(colorMode, {
29
- id,
30
- labels,
31
- text_lid,
32
- purchaseState,
33
- background_color,
34
- size,
35
- ...restProps,
36
- }),
30
+ getTextComponentStyles(colorMode, actualProps),
37
31
  );
38
32
 
39
33
  const wrapperStyles = $derived(
40
- getTextWrapperStyles(restProps, size, background_color),
34
+ getTextWrapperInlineStyles(
35
+ colorMode,
36
+ actualProps,
37
+ actualProps.size,
38
+ actualProps.background_color,
39
+ ),
41
40
  );
42
41
 
43
42
  const variables = getVariablesContext();
44
43
  const { getLocalizedString } = getLocalizationContext();
45
44
  const label = $derived(
46
- replaceVariables(getLocalizedString(text_lid), $variables),
45
+ replaceVariables(getLocalizedString(actualProps.text_lid), $variables),
47
46
  );
47
+
48
48
  const markdownParsed = $derived(getHtmlFromMarkdown(label));
49
49
  </script>
50
50
 
51
- <span style={wrapperStyles} class="rc-pw-text-wrapper">
52
- <Text styleVariables={textStyles} component={tagToRender} {id}>
51
+ <span style={wrapperStyles}>
52
+ <Text style={textStyles} component={tagToRender}>
53
53
  {@html markdownParsed}
54
54
  </Text>
55
55
  </span>
56
-
57
- <style>
58
- .rc-pw-text-wrapper {
59
- display: block;
60
- height: var(--text-height, initial);
61
- width: var(--text-width, initial);
62
- background: var(--text-background, none);
63
- position: var(--text-position, relative);
64
- inset: var(--text-inset, 0);
65
- transform: var(--text-transform, initial);
66
- }
67
- </style>
@@ -1,4 +1,4 @@
1
- import type { TextNodeProps } from "../../data/entities";
1
+ import type { TextNodeProps } from "../../types/components/text";
2
2
  declare const TextNode: import("svelte").Component<TextNodeProps, {}, "">;
3
3
  type TextNode = ReturnType<typeof TextNode>;
4
4
  export default TextNode;