@sanity/sdk-react 0.0.0-alpha.2 → 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.
- package/README.md +38 -67
- package/dist/index.d.ts +4811 -2
- package/dist/index.js +1069 -2
- package/dist/index.js.map +1 -1
- package/package.json +27 -58
- package/src/_exports/index.ts +66 -10
- package/src/components/Login/LoginLinks.test.tsx +4 -14
- package/src/components/Login/LoginLinks.tsx +16 -31
- package/src/components/SDKProvider.test.tsx +79 -0
- package/src/components/SDKProvider.tsx +42 -0
- package/src/components/SanityApp.test.tsx +156 -0
- package/src/components/SanityApp.tsx +90 -0
- package/src/components/auth/AuthBoundary.test.tsx +6 -19
- package/src/components/auth/AuthBoundary.tsx +20 -4
- package/src/components/auth/Login.test.tsx +2 -16
- package/src/components/auth/Login.tsx +11 -30
- package/src/components/auth/LoginCallback.test.tsx +5 -20
- package/src/components/auth/LoginCallback.tsx +9 -14
- package/src/components/auth/LoginError.test.tsx +2 -17
- package/src/components/auth/LoginError.tsx +11 -16
- package/src/components/auth/LoginFooter.test.tsx +2 -16
- package/src/components/auth/LoginFooter.tsx +8 -24
- package/src/components/auth/LoginLayout.test.tsx +2 -16
- package/src/components/auth/LoginLayout.tsx +8 -38
- package/src/components/auth/authTestHelpers.tsx +11 -0
- package/src/components/utils.ts +22 -0
- package/src/context/SanityInstanceContext.ts +4 -0
- package/src/{components/context → context}/SanityProvider.test.tsx +2 -2
- package/src/context/SanityProvider.tsx +50 -0
- package/src/hooks/_synchronous-groq-js.mjs +4 -0
- package/src/hooks/auth/useAuthState.tsx +4 -5
- package/src/hooks/auth/useAuthToken.tsx +1 -1
- package/src/hooks/auth/useCurrentUser.tsx +28 -4
- package/src/hooks/auth/useDashboardOrganizationId.test.tsx +42 -0
- package/src/hooks/auth/useDashboardOrganizationId.tsx +29 -0
- package/src/hooks/auth/useHandleAuthCallback.test.tsx +16 -0
- package/src/hooks/auth/{useHandleCallback.tsx → useHandleAuthCallback.tsx} +7 -6
- package/src/hooks/auth/useLogOut.test.tsx +2 -2
- package/src/hooks/auth/useLogOut.tsx +1 -1
- package/src/hooks/auth/useLoginUrls.tsx +1 -0
- package/src/hooks/client/useClient.ts +9 -30
- package/src/hooks/comlink/useFrameConnection.test.tsx +167 -0
- package/src/hooks/comlink/useFrameConnection.ts +107 -0
- package/src/hooks/comlink/useManageFavorite.test.ts +111 -0
- package/src/hooks/comlink/useManageFavorite.ts +130 -0
- package/src/hooks/comlink/useRecordDocumentHistoryEvent.test.ts +81 -0
- package/src/hooks/comlink/useRecordDocumentHistoryEvent.ts +106 -0
- package/src/hooks/comlink/useWindowConnection.test.ts +135 -0
- package/src/hooks/comlink/useWindowConnection.ts +122 -0
- package/src/hooks/context/useSanityInstance.test.tsx +2 -2
- package/src/hooks/context/useSanityInstance.ts +24 -8
- package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +178 -0
- package/src/hooks/dashboard/useNavigateToStudioDocument.ts +123 -0
- package/src/hooks/dashboard/useStudioWorkspacesByResourceId.test.tsx +278 -0
- package/src/hooks/dashboard/useStudioWorkspacesByResourceId.ts +92 -0
- package/src/hooks/datasets/useDatasets.ts +40 -0
- package/src/hooks/document/useApplyDocumentActions.test.ts +25 -0
- package/src/hooks/document/useApplyDocumentActions.ts +75 -0
- package/src/hooks/document/useDocument.test.ts +81 -0
- package/src/hooks/document/useDocument.ts +107 -0
- package/src/hooks/document/useDocumentEvent.test.ts +63 -0
- package/src/hooks/document/useDocumentEvent.ts +54 -0
- package/src/hooks/document/useDocumentPermissions.ts +84 -0
- package/src/hooks/document/useDocumentSyncStatus.test.ts +16 -0
- package/src/hooks/document/useDocumentSyncStatus.ts +33 -0
- package/src/hooks/document/useEditDocument.test.ts +179 -0
- package/src/hooks/document/useEditDocument.ts +195 -0
- package/src/hooks/documents/useDocuments.test.tsx +152 -0
- package/src/hooks/documents/useDocuments.ts +174 -0
- package/src/hooks/helpers/createCallbackHook.tsx +3 -2
- package/src/hooks/helpers/createStateSourceHook.test.tsx +66 -0
- package/src/hooks/helpers/createStateSourceHook.tsx +29 -10
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +259 -0
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +290 -0
- package/src/hooks/preview/usePreview.test.tsx +19 -10
- package/src/hooks/preview/usePreview.tsx +67 -13
- package/src/hooks/projection/useProjection.test.tsx +218 -0
- package/src/hooks/projection/useProjection.ts +147 -0
- package/src/hooks/projects/useProject.ts +48 -0
- package/src/hooks/projects/useProjects.ts +45 -0
- package/src/hooks/query/useQuery.test.tsx +188 -0
- package/src/hooks/query/useQuery.ts +103 -0
- package/src/hooks/users/useUsers.test.ts +163 -0
- package/src/hooks/users/useUsers.ts +107 -0
- package/src/utils/getEnv.ts +21 -0
- package/src/version.ts +8 -0
- package/src/vite-env.d.ts +10 -0
- package/dist/_chunks-es/useLogOut.js +0 -44
- package/dist/_chunks-es/useLogOut.js.map +0 -1
- package/dist/assets/bundle-CcAyERuZ.css +0 -11
- package/dist/components.d.ts +0 -257
- package/dist/components.js +0 -316
- package/dist/components.js.map +0 -1
- package/dist/hooks.d.ts +0 -187
- package/dist/hooks.js +0 -81
- package/dist/hooks.js.map +0 -1
- package/src/_exports/components.ts +0 -13
- package/src/_exports/hooks.ts +0 -9
- 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/context/SanityProvider.tsx +0 -42
- package/src/css/css.config.js +0 -220
- package/src/css/paramour.css +0 -2347
- package/src/css/styles.css +0 -11
- package/src/hooks/auth/useHandleCallback.test.tsx +0 -16
- package/src/hooks/client/useClient.test.tsx +0 -130
- package/src/hooks/documentCollection/useDocuments.test.ts +0 -130
- package/src/hooks/documentCollection/useDocuments.ts +0 -87
package/dist/hooks.d.ts
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import {AuthProvider} from '@sanity/sdk'
|
|
2
|
-
import {AuthState} from '@sanity/sdk'
|
|
3
|
-
import {CurrentUser} from '@sanity/types'
|
|
4
|
-
import {DocumentHandle} from '@sanity/sdk'
|
|
5
|
-
import {DocumentListOptions} from '@sanity/sdk'
|
|
6
|
-
import {PreviewValue} from '@sanity/sdk'
|
|
7
|
-
import {RefObject} from 'react'
|
|
8
|
-
import type {SanityInstance} from '@sanity/sdk'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A React hook that subscribes to authentication state changes.
|
|
12
|
-
*
|
|
13
|
-
* This hook provides access to the current authentication state type from the Sanity auth store.
|
|
14
|
-
* It automatically re-renders the component when the authentication state changes.
|
|
15
|
-
*
|
|
16
|
-
* @remarks
|
|
17
|
-
* The hook uses `useSyncExternalStore` to safely subscribe to auth state changes
|
|
18
|
-
* and ensure consistency between server and client rendering.
|
|
19
|
-
*
|
|
20
|
-
* @returns The current authentication state type
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```tsx
|
|
24
|
-
* function AuthStatus() {
|
|
25
|
-
* const authState = useAuthState()
|
|
26
|
-
* return <div>Current auth state: {authState}</div>
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @public
|
|
31
|
-
*/
|
|
32
|
-
export declare const useAuthState: () => AuthState
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Hook to get the currently logged in user
|
|
36
|
-
* @public
|
|
37
|
-
* @returns The current user or null if not authenticated
|
|
38
|
-
*/
|
|
39
|
-
export declare const useAuthToken: () => string | null
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Hook to get the currently logged in user
|
|
43
|
-
* @public
|
|
44
|
-
* @returns The current user or null if not authenticated
|
|
45
|
-
*/
|
|
46
|
-
export declare const useCurrentUser: () => CurrentUser | null
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @public
|
|
50
|
-
*/
|
|
51
|
-
export declare interface UseDocuments {
|
|
52
|
-
loadMore: () => void
|
|
53
|
-
results: DocumentHandle[]
|
|
54
|
-
isPending: boolean
|
|
55
|
-
hasMore: boolean
|
|
56
|
-
count: number
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Hook to get the list of documents for specified options
|
|
61
|
-
*
|
|
62
|
-
* @public
|
|
63
|
-
*
|
|
64
|
-
* @param options - options for the document list
|
|
65
|
-
* @returns result of the document list and function to load more
|
|
66
|
-
*/
|
|
67
|
-
export declare function useDocuments(options?: DocumentListOptions): UseDocuments
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* A React hook that returns a function for handling authentication callbacks.
|
|
71
|
-
*
|
|
72
|
-
* @remarks
|
|
73
|
-
* This hook provides access to the authentication store's callback handler,
|
|
74
|
-
* which processes auth redirects by extracting the session ID and fetching the
|
|
75
|
-
* authentication token. If fetching the long-lived token is successful,
|
|
76
|
-
* `handleCallback` will return a Promise that resolves a new location that
|
|
77
|
-
* removes the short-lived token from the URL. Use this in combination with
|
|
78
|
-
* `history.replaceState` or your own router's `replace` function to update the
|
|
79
|
-
* current location without triggering a reload.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```tsx
|
|
83
|
-
* function AuthCallback() {
|
|
84
|
-
* const handleCallback = useHandleCallback()
|
|
85
|
-
* const router = useRouter() // Example router
|
|
86
|
-
*
|
|
87
|
-
* useEffect(() => {
|
|
88
|
-
* async function processCallback() {
|
|
89
|
-
* // Handle the callback and get the cleaned URL
|
|
90
|
-
* const newUrl = await handleCallback(window.location.href)
|
|
91
|
-
*
|
|
92
|
-
* if (newUrl) {
|
|
93
|
-
* // Replace URL without triggering navigation
|
|
94
|
-
* router.replace(newUrl, {shallow: true})
|
|
95
|
-
* }
|
|
96
|
-
* }
|
|
97
|
-
*
|
|
98
|
-
* processCallback().catch(console.error)
|
|
99
|
-
* }, [handleCallback, router])
|
|
100
|
-
*
|
|
101
|
-
* return <div>Completing login...</div>
|
|
102
|
-
* }
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* @returns A callback handler function that processes OAuth redirects
|
|
106
|
-
* @public
|
|
107
|
-
*/
|
|
108
|
-
export declare const useHandleCallback: () => (
|
|
109
|
-
locationHref?: string | undefined,
|
|
110
|
-
) => Promise<string | false>
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* A React hook that retrieves the available authentication provider URLs for login.
|
|
114
|
-
*
|
|
115
|
-
* @remarks
|
|
116
|
-
* This hook fetches the login URLs from the Sanity auth store when the component mounts.
|
|
117
|
-
* Each provider object contains information about an authentication method, including its URL.
|
|
118
|
-
* The hook will suspend if the login URLs have not yet loaded.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```tsx
|
|
122
|
-
* // LoginProviders component that uses the hook
|
|
123
|
-
* function LoginProviders() {
|
|
124
|
-
* const providers = useLoginUrls()
|
|
125
|
-
*
|
|
126
|
-
* return (
|
|
127
|
-
* <div>
|
|
128
|
-
* {providers.map((provider) => (
|
|
129
|
-
* <a key={provider.name} href={provider.url}>
|
|
130
|
-
* Login with {provider.title}
|
|
131
|
-
* </a>
|
|
132
|
-
* ))}
|
|
133
|
-
* </div>
|
|
134
|
-
* )
|
|
135
|
-
* }
|
|
136
|
-
*
|
|
137
|
-
* // Parent component with Suspense boundary
|
|
138
|
-
* function LoginPage() {
|
|
139
|
-
* return (
|
|
140
|
-
* <Suspense fallback={<div>Loading authentication providers...</div>}>
|
|
141
|
-
* <LoginProviders />
|
|
142
|
-
* </Suspense>
|
|
143
|
-
* )
|
|
144
|
-
* }
|
|
145
|
-
* ```
|
|
146
|
-
*
|
|
147
|
-
* @returns An array of {@link AuthProvider} objects containing login URLs and provider information
|
|
148
|
-
* @public
|
|
149
|
-
*/
|
|
150
|
-
export declare function useLoginUrls(): AuthProvider[]
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Hook to log out of the current session
|
|
154
|
-
* @public
|
|
155
|
-
* @returns A function to log out of the current session
|
|
156
|
-
*/
|
|
157
|
-
export declare const useLogOut: () => () => Promise<void>
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* @alpha
|
|
161
|
-
*/
|
|
162
|
-
export declare function usePreview({
|
|
163
|
-
document: {_id, _type},
|
|
164
|
-
ref,
|
|
165
|
-
}: UsePreviewOptions): [PreviewValue, boolean]
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* @alpha
|
|
169
|
-
*/
|
|
170
|
-
export declare interface UsePreviewOptions {
|
|
171
|
-
document: DocumentHandle
|
|
172
|
-
ref?: RefObject<HTMLElement>
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Hook that provides the current Sanity instance from the context.
|
|
177
|
-
* This must be called from within a `SanityProvider` component.
|
|
178
|
-
* @public
|
|
179
|
-
* @returns the current Sanity instance
|
|
180
|
-
* @example
|
|
181
|
-
* ```tsx
|
|
182
|
-
* const instance = useSanityInstance()
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
export declare const useSanityInstance: () => SanityInstance
|
|
186
|
-
|
|
187
|
-
export {}
|
package/dist/hooks.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { createStateSourceHook, useSanityInstance } from "./_chunks-es/useLogOut.js";
|
|
2
|
-
import { useAuthState, useHandleCallback, useLogOut, useLoginUrls } from "./_chunks-es/useLogOut.js";
|
|
3
|
-
import { getTokenState, getCurrentUserState, createDocumentListStore, getPreviewState, resolvePreview } from "@sanity/sdk";
|
|
4
|
-
import { useState, useEffect, useCallback, useSyncExternalStore, useMemo } from "react";
|
|
5
|
-
import { Observable, startWith, distinctUntilChanged, switchMap, EMPTY } from "rxjs";
|
|
6
|
-
const useAuthToken = createStateSourceHook(getTokenState), useCurrentUser = createStateSourceHook(getCurrentUserState), STABLE_EMPTY = {
|
|
7
|
-
results: [],
|
|
8
|
-
isPending: !1,
|
|
9
|
-
hasMore: !1,
|
|
10
|
-
count: 0
|
|
11
|
-
};
|
|
12
|
-
function useDocuments(options = {}) {
|
|
13
|
-
const instance = useSanityInstance(), [ref] = useState(() => ({
|
|
14
|
-
storeInstance: null,
|
|
15
|
-
getCurrent: () => STABLE_EMPTY,
|
|
16
|
-
initialOptions: options
|
|
17
|
-
})), serializedOptions = JSON.stringify(options);
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
ref.storeInstance?.setOptions(JSON.parse(serializedOptions));
|
|
20
|
-
}, [ref, serializedOptions]);
|
|
21
|
-
const subscribe = useCallback(
|
|
22
|
-
(onStoreChanged) => {
|
|
23
|
-
ref.storeInstance = createDocumentListStore(instance), ref.storeInstance.setOptions(ref.initialOptions);
|
|
24
|
-
const state2 = ref.storeInstance.getState();
|
|
25
|
-
ref.getCurrent = state2.getCurrent;
|
|
26
|
-
const unsubscribe = state2.subscribe(onStoreChanged);
|
|
27
|
-
return () => {
|
|
28
|
-
unsubscribe(), ref.storeInstance?.dispose();
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
[instance, ref]
|
|
32
|
-
), getSnapshot = useCallback(() => ref.getCurrent(), [ref]), state = useSyncExternalStore(subscribe, getSnapshot);
|
|
33
|
-
return { loadMore: useCallback(() => {
|
|
34
|
-
ref.storeInstance?.loadMore();
|
|
35
|
-
}, [ref]), ...state };
|
|
36
|
-
}
|
|
37
|
-
function usePreview({
|
|
38
|
-
document: { _id, _type },
|
|
39
|
-
ref
|
|
40
|
-
}) {
|
|
41
|
-
const instance = useSanityInstance(), stateSource = useMemo(
|
|
42
|
-
() => getPreviewState(instance, { document: { _id, _type } }),
|
|
43
|
-
[instance, _id, _type]
|
|
44
|
-
), subscribe = useCallback(
|
|
45
|
-
(onStoreChanged) => {
|
|
46
|
-
const subscription = new Observable((observer) => {
|
|
47
|
-
if (typeof IntersectionObserver > "u") return;
|
|
48
|
-
const intersectionObserver = new IntersectionObserver(
|
|
49
|
-
([entry]) => observer.next(entry.isIntersecting),
|
|
50
|
-
{ rootMargin: "0px", threshold: 0 }
|
|
51
|
-
);
|
|
52
|
-
return ref?.current && intersectionObserver.observe(ref.current), () => intersectionObserver.disconnect();
|
|
53
|
-
}).pipe(
|
|
54
|
-
startWith(!1),
|
|
55
|
-
distinctUntilChanged(),
|
|
56
|
-
switchMap(
|
|
57
|
-
(isVisible) => isVisible ? new Observable((obs) => stateSource.subscribe(() => obs.next())) : EMPTY
|
|
58
|
-
)
|
|
59
|
-
).subscribe({ next: onStoreChanged });
|
|
60
|
-
return () => subscription.unsubscribe();
|
|
61
|
-
},
|
|
62
|
-
[stateSource, ref]
|
|
63
|
-
), getSnapshot = useCallback(() => {
|
|
64
|
-
const previewTuple = stateSource.getCurrent();
|
|
65
|
-
if (!previewTuple[0]) throw resolvePreview(instance, { document: { _id, _type } });
|
|
66
|
-
return previewTuple;
|
|
67
|
-
}, [_id, _type, instance, stateSource]);
|
|
68
|
-
return useSyncExternalStore(subscribe, getSnapshot);
|
|
69
|
-
}
|
|
70
|
-
export {
|
|
71
|
-
useAuthState,
|
|
72
|
-
useAuthToken,
|
|
73
|
-
useCurrentUser,
|
|
74
|
-
useDocuments,
|
|
75
|
-
useHandleCallback,
|
|
76
|
-
useLogOut,
|
|
77
|
-
useLoginUrls,
|
|
78
|
-
usePreview,
|
|
79
|
-
useSanityInstance
|
|
80
|
-
};
|
|
81
|
-
//# sourceMappingURL=hooks.js.map
|
package/dist/hooks.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sources":["../src/hooks/auth/useAuthToken.tsx","../src/hooks/auth/useCurrentUser.tsx","../src/hooks/documentCollection/useDocuments.ts","../src/hooks/preview/usePreview.tsx"],"sourcesContent":["import {getTokenState} from '@sanity/sdk'\n\nimport {createStateSourceHook} from '../helpers/createStateSourceHook'\n\n/**\n * Hook to get the currently logged in user\n * @public\n * @returns The current user or null if not authenticated\n */\nexport const useAuthToken = createStateSourceHook(getTokenState)\n","import {getCurrentUserState} from '@sanity/sdk'\n\nimport {createStateSourceHook} from '../helpers/createStateSourceHook'\n\n/**\n * Hook to get the currently logged in user\n * @public\n * @returns The current user or null if not authenticated\n */\nexport const useCurrentUser = createStateSourceHook(getCurrentUserState)\n","import {createDocumentListStore, type DocumentHandle, type DocumentListOptions} from '@sanity/sdk'\nimport {useCallback, useEffect, useState, useSyncExternalStore} from 'react'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\n/**\n * @public\n */\nexport interface UseDocuments {\n loadMore: () => void\n results: DocumentHandle[]\n isPending: boolean\n hasMore: boolean\n count: number\n}\n\ntype DocumentListStore = ReturnType<typeof createDocumentListStore>\ntype DocumentListState = ReturnType<DocumentListStore['getState']>['getCurrent']\nconst STABLE_EMPTY = {\n results: [],\n isPending: false,\n hasMore: false,\n count: 0,\n}\n\n/**\n * Hook to get the list of documents for specified options\n *\n * @public\n *\n * @param options - options for the document list\n * @returns result of the document list and function to load more\n */\nexport function useDocuments(options: DocumentListOptions = {}): UseDocuments {\n const instance = useSanityInstance()\n\n // NOTE: useState is used because it guaranteed to return a stable reference\n // across renders\n const [ref] = useState<{\n storeInstance: DocumentListStore | null\n getCurrent: DocumentListState\n initialOptions: DocumentListOptions\n }>(() => ({\n storeInstance: null,\n getCurrent: () => STABLE_EMPTY,\n initialOptions: options,\n }))\n\n // serialize options to ensure it only calls `setOptions` when the values\n // themselves changes (in cases where devs put config inline)\n const serializedOptions = JSON.stringify(options)\n useEffect(() => {\n ref.storeInstance?.setOptions(JSON.parse(serializedOptions))\n }, [ref, serializedOptions])\n\n const subscribe = useCallback(\n (onStoreChanged: () => void) => {\n // to match the lifecycle of `useSyncExternalState`, we create the store\n // instance after subscribe and mutate the ref to connect everything\n ref.storeInstance = createDocumentListStore(instance)\n ref.storeInstance.setOptions(ref.initialOptions)\n const state = ref.storeInstance.getState()\n ref.getCurrent = state.getCurrent\n const unsubscribe = state.subscribe(onStoreChanged)\n\n return () => {\n // unsubscribe to clean up the state subscriptions\n unsubscribe()\n // dispose of the instance\n ref.storeInstance?.dispose()\n }\n },\n [instance, ref],\n )\n\n const getSnapshot = useCallback(() => {\n return ref.getCurrent()\n }, [ref])\n\n const state = useSyncExternalStore(subscribe, getSnapshot)\n\n const loadMore = useCallback(() => {\n ref.storeInstance?.loadMore()\n }, [ref])\n\n return {loadMore, ...state}\n}\n","import {type DocumentHandle, getPreviewState, type PreviewValue, resolvePreview} from '@sanity/sdk'\nimport {type RefObject, useCallback, useMemo, useSyncExternalStore} from 'react'\nimport {distinctUntilChanged, EMPTY, Observable, startWith, switchMap} from 'rxjs'\n\nimport {useSanityInstance} from '../context/useSanityInstance'\n\n/**\n * @alpha\n */\nexport interface UsePreviewOptions {\n document: DocumentHandle\n ref?: RefObject<HTMLElement>\n}\n\n/**\n * @alpha\n */\nexport function usePreview({\n document: {_id, _type},\n ref,\n}: UsePreviewOptions): [PreviewValue, boolean] {\n const instance = useSanityInstance()\n\n const stateSource = useMemo(\n () => getPreviewState(instance, {document: {_id, _type}}),\n [instance, _id, _type],\n )\n\n // Create subscribe function for useSyncExternalStore\n const subscribe = useCallback(\n (onStoreChanged: () => void) => {\n const subscription = new Observable<boolean>((observer) => {\n // for environments that don't have an intersection observer\n if (typeof IntersectionObserver === 'undefined') return\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => observer.next(entry.isIntersecting),\n {rootMargin: '0px', threshold: 0},\n )\n if (ref?.current) intersectionObserver.observe(ref.current)\n return () => intersectionObserver.disconnect()\n })\n .pipe(\n startWith(false),\n distinctUntilChanged(),\n switchMap((isVisible) =>\n isVisible\n ? new Observable<void>((obs) => {\n return stateSource.subscribe(() => obs.next())\n })\n : EMPTY,\n ),\n )\n .subscribe({next: onStoreChanged})\n\n return () => subscription.unsubscribe()\n },\n [stateSource, ref],\n )\n\n // Create getSnapshot function to return current state\n const getSnapshot = useCallback(() => {\n const previewTuple = stateSource.getCurrent()\n if (!previewTuple[0]) throw resolvePreview(instance, {document: {_id, _type}})\n return previewTuple as [PreviewValue, boolean]\n }, [_id, _type, instance, stateSource])\n\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n"],"names":["state"],"mappings":";;;;;AASa,MAAA,eAAe,sBAAsB,aAAa,GCAlD,iBAAiB,sBAAsB,mBAAmB,GCSjE,eAAe;AAAA,EACnB,SAAS,CAAC;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AACT;AAUgB,SAAA,aAAa,UAA+B,IAAkB;AAC5E,QAAM,WAAW,kBAAkB,GAI7B,CAAC,GAAG,IAAI,SAIX,OAAO;AAAA,IACR,eAAe;AAAA,IACf,YAAY,MAAM;AAAA,IAClB,gBAAgB;AAAA,EAChB,EAAA,GAII,oBAAoB,KAAK,UAAU,OAAO;AAChD,YAAU,MAAM;AACd,QAAI,eAAe,WAAW,KAAK,MAAM,iBAAiB,CAAC;AAAA,EAAA,GAC1D,CAAC,KAAK,iBAAiB,CAAC;AAE3B,QAAM,YAAY;AAAA,IAChB,CAAC,mBAA+B;AAG1B,UAAA,gBAAgB,wBAAwB,QAAQ,GACpD,IAAI,cAAc,WAAW,IAAI,cAAc;AACzCA,YAAAA,SAAQ,IAAI,cAAc,SAAS;AACzC,UAAI,aAAaA,OAAM;AACjB,YAAA,cAAcA,OAAM,UAAU,cAAc;AAElD,aAAO,MAAM;AAEC,uBAEZ,IAAI,eAAe,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,CAAC,UAAU,GAAG;AAAA,EAGV,GAAA,cAAc,YAAY,MACvB,IAAI,WAAW,GACrB,CAAC,GAAG,CAAC,GAEF,QAAQ,qBAAqB,WAAW,WAAW;AAMlD,SAAA,EAAC,UAJS,YAAY,MAAM;AACjC,QAAI,eAAe,SAAS;AAAA,KAC3B,CAAC,GAAG,CAAC,GAEU,GAAG,MAAK;AAC5B;ACrEO,SAAS,WAAW;AAAA,EACzB,UAAU,EAAC,KAAK,MAAK;AAAA,EACrB;AACF,GAA+C;AACvC,QAAA,WAAW,qBAEX,cAAc;AAAA,IAClB,MAAM,gBAAgB,UAAU,EAAC,UAAU,EAAC,KAAK,MAAK,GAAE;AAAA,IACxD,CAAC,UAAU,KAAK,KAAK;AAAA,KAIjB,YAAY;AAAA,IAChB,CAAC,mBAA+B;AAC9B,YAAM,eAAe,IAAI,WAAoB,CAAC,aAAa;AAErD,YAAA,OAAO,uBAAyB,IAAa;AAEjD,cAAM,uBAAuB,IAAI;AAAA,UAC/B,CAAC,CAAC,KAAK,MAAM,SAAS,KAAK,MAAM,cAAc;AAAA,UAC/C,EAAC,YAAY,OAAO,WAAW,EAAC;AAAA,QAClC;AACI,eAAA,KAAK,WAAS,qBAAqB,QAAQ,IAAI,OAAO,GACnD,MAAM,qBAAqB,WAAW;AAAA,MAC9C,CAAA,EACE;AAAA,QACC,UAAU,EAAK;AAAA,QACf,qBAAqB;AAAA,QACrB;AAAA,UAAU,CAAC,cACT,YACI,IAAI,WAAiB,CAAC,QACb,YAAY,UAAU,MAAM,IAAI,KAAK,CAAC,CAC9C,IACD;AAAA,QAAA;AAAA,MAGP,EAAA,UAAU,EAAC,MAAM,gBAAe;AAE5B,aAAA,MAAM,aAAa,YAAY;AAAA,IACxC;AAAA,IACA,CAAC,aAAa,GAAG;AAAA,EAAA,GAIb,cAAc,YAAY,MAAM;AAC9B,UAAA,eAAe,YAAY,WAAW;AAC5C,QAAI,CAAC,aAAa,CAAC,EAAS,OAAA,eAAe,UAAU,EAAC,UAAU,EAAC,KAAK,SAAO;AACtE,WAAA;AAAA,KACN,CAAC,KAAK,OAAO,UAAU,WAAW,CAAC;AAE/B,SAAA,qBAAqB,WAAW,WAAW;AACpD;"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export {AuthBoundary, type AuthBoundaryProps} from '../components/auth/AuthBoundary'
|
|
2
|
-
export {AuthError} from '../components/auth/AuthError'
|
|
3
|
-
export {Login} from '../components/auth/Login'
|
|
4
|
-
export {LoginCallback} from '../components/auth/LoginCallback'
|
|
5
|
-
export {LoginError, type LoginErrorProps} from '../components/auth/LoginError'
|
|
6
|
-
export {LoginLayout, type LoginLayoutProps} from '../components/auth/LoginLayout'
|
|
7
|
-
export type {SanityProviderProps} from '../components/context/SanityProvider'
|
|
8
|
-
export {SanityProvider} from '../components/context/SanityProvider'
|
|
9
|
-
export {DocumentGridLayout} from '../components/DocumentGridLayout/DocumentGridLayout'
|
|
10
|
-
export {DocumentListLayout} from '../components/DocumentListLayout/DocumentListLayout'
|
|
11
|
-
export {DocumentPreviewLayout} from '../components/DocumentPreviewLayout/DocumentPreviewLayout'
|
|
12
|
-
export {type DocumentPreviewLayoutProps} from '../components/DocumentPreviewLayout/DocumentPreviewLayout'
|
|
13
|
-
export {LoginLinks} from '../components/Login/LoginLinks'
|
package/src/_exports/hooks.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export {useAuthState} from '../hooks/auth/useAuthState'
|
|
2
|
-
export {useAuthToken} from '../hooks/auth/useAuthToken'
|
|
3
|
-
export {useCurrentUser} from '../hooks/auth/useCurrentUser'
|
|
4
|
-
export {useHandleCallback} from '../hooks/auth/useHandleCallback'
|
|
5
|
-
export {useLoginUrls} from '../hooks/auth/useLoginUrls'
|
|
6
|
-
export {useLogOut} from '../hooks/auth/useLogOut'
|
|
7
|
-
export {useSanityInstance} from '../hooks/context/useSanityInstance'
|
|
8
|
-
export {type UseDocuments, useDocuments} from '../hooks/documentCollection/useDocuments'
|
|
9
|
-
export {usePreview, type UsePreviewOptions} from '../hooks/preview/usePreview'
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import {type Meta, type StoryObj} from '@storybook/react'
|
|
2
|
-
|
|
3
|
-
import {DocumentPreviewLayout} from '../DocumentPreviewLayout/DocumentPreviewLayout.tsx'
|
|
4
|
-
import {DocumentGridLayout} from './DocumentGridLayout.tsx'
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof DocumentGridLayout> = {
|
|
7
|
-
title: 'DocumentGridLayout',
|
|
8
|
-
component: DocumentGridLayout,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default meta
|
|
12
|
-
type Story = StoryObj<typeof meta>
|
|
13
|
-
|
|
14
|
-
const mockDocs = [
|
|
15
|
-
{id: '1', title: 'Just a title', url: '#', docType: 'article', status: 'published'},
|
|
16
|
-
{
|
|
17
|
-
id: '2',
|
|
18
|
-
title: 'A title, but also',
|
|
19
|
-
subtitle: 'A subtitle',
|
|
20
|
-
docType: 'article',
|
|
21
|
-
status: 'draft',
|
|
22
|
-
media: {
|
|
23
|
-
type: 'image-asset',
|
|
24
|
-
url: 'https://picsum.photos/75/75',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
id: '3',
|
|
29
|
-
title: 'Hello World',
|
|
30
|
-
subtitle: 'What a nice list I get to live in',
|
|
31
|
-
docType: 'image',
|
|
32
|
-
status: 'published',
|
|
33
|
-
media: {
|
|
34
|
-
type: 'image-asset',
|
|
35
|
-
url: 'https://picsum.photos/80/80',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: '4',
|
|
40
|
-
title: 'I’ve been selected',
|
|
41
|
-
subtitle: 'I feel special',
|
|
42
|
-
selected: true,
|
|
43
|
-
docType: 'video',
|
|
44
|
-
status: 'draft',
|
|
45
|
-
media: {
|
|
46
|
-
type: 'image-asset',
|
|
47
|
-
url: 'https://picsum.photos/100/100',
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: '5',
|
|
52
|
-
title: 'A very long title that at some point might get truncated if it goes for long enough',
|
|
53
|
-
subtitle:
|
|
54
|
-
'Along with a subtitle that is quite long as well, in order to demonstrate the truncation of its text',
|
|
55
|
-
docType: 'audio',
|
|
56
|
-
status: 'published',
|
|
57
|
-
media: {
|
|
58
|
-
type: 'image-asset',
|
|
59
|
-
url: 'https://picsum.photos/75/75',
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: '6',
|
|
64
|
-
title: 'Hello World',
|
|
65
|
-
subtitle: 'What a nice list I get to live in',
|
|
66
|
-
docType: 'pdf',
|
|
67
|
-
status: 'published',
|
|
68
|
-
media: {
|
|
69
|
-
type: 'image-asset',
|
|
70
|
-
url: 'https://picsum.photos/75/75',
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{id: '7', title: 'Just a title', url: '#', docType: 'note', status: 'published,'},
|
|
74
|
-
{
|
|
75
|
-
id: '8',
|
|
76
|
-
title: 'A title, but also',
|
|
77
|
-
subtitle: 'A subtitle',
|
|
78
|
-
docType: 'document',
|
|
79
|
-
status: 'draft',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
id: '9',
|
|
83
|
-
title: 'Hello World',
|
|
84
|
-
subtitle: 'What a nice list I get to live in',
|
|
85
|
-
docType: 'biography',
|
|
86
|
-
status: 'published',
|
|
87
|
-
media: {
|
|
88
|
-
type: 'image-asset',
|
|
89
|
-
url: 'https://picsum.photos/200/200',
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
export const Default: Story = {
|
|
95
|
-
render: () => {
|
|
96
|
-
return (
|
|
97
|
-
<DocumentGridLayout>
|
|
98
|
-
{mockDocs.map((doc) => (
|
|
99
|
-
<li key={doc.id}>
|
|
100
|
-
<DocumentPreviewLayout
|
|
101
|
-
title={doc.title}
|
|
102
|
-
subtitle={doc.subtitle}
|
|
103
|
-
media={doc.media}
|
|
104
|
-
selected={doc.selected}
|
|
105
|
-
docType={doc.docType}
|
|
106
|
-
status={doc.status}
|
|
107
|
-
/>
|
|
108
|
-
</li>
|
|
109
|
-
))}
|
|
110
|
-
</DocumentGridLayout>
|
|
111
|
-
)
|
|
112
|
-
},
|
|
113
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it} from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {render, screen} from '../../../test/test-utils.tsx'
|
|
4
|
-
import {DocumentGridLayout} from './DocumentGridLayout.tsx'
|
|
5
|
-
|
|
6
|
-
describe('DocumentGridLayout', () => {
|
|
7
|
-
const mockDocuments = [
|
|
8
|
-
{
|
|
9
|
-
id: '1',
|
|
10
|
-
title: 'Test Document 1',
|
|
11
|
-
subtitle: 'Subtitle 1',
|
|
12
|
-
docType: 'post',
|
|
13
|
-
status: 'published',
|
|
14
|
-
url: '/doc/1',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
id: '2',
|
|
18
|
-
title: 'Test Document 2',
|
|
19
|
-
subtitle: 'Subtitle 2',
|
|
20
|
-
docType: 'page',
|
|
21
|
-
status: 'draft',
|
|
22
|
-
url: '/doc/2',
|
|
23
|
-
},
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
it('renders the expected content', () => {
|
|
27
|
-
render(
|
|
28
|
-
<DocumentGridLayout>
|
|
29
|
-
{mockDocuments.map((doc) => (
|
|
30
|
-
<li key={doc.id}>{doc.title}</li>
|
|
31
|
-
))}
|
|
32
|
-
</DocumentGridLayout>,
|
|
33
|
-
)
|
|
34
|
-
const list = screen.getByRole('list')
|
|
35
|
-
expect(list.tagName).toBe('OL')
|
|
36
|
-
expect(list.classList).toContain('DocumentGridLayout')
|
|
37
|
-
|
|
38
|
-
const items = screen.getAllByRole('listitem')
|
|
39
|
-
expect(items[0]).toContainHTML('Test Document 1')
|
|
40
|
-
expect(items[1]).toContainHTML('Test Document 2')
|
|
41
|
-
})
|
|
42
|
-
})
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import '../../css/styles.css'
|
|
2
|
-
|
|
3
|
-
import type {PropsWithChildren, ReactElement} from 'react'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export const DocumentGridLayout = (props: PropsWithChildren): ReactElement => {
|
|
9
|
-
return (
|
|
10
|
-
<>
|
|
11
|
-
<style>{`
|
|
12
|
-
.DocumentGridLayout {
|
|
13
|
-
grid-template-columns: repeat(auto-fit, minmax(38ch, 1fr));
|
|
14
|
-
}
|
|
15
|
-
`}</style>
|
|
16
|
-
<ol className="DocumentGridLayout list-none grid">{props.children}</ol>
|
|
17
|
-
</>
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
DocumentGridLayout.displayName = 'DocumentGridLayout'
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import {type Meta, type StoryObj} from '@storybook/react'
|
|
2
|
-
|
|
3
|
-
import {DocumentPreviewLayout} from '../DocumentPreviewLayout/DocumentPreviewLayout.tsx'
|
|
4
|
-
import {DocumentListLayout} from './DocumentListLayout.tsx'
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof DocumentListLayout> = {
|
|
7
|
-
title: 'DocumentListLayout',
|
|
8
|
-
component: DocumentListLayout,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default meta
|
|
12
|
-
type Story = StoryObj<typeof meta>
|
|
13
|
-
|
|
14
|
-
const mockDocs = [
|
|
15
|
-
{id: '1', title: 'Just a title', url: '#', docType: 'article', status: 'published'},
|
|
16
|
-
{
|
|
17
|
-
id: '2',
|
|
18
|
-
title: 'A title, but also',
|
|
19
|
-
subtitle: 'A subtitle',
|
|
20
|
-
docType: 'article',
|
|
21
|
-
status: 'draft',
|
|
22
|
-
media: {
|
|
23
|
-
type: 'image-asset',
|
|
24
|
-
url: 'https://picsum.photos/75/75',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
id: '3',
|
|
29
|
-
title: 'Hello World',
|
|
30
|
-
subtitle: 'What a nice list I get to live in',
|
|
31
|
-
docType: 'image',
|
|
32
|
-
status: 'published',
|
|
33
|
-
media: {
|
|
34
|
-
type: 'image-asset',
|
|
35
|
-
url: 'https://picsum.photos/100/100',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: '4',
|
|
40
|
-
title: 'I’ve been selected',
|
|
41
|
-
subtitle: 'I feel special',
|
|
42
|
-
selected: true,
|
|
43
|
-
docType: 'video',
|
|
44
|
-
status: 'draft',
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: '5',
|
|
48
|
-
title: 'A very long title that at some point might get truncated if it goes for long enough',
|
|
49
|
-
subtitle:
|
|
50
|
-
'Along with a subtitle that is quite long as well, in order to demonstrate the truncation of its text',
|
|
51
|
-
docType: 'audio',
|
|
52
|
-
status: 'published',
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
id: '6',
|
|
56
|
-
title: 'Hello World',
|
|
57
|
-
subtitle: 'What a nice list I get to live in',
|
|
58
|
-
docType: 'pdf',
|
|
59
|
-
status: 'published',
|
|
60
|
-
media: {
|
|
61
|
-
type: 'image-asset',
|
|
62
|
-
url: 'https://picsum.photos/80/80',
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
{id: '7', title: 'Just a title', url: '#', docType: 'note', status: 'published,'},
|
|
66
|
-
{
|
|
67
|
-
id: '8',
|
|
68
|
-
title: 'A title, but also',
|
|
69
|
-
subtitle: 'A subtitle',
|
|
70
|
-
docType: 'document',
|
|
71
|
-
status: 'draft',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
id: '9',
|
|
75
|
-
title: 'Hello World',
|
|
76
|
-
subtitle: 'What a nice list I get to live in',
|
|
77
|
-
docType: 'biography',
|
|
78
|
-
status: 'published',
|
|
79
|
-
media: {
|
|
80
|
-
type: 'image-asset',
|
|
81
|
-
url: 'https://picsum.photos/200/200',
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
]
|
|
85
|
-
|
|
86
|
-
export const Default: Story = {
|
|
87
|
-
render: () => {
|
|
88
|
-
return (
|
|
89
|
-
<DocumentListLayout>
|
|
90
|
-
{mockDocs.map((doc) => (
|
|
91
|
-
<li key={doc.id}>
|
|
92
|
-
<DocumentPreviewLayout
|
|
93
|
-
title={doc.title}
|
|
94
|
-
subtitle={doc.subtitle}
|
|
95
|
-
media={doc.media}
|
|
96
|
-
selected={doc.selected}
|
|
97
|
-
docType={doc.docType}
|
|
98
|
-
status={doc.status}
|
|
99
|
-
/>
|
|
100
|
-
</li>
|
|
101
|
-
))}
|
|
102
|
-
</DocumentListLayout>
|
|
103
|
-
)
|
|
104
|
-
},
|
|
105
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it} from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {render, screen} from '../../../test/test-utils.tsx'
|
|
4
|
-
import {DocumentListLayout} from './DocumentListLayout.tsx'
|
|
5
|
-
|
|
6
|
-
describe('DocumentListLayout', () => {
|
|
7
|
-
const mockDocuments = [
|
|
8
|
-
{
|
|
9
|
-
id: '1',
|
|
10
|
-
title: 'Test Document 1',
|
|
11
|
-
subtitle: 'Subtitle 1',
|
|
12
|
-
docType: 'post',
|
|
13
|
-
status: 'published',
|
|
14
|
-
url: '/doc/1',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
id: '2',
|
|
18
|
-
title: 'Test Document 2',
|
|
19
|
-
subtitle: 'Subtitle 2',
|
|
20
|
-
docType: 'page',
|
|
21
|
-
status: 'draft',
|
|
22
|
-
url: '/doc/2',
|
|
23
|
-
},
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
it('renders the expected content', () => {
|
|
27
|
-
render(
|
|
28
|
-
<DocumentListLayout>
|
|
29
|
-
{mockDocuments.map((doc) => (
|
|
30
|
-
<li key={doc.id}>{doc.title}</li>
|
|
31
|
-
))}
|
|
32
|
-
</DocumentListLayout>,
|
|
33
|
-
)
|
|
34
|
-
const list = screen.getByRole('list')
|
|
35
|
-
expect(list.tagName).toBe('OL')
|
|
36
|
-
expect(list.classList).toContain('DocumentListLayout')
|
|
37
|
-
|
|
38
|
-
const items = screen.getAllByRole('listitem')
|
|
39
|
-
expect(items[0]).toContainHTML('Test Document 1')
|
|
40
|
-
expect(items[1]).toContainHTML('Test Document 2')
|
|
41
|
-
})
|
|
42
|
-
})
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import '../../css/styles.css'
|
|
2
|
-
|
|
3
|
-
import type {PropsWithChildren, ReactElement} from 'react'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export const DocumentListLayout = (props: PropsWithChildren): ReactElement => {
|
|
9
|
-
return <ol className="DocumentListLayout list-none">{props.children}</ol>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
DocumentListLayout.displayName = 'DocumentListLayout'
|