lib-pixelbuild 0.3.9 → 0.4.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 +2 -1
- package/dist/components/ButtonsComponent.js +2 -2
- package/dist/components/CardComponent.js +4 -51
- package/dist/components/DividerComponent.d.ts +5 -0
- package/dist/components/DividerComponent.js +33 -0
- package/dist/components/FormComponent.js +2 -2
- package/dist/components/HeroComponent.d.ts +5 -0
- package/dist/components/HeroComponent.js +51 -0
- package/dist/components/IconComponent.js +2 -2
- package/dist/components/ImageComponent.js +7 -3
- package/dist/components/ListComponent.js +2 -1
- package/dist/components/MapComponent.js +2 -1
- package/dist/components/SliderComponent.js +24 -9
- package/dist/components/TextComponent.js +2 -2
- package/dist/components/VideoComponent.js +7 -2
- package/dist/constants/ComponentEnum.d.ts +1 -0
- package/dist/constants/ComponentEnum.js +2 -1
- package/dist/designSystem/baseCss.d.ts +1 -1
- package/dist/designSystem/baseCss.js +1 -0
- package/dist/designSystem/tokens.d.ts +1 -0
- package/dist/designSystem/tokens.js +2 -0
- package/dist/factories/ComponentFactory.js +6 -1
- package/dist/ui/PbComponentShell.d.ts +8 -0
- package/dist/ui/PbComponentShell.js +12 -0
- package/dist/utils/componentShell.d.ts +10 -0
- package/dist/utils/componentShell.js +41 -0
- package/dist/utils/customCss.d.ts +8 -0
- package/dist/utils/customCss.js +27 -0
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { Suspense, memo, useMemo } from 'react';
|
|
|
3
3
|
import { Helmet } from 'react-helmet-async';
|
|
4
4
|
import { BlockRenderer } from '../renderers/BlockRenderer.js';
|
|
5
5
|
import { buildResponsiveCssForStyles } from '../utils/responsiveStyles.js';
|
|
6
|
+
import { collectCustomCss } from '../utils/customCss.js';
|
|
6
7
|
import { buildFontFamily } from '../utils/fonts.js';
|
|
7
8
|
function mergeStyles(websiteStyles, pageStyles) {
|
|
8
9
|
const merged = Object.assign({}, (websiteStyles || {}));
|
|
@@ -60,6 +61,6 @@ const PageBuilder = memo(function PageBuilder({ website, page, editionMode }) {
|
|
|
60
61
|
(_d = designSystem === null || designSystem === void 0 ? void 0 : designSystem.typography) === null || _d === void 0 ? void 0 : _d.fontSizeBase,
|
|
61
62
|
mergedStyles
|
|
62
63
|
]);
|
|
63
|
-
return (_jsxs(Suspense, { fallback: _jsx("div", { children: ((_e = website.properties) === null || _e === void 0 ? void 0 : _e.loadingMessage) || 'Carregando...' }), children: [!editionMode && (_jsxs(Helmet, { children: [_jsx("title", { children: page.title }), _jsx("meta", { name: "description", content: page.title }), _jsx("meta", { property: "og:title", content: page.title }), _jsx("meta", { property: "og:description", content: page.title }), _jsx("meta", { property: "og:image", content: page.title })] })), _jsxs("div", { style: pageStyle, "data-pb-page": true, children: [_jsx("style", { children: buildResponsiveCssForStyles('[data-pb-page]', page.styles) }), _jsx(BlockRenderer, { blocks: page.blocks, editionMode: editionMode, componentDefaults: website.componentDefaults }), (page.blocks || []).length === 0 && editionMode && (_jsx("div", { style: { padding: '40px', textAlign: 'center', color: '#94a3b8' }, children: "Nenhum conte\u00FAdo adicionado." }))] })] }));
|
|
64
|
+
return (_jsxs(Suspense, { fallback: _jsx("div", { children: ((_e = website.properties) === null || _e === void 0 ? void 0 : _e.loadingMessage) || 'Carregando...' }), children: [!editionMode && (_jsxs(Helmet, { children: [_jsx("title", { children: page.title }), _jsx("meta", { name: "description", content: page.title }), _jsx("meta", { property: "og:title", content: page.title }), _jsx("meta", { property: "og:description", content: page.title }), _jsx("meta", { property: "og:image", content: page.title })] })), _jsxs("div", { style: pageStyle, "data-pb-page": true, children: [_jsx("style", { children: buildResponsiveCssForStyles('[data-pb-page]', page.styles) }), _jsx("style", { children: collectCustomCss(website, page) }), _jsx(BlockRenderer, { blocks: page.blocks, editionMode: editionMode, componentDefaults: website.componentDefaults }), (page.blocks || []).length === 0 && editionMode && (_jsx("div", { style: { padding: '40px', textAlign: 'center', color: '#94a3b8' }, children: "Nenhum conte\u00FAdo adicionado." }))] })] }));
|
|
64
65
|
});
|
|
65
66
|
export { PageBuilder };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
4
|
import { PbButton } from '../ui/PbButton.js';
|
|
5
5
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
6
6
|
import { getString, getNumber, getBoolean } from '../utils/propertyUtils.js';
|
|
@@ -27,7 +27,7 @@ const ButtonsComponent = memo(function ButtonsComponent({ component }) {
|
|
|
27
27
|
containerStyle.alignItems = align;
|
|
28
28
|
else
|
|
29
29
|
containerStyle.justifyContent = align;
|
|
30
|
-
return (_jsx(
|
|
30
|
+
return (_jsx(ComponentShell, { component: component, children: _jsx("div", { style: containerStyle, children: elements.map((element) => {
|
|
31
31
|
const props = element.properties || {};
|
|
32
32
|
const href = getString(props, 'path') || getString(props, 'href');
|
|
33
33
|
const text = getString(props, 'text') || getString(props, 'title');
|
|
@@ -1,38 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
4
|
import { PbRow } from '../ui/PbRow.js';
|
|
5
5
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
6
6
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
7
7
|
const elementFactory = new ElementFactory();
|
|
8
|
-
const INSET_STYLE_KEYS = new Set([
|
|
9
|
-
'borderColor',
|
|
10
|
-
'borderStyle',
|
|
11
|
-
'borderWidth',
|
|
12
|
-
'borderTopWidth',
|
|
13
|
-
'borderRightWidth',
|
|
14
|
-
'borderBottomWidth',
|
|
15
|
-
'borderLeftWidth',
|
|
16
|
-
'borderRadius',
|
|
17
|
-
'backgroundColor',
|
|
18
|
-
'backgroundImage',
|
|
19
|
-
'backgroundSize',
|
|
20
|
-
'backgroundPosition',
|
|
21
|
-
'boxShadow'
|
|
22
|
-
]);
|
|
23
|
-
function splitCardStyles(styles, inset) {
|
|
24
|
-
const container = {};
|
|
25
|
-
const body = {};
|
|
26
|
-
for (const [key, value] of Object.entries(styles !== null && styles !== void 0 ? styles : {})) {
|
|
27
|
-
if (inset && INSET_STYLE_KEYS.has(key)) {
|
|
28
|
-
body[key] = value;
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
container[key] = value;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return { container: container, body: body };
|
|
35
|
-
}
|
|
36
8
|
function applyCardStyles(element, props) {
|
|
37
9
|
const overrides = {};
|
|
38
10
|
if (element.elementType === 'icon') {
|
|
@@ -74,10 +46,7 @@ const CardComponent = memo(function CardComponent({ component }) {
|
|
|
74
46
|
cardTitleSize: properties === null || properties === void 0 ? void 0 : properties.cardTitleSize,
|
|
75
47
|
cardTextColor: properties === null || properties === void 0 ? void 0 : properties.cardTextColor,
|
|
76
48
|
cardTextSize: properties === null || properties === void 0 ? void 0 : properties.cardTextSize,
|
|
77
|
-
cardElementGap: properties === null || properties === void 0 ? void 0 : properties.cardElementGap
|
|
78
|
-
cardContentPadding: properties === null || properties === void 0 ? void 0 : properties.cardContentPadding,
|
|
79
|
-
cardContentAlign: properties === null || properties === void 0 ? void 0 : properties.cardContentAlign,
|
|
80
|
-
cardInsetBorder: properties === null || properties === void 0 ? void 0 : properties.cardInsetBorder
|
|
49
|
+
cardElementGap: properties === null || properties === void 0 ? void 0 : properties.cardElementGap
|
|
81
50
|
}), [
|
|
82
51
|
properties === null || properties === void 0 ? void 0 : properties.cardElement1,
|
|
83
52
|
properties === null || properties === void 0 ? void 0 : properties.cardElement2,
|
|
@@ -89,10 +58,7 @@ const CardComponent = memo(function CardComponent({ component }) {
|
|
|
89
58
|
properties === null || properties === void 0 ? void 0 : properties.cardTitleSize,
|
|
90
59
|
properties === null || properties === void 0 ? void 0 : properties.cardTextColor,
|
|
91
60
|
properties === null || properties === void 0 ? void 0 : properties.cardTextSize,
|
|
92
|
-
properties === null || properties === void 0 ? void 0 : properties.cardElementGap
|
|
93
|
-
properties === null || properties === void 0 ? void 0 : properties.cardContentPadding,
|
|
94
|
-
properties === null || properties === void 0 ? void 0 : properties.cardContentAlign,
|
|
95
|
-
properties === null || properties === void 0 ? void 0 : properties.cardInsetBorder
|
|
61
|
+
properties === null || properties === void 0 ? void 0 : properties.cardElementGap
|
|
96
62
|
]);
|
|
97
63
|
const orderedElements = useMemo(() => {
|
|
98
64
|
const cardOrder = [
|
|
@@ -118,19 +84,6 @@ const CardComponent = memo(function CardComponent({ component }) {
|
|
|
118
84
|
const layout = String((properties === null || properties === void 0 ? void 0 : properties.cardLayout) || 'stacked');
|
|
119
85
|
const rawGap = cardProps.cardElementGap;
|
|
120
86
|
const elementGap = rawGap === '' || rawGap == null ? '0' : String(rawGap);
|
|
121
|
-
const contentPadding = typeof cardProps.cardContentPadding === 'string' ? cardProps.cardContentPadding : '';
|
|
122
|
-
const insetBorder = cardProps.cardInsetBorder === true || cardProps.cardInsetBorder === 'true';
|
|
123
|
-
const contentAlign = typeof cardProps.cardContentAlign === 'string' && cardProps.cardContentAlign !== 'left'
|
|
124
|
-
? cardProps.cardContentAlign
|
|
125
|
-
: undefined;
|
|
126
|
-
const { containerStyle, bodyStyle } = useMemo(() => {
|
|
127
|
-
const { container, body } = splitCardStyles(component.styles, insetBorder);
|
|
128
|
-
if (contentPadding)
|
|
129
|
-
body.padding = contentPadding;
|
|
130
|
-
if (contentAlign)
|
|
131
|
-
body.textAlign = contentAlign;
|
|
132
|
-
return { containerStyle: container, bodyStyle: body };
|
|
133
|
-
}, [component.styles, insetBorder, contentPadding, contentAlign]);
|
|
134
87
|
const rowGapStyle = { gap: elementGap };
|
|
135
88
|
let content;
|
|
136
89
|
if (layout === 'icon-left' || layout === 'icon-right') {
|
|
@@ -148,6 +101,6 @@ const CardComponent = memo(function CardComponent({ component }) {
|
|
|
148
101
|
else {
|
|
149
102
|
content = (_jsx(PbRow, { id: "element-row", style: rowGapStyle, children: elements.map((element) => elementFactory.build(element)) }));
|
|
150
103
|
}
|
|
151
|
-
return
|
|
104
|
+
return _jsx(ComponentShell, { component: component, children: content });
|
|
152
105
|
});
|
|
153
106
|
export { CardComponent };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
|
+
import { getString } from '../utils/propertyUtils.js';
|
|
5
|
+
const DividerComponent = memo(function DividerComponent({ component }) {
|
|
6
|
+
const properties = component.properties || {};
|
|
7
|
+
const orientation = getString(properties, 'orientation', 'horizontal');
|
|
8
|
+
const thickness = getString(properties, 'thickness', '1px');
|
|
9
|
+
const color = getString(properties, 'color', '#e5e7eb');
|
|
10
|
+
const lineStyle = getString(properties, 'lineStyle', 'solid');
|
|
11
|
+
const length = getString(properties, 'length', '100%');
|
|
12
|
+
const align = getString(properties, 'align', 'center');
|
|
13
|
+
const isVertical = orientation === 'vertical';
|
|
14
|
+
const marginLeft = align === 'left' ? '0' : align === 'right' ? 'auto' : 'auto';
|
|
15
|
+
const marginRight = align === 'right' ? '0' : align === 'left' ? 'auto' : 'auto';
|
|
16
|
+
const line = isVertical
|
|
17
|
+
? {
|
|
18
|
+
width: 0,
|
|
19
|
+
height: length,
|
|
20
|
+
borderLeft: `${thickness} ${lineStyle} ${color}`,
|
|
21
|
+
marginLeft,
|
|
22
|
+
marginRight
|
|
23
|
+
}
|
|
24
|
+
: {
|
|
25
|
+
width: length,
|
|
26
|
+
height: 0,
|
|
27
|
+
borderTop: `${thickness} ${lineStyle} ${color}`,
|
|
28
|
+
marginLeft,
|
|
29
|
+
marginRight
|
|
30
|
+
};
|
|
31
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", children: _jsx("div", { style: { display: 'flex', flexDirection: isVertical ? 'row' : 'column', minHeight: isVertical ? undefined : '1px' }, children: _jsx("div", { style: line, "aria-hidden": "true" }) }) }));
|
|
32
|
+
});
|
|
33
|
+
export { DividerComponent };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useEffect, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
4
|
import { PbRow } from '../ui/PbRow.js';
|
|
5
5
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
6
6
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
@@ -19,6 +19,6 @@ const FormComponent = memo(function FormComponent({ component }) {
|
|
|
19
19
|
const handleSubmit = (event) => {
|
|
20
20
|
event.preventDefault();
|
|
21
21
|
};
|
|
22
|
-
return (_jsx(
|
|
22
|
+
return (_jsx(ComponentShell, { component: component, children: _jsx("form", { onSubmit: handleSubmit, noValidate: true, children: _jsx(PbRow, { style: { gap: 0 }, children: elements.map((element) => elementFactory.build(element, component.id)) }) }) }));
|
|
23
23
|
});
|
|
24
24
|
export { FormComponent };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useMemo } from 'react';
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
|
+
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
5
|
+
import { orderBySort } from '../utils/orderBySort.js';
|
|
6
|
+
import { getString } from '../utils/propertyUtils.js';
|
|
7
|
+
const elementFactory = new ElementFactory();
|
|
8
|
+
const HeroComponent = memo(function HeroComponent({ component }) {
|
|
9
|
+
const properties = component.properties || {};
|
|
10
|
+
const mediaType = getString(properties, 'mediaType', 'none');
|
|
11
|
+
const mediaSrc = getString(properties, 'mediaSrc', '');
|
|
12
|
+
const mediaPoster = getString(properties, 'mediaPoster', '');
|
|
13
|
+
const minHeight = getString(properties, 'minHeight', '600px');
|
|
14
|
+
const overlayColor = getString(properties, 'overlayColor', '#000000');
|
|
15
|
+
const overlayOpacity = properties.overlayOpacity !== undefined && properties.overlayOpacity !== ''
|
|
16
|
+
? Number(properties.overlayOpacity)
|
|
17
|
+
: 0.5;
|
|
18
|
+
const contentAlign = getString(properties, 'contentAlign', 'center');
|
|
19
|
+
const contentVerticalAlign = getString(properties, 'contentVerticalAlign', 'center');
|
|
20
|
+
const elements = useMemo(() => orderBySort(component.elements), [component.elements]);
|
|
21
|
+
const justifyContent = contentAlign === 'left' ? 'flex-start' : contentAlign === 'right' ? 'flex-end' : 'center';
|
|
22
|
+
const alignItems = contentVerticalAlign === 'top' ? 'flex-start' : contentVerticalAlign === 'bottom' ? 'flex-end' : 'center';
|
|
23
|
+
const contentStyle = {
|
|
24
|
+
position: 'relative',
|
|
25
|
+
zIndex: 2,
|
|
26
|
+
minHeight,
|
|
27
|
+
display: 'flex',
|
|
28
|
+
flexDirection: 'column',
|
|
29
|
+
justifyContent: alignItems,
|
|
30
|
+
alignItems: justifyContent,
|
|
31
|
+
textAlign: contentAlign === 'left' || contentAlign === 'right' ? contentAlign : 'center'
|
|
32
|
+
};
|
|
33
|
+
const media = useMemo(() => {
|
|
34
|
+
if (mediaType === 'video' && mediaSrc) {
|
|
35
|
+
return (_jsx("video", { autoPlay: true, muted: true, loop: true, playsInline: true, src: mediaSrc, poster: mediaPoster || undefined, style: { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' } }));
|
|
36
|
+
}
|
|
37
|
+
if (mediaType === 'image' && mediaSrc) {
|
|
38
|
+
return (_jsx("img", { src: mediaSrc, alt: "", style: { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' } }));
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}, [mediaType, mediaSrc, mediaPoster]);
|
|
42
|
+
const overlay = (_jsx("div", { style: {
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
inset: 0,
|
|
45
|
+
zIndex: 1,
|
|
46
|
+
backgroundColor: overlayColor,
|
|
47
|
+
opacity: overlayOpacity
|
|
48
|
+
} }));
|
|
49
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", children: _jsxs("div", { style: { position: 'relative', overflow: 'hidden', minHeight }, children: [media, overlay, _jsx("div", { style: contentStyle, children: elements.map((element) => elementFactory.build(element)) })] }) }));
|
|
50
|
+
});
|
|
51
|
+
export { HeroComponent };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
4
|
import { PbRow } from '../ui/PbRow.js';
|
|
5
5
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
6
6
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
7
7
|
const elementFactory = new ElementFactory();
|
|
8
8
|
const IconComponent = memo(function IconComponent({ component }) {
|
|
9
9
|
const elements = useMemo(() => orderBySort(component.elements), [component.elements]);
|
|
10
|
-
return (_jsx(
|
|
10
|
+
return (_jsx(ComponentShell, { component: component, children: _jsx(PbRow, { id: "element-row", style: { justifyContent: 'center', gap: 0 }, children: elements.map((element) => elementFactory.build(element)) }) }));
|
|
11
11
|
});
|
|
12
12
|
export { IconComponent };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
4
|
import { PbRow } from '../ui/PbRow.js';
|
|
5
5
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
6
6
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
@@ -11,8 +11,12 @@ const ImageComponent = memo(function ImageComponent({ component }) {
|
|
|
11
11
|
const fullBleed = getBoolean(component.properties, 'fullBleed', false);
|
|
12
12
|
const elements = useMemo(() => orderBySort(component.elements).map((element) => resolveImageElement(component, element)), [component.elements, component.properties]);
|
|
13
13
|
if (fullBleed) {
|
|
14
|
-
return (_jsx(
|
|
14
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", outerStyle: {
|
|
15
|
+
width: 'calc(100% + var(--pb-gutter, 1.5rem))',
|
|
16
|
+
marginLeft: 'calc(var(--pb-gutter, 1.5rem) * -0.5)',
|
|
17
|
+
marginRight: 'calc(var(--pb-gutter, 1.5rem) * -0.5)'
|
|
18
|
+
}, children: elements.map((element) => elementFactory.build(Object.assign(Object.assign({}, element), { fullBleed: true }))) }));
|
|
15
19
|
}
|
|
16
|
-
return (_jsx(
|
|
20
|
+
return (_jsx(ComponentShell, { component: component, children: _jsx(PbRow, { id: "element-row", style: { gap: 0 }, children: elements.map((element) => elementFactory.build(element)) }) }));
|
|
17
21
|
});
|
|
18
22
|
export { ImageComponent };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
3
4
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
4
5
|
import { ElementTypeEnum } from '../constants/ElementEnum.js';
|
|
5
6
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
@@ -27,6 +28,6 @@ const ListComponent = memo(function ListComponent({ component }) {
|
|
|
27
28
|
}
|
|
28
29
|
return result;
|
|
29
30
|
}, [elements]);
|
|
30
|
-
return (_jsx(
|
|
31
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", children: _jsx("ul", { style: { listStyle: 'none', paddingLeft: 0 }, children: items.map(({ icon, text, id }) => (_jsxs("li", { style: { display: 'flex', alignItems: 'center', justifyContent: itemAlign, marginBottom: itemGap }, children: [_jsx("span", { children: elementFactory.build(icon) }), _jsx("span", { style: { fontSize: itemFontSize }, children: text ? elementFactory.build(text) : null })] }, id))) }) }));
|
|
31
32
|
});
|
|
32
33
|
export { ListComponent };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
3
4
|
const COORDS_PATTERN = /^-?\d+(\.\d+)?$/;
|
|
4
5
|
function isValidCoord(value) {
|
|
5
6
|
if (typeof value !== 'string')
|
|
@@ -18,7 +19,7 @@ export function MapComponent({ component }) {
|
|
|
18
19
|
}
|
|
19
20
|
return `https://maps.google.com/maps?q=${encodeURIComponent(`${latStr},${lngStr}`)}&z=${zoom}&output=embed`;
|
|
20
21
|
}, [lat, lng, zoom]);
|
|
21
|
-
return (_jsx(
|
|
22
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", children: src ? (_jsx("iframe", { title: "Localiza\u00E7\u00E3o", src: src, width: "100%", height: height, style: { border: 0, borderRadius: '4px' }, allowFullScreen: true, loading: "lazy", referrerPolicy: "no-referrer-when-downgrade" })) : (_jsx("div", { style: {
|
|
22
23
|
width: '100%',
|
|
23
24
|
height,
|
|
24
25
|
backgroundColor: placeholderBackgroundColor,
|
|
@@ -3,6 +3,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
4
4
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
5
5
|
import { resolveResponsiveProperties, breakpointFromWidth } from '../utils/responsiveProperties.js';
|
|
6
|
+
import { getComponentShellStyles } from '../utils/componentShell.js';
|
|
6
7
|
const elementFactory = new ElementFactory();
|
|
7
8
|
function cleanComponentStyles(styles) {
|
|
8
9
|
const exclude = new Set(['minHeight', 'display', 'alignItems', 'justifyContent', 'flexDirection']);
|
|
@@ -177,13 +178,27 @@ export function SliderComponent({ component, editionMode = false }) {
|
|
|
177
178
|
const chrome = resolveChromeColors(resolved);
|
|
178
179
|
const useSharedImages = resolved.imageCustomization !== 'separate';
|
|
179
180
|
const sharedImageStyles = resolved.imageStyles || {};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
const { containerStyle, bodyStyle } = useMemo(() => getComponentShellStyles(component), [component]);
|
|
182
|
+
if (resolved.mode === 'marquee') {
|
|
183
|
+
const animName = `pb-marquee-${String(component.id).replace(/[^a-zA-Z0-9_-]/g, '_')}`;
|
|
184
|
+
const marqueeDuration = Number(resolved.marqueeDuration) > 0 ? Number(resolved.marqueeDuration) : 20;
|
|
185
|
+
const marqueeSlides = [...slides, ...slides];
|
|
186
|
+
const keyframes = `@keyframes ${animName}{from{transform:translateX(0)}to{transform:translateX(calc(-50% - ${spacing / 2}px))}}`;
|
|
187
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: keyframes }), _jsx("div", { ref: containerRef, "data-pb-component": component.id, style: Object.assign({ position: 'relative' }, cleanComponentStyles(containerStyle)), children: _jsx("div", { style: bodyStyle, children: _jsx("div", { style: { overflow: 'hidden' }, children: _jsx("div", { style: {
|
|
188
|
+
display: 'flex',
|
|
189
|
+
columnGap: spacing,
|
|
190
|
+
width: 'max-content',
|
|
191
|
+
animation: `${animName} ${marqueeDuration}s linear infinite`,
|
|
192
|
+
userSelect: 'none'
|
|
193
|
+
}, children: marqueeSlides.map((element, i) => (_jsx("div", { style: { width: slideWidth, flexShrink: 0, overflow: 'hidden' }, children: buildSlide(element, fixedHeight, sharedImageStyles, useSharedImages) }, `${element.id}-${i}`))) }) }) }) })] }));
|
|
194
|
+
}
|
|
195
|
+
return (_jsx("div", { ref: containerRef, "data-pb-component": component.id, style: Object.assign({ position: 'relative' }, cleanComponentStyles(containerStyle)), children: _jsxs("div", { style: bodyStyle, children: [_jsx("div", { style: Object.assign({ overflow: 'hidden' }, (fixedHeight ? { height: fixedHeight } : {})), children: _jsx("div", { style: {
|
|
196
|
+
display: 'flex',
|
|
197
|
+
columnGap: spacing,
|
|
198
|
+
transform: `translateX(${translateX}px)`,
|
|
199
|
+
transition: animate && !dragging ? 'transform 0.3s ease' : 'none',
|
|
200
|
+
cursor: dragging ? 'grabbing' : n > 1 ? 'grab' : 'default',
|
|
201
|
+
touchAction: 'pan-y',
|
|
202
|
+
userSelect: 'none'
|
|
203
|
+
}, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onTransitionEnd: handleTransitionEnd, children: trackSlides.map((element, i) => (_jsx("div", { style: { width: slideWidth, flexShrink: 0, overflow: 'hidden' }, children: buildSlide(element, fixedHeight, sharedImageStyles, useSharedImages) }, `${element.id}-${i}`))) }) }), showArrows && (_jsxs(_Fragment, { children: [_jsx(ArrowButton, { side: "left", size: chrome.arrowSize, background: chrome.arrowBackground, color: chrome.arrowColor, onClick: () => goTo(index - 1) }), _jsx(ArrowButton, { side: "right", size: chrome.arrowSize, background: chrome.arrowBackground, color: chrome.arrowColor, onClick: () => goTo(index + 1) })] })), showDots && (_jsx(Dots, { count: n, current: currentIndex, size: chrome.dotSize, activeBackground: chrome.dotActiveBackground, background: chrome.dotBackground, activeColor: chrome.dotActiveColor, color: chrome.dotColor, onGoTo: goToDot }))] }) }));
|
|
189
204
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useMemo } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
4
4
|
import { PbRow } from '../ui/PbRow.js';
|
|
5
5
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
6
6
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
@@ -10,6 +10,6 @@ const elementFactory = new ElementFactory();
|
|
|
10
10
|
const TextComponent = memo(function TextComponent({ component }) {
|
|
11
11
|
const elements = useMemo(() => orderBySort(component.elements).map((element) => resolveImageElement(component, element)), [component.elements, component.properties]);
|
|
12
12
|
const elementGap = getString(component.properties, 'elementGap', '');
|
|
13
|
-
return (_jsx(
|
|
13
|
+
return (_jsx(ComponentShell, { component: component, children: _jsx(PbRow, { id: "element-row", style: { gap: elementGap }, children: elements.map((element) => elementFactory.build(element)) }) }));
|
|
14
14
|
});
|
|
15
15
|
export { TextComponent };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { ComponentShell } from '../ui/PbComponentShell.js';
|
|
3
4
|
import { getBoolean, getString } from '../utils/propertyUtils.js';
|
|
4
5
|
function toEmbed(src) {
|
|
5
6
|
const value = src.trim();
|
|
@@ -124,7 +125,11 @@ export function VideoComponent({ component }) {
|
|
|
124
125
|
color: placeholderTextColor
|
|
125
126
|
}, children: "V\u00EDdeo n\u00E3o configurado" }));
|
|
126
127
|
if (fullBleed) {
|
|
127
|
-
return (_jsx(
|
|
128
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", outerStyle: {
|
|
129
|
+
width: 'calc(100% + var(--pb-gutter, 1.5rem))',
|
|
130
|
+
marginLeft: 'calc(var(--pb-gutter, 1.5rem) * -0.5)',
|
|
131
|
+
marginRight: 'calc(var(--pb-gutter, 1.5rem) * -0.5)'
|
|
132
|
+
}, children: content }));
|
|
128
133
|
}
|
|
129
|
-
return (_jsx(
|
|
134
|
+
return (_jsx(ComponentShell, { component: component, outer: "div", children: content }));
|
|
130
135
|
}
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* valores de destaque usam `var(--pb-*)` com fallback, então o design system
|
|
6
6
|
* (Etapa 1) sobrescreve os tokens sem tocar nestes estilos.
|
|
7
7
|
*/
|
|
8
|
-
export declare const baseCss = "\n/* \u2500\u2500\u2500 Reset e tipografia base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-root, .pb-root *, .pb-root *::before, .pb-root *::after {\n box-sizing: border-box;\n}\n.pb-root {\n margin: 0;\n font-family: var(--pb-font-family, 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);\n font-size: var(--pb-font-size-base, 16px);\n line-height: var(--pb-line-height, 1.6);\n color: var(--pb-color-text, #1f2937);\n background-color: var(--pb-color-background, #ffffff);\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n}\n.pb-root h1, .pb-root h2, .pb-root h3, .pb-root h4, .pb-root h5, .pb-root h6 {\n margin: 0 0 0.5em;\n font-weight: var(--pb-font-weight-bold, 700);\n line-height: 1.2;\n color: var(--pb-color-heading, #111827);\n}\n.pb-root p {\n margin: 0;\n}\n.pb-root img {\n max-width: 100%;\n height: auto;\n}\n.pb-root a {\n color: var(--pb-color-primary, #f58220);\n text-decoration: none;\n}\n.pb-root a:hover {\n text-decoration: underline;\n}\n\n/* \u2500\u2500\u2500 Layout: container / grade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-container {\n width: 100%;\n margin-inline: auto;\n padding-inline: var(--pb-gutter, 1.5rem);\n}\n.pb-container-fluid {\n max-width: none !important;\n padding-inline: var(--pb-gutter, 1.5rem);\n}\n@media (min-width: 576px) {\n .pb-container { max-width: 540px; }\n}\n@media (min-width: 768px) {\n .pb-container { max-width: 720px; }\n}\n@media (min-width: 992px) {\n .pb-container { max-width: 960px; }\n}\n@media (min-width: 1200px) {\n .pb-container { max-width: 1140px; }\n}\n@media (min-width: 1400px) {\n .pb-container { max-width: 1320px; }\n}\n\n.pb-row {\n display: grid;\n grid-template-columns: repeat(12, minmax(0, 1fr));\n gap: var(--pb-gutter, 0);\n}\n.pb-col {\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Bot\u00F5es \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n padding: 0.5em 1.25em;\n font-family: inherit;\n font-size: 1rem;\n font-weight: var(--pb-font-weight-bold, 700);\n line-height: 1.5;\n text-align: center;\n text-decoration: none;\n border: 1px solid transparent;\n border-radius: var(--pb-radius-md, 8px);\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;\n}\n.pb-button:hover { text-decoration: none; }\n.pb-button:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.pb-button-primary {\n background-color: var(--pb-color-primary, #f58220);\n border-color: var(--pb-color-primary, #f58220);\n color: #ffffff;\n}\n.pb-button-primary:hover:not(:disabled) {\n background-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 88%, #000);\n border-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 88%, #000);\n}\n.pb-button-secondary {\n background-color: var(--pb-color-secondary, #64748b);\n border-color: var(--pb-color-secondary, #64748b);\n color: #ffffff;\n}\n.pb-button-success {\n background-color: var(--pb-color-success, #16a34a);\n border-color: var(--pb-color-success, #16a34a);\n color: #ffffff;\n}\n.pb-button-danger {\n background-color: var(--pb-color-danger, #dc2626);\n border-color: var(--pb-color-danger, #dc2626);\n color: #ffffff;\n}\n.pb-button-warning {\n background-color: var(--pb-color-warning, #f59e0b);\n border-color: var(--pb-color-warning, #f59e0b);\n color: #1f2937;\n}\n.pb-button-info {\n background-color: var(--pb-color-info, #0ea5e9);\n border-color: var(--pb-color-info, #0ea5e9);\n color: #ffffff;\n}\n.pb-button-light {\n background-color: var(--pb-color-light, #f8fafc);\n border-color: var(--pb-color-border, #e5e7eb);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-button-dark {\n background-color: var(--pb-color-dark, #0f172a);\n border-color: var(--pb-color-dark, #0f172a);\n color: #ffffff;\n}\n.pb-button-outline-primary {\n background-color: transparent;\n border-color: var(--pb-color-primary, #f58220);\n color: var(--pb-color-primary, #f58220);\n}\n.pb-button-outline-primary:hover:not(:disabled) {\n background-color: var(--pb-color-primary, #f58220);\n color: #ffffff;\n}\n.pb-button-outline-secondary {\n background-color: transparent;\n border-color: var(--pb-color-secondary, #64748b);\n color: var(--pb-color-secondary, #64748b);\n}\n.pb-button-outline-secondary:hover:not(:disabled) {\n background-color: var(--pb-color-secondary, #64748b);\n color: #ffffff;\n}\n.pb-button-link {\n background-color: transparent;\n border-color: transparent;\n color: var(--pb-color-primary, #f58220);\n padding-inline: 0.5em;\n}\n.pb-button-sm {\n padding: 0.375em 0.875em;\n font-size: 0.875rem;\n border-radius: var(--pb-radius-sm, 4px);\n}\n.pb-button-lg {\n padding: 0.625em 1.5em;\n font-size: 1.125rem;\n border-radius: var(--pb-radius-lg, 12px);\n}\n\n/* \u2500\u2500\u2500 Spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-spinner {\n display: inline-block;\n width: 1.5rem;\n height: 1.5rem;\n border: 0.2em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: pb-spin 0.75s linear infinite;\n vertical-align: -0.25em;\n}\n.pb-spinner-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.18em;\n}\n@keyframes pb-spin {\n to { transform: rotate(360deg); }\n}\n\n/* \u2500\u2500\u2500 Alertas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-alert {\n padding: var(--pb-space-md, 16px) var(--pb-space-lg, 24px);\n border: 1px solid;\n border-radius: var(--pb-radius-md, 8px);\n margin-bottom: var(--pb-space-md, 16px);\n}\n.pb-alert-title {\n font-weight: var(--pb-font-weight-bold, 700);\n margin-bottom: 0.25em;\n}\n.pb-alert-primary {\n background-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-info {\n background-color: color-mix(in srgb, var(--pb-color-info, #0ea5e9) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-info, #0ea5e9) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-success {\n background-color: color-mix(in srgb, var(--pb-color-success, #16a34a) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-success, #16a34a) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-warning {\n background-color: color-mix(in srgb, var(--pb-color-warning, #f59e0b) 12%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-warning, #f59e0b) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-danger {\n background-color: color-mix(in srgb, var(--pb-color-danger, #dc2626) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-danger, #dc2626) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-secondary {\n background-color: var(--pb-color-light, #f8fafc);\n border-color: var(--pb-color-border, #e5e7eb);\n color: var(--pb-color-text, #1f2937);\n}\n\n/* \u2500\u2500\u2500 Formul\u00E1rios \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-form-group {\n margin-bottom: var(--pb-space-md, 16px);\n}\n.pb-form-label {\n display: block;\n margin-bottom: 0.375rem;\n font-weight: var(--pb-font-weight-bold, 700);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-form-control,\n.pb-form-select,\n.pb-form-textarea {\n display: block;\n width: 100%;\n padding: 0.5em 0.75em;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n color: var(--pb-color-text, #1f2937);\n background-color: var(--pb-color-surface, #ffffff);\n border: 1px solid var(--pb-color-border, #e5e7eb);\n border-radius: var(--pb-radius-sm, 4px);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n.pb-form-control:focus,\n.pb-form-select:focus,\n.pb-form-textarea:focus {\n outline: none;\n border-color: var(--pb-color-primary, #f58220);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--pb-color-primary, #f58220) 20%, transparent);\n}\n.pb-form-control-invalid,\n.pb-form-select-invalid,\n.pb-form-textarea-invalid {\n border-color: var(--pb-color-danger, #dc2626);\n}\n.pb-invalid-feedback {\n display: block;\n margin-top: 0.375rem;\n font-size: 0.875rem;\n color: var(--pb-color-danger, #dc2626);\n}\n.pb-form-check {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.5rem;\n}\n.pb-form-check-input {\n width: 1.1em;\n height: 1.1em;\n accent-color: var(--pb-color-primary, #f58220);\n flex-shrink: 0;\n}\n.pb-form-check-label {\n font-weight: normal;\n margin-bottom: 0;\n}\n\n/* \u2500\u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-header {\n width: 100%;\n}\n.pb-header-inner {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: var(--pb-space-md, 16px);\n flex-wrap: wrap;\n padding-block: var(--pb-space-sm, 8px);\n}\n.pb-brand {\n display: inline-flex;\n align-items: center;\n text-decoration: none;\n flex-shrink: 0;\n}\n.pb-brand img {\n max-height: 56px;\n width: auto;\n}\n.pb-nav {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: wrap;\n min-width: 0;\n}\n.pb-nav-link {\n display: inline-block;\n padding: 0.5rem 0.75rem;\n color: inherit;\n text-decoration: none;\n font-weight: 500;\n border-bottom: 2px solid transparent;\n transition: color 0.2s ease, border-color 0.2s ease;\n}\n.pb-nav-link:hover {\n text-decoration: none;\n opacity: 0.85;\n}\n.pb-nav-link-active {\n border-bottom-color: currentColor;\n}\n.pb-nav-toggle {\n display: none;\n padding: 0.375rem 0.625rem;\n font-size: 1.25rem;\n line-height: 1;\n background: transparent;\n border: 1px solid var(--pb-color-border, #e5e7eb);\n border-radius: var(--pb-radius-sm, 4px);\n cursor: pointer;\n color: inherit;\n}\n@media (max-width: 991.98px) {\n .pb-nav-toggle { display: inline-flex; align-items: center; }\n .pb-nav { display: none; }\n .pb-nav-open { display: flex; flex-direction: column; width: 100%; }\n}\n\n/* \u2500\u2500\u2500 Footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-footer {\n width: 100%;\n padding-block: var(--pb-space-xl, 32px);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-footer-divider {\n border: none;\n border-top: 1px solid var(--pb-color-border, #e5e7eb);\n margin: var(--pb-space-lg, 24px) 0;\n}\n.pb-social-icons {\n display: flex;\n justify-content: center;\n gap: var(--pb-space-sm, 8px);\n flex-wrap: wrap;\n}\n.pb-social-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n color: inherit;\n text-decoration: none;\n}\n.pb-social-icon:hover {\n text-decoration: none;\n opacity: 0.8;\n}\n\n/* \u2500\u2500\u2500 Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-loading {\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--pb-space-sm, 8px);\n font-weight: 600;\n letter-spacing: 0.08em;\n}\n\n/* \u2500\u2500\u2500 Utilit\u00E1rios de alinhamento \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-text-center { text-align: center; }\n.pb-mb-0 { margin-bottom: 0; }\n";
|
|
8
|
+
export declare const baseCss = "\n/* \u2500\u2500\u2500 Reset e tipografia base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-root, .pb-root *, .pb-root *::before, .pb-root *::after {\n box-sizing: border-box;\n}\n.pb-root {\n margin: 0;\n font-family: var(--pb-font-family, 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);\n font-size: var(--pb-font-size-base, 16px);\n line-height: var(--pb-line-height, 1.6);\n color: var(--pb-color-text, #1f2937);\n background-color: var(--pb-color-background, #ffffff);\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n}\n.pb-root h1, .pb-root h2, .pb-root h3, .pb-root h4, .pb-root h5, .pb-root h6 {\n margin: 0 0 0.5em;\n font-family: var(--pb-font-heading, var(--pb-font-family, 'Inter', system-ui, sans-serif));\n font-weight: var(--pb-font-weight-bold, 700);\n line-height: 1.2;\n color: var(--pb-color-heading, #111827);\n}\n.pb-root p {\n margin: 0;\n}\n.pb-root img {\n max-width: 100%;\n height: auto;\n}\n.pb-root a {\n color: var(--pb-color-primary, #f58220);\n text-decoration: none;\n}\n.pb-root a:hover {\n text-decoration: underline;\n}\n\n/* \u2500\u2500\u2500 Layout: container / grade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-container {\n width: 100%;\n margin-inline: auto;\n padding-inline: var(--pb-gutter, 1.5rem);\n}\n.pb-container-fluid {\n max-width: none !important;\n padding-inline: var(--pb-gutter, 1.5rem);\n}\n@media (min-width: 576px) {\n .pb-container { max-width: 540px; }\n}\n@media (min-width: 768px) {\n .pb-container { max-width: 720px; }\n}\n@media (min-width: 992px) {\n .pb-container { max-width: 960px; }\n}\n@media (min-width: 1200px) {\n .pb-container { max-width: 1140px; }\n}\n@media (min-width: 1400px) {\n .pb-container { max-width: 1320px; }\n}\n\n.pb-row {\n display: grid;\n grid-template-columns: repeat(12, minmax(0, 1fr));\n gap: var(--pb-gutter, 0);\n}\n.pb-col {\n min-width: 0;\n}\n\n/* \u2500\u2500\u2500 Bot\u00F5es \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n padding: 0.5em 1.25em;\n font-family: inherit;\n font-size: 1rem;\n font-weight: var(--pb-font-weight-bold, 700);\n line-height: 1.5;\n text-align: center;\n text-decoration: none;\n border: 1px solid transparent;\n border-radius: var(--pb-radius-md, 8px);\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;\n}\n.pb-button:hover { text-decoration: none; }\n.pb-button:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n}\n\n.pb-button-primary {\n background-color: var(--pb-color-primary, #f58220);\n border-color: var(--pb-color-primary, #f58220);\n color: #ffffff;\n}\n.pb-button-primary:hover:not(:disabled) {\n background-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 88%, #000);\n border-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 88%, #000);\n}\n.pb-button-secondary {\n background-color: var(--pb-color-secondary, #64748b);\n border-color: var(--pb-color-secondary, #64748b);\n color: #ffffff;\n}\n.pb-button-success {\n background-color: var(--pb-color-success, #16a34a);\n border-color: var(--pb-color-success, #16a34a);\n color: #ffffff;\n}\n.pb-button-danger {\n background-color: var(--pb-color-danger, #dc2626);\n border-color: var(--pb-color-danger, #dc2626);\n color: #ffffff;\n}\n.pb-button-warning {\n background-color: var(--pb-color-warning, #f59e0b);\n border-color: var(--pb-color-warning, #f59e0b);\n color: #1f2937;\n}\n.pb-button-info {\n background-color: var(--pb-color-info, #0ea5e9);\n border-color: var(--pb-color-info, #0ea5e9);\n color: #ffffff;\n}\n.pb-button-light {\n background-color: var(--pb-color-light, #f8fafc);\n border-color: var(--pb-color-border, #e5e7eb);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-button-dark {\n background-color: var(--pb-color-dark, #0f172a);\n border-color: var(--pb-color-dark, #0f172a);\n color: #ffffff;\n}\n.pb-button-outline-primary {\n background-color: transparent;\n border-color: var(--pb-color-primary, #f58220);\n color: var(--pb-color-primary, #f58220);\n}\n.pb-button-outline-primary:hover:not(:disabled) {\n background-color: var(--pb-color-primary, #f58220);\n color: #ffffff;\n}\n.pb-button-outline-secondary {\n background-color: transparent;\n border-color: var(--pb-color-secondary, #64748b);\n color: var(--pb-color-secondary, #64748b);\n}\n.pb-button-outline-secondary:hover:not(:disabled) {\n background-color: var(--pb-color-secondary, #64748b);\n color: #ffffff;\n}\n.pb-button-link {\n background-color: transparent;\n border-color: transparent;\n color: var(--pb-color-primary, #f58220);\n padding-inline: 0.5em;\n}\n.pb-button-sm {\n padding: 0.375em 0.875em;\n font-size: 0.875rem;\n border-radius: var(--pb-radius-sm, 4px);\n}\n.pb-button-lg {\n padding: 0.625em 1.5em;\n font-size: 1.125rem;\n border-radius: var(--pb-radius-lg, 12px);\n}\n\n/* \u2500\u2500\u2500 Spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-spinner {\n display: inline-block;\n width: 1.5rem;\n height: 1.5rem;\n border: 0.2em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: pb-spin 0.75s linear infinite;\n vertical-align: -0.25em;\n}\n.pb-spinner-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.18em;\n}\n@keyframes pb-spin {\n to { transform: rotate(360deg); }\n}\n\n/* \u2500\u2500\u2500 Alertas \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-alert {\n padding: var(--pb-space-md, 16px) var(--pb-space-lg, 24px);\n border: 1px solid;\n border-radius: var(--pb-radius-md, 8px);\n margin-bottom: var(--pb-space-md, 16px);\n}\n.pb-alert-title {\n font-weight: var(--pb-font-weight-bold, 700);\n margin-bottom: 0.25em;\n}\n.pb-alert-primary {\n background-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-primary, #f58220) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-info {\n background-color: color-mix(in srgb, var(--pb-color-info, #0ea5e9) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-info, #0ea5e9) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-success {\n background-color: color-mix(in srgb, var(--pb-color-success, #16a34a) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-success, #16a34a) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-warning {\n background-color: color-mix(in srgb, var(--pb-color-warning, #f59e0b) 12%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-warning, #f59e0b) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-danger {\n background-color: color-mix(in srgb, var(--pb-color-danger, #dc2626) 10%, #fff);\n border-color: color-mix(in srgb, var(--pb-color-danger, #dc2626) 35%, #fff);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-alert-secondary {\n background-color: var(--pb-color-light, #f8fafc);\n border-color: var(--pb-color-border, #e5e7eb);\n color: var(--pb-color-text, #1f2937);\n}\n\n/* \u2500\u2500\u2500 Formul\u00E1rios \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-form-group {\n margin-bottom: var(--pb-space-md, 16px);\n}\n.pb-form-label {\n display: block;\n margin-bottom: 0.375rem;\n font-weight: var(--pb-font-weight-bold, 700);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-form-control,\n.pb-form-select,\n.pb-form-textarea {\n display: block;\n width: 100%;\n padding: 0.5em 0.75em;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n color: var(--pb-color-text, #1f2937);\n background-color: var(--pb-color-surface, #ffffff);\n border: 1px solid var(--pb-color-border, #e5e7eb);\n border-radius: var(--pb-radius-sm, 4px);\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n.pb-form-control:focus,\n.pb-form-select:focus,\n.pb-form-textarea:focus {\n outline: none;\n border-color: var(--pb-color-primary, #f58220);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--pb-color-primary, #f58220) 20%, transparent);\n}\n.pb-form-control-invalid,\n.pb-form-select-invalid,\n.pb-form-textarea-invalid {\n border-color: var(--pb-color-danger, #dc2626);\n}\n.pb-invalid-feedback {\n display: block;\n margin-top: 0.375rem;\n font-size: 0.875rem;\n color: var(--pb-color-danger, #dc2626);\n}\n.pb-form-check {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.5rem;\n}\n.pb-form-check-input {\n width: 1.1em;\n height: 1.1em;\n accent-color: var(--pb-color-primary, #f58220);\n flex-shrink: 0;\n}\n.pb-form-check-label {\n font-weight: normal;\n margin-bottom: 0;\n}\n\n/* \u2500\u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-header {\n width: 100%;\n}\n.pb-header-inner {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: var(--pb-space-md, 16px);\n flex-wrap: wrap;\n padding-block: var(--pb-space-sm, 8px);\n}\n.pb-brand {\n display: inline-flex;\n align-items: center;\n text-decoration: none;\n flex-shrink: 0;\n}\n.pb-brand img {\n max-height: 56px;\n width: auto;\n}\n.pb-nav {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: wrap;\n min-width: 0;\n}\n.pb-nav-link {\n display: inline-block;\n padding: 0.5rem 0.75rem;\n color: inherit;\n text-decoration: none;\n font-weight: 500;\n border-bottom: 2px solid transparent;\n transition: color 0.2s ease, border-color 0.2s ease;\n}\n.pb-nav-link:hover {\n text-decoration: none;\n opacity: 0.85;\n}\n.pb-nav-link-active {\n border-bottom-color: currentColor;\n}\n.pb-nav-toggle {\n display: none;\n padding: 0.375rem 0.625rem;\n font-size: 1.25rem;\n line-height: 1;\n background: transparent;\n border: 1px solid var(--pb-color-border, #e5e7eb);\n border-radius: var(--pb-radius-sm, 4px);\n cursor: pointer;\n color: inherit;\n}\n@media (max-width: 991.98px) {\n .pb-nav-toggle { display: inline-flex; align-items: center; }\n .pb-nav { display: none; }\n .pb-nav-open { display: flex; flex-direction: column; width: 100%; }\n}\n\n/* \u2500\u2500\u2500 Footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-footer {\n width: 100%;\n padding-block: var(--pb-space-xl, 32px);\n color: var(--pb-color-text, #1f2937);\n}\n.pb-footer-divider {\n border: none;\n border-top: 1px solid var(--pb-color-border, #e5e7eb);\n margin: var(--pb-space-lg, 24px) 0;\n}\n.pb-social-icons {\n display: flex;\n justify-content: center;\n gap: var(--pb-space-sm, 8px);\n flex-wrap: wrap;\n}\n.pb-social-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n color: inherit;\n text-decoration: none;\n}\n.pb-social-icon:hover {\n text-decoration: none;\n opacity: 0.8;\n}\n\n/* \u2500\u2500\u2500 Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-loading {\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--pb-space-sm, 8px);\n font-weight: 600;\n letter-spacing: 0.08em;\n}\n\n/* \u2500\u2500\u2500 Utilit\u00E1rios de alinhamento \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.pb-text-center { text-align: center; }\n.pb-mb-0 { margin-bottom: 0; }\n";
|
|
@@ -22,6 +22,7 @@ export const baseCss = `
|
|
|
22
22
|
}
|
|
23
23
|
.pb-root h1, .pb-root h2, .pb-root h3, .pb-root h4, .pb-root h5, .pb-root h6 {
|
|
24
24
|
margin: 0 0 0.5em;
|
|
25
|
+
font-family: var(--pb-font-heading, var(--pb-font-family, 'Inter', system-ui, sans-serif));
|
|
25
26
|
font-weight: var(--pb-font-weight-bold, 700);
|
|
26
27
|
line-height: 1.2;
|
|
27
28
|
color: var(--pb-color-heading, #111827);
|
|
@@ -29,6 +29,7 @@ export const defaultTokens = {
|
|
|
29
29
|
},
|
|
30
30
|
typography: {
|
|
31
31
|
fontFamily: "'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
|
|
32
|
+
headingFontFamily: "'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
|
|
32
33
|
fontSizeBase: '16px',
|
|
33
34
|
fontWeightNormal: '400',
|
|
34
35
|
fontWeightBold: '700',
|
|
@@ -101,6 +102,7 @@ export function tokenToCssVars(tokens) {
|
|
|
101
102
|
'--pb-color-muted': colors.muted,
|
|
102
103
|
'--pb-color-border': colors.border,
|
|
103
104
|
'--pb-font-family': typography.fontFamily,
|
|
105
|
+
'--pb-font-heading': typography.headingFontFamily,
|
|
104
106
|
'--pb-font-size-base': typography.fontSizeBase,
|
|
105
107
|
'--pb-font-weight-normal': typography.fontWeightNormal,
|
|
106
108
|
'--pb-font-weight-bold': typography.fontWeightBold,
|
|
@@ -10,6 +10,8 @@ import { MapComponent } from '../components/MapComponent.js';
|
|
|
10
10
|
import { ButtonsComponent } from '../components/ButtonsComponent.js';
|
|
11
11
|
import { IconComponent } from '../components/IconComponent.js';
|
|
12
12
|
import { VideoComponent } from '../components/VideoComponent.js';
|
|
13
|
+
import { HeroComponent } from '../components/HeroComponent.js';
|
|
14
|
+
import { DividerComponent } from '../components/DividerComponent.js';
|
|
13
15
|
/**
|
|
14
16
|
* Aplica os estilos padrão do design system (`componentDefaults`) antes dos
|
|
15
17
|
* estilos da instância — o override da instância prevalece.
|
|
@@ -26,8 +28,11 @@ export class ComponentFactory {
|
|
|
26
28
|
switch (resolved.componentType) {
|
|
27
29
|
case ComponentTypeEnum.Text:
|
|
28
30
|
case ComponentTypeEnum.TextWithImage:
|
|
29
|
-
case ComponentTypeEnum.HeroBanner:
|
|
30
31
|
return _jsx(TextComponent, { component: resolved }, resolved.id);
|
|
32
|
+
case ComponentTypeEnum.HeroBanner:
|
|
33
|
+
return _jsx(HeroComponent, { component: resolved }, resolved.id);
|
|
34
|
+
case ComponentTypeEnum.Divider:
|
|
35
|
+
return _jsx(DividerComponent, { component: resolved }, resolved.id);
|
|
31
36
|
case ComponentTypeEnum.Image:
|
|
32
37
|
return _jsx(ImageComponent, { component: resolved }, resolved.id);
|
|
33
38
|
case ComponentTypeEnum.List:
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
import type { ComponentType } from '../types/ComponentType.js';
|
|
3
|
+
export declare function ComponentShell({ component, outer, outerStyle, children }: {
|
|
4
|
+
readonly component: ComponentType;
|
|
5
|
+
readonly outer?: 'container' | 'div';
|
|
6
|
+
readonly outerStyle?: CSSProperties;
|
|
7
|
+
readonly children: ReactNode;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { PbContainer } from './PbContainer.js';
|
|
4
|
+
import { getComponentShellStyles } from '../utils/componentShell.js';
|
|
5
|
+
export function ComponentShell({ component, outer = 'container', outerStyle, children }) {
|
|
6
|
+
const { containerStyle, bodyStyle } = useMemo(() => getComponentShellStyles(component), [component]);
|
|
7
|
+
const content = _jsx("div", { style: bodyStyle, children: children });
|
|
8
|
+
if (outer === 'div') {
|
|
9
|
+
return (_jsx("div", { "data-pb-component": component.id, style: Object.assign(Object.assign({}, containerStyle), outerStyle), children: content }));
|
|
10
|
+
}
|
|
11
|
+
return (_jsx(PbContainer, { "data-pb-component": component.id, style: Object.assign(Object.assign({}, containerStyle), outerStyle), children: content }));
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import type { ComponentType } from '../types/ComponentType.js';
|
|
3
|
+
export declare function splitComponentStyles(styles: Record<string, unknown> | undefined, inset: boolean): {
|
|
4
|
+
container: CSSProperties;
|
|
5
|
+
body: CSSProperties;
|
|
6
|
+
};
|
|
7
|
+
export declare function getComponentShellStyles(component: ComponentType): {
|
|
8
|
+
containerStyle: CSSProperties;
|
|
9
|
+
bodyStyle: CSSProperties;
|
|
10
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getString, getBoolean } from './propertyUtils.js';
|
|
2
|
+
const INSET_STYLE_KEYS = new Set([
|
|
3
|
+
'borderColor',
|
|
4
|
+
'borderStyle',
|
|
5
|
+
'borderWidth',
|
|
6
|
+
'borderTopWidth',
|
|
7
|
+
'borderRightWidth',
|
|
8
|
+
'borderBottomWidth',
|
|
9
|
+
'borderLeftWidth',
|
|
10
|
+
'borderRadius',
|
|
11
|
+
'backgroundColor',
|
|
12
|
+
'backgroundImage',
|
|
13
|
+
'backgroundSize',
|
|
14
|
+
'backgroundPosition',
|
|
15
|
+
'boxShadow'
|
|
16
|
+
]);
|
|
17
|
+
export function splitComponentStyles(styles, inset) {
|
|
18
|
+
const container = {};
|
|
19
|
+
const body = {};
|
|
20
|
+
for (const [key, value] of Object.entries(styles !== null && styles !== void 0 ? styles : {})) {
|
|
21
|
+
if (inset && INSET_STYLE_KEYS.has(key)) {
|
|
22
|
+
body[key] = value;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
container[key] = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { container: container, body: body };
|
|
29
|
+
}
|
|
30
|
+
export function getComponentShellStyles(component) {
|
|
31
|
+
const properties = component.properties || {};
|
|
32
|
+
const inset = getBoolean(properties, 'contentInsetBorder', false);
|
|
33
|
+
const { container, body } = splitComponentStyles(component.styles, inset);
|
|
34
|
+
const contentPadding = getString(properties, 'contentPadding', '');
|
|
35
|
+
const contentAlign = getString(properties, 'contentAlign', '');
|
|
36
|
+
if (contentPadding)
|
|
37
|
+
body.padding = contentPadding;
|
|
38
|
+
if (contentAlign && contentAlign !== 'left')
|
|
39
|
+
body.textAlign = contentAlign;
|
|
40
|
+
return { containerStyle: container, bodyStyle: body };
|
|
41
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PageType } from '../types/PageType.js';
|
|
2
|
+
import type { WebsiteType } from '../types/WebsiteType.js';
|
|
3
|
+
/**
|
|
4
|
+
* Coleta o `customCss` declarado em qualquer nível (site, página, bloco,
|
|
5
|
+
* componente e elemento) e devolve um único bloco de CSS. É renderizado como
|
|
6
|
+
* `<style>` global, permitindo hover, pseudo-elementos, animações etc.
|
|
7
|
+
*/
|
|
8
|
+
export declare function collectCustomCss(website?: WebsiteType, page?: PageType): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function extract(styles) {
|
|
2
|
+
if (!styles || typeof styles !== 'object')
|
|
3
|
+
return '';
|
|
4
|
+
const css = styles.customCss;
|
|
5
|
+
return typeof css === 'string' && css.trim() ? css.trim() : '';
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Coleta o `customCss` declarado em qualquer nível (site, página, bloco,
|
|
9
|
+
* componente e elemento) e devolve um único bloco de CSS. É renderizado como
|
|
10
|
+
* `<style>` global, permitindo hover, pseudo-elementos, animações etc.
|
|
11
|
+
*/
|
|
12
|
+
export function collectCustomCss(website, page) {
|
|
13
|
+
var _a, _b, _c;
|
|
14
|
+
const parts = [];
|
|
15
|
+
parts.push(extract(website === null || website === void 0 ? void 0 : website.styles));
|
|
16
|
+
parts.push(extract(page === null || page === void 0 ? void 0 : page.styles));
|
|
17
|
+
for (const block of (_a = page === null || page === void 0 ? void 0 : page.blocks) !== null && _a !== void 0 ? _a : []) {
|
|
18
|
+
parts.push(extract(block.styles));
|
|
19
|
+
for (const component of (_b = block.components) !== null && _b !== void 0 ? _b : []) {
|
|
20
|
+
parts.push(extract(component.styles));
|
|
21
|
+
for (const element of (_c = component.elements) !== null && _c !== void 0 ? _c : []) {
|
|
22
|
+
parts.push(extract(element.styles));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return parts.filter(Boolean).join('\n');
|
|
27
|
+
}
|