lib-pixelbuild 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { memo, useMemo } from 'react';
3
- import { PbContainer } from '../ui/PbContainer.js';
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(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsx("div", { style: containerStyle, children: elements.map((element) => {
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,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { memo, useMemo } from 'react';
3
- import { PbContainer } from '../ui/PbContainer.js';
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';
@@ -85,18 +85,22 @@ const CardComponent = memo(function CardComponent({ component }) {
85
85
  const rawGap = cardProps.cardElementGap;
86
86
  const elementGap = rawGap === '' || rawGap == null ? '0' : String(rawGap);
87
87
  const rowGapStyle = { gap: elementGap };
88
+ let content;
88
89
  if (layout === 'icon-left' || layout === 'icon-right') {
89
90
  const icon = elements.find((element) => element.elementType === 'icon');
90
91
  const others = elements.filter((element) => element !== icon);
91
92
  const iconBox = icon ? _jsx("div", { style: { flex: '0 0 auto' }, children: elementFactory.build(stripWidth(icon)) }) : null;
92
93
  const contentBox = (_jsx("div", { style: { flex: '1 1 220px', minWidth: 0 }, children: others.map((element) => elementFactory.build(stripWidth(element))) }));
93
- return (_jsx(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: elementGap, flexWrap: 'wrap' }, children: [layout === 'icon-left' ? iconBox : contentBox, layout === 'icon-left' ? contentBox : iconBox] }) }));
94
+ content = (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: elementGap, flexWrap: 'wrap' }, children: [layout === 'icon-left' ? iconBox : contentBox, layout === 'icon-left' ? contentBox : iconBox] }));
94
95
  }
95
- if (layout === 'icon-top') {
96
+ else if (layout === 'icon-top') {
96
97
  const icon = elements.find((element) => element.elementType === 'icon');
97
98
  const others = elements.filter((element) => element !== icon);
98
- return (_jsx(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsxs("div", { style: { textAlign: 'center', display: 'flex', flexDirection: 'column', gap: elementGap }, children: [icon && _jsx("div", { style: { display: 'inline-block' }, children: elementFactory.build(centerStyles(icon)) }), _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: elementGap }, children: others.map((element) => elementFactory.build(centerStyles(element))) })] }) }));
99
+ content = (_jsxs("div", { style: { textAlign: 'center', display: 'flex', flexDirection: 'column', gap: elementGap }, children: [icon && _jsx("div", { style: { display: 'inline-block' }, children: elementFactory.build(centerStyles(icon)) }), _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: elementGap }, children: others.map((element) => elementFactory.build(centerStyles(element))) })] }));
99
100
  }
100
- return (_jsx(PbContainer, { style: component.styles, children: _jsx(PbRow, { id: "element-row", style: rowGapStyle, children: elements.map((element) => elementFactory.build(element)) }) }));
101
+ else {
102
+ content = (_jsx(PbRow, { id: "element-row", style: rowGapStyle, children: elements.map((element) => elementFactory.build(element)) }));
103
+ }
104
+ return _jsx(ComponentShell, { component: component, children: content });
101
105
  });
102
106
  export { CardComponent };
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { memo, useEffect, useMemo } from 'react';
3
- import { PbContainer } from '../ui/PbContainer.js';
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(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsx("form", { onSubmit: handleSubmit, noValidate: true, children: _jsx(PbRow, { style: { gap: 0 }, children: elements.map((element) => elementFactory.build(element, component.id)) }) }) }));
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 };
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { memo, useMemo } from 'react';
3
- import { PbContainer } from '../ui/PbContainer.js';
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(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsx(PbRow, { id: "element-row", style: { justifyContent: 'center', gap: 0 }, children: elements.map((element) => elementFactory.build(element)) }) }));
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 { PbContainer } from '../ui/PbContainer.js';
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("div", { "data-pb-component": component.id, style: Object.assign(Object.assign({}, component.styles), { width: 'calc(100% + var(--pb-gutter, 1.5rem))', marginLeft: 'calc(var(--pb-gutter, 1.5rem) * -0.5)', marginRight: 'calc(var(--pb-gutter, 1.5rem) * -0.5)' }), children: elements.map((element) => elementFactory.build(Object.assign(Object.assign({}, element), { fullBleed: true }))) }));
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(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsx(PbRow, { id: "element-row", style: { gap: 0 }, children: elements.map((element) => elementFactory.build(element)) }) }));
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("div", { "data-pb-component": component.id, style: component.styles, 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
+ 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("div", { "data-pb-component": component.id, style: component.styles, 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
+ 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,14 @@ 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
- return (_jsxs("div", { ref: containerRef, "data-pb-component": component.id, style: Object.assign({ position: 'relative' }, cleanComponentStyles(component.styles)), children: [_jsx("div", { style: Object.assign({ overflow: 'hidden' }, (fixedHeight ? { height: fixedHeight } : {})), children: _jsx("div", { style: {
181
- display: 'flex',
182
- columnGap: spacing,
183
- transform: `translateX(${translateX}px)`,
184
- transition: animate && !dragging ? 'transform 0.3s ease' : 'none',
185
- cursor: dragging ? 'grabbing' : n > 1 ? 'grab' : 'default',
186
- touchAction: 'pan-y',
187
- userSelect: 'none'
188
- }, 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 }))] }));
181
+ const { containerStyle, bodyStyle } = useMemo(() => getComponentShellStyles(component), [component]);
182
+ 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: {
183
+ display: 'flex',
184
+ columnGap: spacing,
185
+ transform: `translateX(${translateX}px)`,
186
+ transition: animate && !dragging ? 'transform 0.3s ease' : 'none',
187
+ cursor: dragging ? 'grabbing' : n > 1 ? 'grab' : 'default',
188
+ touchAction: 'pan-y',
189
+ userSelect: 'none'
190
+ }, 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
191
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { memo, useMemo } from 'react';
3
- import { PbContainer } from '../ui/PbContainer.js';
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(PbContainer, { "data-pb-component": component.id, style: component.styles, children: _jsx(PbRow, { id: "element-row", style: { gap: elementGap }, children: elements.map((element) => elementFactory.build(element)) }) }));
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("div", { "data-pb-component": component.id, style: Object.assign(Object.assign({}, component.styles), { width: 'calc(100% + var(--pb-gutter, 1.5rem))', marginLeft: 'calc(var(--pb-gutter, 1.5rem) * -0.5)', marginRight: 'calc(var(--pb-gutter, 1.5rem) * -0.5)' }), children: content }));
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("div", { "data-pb-component": component.id, style: component.styles, children: content }));
134
+ return _jsx(ComponentShell, { component: component, outer: "div", children: content });
130
135
  }
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lib-pixelbuild",
3
- "version": "0.3.8",
3
+ "version": "0.4.0",
4
4
  "engines": {
5
5
  "node": "^24.0.0",
6
6
  "npm": ">=10"