@otl-core/section-registry 1.1.7 → 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.
Files changed (2) hide show
  1. package/README.md +1 -194
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -1,196 +1,3 @@
1
1
  # @otl-core/section-registry
2
2
 
3
- Section registry infrastructure for OTL CMS. This package provides the core registry and rendering
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.7",
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.7",
38
- "@otl-core/block-registry": "^1.1.7",
39
- "@otl-core/cms-types": "^1.1.7",
40
- "@otl-core/cms-utils": "^1.1.7"
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": "^18.0.0"
43
+ "react": ">=18.0.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/react": "^19.0.0",