@revenuecat/purchases-ui-js 2.0.5 → 2.1.0

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 (39) hide show
  1. package/dist/components/button/ButtonNode.stories.svelte +20 -0
  2. package/dist/components/button/ButtonNode.svelte +12 -4
  3. package/dist/components/paywall/Node.svelte +4 -0
  4. package/dist/components/paywall/Paywall.svelte +11 -5
  5. package/dist/components/paywall/Paywall.svelte.d.ts +1 -0
  6. package/dist/components/stack/Stack.svelte +6 -3
  7. package/dist/components/stack/Stack.svelte.d.ts +2 -0
  8. package/dist/components/tabs/TabControlToggle.svelte +103 -0
  9. package/dist/components/tabs/TabControlToggle.svelte.d.ts +4 -0
  10. package/dist/components/tabs/Tabs.stories.svelte +439 -0
  11. package/dist/components/tabs/Tabs.svelte +12 -5
  12. package/dist/components/tabs/tabs-context.d.ts +1 -0
  13. package/dist/components/text/TextNode.stories.svelte +106 -0
  14. package/dist/components/text/TextNode.svelte +5 -3
  15. package/dist/components/text/text-utils.d.ts +5 -5
  16. package/dist/components/text/text-utils.js +34 -19
  17. package/dist/components/timeline/TimelineItem.svelte +4 -8
  18. package/dist/components/video/Video.stories.svelte +267 -0
  19. package/dist/components/video/Video.stories.svelte.d.ts +19 -0
  20. package/dist/components/video/Video.svelte +248 -0
  21. package/dist/components/video/Video.svelte.d.ts +4 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +1 -0
  24. package/dist/stores/paywall.d.ts +1 -1
  25. package/dist/stories/paywall-decorator.js +1 -1
  26. package/dist/types/base.d.ts +1 -0
  27. package/dist/types/component.d.ts +3 -2
  28. package/dist/types/components/button.d.ts +7 -1
  29. package/dist/types/components/tabs.d.ts +10 -0
  30. package/dist/types/components/text.d.ts +2 -2
  31. package/dist/types/components/video.d.ts +35 -0
  32. package/dist/types/components/video.js +1 -0
  33. package/dist/types/media.d.ts +17 -4
  34. package/dist/types/ui-config.d.ts +1 -1
  35. package/dist/utils/base-utils.d.ts +2 -1
  36. package/dist/utils/base-utils.js +1 -1
  37. package/dist/utils/style-utils.d.ts +0 -30
  38. package/dist/utils/style-utils.js +0 -66
  39. package/package.json +1 -1
@@ -927,3 +927,442 @@
927
927
  type: "tabs",
928
928
  }}
929
929
  />
930
+
931
+ <Story
932
+ name="Toggle"
933
+ decorators={[
934
+ componentDecorator(),
935
+ localizationDecorator({
936
+ defaultLocale,
937
+ localizations: {
938
+ [defaultLocale]: {
939
+ "9snr-lp9lS": "Show family plans",
940
+ izPmeYOm4j: "Show family plans",
941
+ },
942
+ },
943
+ }),
944
+ ]}
945
+ args={{
946
+ background: null,
947
+ control: {
948
+ stack: {
949
+ background: null,
950
+ background_color: null,
951
+ badge: null,
952
+ border: null,
953
+ components: [
954
+ {
955
+ default_value: true,
956
+ id: "gVAl7ORI44",
957
+ name: "",
958
+ thumb_color_off: {
959
+ light: {
960
+ type: "hex",
961
+ value: "#FFFFFF",
962
+ },
963
+ },
964
+ thumb_color_on: {
965
+ light: {
966
+ type: "hex",
967
+ value: "#FFFFFF",
968
+ },
969
+ },
970
+ track_color_off: {
971
+ light: {
972
+ type: "hex",
973
+ value: "#e1e1e5ff",
974
+ },
975
+ },
976
+ track_color_on: {
977
+ light: {
978
+ type: "hex",
979
+ value: "#576CDBff",
980
+ },
981
+ },
982
+ type: "tab_control_toggle",
983
+ },
984
+ ],
985
+ dimension: {
986
+ alignment: "leading",
987
+ distribution: "start",
988
+ type: "vertical",
989
+ },
990
+ id: "hIpAw5JTtG",
991
+ margin: {
992
+ bottom: 0,
993
+ leading: 0,
994
+ top: 0,
995
+ trailing: 0,
996
+ },
997
+ name: "",
998
+ padding: {
999
+ bottom: 0,
1000
+ leading: 0,
1001
+ top: 0,
1002
+ trailing: 0,
1003
+ },
1004
+ shadow: null,
1005
+ shape: {
1006
+ corners: {
1007
+ bottom_leading: 0,
1008
+ bottom_trailing: 0,
1009
+ top_leading: 0,
1010
+ top_trailing: 0,
1011
+ },
1012
+ type: "rectangle",
1013
+ },
1014
+ size: {
1015
+ height: {
1016
+ type: "fit",
1017
+ value: null,
1018
+ },
1019
+ width: {
1020
+ type: "fit",
1021
+ value: null,
1022
+ },
1023
+ },
1024
+ spacing: 0,
1025
+ type: "stack",
1026
+ },
1027
+ type: "toggle",
1028
+ },
1029
+ default_tab_id: "gi3qRZrSKa",
1030
+ id: "zRnUSrsOhj",
1031
+ margin: {
1032
+ bottom: 0,
1033
+ leading: 0,
1034
+ top: 0,
1035
+ trailing: 0,
1036
+ },
1037
+ name: "",
1038
+ padding: {
1039
+ bottom: 16,
1040
+ leading: 16,
1041
+ top: 16,
1042
+ trailing: 16,
1043
+ },
1044
+ shape: {
1045
+ corners: {
1046
+ bottom_leading: 0,
1047
+ bottom_trailing: 0,
1048
+ top_leading: 0,
1049
+ top_trailing: 0,
1050
+ },
1051
+ type: "rectangle",
1052
+ },
1053
+ size: {
1054
+ height: {
1055
+ type: "fit",
1056
+ value: null,
1057
+ },
1058
+ width: {
1059
+ type: "fill",
1060
+ value: null,
1061
+ },
1062
+ },
1063
+ tabs: [
1064
+ {
1065
+ id: "MEOs13s6G8",
1066
+ name: "OFF",
1067
+ stack: {
1068
+ background: null,
1069
+ background_color: null,
1070
+ badge: null,
1071
+ border: null,
1072
+ components: [
1073
+ {
1074
+ background: {
1075
+ type: "color",
1076
+ value: {
1077
+ light: {
1078
+ type: "hex",
1079
+ value: "#f7f7faff",
1080
+ },
1081
+ },
1082
+ },
1083
+ background_color: null,
1084
+ badge: null,
1085
+ border: null,
1086
+ components: [
1087
+ {
1088
+ background_color: null,
1089
+ color: {
1090
+ light: {
1091
+ type: "hex",
1092
+ value: "#000000e6",
1093
+ },
1094
+ },
1095
+ font_name: null,
1096
+ font_size: 14,
1097
+ font_weight: "regular",
1098
+ font_weight_int: 400,
1099
+ horizontal_alignment: "leading",
1100
+ id: "By5e8IBSbf",
1101
+ margin: {
1102
+ bottom: 0,
1103
+ leading: 0,
1104
+ top: 0,
1105
+ trailing: 0,
1106
+ },
1107
+ name: "",
1108
+ padding: {
1109
+ bottom: 0,
1110
+ leading: 0,
1111
+ top: 0,
1112
+ trailing: 0,
1113
+ },
1114
+ size: {
1115
+ height: {
1116
+ type: "fit",
1117
+ value: null,
1118
+ },
1119
+ width: {
1120
+ type: "fit",
1121
+ value: null,
1122
+ },
1123
+ },
1124
+ text_lid: "9snr-lp9lS",
1125
+ type: "text",
1126
+ },
1127
+ {
1128
+ id: "ZRerJx5wLi",
1129
+ name: "",
1130
+ type: "tab_control",
1131
+ },
1132
+ ],
1133
+ dimension: {
1134
+ alignment: "center",
1135
+ distribution: "space_between",
1136
+ type: "horizontal",
1137
+ },
1138
+ id: "ATrU9MBBJx",
1139
+ margin: {
1140
+ bottom: 0,
1141
+ leading: 16,
1142
+ top: 0,
1143
+ trailing: 16,
1144
+ },
1145
+ name: "Switch stack",
1146
+ padding: {
1147
+ bottom: 8,
1148
+ leading: 24,
1149
+ top: 8,
1150
+ trailing: 8,
1151
+ },
1152
+ shadow: null,
1153
+ shape: {
1154
+ corners: null,
1155
+ type: "pill",
1156
+ },
1157
+ size: {
1158
+ height: {
1159
+ type: "fit",
1160
+ value: null,
1161
+ },
1162
+ width: {
1163
+ type: "fit",
1164
+ value: null,
1165
+ },
1166
+ },
1167
+ spacing: 24,
1168
+ type: "stack",
1169
+ },
1170
+ ],
1171
+ dimension: {
1172
+ alignment: "center",
1173
+ distribution: "center",
1174
+ type: "vertical",
1175
+ },
1176
+ id: "tj1QOsrpFb",
1177
+ margin: {
1178
+ bottom: 0,
1179
+ leading: 0,
1180
+ top: 0,
1181
+ trailing: 0,
1182
+ },
1183
+ name: "Tab",
1184
+ padding: {
1185
+ bottom: 0,
1186
+ leading: 0,
1187
+ top: 0,
1188
+ trailing: 0,
1189
+ },
1190
+ shadow: null,
1191
+ shape: {
1192
+ corners: {
1193
+ bottom_leading: 0,
1194
+ bottom_trailing: 0,
1195
+ top_leading: 0,
1196
+ top_trailing: 0,
1197
+ },
1198
+ type: "rectangle",
1199
+ },
1200
+ size: {
1201
+ height: {
1202
+ type: "fit",
1203
+ value: null,
1204
+ },
1205
+ width: {
1206
+ type: "fill",
1207
+ value: null,
1208
+ },
1209
+ },
1210
+ spacing: 16,
1211
+ type: "stack",
1212
+ },
1213
+ type: "tab",
1214
+ },
1215
+ {
1216
+ id: "gi3qRZrSKa",
1217
+ name: "ON",
1218
+ stack: {
1219
+ background: null,
1220
+ background_color: null,
1221
+ border: null,
1222
+ components: [
1223
+ {
1224
+ background: {
1225
+ type: "color",
1226
+ value: {
1227
+ light: {
1228
+ type: "hex",
1229
+ value: "#f7f7faff",
1230
+ },
1231
+ },
1232
+ },
1233
+ background_color: null,
1234
+ badge: null,
1235
+ border: null,
1236
+ components: [
1237
+ {
1238
+ background_color: null,
1239
+ color: {
1240
+ light: {
1241
+ type: "hex",
1242
+ value: "#000000e6",
1243
+ },
1244
+ },
1245
+ font_name: null,
1246
+ font_size: 14,
1247
+ font_weight: "regular",
1248
+ font_weight_int: 400,
1249
+ horizontal_alignment: "leading",
1250
+ id: "xs9GkrXsl9",
1251
+ margin: {
1252
+ bottom: 0,
1253
+ leading: 0,
1254
+ top: 0,
1255
+ trailing: 0,
1256
+ },
1257
+ name: "",
1258
+ padding: {
1259
+ bottom: 0,
1260
+ leading: 0,
1261
+ top: 0,
1262
+ trailing: 0,
1263
+ },
1264
+ size: {
1265
+ height: {
1266
+ type: "fit",
1267
+ value: null,
1268
+ },
1269
+ width: {
1270
+ type: "fit",
1271
+ value: null,
1272
+ },
1273
+ },
1274
+ text_lid: "izPmeYOm4j",
1275
+ type: "text",
1276
+ },
1277
+ {
1278
+ id: "XMUc_WOeWO",
1279
+ name: "",
1280
+ type: "tab_control",
1281
+ },
1282
+ ],
1283
+ dimension: {
1284
+ alignment: "center",
1285
+ distribution: "space_between",
1286
+ type: "horizontal",
1287
+ },
1288
+ id: "PNnFNzZU4M",
1289
+ margin: {
1290
+ bottom: 0,
1291
+ leading: 16,
1292
+ top: 0,
1293
+ trailing: 16,
1294
+ },
1295
+ name: "Switch stack",
1296
+ padding: {
1297
+ bottom: 8,
1298
+ leading: 24,
1299
+ top: 8,
1300
+ trailing: 8,
1301
+ },
1302
+ shadow: null,
1303
+ shape: {
1304
+ corners: null,
1305
+ type: "pill",
1306
+ },
1307
+ size: {
1308
+ height: {
1309
+ type: "fit",
1310
+ value: null,
1311
+ },
1312
+ width: {
1313
+ type: "fit",
1314
+ value: null,
1315
+ },
1316
+ },
1317
+ spacing: 24,
1318
+ type: "stack",
1319
+ },
1320
+ ],
1321
+ dimension: {
1322
+ alignment: "center",
1323
+ distribution: "center",
1324
+ type: "vertical",
1325
+ },
1326
+ id: "Q6oIOhxGOB",
1327
+ margin: {
1328
+ bottom: 0,
1329
+ leading: 0,
1330
+ top: 0,
1331
+ trailing: 0,
1332
+ },
1333
+ name: "Tab",
1334
+ padding: {
1335
+ bottom: 0,
1336
+ leading: 0,
1337
+ top: 0,
1338
+ trailing: 0,
1339
+ },
1340
+ shadow: null,
1341
+ shape: {
1342
+ corners: {
1343
+ bottom_leading: 0,
1344
+ bottom_trailing: 0,
1345
+ top_leading: 0,
1346
+ top_trailing: 0,
1347
+ },
1348
+ type: "rectangle",
1349
+ },
1350
+ size: {
1351
+ height: {
1352
+ type: "fit",
1353
+ value: null,
1354
+ },
1355
+ width: {
1356
+ type: "fill",
1357
+ value: null,
1358
+ },
1359
+ },
1360
+ spacing: 16,
1361
+ type: "stack",
1362
+ },
1363
+ type: "tab",
1364
+ },
1365
+ ],
1366
+ type: "tabs",
1367
+ }}
1368
+ />
@@ -44,14 +44,20 @@
44
44
  }),
45
45
  );
46
46
 
47
- const tab = writable(
48
- tabs.find((tab) => tab.id === default_tab_id) ?? tabs.at(0),
47
+ const selectedTabIndex = writable(
48
+ Math.max(
49
+ 0,
50
+ tabs.findIndex((tab) => tab.id === default_tab_id),
51
+ ),
49
52
  );
50
53
 
54
+ const tab = derived(selectedTabIndex, (value) => tabs[value]);
55
+
51
56
  const selectTab: SelectTab = (tabId, tabIndex) => {
52
- const nextTab = tabs.find((tab) => tab.id === tabId) ?? tabs.at(tabIndex);
53
- if (nextTab !== undefined) {
54
- tab.set(nextTab);
57
+ const foundIndex = tabs.findIndex((tab) => tab.id === tabId);
58
+ const nextIndex = foundIndex !== -1 ? foundIndex : tabIndex;
59
+ if (nextIndex >= 0 && nextIndex < tabs.length) {
60
+ selectedTabIndex.set(tabIndex);
55
61
  }
56
62
  };
57
63
 
@@ -59,6 +65,7 @@
59
65
  control: readable(control),
60
66
  selectedTabId: derived(tab, (tab) => tab.id),
61
67
  selectTab,
68
+ isActive: derived(selectedTabIndex, (value) => value === 1),
62
69
  });
63
70
  </script>
64
71
 
@@ -5,6 +5,7 @@ interface TabsContext {
5
5
  control: Readable<TabControl>;
6
6
  selectedTabId: Readable<TabProps["id"]>;
7
7
  selectTab: SelectTab;
8
+ isActive: Readable<boolean>;
8
9
  }
9
10
  export declare function setTabsContext(context: TabsContext): void;
10
11
  export declare function getTabsContext(): TabsContext;
@@ -6,6 +6,7 @@
6
6
  import type { VariableDictionary } from "../../types/variables";
7
7
  import { defineMeta } from "@storybook/addon-svelte-csf";
8
8
  import { VARIABLES } from "../paywall/fixtures/variables";
9
+ import { DEFAULT_SPACING } from "../../utils/constants";
9
10
 
10
11
  /*
11
12
  * Documentation for this component can be found in https://www.notion.so/revenuecat/Text-e257cb046e104351861f8364ede617be?pvs=4
@@ -32,6 +33,8 @@
32
33
  width: { type: "fill" },
33
34
  height: { type: "fill" },
34
35
  },
36
+ padding: DEFAULT_SPACING,
37
+ margin: DEFAULT_SPACING,
35
38
  },
36
39
  parameters: {
37
40
  localizations: {
@@ -88,6 +91,109 @@
88
91
  }}
89
92
  />
90
93
 
94
+ <Story
95
+ name="Linear gradeint"
96
+ decorators={[
97
+ localizationDecorator({
98
+ defaultLocale,
99
+ localizations: { [defaultLocale]: { [text_lid]: "Linear gradient" } },
100
+ }),
101
+ ]}
102
+ args={{
103
+ color: {
104
+ light: {
105
+ degrees: 90,
106
+ points: [
107
+ {
108
+ color: "#e81c0fFF",
109
+ percent: 0,
110
+ },
111
+ {
112
+ color: "#0029ffff",
113
+ percent: 100,
114
+ },
115
+ ],
116
+ type: "linear",
117
+ },
118
+ },
119
+ background_color: {
120
+ light: {
121
+ degrees: 90,
122
+ points: [
123
+ {
124
+ color: "#ffffffff",
125
+ percent: 0,
126
+ },
127
+ {
128
+ color: "#000000ff",
129
+ percent: 100,
130
+ },
131
+ ],
132
+ type: "linear",
133
+ },
134
+ },
135
+ font_size: 48,
136
+ font_weight: "regular",
137
+ font_weight_int: 400,
138
+ horizontal_alignment: "leading",
139
+ size: {
140
+ width: { type: "fit" },
141
+ height: { type: "fit" },
142
+ },
143
+ }}
144
+ />
145
+
146
+ <Story
147
+ name="Radial gradient"
148
+ decorators={[
149
+ localizationDecorator({
150
+ defaultLocale,
151
+ localizations: { [defaultLocale]: { [text_lid]: "Radial gradient" } },
152
+ }),
153
+ ]}
154
+ args={{
155
+ color: {
156
+ light: {
157
+ points: [
158
+ {
159
+ color: "#3bf60cff",
160
+ percent: 23,
161
+ },
162
+ {
163
+ color: "#e40fe8ff",
164
+ percent: 100,
165
+ },
166
+ ],
167
+ type: "radial",
168
+ },
169
+ },
170
+ background_color: {
171
+ light: {
172
+ degrees: 90,
173
+ points: [
174
+ {
175
+ color: "#ffffffff",
176
+ percent: 0,
177
+ },
178
+ {
179
+ color: "#000000ff",
180
+ percent: 100,
181
+ },
182
+ ],
183
+ type: "linear",
184
+ },
185
+ },
186
+ font_size: 48,
187
+ font_weight: "regular",
188
+ font_weight_int: 400,
189
+ horizontal_alignment: "leading",
190
+ size: {
191
+ width: { type: "fit" },
192
+ height: { type: "fit" },
193
+ },
194
+ }}
195
+ />
196
+
91
197
  <Story
92
198
  name="With Spacing"
93
199
  args={{
@@ -7,6 +7,7 @@
7
7
  import Text from "./Text.svelte";
8
8
  import { getColorModeContext } from "../../stores/color-mode";
9
9
  import { getLocalizationContext } from "../../stores/localization";
10
+ import { getPaywallContext } from "../../stores/paywall";
10
11
  import { getSelectedStateContext } from "../../stores/selected";
11
12
  import { getVariablesContext } from "../../stores/variables";
12
13
  import type { TextNodeProps } from "../../types/components/text";
@@ -26,8 +27,9 @@
26
27
  const getColorMode = getColorModeContext();
27
28
  const colorMode = $derived(getColorMode());
28
29
 
29
- const { tagToRender, textStyles } = $derived(
30
- getTextComponentStyles(colorMode, actualProps),
30
+ const { uiConfig } = getPaywallContext();
31
+ let textStyles = $derived(
32
+ getTextComponentStyles(colorMode, actualProps, uiConfig.app.fonts),
31
33
  );
32
34
 
33
35
  const wrapperStyles = $derived(
@@ -49,7 +51,7 @@
49
51
  </script>
50
52
 
51
53
  <span style={wrapperStyles}>
52
- <Text style={textStyles} component={tagToRender}>
54
+ <Text style={textStyles} component="span">
53
55
  {@html markdownParsed}
54
56
  </Text>
55
57
  </span>
@@ -1,15 +1,15 @@
1
- import type { ColorMode, SizeType } from "../../types";
1
+ import { type ColorMode, type SizeType } from "../../types";
2
2
  import type { ColorGradientScheme, ColorScheme } from "../../types/colors";
3
3
  import type { TextNodeProps } from "../../types/components/text";
4
+ import type { AppFontsConfig } from "../../types/ui-config";
5
+ import { type CSS } from "../../utils/base-utils";
4
6
  export declare const defaultColor: ColorScheme;
7
+ export declare function mapTextColor(colorMode: ColorMode, scheme: ColorGradientScheme): CSS;
5
8
  /**
6
9
  * Generates comprehensive styles for text components by combining text, component and size styles
7
10
  * @param props - Text component properties including font, color, background, spacing etc.
8
11
  * @returns Object containing text inline styles and the appropriate HTML tag to render
9
12
  */
10
- export declare const getTextComponentStyles: (colorMode: ColorMode, props: TextNodeProps) => {
11
- textStyles: string;
12
- tagToRender: string;
13
- };
13
+ export declare const getTextComponentStyles: (colorMode: ColorMode, props: TextNodeProps, fonts: AppFontsConfig) => string;
14
14
  export declare function getTextWrapperInlineStyles(colorMode: ColorMode, _restProps: Partial<TextNodeProps>, size: SizeType, background_color?: ColorGradientScheme | null): string;
15
15
  export declare function getHtmlFromMarkdown(text?: string): string;