Skip to content

OneGenUi/onegenui-react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@onegenui/react

Predictable. Guardrailed. Fast. React renderer for user-prompted dashboards, widgets, apps, and data visualizations.

Features

  • Visibility Filtering: Components automatically show/hide based on visibility conditions
  • Action Handling: Built-in action execution with confirmation dialogs
  • Validation: Field validation with error display
  • Data Binding: Two-way data binding between UI and data model
  • Streaming: Progressive rendering from streamed UI trees

Installation

npm install @onegenui/react @onegenui/core
# or
pnpm add @onegenui/react @onegenui/core

Quick Start

Basic Setup

import { JSONUIProvider, Renderer, useUIStream } from '@onegenui/react';

// Define your component registry
const registry = {
  Card: ({ element, children }) => (
    <div className="card">
      <h3>{element.props.title}</h3>
      {children}
    </div>
  ),
  Button: ({ element, onAction }) => (
    <button onClick={() => onAction?.(element.props.action)}>
      {element.props.label}
    </button>
  ),
};

// Action handlers
const actionHandlers = {
  submit: async (params) => {
    await api.submit(params);
  },
  export: (params) => {
    download(params.format);
  },
};

function App() {
  const { tree, isStreaming, send, clear } = useUIStream({
    api: '/api/generate',
  });

  return (
    <JSONUIProvider
      registry={registry}
      initialData={{ user: { name: 'John' } }}
      authState={{ isSignedIn: true }}
      actionHandlers={actionHandlers}
    >
      <input
        placeholder="Describe the UI..."
        onKeyDown={(e) => e.key === 'Enter' && send(e.target.value)}
      />
      <Renderer tree={tree} registry={registry} loading={isStreaming} />
    </JSONUIProvider>
  );
}

Using Contexts Directly

import {
  DataProvider,
  VisibilityProvider,
  ActionProvider,
  ValidationProvider,
  useData,
  useVisibility,
  useActions,
  useFieldValidation,
} from '@onegenui/react';

// Data context
function MyComponent() {
  const { data, get, set } = useData();
  const value = get('/user/name');
  
  return (
    <input
      value={value}
      onChange={(e) => set('/user/name', e.target.value)}
    />
  );
}

// Visibility context
function ConditionalComponent({ visible }) {
  const { isVisible } = useVisibility();
  
  if (!isVisible(visible)) {
    return null;
  }
  
  return <div>Visible content</div>;
}

// Action context
function ActionButton({ action }) {
  const { execute, loadingActions } = useActions();
  
  return (
    <button
      onClick={() => execute(action)}
      disabled={loadingActions.has(action.name)}
    >
      {action.name}
    </button>
  );
}

// Validation context
function ValidatedInput({ path, checks }) {
  const { errors, validate, touch } = useFieldValidation(path, { checks });
  const [value, setValue] = useDataBinding(path);
  
  return (
    <div>
      <input
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onBlur={() => { touch(); validate(); }}
      />
      {errors.map((err) => <span key={err}>{err}</span>)}
    </div>
  );
}

Streaming UI

import { useUIStream } from '@onegenui/react';

function StreamingDemo() {
  const {
    tree,        // Current UI tree
    isStreaming, // Whether currently streaming
    error,       // Error if any
    send,        // Send a prompt
    clear,       // Clear the tree
  } = useUIStream({
    api: '/api/generate',
    onComplete: (tree) => console.log('Done:', tree),
    onError: (err) => console.error('Error:', err),
  });

  return (
    <div>
      <button onClick={() => send('Create a dashboard')}>
        Generate
      </button>
      {isStreaming && <span>Generating...</span>}
      {tree && <Renderer tree={tree} registry={registry} />}
    </div>
  );
}

API Reference

Providers

  • JSONUIProvider - Combined provider for all contexts
  • DataProvider - Data model context
  • VisibilityProvider - Visibility evaluation context
  • ActionProvider - Action execution context
  • ValidationProvider - Validation context

Hooks

  • useData() - Access data model
  • useDataValue(path) - Get a single value
  • useDataBinding(path) - Two-way binding like useState
  • useVisibility() - Access visibility evaluation
  • useIsVisible(condition) - Check if condition is visible
  • useActions() - Access action execution
  • useAction(action) - Execute a specific action
  • useValidation() - Access validation context
  • useFieldValidation(path, config) - Field-level validation

Components

  • Renderer - Render a UI tree
  • ConfirmDialog - Default confirmation dialog

Utilities

  • useUIStream(options) - Hook for streaming UI generation
  • flatToTree(elements) - Convert flat list to tree

Component Props

Components in your registry receive these props:

interface ComponentRenderProps<P = Record<string, unknown>> {
  element: UIElement<string, P>;  // The element definition
  children?: ReactNode;           // Rendered children
  onAction?: (action: Action) => void;  // Action callback
  loading?: boolean;              // Streaming in progress
}

Example Component

function MetricComponent({ element }: ComponentRenderProps) {
  const { label, valuePath, format } = element.props;
  const value = useDataValue(valuePath);
  
  const formatted = format === 'currency'
    ? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value)
    : String(value);
  
  return (
    <div className="metric">
      <span className="label">{label}</span>
      <span className="value">{formatted}</span>
    </div>
  );
}

About

React renderer, hooks, contexts, and streaming for OneGenUI

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors