@sanity/sdk-react 1.0.0 → 2.0.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/sdk-react",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "private": false,
5
5
  "description": "Sanity SDK React toolkit for Content OS",
6
6
  "keywords": [
@@ -42,7 +42,7 @@
42
42
  "browserslist": "extends @sanity/browserslist-config",
43
43
  "prettier": "@sanity/prettier-config",
44
44
  "dependencies": {
45
- "@sanity/client": "^7.0.0",
45
+ "@sanity/client": "^7.2.1",
46
46
  "@sanity/message-protocol": "^0.12.0",
47
47
  "@sanity/types": "^3.83.0",
48
48
  "@types/lodash-es": "^4.17.12",
@@ -51,11 +51,11 @@
51
51
  "react-compiler-runtime": "19.1.0-rc.1",
52
52
  "react-error-boundary": "^5.0.0",
53
53
  "rxjs": "^7.8.2",
54
- "@sanity/sdk": "1.0.0"
54
+ "@sanity/sdk": "2.0.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@sanity/browserslist-config": "^1.0.5",
58
- "@sanity/comlink": "^3.0.2",
58
+ "@sanity/comlink": "^3.0.4",
59
59
  "@sanity/pkg-utils": "^7.2.2",
60
60
  "@sanity/prettier-config": "^1.0.3",
61
61
  "@testing-library/jest-dom": "^6.6.3",
@@ -74,11 +74,11 @@
74
74
  "typescript": "^5.8.3",
75
75
  "vite": "^6.3.4",
76
76
  "vitest": "^3.1.2",
77
- "@repo/config-test": "0.0.1",
77
+ "@repo/config-eslint": "0.0.0",
78
78
  "@repo/package.bundle": "3.82.0",
79
+ "@repo/config-test": "0.0.1",
79
80
  "@repo/package.config": "0.0.1",
80
- "@repo/tsconfig": "0.0.1",
81
- "@repo/config-eslint": "0.0.0"
81
+ "@repo/tsconfig": "0.0.1"
82
82
  },
83
83
  "peerDependencies": {
84
84
  "react": "^18.0.0 || ^19.0.0",
@@ -27,6 +27,7 @@ export {
27
27
  type WindowMessageHandler,
28
28
  } from '../hooks/comlink/useWindowConnection'
29
29
  export {useSanityInstance} from '../hooks/context/useSanityInstance'
30
+ export {useDashboardNavigate} from '../hooks/dashboard/useDashboardNavigate'
30
31
  export {useManageFavorite} from '../hooks/dashboard/useManageFavorite'
31
32
  export {
32
33
  type NavigateToStudioResult,
@@ -0,0 +1,44 @@
1
+ import {type PathChangeMessage} from '@sanity/message-protocol'
2
+ import {renderHook} from '@testing-library/react'
3
+ import {beforeEach, describe, expect, it, vi} from 'vitest'
4
+
5
+ import {useDashboardNavigate} from './useDashboardNavigate'
6
+
7
+ const mockOnMessage = vi.fn()
8
+ let mockMessageHandler: ((data: PathChangeMessage['data']) => void) | undefined
9
+
10
+ vi.mock('../comlink/useWindowConnection', () => {
11
+ return {
12
+ useWindowConnection: ({
13
+ onMessage,
14
+ }: {
15
+ onMessage: Record<string, (data: PathChangeMessage['data']) => void>
16
+ }) => {
17
+ mockMessageHandler = onMessage['dashboard/v1/history/change-path']
18
+ return {
19
+ onMessage: mockOnMessage,
20
+ }
21
+ },
22
+ }
23
+ })
24
+
25
+ describe('useDashboardNavigate', () => {
26
+ const mockNavigateFn = vi.fn()
27
+
28
+ beforeEach(() => {
29
+ vi.resetAllMocks()
30
+ mockMessageHandler = undefined
31
+ })
32
+
33
+ it('calls navigate function with correct data when message is received', () => {
34
+ renderHook(() => useDashboardNavigate(mockNavigateFn))
35
+
36
+ const mockNavigationData = {
37
+ path: '/test-path',
38
+ type: 'push' as const,
39
+ }
40
+ mockMessageHandler?.(mockNavigationData)
41
+
42
+ expect(mockNavigateFn).toHaveBeenCalledWith(mockNavigationData)
43
+ })
44
+ })
@@ -0,0 +1,60 @@
1
+ import {type PathChangeMessage, SDK_CHANNEL_NAME, SDK_NODE_NAME} from '@sanity/message-protocol'
2
+
3
+ import {useWindowConnection} from '../comlink/useWindowConnection'
4
+
5
+ /**
6
+ * @public
7
+ *
8
+ * A helper hook designed to be injected into routing components for apps within the Dashboard.
9
+ * While the Dashboard can usually handle navigation, there are special cases when you
10
+ * are already within a target app, and need to navigate to another route inside of that app.
11
+ *
12
+ * For example, your user might "favorite" a document inside of your application.
13
+ * If they click on the Dashboard favorites item in the sidebar, and are already within your application,
14
+ * there needs to be some way for the dashboard to signal to your application to reroute to where that document was favorited.
15
+ *
16
+ * This hook is intended to receive those messages, and takes a function to route to the correct path.
17
+ *
18
+ * @param navigateFn - Function to handle navigation; should accept:
19
+ * - `path`: a string, which will be a relative path (for example, 'my-route')
20
+ * - `type`: 'push', 'replace', or 'pop', which will be the type of navigation to perform
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * import {useDashboardNavigate} from '@sanity/sdk-react'
25
+ * import {BrowserRouter, useNavigate} from 'react-router'
26
+ * import {Suspense} from 'react'
27
+ *
28
+ * function DashboardNavigationHandler() {
29
+ * const navigate = useNavigate()
30
+ * useDashboardNavigate(({path, type}) => {
31
+ * navigate(path, {replace: type === 'replace'})
32
+ * })
33
+ * return null
34
+ * }
35
+ *
36
+ * // Wrap the component with Suspense since the hook may suspend
37
+ * function MyApp() {
38
+ * return (
39
+ * <BrowserRouter>
40
+ * <Suspense>
41
+ * <DashboardNavigationHandler />
42
+ * </Suspense>
43
+ * </BrowserRouter>
44
+ * )
45
+ * }
46
+ * ```
47
+ */
48
+ export function useDashboardNavigate(
49
+ navigateFn: (options: PathChangeMessage['data']) => void,
50
+ ): void {
51
+ useWindowConnection<PathChangeMessage, never>({
52
+ name: SDK_NODE_NAME,
53
+ connectTo: SDK_CHANNEL_NAME,
54
+ onMessage: {
55
+ 'dashboard/v1/history/change-path': (data: PathChangeMessage['data']) => {
56
+ navigateFn(data)
57
+ },
58
+ },
59
+ })
60
+ }
@@ -44,20 +44,18 @@ interface UseManageFavoriteProps extends DocumentHandle {
44
44
  * - `favorite` - Function to add document to favorites
45
45
  * - `unfavorite` - Function to remove document from favorites
46
46
  * - `isFavorited` - Boolean indicating if document is currently favorited
47
- * - `isConnected` - Boolean indicating if connection to Dashboard UI is established
48
47
  *
49
48
  * @example
50
49
  * ```tsx
51
50
  * function FavoriteButton(props: DocumentActionProps) {
52
51
  * const {documentId, documentType} = props
53
- * const {favorite, unfavorite, isFavorited, isConnected} = useManageFavorite({
52
+ * const {favorite, unfavorite, isFavorited} = useManageFavorite({
54
53
  * documentId,
55
54
  * documentType
56
55
  * })
57
56
  *
58
57
  * return (
59
58
  * <Button
60
- * disabled={!isConnected}
61
59
  * onClick={() => isFavorited ? unfavorite() : favorite()}
62
60
  * text={isFavorited ? 'Remove from favorites' : 'Add to favorites'}
63
61
  * />
@@ -33,7 +33,6 @@ export interface NavigateToStudioResult {
33
33
  * studios with the same projectId and dataset
34
34
  * @returns An object containing:
35
35
  * - `navigateToStudioDocument` - Function that when called will navigate to the studio document
36
- * - `isConnected` - Boolean indicating if connection to Dashboard is established
37
36
  *
38
37
  * @example
39
38
  * ```tsx
@@ -42,10 +41,9 @@ export interface NavigateToStudioResult {
42
41
  * import {Suspense} from 'react'
43
42
  *
44
43
  * function NavigateButton({documentHandle}: {documentHandle: DocumentHandle}) {
45
- * const {navigateToStudioDocument, isConnected} = useNavigateToStudioDocument(documentHandle)
44
+ * const {navigateToStudioDocument} = useNavigateToStudioDocument(documentHandle)
46
45
  * return (
47
46
  * <Button
48
- * disabled={!isConnected}
49
47
  * onClick={navigateToStudioDocument}
50
48
  * text="Navigate to Studio Document"
51
49
  * />
@@ -36,7 +36,6 @@ interface UseRecordDocumentHistoryEventProps extends DocumentHandle {
36
36
  * @param documentHandle - The document handle containing document ID and type, like `{_id: '123', _type: 'book'}`
37
37
  * @returns An object containing:
38
38
  * - `recordEvent` - Function to record document interactions
39
- * - `isConnected` - Boolean indicating if connection to Studio is established
40
39
  *
41
40
  * @example
42
41
  * ```tsx
@@ -46,7 +45,7 @@ interface UseRecordDocumentHistoryEventProps extends DocumentHandle {
46
45
  *
47
46
  * function RecordEventButton(props: DocumentActionProps) {
48
47
  * const {documentId, documentType, resourceType, resourceId} = props
49
- * const {recordEvent, isConnected} = useRecordDocumentHistoryEvent({
48
+ * const {recordEvent} = useRecordDocumentHistoryEvent({
50
49
  * documentId,
51
50
  * documentType,
52
51
  * resourceType,
@@ -54,7 +53,6 @@ interface UseRecordDocumentHistoryEventProps extends DocumentHandle {
54
53
  * })
55
54
  * return (
56
55
  * <Button
57
- * disabled={!isConnected}
58
56
  * onClick={() => recordEvent('viewed')}
59
57
  * text="Viewed"
60
58
  * />