@sanity/sdk-react 0.0.0-alpha.18 → 0.0.0-alpha.2

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.
Files changed (113) hide show
  1. package/README.md +54 -111
  2. package/dist/_chunks-es/useLogOut.js +24 -53
  3. package/dist/_chunks-es/useLogOut.js.map +1 -1
  4. package/dist/assets/bundle-CcAyERuZ.css +11 -0
  5. package/dist/components.d.ts +172 -69
  6. package/dist/components.js +277 -197
  7. package/dist/components.js.map +1 -1
  8. package/dist/hooks.d.ts +49 -4307
  9. package/dist/hooks.js +67 -646
  10. package/dist/hooks.js.map +1 -1
  11. package/dist/index.d.ts +3 -3
  12. package/dist/index.js +2 -10
  13. package/dist/index.js.map +1 -1
  14. package/package.json +42 -36
  15. package/src/_exports/components.ts +13 -3
  16. package/src/_exports/hooks.ts +2 -45
  17. package/src/_exports/index.ts +10 -1
  18. package/src/components/DocumentGridLayout/DocumentGridLayout.stories.tsx +113 -0
  19. package/src/components/DocumentGridLayout/DocumentGridLayout.test.tsx +42 -0
  20. package/src/components/DocumentGridLayout/DocumentGridLayout.tsx +21 -0
  21. package/src/components/DocumentListLayout/DocumentListLayout.stories.tsx +105 -0
  22. package/src/components/DocumentListLayout/DocumentListLayout.test.tsx +42 -0
  23. package/src/components/DocumentListLayout/DocumentListLayout.tsx +12 -0
  24. package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.md +49 -0
  25. package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.stories.tsx +39 -0
  26. package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.test.tsx +30 -0
  27. package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.tsx +171 -0
  28. package/src/components/Login/LoginLinks.test.tsx +12 -3
  29. package/src/components/Login/LoginLinks.tsx +29 -14
  30. package/src/components/auth/AuthBoundary.test.tsx +17 -4
  31. package/src/components/auth/AuthBoundary.tsx +4 -20
  32. package/src/components/auth/Login.test.tsx +16 -2
  33. package/src/components/auth/Login.tsx +30 -11
  34. package/src/components/auth/LoginCallback.test.tsx +17 -2
  35. package/src/components/auth/LoginCallback.tsx +10 -5
  36. package/src/components/auth/LoginError.test.tsx +17 -2
  37. package/src/components/auth/LoginError.tsx +16 -11
  38. package/src/components/auth/LoginFooter.test.tsx +16 -2
  39. package/src/components/auth/LoginFooter.tsx +24 -8
  40. package/src/components/auth/LoginLayout.test.tsx +16 -2
  41. package/src/components/auth/LoginLayout.tsx +38 -8
  42. package/src/{context → components/context}/SanityProvider.test.tsx +2 -2
  43. package/src/components/context/SanityProvider.tsx +42 -0
  44. package/src/css/css.config.js +220 -0
  45. package/src/css/paramour.css +2347 -0
  46. package/src/css/styles.css +11 -0
  47. package/src/hooks/auth/useAuthState.tsx +5 -4
  48. package/src/hooks/auth/useAuthToken.tsx +1 -1
  49. package/src/hooks/auth/useCurrentUser.tsx +4 -27
  50. package/src/hooks/auth/useHandleCallback.tsx +0 -1
  51. package/src/hooks/auth/useLogOut.tsx +1 -1
  52. package/src/hooks/auth/useLoginUrls.tsx +0 -1
  53. package/src/hooks/client/useClient.test.tsx +130 -0
  54. package/src/hooks/client/useClient.ts +30 -8
  55. package/src/hooks/context/useSanityInstance.test.tsx +2 -2
  56. package/src/hooks/context/useSanityInstance.ts +8 -24
  57. package/src/hooks/documentCollection/useDocuments.test.ts +130 -0
  58. package/src/hooks/documentCollection/useDocuments.ts +87 -0
  59. package/src/hooks/helpers/createCallbackHook.tsx +2 -3
  60. package/src/hooks/helpers/createStateSourceHook.test.tsx +0 -66
  61. package/src/hooks/helpers/createStateSourceHook.tsx +10 -29
  62. package/src/hooks/preview/usePreview.test.tsx +10 -19
  63. package/src/hooks/preview/usePreview.tsx +13 -67
  64. package/dist/_chunks-es/SanityInstanceContext.js +0 -6
  65. package/dist/_chunks-es/SanityInstanceContext.js.map +0 -1
  66. package/dist/context.d.ts +0 -47
  67. package/dist/context.js +0 -15
  68. package/dist/context.js.map +0 -1
  69. package/src/_exports/context.ts +0 -2
  70. package/src/components/SDKProvider.test.tsx +0 -79
  71. package/src/components/SDKProvider.tsx +0 -42
  72. package/src/components/SanityApp.test.tsx +0 -156
  73. package/src/components/SanityApp.tsx +0 -90
  74. package/src/components/auth/authTestHelpers.tsx +0 -11
  75. package/src/components/utils.ts +0 -22
  76. package/src/context/SanityInstanceContext.ts +0 -4
  77. package/src/context/SanityProvider.tsx +0 -50
  78. package/src/hooks/_synchronous-groq-js.mjs +0 -4
  79. package/src/hooks/comlink/useFrameConnection.test.tsx +0 -157
  80. package/src/hooks/comlink/useFrameConnection.ts +0 -130
  81. package/src/hooks/comlink/useManageFavorite.test.ts +0 -106
  82. package/src/hooks/comlink/useManageFavorite.ts +0 -98
  83. package/src/hooks/comlink/useRecordDocumentHistoryEvent.test.ts +0 -77
  84. package/src/hooks/comlink/useRecordDocumentHistoryEvent.ts +0 -75
  85. package/src/hooks/comlink/useWindowConnection.test.ts +0 -125
  86. package/src/hooks/comlink/useWindowConnection.ts +0 -94
  87. package/src/hooks/datasets/useDatasets.ts +0 -37
  88. package/src/hooks/document/useApplyActions.test.ts +0 -25
  89. package/src/hooks/document/useApplyActions.ts +0 -74
  90. package/src/hooks/document/useDocument.test.ts +0 -81
  91. package/src/hooks/document/useDocument.ts +0 -107
  92. package/src/hooks/document/useDocumentEvent.test.ts +0 -63
  93. package/src/hooks/document/useDocumentEvent.ts +0 -54
  94. package/src/hooks/document/useDocumentSyncStatus.test.ts +0 -16
  95. package/src/hooks/document/useDocumentSyncStatus.ts +0 -30
  96. package/src/hooks/document/useEditDocument.test.ts +0 -179
  97. package/src/hooks/document/useEditDocument.ts +0 -195
  98. package/src/hooks/document/usePermissions.ts +0 -82
  99. package/src/hooks/infiniteList/useInfiniteList.test.tsx +0 -152
  100. package/src/hooks/infiniteList/useInfiniteList.ts +0 -174
  101. package/src/hooks/paginatedList/usePaginatedList.test.tsx +0 -259
  102. package/src/hooks/paginatedList/usePaginatedList.ts +0 -290
  103. package/src/hooks/projection/useProjection.test.tsx +0 -218
  104. package/src/hooks/projection/useProjection.ts +0 -135
  105. package/src/hooks/projects/useProject.ts +0 -45
  106. package/src/hooks/projects/useProjects.ts +0 -41
  107. package/src/hooks/query/useQuery.test.tsx +0 -188
  108. package/src/hooks/query/useQuery.ts +0 -103
  109. package/src/hooks/users/useUsers.test.ts +0 -163
  110. package/src/hooks/users/useUsers.ts +0 -107
  111. package/src/utils/getEnv.ts +0 -21
  112. package/src/version.ts +0 -8
  113. package/src/vite-env.d.ts +0 -10
package/README.md CHANGED
@@ -5,150 +5,93 @@
5
5
  <h1 align="center">Sanity SDK - React</h1>
6
6
  </p>
7
7
 
8
- React hooks for creating Sanity applications.
8
+ React components and hooks for creating Sanity applications.
9
9
 
10
- ## 💻 Installation
10
+ ## Installation
11
11
 
12
12
  ```bash
13
- npm i @sanity/sdk-react @sanity/sdk
13
+ npm i @sanity/sdk-react @sanity/sdk styled-components
14
14
  ```
15
15
 
16
- > 💡 Looking to build a Sanity application? Check out the [Quick Start](#quick-start) section.
17
-
18
- ## 📚 SDK Documentation
16
+ ## SDK Documentation
19
17
 
20
18
  See the [SDK Documentation](https://sdk-docs.sanity.dev) for more information.
21
19
 
22
- ## 🚀 Quick Start
20
+ ## Quick Start
23
21
 
24
22
  Here's how to implement your Sanity application:
25
23
 
26
- 1. Create a new React TypeScript project using the Sanity template
27
-
28
- ```bash
29
- pnpx sanity@latest init --template core-app
30
- cd my-content-os-app
31
- ```
32
-
33
- 2. Install dependencies
34
-
35
- ```bash
36
- npm i
37
- ```
38
-
39
- 3. Run the app
40
-
41
- ```bash
42
- npm run dev
43
- ```
44
-
45
- 4. Open the App in Sanity Dashboard with your organization ID
46
-
47
- ```
48
- https://core.sanity.io/<your-organization-id>?dev=localhost:5173
49
- ```
50
-
51
- 5. Overwrite the `src/App.tsx` file with the following code:
52
-
53
24
  ```tsx
54
- // src/App.tsx
55
- import {SanityConfig} from '@sanity/sdk'
56
- import {SanityApp} from '@sanity/sdk-react/components'
25
+ import {createSanityInstance} from '@sanity/sdk'
26
+ import {AuthBoundary, SanityProvider} from '@sanity/sdk-react/components'
57
27
  import {useCurrentUser, useLogOut} from '@sanity/sdk-react/hooks'
58
-
59
- import './App.css'
60
-
61
- const sanityConfig: SanityConfigs = [
62
- {
63
- projectId: '<your-project-id>',
64
- dataset: '<your-dataset>',
65
- },
66
- ]
28
+ import {Button, Flex, Spinner, Text, ThemeProvider} from '@sanity/ui'
29
+ import {buildTheme} from '@sanity/ui/theme'
30
+ import {Suspense} from 'react'
31
+
32
+ const theme = buildTheme({})
33
+ const sanityInstance = createSanityInstance({
34
+ projectId: '<your-project-id>',
35
+ dataset: '<your-dataset>',
36
+ // optional auth config set projectId and dataset to '' and authScope to 'org' for a global token
37
+ // auth: {
38
+ // authScope: 'org',
39
+ // ...
40
+ // },
41
+ })
67
42
 
68
43
  export function App(): JSX.Element {
69
44
  return (
70
- <SanityApp sanityConfigs={sanityConfigs}>
71
- <MyApp />
72
- </SanityApp>
45
+ <ThemeProvider theme={theme}>
46
+ <Suspense fallback={<Spinner />}>
47
+ <SanityProvider sanityInstance={sanityInstance}>
48
+ <AuthBoundary header={<Text>My Sanity App</Text>}>
49
+ <Authenticated />
50
+ </AuthBoundary>
51
+ </SanityProvider>
52
+ </Suspense>
53
+ </ThemeProvider>
73
54
  )
74
55
  }
75
56
 
76
- function MyApp() {
57
+ function Authenticated() {
77
58
  const currentUser = useCurrentUser()
78
59
  const logout = useLogOut()
79
60
 
80
61
  return (
81
- <div>
82
- <h1>Hello, {currentUser?.name}!</h1>
83
- <button onClick={logout}>Logout</button>
84
- </div>
62
+ <Flex direction="column" gap={2}>
63
+ <Text>Hello, {currentUser?.name}!</Text>
64
+ <Button text="Logout" onClick={logout} mode="ghost" />
65
+ </Flex>
85
66
  )
86
67
  }
87
-
88
- export default App
89
68
  ```
90
69
 
91
- 6. Overwrite the `src/App.css` file with the following code:
92
-
93
- ```css
94
- /* src/App.css */
95
- #root {
96
- margin: auto;
97
- }
98
-
99
- .sc-login-layout {
100
- min-height: 100vh;
101
- display: flex;
102
- background: #f3f3f3;
103
- }
104
-
105
- .sc-login-layout__container {
106
- margin: auto;
107
- padding: 2rem;
108
- }
109
-
110
- .sc-login-layout__card {
111
- background: white;
112
- padding: 2rem;
113
- }
70
+ ## Customizing your application
114
71
 
115
- .sc-login__title,
116
- .sc-login-callback {
117
- text-align: center;
118
- margin-bottom: 2rem;
119
- color: #333;
120
- }
72
+ If you would like to implement a custom look and feel, you can use the hooks in your own components.
121
73
 
122
- .sc-login-providers {
123
- display: flex;
124
- flex-direction: column;
125
- gap: 1rem;
126
- }
74
+ ## Available Hooks
127
75
 
128
- .sc-login-providers a {
129
- padding: 0.8rem;
130
- border: 1px solid #ddd;
131
- text-decoration: none;
132
- color: #333;
133
- text-align: center;
134
- }
76
+ - `useAuthState` - Get current authentication state
77
+ - `useCurrentUser` - Access the currently authenticated user
78
+ - `useAuthToken` - Access the authentication token
79
+ - `useLoginUrls` - Get OAuth login URLs
80
+ - `useLogOut` - Handle user logout
81
+ - `useSanityInstance` - Access the Sanity client instance
82
+ - and more...
135
83
 
136
- .sc-login-footer {
137
- margin-top: 2rem;
138
- text-align: center;
139
- }
84
+ ## TypeScript Support
140
85
 
141
- .sc-login-footer__links {
142
- list-style: none;
143
- padding: 0;
144
- display: flex;
145
- justify-content: center;
146
- gap: 1.5rem;
147
- }
86
+ This package includes TypeScript definitions. You can import types like:
148
87
 
149
- .sc-login-footer__link a {
150
- font-size: 0.9rem;
151
- }
88
+ ```tsx
89
+ import type {
90
+ SanityProviderProps,
91
+ AuthBoundaryProps,
92
+ LoginLayoutProps,
93
+ LoginErrorProps,
94
+ } from '@sanity/react'
152
95
  ```
153
96
 
154
97
  ## License
@@ -1,68 +1,39 @@
1
- import { getAuthState, handleCallback, getLoginUrlsState, fetchLoginUrls, logout } from "@sanity/sdk";
2
- import { c } from "react/compiler-runtime";
3
- import { useContext, useSyncExternalStore, useMemo } from "react";
4
- import { SanityInstanceContext } from "./SanityInstanceContext.js";
5
- const useSanityInstance = (resourceId) => {
6
- const $ = c(5), sanityInstance = useContext(SanityInstanceContext);
1
+ import { getAuthState, getLoginUrlsState, fetchLoginUrls, handleCallback, logout } from "@sanity/sdk";
2
+ import { createContext, useContext, useMemo, useSyncExternalStore, useCallback } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ const SanityInstanceContext = createContext(null), SanityProvider = ({ children, sanityInstance }) => /* @__PURE__ */ jsx(SanityInstanceContext.Provider, { value: sanityInstance, children }), useSanityInstance = () => {
5
+ const sanityInstance = useContext(SanityInstanceContext);
7
6
  if (!sanityInstance)
8
7
  throw new Error("useSanityInstance must be called from within the SanityProvider");
9
- if (sanityInstance.length === 0)
10
- throw new Error("No Sanity instances found");
11
- if (sanityInstance.length === 1 || !resourceId)
12
- return sanityInstance[0];
13
- if (!resourceId)
14
- throw new Error("resourceId is required when there are multiple Sanity instances");
15
- let t0;
16
- if ($[0] !== resourceId || $[1] !== sanityInstance) {
17
- let t1;
18
- $[3] !== resourceId ? (t1 = (inst) => inst.identity.resourceId === resourceId, $[3] = resourceId, $[4] = t1) : t1 = $[4], t0 = sanityInstance.find(t1), $[0] = resourceId, $[1] = sanityInstance, $[2] = t0;
19
- } else
20
- t0 = $[2];
21
- const instance = t0;
22
- if (!instance)
23
- throw new Error(`Sanity instance with resourceId ${resourceId} not found`);
24
- return instance;
8
+ return sanityInstance;
25
9
  };
26
- function createStateSourceHook(options) {
27
- const getState = typeof options == "function" ? options : options.getState, getResourceId = "getResourceId" in options ? options.getResourceId : void 0, suspense = "shouldSuspend" in options && "suspender" in options ? options : void 0;
28
- function useHook(...t0) {
29
- const $ = c(5), params = t0;
30
- let resourceId;
31
- if (getResourceId) {
32
- let t12;
33
- $[0] !== params ? (t12 = getResourceId(...params), $[0] = params, $[1] = t12) : t12 = $[1], resourceId = t12;
34
- }
35
- const instance = useSanityInstance(resourceId);
36
- if (suspense?.suspender && suspense?.shouldSuspend?.(instance, ...params))
37
- throw suspense.suspender(instance, ...params);
38
- let t1;
39
- $[2] !== instance || $[3] !== params ? (t1 = getState(instance, ...params), $[2] = instance, $[3] = params, $[4] = t1) : t1 = $[4];
40
- const state = t1;
41
- return useSyncExternalStore(state.subscribe, state.getCurrent);
10
+ function createStateSourceHook(stateSourceFactory) {
11
+ function useHook(...params) {
12
+ const instance = useSanityInstance(), { subscribe, getCurrent } = useMemo(
13
+ () => stateSourceFactory(instance, ...params),
14
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15
+ [instance, ...params]
16
+ );
17
+ return useSyncExternalStore(subscribe, getCurrent);
42
18
  }
43
19
  return useHook;
44
20
  }
45
21
  const useAuthState = createStateSourceHook(getAuthState);
46
- function createCallbackHook(callback, resourceId) {
47
- function useHook() {
48
- const $ = c(2), instance = useSanityInstance(resourceId);
49
- let t0;
50
- return $[0] !== instance ? (t0 = (...t1) => callback(instance, ...t1), $[0] = instance, $[1] = t0) : t0 = $[1], t0;
51
- }
52
- return useHook;
53
- }
54
- const useHandleCallback = createCallbackHook(handleCallback);
55
22
  function useLoginUrls() {
56
- const instance = useSanityInstance(), {
57
- subscribe,
58
- getCurrent
59
- } = useMemo(() => getLoginUrlsState(instance), [instance]);
23
+ const instance = useSanityInstance(), { subscribe, getCurrent } = useMemo(() => getLoginUrlsState(instance), [instance]);
60
24
  if (!getCurrent()) throw fetchLoginUrls(instance);
61
25
  return useSyncExternalStore(subscribe, getCurrent);
62
26
  }
63
- const useLogOut = createCallbackHook(logout);
27
+ function createCallbackHook(callback) {
28
+ function useHook() {
29
+ const instance = useSanityInstance();
30
+ return useCallback((...params) => callback(instance, ...params), [instance]);
31
+ }
32
+ return useHook;
33
+ }
34
+ const useHandleCallback = createCallbackHook(handleCallback), useLogOut = createCallbackHook(logout);
64
35
  export {
65
- createCallbackHook,
36
+ SanityProvider,
66
37
  createStateSourceHook,
67
38
  useAuthState,
68
39
  useHandleCallback,
@@ -1 +1 @@
1
- {"version":3,"file":"useLogOut.js","sources":["../../src/hooks/context/useSanityInstance.ts","../../src/hooks/helpers/createStateSourceHook.tsx","../../src/hooks/auth/useAuthState.tsx","../../src/hooks/helpers/createCallbackHook.tsx","../../src/hooks/auth/useHandleCallback.tsx","../../src/hooks/auth/useLoginUrls.tsx","../../src/hooks/auth/useLogOut.tsx"],"sourcesContent":["import {type SanityInstance} from '@sanity/sdk'\nimport {useContext} from 'react'\n\nimport {SanityInstanceContext} from '../../context/SanityInstanceContext'\n\n/**\n * `useSanityInstance` returns the current Sanity instance from the application context.\n * This must be called from within a `SanityProvider` component.\n * @internal\n *\n * @param resourceId - The resourceId of the Sanity instance to return (optional)\n * @returns The current Sanity instance\n * @example\n * ```tsx\n * const instance = useSanityInstance('abc123.production')\n * ```\n */\nexport const useSanityInstance = (resourceId?: string): SanityInstance => {\n const sanityInstance = useContext(SanityInstanceContext)\n if (!sanityInstance) {\n throw new Error('useSanityInstance must be called from within the SanityProvider')\n }\n if (sanityInstance.length === 0) {\n throw new Error('No Sanity instances found')\n }\n if (sanityInstance.length === 1 || !resourceId) {\n return sanityInstance[0]\n }\n\n if (!resourceId) {\n throw new Error('resourceId is required when there are multiple Sanity instances')\n }\n\n const instance = sanityInstance.find((inst) => inst.identity.resourceId === resourceId)\n if (!instance) {\n throw new Error(`Sanity instance with resourceId ${resourceId} not found`)\n }\n return instance\n}\n","import {type ResourceId, type SanityInstance, type StateSource} from '@sanity/sdk'\nimport {useSyncExternalStore} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\ntype StateSourceFactory<TParams extends unknown[], TState> = (\n instance: SanityInstance,\n ...params: TParams\n) => StateSource<TState>\n\ninterface CreateStateSourceHookOptions<TParams extends unknown[], TState> {\n getState: StateSourceFactory<TParams, TState>\n shouldSuspend?: (instance: SanityInstance, ...params: TParams) => boolean\n suspender?: (instance: SanityInstance, ...params: TParams) => Promise<unknown>\n getResourceId?: (...params: TParams) => ResourceId | undefined\n}\n\nexport function createStateSourceHook<TParams extends unknown[], TState>(\n options: StateSourceFactory<TParams, TState> | CreateStateSourceHookOptions<TParams, TState>,\n): (...params: TParams) => TState {\n const getState = typeof options === 'function' ? options : options.getState\n const getResourceId = 'getResourceId' in options ? options.getResourceId : undefined\n const suspense = 'shouldSuspend' in options && 'suspender' in options ? options : undefined\n\n function useHook(...params: TParams) {\n let resourceId: ResourceId | undefined\n if (getResourceId) {\n resourceId = getResourceId(...params)\n }\n const instance = useSanityInstance(resourceId)\n if (suspense?.suspender && suspense?.shouldSuspend?.(instance, ...params)) {\n throw suspense.suspender(instance, ...params)\n }\n\n const state = getState(instance, ...params)\n return useSyncExternalStore(state.subscribe, state.getCurrent)\n }\n\n return useHook\n}\n","import {type AuthState, getAuthState} from '@sanity/sdk'\n\nimport {createStateSourceHook} from '../helpers/createStateSourceHook'\n\n/**\n * @internal\n * A React hook that subscribes to authentication state changes.\n *\n * This hook provides access to the current authentication state type from the Sanity auth store.\n * It automatically re-renders when the authentication state changes.\n *\n * @remarks\n * The hook uses `useSyncExternalStore` to safely subscribe to auth state changes\n * and ensure consistency between server and client rendering.\n *\n * @returns The current authentication state type\n *\n * @example\n * ```tsx\n * function AuthStatus() {\n * const authState = useAuthState()\n * return <div>Current auth state: {authState}</div>\n * }\n * ```\n */\nexport const useAuthState: () => AuthState = createStateSourceHook(getAuthState)\n","import {type ResourceId, type SanityInstance} from '@sanity/sdk'\nimport {useCallback} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\nexport function createCallbackHook<TParams extends unknown[], TReturn>(\n callback: (instance: SanityInstance, ...params: TParams) => TReturn,\n resourceId?: ResourceId,\n): () => (...params: TParams) => TReturn {\n function useHook() {\n const instance = useSanityInstance(resourceId)\n return useCallback((...params: TParams) => callback(instance, ...params), [instance])\n }\n\n return useHook\n}\n","import {handleCallback} from '@sanity/sdk'\n\nimport {createCallbackHook} from '../helpers/createCallbackHook'\n\n/**\n * @internal\n * A React hook that returns a function for handling authentication callbacks.\n *\n * @remarks\n * This hook provides access to the authentication store's callback handler,\n * which processes auth redirects by extracting the session ID and fetching the\n * authentication token. If fetching the long-lived token is successful,\n * `handleCallback` will return a Promise that resolves a new location that\n * removes the short-lived token from the URL. Use this in combination with\n * `history.replaceState` or your own router's `replace` function to update the\n * current location without triggering a reload.\n *\n * @example\n * ```tsx\n * function AuthCallback() {\n * const handleCallback = useHandleCallback()\n * const router = useRouter() // Example router\n *\n * useEffect(() => {\n * async function processCallback() {\n * // Handle the callback and get the cleaned URL\n * const newUrl = await handleCallback(window.location.href)\n *\n * if (newUrl) {\n * // Replace URL without triggering navigation\n * router.replace(newUrl, {shallow: true})\n * }\n * }\n *\n * processCallback().catch(console.error)\n * }, [handleCallback, router])\n *\n * return <div>Completing login...</div>\n * }\n * ```\n *\n * @returns A callback handler function that processes OAuth redirects\n * @public\n */\nexport const useHandleCallback = createCallbackHook(handleCallback)\n","import {type AuthProvider, fetchLoginUrls, getLoginUrlsState} from '@sanity/sdk'\nimport {useMemo, useSyncExternalStore} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\n/**\n * @internal\n * A React hook that retrieves the available authentication provider URLs for login.\n *\n * @remarks\n * This hook fetches the login URLs from the Sanity auth store when the component mounts.\n * Each provider object contains information about an authentication method, including its URL.\n * The hook will suspend if the login URLs have not yet loaded.\n *\n * @example\n * ```tsx\n * // LoginProviders component that uses the hook\n * function LoginProviders() {\n * const providers = useLoginUrls()\n *\n * return (\n * <div>\n * {providers.map((provider) => (\n * <a key={provider.name} href={provider.url}>\n * Login with {provider.title}\n * </a>\n * ))}\n * </div>\n * )\n * }\n *\n * // Parent component with Suspense boundary\n * function LoginPage() {\n * return (\n * <Suspense fallback={<div>Loading authentication providers...</div>}>\n * <LoginProviders />\n * </Suspense>\n * )\n * }\n * ```\n *\n * @returns An array of {@link AuthProvider} objects containing login URLs and provider information\n * @public\n */\nexport function useLoginUrls(): AuthProvider[] {\n const instance = useSanityInstance()\n const {subscribe, getCurrent} = useMemo(() => getLoginUrlsState(instance), [instance])\n\n if (!getCurrent()) throw fetchLoginUrls(instance)\n\n return useSyncExternalStore(subscribe, getCurrent as () => AuthProvider[])\n}\n","import {logout} from '@sanity/sdk'\n\nimport {createCallbackHook} from '../helpers/createCallbackHook'\n\n/**\n * Hook to log out of the current session\n * @internal\n * @returns A function to log out of the current session\n */\nexport const useLogOut = createCallbackHook(logout)\n"],"names":["useSanityInstance","resourceId","$","_c","sanityInstance","useContext","SanityInstanceContext","Error","length","t0","t1","inst","identity","find","instance","createStateSourceHook","options","getState","getResourceId","undefined","suspense","useHook","params","suspender","shouldSuspend","state","useSyncExternalStore","subscribe","getCurrent","useAuthState","getAuthState","createCallbackHook","callback","useHandleCallback","handleCallback","useLoginUrls","useMemo","getLoginUrlsState","fetchLoginUrls","useLogOut","logout"],"mappings":";;;;AAiBO,MAAMA,oBAAoBC,CAAA,eAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GAC/BC,iBAAuBC,WAAAC,qBAAgC;AAAC,MAAA,CACnDF;AAAcG,UAAAA,IAAAA,MACD,iEAAiE;AAAA,MAE/EH,eAAcI,WAAa;AAAAD,UAAAA,IAAAA,MACb,2BAA2B;AAEzCH,MAAAA,eAAcI,WAAA,MAAkBP;AAAU,WACrCG,eAAc,CAAA;AAAA,MAAA,CAGlBH;AAAUM,UAAAA,IAAAA,MACG,iEAAiE;AAAAE,MAAAA;AAAA,MAAAP,EAAAD,CAAAA,MAAAA,cAAAC,SAAAE,gBAAA;AAAAM,QAAAA;AAAAR,aAAAD,cAG9CS,KAAAC,UAAUA,KAAIC,SAAAX,eAAyBA,YAAUC,OAAAD,YAAAC,OAAAQ,MAAAA,KAAAR,EAAA,CAAA,GAArEO,KAAAL,eAAcS,KAAMH,EAAiD,GAACR,OAAAD,YAAAC,OAAAE,gBAAAF,OAAAO;AAAAA,EAAA;AAAAA,SAAAP,EAAA,CAAA;AAAvF,QAAAY,WAAiBL;AAAsE,MAAA,CAClFK;AAAQ,UAAA,IAAAP,MACK,mCAAmCN,UAAU,YAAY;AAEpEa,SAAAA;AAAQ;ACpBV,SAASC,sBACdC,SACgC;AAChC,QAAMC,WAAW,OAAOD,WAAY,aAAaA,UAAUA,QAAQC,UAC7DC,gBAAgB,mBAAmBF,UAAUA,QAAQE,gBAAgBC,QACrEC,WAAW,mBAAmBJ,WAAW,eAAeA,UAAUA,UAAUG;AAElF,WAAAE,WAAAZ,IAAA;AAAA,UAAAP,IAAAC,EAAA,CAAA,GAAiBmB,SAAAb;AACXR,QAAAA;AAAkC,QAAAiB,eAAA;AAAAR,UAAAA;AAAAR,eAAAoB,UAEvBZ,MAAAQ,cAAiBI,GAAAA,MAAM,GAACpB,OAAAoB,QAAApB,OAAAQ,OAAAA,MAAAR,EAAA,CAAA,GAArCD,aAAaA;AAAAA,IAAAA;AAEfa,UAAAA,WAAiBd,kBAAkBC,UAAU;AAAC,QAC1CmB,UAAAG,aAAAH,UAAAI,gBAAiDV,UAAaQ,GAAAA,MAAM;AAAC,YACjEF,SAAAG,UAAmBT,UAAQ,GAAKQ,MAAM;AAACZ,QAAAA;AAAAR,MAAAY,CAAAA,MAAAA,YAAAZ,SAAAoB,UAGjCZ,KAAAO,SAASH,UAAQ,GAAKQ,MAAM,GAACpB,OAAAY,UAAAZ,OAAAoB,QAAApB,OAAAQ,MAAAA,KAAAR,EAAA,CAAA;AAA3C,UAAAuB,QAAcf;AAA6B,WACpCgB,qBAAqBD,MAAKE,WAAYF,MAAKG,UAAW;AAAA,EAAA;AAGxDP,SAAAA;AACT;ACdaQ,MAAAA,eAAgCd,sBAAsBe,YAAY;ACpB/DC,SAAAA,mBACdC,UACA/B,YACuC;AACvC,WAAAoB,UAAA;AAAA,UAAAnB,IAAAC,EAAA,CAAA,GACEW,WAAiBd,kBAAAC,UAA4B;AAACQ,QAAAA;AAAAP,WAAAA,SAAAY,YAC3BL,KAAAA,IAAAC,OAAwBsB,SAASlB,UAAQ,GAAxCJ,EAAmD,GAACR,OAAAY,UAAAZ,OAAAO,MAAAA,KAAAP,EAAA,CAAA,GAAjEO;AAAAA,EAAAA;AAGFY,SAAAA;AACT;AC6BaY,MAAAA,oBAAoBF,mBAAmBG,cAAc;ACA3D,SAASC,eAA+B;AACvCrB,QAAAA,WAAWd,qBACX;AAAA,IAAC2B;AAAAA,IAAWC;AAAAA,EAAAA,IAAcQ,QAAQ,MAAMC,kBAAkBvB,QAAQ,GAAG,CAACA,QAAQ,CAAC;AAErF,MAAI,CAACc,WAAAA,EAAc,OAAMU,eAAexB,QAAQ;AAEzCY,SAAAA,qBAAqBC,WAAWC,UAAkC;AAC3E;AC1CaW,MAAAA,YAAYR,mBAAmBS,MAAM;"}
1
+ {"version":3,"file":"useLogOut.js","sources":["../../src/components/context/SanityProvider.tsx","../../src/hooks/context/useSanityInstance.ts","../../src/hooks/helpers/createStateSourceHook.tsx","../../src/hooks/auth/useAuthState.tsx","../../src/hooks/auth/useLoginUrls.tsx","../../src/hooks/helpers/createCallbackHook.tsx","../../src/hooks/auth/useHandleCallback.tsx","../../src/hooks/auth/useLogOut.tsx"],"sourcesContent":["import {type SanityInstance} from '@sanity/sdk'\nimport {createContext, type ReactElement} from 'react'\n\n/**\n * @public\n */\nexport interface SanityProviderProps {\n children: React.ReactNode\n sanityInstance: SanityInstance\n}\n\nexport const SanityInstanceContext = createContext<SanityInstance | null>(null)\n\n/**\n * Top-level context provider that provides a Sanity configuration instance.\n * This must wrap any Sanity SDK React component.\n * @public\n * @param props - Sanity project and dataset configuration\n * @returns Rendered component\n * @example\n * ```tsx\n * import {createSanityInstance} from '@sanity/sdk'\n * import {ExampleComponent, SanityProvider} from '@sanity/sdk-react'\n *\n * const sanityInstance = createSanityInstance({projectId: 'your-project-id', dataset: 'production'})\n *\n * export default function MyApp() {\n * return (\n * <SanityProvider sanityInstance={sanityInstance}>\n * <ExampleComponent />\n * </SanityProvider>\n * )\n * }\n * ```\n */\nexport const SanityProvider = ({children, sanityInstance}: SanityProviderProps): ReactElement => {\n return (\n <SanityInstanceContext.Provider value={sanityInstance}>\n {children}\n </SanityInstanceContext.Provider>\n )\n}\n","import type {SanityInstance} from '@sanity/sdk'\nimport {useContext} from 'react'\n\nimport {SanityInstanceContext} from '../../components/context/SanityProvider'\n\n/**\n * Hook that provides the current Sanity instance from the context.\n * This must be called from within a `SanityProvider` component.\n * @public\n * @returns the current Sanity instance\n * @example\n * ```tsx\n * const instance = useSanityInstance()\n * ```\n */\nexport const useSanityInstance = (): SanityInstance => {\n const sanityInstance = useContext(SanityInstanceContext)\n if (!sanityInstance) {\n throw new Error('useSanityInstance must be called from within the SanityProvider')\n }\n\n return sanityInstance\n}\n","import type {SanityInstance, StateSource} from '@sanity/sdk'\nimport {useMemo, useSyncExternalStore} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\nexport function createStateSourceHook<TParams extends unknown[], TState>(\n stateSourceFactory: (instance: SanityInstance, ...params: TParams) => StateSource<TState>,\n): (...params: TParams) => TState {\n function useHook(...params: TParams) {\n const instance = useSanityInstance()\n const {subscribe, getCurrent} = useMemo(\n () => stateSourceFactory(instance, ...params),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [instance, ...params],\n )\n\n return useSyncExternalStore(subscribe, getCurrent)\n }\n\n return useHook\n}\n","import {getAuthState} from '@sanity/sdk'\n\nimport {createStateSourceHook} from '../helpers/createStateSourceHook'\n\n/**\n * A React hook that subscribes to authentication state changes.\n *\n * This hook provides access to the current authentication state type from the Sanity auth store.\n * It automatically re-renders the component when the authentication state changes.\n *\n * @remarks\n * The hook uses `useSyncExternalStore` to safely subscribe to auth state changes\n * and ensure consistency between server and client rendering.\n *\n * @returns The current authentication state type\n *\n * @example\n * ```tsx\n * function AuthStatus() {\n * const authState = useAuthState()\n * return <div>Current auth state: {authState}</div>\n * }\n * ```\n *\n * @public\n */\nexport const useAuthState = createStateSourceHook(getAuthState)\n","import {type AuthProvider, fetchLoginUrls, getLoginUrlsState} from '@sanity/sdk'\nimport {useMemo, useSyncExternalStore} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\n/**\n * A React hook that retrieves the available authentication provider URLs for login.\n *\n * @remarks\n * This hook fetches the login URLs from the Sanity auth store when the component mounts.\n * Each provider object contains information about an authentication method, including its URL.\n * The hook will suspend if the login URLs have not yet loaded.\n *\n * @example\n * ```tsx\n * // LoginProviders component that uses the hook\n * function LoginProviders() {\n * const providers = useLoginUrls()\n *\n * return (\n * <div>\n * {providers.map((provider) => (\n * <a key={provider.name} href={provider.url}>\n * Login with {provider.title}\n * </a>\n * ))}\n * </div>\n * )\n * }\n *\n * // Parent component with Suspense boundary\n * function LoginPage() {\n * return (\n * <Suspense fallback={<div>Loading authentication providers...</div>}>\n * <LoginProviders />\n * </Suspense>\n * )\n * }\n * ```\n *\n * @returns An array of {@link AuthProvider} objects containing login URLs and provider information\n * @public\n */\nexport function useLoginUrls(): AuthProvider[] {\n const instance = useSanityInstance()\n const {subscribe, getCurrent} = useMemo(() => getLoginUrlsState(instance), [instance])\n\n if (!getCurrent()) throw fetchLoginUrls(instance)\n\n return useSyncExternalStore(subscribe, getCurrent as () => AuthProvider[])\n}\n","import type {SanityInstance} from '@sanity/sdk'\nimport {useCallback} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\nexport function createCallbackHook<TParams extends unknown[], TReturn>(\n callback: (instance: SanityInstance, ...params: TParams) => TReturn,\n): () => (...params: TParams) => TReturn {\n function useHook() {\n const instance = useSanityInstance()\n return useCallback((...params: TParams) => callback(instance, ...params), [instance])\n }\n\n return useHook\n}\n","import {handleCallback} from '@sanity/sdk'\n\nimport {createCallbackHook} from '../helpers/createCallbackHook'\n\n/**\n * A React hook that returns a function for handling authentication callbacks.\n *\n * @remarks\n * This hook provides access to the authentication store's callback handler,\n * which processes auth redirects by extracting the session ID and fetching the\n * authentication token. If fetching the long-lived token is successful,\n * `handleCallback` will return a Promise that resolves a new location that\n * removes the short-lived token from the URL. Use this in combination with\n * `history.replaceState` or your own router's `replace` function to update the\n * current location without triggering a reload.\n *\n * @example\n * ```tsx\n * function AuthCallback() {\n * const handleCallback = useHandleCallback()\n * const router = useRouter() // Example router\n *\n * useEffect(() => {\n * async function processCallback() {\n * // Handle the callback and get the cleaned URL\n * const newUrl = await handleCallback(window.location.href)\n *\n * if (newUrl) {\n * // Replace URL without triggering navigation\n * router.replace(newUrl, {shallow: true})\n * }\n * }\n *\n * processCallback().catch(console.error)\n * }, [handleCallback, router])\n *\n * return <div>Completing login...</div>\n * }\n * ```\n *\n * @returns A callback handler function that processes OAuth redirects\n * @public\n */\nexport const useHandleCallback = createCallbackHook(handleCallback)\n","import {logout} from '@sanity/sdk'\n\nimport {createCallbackHook} from '../helpers/createCallbackHook'\n\n/**\n * Hook to log out of the current session\n * @public\n * @returns A function to log out of the current session\n */\nexport const useLogOut = createCallbackHook(logout)\n"],"names":[],"mappings":";;;AAWO,MAAM,wBAAwB,cAAqC,IAAI,GAwBjE,iBAAiB,CAAC,EAAC,UAAU,eAAc,0BAEnD,sBAAsB,UAAtB,EAA+B,OAAO,gBACpC,SACH,CAAA,GCxBS,oBAAoB,MAAsB;AAC/C,QAAA,iBAAiB,WAAW,qBAAqB;AACvD,MAAI,CAAC;AACG,UAAA,IAAI,MAAM,iEAAiE;AAG5E,SAAA;AACT;ACjBO,SAAS,sBACd,oBACgC;AAChC,WAAS,WAAW,QAAiB;AACnC,UAAM,WAAW,kBAAkB,GAC7B,EAAC,WAAW,WAAc,IAAA;AAAA,MAC9B,MAAM,mBAAmB,UAAU,GAAG,MAAM;AAAA;AAAA,MAE5C,CAAC,UAAU,GAAG,MAAM;AAAA,IACtB;AAEO,WAAA,qBAAqB,WAAW,UAAU;AAAA,EAAA;AAG5C,SAAA;AACT;ACMa,MAAA,eAAe,sBAAsB,YAAY;ACiBvD,SAAS,eAA+B;AAC7C,QAAM,WAAW,qBACX,EAAC,WAAW,WAAU,IAAI,QAAQ,MAAM,kBAAkB,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAErF,MAAI,CAAC,WAAA,EAAc,OAAM,eAAe,QAAQ;AAEzC,SAAA,qBAAqB,WAAW,UAAkC;AAC3E;AC7CO,SAAS,mBACd,UACuC;AACvC,WAAS,UAAU;AACjB,UAAM,WAAW,kBAAkB;AAC5B,WAAA,YAAY,IAAI,WAAoB,SAAS,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC;AAAA,EAAA;AAG/E,SAAA;AACT;AC6Ba,MAAA,oBAAoB,mBAAmB,cAAc,GClCrD,YAAY,mBAAmB,MAAM;"}
@@ -0,0 +1,11 @@
1
+ @import './paramour.css';
2
+
3
+ body {
4
+ color-scheme: light dark;
5
+ color: light-dark(var(--gray-1), var(--gray-10));
6
+ background-color: light-dark(var(--gray-11), var(--gray-1));
7
+ }
8
+
9
+ .container-inline {
10
+ container-type: inline-size;
11
+ }
@@ -1,7 +1,9 @@
1
1
  import {FallbackProps} from 'react-error-boundary'
2
+ import {ForwardRefExoticComponent} from 'react'
3
+ import type {PropsWithChildren} from 'react'
2
4
  import {ReactElement} from 'react'
3
- import {ReactNode} from 'react'
4
- import {SanityConfig} from '@sanity/sdk'
5
+ import {RefAttributes} from 'react'
6
+ import {SanityInstance} from '@sanity/sdk'
5
7
 
6
8
  /**
7
9
  * A component that handles authentication flow and error boundaries for a
@@ -22,7 +24,7 @@ import {SanityConfig} from '@sanity/sdk'
22
24
  * }
23
25
  * ```
24
26
  *
25
- * @internal
27
+ * @alpha
26
28
  */
27
29
  export declare function AuthBoundary({
28
30
  LoginErrorComponent,
@@ -30,9 +32,9 @@ export declare function AuthBoundary({
30
32
  }: AuthBoundaryProps): React.ReactNode
31
33
 
32
34
  /**
33
- * @internal
35
+ * @alpha
34
36
  */
35
- declare interface AuthBoundaryProps extends LoginLayoutProps {
37
+ export declare interface AuthBoundaryProps extends LoginLayoutProps {
36
38
  /**
37
39
  * Custom component to render the login screen.
38
40
  * Receives all login layout props. Defaults to {@link Login}.
@@ -52,14 +54,142 @@ declare interface AuthBoundaryProps extends LoginLayoutProps {
52
54
  }
53
55
 
54
56
  /**
57
+ * Error class for authentication-related errors. Wraps errors thrown during the
58
+ * authentication flow.
59
+ *
60
+ * @remarks
61
+ * This class provides a consistent error type for authentication failures while
62
+ * preserving the original error as the cause. If the original error has a
63
+ * message property, it will be used as the error message.
64
+ *
65
+ * @alpha
66
+ */
67
+ export declare class AuthError extends Error {
68
+ constructor(error: unknown)
69
+ }
70
+
71
+ /**
72
+ * @public
73
+ */
74
+ export declare const DocumentGridLayout: {
75
+ (props: PropsWithChildren): ReactElement
76
+ displayName: string
77
+ }
78
+
79
+ /**
80
+ * @public
81
+ */
82
+ export declare const DocumentListLayout: {
83
+ (props: PropsWithChildren): ReactElement
84
+ displayName: string
85
+ }
86
+
87
+ /**
88
+ * This is a component that renders a document preview.
89
+ *
90
+ * @public
91
+ *
92
+ * @param props - The props for the DocumentPreviewLayout component.
93
+ * @returns - The DocumentPreviewLayout component.
94
+ */
95
+ export declare const DocumentPreviewLayout: ForwardRefExoticComponent<
96
+ DocumentPreviewLayoutProps & RefAttributes<HTMLElement>
97
+ >
98
+
99
+ /**
100
+ * @public
101
+ */
102
+ export declare interface DocumentPreviewLayoutProps {
103
+ docType?: string
104
+ media?:
105
+ | {
106
+ type: string
107
+ url: string
108
+ }
109
+ | null
110
+ | undefined
111
+ onClick?: () => void
112
+ selected?: boolean
113
+ status?: string
114
+ subtitle?: string
115
+ title: string
116
+ }
117
+
118
+ /**
119
+ * Login component that displays available authentication providers.
120
+ * Renders a list of login options with a loading fallback while providers load.
121
+ *
122
+ * @alpha
123
+ */
124
+ export declare function Login({header, footer}: LoginLayoutProps): JSX.Element
125
+
126
+ /**
127
+ * Component shown during auth callback processing that handles login completion.
128
+ * Automatically processes the auth callback when mounted and updates the URL
129
+ * to remove callback parameters without triggering a page reload.
130
+ *
131
+ * @alpha
132
+ */
133
+ export declare function LoginCallback({header, footer}: LoginLayoutProps): React.ReactNode
134
+
135
+ /**
136
+ * Displays authentication error details and provides retry functionality.
137
+ * Only handles {@link AuthError} instances - rethrows other error types.
138
+ *
139
+ * @alpha
140
+ */
141
+ export declare function LoginError({
142
+ error,
143
+ resetErrorBoundary,
144
+ header,
145
+ footer,
146
+ }: LoginErrorProps): React.ReactNode
147
+
148
+ /**
149
+ * @alpha
150
+ */
151
+ export declare type LoginErrorProps = FallbackProps & LoginLayoutProps
152
+
153
+ /**
154
+ * Layout component for login-related screens providing consistent styling and structure.
155
+ * Renders content in a centered card with optional header and footer sections.
156
+ *
157
+ * Can be used to build custom login screens for the AuthBoundary component, including:
158
+ * - Login provider selection (LoginComponent)
159
+ * - OAuth callback handling (CallbackComponent)
160
+ * - Error states (LoginErrorComponent)
161
+ *
162
+ * @example
163
+ * ```tsx
164
+ * // Custom login screen using the layout
165
+ * function CustomLogin({header, footer}: LoginLayoutProps) {
166
+ * return (
167
+ * <LoginLayout
168
+ * header={header}
169
+ * footer={footer}
170
+ * >
171
+ * <CustomLoginContent />
172
+ * </LoginLayout>
173
+ * )
174
+ * }
175
+ *
176
+ * // Use with AuthBoundary
177
+ * <AuthBoundary
178
+ * LoginComponent={CustomLogin}
179
+ * header={<Logo />}
180
+ * >
181
+ * <ProtectedContent />
182
+ * </AuthBoundary>
183
+ * ```
184
+ *
55
185
  * @alpha
56
186
  */
57
- declare type LoginErrorProps = FallbackProps & LoginLayoutProps
187
+ export declare function LoginLayout({children, footer, header}: LoginLayoutProps): React.ReactNode
58
188
 
59
189
  /**
60
190
  * @alpha
61
191
  */
62
- declare interface LoginLayoutProps {
192
+ export declare interface LoginLayoutProps {
63
193
  /** Optional header content rendered at top of card */
64
194
  header?: React.ReactNode
65
195
  /** Optional footer content rendered below card. Defaults to an internal login footer */
@@ -69,86 +199,59 @@ declare interface LoginLayoutProps {
69
199
  }
70
200
 
71
201
  /**
202
+ * Component that handles Sanity authentication flow and renders login provider options
203
+ *
72
204
  * @public
73
205
  *
74
- * The SanityApp component provides your Sanity application with access to your Sanity configuration,
75
- * as well as application context and state which is used by the Sanity React hooks. Your application
76
- * must be wrapped with the SanityApp component to function properly.
206
+ * @returns Rendered component
77
207
  *
78
- * @param props - Your Sanity configuration and the React children to render
79
- * @returns Your Sanity application, integrated with your Sanity configuration and application context
208
+ * @remarks
209
+ * The component handles three states:
210
+ * 1. Loading state during token exchange
211
+ * 2. Success state after successful authentication
212
+ * 3. Provider selection UI when not authenticated
80
213
  *
81
214
  * @example
82
215
  * ```tsx
83
- * import { SanityApp } from '@sanity/sdk-react'
84
- *
85
- * import MyAppRoot from './Root'
86
- *
87
- * // Single project configuration
88
- * const mySanityConfigs = [
89
- * {
90
- * projectId: 'my-project-id',
91
- * dataset: 'production',
92
- * },
93
- * ]
94
- *
95
- * // Or multiple project configurations
96
- * const multipleConfigs = [
97
- * // Configuration for your main project. This will be used as the default project for all hooks if no resource ID override is provided.
98
- * {
99
- * projectId: 'marketing-website-project',
100
- * dataset: 'production',
101
- * },
102
- * // Configuration for a separate blog project
103
- * {
104
- * projectId: 'blog-project',
105
- * dataset: 'production',
106
- * },
107
- * // Configuration for a separate ecommerce project
108
- * {
109
- * projectId: 'ecommerce-project',
110
- * dataset: 'production',
111
- * }
112
- * ]
216
+ * const config = { projectId: 'your-project-id', dataset: 'production' }
217
+ * return <LoginLinks sanityInstance={config} />
218
+ * ```
219
+ */
220
+ export declare const LoginLinks: () => ReactElement
221
+
222
+ /**
223
+ * Top-level context provider that provides a Sanity configuration instance.
224
+ * This must wrap any Sanity SDK React component.
225
+ * @public
226
+ * @param props - Sanity project and dataset configuration
227
+ * @returns Rendered component
228
+ * @example
229
+ * ```tsx
230
+ * import {createSanityInstance} from '@sanity/sdk'
231
+ * import {ExampleComponent, SanityProvider} from '@sanity/sdk-react'
232
+ *
233
+ * const sanityInstance = createSanityInstance({projectId: 'your-project-id', dataset: 'production'})
113
234
  *
114
235
  * export default function MyApp() {
115
236
  * return (
116
- * <SanityApp sanityConfigs={mySanityConfigs}>
117
- * <MyAppRoot />
118
- * </SanityApp>
237
+ * <SanityProvider sanityInstance={sanityInstance}>
238
+ * <ExampleComponent />
239
+ * </SanityProvider>
119
240
  * )
120
241
  * }
121
242
  * ```
122
243
  */
123
- export declare function SanityApp({sanityConfigs, children, fallback}: SanityAppProps): ReactElement
244
+ export declare const SanityProvider: ({
245
+ children,
246
+ sanityInstance,
247
+ }: SanityProviderProps) => ReactElement
124
248
 
125
249
  /**
126
250
  * @public
127
251
  */
128
- export declare interface SanityAppProps {
129
- sanityConfigs: SanityConfig[]
252
+ export declare interface SanityProviderProps {
130
253
  children: React.ReactNode
131
- fallback: React.ReactNode
132
- }
133
-
134
- /**
135
- * @internal
136
- *
137
- * Top-level context provider that provides access to the Sanity SDK.
138
- */
139
- export declare function SDKProvider({
140
- children,
141
- sanityConfigs,
142
- fallback,
143
- }: SDKProviderProps): ReactElement
144
-
145
- /**
146
- * @internal
147
- */
148
- export declare interface SDKProviderProps {
149
- children: ReactNode
150
- sanityConfigs: SanityConfig[]
151
- fallback: ReactNode
254
+ sanityInstance: SanityInstance
152
255
  }
153
256
 
154
257
  export {}