diff --git a/content/docs/guide/plugin-development.md b/content/docs/guide/plugin-development.md index 4de811c8b5..4b29340e55 100644 --- a/content/docs/guide/plugin-development.md +++ b/content/docs/guide/plugin-development.md @@ -95,6 +95,7 @@ export interface BoardProps { ### 2. Build the Implementation + ```tsx // src/BoardImpl.tsx import React from 'react'; @@ -133,6 +134,7 @@ export default function BoardImpl({ schema, className }: BoardProps) { ### 3. Create the Entry Point + ```tsx // src/index.tsx import React, { Suspense } from 'react'; @@ -180,6 +182,8 @@ Field widgets follow the `FieldWidgetComponentProps` interface from `@object-ui/ ```typescript // FieldWidgetComponentProps shape (from packages/fields/src/widgets/types.ts) +import type { FieldMetadata } from '@object-ui/types'; + type FieldWidgetComponentProps = { value: T; onChange: (val: T) => void; @@ -209,6 +213,7 @@ grids, reports). That is precisely why a **field widget** needs an adapter when it is rendered from a schema node instead of from a form. Wrap it once, at registration, and the widget only ever implements one contract: + ```tsx import { ComponentRegistry } from '@object-ui/core'; import { withFieldCarrier } from '@object-ui/fields'; @@ -292,6 +297,7 @@ export function ColorPickerField({ Register it as a field widget: + ```tsx // src/index.tsx import { ComponentRegistry } from '@object-ui/core'; @@ -317,6 +323,7 @@ export { ColorPickerField }; Namespaces prevent type collisions between plugins: + ```tsx import { ComponentRegistry } from '@object-ui/core'; @@ -337,6 +344,8 @@ Use `skipFallback: true` in the metadata if you do **not** want the component to ### Querying Registered Components ```tsx +import { ComponentRegistry } from '@object-ui/core'; + ComponentRegistry.has('board'); // boolean ComponentRegistry.getAllTypes(); // string[] ComponentRegistry.getNamespaceComponents('plugin-board'); // ComponentConfig[] @@ -346,6 +355,7 @@ ComponentRegistry.getNamespaceComponents('plugin-board'); // ComponentConfig Define your schema interface in `types.ts` and extend `BaseSchema`: + ```typescript import type { BaseSchema } from '@object-ui/types'; @@ -358,6 +368,7 @@ export interface BoardSchema extends BaseSchema { Declare `ComponentInput` entries when registering so the visual designer can offer a property panel: + ```tsx ComponentRegistry.register('board', BoardRenderer, { inputs: [ @@ -378,10 +389,14 @@ ComponentRegistry.register('board', BoardRenderer, { ObjectUI uses **Vitest + React Testing Library**. Place tests next to the implementation. + ```tsx // src/BoardImpl.test.tsx import { describe, it, expect } from 'vitest'; import { render, screen } from '@testing-library/react'; +// `toBeInTheDocument` is a jest-dom matcher, not a Vitest one — without this +// import the assertions below do not type-check and do not run. +import '@testing-library/jest-dom'; import BoardImpl from './BoardImpl'; const schema = { @@ -458,6 +473,7 @@ npm publish --access public pnpm add @object-ui/plugin-board ``` + ```tsx // app/main.tsx — import once, auto-registers import '@object-ui/plugin-board'; diff --git a/content/docs/guide/schema-rendering.md b/content/docs/guide/schema-rendering.md index 33f4bacb07..c273d987ae 100644 --- a/content/docs/guide/schema-rendering.md +++ b/content/docs/guide/schema-rendering.md @@ -31,7 +31,7 @@ function App() { const schema = { type: "page", title: "My Dashboard", - body: { /* ... */ } + body: { type: "text", value: "Hello" } } return @@ -43,6 +43,8 @@ function App() { Every schema object must have at minimum a `type` field: ```typescript +import type { CSSProperties } from 'react' + interface BaseSchema { type: string // Component type identifier id?: string // Optional unique identifier @@ -74,6 +76,7 @@ interface BaseSchema { The `SchemaRenderer` accepts a `data` prop that provides context for expressions: + ```tsx const data = { user: { name: "John", role: "admin" }, @@ -98,6 +101,7 @@ Use expression syntax `${}` to reference data: The schema renderer uses a component registry to map schema types to React components: + ```tsx import { ComponentRegistry } from '@object-ui/core' @@ -212,6 +216,7 @@ Object UI includes a powerful expression system for dynamic behavior: Components can emit events that you handle in React: + ```tsx ```tsx import { lazy } from 'react' @@ -275,6 +281,7 @@ registry.register('heavy-chart', HeavyChart) The renderer includes built-in error boundaries: + ```tsx ```tsx // ✅ Good const data = { @@ -345,6 +353,7 @@ const data = { Move logic to expressions instead of creating conditional schemas: + ```tsx // ❌ Bad const schema = user.isAdmin ? adminSchema : userSchema diff --git a/content/docs/guide/theming.md b/content/docs/guide/theming.md index 2466055583..a3e026bca0 100644 --- a/content/docs/guide/theming.md +++ b/content/docs/guide/theming.md @@ -55,6 +55,7 @@ ObjectUI follows the Shadcn convention. Design tokens are defined as HSL channel Components reference these tokens through Tailwind: + ```tsx