diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..b12b42434 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "[mdx]": { + "editor.defaultFormatter": "unifiedjs.vscode-mdx" + } +} diff --git a/website/components/CodeEditor.tsx b/website/components/CodeEditor.tsx deleted file mode 100644 index 42794e650..000000000 --- a/website/components/CodeEditor.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { - SandpackCodeEditor, - SandpackLayout, - SandpackPreview, - SandpackProvider, -} from '@codesandbox/sandpack-react'; - -type CodeEditorProps = { - files: Record; - dependencies?: Record; -}; - -const example = { - '/App.js': `import { AutoForm } from 'uniforms-mui'; -import { ZodBridge } from 'uniforms-bridge-zod'; -import { z } from 'zod'; - -const userSchema = z.object({ - username: z.string(), - password: z.string().min(8), -}); - -const schema = new ZodBridge({ schema: userSchema }); - -export default function App() { - return ( - window.alert(JSON.stringify(model, null, 2))} - /> - ); -}`, -}; - -const defaultDependencies = { - '@mui/material': '^6', - '@emotion/react': '^11', - '@emotion/styled': '^11', - antd: '^5', - uniforms: '4.0.0-beta.2', - 'uniforms-mui': '4.0.0-beta.2', - 'uniforms-bridge-zod': '4.0.0-beta.2', - zod: '^3', -}; - -export function CodeEditor(props: CodeEditorProps) { - const { files = example, dependencies = defaultDependencies } = props; - - return ( - - - {/* */} - - - - - ); -} diff --git a/website/components/CodeEditor/CodeEditor.tsx b/website/components/CodeEditor/CodeEditor.tsx new file mode 100644 index 000000000..8a31249c2 --- /dev/null +++ b/website/components/CodeEditor/CodeEditor.tsx @@ -0,0 +1,40 @@ +import { + SandpackCodeEditor, + SandpackLayout, + SandpackPreview, + SandpackProvider, +} from '@codesandbox/sandpack-react'; +import { + dependencies, + Bridges, +} from '@site/components/CodeEditor/dependencies'; + +type CodeEditorProps = { + files: Record; + bridge: Bridges; +}; + +export function CodeEditor(props: CodeEditorProps) { + const { files, bridge } = props; + + return ( + + + + + + + ); +} diff --git a/website/components/CodeEditor/ajvValidatorFile.ts b/website/components/CodeEditor/ajvValidatorFile.ts new file mode 100644 index 000000000..981df3810 --- /dev/null +++ b/website/components/CodeEditor/ajvValidatorFile.ts @@ -0,0 +1,16 @@ +export const ajvValidatorFile = `import Ajv, { JSONSchemaType } from 'ajv'; + +const ajv = new Ajv({ + allErrors: true, + useDefaults: true, + keywords: ['uniforms'], +}); + +export function createValidator(schema: JSONSchemaType) { + const validator = ajv.compile(schema); + + return (model: Record) => { + validator(model); + return validator.errors?.length ? { details: validator.errors } : null; + }; +}`; diff --git a/website/components/CodeEditor/dependencies.ts b/website/components/CodeEditor/dependencies.ts new file mode 100644 index 000000000..d43ea0e23 --- /dev/null +++ b/website/components/CodeEditor/dependencies.ts @@ -0,0 +1,41 @@ +export enum Bridges { + Zod = 'zod', + JSONSchema = 'json-schema', + SimpleSchema = 'simpl-schema', +} + +const defaultDependencies = { + antd: '^5', + uniforms: '4.0.0-beta.2', + 'uniforms-antd': '4.0.0-beta.2', +}; + +const zodDependencies = { + 'uniforms-bridge-zod': '4.0.0-beta.2', + zod: '^3', +}; + +const jsonSchemaDependencies = { + ajv: '^8', + 'uniforms-bridge-json-schema': '4.0.0-beta.2', +}; + +const simpleSchemaDependencies = { + 'simpl-schema': '^3', + 'uniforms-bridge-simple-schema-2': '4.0.0-beta.2', +}; + +export const dependencies = { + [Bridges.Zod]: { + ...defaultDependencies, + ...zodDependencies, + }, + [Bridges.JSONSchema]: { + ...defaultDependencies, + ...jsonSchemaDependencies, + }, + [Bridges.SimpleSchema]: { + ...defaultDependencies, + ...simpleSchemaDependencies, + }, +}; diff --git a/website/docs/examples/_category_.json b/website/docs/examples/_category_.json new file mode 100644 index 000000000..1f59843e1 --- /dev/null +++ b/website/docs/examples/_category_.json @@ -0,0 +1,5 @@ +{ + "position": 3, + "label": "Examples", + "collapsible": false +} diff --git a/website/docs/examples/basic-usage.mdx b/website/docs/examples/basic-usage.mdx new file mode 100644 index 000000000..c81c11974 --- /dev/null +++ b/website/docs/examples/basic-usage.mdx @@ -0,0 +1,97 @@ +--- +title: 'Basic usage' +sidebar_position: 1 +--- + +import { ajvValidatorFile } from '@site/components/CodeEditor/ajvValidatorFile'; +import { CodeEditor } from '@site/components/CodeEditor/CodeEditor'; + +### Zod + +export const zodFiles = { + '/App.tsx': `import { AutoForm } from 'uniforms-antd'; +import { ZodBridge } from 'uniforms-bridge-zod'; +import { z } from 'zod'; + +const userSchema = z.object({ + username: z.string(), +}); + +const schema = new ZodBridge({ schema: userSchema }); + +export default function App() { + return ( + window.alert(JSON.stringify(model))} + /> + ); +}` +}; + + + +### JSON Schema + +export const jsonSchemaFiles = { + '/App.tsx': `import { AutoForm } from 'uniforms-antd'; +import { schema } from './userSchema'; + +export default function App() { + return ( + window.alert(JSON.stringify(model))} + /> + ); +}`, + '/userSchema.ts': `import { JSONSchemaBridge } from 'uniforms-bridge-json-schema'; +import { JSONSchemaType } from 'ajv' +import { createValidator } from './validator'; + +type FormData = { + username: string; +}; + +const userSchema: JSONSchemaType = { + type: 'object', + properties: { + username: { type: 'string' }, + }, + required: ['username'], +}; + +export const schema = new JSONSchemaBridge({ + schema: userSchema, + validator: createValidator(userSchema), +}); +`, + '/validator.ts': ajvValidatorFile +}; + + + +### SimpleSchema + +export const simpleSchemaFiles = { + '/App.tsx': `import { AutoForm } from 'uniforms-antd'; +import { SimpleSchema2Bridge } from 'uniforms-bridge-simple-schema-2'; +import SimpleSchema from 'simpl-schema'; + +const userSchema = new SimpleSchema({ + username: String +}); + +const schema = new SimpleSchema2Bridge({ schema: userSchema }); + +export default function App() { + return ( + window.alert(JSON.stringify(model))} + /> + ); +}` +} + + diff --git a/website/docs/getting-started/basic-usage.mdx b/website/docs/getting-started/basic-usage.mdx index 5cc1ad432..f7d0997f3 100644 --- a/website/docs/getting-started/basic-usage.mdx +++ b/website/docs/getting-started/basic-usage.mdx @@ -3,7 +3,7 @@ title: 'Basic usage' sidebar_position: 2 --- -import { CodeEditor } from '../../components/CodeEditor'; +import { CodeEditor } from '../../components/CodeEditor/CodeEditor'; :::info This example uses `uniforms-bridge-zod` and `uniforms-antd` packages as this bridge and theme don't require any extra configuration. @@ -56,4 +56,25 @@ That's it! Now we can render our form and see it in action. We have created a simple form with a schema. It uses AntD theme and Zod as our schema validator. Check [advanced usage](/docs/gettings-started/advanced-usage) for more complex examples or play around with the example below. - +export const files = { + '/App.tsx': `import { AutoForm } from 'uniforms-antd'; +import { ZodBridge } from 'uniforms-bridge-zod'; +import { z } from 'zod'; + +const userSchema = z.object({ + username: z.string(), +}); + +const schema = new ZodBridge({ schema: userSchema }); + +export default function App() { + return ( + window.alert(JSON.stringify(model))} + /> + ); +}` +} + +