lib-pixelbuild 0.1.0 → 0.1.2

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.
Files changed (48) hide show
  1. package/dist/builders/PageBuilder.d.ts +1 -1
  2. package/dist/builders/PageBuilder.js +1 -1
  3. package/dist/components/CardComponent.d.ts +2 -1
  4. package/dist/components/CardComponent.js +3 -4
  5. package/dist/components/CarouselComponent.d.ts +1 -1
  6. package/dist/components/CarouselComponent.js +2 -3
  7. package/dist/components/FormComponent.d.ts +2 -1
  8. package/dist/components/FormComponent.js +4 -5
  9. package/dist/components/ListComponent.d.ts +1 -1
  10. package/dist/components/ListComponent.js +4 -3
  11. package/dist/components/LoadingComponent.d.ts +1 -1
  12. package/dist/components/MapComponent.d.ts +1 -1
  13. package/dist/components/MapComponent.js +1 -1
  14. package/dist/components/SliderComponent.d.ts +3 -2
  15. package/dist/components/SliderComponent.js +36 -9
  16. package/dist/components/SocialIconsComponent.d.ts +1 -1
  17. package/dist/components/TextComponent.d.ts +2 -1
  18. package/dist/components/TextComponent.js +3 -4
  19. package/dist/elements/AlertElement.d.ts +3 -2
  20. package/dist/elements/AlertElement.js +6 -3
  21. package/dist/elements/ButtonElement.d.ts +3 -2
  22. package/dist/elements/ButtonElement.js +15 -6
  23. package/dist/elements/ElementColWrapper.d.ts +1 -1
  24. package/dist/elements/FileElement.d.ts +1 -1
  25. package/dist/elements/IconElement.d.ts +2 -1
  26. package/dist/elements/IconElement.js +9 -8
  27. package/dist/elements/ImageElement.d.ts +1 -1
  28. package/dist/elements/InputElement.d.ts +3 -2
  29. package/dist/elements/InputElement.js +77 -7
  30. package/dist/elements/LinkElement.d.ts +1 -1
  31. package/dist/elements/TextElement.d.ts +1 -1
  32. package/dist/factories/ComponentFactory.d.ts +1 -1
  33. package/dist/factories/ComponentFactory.js +2 -2
  34. package/dist/factories/ElementFactory.d.ts +1 -1
  35. package/dist/factories/ElementFactory.js +6 -8
  36. package/dist/layouts/Footer.d.ts +1 -1
  37. package/dist/layouts/Footer.js +1 -1
  38. package/dist/layouts/Header.d.ts +1 -1
  39. package/dist/layouts/Header.js +2 -2
  40. package/dist/layouts/Menu.d.ts +1 -1
  41. package/dist/layouts/SiteLayout.d.ts +1 -1
  42. package/dist/renderers/SectionRenderer.d.ts +4 -2
  43. package/dist/renderers/SectionRenderer.js +32 -16
  44. package/dist/stores/UseFormStore.d.ts +1 -0
  45. package/dist/stores/UseFormStore.js +41 -2
  46. package/dist/utils/orderBySort.d.ts +3 -0
  47. package/dist/utils/orderBySort.js +3 -0
  48. package/package.json +24 -8
@@ -4,4 +4,4 @@ export declare function PageBuilder({ website, page, editionMode }: {
4
4
  readonly website: WebsiteType;
5
5
  readonly page: PageType;
6
6
  readonly editionMode: boolean;
7
- }): import("react/jsx-runtime").JSX.Element;
7
+ }): import("react").JSX.Element;
@@ -36,5 +36,5 @@ export function PageBuilder({ website, page, editionMode }) {
36
36
  marginBottom: mergedStyles.marginBottom,
37
37
  borderRadius: mergedStyles.borderRadius,
38
38
  minHeight: page.sections.length === 0 ? '200px' : undefined,
39
- }, children: [_jsx(SectionRenderer, { sections: page.sections }), page.sections.length === 0 && editionMode && (_jsx("div", { style: { padding: '40px', textAlign: 'center', color: '#94a3b8' }, children: "Nenhuma se\u00E7\u00E3o configurada. Use o editor de layout para adicionar conte\u00FAdo." }))] })] }));
39
+ }, children: [_jsx(SectionRenderer, { sections: page.sections, editionMode: editionMode }), page.sections.length === 0 && editionMode && (_jsx("div", { style: { padding: '40px', textAlign: 'center', color: '#94a3b8' }, children: "Nenhuma se\u00E7\u00E3o configurada. Use o editor de layout para adicionar conte\u00FAdo." }))] })] }));
40
40
  }
@@ -1,4 +1,5 @@
1
+ import React from 'react';
1
2
  import type { ComponentType } from '../types/ComponentType.js';
2
3
  export declare function CardComponent({ component }: {
3
4
  readonly component: ComponentType;
4
- }): import("react/jsx-runtime").JSX.Element;
5
+ }): React.JSX.Element;
@@ -2,11 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Row, Container } from 'react-bootstrap';
4
4
  import { ElementFactory } from '../factories/ElementFactory.js';
5
+ import { orderBySort } from '../utils/orderBySort.js';
6
+ const elementFactory = new ElementFactory();
5
7
  export function CardComponent({ component }) {
6
- const elementFactory = new ElementFactory();
7
- return (_jsx(Container, { style: component.styles, children: _jsx(Row, { id: "element-row", children: component.elements
8
- .sort((a, b) => a.sort - b.sort)
9
- .map((element) => {
8
+ return (_jsx(Container, { style: component.styles, children: _jsx(Row, { id: "element-row", children: orderBySort(component.elements).map((element) => {
10
9
  const e = elementFactory.build(element);
11
10
  return React.cloneElement(e, { key: element.id });
12
11
  }) }) }));
@@ -1,4 +1,4 @@
1
1
  import type { ComponentType } from '../types/ComponentType.js';
2
2
  export declare function CarouselComponent({ component }: {
3
3
  readonly component: ComponentType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Row, Col, Carousel } from 'react-bootstrap';
3
+ import { orderBySort } from '../utils/orderBySort.js';
3
4
  export function CarouselComponent({ component }) {
4
- return (_jsx(Row, { children: _jsx(Col, { children: _jsx(Carousel, { indicators: false, className: "slider", children: component.elements
5
- .sort((a, b) => a.sort - b.sort)
6
- .map((element, index) => (_jsx(Carousel.Item, { children: _jsx("img", { src: String(element.properties.name || element.properties.src || ''), alt: String(element.properties.title || element.properties.alt || ''), style: { width: '100%', height: 'auto', objectFit: 'cover' } }) }, element.id || index))) }) }) }));
5
+ return (_jsx(Row, { children: _jsx(Col, { children: _jsx(Carousel, { indicators: false, className: "slider", children: orderBySort(component.elements).map((element, index) => (_jsx(Carousel.Item, { children: _jsx("img", { src: String(element.properties.name || element.properties.src || ''), alt: String(element.properties.title || element.properties.alt || ''), style: { width: '100%', height: 'auto', objectFit: 'cover' } }) }, element.id || index))) }) }) }));
7
6
  }
@@ -1,4 +1,5 @@
1
+ import React from 'react';
1
2
  import type { ComponentType } from '../types/ComponentType.js';
2
3
  export declare function FormComponent({ component }: {
3
4
  readonly component: ComponentType;
4
- }): import("react/jsx-runtime").JSX.Element;
5
+ }): React.JSX.Element;
@@ -3,8 +3,9 @@ import React, { useEffect } from 'react';
3
3
  import { Form, Row } from 'react-bootstrap';
4
4
  import { UseFormStore } from '../stores/UseFormStore.js';
5
5
  import { ElementFactory } from '../factories/ElementFactory.js';
6
+ import { orderBySort } from '../utils/orderBySort.js';
7
+ const elementFactory = new ElementFactory();
6
8
  export function FormComponent({ component }) {
7
- const elementFactory = new ElementFactory();
8
9
  const registerForm = UseFormStore((state) => state.registerForm);
9
10
  useEffect(() => {
10
11
  registerForm(component.id);
@@ -17,10 +18,8 @@ export function FormComponent({ component }) {
17
18
  console.error('Erro ao enviar o formulário:', error);
18
19
  }
19
20
  };
20
- return (_jsx(Form, { noValidate: true, onSubmit: handleSubmit, style: { textAlign: 'left' }, children: _jsx(Row, { style: { padding: '50px' }, children: component.elements
21
- .sort((a, b) => a.sort - b.sort)
22
- .map((element) => {
23
- const e = elementFactory.build(element);
21
+ return (_jsx(Form, { onSubmit: handleSubmit, children: _jsx(Row, { children: orderBySort(component.elements).map((element) => {
22
+ const e = elementFactory.build(element, component.id);
24
23
  return React.cloneElement(e, { key: element.id });
25
24
  }) }) }));
26
25
  }
@@ -1,4 +1,4 @@
1
1
  import type { ComponentType } from '../types/ComponentType.js';
2
2
  export declare function ListComponent({ component }: {
3
3
  readonly component: ComponentType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -2,9 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Col } from 'react-bootstrap';
3
3
  import { ElementFactory } from '../factories/ElementFactory.js';
4
4
  import { ElementTypeEnum } from '../constants/ElementEnum.js';
5
+ import { orderBySort } from '../utils/orderBySort.js';
6
+ const elementFactory = new ElementFactory();
5
7
  export function ListComponent({ component }) {
6
- const elementFactory = new ElementFactory();
7
- const elements = component.elements.sort((a, b) => a.sort - b.sort);
8
+ const elements = orderBySort(component.elements);
8
9
  const items = [];
9
10
  for (let i = 0; i < elements.length; i++) {
10
11
  const current = elements[i];
@@ -19,5 +20,5 @@ export function ListComponent({ component }) {
19
20
  }
20
21
  }
21
22
  }
22
- return (_jsx(Col, { style: component.styles, children: _jsx("ul", { style: { listStyle: 'none', padding: 0, margin: 0 }, children: items.map(({ icon, text, id }) => (_jsxs("li", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '8px' }, children: [_jsx("span", { children: elementFactory.build(icon) }), _jsx("span", { style: { fontSize: '22px' }, children: text ? elementFactory.build(text) : null })] }, id))) }) }));
23
+ return (_jsx(Col, { style: component.styles, children: _jsx("ul", { style: { listStyle: 'none' }, children: items.map(({ icon, text, id }) => (_jsxs("li", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '8px' }, children: [_jsx("span", { children: elementFactory.build(icon) }), _jsx("span", { style: { fontSize: '22px' }, children: text ? elementFactory.build(text) : null })] }, id))) }) }));
23
24
  }
@@ -1 +1 @@
1
- export declare function LoadingComponent(): import("react/jsx-runtime").JSX.Element;
1
+ export declare function LoadingComponent(): import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import type { ComponentType } from '../types/ComponentType.js';
2
2
  export declare function MapComponent({ component }: {
3
3
  readonly component: ComponentType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -5,7 +5,7 @@ export function MapComponent({ component }) {
5
5
  const src = lat && lng
6
6
  ? `https://maps.google.com/maps?q=${lat},${lng}&z=${zoom}&output=embed`
7
7
  : null;
8
- return (_jsx(Col, { style: component.styles, children: _jsx(Row, { children: _jsx(Col, { style: { padding: 0 }, 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: {
8
+ return (_jsx(Col, { style: component.styles, children: _jsx(Row, { children: _jsx(Col, { 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: {
9
9
  width: '100%',
10
10
  height,
11
11
  backgroundColor: '#e0e0e0',
@@ -1,5 +1,6 @@
1
1
  import type { ComponentType } from '../types/ComponentType.js';
2
2
  import 'keen-slider/keen-slider.min.css';
3
- export declare function SliderComponent({ component }: {
3
+ export declare function SliderComponent({ component, editionMode }: {
4
4
  readonly component: ComponentType;
5
- }): import("react/jsx-runtime").JSX.Element;
5
+ readonly editionMode?: boolean;
6
+ }): import("react").JSX.Element;
@@ -1,16 +1,43 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Row, Col } from 'react-bootstrap';
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
3
  import { useKeenSlider } from 'keen-slider/react.js';
4
4
  import { ElementFactory } from '../factories/ElementFactory.js';
5
+ import { orderBySort } from '../utils/orderBySort.js';
5
6
  import 'keen-slider/keen-slider.min.css';
6
- export function SliderComponent({ component }) {
7
- const elementFactory = new ElementFactory();
8
- const [ref] = useKeenSlider({
9
- loop: true,
7
+ const elementFactory = new ElementFactory();
8
+ function StaticSliderComponent({ component }) {
9
+ const firstSlide = orderBySort(component.elements)[0];
10
+ return (_jsx("div", { style: Object.assign({ position: 'relative', overflow: 'hidden' }, component.styles), children: firstSlide && elementFactory.build(firstSlide) }));
11
+ }
12
+ function InteractiveSliderComponent({ component }) {
13
+ const properties = component.properties;
14
+ const slides = orderBySort(component.elements);
15
+ const [currentSlide, setCurrentSlide] = useState(0);
16
+ const [loaded, setLoaded] = useState(false);
17
+ const [ref, instanceRef] = useKeenSlider({
18
+ loop: slides.length > 1,
10
19
  mode: 'snap',
11
20
  slides: { perView: 1, spacing: 10 },
21
+ created() {
22
+ setLoaded(true);
23
+ },
24
+ slideChanged(slider) {
25
+ setCurrentSlide(slider.track.details.rel);
26
+ }
12
27
  });
13
- return (_jsx(Col, { style: component.styles, children: _jsx(Row, { id: "element-row", children: _jsx(Col, { children: _jsx("div", { ref: ref, className: "keen-slider", children: component.elements
14
- .sort((a, b) => a.sort - b.sort)
15
- .map((element) => (_jsx("div", { className: "keen-slider__slide", children: elementFactory.build(element) }, element.id))) }) }) }) }));
28
+ useEffect(() => {
29
+ if (!properties.autoplay || slides.length < 2)
30
+ return;
31
+ const interval = Number(properties.interval) > 0 ? Number(properties.interval) : 5000;
32
+ const timer = window.setInterval(() => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.next(); }, interval);
33
+ return () => window.clearInterval(timer);
34
+ }, [instanceRef, properties.autoplay, properties.interval, slides.length]);
35
+ const showArrows = Boolean(properties.showArrows) && loaded && slides.length > 1;
36
+ const showDots = Boolean(properties.showDots) && loaded && slides.length > 1;
37
+ return (_jsxs("div", { style: Object.assign({ position: 'relative' }, component.styles), children: [_jsx("div", { ref: ref, className: "keen-slider", children: slides.map((element) => (_jsx("div", { className: "keen-slider__slide", children: elementFactory.build(element) }, element.id))) }), showArrows && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", "aria-label": "Slide anterior", onClick: () => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.prev(); }, style: { position: 'absolute', left: 0, top: '50%', transform: 'translateY(-50%)' }, children: '<' }), _jsx("button", { type: "button", "aria-label": "Proximo slide", onClick: () => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.next(); }, style: { position: 'absolute', right: 0, top: '50%', transform: 'translateY(-50%)' }, children: '>' })] })), showDots && (_jsx("div", { "aria-label": "Navegacao do slider", style: { display: 'flex', justifyContent: 'center', gap: 4 }, children: slides.map((element, index) => (_jsx("button", { type: "button", "aria-label": `Ir para o slide ${index + 1}`, "aria-current": currentSlide === index ? 'true' : undefined, onClick: () => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.moveToIdx(index); }, children: index + 1 }, element.id))) }))] }));
38
+ }
39
+ export function SliderComponent({ component, editionMode = false }) {
40
+ if (editionMode)
41
+ return _jsx(StaticSliderComponent, { component: component });
42
+ return _jsx(InteractiveSliderComponent, { component: component });
16
43
  }
@@ -1,4 +1,4 @@
1
1
  import type { SocialPropertiesType } from '../types/SocialPropertiesType.js';
2
2
  export declare function SocialIconsComponent({ social }: {
3
3
  readonly social: SocialPropertiesType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,4 +1,5 @@
1
+ import React from 'react';
1
2
  import type { ComponentType } from '../types/ComponentType.js';
2
3
  export declare function TextComponent({ component }: {
3
4
  readonly component: ComponentType;
4
- }): import("react/jsx-runtime").JSX.Element;
5
+ }): React.JSX.Element;
@@ -2,11 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Row, Container } from 'react-bootstrap';
4
4
  import { ElementFactory } from '../factories/ElementFactory.js';
5
+ import { orderBySort } from '../utils/orderBySort.js';
6
+ const elementFactory = new ElementFactory();
5
7
  export function TextComponent({ component }) {
6
- const elementFactory = new ElementFactory();
7
- return (_jsx(Container, { style: component.styles, children: _jsx(Row, { id: "element-row", children: component.elements
8
- .sort((a, b) => a.sort - b.sort)
9
- .map((element) => {
8
+ return (_jsx(Container, { style: component.styles, children: _jsx(Row, { id: "element-row", children: orderBySort(component.elements).map((element) => {
10
9
  const e = elementFactory.build(element);
11
10
  return React.cloneElement(e, { key: element.id });
12
11
  }) }) }));
@@ -1,4 +1,5 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
- export declare function AlertElement({ element }: {
2
+ export declare function AlertElement({ element, formId }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ readonly formId?: number;
5
+ }): import("react").JSX.Element;
@@ -3,16 +3,19 @@ import { useEffect } from 'react';
3
3
  import { Alert } from 'react-bootstrap';
4
4
  import { UseFormStore } from '../stores/UseFormStore.js';
5
5
  import { ElementColWrapper } from './ElementColWrapper.js';
6
- export function AlertElement({ element }) {
6
+ export function AlertElement({ element, formId }) {
7
7
  const properties = element.properties;
8
+ const resolvedFormId = formId !== null && formId !== void 0 ? formId : properties.componentId;
8
9
  const hidden = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.hidden; });
9
10
  const registerElement = UseFormStore((state) => state.registerElement);
11
+ const unregisterElement = UseFormStore((state) => state.unregisterElement);
10
12
  useEffect(() => {
11
- registerElement(element.id, element.properties.componentId, {
13
+ registerElement(element.id, resolvedFormId, {
12
14
  type: 'alert',
13
15
  hidden: Boolean(properties.startHidden)
14
16
  });
15
- }, [element.id, properties.startHidden, registerElement]);
17
+ return () => unregisterElement(element.id);
18
+ }, [element.id, properties.startHidden, registerElement, resolvedFormId, unregisterElement]);
16
19
  if (hidden)
17
20
  return null;
18
21
  return (_jsx(ElementColWrapper, { element: element, children: _jsxs(Alert, { hidden: hidden, variant: String(properties.type || 'info'), style: element.styles, children: [_jsx(Alert.Heading, { children: String(properties.title || '') }), _jsx("p", { className: "mb-0", children: String(properties.message || '') })] }) }));
@@ -1,4 +1,5 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
- export declare function ButtonElement({ element }: {
2
+ export declare function ButtonElement({ element, formId }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ readonly formId?: number;
5
+ }): import("react").JSX.Element;
@@ -4,26 +4,33 @@ import { Button, Spinner } from 'react-bootstrap';
4
4
  import { ElementColWrapper } from './ElementColWrapper.js';
5
5
  import { UseFormStore } from '../stores/UseFormStore.js';
6
6
  import { ButtonActionFactory } from '../factories/ButtonActionFactory.js';
7
- export function ButtonElement({ element }) {
7
+ export function ButtonElement({ element, formId }) {
8
8
  var _a;
9
9
  const properties = element.properties;
10
+ const resolvedFormId = formId !== null && formId !== void 0 ? formId : properties.componentId;
10
11
  const hidden = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.hidden; });
11
12
  const loading = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.loading; });
12
13
  const showElement = UseFormStore((state) => state.showElement);
13
14
  const hideElement = UseFormStore((state) => state.hideElement);
14
15
  const registerElement = UseFormStore((state) => state.registerElement);
16
+ const unregisterElement = UseFormStore((state) => state.unregisterElement);
15
17
  useEffect(() => {
16
- registerElement(element.id, properties.componentId, {
18
+ registerElement(element.id, resolvedFormId, {
17
19
  type: 'button',
18
20
  hidden: Boolean(properties.startHidden)
19
21
  });
20
- }, [element.id, properties.startHidden, registerElement]);
22
+ return () => unregisterElement(element.id);
23
+ }, [element.id, properties.startHidden, registerElement, resolvedFormId, unregisterElement]);
21
24
  async function handleClick(event) {
22
25
  var _a;
23
26
  if (!properties.path) {
24
27
  event.preventDefault();
25
- UseFormStore.getState().validateAllFields(properties.componentId);
26
- const formData = UseFormStore.getState().getElementsByForm(properties.componentId);
28
+ const form = event.currentTarget instanceof HTMLButtonElement ? event.currentTarget.form : null;
29
+ if (form && !form.reportValidity())
30
+ return false;
31
+ if (resolvedFormId !== undefined)
32
+ UseFormStore.getState().validateAllFields(resolvedFormId);
33
+ const formData = resolvedFormId === undefined ? [] : UseFormStore.getState().getElementsByForm(resolvedFormId);
27
34
  const hasErrors = formData.some((e) => e.error);
28
35
  if (hasErrors)
29
36
  return false;
@@ -46,5 +53,7 @@ export function ButtonElement({ element }) {
46
53
  if (hidden)
47
54
  return null;
48
55
  return (_jsx(ElementColWrapper, { element: element, children: _jsx(Button, { as: properties.path ? 'a' : 'button', type: properties.type === 'button' || properties.type === 'submit' || properties.type === 'reset'
49
- ? properties.type : undefined, variant: String(properties.type || 'primary'), href: String(properties.path || ''), target: properties.path ? '_blank' : undefined, rel: properties.path ? 'noopener noreferrer' : undefined, disabled: loading, onClick: handleClick, style: element.styles, children: loading ? (_jsxs(_Fragment, { children: [_jsx("output", { "aria-busy": "true", children: _jsx(Spinner, { as: "span", animation: "border", size: "sm", "aria-hidden": "true" }) }), ' ' + (String((_a = properties.message) !== null && _a !== void 0 ? _a : ''))] })) : (String(properties.title || '')) }) }));
56
+ ? properties.type : undefined, variant: String(properties.variant || (properties.type === 'button' || properties.type === 'submit' || properties.type === 'reset'
57
+ ? 'primary'
58
+ : properties.type || 'primary')), href: String(properties.path || ''), target: properties.path ? '_blank' : undefined, rel: properties.path ? 'noopener noreferrer' : undefined, disabled: loading, onClick: handleClick, style: element.styles, children: loading ? (_jsxs(_Fragment, { children: [_jsx("output", { "aria-busy": "true", children: _jsx(Spinner, { as: "span", animation: "border", size: "sm", "aria-hidden": "true" }) }), ' ' + (String((_a = properties.message) !== null && _a !== void 0 ? _a : ''))] })) : (String(properties.text || properties.title || '')) }) }));
50
59
  }
@@ -3,4 +3,4 @@ import type { ElementType } from '../types/ElementType.js';
3
3
  export declare function ElementColWrapper({ element, children }: {
4
4
  readonly element: ElementType;
5
5
  readonly children: ReactNode;
6
- }): import("react/jsx-runtime").JSX.Element;
6
+ }): import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
2
  export declare function FileElement({ element }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,4 +1,5 @@
1
+ import React from 'react';
1
2
  import type { ElementType } from '../types/ElementType.js';
2
3
  export declare function IconElement({ element }: {
3
4
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
5
+ }): React.JSX.Element;
@@ -1,13 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { Suspense } from 'react';
2
+ import { FaArrowRight, FaBars, FaCalendar, FaCheck, FaChevronLeft, FaChevronRight, FaClock, FaEnvelope, FaFacebookF, FaGlobe, FaHeart, FaHome, FaInfoCircle, FaInstagram, FaLink, FaMapMarkerAlt, FaPhone, FaQuestionCircle, FaQuoteLeft, FaSearch, FaShoppingCart, FaStar, FaTimes, FaTwitter, FaUser, FaWhatsapp, FaYoutube, } from 'react-icons/fa';
3
3
  import { ElementColWrapper } from './ElementColWrapper.js';
4
+ const icons = {
5
+ FaArrowRight, FaBars, FaCalendar, FaCheck, FaChevronLeft, FaChevronRight, FaClock,
6
+ FaEnvelope, FaFacebookF, FaGlobe, FaHeart, FaHome, FaInfoCircle, FaInstagram, FaLink,
7
+ FaMapMarkerAlt, FaPhone, FaQuoteLeft, FaSearch, FaShoppingCart, FaStar, FaTimes,
8
+ FaTwitter, FaUser, FaWhatsapp, FaYoutube,
9
+ };
4
10
  export function IconElement({ element }) {
5
11
  const name = String(element.properties.name || '');
6
- const LazyIcon = React.lazy(() => import('react-icons/fa').then((module) => {
7
- const Icon = module[name];
8
- if (!Icon)
9
- throw new Error(`Icon '${name}' not found in pack`);
10
- return { default: Icon };
11
- }));
12
- return (_jsx(ElementColWrapper, { element: element, children: _jsx(Suspense, { fallback: null, children: _jsx(LazyIcon, { size: 20, style: element.styles }) }) }));
12
+ const Icon = icons[name] || FaQuestionCircle;
13
+ return (_jsx(ElementColWrapper, { element: element, children: _jsx(Icon, { size: 20, style: element.styles, "aria-label": name || 'Ícone' }) }));
13
14
  }
@@ -1,4 +1,4 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
2
  export declare function ImageElement({ element }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
- export declare function InputElement({ element }: {
2
+ export declare function InputElement({ element, formId }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ readonly formId?: number;
5
+ }): import("react").JSX.Element;
@@ -1,24 +1,94 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect } from 'react';
3
3
  import { Form } from 'react-bootstrap';
4
- import InputMask from 'react-input-mask';
4
+ import { IMaskInput } from 'react-imask';
5
5
  import { ElementColWrapper } from './ElementColWrapper.js';
6
6
  import { UseFormStore } from '../stores/UseFormStore.js';
7
- export function InputElement({ element }) {
7
+ import { ElementTypeEnum } from '../constants/ElementEnum.js';
8
+ export function InputElement({ element, formId }) {
8
9
  const properties = element.properties;
10
+ const resolvedFormId = formId !== null && formId !== void 0 ? formId : properties.componentId;
9
11
  const hidden = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.hidden; });
10
12
  const error = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.error; });
11
13
  const errorMessage = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.errorMessage; });
12
14
  const registerElement = UseFormStore((state) => state.registerElement);
15
+ const unregisterElement = UseFormStore((state) => state.unregisterElement);
13
16
  const validateFormData = UseFormStore((state) => state.validateFormData);
14
17
  useEffect(() => {
15
- registerElement(element.id, properties.componentId, {
18
+ var _a, _b, _c;
19
+ registerElement(element.id, resolvedFormId, {
16
20
  name: String(properties.name || ''),
17
- type: 'input',
18
- inputValidateId: properties.inputValidateId
21
+ type: element.elementType,
22
+ value: properties.checked ? String((_a = properties.value) !== null && _a !== void 0 ? _a : 'on') : String((_b = properties.value) !== null && _b !== void 0 ? _b : ''),
23
+ inputValidateId: (_c = properties.inputValidateId) !== null && _c !== void 0 ? _c : null
19
24
  });
20
- }, [element.id, properties.name, properties.inputValidateId, registerElement]);
25
+ return () => unregisterElement(element.id);
26
+ }, [
27
+ element.id,
28
+ element.elementType,
29
+ properties.name,
30
+ properties.value,
31
+ properties.checked,
32
+ properties.inputValidateId,
33
+ registerElement,
34
+ unregisterElement,
35
+ resolvedFormId
36
+ ]);
21
37
  if (hidden)
22
38
  return null;
23
- return (_jsx(ElementColWrapper, { element: element, children: _jsxs(Form.Group, { className: "mb-3", controlId: String(properties.name || ''), children: [_jsx(Form.Label, { children: String(properties.title || '') }), _jsx(Form.Control, { as: InputMask, mask: String(properties.mask || ''), onChange: (e) => UseFormStore.getState().setElementState(element.id, { value: e.target.value }), onBlur: (e) => validateFormData(properties.inputValidateId, element.id, e.target.value), required: Boolean(properties.required), name: String(properties.name || ''), placeholder: String(properties.placeholder || ''), isInvalid: !!error, style: element.styles }), _jsx(Form.Control.Feedback, { type: "invalid", children: errorMessage })] }) }));
39
+ const hasMask = element.elementType === ElementTypeEnum.Input && Boolean(properties.mask);
40
+ const label = String(properties.label || properties.title || '');
41
+ const name = String(properties.name || '');
42
+ const controlId = name || `element-${element.id}`;
43
+ const inputValidateId = properties.inputValidateId;
44
+ const options = Array.isArray(properties.options) ? properties.options : [];
45
+ const handleAccept = (value) => {
46
+ UseFormStore.getState().setElementState(element.id, { value });
47
+ };
48
+ const handleBlur = (e) => {
49
+ if (!inputValidateId)
50
+ return;
51
+ let value = e.target.value;
52
+ if (e.target instanceof HTMLInputElement && (e.target.type === 'checkbox' || e.target.type === 'radio')) {
53
+ value = e.target.checked ? e.target.value : '';
54
+ }
55
+ validateFormData(inputValidateId, element.id, value);
56
+ };
57
+ const setValue = (value) => UseFormStore.getState().setElementState(element.id, { value });
58
+ const setCheckedValue = (checked, value) => {
59
+ const store = UseFormStore.getState();
60
+ if (checked && element.elementType === ElementTypeEnum.Radio && name && resolvedFormId !== undefined) {
61
+ store.getElementsByForm(resolvedFormId)
62
+ .filter((field) => field.id !== element.id && field.type === ElementTypeEnum.Radio && field.name === name)
63
+ .forEach((field) => store.setElementState(field.id, { value: '' }));
64
+ }
65
+ store.setElementState(element.id, { value: checked ? value : '' });
66
+ };
67
+ const renderControl = () => {
68
+ var _a, _b, _c, _d, _e;
69
+ if (element.elementType === ElementTypeEnum.Textarea) {
70
+ return (_jsx("textarea", { defaultValue: String((_a = properties.value) !== null && _a !== void 0 ? _a : ''), rows: Number(properties.rows) || 4, onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: Boolean(properties.required), name: name, placeholder: String(properties.placeholder || ''), className: `form-control${error ? ' is-invalid' : ''}`, style: element.styles }));
71
+ }
72
+ if (element.elementType === ElementTypeEnum.Select) {
73
+ return (_jsx("select", { defaultValue: String((_b = properties.value) !== null && _b !== void 0 ? _b : ''), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: Boolean(properties.required), name: name, className: `form-select${error ? ' is-invalid' : ''}`, style: element.styles, children: options.map((option, index) => {
74
+ var _a, _b, _c, _d;
75
+ const data = typeof option === 'object' && option !== null ? option : null;
76
+ const value = String((_a = data === null || data === void 0 ? void 0 : data.value) !== null && _a !== void 0 ? _a : option);
77
+ const text = String((_d = (_c = (_b = data === null || data === void 0 ? void 0 : data.label) !== null && _b !== void 0 ? _b : data === null || data === void 0 ? void 0 : data.text) !== null && _c !== void 0 ? _c : data === null || data === void 0 ? void 0 : data.title) !== null && _d !== void 0 ? _d : value);
78
+ return _jsx("option", { value: value, children: text }, `${value}-${index}`);
79
+ }) }));
80
+ }
81
+ if (element.elementType === ElementTypeEnum.Checkbox || element.elementType === ElementTypeEnum.Radio) {
82
+ const value = String((_c = properties.value) !== null && _c !== void 0 ? _c : 'on');
83
+ return (_jsxs("div", { className: "form-check", children: [_jsx("input", { id: controlId, type: element.elementType, defaultChecked: Boolean(properties.checked), value: value, onChange: (e) => setCheckedValue(e.target.checked, value), onBlur: handleBlur, required: Boolean(properties.required), name: name, className: `form-check-input${error ? ' is-invalid' : ''}`, style: element.styles }), label && _jsx("label", { className: "form-check-label", htmlFor: controlId, children: label })] }));
84
+ }
85
+ if (element.elementType === ElementTypeEnum.File) {
86
+ return (_jsx("div", { className: "alert alert-secondary", role: "status", style: element.styles, children: "Upload de arquivos n\u00E3o dispon\u00EDvel neste formul\u00E1rio." }));
87
+ }
88
+ if (hasMask) {
89
+ return (_jsx(IMaskInput, { mask: String(properties.mask), defaultValue: String((_d = properties.value) !== null && _d !== void 0 ? _d : ''), onAccept: handleAccept, onBlur: handleBlur, required: Boolean(properties.required), name: name, placeholder: String(properties.placeholder || ''), className: `form-control${error ? ' is-invalid' : ''}`, style: element.styles }));
90
+ }
91
+ return (_jsx("input", { type: String(properties.type || 'text'), defaultValue: String((_e = properties.value) !== null && _e !== void 0 ? _e : ''), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: Boolean(properties.required), name: name, placeholder: String(properties.placeholder || ''), className: `form-control${error ? ' is-invalid' : ''}`, style: element.styles }));
92
+ };
93
+ return (_jsx(ElementColWrapper, { element: element, children: _jsxs(Form.Group, { className: "mb-3", controlId: controlId, children: [label && element.elementType !== ElementTypeEnum.Checkbox && element.elementType !== ElementTypeEnum.Radio && (_jsx(Form.Label, { children: label })), renderControl(), error && (_jsx("div", { className: "invalid-feedback", style: { display: 'block' }, children: errorMessage }))] }) }));
24
94
  }
@@ -1,4 +1,4 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
2
  export declare function LinkElement({ element }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import type { ElementType } from '../types/ElementType.js';
2
2
  export declare function TextElement({ element }: {
3
3
  readonly element: ElementType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { ComponentType } from '../types/ComponentType.js';
3
3
  export declare class ComponentFactory {
4
- build(component: ComponentType): React.ReactElement | null;
4
+ build(component: ComponentType, editionMode?: boolean): React.ReactElement | null;
5
5
  }
@@ -8,7 +8,7 @@ import { SliderComponent } from '../components/SliderComponent.js';
8
8
  import { CardComponent } from '../components/CardComponent.js';
9
9
  import { MapComponent } from '../components/MapComponent.js';
10
10
  export class ComponentFactory {
11
- build(component) {
11
+ build(component, editionMode = false) {
12
12
  switch (component.componentType) {
13
13
  case ComponentTypeEnum.Text:
14
14
  case ComponentTypeEnum.TextWithImage:
@@ -19,7 +19,7 @@ export class ComponentFactory {
19
19
  case ComponentTypeEnum.Slider:
20
20
  case ComponentTypeEnum.Gallery:
21
21
  case ComponentTypeEnum.Testimonials:
22
- return _jsx(SliderComponent, { component: component }, component.id);
22
+ return _jsx(SliderComponent, { component: component, editionMode: editionMode }, component.id);
23
23
  case ComponentTypeEnum.Form:
24
24
  return _jsx(FormComponent, { component: component }, component.id);
25
25
  case ComponentTypeEnum.Card:
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { ElementType } from '../types/ElementType.js';
3
3
  export declare class ElementFactory {
4
- build(element: ElementType): React.ReactElement | null;
4
+ build(element: ElementType, formId?: number): React.ReactElement | null;
5
5
  }
@@ -5,32 +5,30 @@ import { ImageElement } from '../elements/ImageElement.js';
5
5
  import { InputElement } from '../elements/InputElement.js';
6
6
  import { IconElement } from '../elements/IconElement.js';
7
7
  import { ButtonElement } from '../elements/ButtonElement.js';
8
- import { FileElement } from '../elements/FileElement.js';
9
8
  import { AlertElement } from '../elements/AlertElement.js';
10
9
  import { LinkElement } from '../elements/LinkElement.js';
11
10
  export class ElementFactory {
12
- build(element) {
11
+ build(element, formId) {
13
12
  switch (element.elementType) {
14
13
  case ElementTypeEnum.Text:
15
- case ElementTypeEnum.Textarea:
16
14
  case ElementTypeEnum.Title:
17
15
  return _jsx(TextElement, { element: element }, element.id);
18
16
  case ElementTypeEnum.Image:
19
17
  case ElementTypeEnum.Video:
20
18
  return _jsx(ImageElement, { element: element }, element.id);
21
19
  case ElementTypeEnum.Input:
20
+ case ElementTypeEnum.Textarea:
22
21
  case ElementTypeEnum.Select:
23
22
  case ElementTypeEnum.Checkbox:
24
23
  case ElementTypeEnum.Radio:
25
- return _jsx(InputElement, { element: element }, element.id);
24
+ case ElementTypeEnum.File:
25
+ return _jsx(InputElement, { element: element, formId: formId }, element.id);
26
26
  case ElementTypeEnum.Icon:
27
27
  return _jsx(IconElement, { element: element }, element.id);
28
28
  case ElementTypeEnum.Button:
29
- return _jsx(ButtonElement, { element: element }, element.id);
30
- case ElementTypeEnum.File:
31
- return _jsx(FileElement, { element: element }, element.id);
29
+ return _jsx(ButtonElement, { element: element, formId: formId }, element.id);
32
30
  case ElementTypeEnum.Alert:
33
- return _jsx(AlertElement, { element: element }, element.id);
31
+ return _jsx(AlertElement, { element: element, formId: formId }, element.id);
34
32
  case ElementTypeEnum.Link:
35
33
  return _jsx(LinkElement, { element: element }, element.id);
36
34
  case ElementTypeEnum.Divider:
@@ -1,4 +1,4 @@
1
1
  import { WebsiteType } from '../types/WebsiteType.js';
2
2
  export declare function Footer({ website }: {
3
3
  readonly website: WebsiteType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -7,5 +7,5 @@ export function Footer({ website }) {
7
7
  const social = (_a = website.properties) === null || _a === void 0 ? void 0 : _a.social;
8
8
  const footer = website.footer.properties;
9
9
  const styles = website.footer.styles;
10
- return (_jsx(Container, { fluid: styles.fluid || undefined, style: { backgroundColor: styles.backgroundColor }, children: _jsxs(Row, { id: 'footer', style: styles, children: [_jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex justify-content-center", style: { marginBottom: '30px' }, children: social && (_jsx(SocialIconsComponent, { social: social })) }), _jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex flex-column align-items-center", style: { padding: '20px' }, dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(footer.text1) } }), _jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex flex-column align-items-center", style: { padding: '20px' }, dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(footer.text2) } }), _jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex justify-content-center", dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(footer.text3) } }), _jsxs(Col, { xs: 12, sm: 12, md: 12, lg: 12, children: [_jsx("hr", { className: "footer-divider" }), _jsxs("p", { className: "text-center mb-0", children: ["\u00A9 ", new Date().getFullYear(), " ", website.name] })] })] }) }));
10
+ return (_jsx(Container, { fluid: styles.fluid || undefined, style: { backgroundColor: styles.backgroundColor }, children: _jsxs(Row, { id: 'footer', style: styles, children: [_jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex justify-content-center", style: { marginBottom: '30px' }, children: social && (_jsx(SocialIconsComponent, { social: social })) }), _jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex flex-column align-items-center", dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(footer.text1) } }), _jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex flex-column align-items-center", dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(footer.text2) } }), _jsx(Col, { xs: 12, sm: 12, md: 12, lg: 12, className: "d-flex justify-content-center", dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(footer.text3) } }), _jsxs(Col, { xs: 12, sm: 12, md: 12, lg: 12, children: [_jsx("hr", { className: "footer-divider" }), _jsxs("p", { className: "text-center mb-0", children: ["\u00A9 ", new Date().getFullYear(), " ", website.name] })] })] }) }));
11
11
  }
@@ -1,4 +1,4 @@
1
1
  import type { WebsiteType } from '../types/WebsiteType.js';
2
2
  export declare function Header({ website }: {
3
3
  readonly website: WebsiteType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,8 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Container, Row, Col } from 'react-bootstrap';
3
3
  export function Header({ website }) {
4
4
  const headerProperties = website.header.properties;
5
5
  const headerStyles = website.header.styles;
6
6
  const domain = website.domain.replaceAll('.', '');
7
- return (_jsx(Container, { fluid: headerStyles.fluid || undefined, style: { backgroundColor: headerStyles.backgroundColor }, children: _jsxs(Row, { id: "header", children: [_jsx(Col, { xs: 3, md: 3, lg: 3, style: Object.assign({ display: headerProperties.showLogo ? 'block' : 'none' }, headerStyles), children: _jsx("img", { src: `https://noisdev-website-images.s3.sa-east-1.amazonaws.com/${domain}/${website.logo}`, width: "200", className: "d-inline-block align-top", alt: "Logo", style: { textAlign: headerProperties.logoAlign } }) }), _jsx(Col, { lg: 2, children: "Social Icons" }), _jsx(Col, { lg: 3, children: "Email" }), _jsx(Col, { lg: 2, children: "Liga\u00E7\u00F5es" }), _jsx(Col, { lg: 2, children: "Localiza\u00E7\u00E3o" })] }) }));
7
+ return (_jsx(Container, { fluid: headerStyles.fluid || undefined, style: { backgroundColor: headerStyles.backgroundColor }, children: _jsx(Row, { id: "header", children: _jsx(Col, { xs: 3, md: 3, lg: 3, style: Object.assign({ display: headerProperties.showLogo ? 'block' : 'none' }, headerStyles), children: _jsx("img", { src: `https://noisdev-website-images.s3.sa-east-1.amazonaws.com/${domain}/${website.logo}`, width: "200", className: "d-inline-block align-top", alt: "Logo", style: { textAlign: headerProperties.logoAlign } }) }) }) }));
8
8
  }
@@ -2,4 +2,4 @@ import type { PageType } from '../types/PageType.js';
2
2
  export declare function Menu({ page, websitePages }: {
3
3
  readonly page?: PageType;
4
4
  readonly websitePages?: PageType[];
5
- }): import("react/jsx-runtime").JSX.Element;
5
+ }): import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import type { WebsiteType } from '../types/WebsiteType.js';
2
2
  export declare function SiteLayout({ website }: {
3
3
  readonly website: WebsiteType;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -1,4 +1,6 @@
1
+ import React from 'react';
1
2
  import type { SectionType } from '../types/SectionType.js';
2
- export declare function SectionRenderer({ sections }: {
3
+ export declare function SectionRenderer({ sections, editionMode }: {
3
4
  readonly sections: SectionType[];
4
- }): import("react/jsx-runtime").JSX.Element;
5
+ readonly editionMode?: boolean;
6
+ }): React.JSX.Element;
@@ -1,7 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Container, Row, Col } from 'react-bootstrap';
4
4
  import { ComponentFactory } from '../factories/ComponentFactory.js';
5
+ import { orderBySort } from '../utils/orderBySort.js';
6
+ const componentFactory = new ComponentFactory();
5
7
  function colWidthValue(width, offset) {
6
8
  if (width === undefined && offset === undefined)
7
9
  return undefined;
@@ -10,30 +12,44 @@ function colWidthValue(width, offset) {
10
12
  }
11
13
  return width;
12
14
  }
13
- function renderSection(section) {
14
- const content = (_jsx(Row, { id: `section-${section.id}`, style: section.sectionType === 'row' ? section.styles : undefined, children: section.columns.map(renderColumn) }));
15
+ function columnContent(column, editionMode) {
16
+ return (_jsxs(_Fragment, { children: [orderBySort(column.components.filter((component) => component.enabled)).map((component) => componentFactory.build(component, editionMode)), orderBySort(column.childSections).map((childSection) => (_jsx(React.Fragment, { children: renderSection(childSection, editionMode) }, childSection.id)))] }));
17
+ }
18
+ function gridClass(id) {
19
+ return `pixelbuild-grid-${String(id).replace(/[^a-zA-Z0-9_-]/g, '_')}`;
20
+ }
21
+ function renderGrid(section, editionMode) {
22
+ const grid = gridClass(section.id);
23
+ const columns = section.columns.filter((column) => column.components.some((component) => component.enabled) || column.childSections.length > 0);
24
+ const css = columns.map((column) => {
25
+ const properties = column.properties || {};
26
+ const row = Math.max(0, Number(properties.row) || 0);
27
+ const rowSpan = Math.max(1, Number(properties.rowSpan) || 1);
28
+ const xs = column.width.xs || 12;
29
+ const sm = column.width.sm || xs;
30
+ const md = column.width.md || sm;
31
+ const columnClass = gridClass(column.id);
32
+ return `.${grid} .${columnClass}{grid-column:span ${xs};grid-row:auto;min-width:0}@media (min-width:576px){.${grid} .${columnClass}{grid-column:span ${sm}}}@media (min-width:768px){.${grid} .${columnClass}{grid-column:span ${md};grid-row:${row + 1}/span ${rowSpan}}}`;
33
+ }).join('');
34
+ return (_jsxs(_Fragment, { children: [_jsx("style", { children: `.${grid}{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem}${css}` }), _jsx("div", { id: `section-${section.id}`, className: grid, style: section.sectionType === 'row' ? section.styles : undefined, children: columns.map((column) => (_jsx("div", { id: `column-${column.id}`, className: gridClass(column.id), style: column.styles, children: columnContent(column, editionMode) }, column.id))) })] }));
35
+ }
36
+ function renderSection(section, editionMode) {
37
+ const usesGrid = section.columns.some((column) => { var _a, _b; return ((_a = column.properties) === null || _a === void 0 ? void 0 : _a.row) !== undefined || Number((_b = column.properties) === null || _b === void 0 ? void 0 : _b.rowSpan) > 1; });
38
+ const content = usesGrid ? renderGrid(section, editionMode) : (_jsx(Row, { id: `section-${section.id}`, style: section.sectionType === 'row' ? section.styles : undefined, children: section.columns.map((column) => renderColumn(column, editionMode)) }));
15
39
  if (section.sectionType === 'container-fluid') {
16
40
  return _jsx(Container, { fluid: true, style: section.styles, children: content });
17
41
  }
18
42
  if (section.sectionType === 'container') {
19
43
  return _jsx(Container, { style: section.styles, children: content });
20
44
  }
21
- return content;
45
+ return _jsx(Container, { fluid: true, children: content });
22
46
  }
23
- function renderColumn(column) {
24
- const componentFactory = new ComponentFactory();
25
- return (_jsxs(Col, { id: `column-${column.id}`, xs: colWidthValue(column.width.xs, column.offset.xs), sm: colWidthValue(column.width.sm, column.offset.sm), md: colWidthValue(column.width.md, column.offset.md), lg: colWidthValue(column.width.lg, column.offset.lg), xl: colWidthValue(column.width.xl, column.offset.xl), style: column.styles, children: [column.components
26
- .filter((c) => c.enabled)
27
- .sort((a, b) => a.sort - b.sort)
28
- .map((component) => componentFactory.build(component)), column.childSections
29
- .sort((a, b) => a.sort - b.sort)
30
- .map((childSection) => renderSection(childSection))] }, column.id));
47
+ function renderColumn(column, editionMode) {
48
+ return (_jsx(Col, { id: `column-${column.id}`, xs: colWidthValue(column.width.xs, column.offset.xs), sm: colWidthValue(column.width.sm, column.offset.sm), md: colWidthValue(column.width.md, column.offset.md), lg: colWidthValue(column.width.lg, column.offset.lg), xl: colWidthValue(column.width.xl, column.offset.xl), style: column.styles, children: columnContent(column, editionMode) }, column.id));
31
49
  }
32
- export function SectionRenderer({ sections }) {
50
+ export function SectionRenderer({ sections, editionMode = false }) {
33
51
  if (!sections || sections.length === 0) {
34
52
  return null;
35
53
  }
36
- return (_jsx(_Fragment, { children: sections
37
- .sort((a, b) => a.sort - b.sort)
38
- .map((section) => (_jsx(React.Fragment, { children: renderSection(section) }, section.id))) }));
54
+ return (_jsx(_Fragment, { children: orderBySort(sections).map((section) => (_jsx(React.Fragment, { children: renderSection(section, editionMode) }, section.id))) }));
39
55
  }
@@ -20,6 +20,7 @@ export interface FormStoreState {
20
20
  elements: Record<string, FormElement>;
21
21
  registerForm: (formId: number) => void;
22
22
  registerElement: (elementId: number, formId?: number | null, initialState?: Partial<FormElement>) => void;
23
+ unregisterElement: (elementId: number) => void;
23
24
  validateFormData: (inputValidateId: number, elementId: number, value: string) => void;
24
25
  validateAllFields: (formId: number) => void;
25
26
  setElementState: (elementId: number, newState: Partial<FormElement>) => void;
@@ -7,8 +7,33 @@ const UseFormStore = create((set, get) => ({
7
7
  forms: Object.assign(Object.assign({}, state.forms), { [formId]: state.forms[formId] || { elements: [] } })
8
8
  })),
9
9
  registerElement: (elementId, formId = null, initialState = {}) => set((state) => {
10
- if (state.elements[elementId])
11
- return {};
10
+ var _a, _b;
11
+ const existingElement = state.elements[elementId];
12
+ if (existingElement) {
13
+ const updatedElement = Object.assign(Object.assign(Object.assign({}, existingElement), initialState), { formId, value: (_b = (_a = existingElement.value) !== null && _a !== void 0 ? _a : initialState.value) !== null && _b !== void 0 ? _b : null });
14
+ if (existingElement.formId === formId) {
15
+ return {
16
+ elements: Object.assign(Object.assign({}, state.elements), { [elementId]: updatedElement })
17
+ };
18
+ }
19
+ const newForms = Object.assign({}, state.forms);
20
+ if (existingElement.formId) {
21
+ const previousForm = state.forms[existingElement.formId];
22
+ if (previousForm) {
23
+ newForms[existingElement.formId] = Object.assign(Object.assign({}, previousForm), { elements: previousForm.elements.filter((id) => id !== elementId.toString()) });
24
+ }
25
+ }
26
+ if (formId) {
27
+ const nextForm = state.forms[formId] || { elements: [] };
28
+ newForms[formId] = Object.assign(Object.assign({}, nextForm), { elements: nextForm.elements.includes(elementId.toString())
29
+ ? nextForm.elements
30
+ : [...nextForm.elements, elementId.toString()] });
31
+ }
32
+ return {
33
+ elements: Object.assign(Object.assign({}, state.elements), { [elementId]: updatedElement }),
34
+ forms: newForms
35
+ };
36
+ }
12
37
  const newElements = Object.assign(Object.assign({}, state.elements), { [elementId]: Object.assign({ id: elementId, name: null, type: null, formId, value: null, loading: false, hidden: false, error: false, errorMessage: null, inputValidateId: null }, initialState) });
13
38
  const newForms = Object.assign({}, state.forms);
14
39
  if (formId) {
@@ -24,6 +49,20 @@ const UseFormStore = create((set, get) => ({
24
49
  forms: newForms
25
50
  };
26
51
  }),
52
+ unregisterElement: (elementId) => set((state) => {
53
+ const element = state.elements[elementId];
54
+ if (!element)
55
+ return {};
56
+ const elements = Object.assign({}, state.elements);
57
+ delete elements[elementId];
58
+ const forms = Object.assign({}, state.forms);
59
+ if (element.formId) {
60
+ const form = forms[element.formId];
61
+ if (form)
62
+ forms[element.formId] = Object.assign(Object.assign({}, form), { elements: form.elements.filter((id) => id !== elementId.toString()) });
63
+ }
64
+ return { elements, forms };
65
+ }),
27
66
  validateFormData: (inputValidateId, elementId, value) => {
28
67
  const inputValidateFactory = new InputValidateFactory();
29
68
  const validation = inputValidateFactory.build(inputValidateId, value);
@@ -0,0 +1,3 @@
1
+ export declare function orderBySort<T extends {
2
+ readonly sort: number;
3
+ }>(items: readonly T[]): T[];
@@ -0,0 +1,3 @@
1
+ export function orderBySort(items) {
2
+ return [...items].sort((a, b) => a.sort - b.sort);
3
+ }
package/package.json CHANGED
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "name": "lib-pixelbuild",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
+ "engines": {
5
+ "node": "^24.18.0",
6
+ "npm": ">=10"
7
+ },
4
8
  "type": "module",
5
9
  "main": "./dist/index.js",
6
10
  "module": "./dist/index.d.js",
@@ -55,36 +59,48 @@
55
59
  "@types/react": "^18.3.3",
56
60
  "@types/react-bootstrap": "^1.0.1",
57
61
  "@types/react-dom": "^18.3.0",
58
- "@types/react-input-mask": "^3.0.6",
59
62
  "@types/react-slick": "^0.23.13",
60
63
  "@typescript-eslint/eslint-plugin": "^8.35.0",
61
64
  "@typescript-eslint/parser": "^8.35.0",
62
65
  "bootstrap": "^5.3.7",
63
- "eslint": "^9.31.0",
66
+ "eslint": "^10.8.0",
64
67
  "eslint-config-prettier": "^10.1.5",
65
68
  "eslint-plugin-prettier": "^5.5.1",
66
- "eslint-plugin-react": "^7.37.5",
69
+ "eslint-plugin-react": "^7.22.0",
67
70
  "eslint-plugin-react-hooks": "^5.2.0",
68
71
  "eslint-plugin-react-refresh": "^0.4.20",
69
72
  "prettier": "^3.6.2",
70
73
  "tsc-esm-fix": "^3.1.2",
74
+ "dompurify": "^3.2.6",
75
+ "keen-slider": "^6.8.6",
76
+ "react": "^18.2.0",
77
+ "react-bootstrap": "^2.10.10",
78
+ "react-dom": "^18.2.0",
79
+ "react-ga4": "^2.1.0",
80
+ "react-helmet-async": "^2.0.5",
81
+ "react-icons": "^5.3.0",
82
+ "react-imask": "^7.6.1",
83
+ "react-router-dom": "^6.28.0",
84
+ "react-slick": "^0.30.3",
85
+ "slick-carousel": "^1.8.1",
71
86
  "typescript": "^5.8.3",
72
- "typescript-eslint": "^8.34.1"
87
+ "typescript-eslint": "^8.34.1",
88
+ "zustand": "^5.0.5"
73
89
  },
74
90
  "peerDependencies": {
75
91
  "bootstrap": "^5.0.0",
76
92
  "dompurify": "^3.2.6",
93
+ "keen-slider": "^6.8.6",
77
94
  "react": "^18.0.0",
78
95
  "react-bootstrap": "^2.10.10",
79
96
  "react-dom": "^18.0.0",
80
97
  "react-ga4": "^2.1.0",
81
98
  "react-helmet-async": "^2.0.5",
82
99
  "react-icons": "^5.3.0",
83
- "react-input-mask": "^2.0.4",
84
100
  "react-router-dom": "^6.28.0 || ^7.0.0",
85
101
  "react-slick": "^0.30.3",
86
102
  "slick-carousel": "^1.8.1",
87
- "zustand": "^5.0.5",
88
- "keen-slider": "^6.8.6"
103
+ "react-imask": "^7.6.1",
104
+ "zustand": "^5.0.5"
89
105
  }
90
106
  }