Skip to content

Commit 29c368a

Browse files
committed
Refactor component prompt structure to clarify widget categories and contracts
1 parent 753d278 commit 29c368a

File tree

1 file changed

+125
-50
lines changed

1 file changed

+125
-50
lines changed

content/prompts/development/component.prompt.md

Lines changed: 125 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,149 @@
66

77
---
88

9-
## 1. The Widget Protocol
9+
## 1. Component Categories
10+
11+
You will be asked to build components in these 3 standard slots. Refer to `packages/spec` for the complete Zod definitions.
12+
13+
### A. Field Widgets (`field.*`)
14+
Responsible for **Input** (Edit Mode) and **Display** (Read Mode) of a specific data type.
15+
* **Contract:** Must implement `FieldWidgetProps` (Ref: `src/ui/widget.zod.ts`).
16+
```typescript
17+
type FieldWidgetProps<T = any> = {
18+
value: T;
19+
onChange: (val: T) => void;
20+
field: FieldSchema; // Config
21+
readonly?: boolean;
22+
}
23+
```
24+
* **Required Types (Ref: `src/data/field.zod.ts`):**
25+
* **Core:** `text`, `textarea`, `email`, `url`, `phone`, `password`
26+
* **Rich Content:** `markdown`, `html`, `richtext`
27+
* **Numbers:** `number`, `currency`, `percent`
28+
* **Date & Time:** `date`, `datetime`, `time`
29+
* **Logic:** `boolean` (Checkbox/Switch)
30+
* **Selection:** `select` (Dropdown/Radio)
31+
* **Relational:** `lookup` (Searchable Ref), `master_detail`
32+
* **Media:** `image` (Upload/Preview), `file`, `avatar`
33+
* **Calculated:** `formula` (Readonly), `summary`, `autonumber`
34+
* **Enhanced:** `location` (Lat/Long Map), `address`, `code` (Monaco), `color` (Picker), `rating` (Stars), `slider` (Range), `signature` (Pad), `qrcode` (Generator).
35+
36+
### B. List View Layouts (`view.list.*`)
37+
Responsible for rendering a collection of records.
38+
* **Contract:** Must implement `ListViewComponentProps`.
39+
```typescript
40+
type ListViewComponentProps = {
41+
config: ListView; // Config (Ref:src/ui/view.zod.ts)
42+
data: any[]; // Runtime Collection
43+
isLoading?: boolean;
44+
onAction?: (actionId: string, record: any) => void;
45+
onSelectionChange?: (selectedIds: string[]) => void;
46+
}
47+
```
48+
* **Required Types:** `grid` (DataGrid), `kanban` (Drag & Drop), `calendar` (Events), `gantt` (Timeline), `map` (Markers).
49+
50+
### C. Form View Layouts (`view.form.*`)
51+
Responsible for rendering a single record detail.
52+
* **Contract:** Must implement `FormViewComponentProps`.
53+
```typescript
54+
type FormViewComponentProps = {
55+
config: FormView; // Config (Ref:src/ui/view.zod.ts)
56+
data: any; // Single Runtime Record
57+
isLoading?: boolean;
58+
onAction?: (actionId: string, record: any) => void;
59+
onChange?: (field: string, value: any) => void;
60+
}
61+
```
62+
* **Required Types:** `simple` (Sections), `tabbed` (Tabs), `wizard` (Steps).
63+
64+
### D. Dashboard Widgets (`widget.*`)
65+
Standalone cards placed on a dashboard grid.
66+
* **Contract:** Must implement `DashboardWidgetProps` (Ref: `src/ui/dashboard.zod.ts`).
67+
```typescript
68+
type DashboardWidgetProps = {
69+
config: DashboardWidgetSchema; // Config
70+
data?: any; // Runtime Data (optional)
71+
width: number;
72+
height: number;
73+
}
74+
```
75+
* **Required Types (Ref: `src/ui/dashboard.zod.ts`):**
76+
* **Charts:** `metric` (KPI), `bar`, `line`, `pie`, `donut`, `funnel`.
77+
* **Content:** `table` (Data List), `text` (Rich Text/Markdown).
1078
11-
Widgets are the atomic building blocks of ObjectUI. They render specific `FieldTypes` or `ViewComponents`.
12-
13-
**Reference:** `@objectstack/spec` -> `dist/ui/widget.zod.d.ts`
14-
15-
## 2. Widget Registration
16-
17-
You must register the component map so the Server-Driven UI engine knows what to render.
18-
19-
```typescript
20-
// src/components/registry.ts
21-
import { RatingField } from './RatingField';
22-
import { KanbanBoard } from './KanbanBoard';
23-
24-
export const widgetRegistry = {
25-
// Field Widgets (Input/Display)
26-
'field.rating': RatingField,
27-
28-
// View Widgets (Layouts)
29-
'view.kanban': KanbanBoard
30-
};
31-
```
79+
---
3280
33-
## 3. The Component Contract
81+
## 2. API Reference & Contracts
3482
35-
All field widgets receive a standard set of props.
83+
### A. Field Widget Implementation
84+
**Reference:** `@objectstack/spec` -> `dist/ui/widget.zod.d.ts`
3685
3786
```typescript
38-
import { FieldSchema } from '@objectstack/spec/data';
39-
40-
interface FieldWidgetProps<T = any> {
41-
// Data
42-
value: T;
43-
onChange: (newValue: T) => void;
44-
45-
// Metadata
46-
field: FieldSchema; // The Zod definition
47-
mode: 'read' | 'edit';
48-
errorMessage?: string;
49-
50-
// Context
51-
objectName: string;
52-
recordId?: string;
53-
}
54-
```
55-
56-
### Example: Rating Star Widget
57-
```tsx
58-
export function RatingField({ value, onChange, mode, field }: FieldWidgetProps<number>) {
59-
const max = field.scale || 5;
87+
import { FieldWidgetProps } from '@objectstack/spec/ui';
88+
89+
export function RatingField({
90+
value,
91+
onChange,
92+
field,
93+
mode
94+
}: FieldWidgetProps<number>) {
6095

6196
if (mode === 'read') {
62-
return <div>{''.repeat(value)}</div>;
97+
return <span>{''.repeat(value || 0)}</span>;
6398
}
6499

65100
return (
66101
<div className="flex gap-1">
67-
{Array.from({ length: max }).map((_, i) => (
68-
<button key={i} onClick={() => onChange(i + 1)}>
69-
{i < value ? '' : ''}
102+
{[1, 2, 3, 4, 5].map((star) => (
103+
<button
104+
key={star}
105+
onClick={() => onChange(star)}
106+
className={star <= value ? 'text-yellow-500' : 'text-gray-300'}
107+
>
108+
70109
</button>
71110
))}
72111
</div>
73112
);
74113
}
75114
```
76115

116+
### B. Dashboard Widget Implementation
117+
**Reference:** `@objectstack/spec` -> `dist/ui/dashboard.zod.d.ts`
118+
119+
```typescript
120+
import { DashboardWidgetProps } from '@objectstack/spec/ui';
121+
122+
export function WelcomeCard({ config, user }: DashboardWidgetProps) {
123+
return (
124+
<div className="card p-4 bg-blue-50">
125+
<h3>Hello, {user.name}!</h3>
126+
<p>{config.welcomeMessage || 'Have a great day.'}</p>
127+
</div>
128+
);
129+
}
130+
```
131+
132+
---
133+
134+
## 3. Widget Registration
135+
136+
You must register the component map so the Server-Driven UI engine knows what to render.
137+
138+
```typescript
139+
// src/components/registry.ts
140+
import { RatingField } from './RatingField';
141+
import { WelcomeCard } from './WelcomeCard';
142+
143+
export const widgetRegistry = {
144+
// Field Widgets (Maps to FieldType or Custom 'widget' property)
145+
'field.rating': RatingField,
146+
147+
// Dashboard Widgets (Maps to widget 'type')
148+
'widget.welcome_card': WelcomeCard
149+
};
150+
```
151+
77152
## 4. Key Directives for AI
78153

79154
* **Statelessness:** Widgets should rely on `props.value` and `props.onChange`. Avoid internal state unless necessary for transient UI interactions (like hover).

0 commit comments

Comments
 (0)