UI Schema Descriptor
Problem to solve
Separate UI needs (attributes, labels, etc.) from the input JSON Schema.
Further details
A JSON Schema is a way to describe functional needs for a business: login, customer, user, employee...
It can be used to validate user inputs in a SPA application (Vue.js) and in a Rest API side (Node.js, Spring Boot) or in a mobile app (Android).
So FormSchema should not add additional un-standard fields just to describe UI needs.
Proposal
Create a completely separated API for all UI needs. It will be used to describe attributes and labels for a JSON Schema property for instance.
The object can be called UI Schema Descriptor and could be have this API:
type SchemaType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
type FieldKind = SchemaType | 'enum' | 'radio' | 'list' | 'textarea' | 'checkbox';
type Component = string | VueComponent | AsyncComponent;
type DescriptorInstance = ScalarDescriptor | ObjectDescriptor | ArrayDescriptor;
interface AbstractUISchemaDescriptor {
kind?: FieldKind;
label?: string;
helper?: string;
component?: Component;
attrs?: {
[attr: string]: unknown;
};
props?: {
[prop: string]: unknown;
};
}
interface ScalarDescriptor extends AbstractUISchemaDescriptor {
items?: {
[key: string]: DescriptorInstance;
};
}
interface ObjectDescriptor extends AbstractUISchemaDescriptor {
properties?: {
[property: string]: DescriptorInstance;
};
order?: string[];
}
interface ButtonDescriptor {
label: string;
tooltip?: string;
}
interface ArrayDescriptor extends AbstractUISchemaDescriptor {
items?: DescriptorInstance[] | DescriptorInstance;
buttons: {
push: ButtonDescriptor;
clear: ButtonDescriptor;
moveUp: ButtonDescriptor;
moveDown: ButtonDescriptor;
delete: ButtonDescriptor;
};
}
interface DescriptorConstructor {
get: <T = DescriptorInstance>(schema: JsonSchema, kind?: FieldKind) => T;
}
And the usage could be:
<FormSchema
:schema="newsletterSchema"
:descriptor="newsletterUiSchema"
:components="customComponentsMap"/>
Edited by Sébastien Demanou