@growth-rail/react 2.0.1 → 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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,50 @@
1
+ # @growth-rail/react
2
+
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Fixed issues and modified usage
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @growth-rail/core@2.2.0
13
+
14
+ ## 2.0.2
15
+
16
+ ### Patch Changes
17
+
18
+ - added read me
19
+ - Updated dependencies
20
+ - @growth-rail/core@2.0.1
21
+
22
+ ## 2.0.1
23
+
24
+ ### Patch Changes
25
+
26
+ - dependency fixed
27
+
28
+ ## 2.0.0
29
+
30
+ ### Major Changes
31
+
32
+ - option type changes
33
+
34
+ ## 1.0.1
35
+
36
+ ### Patch Changes
37
+
38
+ - Updated dependencies [d4cc14b]
39
+ - @growth-rail/core@2.0.0
40
+
41
+ ## 1.0.0
42
+
43
+ ### Major Changes
44
+
45
+ - Initial SDK Version
46
+
47
+ ### Patch Changes
48
+
49
+ - Updated dependencies
50
+ - @growth-rail/core@1.0.0
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # @growth-rail/react
2
+
3
+ The Official Growth Rail React SDK. Easily integrate referral programs, track user growth, and display referral dashboards in your React applications.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **Context-based Initialization**: Seamless setup with `GrowthRailProvider`.
8
+ - **Hooks for Ease of Use**: Access the SDK anywhere with the `useGrowthRail` hook.
9
+ - **Built-in UI Components**: Drop-in widgets like `ReferralDashboard` to get started instantly.
10
+ - **Fully Type-Safe**: Written in TypeScript with complete definition support.
11
+ - **Small Footprint**: Optimized for performance and minimal bundle size.
12
+
13
+ ## 📦 Installation
14
+
15
+ This package requires `@growth-rail/core` as a dependency and `react` as a peer dependency.
16
+
17
+ ```bash
18
+ # npm
19
+ npm install @growth-rail/react @growth-rail/core
20
+
21
+ # yarn
22
+ yarn add @growth-rail/react @growth-rail/core
23
+
24
+ # pnpm
25
+ pnpm add @growth-rail/react @growth-rail/core
26
+ ```
27
+
28
+ ## 🛠 Usage
29
+
30
+ ### 1. Wrap your App with `GrowthRailProvider`
31
+
32
+ Initialize the SDK at the root of your application. Provide your Project Secret Key and optionally a `userId` if the user is already authenticated.
33
+
34
+ ```tsx
35
+ import { GrowthRailProvider } from '@growth-rail/react';
36
+
37
+ function App() {
38
+ return (
39
+ <GrowthRailProvider
40
+ projectSecretKey="your_project_secret_key_here"
41
+ userId="user_123" // Optional: initialize for a specific user
42
+ >
43
+ <your-application-code />
44
+ </GrowthRailProvider>
45
+ );
46
+ }
47
+ ```
48
+
49
+ ### 2. Track Events and Get User Info
50
+
51
+ Use the `useGrowthRail` hook in any child component to track events or initialize users.
52
+
53
+ ```tsx
54
+ import { useGrowthRail } from '@growth-rail/react';
55
+
56
+ export function ActionButton() {
57
+ const { trackRewardEvent, isLoading } = useGrowthRail();
58
+
59
+ const handleAction = async () => {
60
+ await trackRewardEvent('purchase_completed');
61
+ console.log('Action tracked!');
62
+ };
63
+
64
+ return (
65
+ <button onClick={handleAction} disabled={isLoading}>
66
+ {isLoading ? 'Processing...' : 'Complete Action'}
67
+ </button>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ### 3. Display the Referral Dashboard
73
+
74
+ Use the `ReferralDashboard` component to provide a white-labeled UI where users can see their referral link and rewards.
75
+
76
+ ```tsx
77
+ import { ReferralDashboard } from '@growth-rail/react';
78
+
79
+ export function DashboardPage() {
80
+ return (
81
+ <div style={{ padding: '20px' }}>
82
+ <h1>My Rewards</h1>
83
+ <ReferralDashboard
84
+ title="Invite your friends and earn!"
85
+ onLinkCopied={() => alert('Link copied!')}
86
+ />
87
+ </div>
88
+ );
89
+ }
90
+ ```
91
+
92
+ ## 📖 API Reference
93
+
94
+ ### `useGrowthRail()`
95
+
96
+ The main hook for interacting with the Growth Rail SDK.
97
+
98
+ **Methods:**
99
+ - `initAppUser(userId)`: Initializes the SDK for a specific user.
100
+ - `trackRewardEvent(eventName?)`: Tracks a custom event for attribution and rewards.
101
+ - `showReferralDashboard(options?)`: Programmatically triggers the referral dashboard modal.
102
+ - `showFloatingButton(options)`: Displays the floating referral trigger button.
103
+ - `hideFloatingButton()`: Removes the floating referral trigger button.
104
+
105
+ **State:**
106
+ - `isLoading`: Boolean indicating if an async operation is pending.
107
+ - `error`: The last error that occurred (if any).
108
+
109
+ ### `ReferralDashboard`
110
+
111
+ An inline dashboard component for your application.
112
+
113
+ | Prop | Type | Description |
114
+ | :--- | :--- | :--- |
115
+ | `title` | `string` | Optional title for the dashboard. |
116
+ | `onLinkCopied` | `() => void` | Callback when the referral link is copied. |
117
+
118
+ For full documentation, visit [docs.growthrail.com](https://docs.growthrail.com).
119
+
120
+ ## 📄 License
121
+
122
+ MIT © [Growth Rail](https://growthrail.com)
package/dist/index.d.mts CHANGED
@@ -1,29 +1,90 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { GrowthRailOptions, AppUserType, GrowthRail, ReferrerTriggerButton, ReferrerModalOptions } from '@growth-rail/core';
3
- export { AppUserType, GrowthRailOptions } from '@growth-rail/core';
3
+ export { AppUserType, GrowthRailOptions, ReferrerExperience, ReferrerModalOptions, ReferrerTriggerButton } from '@growth-rail/core';
4
4
 
5
+ /**
6
+ * Props for the GrowthRailProvider component.
7
+ */
5
8
  interface GrowthRailProviderProps extends GrowthRailOptions {
9
+ /** The unique ID for the current application user. */
6
10
  userId?: string;
11
+ /** Your application components. */
7
12
  children: ReactNode;
8
13
  }
14
+ /**
15
+ * Root provider component for GrowthRail in React applications.
16
+ * This component initializes the SDK and manages the user's authentication state.
17
+ *
18
+ * Wrap your app (or a specific feature tree) with this provider.
19
+ *
20
+ * @example
21
+ * <GrowthRailProvider projectSecretKey="your-api-key" userId="user-123">
22
+ * <App />
23
+ * </GrowthRailProvider>
24
+ */
9
25
  declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
10
26
 
27
+ /**
28
+ * The return type of the useGrowthRail hook.
29
+ */
11
30
  interface UseGrowthRailReturn {
12
- initUser: (userId: string) => Promise<AppUserType>;
13
- trackReward: (eventName?: string) => Promise<void>;
31
+ /**
32
+ * Initializes a user in the GrowthRail system.
33
+ * @param userId - Unique identifier for the user.
34
+ */
35
+ initAppUser: (userId: string) => Promise<AppUserType>;
36
+ /**
37
+ * Tracks a reward-eligible event for the current user.
38
+ * @param eventName - Optional name of the event.
39
+ */
40
+ trackRewardEvent: (eventName?: string) => Promise<void>;
41
+ /**
42
+ * Manually triggers the referral dashboard modal.
43
+ * @param options - Customization options for the modal.
44
+ */
14
45
  showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;
46
+ /**
47
+ * Manually shows or updates the floating referral trigger button.
48
+ * @param options - Configuration for the button.
49
+ */
15
50
  showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
51
+ /** Hides the floating referral trigger button. */
16
52
  hideFloatingButton: () => void;
53
+ /** Whether an asynchronous operation (like init or track) is in progress. */
17
54
  isLoading: boolean;
55
+ /** The last error that occurred during an operation. */
18
56
  error: Error | null;
19
57
  }
58
+ /**
59
+ * A hook that provides access to GrowthRail SDK methods and state.
60
+ *
61
+ * @returns An object containing methods to manage referrals and track state.
62
+ *
63
+ * @example
64
+ * const { showReferralDashboard, trackRewardEvent } = useGrowthRail();
65
+ */
20
66
  declare const useGrowthRail: () => UseGrowthRailReturn;
21
67
 
68
+ /**
69
+ * Props for the ReferralDashboard component.
70
+ */
22
71
  interface ReferralDashboardProps {
72
+ /** Optional override for the dashboard title. */
23
73
  title?: string;
74
+ /** Customization options for the dashboard's appearance. */
24
75
  appearance?: ReferrerModalOptions;
76
+ /** Callback fired when the referral link is copied to the clipboard. */
25
77
  onLinkCopied?: () => void;
26
78
  }
79
+ /**
80
+ * An inline referral dashboard component.
81
+ * Unlike the global modal, this component renders directly within your layout.
82
+ *
83
+ * @example
84
+ * <div style={{ height: '500px' }}>
85
+ * <ReferralDashboard title="Invite your team" />
86
+ * </div>
87
+ */
27
88
  declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
28
89
 
29
90
  export { GrowthRailProvider, ReferralDashboard, type ReferralDashboardProps, type UseGrowthRailReturn, useGrowthRail };
package/dist/index.d.ts CHANGED
@@ -1,29 +1,90 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { GrowthRailOptions, AppUserType, GrowthRail, ReferrerTriggerButton, ReferrerModalOptions } from '@growth-rail/core';
3
- export { AppUserType, GrowthRailOptions } from '@growth-rail/core';
3
+ export { AppUserType, GrowthRailOptions, ReferrerExperience, ReferrerModalOptions, ReferrerTriggerButton } from '@growth-rail/core';
4
4
 
5
+ /**
6
+ * Props for the GrowthRailProvider component.
7
+ */
5
8
  interface GrowthRailProviderProps extends GrowthRailOptions {
9
+ /** The unique ID for the current application user. */
6
10
  userId?: string;
11
+ /** Your application components. */
7
12
  children: ReactNode;
8
13
  }
14
+ /**
15
+ * Root provider component for GrowthRail in React applications.
16
+ * This component initializes the SDK and manages the user's authentication state.
17
+ *
18
+ * Wrap your app (or a specific feature tree) with this provider.
19
+ *
20
+ * @example
21
+ * <GrowthRailProvider projectSecretKey="your-api-key" userId="user-123">
22
+ * <App />
23
+ * </GrowthRailProvider>
24
+ */
9
25
  declare const GrowthRailProvider: React.FC<GrowthRailProviderProps>;
10
26
 
27
+ /**
28
+ * The return type of the useGrowthRail hook.
29
+ */
11
30
  interface UseGrowthRailReturn {
12
- initUser: (userId: string) => Promise<AppUserType>;
13
- trackReward: (eventName?: string) => Promise<void>;
31
+ /**
32
+ * Initializes a user in the GrowthRail system.
33
+ * @param userId - Unique identifier for the user.
34
+ */
35
+ initAppUser: (userId: string) => Promise<AppUserType>;
36
+ /**
37
+ * Tracks a reward-eligible event for the current user.
38
+ * @param eventName - Optional name of the event.
39
+ */
40
+ trackRewardEvent: (eventName?: string) => Promise<void>;
41
+ /**
42
+ * Manually triggers the referral dashboard modal.
43
+ * @param options - Customization options for the modal.
44
+ */
14
45
  showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;
46
+ /**
47
+ * Manually shows or updates the floating referral trigger button.
48
+ * @param options - Configuration for the button.
49
+ */
15
50
  showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;
51
+ /** Hides the floating referral trigger button. */
16
52
  hideFloatingButton: () => void;
53
+ /** Whether an asynchronous operation (like init or track) is in progress. */
17
54
  isLoading: boolean;
55
+ /** The last error that occurred during an operation. */
18
56
  error: Error | null;
19
57
  }
58
+ /**
59
+ * A hook that provides access to GrowthRail SDK methods and state.
60
+ *
61
+ * @returns An object containing methods to manage referrals and track state.
62
+ *
63
+ * @example
64
+ * const { showReferralDashboard, trackRewardEvent } = useGrowthRail();
65
+ */
20
66
  declare const useGrowthRail: () => UseGrowthRailReturn;
21
67
 
68
+ /**
69
+ * Props for the ReferralDashboard component.
70
+ */
22
71
  interface ReferralDashboardProps {
72
+ /** Optional override for the dashboard title. */
23
73
  title?: string;
74
+ /** Customization options for the dashboard's appearance. */
24
75
  appearance?: ReferrerModalOptions;
76
+ /** Callback fired when the referral link is copied to the clipboard. */
25
77
  onLinkCopied?: () => void;
26
78
  }
79
+ /**
80
+ * An inline referral dashboard component.
81
+ * Unlike the global modal, this component renders directly within your layout.
82
+ *
83
+ * @example
84
+ * <div style={{ height: '500px' }}>
85
+ * <ReferralDashboard title="Invite your team" />
86
+ * </div>
87
+ */
27
88
  declare const ReferralDashboard: React.FC<ReferralDashboardProps>;
28
89
 
29
90
  export { GrowthRailProvider, ReferralDashboard, type ReferralDashboardProps, type UseGrowthRailReturn, useGrowthRail };
package/dist/index.js CHANGED
@@ -61,7 +61,7 @@ var import_core2 = require("@growth-rail/core");
61
61
  var useGrowthRail = () => {
62
62
  const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
63
63
  const [error, setError] = (0, import_react2.useState)(null);
64
- const initUser = (0, import_react2.useCallback)(async (userId) => {
64
+ const initAppUser = (0, import_react2.useCallback)(async (userId) => {
65
65
  setIsLoading(true);
66
66
  setError(null);
67
67
  try {
@@ -75,7 +75,7 @@ var useGrowthRail = () => {
75
75
  setIsLoading(false);
76
76
  }
77
77
  }, []);
78
- const trackReward = (0, import_react2.useCallback)(async (eventName) => {
78
+ const trackRewardEvent = (0, import_react2.useCallback)(async (eventName) => {
79
79
  setIsLoading(true);
80
80
  setError(null);
81
81
  try {
@@ -98,8 +98,8 @@ var useGrowthRail = () => {
98
98
  import_core2.GrowthRail.destroyTriggerButton();
99
99
  }, []);
100
100
  return {
101
- initUser,
102
- trackReward,
101
+ initAppUser,
102
+ trackRewardEvent,
103
103
  showReferralDashboard,
104
104
  showFloatingButton,
105
105
  hideFloatingButton,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/GrowthRailProvider.tsx","../src/useGrowthRail.ts","../src/ReferralDashboard.tsx"],"sourcesContent":["export { GrowthRailProvider } from './GrowthRailProvider';\nexport { useGrowthRail, type UseGrowthRailReturn } from './useGrowthRail';\nexport { \n ReferralDashboard, \n type ReferralDashboardProps,\n} from './ReferralDashboard';\n\nexport type { GrowthRailOptions, AppUserType } from '@growth-rail/core';\n","import React, { useEffect, useRef, useState, ReactNode } from 'react';\nimport { GrowthRail, GrowthRailOptions } from '@growth-rail/core';\n\ninterface GrowthRailProviderProps extends GrowthRailOptions {\n userId?: string;\n children: ReactNode;\n}\n\nexport const GrowthRailProvider: React.FC<GrowthRailProviderProps> = ({ \n children, \n userId,\n ...options \n}) => {\n const [isReady, setIsReady] = useState(GrowthRail.isInitialized());\n const initialized = useRef(false);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n GrowthRail.init(options);\n if (userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n setIsReady(true);\n }, []);\n\n useEffect(() => {\n if (initialized.current && userId && GrowthRail.getUserId() !== userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n }, [userId]);\n\n if (!isReady) return null;\n\n return <>{children}</>;\n};\n","import { useState, useCallback } from 'react';\nimport { GrowthRail, AppUserType, ReferrerTriggerButton } from '@growth-rail/core';\n\nexport interface UseGrowthRailReturn {\n initUser: (userId: string) => Promise<AppUserType>;\n trackReward: (eventName?: string) => Promise<void>;\n showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;\n showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;\n hideFloatingButton: () => void;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport const useGrowthRail = (): UseGrowthRailReturn => {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const initUser = useCallback(async (userId: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const user = await GrowthRail.initAppUser(userId);\n return user;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const trackReward = useCallback(async (eventName?: string) => {\n setIsLoading(true);\n setError(null);\n try {\n await GrowthRail.trackRewardEvent(eventName);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const showReferralDashboard = useCallback((options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => {\n GrowthRail.showReferralDashboard(options);\n }, []);\n\n const showFloatingButton = useCallback((options: Partial<ReferrerTriggerButton>) => {\n GrowthRail.createTriggerButton(options);\n }, []);\n\n const hideFloatingButton = useCallback(() => {\n GrowthRail.destroyTriggerButton();\n }, []);\n\n return {\n initUser,\n trackReward,\n showReferralDashboard,\n showFloatingButton,\n hideFloatingButton,\n isLoading,\n error,\n };\n};\n","import React, { useEffect, useRef } from 'react';\nimport { GrowthRail, ReferrerModalOptions, ReferralModal, ReferrerExperience } from '@growth-rail/core';\n\nexport interface ReferralDashboardProps {\n title?: string;\n appearance?: ReferrerModalOptions;\n onLinkCopied?: () => void;\n}\n\nexport const ReferralDashboard: React.FC<ReferralDashboardProps> = ({\n title,\n appearance = {},\n onLinkCopied,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<ReferralModal | null>(null);\n\n useEffect(() => {\n let mounted = true;\n if (!containerRef.current) return;\n\n GrowthRail.ensureUserReady().then((user) => {\n if (!mounted || !containerRef.current) return;\n\n const deps = {\n isUserReady: () => GrowthRail.isUserReady(),\n getReferralLink: () => {\n try {\n return GrowthRail.getReferralLink();\n } catch {\n return '';\n }\n },\n };\n\n // Construct experience config directly from BE\n const experience: ReferrerExperience = {\n trigger: user.referrerExperience.trigger,\n modal: {\n ...user.referrerExperience.modal,\n ...(title ? { title } : {}),\n ...appearance,\n },\n };\n\n modalRef.current = new ReferralModal(deps, experience);\n modalRef.current.show(appearance, containerRef.current);\n }).catch((err) => {\n console.error('GrowthRail: User initialization failed', err);\n });\n\n return () => {\n mounted = false;\n if (modalRef.current) {\n modalRef.current.hide();\n modalRef.current = null;\n }\n };\n }, [title, appearance]);\n\n return (\n <div \n ref={containerRef} \n style={{ \n width: '100%', \n height: '100%', \n minHeight: '400px',\n position: 'relative' \n }} \n />\n );\n};\n"],"mappings":"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","names":["import_react","import_core","error","import_react","import_core","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/GrowthRailProvider.tsx","../src/useGrowthRail.ts","../src/ReferralDashboard.tsx"],"sourcesContent":["/**\n * GrowthRail React SDK\n * \n * This package provide React components and hooks for the GrowthRail referral system.\n * It is built on top of the `@growth-rail/core` package.\n */\n\n/** Root provider component for initializing GrowthRail. */\nexport { GrowthRailProvider } from './GrowthRailProvider';\n\n/** Hook for accessing GrowthRail methods and state. */\nexport { useGrowthRail, type UseGrowthRailReturn } from './useGrowthRail';\n\n/** Inline referral dashboard component. */\nexport { \n ReferralDashboard, \n type ReferralDashboardProps,\n} from './ReferralDashboard';\n\n/** Re-exported core types. */\nexport type { \n GrowthRailOptions, \n AppUserType,\n ReferrerModalOptions,\n ReferrerExperience,\n ReferrerTriggerButton \n} from '@growth-rail/core';\n","import React, { useEffect, useRef, useState, ReactNode } from 'react';\nimport { GrowthRail, GrowthRailOptions } from '@growth-rail/core';\n\n/**\n * Props for the GrowthRailProvider component.\n */\ninterface GrowthRailProviderProps extends GrowthRailOptions {\n /** The unique ID for the current application user. */\n userId?: string;\n /** Your application components. */\n children: ReactNode;\n}\n\n/**\n * Root provider component for GrowthRail in React applications.\n * This component initializes the SDK and manages the user's authentication state.\n * \n * Wrap your app (or a specific feature tree) with this provider.\n * \n * @example\n * <GrowthRailProvider projectSecretKey=\"your-api-key\" userId=\"user-123\">\n * <App />\n * </GrowthRailProvider>\n */\nexport const GrowthRailProvider: React.FC<GrowthRailProviderProps> = ({ \n children, \n userId,\n ...options \n}) => {\n\n const [isReady, setIsReady] = useState(GrowthRail.isInitialized());\n const initialized = useRef(false);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n GrowthRail.init(options);\n if (userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n setIsReady(true);\n }, []);\n\n useEffect(() => {\n if (initialized.current && userId && GrowthRail.getUserId() !== userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n }, [userId]);\n\n if (!isReady) return null;\n\n return <>{children}</>;\n};\n","import { useState, useCallback } from 'react';\nimport { GrowthRail, AppUserType, ReferrerTriggerButton } from '@growth-rail/core';\n\n/**\n * The return type of the useGrowthRail hook.\n */\nexport interface UseGrowthRailReturn {\n /** \n * Initializes a user in the GrowthRail system. \n * @param userId - Unique identifier for the user.\n */\n initAppUser: (userId: string) => Promise<AppUserType>;\n /** \n * Tracks a reward-eligible event for the current user.\n * @param eventName - Optional name of the event.\n */\n trackRewardEvent: (eventName?: string) => Promise<void>;\n /** \n * Manually triggers the referral dashboard modal.\n * @param options - Customization options for the modal.\n */\n showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;\n /** \n * Manually shows or updates the floating referral trigger button.\n * @param options - Configuration for the button.\n */\n showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;\n /** Hides the floating referral trigger button. */\n hideFloatingButton: () => void;\n /** Whether an asynchronous operation (like init or track) is in progress. */\n isLoading: boolean;\n /** The last error that occurred during an operation. */\n error: Error | null;\n}\n\n/**\n * A hook that provides access to GrowthRail SDK methods and state.\n * \n * @returns An object containing methods to manage referrals and track state.\n * \n * @example\n * const { showReferralDashboard, trackRewardEvent } = useGrowthRail();\n */\nexport const useGrowthRail = (): UseGrowthRailReturn => {\n\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const initAppUser = useCallback(async (userId: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const user = await GrowthRail.initAppUser(userId);\n return user;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const trackRewardEvent = useCallback(async (eventName?: string) => {\n setIsLoading(true);\n setError(null);\n try {\n await GrowthRail.trackRewardEvent(eventName);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const showReferralDashboard = useCallback((options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => {\n GrowthRail.showReferralDashboard(options);\n }, []);\n\n const showFloatingButton = useCallback((options: Partial<ReferrerTriggerButton>) => {\n GrowthRail.createTriggerButton(options);\n }, []);\n\n const hideFloatingButton = useCallback(() => {\n GrowthRail.destroyTriggerButton();\n }, []);\n\n return {\n initAppUser,\n trackRewardEvent,\n showReferralDashboard,\n showFloatingButton,\n hideFloatingButton,\n isLoading,\n error,\n };\n};\n","import React, { useEffect, useRef } from 'react';\nimport { GrowthRail, ReferrerModalOptions, ReferralModal, ReferrerExperience } from '@growth-rail/core';\n\n/**\n * Props for the ReferralDashboard component.\n */\nexport interface ReferralDashboardProps {\n /** Optional override for the dashboard title. */\n title?: string;\n /** Customization options for the dashboard's appearance. */\n appearance?: ReferrerModalOptions;\n /** Callback fired when the referral link is copied to the clipboard. */\n onLinkCopied?: () => void;\n}\n\n/**\n * An inline referral dashboard component.\n * Unlike the global modal, this component renders directly within your layout.\n * \n * @example\n * <div style={{ height: '500px' }}>\n * <ReferralDashboard title=\"Invite your team\" />\n * </div>\n */\nexport const ReferralDashboard: React.FC<ReferralDashboardProps> = ({\n title,\n appearance = {},\n onLinkCopied,\n}) => {\n\n const containerRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<ReferralModal | null>(null);\n\n useEffect(() => {\n let mounted = true;\n if (!containerRef.current) return;\n\n GrowthRail.ensureUserReady().then((user) => {\n if (!mounted || !containerRef.current) return;\n\n const deps = {\n isUserReady: () => GrowthRail.isUserReady(),\n getReferralLink: () => {\n try {\n return GrowthRail.getReferralLink();\n } catch {\n return '';\n }\n },\n };\n\n // Construct experience config directly from BE\n const experience: ReferrerExperience = {\n trigger: user.referrerExperience.trigger,\n modal: {\n ...user.referrerExperience.modal,\n ...(title ? { title } : {}),\n ...appearance,\n },\n };\n\n modalRef.current = new ReferralModal(deps, experience);\n modalRef.current.show(appearance, containerRef.current);\n }).catch((err) => {\n console.error('GrowthRail: User initialization failed', err);\n });\n\n return () => {\n mounted = false;\n if (modalRef.current) {\n modalRef.current.hide();\n modalRef.current = null;\n }\n };\n }, [title, appearance]);\n\n return (\n <div \n ref={containerRef} \n style={{ \n width: '100%', \n height: '100%', \n minHeight: '400px',\n position: 'relative' \n }} \n />\n );\n};\n"],"mappings":"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","names":["import_react","import_core","error","import_react","import_core","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -33,7 +33,7 @@ import { GrowthRail as GrowthRail2 } from "@growth-rail/core";
33
33
  var useGrowthRail = () => {
34
34
  const [isLoading, setIsLoading] = useState2(false);
35
35
  const [error, setError] = useState2(null);
36
- const initUser = useCallback(async (userId) => {
36
+ const initAppUser = useCallback(async (userId) => {
37
37
  setIsLoading(true);
38
38
  setError(null);
39
39
  try {
@@ -47,7 +47,7 @@ var useGrowthRail = () => {
47
47
  setIsLoading(false);
48
48
  }
49
49
  }, []);
50
- const trackReward = useCallback(async (eventName) => {
50
+ const trackRewardEvent = useCallback(async (eventName) => {
51
51
  setIsLoading(true);
52
52
  setError(null);
53
53
  try {
@@ -70,8 +70,8 @@ var useGrowthRail = () => {
70
70
  GrowthRail2.destroyTriggerButton();
71
71
  }, []);
72
72
  return {
73
- initUser,
74
- trackReward,
73
+ initAppUser,
74
+ trackRewardEvent,
75
75
  showReferralDashboard,
76
76
  showFloatingButton,
77
77
  hideFloatingButton,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/GrowthRailProvider.tsx","../src/useGrowthRail.ts","../src/ReferralDashboard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, ReactNode } from 'react';\nimport { GrowthRail, GrowthRailOptions } from '@growth-rail/core';\n\ninterface GrowthRailProviderProps extends GrowthRailOptions {\n userId?: string;\n children: ReactNode;\n}\n\nexport const GrowthRailProvider: React.FC<GrowthRailProviderProps> = ({ \n children, \n userId,\n ...options \n}) => {\n const [isReady, setIsReady] = useState(GrowthRail.isInitialized());\n const initialized = useRef(false);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n GrowthRail.init(options);\n if (userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n setIsReady(true);\n }, []);\n\n useEffect(() => {\n if (initialized.current && userId && GrowthRail.getUserId() !== userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n }, [userId]);\n\n if (!isReady) return null;\n\n return <>{children}</>;\n};\n","import { useState, useCallback } from 'react';\nimport { GrowthRail, AppUserType, ReferrerTriggerButton } from '@growth-rail/core';\n\nexport interface UseGrowthRailReturn {\n initUser: (userId: string) => Promise<AppUserType>;\n trackReward: (eventName?: string) => Promise<void>;\n showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;\n showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;\n hideFloatingButton: () => void;\n isLoading: boolean;\n error: Error | null;\n}\n\nexport const useGrowthRail = (): UseGrowthRailReturn => {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const initUser = useCallback(async (userId: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const user = await GrowthRail.initAppUser(userId);\n return user;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const trackReward = useCallback(async (eventName?: string) => {\n setIsLoading(true);\n setError(null);\n try {\n await GrowthRail.trackRewardEvent(eventName);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const showReferralDashboard = useCallback((options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => {\n GrowthRail.showReferralDashboard(options);\n }, []);\n\n const showFloatingButton = useCallback((options: Partial<ReferrerTriggerButton>) => {\n GrowthRail.createTriggerButton(options);\n }, []);\n\n const hideFloatingButton = useCallback(() => {\n GrowthRail.destroyTriggerButton();\n }, []);\n\n return {\n initUser,\n trackReward,\n showReferralDashboard,\n showFloatingButton,\n hideFloatingButton,\n isLoading,\n error,\n };\n};\n","import React, { useEffect, useRef } from 'react';\nimport { GrowthRail, ReferrerModalOptions, ReferralModal, ReferrerExperience } from '@growth-rail/core';\n\nexport interface ReferralDashboardProps {\n title?: string;\n appearance?: ReferrerModalOptions;\n onLinkCopied?: () => void;\n}\n\nexport const ReferralDashboard: React.FC<ReferralDashboardProps> = ({\n title,\n appearance = {},\n onLinkCopied,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<ReferralModal | null>(null);\n\n useEffect(() => {\n let mounted = true;\n if (!containerRef.current) return;\n\n GrowthRail.ensureUserReady().then((user) => {\n if (!mounted || !containerRef.current) return;\n\n const deps = {\n isUserReady: () => GrowthRail.isUserReady(),\n getReferralLink: () => {\n try {\n return GrowthRail.getReferralLink();\n } catch {\n return '';\n }\n },\n };\n\n // Construct experience config directly from BE\n const experience: ReferrerExperience = {\n trigger: user.referrerExperience.trigger,\n modal: {\n ...user.referrerExperience.modal,\n ...(title ? { title } : {}),\n ...appearance,\n },\n };\n\n modalRef.current = new ReferralModal(deps, experience);\n modalRef.current.show(appearance, containerRef.current);\n }).catch((err) => {\n console.error('GrowthRail: User initialization failed', err);\n });\n\n return () => {\n mounted = false;\n if (modalRef.current) {\n modalRef.current.hide();\n modalRef.current = null;\n }\n };\n }, [title, appearance]);\n\n return (\n <div \n ref={containerRef} \n style={{ \n width: '100%', \n height: '100%', \n minHeight: '400px',\n position: 'relative' \n }} \n />\n );\n};\n"],"mappings":"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","names":["useState","GrowthRail","error","useEffect","useRef","GrowthRail","jsx"]}
1
+ {"version":3,"sources":["../src/GrowthRailProvider.tsx","../src/useGrowthRail.ts","../src/ReferralDashboard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, ReactNode } from 'react';\nimport { GrowthRail, GrowthRailOptions } from '@growth-rail/core';\n\n/**\n * Props for the GrowthRailProvider component.\n */\ninterface GrowthRailProviderProps extends GrowthRailOptions {\n /** The unique ID for the current application user. */\n userId?: string;\n /** Your application components. */\n children: ReactNode;\n}\n\n/**\n * Root provider component for GrowthRail in React applications.\n * This component initializes the SDK and manages the user's authentication state.\n * \n * Wrap your app (or a specific feature tree) with this provider.\n * \n * @example\n * <GrowthRailProvider projectSecretKey=\"your-api-key\" userId=\"user-123\">\n * <App />\n * </GrowthRailProvider>\n */\nexport const GrowthRailProvider: React.FC<GrowthRailProviderProps> = ({ \n children, \n userId,\n ...options \n}) => {\n\n const [isReady, setIsReady] = useState(GrowthRail.isInitialized());\n const initialized = useRef(false);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n GrowthRail.init(options);\n if (userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n setIsReady(true);\n }, []);\n\n useEffect(() => {\n if (initialized.current && userId && GrowthRail.getUserId() !== userId) {\n GrowthRail.initAppUser(userId).catch(console.error);\n }\n }, [userId]);\n\n if (!isReady) return null;\n\n return <>{children}</>;\n};\n","import { useState, useCallback } from 'react';\nimport { GrowthRail, AppUserType, ReferrerTriggerButton } from '@growth-rail/core';\n\n/**\n * The return type of the useGrowthRail hook.\n */\nexport interface UseGrowthRailReturn {\n /** \n * Initializes a user in the GrowthRail system. \n * @param userId - Unique identifier for the user.\n */\n initAppUser: (userId: string) => Promise<AppUserType>;\n /** \n * Tracks a reward-eligible event for the current user.\n * @param eventName - Optional name of the event.\n */\n trackRewardEvent: (eventName?: string) => Promise<void>;\n /** \n * Manually triggers the referral dashboard modal.\n * @param options - Customization options for the modal.\n */\n showReferralDashboard: (options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => void;\n /** \n * Manually shows or updates the floating referral trigger button.\n * @param options - Configuration for the button.\n */\n showFloatingButton: (options: Partial<ReferrerTriggerButton>) => void;\n /** Hides the floating referral trigger button. */\n hideFloatingButton: () => void;\n /** Whether an asynchronous operation (like init or track) is in progress. */\n isLoading: boolean;\n /** The last error that occurred during an operation. */\n error: Error | null;\n}\n\n/**\n * A hook that provides access to GrowthRail SDK methods and state.\n * \n * @returns An object containing methods to manage referrals and track state.\n * \n * @example\n * const { showReferralDashboard, trackRewardEvent } = useGrowthRail();\n */\nexport const useGrowthRail = (): UseGrowthRailReturn => {\n\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const initAppUser = useCallback(async (userId: string) => {\n setIsLoading(true);\n setError(null);\n try {\n const user = await GrowthRail.initAppUser(userId);\n return user;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const trackRewardEvent = useCallback(async (eventName?: string) => {\n setIsLoading(true);\n setError(null);\n try {\n await GrowthRail.trackRewardEvent(eventName);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const showReferralDashboard = useCallback((options?: Parameters<typeof GrowthRail.showReferralDashboard>[0]) => {\n GrowthRail.showReferralDashboard(options);\n }, []);\n\n const showFloatingButton = useCallback((options: Partial<ReferrerTriggerButton>) => {\n GrowthRail.createTriggerButton(options);\n }, []);\n\n const hideFloatingButton = useCallback(() => {\n GrowthRail.destroyTriggerButton();\n }, []);\n\n return {\n initAppUser,\n trackRewardEvent,\n showReferralDashboard,\n showFloatingButton,\n hideFloatingButton,\n isLoading,\n error,\n };\n};\n","import React, { useEffect, useRef } from 'react';\nimport { GrowthRail, ReferrerModalOptions, ReferralModal, ReferrerExperience } from '@growth-rail/core';\n\n/**\n * Props for the ReferralDashboard component.\n */\nexport interface ReferralDashboardProps {\n /** Optional override for the dashboard title. */\n title?: string;\n /** Customization options for the dashboard's appearance. */\n appearance?: ReferrerModalOptions;\n /** Callback fired when the referral link is copied to the clipboard. */\n onLinkCopied?: () => void;\n}\n\n/**\n * An inline referral dashboard component.\n * Unlike the global modal, this component renders directly within your layout.\n * \n * @example\n * <div style={{ height: '500px' }}>\n * <ReferralDashboard title=\"Invite your team\" />\n * </div>\n */\nexport const ReferralDashboard: React.FC<ReferralDashboardProps> = ({\n title,\n appearance = {},\n onLinkCopied,\n}) => {\n\n const containerRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<ReferralModal | null>(null);\n\n useEffect(() => {\n let mounted = true;\n if (!containerRef.current) return;\n\n GrowthRail.ensureUserReady().then((user) => {\n if (!mounted || !containerRef.current) return;\n\n const deps = {\n isUserReady: () => GrowthRail.isUserReady(),\n getReferralLink: () => {\n try {\n return GrowthRail.getReferralLink();\n } catch {\n return '';\n }\n },\n };\n\n // Construct experience config directly from BE\n const experience: ReferrerExperience = {\n trigger: user.referrerExperience.trigger,\n modal: {\n ...user.referrerExperience.modal,\n ...(title ? { title } : {}),\n ...appearance,\n },\n };\n\n modalRef.current = new ReferralModal(deps, experience);\n modalRef.current.show(appearance, containerRef.current);\n }).catch((err) => {\n console.error('GrowthRail: User initialization failed', err);\n });\n\n return () => {\n mounted = false;\n if (modalRef.current) {\n modalRef.current.hide();\n modalRef.current = null;\n }\n };\n }, [title, appearance]);\n\n return (\n <div \n ref={containerRef} \n style={{ \n width: '100%', \n height: '100%', \n minHeight: '400px',\n position: 'relative' \n }} \n />\n );\n};\n"],"mappings":"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","names":["useState","GrowthRail","error","useEffect","useRef","GrowthRail","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-rail/react",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Growth Rail React SDK",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -13,7 +13,9 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "README.md",
18
+ "CHANGELOG.md"
17
19
  ],
18
20
  "scripts": {
19
21
  "build": "tsup",
@@ -27,7 +29,7 @@
27
29
  "react-dom": ">=16.8"
28
30
  },
29
31
  "dependencies": {
30
- "@growth-rail/core": "^2.0.0"
32
+ "@growth-rail/core": "^2.2.0"
31
33
  },
32
34
  "devDependencies": {
33
35
  "@growth-rail/eslint-config": "*",