@stytch/react 2.0.0 → 3.0.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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @stytch/react
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 15dbe7d: Releasing UI components for our B2B SDKs.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [15dbe7d]
12
+ - @stytch/vanilla-js@0.13.0
13
+
3
14
  ## 2.0.0
4
15
 
5
16
  ### Patch Changes
@@ -1,11 +1,12 @@
1
1
  /// <reference types="react" />
2
2
  import React from "react";
3
3
  import { ReactNode } from "react";
4
- import { Member, MemberSession, StytchB2BHeadlessClient } from "@stytch/vanilla-js/b2b";
4
+ import { Member, MemberSession, StytchB2BHeadlessClient, StytchB2BUIClient } from "@stytch/vanilla-js/b2b";
5
+ import { Callbacks, StyleConfig, StytchB2BUIConfig } from "@stytch/vanilla-js";
5
6
  /**
6
7
  * The Stytch Client object passed in to <StytchProvider /> in your application root.
7
8
  */
8
- type StytchB2BClient = StytchB2BHeadlessClient;
9
+ type StytchB2BClient = StytchB2BHeadlessClient | StytchB2BUIClient;
9
10
  type SWRMember = {
10
11
  /**
11
12
  * Either the active {@link Member} object, or null if the user is not logged in.
@@ -89,5 +90,107 @@ type StytchB2BProviderProps = {
89
90
  * )
90
91
  */
91
92
  declare const StytchB2BProvider: ({ stytch, children }: StytchB2BProviderProps) => JSX.Element;
92
- export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, withStytchB2BClient, withStytchMemberSession, withStytchMember };
93
+ interface StytchB2BProps {
94
+ /**
95
+ * An optional {@link StyleConfig} to customize the look and feel of the screen.
96
+ *
97
+ * @example
98
+ * {
99
+ * fontFamily: 'Arial, Helvetica, sans-serif',
100
+ * width: '360px',
101
+ * primaryColor: '#19303D',
102
+ * }
103
+ */
104
+ styles?: StyleConfig;
105
+ /**
106
+ * An optional {@link Callbacks} object.
107
+ *
108
+ * @example
109
+ * {
110
+ * onError: ({message}) => {
111
+ * console.error('Stytch error', message)
112
+ * }
113
+ * }
114
+ *
115
+ * @example
116
+ * {
117
+ * onEvent: ({type, data}) => {
118
+ * if(type === StytchEventType.B2BMagicLinkAuthenticate) {
119
+ * console.log('Logged in with', data);
120
+ * }
121
+ * }
122
+ * }
123
+ */
124
+ callbacks?: Callbacks;
125
+ /**
126
+ * A {@link StytchB2BUIConfig} object. Add products and product-specific config to this object to change the login methods shown.
127
+ *
128
+ *
129
+ * @example
130
+ * {
131
+ * products: ['emailMagicLinks'],
132
+ * authFlowType: "Discovery",
133
+ * emailMagicLinksOptions: {
134
+ * discoveryRedirectURL: 'https://example.com/authenticate',
135
+ * },
136
+ * sessionOptions: {
137
+ * sessionDurationMinutes: 60,
138
+ * },
139
+ * }
140
+ *
141
+ * @example
142
+ * {
143
+ * products: ['emailMagicLinks', 'sso'],
144
+ * authFlowType: "Organization",
145
+ * emailMagicLinksOptions: {
146
+ * loginRedirectURL: 'https://example.com/authenticate',
147
+ * signupRedirectURL: 'https://example.com/authenticate',
148
+ * },
149
+ * ssoOptions: {
150
+ * loginRedirectURL: 'https://example.com/authenticate',
151
+ * signupRedirectURL: 'https://example.com/authenticate',
152
+ * },
153
+ * sessionOptions: {
154
+ * sessionDurationMinutes: 60,
155
+ * },
156
+ * }
157
+ */
158
+ config: StytchB2BUIConfig;
159
+ }
160
+ /**
161
+ * The Stytch B2B UI component.
162
+ * This component can only be used with a {@link StytchB2BUIClient} client constructor
163
+ * passed into the {@link StytchB2BProvider}
164
+ *
165
+ * See the {@link https://stytch.com/docs/b2b/sdks/javascript-sdk online reference}
166
+ *
167
+ * @example
168
+ * <StytchB2B
169
+ * config={{
170
+ * authFlowType: "Organization",
171
+ * emailMagicLinksOptions: {
172
+ * loginRedirectURL: 'https://example.com/authenticate',
173
+ * signupRedirectURL: 'https://example.com/authenticate',
174
+ * },
175
+ * ssoOptions: {
176
+ * loginRedirectURL: 'https://example.com/authenticate',
177
+ * signupRedirectURL: 'https://example.com/authenticate',
178
+ * },
179
+ * sessionOptions: {
180
+ * sessionDurationMinutes: 60,
181
+ * }
182
+ * }}
183
+ * styles={{
184
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
185
+ * primaryColor: '#0577CA',
186
+ * width: '321px',
187
+ * }}
188
+ * callbacks={{
189
+ * onEvent: (event) => console.log(event)
190
+ * }}
191
+ * />
192
+ * @param props {@link StytchB2BProps}
193
+ */
194
+ declare const StytchB2B: ({ styles, callbacks, config }: StytchB2BProps) => JSX.Element;
195
+ export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, withStytchB2BClient, withStytchMemberSession, withStytchMember, StytchB2B };
93
196
  export type { StytchB2BProviderProps };
@@ -1,11 +1,12 @@
1
1
  /// <reference types="react" />
2
2
  import React from "react";
3
3
  import { ReactNode } from "react";
4
- import { Member, MemberSession, StytchB2BHeadlessClient } from "@stytch/vanilla-js/b2b";
4
+ import { Member, MemberSession, StytchB2BHeadlessClient, StytchB2BUIClient } from "@stytch/vanilla-js/b2b";
5
+ import { Callbacks, StyleConfig, StytchB2BUIConfig } from "@stytch/vanilla-js";
5
6
  /**
6
7
  * The Stytch Client object passed in to <StytchProvider /> in your application root.
7
8
  */
8
- type StytchB2BClient = StytchB2BHeadlessClient;
9
+ type StytchB2BClient = StytchB2BHeadlessClient | StytchB2BUIClient;
9
10
  type SWRMember = {
10
11
  /**
11
12
  * Either the active {@link Member} object, or null if the user is not logged in.
@@ -89,5 +90,107 @@ type StytchB2BProviderProps = {
89
90
  * )
90
91
  */
91
92
  declare const StytchB2BProvider: ({ stytch, children }: StytchB2BProviderProps) => JSX.Element;
92
- export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, withStytchB2BClient, withStytchMemberSession, withStytchMember };
93
+ interface StytchB2BProps {
94
+ /**
95
+ * An optional {@link StyleConfig} to customize the look and feel of the screen.
96
+ *
97
+ * @example
98
+ * {
99
+ * fontFamily: 'Arial, Helvetica, sans-serif',
100
+ * width: '360px',
101
+ * primaryColor: '#19303D',
102
+ * }
103
+ */
104
+ styles?: StyleConfig;
105
+ /**
106
+ * An optional {@link Callbacks} object.
107
+ *
108
+ * @example
109
+ * {
110
+ * onError: ({message}) => {
111
+ * console.error('Stytch error', message)
112
+ * }
113
+ * }
114
+ *
115
+ * @example
116
+ * {
117
+ * onEvent: ({type, data}) => {
118
+ * if(type === StytchEventType.B2BMagicLinkAuthenticate) {
119
+ * console.log('Logged in with', data);
120
+ * }
121
+ * }
122
+ * }
123
+ */
124
+ callbacks?: Callbacks;
125
+ /**
126
+ * A {@link StytchB2BUIConfig} object. Add products and product-specific config to this object to change the login methods shown.
127
+ *
128
+ *
129
+ * @example
130
+ * {
131
+ * products: ['emailMagicLinks'],
132
+ * authFlowType: "Discovery",
133
+ * emailMagicLinksOptions: {
134
+ * discoveryRedirectURL: 'https://example.com/authenticate',
135
+ * },
136
+ * sessionOptions: {
137
+ * sessionDurationMinutes: 60,
138
+ * },
139
+ * }
140
+ *
141
+ * @example
142
+ * {
143
+ * products: ['emailMagicLinks', 'sso'],
144
+ * authFlowType: "Organization",
145
+ * emailMagicLinksOptions: {
146
+ * loginRedirectURL: 'https://example.com/authenticate',
147
+ * signupRedirectURL: 'https://example.com/authenticate',
148
+ * },
149
+ * ssoOptions: {
150
+ * loginRedirectURL: 'https://example.com/authenticate',
151
+ * signupRedirectURL: 'https://example.com/authenticate',
152
+ * },
153
+ * sessionOptions: {
154
+ * sessionDurationMinutes: 60,
155
+ * },
156
+ * }
157
+ */
158
+ config: StytchB2BUIConfig;
159
+ }
160
+ /**
161
+ * The Stytch B2B UI component.
162
+ * This component can only be used with a {@link StytchB2BUIClient} client constructor
163
+ * passed into the {@link StytchB2BProvider}
164
+ *
165
+ * See the {@link https://stytch.com/docs/b2b/sdks/javascript-sdk online reference}
166
+ *
167
+ * @example
168
+ * <StytchB2B
169
+ * config={{
170
+ * authFlowType: "Organization",
171
+ * emailMagicLinksOptions: {
172
+ * loginRedirectURL: 'https://example.com/authenticate',
173
+ * signupRedirectURL: 'https://example.com/authenticate',
174
+ * },
175
+ * ssoOptions: {
176
+ * loginRedirectURL: 'https://example.com/authenticate',
177
+ * signupRedirectURL: 'https://example.com/authenticate',
178
+ * },
179
+ * sessionOptions: {
180
+ * sessionDurationMinutes: 60,
181
+ * }
182
+ * }}
183
+ * styles={{
184
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
185
+ * primaryColor: '#0577CA',
186
+ * width: '321px',
187
+ * }}
188
+ * callbacks={{
189
+ * onEvent: (event) => console.log(event)
190
+ * }}
191
+ * />
192
+ * @param props {@link StytchB2BProps}
193
+ */
194
+ declare const StytchB2B: ({ styles, callbacks, config }: StytchB2BProps) => JSX.Element;
195
+ export { StytchB2BProvider, useStytchB2BClient, useStytchMemberSession, useStytchMember, withStytchB2BClient, withStytchMemberSession, withStytchMember, StytchB2B };
93
196
  export type { StytchB2BProviderProps };
@@ -1,4 +1,4 @@
1
- import React, { useRef, useState, useEffect, useCallback, createContext, useContext, useMemo } from 'react';
1
+ import React, { useRef, useState, useEffect, useCallback, createContext, useContext, useMemo, useLayoutEffect } from 'react';
2
2
 
3
3
  const noProviderError = (item, provider = 'StytchProvider') => `${item} can only be used inside <${provider}>.`;
4
4
  const B2BProviderMustBeUniqueError = 'You cannot render a <StytchB2BProvider> inside another <StytchB2BProvider>.';
@@ -6,6 +6,9 @@ const noSSRError = `The @stytch/react library is not meant for use with serversi
6
6
  Use the @stytch/nextjs library instead -
7
7
  npm remove @stytch/react && npm install @stytch/nextjs
8
8
  `;
9
+ const noHeadlessClientError = `Tried to create a Stytch Login UI element using the Stytch Headless SDK.
10
+ You must use the UI SDK to use UI elements.
11
+ Please make sure you are importing from @stytch/vanilla-js and not from the @stytch/vanilla-js/headless.`;
9
12
 
10
13
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
14
  function invariant(cond, message) {
@@ -42,6 +45,9 @@ const StytchB2BContext = createContext({ isMounted: false });
42
45
  const StytchMemberContext = createContext(initialMember);
43
46
  const StytchMemberSessionContext = createContext(initialMemberSession);
44
47
  const useIsMounted__INTERNAL = () => useContext(StytchB2BContext).isMounted;
48
+ const isUIClient = (client) => {
49
+ return client.mount !== undefined;
50
+ };
45
51
  /**
46
52
  * Returns the active Member.
47
53
  * Check the fromCache property to determine if the member data is from persistent storage.
@@ -156,4 +162,63 @@ const StytchB2BProvider = ({ stytch, children }) => {
156
162
  React.createElement(StytchMemberSessionContext.Provider, { value: finalMemberSession }, children))));
157
163
  };
158
164
 
159
- export { StytchB2BProvider, useStytchB2BClient, useStytchMember, useStytchMemberSession, withStytchB2BClient, withStytchMember, withStytchMemberSession };
165
+ /**
166
+ * The Stytch B2B UI component.
167
+ * This component can only be used with a {@link StytchB2BUIClient} client constructor
168
+ * passed into the {@link StytchB2BProvider}
169
+ *
170
+ * See the {@link https://stytch.com/docs/b2b/sdks/javascript-sdk online reference}
171
+ *
172
+ * @example
173
+ * <StytchB2B
174
+ * config={{
175
+ * authFlowType: "Organization",
176
+ * emailMagicLinksOptions: {
177
+ * loginRedirectURL: 'https://example.com/authenticate',
178
+ * signupRedirectURL: 'https://example.com/authenticate',
179
+ * },
180
+ * ssoOptions: {
181
+ * loginRedirectURL: 'https://example.com/authenticate',
182
+ * signupRedirectURL: 'https://example.com/authenticate',
183
+ * },
184
+ * sessionOptions: {
185
+ * sessionDurationMinutes: 60,
186
+ * }
187
+ * }}
188
+ * styles={{
189
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
190
+ * primaryColor: '#0577CA',
191
+ * width: '321px',
192
+ * }}
193
+ * callbacks={{
194
+ * onEvent: (event) => console.log(event)
195
+ * }}
196
+ * />
197
+ * @param props {@link StytchB2BProps}
198
+ */
199
+ const StytchB2B = ({ styles, callbacks, config }) => {
200
+ invariant(useIsMounted__INTERNAL(), noProviderError('<StytchB2B />'));
201
+ const stytchClient = useStytchB2BClient();
202
+ const containerEl = useRef(null);
203
+ useLayoutEffect(() => {
204
+ if (!isUIClient(stytchClient)) {
205
+ throw Error(noHeadlessClientError);
206
+ }
207
+ if (!containerEl.current) {
208
+ return;
209
+ }
210
+ if (!containerEl.current.id) {
211
+ const randId = Math.floor(Math.random() * 1e6);
212
+ containerEl.current.id = `stytch-b2b-ui-${randId}`;
213
+ }
214
+ stytchClient.mount({
215
+ callbacks,
216
+ config,
217
+ elementId: `#${containerEl.current.id}`,
218
+ styles,
219
+ });
220
+ }, [stytchClient, styles, callbacks]);
221
+ return React.createElement("div", { ref: containerEl });
222
+ };
223
+
224
+ export { StytchB2B, StytchB2BProvider, useStytchB2BClient, useStytchMember, useStytchMemberSession, withStytchB2BClient, withStytchMember, withStytchMemberSession };
package/dist/b2b/index.js CHANGED
@@ -14,6 +14,9 @@ const noSSRError = `The @stytch/react library is not meant for use with serversi
14
14
  Use the @stytch/nextjs library instead -
15
15
  npm remove @stytch/react && npm install @stytch/nextjs
16
16
  `;
17
+ const noHeadlessClientError = `Tried to create a Stytch Login UI element using the Stytch Headless SDK.
18
+ You must use the UI SDK to use UI elements.
19
+ Please make sure you are importing from @stytch/vanilla-js and not from the @stytch/vanilla-js/headless.`;
17
20
 
18
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
22
  function invariant(cond, message) {
@@ -50,6 +53,9 @@ const StytchB2BContext = React.createContext({ isMounted: false });
50
53
  const StytchMemberContext = React.createContext(initialMember);
51
54
  const StytchMemberSessionContext = React.createContext(initialMemberSession);
52
55
  const useIsMounted__INTERNAL = () => React.useContext(StytchB2BContext).isMounted;
56
+ const isUIClient = (client) => {
57
+ return client.mount !== undefined;
58
+ };
53
59
  /**
54
60
  * Returns the active Member.
55
61
  * Check the fromCache property to determine if the member data is from persistent storage.
@@ -164,6 +170,66 @@ const StytchB2BProvider = ({ stytch, children }) => {
164
170
  React__default['default'].createElement(StytchMemberSessionContext.Provider, { value: finalMemberSession }, children))));
165
171
  };
166
172
 
173
+ /**
174
+ * The Stytch B2B UI component.
175
+ * This component can only be used with a {@link StytchB2BUIClient} client constructor
176
+ * passed into the {@link StytchB2BProvider}
177
+ *
178
+ * See the {@link https://stytch.com/docs/b2b/sdks/javascript-sdk online reference}
179
+ *
180
+ * @example
181
+ * <StytchB2B
182
+ * config={{
183
+ * authFlowType: "Organization",
184
+ * emailMagicLinksOptions: {
185
+ * loginRedirectURL: 'https://example.com/authenticate',
186
+ * signupRedirectURL: 'https://example.com/authenticate',
187
+ * },
188
+ * ssoOptions: {
189
+ * loginRedirectURL: 'https://example.com/authenticate',
190
+ * signupRedirectURL: 'https://example.com/authenticate',
191
+ * },
192
+ * sessionOptions: {
193
+ * sessionDurationMinutes: 60,
194
+ * }
195
+ * }}
196
+ * styles={{
197
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
198
+ * primaryColor: '#0577CA',
199
+ * width: '321px',
200
+ * }}
201
+ * callbacks={{
202
+ * onEvent: (event) => console.log(event)
203
+ * }}
204
+ * />
205
+ * @param props {@link StytchB2BProps}
206
+ */
207
+ const StytchB2B = ({ styles, callbacks, config }) => {
208
+ invariant(useIsMounted__INTERNAL(), noProviderError('<StytchB2B />'));
209
+ const stytchClient = useStytchB2BClient();
210
+ const containerEl = React.useRef(null);
211
+ React.useLayoutEffect(() => {
212
+ if (!isUIClient(stytchClient)) {
213
+ throw Error(noHeadlessClientError);
214
+ }
215
+ if (!containerEl.current) {
216
+ return;
217
+ }
218
+ if (!containerEl.current.id) {
219
+ const randId = Math.floor(Math.random() * 1e6);
220
+ containerEl.current.id = `stytch-b2b-ui-${randId}`;
221
+ }
222
+ stytchClient.mount({
223
+ callbacks,
224
+ config,
225
+ elementId: `#${containerEl.current.id}`,
226
+ styles,
227
+ });
228
+ }, [stytchClient, styles, callbacks]);
229
+ return React__default['default'].createElement("div", { ref: containerEl });
230
+ };
231
+
232
+ exports.StytchB2B = StytchB2B;
167
233
  exports.StytchB2BProvider = StytchB2BProvider;
168
234
  exports.useStytchB2BClient = useStytchB2BClient;
169
235
  exports.useStytchMember = useStytchMember;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stytch/react",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Stytch's official React Library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -32,7 +32,7 @@
32
32
  ],
33
33
  "devDependencies": {
34
34
  "@babel/runtime": "7.18.6",
35
- "@stytch/vanilla-js": "0.12.0",
35
+ "@stytch/vanilla-js": "0.13.0",
36
36
  "@testing-library/react": "14.0.0",
37
37
  "eslint-config-custom": "0.0.1",
38
38
  "react-test-renderer": "18.0.0",
@@ -40,7 +40,7 @@
40
40
  "typescript": "4.7.4"
41
41
  },
42
42
  "peerDependencies": {
43
- "@stytch/vanilla-js": "^0.12.0",
43
+ "@stytch/vanilla-js": "^0.13.0",
44
44
  "react": ">= 17.0.2",
45
45
  "react-dom": ">= 17.0.2"
46
46
  }