@sanity/sdk-react 0.0.0-alpha.20 → 0.0.0-alpha.3
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/README.md +76 -34
- package/dist/_chunks-es/useLogOut.js +44 -0
- package/dist/_chunks-es/useLogOut.js.map +1 -0
- package/dist/assets/bundle-CcAyERuZ.css +11 -0
- package/dist/components.d.ts +259 -0
- package/dist/components.js +301 -0
- package/dist/components.js.map +1 -0
- package/dist/hooks.d.ts +186 -0
- package/dist/hooks.js +81 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +2 -4742
- package/dist/index.js +2 -1054
- package/dist/index.js.map +1 -1
- package/package.json +43 -23
- package/src/_exports/components.ts +13 -0
- package/src/_exports/hooks.ts +9 -0
- package/src/_exports/index.ts +10 -66
- package/src/components/DocumentGridLayout/DocumentGridLayout.stories.tsx +113 -0
- package/src/components/DocumentGridLayout/DocumentGridLayout.test.tsx +42 -0
- package/src/components/DocumentGridLayout/DocumentGridLayout.tsx +21 -0
- package/src/components/DocumentListLayout/DocumentListLayout.stories.tsx +105 -0
- package/src/components/DocumentListLayout/DocumentListLayout.test.tsx +42 -0
- package/src/components/DocumentListLayout/DocumentListLayout.tsx +12 -0
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.md +49 -0
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.stories.tsx +39 -0
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.test.tsx +30 -0
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.tsx +171 -0
- package/src/components/Login/LoginLinks.test.tsx +12 -2
- package/src/components/Login/LoginLinks.tsx +29 -14
- package/src/components/auth/AuthBoundary.test.tsx +17 -4
- package/src/components/auth/AuthBoundary.tsx +4 -20
- package/src/components/auth/Login.test.tsx +16 -2
- package/src/components/auth/Login.tsx +16 -10
- package/src/components/auth/LoginCallback.test.tsx +17 -2
- package/src/components/auth/LoginCallback.tsx +5 -4
- package/src/components/auth/LoginError.test.tsx +17 -2
- package/src/components/auth/LoginError.tsx +11 -11
- package/src/components/auth/LoginFooter.test.tsx +16 -2
- package/src/components/auth/LoginFooter.tsx +23 -9
- package/src/components/auth/LoginLayout.test.tsx +16 -2
- package/src/components/auth/LoginLayout.tsx +19 -7
- package/src/{context → components/context}/SanityProvider.test.tsx +2 -2
- package/src/components/context/SanityProvider.tsx +42 -0
- package/src/css/css.config.js +220 -0
- package/src/css/paramour.css +2347 -0
- package/src/css/styles.css +11 -0
- package/src/hooks/auth/useAuthState.tsx +5 -4
- package/src/hooks/auth/useAuthToken.tsx +1 -1
- package/src/hooks/auth/useCurrentUser.tsx +4 -27
- package/src/hooks/auth/useHandleCallback.tsx +0 -1
- package/src/hooks/auth/useLogOut.tsx +1 -1
- package/src/hooks/auth/useLoginUrls.tsx +0 -1
- package/src/hooks/client/useClient.test.tsx +130 -0
- package/src/hooks/client/useClient.ts +30 -8
- package/src/hooks/context/useSanityInstance.test.tsx +2 -2
- package/src/hooks/context/useSanityInstance.ts +8 -24
- package/src/hooks/documentCollection/useDocuments.test.ts +130 -0
- package/src/hooks/documentCollection/useDocuments.ts +87 -0
- package/src/hooks/helpers/createCallbackHook.tsx +2 -3
- package/src/hooks/helpers/createStateSourceHook.test.tsx +0 -66
- package/src/hooks/helpers/createStateSourceHook.tsx +10 -29
- package/src/hooks/preview/usePreview.test.tsx +11 -20
- package/src/hooks/preview/usePreview.tsx +12 -66
- package/src/components/SDKProvider.test.tsx +0 -79
- package/src/components/SDKProvider.tsx +0 -42
- package/src/components/SanityApp.test.tsx +0 -156
- package/src/components/SanityApp.tsx +0 -90
- package/src/components/auth/authTestHelpers.tsx +0 -11
- package/src/components/utils.ts +0 -22
- package/src/context/SanityInstanceContext.ts +0 -4
- package/src/context/SanityProvider.tsx +0 -50
- package/src/hooks/_synchronous-groq-js.mjs +0 -4
- package/src/hooks/auth/useDashboardOrganizationId.test.tsx +0 -42
- package/src/hooks/auth/useDashboardOrganizationId.tsx +0 -29
- package/src/hooks/comlink/useFrameConnection.test.tsx +0 -167
- package/src/hooks/comlink/useFrameConnection.ts +0 -107
- package/src/hooks/comlink/useManageFavorite.test.ts +0 -106
- package/src/hooks/comlink/useManageFavorite.ts +0 -101
- package/src/hooks/comlink/useRecordDocumentHistoryEvent.test.ts +0 -77
- package/src/hooks/comlink/useRecordDocumentHistoryEvent.ts +0 -79
- package/src/hooks/comlink/useWindowConnection.test.ts +0 -135
- package/src/hooks/comlink/useWindowConnection.ts +0 -122
- package/src/hooks/dashboard/useNavigateToStudioDocument.ts +0 -97
- package/src/hooks/dashboard/useStudioWorkspacesByResourceId.test.tsx +0 -274
- package/src/hooks/dashboard/useStudioWorkspacesByResourceId.ts +0 -91
- package/src/hooks/datasets/useDatasets.ts +0 -37
- package/src/hooks/document/useApplyActions.test.ts +0 -25
- package/src/hooks/document/useApplyActions.ts +0 -74
- package/src/hooks/document/useDocument.test.ts +0 -81
- package/src/hooks/document/useDocument.ts +0 -107
- package/src/hooks/document/useDocumentEvent.test.ts +0 -63
- package/src/hooks/document/useDocumentEvent.ts +0 -54
- package/src/hooks/document/useDocumentSyncStatus.test.ts +0 -16
- package/src/hooks/document/useDocumentSyncStatus.ts +0 -30
- package/src/hooks/document/useEditDocument.test.ts +0 -179
- package/src/hooks/document/useEditDocument.ts +0 -195
- package/src/hooks/document/usePermissions.ts +0 -82
- package/src/hooks/infiniteList/useInfiniteList.test.tsx +0 -152
- package/src/hooks/infiniteList/useInfiniteList.ts +0 -174
- package/src/hooks/paginatedList/usePaginatedList.test.tsx +0 -259
- package/src/hooks/paginatedList/usePaginatedList.ts +0 -290
- package/src/hooks/projection/useProjection.test.tsx +0 -218
- package/src/hooks/projection/useProjection.ts +0 -147
- package/src/hooks/projects/useProject.ts +0 -45
- package/src/hooks/projects/useProjects.ts +0 -41
- package/src/hooks/query/useQuery.test.tsx +0 -188
- package/src/hooks/query/useQuery.ts +0 -103
- package/src/hooks/users/useUsers.test.ts +0 -163
- package/src/hooks/users/useUsers.ts +0 -107
- package/src/utils/getEnv.ts +0 -21
- package/src/version.ts +0 -8
- package/src/vite-env.d.ts +0 -10
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Button, Card, Container, Flex, Heading, Stack} from '@sanity/ui'
|
|
1
2
|
import {type ReactElement} from 'react'
|
|
2
3
|
|
|
3
4
|
import {useAuthState} from '../../hooks/auth/useAuthState'
|
|
@@ -29,30 +30,44 @@ export const LoginLinks = (): ReactElement => {
|
|
|
29
30
|
useHandleCallback()
|
|
30
31
|
|
|
31
32
|
if (authState.type === 'logging-in') {
|
|
32
|
-
return <div
|
|
33
|
+
return <div>Logging in...</div>
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
// Show success state after authentication
|
|
36
37
|
if (authState.type === 'logged-in') {
|
|
37
|
-
return <div
|
|
38
|
+
return <div>You are logged in</div>
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Render provider selection UI
|
|
43
|
+
* Uses Sanity UI components for consistent styling
|
|
42
44
|
*/
|
|
43
45
|
return (
|
|
44
|
-
<
|
|
45
|
-
<
|
|
46
|
+
<Card height="fill" overflow="auto" paddingX={4}>
|
|
47
|
+
<Flex height="fill" direction="column" align="center" justify="center" paddingTop={4}>
|
|
48
|
+
<Container width={0}>
|
|
49
|
+
<Stack space={4}>
|
|
50
|
+
<Heading align="center" size={1}>
|
|
51
|
+
Choose login provider
|
|
52
|
+
</Heading>
|
|
46
53
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
<Stack space={2}>
|
|
55
|
+
{loginUrls.map((provider, index) => (
|
|
56
|
+
<Button
|
|
57
|
+
key={`${provider.url}_${index}`}
|
|
58
|
+
as="a"
|
|
59
|
+
href={provider.url}
|
|
60
|
+
mode="ghost"
|
|
61
|
+
tone="default"
|
|
62
|
+
space={3}
|
|
63
|
+
padding={3}
|
|
64
|
+
text={provider.title}
|
|
65
|
+
/>
|
|
66
|
+
))}
|
|
67
|
+
</Stack>
|
|
68
|
+
</Stack>
|
|
69
|
+
</Container>
|
|
70
|
+
</Flex>
|
|
71
|
+
</Card>
|
|
57
72
|
)
|
|
58
73
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {AuthStateType} from '@sanity/sdk'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {AuthStateType, createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {render, screen, waitFor} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
4
6
|
import {beforeEach, describe, expect, it, type MockInstance, vi} from 'vitest'
|
|
5
7
|
|
|
8
|
+
import {useAuthState} from '../../hooks/auth/useAuthState'
|
|
9
|
+
import {SanityProvider} from '../context/SanityProvider'
|
|
6
10
|
import {AuthBoundary} from './AuthBoundary'
|
|
7
|
-
import {renderWithWrappers} from './authTestHelpers'
|
|
8
11
|
|
|
9
12
|
// Mock hooks
|
|
10
13
|
vi.mock('../../hooks/auth/useAuthState', () => ({
|
|
@@ -35,6 +38,16 @@ vi.mock('./AuthError', async (importOriginal) => {
|
|
|
35
38
|
}
|
|
36
39
|
})
|
|
37
40
|
|
|
41
|
+
const theme = buildTheme({})
|
|
42
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
43
|
+
const renderWithWrappers = (ui: React.ReactElement) => {
|
|
44
|
+
return render(
|
|
45
|
+
<ThemeProvider theme={theme}>
|
|
46
|
+
<SanityProvider sanityInstance={sanityInstance}>{ui}</SanityProvider>
|
|
47
|
+
</ThemeProvider>,
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
38
51
|
describe('AuthBoundary', () => {
|
|
39
52
|
let consoleErrorSpy: MockInstance
|
|
40
53
|
beforeEach(() => {
|
|
@@ -3,32 +3,16 @@ import {useMemo} from 'react'
|
|
|
3
3
|
import {ErrorBoundary, type FallbackProps} from 'react-error-boundary'
|
|
4
4
|
|
|
5
5
|
import {useAuthState} from '../../hooks/auth/useAuthState'
|
|
6
|
-
import {isInIframe} from '../utils'
|
|
7
6
|
import {AuthError} from './AuthError'
|
|
8
7
|
import {Login} from './Login'
|
|
9
8
|
import {LoginCallback} from './LoginCallback'
|
|
10
9
|
import {LoginError, type LoginErrorProps} from './LoginError'
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
// Only import bridge if we're in an iframe. This assumes that the app is
|
|
14
|
-
// running within SanityOS if it is in an iframe.
|
|
15
|
-
if (isInIframe()) {
|
|
16
|
-
const parsedUrl = new URL(window.location.href)
|
|
17
|
-
const mode = new URLSearchParams(parsedUrl.hash.slice(1)).get('mode')
|
|
18
|
-
const script = document.createElement('script')
|
|
19
|
-
script.src =
|
|
20
|
-
mode === 'core-ui--staging'
|
|
21
|
-
? 'https://core.sanity-cdn.work/bridge.js'
|
|
22
|
-
: 'https://core.sanity-cdn.com/bridge.js'
|
|
23
|
-
script.type = 'module'
|
|
24
|
-
script.async = true
|
|
25
|
-
document.head.appendChild(script)
|
|
26
|
-
}
|
|
10
|
+
import type {LoginLayoutProps} from './LoginLayout'
|
|
27
11
|
|
|
28
12
|
/**
|
|
29
|
-
* @
|
|
13
|
+
* @alpha
|
|
30
14
|
*/
|
|
31
|
-
interface AuthBoundaryProps extends LoginLayoutProps {
|
|
15
|
+
export interface AuthBoundaryProps extends LoginLayoutProps {
|
|
32
16
|
/**
|
|
33
17
|
* Custom component to render the login screen.
|
|
34
18
|
* Receives all login layout props. Defaults to {@link Login}.
|
|
@@ -68,7 +52,7 @@ interface AuthBoundaryProps extends LoginLayoutProps {
|
|
|
68
52
|
* }
|
|
69
53
|
* ```
|
|
70
54
|
*
|
|
71
|
-
* @
|
|
55
|
+
* @alpha
|
|
72
56
|
*/
|
|
73
57
|
export function AuthBoundary({
|
|
74
58
|
LoginErrorComponent = LoginError,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {render, screen} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
2
6
|
import {describe, expect, it, vi} from 'vitest'
|
|
3
7
|
|
|
4
|
-
import {
|
|
8
|
+
import {SanityProvider} from '../context/SanityProvider'
|
|
5
9
|
import {Login} from './Login'
|
|
6
10
|
|
|
7
11
|
vi.mock('../../hooks/auth/useLoginUrls', () => ({
|
|
@@ -11,6 +15,16 @@ vi.mock('../../hooks/auth/useLoginUrls', () => ({
|
|
|
11
15
|
]),
|
|
12
16
|
}))
|
|
13
17
|
|
|
18
|
+
const theme = buildTheme({})
|
|
19
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
20
|
+
const renderWithWrappers = (ui: React.ReactElement) => {
|
|
21
|
+
return render(
|
|
22
|
+
<ThemeProvider theme={theme}>
|
|
23
|
+
<SanityProvider sanityInstance={sanityInstance}>{ui}</SanityProvider>
|
|
24
|
+
</ThemeProvider>,
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
describe('Login', () => {
|
|
15
29
|
it('renders login providers', () => {
|
|
16
30
|
renderWithWrappers(<Login />)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Button, Flex, Heading, Spinner} from '@sanity/ui'
|
|
1
2
|
import {type JSX, Suspense} from 'react'
|
|
2
3
|
|
|
3
4
|
import {useLoginUrls} from '../../hooks/auth/useLoginUrls'
|
|
@@ -8,18 +9,25 @@ import {LoginLayout, type LoginLayoutProps} from './LoginLayout'
|
|
|
8
9
|
* Renders a list of login options with a loading fallback while providers load.
|
|
9
10
|
*
|
|
10
11
|
* @alpha
|
|
11
|
-
* @internal
|
|
12
12
|
*/
|
|
13
13
|
export function Login({header, footer}: LoginLayoutProps): JSX.Element {
|
|
14
14
|
return (
|
|
15
15
|
<LoginLayout header={header} footer={footer}>
|
|
16
|
-
<
|
|
17
|
-
<
|
|
16
|
+
<Flex direction="column" gap={4}>
|
|
17
|
+
<Heading as="h1" size={1} align="center">
|
|
18
|
+
Choose login provider
|
|
19
|
+
</Heading>
|
|
18
20
|
|
|
19
|
-
<Suspense
|
|
21
|
+
<Suspense
|
|
22
|
+
fallback={
|
|
23
|
+
<Flex align="center" justify="center" style={{height: '123px'}}>
|
|
24
|
+
<Spinner />
|
|
25
|
+
</Flex>
|
|
26
|
+
}
|
|
27
|
+
>
|
|
20
28
|
<Providers />
|
|
21
29
|
</Suspense>
|
|
22
|
-
</
|
|
30
|
+
</Flex>
|
|
23
31
|
</LoginLayout>
|
|
24
32
|
)
|
|
25
33
|
}
|
|
@@ -28,12 +36,10 @@ function Providers() {
|
|
|
28
36
|
const loginUrls = useLoginUrls()
|
|
29
37
|
|
|
30
38
|
return (
|
|
31
|
-
<
|
|
39
|
+
<Flex direction="column" gap={3}>
|
|
32
40
|
{loginUrls.map(({title, url}) => (
|
|
33
|
-
<
|
|
34
|
-
{title}
|
|
35
|
-
</a>
|
|
41
|
+
<Button key={url} text={title} as="a" href={url} mode="ghost" />
|
|
36
42
|
))}
|
|
37
|
-
</
|
|
43
|
+
</Flex>
|
|
38
44
|
)
|
|
39
45
|
}
|
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {render, screen, waitFor} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
2
6
|
import {afterAll, beforeAll, beforeEach, describe, expect, it, vi} from 'vitest'
|
|
3
7
|
|
|
4
|
-
import {
|
|
8
|
+
import {SanityProvider} from '../context/SanityProvider'
|
|
9
|
+
|
|
10
|
+
const theme = buildTheme({})
|
|
11
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
12
|
+
|
|
13
|
+
const renderWithWrappers = (ui: React.ReactElement) => {
|
|
14
|
+
return render(
|
|
15
|
+
<ThemeProvider theme={theme}>
|
|
16
|
+
<SanityProvider sanityInstance={sanityInstance}>{ui}</SanityProvider>
|
|
17
|
+
</ThemeProvider>,
|
|
18
|
+
)
|
|
19
|
+
}
|
|
5
20
|
|
|
6
21
|
// Mock `useHandleCallback`
|
|
7
22
|
vi.mock('../../hooks/auth/useHandleCallback', () => ({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Flex, Spinner, Text} from '@sanity/ui'
|
|
1
2
|
import {useEffect} from 'react'
|
|
2
3
|
|
|
3
4
|
import {useHandleCallback} from '../../hooks/auth/useHandleCallback'
|
|
@@ -27,10 +28,10 @@ export function LoginCallback({header, footer}: LoginLayoutProps): React.ReactNo
|
|
|
27
28
|
|
|
28
29
|
return (
|
|
29
30
|
<LoginLayout header={header} footer={footer}>
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
</
|
|
31
|
+
<Flex direction="column" justify="center" align="center" gap={4} style={{margin: 'auto'}}>
|
|
32
|
+
<Text size={1}>Logging you in…</Text>
|
|
33
|
+
<Spinner size={4} />
|
|
34
|
+
</Flex>
|
|
34
35
|
</LoginLayout>
|
|
35
36
|
)
|
|
36
37
|
}
|
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
2
6
|
import {describe, expect, it, vi} from 'vitest'
|
|
3
7
|
|
|
8
|
+
import {SanityProvider} from '../context/SanityProvider'
|
|
4
9
|
import {AuthError} from './AuthError'
|
|
5
|
-
import {renderWithWrappers} from './authTestHelpers'
|
|
6
10
|
import {LoginError} from './LoginError'
|
|
7
11
|
|
|
8
12
|
vi.mock('../../hooks/auth/useLogOut', () => ({
|
|
9
13
|
useLogOut: vi.fn(() => async () => {}),
|
|
10
14
|
}))
|
|
11
15
|
|
|
16
|
+
const theme = buildTheme({})
|
|
17
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
18
|
+
|
|
19
|
+
const renderWithWrappers = (ui: React.ReactElement) => {
|
|
20
|
+
return render(
|
|
21
|
+
<ThemeProvider theme={theme}>
|
|
22
|
+
<SanityProvider sanityInstance={sanityInstance}>{ui}</SanityProvider>
|
|
23
|
+
</ThemeProvider>,
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
describe('LoginError', () => {
|
|
13
28
|
it('shows authentication error and retry button', async () => {
|
|
14
29
|
const mockReset = vi.fn()
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Button, Flex, Text} from '@sanity/ui'
|
|
1
2
|
import {useCallback} from 'react'
|
|
2
3
|
import {type FallbackProps} from 'react-error-boundary'
|
|
3
4
|
|
|
@@ -32,18 +33,17 @@ export function LoginError({
|
|
|
32
33
|
|
|
33
34
|
return (
|
|
34
35
|
<LoginLayout header={header} footer={footer}>
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<h2
|
|
38
|
-
|
|
36
|
+
<Flex direction="column" gap={4} style={{margin: 'auto'}}>
|
|
37
|
+
<Flex direction="column" gap={3}>
|
|
38
|
+
<Text as="h2" align="center" weight="bold" size={3}>
|
|
39
|
+
Authentication Error
|
|
40
|
+
</Text>
|
|
41
|
+
<Text size={1} align="center">
|
|
39
42
|
Please try again or contact support if the problem persists.
|
|
40
|
-
</
|
|
41
|
-
</
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Retry
|
|
45
|
-
</button>
|
|
46
|
-
</div>
|
|
43
|
+
</Text>
|
|
44
|
+
</Flex>
|
|
45
|
+
<Button text="Retry" tone="primary" onClick={handleRetry} />
|
|
46
|
+
</Flex>
|
|
47
47
|
</LoginLayout>
|
|
48
48
|
)
|
|
49
49
|
}
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {render, screen} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
2
6
|
import {describe, expect, it} from 'vitest'
|
|
3
7
|
|
|
4
|
-
import {
|
|
8
|
+
import {SanityProvider} from '../context/SanityProvider'
|
|
5
9
|
import {LoginFooter} from './LoginFooter'
|
|
6
10
|
|
|
11
|
+
const theme = buildTheme({})
|
|
12
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
13
|
+
const renderWithWrappers = (ui: React.ReactElement) => {
|
|
14
|
+
return render(
|
|
15
|
+
<ThemeProvider theme={theme}>
|
|
16
|
+
<SanityProvider sanityInstance={sanityInstance}>{ui}</SanityProvider>
|
|
17
|
+
</ThemeProvider>,
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
7
21
|
describe('LoginFooter', () => {
|
|
8
22
|
it('renders footer links', () => {
|
|
9
23
|
renderWithWrappers(<LoginFooter />)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {SanityLogo} from '@sanity/logos'
|
|
2
|
+
import {Flex, Text} from '@sanity/ui'
|
|
2
3
|
import {Fragment} from 'react'
|
|
3
4
|
|
|
4
5
|
const LINKS = [
|
|
@@ -32,20 +33,33 @@ const LINKS = [
|
|
|
32
33
|
*/
|
|
33
34
|
export function LoginFooter(): React.ReactNode {
|
|
34
35
|
return (
|
|
35
|
-
<
|
|
36
|
-
<
|
|
36
|
+
<Flex direction="column" gap={4} justify="center" align="center" paddingTop={2}>
|
|
37
|
+
<Text size={3}>
|
|
38
|
+
<SanityLogo />
|
|
39
|
+
</Text>
|
|
37
40
|
|
|
38
|
-
<
|
|
39
|
-
{LINKS.map((link) => (
|
|
41
|
+
<Flex align="center" gap={2}>
|
|
42
|
+
{LINKS.map((link, index) => (
|
|
40
43
|
<Fragment key={link.title}>
|
|
41
|
-
<
|
|
42
|
-
<a
|
|
44
|
+
<Text muted size={1}>
|
|
45
|
+
<a
|
|
46
|
+
href={link.url}
|
|
47
|
+
target="_blank"
|
|
48
|
+
rel="noopener noreferrer"
|
|
49
|
+
style={{color: 'inherit'}}
|
|
50
|
+
>
|
|
43
51
|
{link.title}
|
|
44
52
|
</a>
|
|
45
|
-
</
|
|
53
|
+
</Text>
|
|
54
|
+
|
|
55
|
+
{index < LINKS.length - 1 && (
|
|
56
|
+
<Text size={1} muted>
|
|
57
|
+
•
|
|
58
|
+
</Text>
|
|
59
|
+
)}
|
|
46
60
|
</Fragment>
|
|
47
61
|
))}
|
|
48
|
-
</
|
|
49
|
-
</
|
|
62
|
+
</Flex>
|
|
63
|
+
</Flex>
|
|
50
64
|
)
|
|
51
65
|
}
|
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {render, screen} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
2
6
|
import {describe, expect, it} from 'vitest'
|
|
3
7
|
|
|
4
|
-
import {
|
|
8
|
+
import {SanityProvider} from '../context/SanityProvider'
|
|
5
9
|
import {LoginLayout} from './LoginLayout'
|
|
6
10
|
|
|
11
|
+
const theme = buildTheme({})
|
|
12
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
13
|
+
const renderWithWrappers = (ui: React.ReactElement) => {
|
|
14
|
+
return render(
|
|
15
|
+
<ThemeProvider theme={theme}>
|
|
16
|
+
<SanityProvider sanityInstance={sanityInstance}>{ui}</SanityProvider>
|
|
17
|
+
</ThemeProvider>,
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
7
21
|
describe('LoginLayout', () => {
|
|
8
22
|
it('renders header, children, and footer', () => {
|
|
9
23
|
renderWithWrappers(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {Card, Flex} from '@sanity/ui'
|
|
2
|
+
|
|
1
3
|
import {LoginFooter} from './LoginFooter'
|
|
2
4
|
|
|
3
5
|
/**
|
|
@@ -54,16 +56,26 @@ export function LoginLayout({
|
|
|
54
56
|
header,
|
|
55
57
|
}: LoginLayoutProps): React.ReactNode {
|
|
56
58
|
return (
|
|
57
|
-
<div
|
|
58
|
-
<
|
|
59
|
-
<
|
|
60
|
-
|
|
59
|
+
<div style={{width: '100%', display: 'flex'}}>
|
|
60
|
+
<Flex direction="column" gap={4} style={{width: '320px', margin: 'auto', display: 'flex'}}>
|
|
61
|
+
<Card border radius={2} paddingY={4}>
|
|
62
|
+
<Flex direction="column" gap={4}>
|
|
63
|
+
{header && (
|
|
64
|
+
<Card borderBottom paddingX={4} paddingBottom={3}>
|
|
65
|
+
{header}
|
|
66
|
+
</Card>
|
|
67
|
+
)}
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
{children && (
|
|
70
|
+
<Flex paddingX={4} direction="column" style={{minHeight: '154px'}}>
|
|
71
|
+
{children}
|
|
72
|
+
</Flex>
|
|
73
|
+
)}
|
|
74
|
+
</Flex>
|
|
75
|
+
</Card>
|
|
64
76
|
|
|
65
77
|
{footer}
|
|
66
|
-
</
|
|
78
|
+
</Flex>
|
|
67
79
|
</div>
|
|
68
80
|
)
|
|
69
81
|
}
|
|
@@ -2,7 +2,7 @@ import {createSanityInstance} from '@sanity/sdk'
|
|
|
2
2
|
import {render} from '@testing-library/react'
|
|
3
3
|
import {describe, expect, it} from 'vitest'
|
|
4
4
|
|
|
5
|
-
import {useSanityInstance} from '
|
|
5
|
+
import {useSanityInstance} from '../../hooks/context/useSanityInstance'
|
|
6
6
|
import {SanityProvider} from './SanityProvider'
|
|
7
7
|
|
|
8
8
|
describe('SanityProvider', () => {
|
|
@@ -15,7 +15,7 @@ describe('SanityProvider', () => {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const {getByTestId} = render(
|
|
18
|
-
<SanityProvider
|
|
18
|
+
<SanityProvider sanityInstance={sanityInstance}>
|
|
19
19
|
<TestComponent />
|
|
20
20
|
</SanityProvider>,
|
|
21
21
|
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {type SanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {createContext, type ReactElement} from 'react'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface SanityProviderProps {
|
|
8
|
+
children: React.ReactNode
|
|
9
|
+
sanityInstance: SanityInstance
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const SanityInstanceContext = createContext<SanityInstance | null>(null)
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Top-level context provider that provides a Sanity configuration instance.
|
|
16
|
+
* This must wrap any Sanity SDK React component.
|
|
17
|
+
* @public
|
|
18
|
+
* @param props - Sanity project and dataset configuration
|
|
19
|
+
* @returns Rendered component
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import {createSanityInstance} from '@sanity/sdk'
|
|
23
|
+
* import {ExampleComponent, SanityProvider} from '@sanity/sdk-react'
|
|
24
|
+
*
|
|
25
|
+
* const sanityInstance = createSanityInstance({projectId: 'your-project-id', dataset: 'production'})
|
|
26
|
+
*
|
|
27
|
+
* export default function MyApp() {
|
|
28
|
+
* return (
|
|
29
|
+
* <SanityProvider sanityInstance={sanityInstance}>
|
|
30
|
+
* <ExampleComponent />
|
|
31
|
+
* </SanityProvider>
|
|
32
|
+
* )
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const SanityProvider = ({children, sanityInstance}: SanityProviderProps): ReactElement => {
|
|
37
|
+
return (
|
|
38
|
+
<SanityInstanceContext.Provider value={sanityInstance}>
|
|
39
|
+
{children}
|
|
40
|
+
</SanityInstanceContext.Provider>
|
|
41
|
+
)
|
|
42
|
+
}
|