@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
@@ -75,6 +75,7 @@
75
75
  id2: "Navigate back",
76
76
  id3: "Navigate to",
77
77
  id4: "URL navigation",
78
+ id5: "Workflow Action",
78
79
  },
79
80
  },
80
81
  }),
@@ -166,3 +167,22 @@
166
167
  },
167
168
  }}
168
169
  />
170
+
171
+ <Story
172
+ name="Workflow Action"
173
+ args={{
174
+ action: {
175
+ type: "workflow",
176
+ },
177
+ triggers: {
178
+ on_press: "workflow-action-id",
179
+ },
180
+ stack: {
181
+ ...stackProps(5),
182
+ background_color: {
183
+ dark: { type: "hex", value: "#9C27B0" },
184
+ light: { type: "hex", value: "#9C27B0" },
185
+ },
186
+ },
187
+ }}
188
+ />
@@ -17,10 +17,16 @@
17
17
 
18
18
  const { onButtonAction } = getPaywallContext();
19
19
 
20
- const onclick = () => onButtonAction(props.action);
20
+ const onclick = () => {
21
+ const actionId = props.triggers?.on_press;
22
+ onButtonAction(props.action, actionId);
23
+ };
21
24
 
22
25
  const visible = $derived.by(() => {
23
26
  switch (action.type) {
27
+ case "workflow":
28
+ return true;
29
+ case "restore_purchases":
24
30
  case "navigate_back":
25
31
  return false;
26
32
  case "navigate_to":
@@ -29,8 +35,10 @@
29
35
  return true;
30
36
  }
31
37
  });
38
+
39
+ const style = $derived({
40
+ visibility: visible ? "visible" : "hidden",
41
+ });
32
42
  </script>
33
43
 
34
- {#if visible}
35
- <Stack {...props.stack} {onclick} />
36
- {/if}
44
+ <Stack {...props.stack} {onclick} {style} />
@@ -6,6 +6,7 @@
6
6
  PurchaseButton,
7
7
  Stack,
8
8
  Timeline,
9
+ Video,
9
10
  } from "../..";
10
11
  import ButtonNode from "../button/ButtonNode.svelte";
11
12
  import TextNode from "../text/TextNode.svelte";
@@ -15,6 +16,7 @@
15
16
  import Icon from "../icon/Icon.svelte";
16
17
  import TabControl from "../tabs/TabControl.svelte";
17
18
  import TabControlButton from "../tabs/TabControlButton.svelte";
19
+ import TabControlToggle from "../tabs/TabControlToggle.svelte";
18
20
  import Tabs from "../tabs/Tabs.svelte";
19
21
 
20
22
  interface Props {
@@ -31,10 +33,12 @@
31
33
  purchase_button: PurchaseButton,
32
34
  stack: Stack,
33
35
  tab_control_button: TabControlButton,
36
+ tab_control_toggle: TabControlToggle,
34
37
  tab_control: TabControl,
35
38
  tabs: Tabs,
36
39
  text: TextNode,
37
40
  timeline: Timeline,
41
+ video: Video,
38
42
  } satisfies {
39
43
  [key in Component["type"]]: SvelteComponent<
40
44
  Extract<Component, { type: key }>
@@ -19,8 +19,8 @@
19
19
  import { findSelectedPackageId } from "../../utils/style-utils";
20
20
  import { onMount } from "svelte";
21
21
  import { derived, readable, writable } from "svelte/store";
22
- import Sheet from "./Sheet.svelte";
23
22
  import Stack from "../stack/Stack.svelte";
23
+ import Sheet from "./Sheet.svelte";
24
24
 
25
25
  interface Props {
26
26
  paywallData: PaywallData;
@@ -33,6 +33,7 @@
33
33
  onVisitCustomerCenterClicked?: () => void;
34
34
  onRestorePurchasesClicked?: () => void;
35
35
  onNavigateToUrlClicked?: (url: string) => void;
36
+ onActionTriggered?: (actionId: string) => void;
36
37
  onError?: (error: unknown) => void;
37
38
  }
38
39
 
@@ -46,6 +47,7 @@
46
47
  onVisitCustomerCenterClicked,
47
48
  onRestorePurchasesClicked,
48
49
  onNavigateToUrlClicked,
50
+ onActionTriggered,
49
51
  onError,
50
52
  uiConfig,
51
53
  }: Props = $props();
@@ -76,8 +78,13 @@
76
78
 
77
79
  let sheet = $state<SheetProps>();
78
80
 
79
- const onButtonAction = (action: Action) => {
81
+ const onButtonAction = (action: Action, actionId?: string) => {
80
82
  switch (action.type) {
83
+ case "workflow":
84
+ if (actionId) {
85
+ onActionTriggered?.(actionId);
86
+ }
87
+ return;
81
88
  case "navigate_back":
82
89
  onBackClicked?.();
83
90
  return;
@@ -139,7 +146,7 @@
139
146
  </script>
140
147
 
141
148
  <svelte:boundary onerror={onError}>
142
- <div id="paywall" class={paywallClass} {style}>
149
+ <div class={paywallClass} {style}>
143
150
  <Stack {...stack} />
144
151
 
145
152
  {#if sticky_footer}
@@ -159,9 +166,8 @@
159
166
  flex-direction: column;
160
167
  align-items: stretch;
161
168
  height: 100%;
162
- overflow: hidden;
163
169
 
164
- transition-property: filter transform;
170
+ transition-property: filter, transform;
165
171
  transition-duration: 0.1s;
166
172
  transition-timing-function: ease-in-out;
167
173
  transform-origin: center;
@@ -13,6 +13,7 @@ interface Props {
13
13
  onVisitCustomerCenterClicked?: () => void;
14
14
  onRestorePurchasesClicked?: () => void;
15
15
  onNavigateToUrlClicked?: (url: string) => void;
16
+ onActionTriggered?: (actionId: string) => void;
16
17
  onError?: (error: unknown) => void;
17
18
  }
18
19
  declare const Paywall: import("svelte").Component<Props, {}, "">;
@@ -12,6 +12,7 @@
12
12
  mapSize,
13
13
  mapSpacing,
14
14
  px,
15
+ type CSS,
15
16
  } from "../../utils/base-utils";
16
17
  import { getActiveStateProps } from "../../utils/style-utils";
17
18
  import type { Snippet } from "svelte";
@@ -20,10 +21,11 @@
20
21
  interface MiscProps {
21
22
  onclick?: () => void;
22
23
  children?: Snippet;
24
+ style?: CSS;
23
25
  }
24
26
 
25
27
  const props: StackProps & MiscProps = $props();
26
- const { onclick, children } = props;
28
+ const { onclick, children, style } = props;
27
29
 
28
30
  const selectedState = getSelectedStateContext();
29
31
  const {
@@ -49,8 +51,9 @@
49
51
  const getColorMode = getColorModeContext();
50
52
  const colorMode = $derived(getColorMode());
51
53
 
52
- const style = $derived(
54
+ const stackStyle = $derived(
53
55
  css({
56
+ ...style,
54
57
  display: "flex",
55
58
  position: "relative",
56
59
  width: mapSize(size.width),
@@ -91,7 +94,7 @@
91
94
  this={onclick !== undefined ? "button" : "div"}
92
95
  role={onclick !== undefined ? "button" : undefined}
93
96
  {onclick}
94
- {style}
97
+ style={stackStyle}
95
98
  class="stack"
96
99
  >
97
100
  {#if badge}
@@ -1,8 +1,10 @@
1
1
  import type { StackProps } from "../../types/components/stack";
2
+ import { type CSS } from "../../utils/base-utils";
2
3
  import type { Snippet } from "svelte";
3
4
  interface MiscProps {
4
5
  onclick?: () => void;
5
6
  children?: Snippet;
7
+ style?: CSS;
6
8
  }
7
9
  type $$ComponentProps = StackProps & MiscProps;
8
10
  declare const Stack: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -0,0 +1,103 @@
1
+ <script lang="ts">
2
+ import { getColorModeContext } from "../../stores/color-mode";
3
+ import {
4
+ getSelectedStateContext,
5
+ setSelectedStateContext,
6
+ } from "../../stores/selected";
7
+ import type { TabControlToggleProps } from "../../types/components/tabs";
8
+ import { css, mapColor } from "../../utils/base-utils";
9
+ import { getActiveStateProps } from "../../utils/style-utils";
10
+ import { getTabsContext } from "./tabs-context";
11
+
12
+ const props: TabControlToggleProps = $props();
13
+
14
+ const selectedState = getSelectedStateContext();
15
+ const {
16
+ default_value,
17
+ thumb_color_on,
18
+ thumb_color_off,
19
+ track_color_on,
20
+ track_color_off,
21
+ } = $derived.by(() => {
22
+ return {
23
+ ...props,
24
+ ...getActiveStateProps($selectedState, props.overrides),
25
+ };
26
+ });
27
+
28
+ const { isActive, selectTab } = getTabsContext();
29
+ setSelectedStateContext(isActive);
30
+
31
+ const getColorMode = getColorModeContext();
32
+ const colorMode = $derived(getColorMode());
33
+
34
+ const toggleStyle = $derived(
35
+ css({
36
+ background: $isActive
37
+ ? mapColor(colorMode, track_color_on)
38
+ : mapColor(colorMode, track_color_off),
39
+ }),
40
+ );
41
+
42
+ const thumbStyle = $derived(
43
+ css({
44
+ left: $isActive ? "22px" : "2px",
45
+ background: $isActive
46
+ ? mapColor(colorMode, thumb_color_on)
47
+ : mapColor(colorMode, thumb_color_off),
48
+ }),
49
+ );
50
+
51
+ const onclick = () => {
52
+ selectTab("", $isActive ? 0 : 1);
53
+ };
54
+
55
+ const onkeydown = (event: KeyboardEvent) => {
56
+ if (event.code === "Enter" || event.code === "Space") {
57
+ onclick();
58
+ }
59
+ };
60
+ </script>
61
+
62
+ <div
63
+ role="button"
64
+ tabindex="0"
65
+ aria-label="Toggle"
66
+ class="toggle"
67
+ style={toggleStyle}
68
+ {onclick}
69
+ {onkeydown}
70
+ >
71
+ <div class="thumb" style={thumbStyle}></div>
72
+ </div>
73
+
74
+ <style>
75
+ .toggle {
76
+ appearance: none;
77
+
78
+ --height: 31px;
79
+
80
+ position: relative;
81
+ width: 51px;
82
+ height: var(--height);
83
+ border-radius: calc(var(--height) / 2);
84
+ cursor: pointer;
85
+ user-select: none;
86
+ transition: background-color 300ms ease;
87
+ }
88
+
89
+ .thumb {
90
+ --size: 27px;
91
+ position: absolute;
92
+ top: 2px;
93
+ width: var(--size);
94
+ height: var(--size);
95
+ border-radius: 50%;
96
+ box-shadow:
97
+ 0 1px 3px rgba(0, 0, 0, 0.2),
98
+ 0 1px 2px rgba(0, 0, 0, 0.12);
99
+ transition:
100
+ left 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
101
+ background-color 300ms ease;
102
+ }
103
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { TabControlToggleProps } from "../../types/components/tabs";
2
+ declare const TabControlToggle: import("svelte").Component<TabControlToggleProps, {}, "">;
3
+ type TabControlToggle = ReturnType<typeof TabControlToggle>;
4
+ export default TabControlToggle;