Skip to content

Commit 4881f0c

Browse files
committed
feat: enhance PageRenderer to support regions and legacy body rendering
1 parent 28ae2ec commit 4881f0c

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
import { describe, it, expect } from 'vitest';
3+
import { render, screen } from '@testing-library/react';
4+
import React from 'react';
5+
import { PageRenderer } from '../renderers/layout/page'; // Direct import to test logic
6+
import { ComponentRegistry } from '@object-ui/core';
7+
8+
// Mock SchemaRenderer to verify it's called
9+
import { SchemaRenderer } from '@object-ui/react';
10+
import { vi } from 'vitest';
11+
12+
// Mock the SchemaRenderer to avoid full tree recursion deps
13+
vi.mock('@object-ui/react', () => ({
14+
SchemaRenderer: ({ schema }: any) => <div data-testid="child-node">{schema.type}:{schema.value || schema.name}</div>
15+
}));
16+
17+
describe('PageRenderer Regions', () => {
18+
it('should render components from regions', () => {
19+
const schema: any = {
20+
type: 'page',
21+
title: 'Test Page',
22+
regions: [
23+
{
24+
name: 'main',
25+
components: [
26+
{ type: 'text', value: 'Region Content 1' },
27+
{ type: 'button', label: 'Region Button' }
28+
]
29+
}
30+
]
31+
};
32+
33+
render(<PageRenderer schema={schema} />);
34+
35+
// Check if title is rendered
36+
expect(screen.getByText('Test Page')).toBeDefined();
37+
38+
// Check real content (since mock didn't take effect, we verify real render)
39+
// The text component renders the value directly
40+
expect(screen.getByText('Region Content 1')).toBeDefined();
41+
42+
// The button component renders the label
43+
expect(screen.getByText('Region Button')).toBeDefined();
44+
});
45+
46+
it('should render legacy body', () => {
47+
const schema: any = {
48+
type: 'page',
49+
title: 'Legacy Page',
50+
body: [
51+
{ type: 'text', value: 'Body Content' }
52+
]
53+
};
54+
55+
render(<PageRenderer schema={schema} />);
56+
57+
expect(screen.getByText('Body Content')).toBeDefined();
58+
});
59+
});

packages/components/src/renderers/layout/page.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,18 @@ export const PageRenderer: React.FC<{ schema: PageSchema; className?: string; [k
1717
className,
1818
...props
1919
}) => {
20-
// Support both body (legacy/playground) and children
21-
const content = schema.body || schema.children;
22-
const nodes = Array.isArray(content) ? content : (content ? [content] : []);
20+
// Support regions (spec compliant), body (legacy), and children
21+
let nodes: any[] = [];
22+
23+
if (schema.regions && schema.regions.length > 0) {
24+
// If regions are present, flatten their components into the main flow
25+
// Ideally, we might want a grid layout here, but linear stacking works for simple single-region pages
26+
nodes = schema.regions.flatMap(r => r.components || []);
27+
} else {
28+
// Fallback to direct children/body
29+
const content = schema.body || schema.children;
30+
nodes = Array.isArray(content) ? content : (content ? [content] : []);
31+
}
2332

2433
// Extract designer-related props
2534
const {
@@ -68,7 +77,7 @@ export const PageRenderer: React.FC<{ schema: PageSchema; className?: string; [k
6877
);
6978
};
7079

71-
const pageMeta = {
80+
const pageMeta: any = {
7281
namespace: 'ui',
7382
label: 'Page',
7483
icon: 'Layout',
@@ -80,7 +89,6 @@ const pageMeta = {
8089
name: 'body',
8190
type: 'array',
8291
label: 'Content',
83-
// @ts-expect-error - itemType is experimental/extended metadata
8492
itemType: 'component'
8593
}
8694
]

0 commit comments

Comments
 (0)