@otl-core/section-registry 1.1.8 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -194
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,196 +1,3 @@
|
|
|
1
1
|
# @otl-core/section-registry
|
|
2
2
|
|
|
3
|
-
Section registry
|
|
4
|
-
system for section components and pages.
|
|
5
|
-
|
|
6
|
-
## Purpose
|
|
7
|
-
|
|
8
|
-
This package contains **ONLY infrastructure** - registry classes, renderers (SectionRenderer,
|
|
9
|
-
PageRenderer). Actual section components (Grid, Flexbox, Spacer) and utilities (SectionWrapper)
|
|
10
|
-
remain in your application code for customization.
|
|
11
|
-
|
|
12
|
-
## SSR Compatibility
|
|
13
|
-
|
|
14
|
-
All components in this package are **server-component safe** and work with Next.js App Router SSR:
|
|
15
|
-
|
|
16
|
-
- No client-only hooks (useState, useEffect, useMemo, etc.)
|
|
17
|
-
- Pure synchronous logic
|
|
18
|
-
- Deterministic rendering
|
|
19
|
-
|
|
20
|
-
Individual section components in your app can be client components if they need interactivity - just
|
|
21
|
-
add `"use client"` at the top of those files.
|
|
22
|
-
|
|
23
|
-
**Important**: If you're using SectionWrapper in your app, make sure it doesn't use `useMemo` or
|
|
24
|
-
other client hooks. Simply call utility functions directly instead of memoizing them.
|
|
25
|
-
|
|
26
|
-
## Installation
|
|
27
|
-
|
|
28
|
-
This package is part of the OTL CMS monorepo and uses workspace protocol:
|
|
29
|
-
|
|
30
|
-
```json
|
|
31
|
-
{
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"@otl-core/section-registry": "workspace:*"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
|
|
40
|
-
### 1. Create a Registry Instance
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
// In your app: src/lib/registries/section-registry.ts
|
|
44
|
-
import { SectionRegistry } from "@otl-core/section-registry";
|
|
45
|
-
import Grid from "@/components/sections/grid";
|
|
46
|
-
import Flexbox from "@/components/sections/flexbox";
|
|
47
|
-
import Spacer from "@/components/sections/spacer";
|
|
48
|
-
|
|
49
|
-
export const sectionRegistry = new SectionRegistry();
|
|
50
|
-
|
|
51
|
-
// Register your sections
|
|
52
|
-
sectionRegistry.register("grid", Grid);
|
|
53
|
-
sectionRegistry.register("flexbox", Flexbox);
|
|
54
|
-
sectionRegistry.register("spacer", Spacer);
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### 2. Use SectionRenderer
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { SectionRenderer } from '@otl-core/section-registry';
|
|
61
|
-
import { sectionRegistry } from '@/lib/registries/section-registry';
|
|
62
|
-
import { blockRegistry } from '@/lib/registries/block-registry';
|
|
63
|
-
|
|
64
|
-
export default function MyPage({ sections }) {
|
|
65
|
-
return (
|
|
66
|
-
<div>
|
|
67
|
-
{sections.map((section) => (
|
|
68
|
-
<SectionRenderer
|
|
69
|
-
key={section.id}
|
|
70
|
-
section={section}
|
|
71
|
-
sectionRegistry={sectionRegistry}
|
|
72
|
-
blockRegistry={blockRegistry} // For sections that render blocks
|
|
73
|
-
siteId="your-site-id"
|
|
74
|
-
/>
|
|
75
|
-
))}
|
|
76
|
-
</div>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### 3. Use PageRenderer
|
|
82
|
-
|
|
83
|
-
For full page rendering:
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
import { PageRenderer } from '@otl-core/section-registry';
|
|
87
|
-
import { sectionRegistry } from '@/lib/registries/section-registry';
|
|
88
|
-
import { blockRegistry } from '@/lib/registries/block-registry';
|
|
89
|
-
|
|
90
|
-
export default function Page({ pageData }) {
|
|
91
|
-
return (
|
|
92
|
-
<PageRenderer
|
|
93
|
-
sections={pageData.sections}
|
|
94
|
-
sectionRegistry={sectionRegistry}
|
|
95
|
-
blockRegistry={blockRegistry}
|
|
96
|
-
siteId="your-site-id"
|
|
97
|
-
/>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### 4. Section Components
|
|
103
|
-
|
|
104
|
-
Your section components receive these props:
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
interface SectionComponentProps {
|
|
108
|
-
config: Record<string, unknown>;
|
|
109
|
-
blockRegistry?: BlockRegistry; // For rendering nested blocks
|
|
110
|
-
siteId?: string; // For form blocks
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export default function Grid({
|
|
114
|
-
config,
|
|
115
|
-
blockRegistry,
|
|
116
|
-
siteId,
|
|
117
|
-
}: SectionComponentProps) {
|
|
118
|
-
// Your section implementation
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## API Reference
|
|
123
|
-
|
|
124
|
-
### SectionRegistry
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
class SectionRegistry<TProps> {
|
|
128
|
-
register(type: string, component: ComponentType<TProps>): void;
|
|
129
|
-
get(type: string): ComponentType<TProps> | undefined;
|
|
130
|
-
has(type: string): boolean;
|
|
131
|
-
getAll(): string[];
|
|
132
|
-
size(): number;
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### SectionRenderer Props
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
interface SectionRendererProps {
|
|
140
|
-
section: SchemaInstance;
|
|
141
|
-
sectionRegistry: SectionRegistry;
|
|
142
|
-
blockRegistry?: BlockRegistry; // Optional, for sections that render blocks
|
|
143
|
-
siteId?: string; // Optional, for form blocks
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### PageRenderer Props
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
interface PageRendererProps {
|
|
151
|
-
sections: SchemaInstance[];
|
|
152
|
-
sectionRegistry: SectionRegistry;
|
|
153
|
-
blockRegistry?: BlockRegistry;
|
|
154
|
-
siteId?: string;
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## SectionWrapper Utility
|
|
159
|
-
|
|
160
|
-
SectionWrapper is **NOT included** in this package - it remains in your application code so you can
|
|
161
|
-
customize it.
|
|
162
|
-
|
|
163
|
-
**SSR Fix Required**: If your SectionWrapper uses `useMemo`, remove it:
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
// BAD - breaks SSR
|
|
167
|
-
const responsiveCSS = useMemo(() => {
|
|
168
|
-
return generateResponsiveSpacingCSS(...);
|
|
169
|
-
}, [deps]);
|
|
170
|
-
|
|
171
|
-
// GOOD - SSR safe
|
|
172
|
-
const responsiveCSS = generateResponsiveSpacingCSS(...);
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
The function call is cheap enough that memoization isn't critical, and this keeps the component
|
|
176
|
-
SSR-compatible.
|
|
177
|
-
|
|
178
|
-
## Error Handling
|
|
179
|
-
|
|
180
|
-
If a section type is not found in the registry, `ComponentNotFound` is rendered, which:
|
|
181
|
-
|
|
182
|
-
- Logs detailed error information in development
|
|
183
|
-
- Logs minimal error in production
|
|
184
|
-
- Renders invisible placeholder to prevent layout breaks
|
|
185
|
-
|
|
186
|
-
## Best Practices
|
|
187
|
-
|
|
188
|
-
1. **Keep components in your app**: Section components and SectionWrapper stay in your application
|
|
189
|
-
2. **Server-first**: Use server components by default, only add `"use client"` when needed
|
|
190
|
-
3. **Pass registries**: Section components that render blocks need `blockRegistry` prop
|
|
191
|
-
4. **No client hooks in SectionWrapper**: Keep utilities SSR-safe
|
|
192
|
-
5. **Type safety**: Import types from this package for consistency
|
|
193
|
-
|
|
194
|
-
## Examples
|
|
195
|
-
|
|
196
|
-
See `frontend/engine/examples/custom-section-example.tsx` for a complete example.
|
|
3
|
+
Section registry and page renderer for [OTL CMS](https://otl.studio). Maps CMS section types to React components and renders full pages.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@otl-core/section-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Section registry and page renderer for OTL CMS",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"url": "https://github.com/otl-core/section-registry.git"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@otl-core/analytics": "^1.1.
|
|
38
|
-
"@otl-core/block-registry": "^1.1.
|
|
39
|
-
"@otl-core/cms-types": "^1.1.
|
|
40
|
-
"@otl-core/cms-utils": "^1.1.
|
|
37
|
+
"@otl-core/analytics": "^1.1.9",
|
|
38
|
+
"@otl-core/block-registry": "^1.1.9",
|
|
39
|
+
"@otl-core/cms-types": "^1.1.9",
|
|
40
|
+
"@otl-core/cms-utils": "^1.1.9"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"react": "
|
|
43
|
+
"react": ">=18.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/react": "^19.0.0",
|