asasvirtuais
v3.0.0
Published
React form and action management utilities - v3 Monorepo Edition
Readme
asasvirtuais
React form and action management utilities for building data-driven applications.
Installation
From npm
npm install asasvirtuaisFrom esm.sh
import { Form } from 'https://esm.sh/[email protected]/forms'
import { useFields } from 'https://esm.sh/[email protected]/fields'
import { useAction } from 'https://esm.sh/[email protected]/action'Quick Start: Forms
Simple Form
import { Form } from 'asasvirtuais/forms'
type LoginFields = {
email: string
password: string
}
type LoginResult = {
token: string
}
async function loginAction(fields: LoginFields): Promise<LoginResult> {
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify(fields)
})
return response.json()
}
function LoginForm() {
return (
<Form<LoginFields, LoginResult>
defaults={{ email: '', password: '' }}
action={loginAction}
>
{({ fields, setField, submit, loading, error }) => (
<form onSubmit={submit}>
<input
type="email"
value={fields.email}
onChange={(e) => setField('email', e.target.value)}
/>
<input
type="password"
value={fields.password}
onChange={(e) => setField('password', e.target.value)}
/>
<button type="submit" disabled={loading}>
{loading ? 'Logging in...' : 'Login'}
</button>
{error && <p>Error: {error.message}</p>}
</form>
)}
</Form>
)
}Core Modules
1. asasvirtuais/forms
Self-contained form nodes that manage state and actions. Nest forms to create complex workflows.
2. asasvirtuais/interface
Components and hooks for data-driven React apps.
Sub-modules:
asasvirtuais/interface: Main React CRUD components.asasvirtuais/interface/indexed: IndexedDB storage via Dexie.asasvirtuais/fetch-interface: REST API adapter.asasvirtuais/yaml-interface: Local flat-file adapter.
Todo App Example
1. Define Schema
import { z } from 'zod';
export const todoSchema = {
readable: z.object({
id: z.string(),
text: z.string(),
completed: z.boolean(),
}),
writable: z.object({
text: z.string(),
completed: z.boolean().optional(),
}),
}2. Provide Context
import { FetchInterfaceProvider } from 'asasvirtuais/fetch-interface'
import { TableProvider } from 'asasvirtuais/interface'
import { todoSchema } from './database'
export default function RootLayout({ children }) {
return (
<FetchInterfaceProvider schema={todoSchema} baseUrl='/api/v1'>
<TableProvider table='todos' schema={todoSchema} interface={useInterface()}>
{children}
</TableProvider>
</FetchInterfaceProvider>
)
}3. Build UI
'use client'
import { useTable, CreateForm } from 'asasvirtuais/interface'
import { todoSchema } from '@/app/database'
function TodoList() {
const { array, remove } = useTable('todos', todoSchema)
return (
<>
<CreateForm table="todos" schema={todoSchema} defaults={{ text: '' }}>
{({ fields, setField, submit }) => (
<form onSubmit={submit}>
<input
value={fields.text}
onChange={(e) => setField('text', e.target.value)}
/>
<button type="submit">Add Todo</button>
</form>
)}
</CreateForm>
<ul>
{array.map(todo => (
<li key={todo.id}>
{todo.text}
<button onClick={() => remove.trigger({ id: todo.id })}>Delete</button>
</li>
))}
</ul>
</>
)
}Model Package Path
A model package is a self-contained module for a specific data model.
Structure
packages/[model-name]/
├── index.ts # Schema + types
├── fields.tsx # Form fields
├── forms.tsx # CRUD forms
├── provider.tsx # Context + hooks
└── components.tsx # Display components