@sanity/sdk-react 0.0.0-alpha.11 → 0.0.0-alpha.12

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 (35) hide show
  1. package/README.md +0 -10
  2. package/dist/_chunks-es/context.js.map +1 -1
  3. package/dist/_chunks-es/useLogOut.js.map +1 -1
  4. package/dist/components.js +8 -1
  5. package/dist/components.js.map +1 -1
  6. package/dist/context.d.ts +4 -2
  7. package/dist/hooks.d.ts +401 -92
  8. package/dist/hooks.js +36 -11
  9. package/dist/hooks.js.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/package.json +4 -4
  13. package/src/_exports/hooks.ts +4 -2
  14. package/src/_exports/index.ts +1 -1
  15. package/src/components/SanityApp.tsx +8 -0
  16. package/src/components/auth/AuthBoundary.tsx +3 -2
  17. package/src/components/utils.ts +3 -0
  18. package/src/context/SanityProvider.tsx +4 -2
  19. package/src/hooks/auth/useAuthState.tsx +0 -2
  20. package/src/hooks/auth/useCurrentUser.tsx +2 -1
  21. package/src/hooks/client/useClient.ts +1 -0
  22. package/src/hooks/comlink/useFrameConnection.test.tsx +45 -10
  23. package/src/hooks/comlink/useFrameConnection.ts +24 -5
  24. package/src/hooks/comlink/useWindowConnection.test.ts +43 -12
  25. package/src/hooks/comlink/useWindowConnection.ts +13 -1
  26. package/src/hooks/context/useSanityInstance.ts +1 -1
  27. package/src/hooks/document/useApplyActions.ts +45 -1
  28. package/src/hooks/document/useDocument.ts +77 -3
  29. package/src/hooks/document/useDocumentEvent.ts +23 -1
  30. package/src/hooks/document/useDocumentSyncStatus.test.ts +1 -1
  31. package/src/hooks/document/useDocumentSyncStatus.ts +25 -2
  32. package/src/hooks/document/useEditDocument.ts +118 -3
  33. package/src/hooks/document/usePermissions.ts +28 -0
  34. package/src/hooks/documentCollection/useDocuments.ts +15 -7
  35. package/src/hooks/preview/usePreview.tsx +7 -4
@@ -1,8 +1,8 @@
1
- import {type Message, type Node} from '@sanity/comlink'
1
+ import {type Message, type Node, type Status} from '@sanity/comlink'
2
2
  import {getOrCreateNode, releaseNode} from '@sanity/sdk'
3
3
  import {beforeEach, describe, expect, it, vi} from 'vitest'
4
4
 
5
- import {renderHook} from '../../../test/test-utils'
5
+ import {act, renderHook} from '../../../test/test-utils'
6
6
  import {useWindowConnection} from './useWindowConnection'
7
7
 
8
8
  vi.mock(import('@sanity/sdk'), async (importOriginal) => {
@@ -26,24 +26,55 @@ interface AnotherMessage {
26
26
 
27
27
  type TestMessages = TestMessage | AnotherMessage
28
28
 
29
- function createMockNode() {
30
- return {
31
- // return unsubscribe function
32
- on: vi.fn(() => () => {}),
33
- post: vi.fn(),
34
- stop: vi.fn(),
35
- } as unknown as Node<Message, Message>
36
- }
37
-
38
29
  describe('useWindowConnection', () => {
39
30
  let node: Node<Message, Message>
31
+ let statusCallback: ((status: Status) => void) | null = null
32
+
33
+ function createMockNode() {
34
+ return {
35
+ // return unsubscribe function
36
+ on: vi.fn(() => () => {}),
37
+ post: vi.fn(),
38
+ stop: vi.fn(),
39
+ onStatus: vi.fn((callback) => {
40
+ statusCallback = callback
41
+ return () => {}
42
+ }),
43
+ } as unknown as Node<Message, Message>
44
+ }
40
45
 
41
46
  beforeEach(() => {
47
+ statusCallback = null
42
48
  node = createMockNode()
43
-
44
49
  vi.mocked(getOrCreateNode).mockReturnValue(node as unknown as Node<Message, Message>)
45
50
  })
46
51
 
52
+ it('should initialize with idle status', () => {
53
+ const {result} = renderHook(() =>
54
+ useWindowConnection<TestMessages, TestMessages>({
55
+ name: 'test',
56
+ connectTo: 'window',
57
+ }),
58
+ )
59
+
60
+ expect(result.current.status).toBe('idle')
61
+ })
62
+
63
+ it('should update status to connected when node connects', async () => {
64
+ const {result} = renderHook(() =>
65
+ useWindowConnection<TestMessages, TestMessages>({
66
+ name: 'test',
67
+ connectTo: 'window',
68
+ }),
69
+ )
70
+
71
+ expect(result.current.status).toBe('idle')
72
+ act(() => {
73
+ statusCallback?.('connected')
74
+ })
75
+ expect(result.current.status).toBe('connected')
76
+ })
77
+
47
78
  it('should register message handlers', () => {
48
79
  const mockHandler = vi.fn()
49
80
  const mockData = {someData: 'test'}
@@ -1,5 +1,6 @@
1
+ import {type Status} from '@sanity/comlink'
1
2
  import {type FrameMessage, getOrCreateNode, releaseNode, type WindowMessage} from '@sanity/sdk'
2
- import {useCallback, useEffect, useMemo} from 'react'
3
+ import {useCallback, useEffect, useMemo, useState} from 'react'
3
4
 
4
5
  import {useSanityInstance} from '../context/useSanityInstance'
5
6
 
@@ -27,6 +28,7 @@ export interface WindowConnection<TMessage extends WindowMessage> {
27
28
  type: TType,
28
29
  data?: Extract<TMessage, {type: TType}>['data'],
29
30
  ) => void
31
+ status: Status
30
32
  }
31
33
 
32
34
  /**
@@ -38,12 +40,21 @@ export function useWindowConnection<
38
40
  >(options: UseWindowConnectionOptions<TFrameMessage>): WindowConnection<TWindowMessage> {
39
41
  const {name, onMessage, connectTo} = options
40
42
  const instance = useSanityInstance()
43
+ const [status, setStatus] = useState<Status>('idle')
41
44
 
42
45
  const node = useMemo(
43
46
  () => getOrCreateNode(instance, {name, connectTo}),
44
47
  [instance, name, connectTo],
45
48
  )
46
49
 
50
+ useEffect(() => {
51
+ const unsubscribe = node.onStatus((newStatus) => {
52
+ setStatus(newStatus)
53
+ })
54
+
55
+ return unsubscribe
56
+ }, [node, instance, name])
57
+
47
58
  useEffect(() => {
48
59
  if (!onMessage) return
49
60
 
@@ -78,5 +89,6 @@ export function useWindowConnection<
78
89
 
79
90
  return {
80
91
  sendMessage,
92
+ status,
81
93
  }
82
94
  }
@@ -6,7 +6,7 @@ import {SanityInstanceContext} from '../../context/SanityProvider'
6
6
  /**
7
7
  * `useSanityInstance` returns the current Sanity instance from the application context.
8
8
  * This must be called from within a `SanityProvider` component.
9
- * @public
9
+ * @internal
10
10
  * @returns The current Sanity instance
11
11
  * @example
12
12
  * ```tsx
@@ -8,11 +8,55 @@ import {type SanityDocument} from '@sanity/types'
8
8
 
9
9
  import {createCallbackHook} from '../helpers/createCallbackHook'
10
10
 
11
- /** @beta */
11
+ /**
12
+ *
13
+ * @beta
14
+ *
15
+ * Provides a callback for applying one or more actions to a document.
16
+ *
17
+ * @category Documents
18
+ * @returns A function that takes one more more {@link DocumentAction}s and returns a promise that resolves to an {@link ActionsResult}.
19
+ * @example Publish or unpublish a document
20
+ * ```
21
+ * import { publishDocument, unpublishDocument } from '@sanity/sdk'
22
+ * import { useApplyActions } from '@sanity/sdk-react'
23
+ *
24
+ * const apply = useApplyActions()
25
+ * const myDocument = { _id: 'my-document-id', _type: 'my-document-type' }
26
+ *
27
+ * return (
28
+ * <button onClick={() => apply(publishDocument(myDocument))}>Publish</button>
29
+ * <button onClick={() => apply(unpublishDocument(myDocument))}>Unpublish</button>
30
+ * )
31
+ * ```
32
+ *
33
+ * @example Create and publish a new document
34
+ * ```
35
+ * import { createDocument, publishDocument } from '@sanity/sdk'
36
+ * import { useApplyActions } from '@sanity/sdk-react'
37
+ *
38
+ * const apply = useApplyActions()
39
+ *
40
+ * const handleCreateAndPublish = () => {
41
+ * const handle = { _id: window.crypto.randomUUID(), _type: 'my-document-type' }
42
+ * apply([
43
+ * createDocument(handle),
44
+ * publishDocument(handle),
45
+ * ])
46
+ * }
47
+ *
48
+ * return (
49
+ * <button onClick={handleCreateAndPublish}>
50
+ * I’m feeling lucky
51
+ * </button>
52
+ * )
53
+ * ```
54
+ */
12
55
  export function useApplyActions(): <TDocument extends SanityDocument>(
13
56
  action: DocumentAction<TDocument> | DocumentAction<TDocument>[],
14
57
  options?: ApplyActionsOptions,
15
58
  ) => Promise<ActionsResult<TDocument>>
59
+
16
60
  /** @beta */
17
61
  export function useApplyActions(): (
18
62
  action: DocumentAction | DocumentAction[],
@@ -10,16 +10,90 @@ import {useCallback, useMemo, useSyncExternalStore} from 'react'
10
10
 
11
11
  import {useSanityInstance} from '../context/useSanityInstance'
12
12
 
13
- /** @beta */
13
+ /**
14
+ * @beta
15
+ *
16
+ * ## useDocument(doc, path)
17
+ * Read and subscribe to nested values in a document
18
+ * @category Documents
19
+ * @param doc - The document to read state from
20
+ * @param path - The path to the nested value to read from
21
+ * @returns The value at the specified path
22
+ * @example
23
+ * ```tsx
24
+ * import {type DocumentHandle, useDocument} from '@sanity/sdk-react'
25
+ *
26
+ * function OrderLink({documentHandle}: {documentHandle: DocumentHandle}) {
27
+ * const title = useDocument(documentHandle, 'title')
28
+ * const id = useDocument(documentHandle, '_id')
29
+ *
30
+ * return (
31
+ * <a href=`/order/${id}`>Order {title} today!</a>
32
+ * )
33
+ * }
34
+ * ```
35
+ *
36
+ */
14
37
  export function useDocument<
15
38
  TDocument extends SanityDocument,
16
39
  TPath extends JsonMatchPath<TDocument>,
17
40
  >(doc: string | DocumentHandle<TDocument>, path: TPath): JsonMatch<TDocument, TPath> | undefined
18
- /** @beta */
41
+
42
+ /**
43
+ * @beta
44
+ * ## useDocument(doc)
45
+ * Read and subscribe to an entire document
46
+ * @param doc - The document to read state from
47
+ * @returns The document state as an object
48
+ * @example
49
+ * ```tsx
50
+ * import {type SanityDocument, type DocumentHandle, useDocument} from '@sanity/sdk-react'
51
+ *
52
+ * interface Book extends SanityDocument {
53
+ * title: string
54
+ * author: string
55
+ * summary: string
56
+ * }
57
+ *
58
+ * function DocumentView({documentHandle}: {documentHandle: DocumentHandle}) {
59
+ * const book = useDocument<Book>(documentHandle)
60
+ *
61
+ * return (
62
+ * <article>
63
+ * <h1>{book?.title}</h1>
64
+ * <address>By {book?.author}</address>
65
+ *
66
+ * <h2>Summary</h2>
67
+ * {book?.summary}
68
+ *
69
+ * <h2>Order</h2>
70
+ * <a href=`/order/${book._id}`>Order {book?.title} today!</a>
71
+ * </article>
72
+ * )
73
+ * }
74
+ * ```
75
+ *
76
+ */
19
77
  export function useDocument<TDocument extends SanityDocument>(
20
78
  doc: string | DocumentHandle<TDocument>,
21
79
  ): TDocument | null
22
- /** @beta */
80
+
81
+ /**
82
+ * @beta
83
+ * Reads and subscribes to a document’s realtime state, incorporating both local and remote changes.
84
+ * When called with a `path` argument, the hook will return the nested value’s state.
85
+ * When called without a `path` argument, the entire document’s state will be returned.
86
+ *
87
+ * @remarks
88
+ * `useDocument` is designed to be used within a realtime context in which local updates to documents
89
+ * need to be displayed before they are persisted to the remote copy. This can be useful within a collaborative
90
+ * or realtime editing interface where local changes need to be reflected immediately.
91
+ *
92
+ * However, this hook can be too resource intensive for applications where static document values simply
93
+ * need to be displayed (or when changes to documents don’t need to be reflected immediately);
94
+ * consider using `usePreview` or `useQuery` for these use cases instead. These hooks leverage the Sanity
95
+ * Live Content API to provide a more efficient way to read and subscribe to document state.
96
+ */
23
97
  export function useDocument(doc: string | DocumentHandle, path?: string): unknown {
24
98
  const documentId = typeof doc === 'string' ? doc : doc._id
25
99
  const instance = useSanityInstance()
@@ -3,7 +3,29 @@ import {useCallback, useEffect, useInsertionEffect, useRef} from 'react'
3
3
 
4
4
  import {useSanityInstance} from '../context/useSanityInstance'
5
5
 
6
- /** @beta */
6
+ /**
7
+ *
8
+ * @beta
9
+ *
10
+ * Subscribes an event handler to events in your application’s document store, such as document
11
+ * creation, deletion, and updates.
12
+ *
13
+ * @category Documents
14
+ * @param handler - The event handler to register.
15
+ * @example
16
+ * ```
17
+ * import {useDocumentEvent} from '@sanity/sdk-react'
18
+ * import {type DocumentEvent} from '@sanity/sdk'
19
+ *
20
+ * useDocumentEvent((event) => {
21
+ * if (event.type === DocumentEvent.DocumentDeletedEvent) {
22
+ * alert(`Document with ID ${event.documentId} deleted!`)
23
+ * } else {
24
+ * console.log(event)
25
+ * }
26
+ * })
27
+ * ```
28
+ */
7
29
  export function useDocumentEvent(handler: (documentEvent: DocumentEvent) => void): void {
8
30
  const ref = useRef(handler)
9
31
 
@@ -7,7 +7,7 @@ import {createStateSourceHook} from '../helpers/createStateSourceHook'
7
7
  vi.mock('../helpers/createStateSourceHook', () => ({createStateSourceHook: vi.fn(identity)}))
8
8
  vi.mock('@sanity/sdk', () => ({getDocumentSyncStatus: vi.fn()}))
9
9
 
10
- describe('useAuthToken', () => {
10
+ describe('useDocumentSyncStatus', () => {
11
11
  it('calls `createStateSourceHook` with `getTokenState`', async () => {
12
12
  const {useDocumentSyncStatus} = await import('./useDocumentSyncStatus')
13
13
  expect(createStateSourceHook).toHaveBeenCalledWith(getDocumentSyncStatus)
@@ -1,6 +1,29 @@
1
- import {getDocumentSyncStatus} from '@sanity/sdk'
1
+ import {type DocumentHandle, getDocumentSyncStatus} from '@sanity/sdk'
2
2
 
3
3
  import {createStateSourceHook} from '../helpers/createStateSourceHook'
4
4
 
5
+ type UseDocumentSyncStatus = {
6
+ /**
7
+ * Exposes the document’s sync status between local and remote document states.
8
+ *
9
+ * @category Documents
10
+ * @param doc - The document handle to get sync status for
11
+ * @returns `true` if local changes are synced with remote, `false` if the changes are not synced, and `undefined` if the document is not found
12
+ * @example Disable a Save button when there are no changes to sync
13
+ * ```
14
+ * const myDocumentHandle = { _id: 'documentId', _type: 'documentType' }
15
+ * const documentSynced = useDocumentSyncStatus(myDocumentHandle)
16
+ *
17
+ * return (
18
+ * <button disabled={documentSynced}>
19
+ * Save Changes
20
+ * </button>
21
+ * )
22
+ * ```
23
+ */
24
+ (doc: DocumentHandle): boolean | undefined
25
+ }
26
+
5
27
  /** @beta */
6
- export const useDocumentSyncStatus = createStateSourceHook(getDocumentSyncStatus)
28
+ export const useDocumentSyncStatus: UseDocumentSyncStatus =
29
+ createStateSourceHook(getDocumentSyncStatus)
@@ -17,7 +17,52 @@ const ignoredKeys = ['_id', '_type', '_createdAt', '_updatedAt', '_rev']
17
17
 
18
18
  type Updater<TValue> = TValue | ((nextValue: TValue) => TValue)
19
19
 
20
- /** @beta */
20
+ /**
21
+ *
22
+ * @beta
23
+ *
24
+ * ## useEditDocument(doc, path)
25
+ * Edit a nested value within a document
26
+ *
27
+ * @category Documents
28
+ * @param doc - The document to be edited; either as a document handle or the document’s ID a string
29
+ * @param path - The path to the nested value to be edited
30
+ * @returns A function to update the nested value. Accepts either a new value, or an updater function that exposes the previous value and returns a new value.
31
+ * @example Update a document’s name by providing the new value directly
32
+ * ```
33
+ * const handle = { _id: 'documentId', _type: 'documentType' }
34
+ * const name = useDocument(handle, 'name')
35
+ * const editName = useEditDocument(handle, 'name')
36
+ *
37
+ * function handleNameChange(event: React.ChangeEvent<HTMLInputElement>) {
38
+ * editName(event.target.value)
39
+ * }
40
+ *
41
+ * return (
42
+ * <input type='text' value={name} onChange={handleNameChange} />
43
+ * )
44
+ * ```
45
+ *
46
+ * @example Update a count on a document by providing an updater function
47
+ * ```
48
+ * const handle = { _id: 'documentId', _type: 'documentType' }
49
+ * const count = useDocument(handle, 'count')
50
+ * const editCount = useEditDocument(handle, 'count')
51
+ *
52
+ * function incrementCount() {
53
+ * editCount(previousCount => previousCount + 1)
54
+ * }
55
+ *
56
+ * return (
57
+ * <>
58
+ * <button onClick={incrementCount}>
59
+ * Increment
60
+ * </button>
61
+ * Current count: {count}
62
+ * </>
63
+ * )
64
+ * ```
65
+ */
21
66
  export function useEditDocument<
22
67
  TDocument extends SanityDocument,
23
68
  TPath extends JsonMatchPath<TDocument>,
@@ -25,11 +70,81 @@ export function useEditDocument<
25
70
  doc: string | DocumentHandle<TDocument>,
26
71
  path: TPath,
27
72
  ): (nextValue: Updater<JsonMatch<TDocument, TPath>>) => Promise<ActionsResult<TDocument>>
28
- /** @beta */
73
+
74
+ /**
75
+ *
76
+ * @beta
77
+ *
78
+ * ## useEditDocument(doc)
79
+ * Edit an entire document
80
+ * @param doc - The document to be edited; either as a document handle or the document’s ID a string
81
+ * @returns A function to update the document state. Accepts either a new document state, or an updater function that exposes the previous document state and returns the new document state.
82
+ * @example
83
+ * ```
84
+ * const myDocumentHandle = { _id: 'documentId', _type: 'documentType' }
85
+ *
86
+ * const myDocument = useDocument(myDocumentHandle)
87
+ * const { title, price } = myDocument
88
+ *
89
+ * const editMyDocument = useEditDocument(myDocumentHandle)
90
+ *
91
+ * function handleFieldChange(e: React.ChangeEvent<HTMLInputElement>) {
92
+ * const {name, value} = e.currentTarget
93
+ * // Use an updater function to update the document state based on the previous state
94
+ * editMyDocument(previousDocument => ({
95
+ * ...previousDocument,
96
+ * [name]: value
97
+ * }))
98
+ * }
99
+ *
100
+ * function handleSaleChange(e: React.ChangeEvent<HTMLInputElement>) {
101
+ * const { checked } = e.currentTarget
102
+ * if (checked) {
103
+ * // Use an updater function to add a new salePrice field;
104
+ * // set it at a 20% discount off the normal price
105
+ * editMyDocument(previousDocument => ({
106
+ * ...previousDocument,
107
+ * salePrice: previousDocument.price * 0.8,
108
+ * }))
109
+ * } else {
110
+ * // Get the document state without the salePrice field
111
+ * const { salePrice, ...rest } = myDocument
112
+ * // Update the document state to remove the salePrice field
113
+ * editMyDocument(rest)
114
+ * }
115
+ * }
116
+ *
117
+ * return (
118
+ * <>
119
+ * <form onSubmit={e => e.preventDefault()}>
120
+ * <input name='title' type='text' value={title} onChange={handleFieldChange} />
121
+ * <input name='price' type='number' value={price} onChange={handleFieldChange} />
122
+ * <input
123
+ * name='salePrice'
124
+ * type='checkbox'
125
+ * checked={Object(myDocument).hasOwnProperty('salePrice')}
126
+ * onChange={handleSaleChange}
127
+ * />
128
+ * </form>
129
+ * <pre><code>
130
+ * {JSON.stringify(myDocument, null, 2)}
131
+ * </code></pre>
132
+ * </>
133
+ * )
134
+ * ```
135
+ */
29
136
  export function useEditDocument<TDocument extends SanityDocument>(
30
137
  doc: string | DocumentHandle<TDocument>,
31
138
  ): (nextValue: Updater<TDocument>) => Promise<ActionsResult<TDocument>>
32
- /** @beta */
139
+
140
+ /**
141
+ *
142
+ * @beta
143
+ *
144
+ * Enables editing of a document’s state.
145
+ * When called with a `path` argument, the hook will return a function for updating a nested value.
146
+ * When called without a `path` argument, the hook will return a function for updating the entire document.
147
+ */
33
148
  export function useEditDocument(
34
149
  doc: string | DocumentHandle,
35
150
  path?: string,
@@ -0,0 +1,28 @@
1
+ import {type DocumentAction, getPermissionsState, type PermissionsResult} from '@sanity/sdk'
2
+ import {useCallback, useMemo, useSyncExternalStore} from 'react'
3
+ import {filter, firstValueFrom} from 'rxjs'
4
+
5
+ import {useSanityInstance} from '../context/useSanityInstance'
6
+
7
+ /** @beta */
8
+ export function usePermissions(actions: DocumentAction | DocumentAction[]): PermissionsResult {
9
+ const instance = useSanityInstance()
10
+ const isDocumentReady = useCallback(
11
+ () => getPermissionsState(instance, actions).getCurrent() !== undefined,
12
+ [actions, instance],
13
+ )
14
+ if (!isDocumentReady()) {
15
+ throw firstValueFrom(
16
+ getPermissionsState(instance, actions).observable.pipe(
17
+ filter((result) => result !== undefined),
18
+ ),
19
+ )
20
+ }
21
+
22
+ const {subscribe, getCurrent} = useMemo(
23
+ () => getPermissionsState(instance, actions),
24
+ [actions, instance],
25
+ )
26
+
27
+ return useSyncExternalStore(subscribe, getCurrent) as PermissionsResult
28
+ }
@@ -5,8 +5,10 @@ import {useSanityInstance} from '../context/useSanityInstance'
5
5
 
6
6
  /**
7
7
  * @public
8
+ * A live collection of {@link DocumentHandle}s, along with metadata about the collection and a function for loading more of them.
9
+ * @category Types
8
10
  */
9
- export interface DocumentCollection {
11
+ export interface DocumentHandleCollection {
10
12
  /** Retrieve more documents matching the provided options */
11
13
  loadMore: () => void
12
14
  /** The retrieved document handles of the documents matching the provided options */
@@ -31,13 +33,19 @@ const STABLE_EMPTY = {
31
33
  /**
32
34
  * @public
33
35
  *
34
- * The `useDocuments` hook retrieves and provides access to a live collection of documents, optionally filtered, sorted, and matched to a given Content Lake perspective.
35
- * Because the returned document collection is live, the results will update in real time until the component invoking the hook is unmounted.
36
+ * Retrieves and provides access to a live collection of {@link DocumentHandle}s, with an optional filter and sort applied.
37
+ * The returned document handles are canonical — that is, they refer to the document in its current state, whether draft, published, or within a release or perspective.
38
+ * Because the returned document handle collection is live, the results will update in real time until the component invoking the hook is unmounted.
36
39
  *
40
+ * @remarks
41
+ * {@link DocumentHandle}s are used by many other hooks (such as {@link usePreview}, {@link useDocument}, and {@link useEditDocument})
42
+ * to work with documents in various ways without the entire document needing to be fetched upfront.
43
+ *
44
+ * @category Documents
37
45
  * @param options - Options for narrowing and sorting the document collection
38
- * @returns The collection of documents matching the provided options (if any), as well as properties describing the collection and a function to load more.
46
+ * @returns The collection of document handles matching the provided options (if any), as well as properties describing the collection and a function to load more.
39
47
  *
40
- * @example Retrieving all documents of type 'movie'
48
+ * @example Retrieving document handles for all documents of type 'movie'
41
49
  * ```
42
50
  * const { results, isPending } = useDocuments({ filter: '_type == "movie"' })
43
51
  *
@@ -54,7 +62,7 @@ const STABLE_EMPTY = {
54
62
  * )
55
63
  * ```
56
64
  *
57
- * @example Retrieving all movies released since 1980, sorted by director’s last name
65
+ * @example Retrieving document handles for all movies released since 1980, sorted by director’s last name
58
66
  * ```
59
67
  * const { results } = useDocuments({
60
68
  * filter: '_type == "movie" && releaseDate >= "1980-01-01"',
@@ -79,7 +87,7 @@ const STABLE_EMPTY = {
79
87
  * )
80
88
  * ```
81
89
  */
82
- export function useDocuments(options: DocumentListOptions = {}): DocumentCollection {
90
+ export function useDocuments(options: DocumentListOptions = {}): DocumentHandleCollection {
83
91
  const instance = useSanityInstance()
84
92
 
85
93
  // NOTE: useState is used because it guaranteed to return a stable reference
@@ -5,7 +5,8 @@ import {distinctUntilChanged, EMPTY, Observable, startWith, switchMap} from 'rxj
5
5
  import {useSanityInstance} from '../context/useSanityInstance'
6
6
 
7
7
  /**
8
- * @alpha
8
+ * @beta
9
+ * @category Types
9
10
  */
10
11
  export interface UsePreviewOptions {
11
12
  document: DocumentHandle
@@ -13,7 +14,8 @@ export interface UsePreviewOptions {
13
14
  }
14
15
 
15
16
  /**
16
- * @alpha
17
+ * @beta
18
+ * @category Types
17
19
  */
18
20
  export interface UsePreviewResults {
19
21
  /** The results of resolving the document’s preview values */
@@ -23,13 +25,14 @@ export interface UsePreviewResults {
23
25
  }
24
26
 
25
27
  /**
26
- * @alpha
28
+ * @beta
27
29
  *
28
- * The `usePreview` hook takes a document (via a `DocumentHandle`) and returns its resolved preview values,
30
+ * Returns the preview values of a document (specified via a `DocumentHandle`),
29
31
  * including the document’s `title`, `subtitle`, `media`, and `status`. These values are live and will update in realtime.
30
32
  * To reduce unnecessary network requests for resolving the preview values, an optional `ref` can be passed to the hook so that preview
31
33
  * resolution will only occur if the `ref` is intersecting the current viewport.
32
34
  *
35
+ * @category Documents
33
36
  * @param options - The document handle for the document you want to resolve preview values for, and an optional ref
34
37
  * @returns The preview values for the given document and a boolean to indicate whether the resolution is pending
35
38
  *