@editora/ui-react

React wrappers, providers, and hooks for @editora/ui-core Web Components.

Overview

@editora/ui-react provides React-native ergonomics on top of Web Components from @editora/ui-core. It includes typed wrappers, hooks for common workflows, and providers for dialogs and theme state.

Installation

npm install @editora/ui-react @editora/ui-core

Peer dependencies: react, react-dom.

Quick Start

import { Button, Input, ThemeProvider } from '@editora/ui-react';

export function App() {
 return (
 <ThemeProvider>
 <div style={{ display: 'grid', gap: 12, maxWidth: 360 }}>
 <Input name="title" label="Title" placeholder="Untitled" clearable />
 <Button variant="primary">Save</Button>
 </div>
 </ThemeProvider>
 );
}

Import Rule

Prefer package-root imports from @editora/ui-react. If you deep-import wrappers directly, ensure @editora/ui-core is imported first so custom elements are registered.

Providers and Hooks

API Type Use Case
ThemeProvider, useTheme Provider + hook Token-based theming and persisted theme state.
DialogProvider, useDialog Provider + hook Promise-based confirm/prompt dialog workflows.
AlertDialogProvider, useAlertDialog Provider + hook Destructive/alert flow confirmations with accessibility defaults.
useForm Hook Validation, submit, dirty-state, reset, and value extraction from wrapped forms.

Common Patterns

1. Form + useForm

import { Form, Field, Input, Button, useForm } from '@editora/ui-react';

export function ProfileForm() {
 const { ref, submit, validate, getValues, reset, isDirty } = useForm();

 return (
 <Form
 ref={ref}
 autosave
 guardUnsaved
 onSubmit={(values) => console.log('submit', values)}
 onInvalid={(errors) => console.log('invalid', errors)}
 >
 <Field label="Full name" required>
 <Input name="fullName" required />
 </Field>

 <Field label="Email" required>
 <Input name="email" type="email" required />
 </Field>

 <Button onClick={() => submit()} disabled={!isDirty()}>Submit</Button>
 <Button variant="secondary" onClick={() => reset()}>Reset</Button>
 <Button variant="secondary" onClick={() => console.log(getValues())}>Values</Button>
 </Form>
 );
}

2. Dialog providers

import { DialogProvider, useDialog, AlertDialogProvider, useAlertDialog, Button } from '@editora/ui-react';

function Actions() {
 const dialog = useDialog();
 const alerts = useAlertDialog();

 return (
 <div style={{ display: 'flex', gap: 8 }}>
 <Button onClick={async () => {
 const res = await dialog.confirm({ title: 'Archive project?' });
 console.log(res);
 }}>Confirm</Button>

 <Button variant="secondary" onClick={async () => {
 const res = await alerts.prompt({ title: 'Rename' });
 console.log(res);
 }}>Prompt</Button>
 </div>
 );
}

export function DialogExample() {
 return (
 <DialogProvider>
 <AlertDialogProvider>
 <Actions />
 </AlertDialogProvider>
 </DialogProvider>
 );
}

3. Data table workflows

import { DataTable, Pagination } from '@editora/ui-react';
import { useState } from 'react';

export function UsersTable() {
 const [page, setPage] = useState(1);

 return (
 <div style={{ display: 'grid', gap: 10 }}>
 <DataTable
 sortable
 selectable
 page={page}
 pageSize={10}
 paginationId="users-pager"
 onPageChange={(d) => setPage(d.page)}
 onSortChange={(d) => console.log('sort', d)}
 onRowSelect={(d) => console.log('rows', d.indices)}
 >
 {/* table markup */}
 </DataTable>

 <Pagination id="users-pager" page={String(page)} />
 </div>
 );
}

4. Gantt planning workspace

Gantt provides an interactive project timeline for release plans, delivery roadmaps, and dependency-heavy schedules. It supports task, summary, and milestone rows; baselines; critical tasks; split segments; dependency links; drag/resize editing; keyboard selection; and virtualized rendering for large plans.

import { Gantt, type GanttLink, type GanttTask } from '@editora/ui-react';
import { useState } from 'react';

const initialTasks: GanttTask[] = [
 {
 id: 'foundation',
 label: 'Foundation build',
 start: '2026-02-01',
 end: '2026-02-18',
 progress: 68,
 baselineStart: '2026-01-29',
 baselineEnd: '2026-02-14',
 critical: true
 },
 {
 id: 'launch',
 label: 'Launch milestone',
 start: '2026-02-28',
 type: 'milestone',
 tone: 'success'
 }
];

const links: GanttLink[] = [
 { id: 'foundation-launch', source: 'foundation', target: 'launch', type: 'e2s' }
];

export function ReleasePlan() {
 const [tasks, setTasks] = useState(initialTasks);

 return (
 <Gantt
 tasks={tasks}
 links={links}
 zoom="week"
 sort="start"
 barVariant="soft"
 onTaskChange={({ id, start, end }) => {
 setTasks((items) => items.map((task) => (
 task.id === id ? { ...task, start: start ?? task.start, end: end ?? task.end } : task
 )));
 }}
 onTaskDelete={({ id }) => setTasks((items) => items.filter((task) => task.id !== id))}
 onLinkSelect={(detail) => console.log('dependency selected', detail)}
 />
 );
}
  • Dependency types: e2s, s2s, e2e, and s2e.
  • Bar variants: solid, soft, striped, outline, and glass.
  • Scale support: automatic row virtualization for large schedules, including the 10,000-task Storybook example.

Component Groups

  • Forms: Form, Field, Input, Textarea, Select, Combobox, Switch, Checkbox, DatePicker, ColorPicker
  • Data: DataTable, Pagination, Table, Calendar, Chart, Timeline, Gantt, Progress
  • Overlay: Dialog, AlertDialog, Popover, Tooltip, Dropdown, Drawer
  • Layout: Layout, Sidebar, Tabs, Grid, Flex, Container, Section

Theming

import { ThemeProvider } from '@editora/ui-react';

<ThemeProvider
 tokens={{
 colors: { primary: '#0f766e', text: '#0f172a', background: '#ffffff' },
 radius: '10px'
 }}
 storageKey="my-app.theme"
>
 {/** app */}
</ThemeProvider>

SSR and StrictMode Notes

  • Providers are SSR-safe and create host nodes on client mount.
  • Promise dialog providers are StrictMode-safe and clean up on unmount.
  • Avoid calling custom element imperative methods until component mount is complete.

Production Guidance

  • Keep root imports from @editora/ui-react to avoid registration drift.
  • Batch expensive state updates around large table operations.
  • Prefer declarative props over direct DOM mutation of wrapped components.

Related Docs