Skip to content

Commit a06b4be

Browse files
committed
Backport changes
1 parent 583f7a9 commit a06b4be

File tree

12 files changed

+146
-7
lines changed

12 files changed

+146
-7
lines changed

packages/chrome-extension/src/__tests__/__snapshots__/exports.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ exports[`public exports > should not include a breaking change 1`] = `
3535
"useClerk",
3636
"useEmailLink",
3737
"useOrganization",
38+
"useOrganizationCreationDefaults",
3839
"useOrganizationList",
3940
"useReverification",
4041
"useSession",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export {
66
useEmailLink,
77
useOrganization,
88
useOrganizationList,
9+
useOrganizationCreationDefaults,
910
useSession,
1011
useSessionList,
1112
useSignIn,

packages/nextjs/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export {
5252
useClerk,
5353
useEmailLink,
5454
useOrganization,
55+
useOrganizationCreationDefaults,
5556
useOrganizationList,
5657
useReverification,
5758
useSession,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ exports[`root public exports > should not change unexpectedly 1`] = `
5959
"useClerk",
6060
"useEmailLink",
6161
"useOrganization",
62+
"useOrganizationCreationDefaults",
6263
"useOrganizationList",
6364
"useReverification",
6465
"useSession",

packages/react/src/hooks/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export { useSignIn, useSignUp, useWaitlist } from './useClerkSignal';
44
export {
55
useClerk,
66
useOrganization,
7+
useOrganizationCreationDefaults,
78
useOrganizationList,
89
useSessionList,
910
useUser,
@@ -15,3 +16,4 @@ export {
1516
__experimental_PaymentElementProvider,
1617
__experimental_PaymentElement,
1718
} from '@clerk/shared/react';
19+
export type { UseOrganizationCreationDefaultsParams, UseOrganizationCreationDefaultsReturn } from '@clerk/shared/react';

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.types';
49
export { useOrganizationList } from './useOrganizationList';
510
export { useAttemptToEnableOrganizations } from './useAttemptToEnableOrganizations';
611
export { useSafeLayoutEffect } from './useSafeLayoutEffect';
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+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 { useAssertWrappedByClerkProvider, useClerkInstanceContext, useUserContext } from '../contexts';
6+
import { useOrganizationCreationDefaultsCacheKeys } from './useOrganizationCreationDefaults.shared';
7+
import type {
8+
UseOrganizationCreationDefaultsParams,
9+
UseOrganizationCreationDefaultsReturn,
10+
} from './useOrganizationCreationDefaults.types';
11+
12+
const HOOK_NAME = 'useOrganizationCreationDefaults';
13+
14+
/**
15+
* The `useOrganizationCreationDefaults()` hook retrieves the organization creation defaults for the current user.
16+
*
17+
* @example
18+
* ### Basic usage
19+
*
20+
* ```tsx
21+
* import { useOrganizationCreationDefaults } from '@clerk/clerk-react'
22+
*
23+
* export default function CreateOrganizationForm() {
24+
* const { data, isLoading } = useOrganizationCreationDefaults()
25+
*
26+
* if (isLoading) return <div>Loading...</div>
27+
*
28+
* return (
29+
* <form>
30+
* <input defaultValue={data?.form.name} placeholder="Organization name" />
31+
* <input defaultValue={data?.form.slug} placeholder="Slug" />
32+
* <button type="submit">Create</button>
33+
* </form>
34+
* )
35+
* }
36+
* ```
37+
*/
38+
export function useOrganizationCreationDefaults(
39+
params: UseOrganizationCreationDefaultsParams = {},
40+
): UseOrganizationCreationDefaultsReturn {
41+
useAssertWrappedByClerkProvider(HOOK_NAME);
42+
43+
const { keepPreviousData = true, enabled = true } = params;
44+
const clerk = useClerkInstanceContext();
45+
const user = useUserContext();
46+
47+
// @ts-expect-error `__unstable__environment` is not typed
48+
const environment = clerk.__unstable__environment as unknown as EnvironmentResource | null | undefined;
49+
const featureEnabled = environment?.organizationSettings?.organizationCreationDefaults?.enabled ?? false;
50+
51+
clerk.telemetry?.record(eventMethodCalled(HOOK_NAME));
52+
53+
const { queryKey } = useOrganizationCreationDefaultsCacheKeys({ userId: user?.id ?? null });
54+
55+
const queryEnabled = Boolean(user) && enabled && featureEnabled && clerk.loaded;
56+
57+
const query = useClerkQuery({
58+
queryKey,
59+
queryFn: user?.getOrganizationCreationDefaults,
60+
enabled: queryEnabled,
61+
placeholderData: defineKeepPreviousDataFn(keepPreviousData),
62+
});
63+
64+
return {
65+
data: query.data,
66+
error: (query.error ?? null) as UseOrganizationCreationDefaultsReturn['error'],
67+
isLoading: query.isLoading,
68+
isFetching: query.isFetching,
69+
};
70+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { ClerkAPIResponseError } from '../../errors/clerkApiResponseError';
2+
import type { OrganizationCreationDefaultsResource } from '../../types';
3+
4+
export type UseOrganizationCreationDefaultsParams = {
5+
/**
6+
* If true, the previous data will be kept in the cache until new data is fetched.
7+
*
8+
* @default true
9+
*/
10+
keepPreviousData?: boolean;
11+
/**
12+
* If `true`, a request will be triggered when the hook is mounted.
13+
*
14+
* @default true
15+
*/
16+
enabled?: boolean;
17+
};
18+
19+
export type UseOrganizationCreationDefaultsReturn = {
20+
/**
21+
* The organization creation defaults resource, `undefined` before the first fetch, or `null` if not available.
22+
*/
23+
data: OrganizationCreationDefaultsResource | undefined | null;
24+
/**
25+
* Any error that occurred during the data fetch, or `null` if no error occurred.
26+
*/
27+
error: ClerkAPIResponseError | null;
28+
/**
29+
* A boolean that indicates whether the initial data is still being fetched.
30+
*/
31+
isLoading: boolean;
32+
/**
33+
* A boolean that indicates whether any request is still in flight, including background updates.
34+
*/
35+
isFetching: boolean;
36+
};

packages/shared/src/react/stable-keys.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const INVITATIONS_KEY = 'invitations';
1212
// Keys for `useAPIKeys`
1313
const API_KEYS_KEY = 'apiKeys';
1414

15+
// Keys for `useOrganizationCreationDefaults`
16+
const ORGANIZATION_CREATION_DEFAULTS_KEY = 'organizationCreationDefaults';
17+
1518
// Keys for `usePlans`
1619
const PLANS_KEY = 'billing-plans';
1720

@@ -48,6 +51,9 @@ export const STABLE_KEYS = {
4851

4952
// Keys for `useAPIKeys`
5053
API_KEYS_KEY,
54+
55+
// Keys for `useOrganizationCreationDefaults`
56+
ORGANIZATION_CREATION_DEFAULTS_KEY,
5157
} as const;
5258

5359
export type ResourceCacheStableKey = (typeof STABLE_KEYS)[keyof typeof STABLE_KEYS];

0 commit comments

Comments
 (0)