Skip to main content

React DOM Component Kit

Build performant, accessible web applications with @boodoo/react (boodoo/react). Pure React components designed specifically for web and Next.js, featuring zero DOM-hijacking scripts, native semantic HTML elements, accessible form fields, expandable tables, and scoped CSS layer integration.

Pure DOM Components

Zero React Native primitives on web. Direct semantic rendering into <button>, <dialog>, <table>, and <input>.

Scoped CSS & Host Theming

Ships under @layer boodoo and .boodoo namespace without reboot resets, avoiding style leaks into host apps.

Multi-Platform Parity

Shares identical component names and prop mental models with boodoo/react-native for seamless cross-platform teams.


1. Installation & Setup

Install Boodoo and peer dependencies into your React 18+ or Next.js 14+ project:

npm install boodoo react react-dom

Import the scoped React stylesheet in your application root (e.g. app/layout.tsx, src/main.jsx, or _app.tsx):

import 'boodoo/css/react';
// Or if you want the full global utility classes:
// import 'boodoo/css';

2. BoodooProvider & Density

Wrap your application root with BoodooProvider to control themes and UI density:

import { BoodooProvider, Button } from 'boodoo/react';

export default function App() {
  return (
    <BoodooProvider theme="auto" density="compact">
      <div className="p-4">
        <Button variant="primary">Compact Theme Button</Button>
      </div>
    </BoodooProvider>
  );
}

3. Accessible Form Controls (`Field`)

The Field wrapper automatically wires id, htmlFor, aria-describedby, and aria-invalid down to form inputs:

import { Field, Input, Select } from 'boodoo/react';

export function UserForm() {
  return (
    <form className="d-flex flex-column gap-3 max-w-md">
      <Field
        label="Work Email"
        required
        description="We will send your verification token here."
        learnMore="We respect your privacy. No marketing emails without consent."
      >
        <Input type="email" placeholder="alex@company.com" />
      </Field>

      <Field label="Account Role">
        <Select
          options={[
            { label: 'Administrator', value: 'admin' },
            { label: 'Editor', value: 'editor' },
            { label: 'Viewer', value: 'viewer' },
          ]}
        />
      </Field>
    </form>
  );
}

4. Combobox with Accent-Folding

Keyboard-accessible autocomplete with fuzzy search and subtitle metadata:

import { Combobox } from 'boodoo/react';

const users = [
  { label: 'René Descartes', value: 'rene', meta: 'Philosophy / Paris' },
  { label: 'Søren Kierkegaard', value: 'soren', meta: 'Theology / Copenhagen' },
  { label: 'Ada Lovelace', value: 'ada', meta: 'Computing / London' },
];

export function UserSearch() {
  return (
    <Combobox
      items={users}
      placeholder="Search philosopher (try 'Rene' or 'Soren')..."
      onChange={(val) => console.log('Selected:', val)}
    />
  );
}

5. Controlled Data Table

Sort columns and expand rows declaratively without DOM manipulation:

import { useState } from 'react';
import { Table, Badge } from 'boodoo/react';

const columns = [
  { key: 'name', title: 'Service Name', sortable: true },
  {
    key: 'status',
    title: 'Health',
    render: (val) => (
      <Badge variant={val === 'active' ? 'success' : 'warning'}>
        {val}
      </Badge>
    ),
  },
  { key: 'latency', title: 'Latency (ms)', sortable: true },
];

const data = [
  { id: '1', name: 'API Gateway', status: 'active', latency: 42, details: 'v2.4.1 deployed in us-east-1' },
  { id: '2', name: 'Auth Service', status: 'active', latency: 19, details: 'Session cache warm, 0 failures' },
];

export function MetricsTable() {
  const [sortCol, setSortCol] = useState('name');
  const [sortDir, setSortDir] = useState('asc');
  const [expanded, setExpanded] = useState(['1']);

  return (
    <Table
      columns={columns}
      data={data}
      keyField="id"
      sortColumn={sortCol}
      sortDirection={sortDir}
      onSort={(key, dir) => {
        setSortCol(key);
        setSortDir(dir);
      }}
      expandedKeys={expanded}
      expandedRowRender={(row) => (
        <div className="p-3 bg-light rounded text-muted fs-7">
          <strong>Telemetry Details:</strong> {row.details}
        </div>
      )}
    />
  );
}

6. Action Barrier ConfirmDialog

Prevent destructive accidents by requiring matching confirmation strings:

import { useState } from 'react';
import { ConfirmDialog, Button } from 'boodoo/react';

export function ProjectSettings() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <Button variant="danger" onClick={() => setIsOpen(true)}>
        Delete Workspace
      </Button>

      <ConfirmDialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        onConfirm={() => {
          console.log('Deleted workspace');
          setIsOpen(false);
        }}
        title="Delete Workspace"
        message="This action is irreversible. All associated metrics, API keys, and databases will be purged."
        mustMatch="DELETE WORKSPACE"
        confirmLabel="Permanently Delete"
      />
    </>
  );
}