lib-pixelbuild 0.2.2 → 0.3.1
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/dist/builders/PageBuilder.js +42 -29
- package/dist/components/ButtonsComponent.js +6 -5
- package/dist/components/CardComponent.js +13 -7
- package/dist/components/FormComponent.js +3 -2
- package/dist/components/IconComponent.d.ts +5 -0
- package/dist/components/IconComponent.js +12 -0
- package/dist/components/ImageComponent.js +4 -3
- package/dist/components/ListComponent.js +1 -2
- package/dist/components/LoadingComponent.js +2 -2
- package/dist/components/MapComponent.js +10 -11
- package/dist/components/SliderComponent.d.ts +1 -1
- package/dist/components/SliderComponent.js +8 -10
- package/dist/components/SocialIconsComponent.js +3 -4
- package/dist/components/TextComponent.js +3 -2
- package/dist/components/VideoComponent.d.ts +4 -0
- package/dist/components/VideoComponent.js +34 -0
- package/dist/constants/ComponentEnum.d.ts +1 -0
- package/dist/constants/ComponentEnum.js +1 -0
- package/dist/designSystem/baseCss.d.ts +8 -0
- package/dist/designSystem/baseCss.js +406 -0
- package/dist/designSystem/buildSiteCss.d.ts +8 -0
- package/dist/designSystem/buildSiteCss.js +11 -0
- package/dist/designSystem/index.d.ts +6 -0
- package/dist/designSystem/index.js +5 -0
- package/dist/designSystem/theme.d.ts +9 -0
- package/dist/designSystem/theme.js +11 -0
- package/dist/designSystem/themeVars.d.ts +8 -0
- package/dist/designSystem/themeVars.js +9 -0
- package/dist/designSystem/tokens.d.ts +82 -0
- package/dist/designSystem/tokens.js +144 -0
- package/dist/elements/AlertElement.js +4 -4
- package/dist/elements/ButtonElement.js +5 -3
- package/dist/elements/ElementColWrapper.js +2 -2
- package/dist/elements/IconMap.js +2 -2
- package/dist/elements/InputElement.js +10 -9
- package/dist/elements/TextElement.js +4 -0
- package/dist/factories/ComponentFactory.d.ts +2 -1
- package/dist/factories/ComponentFactory.js +28 -11
- package/dist/index.d.ts +16 -3
- package/dist/index.js +14 -1
- package/dist/layouts/Footer.js +16 -5
- package/dist/layouts/Header.js +20 -10
- package/dist/layouts/SiteLayout.js +3 -2
- package/dist/renderers/BlockRenderer.d.ts +8 -0
- package/dist/renderers/BlockRenderer.js +68 -0
- package/dist/types/{SectionColumnType.d.ts → BlockType.d.ts} +2 -6
- package/dist/types/ComponentType.d.ts +3 -0
- package/dist/types/PageType.d.ts +2 -2
- package/dist/types/WebsiteType.d.ts +5 -0
- package/dist/ui/PbAlert.d.ts +10 -0
- package/dist/ui/PbAlert.js +8 -0
- package/dist/ui/PbButton.d.ts +20 -0
- package/dist/ui/PbButton.js +20 -0
- package/dist/ui/PbCol.d.ts +14 -0
- package/dist/ui/PbCol.js +43 -0
- package/dist/ui/PbContainer.d.ts +7 -0
- package/dist/ui/PbContainer.js +17 -0
- package/dist/ui/PbRow.d.ts +7 -0
- package/dist/ui/PbRow.js +17 -0
- package/dist/ui/PbSpinner.d.ts +3 -0
- package/dist/ui/PbSpinner.js +5 -0
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.js +6 -0
- package/dist/utils/imageCustomization.js +1 -3
- package/dist/utils/responsiveStyles.d.ts +2 -2
- package/dist/utils/responsiveStyles.js +10 -19
- package/package.json +1 -6
- package/dist/renderers/SectionRenderer.d.ts +0 -6
- package/dist/renderers/SectionRenderer.js +0 -88
- package/dist/types/SectionType.d.ts +0 -10
- package/dist/types/SectionType.js +0 -1
- /package/dist/types/{SectionColumnType.js → BlockType.js} +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design System tokens.
|
|
3
|
+
*
|
|
4
|
+
* Fontes de verdade para cores, tipografia, espaçamento, raio e sombra do site
|
|
5
|
+
* público. Cada token é exposto como uma variável CSS `--pb-*` e os componentes
|
|
6
|
+
* do `lib-pixelbuild` consomem via `var(--pb-*, <fallback>)`, de forma que um
|
|
7
|
+
* site sem design system configurado continua com aparência padrão.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Valores padrão. Mantidos neutros e modernos para que um site sem
|
|
11
|
+
* personalização não tenha cara de "framework genérico".
|
|
12
|
+
*/
|
|
13
|
+
export const defaultTokens = {
|
|
14
|
+
colors: {
|
|
15
|
+
primary: '#F58220',
|
|
16
|
+
secondary: '#64748B',
|
|
17
|
+
success: '#16A34A',
|
|
18
|
+
danger: '#DC2626',
|
|
19
|
+
warning: '#F59E0B',
|
|
20
|
+
info: '#0EA5E9',
|
|
21
|
+
light: '#F8FAFC',
|
|
22
|
+
dark: '#0F172A',
|
|
23
|
+
background: '#FFFFFF',
|
|
24
|
+
surface: '#FFFFFF',
|
|
25
|
+
text: '#1F2937',
|
|
26
|
+
heading: '#111827',
|
|
27
|
+
muted: '#6B7280',
|
|
28
|
+
border: '#E5E7EB'
|
|
29
|
+
},
|
|
30
|
+
typography: {
|
|
31
|
+
fontFamily: "'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
|
|
32
|
+
fontSizeBase: '16px',
|
|
33
|
+
fontWeightNormal: '400',
|
|
34
|
+
fontWeightBold: '700',
|
|
35
|
+
lineHeight: '1.6'
|
|
36
|
+
},
|
|
37
|
+
spacing: {
|
|
38
|
+
none: '0',
|
|
39
|
+
xs: '4px',
|
|
40
|
+
sm: '8px',
|
|
41
|
+
md: '16px',
|
|
42
|
+
lg: '24px',
|
|
43
|
+
xl: '32px',
|
|
44
|
+
xxl: '48px'
|
|
45
|
+
},
|
|
46
|
+
radius: {
|
|
47
|
+
none: '0',
|
|
48
|
+
sm: '4px',
|
|
49
|
+
md: '8px',
|
|
50
|
+
lg: '12px',
|
|
51
|
+
full: '9999px'
|
|
52
|
+
},
|
|
53
|
+
shadow: {
|
|
54
|
+
none: 'none',
|
|
55
|
+
sm: '0 1px 2px rgba(0,0,0,0.05)',
|
|
56
|
+
md: '0 4px 12px rgba(0,0,0,0.08)',
|
|
57
|
+
lg: '0 8px 24px rgba(0,0,0,0.12)'
|
|
58
|
+
},
|
|
59
|
+
gutter: '1.5rem'
|
|
60
|
+
};
|
|
61
|
+
function mergePartial(base, partial) {
|
|
62
|
+
if (!partial)
|
|
63
|
+
return base;
|
|
64
|
+
const result = Object.assign({}, base);
|
|
65
|
+
for (const key of Object.keys(partial)) {
|
|
66
|
+
const value = partial[key];
|
|
67
|
+
if (value === undefined)
|
|
68
|
+
continue;
|
|
69
|
+
const baseValue = base[key];
|
|
70
|
+
if (typeof baseValue === 'object' && baseValue !== null && typeof value === 'object' && value !== null) {
|
|
71
|
+
;
|
|
72
|
+
result[key] = Object.assign(Object.assign({}, baseValue), value);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
;
|
|
76
|
+
result[key] = value;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
export function mergeTokens(base, partial) {
|
|
82
|
+
const merged = mergePartial(base, partial || {});
|
|
83
|
+
return merged;
|
|
84
|
+
}
|
|
85
|
+
/** Mapeia os tokens para pares `--pb-*` → valor. */
|
|
86
|
+
export function tokenToCssVars(tokens) {
|
|
87
|
+
const { colors, typography, spacing, radius, shadow } = tokens;
|
|
88
|
+
return {
|
|
89
|
+
'--pb-color-primary': colors.primary,
|
|
90
|
+
'--pb-color-secondary': colors.secondary,
|
|
91
|
+
'--pb-color-success': colors.success,
|
|
92
|
+
'--pb-color-danger': colors.danger,
|
|
93
|
+
'--pb-color-warning': colors.warning,
|
|
94
|
+
'--pb-color-info': colors.info,
|
|
95
|
+
'--pb-color-light': colors.light,
|
|
96
|
+
'--pb-color-dark': colors.dark,
|
|
97
|
+
'--pb-color-background': colors.background,
|
|
98
|
+
'--pb-color-surface': colors.surface,
|
|
99
|
+
'--pb-color-text': colors.text,
|
|
100
|
+
'--pb-color-heading': colors.heading,
|
|
101
|
+
'--pb-color-muted': colors.muted,
|
|
102
|
+
'--pb-color-border': colors.border,
|
|
103
|
+
'--pb-font-family': typography.fontFamily,
|
|
104
|
+
'--pb-font-size-base': typography.fontSizeBase,
|
|
105
|
+
'--pb-font-weight-normal': typography.fontWeightNormal,
|
|
106
|
+
'--pb-font-weight-bold': typography.fontWeightBold,
|
|
107
|
+
'--pb-line-height': typography.lineHeight,
|
|
108
|
+
'--pb-space-none': spacing.none,
|
|
109
|
+
'--pb-space-xs': spacing.xs,
|
|
110
|
+
'--pb-space-sm': spacing.sm,
|
|
111
|
+
'--pb-space-md': spacing.md,
|
|
112
|
+
'--pb-space-lg': spacing.lg,
|
|
113
|
+
'--pb-space-xl': spacing.xl,
|
|
114
|
+
'--pb-space-xxl': spacing.xxl,
|
|
115
|
+
'--pb-radius-none': radius.none,
|
|
116
|
+
'--pb-radius-sm': radius.sm,
|
|
117
|
+
'--pb-radius-md': radius.md,
|
|
118
|
+
'--pb-radius-lg': radius.lg,
|
|
119
|
+
'--pb-radius-full': radius.full,
|
|
120
|
+
'--pb-shadow-none': shadow.none,
|
|
121
|
+
'--pb-shadow-sm': shadow.sm,
|
|
122
|
+
'--pb-shadow-md': shadow.md,
|
|
123
|
+
'--pb-shadow-lg': shadow.lg,
|
|
124
|
+
'--pb-gutter': tokens.gutter
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/** Gera o bloco `:root { --pb-*: ... }` a partir dos tokens (com defaults). */
|
|
128
|
+
export function buildTokenCss(tokens) {
|
|
129
|
+
const merged = mergeTokens(defaultTokens, tokens);
|
|
130
|
+
const vars = tokenToCssVars(merged);
|
|
131
|
+
const lines = Object.entries(vars)
|
|
132
|
+
.map(([key, value]) => ` ${key}: ${value};`)
|
|
133
|
+
.join('\n');
|
|
134
|
+
return `:root {\n${lines}\n}`;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Retorna o mapa de variáveis `--pb-*` (com defaults mesclados) para aplicação
|
|
138
|
+
* inline em um elemento raiz — permite que a troca de token reflita em tempo
|
|
139
|
+
* real no preview sem reinjetar o `<head>`.
|
|
140
|
+
*/
|
|
141
|
+
export function buildThemeVars(designSystem) {
|
|
142
|
+
const merged = mergeTokens(defaultTokens, designSystem);
|
|
143
|
+
return tokenToCssVars(merged);
|
|
144
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { PbAlert } from '../ui/PbAlert.js';
|
|
4
4
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
5
5
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
6
6
|
import { getString, getNumber, getBoolean } from '../utils/propertyUtils.js';
|
|
@@ -16,8 +16,8 @@ export function AlertElement({ element, formId }) {
|
|
|
16
16
|
hidden: getBoolean(properties, 'startHidden')
|
|
17
17
|
});
|
|
18
18
|
return () => unregisterElement(element.id);
|
|
19
|
-
}, [element.id, properties.startHidden, registerElement,
|
|
19
|
+
}, [element.id, properties.startHidden, registerElement, unregisterElement, resolvedFormId]);
|
|
20
20
|
if (hidden)
|
|
21
21
|
return null;
|
|
22
|
-
return (_jsx(ElementColWrapper, { element: element, children:
|
|
22
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx(PbAlert, { variant: getString(properties, 'type', 'info'), style: element.styles, title: getString(properties, 'title'), children: _jsx("p", { className: "pb-mb-0", children: getString(properties, 'message') }) }) }));
|
|
23
23
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
|
-
import { Button, Spinner } from 'react-bootstrap';
|
|
4
3
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
4
|
+
import { PbButton } from '../ui/PbButton.js';
|
|
5
|
+
import { PbSpinner } from '../ui/PbSpinner.js';
|
|
5
6
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
6
7
|
import { buttonActionFactory } from '../factories/ButtonActionFactory.js';
|
|
7
8
|
import { ButtonActionEnum } from '../constants/ButtonActionEnum.js';
|
|
@@ -21,7 +22,7 @@ export function ButtonElement({ element, formId }) {
|
|
|
21
22
|
hidden: getBoolean(properties, 'startHidden')
|
|
22
23
|
});
|
|
23
24
|
return () => unregisterElement(element.id);
|
|
24
|
-
}, [element.id, properties.startHidden, registerElement,
|
|
25
|
+
}, [element.id, properties.startHidden, registerElement, unregisterElement, resolvedFormId]);
|
|
25
26
|
async function handleClick(event) {
|
|
26
27
|
var _a, _b, _c;
|
|
27
28
|
if (!properties.path) {
|
|
@@ -70,5 +71,6 @@ export function ButtonElement({ element, formId }) {
|
|
|
70
71
|
? properties.type
|
|
71
72
|
: undefined;
|
|
72
73
|
const size = getString(properties, 'size');
|
|
73
|
-
|
|
74
|
+
const variant = getString(properties, 'variant', buttonType ? 'primary' : getString(properties, 'type', 'primary'));
|
|
75
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx(PbButton, { href: getString(properties, 'path') || undefined, target: properties.path ? getString(properties, 'target', '_self') : undefined, type: buttonType, variant: variant, size: size === 'sm' || size === 'lg' ? size : undefined, disabled: loading, onClick: handleClick, style: element.styles, children: loading ? (_jsxs(_Fragment, { children: [_jsx("output", { "aria-busy": "true", children: _jsx(PbSpinner, { size: "sm" }) }), ' ' + getString(properties, 'message')] })) : (getString(properties, 'text') || getString(properties, 'title')) }) }));
|
|
74
76
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { PbCol } from '../ui/PbCol.js';
|
|
3
3
|
export function ElementColWrapper({ element, children }) {
|
|
4
4
|
var _a;
|
|
5
5
|
const style = {};
|
|
@@ -10,5 +10,5 @@ export function ElementColWrapper({ element, children }) {
|
|
|
10
10
|
if ((_a = element.styles) === null || _a === void 0 ? void 0 : _a.textAlign) {
|
|
11
11
|
style.textAlign = element.styles.textAlign;
|
|
12
12
|
}
|
|
13
|
-
return (_jsx(
|
|
13
|
+
return (_jsx(PbCol, { colId: element.id, width: element.width, offset: element.offset, style: style, "data-pb-element": element.id, children: children }));
|
|
14
14
|
}
|
package/dist/elements/IconMap.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FaArrowRight, FaArrowLeft, FaArrowUp, FaArrowDown, FaChevronRight, FaChevronLeft, FaChevronUp, FaChevronDown, FaLongArrowAltRight, FaLongArrowAltLeft, FaBars, FaTimes, FaCheck, FaPlus, FaMinus, FaSearch, FaHome, FaUser, FaUsers, FaCog, FaInfoCircle, FaQuestionCircle, FaExclamationTriangle, FaCheckCircle, FaTimesCircle, FaExternalLinkAlt, FaDownload, FaUpload, FaSync, FaLock, FaUnlock, FaEye, FaEyeSlash, FaBell, FaStar, FaHeart, FaList, FaTh, FaThLarge, FaFilter, FaPhone, FaEnvelope, FaEnvelopeOpen, FaComment, FaComments, FaQuoteLeft, FaQuoteRight, FaPaperPlane, FaFacebookF, FaInstagram, FaWhatsapp, FaYoutube, FaTwitter, FaLinkedinIn, FaPinterestP, FaShoppingCart, FaShoppingBag, FaCreditCard, FaMoneyBillWave, FaTag, FaTags, FaGift, FaTruck, FaMapMarkerAlt, FaMap, FaMapPin, FaGlobe, FaCompass, FaLocationArrow, FaClock, FaCalendar, FaCalendarAlt, FaHourglassHalf, FaImage, FaImages, FaCamera, FaVideo, FaFilm, FaMusic, FaHeadphones, FaPlay, FaBriefcase, FaBuilding, FaChartBar, FaChartLine, FaChartPie, FaRocket, FaLightbulb, FaTrophy, FaMedal, FaFlag, FaFile, FaFolder, FaLink, FaPencilAlt, FaTrashAlt, FaCopy, FaCloud, FaWifi, FaMobileAlt
|
|
1
|
+
import { FaArrowRight, FaArrowLeft, FaArrowUp, FaArrowDown, FaChevronRight, FaChevronLeft, FaChevronUp, FaChevronDown, FaLongArrowAltRight, FaLongArrowAltLeft, FaBars, FaTimes, FaCheck, FaPlus, FaMinus, FaSearch, FaHome, FaUser, FaUsers, FaCog, FaInfoCircle, FaQuestionCircle, FaExclamationTriangle, FaCheckCircle, FaTimesCircle, FaExternalLinkAlt, FaDownload, FaUpload, FaSync, FaLock, FaUnlock, FaEye, FaEyeSlash, FaBell, FaStar, FaHeart, FaList, FaTh, FaThLarge, FaFilter, FaPhone, FaEnvelope, FaEnvelopeOpen, FaComment, FaComments, FaQuoteLeft, FaQuoteRight, FaPaperPlane, FaFacebookF, FaInstagram, FaWhatsapp, FaYoutube, FaTwitter, FaLinkedinIn, FaPinterestP, FaShoppingCart, FaShoppingBag, FaCreditCard, FaMoneyBillWave, FaTag, FaTags, FaGift, FaTruck, FaMapMarkerAlt, FaMap, FaMapPin, FaGlobe, FaCompass, FaLocationArrow, FaClock, FaCalendar, FaCalendarAlt, FaHourglassHalf, FaImage, FaImages, FaCamera, FaVideo, FaFilm, FaMusic, FaHeadphones, FaPlay, FaBriefcase, FaBuilding, FaChartBar, FaChartLine, FaChartPie, FaRocket, FaLightbulb, FaTrophy, FaMedal, FaFlag, FaFile, FaFolder, FaLink, FaPencilAlt, FaTrashAlt, FaCopy, FaCloud, FaWifi, FaMobileAlt } from 'react-icons/fa';
|
|
2
2
|
export const iconMap = {
|
|
3
3
|
'arrow-right': FaArrowRight,
|
|
4
4
|
'arrow-left': FaArrowLeft,
|
|
@@ -99,5 +99,5 @@ export const iconMap = {
|
|
|
99
99
|
copy: FaCopy,
|
|
100
100
|
cloud: FaCloud,
|
|
101
101
|
wifi: FaWifi,
|
|
102
|
-
mobile: FaMobileAlt
|
|
102
|
+
mobile: FaMobileAlt
|
|
103
103
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
|
-
import { Form } from 'react-bootstrap';
|
|
4
3
|
import { IMaskInput } from 'react-imask';
|
|
5
4
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
6
5
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
@@ -66,12 +65,14 @@ export function InputElement({ element, formId }) {
|
|
|
66
65
|
}
|
|
67
66
|
store.setElementState(element.id, { value: checked ? value : '' });
|
|
68
67
|
};
|
|
68
|
+
const isCheck = element.elementType === ElementTypeEnum.Checkbox || element.elementType === ElementTypeEnum.Radio;
|
|
69
69
|
const renderControl = () => {
|
|
70
|
+
const baseClass = error ? 'pb-form-control-invalid' : '';
|
|
70
71
|
if (element.elementType === ElementTypeEnum.Textarea) {
|
|
71
|
-
return (_jsx("textarea", { defaultValue: getString(properties, 'value'), rows: getNumber(properties, 'rows') || 4, onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `form-
|
|
72
|
+
return (_jsx("textarea", { defaultValue: getString(properties, 'value'), rows: getNumber(properties, 'rows') || 4, onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `pb-form-textarea ${baseClass}`.trim(), style: element.styles }));
|
|
72
73
|
}
|
|
73
74
|
if (element.elementType === ElementTypeEnum.Select) {
|
|
74
|
-
return (_jsx("select", { defaultValue: getString(properties, 'value'), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, className: `form-select${
|
|
75
|
+
return (_jsx("select", { defaultValue: getString(properties, 'value'), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, className: `pb-form-select ${baseClass}`.trim(), style: element.styles, children: options.map((option, index) => {
|
|
75
76
|
var _a, _b, _c, _d;
|
|
76
77
|
const data = typeof option === 'object' && option !== null ? option : null;
|
|
77
78
|
const value = String((_a = data === null || data === void 0 ? void 0 : data.value) !== null && _a !== void 0 ? _a : option);
|
|
@@ -79,17 +80,17 @@ export function InputElement({ element, formId }) {
|
|
|
79
80
|
return (_jsx("option", { value: value, children: text }, `${value}-${index}`));
|
|
80
81
|
}) }));
|
|
81
82
|
}
|
|
82
|
-
if (
|
|
83
|
+
if (isCheck) {
|
|
83
84
|
const value = getString(properties, 'value', 'on');
|
|
84
|
-
return (_jsxs("div", { className: "form-check", children: [_jsx("input", { id: controlId, type: element.elementType, defaultChecked: getBoolean(properties, 'checked'), value: value, onChange: (e) => setCheckedValue(e.target.checked, value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, className: `form-check-input${error ? '
|
|
85
|
+
return (_jsxs("div", { className: "pb-form-check", children: [_jsx("input", { id: controlId, type: element.elementType, defaultChecked: getBoolean(properties, 'checked'), value: value, onChange: (e) => setCheckedValue(e.target.checked, value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, className: `pb-form-check-input${error ? ' pb-form-check-invalid' : ''}`, style: element.styles }), label && (_jsx("label", { className: "pb-form-check-label", htmlFor: controlId, children: label }))] }));
|
|
85
86
|
}
|
|
86
87
|
if (element.elementType === ElementTypeEnum.File) {
|
|
87
|
-
return (_jsx("div", { className: "alert alert-secondary", role: "status", style: element.styles, children: "File upload not available in this form." }));
|
|
88
|
+
return (_jsx("div", { className: "pb-alert pb-alert-secondary", role: "status", style: element.styles, children: "File upload not available in this form." }));
|
|
88
89
|
}
|
|
89
90
|
if (hasMask) {
|
|
90
|
-
return (_jsx(IMaskInput, { mask: getString(properties, 'mask'), defaultValue: getString(properties, 'value'), onAccept: handleAccept, onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `form-control${
|
|
91
|
+
return (_jsx(IMaskInput, { mask: getString(properties, 'mask'), defaultValue: getString(properties, 'value'), onAccept: handleAccept, onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `pb-form-control ${baseClass}`.trim(), style: element.styles }));
|
|
91
92
|
}
|
|
92
|
-
return (_jsx("input", { type: getString(properties, 'type', 'text'), defaultValue: getString(properties, 'value'), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `form-control${
|
|
93
|
+
return (_jsx("input", { type: getString(properties, 'type', 'text'), defaultValue: getString(properties, 'value'), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `pb-form-control ${baseClass}`.trim(), style: element.styles }));
|
|
93
94
|
};
|
|
94
|
-
return (_jsx(ElementColWrapper, { element: element, children: _jsxs(
|
|
95
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsxs("div", { className: "pb-form-group", id: controlId, children: [label && !isCheck && (_jsx("label", { className: "pb-form-label", htmlFor: controlId, children: label })), renderControl(), error && (_jsx("div", { className: "pb-invalid-feedback", role: "alert", children: errorMessage }))] }) }));
|
|
95
96
|
}
|
|
@@ -4,10 +4,14 @@ import { ElementColWrapper } from './ElementColWrapper.js';
|
|
|
4
4
|
export function TextElement({ element }) {
|
|
5
5
|
const properties = element.properties;
|
|
6
6
|
const text = String(properties.text || properties.title || properties.message || '');
|
|
7
|
+
const isSimple = properties.editorType === 'simple';
|
|
7
8
|
if (element.elementType === 'title') {
|
|
8
9
|
const tag = String(properties.tag || 'h2');
|
|
9
10
|
const TitleTag = tag;
|
|
10
11
|
return (_jsx(ElementColWrapper, { element: element, children: _jsx(TitleTag, { style: Object.assign({ margin: 0 }, element.styles), children: text }) }));
|
|
11
12
|
}
|
|
13
|
+
if (isSimple) {
|
|
14
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx("div", { style: Object.assign({ whiteSpace: 'pre-wrap' }, element.styles), children: text }) }));
|
|
15
|
+
}
|
|
12
16
|
return (_jsx(ElementColWrapper, { element: element, children: _jsx("div", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(text) }, style: element.styles }) }));
|
|
13
17
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ComponentType } from '../types/ComponentType.js';
|
|
3
|
+
import type { ComponentDefaults } from '../types/WebsiteType.js';
|
|
3
4
|
export declare class ComponentFactory {
|
|
4
|
-
build(component: ComponentType, editionMode?: boolean): React.ReactElement | null;
|
|
5
|
+
build(component: ComponentType, editionMode?: boolean, defaults?: ComponentDefaults): React.ReactElement | null;
|
|
5
6
|
}
|
|
@@ -8,32 +8,49 @@ import { SliderComponent } from '../components/SliderComponent.js';
|
|
|
8
8
|
import { CardComponent } from '../components/CardComponent.js';
|
|
9
9
|
import { MapComponent } from '../components/MapComponent.js';
|
|
10
10
|
import { ButtonsComponent } from '../components/ButtonsComponent.js';
|
|
11
|
+
import { IconComponent } from '../components/IconComponent.js';
|
|
12
|
+
import { VideoComponent } from '../components/VideoComponent.js';
|
|
13
|
+
/**
|
|
14
|
+
* Aplica os estilos padrão do design system (`componentDefaults`) antes dos
|
|
15
|
+
* estilos da instância — o override da instância prevalece.
|
|
16
|
+
*/
|
|
17
|
+
function applyDefaults(component, defaults) {
|
|
18
|
+
const typeDefaults = defaults === null || defaults === void 0 ? void 0 : defaults[component.componentType];
|
|
19
|
+
if (!typeDefaults || Object.keys(typeDefaults).length === 0)
|
|
20
|
+
return component;
|
|
21
|
+
return Object.assign(Object.assign({}, component), { styles: Object.assign(Object.assign({}, typeDefaults), component.styles) });
|
|
22
|
+
}
|
|
11
23
|
export class ComponentFactory {
|
|
12
|
-
build(component, editionMode = false) {
|
|
13
|
-
|
|
24
|
+
build(component, editionMode = false, defaults) {
|
|
25
|
+
const resolved = applyDefaults(component, defaults);
|
|
26
|
+
switch (resolved.componentType) {
|
|
14
27
|
case ComponentTypeEnum.Text:
|
|
15
28
|
case ComponentTypeEnum.TextWithImage:
|
|
16
29
|
case ComponentTypeEnum.HeroBanner:
|
|
17
|
-
return _jsx(TextComponent, { component:
|
|
30
|
+
return _jsx(TextComponent, { component: resolved }, resolved.id);
|
|
18
31
|
case ComponentTypeEnum.Image:
|
|
19
|
-
return _jsx(ImageComponent, { component:
|
|
32
|
+
return _jsx(ImageComponent, { component: resolved }, resolved.id);
|
|
20
33
|
case ComponentTypeEnum.List:
|
|
21
|
-
return _jsx(ListComponent, { component:
|
|
34
|
+
return _jsx(ListComponent, { component: resolved }, resolved.id);
|
|
22
35
|
case ComponentTypeEnum.Slider:
|
|
23
36
|
case ComponentTypeEnum.Gallery:
|
|
24
37
|
case ComponentTypeEnum.Testimonials:
|
|
25
|
-
return _jsx(SliderComponent, { component:
|
|
38
|
+
return _jsx(SliderComponent, { component: resolved, editionMode: editionMode }, resolved.id);
|
|
26
39
|
case ComponentTypeEnum.Form:
|
|
27
|
-
return _jsx(FormComponent, { component:
|
|
40
|
+
return _jsx(FormComponent, { component: resolved }, resolved.id);
|
|
28
41
|
case ComponentTypeEnum.Card:
|
|
29
42
|
case ComponentTypeEnum.Faq:
|
|
30
|
-
return _jsx(CardComponent, { component:
|
|
43
|
+
return _jsx(CardComponent, { component: resolved }, resolved.id);
|
|
31
44
|
case ComponentTypeEnum.Map:
|
|
32
|
-
return _jsx(MapComponent, { component:
|
|
45
|
+
return _jsx(MapComponent, { component: resolved }, resolved.id);
|
|
33
46
|
case ComponentTypeEnum.Buttons:
|
|
34
|
-
return _jsx(ButtonsComponent, { component:
|
|
47
|
+
return _jsx(ButtonsComponent, { component: resolved }, resolved.id);
|
|
48
|
+
case ComponentTypeEnum.Icon:
|
|
49
|
+
return _jsx(IconComponent, { component: resolved }, resolved.id);
|
|
50
|
+
case ComponentTypeEnum.Video:
|
|
51
|
+
return _jsx(VideoComponent, { component: resolved }, resolved.id);
|
|
35
52
|
default:
|
|
36
|
-
throw new Error('Invalid component type: ' +
|
|
53
|
+
throw new Error('Invalid component type: ' + resolved.componentType);
|
|
37
54
|
}
|
|
38
55
|
}
|
|
39
56
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export type { RawWebsiteType } from './types/RawWebsiteType.js';
|
|
2
2
|
export type { WebsiteType } from './types/WebsiteType.js';
|
|
3
3
|
export type { PageType } from './types/PageType.js';
|
|
4
|
-
export type {
|
|
5
|
-
export type { SectionColumnType } from './types/SectionColumnType.js';
|
|
4
|
+
export type { BlockType } from './types/BlockType.js';
|
|
6
5
|
export type { ColumnWidthType } from './types/ColumnWidthType.js';
|
|
7
6
|
export type { ComponentType } from './types/ComponentType.js';
|
|
8
7
|
export type { ElementType } from './types/ElementType.js';
|
|
@@ -12,7 +11,9 @@ export { Header } from './layouts/Header.js';
|
|
|
12
11
|
export { Footer } from './layouts/Footer.js';
|
|
13
12
|
export { SiteLayout, type EmailApiConfig } from './layouts/SiteLayout.js';
|
|
14
13
|
export { PageBuilder } from './builders/PageBuilder.js';
|
|
15
|
-
export {
|
|
14
|
+
export { BlockRenderer } from './renderers/BlockRenderer.js';
|
|
15
|
+
export { IconComponent } from './components/IconComponent.js';
|
|
16
|
+
export { VideoComponent } from './components/VideoComponent.js';
|
|
16
17
|
export { LoadingComponent } from './components/LoadingComponent.js';
|
|
17
18
|
export { ComponentFactory } from './factories/ComponentFactory.js';
|
|
18
19
|
export { ElementFactory } from './factories/ElementFactory.js';
|
|
@@ -24,3 +25,15 @@ export { analyticsService } from './services/AnalyticsService.js';
|
|
|
24
25
|
export { buttonActionFactory } from './factories/ButtonActionFactory.js';
|
|
25
26
|
export type { EmailServiceConfig, EmailSendOptions } from './services/EmailService.js';
|
|
26
27
|
export type { EmailSettingsType } from './types/EmailSettingsType.js';
|
|
28
|
+
export type { DesignTokens, DesignColors, DesignTypography, DesignSpacing, DesignRadius, DesignShadow, PartialDesignTokens, DeepPartial } from './designSystem/tokens.js';
|
|
29
|
+
export { defaultTokens, mergeTokens, tokenToCssVars, buildTokenCss, buildThemeVars } from './designSystem/tokens.js';
|
|
30
|
+
export { baseCss } from './designSystem/baseCss.js';
|
|
31
|
+
export { buildSiteCss } from './designSystem/buildSiteCss.js';
|
|
32
|
+
export { themeVarsStyle } from './designSystem/themeVars.js';
|
|
33
|
+
export { ThemeStyle } from './designSystem/theme.js';
|
|
34
|
+
export { PbContainer } from './ui/PbContainer.js';
|
|
35
|
+
export { PbRow } from './ui/PbRow.js';
|
|
36
|
+
export { PbCol } from './ui/PbCol.js';
|
|
37
|
+
export { PbButton } from './ui/PbButton.js';
|
|
38
|
+
export { PbSpinner } from './ui/PbSpinner.js';
|
|
39
|
+
export { PbAlert } from './ui/PbAlert.js';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,9 @@ export { Header } from './layouts/Header.js';
|
|
|
2
2
|
export { Footer } from './layouts/Footer.js';
|
|
3
3
|
export { SiteLayout } from './layouts/SiteLayout.js';
|
|
4
4
|
export { PageBuilder } from './builders/PageBuilder.js';
|
|
5
|
-
export {
|
|
5
|
+
export { BlockRenderer } from './renderers/BlockRenderer.js';
|
|
6
|
+
export { IconComponent } from './components/IconComponent.js';
|
|
7
|
+
export { VideoComponent } from './components/VideoComponent.js';
|
|
6
8
|
export { LoadingComponent } from './components/LoadingComponent.js';
|
|
7
9
|
export { ComponentFactory } from './factories/ComponentFactory.js';
|
|
8
10
|
export { ElementFactory } from './factories/ElementFactory.js';
|
|
@@ -12,3 +14,14 @@ export { ElementTypeEnum } from './constants/ElementEnum.js';
|
|
|
12
14
|
export { ButtonActionEnum } from './constants/ButtonActionEnum.js';
|
|
13
15
|
export { analyticsService } from './services/AnalyticsService.js';
|
|
14
16
|
export { buttonActionFactory } from './factories/ButtonActionFactory.js';
|
|
17
|
+
export { defaultTokens, mergeTokens, tokenToCssVars, buildTokenCss, buildThemeVars } from './designSystem/tokens.js';
|
|
18
|
+
export { baseCss } from './designSystem/baseCss.js';
|
|
19
|
+
export { buildSiteCss } from './designSystem/buildSiteCss.js';
|
|
20
|
+
export { themeVarsStyle } from './designSystem/themeVars.js';
|
|
21
|
+
export { ThemeStyle } from './designSystem/theme.js';
|
|
22
|
+
export { PbContainer } from './ui/PbContainer.js';
|
|
23
|
+
export { PbRow } from './ui/PbRow.js';
|
|
24
|
+
export { PbCol } from './ui/PbCol.js';
|
|
25
|
+
export { PbButton } from './ui/PbButton.js';
|
|
26
|
+
export { PbSpinner } from './ui/PbSpinner.js';
|
|
27
|
+
export { PbAlert } from './ui/PbAlert.js';
|
package/dist/layouts/Footer.js
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import DOMPurify from 'dompurify';
|
|
3
|
-
import {
|
|
3
|
+
import { PbContainer } from '../ui/PbContainer.js';
|
|
4
|
+
import { PbRow } from '../ui/PbRow.js';
|
|
5
|
+
import { PbCol } from '../ui/PbCol.js';
|
|
4
6
|
import { SocialIconsComponent } from '../components/SocialIconsComponent.js';
|
|
5
7
|
export function Footer({ website }) {
|
|
6
|
-
var _a;
|
|
8
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7
9
|
const social = (_a = website.properties) === null || _a === void 0 ? void 0 : _a.social;
|
|
8
|
-
const
|
|
9
|
-
const styles = website.footer.styles;
|
|
10
|
-
|
|
10
|
+
const footerProps = ((_b = website.footer) === null || _b === void 0 ? void 0 : _b.properties) || {};
|
|
11
|
+
const styles = ((_c = website.footer) === null || _c === void 0 ? void 0 : _c.styles) || {};
|
|
12
|
+
const fluid = styles.fluid || undefined;
|
|
13
|
+
const baseStyle = Object.assign({}, styles);
|
|
14
|
+
delete baseStyle.fluid;
|
|
15
|
+
delete baseStyle.responsive;
|
|
16
|
+
const textStyle = {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
flexDirection: 'column',
|
|
19
|
+
alignItems: 'center'
|
|
20
|
+
};
|
|
21
|
+
return (_jsx(PbContainer, { fluid: fluid || undefined, children: _jsx("footer", { id: "footer", className: "pb-footer", style: { backgroundColor: styles.backgroundColor }, children: _jsxs(PbRow, { children: [_jsx(PbCol, { width: { xs: 12 }, style: { marginBottom: '30px' }, children: social && _jsx(SocialIconsComponent, { social: social, color: styles.socialIconColor || styles.color }) }), _jsx(PbCol, { width: { xs: 12 }, style: textStyle, children: _jsx("div", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize((_d = footerProps.text1) !== null && _d !== void 0 ? _d : '') } }) }), _jsx(PbCol, { width: { xs: 12 }, style: textStyle, children: _jsx("div", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize((_e = footerProps.text2) !== null && _e !== void 0 ? _e : '') } }) }), _jsx(PbCol, { width: { xs: 12 }, style: { display: 'flex', justifyContent: 'center' }, children: _jsx("div", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize((_f = footerProps.text3) !== null && _f !== void 0 ? _f : '') } }) }), _jsxs(PbCol, { width: { xs: 12 }, children: [_jsx("hr", { className: "pb-footer-divider" }), _jsxs("p", { className: "pb-text-center pb-mb-0", style: baseStyle, children: ["\u00A9 ", new Date().getFullYear(), " ", website.name] })] })] }) }) }));
|
|
11
22
|
}
|
package/dist/layouts/Header.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo, useCallback } from 'react';
|
|
2
|
+
import { useMemo, useCallback, useState } from 'react';
|
|
3
3
|
import { useLocation } from 'react-router-dom';
|
|
4
|
-
import {
|
|
4
|
+
import { PbContainer } from '../ui/PbContainer.js';
|
|
5
5
|
export function Header({ website, imageBaseUrl }) {
|
|
6
|
-
|
|
7
|
-
const
|
|
6
|
+
var _a, _b;
|
|
7
|
+
const headerProperties = ((_a = website.header) === null || _a === void 0 ? void 0 : _a.properties) || {};
|
|
8
|
+
const headerStyles = ((_b = website.header) === null || _b === void 0 ? void 0 : _b.styles) || {};
|
|
8
9
|
const location = useLocation();
|
|
10
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
9
11
|
const menuPages = useMemo(() => (website.pages || []).filter((p) => p.menu === true).sort((a, b) => (a.menuOrder || 0) - (b.menuOrder || 0)), [website.pages]);
|
|
10
12
|
const isActive = useCallback((path) => {
|
|
11
13
|
const currentPath = location.pathname;
|
|
@@ -18,6 +20,7 @@ export function Header({ website, imageBaseUrl }) {
|
|
|
18
20
|
const logoAlign = headerProperties.logoAlign || 'center';
|
|
19
21
|
const menuLinkColor = headerStyles.menuLinkColor || headerStyles.color || undefined;
|
|
20
22
|
const menuActiveLinkColor = headerStyles.menuActiveLinkColor || headerStyles.menuLinkColor || headerStyles.color || undefined;
|
|
23
|
+
const textAlign = headerStyles.textAlign || 'left';
|
|
21
24
|
const brandStyle = { padding: 0 };
|
|
22
25
|
if (showMenu) {
|
|
23
26
|
if (logoAlign === 'right')
|
|
@@ -36,17 +39,24 @@ export function Header({ website, imageBaseUrl }) {
|
|
|
36
39
|
else if (logoAlign === 'right') {
|
|
37
40
|
brandStyle.marginLeft = 'auto';
|
|
38
41
|
}
|
|
39
|
-
|
|
42
|
+
const innerStyle = { textAlign };
|
|
43
|
+
if (textAlign === 'center')
|
|
44
|
+
innerStyle.justifyContent = 'center';
|
|
45
|
+
else if (textAlign === 'right')
|
|
46
|
+
innerStyle.justifyContent = 'flex-end';
|
|
47
|
+
const closeMenu = useCallback(() => setMenuOpen(false), []);
|
|
48
|
+
return (_jsx("header", { className: "pb-header", style: {
|
|
49
|
+
backgroundColor: headerStyles.backgroundColor || undefined,
|
|
50
|
+
color: headerStyles.color || undefined
|
|
51
|
+
}, children: _jsx(PbContainer, { fluid: headerStyles.fluid || undefined, children: _jsxs("div", { className: "pb-header-inner", style: innerStyle, children: [headerProperties.showLogo && logoUrl && (_jsx("a", { className: "pb-brand", href: "/", style: brandStyle, "aria-label": "P\u00E1gina inicial", children: _jsx("img", { src: logoUrl, width: Number(headerProperties.logoWidth) || 200, alt: "Logo" }) })), showMenu && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "pb-nav-toggle", "aria-label": menuOpen ? 'Fechar menu' : 'Abrir menu', "aria-expanded": menuOpen, onClick: () => setMenuOpen((open) => !open), children: "\u2630" }), _jsx("nav", { className: `pb-nav${menuOpen ? ' pb-nav-open' : ''}`, "aria-label": "Menu principal", children: menuPages.map((p) => {
|
|
40
52
|
const active = isActive(p.path);
|
|
41
|
-
return (_jsx(
|
|
53
|
+
return (_jsx("a", { href: p.path, onClick: closeMenu, className: `pb-nav-link${active ? ' pb-nav-link-active' : ''}`, style: {
|
|
42
54
|
color: active ? menuActiveLinkColor : menuLinkColor,
|
|
43
55
|
fontSize: headerStyles.menuFontSize || undefined,
|
|
44
56
|
letterSpacing: headerStyles.menuLetterSpacing || undefined,
|
|
45
57
|
textTransform: headerStyles.menuTextTransform || undefined,
|
|
46
58
|
margin: '0 12px',
|
|
47
|
-
paddingBottom: '4px'
|
|
48
|
-
borderBottom: active && menuActiveLinkColor ? `2px solid ${menuActiveLinkColor}` : '2px solid transparent',
|
|
49
|
-
transition: 'color 0.3s, border-color 0.3s',
|
|
59
|
+
paddingBottom: '4px'
|
|
50
60
|
}, children: p.title }, p.id));
|
|
51
|
-
}) }) })] })
|
|
61
|
+
}) })] }))] }) }) }));
|
|
52
62
|
}
|
|
@@ -4,10 +4,11 @@ import { Outlet } from 'react-router-dom';
|
|
|
4
4
|
import { Helmet } from 'react-helmet-async';
|
|
5
5
|
import { Header } from './Header.js';
|
|
6
6
|
import { Footer } from './Footer.js';
|
|
7
|
+
import { ThemeStyle } from '../designSystem/theme.js';
|
|
7
8
|
import { buildFontFamily, buildGoogleFontsHref } from '../utils/fonts.js';
|
|
8
9
|
import { buttonActionFactory } from '../factories/ButtonActionFactory.js';
|
|
9
10
|
export function SiteLayout({ website, imageBaseUrl, emailApi }) {
|
|
10
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
11
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
11
12
|
const fontFamily = buildFontFamily((_a = website.styles) === null || _a === void 0 ? void 0 : _a.fontFamily);
|
|
12
13
|
const fontHref = buildGoogleFontsHref((_b = website.styles) === null || _b === void 0 ? void 0 : _b.fontFamily);
|
|
13
14
|
useEffect(() => {
|
|
@@ -35,5 +36,5 @@ export function SiteLayout({ website, imageBaseUrl, emailApi }) {
|
|
|
35
36
|
(_f = (_e = website.properties) === null || _e === void 0 ? void 0 : _e.email) === null || _f === void 0 ? void 0 : _f.recipientName,
|
|
36
37
|
(_h = (_g = website.properties) === null || _g === void 0 ? void 0 : _g.email) === null || _h === void 0 ? void 0 : _h.subject
|
|
37
38
|
]);
|
|
38
|
-
return (_jsxs(_Fragment, { children: [fontHref && (_jsxs(Helmet, { children: [_jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "" }), _jsx("link", { href: fontHref, rel: "stylesheet" })] })), _jsxs("div", { id: "site-layout", style: { backgroundColor: website.styles.backgroundColor, color: website.styles.color, fontFamily }, children: [_jsx(Header, { website: website, imageBaseUrl: imageBaseUrl }), _jsx(Outlet, {}), _jsx(Footer, { website: website })] })] }));
|
|
39
|
+
return (_jsxs(_Fragment, { children: [_jsx(ThemeStyle, { designSystem: website.designSystem }), fontHref && (_jsxs(Helmet, { children: [_jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "" }), _jsx("link", { href: fontHref, rel: "stylesheet" })] })), _jsxs("div", { id: "site-layout", className: "pb-root", style: { backgroundColor: (_j = website.styles) === null || _j === void 0 ? void 0 : _j.backgroundColor, color: (_k = website.styles) === null || _k === void 0 ? void 0 : _k.color, fontFamily }, children: [_jsx(Header, { website: website, imageBaseUrl: imageBaseUrl }), _jsx(Outlet, {}), _jsx(Footer, { website: website })] })] }));
|
|
39
40
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BlockType } from '../types/BlockType.js';
|
|
2
|
+
import type { ComponentDefaults } from '../types/WebsiteType.js';
|
|
3
|
+
declare const BlockRenderer: import("react").NamedExoticComponent<{
|
|
4
|
+
readonly blocks: BlockType[];
|
|
5
|
+
readonly editionMode?: boolean;
|
|
6
|
+
readonly componentDefaults?: ComponentDefaults;
|
|
7
|
+
}>;
|
|
8
|
+
export { BlockRenderer };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useMemo } from 'react';
|
|
3
|
+
import { PbContainer } from '../ui/PbContainer.js';
|
|
4
|
+
import { ComponentFactory } from '../factories/ComponentFactory.js';
|
|
5
|
+
import { orderBySort } from '../utils/orderBySort.js';
|
|
6
|
+
import { buildResponsiveCss } from '../utils/responsiveStyles.js';
|
|
7
|
+
const componentFactory = new ComponentFactory();
|
|
8
|
+
function gridClass(id) {
|
|
9
|
+
return `pixelbuild-grid-${String(id).replace(/[^a-zA-Z0-9_-]/g, '_')}`;
|
|
10
|
+
}
|
|
11
|
+
const BlockGrid = memo(function BlockGrid({ block, editionMode, componentDefaults }) {
|
|
12
|
+
const grid = gridClass(block.id);
|
|
13
|
+
const components = orderBySort(block.components);
|
|
14
|
+
const css = useMemo(() => {
|
|
15
|
+
const rules = components
|
|
16
|
+
.map((component) => {
|
|
17
|
+
var _a, _b, _c;
|
|
18
|
+
const properties = component.properties || {};
|
|
19
|
+
const row = Math.max(0, Number(properties.row) || 0);
|
|
20
|
+
const rowSpan = Math.max(1, Number(properties.rowSpan) || 1);
|
|
21
|
+
const xs = ((_a = component.width) === null || _a === void 0 ? void 0 : _a.xs) || 12;
|
|
22
|
+
const sm = ((_b = component.width) === null || _b === void 0 ? void 0 : _b.sm) || xs;
|
|
23
|
+
const md = ((_c = component.width) === null || _c === void 0 ? void 0 : _c.md) || sm;
|
|
24
|
+
const cls = gridClass(component.id);
|
|
25
|
+
return [
|
|
26
|
+
`.${grid} .${cls}{grid-column:span ${xs};grid-row:auto;min-width:0}`,
|
|
27
|
+
`@media (min-width:576px){.${grid} .${cls}{grid-column:span ${sm}}}`,
|
|
28
|
+
`@media (min-width:768px){.${grid} .${cls}{grid-column:span ${md};grid-row:${row + 1}/span ${rowSpan}}}`
|
|
29
|
+
].join('');
|
|
30
|
+
})
|
|
31
|
+
.join('');
|
|
32
|
+
return `.${grid}{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--pb-gutter,1rem)}${rules}`;
|
|
33
|
+
}, [grid, components]);
|
|
34
|
+
if (editionMode && components.length === 0) {
|
|
35
|
+
return (_jsxs("div", { "data-pixelbuild-empty-block": block.id, style: {
|
|
36
|
+
minHeight: 80,
|
|
37
|
+
display: 'flex',
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
justifyContent: 'center',
|
|
40
|
+
gap: 6,
|
|
41
|
+
border: '1.5px dashed #c4d0dc',
|
|
42
|
+
color: '#94a3b8',
|
|
43
|
+
fontSize: 13,
|
|
44
|
+
cursor: 'pointer',
|
|
45
|
+
textAlign: 'center',
|
|
46
|
+
borderRadius: 8
|
|
47
|
+
}, children: [_jsx("span", { style: { fontSize: 18, lineHeight: 1 }, children: "+" }), "Adicionar componente"] }));
|
|
48
|
+
}
|
|
49
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: css }), _jsx("div", { className: grid, children: components.map((component) => (_jsx("div", { className: gridClass(component.id), children: componentFactory.build(component, editionMode, componentDefaults) }, component.id))) })] }));
|
|
50
|
+
});
|
|
51
|
+
const BlockContent = memo(function BlockContent({ block, editionMode, componentDefaults }) {
|
|
52
|
+
const content = useMemo(() => _jsx(BlockGrid, { block: block, editionMode: editionMode, componentDefaults: componentDefaults }), [block, editionMode, componentDefaults]);
|
|
53
|
+
if (block.sectionType === 'container-fluid') {
|
|
54
|
+
return (_jsx(PbContainer, { fluid: true, "data-pb-block": block.id, style: block.styles, children: content }));
|
|
55
|
+
}
|
|
56
|
+
if (block.sectionType === 'container') {
|
|
57
|
+
return (_jsx(PbContainer, { "data-pb-block": block.id, style: block.styles, children: content }));
|
|
58
|
+
}
|
|
59
|
+
return _jsx(PbContainer, { fluid: true, children: content });
|
|
60
|
+
});
|
|
61
|
+
const BlockRenderer = memo(function BlockRenderer({ blocks, editionMode = false, componentDefaults }) {
|
|
62
|
+
const sorted = useMemo(() => orderBySort(blocks || []), [blocks]);
|
|
63
|
+
if (sorted.length === 0) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: buildResponsiveCss(sorted) }), sorted.map((block) => (_jsx(BlockContent, { block: block, editionMode: editionMode, componentDefaults: componentDefaults }, block.id)))] }));
|
|
67
|
+
});
|
|
68
|
+
export { BlockRenderer };
|