@xwadex/fesd-next 0.3.4-7.21 → 0.3.4-7.23

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 (111) hide show
  1. package/dist/components/content-builders/article4/article4cora/article4cora-roots.d.ts +4 -0
  2. package/dist/components/content-builders/article4/article4cora/article4cora-roots.js +79 -0
  3. package/dist/components/content-builders/article4/article4cora/media-base/index.d.ts +2 -0
  4. package/dist/components/content-builders/article4/article4cora/media-base/index.js +2 -0
  5. package/dist/components/content-builders/article4/article4cora/media-base/media-base-root.d.ts +15 -0
  6. package/dist/components/content-builders/article4/article4cora/media-base/media-base-root.js +52 -0
  7. package/dist/components/content-builders/article4/article4cora/media-cover/index.d.ts +2 -0
  8. package/dist/components/content-builders/article4/article4cora/media-cover/index.js +2 -0
  9. package/dist/components/content-builders/article4/article4cora/media-cover/media-cover-root.d.ts +15 -0
  10. package/dist/components/content-builders/article4/article4cora/media-cover/media-cover-root.js +23 -0
  11. package/dist/components/content-builders/article4/article4cora/media-embla/index.d.ts +2 -0
  12. package/dist/components/content-builders/article4/article4cora/media-embla/index.js +2 -0
  13. package/dist/components/content-builders/article4/article4cora/media-embla/media-embla-root.d.ts +25 -0
  14. package/dist/components/content-builders/article4/article4cora/media-embla/media-embla-root.js +107 -0
  15. package/dist/components/content-builders/article4/baseBlock.d.ts +17 -0
  16. package/dist/components/content-builders/article4/baseBlock.js +115 -0
  17. package/dist/components/content-builders/article4/commonComponents.d.ts +53 -0
  18. package/dist/components/content-builders/article4/commonComponents.js +81 -0
  19. package/dist/components/content-builders/article4/config.d.ts +4 -0
  20. package/dist/components/content-builders/article4/config.js +6 -0
  21. package/dist/components/content-builders/article4/index.d.ts +12 -0
  22. package/dist/components/content-builders/article4/index.js +12 -0
  23. package/dist/components/content-builders/article4/type10Block.d.ts +14 -0
  24. package/dist/components/content-builders/article4/type10Block.js +24 -0
  25. package/dist/components/content-builders/article4/type1Block.d.ts +9 -0
  26. package/dist/components/content-builders/article4/type1Block.js +12 -0
  27. package/dist/components/content-builders/article4/type2Block.d.ts +9 -0
  28. package/dist/components/content-builders/article4/type2Block.js +17 -0
  29. package/dist/components/content-builders/article4/type3Block.d.ts +8 -0
  30. package/dist/components/content-builders/article4/type3Block.js +12 -0
  31. package/dist/components/content-builders/article4/type4Block.d.ts +27 -0
  32. package/dist/components/content-builders/article4/type4Block.js +53 -0
  33. package/dist/components/content-builders/article4/type5Block.d.ts +24 -0
  34. package/dist/components/content-builders/article4/type5Block.js +43 -0
  35. package/dist/components/content-builders/article4/type6Block.d.ts +24 -0
  36. package/dist/components/content-builders/article4/type6Block.js +43 -0
  37. package/dist/components/content-builders/article4/type7Block.d.ts +12 -0
  38. package/dist/components/content-builders/article4/type7Block.js +19 -0
  39. package/dist/components/content-builders/article4/type8Block.d.ts +11 -0
  40. package/dist/components/content-builders/article4/type8Block.js +14 -0
  41. package/dist/components/content-builders/article4/type9Block.d.ts +11 -0
  42. package/dist/components/content-builders/article4/type9Block.js +19 -0
  43. package/dist/components/content-builders/blocks/base-block.d.ts +12 -0
  44. package/dist/components/content-builders/blocks/base-block.js +91 -0
  45. package/dist/components/content-builders/blocks/headers-block.d.ts +20 -0
  46. package/dist/components/content-builders/blocks/headers-block.js +49 -0
  47. package/dist/components/content-builders/blocks/index.d.ts +4 -0
  48. package/dist/components/content-builders/blocks/index.js +4 -0
  49. package/dist/components/content-builders/blocks/media-content.d.ts +7 -0
  50. package/dist/components/content-builders/blocks/media-content.js +23 -0
  51. package/dist/components/content-builders/blocks/root-header.d.ts +11 -0
  52. package/dist/components/content-builders/blocks/root-header.js +14 -0
  53. package/dist/components/content-builders/blocks/roots.d.ts +8 -0
  54. package/dist/components/content-builders/blocks/roots.js +23 -0
  55. package/dist/components/content-builders/blocks/text-content.d.ts +20 -0
  56. package/dist/components/content-builders/blocks/text-content.js +190 -0
  57. package/dist/components/content-builders/content-builder-actionbar.d.ts +1 -0
  58. package/dist/components/content-builders/content-builder-actionbar.js +64 -0
  59. package/dist/components/content-builders/content-builder-blocks-dialogs.d.ts +4 -0
  60. package/dist/components/content-builders/content-builder-blocks-dialogs.js +45 -0
  61. package/dist/components/content-builders/content-builder-blocks.d.ts +15 -0
  62. package/dist/components/content-builders/content-builder-blocks.js +40 -0
  63. package/dist/components/content-builders/content-builder-builder.d.ts +13 -0
  64. package/dist/components/content-builders/content-builder-builder.js +17 -0
  65. package/dist/components/content-builders/content-builder-configs.d.ts +203 -0
  66. package/dist/components/content-builders/content-builder-configs.js +125 -0
  67. package/dist/components/content-builders/content-builder-context.d.ts +24 -0
  68. package/dist/components/content-builders/content-builder-context.js +47 -0
  69. package/dist/components/content-builders/content-builder-fields.d.ts +1 -0
  70. package/dist/components/content-builders/content-builder-fields.js +5 -0
  71. package/dist/components/content-builders/content-builder-functionbar.d.ts +1 -0
  72. package/dist/components/content-builders/content-builder-functionbar.js +37 -0
  73. package/dist/components/content-builders/content-builder-helpers.d.ts +9 -0
  74. package/dist/components/content-builders/content-builder-helpers.js +43 -0
  75. package/dist/components/content-builders/content-builder-hooks.d.ts +39 -0
  76. package/dist/components/content-builders/content-builder-hooks.js +129 -0
  77. package/dist/components/content-builders/content-builder-iframe.d.ts +5 -0
  78. package/dist/components/content-builders/content-builder-iframe.js +15 -0
  79. package/dist/components/content-builders/content-builder-overlay.d.ts +1 -0
  80. package/dist/components/content-builders/content-builder-overlay.js +22 -0
  81. package/dist/components/content-builders/content-builder-panels.d.ts +10 -0
  82. package/dist/components/content-builders/content-builder-panels.js +165 -0
  83. package/dist/components/content-builders/content-builder-preview.d.ts +4 -0
  84. package/dist/components/content-builders/content-builder-preview.js +22 -0
  85. package/dist/components/content-builders/content-builder-pucks-context.d.ts +13 -0
  86. package/dist/components/content-builders/content-builder-pucks-context.js +17 -0
  87. package/dist/components/content-builders/content-builder-pucks-hooks.d.ts +17 -0
  88. package/dist/components/content-builders/content-builder-pucks-hooks.js +119 -0
  89. package/dist/components/content-builders/content-builder-render.d.ts +6 -0
  90. package/dist/components/content-builders/content-builder-render.js +6 -0
  91. package/dist/components/content-builders/content-builder.d.ts +7 -0
  92. package/dist/components/content-builders/content-builder.js +24 -0
  93. package/dist/components/content-builders/fields/fields-tabs.d.ts +5 -0
  94. package/dist/components/content-builders/fields/fields-tabs.js +9 -0
  95. package/dist/components/content-builders/index.d.ts +5 -0
  96. package/dist/components/content-builders/index.js +5 -0
  97. package/dist/components/content-builders/initial-datas.d.ts +56 -0
  98. package/dist/components/content-builders/initial-datas.js +818 -0
  99. package/dist/components/emblas/embla-container.d.ts +8 -0
  100. package/dist/components/emblas/embla-container.js +13 -0
  101. package/dist/components/emblas/embla-context.d.ts +21 -0
  102. package/dist/components/emblas/embla-context.js +13 -0
  103. package/dist/components/emblas/embla.d.ts +20 -0
  104. package/dist/components/emblas/embla.js +125 -0
  105. package/dist/components/emblas/emblas-pagination.d.ts +11 -0
  106. package/dist/components/emblas/emblas-pagination.js +90 -0
  107. package/dist/components/emblas/index.d.ts +4 -0
  108. package/dist/components/emblas/index.js +4 -0
  109. package/dist/components/index.d.ts +2 -0
  110. package/dist/components/index.js +2 -0
  111. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ export function useBuilder({ builderProps }) {
4
+ const { config, defaultViewport = "1920" } = builderProps;
5
+ // const navigate = useNavigate()
6
+ const builderRef = useRef(null);
7
+ const resizeObserverRef = useRef(null);
8
+ const [viewport, setViewport] = useState({
9
+ view: defaultViewport, zoom: 1
10
+ });
11
+ const [blocksViews, setBlocksViews] = useState({ active: false });
12
+ const [panels, setPanels] = useState({
13
+ pageEditor: { x: 0, y: 0, z: 1, active: false },
14
+ contentEditor: { x: 0, y: 0, z: 1, active: false },
15
+ });
16
+ const setBuilderDragging = useCallback((state) => {
17
+ if (!builderRef?.current)
18
+ return;
19
+ builderRef.current.setAttribute("data-drag", JSON.stringify(state));
20
+ }, []);
21
+ const selectBuilderBlocks = useCallback(async () => {
22
+ setBuilderDragging(true);
23
+ return new Promise((resolve) => {
24
+ setBlocksViews({ active: true, callback: resolve });
25
+ });
26
+ }, []);
27
+ const setBuilderNewBlocks = useCallback((block) => {
28
+ setBuilderDragging(false);
29
+ blocksViews.callback?.(block);
30
+ requestAnimationFrame(() => {
31
+ setBlocksViews({ active: false });
32
+ });
33
+ }, [blocksViews]);
34
+ const setBuilderPanelsActive = useCallback((id, active) => {
35
+ if (!id)
36
+ return;
37
+ setPanels?.(prev => {
38
+ const next = ({ ...prev, [id]: { ...prev[id], active: active } });
39
+ return next;
40
+ });
41
+ }, []);
42
+ const setBuilderViewport = useCallback((viewport) => {
43
+ setViewport(prev => ({ ...prev, ...viewport }));
44
+ }, []);
45
+ const saveBuilderData = useCallback((data) => {
46
+ console.log("latest data", data);
47
+ // navigate({
48
+ // to: "/test/puck/preview",
49
+ // search: { datas: data },
50
+ // viewTransition: true
51
+ // })
52
+ }, []);
53
+ // const resizeObserver = useEffectEvent(([entry]: any) => {
54
+ // if (!entry) return
55
+ // console.log(entry);
56
+ // const scale = Math.min(1, entry.contentRect.width / 1920)
57
+ // if (entry.contentRect.width <= 1920) {
58
+ // console.log({ width: entry.contentRect.width, scale });
59
+ // }
60
+ // })
61
+ // const resizeScaleBuilder = useEffectEvent((active: boolean) => {
62
+ // if (!builderRef?.current) return
63
+ // if (active && !resizeObserverRef?.current) {
64
+ // resizeObserverRef.current = new ResizeObserver(resizeObserver)
65
+ // return resizeObserverRef.current.observe(builderRef?.current)
66
+ // }
67
+ // if (!active && resizeObserverRef?.current) {
68
+ // resizeObserverRef.current?.disconnect()
69
+ // resizeObserverRef.current = null
70
+ // }
71
+ // })
72
+ // useEffect(() => {
73
+ // resizeScaleBuilder(true)
74
+ // return () => resizeScaleBuilder(false)
75
+ // }, [builderRef?.current])
76
+ useEffect(() => {
77
+ const onKeyDown = (e) => {
78
+ const key = e.key?.toLowerCase();
79
+ const isCmdOrCtrl = e.metaKey || e.ctrlKey;
80
+ // Puck 的 previewMode 切換熱鍵:cmd+i / ctrl+i
81
+ if (isCmdOrCtrl && key === "i") {
82
+ e.preventDefault();
83
+ e.stopPropagation();
84
+ }
85
+ };
86
+ window.addEventListener("keydown", onKeyDown, true); // <- capture
87
+ return () => window.removeEventListener("keydown", onKeyDown, true);
88
+ }, []);
89
+ return {
90
+ config,
91
+ builderRef,
92
+ viewport,
93
+ blocksViews,
94
+ panels,
95
+ selectBuilderBlocks,
96
+ setBuilderBlockView: setBlocksViews,
97
+ setBuilderPanels: setPanels,
98
+ setBuilderPanelsActive,
99
+ setBuilderViewport,
100
+ setBuilderDragging,
101
+ setBuilderNewBlocks,
102
+ saveBuilderData,
103
+ };
104
+ }
105
+ export const useBuilderIframe = ({ iframeDocument, callback, isPreviewKeyDown, }) => {
106
+ const killPreviewKeyModeDown = (action) => {
107
+ if (!iframeDocument || !isPreviewKeyDown)
108
+ return;
109
+ if (action == "add")
110
+ iframeDocument.addEventListener("keydown", cancelPreviewModeKeyDown, true);
111
+ else
112
+ document.removeEventListener("keydown", cancelPreviewModeKeyDown, true);
113
+ };
114
+ useEffect(() => {
115
+ if (!iframeDocument)
116
+ return;
117
+ requestAnimationFrame(() => { callback?.(iframeDocument); });
118
+ killPreviewKeyModeDown("add");
119
+ return () => killPreviewKeyModeDown("remove");
120
+ }, [iframeDocument]);
121
+ };
122
+ function cancelPreviewModeKeyDown(e) {
123
+ const key = e.key?.toLowerCase();
124
+ const isCmdOrCtrl = e.metaKey || e.ctrlKey;
125
+ if (isCmdOrCtrl && key === "i") {
126
+ e.preventDefault();
127
+ e.stopPropagation();
128
+ }
129
+ }
@@ -0,0 +1,5 @@
1
+ export interface BuilderIframeProps {
2
+ document?: Document;
3
+ children?: React.ReactNode;
4
+ }
5
+ export declare const BuilderIframe: import("react").MemoExoticComponent<({ document, children }: BuilderIframeProps) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo } from "react";
4
+ import { useBuilderIframe } from "./content-builder-hooks";
5
+ export const BuilderIframe = memo(({ document, children }) => {
6
+ useBuilderIframe({
7
+ callback: (document) => {
8
+ if (document)
9
+ document.body.style.overflowY = "auto";
10
+ },
11
+ iframeDocument: document,
12
+ isPreviewKeyDown: true
13
+ });
14
+ return _jsx(_Fragment, { children: children });
15
+ });
@@ -0,0 +1 @@
1
+ export declare const BuilderComponentOverlay: import("react").MemoExoticComponent<({ children, componentType, isSelected }: any) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { memo, useCallback } 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
+ // TODO 要改為判斷哪些元件可以插入
12
+ const isinsterBlock = isSelected && (componentType == "BaseBlock" || componentType == "BaseBlockSue");
13
+ const addBeforeBlack = useCallback((e) => {
14
+ e?.stopPropagation();
15
+ insterBlock("before");
16
+ }, [insterBlock]);
17
+ const addAfterBlack = useCallback((e) => {
18
+ e?.stopPropagation();
19
+ insterBlock("after");
20
+ }, [insterBlock]);
21
+ return (_jsxs(_Fragment, { children: [isinsterBlock && _jsx("button", { onClick: addBeforeBlack, className: cn("border rounded-4xl bg-gray-900 text-white p-2 text-xs", "absolute -top-4 left-1/2 -translate-x-1/2", "cursor-pointer pointer-events-auto"), children: _jsx(Plus, { size: 15 }) }), _jsx("div", { className: "border-indigo-600 bg-indigo-600/5 border-2 h-full w-full", children: children }), isinsterBlock && _jsx("button", { onClick: addAfterBlack, className: cn("border rounded-4xl bg-gray-900 text-white p-2 text-xs", "absolute -bottom-4 left-1/2 -translate-x-1/2", "pointer-events-auto cursor-pointer"), children: _jsx(Plus, { size: 15 }) })] }));
22
+ });
@@ -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,165 @@
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 { usePuckSelectedItem } 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 = usePuckSelectedItem();
131
+ const { config: { components } } = useBuilderContext();
132
+ const { type } = selectedItem ?? {};
133
+ const label = type ? components[type].label : type;
134
+ return (_jsx(_Fragment, { children: selectedItem && _jsx(DraggablePanel, { id: "contentEditor", defaultPos: {
135
+ offsetX: 40,
136
+ offsetY: 80,
137
+ align: "rightTop"
138
+ }, children: _jsxs("div", { className: cn("w-87.5", "min-h-87.5", "h-full", "overflow-y-auto", "max-h-187.5"), children: [_jsx("div", { className: "px-4 font-semibold text-md", children: label }), _jsx("div", { children: _jsx(BuilderFields, {}) })] }) }) }));
139
+ });
140
+ const BuilderPanelsContext = memo(({ children }) => {
141
+ const { builderRef, setBuilderDragging, } = useBuilderContext();
142
+ const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
143
+ coordinateGetter: sortableKeyboardCoordinates,
144
+ }));
145
+ const dragModifiers = useCallback(({ transform, activeNodeRect }) => {
146
+ if (!activeNodeRect || !builderRef?.current)
147
+ return transform;
148
+ const containerRect = builderRef.current.getBoundingClientRect();
149
+ const boxWidth = activeNodeRect.width;
150
+ const boxHeight = activeNodeRect.height;
151
+ const originalLeft = activeNodeRect.left;
152
+ const originalTop = activeNodeRect.top;
153
+ const minX = containerRect.left - originalLeft;
154
+ const maxX = containerRect.right - (originalLeft + boxWidth);
155
+ const minY = containerRect.top - originalTop;
156
+ const maxY = containerRect.bottom - (originalTop + boxHeight);
157
+ return {
158
+ ...transform,
159
+ x: Math.min(Math.max(transform.x, minX), maxX),
160
+ y: Math.min(Math.max(transform.y, minY), maxY),
161
+ };
162
+ }, [builderRef]);
163
+ return (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragStart: (e) => setBuilderDragging?.(true), onDragEnd: (e) => setBuilderDragging?.(false), modifiers: [dragModifiers], children: children }));
164
+ });
165
+ 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,22 @@
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-50! overflow-y-auto", isScreenView ? "p-0 pt-10" : "p-10"), style: {
15
+ background: `url("data:image/svg+xml,%3Csvg width='24' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='12' cy='12' r='1' fill='%239ca3af'/%3E%3C/svg%3E")`,
16
+ }, onClick: () => {
17
+ selectBlock(null);
18
+ }, 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, minHeight: scerrnHeight }, ...props }) }) }));
19
+ });
20
+ export const BuilderPreview = memo((props) => {
21
+ return (_jsx(BuilderViewport, { children: _jsx(Puck.Preview, { ...props, "data-component": "builder-preview", id: "builders-preview" }) }));
22
+ });
@@ -0,0 +1,13 @@
1
+ export interface BuilderPucksContextValue {
2
+ setPreviewMode: (state: "edit" | "interactive" | ((previewMode: "edit" | "interactive") => typeof previewMode)) => void;
3
+ insterBlock: (to?: "before" | "after") => void;
4
+ orderBlock: (move: "up" | "down") => void;
5
+ selectBlock: (id?: string | null) => void;
6
+ unSelectBlock: () => void;
7
+ scrollToBlock: (id: string) => void;
8
+ }
9
+ export interface BuilderPucksContextProps {
10
+ children: React.ReactNode;
11
+ }
12
+ export declare const BuilderPucksContextProviders: import("react").MemoExoticComponent<({ children }: BuilderPucksContextProps) => import("react/jsx-runtime").JSX.Element>;
13
+ export declare const useBuilderPucksContext: () => BuilderPucksContextValue;
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, memo, use } from "react";
4
+ import { useBuilderPucks } from "./content-builder-pucks-hooks";
5
+ import { useBuilderContext } from "./content-builder-context";
6
+ const BuilderPucksContext = createContext(null);
7
+ export const BuilderPucksContextProviders = memo(({ children }) => {
8
+ const { builderProps } = useBuilderContext();
9
+ const BuilderRoots = useBuilderPucks();
10
+ return _jsx(BuilderPucksContext, { value: BuilderRoots, children: children });
11
+ });
12
+ export const useBuilderPucksContext = () => {
13
+ const context = use(BuilderPucksContext);
14
+ if (!context)
15
+ throw new Error("BuilderPucksContext must be used inside BuilderPucksContextProviders");
16
+ return context;
17
+ };
@@ -0,0 +1,17 @@
1
+ import { createUsePuck } from "@puckeditor/core";
2
+ import { scrollToBlock } from "./content-builder-helpers";
3
+ import type { Config } from "@puckeditor/core";
4
+ export declare const usePuck: ReturnType<typeof createUsePuck>;
5
+ export declare const usePuckSelectedItem: () => import("@puckeditor/core").ComponentData<any, string, import("@puckeditor/core").DefaultComponents> | null;
6
+ export declare const usePuckPreviewMode: () => "edit" | "interactive";
7
+ export interface UseBuilderRootsOptions {
8
+ config: Config;
9
+ }
10
+ export declare function useBuilderPucks(): {
11
+ setPreviewMode: (state: "edit" | "interactive" | ((previewMode: "edit" | "interactive") => typeof previewMode)) => void;
12
+ selectBlock: (id?: string | null) => void;
13
+ unSelectBlock: () => void;
14
+ insterBlock: (inster?: "before" | "after") => Promise<void>;
15
+ orderBlock: (move: "up" | "down") => void;
16
+ scrollToBlock: typeof scrollToBlock;
17
+ };
@@ -0,0 +1,119 @@
1
+ "use client";
2
+ import { useCallback, useMemo } from "react";
3
+ import { createUsePuck, useGetPuck } from "@puckeditor/core";
4
+ import { createComponentId, scrollToBlock } from "./content-builder-helpers";
5
+ import { useBuilderContext } from "./content-builder-context";
6
+ export const usePuck = createUsePuck();
7
+ export const usePuckSelectedItem = () => usePuck((api) => api.selectedItem);
8
+ export const usePuckPreviewMode = () => usePuck((api) => api.appState.ui.previewMode);
9
+ export function useBuilderPucks() {
10
+ const getPuck = useGetPuck();
11
+ const { selectBuilderBlocks, setBuilderPanels } = useBuilderContext();
12
+ const selectBlock = useCallback((id) => {
13
+ const { dispatch, getSelectorForId } = getPuck();
14
+ const selector = id ? getSelectorForId(id) : null;
15
+ dispatch({ type: "setUi", ui: { itemSelector: selector } });
16
+ }, []);
17
+ const unSelectBlock = useCallback(() => {
18
+ const { dispatch } = getPuck();
19
+ dispatch({ type: "setUi", ui: { itemSelector: undefined } });
20
+ }, []);
21
+ const onAfterCallback = useCallback((id) => {
22
+ selectBlock(id);
23
+ requestAnimationFrame(() => scrollToBlock(id));
24
+ }, []);
25
+ const insterBlock = useCallback(async (inster) => {
26
+ const { appState, dispatch, selectedItem, getParentById } = getPuck();
27
+ const blockType = await selectBuilderBlocks?.();
28
+ if (typeof blockType !== "string")
29
+ return;
30
+ const { id: itemId } = selectedItem?.props ?? {};
31
+ const itemParent = itemId
32
+ ? getParentById(itemId)
33
+ : { type: "root" };
34
+ if (itemParent?.type !== "root")
35
+ return;
36
+ const nextContent = [...appState.data.content];
37
+ const selectedIndex = nextContent.findIndex((item) => item.props.id == itemId);
38
+ const safeIndex = selectedIndex < 0 ? nextContent.length : selectedIndex;
39
+ const insertIndex = inster === "before" ? safeIndex : safeIndex + 1;
40
+ const blockId = createComponentId(blockType);
41
+ dispatch({
42
+ type: "insert",
43
+ componentType: blockType,
44
+ destinationIndex: insertIndex,
45
+ destinationZone: "root:default-zone",
46
+ id: blockId,
47
+ });
48
+ requestAnimationFrame(() => onAfterCallback(blockId));
49
+ }, [selectBuilderBlocks]);
50
+ const orderBlock = (move) => {
51
+ const { appState, dispatch, selectedItem, getParentById } = getPuck();
52
+ const { id: itemId } = selectedItem?.props ?? {};
53
+ const itemParent = itemId
54
+ ? getParentById(itemId)
55
+ : { type: "root" };
56
+ if (itemParent?.type !== "root")
57
+ return;
58
+ const nextContent = [...appState.data.content];
59
+ const selectedIndex = nextContent.findIndex((item) => item.props.id == itemId);
60
+ const maxIndex = nextContent.length - 1;
61
+ if (move === "up" && selectedIndex == 0)
62
+ return;
63
+ if (move === "down" && selectedIndex == maxIndex)
64
+ return;
65
+ const newIndex = selectedIndex + (move === "up" ? -1 : 1);
66
+ dispatch({
67
+ type: "reorder",
68
+ sourceIndex: selectedIndex,
69
+ destinationIndex: newIndex,
70
+ destinationZone: "root:default-zone",
71
+ });
72
+ requestAnimationFrame(() => onAfterCallback(itemId));
73
+ };
74
+ // const setComponentData = useCallback(({ propsKey, value }: any) => {
75
+ // const { appState, dispatch, selectedItem, getParentById } = getPuck()
76
+ // if (!selectedItem) return
77
+ // const { id: itemId } = selectedItem.props
78
+ // const { id: parentId } = getParentById(itemId)?.props ?? {}
79
+ // const nextData = walkTree(appState.data, config,
80
+ // (content, options) => parentId == options.parentId
81
+ // ? content.map((child) => child.props.id == itemId
82
+ // ? setDeep(child, propsKey, value)
83
+ // : child)
84
+ // : content
85
+ // )
86
+ // dispatch({ type: "setData", data: nextData })
87
+ // }, [config])
88
+ const setPreviewMode = (state) => {
89
+ const { appState, dispatch } = getPuck();
90
+ const ui = {
91
+ previewMode: typeof state == "function" ? state(appState.ui.previewMode) : state,
92
+ itemSelector: null
93
+ };
94
+ dispatch({ type: "setUi", ui });
95
+ requestAnimationFrame(() => {
96
+ setBuilderPanels((panels) => Object.keys(panels).reduce((init, key) => {
97
+ const nextValue = { ...panels[key], active: false };
98
+ return { ...init, [key]: nextValue };
99
+ }, {}));
100
+ });
101
+ };
102
+ const BuilderRoots = useMemo(() => ({
103
+ setPreviewMode,
104
+ selectBlock,
105
+ unSelectBlock,
106
+ insterBlock,
107
+ orderBlock,
108
+ scrollToBlock
109
+ }), [
110
+ getPuck,
111
+ setPreviewMode,
112
+ selectBlock,
113
+ unSelectBlock,
114
+ insterBlock,
115
+ orderBlock,
116
+ scrollToBlock
117
+ ]);
118
+ return BuilderRoots;
119
+ }
@@ -0,0 +1,6 @@
1
+ import { Config } from "@puckeditor/core";
2
+ export interface BuilderRenderProps {
3
+ data: Record<string, undefined>;
4
+ config: Config;
5
+ }
6
+ export declare const BuilderRender: React.FC<BuilderRenderProps>;
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Render } from "@puckeditor/core";
4
+ export const BuilderRender = (props) => {
5
+ return (_jsx(Render, { ...props }));
6
+ };
@@ -0,0 +1,7 @@
1
+ import type { PuckProps } from "./content-builder-builder";
2
+ import type { BuildersViewport } from "./content-builder-hooks";
3
+ export interface ContentBuilderProps extends PuckProps {
4
+ defaultViewport?: BuildersViewport["view"];
5
+ }
6
+ declare const ContentBuilder: React.FC<ContentBuilderProps>;
7
+ export { ContentBuilder };
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { memo } from "react";
4
+ import { BuilderFunctionBar } from "./content-builder-functionbar";
5
+ import { BuilderContextProviders } from "./content-builder-context";
6
+ import { BuilderEditorPannel, BuilderPanelsContext } from "./content-builder-panels";
7
+ import { Builder } from "./content-builder-builder";
8
+ import { BuilderPreview } from "./content-builder-preview";
9
+ import { BuilderPucksContextProviders } from "./content-builder-pucks-context";
10
+ import { BuilderBlocksDialog } from "./content-builder-blocks-dialogs";
11
+ const ContentBuilder = memo((props) => {
12
+ if (!props?.data || !props?.config)
13
+ return null;
14
+ // const {
15
+ // data,
16
+ // builderConfigs,
17
+ // builderOverrides,
18
+ // blacksConfigs,
19
+ // blacksOverrides
20
+ // } = props
21
+ return (_jsx(BuilderContextProviders, { metadata: { build: true }, ...props, children: _jsx(Builder, { children: _jsxs(BuilderPucksContextProviders, { children: [_jsx(BuilderPanelsContext, { children: _jsx(BuilderEditorPannel, {}) }), _jsx(BuilderFunctionBar, {}), _jsx(BuilderPreview, {}), _jsx(BuilderBlocksDialog, {})] }) }) }));
22
+ });
23
+ ContentBuilder.displayName = "ContentBuilder";
24
+ export { ContentBuilder };
@@ -0,0 +1,5 @@
1
+ export interface PropsTypes extends React.ComponentProps<"div"> {
2
+ value?: string;
3
+ }
4
+ declare const FieldsTabs: React.FC<PropsTypes>;
5
+ export default FieldsTabs;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { AutoField, FieldLabel } from "@puckeditor/core";
3
+ import { useState } from "react";
4
+ const FieldsTabs = ({ onChange, value }) => {
5
+ const [tab, setTab] = useState("A");
6
+ return (_jsxs(FieldLabel, { label: "Title2", readOnly: true, children: [_jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: () => setTab("A"), className: "flex-1 p-2 border", children: "A" }), _jsx("button", { onClick: () => setTab("B"), className: "flex-1 p-2 border", children: "B" })] }), tab == "A" && _jsx("div", { children: _jsx(AutoField, { field: { type: "text" }, onChange: onChange, value: value ?? "wade", readOnly: true }) }), tab == "B" && _jsx("div", { children: "B" })] }));
7
+ };
8
+ FieldsTabs.displayName = "FieldsTabs";
9
+ export default FieldsTabs;
@@ -0,0 +1,5 @@
1
+ export * from "./content-builder";
2
+ export * from "./content-builder-render";
3
+ export * from "./initial-datas";
4
+ export * from "./content-builder-hooks";
5
+ export * from "./content-builder-configs";
@@ -0,0 +1,5 @@
1
+ export * from "./content-builder";
2
+ export * from "./content-builder-render";
3
+ export * from "./initial-datas";
4
+ export * from "./content-builder-hooks";
5
+ export * from "./content-builder-configs";