Radosław Miernik
Open source? Embrace, understand, develop.
uniforms
!aldeed:autoform
for React
(that's basically it)
Use every schema
with every theme.
(even your own)
import SimpleSchema from 'simpl-schema';
export const schema = new SimpleSchema({
title: { type: String, max: 200 },
author: { type: String },
copies: { type: Number, label: 'Number of copies', min: 0 },
lastCheckedOut: {
type: Date,
label: 'Last date this book was checked out',
optional: true,
},
});
import { SimpleSchema2Bridge } from 'uniforms-bridge-simple-schema-2';
import { schema } from './schema';
export const bridge = new SimpleSchema2Bridge(schema);
import { AutoForm } from 'uniforms-???';
import { bridge } from './bridge';
async function onBookSubmit(model) {
await api.books.save(model);
}
export function BookForm {
return (
<AutoForm
schema={bridge}
onSubmit={onBookSubmit}
/>
);
}
uniforms-unstyled
uniforms-semantic
uniforms-material
uniforms-antd
uniforms-bootstrap3
uniforms-bootstrap4
import { connectField } from 'uniforms';
function Rating({ onChange, value = 0 }) {
return (
<div>
{Array.from({ length: 5 }, (_, index) =>
<span key={index} onClick={() => onChange(index)}>
{index <= value ? '★' : '☆'}
</span>
)}
</div>
);
}
export const RatingField = connectField(Rating);
Anything with onChange
and value
will work.
v3
import { useField } from 'uniforms';
export function RatingField({ name }) {
const { onChange, value = 0 } = useField(name);
return (
<div>
{Array.from({ length: 5 }, (_, index) =>
<span key={index} onClick={() => onChange(index)}>
{index <= value ? '★' : '☆'}
</span>
)}
</div>
);
}
Hooks are opt-in - connectField
still works.
import { AutoForm, AutoField, NumField, TextField } from 'uniforms-???';
import { RatingField } from './RatingField';
import { bridge } from './bridge';
async function onSubmit(model) { /* ... */ }
export function CustomForm() {
return (
<AutoForm schema={bridge} onSubmit={onSubmit}>
{/* AutoField will pick correct field component */}
<AutoField name="name" />
{/* Explicitly select component */}
<TextField name="name" />
<NumField name="age" />
{/* Custom fields works the same */}
<RatingField name="rating" />
</AutoForm>
);
}
import { GraphQLBridge } from 'uniforms-bridge-graphql';
import schema from './schema.graphql';
// See docs for more about validator and options.
function validator(model) {
return model.title ? null : {
details: [{ name: 'title', message: 'Title!' }],
};
}
// Extra props for field components.
const options = { 'address.street': { label: 'Street' } };
export const bridge = new GraphQLBridge(
schema.getType('Customer'),
validator,
options,
);
type Address {
city: String!
street: String
}
type Customer {
address: Address
secret: Float
}
import Ajv from 'ajv';
import { JSONSchemaBridge } from 'uniforms-bridge-json-schema';
import { schema } from './schema';
const ajv = new Ajv({ allErrors: true, useDefaults: true });
function createValidator(schema) {
const validator = ajv.compile(schema);
return model => {
validator(model);
return validator.errors?.length
? { details: validator.errors }
: null;
};
}
export const bridge = new JSONSchemaBridge(
schema,
createValidator(schema),
);
export const schema = {
type: 'object',
properties: {
name: { type: 'string' },
experience: {
type: 'integer',
minimum: 0,
maximum: 100,
},
},
required: ['name'],
};
uniforms
are 100% open source, backed by Vazco, and developed by Vazco Open Source Group
(no one was hurt nor forced during development)
(really)
First public version was released on 10 May 2016.
First deployed version went live on 2 May 2016.
Version 2 was released on
10 June 2019.
Version 3 is due... Soon.
By Radosław Miernik
Meteor Impact 2020