@xwadex/fesd-next 0.3.4-7.20 → 0.3.4-7.22

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 (58) hide show
  1. package/dist/components/content-builders/blocks/base-block.d.ts +8 -0
  2. package/dist/components/content-builders/blocks/base-block.js +95 -0
  3. package/dist/components/content-builders/blocks/index.d.ts +4 -0
  4. package/dist/components/content-builders/blocks/index.js +4 -0
  5. package/dist/components/content-builders/blocks/media-content.d.ts +7 -0
  6. package/dist/components/content-builders/blocks/media-content.js +23 -0
  7. package/dist/components/content-builders/blocks/root-header.d.ts +19 -0
  8. package/dist/components/content-builders/blocks/root-header.js +84 -0
  9. package/dist/components/content-builders/blocks/roots.d.ts +8 -0
  10. package/dist/components/content-builders/blocks/roots.js +18 -0
  11. package/dist/components/content-builders/blocks/text-content.d.ts +20 -0
  12. package/dist/components/content-builders/blocks/text-content.js +126 -0
  13. package/dist/components/content-builders/content-builder-actionbar.d.ts +2 -0
  14. package/dist/components/content-builders/content-builder-actionbar.js +21 -0
  15. package/dist/components/content-builders/content-builder-blocks.d.ts +4 -0
  16. package/dist/components/content-builders/content-builder-blocks.js +15 -0
  17. package/dist/components/content-builders/content-builder-configs.d.ts +10 -0
  18. package/dist/components/content-builders/content-builder-configs.js +55 -0
  19. package/dist/components/content-builders/content-builder-context.d.ts +22 -0
  20. package/dist/components/content-builders/content-builder-context.js +46 -0
  21. package/dist/components/content-builders/content-builder-fields.d.ts +1 -0
  22. package/dist/components/content-builders/content-builder-fields.js +5 -0
  23. package/dist/components/content-builders/content-builder-functionbar.d.ts +1 -0
  24. package/dist/components/content-builders/content-builder-functionbar.js +25 -0
  25. package/dist/components/content-builders/content-builder-helpers.d.ts +14 -0
  26. package/dist/components/content-builders/content-builder-helpers.js +45 -0
  27. package/dist/components/content-builders/content-builder-hooks.d.ts +32 -0
  28. package/dist/components/content-builders/content-builder-hooks.js +65 -0
  29. package/dist/components/content-builders/content-builder-iframe.d.ts +1 -0
  30. package/dist/components/content-builders/content-builder-iframe.js +8 -0
  31. package/dist/components/content-builders/content-builder-initial.d.ts +84 -0
  32. package/dist/components/content-builders/content-builder-initial.js +135 -0
  33. package/dist/components/content-builders/content-builder-overlay.d.ts +1 -0
  34. package/dist/components/content-builders/content-builder-overlay.js +21 -0
  35. package/dist/components/content-builders/content-builder-panels.d.ts +10 -0
  36. package/dist/components/content-builders/content-builder-panels.js +162 -0
  37. package/dist/components/content-builders/content-builder-preview.d.ts +4 -0
  38. package/dist/components/content-builders/content-builder-preview.js +20 -0
  39. package/dist/components/content-builders/content-builder-pucks-context.d.ts +12 -0
  40. package/dist/components/content-builders/content-builder-pucks-context.js +17 -0
  41. package/dist/components/content-builders/content-builder-pucks-hooks.d.ts +17 -0
  42. package/dist/components/content-builders/content-builder-pucks-hooks.js +89 -0
  43. package/dist/components/content-builders/content-builder-roots.d.ts +15 -0
  44. package/dist/components/content-builders/content-builder-roots.js +13 -0
  45. package/dist/components/content-builders/content-builder.d.ts +7 -0
  46. package/dist/components/content-builders/content-builder.js +17 -0
  47. package/dist/components/content-builders/content-render.d.ts +7 -0
  48. package/dist/components/content-builders/content-render.js +8 -0
  49. package/dist/components/content-builders/fields/fields-tabs.d.ts +5 -0
  50. package/dist/components/content-builders/fields/fields-tabs.js +9 -0
  51. package/dist/components/content-builders/index.d.ts +6 -0
  52. package/dist/components/content-builders/index.js +6 -0
  53. package/dist/components/index.d.ts +1 -0
  54. package/dist/components/index.js +1 -0
  55. package/dist/components/puck-contents/puck-contents-editor.d.ts +1 -0
  56. package/dist/components/puck-contents/puck-contents-editor.js +2 -2
  57. package/dist/components/puck-contents/puck-contents-rander.js +4 -0
  58. package/package.json +1 -1
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Expand, Eye, LaptopMinimal, Maximize, Minus, Monitor, Plus, Shrink, Smartphone, Tablet } from "lucide-react";
4
+ import { useBuilderContext } from "./content-builder-context";
5
+ import { useBuilderPucksContext } from "./content-builder-pucks-context";
6
+ import { getPuckPreviewMode } from "./content-builder-pucks-hooks";
7
+ import { cn } from "../../shadcns/index.js";
8
+ export const BuilderFunctionBar = () => {
9
+ const { viewport, setBuilderViewport } = useBuilderContext();
10
+ const { insterBlock, setPreviewMode } = useBuilderPucksContext();
11
+ const previewMode = getPuckPreviewMode();
12
+ return (_jsxs("div", { className: cn("absolute", "w-full", "h-10", "flex", "justify-between", "items-center", "gap-5", "px-5", "**: select-none"), style: { display: "flex", gap: 8 }, children: [_jsx("div", { className: "flex-1 flex", children: _jsxs("button", { className: cn("cursor-pointer flex flex-rows gap-1 items-center font-semibold text-md"), onClick: () => {
13
+ if (previewMode == "interactive")
14
+ return;
15
+ insterBlock();
16
+ }, children: [_jsx(Plus, { size: 18 }), _jsx("div", { children: "Add Block" })] }) }), _jsxs("div", { className: "flex-1 flex gap-5 justify-center", children: [_jsx("button", { className: "cursor-pointer", onClick: () => setBuilderViewport({ view: "360" }), children: _jsx(Smartphone, { size: 15, strokeWidth: 2.5 }) }), _jsx("button", { className: "cursor-pointer", onClick: () => setBuilderViewport({ view: "768" }), children: _jsx(Tablet, { size: 15, strokeWidth: 2.5 }) }), _jsx("button", { className: "cursor-pointer", onClick: () => setBuilderViewport({ view: "1400" }), children: _jsx(LaptopMinimal, { size: 17, strokeWidth: 2.2 }) }), _jsx("button", { className: "cursor-pointer", onClick: () => setBuilderViewport({ view: "1920" }), children: _jsx(Monitor, { size: 16, strokeWidth: 2.2 }) }), _jsx("button", { className: "cursor-pointer", onClick: () => setBuilderViewport({ view: "screen", zoom: 1 }), children: _jsx(Maximize, { size: 16, strokeWidth: 2.6 }) }), _jsx("button", { className: "cursor-pointer", onClick: () => setBuilderViewport({
17
+ view: viewport.view == "fullscreen" ? "screen" : "fullscreen",
18
+ zoom: 1
19
+ }), children: viewport.view == "fullscreen"
20
+ ? _jsx(Shrink, { size: 15, strokeWidth: 1.7 })
21
+ : _jsx(Expand, { size: 15, strokeWidth: 1.7 }) }), _jsxs("div", { className: "flex gap-2 justify-center items-center", children: [_jsx("button", { onClick: () => setBuilderViewport({ zoom: Math.max(0.5, (viewport?.zoom ?? 1) - 0.1) }), children: _jsx(Minus, { size: 15, strokeWidth: 1.7 }) }), _jsx("button", { onClick: () => setBuilderViewport({ zoom: Math.min(1, (viewport?.zoom ?? 1) + 0.1) }), children: _jsx(Plus, { size: 15, strokeWidth: 1.7 }) }), _jsx("button", { className: "font-semibold text-xs", onClick: () => setBuilderViewport({ zoom: 1 }), children: `${Math.floor((viewport?.zoom ?? 1) * 100)}%` })] })] }), _jsx("div", { className: "flex-1 flex justify-end", children: _jsxs("button", { className: "cursor-pointer flex flex-rows gap-1 items-center font-semibold text-md", onClick: () => {
22
+ setPreviewMode(previewMode == "edit" ? "interactive" : "edit");
23
+ setBuilderViewport({ view: previewMode == "edit" ? "fullscreen" : "1920", zoom: 1 });
24
+ }, children: [_jsx("div", { children: previewMode == "edit" ? "Preview" : "Build" }), _jsx(Eye, { size: 18 })] }) })] }));
25
+ };
@@ -0,0 +1,14 @@
1
+ export declare function scrollToBlock(id: string): void;
2
+ export declare function createComponentId(type: string): string;
3
+ export declare function createSlotsId(props: any): void;
4
+ export declare function createComponentProps(config: any): {
5
+ type: any;
6
+ props: any;
7
+ };
8
+ export declare const getSlotsKey: (zone?: string) => {
9
+ parentId?: undefined;
10
+ slotName?: undefined;
11
+ } | {
12
+ parentId: string;
13
+ slotName: string;
14
+ };
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ export function scrollToBlock(id) {
3
+ const iframe = document.querySelector(`#preview-frame`);
4
+ if (!iframe)
5
+ return;
6
+ const iframeBody = (iframe.contentDocument)?.body;
7
+ const el = iframeBody?.querySelector(`[data-puck-component="${id}"]`);
8
+ el?.scrollIntoView({ behavior: "smooth", block: "center" });
9
+ }
10
+ export function createComponentId(type) {
11
+ const now = new Date();
12
+ const date = now.getFullYear().toString() +
13
+ String(now.getMonth() + 1).padStart(2, "0") +
14
+ String(now.getDate()).padStart(2, "0");
15
+ const time = String(now.getHours()).padStart(2, "0") +
16
+ String(now.getMinutes()).padStart(2, "0") +
17
+ String(now.getSeconds()).padStart(2, "0");
18
+ const random = Math.random().toString(36).slice(2, 8);
19
+ return `${type}-${date}-${time}-${random}`;
20
+ }
21
+ export function createSlotsId(props) {
22
+ if (!props)
23
+ return;
24
+ for (const [key, value] of Object.entries(props)) {
25
+ if (key.startsWith("slot") && Array.isArray(value))
26
+ value.forEach((item) => {
27
+ if (!item?.type || !item?.props)
28
+ return;
29
+ item.props["id"] = createComponentId(item.type);
30
+ createSlotsId(item.props);
31
+ });
32
+ }
33
+ }
34
+ export function createComponentProps(config) {
35
+ const { defaultProps: props, label } = config;
36
+ props["id"] = createComponentId(label);
37
+ createSlotsId(props);
38
+ return { type: label, props };
39
+ }
40
+ export const getSlotsKey = (zone) => {
41
+ if (!zone)
42
+ return {};
43
+ const [parentId, slotName] = zone.split(":");
44
+ return { parentId, slotName };
45
+ };
@@ -0,0 +1,32 @@
1
+ import { ContentBuilderProps } from "./content-builder";
2
+ export interface BlocksViews {
3
+ active: boolean;
4
+ callback?: (value: string | boolean) => void;
5
+ }
6
+ export interface BuildersViewport {
7
+ view?: "360" | "768" | "1400" | "1920" | "screen" | "fullscreen";
8
+ zoom?: number;
9
+ }
10
+ export type BuildersPanels = Record<string, {
11
+ x?: number;
12
+ y?: number;
13
+ z?: number;
14
+ active?: boolean;
15
+ }>;
16
+ export interface ContentBuilderOptions {
17
+ builderProps: ContentBuilderProps;
18
+ }
19
+ export declare function useContentBuilder({ builderProps }: ContentBuilderOptions): {
20
+ builderRef: import("react").RefObject<HTMLDivElement | null>;
21
+ viewport: BuildersViewport;
22
+ blocksViews: BlocksViews;
23
+ panels: BuildersPanels;
24
+ selectBuilderBlocks: () => Promise<string | boolean>;
25
+ setBuilderBlockView: import("react").Dispatch<import("react").SetStateAction<BlocksViews>>;
26
+ setBuilderPanels: import("react").Dispatch<import("react").SetStateAction<BuildersPanels>>;
27
+ setBuilderPanelsActive: (id: string, active?: boolean) => void;
28
+ setBuilderViewport: (viewport: BuildersViewport) => void;
29
+ setBuilderDragging: (state: boolean) => void;
30
+ setBuilderNewBlocks: (block: string | boolean) => void;
31
+ saveBuilderData: (data: any) => void;
32
+ };
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { useCallback, useRef, useState } from "react";
3
+ export function useContentBuilder({ builderProps }) {
4
+ const { defaultViewport } = builderProps;
5
+ const builderRef = useRef(null);
6
+ const [viewport, setViewport] = useState({
7
+ view: defaultViewport ?? "1920", zoom: 1
8
+ });
9
+ const [blocksViews, setBlocksViews] = useState({ active: false });
10
+ const [panels, setPanels] = useState({
11
+ pageEditor: { x: 0, y: 0, z: 1, active: false },
12
+ contentEditor: { x: 0, y: 0, z: 1, active: false },
13
+ });
14
+ const setBuilderDragging = useCallback((state) => {
15
+ if (!builderRef?.current)
16
+ return;
17
+ builderRef.current.setAttribute("data-drag", JSON.stringify(state));
18
+ }, []);
19
+ const selectBuilderBlocks = useCallback(async () => {
20
+ setBuilderDragging(true);
21
+ return new Promise((resolve) => {
22
+ setBlocksViews({ active: true, callback: resolve });
23
+ });
24
+ }, []);
25
+ const setBuilderNewBlocks = useCallback((block) => {
26
+ setBuilderDragging(false);
27
+ blocksViews.callback?.(block);
28
+ requestAnimationFrame(() => {
29
+ setBlocksViews({ active: false });
30
+ });
31
+ }, [blocksViews]);
32
+ const setBuilderPanelsActive = useCallback((id, active) => {
33
+ if (!id)
34
+ return;
35
+ setPanels?.(prev => {
36
+ const next = ({ ...prev, [id]: { ...prev[id], active: active } });
37
+ return next;
38
+ });
39
+ }, []);
40
+ const setBuilderViewport = useCallback((viewport) => {
41
+ setViewport(prev => ({ ...prev, ...viewport }));
42
+ }, []);
43
+ const saveBuilderData = useCallback((data) => {
44
+ console.log("latest data", data);
45
+ // navigate({
46
+ // to: "/test/puck/preview",
47
+ // search: { datas: data },
48
+ // viewTransition: true
49
+ // })
50
+ }, []);
51
+ return {
52
+ builderRef,
53
+ viewport,
54
+ blocksViews,
55
+ panels,
56
+ selectBuilderBlocks,
57
+ setBuilderBlockView: setBlocksViews,
58
+ setBuilderPanels: setPanels,
59
+ setBuilderPanelsActive,
60
+ setBuilderViewport,
61
+ setBuilderDragging,
62
+ setBuilderNewBlocks,
63
+ saveBuilderData,
64
+ };
65
+ }
@@ -0,0 +1 @@
1
+ export declare const BuilderIframe: import("react").MemoExoticComponent<({ document, children }: any) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo } from "react";
4
+ export const BuilderIframe = memo(({ document, children }) => {
5
+ if (document)
6
+ document.body.style.overflowY = "auto";
7
+ return _jsx(_Fragment, { children: children });
8
+ });
@@ -0,0 +1,84 @@
1
+ export declare const initialData: {
2
+ root: {
3
+ props: {
4
+ title: string;
5
+ description: string;
6
+ };
7
+ };
8
+ content: ({
9
+ type: string;
10
+ props: {
11
+ slotMediaBlock: {
12
+ type: string;
13
+ props: {
14
+ id: string;
15
+ imgs: string;
16
+ alt: string;
17
+ products: number[];
18
+ };
19
+ }[];
20
+ slotTextBlock: {
21
+ type: string;
22
+ props: {
23
+ id: string;
24
+ title: string;
25
+ subTitle: string;
26
+ description: string;
27
+ titleOptions: {
28
+ content2: string;
29
+ tage2: string;
30
+ color2: string;
31
+ align2: string;
32
+ };
33
+ };
34
+ }[];
35
+ options: {
36
+ textAlign: string;
37
+ textAlign2: string;
38
+ };
39
+ background: {
40
+ isImage: string;
41
+ };
42
+ id: string;
43
+ };
44
+ } | {
45
+ type: string;
46
+ props: {
47
+ slotMediaBlock: {
48
+ type: string;
49
+ props: {
50
+ id: string;
51
+ imgs: string;
52
+ alt: string;
53
+ };
54
+ }[];
55
+ slotTextBlock: {
56
+ type: string;
57
+ props: {
58
+ id: string;
59
+ title: string;
60
+ subTitle: string;
61
+ description: string;
62
+ titleOptions: {
63
+ content2: string;
64
+ age2: string;
65
+ color2: string;
66
+ align2: string;
67
+ };
68
+ };
69
+ }[];
70
+ options: {
71
+ textAlign: string;
72
+ textAlign2: string;
73
+ };
74
+ background: {
75
+ isImage: string;
76
+ };
77
+ id: string;
78
+ };
79
+ })[];
80
+ zones: {};
81
+ ex: {
82
+ "slotMediaBlock.products": number[];
83
+ };
84
+ };
@@ -0,0 +1,135 @@
1
+ export const initialData = {
2
+ root: {
3
+ props: {
4
+ title: "Hello, world",
5
+ description: "Lorem ipsum",
6
+ }
7
+ },
8
+ content: [
9
+ {
10
+ type: "BaseBlock",
11
+ props: {
12
+ slotMediaBlock: [
13
+ {
14
+ type: "MediaContent",
15
+ props: {
16
+ id: "MediaContent-168337f3-0b6f-43d8-8850-6f402eedcb65",
17
+ imgs: "/01.png",
18
+ alt: "alt",
19
+ products: [1, 2, 3, 4, 5, 6]
20
+ }
21
+ }
22
+ ],
23
+ slotTextBlock: [
24
+ {
25
+ type: "TextContent",
26
+ props: {
27
+ id: "TextContent-5679409f-98c3-40b5-8a80-ab322f90695f",
28
+ title: "Content that adapts to your layout",
29
+ subTitle: "Designed for clarity and consistency",
30
+ description: "This section supports flexible content placement and alignment across different screen sizes.",
31
+ titleOptions: {
32
+ content2: "Content that adapts to your layout",
33
+ tage2: "h3",
34
+ color2: "",
35
+ align2: "left"
36
+ }
37
+ }
38
+ }
39
+ ],
40
+ options: {
41
+ textAlign: "left",
42
+ textAlign2: "top"
43
+ },
44
+ background: {
45
+ isImage: "no"
46
+ },
47
+ id: "BaseBlock-aff75e04-815f-4014-97df-83f886fb5f76"
48
+ }
49
+ },
50
+ {
51
+ type: "BaseBlock",
52
+ props: {
53
+ slotMediaBlock: [
54
+ {
55
+ type: "MediaContent",
56
+ props: {
57
+ id: "MediaContent-d8dd3ec5-7b3d-487d-81d8-56468tf517be",
58
+ imgs: "/01.png",
59
+ alt: "alt"
60
+ }
61
+ }
62
+ ],
63
+ slotTextBlock: [
64
+ {
65
+ type: "TextContent",
66
+ props: {
67
+ id: "TextContent-0c983fb1-559e-4c82-8830-4e1b3tda07d4",
68
+ title: "Content that adapts to your layout",
69
+ subTitle: "Designed for clarity and consistency",
70
+ description: "This section supports flexible content placement and alignment across different screen sizes.",
71
+ titleOptions: {
72
+ content2: "Content that adapts to your layout",
73
+ age2: "h3",
74
+ color2: "",
75
+ align2: "left"
76
+ }
77
+ }
78
+ }
79
+ ],
80
+ options: {
81
+ textAlign: "right",
82
+ textAlign2: "top"
83
+ },
84
+ background: {
85
+ isImage: "no"
86
+ },
87
+ id: "BaseBlock-494258fc-5ee2-4403-9788-acb88t4205d8"
88
+ }
89
+ },
90
+ {
91
+ type: "BaseBlock",
92
+ props: {
93
+ slotMediaBlock: [
94
+ {
95
+ type: "MediaContent",
96
+ props: {
97
+ id: "MediaContent-d8dd3ec5-7b3d-487d-81d8-56468bf517be",
98
+ imgs: "/01.png",
99
+ alt: "alt"
100
+ }
101
+ }
102
+ ],
103
+ slotTextBlock: [
104
+ {
105
+ type: "TextContent",
106
+ props: {
107
+ id: "TextContent-0c983fb1-559e-4c82-8830-4e1b3ada07d4",
108
+ title: "Content that adapts to your layout",
109
+ subTitle: "Designed for clarity and consistency",
110
+ description: "This section supports flexible content placement and alignment across different screen sizes.",
111
+ titleOptions: {
112
+ content2: "Content that adapts to your layout",
113
+ age2: "h3",
114
+ color2: "",
115
+ align2: "left"
116
+ }
117
+ }
118
+ }
119
+ ],
120
+ options: {
121
+ textAlign: "left",
122
+ textAlign2: "top"
123
+ },
124
+ background: {
125
+ isImage: "no"
126
+ },
127
+ id: "BaseBlock-494258fc-5ee2-4403-9788-acb8824205d8"
128
+ }
129
+ },
130
+ ],
131
+ zones: {},
132
+ ex: {
133
+ "slotMediaBlock.products": [1, 2, 3, 4, 5, 6]
134
+ }
135
+ };
@@ -0,0 +1 @@
1
+ export declare const BuilderComponentOverlay: import("react").MemoExoticComponent<({ children, componentType, isSelected }: any) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { memo } from "react";
4
+ import { useBuilderContext } from "./content-builder-context";
5
+ import { Plus } from "lucide-react";
6
+ import { useBuilderPucksContext } from "./content-builder-pucks-context";
7
+ import { cn } from "../../shadcns/index.js";
8
+ export const BuilderComponentOverlay = memo(({ children, componentType, isSelected }) => {
9
+ const { setBuilderPanelsActive } = useBuilderContext();
10
+ const { insterBlock } = useBuilderPucksContext();
11
+ const isinsterBlock = isSelected && componentType == "BaseBlock";
12
+ return (_jsxs(_Fragment, { children: [isinsterBlock && _jsx("button", { onClick: (e) => {
13
+ e.stopPropagation();
14
+ insterBlock("before");
15
+ // setBuilderPanelsActive("blocksSelector", true)
16
+ }, className: cn("border rounded-4xl bg-indigo-700 text-white p-2 text-xs", "absolute -top-4 left-1/2", "cursor-pointer pointer-events-auto"), children: _jsx(Plus, { size: 15 }) }), _jsx("div", { className: "border-indigo-600 bg-indigo-600/5 border h-full w-full", children: children }), isinsterBlock && _jsx("button", { onClick: (e) => {
17
+ e.stopPropagation();
18
+ insterBlock("after");
19
+ // setBuilderPanelsActive("blocksSelector", true)
20
+ }, className: cn("border rounded-4xl bg-indigo-700 text-white p-2 text-xs", "absolute -bottom-4 left-1/2", "pointer-events-auto cursor-pointer"), children: _jsx(Plus, { size: 15 }) })] }));
21
+ });
@@ -0,0 +1,10 @@
1
+ import type { DragEndEvent, DragStartEvent } from "@dnd-kit/core";
2
+ declare const BuilderEditorPannel: import("react").MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element>;
3
+ export interface PropsTypes {
4
+ children?: React.ReactNode;
5
+ dragContainer?: React.RefObject<HTMLDivElement | null>;
6
+ onDragStart?: (event: DragStartEvent) => void;
7
+ onDragEnd?: (event: DragEndEvent) => void;
8
+ }
9
+ declare const BuilderPanelsContext: React.FC<PropsTypes>;
10
+ export { BuilderPanelsContext, BuilderEditorPannel, };
@@ -0,0 +1,162 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { memo, useCallback, useEffect, useEffectEvent, useRef } from "react";
4
+ import { createPortal } from "react-dom";
5
+ import { sortableKeyboardCoordinates } from "@dnd-kit/sortable";
6
+ import { useSensors, useSensor, closestCenter, DndContext, KeyboardSensor, PointerSensor, useDndMonitor, useDraggable } from "@dnd-kit/core";
7
+ import { BuilderFields } from "./content-builder-fields";
8
+ import { useBuilderContext } from "./content-builder-context";
9
+ import { getPuckSelectedItem } from "./content-builder-pucks-hooks";
10
+ import { cn } from "../../shadcns/index.js";
11
+ const DraggablePanel = memo((props) => {
12
+ const { id, children, defaultPos = {
13
+ align: "left",
14
+ offsetX: 0,
15
+ offsetY: 0
16
+ } } = props;
17
+ const { attributes, listeners, setNodeRef, transform, setActivatorNodeRef } = useDraggable({ id });
18
+ const { setBuilderPanelsActive, setBuilderPanels, panels, builderRef } = useBuilderContext();
19
+ const { x = 0, y = 0, z = 0, active = false } = panels?.[id] ?? {};
20
+ const draggableRef = useRef(null);
21
+ const initPositions = useEffectEvent(() => {
22
+ if (!draggableRef.current || !active)
23
+ return;
24
+ const position = { x: 0, y: 0 };
25
+ const { width: panelW, height: panelH } = draggableRef.current.getBoundingClientRect();
26
+ const { align, offsetX = 0, offsetY = 0 } = defaultPos;
27
+ const viewportW = document.documentElement.clientWidth;
28
+ const viewportH = document.documentElement.clientHeight;
29
+ if (align === "right" || align === "rightTop" || align === "rightBottom") {
30
+ position.x = viewportW - panelW - offsetX;
31
+ }
32
+ else if (align === "left" || align === "leftTop" || align === "leftBottom") {
33
+ position.x = offsetX;
34
+ }
35
+ else if (align === "center") {
36
+ position.x = Math.round((viewportW - panelW) / 2) + offsetX;
37
+ }
38
+ if (align === "top" || align === "leftTop" || align === "rightTop") {
39
+ position.y = offsetY;
40
+ }
41
+ else if (align === "bottom" || align === "leftBottom" || align === "rightBottom") {
42
+ position.y = viewportH - panelH - offsetY;
43
+ }
44
+ else if (align === "center") {
45
+ position.y = Math.round((viewportH - panelH) / 2) + offsetY;
46
+ }
47
+ draggableRef.current.style.left = position.x + "px";
48
+ draggableRef.current.style.top = position.y + "px";
49
+ setBuilderPanels?.((prev) => {
50
+ const prevPosition = prev[id];
51
+ const panelPosition = { ...prevPosition, ...position };
52
+ return { ...prev, [id]: panelPosition };
53
+ });
54
+ });
55
+ const dragEndPositions = useCallback((delta) => {
56
+ setBuilderPanels?.((prev) => {
57
+ const prevPosition = prev[id];
58
+ const panelPosition = {
59
+ ...prevPosition,
60
+ x: (delta?.x ?? 0) + prevPosition.x,
61
+ y: (delta?.y ?? 0) + prevPosition.y,
62
+ z: prevPosition.z,
63
+ };
64
+ return { ...prev, [id]: panelPosition };
65
+ });
66
+ }, [setBuilderPanels, id]);
67
+ const dragStartPositionsZ = useCallback(() => {
68
+ setBuilderPanels?.((prev) => {
69
+ const prevPosition = prev[id];
70
+ const panelsZ = Object.values(prev).map((pos) => pos.z);
71
+ const maxZ = Math.max(...panelsZ) + 1;
72
+ return { ...prev, [id]: { ...prevPosition, z: maxZ } };
73
+ });
74
+ }, [setBuilderPanels, id]);
75
+ const resizePositions = useCallback(() => {
76
+ setBuilderPanels?.((prev) => {
77
+ if (draggableRef?.current && builderRef?.current && prev[id]) {
78
+ const prevPosition = prev[id];
79
+ const panelRect = draggableRef.current.getBoundingClientRect();
80
+ const builderRect = builderRef.current.getBoundingClientRect();
81
+ const maxX = builderRect.width - panelRect.width;
82
+ const maxY = builderRect.height - panelRect.height;
83
+ if (prevPosition.x > maxX || prevPosition.y > maxY) {
84
+ const x = Math.min(Math.max(prevPosition.x, 0), Math.max(0, maxX));
85
+ const y = Math.min(Math.max(prevPosition.y, 0), Math.max(0, maxY));
86
+ return { ...prev, [id]: { ...prevPosition, x, y } };
87
+ }
88
+ }
89
+ return prev;
90
+ });
91
+ }, [setBuilderPanels, id]);
92
+ useDndMonitor({
93
+ onDragStart: ({ active }) => {
94
+ if (active?.id !== id)
95
+ return;
96
+ dragStartPositionsZ();
97
+ },
98
+ onDragEnd: ({ delta, active }) => {
99
+ if (active?.id !== id)
100
+ return;
101
+ dragEndPositions(delta);
102
+ },
103
+ });
104
+ useEffect(() => {
105
+ if (!draggableRef?.current || !active)
106
+ return;
107
+ initPositions();
108
+ window.addEventListener("resize", resizePositions);
109
+ return () => window.removeEventListener("resize", resizePositions);
110
+ }, [resizePositions, active]);
111
+ // useEffect(() => {
112
+ // setBuilderPanels?.(prev => {
113
+ // const next = ({ ...prev, [id]: { ...prev[id], active: false } })
114
+ // return next
115
+ // })
116
+ // }, [selectedItem])
117
+ return (_jsx(_Fragment, { children: active && createPortal(_jsxs("div", { ref: (node) => {
118
+ setNodeRef(node);
119
+ draggableRef.current = node;
120
+ }, className: cn("fixed", "bg-white", "shadow-xl", "overflow-hidden", "rounded-md", "border"), style: {
121
+ zIndex: z,
122
+ left: x,
123
+ top: y,
124
+ transform: transform
125
+ ? `translate3d(${transform.x}px, ${transform.y}px, 0)`
126
+ : undefined
127
+ }, children: [_jsxs("div", { className: "flex flex-row justify-between", children: [_jsx("div", { ref: setActivatorNodeRef, className: cn("w-5", "h-5", "bg-red-600", "cursor-grab", "active:cursor-grabbing"), ...attributes, ...listeners }), _jsx("button", { className: cn("px-2", "py-1", "cursor-pointer"), onClick: () => setBuilderPanelsActive(id, false), children: "close" })] }), children] }), document.body) }));
128
+ });
129
+ const BuilderEditorPannel = memo(() => {
130
+ const selectedItem = getPuckSelectedItem();
131
+ return (_jsx(_Fragment, { children: selectedItem && _jsx(DraggablePanel, { id: "contentEditor", defaultPos: {
132
+ offsetX: 40,
133
+ offsetY: 80,
134
+ align: "rightTop"
135
+ }, children: _jsx("div", { className: cn("w-87.5", "min-h-87.5", "h-full", "overflow-y-auto", "max-h-187.5"), children: _jsx(BuilderFields, {}) }) }) }));
136
+ });
137
+ const BuilderPanelsContext = memo(({ children }) => {
138
+ const { builderRef, setBuilderDragging, } = useBuilderContext();
139
+ const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
140
+ coordinateGetter: sortableKeyboardCoordinates,
141
+ }));
142
+ const dragModifiers = useCallback(({ transform, activeNodeRect }) => {
143
+ if (!activeNodeRect || !builderRef?.current)
144
+ return transform;
145
+ const containerRect = builderRef.current.getBoundingClientRect();
146
+ const boxWidth = activeNodeRect.width;
147
+ const boxHeight = activeNodeRect.height;
148
+ const originalLeft = activeNodeRect.left;
149
+ const originalTop = activeNodeRect.top;
150
+ const minX = containerRect.left - originalLeft;
151
+ const maxX = containerRect.right - (originalLeft + boxWidth);
152
+ const minY = containerRect.top - originalTop;
153
+ const maxY = containerRect.bottom - (originalTop + boxHeight);
154
+ return {
155
+ ...transform,
156
+ x: Math.min(Math.max(transform.x, minX), maxX),
157
+ y: Math.min(Math.max(transform.y, minY), maxY),
158
+ };
159
+ }, [builderRef]);
160
+ return (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragStart: (e) => setBuilderDragging?.(true), onDragEnd: (e) => setBuilderDragging?.(false), modifiers: [dragModifiers], children: children }));
161
+ });
162
+ export { BuilderPanelsContext, BuilderEditorPannel, };
@@ -0,0 +1,4 @@
1
+ export declare const BuilderViewport: React.FC<React.ComponentProps<"div">>;
2
+ export declare const BuilderPreview: import("react").MemoExoticComponent<(props: {
3
+ id?: string;
4
+ }) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo } from "react";
4
+ import { Puck } from "@puckeditor/core";
5
+ import { useBuilderContext } from "./content-builder-context";
6
+ import { useBuilderPucksContext } from "./content-builder-pucks-context";
7
+ import { cn } from "../../shadcns/index.js";
8
+ export const BuilderViewport = memo((props) => {
9
+ const { viewport } = useBuilderContext();
10
+ const { selectBlock } = useBuilderPucksContext();
11
+ const isScreenView = viewport.view == "screen" || viewport.view == "fullscreen";
12
+ const screenTransform = `scale(${viewport.zoom})`;
13
+ const scerrnHeight = viewport?.zoom && viewport.zoom < 1 ? `${100 * (1 / viewport.zoom)}%` : undefined;
14
+ return (_jsx("div", { "data-component": "builder-viewport", className: cn("w-full h-full flex justify-center items-start bg-gray-100 overflow-y-auto", isScreenView ? "p-0 pt-10" : "p-10"), onClick: () => {
15
+ selectBlock(null);
16
+ }, children: _jsx("div", { className: cn("h-full duration-150 transition-[width]", viewport.view == "360" && "w-90", viewport.view == "768" && "w-3xl", viewport.view == "1400" && "w-350", viewport.view == "1920" && "w-480", isScreenView && "w-full"), children: _jsx("div", { className: cn("border w-full h-full shadow-2xl rounded bg-white verflow-hidden", "origin-top duration-150 transition-[transform_height] select-none"), style: { transform: screenTransform, height: scerrnHeight }, ...props }) }) }));
17
+ });
18
+ export const BuilderPreview = memo((props) => {
19
+ return (_jsx(BuilderViewport, { children: _jsx(Puck.Preview, { ...props, "data-component": "builder-preview", id: "builders-preview" }) }));
20
+ });
@@ -0,0 +1,12 @@
1
+ export interface BuilderPucksContextValue {
2
+ setPreviewMode: (state: "edit" | "interactive" | ((previewMode: "edit" | "interactive") => typeof previewMode)) => void;
3
+ setComponentData: ({ propsKey, value }: any) => void;
4
+ insterBlock: (to?: "before" | "after") => void;
5
+ selectBlock: (id?: string | null) => void;
6
+ scrollToBlock: (id: string) => void;
7
+ }
8
+ export interface BuilderPucksContextProps {
9
+ children: React.ReactNode;
10
+ }
11
+ export declare const BuilderPucksContextProviders: import("react").MemoExoticComponent<({ children }: BuilderPucksContextProps) => import("react/jsx-runtime").JSX.Element>;
12
+ export declare const useBuilderPucksContext: () => BuilderPucksContextValue;