Skip to content

Commit 64a35f7

Browse files
authored
feat(clerk-js,shared): Export useOrganizationCreationDefaults hook (#7690)
1 parent aebb8df commit 64a35f7

File tree

16 files changed

+238
-8
lines changed

16 files changed

+238
-8
lines changed

.changeset/blue-books-return.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
'@clerk/nextjs': minor
4+
'@clerk/shared': minor
5+
'@clerk/clerk-react': minor
6+
---
7+
8+
Export `useOrganizationCreationDefaults` hook to fetch suggested organization name and logo from default naming rules

packages/clerk-js/src/ui/components/SessionTasks/tasks/TaskChooseOrganization/index.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import { useClerk, useSession, useUser } from '@clerk/shared/react';
1+
import { useClerk, useOrganizationCreationDefaults, useSession, useUser } from '@clerk/shared/react';
22
import type { OrganizationCreationDefaultsResource } from '@clerk/shared/types';
33
import { useState } from 'react';
44

5-
import { useEnvironment, useSignOutContext, withCoreSessionSwitchGuard } from '@/ui/contexts';
5+
import { useSignOutContext, withCoreSessionSwitchGuard } from '@/ui/contexts';
66
import { descriptors, Flex, Flow, localizationKeys, Spinner } from '@/ui/customizables';
77
import { Card } from '@/ui/elements/Card';
88
import { withCardStateProvider } from '@/ui/elements/contexts';
99
import { Header } from '@/ui/elements/Header';
10-
import { useFetch } from '@/ui/hooks';
1110
import { useMultipleSessions } from '@/ui/hooks/useMultipleSessions';
1211
import { useOrganizationListInView } from '@/ui/hooks/useOrganizationListInView';
1312

@@ -18,11 +17,7 @@ import { CreateOrganizationScreen } from './CreateOrganizationScreen';
1817
const TaskChooseOrganizationInternal = () => {
1918
const { user } = useUser();
2019
const { userMemberships, userSuggestions, userInvitations } = useOrganizationListInView();
21-
const { organizationSettings } = useEnvironment();
22-
const organizationCreationDefaults = useFetch(
23-
organizationSettings.organizationCreationDefaults?.enabled ? user?.getOrganizationCreationDefaults : undefined,
24-
'organization-creation-defaults',
25-
);
20+
const organizationCreationDefaults = useOrganizationCreationDefaults();
2621

2722
const isLoading =
2823
userMemberships?.isLoading ||

packages/nextjs/src/client-boundary/hooks.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export {
44
useClerk,
55
useEmailLink,
66
useOrganization,
7+
useOrganizationCreationDefaults,
78
useOrganizationList,
89
useSession,
910
useSessionList,
@@ -12,6 +13,7 @@ export {
1213
useUser,
1314
useReverification,
1415
} from '@clerk/clerk-react';
16+
export type { UseOrganizationCreationDefaultsParams, UseOrganizationCreationDefaultsReturn } from '@clerk/clerk-react';
1517

1618
export {
1719
isClerkAPIResponseError,

packages/nextjs/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export {
5151
useClerk,
5252
useEmailLink,
5353
useOrganization,
54+
useOrganizationCreationDefaults,
5455
useOrganizationList,
5556
useReverification,
5657
useSession,
@@ -59,6 +60,10 @@ export {
5960
useSignUp,
6061
useUser,
6162
} from './client-boundary/hooks';
63+
export type {
64+
UseOrganizationCreationDefaultsParams,
65+
UseOrganizationCreationDefaultsReturn,
66+
} from './client-boundary/hooks';
6267

6368
/**
6469
* Conditionally export components that exhibit different behavior

packages/react-router/src/__tests__/__snapshots__/exports.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ exports[`root public exports > should not change unexpectedly 1`] = `
5252
"useClerk",
5353
"useEmailLink",
5454
"useOrganization",
55+
"useOrganizationCreationDefaults",
5556
"useOrganizationList",
5657
"useReverification",
5758
"useSession",

packages/react/src/hooks/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { useSignUp } from './useSignUp';
55
export {
66
useClerk,
77
useOrganization,
8+
useOrganizationCreationDefaults,
89
useOrganizationList,
910
useSessionList,
1011
useUser,
@@ -16,3 +17,4 @@ export {
1617
__experimental_PaymentElementProvider,
1718
__experimental_PaymentElement,
1819
} from '@clerk/shared/react';
20+
export type { UseOrganizationCreationDefaultsParams, UseOrganizationCreationDefaultsReturn } from '@clerk/shared/react';

packages/remix/src/__tests__/__snapshots__/exports.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ exports[`root public exports > should not change unexpectedly 1`] = `
4747
"useClerk",
4848
"useEmailLink",
4949
"useOrganization",
50+
"useOrganizationCreationDefaults",
5051
"useOrganizationList",
5152
"useReverification",
5253
"useSession",

packages/shared/src/react/hooks/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
export { assertContextExists, createContextAndHook } from './createContextAndHook';
22
export { useAPIKeys as __experimental_useAPIKeys } from './useAPIKeys';
33
export { useOrganization } from './useOrganization';
4+
export { useOrganizationCreationDefaults } from './useOrganizationCreationDefaults';
5+
export type {
6+
UseOrganizationCreationDefaultsParams,
7+
UseOrganizationCreationDefaultsReturn,
8+
} from './useOrganizationCreationDefaults';
49
export { useOrganizationList } from './useOrganizationList';
510
export { useAttemptToEnableOrganizations } from './useAttemptToEnableOrganizations';
611
export { useSafeLayoutEffect } from './useSafeLayoutEffect';
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { eventMethodCalled } from '../../telemetry/events/method-called';
2+
import type { EnvironmentResource } from '../../types/environment';
3+
import { defineKeepPreviousDataFn } from '../clerk-rq/keep-previous-data';
4+
import { useClerkQuery } from '../clerk-rq/useQuery';
5+
import { useClerkInstanceContext, useUserContext } from '../contexts';
6+
import { useOrganizationCreationDefaultsCacheKeys } from './useOrganizationCreationDefaults.shared';
7+
import type {
8+
UseOrganizationCreationDefaultsParams,
9+
UseOrganizationCreationDefaultsReturn,
10+
} from './useOrganizationCreationDefaults.types';
11+
12+
/**
13+
* The `useOrganizationCreationDefaults()` hook retrieves the organization creation defaults for the current user.
14+
*
15+
* @example
16+
* ### Basic usage
17+
*
18+
* ```tsx
19+
* import { useOrganizationCreationDefaults } from '@clerk/clerk-react'
20+
*
21+
* export default function CreateOrganizationForm() {
22+
* const { data, isLoading } = useOrganizationCreationDefaults()
23+
*
24+
* if (isLoading) return <div>Loading...</div>
25+
*
26+
* return (
27+
* <form>
28+
* <input defaultValue={data?.form.name} placeholder="Organization name" />
29+
* <input defaultValue={data?.form.slug} placeholder="Slug" />
30+
* <button type="submit">Create</button>
31+
* </form>
32+
* )
33+
* }
34+
* ```
35+
*/
36+
export function useOrganizationCreationDefaults(
37+
params: UseOrganizationCreationDefaultsParams = {},
38+
): UseOrganizationCreationDefaultsReturn {
39+
const { keepPreviousData = true, enabled = true } = params;
40+
const clerk = useClerkInstanceContext();
41+
const user = useUserContext();
42+
43+
// @ts-expect-error `__unstable__environment` is not typed
44+
const environment = clerk.__unstable__environment as unknown as EnvironmentResource | null | undefined;
45+
const featureEnabled = environment?.organizationSettings?.organizationCreationDefaults?.enabled ?? false;
46+
47+
clerk.telemetry?.record(eventMethodCalled('useOrganizationCreationDefaults'));
48+
49+
const { queryKey } = useOrganizationCreationDefaultsCacheKeys({ userId: user?.id ?? null });
50+
51+
const queryEnabled = Boolean(user) && enabled && featureEnabled && clerk.loaded;
52+
53+
const query = useClerkQuery({
54+
queryKey,
55+
queryFn: user?.getOrganizationCreationDefaults,
56+
enabled: queryEnabled,
57+
placeholderData: defineKeepPreviousDataFn(keepPreviousData),
58+
});
59+
60+
return {
61+
data: query.data,
62+
error: (query.error ?? null) as UseOrganizationCreationDefaultsReturn['error'],
63+
isLoading: query.isLoading,
64+
isFetching: query.isFetching,
65+
};
66+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { useMemo } from 'react';
2+
3+
import { STABLE_KEYS } from '../stable-keys';
4+
import { createCacheKeys } from './createCacheKeys';
5+
6+
export function useOrganizationCreationDefaultsCacheKeys(params: { userId: string | null }) {
7+
const { userId } = params;
8+
return useMemo(() => {
9+
return createCacheKeys({
10+
stablePrefix: STABLE_KEYS.ORGANIZATION_CREATION_DEFAULTS_KEY,
11+
authenticated: Boolean(userId),
12+
tracked: {
13+
userId: userId ?? null,
14+
},
15+
untracked: {
16+
args: {},
17+
},
18+
});
19+
}, [userId]);
20+
}

0 commit comments

Comments
 (0)