1
- import { DirectiveNode , DocumentNode , OperationTypeNode , parse } from "graphql" ;
1
+ import { DirectiveNode , DocumentNode , OperationTypeNode } from "graphql" ;
2
2
import { ReactNode , useContext , useMemo } from "react" ;
3
3
import { findDirective , parseDirectiveArguments } from "@directive" ;
4
4
import { ViewRenderer } from "@renderers/fields" ;
@@ -9,7 +9,11 @@ import { directiveSchemaMap } from "@directive/schema";
9
9
import { mergeFieldConfigs } from "@readers/shared" ;
10
10
import { buildDefaultViewFieldConfigs , viewFieldMerger } from "@readers/field" ;
11
11
import { buildDefaultFormFieldConfigs , formFieldMerger } from "@readers/form" ;
12
- import { buildRootDocument , FieldVariables } from "@/visitor" ;
12
+ import {
13
+ buildRootDocument ,
14
+ FieldVariables ,
15
+ GeneralDocumentType ,
16
+ } from "@/visitor" ;
13
17
import { Field , Fields } from "@/visitor/fields" ;
14
18
import { FabrixComponentData , useDataFetch , Value } from "@/fetcher" ;
15
19
@@ -105,10 +109,15 @@ export type FieldConfigs = {
105
109
fields : FieldConfig [ ] ;
106
110
} ;
107
111
108
- export const useFieldConfigs = ( query : DocumentNode | string ) => {
109
- const rootDocument = buildRootDocument (
110
- typeof query === "string" ? parse ( query ) : query ,
111
- ) ;
112
+ export const useFieldConfigs = <
113
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
+ TData = any ,
115
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
+ TVariables = Record < string , any > ,
117
+ > (
118
+ query : GeneralDocumentType < TData , TVariables > ,
119
+ ) => {
120
+ const rootDocument = buildRootDocument ( query ) ;
112
121
const context = useContext ( FabrixContext ) ;
113
122
const fieldConfigs = useMemo ( ( ) => {
114
123
return rootDocument . map ( ( { name, document, fields, opType, variables } ) =>
@@ -142,11 +151,14 @@ export const useFieldConfigs = (query: DocumentNode | string) => {
142
151
return { fieldConfigs } ;
143
152
} ;
144
153
145
- type FabrixComponentCommonProps = {
154
+ type FabrixComponentCommonProps <
155
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
156
+ TVariables = Record < string , any > ,
157
+ > = {
146
158
/**
147
159
* The variables to call the query with.
148
160
*/
149
- variables ?: Record < string , unknown > ;
161
+ variables ?: TVariables ;
150
162
151
163
/**
152
164
* The title of the query.
@@ -164,7 +176,12 @@ type FabrixComponentCommonProps = {
164
176
contentClassName ?: string ;
165
177
} ;
166
178
167
- export type FabrixComponentProps = FabrixComponentCommonProps & {
179
+ export type FabrixComponentProps <
180
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
181
+ TData = any ,
182
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
+ TVariables = Record < string , any > ,
184
+ > = FabrixComponentCommonProps < TVariables > & {
168
185
/**
169
186
* The query to render.
170
187
*
@@ -178,19 +195,21 @@ export type FabrixComponentProps = FabrixComponentCommonProps & {
178
195
* }
179
196
* ```
180
197
*/
181
- query : DocumentNode | string ;
198
+ query : GeneralDocumentType < TData , TVariables > ;
182
199
183
- children ?: ( props : FabrixComponentChildrenProps ) => ReactNode ;
200
+ children ?: ( props : FabrixComponentChildrenProps < TData > ) => ReactNode ;
184
201
} ;
185
202
186
203
type FabrixComponentChildrenExtraProps = { key ?: string ; className ?: string } ;
187
204
188
- export type FabrixComponentChildrenProps = {
205
+ export type FabrixComponentChildrenProps <
206
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
+ TData = any ,
208
+ > = {
189
209
/**
190
210
* The data fetched from the query
191
211
*/
192
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
- data : any ;
212
+ data : TData ;
194
213
195
214
/**
196
215
* Get the component by root field name
@@ -204,7 +223,9 @@ export type FabrixComponentChildrenProps = {
204
223
* ```
205
224
*/
206
225
getComponent : (
207
- rootFieldName : string ,
226
+ rootFieldName : TData extends Record < string , unknown >
227
+ ? Exclude < Extract < keyof TData , string > , "__typename" >
228
+ : string ,
208
229
extraProps ?: FabrixComponentChildrenExtraProps ,
209
230
fieldsRenderer ?: FabrixComponentFieldsRenderer ,
210
231
) => ReactNode ;
@@ -232,7 +253,14 @@ export type FabrixComponentChildrenProps = {
232
253
* </FabrixComponent>
233
254
* ```
234
255
*/
235
- export const FabrixComponent = ( props : FabrixComponentProps ) => {
256
+ export const FabrixComponent = <
257
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
258
+ TData = any ,
259
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
+ TVariables = Record < string , any > ,
261
+ > (
262
+ props : FabrixComponentProps < TData , TVariables > ,
263
+ ) => {
236
264
const renderComponent = getComponentRendererFn (
237
265
props ,
238
266
getComponentFn (
@@ -270,8 +298,13 @@ export const FabrixComponent = (props: FabrixComponentProps) => {
270
298
return < div className = "fabrix wrapper" > { renderComponent ( ) } </ div > ;
271
299
} ;
272
300
273
- export const getComponentRendererFn = (
274
- props : FabrixComponentProps ,
301
+ export const getComponentRendererFn = <
302
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
303
+ TData = any ,
304
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
305
+ TVariables = Record < string , any > ,
306
+ > (
307
+ props : FabrixComponentProps < TData , TVariables > ,
275
308
getComponent : ReturnType < typeof getComponentFn > ,
276
309
) => {
277
310
const context = useContext ( FabrixContext ) ;
@@ -282,7 +315,7 @@ export const getComponentRendererFn = (
282
315
}
283
316
284
317
return ( ) => {
285
- const { fetching, error, data } = useDataFetch ( {
318
+ const { fetching, error, data } = useDataFetch < TData , TVariables > ( {
286
319
query : fieldConfig . document ,
287
320
variables : props . variables ,
288
321
pause : fieldConfig . type !== OperationTypeNode . QUERY ,
@@ -296,10 +329,10 @@ export const getComponentRendererFn = (
296
329
throw error ;
297
330
}
298
331
299
- const component = getComponent ( fieldConfig , data , context ) ;
332
+ const component = getComponent ( fieldConfig , data ?? { } , context ) ;
300
333
if ( props . children ) {
301
334
return props . children ( {
302
- data,
335
+ data : data ?? ( { } as TData ) ,
303
336
getComponent : component ,
304
337
} ) ;
305
338
}
@@ -320,7 +353,15 @@ type RendererFn = (
320
353
) => ReactNode ;
321
354
322
355
export const getComponentFn =
323
- ( props : FabrixComponentProps , rendererFn : RendererFn ) =>
356
+ <
357
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
358
+ TData = any ,
359
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
360
+ TVariables = Record < string , any > ,
361
+ > (
362
+ props : FabrixComponentProps < TData , TVariables > ,
363
+ rendererFn : RendererFn ,
364
+ ) =>
324
365
(
325
366
fieldConfig : FieldConfigs ,
326
367
data : FabrixComponentData | undefined ,
0 commit comments