Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 83 additions & 30 deletions docs/en-US/guide/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ pnpm add @schepta/core

# Install React adapter and factory (for React projects)
pnpm add @schepta/adapter-react @schepta/factory-react

# Install React Hook Form (required for forms)
pnpm add react-hook-form
```

FormFactory uses native React state by default, so **no form library is required** for your first form. To integrate with React Hook Form or Formik later, see the [React Showcase](/en-US/showcases/react) for examples.

## Setting Up the Provider

The `ScheptaProvider` is the central configuration point for your application. It manages global component registrations, middleware, and context that all factories can access.
Expand Down Expand Up @@ -56,7 +55,9 @@ function App() {

| Prop | Type | Description |
|------|------|-------------|
| `components` | `Record<string, ComponentSpec>` | Global component registry |
| `components` | `Record<string, ComponentSpec>` | Global component registry (optional) |
| `customComponents` | `Record<string, ComponentSpec>` | Custom components keyed by schema key (optional) |
| `renderers` | `Partial<Record<ComponentType, RendererFn>>` | Custom renderers per component type (optional) |
| `middlewares` | `Middleware[]` | Global middleware stack |
| `externalContext` | `object` | Shared context (user, API, etc.) |
| `debug` | `object` | Debug configuration |
Expand All @@ -70,9 +71,9 @@ Components must be registered using `createComponentSpec` before they can be use
schepta supports several component types:

- **`field`** - Input fields (text, select, checkbox, etc.)
- **`container`** - Container components (FormField, FormSection, etc.)
- **`content`** - Content components (titles, buttons, etc.)
- **`FormContainer`** - Root form container
- **`container`** - Container components (FormField, FormSection, FormContainer, etc.)
- **`content`** - Content components (titles, etc.)
- **`button`** - Button components (e.g. SubmitButton)

### Creating Component Specs

Expand Down Expand Up @@ -102,7 +103,7 @@ const components = {
InputText: createComponentSpec({
id: 'InputText',
type: 'field',
factory: (props, runtime) => InputText,
component: (props, runtime) => InputText,
}),
};
```
Expand All @@ -112,7 +113,7 @@ const components = {
```tsx
import { createComponentSpec } from '@schepta/core';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import { useScheptaFormAdapter } from '@schepta/factory-react';

// Define your components
const InputText = React.forwardRef<HTMLInputElement, any>((props, ref) => {
Expand Down Expand Up @@ -144,67 +145,118 @@ const FormSectionTitle = ({ 'x-content': content, ...props }: any) => {
return <h2 {...props}>{content}</h2>;
};

const FormSectionGroup = ({ children, ...props }: any) => {
return <div style={{ display: 'grid', gap: '16px' }} {...props}>{children}</div>;
};

const FormSectionGroupContainer = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const SubmitButton = ({ 'x-content': content, ...props }: any) => {
const { handleSubmit } = useFormContext();
return (
<button
type="button"
onClick={() => handleSubmit(props.onSubmit)()}
{...props}
>
<button type="submit" {...props}>
{content || 'Submit'}
</button>
);
};

const FormContainer = ({ children, ...props }: any) => {
return <form {...props}>{children}</form>;
const FormContainer = ({ children, onSubmit, ...props }: any) => {
const adapter = useScheptaFormAdapter();
const handleFormSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (onSubmit) adapter.handleSubmit(onSubmit)();
};
return (
<form onSubmit={handleFormSubmit} {...props}>
{children}
</form>
);
};

// Register all components using createComponentSpec
export const globalComponents = {
'FormContainer': createComponentSpec({
FormContainer: createComponentSpec({
id: 'FormContainer',
type: 'FormContainer',
factory: (props, runtime) => FormContainer,
type: 'container',
component: (props, runtime) => FormContainer,
}),
InputText: createComponentSpec({
id: 'InputText',
type: 'field',
factory: (props, runtime) => InputText,
component: (props, runtime) => InputText,
}),
FormField: createComponentSpec({
id: 'FormField',
type: 'container',
factory: (props, runtime) => FormField,
component: (props, runtime) => FormField,
}),
FormSectionContainer: createComponentSpec({
id: 'FormSectionContainer',
type: 'container',
factory: (props, runtime) => FormSectionContainer,
component: (props, runtime) => FormSectionContainer,
}),
FormSectionTitle: createComponentSpec({
id: 'FormSectionTitle',
type: 'content',
factory: (props, runtime) => FormSectionTitle,
component: (props, runtime) => FormSectionTitle,
}),
FormSectionGroup: createComponentSpec({
id: 'FormSectionGroup',
type: 'container',
component: (props, runtime) => FormSectionGroup,
}),
FormSectionGroupContainer: createComponentSpec({
id: 'FormSectionGroupContainer',
type: 'container',
component: (props, runtime) => FormSectionGroupContainer,
}),
SubmitButton: createComponentSpec({
id: 'SubmitButton',
type: 'content',
factory: (props, runtime) => SubmitButton,
type: 'button',
component: (props, runtime) => SubmitButton,
}),
};
```

## Your First Form

Now let's create a complete example combining everything:
Now let's create a complete example combining everything.

### Minimal Example (Using Defaults)

FormFactory ships with built-in components, so you can render a form with just a schema and `onSubmit`—no custom registration required:

```tsx
import React from 'react';
import { ScheptaProvider } from '@schepta/adapter-react';
import { FormFactory } from '@schepta/factory-react';
import formSchema from './form-schema.json';

function App() {
const handleSubmit = (values: any) => {
console.log('Form submitted:', values);
};

return (
<ScheptaProvider>
<div style={{ padding: '24px', maxWidth: '800px', margin: '0 auto' }}>
<h1>My First schepta Form</h1>
<FormFactory schema={formSchema} onSubmit={handleSubmit} />
</div>
</ScheptaProvider>
);
}

export default App;
```

### 1. Define Your Schema

You can use `x-component-props` or `x-ui` for field labels and placeholders. The `$schema` property is optional (useful for IDE validation when working inside the monorepo).

```json
{
"$schema": "../../packages/factories/src/schemas/form-schema.json",
"$id": "my-first-form",
"type": "object",
"x-component": "FormContainer",
Expand Down Expand Up @@ -233,7 +285,7 @@ Now let's create a complete example combining everything:
"firstName": {
"type": "string",
"x-component": "InputText",
"x-ui": {
"x-component-props": {
"label": "First Name",
"placeholder": "Enter your first name"
},
Expand All @@ -258,7 +310,7 @@ Now let's create a complete example combining everything:
}
```

### 2. Complete React Example
### 2. Complete React Example (With Custom Components)

```tsx
import React from 'react';
Expand Down Expand Up @@ -313,4 +365,5 @@ Learn the fundamental concepts that power schepta:

## Resources

- [React Showcase](/en-US/showcases/react) - Examples with React Hook Form and Formik
- [GitHub Repository](https://github.com/guynikan/schepta)
Loading