lib-pixelbuild 0.2.1 → 0.2.3
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 -26
- package/dist/components/ButtonsComponent.d.ts +5 -0
- package/dist/components/ButtonsComponent.js +45 -0
- package/dist/components/CardComponent.js +31 -6
- package/dist/components/FormComponent.js +9 -4
- package/dist/components/{CarouselComponent.d.ts → IconComponent.d.ts} +3 -2
- package/dist/components/IconComponent.js +12 -0
- package/dist/components/ImageComponent.d.ts +5 -0
- package/dist/components/ImageComponent.js +18 -0
- package/dist/components/ListComponent.js +5 -2
- package/dist/components/LoadingComponent.js +2 -2
- package/dist/components/MapComponent.js +11 -12
- package/dist/components/SliderComponent.d.ts +0 -1
- package/dist/components/SliderComponent.js +173 -93
- package/dist/components/SocialIconsComponent.d.ts +3 -2
- package/dist/components/SocialIconsComponent.js +20 -16
- package/dist/components/TextComponent.js +5 -3
- package/dist/constants/ComponentEnum.d.ts +2 -0
- package/dist/constants/ComponentEnum.js +2 -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 +21 -7
- package/dist/elements/ElementColWrapper.js +11 -2
- package/dist/elements/IconElement.js +5 -5
- package/dist/elements/IconMap.js +101 -28
- package/dist/elements/InputElement.js +10 -9
- package/dist/elements/TextElement.js +5 -1
- package/dist/factories/ButtonActionFactory.d.ts +3 -4
- package/dist/factories/ButtonActionFactory.js +2 -2
- package/dist/factories/ComponentFactory.d.ts +2 -1
- package/dist/factories/ComponentFactory.js +29 -12
- package/dist/index.d.ts +20 -5
- package/dist/index.js +15 -1
- package/dist/layouts/Footer.js +13 -2
- package/dist/layouts/Header.js +43 -16
- package/dist/layouts/SiteLayout.d.ts +8 -1
- package/dist/layouts/SiteLayout.js +36 -3
- package/dist/renderers/BlockRenderer.d.ts +8 -0
- package/dist/renderers/BlockRenderer.js +68 -0
- package/dist/services/EmailService.d.ts +14 -5
- package/dist/services/EmailService.js +21 -24
- package/dist/stores/UseFormStore.d.ts +7 -2
- package/dist/stores/UseFormStore.js +8 -3
- package/dist/types/{SectionColumnType.d.ts → BlockType.d.ts} +2 -6
- package/dist/types/ComponentType.d.ts +3 -0
- package/dist/types/ElementType.d.ts +1 -0
- package/dist/types/EmailSettingsType.d.ts +5 -0
- package/dist/types/HeaderPropertiesType.d.ts +1 -0
- package/dist/types/MailBodyType.d.ts +2 -0
- package/dist/types/PageType.d.ts +2 -2
- package/dist/types/SocialPropertiesType.d.ts +3 -11
- package/dist/types/StylesType.d.ts +12 -0
- package/dist/types/WebsitePropertiesType.d.ts +2 -0
- package/dist/types/WebsiteType.d.ts +6 -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/emailTemplate.d.ts +7 -0
- package/dist/utils/emailTemplate.js +66 -0
- package/dist/utils/fonts.d.ts +2 -0
- package/dist/utils/fonts.js +10 -0
- package/dist/utils/imageCustomization.d.ts +3 -0
- package/dist/utils/imageCustomization.js +9 -0
- package/dist/utils/responsiveProperties.d.ts +2 -0
- package/dist/utils/responsiveProperties.js +28 -0
- package/dist/utils/responsiveStyles.d.ts +6 -0
- package/dist/utils/responsiveStyles.js +73 -0
- package/package.json +1 -8
- package/dist/components/CarouselComponent.js +0 -6
- package/dist/layouts/Menu.d.ts +0 -5
- package/dist/layouts/Menu.js +0 -34
- package/dist/renderers/SectionRenderer.d.ts +0 -6
- package/dist/renderers/SectionRenderer.js +0 -73
- package/dist/types/SectionType.d.ts +0 -10
- /package/dist/types/{SectionColumnType.js → BlockType.js} +0 -0
- /package/dist/types/{SectionType.js → EmailSettingsType.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,9 +1,11 @@
|
|
|
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';
|
|
8
|
+
import { ButtonActionEnum } from '../constants/ButtonActionEnum.js';
|
|
7
9
|
import { getString, getNumber, getBoolean } from '../utils/propertyUtils.js';
|
|
8
10
|
export function ButtonElement({ element, formId }) {
|
|
9
11
|
const properties = element.properties;
|
|
@@ -20,9 +22,9 @@ export function ButtonElement({ element, formId }) {
|
|
|
20
22
|
hidden: getBoolean(properties, 'startHidden')
|
|
21
23
|
});
|
|
22
24
|
return () => unregisterElement(element.id);
|
|
23
|
-
}, [element.id, properties.startHidden, registerElement,
|
|
25
|
+
}, [element.id, properties.startHidden, registerElement, unregisterElement, resolvedFormId]);
|
|
24
26
|
async function handleClick(event) {
|
|
25
|
-
var _a;
|
|
27
|
+
var _a, _b, _c;
|
|
26
28
|
if (!properties.path) {
|
|
27
29
|
event.preventDefault();
|
|
28
30
|
const form = event.currentTarget instanceof HTMLButtonElement ? event.currentTarget.form : null;
|
|
@@ -35,11 +37,21 @@ export function ButtonElement({ element, formId }) {
|
|
|
35
37
|
if (hasErrors)
|
|
36
38
|
return false;
|
|
37
39
|
UseFormStore.getState().setElementState(element.id, { loading: true });
|
|
38
|
-
const actionId = getNumber(properties, 'actionId');
|
|
40
|
+
const actionId = (_a = getNumber(properties, 'actionId')) !== null && _a !== void 0 ? _a : (properties.type === 'submit' ? ButtonActionEnum.SendMail : undefined);
|
|
39
41
|
if (actionId) {
|
|
40
|
-
|
|
42
|
+
const formConfig = resolvedFormId !== undefined ? (_b = UseFormStore.getState().forms[resolvedFormId]) === null || _b === void 0 ? void 0 : _b.email : undefined;
|
|
43
|
+
try {
|
|
44
|
+
await buttonActionFactory.build(actionId, formData, {
|
|
45
|
+
recipient: formConfig === null || formConfig === void 0 ? void 0 : formConfig.recipient,
|
|
46
|
+
subject: formConfig === null || formConfig === void 0 ? void 0 : formConfig.subject,
|
|
47
|
+
formId: resolvedFormId
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.warn('Não foi possível enviar o formulário:', error);
|
|
52
|
+
}
|
|
41
53
|
}
|
|
42
|
-
const loadingTime = (
|
|
54
|
+
const loadingTime = (_c = getNumber(properties, 'loadingTime')) !== null && _c !== void 0 ? _c : 0;
|
|
43
55
|
setTimeout(() => {
|
|
44
56
|
if (getBoolean(properties, 'hideOnClick'))
|
|
45
57
|
hideElement(element.id);
|
|
@@ -58,5 +70,7 @@ export function ButtonElement({ element, formId }) {
|
|
|
58
70
|
const buttonType = properties.type === 'button' || properties.type === 'submit' || properties.type === 'reset'
|
|
59
71
|
? properties.type
|
|
60
72
|
: undefined;
|
|
61
|
-
|
|
73
|
+
const size = getString(properties, 'size');
|
|
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')) }) }));
|
|
62
76
|
}
|
|
@@ -1,5 +1,14 @@
|
|
|
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
|
+
const style = {};
|
|
6
|
+
if (element.fullBleed) {
|
|
7
|
+
style.paddingLeft = '0';
|
|
8
|
+
style.paddingRight = '0';
|
|
9
|
+
}
|
|
10
|
+
if ((_a = element.styles) === null || _a === void 0 ? void 0 : _a.textAlign) {
|
|
11
|
+
style.textAlign = element.styles.textAlign;
|
|
12
|
+
}
|
|
13
|
+
return (_jsx(PbCol, { colId: element.id, width: element.width, offset: element.offset, style: style, "data-pb-element": element.id, children: children }));
|
|
5
14
|
}
|
|
@@ -3,13 +3,13 @@ import { Suspense, useMemo } from 'react';
|
|
|
3
3
|
import { iconMap } from './IconMap.js';
|
|
4
4
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
5
5
|
function FallbackIcon({ name }) {
|
|
6
|
-
const Icon = iconMap[name] || iconMap.
|
|
6
|
+
const Icon = iconMap[name] || iconMap.question;
|
|
7
7
|
return _jsx(Icon, { size: "1em", "aria-label": name || 'Icon' });
|
|
8
8
|
}
|
|
9
9
|
export function IconElement({ element }) {
|
|
10
|
-
var _a;
|
|
11
10
|
const name = String(element.properties.name || '');
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
11
|
+
const styles = element.styles || {};
|
|
12
|
+
const iconSize = styles.fontSize || '1.25rem';
|
|
13
|
+
const Icon = useMemo(() => iconMap[name] || iconMap.question, [name]);
|
|
14
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx("span", { style: { fontSize: iconSize, display: 'inline-flex', color: styles.color }, children: _jsx(Suspense, { fallback: _jsx(FallbackIcon, { name: name }), children: _jsx(Icon, { size: "1em", color: styles.color, style: styles, "aria-label": name || 'Icon' }) }) }) }));
|
|
15
15
|
}
|
package/dist/elements/IconMap.js
CHANGED
|
@@ -1,30 +1,103 @@
|
|
|
1
|
-
import { FaArrowRight,
|
|
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
|
-
FaArrowRight,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
3
|
+
'arrow-right': FaArrowRight,
|
|
4
|
+
'arrow-left': FaArrowLeft,
|
|
5
|
+
'arrow-up': FaArrowUp,
|
|
6
|
+
'arrow-down': FaArrowDown,
|
|
7
|
+
'chevron-right': FaChevronRight,
|
|
8
|
+
'chevron-left': FaChevronLeft,
|
|
9
|
+
'chevron-up': FaChevronUp,
|
|
10
|
+
'chevron-down': FaChevronDown,
|
|
11
|
+
'long-arrow-right': FaLongArrowAltRight,
|
|
12
|
+
'long-arrow-left': FaLongArrowAltLeft,
|
|
13
|
+
bars: FaBars,
|
|
14
|
+
times: FaTimes,
|
|
15
|
+
check: FaCheck,
|
|
16
|
+
plus: FaPlus,
|
|
17
|
+
minus: FaMinus,
|
|
18
|
+
search: FaSearch,
|
|
19
|
+
home: FaHome,
|
|
20
|
+
user: FaUser,
|
|
21
|
+
users: FaUsers,
|
|
22
|
+
cog: FaCog,
|
|
23
|
+
info: FaInfoCircle,
|
|
24
|
+
question: FaQuestionCircle,
|
|
25
|
+
exclamation: FaExclamationTriangle,
|
|
26
|
+
'check-circle': FaCheckCircle,
|
|
27
|
+
'times-circle': FaTimesCircle,
|
|
28
|
+
'external-link': FaExternalLinkAlt,
|
|
29
|
+
download: FaDownload,
|
|
30
|
+
upload: FaUpload,
|
|
31
|
+
sync: FaSync,
|
|
32
|
+
lock: FaLock,
|
|
33
|
+
unlock: FaUnlock,
|
|
34
|
+
eye: FaEye,
|
|
35
|
+
'eye-slash': FaEyeSlash,
|
|
36
|
+
bell: FaBell,
|
|
37
|
+
star: FaStar,
|
|
38
|
+
heart: FaHeart,
|
|
39
|
+
list: FaList,
|
|
40
|
+
grid: FaTh,
|
|
41
|
+
'grid-large': FaThLarge,
|
|
42
|
+
filter: FaFilter,
|
|
43
|
+
phone: FaPhone,
|
|
44
|
+
envelope: FaEnvelope,
|
|
45
|
+
'envelope-open': FaEnvelopeOpen,
|
|
46
|
+
comment: FaComment,
|
|
47
|
+
comments: FaComments,
|
|
48
|
+
'quote-left': FaQuoteLeft,
|
|
49
|
+
'quote-right': FaQuoteRight,
|
|
50
|
+
'paper-plane': FaPaperPlane,
|
|
51
|
+
facebook: FaFacebookF,
|
|
52
|
+
instagram: FaInstagram,
|
|
53
|
+
whatsapp: FaWhatsapp,
|
|
54
|
+
youtube: FaYoutube,
|
|
55
|
+
twitter: FaTwitter,
|
|
56
|
+
linkedin: FaLinkedinIn,
|
|
57
|
+
pinterest: FaPinterestP,
|
|
58
|
+
'shopping-cart': FaShoppingCart,
|
|
59
|
+
'shopping-bag': FaShoppingBag,
|
|
60
|
+
'credit-card': FaCreditCard,
|
|
61
|
+
money: FaMoneyBillWave,
|
|
62
|
+
tag: FaTag,
|
|
63
|
+
tags: FaTags,
|
|
64
|
+
gift: FaGift,
|
|
65
|
+
truck: FaTruck,
|
|
66
|
+
'map-marker': FaMapMarkerAlt,
|
|
67
|
+
map: FaMap,
|
|
68
|
+
'map-pin': FaMapPin,
|
|
69
|
+
globe: FaGlobe,
|
|
70
|
+
compass: FaCompass,
|
|
71
|
+
'location-arrow': FaLocationArrow,
|
|
72
|
+
clock: FaClock,
|
|
73
|
+
calendar: FaCalendar,
|
|
74
|
+
'calendar-alt': FaCalendarAlt,
|
|
75
|
+
hourglass: FaHourglassHalf,
|
|
76
|
+
image: FaImage,
|
|
77
|
+
images: FaImages,
|
|
78
|
+
camera: FaCamera,
|
|
79
|
+
video: FaVideo,
|
|
80
|
+
film: FaFilm,
|
|
81
|
+
music: FaMusic,
|
|
82
|
+
headphones: FaHeadphones,
|
|
83
|
+
play: FaPlay,
|
|
84
|
+
briefcase: FaBriefcase,
|
|
85
|
+
building: FaBuilding,
|
|
86
|
+
'chart-bar': FaChartBar,
|
|
87
|
+
'chart-line': FaChartLine,
|
|
88
|
+
'chart-pie': FaChartPie,
|
|
89
|
+
rocket: FaRocket,
|
|
90
|
+
lightbulb: FaLightbulb,
|
|
91
|
+
trophy: FaTrophy,
|
|
92
|
+
medal: FaMedal,
|
|
93
|
+
flag: FaFlag,
|
|
94
|
+
file: FaFile,
|
|
95
|
+
folder: FaFolder,
|
|
96
|
+
link: FaLink,
|
|
97
|
+
pencil: FaPencilAlt,
|
|
98
|
+
trash: FaTrashAlt,
|
|
99
|
+
copy: FaCopy,
|
|
100
|
+
cloud: FaCloud,
|
|
101
|
+
wifi: FaWifi,
|
|
102
|
+
mobile: FaMobileAlt
|
|
30
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
|
-
return (_jsx(ElementColWrapper, { element: element, children: _jsx(TitleTag, { style: element.styles, children: text }) }));
|
|
11
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx(TitleTag, { style: Object.assign({ margin: 0 }, element.styles), children: text }) }));
|
|
12
|
+
}
|
|
13
|
+
if (isSimple) {
|
|
14
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx("div", { style: Object.assign({ whiteSpace: 'pre-wrap' }, element.styles), children: text }) }));
|
|
11
15
|
}
|
|
12
16
|
return (_jsx(ElementColWrapper, { element: element, children: _jsx("div", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(text) }, style: element.styles }) }));
|
|
13
17
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { type EmailServiceConfig } from '../services/EmailService.js';
|
|
1
|
+
import { type EmailServiceConfig, type EmailSendOptions } from '../services/EmailService.js';
|
|
2
2
|
import type { FormFieldsType } from '../types/FormFieldsType.js';
|
|
3
|
-
import type { MailBodyType } from '../types/MailBodyType.js';
|
|
4
3
|
declare class ButtonActionFactory {
|
|
5
4
|
private emailService;
|
|
6
5
|
configureEmail(config: EmailServiceConfig): void;
|
|
7
|
-
build(actionId: number, data: FormFieldsType[]): Promise<
|
|
6
|
+
build(actionId: number, data: FormFieldsType[], options?: EmailSendOptions): Promise<boolean>;
|
|
8
7
|
}
|
|
9
8
|
export declare const buttonActionFactory: ButtonActionFactory;
|
|
10
|
-
export type { EmailServiceConfig } from '../services/EmailService.js';
|
|
9
|
+
export type { EmailServiceConfig, EmailSendOptions } from '../services/EmailService.js';
|
|
@@ -7,13 +7,13 @@ class ButtonActionFactory {
|
|
|
7
7
|
configureEmail(config) {
|
|
8
8
|
this.emailService = new EmailService(config);
|
|
9
9
|
}
|
|
10
|
-
async build(actionId, data) {
|
|
10
|
+
async build(actionId, data, options) {
|
|
11
11
|
switch (actionId) {
|
|
12
12
|
case ButtonActionEnum.SendMail: {
|
|
13
13
|
if (!this.emailService) {
|
|
14
14
|
throw new Error('EmailService not configured. Call configureEmail() before using SendMail action.');
|
|
15
15
|
}
|
|
16
|
-
return this.emailService.sendMail(data);
|
|
16
|
+
return this.emailService.sendMail(data, options);
|
|
17
17
|
}
|
|
18
18
|
default:
|
|
19
19
|
throw new Error('Invalid button action: ' + actionId);
|
|
@@ -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
|
}
|
|
@@ -1,36 +1,53 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { ComponentTypeEnum } from '../constants/ComponentEnum.js';
|
|
3
3
|
import { TextComponent } from '../components/TextComponent.js';
|
|
4
|
+
import { ImageComponent } from '../components/ImageComponent.js';
|
|
4
5
|
import { ListComponent } from '../components/ListComponent.js';
|
|
5
|
-
import { CarouselComponent } from '../components/CarouselComponent.js';
|
|
6
6
|
import { FormComponent } from '../components/FormComponent.js';
|
|
7
7
|
import { SliderComponent } from '../components/SliderComponent.js';
|
|
8
8
|
import { CardComponent } from '../components/CardComponent.js';
|
|
9
9
|
import { MapComponent } from '../components/MapComponent.js';
|
|
10
|
+
import { ButtonsComponent } from '../components/ButtonsComponent.js';
|
|
11
|
+
import { IconComponent } from '../components/IconComponent.js';
|
|
12
|
+
/**
|
|
13
|
+
* Aplica os estilos padrão do design system (`componentDefaults`) antes dos
|
|
14
|
+
* estilos da instância — o override da instância prevalece.
|
|
15
|
+
*/
|
|
16
|
+
function applyDefaults(component, defaults) {
|
|
17
|
+
const typeDefaults = defaults === null || defaults === void 0 ? void 0 : defaults[component.componentType];
|
|
18
|
+
if (!typeDefaults || Object.keys(typeDefaults).length === 0)
|
|
19
|
+
return component;
|
|
20
|
+
return Object.assign(Object.assign({}, component), { styles: Object.assign(Object.assign({}, typeDefaults), component.styles) });
|
|
21
|
+
}
|
|
10
22
|
export class ComponentFactory {
|
|
11
|
-
build(component, editionMode = false) {
|
|
12
|
-
|
|
23
|
+
build(component, editionMode = false, defaults) {
|
|
24
|
+
const resolved = applyDefaults(component, defaults);
|
|
25
|
+
switch (resolved.componentType) {
|
|
13
26
|
case ComponentTypeEnum.Text:
|
|
14
27
|
case ComponentTypeEnum.TextWithImage:
|
|
15
28
|
case ComponentTypeEnum.HeroBanner:
|
|
16
|
-
return _jsx(TextComponent, { component:
|
|
29
|
+
return _jsx(TextComponent, { component: resolved }, resolved.id);
|
|
30
|
+
case ComponentTypeEnum.Image:
|
|
31
|
+
return _jsx(ImageComponent, { component: resolved }, resolved.id);
|
|
17
32
|
case ComponentTypeEnum.List:
|
|
18
|
-
return _jsx(ListComponent, { component:
|
|
33
|
+
return _jsx(ListComponent, { component: resolved }, resolved.id);
|
|
19
34
|
case ComponentTypeEnum.Slider:
|
|
20
35
|
case ComponentTypeEnum.Gallery:
|
|
21
36
|
case ComponentTypeEnum.Testimonials:
|
|
22
|
-
return _jsx(SliderComponent, { component:
|
|
37
|
+
return _jsx(SliderComponent, { component: resolved, editionMode: editionMode }, resolved.id);
|
|
23
38
|
case ComponentTypeEnum.Form:
|
|
24
|
-
return _jsx(FormComponent, { component:
|
|
39
|
+
return _jsx(FormComponent, { component: resolved }, resolved.id);
|
|
25
40
|
case ComponentTypeEnum.Card:
|
|
26
41
|
case ComponentTypeEnum.Faq:
|
|
27
|
-
return _jsx(CardComponent, { component:
|
|
28
|
-
case ComponentTypeEnum.Image:
|
|
29
|
-
return _jsx(CarouselComponent, { component: component }, component.id);
|
|
42
|
+
return _jsx(CardComponent, { component: resolved }, resolved.id);
|
|
30
43
|
case ComponentTypeEnum.Map:
|
|
31
|
-
return _jsx(MapComponent, { component:
|
|
44
|
+
return _jsx(MapComponent, { component: resolved }, resolved.id);
|
|
45
|
+
case ComponentTypeEnum.Buttons:
|
|
46
|
+
return _jsx(ButtonsComponent, { component: resolved }, resolved.id);
|
|
47
|
+
case ComponentTypeEnum.Icon:
|
|
48
|
+
return _jsx(IconComponent, { component: resolved }, resolved.id);
|
|
32
49
|
default:
|
|
33
|
-
throw new Error('Invalid component type: ' +
|
|
50
|
+
throw new Error('Invalid component type: ' + resolved.componentType);
|
|
34
51
|
}
|
|
35
52
|
}
|
|
36
53
|
}
|
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';
|
|
@@ -10,14 +9,30 @@ export type { PropertiesType } from './types/PropertiesType.js';
|
|
|
10
9
|
export type { StylesType } from './types/StylesType.js';
|
|
11
10
|
export { Header } from './layouts/Header.js';
|
|
12
11
|
export { Footer } from './layouts/Footer.js';
|
|
13
|
-
export { SiteLayout } from './layouts/SiteLayout.js';
|
|
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
16
|
export { LoadingComponent } from './components/LoadingComponent.js';
|
|
17
17
|
export { ComponentFactory } from './factories/ComponentFactory.js';
|
|
18
18
|
export { ElementFactory } from './factories/ElementFactory.js';
|
|
19
|
+
export { iconMap } from './elements/IconMap.js';
|
|
19
20
|
export { ComponentTypeEnum } from './constants/ComponentEnum.js';
|
|
20
21
|
export { ElementTypeEnum } from './constants/ElementEnum.js';
|
|
22
|
+
export { ButtonActionEnum } from './constants/ButtonActionEnum.js';
|
|
21
23
|
export { analyticsService } from './services/AnalyticsService.js';
|
|
22
24
|
export { buttonActionFactory } from './factories/ButtonActionFactory.js';
|
|
23
|
-
export type { EmailServiceConfig } from './services/EmailService.js';
|
|
25
|
+
export type { EmailServiceConfig, EmailSendOptions } from './services/EmailService.js';
|
|
26
|
+
export type { EmailSettingsType } from './types/EmailSettingsType.js';
|
|
27
|
+
export type { DesignTokens, DesignColors, DesignTypography, DesignSpacing, DesignRadius, DesignShadow, PartialDesignTokens, DeepPartial } from './designSystem/tokens.js';
|
|
28
|
+
export { defaultTokens, mergeTokens, tokenToCssVars, buildTokenCss, buildThemeVars } from './designSystem/tokens.js';
|
|
29
|
+
export { baseCss } from './designSystem/baseCss.js';
|
|
30
|
+
export { buildSiteCss } from './designSystem/buildSiteCss.js';
|
|
31
|
+
export { themeVarsStyle } from './designSystem/themeVars.js';
|
|
32
|
+
export { ThemeStyle } from './designSystem/theme.js';
|
|
33
|
+
export { PbContainer } from './ui/PbContainer.js';
|
|
34
|
+
export { PbRow } from './ui/PbRow.js';
|
|
35
|
+
export { PbCol } from './ui/PbCol.js';
|
|
36
|
+
export { PbButton } from './ui/PbButton.js';
|
|
37
|
+
export { PbSpinner } from './ui/PbSpinner.js';
|
|
38
|
+
export { PbAlert } from './ui/PbAlert.js';
|