@sanity/sdk-react 0.0.0-alpha.3 → 0.0.0-alpha.5
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 +78 -28
- package/dist/_chunks-es/context.js +8 -0
- package/dist/_chunks-es/context.js.map +1 -0
- package/dist/_chunks-es/useLogOut.js +11 -11
- package/dist/_chunks-es/useLogOut.js.map +1 -1
- package/dist/components.d.ts +11 -186
- package/dist/components.js +52 -198
- package/dist/components.js.map +1 -1
- package/dist/context.d.ts +39 -0
- package/dist/context.js +5 -0
- package/dist/context.js.map +1 -0
- package/dist/hooks.d.ts +201 -15
- package/dist/hooks.js +80 -11
- package/dist/hooks.js.map +1 -1
- package/package.json +17 -15
- package/src/_exports/components.ts +2 -13
- package/src/_exports/context.ts +2 -0
- package/src/_exports/hooks.ts +18 -2
- package/src/components/SanityApp.test.tsx +54 -0
- package/src/components/SanityApp.tsx +26 -0
- package/src/components/auth/AuthBoundary.test.tsx +5 -18
- package/src/components/auth/AuthBoundary.tsx +2 -2
- package/src/components/auth/Login.test.tsx +3 -17
- package/src/components/auth/Login.tsx +25 -16
- package/src/components/auth/LoginCallback.test.tsx +2 -17
- package/src/components/auth/LoginCallback.tsx +6 -4
- package/src/components/auth/LoginError.test.tsx +2 -17
- package/src/components/auth/LoginError.tsx +8 -12
- package/src/components/auth/LoginFooter.test.tsx +2 -16
- package/src/components/auth/LoginFooter.tsx +11 -18
- package/src/components/auth/LoginLayout.test.tsx +2 -16
- package/src/components/auth/LoginLayout.tsx +8 -19
- package/src/components/auth/authTestHelpers.tsx +18 -0
- package/src/{components/context → context}/SanityProvider.test.tsx +1 -1
- package/src/hooks/client/useClient.test.tsx +1 -1
- package/src/hooks/comlink/useFrameConnection.test.tsx +122 -0
- package/src/hooks/comlink/useFrameConnection.ts +111 -0
- package/src/hooks/comlink/useWindowConnection.test.ts +94 -0
- package/src/hooks/comlink/useWindowConnection.ts +82 -0
- package/src/hooks/context/useSanityInstance.test.tsx +1 -1
- package/src/hooks/context/useSanityInstance.ts +2 -2
- package/src/hooks/documentCollection/useDocuments.ts +53 -6
- package/src/hooks/helpers/createCallbackHook.tsx +1 -1
- package/src/hooks/helpers/createStateSourceHook.tsx +1 -1
- package/src/hooks/preview/usePreview.test.tsx +17 -8
- package/src/hooks/preview/usePreview.tsx +52 -7
- package/src/vite-env.d.ts +10 -0
- package/dist/assets/bundle-CcAyERuZ.css +0 -11
- package/src/components/DocumentGridLayout/DocumentGridLayout.stories.tsx +0 -113
- package/src/components/DocumentGridLayout/DocumentGridLayout.test.tsx +0 -42
- package/src/components/DocumentGridLayout/DocumentGridLayout.tsx +0 -21
- package/src/components/DocumentListLayout/DocumentListLayout.stories.tsx +0 -105
- package/src/components/DocumentListLayout/DocumentListLayout.test.tsx +0 -42
- package/src/components/DocumentListLayout/DocumentListLayout.tsx +0 -12
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.md +0 -49
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.stories.tsx +0 -39
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.test.tsx +0 -30
- package/src/components/DocumentPreviewLayout/DocumentPreviewLayout.tsx +0 -171
- package/src/components/Login/LoginLinks.test.tsx +0 -100
- package/src/components/Login/LoginLinks.tsx +0 -73
- package/src/css/css.config.js +0 -220
- package/src/css/paramour.css +0 -2347
- package/src/css/styles.css +0 -11
- /package/src/{components/context → context}/SanityProvider.tsx +0 -0
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {AuthStateType
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {render, screen, waitFor} from '@testing-library/react'
|
|
5
|
-
import React from 'react'
|
|
1
|
+
import {AuthStateType} from '@sanity/sdk'
|
|
2
|
+
import {useAuthState} from '@sanity/sdk-react/hooks'
|
|
3
|
+
import {screen, waitFor} from '@testing-library/react'
|
|
6
4
|
import {beforeEach, describe, expect, it, type MockInstance, vi} from 'vitest'
|
|
7
5
|
|
|
8
|
-
import {useAuthState} from '../../hooks/auth/useAuthState'
|
|
9
|
-
import {SanityProvider} from '../context/SanityProvider'
|
|
10
6
|
import {AuthBoundary} from './AuthBoundary'
|
|
7
|
+
import {renderWithWrappers} from './authTestHelpers'
|
|
11
8
|
|
|
12
9
|
// Mock hooks
|
|
13
10
|
vi.mock('../../hooks/auth/useAuthState', () => ({
|
|
@@ -38,16 +35,6 @@ vi.mock('./AuthError', async (importOriginal) => {
|
|
|
38
35
|
}
|
|
39
36
|
})
|
|
40
37
|
|
|
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
|
-
|
|
51
38
|
describe('AuthBoundary', () => {
|
|
52
39
|
let consoleErrorSpy: MockInstance
|
|
53
40
|
beforeEach(() => {
|
|
@@ -67,7 +54,7 @@ describe('AuthBoundary', () => {
|
|
|
67
54
|
renderWithWrappers(<AuthBoundary>Protected Content</AuthBoundary>)
|
|
68
55
|
|
|
69
56
|
// The login screen should show "Choose login provider" by default
|
|
70
|
-
expect(screen.getByText('Choose login provider')).toBeInTheDocument()
|
|
57
|
+
expect(screen.getByText('Choose login provider:')).toBeInTheDocument()
|
|
71
58
|
expect(screen.queryByText('Protected Content')).not.toBeInTheDocument()
|
|
72
59
|
})
|
|
73
60
|
|
|
@@ -7,12 +7,12 @@ import {AuthError} from './AuthError'
|
|
|
7
7
|
import {Login} from './Login'
|
|
8
8
|
import {LoginCallback} from './LoginCallback'
|
|
9
9
|
import {LoginError, type LoginErrorProps} from './LoginError'
|
|
10
|
-
import type
|
|
10
|
+
import {type LoginLayoutProps} from './LoginLayout'
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @alpha
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
interface AuthBoundaryProps extends LoginLayoutProps {
|
|
16
16
|
/**
|
|
17
17
|
* Custom component to render the login screen.
|
|
18
18
|
* Receives all login layout props. Defaults to {@link Login}.
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
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'
|
|
1
|
+
import {screen} from '@testing-library/react'
|
|
6
2
|
import {describe, expect, it, vi} from 'vitest'
|
|
7
3
|
|
|
8
|
-
import {
|
|
4
|
+
import {renderWithWrappers} from './authTestHelpers'
|
|
9
5
|
import {Login} from './Login'
|
|
10
6
|
|
|
11
7
|
vi.mock('../../hooks/auth/useLoginUrls', () => ({
|
|
@@ -15,20 +11,10 @@ vi.mock('../../hooks/auth/useLoginUrls', () => ({
|
|
|
15
11
|
]),
|
|
16
12
|
}))
|
|
17
13
|
|
|
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
|
-
|
|
28
14
|
describe('Login', () => {
|
|
29
15
|
it('renders login providers', () => {
|
|
30
16
|
renderWithWrappers(<Login />)
|
|
31
|
-
expect(screen.getByText('Choose login provider')).toBeInTheDocument()
|
|
17
|
+
expect(screen.getByText('Choose login provider:')).toBeInTheDocument()
|
|
32
18
|
expect(screen.getByRole('link', {name: 'Provider A'})).toHaveAttribute(
|
|
33
19
|
'href',
|
|
34
20
|
'https://provider-a.com/auth',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Button, Flex, Heading, Spinner} from '@sanity/ui'
|
|
1
|
+
import {Box, Button, Flex, Heading, Spinner, Stack} from '@sanity/ui'
|
|
2
2
|
import {type JSX, Suspense} from 'react'
|
|
3
3
|
|
|
4
4
|
import {useLoginUrls} from '../../hooks/auth/useLoginUrls'
|
|
@@ -9,25 +9,26 @@ import {LoginLayout, type LoginLayoutProps} from './LoginLayout'
|
|
|
9
9
|
* Renders a list of login options with a loading fallback while providers load.
|
|
10
10
|
*
|
|
11
11
|
* @alpha
|
|
12
|
+
* @internal
|
|
12
13
|
*/
|
|
13
14
|
export function Login({header, footer}: LoginLayoutProps): JSX.Element {
|
|
14
15
|
return (
|
|
15
16
|
<LoginLayout header={header} footer={footer}>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</Heading>
|
|
17
|
+
<Heading as="h6" align="center">
|
|
18
|
+
Choose login provider:
|
|
19
|
+
</Heading>
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
<Suspense
|
|
22
|
+
fallback={
|
|
23
|
+
<Box padding={5}>
|
|
24
|
+
<Flex align="center" justify="center">
|
|
24
25
|
<Spinner />
|
|
25
26
|
</Flex>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
</
|
|
27
|
+
</Box>
|
|
28
|
+
}
|
|
29
|
+
>
|
|
30
|
+
<Providers />
|
|
31
|
+
</Suspense>
|
|
31
32
|
</LoginLayout>
|
|
32
33
|
)
|
|
33
34
|
}
|
|
@@ -36,10 +37,18 @@ function Providers() {
|
|
|
36
37
|
const loginUrls = useLoginUrls()
|
|
37
38
|
|
|
38
39
|
return (
|
|
39
|
-
<
|
|
40
|
+
<Stack space={3} marginY={5}>
|
|
40
41
|
{loginUrls.map(({title, url}) => (
|
|
41
|
-
<Button
|
|
42
|
+
<Button
|
|
43
|
+
key={url}
|
|
44
|
+
as="a"
|
|
45
|
+
href={url}
|
|
46
|
+
mode="ghost"
|
|
47
|
+
text={title}
|
|
48
|
+
textAlign="center"
|
|
49
|
+
fontSize={2}
|
|
50
|
+
></Button>
|
|
42
51
|
))}
|
|
43
|
-
</
|
|
52
|
+
</Stack>
|
|
44
53
|
)
|
|
45
54
|
}
|
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
import {
|
|
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'
|
|
1
|
+
import {screen, waitFor} from '@testing-library/react'
|
|
6
2
|
import {afterAll, beforeAll, beforeEach, describe, expect, it, vi} from 'vitest'
|
|
7
3
|
|
|
8
|
-
import {
|
|
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
|
-
}
|
|
4
|
+
import {renderWithWrappers} from './authTestHelpers'
|
|
20
5
|
|
|
21
6
|
// Mock `useHandleCallback`
|
|
22
7
|
vi.mock('../../hooks/auth/useHandleCallback', () => ({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Flex,
|
|
1
|
+
import {Flex, Heading, Spinner} from '@sanity/ui'
|
|
2
2
|
import {useEffect} from 'react'
|
|
3
3
|
|
|
4
4
|
import {useHandleCallback} from '../../hooks/auth/useHandleCallback'
|
|
@@ -28,9 +28,11 @@ export function LoginCallback({header, footer}: LoginLayoutProps): React.ReactNo
|
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
30
|
<LoginLayout header={header} footer={footer}>
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
<Heading as="h6" align="center">
|
|
32
|
+
Logging you in…
|
|
33
|
+
</Heading>
|
|
34
|
+
<Flex paddingY={5} align="center" justify="center">
|
|
35
|
+
<Spinner />
|
|
34
36
|
</Flex>
|
|
35
37
|
</LoginLayout>
|
|
36
38
|
)
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
import {
|
|
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'
|
|
1
|
+
import {fireEvent, screen, waitFor} from '@testing-library/react'
|
|
6
2
|
import {describe, expect, it, vi} from 'vitest'
|
|
7
3
|
|
|
8
|
-
import {SanityProvider} from '../context/SanityProvider'
|
|
9
4
|
import {AuthError} from './AuthError'
|
|
5
|
+
import {renderWithWrappers} from './authTestHelpers'
|
|
10
6
|
import {LoginError} from './LoginError'
|
|
11
7
|
|
|
12
8
|
vi.mock('../../hooks/auth/useLogOut', () => ({
|
|
13
9
|
useLogOut: vi.fn(() => async () => {}),
|
|
14
10
|
}))
|
|
15
11
|
|
|
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
|
-
|
|
27
12
|
describe('LoginError', () => {
|
|
28
13
|
it('shows authentication error and retry button', async () => {
|
|
29
14
|
const mockReset = vi.fn()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Button,
|
|
1
|
+
import {Button, Heading, Stack, Text} from '@sanity/ui'
|
|
2
2
|
import {useCallback} from 'react'
|
|
3
3
|
import {type FallbackProps} from 'react-error-boundary'
|
|
4
4
|
|
|
@@ -33,17 +33,13 @@ export function LoginError({
|
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<LoginLayout header={header} footer={footer}>
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</Text>
|
|
44
|
-
</Flex>
|
|
45
|
-
<Button text="Retry" tone="primary" onClick={handleRetry} />
|
|
46
|
-
</Flex>
|
|
36
|
+
<Stack space={5} marginBottom={5}>
|
|
37
|
+
<Heading as="h6" align="center">
|
|
38
|
+
Authentication Error
|
|
39
|
+
</Heading>
|
|
40
|
+
<Text align="center">Please try again or contact support if the problem persists.</Text>
|
|
41
|
+
<Button mode="ghost" onClick={handleRetry} text="Retry" fontSize={2} />
|
|
42
|
+
</Stack>
|
|
47
43
|
</LoginLayout>
|
|
48
44
|
)
|
|
49
45
|
}
|
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
import {
|
|
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'
|
|
1
|
+
import {screen} from '@testing-library/react'
|
|
6
2
|
import {describe, expect, it} from 'vitest'
|
|
7
3
|
|
|
8
|
-
import {
|
|
4
|
+
import {renderWithWrappers} from './authTestHelpers'
|
|
9
5
|
import {LoginFooter} from './LoginFooter'
|
|
10
6
|
|
|
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
|
-
|
|
21
7
|
describe('LoginFooter', () => {
|
|
22
8
|
it('renders footer links', () => {
|
|
23
9
|
renderWithWrappers(<LoginFooter />)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {SanityLogo} from '@sanity/logos'
|
|
2
|
-
import {Flex, Text} from '@sanity/ui'
|
|
3
|
-
import {Fragment} from 'react'
|
|
2
|
+
import {Box, Flex, Inline, Text} from '@sanity/ui'
|
|
4
3
|
|
|
5
4
|
const LINKS = [
|
|
6
5
|
{
|
|
@@ -33,15 +32,15 @@ const LINKS = [
|
|
|
33
32
|
*/
|
|
34
33
|
export function LoginFooter(): React.ReactNode {
|
|
35
34
|
return (
|
|
36
|
-
<
|
|
37
|
-
<
|
|
35
|
+
<Box>
|
|
36
|
+
<Flex justify="center">
|
|
38
37
|
<SanityLogo />
|
|
39
|
-
</
|
|
38
|
+
</Flex>
|
|
40
39
|
|
|
41
|
-
<Flex
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
<Text
|
|
40
|
+
<Flex justify="center">
|
|
41
|
+
<Inline space={2} paddingY={3}>
|
|
42
|
+
{LINKS.map((link) => (
|
|
43
|
+
<Text size={0} key={link.url}>
|
|
45
44
|
<a
|
|
46
45
|
href={link.url}
|
|
47
46
|
target="_blank"
|
|
@@ -51,15 +50,9 @@ export function LoginFooter(): React.ReactNode {
|
|
|
51
50
|
{link.title}
|
|
52
51
|
</a>
|
|
53
52
|
</Text>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
<Text size={1} muted>
|
|
57
|
-
•
|
|
58
|
-
</Text>
|
|
59
|
-
)}
|
|
60
|
-
</Fragment>
|
|
61
|
-
))}
|
|
53
|
+
))}
|
|
54
|
+
</Inline>
|
|
62
55
|
</Flex>
|
|
63
|
-
</
|
|
56
|
+
</Box>
|
|
64
57
|
)
|
|
65
58
|
}
|
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
import {
|
|
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'
|
|
1
|
+
import {screen} from '@testing-library/react'
|
|
6
2
|
import {describe, expect, it} from 'vitest'
|
|
7
3
|
|
|
8
|
-
import {
|
|
4
|
+
import {renderWithWrappers} from './authTestHelpers'
|
|
9
5
|
import {LoginLayout} from './LoginLayout'
|
|
10
6
|
|
|
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
|
-
|
|
21
7
|
describe('LoginLayout', () => {
|
|
22
8
|
it('renders header, children, and footer', () => {
|
|
23
9
|
renderWithWrappers(
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {Card,
|
|
1
|
+
import {Card, Container} from '@sanity/ui'
|
|
2
2
|
|
|
3
3
|
import {LoginFooter} from './LoginFooter'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @alpha
|
|
7
|
+
* @internal
|
|
7
8
|
*/
|
|
8
9
|
export interface LoginLayoutProps {
|
|
9
10
|
/** Optional header content rendered at top of card */
|
|
@@ -56,26 +57,14 @@ export function LoginLayout({
|
|
|
56
57
|
header,
|
|
57
58
|
}: LoginLayoutProps): React.ReactNode {
|
|
58
59
|
return (
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
<Flex direction="column" gap={4}>
|
|
63
|
-
{header && (
|
|
64
|
-
<Card borderBottom paddingX={4} paddingBottom={3}>
|
|
65
|
-
{header}
|
|
66
|
-
</Card>
|
|
67
|
-
)}
|
|
60
|
+
<Container width={0}>
|
|
61
|
+
<Card shadow={1} radius={2} padding={4}>
|
|
62
|
+
{header && header}
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
<Flex paddingX={4} direction="column" style={{minHeight: '154px'}}>
|
|
71
|
-
{children}
|
|
72
|
-
</Flex>
|
|
73
|
-
)}
|
|
74
|
-
</Flex>
|
|
75
|
-
</Card>
|
|
64
|
+
{children && children}
|
|
76
65
|
|
|
77
66
|
{footer}
|
|
78
|
-
</
|
|
79
|
-
</
|
|
67
|
+
</Card>
|
|
68
|
+
</Container>
|
|
80
69
|
)
|
|
81
70
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {createSanityInstance} from '@sanity/sdk'
|
|
2
|
+
import {ThemeProvider} from '@sanity/ui'
|
|
3
|
+
import {buildTheme} from '@sanity/ui/theme'
|
|
4
|
+
import {render, type RenderResult} from '@testing-library/react'
|
|
5
|
+
import React from 'react'
|
|
6
|
+
|
|
7
|
+
import {SanityProvider} from '../../context/SanityProvider'
|
|
8
|
+
|
|
9
|
+
const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
|
|
10
|
+
const theme = buildTheme()
|
|
11
|
+
|
|
12
|
+
export const renderWithWrappers = (ui: React.ReactElement): RenderResult => {
|
|
13
|
+
return render(
|
|
14
|
+
<SanityProvider sanityInstance={sanityInstance}>
|
|
15
|
+
<ThemeProvider theme={theme}>{ui}</ThemeProvider>
|
|
16
|
+
</SanityProvider>,
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -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', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {type SanityClient} from '@sanity/client'
|
|
2
2
|
import {act} from '@testing-library/react'
|
|
3
|
-
import type
|
|
3
|
+
import {type Subscribable, type Subscriber} from 'rxjs'
|
|
4
4
|
import {beforeEach, describe, expect, it, vi} from 'vitest'
|
|
5
5
|
|
|
6
6
|
import {renderHook} from '../../../test/test-utils'
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {type ChannelInstance, type Controller} from '@sanity/comlink'
|
|
2
|
+
import {beforeEach, describe, expect, it, vi} from 'vitest'
|
|
3
|
+
|
|
4
|
+
import {renderHook} from '../../../test/test-utils'
|
|
5
|
+
import {useFrameConnection} from './useFrameConnection'
|
|
6
|
+
|
|
7
|
+
vi.mock(import('@sanity/sdk'), async (importOriginal) => {
|
|
8
|
+
const actual = await importOriginal()
|
|
9
|
+
return {
|
|
10
|
+
...actual,
|
|
11
|
+
getOrCreateChannel: vi.fn(),
|
|
12
|
+
getOrCreateController: vi.fn(),
|
|
13
|
+
releaseChannel: vi.fn(),
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const {getOrCreateChannel, getOrCreateController, releaseChannel} = await import('@sanity/sdk')
|
|
18
|
+
|
|
19
|
+
interface TestControllerMessage {
|
|
20
|
+
type: 'TEST_MESSAGE'
|
|
21
|
+
data: {
|
|
22
|
+
someData: string
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface TestNodeMessage {
|
|
27
|
+
type: 'NODE_MESSAGE'
|
|
28
|
+
data: {
|
|
29
|
+
someData: string
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function createMockChannel() {
|
|
34
|
+
return {
|
|
35
|
+
on: vi.fn(() => () => {}),
|
|
36
|
+
post: vi.fn(),
|
|
37
|
+
stop: vi.fn(),
|
|
38
|
+
} as unknown as ChannelInstance<TestControllerMessage, TestNodeMessage>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe('useFrameController', () => {
|
|
42
|
+
let channel: ChannelInstance<TestControllerMessage, TestNodeMessage>
|
|
43
|
+
let controller: Controller
|
|
44
|
+
let removeTargetMock: ReturnType<typeof vi.fn>
|
|
45
|
+
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
channel = createMockChannel()
|
|
48
|
+
removeTargetMock = vi.fn()
|
|
49
|
+
controller = {
|
|
50
|
+
addTarget: vi.fn(() => removeTargetMock),
|
|
51
|
+
destroy: vi.fn(),
|
|
52
|
+
} as unknown as Controller
|
|
53
|
+
vi.mocked(getOrCreateChannel).mockReturnValue(channel)
|
|
54
|
+
vi.mocked(getOrCreateController).mockReturnValue(controller)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('should register and execute message handlers', () => {
|
|
58
|
+
const mockHandler = vi.fn()
|
|
59
|
+
const mockData = {someData: 'test'}
|
|
60
|
+
renderHook(() =>
|
|
61
|
+
useFrameConnection({
|
|
62
|
+
name: 'test',
|
|
63
|
+
connectTo: 'iframe',
|
|
64
|
+
targetOrigin: '*',
|
|
65
|
+
onMessage: {
|
|
66
|
+
TEST_MESSAGE: mockHandler,
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const onCallback = vi.mocked(channel.on).mock.calls[0][1]
|
|
72
|
+
onCallback(mockData)
|
|
73
|
+
expect(mockHandler).toHaveBeenCalledWith(mockData)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should handle connecting frames and cleanup on disconnect', () => {
|
|
77
|
+
const {result} = renderHook(() =>
|
|
78
|
+
useFrameConnection({
|
|
79
|
+
name: 'test',
|
|
80
|
+
connectTo: 'iframe',
|
|
81
|
+
targetOrigin: '*',
|
|
82
|
+
}),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
const mockWindow = {} as Window
|
|
86
|
+
const cleanup = result.current.connect(mockWindow)
|
|
87
|
+
|
|
88
|
+
expect(controller.addTarget).toHaveBeenCalledWith(mockWindow)
|
|
89
|
+
|
|
90
|
+
// Test cleanup
|
|
91
|
+
cleanup()
|
|
92
|
+
expect(removeTargetMock).toHaveBeenCalled()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('should send messages correctly', () => {
|
|
96
|
+
const {result} = renderHook(() =>
|
|
97
|
+
useFrameConnection<TestControllerMessage, TestNodeMessage>({
|
|
98
|
+
name: 'test',
|
|
99
|
+
connectTo: 'iframe',
|
|
100
|
+
targetOrigin: '*',
|
|
101
|
+
}),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
const mockData = {someData: 'test'}
|
|
105
|
+
result.current.sendMessage('TEST_MESSAGE', mockData)
|
|
106
|
+
|
|
107
|
+
expect(channel.post).toHaveBeenCalledWith('TEST_MESSAGE', mockData)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('should cleanup on unmount', () => {
|
|
111
|
+
const {unmount} = renderHook(() =>
|
|
112
|
+
useFrameConnection({
|
|
113
|
+
name: 'test',
|
|
114
|
+
connectTo: 'iframe',
|
|
115
|
+
targetOrigin: '*',
|
|
116
|
+
}),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
unmount()
|
|
120
|
+
expect(releaseChannel).toHaveBeenCalled()
|
|
121
|
+
})
|
|
122
|
+
})
|