Skip to content

Commit 12336de

Browse files
committed
add base field
1 parent f19f2d4 commit 12336de

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

next/src/field/object.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { JSONSchema } from 'json-schema-typed'
2+
import type { Field } from './type'
3+
import { setCustomOrder } from '../custom/order'
4+
import { buildFieldSingle } from './single'
5+
6+
export function buildFieldObject(params: {
7+
schema: JSONSchema
8+
}): Field[] {
9+
const { schema } = params
10+
11+
if (typeof schema === 'boolean')
12+
throw new Error('Schema must be an object')
13+
14+
if (schema.type !== 'object')
15+
throw new Error('Schema must be of type "object"')
16+
17+
const fields: Field[] = []
18+
19+
Object
20+
.entries(schema.properties ?? {})
21+
.forEach((entry) => {
22+
const [name, schema] = entry
23+
const field = buildFieldSingle({ name, schema })
24+
if (field !== null)
25+
fields.push(field)
26+
})
27+
28+
const withOrder = setCustomOrder({ fields, schema })
29+
30+
return withOrder
31+
}

next/src/field/single.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { JsfSchema } from '../types'
2+
import type { Field } from './type'
3+
import { buildFieldObject } from './object'
4+
5+
/**
6+
* Build a single UI field from a single schema property
7+
*/
8+
export function buildFieldSingle(params: {
9+
name: string
10+
schema: JsfSchema
11+
}): Field | null {
12+
const { name, schema } = params
13+
14+
// This is different than schema.type === "boolean"
15+
if (typeof schema === 'boolean')
16+
return null
17+
18+
// Common properties for all field types
19+
const field: Field = {
20+
name,
21+
label: schema.title,
22+
}
23+
24+
// Recursive for objects
25+
if (schema.type === 'object') {
26+
field.fields = buildFieldObject({ schema })
27+
}
28+
29+
return field
30+
}

next/src/field/type.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* WIP interface for UI field output
3+
*/
4+
export interface Field {
5+
name: string
6+
label?: string
7+
fields?: Field[]
8+
}

next/src/form.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import type { Field } from './field/type'
12
import type { JsfSchema, SchemaValue } from './types'
23
import type { SchemaValidationErrorType } from './validation/schema'
4+
import { buildFieldObject } from './field/object'
35
import { validateSchema } from './validation/schema'
46

57
interface FormResult {
6-
fields: never[]
8+
fields: Field[]
79
isError: boolean
810
error: string | null
911
handleValidation: (value: SchemaValue) => ValidationResult
@@ -83,7 +85,23 @@ interface CreateHeadlessFormOptions {
8385
initialValues?: SchemaValue
8486
}
8587

86-
export function createHeadlessForm(schema: JsfSchema, options: CreateHeadlessFormOptions = {}): FormResult {
88+
function buildFields(params: {
89+
schema: JsfSchema
90+
}): Field[] {
91+
const { schema } = params
92+
93+
if (typeof schema === 'boolean')
94+
return []
95+
96+
const fields: Field[] = buildFieldObject({ schema })
97+
98+
return fields
99+
}
100+
101+
export function createHeadlessForm(
102+
schema: JsfSchema,
103+
options: CreateHeadlessFormOptions = {},
104+
): FormResult {
87105
const errors = validateSchema(options.initialValues, schema)
88106
const validationResult = validationErrorsToFormErrors(errors)
89107
const isError = validationResult !== null
@@ -94,7 +112,7 @@ export function createHeadlessForm(schema: JsfSchema, options: CreateHeadlessFor
94112
}
95113

96114
return {
97-
fields: [],
115+
fields: buildFields({ schema }),
98116
isError,
99117
error: null,
100118
handleValidation,

0 commit comments

Comments
 (0)