@json-render/image 0.1.0
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/LICENSE +201 -0
- package/README.md +167 -0
- package/dist/catalog.d.mts +265 -0
- package/dist/catalog.d.ts +265 -0
- package/dist/catalog.js +207 -0
- package/dist/catalog.js.map +1 -0
- package/dist/catalog.mjs +7 -0
- package/dist/catalog.mjs.map +1 -0
- package/dist/chunk-A67OT34V.mjs +41 -0
- package/dist/chunk-A67OT34V.mjs.map +1 -0
- package/dist/chunk-KQSKKHJA.mjs +348 -0
- package/dist/chunk-KQSKKHJA.mjs.map +1 -0
- package/dist/chunk-PMEELRVP.mjs +183 -0
- package/dist/chunk-PMEELRVP.mjs.map +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +600 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +19 -0
- package/dist/index.mjs.map +1 -0
- package/dist/render-DyXCSaYW.d.mts +40 -0
- package/dist/render-DyXCSaYW.d.ts +40 -0
- package/dist/render.d.mts +4 -0
- package/dist/render.d.ts +4 -0
- package/dist/render.js +380 -0
- package/dist/render.js.map +1 -0
- package/dist/render.mjs +11 -0
- package/dist/render.mjs.map +1 -0
- package/dist/server.d.mts +53 -0
- package/dist/server.d.ts +53 -0
- package/dist/server.js +248 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +11 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// src/render.tsx
|
|
2
|
+
import satori from "satori";
|
|
3
|
+
import {
|
|
4
|
+
resolveElementProps,
|
|
5
|
+
evaluateVisibility,
|
|
6
|
+
getByPath
|
|
7
|
+
} from "@json-render/core";
|
|
8
|
+
|
|
9
|
+
// src/components/standard.tsx
|
|
10
|
+
import { jsx } from "react/jsx-runtime";
|
|
11
|
+
var headingSizes = {
|
|
12
|
+
h1: 48,
|
|
13
|
+
h2: 36,
|
|
14
|
+
h3: 28,
|
|
15
|
+
h4: 22
|
|
16
|
+
};
|
|
17
|
+
var headingWeights = {
|
|
18
|
+
h1: 700,
|
|
19
|
+
h2: 700,
|
|
20
|
+
h3: 600,
|
|
21
|
+
h4: 600
|
|
22
|
+
};
|
|
23
|
+
function cleanStyle(raw) {
|
|
24
|
+
const out = {};
|
|
25
|
+
for (const k in raw) {
|
|
26
|
+
if (raw[k] !== void 0 && raw[k] !== null) {
|
|
27
|
+
out[k] = raw[k];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
function FrameComponent({
|
|
33
|
+
element,
|
|
34
|
+
children
|
|
35
|
+
}) {
|
|
36
|
+
const p = element.props;
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
style: cleanStyle({
|
|
41
|
+
display: p.display ?? "flex",
|
|
42
|
+
flexDirection: p.flexDirection ?? "column",
|
|
43
|
+
width: p.width,
|
|
44
|
+
height: p.height,
|
|
45
|
+
backgroundColor: p.backgroundColor ?? "white",
|
|
46
|
+
padding: p.padding,
|
|
47
|
+
alignItems: p.alignItems,
|
|
48
|
+
justifyContent: p.justifyContent
|
|
49
|
+
}),
|
|
50
|
+
children
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function BoxComponent({
|
|
55
|
+
element,
|
|
56
|
+
children
|
|
57
|
+
}) {
|
|
58
|
+
const p = element.props;
|
|
59
|
+
return /* @__PURE__ */ jsx(
|
|
60
|
+
"div",
|
|
61
|
+
{
|
|
62
|
+
style: cleanStyle({
|
|
63
|
+
display: "flex",
|
|
64
|
+
flexDirection: p.flexDirection ?? "column",
|
|
65
|
+
padding: p.padding,
|
|
66
|
+
paddingTop: p.paddingTop,
|
|
67
|
+
paddingBottom: p.paddingBottom,
|
|
68
|
+
paddingLeft: p.paddingLeft,
|
|
69
|
+
paddingRight: p.paddingRight,
|
|
70
|
+
margin: p.margin,
|
|
71
|
+
backgroundColor: p.backgroundColor,
|
|
72
|
+
borderWidth: p.borderWidth,
|
|
73
|
+
borderColor: p.borderColor,
|
|
74
|
+
borderRadius: p.borderRadius,
|
|
75
|
+
borderStyle: p.borderWidth ? "solid" : void 0,
|
|
76
|
+
flex: p.flex,
|
|
77
|
+
width: p.width,
|
|
78
|
+
height: p.height,
|
|
79
|
+
alignItems: p.alignItems,
|
|
80
|
+
justifyContent: p.justifyContent,
|
|
81
|
+
position: p.position,
|
|
82
|
+
top: p.top,
|
|
83
|
+
left: p.left,
|
|
84
|
+
right: p.right,
|
|
85
|
+
bottom: p.bottom,
|
|
86
|
+
overflow: p.overflow
|
|
87
|
+
}),
|
|
88
|
+
children
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
function RowComponent({
|
|
93
|
+
element,
|
|
94
|
+
children
|
|
95
|
+
}) {
|
|
96
|
+
const p = element.props;
|
|
97
|
+
return /* @__PURE__ */ jsx(
|
|
98
|
+
"div",
|
|
99
|
+
{
|
|
100
|
+
style: cleanStyle({
|
|
101
|
+
display: "flex",
|
|
102
|
+
flexDirection: "row",
|
|
103
|
+
gap: p.gap,
|
|
104
|
+
alignItems: p.alignItems,
|
|
105
|
+
justifyContent: p.justifyContent,
|
|
106
|
+
padding: p.padding,
|
|
107
|
+
flex: p.flex,
|
|
108
|
+
flexWrap: p.wrap ? "wrap" : void 0
|
|
109
|
+
}),
|
|
110
|
+
children
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
function ColumnComponent({
|
|
115
|
+
element,
|
|
116
|
+
children
|
|
117
|
+
}) {
|
|
118
|
+
const p = element.props;
|
|
119
|
+
return /* @__PURE__ */ jsx(
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
style: cleanStyle({
|
|
123
|
+
display: "flex",
|
|
124
|
+
flexDirection: "column",
|
|
125
|
+
gap: p.gap,
|
|
126
|
+
alignItems: p.alignItems,
|
|
127
|
+
justifyContent: p.justifyContent,
|
|
128
|
+
padding: p.padding,
|
|
129
|
+
flex: p.flex
|
|
130
|
+
}),
|
|
131
|
+
children
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
function HeadingComponent({
|
|
136
|
+
element
|
|
137
|
+
}) {
|
|
138
|
+
const p = element.props;
|
|
139
|
+
const level = p.level ?? "h2";
|
|
140
|
+
return /* @__PURE__ */ jsx(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
style: cleanStyle({
|
|
144
|
+
display: "flex",
|
|
145
|
+
fontSize: headingSizes[level] ?? 36,
|
|
146
|
+
fontWeight: headingWeights[level] ?? 700,
|
|
147
|
+
color: p.color ?? "black",
|
|
148
|
+
textAlign: p.align ?? "left",
|
|
149
|
+
letterSpacing: p.letterSpacing,
|
|
150
|
+
lineHeight: p.lineHeight ?? 1.2
|
|
151
|
+
}),
|
|
152
|
+
children: p.text
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
function TextComponent({
|
|
157
|
+
element
|
|
158
|
+
}) {
|
|
159
|
+
const p = element.props;
|
|
160
|
+
return /* @__PURE__ */ jsx(
|
|
161
|
+
"div",
|
|
162
|
+
{
|
|
163
|
+
style: cleanStyle({
|
|
164
|
+
display: "flex",
|
|
165
|
+
fontSize: p.fontSize ?? 16,
|
|
166
|
+
color: p.color ?? "black",
|
|
167
|
+
textAlign: p.align ?? "left",
|
|
168
|
+
fontWeight: p.fontWeight === "bold" ? 700 : 400,
|
|
169
|
+
fontStyle: p.fontStyle ?? "normal",
|
|
170
|
+
lineHeight: p.lineHeight ?? 1.4,
|
|
171
|
+
letterSpacing: p.letterSpacing,
|
|
172
|
+
textDecoration: p.textDecoration
|
|
173
|
+
}),
|
|
174
|
+
children: p.text
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
function ImageComponent({
|
|
179
|
+
element
|
|
180
|
+
}) {
|
|
181
|
+
const p = element.props;
|
|
182
|
+
return /* @__PURE__ */ jsx(
|
|
183
|
+
"img",
|
|
184
|
+
{
|
|
185
|
+
src: p.src,
|
|
186
|
+
width: p.width ?? void 0,
|
|
187
|
+
height: p.height ?? void 0,
|
|
188
|
+
style: cleanStyle({
|
|
189
|
+
borderRadius: p.borderRadius,
|
|
190
|
+
objectFit: p.objectFit ?? "contain"
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
function DividerComponent({
|
|
196
|
+
element
|
|
197
|
+
}) {
|
|
198
|
+
const p = element.props;
|
|
199
|
+
return /* @__PURE__ */ jsx(
|
|
200
|
+
"div",
|
|
201
|
+
{
|
|
202
|
+
style: {
|
|
203
|
+
display: "flex",
|
|
204
|
+
width: "100%",
|
|
205
|
+
borderBottom: `${p.thickness ?? 1}px solid ${p.color ?? "#e5e7eb"}`,
|
|
206
|
+
marginTop: p.marginTop ?? 8,
|
|
207
|
+
marginBottom: p.marginBottom ?? 8
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
function SpacerComponent({
|
|
213
|
+
element
|
|
214
|
+
}) {
|
|
215
|
+
const p = element.props;
|
|
216
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", height: p.height ?? 20 } });
|
|
217
|
+
}
|
|
218
|
+
var standardComponents = {
|
|
219
|
+
Frame: FrameComponent,
|
|
220
|
+
Box: BoxComponent,
|
|
221
|
+
Row: RowComponent,
|
|
222
|
+
Column: ColumnComponent,
|
|
223
|
+
Heading: HeadingComponent,
|
|
224
|
+
Text: TextComponent,
|
|
225
|
+
Image: ImageComponent,
|
|
226
|
+
Divider: DividerComponent,
|
|
227
|
+
Spacer: SpacerComponent
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// src/render.tsx
|
|
231
|
+
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
232
|
+
var noopEmit = () => {
|
|
233
|
+
};
|
|
234
|
+
function renderElement(elementKey, spec, registry, stateModel, repeatItem, repeatIndex, repeatBasePath) {
|
|
235
|
+
const element = spec.elements[elementKey];
|
|
236
|
+
if (!element) return null;
|
|
237
|
+
const ctx = {
|
|
238
|
+
stateModel,
|
|
239
|
+
repeatItem,
|
|
240
|
+
repeatIndex,
|
|
241
|
+
repeatBasePath
|
|
242
|
+
};
|
|
243
|
+
if (element.visible !== void 0) {
|
|
244
|
+
if (!evaluateVisibility(element.visible, ctx)) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const resolvedProps = resolveElementProps(
|
|
249
|
+
element.props,
|
|
250
|
+
ctx
|
|
251
|
+
);
|
|
252
|
+
const resolvedElement = { ...element, props: resolvedProps };
|
|
253
|
+
const Component = registry[resolvedElement.type];
|
|
254
|
+
if (!Component) return null;
|
|
255
|
+
if (resolvedElement.repeat) {
|
|
256
|
+
const items = getByPath(stateModel, resolvedElement.repeat.statePath) ?? [];
|
|
257
|
+
const fragments = items.map((item, index) => {
|
|
258
|
+
const key = resolvedElement.repeat.key && typeof item === "object" && item !== null ? String(
|
|
259
|
+
item[resolvedElement.repeat.key] ?? index
|
|
260
|
+
) : String(index);
|
|
261
|
+
const childPath = `${resolvedElement.repeat.statePath}/${index}`;
|
|
262
|
+
const children2 = resolvedElement.children?.map(
|
|
263
|
+
(childKey) => renderElement(
|
|
264
|
+
childKey,
|
|
265
|
+
spec,
|
|
266
|
+
registry,
|
|
267
|
+
stateModel,
|
|
268
|
+
item,
|
|
269
|
+
index,
|
|
270
|
+
childPath
|
|
271
|
+
)
|
|
272
|
+
);
|
|
273
|
+
return /* @__PURE__ */ jsx2(Component, { element: resolvedElement, emit: noopEmit, children: children2 }, key);
|
|
274
|
+
});
|
|
275
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: fragments });
|
|
276
|
+
}
|
|
277
|
+
const children = resolvedElement.children?.map(
|
|
278
|
+
(childKey) => renderElement(
|
|
279
|
+
childKey,
|
|
280
|
+
spec,
|
|
281
|
+
registry,
|
|
282
|
+
stateModel,
|
|
283
|
+
repeatItem,
|
|
284
|
+
repeatIndex,
|
|
285
|
+
repeatBasePath
|
|
286
|
+
)
|
|
287
|
+
);
|
|
288
|
+
return /* @__PURE__ */ jsx2(Component, { element: resolvedElement, emit: noopEmit, children: children && children.length > 0 ? children : void 0 }, elementKey);
|
|
289
|
+
}
|
|
290
|
+
function getDimensions(spec, options = {}) {
|
|
291
|
+
if (options.width && options.height) {
|
|
292
|
+
return { width: options.width, height: options.height };
|
|
293
|
+
}
|
|
294
|
+
const rootElement = spec.elements[spec.root];
|
|
295
|
+
const props = rootElement?.props;
|
|
296
|
+
return {
|
|
297
|
+
width: options.width ?? props?.width ?? 1200,
|
|
298
|
+
height: options.height ?? props?.height ?? 630
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function buildTree(spec, options = {}) {
|
|
302
|
+
const {
|
|
303
|
+
registry: customRegistry,
|
|
304
|
+
includeStandard = true,
|
|
305
|
+
state = {}
|
|
306
|
+
} = options;
|
|
307
|
+
const mergedState = {
|
|
308
|
+
...spec.state,
|
|
309
|
+
...state
|
|
310
|
+
};
|
|
311
|
+
const registry = {
|
|
312
|
+
...includeStandard ? standardComponents : {},
|
|
313
|
+
...customRegistry
|
|
314
|
+
};
|
|
315
|
+
const root = renderElement(spec.root, spec, registry, mergedState);
|
|
316
|
+
return root ?? /* @__PURE__ */ jsx2(Fragment, {});
|
|
317
|
+
}
|
|
318
|
+
async function renderToSvg(spec, options = {}) {
|
|
319
|
+
const tree = buildTree(spec, options);
|
|
320
|
+
const { width, height } = getDimensions(spec, options);
|
|
321
|
+
return satori(tree, {
|
|
322
|
+
width,
|
|
323
|
+
height,
|
|
324
|
+
fonts: options.fonts ?? []
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
async function renderToPng(spec, options = {}) {
|
|
328
|
+
const svg = await renderToSvg(spec, options);
|
|
329
|
+
let Resvg;
|
|
330
|
+
try {
|
|
331
|
+
const mod = await import("@resvg/resvg-js");
|
|
332
|
+
Resvg = mod.Resvg;
|
|
333
|
+
} catch {
|
|
334
|
+
throw new Error(
|
|
335
|
+
"@resvg/resvg-js is required for PNG output. Install it with: npm install @resvg/resvg-js"
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
const resvg = new Resvg(svg);
|
|
339
|
+
const pngData = resvg.render();
|
|
340
|
+
return pngData.asPng();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export {
|
|
344
|
+
standardComponents,
|
|
345
|
+
renderToSvg,
|
|
346
|
+
renderToPng
|
|
347
|
+
};
|
|
348
|
+
//# sourceMappingURL=chunk-KQSKKHJA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/render.tsx","../src/components/standard.tsx"],"sourcesContent":["import React from \"react\";\nimport satori, { type SatoriOptions } from \"satori\";\nimport type { Spec, UIElement } from \"@json-render/core\";\nimport {\n resolveElementProps,\n evaluateVisibility,\n getByPath,\n type PropResolutionContext,\n} from \"@json-render/core\";\nimport { standardComponents } from \"./components/standard\";\nimport type { ComponentRegistry } from \"./types\";\n\nexport { standardComponents };\n\nexport interface RenderOptions {\n registry?: ComponentRegistry;\n includeStandard?: boolean;\n state?: Record<string, unknown>;\n fonts?: SatoriOptions[\"fonts\"];\n /** Override the Frame width. When omitted, uses the Frame component's width prop. */\n width?: number;\n /** Override the Frame height. When omitted, uses the Frame component's height prop. */\n height?: number;\n}\n\nconst noopEmit = () => {};\n\nfunction renderElement(\n elementKey: string,\n spec: Spec,\n registry: ComponentRegistry,\n stateModel: Record<string, unknown>,\n repeatItem?: unknown,\n repeatIndex?: number,\n repeatBasePath?: string,\n): React.ReactElement | null {\n const element = spec.elements[elementKey];\n if (!element) return null;\n\n const ctx: PropResolutionContext = {\n stateModel,\n repeatItem,\n repeatIndex,\n repeatBasePath,\n };\n\n if (element.visible !== undefined) {\n if (!evaluateVisibility(element.visible, ctx)) {\n return null;\n }\n }\n\n const resolvedProps = resolveElementProps(\n element.props as Record<string, unknown>,\n ctx,\n );\n const resolvedElement: UIElement = { ...element, props: resolvedProps };\n\n const Component = registry[resolvedElement.type];\n if (!Component) return null;\n\n if (resolvedElement.repeat) {\n const items =\n (getByPath(stateModel, resolvedElement.repeat.statePath) as\n | unknown[]\n | undefined) ?? [];\n\n const fragments = items.map((item, index) => {\n const key =\n resolvedElement.repeat!.key && typeof item === \"object\" && item !== null\n ? String(\n (item as Record<string, unknown>)[resolvedElement.repeat!.key!] ??\n index,\n )\n : String(index);\n\n const childPath = `${resolvedElement.repeat!.statePath}/${index}`;\n const children = resolvedElement.children?.map((childKey) =>\n renderElement(\n childKey,\n spec,\n registry,\n stateModel,\n item,\n index,\n childPath,\n ),\n );\n\n return (\n <Component key={key} element={resolvedElement} emit={noopEmit}>\n {children}\n </Component>\n );\n });\n\n return <>{fragments}</>;\n }\n\n const children = resolvedElement.children?.map((childKey) =>\n renderElement(\n childKey,\n spec,\n registry,\n stateModel,\n repeatItem,\n repeatIndex,\n repeatBasePath,\n ),\n );\n\n return (\n <Component key={elementKey} element={resolvedElement} emit={noopEmit}>\n {children && children.length > 0 ? children : undefined}\n </Component>\n );\n}\n\ninterface ImageDimensions {\n width: number;\n height: number;\n}\n\nfunction getDimensions(\n spec: Spec,\n options: RenderOptions = {},\n): ImageDimensions {\n if (options.width && options.height) {\n return { width: options.width, height: options.height };\n }\n\n const rootElement = spec.elements[spec.root];\n const props = rootElement?.props as Record<string, unknown> | undefined;\n\n return {\n width: options.width ?? (props?.width as number) ?? 1200,\n height: options.height ?? (props?.height as number) ?? 630,\n };\n}\n\nfunction buildTree(\n spec: Spec,\n options: RenderOptions = {},\n): React.ReactElement {\n const {\n registry: customRegistry,\n includeStandard = true,\n state = {},\n } = options;\n\n const mergedState: Record<string, unknown> = {\n ...spec.state,\n ...state,\n };\n\n const registry: ComponentRegistry = {\n ...(includeStandard ? standardComponents : {}),\n ...customRegistry,\n };\n\n const root = renderElement(spec.root, spec, registry, mergedState);\n return root ?? <></>;\n}\n\n/**\n * Render a json-render spec to an SVG string.\n *\n * Uses Satori to convert the spec's component tree into SVG.\n * No additional dependencies are needed beyond satori.\n */\nexport async function renderToSvg(\n spec: Spec,\n options: RenderOptions = {},\n): Promise<string> {\n const tree = buildTree(spec, options);\n const { width, height } = getDimensions(spec, options);\n\n return satori(tree as React.ReactNode, {\n width,\n height,\n fonts: options.fonts ?? [],\n });\n}\n\n/**\n * Render a json-render spec to a PNG buffer.\n *\n * Requires `@resvg/resvg-js` to be installed as a peer dependency.\n * The SVG is first generated via Satori, then rasterized to PNG.\n */\nexport async function renderToPng(\n spec: Spec,\n options: RenderOptions = {},\n): Promise<Uint8Array> {\n const svg = await renderToSvg(spec, options);\n\n let Resvg: typeof import(\"@resvg/resvg-js\").Resvg;\n try {\n const mod = await import(\"@resvg/resvg-js\");\n Resvg = mod.Resvg;\n } catch {\n throw new Error(\n \"@resvg/resvg-js is required for PNG output. Install it with: npm install @resvg/resvg-js\",\n );\n }\n\n const resvg = new Resvg(svg);\n const pngData = resvg.render();\n return pngData.asPng();\n}\n","import React from \"react\";\nimport type { ComponentRenderProps, ComponentRegistry } from \"../types\";\nimport type { StandardComponentProps } from \"../catalog\";\n\nconst headingSizes: Record<string, number> = {\n h1: 48,\n h2: 36,\n h3: 28,\n h4: 22,\n};\n\nconst headingWeights: Record<string, number> = {\n h1: 700,\n h2: 700,\n h3: 600,\n h4: 600,\n};\n\n/**\n * Satori crashes on explicit `undefined` style values (e.g. `padding: undefined`).\n * Strip them so only defined properties are passed.\n */\nfunction cleanStyle(raw: Record<string, unknown>): React.CSSProperties {\n const out: Record<string, unknown> = {};\n for (const k in raw) {\n if (raw[k] !== undefined && raw[k] !== null) {\n out[k] = raw[k];\n }\n }\n return out as React.CSSProperties;\n}\n\n// =============================================================================\n// Root\n// =============================================================================\n\nfunction FrameComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Frame\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: p.display ?? \"flex\",\n flexDirection: p.flexDirection ?? \"column\",\n width: p.width,\n height: p.height,\n backgroundColor: p.backgroundColor ?? \"white\",\n padding: p.padding,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n })}\n >\n {children}\n </div>\n );\n}\n\n// =============================================================================\n// Layout Components\n// =============================================================================\n\nfunction BoxComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Box\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n flexDirection: p.flexDirection ?? \"column\",\n padding: p.padding,\n paddingTop: p.paddingTop,\n paddingBottom: p.paddingBottom,\n paddingLeft: p.paddingLeft,\n paddingRight: p.paddingRight,\n margin: p.margin,\n backgroundColor: p.backgroundColor,\n borderWidth: p.borderWidth,\n borderColor: p.borderColor,\n borderRadius: p.borderRadius,\n borderStyle: p.borderWidth ? \"solid\" : undefined,\n flex: p.flex,\n width: p.width,\n height: p.height,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n position: p.position,\n top: p.top,\n left: p.left,\n right: p.right,\n bottom: p.bottom,\n overflow: p.overflow,\n })}\n >\n {children}\n </div>\n );\n}\n\nfunction RowComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Row\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n flexDirection: \"row\",\n gap: p.gap,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n padding: p.padding,\n flex: p.flex,\n flexWrap: p.wrap ? \"wrap\" : undefined,\n })}\n >\n {children}\n </div>\n );\n}\n\nfunction ColumnComponent({\n element,\n children,\n}: ComponentRenderProps<StandardComponentProps<\"Column\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n flexDirection: \"column\",\n gap: p.gap,\n alignItems: p.alignItems,\n justifyContent: p.justifyContent,\n padding: p.padding,\n flex: p.flex,\n })}\n >\n {children}\n </div>\n );\n}\n\n// =============================================================================\n// Content Components\n// =============================================================================\n\nfunction HeadingComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Heading\">>) {\n const p = element.props;\n const level = p.level ?? \"h2\";\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n fontSize: headingSizes[level] ?? 36,\n fontWeight: headingWeights[level] ?? 700,\n color: p.color ?? \"black\",\n textAlign: p.align ?? \"left\",\n letterSpacing: p.letterSpacing,\n lineHeight: p.lineHeight ?? 1.2,\n })}\n >\n {p.text}\n </div>\n );\n}\n\nfunction TextComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Text\">>) {\n const p = element.props;\n\n return (\n <div\n style={cleanStyle({\n display: \"flex\",\n fontSize: p.fontSize ?? 16,\n color: p.color ?? \"black\",\n textAlign: p.align ?? \"left\",\n fontWeight: p.fontWeight === \"bold\" ? 700 : 400,\n fontStyle: p.fontStyle ?? \"normal\",\n lineHeight: p.lineHeight ?? 1.4,\n letterSpacing: p.letterSpacing,\n textDecoration: p.textDecoration,\n })}\n >\n {p.text}\n </div>\n );\n}\n\nfunction ImageComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Image\">>) {\n const p = element.props;\n\n return (\n <img\n src={p.src}\n width={p.width ?? undefined}\n height={p.height ?? undefined}\n style={cleanStyle({\n borderRadius: p.borderRadius,\n objectFit: p.objectFit ?? \"contain\",\n })}\n />\n );\n}\n\n// =============================================================================\n// Decorative Components\n// =============================================================================\n\nfunction DividerComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Divider\">>) {\n const p = element.props;\n\n return (\n <div\n style={{\n display: \"flex\",\n width: \"100%\",\n borderBottom: `${p.thickness ?? 1}px solid ${p.color ?? \"#e5e7eb\"}`,\n marginTop: p.marginTop ?? 8,\n marginBottom: p.marginBottom ?? 8,\n }}\n />\n );\n}\n\nfunction SpacerComponent({\n element,\n}: ComponentRenderProps<StandardComponentProps<\"Spacer\">>) {\n const p = element.props;\n\n return <div style={{ display: \"flex\", height: p.height ?? 20 }} />;\n}\n\n// =============================================================================\n// Registry\n// =============================================================================\n\nexport const standardComponents: ComponentRegistry = {\n Frame: FrameComponent,\n Box: BoxComponent,\n Row: RowComponent,\n Column: ColumnComponent,\n Heading: HeadingComponent,\n Text: TextComponent,\n Image: ImageComponent,\n Divider: DividerComponent,\n Spacer: SpacerComponent,\n};\n"],"mappings":"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","names":["jsx","children","jsx"]}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// src/catalog.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var standardComponentDefinitions = {
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
// Root
|
|
6
|
+
// ==========================================================================
|
|
7
|
+
Frame: {
|
|
8
|
+
props: z.object({
|
|
9
|
+
width: z.number(),
|
|
10
|
+
height: z.number(),
|
|
11
|
+
backgroundColor: z.string().nullable(),
|
|
12
|
+
padding: z.number().nullable(),
|
|
13
|
+
display: z.enum(["flex", "none"]).nullable(),
|
|
14
|
+
flexDirection: z.enum(["row", "column"]).nullable(),
|
|
15
|
+
alignItems: z.enum(["flex-start", "center", "flex-end", "stretch"]).nullable(),
|
|
16
|
+
justifyContent: z.enum([
|
|
17
|
+
"flex-start",
|
|
18
|
+
"center",
|
|
19
|
+
"flex-end",
|
|
20
|
+
"space-between",
|
|
21
|
+
"space-around"
|
|
22
|
+
]).nullable()
|
|
23
|
+
}),
|
|
24
|
+
slots: ["default"],
|
|
25
|
+
description: "Root image container. Defines the output image dimensions and background. Must be the root element.",
|
|
26
|
+
example: { width: 1200, height: 630, backgroundColor: "#ffffff" }
|
|
27
|
+
},
|
|
28
|
+
// ==========================================================================
|
|
29
|
+
// Layout Components
|
|
30
|
+
// ==========================================================================
|
|
31
|
+
Box: {
|
|
32
|
+
props: z.object({
|
|
33
|
+
padding: z.number().nullable(),
|
|
34
|
+
paddingTop: z.number().nullable(),
|
|
35
|
+
paddingBottom: z.number().nullable(),
|
|
36
|
+
paddingLeft: z.number().nullable(),
|
|
37
|
+
paddingRight: z.number().nullable(),
|
|
38
|
+
margin: z.number().nullable(),
|
|
39
|
+
backgroundColor: z.string().nullable(),
|
|
40
|
+
borderWidth: z.number().nullable(),
|
|
41
|
+
borderColor: z.string().nullable(),
|
|
42
|
+
borderRadius: z.number().nullable(),
|
|
43
|
+
flex: z.number().nullable(),
|
|
44
|
+
width: z.union([z.number(), z.string()]).nullable(),
|
|
45
|
+
height: z.union([z.number(), z.string()]).nullable(),
|
|
46
|
+
alignItems: z.enum(["flex-start", "center", "flex-end", "stretch"]).nullable(),
|
|
47
|
+
justifyContent: z.enum([
|
|
48
|
+
"flex-start",
|
|
49
|
+
"center",
|
|
50
|
+
"flex-end",
|
|
51
|
+
"space-between",
|
|
52
|
+
"space-around"
|
|
53
|
+
]).nullable(),
|
|
54
|
+
flexDirection: z.enum(["row", "column"]).nullable(),
|
|
55
|
+
position: z.enum(["relative", "absolute"]).nullable(),
|
|
56
|
+
top: z.number().nullable(),
|
|
57
|
+
left: z.number().nullable(),
|
|
58
|
+
right: z.number().nullable(),
|
|
59
|
+
bottom: z.number().nullable(),
|
|
60
|
+
overflow: z.enum(["visible", "hidden"]).nullable()
|
|
61
|
+
}),
|
|
62
|
+
slots: ["default"],
|
|
63
|
+
description: "Generic container with padding, margin, background, border, and flex alignment. Supports absolute positioning.",
|
|
64
|
+
example: {
|
|
65
|
+
padding: 20,
|
|
66
|
+
backgroundColor: "#f9f9f9",
|
|
67
|
+
borderRadius: 8,
|
|
68
|
+
alignItems: "center"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
Row: {
|
|
72
|
+
props: z.object({
|
|
73
|
+
gap: z.number().nullable(),
|
|
74
|
+
alignItems: z.enum(["flex-start", "center", "flex-end", "stretch"]).nullable(),
|
|
75
|
+
justifyContent: z.enum([
|
|
76
|
+
"flex-start",
|
|
77
|
+
"center",
|
|
78
|
+
"flex-end",
|
|
79
|
+
"space-between",
|
|
80
|
+
"space-around"
|
|
81
|
+
]).nullable(),
|
|
82
|
+
padding: z.number().nullable(),
|
|
83
|
+
flex: z.number().nullable(),
|
|
84
|
+
wrap: z.boolean().nullable()
|
|
85
|
+
}),
|
|
86
|
+
slots: ["default"],
|
|
87
|
+
description: "Horizontal flex layout. Use for placing elements side by side.",
|
|
88
|
+
example: { gap: 10, alignItems: "center" }
|
|
89
|
+
},
|
|
90
|
+
Column: {
|
|
91
|
+
props: z.object({
|
|
92
|
+
gap: z.number().nullable(),
|
|
93
|
+
alignItems: z.enum(["flex-start", "center", "flex-end", "stretch"]).nullable(),
|
|
94
|
+
justifyContent: z.enum([
|
|
95
|
+
"flex-start",
|
|
96
|
+
"center",
|
|
97
|
+
"flex-end",
|
|
98
|
+
"space-between",
|
|
99
|
+
"space-around"
|
|
100
|
+
]).nullable(),
|
|
101
|
+
padding: z.number().nullable(),
|
|
102
|
+
flex: z.number().nullable()
|
|
103
|
+
}),
|
|
104
|
+
slots: ["default"],
|
|
105
|
+
description: "Vertical flex layout. Use for stacking elements top to bottom.",
|
|
106
|
+
example: { gap: 8, padding: 10 }
|
|
107
|
+
},
|
|
108
|
+
// ==========================================================================
|
|
109
|
+
// Content Components
|
|
110
|
+
// ==========================================================================
|
|
111
|
+
Heading: {
|
|
112
|
+
props: z.object({
|
|
113
|
+
text: z.string(),
|
|
114
|
+
level: z.enum(["h1", "h2", "h3", "h4"]).nullable(),
|
|
115
|
+
color: z.string().nullable(),
|
|
116
|
+
align: z.enum(["left", "center", "right"]).nullable(),
|
|
117
|
+
letterSpacing: z.union([z.number(), z.string()]).nullable(),
|
|
118
|
+
lineHeight: z.number().nullable()
|
|
119
|
+
}),
|
|
120
|
+
slots: [],
|
|
121
|
+
description: "Heading text at various levels. h1 is largest, h4 is smallest.",
|
|
122
|
+
example: { text: "Hello World", level: "h1", color: "#000000" }
|
|
123
|
+
},
|
|
124
|
+
Text: {
|
|
125
|
+
props: z.object({
|
|
126
|
+
text: z.string(),
|
|
127
|
+
fontSize: z.number().nullable(),
|
|
128
|
+
color: z.string().nullable(),
|
|
129
|
+
align: z.enum(["left", "center", "right"]).nullable(),
|
|
130
|
+
fontWeight: z.enum(["normal", "bold"]).nullable(),
|
|
131
|
+
fontStyle: z.enum(["normal", "italic"]).nullable(),
|
|
132
|
+
lineHeight: z.number().nullable(),
|
|
133
|
+
letterSpacing: z.union([z.number(), z.string()]).nullable(),
|
|
134
|
+
textDecoration: z.enum(["none", "underline", "line-through"]).nullable()
|
|
135
|
+
}),
|
|
136
|
+
slots: [],
|
|
137
|
+
description: "Body text with configurable size, color, weight, and alignment.",
|
|
138
|
+
example: { text: "Some content here.", fontSize: 16, color: "#333333" }
|
|
139
|
+
},
|
|
140
|
+
Image: {
|
|
141
|
+
props: z.object({
|
|
142
|
+
src: z.string(),
|
|
143
|
+
width: z.number().nullable(),
|
|
144
|
+
height: z.number().nullable(),
|
|
145
|
+
borderRadius: z.number().nullable(),
|
|
146
|
+
objectFit: z.enum(["contain", "cover", "fill", "none"]).nullable()
|
|
147
|
+
}),
|
|
148
|
+
slots: [],
|
|
149
|
+
description: "Image from a URL. Specify width and/or height to control size. For placeholder images use https://picsum.photos/{width}/{height}?random={n}.",
|
|
150
|
+
example: {
|
|
151
|
+
src: "https://picsum.photos/400/300?random=1",
|
|
152
|
+
width: 400,
|
|
153
|
+
height: 300
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
// ==========================================================================
|
|
157
|
+
// Decorative Components
|
|
158
|
+
// ==========================================================================
|
|
159
|
+
Divider: {
|
|
160
|
+
props: z.object({
|
|
161
|
+
color: z.string().nullable(),
|
|
162
|
+
thickness: z.number().nullable(),
|
|
163
|
+
marginTop: z.number().nullable(),
|
|
164
|
+
marginBottom: z.number().nullable()
|
|
165
|
+
}),
|
|
166
|
+
slots: [],
|
|
167
|
+
description: "Horizontal line separator between content sections.",
|
|
168
|
+
example: { color: "#e5e7eb", thickness: 1 }
|
|
169
|
+
},
|
|
170
|
+
Spacer: {
|
|
171
|
+
props: z.object({
|
|
172
|
+
height: z.number().nullable()
|
|
173
|
+
}),
|
|
174
|
+
slots: [],
|
|
175
|
+
description: "Empty vertical space between elements.",
|
|
176
|
+
example: { height: 20 }
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
standardComponentDefinitions
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=chunk-PMEELRVP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Standard component definitions for image catalogs.\n *\n * These define the available image components with their Zod prop schemas.\n * All components render to Satori-compatible JSX (HTML-like elements with\n * inline CSS flexbox styles).\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Root\n // ==========================================================================\n\n Frame: {\n props: z.object({\n width: z.number(),\n height: z.number(),\n backgroundColor: z.string().nullable(),\n padding: z.number().nullable(),\n display: z.enum([\"flex\", \"none\"]).nullable(),\n flexDirection: z.enum([\"row\", \"column\"]).nullable(),\n alignItems: z\n .enum([\"flex-start\", \"center\", \"flex-end\", \"stretch\"])\n .nullable(),\n justifyContent: z\n .enum([\n \"flex-start\",\n \"center\",\n \"flex-end\",\n \"space-between\",\n \"space-around\",\n ])\n .nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Root image container. Defines the output image dimensions and background. Must be the root element.\",\n example: { width: 1200, height: 630, backgroundColor: \"#ffffff\" },\n },\n\n // ==========================================================================\n // Layout Components\n // ==========================================================================\n\n Box: {\n props: z.object({\n padding: z.number().nullable(),\n paddingTop: z.number().nullable(),\n paddingBottom: z.number().nullable(),\n paddingLeft: z.number().nullable(),\n paddingRight: z.number().nullable(),\n margin: z.number().nullable(),\n backgroundColor: z.string().nullable(),\n borderWidth: z.number().nullable(),\n borderColor: z.string().nullable(),\n borderRadius: z.number().nullable(),\n flex: z.number().nullable(),\n width: z.union([z.number(), z.string()]).nullable(),\n height: z.union([z.number(), z.string()]).nullable(),\n alignItems: z\n .enum([\"flex-start\", \"center\", \"flex-end\", \"stretch\"])\n .nullable(),\n justifyContent: z\n .enum([\n \"flex-start\",\n \"center\",\n \"flex-end\",\n \"space-between\",\n \"space-around\",\n ])\n .nullable(),\n flexDirection: z.enum([\"row\", \"column\"]).nullable(),\n position: z.enum([\"relative\", \"absolute\"]).nullable(),\n top: z.number().nullable(),\n left: z.number().nullable(),\n right: z.number().nullable(),\n bottom: z.number().nullable(),\n overflow: z.enum([\"visible\", \"hidden\"]).nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Generic container with padding, margin, background, border, and flex alignment. Supports absolute positioning.\",\n example: {\n padding: 20,\n backgroundColor: \"#f9f9f9\",\n borderRadius: 8,\n alignItems: \"center\",\n },\n },\n\n Row: {\n props: z.object({\n gap: z.number().nullable(),\n alignItems: z\n .enum([\"flex-start\", \"center\", \"flex-end\", \"stretch\"])\n .nullable(),\n justifyContent: z\n .enum([\n \"flex-start\",\n \"center\",\n \"flex-end\",\n \"space-between\",\n \"space-around\",\n ])\n .nullable(),\n padding: z.number().nullable(),\n flex: z.number().nullable(),\n wrap: z.boolean().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Horizontal flex layout. Use for placing elements side by side.\",\n example: { gap: 10, alignItems: \"center\" },\n },\n\n Column: {\n props: z.object({\n gap: z.number().nullable(),\n alignItems: z\n .enum([\"flex-start\", \"center\", \"flex-end\", \"stretch\"])\n .nullable(),\n justifyContent: z\n .enum([\n \"flex-start\",\n \"center\",\n \"flex-end\",\n \"space-between\",\n \"space-around\",\n ])\n .nullable(),\n padding: z.number().nullable(),\n flex: z.number().nullable(),\n }),\n slots: [\"default\"],\n description:\n \"Vertical flex layout. Use for stacking elements top to bottom.\",\n example: { gap: 8, padding: 10 },\n },\n\n // ==========================================================================\n // Content Components\n // ==========================================================================\n\n Heading: {\n props: z.object({\n text: z.string(),\n level: z.enum([\"h1\", \"h2\", \"h3\", \"h4\"]).nullable(),\n color: z.string().nullable(),\n align: z.enum([\"left\", \"center\", \"right\"]).nullable(),\n letterSpacing: z.union([z.number(), z.string()]).nullable(),\n lineHeight: z.number().nullable(),\n }),\n slots: [],\n description:\n \"Heading text at various levels. h1 is largest, h4 is smallest.\",\n example: { text: \"Hello World\", level: \"h1\", color: \"#000000\" },\n },\n\n Text: {\n props: z.object({\n text: z.string(),\n fontSize: z.number().nullable(),\n color: z.string().nullable(),\n align: z.enum([\"left\", \"center\", \"right\"]).nullable(),\n fontWeight: z.enum([\"normal\", \"bold\"]).nullable(),\n fontStyle: z.enum([\"normal\", \"italic\"]).nullable(),\n lineHeight: z.number().nullable(),\n letterSpacing: z.union([z.number(), z.string()]).nullable(),\n textDecoration: z.enum([\"none\", \"underline\", \"line-through\"]).nullable(),\n }),\n slots: [],\n description:\n \"Body text with configurable size, color, weight, and alignment.\",\n example: { text: \"Some content here.\", fontSize: 16, color: \"#333333\" },\n },\n\n Image: {\n props: z.object({\n src: z.string(),\n width: z.number().nullable(),\n height: z.number().nullable(),\n borderRadius: z.number().nullable(),\n objectFit: z.enum([\"contain\", \"cover\", \"fill\", \"none\"]).nullable(),\n }),\n slots: [],\n description:\n \"Image from a URL. Specify width and/or height to control size. For placeholder images use https://picsum.photos/{width}/{height}?random={n}.\",\n example: {\n src: \"https://picsum.photos/400/300?random=1\",\n width: 400,\n height: 300,\n },\n },\n\n // ==========================================================================\n // Decorative Components\n // ==========================================================================\n\n Divider: {\n props: z.object({\n color: z.string().nullable(),\n thickness: z.number().nullable(),\n marginTop: z.number().nullable(),\n marginBottom: z.number().nullable(),\n }),\n slots: [],\n description: \"Horizontal line separator between content sections.\",\n example: { color: \"#e5e7eb\", thickness: 1 },\n },\n\n Spacer: {\n props: z.object({\n height: z.number().nullable(),\n }),\n slots: [],\n description: \"Empty vertical space between elements.\",\n example: { height: 20 },\n },\n};\n\nexport type StandardComponentDefinitions = typeof standardComponentDefinitions;\n\nexport type StandardComponentProps<\n K extends keyof StandardComponentDefinitions,\n> = StandardComponentDefinitions[K][\"props\"] extends { _output: infer O }\n ? O\n : z.output<StandardComponentDefinitions[K][\"props\"]>;\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ComponentContext, ComponentFn, Components, ImageSchema, ImageSpec, SetState, schema } from './server.mjs';
|
|
2
|
+
export { Spec, StateModel } from '@json-render/core';
|
|
3
|
+
export { b as ComponentRegistry, C as ComponentRenderProps, a as ComponentRenderer, R as RenderOptions, c as renderToPng, r as renderToSvg, s as standardComponents } from './render-DyXCSaYW.mjs';
|
|
4
|
+
export { StandardComponentDefinitions, StandardComponentProps, standardComponentDefinitions } from './catalog.mjs';
|
|
5
|
+
import 'satori';
|
|
6
|
+
import 'react';
|
|
7
|
+
import 'zod';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ComponentContext, ComponentFn, Components, ImageSchema, ImageSpec, SetState, schema } from './server.js';
|
|
2
|
+
export { Spec, StateModel } from '@json-render/core';
|
|
3
|
+
export { b as ComponentRegistry, C as ComponentRenderProps, a as ComponentRenderer, R as RenderOptions, c as renderToPng, r as renderToSvg, s as standardComponents } from './render-DyXCSaYW.js';
|
|
4
|
+
export { StandardComponentDefinitions, StandardComponentProps, standardComponentDefinitions } from './catalog.js';
|
|
5
|
+
import 'satori';
|
|
6
|
+
import 'react';
|
|
7
|
+
import 'zod';
|