Getting Started
React

React

better-form works with any React setup including Vite, Create React App, and custom configurations.

Installation

npm install @better_form/core

Setup

Vite

1. Import styles in your main entry file:

src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import '@better_form/core/styles';
import App from './App';
import './index.css';
 
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

2. Create your form component:

src/components/ContactForm.tsx
import { WizardProvider, WizardContainer, defaultFieldComponents } from '@better_form/core';
import type { WizardConfig } from '@better_form/core';
 
const config: WizardConfig = {
  id: 'contact-form',
  steps: [
    {
      id: 'step-1',
      title: 'Your Details',
      fieldGroups: [
        {
          id: 'personal',
          fields: [
            {
              id: 'name',
              name: 'name',
              label: 'Full Name',
              type: 'text',
              validation: { required: true },
            },
            {
              id: 'email',
              name: 'email',
              label: 'Email',
              type: 'email',
              validation: { required: true },
            },
          ],
        },
      ],
    },
    {
      id: 'step-2',
      title: 'Message',
      fieldGroups: [
        {
          id: 'message',
          fields: [
            {
              id: 'subject',
              name: 'subject',
              label: 'Subject',
              type: 'text',
            },
            {
              id: 'message',
              name: 'message',
              label: 'Your Message',
              type: 'textarea',
              validation: { required: true },
            },
          ],
        },
      ],
    },
  ],
};
 
export function ContactForm() {
  const handleSubmit = async (data: Record<string, unknown>) => {
    console.log('Form data:', data);
    // Send to your API
  };
 
  return (
    <WizardProvider
      config={config}
      fieldComponents={defaultFieldComponents}
      onSubmit={handleSubmit}
    >
      <WizardContainer />
    </WizardProvider>
  );
}

3. Use in your App:

src/App.tsx
import { ContactForm } from './components/ContactForm';
 
function App() {
  return (
    <div className="container">
      <h1>Contact Us</h1>
      <ContactForm />
    </div>
  );
}
 
export default App;

Multi-Step Form Example

Here's a complete multi-step form example:

src/components/RegistrationForm.tsx
import { WizardProvider, WizardContainer, defaultFieldComponents } from '@better_form/core';
import type { WizardConfig } from '@better_form/core';
 
const registrationConfig: WizardConfig = {
  id: 'registration',
  steps: [
    {
      id: 'account',
      title: 'Account',
      description: 'Create your account credentials',
      fieldGroups: [
        {
          id: 'credentials',
          fields: [
            {
              id: 'email',
              name: 'email',
              label: 'Email Address',
              type: 'email',
              placeholder: 'you@example.com',
              validation: { required: true },
            },
            {
              id: 'password',
              name: 'password',
              label: 'Password',
              type: 'password',
              validation: {
                required: true,
                minLength: 8,
              },
            },
          ],
        },
      ],
    },
    {
      id: 'profile',
      title: 'Profile',
      description: 'Tell us about yourself',
      fieldGroups: [
        {
          id: 'personal',
          fields: [
            {
              id: 'firstName',
              name: 'firstName',
              label: 'First Name',
              type: 'text',
              validation: { required: true },
            },
            {
              id: 'lastName',
              name: 'lastName',
              label: 'Last Name',
              type: 'text',
              validation: { required: true },
            },
            {
              id: 'bio',
              name: 'bio',
              label: 'Bio',
              type: 'textarea',
              placeholder: 'Tell us about yourself...',
            },
          ],
        },
      ],
    },
    {
      id: 'preferences',
      title: 'Preferences',
      description: 'Customize your experience',
      fieldGroups: [
        {
          id: 'settings',
          fields: [
            {
              id: 'newsletter',
              name: 'newsletter',
              label: 'Subscribe to newsletter',
              type: 'checkbox',
            },
            {
              id: 'theme',
              name: 'theme',
              label: 'Preferred Theme',
              type: 'select',
              options: [
                { value: 'light', label: 'Light' },
                { value: 'dark', label: 'Dark' },
                { value: 'system', label: 'System' },
              ],
            },
          ],
        },
      ],
    },
  ],
};
 
export function RegistrationForm() {
  const handleSubmit = async (data: Record<string, unknown>) => {
    // Send registration data to your API
    const response = await fetch('/api/register', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
 
    if (response.ok) {
      // Handle success
      window.location.href = '/dashboard';
    }
  };
 
  return (
    <WizardProvider
      config={registrationConfig}
      fieldComponents={defaultFieldComponents}
      onSubmit={handleSubmit}
    >
      <WizardContainer />
    </WizardProvider>
  );
}

Custom Styling

You can customize the look and feel using CSS variables:

src/index.css
:root {
  --bf-primary: #3b82f6;
  --bf-primary-hover: #2563eb;
  --bf-border-radius: 8px;
  --bf-font-family: 'Inter', sans-serif;
}

See the Styling Guide for more customization options.

With React Router

src/App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { ContactForm } from './components/ContactForm';
import { RegistrationForm } from './components/RegistrationForm';
 
function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/contact" element={<ContactForm />} />
        <Route path="/register" element={<RegistrationForm />} />
      </Routes>
    </BrowserRouter>
  );
}
 
export default App;

Troubleshooting

Module Not Found

Ensure you have the correct import paths:

// Correct
import { WizardProvider } from '@better_form/core';
 
// Incorrect
import { WizardProvider } from '@better_form/core';

Styles Not Appearing

  1. Make sure you import styles before your component CSS
  2. Check that the import path is correct: '@better_form/core/styles'

TypeScript Configuration

For best TypeScript support, ensure your tsconfig.json has:

tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "strict": true
  }
}