@woodylab/payload 0.0.121 → 0.0.123

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.
@@ -0,0 +1,6 @@
1
+ import type { ReactNode } from 'react';
2
+ type CardProps = {
3
+ children?: ReactNode;
4
+ };
5
+ export declare const Card: ({ children }: CardProps) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const Card = ({ children }) => {
3
+ return _jsx("div", { children: children ?? 'Card works' });
4
+ };
@@ -0,0 +1 @@
1
+ export declare function ComponentRenderer({ type, view, data }: any): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,29 @@
1
+ // components/ComponentRenderer.tsx
2
+ 'use client';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { componentRegistry } from './registry';
5
+ function getValueByPath(obj, path) {
6
+ return path.split('.').reduce((acc, key) => acc?.[key], obj);
7
+ }
8
+ export function ComponentRenderer({ type, view, data }) {
9
+ if (type !== 'view')
10
+ return null;
11
+ const rows = data[view.dataSet];
12
+ const Container = componentRegistry[view.component.componentName];
13
+ const Row = componentRegistry[view.rowComponent.componentName];
14
+ if (!Container || !Row)
15
+ return null;
16
+ const containerClassNames = Array.isArray(view.viewMode)
17
+ ? view.viewMode.map((mode) => mode?.className || '').join(' ')
18
+ : '';
19
+ return (_jsx(Container, { className: containerClassNames, children: rows.map((item, i) => {
20
+ const props = {};
21
+ for (const [k, v] of Object.entries(view.rowPropsMapping ?? {})) {
22
+ props[k] = getValueByPath(item, v);
23
+ }
24
+ const rowClassNames = Array.isArray(view.rowViewMode)
25
+ ? view.rowViewMode.map((mode) => mode?.className || '').join(' ')
26
+ : '';
27
+ return _jsx(Row, { ...props, className: rowClassNames }, i);
28
+ }) }));
29
+ }
@@ -0,0 +1,4 @@
1
+ export declare function PageRenderer({ layout, serverData, }: {
2
+ layout: any[];
3
+ serverData: Record<number, any[]>;
4
+ }): Promise<import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // #TODO Gestire doppio caricamento dati:
3
+ // 1 lato payload usando come già fatto api interne di payload mappando i campi in un blocco di tipo view dedicato
4
+ import { resolveInlineComponent } from '../utils/resolveInlineComponent';
5
+ import { ViewBlock } from './ViewBlock';
6
+ // 2 recupero dati sempre lato server chiamando un EP in maniera asincrona e gestendo il corretto binding
7
+ export async function PageRenderer({ layout, serverData, }) {
8
+ const resolvedLayout = layout.map((block, index) => {
9
+ if (block.blockType !== 'view')
10
+ return block;
11
+ console.log(block);
12
+ console.log(serverData);
13
+ return {
14
+ blockType: block.blockType,
15
+ component: block.component,
16
+ viewMode: block.viewMode,
17
+ containerProps: block.containerProps,
18
+ rowComponent: block.rowComponent,
19
+ rowViewMode: block.rowViewMode,
20
+ rowPropsMapping: block.rowPropsMapping,
21
+ rowChildren: block.rowChildren,
22
+ _resolvedData: serverData[index] ?? [],
23
+ _resolvedOk: true,
24
+ };
25
+ });
26
+ return (_jsx(_Fragment, { children: resolvedLayout.map((block, i) => {
27
+ if (block.blockType === 'view') {
28
+ return _jsx(ViewBlock, { ...block }, i);
29
+ }
30
+ const resolved = resolveInlineComponent(block);
31
+ if (!resolved)
32
+ return null;
33
+ const { Component, props } = resolved;
34
+ return _jsx(Component, { ...props }, i);
35
+ }) }));
36
+ }
@@ -0,0 +1 @@
1
+ export declare function ViewBlock(block: any): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { componentRegistry } from './registry';
4
+ function resolveClassName(viewMode) {
5
+ if (Array.isArray(viewMode) && viewMode.length > 0) {
6
+ return viewMode
7
+ .map((vm) => vm?.css.className)
8
+ .filter(Boolean)
9
+ .join(' ');
10
+ }
11
+ return viewMode?.css.className ?? '';
12
+ }
13
+ export function ViewBlock(block) {
14
+ const { component, viewMode, rowComponent, rowViewMode, containerProps = {}, rowPropsMapping = {}, rowChildren = [], _resolvedData = [], _resolvedOk = true, } = block;
15
+ const Container = componentRegistry[component.componentName];
16
+ const Row = componentRegistry[rowComponent.componentName];
17
+ if (!Container || !Row)
18
+ return null;
19
+ if (!_resolvedOk) {
20
+ return (_jsx(Container, { className: resolveClassName(viewMode), children: _jsx("div", { className: "text-red-600", children: "Impossibile caricare i dati" }) }));
21
+ }
22
+ //#TODO gestire rendering di molteplici rowChildren al mometno stampa solo il primo elemento dell'array
23
+ // --- helper per render figli di riga (con sourceProps mapping) ---
24
+ const renderRowChildren = (children, item) => {
25
+ return children.map((child, idx) => {
26
+ const ChildComp = componentRegistry[child.definition?.componentName];
27
+ if (!ChildComp)
28
+ return null;
29
+ const childVM = Array.isArray(child.viewMode) ? child.viewMode[0] : child.viewMode;
30
+ const hasSourceProps = child.sourceProps &&
31
+ typeof child.sourceProps === 'object' &&
32
+ Object.keys(child.sourceProps).length > 0;
33
+ let finalProps = {};
34
+ if (hasSourceProps) {
35
+ for (const [key, path] of Object.entries(child.sourceProps)) {
36
+ // @ts-ignore
37
+ finalProps[key] = path
38
+ .toString()
39
+ .split('.')
40
+ .reduce((acc, k) => acc?.[k], item);
41
+ }
42
+ }
43
+ else {
44
+ // fallback ai props statici
45
+ finalProps = child.staticProps || {};
46
+ }
47
+ return _jsx(ChildComp, { ...finalProps, className: resolveClassName(childVM) }, idx);
48
+ });
49
+ };
50
+ return (_jsx(Container, { className: resolveClassName(viewMode), ...containerProps, children: _resolvedData.map((item, i) => {
51
+ const props = {};
52
+ // mapping valori verso props della card
53
+ for (const [key, path] of Object.entries(rowPropsMapping)) {
54
+ // @ts-ignore
55
+ props[key] = path
56
+ .toString()
57
+ .split('.')
58
+ .reduce((acc, k) => acc?.[k], item);
59
+ }
60
+ return (_jsx(Row, { ...props, className: resolveClassName(rowViewMode), children: rowChildren?.length > 0 ? renderRowChildren(rowChildren, item) : null }, i));
61
+ }) }));
62
+ }
@@ -0,0 +1,5 @@
1
+ export { Card } from './Card';
2
+ export { ViewBlock } from './ViewBlock';
3
+ export { ComponentRenderer } from './ComponentRenderer';
4
+ export { PageRenderer } from './PageRenderer';
5
+ export * from './registry';
@@ -0,0 +1,5 @@
1
+ export { Card } from './Card';
2
+ export { ViewBlock } from './ViewBlock';
3
+ export { ComponentRenderer } from './ComponentRenderer';
4
+ export { PageRenderer } from './PageRenderer';
5
+ export * from './registry';
@@ -0,0 +1 @@
1
+ export declare const componentRegistry: Record<string, any>;
@@ -0,0 +1,5 @@
1
+ // components/registry.ts
2
+ import { Card } from './Card';
3
+ export const componentRegistry = {
4
+ Card,
5
+ };
@@ -0,0 +1,4 @@
1
+ export declare function resolveInlineComponent(block: any): {
2
+ Component: any;
3
+ props: any;
4
+ } | null;
@@ -0,0 +1,35 @@
1
+ // uims/resolveInlineComponent.ts
2
+ import { componentRegistry } from '../react';
3
+ export function resolveInlineComponent(block) {
4
+ const { definition, viewMode } = block;
5
+ if (!definition)
6
+ return null;
7
+ const Component = componentRegistry[definition.componentName];
8
+ if (!Component)
9
+ return null;
10
+ /* Caso CTA (inline typed) */
11
+ if (block.blockType === 'cta-block') {
12
+ return {
13
+ Component,
14
+ props: {
15
+ title: block.title,
16
+ description: block.description,
17
+ action: block.actionLabel
18
+ ? {
19
+ label: block.actionLabel,
20
+ href: block.actionHref,
21
+ }
22
+ : undefined,
23
+ className: viewMode?.css.className ?? definition.defaultStyle,
24
+ },
25
+ };
26
+ }
27
+ /* Caso component-instance generico */
28
+ return {
29
+ Component,
30
+ props: {
31
+ ...(block.props ?? {}),
32
+ className: viewMode?.css.className ?? definition.defaultStyle,
33
+ },
34
+ };
35
+ }
@@ -0,0 +1,4 @@
1
+ export declare function resolveViewRow({ item, rowComponent, rowViewMode, rowPropsMapping }: any): {
2
+ Row: any;
3
+ props: Record<string, any>;
4
+ } | null;
@@ -0,0 +1,15 @@
1
+ // uims/resolveViewRow.ts
2
+ import { componentRegistry } from '../react';
3
+ export function resolveViewRow({ item, rowComponent, rowViewMode, rowPropsMapping }) {
4
+ const Row = componentRegistry[rowComponent.componentName];
5
+ console.log(rowComponent);
6
+ if (!Row)
7
+ return null;
8
+ const props = {};
9
+ for (const prop in rowPropsMapping) {
10
+ const path = rowPropsMapping[prop];
11
+ props[prop] = path.split('.').reduce((acc, key) => acc?.[key], item);
12
+ }
13
+ props.className = rowViewMode?.css.className ?? rowComponent.defaultStyle;
14
+ return { Row, props };
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@woodylab/payload",
3
- "version": "0.0.121",
3
+ "version": "0.0.123",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.esm.js",
@@ -1,11 +0,0 @@
1
- declare function generateCssVars(settings: {
2
- headingFont?: string;
3
- textFont?: string;
4
- foregroundColor?: string;
5
- primaryColor?: string;
6
- secondaryColor?: string;
7
- accentColor?: string;
8
- darkColor?: string;
9
- lightColor?: string;
10
- }): string;
11
- export default generateCssVars;
@@ -1,110 +0,0 @@
1
- import hexToRgb from './hexToRgb';
2
- function generateCssVars(settings) {
3
- // Gestione robusta dei font
4
- const fontWeights = [300, 400, 500, 600, 700, 800];
5
- const fontsToImport = [settings.headingFont, settings.textFont]
6
- .filter(Boolean)
7
- .map((f) => {
8
- if (!f)
9
- return '';
10
- // Aggiungiamo il parametro wght per specificare i pesi da caricare
11
- return `@import url('https://fonts.googleapis.com/css2?family=${f.replace(/ /g, '+')}:wght@${fontWeights.join(';')}&display=swap');`;
12
- })
13
- .join('\n');
14
- const generateOpacityVariants = (color, name) => {
15
- if (!color) {
16
- return '';
17
- }
18
- try {
19
- const rgbValue = hexToRgb(color);
20
- if (!rgbValue ||
21
- typeof rgbValue.r !== 'number' ||
22
- typeof rgbValue.g !== 'number' ||
23
- typeof rgbValue.b !== 'number') {
24
- console.warn(`Impossibile convertire il colore ${name}: ${color}`);
25
- return '';
26
- }
27
- const { r, g, b } = rgbValue;
28
- const opacityVars = Array.from({ length: 9 }, (_, i) => {
29
- const opacity = (i + 1) * 10;
30
- return `--color-${name}-${opacity}: rgba(${r}, ${g}, ${b}, ${opacity / 100});`;
31
- }).join('\n');
32
- return `
33
- --color-${name}: rgb(${r}, ${g}, ${b}); /* Default (opacità 1) */
34
- ${opacityVars}
35
- `;
36
- }
37
- catch (error) {
38
- console.warn(`Errore nella generazione delle varianti di opacità per ${name}: ${error}`);
39
- return '';
40
- }
41
- };
42
- const generateBrightnessVariants = (color, name) => {
43
- if (!color) {
44
- return '';
45
- }
46
- try {
47
- const rgbValue = hexToRgb(color);
48
- if (!rgbValue ||
49
- typeof rgbValue.r !== 'number' ||
50
- typeof rgbValue.g !== 'number' ||
51
- typeof rgbValue.b !== 'number') {
52
- console.warn(`Impossibile convertire il colore ${name}: ${color}`);
53
- return '';
54
- }
55
- const { r, g, b } = rgbValue;
56
- const clamp = (value) => Math.max(0, Math.min(255, Math.round(value)));
57
- const mixWith = (target, amount) => clamp(r + (target - r) * amount) +
58
- ',' +
59
- clamp(g + (target - g) * amount) +
60
- ',' +
61
- clamp(b + (target - b) * amount);
62
- const lighter = Array.from({ length: 4 }, (_, i) => {
63
- const step = (i + 1) / 5;
64
- return `--color-${name}-light-${i + 1}: rgb(${mixWith(255, step)});`;
65
- }).join('\n');
66
- const darker = Array.from({ length: 4 }, (_, i) => {
67
- const step = (i + 1) / 5;
68
- return `--color-${name}-dark-${i + 1}: rgb(${mixWith(0, step)});`;
69
- }).join('\n');
70
- return `--color-${name}: rgb(${r}, ${g}, ${b});
71
- ${lighter}
72
- ${darker}
73
- `;
74
- }
75
- catch (error) {
76
- console.warn(`Errore nella generazione delle varianti di brightness per ${name}: ${error}`);
77
- return '';
78
- }
79
- };
80
- // Genera variabili solo per i colori forniti
81
- const primaryVars = `${generateOpacityVariants(settings.primaryColor, 'primary')} ${generateBrightnessVariants(settings.primaryColor, 'primary')}`;
82
- const secondaryVars = `${generateOpacityVariants(settings.secondaryColor, 'secondary')} ${generateBrightnessVariants(settings.secondaryColor, 'secondary')}`;
83
- const accentVars = `${generateOpacityVariants(settings.secondaryColor, 'accent')} ${generateBrightnessVariants(settings.secondaryColor, 'accent')}`;
84
- const darkVars = `${generateOpacityVariants(settings.secondaryColor, 'dark')} ${generateBrightnessVariants(settings.secondaryColor, 'dark')}`;
85
- const lightVars = `${generateOpacityVariants(settings.secondaryColor, 'light')} ${generateBrightnessVariants(settings.secondaryColor, 'light')}`;
86
- // Genera i valori dei font in modo sicuro
87
- const headingFontValue = settings.headingFont
88
- ? `'${settings.headingFont}', sans-serif`
89
- : 'system-layout, sans-serif';
90
- const textFontValue = settings.textFont
91
- ? `'${settings.textFont}', sans-serif`
92
- : 'system-layout, sans-serif';
93
- return `
94
- ${fontsToImport}
95
-
96
- :root {
97
- --font-heading: ${headingFontValue};
98
- --font-text: ${textFontValue};
99
- --color-white: #ffffff;
100
- --color-black: #000000;
101
- --color-foreground: ${settings.foregroundColor || '#FFFFFF'};
102
- ${primaryVars}
103
- ${secondaryVars}
104
- ${accentVars}
105
- ${darkVars}
106
- ${lightVars}
107
- }
108
- `;
109
- }
110
- export default generateCssVars;