@revenuecat/purchases-ui-js 2.1.1 → 2.2.1

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 (26) hide show
  1. package/dist/components/options/InputMultipleChoice.stories.svelte +207 -0
  2. package/dist/components/options/InputMultipleChoice.stories.svelte.d.ts +19 -0
  3. package/dist/components/options/InputMultipleChoice.svelte +9 -0
  4. package/dist/components/options/InputMultipleChoice.svelte.d.ts +4 -0
  5. package/dist/components/options/InputOption.stories.svelte +251 -0
  6. package/dist/components/options/InputOption.stories.svelte.d.ts +19 -0
  7. package/dist/components/options/InputOption.svelte +18 -0
  8. package/dist/components/options/InputOption.svelte.d.ts +4 -0
  9. package/dist/components/options/InputSingleChoice.stories.svelte +207 -0
  10. package/dist/components/options/InputSingleChoice.stories.svelte.d.ts +19 -0
  11. package/dist/components/options/InputSingleChoice.svelte +9 -0
  12. package/dist/components/options/InputSingleChoice.svelte.d.ts +4 -0
  13. package/dist/components/paywall/Node.svelte +6 -0
  14. package/dist/components/paywall/Paywall.stories.svelte +15 -0
  15. package/dist/components/paywall/Paywall.svelte +9 -0
  16. package/dist/components/paywall/Paywall.svelte.d.ts +4 -0
  17. package/dist/components/purchase-button/PurchaseButton.svelte +11 -2
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.js +3 -0
  20. package/dist/stores/paywall.d.ts +4 -0
  21. package/dist/stories/paywall-decorator.d.ts +4 -1
  22. package/dist/stories/paywall-decorator.js +2 -1
  23. package/dist/types/component.d.ts +2 -1
  24. package/dist/types/components/options.d.ts +17 -0
  25. package/dist/types/components/options.js +1 -0
  26. package/package.json +1 -1
@@ -0,0 +1,207 @@
1
+ <script module lang="ts">
2
+ import InputMultipleChoice from "./InputMultipleChoice.svelte";
3
+ import { componentDecorator } from "../../stories/component-decorator";
4
+ import { localizationDecorator } from "../../stories/localization-decorator";
5
+ import type { InputMultipleChoiceProps } from "../../types/components/options";
6
+ import { defineMeta } from "@storybook/addon-svelte-csf";
7
+
8
+ const defaultLocale = "en_US";
9
+
10
+ const { Story } = defineMeta({
11
+ title: "Components/Options/InputMultipleChoice",
12
+ component: InputMultipleChoice,
13
+ decorators: [
14
+ componentDecorator(),
15
+ localizationDecorator({
16
+ defaultLocale,
17
+ localizations: {
18
+ [defaultLocale]: {
19
+ checkbox1: "Email notifications",
20
+ checkbox2: "SMS notifications",
21
+ checkbox3: "Push notifications",
22
+ },
23
+ },
24
+ }),
25
+ ],
26
+ args: {
27
+ type: "input_multiple_choice",
28
+ id: "multiple-choice-1",
29
+ name: "Multiple Choice Input",
30
+ field_id: "user_preferences",
31
+ stack: {
32
+ type: "stack",
33
+ id: "stack-1",
34
+ name: "Choice Stack",
35
+ components: [
36
+ {
37
+ type: "text",
38
+ id: "text-1",
39
+ name: "Choice Label",
40
+ text_lid: "checkbox1",
41
+ color: {
42
+ light: { type: "hex", value: "#000000" },
43
+ dark: { type: "hex", value: "#FFFFFF" },
44
+ },
45
+ font_size: "body_m",
46
+ font_weight: "regular",
47
+ horizontal_alignment: "leading",
48
+ size: {
49
+ width: { type: "fit" },
50
+ height: { type: "fit" },
51
+ },
52
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
53
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
54
+ background_color: null,
55
+ },
56
+ ],
57
+ dimension: {
58
+ type: "vertical",
59
+ alignment: "leading",
60
+ distribution: "start",
61
+ },
62
+ size: {
63
+ width: { type: "fill" },
64
+ height: { type: "fit" },
65
+ },
66
+ spacing: 8,
67
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
68
+ padding: { top: 16, trailing: 16, bottom: 16, leading: 16 },
69
+ background_color: {
70
+ light: { type: "hex", value: "#F5F5F5" },
71
+ dark: { type: "hex", value: "#2A2A2A" },
72
+ },
73
+ background: null,
74
+ border: {
75
+ width: 1,
76
+ color: {
77
+ light: { type: "hex", value: "#E0E0E0" },
78
+ dark: { type: "hex", value: "#404040" },
79
+ },
80
+ },
81
+ shape: {
82
+ type: "rectangle",
83
+ corners: {
84
+ top_leading: 8,
85
+ top_trailing: 8,
86
+ bottom_leading: 8,
87
+ bottom_trailing: 8,
88
+ },
89
+ },
90
+ shadow: null,
91
+ badge: null,
92
+ },
93
+ } satisfies InputMultipleChoiceProps,
94
+ });
95
+ </script>
96
+
97
+ <Story name="Default" />
98
+
99
+ <Story
100
+ name="With Multiple Checkboxes"
101
+ args={{
102
+ stack: {
103
+ type: "stack",
104
+ id: "stack-2",
105
+ name: "Multi Checkbox Stack",
106
+ components: [
107
+ {
108
+ type: "text",
109
+ id: "text-1",
110
+ name: "Checkbox 1",
111
+ text_lid: "checkbox1",
112
+ color: {
113
+ light: { type: "hex", value: "#000000" },
114
+ },
115
+ font_size: "body_m",
116
+ font_weight: "regular",
117
+ horizontal_alignment: "leading",
118
+ size: {
119
+ width: { type: "fill" },
120
+ height: { type: "fit" },
121
+ },
122
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
123
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
124
+ background_color: null,
125
+ },
126
+ {
127
+ type: "text",
128
+ id: "text-2",
129
+ name: "Checkbox 2",
130
+ text_lid: "checkbox2",
131
+ color: {
132
+ light: { type: "hex", value: "#000000" },
133
+ },
134
+ font_size: "body_m",
135
+ font_weight: "regular",
136
+ horizontal_alignment: "leading",
137
+ size: {
138
+ width: { type: "fill" },
139
+ height: { type: "fit" },
140
+ },
141
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
142
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
143
+ background_color: null,
144
+ },
145
+ {
146
+ type: "text",
147
+ id: "text-3",
148
+ name: "Checkbox 3",
149
+ text_lid: "checkbox3",
150
+ color: {
151
+ light: { type: "hex", value: "#000000" },
152
+ },
153
+ font_size: "body_m",
154
+ font_weight: "regular",
155
+ horizontal_alignment: "leading",
156
+ size: {
157
+ width: { type: "fill" },
158
+ height: { type: "fit" },
159
+ },
160
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
161
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
162
+ background_color: null,
163
+ },
164
+ ],
165
+ dimension: {
166
+ type: "vertical",
167
+ alignment: "leading",
168
+ distribution: "start",
169
+ },
170
+ size: {
171
+ width: { type: "fill" },
172
+ height: { type: "fit" },
173
+ },
174
+ spacing: 8,
175
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
176
+ padding: { top: 16, trailing: 16, bottom: 16, leading: 16 },
177
+ background_color: {
178
+ light: { type: "hex", value: "#FFFFFF" },
179
+ },
180
+ background: null,
181
+ border: {
182
+ width: 1,
183
+ color: {
184
+ light: { type: "hex", value: "#DDDDDD" },
185
+ },
186
+ },
187
+ shape: {
188
+ type: "rectangle",
189
+ corners: {
190
+ top_leading: 12,
191
+ top_trailing: 12,
192
+ bottom_leading: 12,
193
+ bottom_trailing: 12,
194
+ },
195
+ },
196
+ shadow: {
197
+ x: 0,
198
+ y: 2,
199
+ radius: 4,
200
+ color: {
201
+ light: { type: "hex", value: "#00000020" },
202
+ },
203
+ },
204
+ badge: null,
205
+ },
206
+ }}
207
+ />
@@ -0,0 +1,19 @@
1
+ import InputMultipleChoice from "./InputMultipleChoice.svelte";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const InputMultipleChoice: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type InputMultipleChoice = InstanceType<typeof InputMultipleChoice>;
19
+ export default InputMultipleChoice;
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ import Node from "../paywall/Node.svelte";
3
+ import type { InputMultipleChoiceProps } from "../../types/components/options";
4
+
5
+ const props: InputMultipleChoiceProps = $props();
6
+ const { stack } = props;
7
+ </script>
8
+
9
+ <Node nodeData={stack} />
@@ -0,0 +1,4 @@
1
+ import type { InputMultipleChoiceProps } from "../../types/components/options";
2
+ declare const InputMultipleChoice: import("svelte").Component<InputMultipleChoiceProps, {}, "">;
3
+ type InputMultipleChoice = ReturnType<typeof InputMultipleChoice>;
4
+ export default InputMultipleChoice;
@@ -0,0 +1,251 @@
1
+ <script module lang="ts">
2
+ import InputOption from "./InputOption.svelte";
3
+ import { componentDecorator } from "../../stories/component-decorator";
4
+ import { localizationDecorator } from "../../stories/localization-decorator";
5
+ import type { InputOptionProps } from "../../types/components/options";
6
+ import { defineMeta } from "@storybook/addon-svelte-csf";
7
+
8
+ const defaultLocale = "en_US";
9
+
10
+ const { Story } = defineMeta({
11
+ title: "Components/Options/InputOption",
12
+ component: InputOption,
13
+ decorators: [
14
+ componentDecorator(),
15
+ localizationDecorator({
16
+ defaultLocale,
17
+ localizations: {
18
+ [defaultLocale]: {
19
+ option_text: "Premium Plan",
20
+ option_description: "Unlock all features",
21
+ },
22
+ },
23
+ }),
24
+ ],
25
+ args: {
26
+ type: "input_option",
27
+ id: "option-1",
28
+ name: "Input Option",
29
+ option_id: "option_premium",
30
+ stack: {
31
+ type: "stack",
32
+ id: "stack-1",
33
+ name: "Option Stack",
34
+ components: [
35
+ {
36
+ type: "text",
37
+ id: "text-1",
38
+ name: "Option Text",
39
+ text_lid: "option_text",
40
+ color: {
41
+ light: { type: "hex", value: "#000000" },
42
+ dark: { type: "hex", value: "#FFFFFF" },
43
+ },
44
+ font_size: "body_l",
45
+ font_weight: "semibold",
46
+ horizontal_alignment: "leading",
47
+ size: {
48
+ width: { type: "fit" },
49
+ height: { type: "fit" },
50
+ },
51
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
52
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
53
+ background_color: null,
54
+ },
55
+ ],
56
+ dimension: {
57
+ type: "vertical",
58
+ alignment: "leading",
59
+ distribution: "start",
60
+ },
61
+ size: {
62
+ width: { type: "fill" },
63
+ height: { type: "fit" },
64
+ },
65
+ spacing: 4,
66
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
67
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
68
+ background_color: {
69
+ light: { type: "hex", value: "#F9F9F9" },
70
+ dark: { type: "hex", value: "#2A2A2A" },
71
+ },
72
+ background: null,
73
+ border: {
74
+ width: 2,
75
+ color: {
76
+ light: { type: "hex", value: "#4A90E2" },
77
+ dark: { type: "hex", value: "#4A90E2" },
78
+ },
79
+ },
80
+ shape: {
81
+ type: "rectangle",
82
+ corners: {
83
+ top_leading: 8,
84
+ top_trailing: 8,
85
+ bottom_leading: 8,
86
+ bottom_trailing: 8,
87
+ },
88
+ },
89
+ shadow: null,
90
+ badge: null,
91
+ },
92
+ } satisfies InputOptionProps,
93
+ });
94
+ </script>
95
+
96
+ <Story name="Default" />
97
+
98
+ <Story
99
+ name="With Description"
100
+ args={{
101
+ stack: {
102
+ type: "stack",
103
+ id: "stack-2",
104
+ name: "Option Stack with Description",
105
+ components: [
106
+ {
107
+ type: "text",
108
+ id: "text-1",
109
+ name: "Option Title",
110
+ text_lid: "option_text",
111
+ color: {
112
+ light: { type: "hex", value: "#000000" },
113
+ },
114
+ font_size: "body_l",
115
+ font_weight: "bold",
116
+ horizontal_alignment: "leading",
117
+ size: {
118
+ width: { type: "fill" },
119
+ height: { type: "fit" },
120
+ },
121
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
122
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
123
+ background_color: null,
124
+ },
125
+ {
126
+ type: "text",
127
+ id: "text-2",
128
+ name: "Option Description",
129
+ text_lid: "option_description",
130
+ color: {
131
+ light: { type: "hex", value: "#666666" },
132
+ },
133
+ font_size: "body_s",
134
+ font_weight: "regular",
135
+ horizontal_alignment: "leading",
136
+ size: {
137
+ width: { type: "fill" },
138
+ height: { type: "fit" },
139
+ },
140
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
141
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
142
+ background_color: null,
143
+ },
144
+ ],
145
+ dimension: {
146
+ type: "vertical",
147
+ alignment: "leading",
148
+ distribution: "start",
149
+ },
150
+ size: {
151
+ width: { type: "fill" },
152
+ height: { type: "fit" },
153
+ },
154
+ spacing: 8,
155
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
156
+ padding: { top: 16, trailing: 16, bottom: 16, leading: 16 },
157
+ background_color: {
158
+ light: { type: "hex", value: "#FFFFFF" },
159
+ },
160
+ background: null,
161
+ border: {
162
+ width: 2,
163
+ color: {
164
+ light: { type: "hex", value: "#4A90E2" },
165
+ },
166
+ },
167
+ shape: {
168
+ type: "rectangle",
169
+ corners: {
170
+ top_leading: 12,
171
+ top_trailing: 12,
172
+ bottom_leading: 12,
173
+ bottom_trailing: 12,
174
+ },
175
+ },
176
+ shadow: {
177
+ x: 0,
178
+ y: 4,
179
+ radius: 8,
180
+ color: {
181
+ light: { type: "hex", value: "#00000015" },
182
+ },
183
+ },
184
+ badge: null,
185
+ },
186
+ }}
187
+ />
188
+
189
+ <Story
190
+ name="Pill Shape"
191
+ args={{
192
+ stack: {
193
+ type: "stack",
194
+ id: "stack-3",
195
+ name: "Pill Option",
196
+ components: [
197
+ {
198
+ type: "text",
199
+ id: "text-1",
200
+ name: "Option Text",
201
+ text_lid: "option_text",
202
+ color: {
203
+ light: { type: "hex", value: "#FFFFFF" },
204
+ },
205
+ font_size: "body_m",
206
+ font_weight: "semibold",
207
+ horizontal_alignment: "center",
208
+ size: {
209
+ width: { type: "fit" },
210
+ height: { type: "fit" },
211
+ },
212
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
213
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
214
+ background_color: null,
215
+ },
216
+ ],
217
+ dimension: {
218
+ type: "horizontal",
219
+ alignment: "center",
220
+ distribution: "center",
221
+ },
222
+ size: {
223
+ width: { type: "fit" },
224
+ height: { type: "fit" },
225
+ },
226
+ spacing: 0,
227
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
228
+ padding: { top: 12, trailing: 24, bottom: 12, leading: 24 },
229
+ background_color: null,
230
+ background: {
231
+ type: "color",
232
+ value: {
233
+ light: { type: "hex", value: "#4A90E2" },
234
+ },
235
+ },
236
+ border: null,
237
+ shape: {
238
+ type: "pill",
239
+ },
240
+ shadow: {
241
+ x: 0,
242
+ y: 2,
243
+ radius: 4,
244
+ color: {
245
+ light: { type: "hex", value: "#00000030" },
246
+ },
247
+ },
248
+ badge: null,
249
+ },
250
+ }}
251
+ />
@@ -0,0 +1,19 @@
1
+ import InputOption from "./InputOption.svelte";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const InputOption: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type InputOption = InstanceType<typeof InputOption>;
19
+ export default InputOption;
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ import Stack from "../stack/Stack.svelte";
3
+ import { getPaywallContext } from "../../stores/paywall";
4
+ import type { InputOptionProps } from "../../types/components/options";
5
+
6
+ const props: InputOptionProps = $props();
7
+ const { stack } = props;
8
+
9
+ const { onButtonAction } = getPaywallContext();
10
+
11
+ const onclick = () => {
12
+ const actionId = props.triggers?.on_press;
13
+ // Create a workflow action to pass up through the callback
14
+ onButtonAction({ type: "workflow" }, actionId);
15
+ };
16
+ </script>
17
+
18
+ <Stack {...stack} {onclick} />
@@ -0,0 +1,4 @@
1
+ import type { InputOptionProps } from "../../types/components/options";
2
+ declare const InputOption: import("svelte").Component<InputOptionProps, {}, "">;
3
+ type InputOption = ReturnType<typeof InputOption>;
4
+ export default InputOption;
@@ -0,0 +1,207 @@
1
+ <script module lang="ts">
2
+ import InputSingleChoice from "./InputSingleChoice.svelte";
3
+ import { componentDecorator } from "../../stories/component-decorator";
4
+ import { localizationDecorator } from "../../stories/localization-decorator";
5
+ import type { InputSingleChoiceProps } from "../../types/components/options";
6
+ import { defineMeta } from "@storybook/addon-svelte-csf";
7
+
8
+ const defaultLocale = "en_US";
9
+
10
+ const { Story } = defineMeta({
11
+ title: "Components/Options/InputSingleChoice",
12
+ component: InputSingleChoice,
13
+ decorators: [
14
+ componentDecorator(),
15
+ localizationDecorator({
16
+ defaultLocale,
17
+ localizations: {
18
+ [defaultLocale]: {
19
+ option1: "Option 1",
20
+ option2: "Option 2",
21
+ option3: "Option 3",
22
+ },
23
+ },
24
+ }),
25
+ ],
26
+ args: {
27
+ type: "input_single_choice",
28
+ id: "single-choice-1",
29
+ name: "Single Choice Input",
30
+ field_id: "user_preference",
31
+ stack: {
32
+ type: "stack",
33
+ id: "stack-1",
34
+ name: "Choice Stack",
35
+ components: [
36
+ {
37
+ type: "text",
38
+ id: "text-1",
39
+ name: "Choice Label",
40
+ text_lid: "option1",
41
+ color: {
42
+ light: { type: "hex", value: "#000000" },
43
+ dark: { type: "hex", value: "#FFFFFF" },
44
+ },
45
+ font_size: "body_m",
46
+ font_weight: "regular",
47
+ horizontal_alignment: "leading",
48
+ size: {
49
+ width: { type: "fit" },
50
+ height: { type: "fit" },
51
+ },
52
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
53
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
54
+ background_color: null,
55
+ },
56
+ ],
57
+ dimension: {
58
+ type: "vertical",
59
+ alignment: "leading",
60
+ distribution: "start",
61
+ },
62
+ size: {
63
+ width: { type: "fill" },
64
+ height: { type: "fit" },
65
+ },
66
+ spacing: 8,
67
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
68
+ padding: { top: 16, trailing: 16, bottom: 16, leading: 16 },
69
+ background_color: {
70
+ light: { type: "hex", value: "#F5F5F5" },
71
+ dark: { type: "hex", value: "#2A2A2A" },
72
+ },
73
+ background: null,
74
+ border: {
75
+ width: 1,
76
+ color: {
77
+ light: { type: "hex", value: "#E0E0E0" },
78
+ dark: { type: "hex", value: "#404040" },
79
+ },
80
+ },
81
+ shape: {
82
+ type: "rectangle",
83
+ corners: {
84
+ top_leading: 8,
85
+ top_trailing: 8,
86
+ bottom_leading: 8,
87
+ bottom_trailing: 8,
88
+ },
89
+ },
90
+ shadow: null,
91
+ badge: null,
92
+ },
93
+ } satisfies InputSingleChoiceProps,
94
+ });
95
+ </script>
96
+
97
+ <Story name="Default" />
98
+
99
+ <Story
100
+ name="With Multiple Options"
101
+ args={{
102
+ stack: {
103
+ type: "stack",
104
+ id: "stack-2",
105
+ name: "Multi Choice Stack",
106
+ components: [
107
+ {
108
+ type: "text",
109
+ id: "text-1",
110
+ name: "Option 1",
111
+ text_lid: "option1",
112
+ color: {
113
+ light: { type: "hex", value: "#000000" },
114
+ },
115
+ font_size: "body_m",
116
+ font_weight: "medium",
117
+ horizontal_alignment: "leading",
118
+ size: {
119
+ width: { type: "fill" },
120
+ height: { type: "fit" },
121
+ },
122
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
123
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
124
+ background_color: null,
125
+ },
126
+ {
127
+ type: "text",
128
+ id: "text-2",
129
+ name: "Option 2",
130
+ text_lid: "option2",
131
+ color: {
132
+ light: { type: "hex", value: "#000000" },
133
+ },
134
+ font_size: "body_m",
135
+ font_weight: "medium",
136
+ horizontal_alignment: "leading",
137
+ size: {
138
+ width: { type: "fill" },
139
+ height: { type: "fit" },
140
+ },
141
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
142
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
143
+ background_color: null,
144
+ },
145
+ {
146
+ type: "text",
147
+ id: "text-3",
148
+ name: "Option 3",
149
+ text_lid: "option3",
150
+ color: {
151
+ light: { type: "hex", value: "#000000" },
152
+ },
153
+ font_size: "body_m",
154
+ font_weight: "medium",
155
+ horizontal_alignment: "leading",
156
+ size: {
157
+ width: { type: "fill" },
158
+ height: { type: "fit" },
159
+ },
160
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
161
+ padding: { top: 12, trailing: 16, bottom: 12, leading: 16 },
162
+ background_color: null,
163
+ },
164
+ ],
165
+ dimension: {
166
+ type: "vertical",
167
+ alignment: "leading",
168
+ distribution: "start",
169
+ },
170
+ size: {
171
+ width: { type: "fill" },
172
+ height: { type: "fit" },
173
+ },
174
+ spacing: 0,
175
+ margin: { top: 0, trailing: 0, bottom: 0, leading: 0 },
176
+ padding: { top: 0, trailing: 0, bottom: 0, leading: 0 },
177
+ background_color: {
178
+ light: { type: "hex", value: "#FFFFFF" },
179
+ },
180
+ background: null,
181
+ border: {
182
+ width: 1,
183
+ color: {
184
+ light: { type: "hex", value: "#DDDDDD" },
185
+ },
186
+ },
187
+ shape: {
188
+ type: "rectangle",
189
+ corners: {
190
+ top_leading: 12,
191
+ top_trailing: 12,
192
+ bottom_leading: 12,
193
+ bottom_trailing: 12,
194
+ },
195
+ },
196
+ shadow: {
197
+ x: 0,
198
+ y: 2,
199
+ radius: 4,
200
+ color: {
201
+ light: { type: "hex", value: "#00000020" },
202
+ },
203
+ },
204
+ badge: null,
205
+ },
206
+ }}
207
+ />
@@ -0,0 +1,19 @@
1
+ import InputSingleChoice from "./InputSingleChoice.svelte";
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const InputSingleChoice: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type InputSingleChoice = InstanceType<typeof InputSingleChoice>;
19
+ export default InputSingleChoice;
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ import Node from "../paywall/Node.svelte";
3
+ import type { InputSingleChoiceProps } from "../../types/components/options";
4
+
5
+ const props: InputSingleChoiceProps = $props();
6
+ const { stack } = props;
7
+ </script>
8
+
9
+ <Node nodeData={stack} />
@@ -0,0 +1,4 @@
1
+ import type { InputSingleChoiceProps } from "../../types/components/options";
2
+ declare const InputSingleChoice: import("svelte").Component<InputSingleChoiceProps, {}, "">;
3
+ type InputSingleChoice = ReturnType<typeof InputSingleChoice>;
4
+ export default InputSingleChoice;
@@ -9,6 +9,9 @@
9
9
  Video,
10
10
  } from "../..";
11
11
  import ButtonNode from "../button/ButtonNode.svelte";
12
+ import InputMultipleChoice from "../options/InputMultipleChoice.svelte";
13
+ import InputOption from "../options/InputOption.svelte";
14
+ import InputSingleChoice from "../options/InputSingleChoice.svelte";
12
15
  import TextNode from "../text/TextNode.svelte";
13
16
  import type { Component } from "../../types/component";
14
17
  import type { Component as SvelteComponent } from "svelte";
@@ -29,6 +32,9 @@
29
32
  footer: Footer,
30
33
  icon: Icon,
31
34
  image: Image,
35
+ input_multiple_choice: InputMultipleChoice,
36
+ input_option: InputOption,
37
+ input_single_choice: InputSingleChoice,
32
38
  package: Package,
33
39
  purchase_button: PurchaseButton,
34
40
  stack: Stack,
@@ -322,3 +322,18 @@
322
322
  paywallData: listTemplate,
323
323
  }}
324
324
  />
325
+
326
+ <Story
327
+ name="Wallet Button"
328
+ args={{
329
+ paywallData: pastaPaywallData,
330
+ walletButtonRender: (element: HTMLElement, selectedPackageId) => {
331
+ const newDiv = document.createElement("div");
332
+ newDiv.innerText = "Hi! I was injected from the walletButtonRender";
333
+ newDiv.style.width = "100%";
334
+ newDiv.style.textAlign = "center";
335
+ element.append(newDiv);
336
+ return {};
337
+ },
338
+ }}
339
+ />
@@ -40,6 +40,13 @@
40
40
  onNavigateToUrlClicked?: (url: string) => void;
41
41
  onActionTriggered?: (actionId: string) => void;
42
42
  onError?: (error: unknown) => void;
43
+ walletButtonRender?: (
44
+ node: HTMLElement,
45
+ selectedPackageId: string,
46
+ ) => {
47
+ destroy?: () => void;
48
+ update?: (selectedPackageId: string) => void;
49
+ };
43
50
  }
44
51
 
45
52
  const {
@@ -56,6 +63,7 @@
56
63
  onActionTriggered,
57
64
  onError,
58
65
  uiConfig,
66
+ walletButtonRender,
59
67
  }: Props = $props();
60
68
 
61
69
  const getColorMode = setColorModeContext(() => preferredColorMode);
@@ -127,6 +135,7 @@
127
135
  infoPerPackage: readable(infoPerPackage),
128
136
  onPurchase,
129
137
  onButtonAction,
138
+ walletButtonRender,
130
139
  uiConfig,
131
140
  });
132
141
 
@@ -16,6 +16,10 @@ interface Props {
16
16
  onNavigateToUrlClicked?: (url: string) => void;
17
17
  onActionTriggered?: (actionId: string) => void;
18
18
  onError?: (error: unknown) => void;
19
+ walletButtonRender?: (node: HTMLElement, selectedPackageId: string) => {
20
+ destroy?: () => void;
21
+ update?: (selectedPackageId: string) => void;
22
+ };
19
23
  }
20
24
  declare const Paywall: import("svelte").Component<Props, {}, "">;
21
25
  type Paywall = ReturnType<typeof Paywall>;
@@ -4,8 +4,17 @@
4
4
  import type { PurchaseButtonProps } from "../../types/components/purchase-button";
5
5
 
6
6
  const { stack }: PurchaseButtonProps = $props();
7
-
8
- const { onPurchase } = getPaywallContext();
7
+ const { onPurchase, walletButtonRender, selectedPackageId } =
8
+ getPaywallContext();
9
9
  </script>
10
10
 
11
+ {#if walletButtonRender}
12
+ {#if $selectedPackageId}
13
+ <div
14
+ style="width: 100%; margin-bottom:20px"
15
+ use:walletButtonRender={$selectedPackageId}
16
+ ></div>
17
+ {/if}
18
+ {/if}
19
+
11
20
  <Stack {...stack} onclick={onPurchase} />
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export { default as ButtonDeprecated } from "./components/button/Button.svelte";
2
2
  export { default as Footer } from "./components/footer/Footer.svelte";
3
3
  export { default as Image } from "./components/image/Image.svelte";
4
+ export { default as InputMultipleChoice } from "./components/options/InputMultipleChoice.svelte";
5
+ export { default as InputOption } from "./components/options/InputOption.svelte";
6
+ export { default as InputSingleChoice } from "./components/options/InputSingleChoice.svelte";
4
7
  export { default as Package } from "./components/package/Package.svelte";
5
8
  export { default as Paywall } from "./components/paywall/Paywall.svelte";
6
9
  export { default as PurchaseButton } from "./components/purchase-button/PurchaseButton.svelte";
package/dist/index.js CHANGED
@@ -2,6 +2,9 @@
2
2
  export { default as ButtonDeprecated } from "./components/button/Button.svelte";
3
3
  export { default as Footer } from "./components/footer/Footer.svelte";
4
4
  export { default as Image } from "./components/image/Image.svelte";
5
+ export { default as InputMultipleChoice } from "./components/options/InputMultipleChoice.svelte";
6
+ export { default as InputOption } from "./components/options/InputOption.svelte";
7
+ export { default as InputSingleChoice } from "./components/options/InputSingleChoice.svelte";
5
8
  export { default as Package } from "./components/package/Package.svelte";
6
9
  export { default as Paywall } from "./components/paywall/Paywall.svelte";
7
10
  export { default as PurchaseButton } from "./components/purchase-button/PurchaseButton.svelte";
@@ -7,6 +7,10 @@ type PaywallContext = Readonly<{
7
7
  variablesPerPackage: Readable<Record<string, VariableDictionary> | undefined>;
8
8
  infoPerPackage: Readable<Record<string, PackageInfo> | undefined>;
9
9
  onPurchase: () => void;
10
+ walletButtonRender?: (node: HTMLElement, selectedPackageId: string) => {
11
+ destroy?: () => void;
12
+ update?: (selectedPackageId: string) => void;
13
+ };
10
14
  onButtonAction: (action: Action, actionId?: string) => void;
11
15
  uiConfig: UIConfig;
12
16
  }>;
@@ -1,2 +1,5 @@
1
1
  import type { DecoratorFunction, Renderer } from "storybook/internal/csf";
2
- export declare function paywallDecorator<TRenderer extends Renderer, TArgs>(): DecoratorFunction<TRenderer, TArgs>;
2
+ export declare function paywallDecorator<TRenderer extends Renderer, TArgs>(walletButtonRender?: (node: HTMLElement, selectedPackageId: string) => {
3
+ destroy?: () => void;
4
+ update?: (selectedPackageId: string) => void;
5
+ }): DecoratorFunction<TRenderer, TArgs>;
@@ -1,6 +1,6 @@
1
1
  import { setPaywallContext } from "../stores/paywall";
2
2
  import { readable, writable } from "svelte/store";
3
- export function paywallDecorator() {
3
+ export function paywallDecorator(walletButtonRender) {
4
4
  return (Story) => {
5
5
  const selectedPackageId = writable(undefined);
6
6
  selectedPackageId.subscribe((packageId) => {
@@ -19,6 +19,7 @@ export function paywallDecorator() {
19
19
  infoPerPackage: readable(undefined),
20
20
  onPurchase: () => window.alert("Purchase clicked"),
21
21
  onButtonAction: (action, actionId) => window.alert(`Button clicked: ${JSON.stringify({ action, actionId }, undefined, 2)}`),
22
+ walletButtonRender,
22
23
  uiConfig: emptyUiConfig,
23
24
  });
24
25
  return Story();
@@ -3,6 +3,7 @@ import type { CarouselProps } from "./components/carousel";
3
3
  import type { FooterProps } from "./components/footer";
4
4
  import type { IconProps } from "./components/icon";
5
5
  import type { ImageProps } from "./components/image";
6
+ import type { InputMultipleChoiceProps, InputOptionProps, InputSingleChoiceProps } from "./components/options";
6
7
  import type { PackageProps } from "./components/package";
7
8
  import type { PurchaseButtonProps } from "./components/purchase-button";
8
9
  import type { StackProps } from "./components/stack";
@@ -10,4 +11,4 @@ import type { TabControlButtonProps, TabControlProps, TabControlToggleProps, Tab
10
11
  import type { TextNodeProps } from "./components/text";
11
12
  import type { TimelineProps } from "./components/timeline";
12
13
  import type { VideoProps } from "./components/video";
13
- export type Component = ButtonProps | CarouselProps | FooterProps | IconProps | ImageProps | PackageProps | PurchaseButtonProps | StackProps | TabControlButtonProps | TabControlToggleProps | TabControlProps | TabsProps | TextNodeProps | TimelineProps | VideoProps;
14
+ export type Component = ButtonProps | CarouselProps | FooterProps | IconProps | ImageProps | InputMultipleChoiceProps | InputOptionProps | InputSingleChoiceProps | PackageProps | PurchaseButtonProps | StackProps | TabControlButtonProps | TabControlToggleProps | TabControlProps | TabsProps | TextNodeProps | TimelineProps | VideoProps;
@@ -0,0 +1,17 @@
1
+ import type { BaseComponent } from "../base";
2
+ import type { StackProps } from "./stack";
3
+ export interface InputSingleChoiceProps extends BaseComponent {
4
+ type: "input_single_choice";
5
+ field_id: string;
6
+ stack: StackProps;
7
+ }
8
+ export interface InputMultipleChoiceProps extends BaseComponent {
9
+ type: "input_multiple_choice";
10
+ field_id: string;
11
+ stack: StackProps;
12
+ }
13
+ export interface InputOptionProps extends BaseComponent {
14
+ type: "input_option";
15
+ option_id: string;
16
+ stack: StackProps;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
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": "2.1.1",
5
+ "version": "2.2.1",
6
6
  "author": {
7
7
  "name": "RevenueCat, Inc."
8
8
  },