diff --git a/docs/en-US/guide/quick-start.md b/docs/en-US/guide/quick-start.md index a717a33..7bbe531 100644 --- a/docs/en-US/guide/quick-start.md +++ b/docs/en-US/guide/quick-start.md @@ -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. @@ -56,7 +55,9 @@ function App() { | Prop | Type | Description | |------|------|-------------| -| `components` | `Record` | Global component registry | +| `components` | `Record` | Global component registry (optional) | +| `customComponents` | `Record` | Custom components keyed by schema key (optional) | +| `renderers` | `Partial>` | Custom renderers per component type (optional) | | `middlewares` | `Middleware[]` | Global middleware stack | | `externalContext` | `object` | Shared context (user, API, etc.) | | `debug` | `object` | Debug configuration | @@ -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 @@ -102,7 +103,7 @@ const components = { InputText: createComponentSpec({ id: 'InputText', type: 'field', - factory: (props, runtime) => InputText, + component: (props, runtime) => InputText, }), }; ``` @@ -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((props, ref) => { @@ -144,67 +145,118 @@ const FormSectionTitle = ({ 'x-content': content, ...props }: any) => { return

{content}

; }; +const FormSectionGroup = ({ children, ...props }: any) => { + return
{children}
; +}; + +const FormSectionGroupContainer = ({ children, ...props }: any) => { + return
{children}
; +}; + const SubmitButton = ({ 'x-content': content, ...props }: any) => { - const { handleSubmit } = useFormContext(); return ( - ); }; -const FormContainer = ({ children, ...props }: any) => { - return
{children}
; +const FormContainer = ({ children, onSubmit, ...props }: any) => { + const adapter = useScheptaFormAdapter(); + const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (onSubmit) adapter.handleSubmit(onSubmit)(); + }; + return ( +
+ {children} +
+ ); }; // 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 ( + +
+

My First schepta Form

+ +
+
+ ); +} + +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", @@ -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" }, @@ -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'; @@ -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) diff --git a/docs/es-ES/guide/quick-start.md b/docs/es-ES/guide/quick-start.md index b684d56..a63cb1b 100644 --- a/docs/es-ES/guide/quick-start.md +++ b/docs/es-ES/guide/quick-start.md @@ -21,11 +21,10 @@ pnpm add @schepta/core # Instalar adaptador y factory de React (para proyectos React) pnpm add @schepta/adapter-react @schepta/factory-react - -# Instalar React Hook Form (requerido para formularios) -pnpm add react-hook-form ``` +FormFactory usa estado nativo de React por defecto, así que **no se requiere ninguna biblioteca de formularios** para tu primer formulario. Para integrar con React Hook Form o Formik más adelante, consulta el [Showcase React](/es-ES/showcases/react). + ## Configuración del Provider El `ScheptaProvider` es el punto central de configuración para tu aplicación. Gestiona los registros globales de componentes, middleware y contexto que todas las factories pueden acceder. @@ -56,7 +55,9 @@ function App() { | Prop | Tipo | Descripción | |------|------|-------------| -| `components` | `Record` | Registro global de componentes | +| `components` | `Record` | Registro global de componentes (opcional) | +| `customComponents` | `Record` | Componentes customizados por clave del schema (opcional) | +| `renderers` | `Partial>` | Renderers customizados por tipo de componente (opcional) | | `middlewares` | `Middleware[]` | Pila global de middleware | | `externalContext` | `object` | Contexto compartido (usuario, API, etc.) | | `debug` | `object` | Configuración de depuración | @@ -70,9 +71,9 @@ Los componentes deben registrarse usando `createComponentSpec` antes de poder us schepta soporta varios tipos de componentes: - **`field`** - Campos de entrada (texto, select, checkbox, etc.) -- **`container`** - Componentes contenedores (FormField, FormSection, etc.) -- **`content`** - Componentes de contenido (títulos, botones, etc.) -- **`FormContainer`** - Contenedor raíz del formulario +- **`container`** - Componentes contenedores (FormField, FormSection, FormContainer, etc.) +- **`content`** - Componentes de contenido (títulos, etc.) +- **`button`** - Componentes de botón (ej. SubmitButton) ### Creando Especificaciones de Componentes @@ -102,7 +103,7 @@ const components = { InputText: createComponentSpec({ id: 'InputText', type: 'field', - factory: (props, runtime) => InputText, + component: (props, runtime) => InputText, }), }; ``` @@ -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 tus componentes const InputText = React.forwardRef((props, ref) => { @@ -144,67 +145,118 @@ const FormSectionTitle = ({ 'x-content': content, ...props }: any) => { return

{content}

; }; +const FormSectionGroup = ({ children, ...props }: any) => { + return
{children}
; +}; + +const FormSectionGroupContainer = ({ children, ...props }: any) => { + return
{children}
; +}; + const SubmitButton = ({ 'x-content': content, ...props }: any) => { - const { handleSubmit } = useFormContext(); return ( - ); }; -const FormContainer = ({ children, ...props }: any) => { - return
{children}
; +const FormContainer = ({ children, onSubmit, ...props }: any) => { + const adapter = useScheptaFormAdapter(); + const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (onSubmit) adapter.handleSubmit(onSubmit)(); + }; + return ( +
+ {children} +
+ ); }; // Registrar todos los componentes usando 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, }), }; ``` ## Tu Primer Formulario -Ahora vamos a crear un ejemplo completo combinando todo: +Ahora vamos a crear un ejemplo completo combinando todo. + +### Ejemplo Mínimo (Usando los Valores por Defecto) + +FormFactory incluye componentes integrados, así que puedes renderizar un formulario solo con un schema y `onSubmit`—sin registro customizado: + +```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 ( + +
+

Mi Primer Formulario schepta

+ +
+
+ ); +} + +export default App; +``` ### 1. Define tu Schema +Puedes usar `x-component-props` o `x-ui` para etiquetas y placeholders de los campos. La propiedad `$schema` es opcional (útil para validación en el IDE dentro del monorepo). + ```json { - "$schema": "../../packages/factories/src/schemas/form-schema.json", "$id": "my-first-form", "type": "object", "x-component": "FormContainer", @@ -233,7 +285,7 @@ Ahora vamos a crear un ejemplo completo combinando todo: "firstName": { "type": "string", "x-component": "InputText", - "x-ui": { + "x-component-props": { "label": "First Name", "placeholder": "Enter your first name" }, @@ -258,7 +310,7 @@ Ahora vamos a crear un ejemplo completo combinando todo: } ``` -### 2. Ejemplo Completo de React +### 2. Ejemplo Completo de React (Con Componentes Customizados) ```tsx import React from 'react'; @@ -313,5 +365,5 @@ Aprende los conceptos fundamentales que impulsan schepta: ## Recursos +- [Showcase React](/es-ES/showcases/react) - Ejemplos con React Hook Form y Formik - [Repositorio GitHub](https://github.com/guynikan/schepta) - diff --git a/docs/pt-BR/guide/quick-start.md b/docs/pt-BR/guide/quick-start.md index ee76f20..e945ff1 100644 --- a/docs/pt-BR/guide/quick-start.md +++ b/docs/pt-BR/guide/quick-start.md @@ -21,11 +21,10 @@ pnpm add @schepta/core # Instalar adapter e factory React (para projetos React) pnpm add @schepta/adapter-react @schepta/factory-react - -# Instalar React Hook Form (necessário para formulários) -pnpm add react-hook-form ``` +O FormFactory usa estado nativo do React por padrão, então **nenhuma biblioteca de formulário é obrigatória** para o primeiro formulário. Para integrar com React Hook Form ou Formik depois, veja o [Showcase React](/pt-BR/showcases/react). + ## Configurando o Provider O `ScheptaProvider` é o ponto central de configuração da sua aplicação. Ele gerencia registros globais de componentes, middleware e contexto que todas as factories podem acessar. @@ -55,8 +54,10 @@ function App() { ### Props do Provider | Prop | Tipo | Descrição | -|------|------|-----------| -| `components` | `Record` | Registro global de componentes | +|------|------|-------------| +| `components` | `Record` | Registro global de componentes (opcional) | +| `customComponents` | `Record` | Componentes customizados por chave do schema (opcional) | +| `renderers` | `Partial>` | Renderers customizados por tipo de componente (opcional) | | `middlewares` | `Middleware[]` | Stack global de middleware | | `externalContext` | `object` | Contexto compartilhado (usuário, API, etc.) | | `debug` | `object` | Configuração de debug | @@ -70,9 +71,9 @@ Componentes devem ser registrados usando `createComponentSpec` antes de poderem O schepta suporta vários tipos de componentes: - **`field`** - Campos de entrada (texto, select, checkbox, etc.) -- **`container`** - Componentes container (FormField, FormSection, etc.) -- **`content`** - Componentes de conteúdo (títulos, botões, etc.) -- **`FormContainer`** - Container raiz do formulário +- **`container`** - Componentes container (FormField, FormSection, FormContainer, etc.) +- **`content`** - Componentes de conteúdo (títulos, etc.) +- **`button`** - Componentes de botão (ex.: SubmitButton) ### Criando Component Specs @@ -102,7 +103,7 @@ const components = { InputText: createComponentSpec({ id: 'InputText', type: 'field', - factory: (props, runtime) => InputText, + component: (props, runtime) => InputText, }), }; ``` @@ -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'; // Definir seus componentes const InputText = React.forwardRef((props, ref) => { @@ -144,67 +145,118 @@ const FormSectionTitle = ({ 'x-content': content, ...props }: any) => { return

{content}

; }; +const FormSectionGroup = ({ children, ...props }: any) => { + return
{children}
; +}; + +const FormSectionGroupContainer = ({ children, ...props }: any) => { + return
{children}
; +}; + const SubmitButton = ({ 'x-content': content, ...props }: any) => { - const { handleSubmit } = useFormContext(); return ( - ); }; -const FormContainer = ({ children, ...props }: any) => { - return
{children}
; +const FormContainer = ({ children, onSubmit, ...props }: any) => { + const adapter = useScheptaFormAdapter(); + const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (onSubmit) adapter.handleSubmit(onSubmit)(); + }; + return ( +
+ {children} +
+ ); }; // Registrar todos os componentes usando 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, }), }; ``` ## Seu Primeiro Formulário -Agora vamos criar um exemplo completo combinando tudo: +Agora vamos criar um exemplo completo combinando tudo. + +### Exemplo Mínimo (Usando os Padrões) + +O FormFactory já inclui componentes built-in, então você pode renderizar um formulário apenas com um schema e `onSubmit`—sem registro customizado: + +```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('Formulário enviado:', values); + }; + + return ( + +
+

Meu Primeiro Formulário schepta

+ +
+
+ ); +} + +export default App; +``` ### 1. Definir Seu Schema +Você pode usar `x-component-props` ou `x-ui` para rótulos e placeholders dos campos. A propriedade `$schema` é opcional (útil para validação na IDE dentro do monorepo). + ```json { - "$schema": "../../packages/factories/src/schemas/form-schema.json", "$id": "meu-primeiro-formulario", "type": "object", "x-component": "FormContainer", @@ -233,7 +285,7 @@ Agora vamos criar um exemplo completo combinando tudo: "firstName": { "type": "string", "x-component": "InputText", - "x-ui": { + "x-component-props": { "label": "Primeiro Nome", "placeholder": "Digite seu primeiro nome" }, @@ -258,7 +310,7 @@ Agora vamos criar um exemplo completo combinando tudo: } ``` -### 2. Exemplo Completo em React +### 2. Exemplo Completo em React (Com Componentes Customizados) ```tsx import React from 'react'; @@ -294,6 +346,7 @@ function App() { export default App; ``` + ## Próximos Passos Agora que você tem o básico, explore mais: @@ -312,4 +365,5 @@ Aprenda os conceitos fundamentais que impulsionam o schepta: ## Recursos +- [Showcase React](/pt-BR/showcases/react) - Exemplos com React Hook Form e Formik - [Repositório GitHub](https://github.com/guynikan/schepta)