View Package

The @repo/view package provides a schema-driven approach to building UI components with integrated CRUD functionality, internationalization support, and error handling. It enables developers to define complex UI components using JSON schemas, with full type safety and validation.

Features

  • Schema-Driven Views: Define your UI components using JSON schemas
  • Type Safety: Enhanced type definitions for different view types
  • Validation: Zod-based schema validation to ensure compatibility with CRUD components
  • Internationalization: Built-in support for multiple languages
  • Error Handling: Comprehensive error handling with custom error boundaries
  • Persistence: Storage providers for both client and server-side persistence
  • Extensible: Plugin system for custom field types and renderers

Installation

This package is part of the zopio monorepo and is available to all applications in the workspace.

# If you're adding it to a new package in the monorepo
pnpm add @repo/view

Package Structure

The View package is organized into several subpackages:

  • Engine: Core view rendering functionality
  • Hooks: React hooks for view operations
  • Service: Storage and persistence for view schemas
  • i18n: Internationalization support
  • Schema: Schema definitions and validation
  • Types: TypeScript type definitions

Dependencies

The View package depends on the following packages:

  • @repo/crud: For CRUD operations and UI components
  • @repo/design-system: For UI components
  • next-intl: Internationalization support
  • zod: Schema validation

Basic Usage

Rendering a View

import { renderView, ViewSchema } from '@repo/view';

// Define a form view schema
const formSchema: ViewSchema = {
  id: 'user-form',
  type: 'form',
  schema: 'user',
  fields: {
    name: {
      label: 'Name',
      type: 'string',
      required: true
    },
    email: {
      label: 'Email',
      type: 'string',
      required: true
    }
  }
};

// Render the view
function UserForm() {
  return renderView(formSchema, {
    onSubmit: (data) => {
      console.log('Form submitted:', data);
    }
  });
}

Using View Hooks

import { useView } from '@repo/view/hooks';

function UserFormContainer() {
  const { view, loading, error } = useView('user-form');
  
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!view) return <div>View not found</div>;
  
  return renderView(view, {
    onSubmit: (data) => {
      console.log('Form submitted:', data);
    }
  });
}

Persisting View Schemas

import { initViewService, saveView, getView } from '@repo/view/service';

// Initialize with local storage
initViewService({ type: 'local', storagePrefix: 'my-app' });

// Save a view schema
await saveView('my-view', myViewSchema);

// Get a view schema
const viewSchema = await getView('my-view');

View Types

The package supports the following view types:

  • Form: For creating and editing data
  • Table: For displaying tabular data
  • Detail: For displaying detailed information about a record
  • Audit Log: For displaying audit logs
  • Import: For importing data
  • Export: For exporting data
  • Dashboard: For displaying multiple views in a dashboard layout
  • Wizard: For multi-step forms and processes

Internationalization

The View package supports internationalization using next-intl:

import { useViewTranslations } from '@repo/view/i18n';

function MyComponent() {
  const t = useViewTranslations('view');
  
  return (
    <div>
      <h1>{t('common.title')}</h1>
      <p>{t('common.description')}</p>
    </div>
  );
}

Supported Locales

  • English (en)
  • Turkish (tr)
  • Spanish (es)
  • German (de)

Error Handling

The package includes a comprehensive error handling system:

import { ViewErrorBoundary } from '@repo/view/engine/error';

function MyComponent() {
  return (
    <ViewErrorBoundary fallback={(error) => <div>Custom error UI: {error.message}</div>}>
      {/* Your view components */}
    </ViewErrorBoundary>
  );
}

Integration with View Builder

The View package is designed to work seamlessly with the View Builder package, which provides a visual interface for creating and editing view schemas:

import { ViewBuilder } from '@repo/view-builder';
import { renderView } from '@repo/view';
import { useState } from 'react';

function ViewBuilderWithPreview() {
  const [schema, setSchema] = useState(null);
  
  const handleSchemaChange = (newSchema) => {
    setSchema(newSchema);
  };
  
  return (
    <div className="grid grid-cols-2 gap-4 h-screen">
      <div>
        <ViewBuilder onChange={handleSchemaChange} />
      </div>
      <div className="border p-4 rounded-md">
        {schema && renderView(schema)}
      </div>
    </div>
  );
}

Detailed Documentation

For more detailed information on using the View package, see the following pages:

Core Concepts

View Schema

The View Schema is the core concept of the package, defining the structure and behavior of UI components:

interface ViewSchema {
  /** Unique identifier for the view */
  id: string;
  /** Type of view (form, table, detail, etc.) */
  type: ViewType;
  /** Schema name for CRUD operations */
  schema: string;
  /** Fields to display in the view */
  fields?: Record<string, FieldDefinition>;
  /** Layout configuration */
  layout?: LayoutConfiguration;
  /** Internationalization namespace */
  i18nNamespace?: string;
  /** Additional configuration options */
  options?: Record<string, unknown>;
}

View Engine

The View Engine is responsible for rendering views based on schemas and handling interactions:

interface ViewEngineOptions {
  /** Default locale for internationalization */
  defaultLocale?: string;
  /** Supported locales for internationalization */
  supportedLocales?: string[];
  /** Storage provider for view schemas */
  storageProvider?: StorageProvider;
}

View Designer

The View Designer provides a visual interface for creating and editing view schemas:

interface ViewDesignerProps {
  /** Current schema value */
  value: ViewSchema;
  /** Callback when schema changes */
  onChange: (schema: ViewSchema) => void;
  /** Available schemas for CRUD operations */
  availableSchemas?: string[];
  /** Additional options */
  options?: ViewDesignerOptions;
}

API Reference

Components

  • renderView(schema, options): Renders a view based on the provided schema
  • ViewErrorBoundary: Error boundary component for catching and displaying view rendering errors
  • ViewDesigner: Component for visually designing view schemas
  • ViewDesignerForm: Form component for editing view schemas

Hooks

  • useViewTranslations(namespace): Hook for accessing translations
  • useViewSchema(id): Hook for fetching a view schema by ID

Functions

  • validateViewSchema(schema): Validates a view schema
  • safeValidateViewSchema(schema): Safely validates a view schema (doesn’t throw errors)
  • initViewService(options): Initializes the view service with storage options
  • saveView(id, schema): Saves a view schema
  • getView(id): Gets a view schema by ID
  • listViews(): Lists all available view schemas
  • deleteView(id): Deletes a view schema