+
);
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/tasks/ForceOrganizationSelection.tsx b/packages/clerk-js/src/ui/components/SessionTasks/tasks/ForceOrganizationSelection.tsx
deleted file mode 100644
index 5f98dba91eb..00000000000
--- a/packages/clerk-js/src/ui/components/SessionTasks/tasks/ForceOrganizationSelection.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import { useOrganizationList } from '@clerk/shared/react/index';
-import type { PropsWithChildren } from 'react';
-import { useEffect, useRef, useState } from 'react';
-
-import { OrganizationListContext } from '@/ui/contexts';
-import { useSessionTasksContext } from '@/ui/contexts/components/SessionTasks';
-import { Card } from '@/ui/elements/Card';
-import { useCardState, withCardStateProvider } from '@/ui/elements/contexts';
-
-import { Box, descriptors, Flex, localizationKeys, Spinner } from '../../../customizables';
-import { CreateOrganizationForm } from '../../CreateOrganization/CreateOrganizationForm';
-import { OrganizationListPageList } from '../../OrganizationList/OrganizationListPage';
-import { organizationListParams } from '../../OrganizationSwitcher/utils';
-
-/**
- * @internal
- */
-export const ForceOrganizationSelectionTask = withCardStateProvider(() => {
- const { userMemberships, userInvitations, userSuggestions } = useOrganizationList(organizationListParams);
- const currentFlow = useRef<'create-organization' | 'organization-selection'>();
-
- const isLoading = userMemberships?.isLoading || userInvitations?.isLoading || userSuggestions?.isLoading;
- const hasData = !!(userMemberships?.count || userInvitations?.count || userSuggestions?.count);
-
- if (isLoading) {
- return (
-
-
-
- );
- }
-
- // Only show the organization selection page if organizations exist when the component first mounts.
- // This prevents unwanted screen transitions that could occur from data revalidation,
- // such as when a user accepts an organization invitation and the membership list updates.
- if (hasData || currentFlow.current === 'organization-selection') {
- return ;
- }
-
- return ;
-});
-
-type CommonPageProps = {
- currentFlow: React.MutableRefObject<'create-organization' | 'organization-selection' | undefined>;
-};
-
-const OrganizationSelectionPage = ({ currentFlow }: CommonPageProps) => {
- const [showCreateOrganizationForm, setShowCreateOrganizationForm] = useState(false);
-
- useEffect(() => {
- currentFlow.current = 'organization-selection';
- }, [currentFlow]);
-
- return (
-
-
- {showCreateOrganizationForm ? (
- ({
- padding: `${t.space.$none} ${t.space.$5} ${t.space.$5}`,
- })}
- >
- setShowCreateOrganizationForm(false)}
- />
-
- ) : (
- setShowCreateOrganizationForm(true)} />
- )}
-
-
- );
-};
-
-const CreateOrganizationPage = ({ currentFlow }: CommonPageProps) => {
- useEffect(() => {
- currentFlow.current = 'create-organization';
- }, [currentFlow]);
-
- return (
-
- ({
- padding: `${t.space.$none} ${t.space.$5} ${t.space.$5}`,
- })}
- >
-
-
-
- );
-};
-
-const FlowCard = ({ children }: PropsWithChildren) => {
- const card = useCardState();
- const { currentTaskContainer } = useSessionTasksContext();
-
- return (
-
- ({ padding: `${t.space.$8} ${t.space.$none} ${t.space.$none}` })}>
- ({ margin: `${t.space.$none} ${t.space.$5}` })}>{card.error}
- {children}
-
-
-
- );
-};
-
-const FlowLoadingState = () => (
- ({
- height: '100%',
- minHeight: t.sizes.$60,
- })}
- >
-
-
-);
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/tasks/TaskSelectOrganization.tsx b/packages/clerk-js/src/ui/components/SessionTasks/tasks/TaskSelectOrganization.tsx
new file mode 100644
index 00000000000..cf2671d434f
--- /dev/null
+++ b/packages/clerk-js/src/ui/components/SessionTasks/tasks/TaskSelectOrganization.tsx
@@ -0,0 +1,26 @@
+import { OrganizationListContext, withCoreSessionSwitchGuard } from '@/ui/contexts';
+import { useTaskSelectOrganizationContext } from '@/ui/contexts/components/SessionTasks';
+import { withCardStateProvider } from '@/ui/elements/contexts';
+
+import { OrganizationList } from '../../OrganizationList';
+import { withTaskGuard } from './withTaskGuard';
+
+const TaskSelectOrganizationInternal = () => {
+ const ctx = useTaskSelectOrganizationContext();
+
+ return (
+
+
+
+ );
+};
+
+export const TaskSelectOrganization = withCoreSessionSwitchGuard(
+ withTaskGuard(withCardStateProvider(TaskSelectOrganizationInternal)),
+);
diff --git a/packages/clerk-js/src/ui/components/SessionTasks/tasks/withTaskGuard.ts b/packages/clerk-js/src/ui/components/SessionTasks/tasks/withTaskGuard.ts
new file mode 100644
index 00000000000..36d07e86fb2
--- /dev/null
+++ b/packages/clerk-js/src/ui/components/SessionTasks/tasks/withTaskGuard.ts
@@ -0,0 +1,25 @@
+import type { ComponentType } from 'react';
+
+import { warnings } from '@/core/warnings';
+import { withRedirect } from '@/ui/common';
+import { useTaskSelectOrganizationContext } from '@/ui/contexts/components/SessionTasks';
+import type { AvailableComponentProps } from '@/ui/types';
+
+export const withTaskGuard = (Component: ComponentType
) => {
+ const displayName = Component.displayName || Component.name || 'Component';
+ Component.displayName = displayName;
+
+ const HOC = (props: P) => {
+ const ctx = useTaskSelectOrganizationContext();
+ return withRedirect(
+ Component,
+ clerk => !clerk.session?.currentTask,
+ ({ clerk }) => ctx.redirectUrlComplete || clerk.buildAfterSignInUrl(),
+ warnings.cannotRenderComponentWhenTaskDoesNotExist,
+ )(props);
+ };
+
+ HOC.displayName = `withTaskGuard(${displayName})`;
+
+ return HOC;
+};
diff --git a/packages/clerk-js/src/ui/contexts/ClerkUIComponentsContext.tsx b/packages/clerk-js/src/ui/contexts/ClerkUIComponentsContext.tsx
index 2cada4a7da1..b3651a5c44d 100644
--- a/packages/clerk-js/src/ui/contexts/ClerkUIComponentsContext.tsx
+++ b/packages/clerk-js/src/ui/contexts/ClerkUIComponentsContext.tsx
@@ -2,6 +2,7 @@ import type {
__internal_OAuthConsentProps,
APIKeysProps,
PricingTableProps,
+ TaskSelectOrganizationProps,
UserButtonProps,
WaitlistProps,
} from '@clerk/types';
@@ -25,6 +26,7 @@ import {
UserVerificationContext,
WaitlistContext,
} from './components';
+import { SessionTasksContext, TaskSelectOrganizationContext } from './components/SessionTasks';
export function ComponentContextProvider({
componentName,
@@ -108,6 +110,16 @@ export function ComponentContextProvider({
{children}
);
+ case 'TaskSelectOrganization':
+ return (
+
+
+ {children}
+
+
+ );
default:
throw new Error(`Unknown component context: ${componentName}`);
}
diff --git a/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts b/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
index 1c9e0be6c5c..73008bab797 100644
--- a/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
+++ b/packages/clerk-js/src/ui/contexts/components/SessionTasks.ts
@@ -1,10 +1,10 @@
import { createContext, useContext } from 'react';
-import type { SessionTasksCtx } from '../../types';
+import type { SessionTasksCtx, TaskSelectOrganizationCtx } from '../../types';
export const SessionTasksContext = createContext(null);
-export const useSessionTasksContext = () => {
+export const useSessionTasksContext = (): SessionTasksCtx => {
const context = useContext(SessionTasksContext);
if (context === null) {
@@ -13,3 +13,17 @@ export const useSessionTasksContext = () => {
return context;
};
+
+export const TaskSelectOrganizationContext = createContext(null);
+
+export const useTaskSelectOrganizationContext = (): TaskSelectOrganizationCtx => {
+ const context = useContext(TaskSelectOrganizationContext);
+
+ if (context === null) {
+ throw new Error(
+ 'Clerk: useTaskSelectOrganizationContext called outside of the mounted TaskSelectOrganization component.',
+ );
+ }
+
+ return context;
+};
diff --git a/packages/clerk-js/src/ui/elements/contexts/index.tsx b/packages/clerk-js/src/ui/elements/contexts/index.tsx
index 7204a7a14d2..ea1ed35f8e2 100644
--- a/packages/clerk-js/src/ui/elements/contexts/index.tsx
+++ b/packages/clerk-js/src/ui/elements/contexts/index.tsx
@@ -99,7 +99,8 @@ export type FlowMetadata = {
| 'pricingTable'
| 'apiKeys'
| 'oauthConsent'
- | 'subscriptionDetails';
+ | 'subscriptionDetails'
+ | 'taskSelectOrganization';
part?:
| 'start'
| 'emailCode'
diff --git a/packages/clerk-js/src/ui/lazyModules/components.ts b/packages/clerk-js/src/ui/lazyModules/components.ts
index daa94dc0368..a4072adf412 100644
--- a/packages/clerk-js/src/ui/lazyModules/components.ts
+++ b/packages/clerk-js/src/ui/lazyModules/components.ts
@@ -20,6 +20,8 @@ const componentImportPaths = {
PricingTable: () => import(/* webpackChunkName: "pricingTable" */ '../components/PricingTable'),
Checkout: () => import(/* webpackChunkName: "checkout" */ '../components/Checkout'),
SessionTasks: () => import(/* webpackChunkName: "sessionTasks" */ '../components/SessionTasks'),
+ TaskSelectOrganization: () =>
+ import(/* webpackChunkName: "taskSelectOrganization" */ '../components/SessionTasks/tasks/TaskSelectOrganization'),
PlanDetails: () => import(/* webpackChunkName: "planDetails" */ '../components/Plans/PlanDetails'),
SubscriptionDetails: () => import(/* webpackChunkName: "subscriptionDetails" */ '../components/SubscriptionDetails'),
APIKeys: () => import(/* webpackChunkName: "apiKeys" */ '../components/ApiKeys/ApiKeys'),
@@ -103,6 +105,10 @@ export const APIKeys = lazy(() => componentImportPaths.APIKeys().then(module =>
export const Checkout = lazy(() => componentImportPaths.Checkout().then(module => ({ default: module.Checkout })));
+export const TaskSelectOrganization = lazy(() =>
+ componentImportPaths.TaskSelectOrganization().then(module => ({ default: module.TaskSelectOrganization })),
+);
+
export const PlanDetails = lazy(() =>
componentImportPaths.PlanDetails().then(module => ({ default: module.PlanDetails })),
);
@@ -149,6 +155,7 @@ export const ClerkComponents = {
APIKeys,
OAuthConsent,
SubscriptionDetails,
+ TaskSelectOrganization,
};
export type ClerkComponentName = keyof typeof ClerkComponents;
diff --git a/packages/clerk-js/src/ui/types.ts b/packages/clerk-js/src/ui/types.ts
index 9673d239350..c3f4454ffd7 100644
--- a/packages/clerk-js/src/ui/types.ts
+++ b/packages/clerk-js/src/ui/types.ts
@@ -18,24 +18,25 @@ import type {
SignUpFallbackRedirectUrl,
SignUpForceRedirectUrl,
SignUpProps,
+ TaskSelectOrganizationProps,
UserButtonProps,
UserProfileProps,
WaitlistProps,
} from '@clerk/types';
export type {
+ __internal_OAuthConsentProps,
+ __internal_UserVerificationProps,
+ CreateOrganizationProps,
GoogleOneTapProps,
+ OrganizationListProps,
+ OrganizationProfileProps,
+ OrganizationSwitcherProps,
SignInProps,
SignUpProps,
UserButtonProps,
UserProfileProps,
- OrganizationSwitcherProps,
- OrganizationProfileProps,
- CreateOrganizationProps,
- OrganizationListProps,
WaitlistProps,
- __internal_UserVerificationProps,
- __internal_OAuthConsentProps,
};
export type AvailableComponentProps =
@@ -53,7 +54,8 @@ export type AvailableComponentProps =
| __internal_UserVerificationProps
| __internal_SubscriptionDetailsProps
| __internal_PlanDetailsProps
- | APIKeysProps;
+ | APIKeysProps
+ | TaskSelectOrganizationProps;
type ComponentMode = 'modal' | 'mounted';
type SignInMode = 'modal' | 'redirect';
@@ -132,9 +134,12 @@ export type CheckoutCtx = __internal_CheckoutProps & {
} & NewSubscriptionRedirectUrl;
export type SessionTasksCtx = {
- nextTask: () => Promise;
- redirectUrlComplete?: string;
- currentTaskContainer: React.RefObject | null;
+ redirectUrlComplete: string;
+ currentTaskContainer?: React.RefObject | null;
+};
+
+export type TaskSelectOrganizationCtx = TaskSelectOrganizationProps & {
+ componentName: 'TaskSelectOrganization';
};
export type OAuthConsentCtx = __internal_OAuthConsentProps & {
@@ -166,5 +171,6 @@ export type AvailableComponentCtx =
| APIKeysCtx
| OAuthConsentCtx
| SubscriptionDetailsCtx
- | PlanDetailsCtx;
+ | PlanDetailsCtx
+ | TaskSelectOrganizationCtx;
export type AvailableComponentName = AvailableComponentCtx['componentName'];
diff --git a/packages/nextjs/src/client-boundary/uiComponents.tsx b/packages/nextjs/src/client-boundary/uiComponents.tsx
index 38f0a9be4f9..50e0365c316 100644
--- a/packages/nextjs/src/client-boundary/uiComponents.tsx
+++ b/packages/nextjs/src/client-boundary/uiComponents.tsx
@@ -12,18 +12,19 @@ import React from 'react';
import { useEnforceCorrectRoutingProps } from './hooks/useEnforceRoutingProps';
export {
+ APIKeys,
CreateOrganization,
+ GoogleOneTap,
OrganizationList,
OrganizationSwitcher,
+ PricingTable,
SignInButton,
SignInWithMetamaskButton,
SignOutButton,
SignUpButton,
+ TaskSelectOrganization,
UserButton,
- GoogleOneTap,
Waitlist,
- PricingTable,
- APIKeys,
} from '@clerk/clerk-react';
// The assignment of UserProfile with BaseUserProfile props is used
diff --git a/packages/nextjs/src/index.ts b/packages/nextjs/src/index.ts
index f57260044ac..b3f31c65cb5 100644
--- a/packages/nextjs/src/index.ts
+++ b/packages/nextjs/src/index.ts
@@ -4,10 +4,10 @@
*/
export {
AuthenticateWithRedirectCallback,
- ClerkLoaded,
- ClerkLoading,
ClerkDegraded,
ClerkFailed,
+ ClerkLoaded,
+ ClerkLoading,
RedirectToCreateOrganization,
RedirectToOrganizationProfile,
RedirectToSignIn,
@@ -20,22 +20,23 @@ export {
* If you do, app router will break.
*/
export {
+ APIKeys,
CreateOrganization,
+ GoogleOneTap,
OrganizationList,
OrganizationProfile,
OrganizationSwitcher,
+ PricingTable,
SignIn,
SignInButton,
SignInWithMetamaskButton,
SignOutButton,
SignUp,
SignUpButton,
+ TaskSelectOrganization,
UserButton,
UserProfile,
- GoogleOneTap,
Waitlist,
- PricingTable,
- APIKeys,
} from './client-boundary/uiComponents';
/**
@@ -48,12 +49,12 @@ export {
useEmailLink,
useOrganization,
useOrganizationList,
+ useReverification,
useSession,
useSessionList,
useSignIn,
useSignUp,
useUser,
- useReverification,
} from './client-boundary/hooks';
/**
diff --git a/packages/react-router/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/react-router/src/__tests__/__snapshots__/exports.test.ts.snap
index 8ad881f8b90..cf341e7e63b 100644
--- a/packages/react-router/src/__tests__/__snapshots__/exports.test.ts.snap
+++ b/packages/react-router/src/__tests__/__snapshots__/exports.test.ts.snap
@@ -29,6 +29,7 @@ exports[`root public exports > should not change unexpectedly 1`] = `
"SignUpButton",
"SignedIn",
"SignedOut",
+ "TaskSelectOrganization",
"UserButton",
"UserProfile",
"Waitlist",
diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts
index a905a3aea0b..1bf25df2516 100644
--- a/packages/react/src/components/index.ts
+++ b/packages/react/src/components/index.ts
@@ -1,37 +1,38 @@
export {
- SignUp,
- SignIn,
- UserProfile,
- UserButton,
- OrganizationSwitcher,
- OrganizationProfile,
+ APIKeys,
CreateOrganization,
- OrganizationList,
GoogleOneTap,
- Waitlist,
+ OrganizationList,
+ OrganizationProfile,
+ OrganizationSwitcher,
PricingTable,
- APIKeys,
+ SignIn,
+ SignUp,
+ TaskSelectOrganization,
+ UserButton,
+ UserProfile,
+ Waitlist,
} from './uiComponents';
export {
- ClerkLoaded,
- ClerkLoading,
+ AuthenticateWithRedirectCallback,
ClerkDegraded,
ClerkFailed,
- SignedOut,
- SignedIn,
+ ClerkLoaded,
+ ClerkLoading,
Protect,
+ RedirectToCreateOrganization,
+ RedirectToOrganizationProfile,
RedirectToSignIn,
RedirectToSignUp,
RedirectToUserProfile,
- AuthenticateWithRedirectCallback,
- RedirectToCreateOrganization,
- RedirectToOrganizationProfile,
+ SignedIn,
+ SignedOut,
} from './controlComponents';
export type { ProtectProps } from './controlComponents';
export { SignInButton } from './SignInButton';
-export { SignUpButton } from './SignUpButton';
-export { SignOutButton } from './SignOutButton';
export { SignInWithMetamaskButton } from './SignInWithMetamaskButton';
+export { SignOutButton } from './SignOutButton';
+export { SignUpButton } from './SignUpButton';
diff --git a/packages/react/src/components/uiComponents.tsx b/packages/react/src/components/uiComponents.tsx
index 5e628d65789..d3b6242b7de 100644
--- a/packages/react/src/components/uiComponents.tsx
+++ b/packages/react/src/components/uiComponents.tsx
@@ -9,6 +9,7 @@ import type {
PricingTableProps,
SignInProps,
SignUpProps,
+ TaskSelectOrganizationProps,
UserButtonProps,
UserProfileProps,
WaitlistProps,
@@ -633,3 +634,31 @@ export const APIKeys = withClerk(
},
{ component: 'ApiKeys', renderWhileLoading: true },
);
+
+export const TaskSelectOrganization = withClerk(
+ ({ clerk, component, fallback, ...props }: WithClerkProp) => {
+ const mountingStatus = useWaitForComponentMount(component);
+ const shouldShowFallback = mountingStatus === 'rendering' || !clerk.loaded;
+
+ const rendererRootProps = {
+ ...(shouldShowFallback && fallback && { style: { display: 'none' } }),
+ };
+
+ return (
+ <>
+ {shouldShowFallback && fallback}
+ {clerk.loaded && (
+
+ )}
+ >
+ );
+ },
+ { component: 'TaskSelectOrganization', renderWhileLoading: true },
+);
diff --git a/packages/react/src/isomorphicClerk.ts b/packages/react/src/isomorphicClerk.ts
index 1250c68c739..8e7deb0ce02 100644
--- a/packages/react/src/isomorphicClerk.ts
+++ b/packages/react/src/isomorphicClerk.ts
@@ -44,6 +44,7 @@ import type {
SignUpProps,
SignUpRedirectOptions,
SignUpResource,
+ TaskSelectOrganizationProps,
UnsubscribeCallback,
UserButtonProps,
UserProfileProps,
@@ -141,6 +142,7 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
private premountPricingTableNodes = new Map();
private premountApiKeysNodes = new Map();
private premountOAuthConsentNodes = new Map();
+ private premountTaskSelectOrganizationNodes = new Map();
// A separate Map of `addListener` method calls to handle multiple listeners.
private premountAddListenerCalls = new Map<
ListenerCallback,
@@ -631,6 +633,10 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
clerkjs.__internal_mountOAuthConsent(node, props);
});
+ this.premountTaskSelectOrganizationNodes.forEach((props, node) => {
+ clerkjs.mountTaskSelectOrganization(node, props);
+ });
+
/**
* Only update status in case `clerk.status` is missing. In any other case, `clerk-js` should be the orchestrator.
*/
@@ -1128,6 +1134,22 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}
};
+ mountTaskSelectOrganization = (node: HTMLDivElement, props?: TaskSelectOrganizationProps): void => {
+ if (this.clerkjs && this.loaded) {
+ this.clerkjs.mountTaskSelectOrganization(node, props);
+ } else {
+ this.premountTaskSelectOrganizationNodes.set(node, props);
+ }
+ };
+
+ unmountTaskSelectOrganization = (node: HTMLDivElement): void => {
+ if (this.clerkjs && this.loaded) {
+ this.clerkjs.unmountTaskSelectOrganization(node);
+ } else {
+ this.premountTaskSelectOrganizationNodes.delete(node);
+ }
+ };
+
addListener = (listener: ListenerCallback): UnsubscribeCallback => {
if (this.clerkjs) {
return this.clerkjs.addListener(listener);
diff --git a/packages/remix/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/remix/src/__tests__/__snapshots__/exports.test.ts.snap
index c642b325a6e..ec0a68f23ca 100644
--- a/packages/remix/src/__tests__/__snapshots__/exports.test.ts.snap
+++ b/packages/remix/src/__tests__/__snapshots__/exports.test.ts.snap
@@ -30,6 +30,7 @@ exports[`root public exports > should not change unexpectedly 1`] = `
"SignUpButton",
"SignedIn",
"SignedOut",
+ "TaskSelectOrganization",
"UserButton",
"UserProfile",
"Waitlist",
diff --git a/packages/tanstack-react-start/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/tanstack-react-start/src/__tests__/__snapshots__/exports.test.ts.snap
index be0a59fc5f9..2bf005468b4 100644
--- a/packages/tanstack-react-start/src/__tests__/__snapshots__/exports.test.ts.snap
+++ b/packages/tanstack-react-start/src/__tests__/__snapshots__/exports.test.ts.snap
@@ -41,6 +41,7 @@ exports[`root public exports > should not change unexpectedly 1`] = `
"SignUpButton",
"SignedIn",
"SignedOut",
+ "TaskSelectOrganization",
"UserButton",
"UserProfile",
"Waitlist",
diff --git a/packages/types/src/appearance.ts b/packages/types/src/appearance.ts
index 4e39e02ebe8..e5333b5c7c5 100644
--- a/packages/types/src/appearance.ts
+++ b/packages/types/src/appearance.ts
@@ -956,6 +956,7 @@ export type PlanDetailTheme = Theme;
export type SubscriptionDetailsTheme = Theme;
export type APIKeysTheme = Theme;
export type OAuthConsentTheme = Theme;
+export type TaskSelectOrganizationTheme = Theme;
type GlobalAppearanceOptions = {
/**
@@ -1028,4 +1029,8 @@ export type Appearance = T &
* Theme overrides that only apply to the `` component
*/
__internal_oauthConsent?: T;
+ /**
+ * Theme overrides that only apply to the `` component
+ */
+ taskSelectOrganization?: T;
};
diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts
index 652e06174de..af12ec8df19 100644
--- a/packages/types/src/clerk.ts
+++ b/packages/types/src/clerk.ts
@@ -14,6 +14,7 @@ import type {
SignInTheme,
SignUpTheme,
SubscriptionDetailsTheme,
+ TaskSelectOrganizationTheme,
UserButtonTheme,
UserProfileTheme,
UserVerificationTheme,
@@ -557,6 +558,21 @@ export interface Clerk {
*/
__internal_unmountOAuthConsent: (targetNode: HTMLDivElement) => void;
+ /**
+ * Mounts a TaskSelectOrganization component at the target element.
+ * @param targetNode Target node to mount the TaskSelectOrganization component.
+ * @param props configuration parameters.
+ */
+ mountTaskSelectOrganization: (targetNode: HTMLDivElement, props?: TaskSelectOrganizationProps) => void;
+
+ /**
+ * Unmount a TaskSelectOrganization component from the target element.
+ * If there is no component mounted at the target node, results in a noop.
+ *
+ * @param targetNode Target node to unmount the TaskSelectOrganization component from.
+ */
+ unmountTaskSelectOrganization: (targetNode: HTMLDivElement) => void;
+
/**
* @internal
* Loads Stripe libraries for commerce functionality
@@ -2036,6 +2052,14 @@ export type SignUpButtonProps = (SignUpButtonPropsModal | ButtonPropsRedirect) &
| 'oauthFlow'
>;
+export type TaskSelectOrganizationProps = {
+ /**
+ * Full URL or path to navigate to after successfully resolving all tasks
+ */
+ redirectUrlComplete: string;
+ appearance?: TaskSelectOrganizationTheme;
+};
+
export type CreateOrganizationInvitationParams = {
emailAddress: string;
role: OrganizationCustomRoleKey;