@ic-reactor/candid 3.0.13-beta.0 → 3.0.14-beta.1

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.
@@ -1,44 +1,15 @@
1
1
  import type { BaseActor, FunctionName, FunctionType } from "@ic-reactor/core"
2
2
  import * as z from "zod"
3
+ import type { VisitorDataType, TextFormat, NumberFormat } from "../types"
3
4
 
4
- // ════════════════════════════════════════════════════════════════════════════
5
- // Field Type Union
6
- // ════════════════════════════════════════════════════════════════════════════
7
-
8
- export type ArgumentFieldType =
9
- | "record"
10
- | "variant"
11
- | "tuple"
12
- | "optional"
13
- | "vector"
14
- | "blob"
15
- | "recursive"
16
- | "principal"
17
- | "number"
18
- | "text"
19
- | "boolean"
20
- | "null"
21
- | "unknown"
5
+ export type { VisitorDataType, TextFormat, NumberFormat }
22
6
 
23
7
  // ════════════════════════════════════════════════════════════════════════════
24
- // Component Type Hints
8
+ // Component & UI Types
25
9
  // ════════════════════════════════════════════════════════════════════════════
26
10
 
27
11
  /**
28
12
  * Suggested component type for rendering the field.
29
- * This eliminates the need for switch statements in the frontend.
30
- *
31
- * @example
32
- * ```tsx
33
- * const componentMap = {
34
- * 'text-input': TextField,
35
- * 'number-input': NumberField,
36
- * 'boolean-checkbox': BooleanField,
37
- * // ...
38
- * }
39
- * const Component = componentMap[field.component]
40
- * return <Component field={field} />
41
- * ```
42
13
  */
43
14
  export type FieldComponentType =
44
15
  | "record-container"
@@ -55,13 +26,8 @@ export type FieldComponentType =
55
26
  | "recursive-lazy"
56
27
  | "unknown-fallback"
57
28
 
58
- // ════════════════════════════════════════════════════════════════════════════
59
- // Render Hints for UI Rendering Strategy
60
- // ════════════════════════════════════════════════════════════════════════════
61
-
62
29
  /**
63
30
  * Input type hints for HTML input elements.
64
- * Used by primitive fields to suggest the appropriate input type.
65
31
  */
66
32
  export type InputType =
67
33
  | "text"
@@ -73,66 +39,28 @@ export type InputType =
73
39
 
74
40
  /**
75
41
  * Rendering hints for the UI.
76
- * Eliminates the need for frontend to maintain COMPLEX_TYPES arrays.
77
- *
78
- * @example
79
- * ```tsx
80
- * // Frontend no longer needs:
81
- * // const COMPLEX_TYPES = ["record", "tuple", "variant", "vector", "optional"]
82
- *
83
- * // Instead use:
84
- * if (field.renderHint.isCompound) {
85
- * return <CompoundFieldRenderer field={field} />
86
- * }
87
- * return <PrimitiveInput field={field} />
88
- * ```
89
42
  */
90
43
  export interface RenderHint {
91
- /** Whether this field has its own container/card styling (compound types) */
92
44
  isCompound: boolean
93
- /** Whether this is a leaf input (primitive types) */
94
45
  isPrimitive: boolean
95
- /** Suggested input type for HTML input elements */
96
46
  inputType?: InputType
97
- /** Description or help text for the field (derived from Candid) */
98
47
  description?: string
99
48
  }
100
49
 
101
- // ════════════════════════════════════════════════════════════════════════════
102
- // Primitive Input Props
103
- // ════════════════════════════════════════════════════════════════════════════
104
-
105
50
  /**
106
51
  * Pre-computed HTML input props for primitive fields.
107
- * Can be spread directly onto an input element.
108
- *
109
- * @example
110
- * ```tsx
111
- * <input {...field.inputProps} value={value} onChange={handleChange} />
112
- * ```
113
52
  */
114
53
  export interface PrimitiveInputProps {
115
- /** HTML input type */
116
- type?: "text" | "number" | "checkbox"
117
- /** Placeholder text */
54
+ type?: "text" | "number" | "checkbox" | "email" | "url" | "tel"
118
55
  placeholder?: string
119
- /** Minimum value for number inputs */
120
56
  min?: string | number
121
- /** Maximum value for number inputs */
122
57
  max?: string | number
123
- /** Step value for number inputs */
124
58
  step?: string | number
125
- /** Pattern for text inputs */
126
59
  pattern?: string
127
- /** Input mode for virtual keyboards */
128
- inputMode?: "text" | "numeric" | "decimal"
129
- /** Autocomplete hint */
60
+ inputMode?: "text" | "numeric" | "decimal" | "email" | "tel" | "url"
130
61
  autoComplete?: string
131
- /** Whether to check spelling */
132
62
  spellCheck?: boolean
133
- /** Minimum length for text inputs */
134
63
  minLength?: number
135
- /** Maximum length for text inputs */
136
64
  maxLength?: number
137
65
  }
138
66
 
@@ -140,481 +68,215 @@ export interface PrimitiveInputProps {
140
68
  // Base Field Interface
141
69
  // ════════════════════════════════════════════════════════════════════════════
142
70
 
143
- export interface FieldBase<TValue = unknown> {
144
- /** The field type */
145
- type: ArgumentFieldType
146
- /** Raw label from Candid: "__arg0", "_0_" */
71
+ interface FieldBase<T extends VisitorDataType = VisitorDataType> {
72
+ type: T
147
73
  label: string
148
- /**
149
- * Pre-formatted display label for UI rendering.
150
- * Transforms raw labels into human-readable format.
151
- *
152
- * @example
153
- * "__arg0" => "Arg 0"
154
- * "_0_" => "Item 0"
155
- * "created_at_time" => "Created At Time"
156
- */
157
74
  displayLabel: string
158
- /**
159
- * Form field name path for binding.
160
- * Uses bracket notation for array indices: `[0]`, `args[0].owner`, `tags[1]`
161
- * Compatible with TanStack Form's `form.Field` name prop.
162
- *
163
- * @example
164
- * ```tsx
165
- * <form.Field name={field.name}>
166
- * {(fieldApi) => <input {...} />}
167
- * </form.Field>
168
- * ```
169
- */
170
75
  name: string
171
- /**
172
- * Suggested component type for rendering this field.
173
- * Eliminates the need for switch statements in the frontend.
174
- */
175
76
  component: FieldComponentType
176
- /**
177
- * Rendering hints for UI strategy.
178
- * Use this to determine if the field needs a container or is a simple input.
179
- */
180
77
  renderHint: RenderHint
181
- /** Zod schema for field validation */
182
78
  schema: z.ZodTypeAny
183
- /** Default value for the field */
184
- defaultValue: TValue
185
- /** Original Candid type name for reference */
186
- candidType?: string
79
+ candidType: string
80
+ defaultValue: unknown
187
81
  }
188
82
 
189
83
  // ════════════════════════════════════════════════════════════════════════════
190
- // Compound Types
84
+ // Field Extras
191
85
  // ════════════════════════════════════════════════════════════════════════════
192
86
 
193
- export interface RecordField extends FieldBase<Record<string, unknown>> {
194
- type: "record"
195
- /** Child fields in the record */
196
- fields: Field[]
197
- /** Map of field label to its metadata for quick lookup */
198
- fieldMap: Map<string, Field>
87
+ export interface BlobLimits {
88
+ maxHexBytes: number
89
+ maxFileBytes: number
90
+ maxHexDisplayLength: number
91
+ }
92
+
93
+ export interface BlobValidationResult {
94
+ valid: boolean
95
+ error?: string
96
+ }
97
+
98
+ interface RecordExtras {
99
+ fields: FieldNode[]
100
+ defaultValue: Record<string, unknown>
199
101
  }
200
102
 
201
- export interface VariantField extends FieldBase<Record<string, unknown>> {
202
- type: "variant"
203
- /** All variant option fields */
204
- fields: Field[]
205
- /** List of variant option names */
206
- options: string[]
207
- /** Default selected option */
103
+ interface VariantExtras {
104
+ fields: FieldNode[]
208
105
  defaultOption: string
209
- /** Map of option name to its field metadata */
210
- optionMap: Map<string, Field>
211
- /**
212
- * Get default value for a specific option.
213
- * Useful when switching between variant options.
214
- *
215
- * @example
216
- * ```tsx
217
- * const handleOptionChange = (newOption: string) => {
218
- * const newDefault = field.getOptionDefault(newOption)
219
- * fieldApi.handleChange(newDefault)
220
- * }
221
- * ```
222
- */
106
+ defaultValue: Record<string, unknown>
223
107
  getOptionDefault: (option: string) => Record<string, unknown>
224
- /**
225
- * Get the field for a specific option.
226
- *
227
- * @example
228
- * ```tsx
229
- * const transferField = field.getField("Transfer")
230
- * ```
231
- */
232
- getField: (option: string) => Field
233
- /**
234
- * Get the currently selected option from a value.
235
- * Returns the first valid key found, or the default option.
236
- *
237
- * @example
238
- * ```tsx
239
- * const selectedOption = field.getSelectedOption(currentValue)
240
- * // { Transfer: {...} } => "Transfer"
241
- * ```
242
- */
108
+ getField: (option: string) => FieldNode
243
109
  getSelectedOption: (value: Record<string, unknown>) => string
244
- /**
245
- * Get the selected field from a value.
246
- * Combines getSelectedOption and getField for convenience.
247
- *
248
- * @example
249
- * ```tsx
250
- * // Current (verbose):
251
- * const validKeys = Object.keys(currentValue).filter(k => field.options.includes(k))
252
- * const selected = validKeys[0] ?? field.options[0]
253
- * const selectedIndex = Math.max(0, field.options.indexOf(selected))
254
- * const selectedField = field.fields[selectedIndex]
255
- *
256
- * // Proposed (simple):
257
- * const selectedField = field.getSelectedField(currentValue)
258
- * ```
259
- */
260
- getSelectedField: (value: Record<string, unknown>) => Field
110
+ getSelectedField: (value: Record<string, unknown>) => FieldNode
261
111
  }
262
112
 
263
- export interface TupleField extends FieldBase<unknown[]> {
264
- type: "tuple"
265
- /** Tuple element fields in order */
266
- fields: Field[]
113
+ interface TupleExtras {
114
+ fields: FieldNode[]
115
+ defaultValue: unknown[]
267
116
  }
268
117
 
269
- export interface OptionalField extends FieldBase<null> {
270
- type: "optional"
271
- /** The inner field when value is present */
272
- innerField: Field
273
- /**
274
- * Get default value when enabling the optional.
275
- * Returns the inner field's default value.
276
- *
277
- * @example
278
- * ```tsx
279
- * const handleToggle = (enabled: boolean) => {
280
- * if (enabled) {
281
- * fieldApi.handleChange(field.getInnerDefault())
282
- * } else {
283
- * fieldApi.handleChange(null)
284
- * }
285
- * }
286
- * ```
287
- */
118
+ interface OptionalExtras {
119
+ innerField: FieldNode
120
+ defaultValue: null
288
121
  getInnerDefault: () => unknown
289
- /**
290
- * Check if a value represents an enabled optional.
291
- * Returns true if the value is not null or undefined.
292
- *
293
- * @example
294
- * ```tsx
295
- * // Current:
296
- * const enabled = fieldApi.state.value !== null && typeof fieldApi.state.value !== "undefined"
297
- *
298
- * // Proposed:
299
- * const enabled = field.isEnabled(fieldApi.state.value)
300
- * ```
301
- */
302
122
  isEnabled: (value: unknown) => boolean
303
123
  }
304
124
 
305
- export interface VectorField extends FieldBase<unknown[]> {
306
- type: "vector"
307
- /** Template field for vector items */
308
- itemField: Field
309
- /**
310
- * Get a new item with default values.
311
- * Used when adding items to the vector.
312
- *
313
- * @example
314
- * ```tsx
315
- * <button onClick={() => fieldApi.pushValue(field.getItemDefault())}>
316
- * Add Item
317
- * </button>
318
- * ```
319
- */
125
+ interface VectorExtras {
126
+ itemField: FieldNode
127
+ defaultValue: unknown[]
320
128
  getItemDefault: () => unknown
321
- /**
322
- * Create a properly configured item field for a specific index.
323
- * Handles name path and label generation.
324
- *
325
- * @example
326
- * ```tsx
327
- * // Current:
328
- * renderField({
329
- * ...field.itemField,
330
- * label: itemLabel,
331
- * name: itemFieldName
332
- * })
333
- *
334
- * // Proposed:
335
- * const itemField = field.createItemField(index, { label: itemLabel })
336
- * renderField(itemField)
337
- * ```
338
- */
339
- createItemField: (index: number, overrides?: { label?: string }) => Field
340
- }
341
-
342
- /**
343
- * Blob field size limits.
344
- */
345
- export interface BlobLimits {
346
- /** Maximum bytes when entering as hex (e.g., 512 bytes) */
347
- maxHexBytes: number
348
- /** Maximum file size in bytes (e.g., 2MB ICP limit) */
349
- maxFileBytes: number
350
- /** Maximum hex display length before truncation */
351
- maxHexDisplayLength: number
352
- }
353
-
354
- /**
355
- * Validation result for blob input.
356
- */
357
- export interface BlobValidationResult {
358
- /** Whether the input is valid */
359
- valid: boolean
360
- /** Error message if invalid */
361
- error?: string
129
+ createItemField: (index: number, overrides?: { label?: string }) => FieldNode
362
130
  }
363
131
 
364
- export interface BlobField extends FieldBase<string> {
365
- type: "blob"
366
- /** Item field for individual bytes (nat8) */
367
- itemField: Field
368
- /** Accepted input formats */
132
+ interface BlobExtras {
133
+ itemField: FieldNode
369
134
  acceptedFormats: ("hex" | "base64" | "file")[]
370
- /** Size limits for blob input */
371
135
  limits: BlobLimits
372
- /**
373
- * Normalize hex input (remove 0x prefix, lowercase, etc.)
374
- *
375
- * @example
376
- * ```tsx
377
- * const normalized = field.normalizeHex("0xDEADBEEF")
378
- * // => "deadbeef"
379
- * ```
380
- */
381
136
  normalizeHex: (input: string) => string
382
- /**
383
- * Validate blob input value.
384
- *
385
- * @example
386
- * ```tsx
387
- * const result = field.validateInput(value)
388
- * if (!result.valid) {
389
- * setError(result.error)
390
- * }
391
- * ```
392
- */
393
137
  validateInput: (value: string | Uint8Array) => BlobValidationResult
138
+ defaultValue: string
394
139
  }
395
140
 
396
- export interface RecursiveField extends FieldBase<undefined> {
397
- type: "recursive"
398
- /** Type name for the recursive type */
141
+ interface RecursiveExtras {
399
142
  typeName: string
400
- /** Lazily extract the inner field to prevent infinite loops */
401
- extract: () => Field
402
- /**
403
- * Get default value for the recursive type.
404
- * Evaluates the inner type on demand.
405
- */
143
+ extract: () => FieldNode
406
144
  getInnerDefault: () => unknown
145
+ defaultValue: undefined
407
146
  }
408
147
 
409
- // ════════════════════════════════════════════════════════════════════════════
410
- // Primitive Types
411
- // ════════════════════════════════════════════════════════════════════════════
412
-
413
- export interface PrincipalField extends FieldBase<string> {
414
- type: "principal"
148
+ interface PrincipalExtras {
415
149
  maxLength: number
416
150
  minLength: number
417
- /**
418
- * Pre-computed HTML input props for direct spreading.
419
- * @example
420
- * ```tsx
421
- * <input {...field.inputProps} value={value} onChange={handleChange} />
422
- * ```
423
- */
151
+ format: TextFormat
424
152
  inputProps: PrimitiveInputProps
153
+ defaultValue: string
425
154
  }
426
155
 
427
- export interface NumberField extends FieldBase<string> {
428
- type: "number"
429
- /**
430
- * Original Candid type: nat, int, nat8, nat16, nat32, nat64, int8, int16, int32, int64, float32, float64
431
- */
432
- candidType: string
433
- /** Whether this is an unsigned type */
156
+ interface NumberExtras {
434
157
  unsigned: boolean
435
- /** Whether this is a floating point type */
436
158
  isFloat: boolean
437
- /** Bit width if applicable (8, 16, 32, 64, or undefined for unbounded) */
438
159
  bits?: number
439
- /** Minimum value constraint (for bounded types) */
440
160
  min?: string
441
- /** Maximum value constraint (for bounded types) */
442
161
  max?: string
443
- /**
444
- * Pre-computed HTML input props for direct spreading.
445
- * @example
446
- * ```tsx
447
- * <input {...field.inputProps} value={value} onChange={handleChange} />
448
- * ```
449
- */
162
+ format: NumberFormat
450
163
  inputProps: PrimitiveInputProps
164
+ defaultValue: string
451
165
  }
452
166
 
453
- export interface TextField extends FieldBase<string> {
454
- type: "text"
455
- /** Minimum length constraint */
167
+ interface TextExtras {
456
168
  minLength?: number
457
- /** Maximum length constraint */
458
169
  maxLength?: number
459
- /** Whether to render as multiline textarea */
460
170
  multiline?: boolean
461
- /**
462
- * Pre-computed HTML input props for direct spreading.
463
- * @example
464
- * ```tsx
465
- * <input {...field.inputProps} value={value} onChange={handleChange} />
466
- * ```
467
- */
171
+ format: TextFormat
468
172
  inputProps: PrimitiveInputProps
173
+ defaultValue: string
469
174
  }
470
175
 
471
- export interface BooleanField extends FieldBase<boolean> {
472
- type: "boolean"
473
- /**
474
- * Pre-computed HTML input props for direct spreading.
475
- * @example
476
- * ```tsx
477
- * <input {...field.inputProps} checked={value} onChange={handleChange} />
478
- * ```
479
- */
176
+ interface BooleanExtras {
480
177
  inputProps: PrimitiveInputProps
178
+ defaultValue: boolean
481
179
  }
482
180
 
483
- export interface NullField extends FieldBase<null> {
484
- type: "null"
181
+ interface NullExtras {
182
+ defaultValue: null
485
183
  }
486
184
 
487
- export interface UnknownField extends FieldBase<undefined> {
488
- type: "unknown"
185
+ interface UnknownExtras {
186
+ defaultValue: undefined
489
187
  }
490
188
 
491
- // ════════════════════════════════════════════════════════════════════════════
492
- // Union Type
493
- // ════════════════════════════════════════════════════════════════════════════
189
+ type FieldExtras<T extends VisitorDataType> = T extends "record"
190
+ ? RecordExtras
191
+ : T extends "variant"
192
+ ? VariantExtras
193
+ : T extends "tuple"
194
+ ? TupleExtras
195
+ : T extends "optional"
196
+ ? OptionalExtras
197
+ : T extends "vector"
198
+ ? VectorExtras
199
+ : T extends "blob"
200
+ ? BlobExtras
201
+ : T extends "recursive"
202
+ ? RecursiveExtras
203
+ : T extends "principal"
204
+ ? PrincipalExtras
205
+ : T extends "number"
206
+ ? NumberExtras
207
+ : T extends "text"
208
+ ? TextExtras
209
+ : T extends "boolean"
210
+ ? BooleanExtras
211
+ : T extends "null"
212
+ ? NullExtras
213
+ : T extends "unknown"
214
+ ? UnknownExtras
215
+ : {}
494
216
 
495
- export type Field =
496
- | RecordField
497
- | VariantField
498
- | TupleField
499
- | OptionalField
500
- | VectorField
501
- | BlobField
502
- | RecursiveField
503
- | PrincipalField
504
- | NumberField
505
- | TextField
506
- | BooleanField
507
- | NullField
508
- | UnknownField
217
+ /**
218
+ * A unified field node that contains all metadata needed for rendering.
219
+ */
220
+ export type FieldNode<T extends VisitorDataType = VisitorDataType> =
221
+ T extends any ? FieldBase<T> & FieldExtras<T> : never
222
+
223
+ export type RecordField = FieldNode<"record">
224
+ export type VariantField = FieldNode<"variant">
225
+ export type TupleField = FieldNode<"tuple">
226
+ export type OptionalField = FieldNode<"optional">
227
+ export type VectorField = FieldNode<"vector">
228
+ export type BlobField = FieldNode<"blob">
229
+ export type RecursiveField = FieldNode<"recursive">
230
+ export type PrincipalField = FieldNode<"principal">
231
+ export type NumberField = FieldNode<"number">
232
+ export type TextField = FieldNode<"text">
233
+ export type BooleanField = FieldNode<"boolean">
234
+ export type NullField = FieldNode<"null">
235
+ export type UnknownField = FieldNode<"unknown">
509
236
 
510
237
  // ════════════════════════════════════════════════════════════════════════════
511
- // Form Metadata - TanStack Form Integration
238
+ // Form Metadata
512
239
  // ════════════════════════════════════════════════════════════════════════════
513
240
 
514
- /**
515
- * Form metadata for a Candid method.
516
- * Contains all information needed to create a TanStack Form instance.
517
- *
518
- * @example
519
- * ```tsx
520
- * import { useForm } from '@tanstack/react-form'
521
- *
522
- * function MethodForm({ meta }: { meta: FormMeta }) {
523
- * const form = useForm({
524
- * ...meta.formOptions,
525
- * onSubmit: async ({ value }) => {
526
- * await actor[meta.functionName](...value)
527
- * }
528
- * })
529
- *
530
- * return (
531
- * <form onSubmit={(e) => { e.preventDefault(); form.handleSubmit() }}>
532
- * {meta.fields.map(field => (
533
- * <form.Field key={field.name} name={field.name}>
534
- * {(fieldApi) => <DynamicInput field={field} fieldApi={fieldApi} />}
535
- * </form.Field>
536
- * ))}
537
- * <button type="submit">Submit</button>
538
- * </form>
539
- * )
540
- * }
541
- * ```
542
- */
543
241
  export interface ArgumentsMeta<
544
242
  A = BaseActor,
545
243
  Name extends FunctionName<A> = FunctionName<A>,
546
244
  > {
547
- /** Whether this is a "query" or "update" function */
548
245
  functionType: FunctionType
549
- /** The function name */
550
246
  functionName: Name
551
- /** Argument field definitions for rendering */
552
- fields: Field[]
553
- /** Default values for all arguments (as a tuple) */
247
+ fields: FieldNode[]
554
248
  defaultValues: unknown[]
555
- /** Combined Zod schema for all arguments */
556
249
  schema: z.ZodTuple<[z.ZodTypeAny, ...z.ZodTypeAny[]]>
557
- /** Number of arguments */
558
250
  argCount: number
559
- /** Whether the function takes no arguments */
560
251
  isNoArgs: boolean
561
252
  }
562
253
 
563
- /**
564
- * Options that can be spread into useForm().
565
- * Pre-configured with defaultValues and validators.
566
- */
567
254
  export interface FormOptions {
568
- /** Initial form values */
569
255
  defaultValues: unknown[]
570
- /** Validators using the Zod schema */
571
256
  validators: {
572
257
  onChange: z.ZodTypeAny
573
258
  onBlur: z.ZodTypeAny
574
259
  }
575
260
  }
576
261
 
577
- /**
578
- * Service-level form metadata.
579
- * Maps each method name to its FormMeta.
580
- */
581
262
  export type ArgumentsServiceMeta<A = BaseActor> = {
582
263
  [K in FunctionName<A>]: ArgumentsMeta<A, K>
583
264
  }
584
265
 
585
266
  // ════════════════════════════════════════════════════════════════════════════
586
- // Type Utilities & Guards
267
+ // Type Utilities
587
268
  // ════════════════════════════════════════════════════════════════════════════
588
269
 
589
- /** Extract a specific field type */
590
- export type FieldByType<T extends ArgumentFieldType> = Extract<
591
- Field,
270
+ export type FieldByType<T extends VisitorDataType> = Extract<
271
+ FieldNode,
592
272
  { type: T }
593
273
  >
594
274
 
595
- /**
596
- * Props type helper for field components.
597
- * Use this to type your field components for better DX.
598
- *
599
- * @example
600
- * ```tsx
601
- * const VariantField: React.FC<FieldProps<'variant'>> = ({ field, renderField }) => {
602
- * // field is properly typed as VariantField
603
- * return (
604
- * <div>
605
- * <select>{field.options.map(opt => ...)}</select>
606
- * {renderField?.(field.getSelectedField(currentValue))}
607
- * </div>
608
- * )
609
- * }
610
- * ```
611
- */
612
- export type FieldProps<T extends ArgumentFieldType> = {
275
+ export type FieldProps<T extends VisitorDataType> = {
613
276
  field: FieldByType<T>
614
- renderField?: (child: Field) => React.ReactNode
277
+ renderField?: (child: FieldNode) => React.ReactNode
615
278
  }
616
279
 
617
- /** Compound field types that contain other fields */
618
280
  export type CompoundField =
619
281
  | RecordField
620
282
  | VariantField
@@ -623,38 +285,9 @@ export type CompoundField =
623
285
  | VectorField
624
286
  | RecursiveField
625
287
 
626
- /** Primitive field types */
627
288
  export type PrimitiveField =
628
289
  | PrincipalField
629
290
  | NumberField
630
291
  | TextField
631
292
  | BooleanField
632
293
  | NullField
633
-
634
- /**
635
- * A complete mapping of component types to React components.
636
- * Use this type when defining your component map.
637
- *
638
- * @example
639
- * ```tsx
640
- * const componentMap: ComponentMap<typeof MyTextInput, typeof MyNumberInput, ...> = {
641
- * 'text-input': MyTextInput,
642
- * 'number-input': MyNumberInput,
643
- * // ...
644
- * }
645
- * ```
646
- */
647
- export type ComponentMap<
648
- TComponents extends Record<FieldComponentType, unknown>,
649
- > = {
650
- [K in FieldComponentType]: TComponents[K]
651
- }
652
-
653
- /**
654
- * Get the component type for a given field component type.
655
- * Useful for typing dynamic component lookups.
656
- */
657
- export type GetComponentType<
658
- TMap extends Partial<Record<FieldComponentType, unknown>>,
659
- TKey extends FieldComponentType,
660
- > = TKey extends keyof TMap ? TMap[TKey] : never