@sanity/sdk-react 0.0.0-alpha.20 → 0.0.0-alpha.21

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 (40) hide show
  1. package/dist/index.d.ts +276 -207
  2. package/dist/index.js +90 -75
  3. package/dist/index.js.map +1 -1
  4. package/package.json +3 -3
  5. package/src/_exports/index.ts +11 -11
  6. package/src/components/Login/LoginLinks.test.tsx +2 -2
  7. package/src/components/Login/LoginLinks.tsx +2 -2
  8. package/src/components/auth/AuthBoundary.test.tsx +2 -2
  9. package/src/components/auth/LoginCallback.test.tsx +3 -3
  10. package/src/components/auth/LoginCallback.tsx +4 -4
  11. package/src/hooks/auth/useCurrentUser.tsx +1 -0
  12. package/src/hooks/auth/useHandleAuthCallback.test.tsx +16 -0
  13. package/src/hooks/auth/{useHandleCallback.tsx → useHandleAuthCallback.tsx} +6 -6
  14. package/src/hooks/auth/useLogOut.test.tsx +2 -2
  15. package/src/hooks/client/useClient.ts +1 -0
  16. package/src/hooks/comlink/useManageFavorite.test.ts +9 -4
  17. package/src/hooks/comlink/useManageFavorite.ts +42 -13
  18. package/src/hooks/comlink/useRecordDocumentHistoryEvent.test.ts +7 -3
  19. package/src/hooks/comlink/useRecordDocumentHistoryEvent.ts +39 -12
  20. package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +178 -0
  21. package/src/hooks/dashboard/useNavigateToStudioDocument.ts +31 -5
  22. package/src/hooks/dashboard/useStudioWorkspacesByResourceId.test.tsx +5 -1
  23. package/src/hooks/dashboard/useStudioWorkspacesByResourceId.ts +4 -3
  24. package/src/hooks/datasets/useDatasets.ts +6 -3
  25. package/src/hooks/document/useApplyDocumentActions.test.ts +25 -0
  26. package/src/hooks/document/{useApplyActions.ts → useApplyDocumentActions.ts} +13 -12
  27. package/src/hooks/document/{usePermissions.ts → useDocumentPermissions.ts} +8 -6
  28. package/src/hooks/document/useDocumentSyncStatus.ts +4 -1
  29. package/src/hooks/document/useEditDocument.test.ts +8 -8
  30. package/src/hooks/document/useEditDocument.ts +2 -2
  31. package/src/hooks/{infiniteList/useInfiniteList.test.tsx → documents/useDocuments.test.tsx} +9 -9
  32. package/src/hooks/{infiniteList/useInfiniteList.ts → documents/useDocuments.ts} +10 -10
  33. package/src/hooks/{paginatedList/usePaginatedList.test.tsx → paginatedDocuments/usePaginatedDocuments.test.tsx} +14 -14
  34. package/src/hooks/{paginatedList/usePaginatedList.ts → paginatedDocuments/usePaginatedDocuments.ts} +7 -7
  35. package/src/hooks/preview/usePreview.tsx +2 -2
  36. package/src/hooks/projection/useProjection.ts +2 -2
  37. package/src/hooks/projects/useProject.ts +4 -1
  38. package/src/hooks/projects/useProjects.ts +7 -3
  39. package/src/hooks/auth/useHandleCallback.test.tsx +0 -16
  40. package/src/hooks/document/useApplyActions.test.ts +0 -25
@@ -11,18 +11,18 @@ const DEFAULT_PERSPECTIVE = 'drafts'
11
11
  * Result structure returned from the infinite list query
12
12
  * @internal
13
13
  */
14
- interface InfiniteListQueryResult {
14
+ interface UseDocumentsQueryResult {
15
15
  count: number
16
16
  data: DocumentHandle[]
17
17
  }
18
18
 
19
19
  /**
20
- * Configuration options for the useInfiniteList hook
20
+ * Configuration options for the useDocuments hook
21
21
  *
22
22
  * @beta
23
23
  * @category Types
24
24
  */
25
- export interface InfiniteListOptions extends QueryOptions {
25
+ export interface DocumentsOptions extends QueryOptions {
26
26
  /**
27
27
  * GROQ filter expression to apply to the query
28
28
  */
@@ -42,12 +42,12 @@ export interface InfiniteListOptions extends QueryOptions {
42
42
  }
43
43
 
44
44
  /**
45
- * Return value from the useInfiniteList hook
45
+ * Return value from the useDocuments hook
46
46
  *
47
47
  * @beta
48
48
  * @category Types
49
49
  */
50
- export interface InfiniteList {
50
+ export interface DocumentsResponse {
51
51
  /**
52
52
  * Array of document handles for the current batch
53
53
  */
@@ -78,10 +78,10 @@ export interface InfiniteList {
78
78
  * @beta
79
79
  * @category Documents
80
80
  * @param options - Configuration options for the infinite list
81
- * @returns An object containing the list of document handles, the loading state, the total count of retrived document handles, and a function to load more
81
+ * @returns An object containing the list of document handles, the loading state, the total count of retrieved document handles, and a function to load more
82
82
  * @example
83
83
  * ```tsx
84
- * const {data, hasMore, isPending, loadMore} = useInfiniteList({
84
+ * const {data, hasMore, isPending, loadMore} = useDocuments({
85
85
  * filter: '_type == "post"',
86
86
  * search: searchTerm,
87
87
  * batchSize: 10,
@@ -104,14 +104,14 @@ export interface InfiniteList {
104
104
  * ```
105
105
  *
106
106
  */
107
- export function useInfiniteList({
107
+ export function useDocuments({
108
108
  batchSize = DEFAULT_BATCH_SIZE,
109
109
  params,
110
110
  search,
111
111
  filter,
112
112
  orderings,
113
113
  ...options
114
- }: InfiniteListOptions): InfiniteList {
114
+ }: DocumentsOptions): DocumentsResponse {
115
115
  const perspective = options.perspective ?? DEFAULT_PERSPECTIVE
116
116
  const [limit, setLimit] = useState(batchSize)
117
117
 
@@ -155,7 +155,7 @@ export function useInfiniteList({
155
155
  const {
156
156
  data: {count, data},
157
157
  isPending,
158
- } = useQuery<InfiniteListQueryResult>(`{"count":${countQuery},"data":${dataQuery}}`, {
158
+ } = useQuery<UseDocumentsQueryResult>(`{"count":${countQuery},"data":${dataQuery}}`, {
159
159
  ...options,
160
160
  params,
161
161
  perspective,
@@ -3,11 +3,11 @@ import {describe, vi} from 'vitest'
3
3
 
4
4
  import {evaluateSync, parse} from '../_synchronous-groq-js.mjs'
5
5
  import {useQuery} from '../query/useQuery'
6
- import {usePaginatedList} from './usePaginatedList'
6
+ import {usePaginatedDocuments} from './usePaginatedDocuments'
7
7
 
8
8
  vi.mock('../query/useQuery')
9
9
 
10
- describe('usePaginatedList', () => {
10
+ describe('usePaginatedDocuments', () => {
11
11
  beforeEach(() => {
12
12
  const dataset = [
13
13
  {
@@ -76,14 +76,14 @@ describe('usePaginatedList', () => {
76
76
 
77
77
  it('should respect custom page size', () => {
78
78
  const customPageSize = 2
79
- const {result} = renderHook(() => usePaginatedList({pageSize: customPageSize}))
79
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize: customPageSize}))
80
80
 
81
81
  expect(result.current.pageSize).toBe(customPageSize)
82
82
  expect(result.current.data.length).toBeLessThanOrEqual(customPageSize)
83
83
  })
84
84
 
85
85
  it('should filter by document type', () => {
86
- const {result} = renderHook(() => usePaginatedList({filter: '_type == "movie"'}))
86
+ const {result} = renderHook(() => usePaginatedDocuments({filter: '_type == "movie"'}))
87
87
 
88
88
  expect(result.current.data.every((doc) => doc._type === 'movie')).toBe(true)
89
89
  expect(result.current.count).toBe(5) // 5 movies in the dataset
@@ -91,7 +91,7 @@ describe('usePaginatedList', () => {
91
91
 
92
92
  // groq-js doesn't support search filters yet
93
93
  it.skip('should apply search filter', () => {
94
- const {result} = renderHook(() => usePaginatedList({search: 'inter'}))
94
+ const {result} = renderHook(() => usePaginatedDocuments({search: 'inter'}))
95
95
 
96
96
  // Should match "Interstellar"
97
97
  expect(result.current.data.some((doc) => doc._id === 'movie3')).toBe(true)
@@ -99,7 +99,7 @@ describe('usePaginatedList', () => {
99
99
 
100
100
  it('should apply ordering', () => {
101
101
  const {result} = renderHook(() =>
102
- usePaginatedList({
102
+ usePaginatedDocuments({
103
103
  filter: '_type == "movie"',
104
104
  orderings: [{field: 'releaseYear', direction: 'desc'}],
105
105
  }),
@@ -111,7 +111,7 @@ describe('usePaginatedList', () => {
111
111
 
112
112
  it('should calculate pagination values correctly', () => {
113
113
  const pageSize = 2
114
- const {result} = renderHook(() => usePaginatedList({pageSize}))
114
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
115
115
 
116
116
  expect(result.current.currentPage).toBe(1)
117
117
  expect(result.current.totalPages).toBe(3) // 6 items with page size 2
@@ -122,7 +122,7 @@ describe('usePaginatedList', () => {
122
122
 
123
123
  it('should navigate to next page', () => {
124
124
  const pageSize = 2
125
- const {result} = renderHook(() => usePaginatedList({pageSize}))
125
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
126
126
 
127
127
  expect(result.current.currentPage).toBe(1)
128
128
  expect(result.current.data.length).toBe(pageSize)
@@ -138,7 +138,7 @@ describe('usePaginatedList', () => {
138
138
 
139
139
  it('should navigate to previous page', () => {
140
140
  const pageSize = 2
141
- const {result} = renderHook(() => usePaginatedList({pageSize}))
141
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
142
142
 
143
143
  // Go to page 2 first
144
144
  act(() => {
@@ -158,7 +158,7 @@ describe('usePaginatedList', () => {
158
158
 
159
159
  it('should navigate to first page', () => {
160
160
  const pageSize = 2
161
- const {result} = renderHook(() => usePaginatedList({pageSize}))
161
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
162
162
 
163
163
  // Go to last page first
164
164
  act(() => {
@@ -178,7 +178,7 @@ describe('usePaginatedList', () => {
178
178
 
179
179
  it('should navigate to last page', () => {
180
180
  const pageSize = 2
181
- const {result} = renderHook(() => usePaginatedList({pageSize}))
181
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
182
182
 
183
183
  act(() => {
184
184
  result.current.lastPage()
@@ -190,7 +190,7 @@ describe('usePaginatedList', () => {
190
190
 
191
191
  it('should navigate to specific page', () => {
192
192
  const pageSize = 2
193
- const {result} = renderHook(() => usePaginatedList({pageSize}))
193
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
194
194
 
195
195
  act(() => {
196
196
  result.current.goToPage(2) // Go to page 2
@@ -215,7 +215,7 @@ describe('usePaginatedList', () => {
215
215
 
216
216
  it('should set page availability flags correctly', () => {
217
217
  const pageSize = 2
218
- const {result} = renderHook(() => usePaginatedList({pageSize}))
218
+ const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
219
219
  // On first page
220
220
  expect(result.current.hasFirstPage).toBe(false)
221
221
  expect(result.current.hasPreviousPage).toBe(false)
@@ -241,7 +241,7 @@ describe('usePaginatedList', () => {
241
241
 
242
242
  // New test case for resetting the current page when filter changes
243
243
  it('should reset current page when filter changes', () => {
244
- const {result, rerender} = renderHook((props) => usePaginatedList(props), {
244
+ const {result, rerender} = renderHook((props) => usePaginatedDocuments(props), {
245
245
  initialProps: {pageSize: 2, filter: ''},
246
246
  })
247
247
  // Initially, current page should be 1
@@ -7,12 +7,12 @@ import {useQuery} from '../query/useQuery'
7
7
  const DEFAULT_PERSPECTIVE = 'drafts'
8
8
 
9
9
  /**
10
- * Configuration options for the usePaginatedList hook
10
+ * Configuration options for the usePaginatedDocuments hook
11
11
  *
12
12
  * @beta
13
13
  * @category Types
14
14
  */
15
- export interface PaginatedListOptions extends QueryOptions {
15
+ export interface PaginatedDocumentsOptions extends QueryOptions {
16
16
  /**
17
17
  * GROQ filter expression to apply to the query
18
18
  */
@@ -32,12 +32,12 @@ export interface PaginatedListOptions extends QueryOptions {
32
32
  }
33
33
 
34
34
  /**
35
- * Return value from the usePaginatedList hook
35
+ * Return value from the usePaginatedDocuments hook
36
36
  *
37
37
  * @beta
38
38
  * @category Types
39
39
  */
40
- export interface PaginatedList {
40
+ export interface PaginatedDocumentsResponse {
41
41
  /**
42
42
  * Array of document handles for the current page
43
43
  */
@@ -136,7 +136,7 @@ export interface PaginatedList {
136
136
  * previousPage,
137
137
  * hasNextPage,
138
138
  * hasPreviousPage
139
- * } = usePaginatedList({
139
+ * } = usePaginatedDocuments({
140
140
  * filter: '_type == "post"',
141
141
  * search: searchTerm,
142
142
  * pageSize: 10,
@@ -160,14 +160,14 @@ export interface PaginatedList {
160
160
  * ```
161
161
  *
162
162
  */
163
- export function usePaginatedList({
163
+ export function usePaginatedDocuments({
164
164
  filter = '',
165
165
  pageSize = 25,
166
166
  params = {},
167
167
  orderings,
168
168
  search,
169
169
  ...options
170
- }: PaginatedListOptions = {}): PaginatedList {
170
+ }: PaginatedDocumentsOptions = {}): PaginatedDocumentsResponse {
171
171
  const [pageIndex, setPageIndex] = useState(0)
172
172
  const key = JSON.stringify({filter, search, params, orderings, pageSize})
173
173
  // Reset the pageIndex to 0 whenever any query parameters (filter, search,
@@ -51,12 +51,12 @@ export interface UsePreviewResults {
51
51
  * }
52
52
  *
53
53
  * // DocumentList.jsx
54
- * const { data, isPending } = useDocuments({ filter: '_type == "movie"' })
54
+ * const { data } = useDocuments({ filter: '_type == "movie"' })
55
55
  * return (
56
56
  * <div>
57
57
  * <h1>Movies</h1>
58
58
  * <ul>
59
- * {isPending ? 'Loading…' : data.map(movie => (
59
+ * {data.map(movie => (
60
60
  * <li key={movie._id}>
61
61
  * <Suspense fallback='Loading…'>
62
62
  * <PreviewComponent document={movie} />
@@ -65,10 +65,10 @@ export interface UseProjectionResults<TResult extends object> {
65
65
  * }
66
66
  * ```
67
67
  *
68
- * @example Combining with useInfiniteList to render a collection with specific fields
68
+ * @example Combining with useDocuments to render a collection with specific fields
69
69
  * ```
70
70
  * // DocumentList.jsx
71
- * const { data } = useInfiniteList({ filter: '_type == "article"' })
71
+ * const { data } = useDocuments({ filter: '_type == "article"' })
72
72
  * return (
73
73
  * <div>
74
74
  * <h1>Books</h1>
@@ -32,7 +32,10 @@ type UseProject = {
32
32
  (projectId: string): SanityProject
33
33
  }
34
34
 
35
- /** @public */
35
+ /**
36
+ * @public
37
+ * @function
38
+ */
36
39
  export const useProject: UseProject = createStateSourceHook({
37
40
  // remove `undefined` since we're suspending when that is the case
38
41
  getState: getProjectState as (
@@ -6,16 +6,17 @@ import {createStateSourceHook} from '../helpers/createStateSourceHook'
6
6
  /**
7
7
  * @public
8
8
  * @category Types
9
+ * @interface
9
10
  */
10
11
  export type ProjectWithoutMembers = Omit<SanityProject, 'members'>
11
12
 
12
13
  type UseProjects = {
13
14
  /**
14
15
  *
15
- * Returns metadata for each project in your organization.
16
+ * Returns metadata for each project you have access to.
16
17
  *
17
18
  * @category Projects
18
- * @returns An array of metadata (minus the projects’ members) for each project in your organization
19
+ * @returns An array of metadata (minus the projects’ members) for each project
19
20
  * @example
20
21
  * ```tsx
21
22
  * const projects = useProjects()
@@ -32,7 +33,10 @@ type UseProjects = {
32
33
  (): ProjectWithoutMembers[]
33
34
  }
34
35
 
35
- /** @public */
36
+ /**
37
+ * @public
38
+ * @function
39
+ */
36
40
  export const useProjects: UseProjects = createStateSourceHook({
37
41
  // remove `undefined` since we're suspending when that is the case
38
42
  getState: getProjectsState as (instance: SanityInstance) => StateSource<ProjectWithoutMembers[]>,
@@ -1,16 +0,0 @@
1
- import {handleCallback} from '@sanity/sdk'
2
- import {identity} from 'rxjs'
3
- import {describe, it} from 'vitest'
4
-
5
- import {createCallbackHook} from '../helpers/createCallbackHook'
6
-
7
- vi.mock('../helpers/createCallbackHook', () => ({createCallbackHook: vi.fn(identity)}))
8
- vi.mock('@sanity/sdk', () => ({handleCallback: vi.fn()}))
9
-
10
- describe('useHandleCallback', () => {
11
- it('calls `createCallbackHook` with `handleCallback`', async () => {
12
- const {useHandleCallback} = await import('./useHandleCallback')
13
- expect(createCallbackHook).toHaveBeenCalledWith(handleCallback)
14
- expect(useHandleCallback).toBe(handleCallback)
15
- })
16
- })
@@ -1,25 +0,0 @@
1
- import {applyActions, createDocument, type ResourceId} from '@sanity/sdk'
2
- import {describe, it} from 'vitest'
3
-
4
- import {createCallbackHook} from '../helpers/createCallbackHook'
5
-
6
- vi.mock('../helpers/createCallbackHook', () => ({
7
- createCallbackHook: vi.fn((cb) => () => cb),
8
- }))
9
- vi.mock('@sanity/sdk', async (importOriginal) => {
10
- const original = await importOriginal<typeof import('@sanity/sdk')>()
11
- return {...original, applyActions: vi.fn()}
12
- })
13
-
14
- describe('useApplyActions', () => {
15
- it('calls `createCallbackHook` with `applyActions`', async () => {
16
- const {useApplyActions} = await import('./useApplyActions')
17
- const resourceId: ResourceId = 'project1.dataset1'
18
- expect(createCallbackHook).not.toHaveBeenCalled()
19
-
20
- expect(applyActions).not.toHaveBeenCalled()
21
- const apply = useApplyActions(resourceId)
22
- apply(createDocument({_type: 'author'}))
23
- expect(applyActions).toHaveBeenCalledWith(createDocument({_type: 'author'}))
24
- })
25
- })