@webiny/app-website-builder 6.4.4-beta.6 → 6.4.4-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BaseEditor/commandHandlers/CloneElement.d.ts +1 -0
- package/BaseEditor/commandHandlers/CloneElement.js +17 -0
- package/BaseEditor/commandHandlers/CloneElement.js.map +1 -0
- package/BaseEditor/commandHandlers/index.js +2 -1
- package/BaseEditor/commandHandlers/index.js.map +1 -1
- package/BaseEditor/commands.d.ts +3 -0
- package/BaseEditor/commands.js +2 -0
- package/BaseEditor/commands.js.map +1 -1
- package/BaseEditor/defaultConfig/DefaultEditorConfig.js +9 -0
- package/BaseEditor/defaultConfig/DefaultEditorConfig.js.map +1 -1
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.d.ts +2 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.js +25 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.js.map +1 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.d.ts +2 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.js +26 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.js.map +1 -0
- package/BaseEditor/defaultConfig/Sidebar/ElementPreview.js +12 -2
- package/BaseEditor/defaultConfig/Sidebar/ElementPreview.js.map +1 -1
- package/editorSdk/utils/$cloneElement.d.ts +2 -0
- package/editorSdk/utils/$cloneElement.js +112 -0
- package/editorSdk/utils/$cloneElement.js.map +1 -0
- package/editorSdk/utils/index.d.ts +1 -0
- package/editorSdk/utils/index.js +1 -0
- package/package.json +23 -23
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CloneElement: () => null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useDocumentEditor } from "../../DocumentEditor/index.js";
|
|
3
|
+
import { Commands } from "../index.js";
|
|
4
|
+
import { $cloneElement } from "../../editorSdk/utils/index.js";
|
|
5
|
+
const CloneElement = ()=>{
|
|
6
|
+
const editor = useDocumentEditor();
|
|
7
|
+
useEffect(()=>editor.registerCommandHandler(Commands.CloneElement, (payload)=>{
|
|
8
|
+
const newId = $cloneElement(editor, payload.id);
|
|
9
|
+
if (newId) editor.executeCommand(Commands.SelectElement, {
|
|
10
|
+
id: newId
|
|
11
|
+
});
|
|
12
|
+
}), []);
|
|
13
|
+
return null;
|
|
14
|
+
};
|
|
15
|
+
export { CloneElement };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=CloneElement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseEditor/commandHandlers/CloneElement.js","sources":["../../../src/BaseEditor/commandHandlers/CloneElement.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useDocumentEditor } from \"~/DocumentEditor/index.js\";\nimport { Commands } from \"~/BaseEditor/index.js\";\nimport { $cloneElement } from \"~/editorSdk/utils/index.js\";\n\nexport const CloneElement = () => {\n const editor = useDocumentEditor();\n\n useEffect(() => {\n return editor.registerCommandHandler(Commands.CloneElement, payload => {\n const newId = $cloneElement(editor, payload.id);\n if (newId) {\n editor.executeCommand(Commands.SelectElement, { id: newId });\n }\n });\n }, []);\n\n return null;\n};\n"],"names":["CloneElement","editor","useDocumentEditor","useEffect","Commands","payload","newId","$cloneElement"],"mappings":";;;;AAKO,MAAMA,eAAe;IACxB,MAAMC,SAASC;IAEfC,UAAU,IACCF,OAAO,sBAAsB,CAACG,SAAS,YAAY,EAAEC,CAAAA;YACxD,MAAMC,QAAQC,cAAcN,QAAQI,QAAQ,EAAE;YAC9C,IAAIC,OACAL,OAAO,cAAc,CAACG,SAAS,aAAa,EAAE;gBAAE,IAAIE;YAAM;QAElE,IACD,EAAE;IAEL,OAAO;AACX"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import react from "react";
|
|
2
|
+
import { CloneElement } from "./CloneElement.js";
|
|
2
3
|
import { CreateElement } from "./CreateElement.js";
|
|
3
4
|
import { DeleteElement } from "./DeleteElement.js";
|
|
4
5
|
import { MoveElement } from "./MoveElement.js";
|
|
5
6
|
import { DeselectElement } from "./DeselectElement.js";
|
|
6
7
|
import { SelectElement } from "./SelectElement.js";
|
|
7
8
|
import { HighlightElement } from "./HighlightElement.js";
|
|
8
|
-
const CommandHandlers = /*#__PURE__*/ react.memo(()=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(CreateElement, null), /*#__PURE__*/ react.createElement(DeleteElement, null), /*#__PURE__*/ react.createElement(MoveElement, null), /*#__PURE__*/ react.createElement(DeselectElement, null), /*#__PURE__*/ react.createElement(SelectElement, null), /*#__PURE__*/ react.createElement(HighlightElement, null)));
|
|
9
|
+
const CommandHandlers = /*#__PURE__*/ react.memo(()=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(CloneElement, null), /*#__PURE__*/ react.createElement(CreateElement, null), /*#__PURE__*/ react.createElement(DeleteElement, null), /*#__PURE__*/ react.createElement(MoveElement, null), /*#__PURE__*/ react.createElement(DeselectElement, null), /*#__PURE__*/ react.createElement(SelectElement, null), /*#__PURE__*/ react.createElement(HighlightElement, null)));
|
|
9
10
|
CommandHandlers.displayName = "CommandHandlers";
|
|
10
11
|
export { CommandHandlers };
|
|
11
12
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEditor/commandHandlers/index.js","sources":["../../../src/BaseEditor/commandHandlers/index.tsx"],"sourcesContent":["import React from \"react\";\nimport { CreateElement } from \"./CreateElement.js\";\nimport { DeleteElement } from \"./DeleteElement.js\";\nimport { MoveElement } from \"./MoveElement.js\";\nimport { DeselectElement } from \"./DeselectElement.js\";\nimport { SelectElement } from \"./SelectElement.js\";\nimport { HighlightElement } from \"./HighlightElement.js\";\n\nexport const CommandHandlers = React.memo(() => {\n return (\n <>\n <CreateElement />\n <DeleteElement />\n <MoveElement />\n <DeselectElement />\n <SelectElement />\n <HighlightElement />\n </>\n );\n});\n\nCommandHandlers.displayName = \"CommandHandlers\";\n"],"names":["CommandHandlers","React","CreateElement","DeleteElement","MoveElement","DeselectElement","SelectElement","HighlightElement"],"mappings":"
|
|
1
|
+
{"version":3,"file":"BaseEditor/commandHandlers/index.js","sources":["../../../src/BaseEditor/commandHandlers/index.tsx"],"sourcesContent":["import React from \"react\";\nimport { CloneElement } from \"./CloneElement.js\";\nimport { CreateElement } from \"./CreateElement.js\";\nimport { DeleteElement } from \"./DeleteElement.js\";\nimport { MoveElement } from \"./MoveElement.js\";\nimport { DeselectElement } from \"./DeselectElement.js\";\nimport { SelectElement } from \"./SelectElement.js\";\nimport { HighlightElement } from \"./HighlightElement.js\";\n\nexport const CommandHandlers = React.memo(() => {\n return (\n <>\n <CloneElement />\n <CreateElement />\n <DeleteElement />\n <MoveElement />\n <DeselectElement />\n <SelectElement />\n <HighlightElement />\n </>\n );\n});\n\nCommandHandlers.displayName = \"CommandHandlers\";\n"],"names":["CommandHandlers","React","CloneElement","CreateElement","DeleteElement","MoveElement","DeselectElement","SelectElement","HighlightElement"],"mappings":";;;;;;;;AASO,MAAMA,kBAAkB,WAAHA,GAAGC,MAAAA,IAAU,CAAC,IAC/B,WAAP,GACI,wDACI,oBAACC,cAAYA,OAAAA,WAAAA,GACb,oBAACC,eAAaA,OAAAA,WAAAA,GACd,oBAACC,eAAaA,OAAAA,WAAAA,GACd,oBAACC,aAAWA,OAAAA,WAAAA,GACZ,oBAACC,iBAAeA,OAAAA,WAAAA,GAChB,oBAACC,eAAaA,OAAAA,WAAAA,GACd,oBAACC,kBAAgBA;AAK7BR,gBAAgB,WAAW,GAAG"}
|
package/BaseEditor/commands.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ElementFactoryCreateElementParams } from "@webiny/website-builder-sdk";
|
|
2
2
|
import type { WebsiteBuilderTheme } from "@webiny/website-builder-sdk/types/WebsiteBuilderTheme.js";
|
|
3
3
|
export declare const Commands: {
|
|
4
|
+
CloneElement: import("~/editorSdk/createCommand.js").Command<{
|
|
5
|
+
id: string;
|
|
6
|
+
}>;
|
|
4
7
|
CreateElement: import("~/editorSdk/createCommand.js").Command<{
|
|
5
8
|
componentName: string;
|
|
6
9
|
parentId: string;
|
package/BaseEditor/commands.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createCommand } from "../editorSdk/createCommand.js";
|
|
2
2
|
const CreateElement = createCommand("CREATE_ELEMENT");
|
|
3
3
|
const MoveElement = createCommand("MOVE_ELEMENT");
|
|
4
|
+
const CloneElement = createCommand("CLONE_ELEMENT");
|
|
4
5
|
const DeleteElement = createCommand("DELETE_ELEMENT");
|
|
5
6
|
const SelectElement = createCommand("SELECT_ELEMENT");
|
|
6
7
|
const HighlightElement = createCommand("HIGHLIGHT_ELEMENT");
|
|
@@ -10,6 +11,7 @@ const RefreshPreview = createCommand("REFRESH_PREVIEW");
|
|
|
10
11
|
const PreviewPatchElement = createCommand("PREVIEW_PATCH_ELEMENT");
|
|
11
12
|
const SendPreviewMessage = createCommand("SEND_PREVIEW_MESSAGE");
|
|
12
13
|
const Commands = {
|
|
14
|
+
CloneElement: CloneElement,
|
|
13
15
|
CreateElement: CreateElement,
|
|
14
16
|
DeleteElement: DeleteElement,
|
|
15
17
|
MoveElement: MoveElement,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEditor/commands.js","sources":["../../src/BaseEditor/commands.ts"],"sourcesContent":["import { createCommand } from \"~/editorSdk/createCommand.js\";\nimport type { ElementFactoryCreateElementParams } from \"@webiny/website-builder-sdk\";\nimport type { WebsiteBuilderTheme } from \"@webiny/website-builder-sdk/types/WebsiteBuilderTheme.js\";\n\nconst CreateElement = createCommand<{\n // Name of the component to use.\n componentName: string;\n // Parent element for the new element.\n parentId: string;\n // Parent element slot (e.g., `children`, `heroBanner`, `tabsList.0.content`).\n slot: string;\n // Index within the slot. Omit to append at the end.\n index?: number;\n // Bindings\n bindings?: ElementFactoryCreateElementParams[\"bindings\"];\n}>(\"CREATE_ELEMENT\");\n\nconst MoveElement = createCommand<{\n // ID of the element to move.\n elementId: string;\n // Parent element for the new element.\n parentId: string;\n // Parent element slot (e.g., `children`, `heroBanner`, `tabsList.0.content`).\n slot: string;\n // Index within the slot.\n index: number;\n}>(\"MOVE_ELEMENT\");\n\nconst DeleteElement = createCommand<{\n id: string;\n}>(\"DELETE_ELEMENT\");\n\nconst SelectElement = createCommand<{ id: string }>(\"SELECT_ELEMENT\");\n\nconst HighlightElement = createCommand<{ id: string }>(\"HIGHLIGHT_ELEMENT\");\n\nconst SetTheme = createCommand<{ theme: WebsiteBuilderTheme }>(\"SET_THEME\");\n\nconst DeselectElement = createCommand<never>(\"DESELECT_ELEMENT\");\n\nconst RefreshPreview = createCommand<never>(\"REFRESH_PREVIEW\");\n\nconst PreviewPatchElement = createCommand<{ elementId: string; patch: any[] }>(\n \"PREVIEW_PATCH_ELEMENT\"\n);\n\nconst SendPreviewMessage = createCommand<{ type: string; payload?: any }>(\"SEND_PREVIEW_MESSAGE\");\n\nexport const Commands = {\n CreateElement,\n DeleteElement,\n MoveElement,\n SelectElement,\n DeselectElement,\n HighlightElement,\n RefreshPreview,\n PreviewPatchElement,\n SendPreviewMessage,\n SetTheme\n};\n"],"names":["CreateElement","createCommand","MoveElement","DeleteElement","SelectElement","HighlightElement","SetTheme","DeselectElement","RefreshPreview","PreviewPatchElement","SendPreviewMessage","Commands"],"mappings":";AAIA,MAAMA,gBAAgBC,cAWnB;AAEH,MAAMC,cAAcD,cASjB;AAEH,MAAME,
|
|
1
|
+
{"version":3,"file":"BaseEditor/commands.js","sources":["../../src/BaseEditor/commands.ts"],"sourcesContent":["import { createCommand } from \"~/editorSdk/createCommand.js\";\nimport type { ElementFactoryCreateElementParams } from \"@webiny/website-builder-sdk\";\nimport type { WebsiteBuilderTheme } from \"@webiny/website-builder-sdk/types/WebsiteBuilderTheme.js\";\n\nconst CreateElement = createCommand<{\n // Name of the component to use.\n componentName: string;\n // Parent element for the new element.\n parentId: string;\n // Parent element slot (e.g., `children`, `heroBanner`, `tabsList.0.content`).\n slot: string;\n // Index within the slot. Omit to append at the end.\n index?: number;\n // Bindings\n bindings?: ElementFactoryCreateElementParams[\"bindings\"];\n}>(\"CREATE_ELEMENT\");\n\nconst MoveElement = createCommand<{\n // ID of the element to move.\n elementId: string;\n // Parent element for the new element.\n parentId: string;\n // Parent element slot (e.g., `children`, `heroBanner`, `tabsList.0.content`).\n slot: string;\n // Index within the slot.\n index: number;\n}>(\"MOVE_ELEMENT\");\n\nconst CloneElement = createCommand<{ id: string }>(\"CLONE_ELEMENT\");\n\nconst DeleteElement = createCommand<{\n id: string;\n}>(\"DELETE_ELEMENT\");\n\nconst SelectElement = createCommand<{ id: string }>(\"SELECT_ELEMENT\");\n\nconst HighlightElement = createCommand<{ id: string }>(\"HIGHLIGHT_ELEMENT\");\n\nconst SetTheme = createCommand<{ theme: WebsiteBuilderTheme }>(\"SET_THEME\");\n\nconst DeselectElement = createCommand<never>(\"DESELECT_ELEMENT\");\n\nconst RefreshPreview = createCommand<never>(\"REFRESH_PREVIEW\");\n\nconst PreviewPatchElement = createCommand<{ elementId: string; patch: any[] }>(\n \"PREVIEW_PATCH_ELEMENT\"\n);\n\nconst SendPreviewMessage = createCommand<{ type: string; payload?: any }>(\"SEND_PREVIEW_MESSAGE\");\n\nexport const Commands = {\n CloneElement,\n CreateElement,\n DeleteElement,\n MoveElement,\n SelectElement,\n DeselectElement,\n HighlightElement,\n RefreshPreview,\n PreviewPatchElement,\n SendPreviewMessage,\n SetTheme\n};\n"],"names":["CreateElement","createCommand","MoveElement","CloneElement","DeleteElement","SelectElement","HighlightElement","SetTheme","DeselectElement","RefreshPreview","PreviewPatchElement","SendPreviewMessage","Commands"],"mappings":";AAIA,MAAMA,gBAAgBC,cAWnB;AAEH,MAAMC,cAAcD,cASjB;AAEH,MAAME,eAAeF,cAA8B;AAEnD,MAAMG,gBAAgBH,cAEnB;AAEH,MAAMI,gBAAgBJ,cAA8B;AAEpD,MAAMK,mBAAmBL,cAA8B;AAEvD,MAAMM,WAAWN,cAA8C;AAE/D,MAAMO,kBAAkBP,cAAqB;AAE7C,MAAMQ,iBAAiBR,cAAqB;AAE5C,MAAMS,sBAAsBT,cACxB;AAGJ,MAAMU,qBAAqBV,cAA+C;AAEnE,MAAMW,WAAW;IACpBT,cAAAA;IACAH,eAAAA;IACAI,eAAAA;IACAF,aAAAA;IACAG,eAAAA;IACAG,iBAAAA;IACAF,kBAAAA;IACAG,gBAAAA;IACAC,qBAAAA;IACAC,oBAAAA;IACAJ,UAAAA;AACJ"}
|
|
@@ -10,6 +10,8 @@ import { CommandHandlers } from "../commandHandlers/index.js";
|
|
|
10
10
|
import { ElementSettings } from "./Sidebar/ElementSettings/ElementSettings.js";
|
|
11
11
|
import { ElementInputRenderers } from "./ElementInputRenderers.js";
|
|
12
12
|
import { ContentPreviewConfig } from "./Content/ContentPreviewConfig.js";
|
|
13
|
+
import { CloneElementAction } from "./Sidebar/ElementActions/CloneElementAction.js";
|
|
14
|
+
import { DeleteElementAction } from "./Sidebar/ElementActions/DeleteElementAction.js";
|
|
13
15
|
const { Ui: Ui } = EditorConfig;
|
|
14
16
|
const ClickToActivate = ()=>/*#__PURE__*/ react.createElement(Ui.NoActiveElement, null, /*#__PURE__*/ react.createElement(SidebarEmptyState, {
|
|
15
17
|
message: "Select an element in the canvas to edit properties."
|
|
@@ -44,6 +46,13 @@ const DefaultEditorConfig = /*#__PURE__*/ react.memo(()=>/*#__PURE__*/ react.cre
|
|
|
44
46
|
name: "elementSettings",
|
|
45
47
|
group: "element",
|
|
46
48
|
element: /*#__PURE__*/ react.createElement(Ui.OnActiveElement, null, /*#__PURE__*/ react.createElement(ElementSettings, null))
|
|
49
|
+
}), /*#__PURE__*/ react.createElement(EditorConfig.ElementAction, {
|
|
50
|
+
name: "cloneElement",
|
|
51
|
+
element: /*#__PURE__*/ react.createElement(CloneElementAction, null)
|
|
52
|
+
}), /*#__PURE__*/ react.createElement(EditorConfig.ElementAction, {
|
|
53
|
+
name: "deleteElement",
|
|
54
|
+
element: /*#__PURE__*/ react.createElement(DeleteElementAction, null),
|
|
55
|
+
after: "cloneElement"
|
|
47
56
|
}))));
|
|
48
57
|
DefaultEditorConfig.displayName = "DefaultEditorConfig";
|
|
49
58
|
export { DefaultEditorConfig };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEditor/defaultConfig/DefaultEditorConfig.js","sources":["../../../src/BaseEditor/defaultConfig/DefaultEditorConfig.tsx"],"sourcesContent":["import React from \"react\";\nimport { EditorConfig } from \"~/BaseEditor/config/index.js\";\nimport { SidebarEmptyState } from \"./Sidebar/SidebarEmptyState.js\";\nimport { StyleSettingsGroup } from \"./Sidebar/StyleSettings/StyleSettingsGroup.js\";\nimport { StyleProperties } from \"./Sidebar/StyleSettings/StyleProperties.js\";\nimport { ElementSettingsGroup } from \"./Sidebar/ElementSettings/ElementSettingsGroup.js\";\nimport { InsertElementsTab } from \"./Toolbar/InsertElements/InsertElementsTab.js\";\nimport { NavigatorTab } from \"./Toolbar/Navigator/NavigatorTab.js\";\nimport { CommandHandlers } from \"~/BaseEditor/commandHandlers/index.js\";\nimport { ElementSettings } from \"./Sidebar/ElementSettings/ElementSettings.js\";\nimport { ElementInputRenderers } from \"./ElementInputRenderers.js\";\nimport { ContentPreviewConfig } from \"./Content/ContentPreviewConfig.js\";\n\nconst { Ui } = EditorConfig;\n\nconst ClickToActivate = () => {\n return (\n <Ui.NoActiveElement>\n <SidebarEmptyState message={\"Select an element in the canvas to edit properties.\"} />\n </Ui.NoActiveElement>\n );\n};\n\nexport const DefaultEditorConfig = React.memo(() => {\n return (\n <>\n <CommandHandlers />\n <EditorConfig>\n <ElementInputRenderers />\n <ContentPreviewConfig />\n <Ui.Toolbar.Element\n name={\"insertElements\"}\n group={\"tabs\"}\n element={<InsertElementsTab />}\n />\n <Ui.Toolbar.Element name={\"navigator\"} group={\"tabs\"} element={<NavigatorTab />} />\n {/* Sidebar Groups */}\n <Ui.Sidebar.Group name={\"element\"} element={<ElementSettingsGroup />} />\n <Ui.Sidebar.Group name={\"style\"} element={<StyleSettingsGroup />} />\n {/* Style Settings Tab */}\n <Ui.Sidebar.Element\n name={\"styleSettings\"}\n group={\"style\"}\n element={\n <Ui.OnActiveElement>\n <StyleProperties />\n </Ui.OnActiveElement>\n }\n />\n <Ui.Sidebar.Element\n name={\"styleInactive\"}\n group={\"style\"}\n element={<ClickToActivate />}\n />\n {/* Element Settings Tab */}\n <Ui.Sidebar.Element\n name={\"elementInactive\"}\n group={\"element\"}\n element={<ClickToActivate />}\n />\n {/* This element renders element properties. */}\n <Ui.Sidebar.Element\n name={\"elementSettings\"}\n group={\"element\"}\n element={\n <Ui.OnActiveElement>\n <ElementSettings />\n </Ui.OnActiveElement>\n }\n />\n {/*<Ui.Sidebar.Element\n name={\"stateEditor\"}\n group={\"element\"}\n element={<DocumentStateEditor />}\n />*/}\n </EditorConfig>\n </>\n );\n});\n\nDefaultEditorConfig.displayName = \"DefaultEditorConfig\";\n"],"names":["Ui","EditorConfig","ClickToActivate","SidebarEmptyState","DefaultEditorConfig","React","CommandHandlers","ElementInputRenderers","ContentPreviewConfig","InsertElementsTab","NavigatorTab","ElementSettingsGroup","StyleSettingsGroup","StyleProperties","ElementSettings"],"mappings":"
|
|
1
|
+
{"version":3,"file":"BaseEditor/defaultConfig/DefaultEditorConfig.js","sources":["../../../src/BaseEditor/defaultConfig/DefaultEditorConfig.tsx"],"sourcesContent":["import React from \"react\";\nimport { EditorConfig } from \"~/BaseEditor/config/index.js\";\nimport { SidebarEmptyState } from \"./Sidebar/SidebarEmptyState.js\";\nimport { StyleSettingsGroup } from \"./Sidebar/StyleSettings/StyleSettingsGroup.js\";\nimport { StyleProperties } from \"./Sidebar/StyleSettings/StyleProperties.js\";\nimport { ElementSettingsGroup } from \"./Sidebar/ElementSettings/ElementSettingsGroup.js\";\nimport { InsertElementsTab } from \"./Toolbar/InsertElements/InsertElementsTab.js\";\nimport { NavigatorTab } from \"./Toolbar/Navigator/NavigatorTab.js\";\nimport { CommandHandlers } from \"~/BaseEditor/commandHandlers/index.js\";\nimport { ElementSettings } from \"./Sidebar/ElementSettings/ElementSettings.js\";\nimport { ElementInputRenderers } from \"./ElementInputRenderers.js\";\nimport { ContentPreviewConfig } from \"./Content/ContentPreviewConfig.js\";\nimport { CloneElementAction } from \"./Sidebar/ElementActions/CloneElementAction.js\";\nimport { DeleteElementAction } from \"./Sidebar/ElementActions/DeleteElementAction.js\";\n\nconst { Ui } = EditorConfig;\n\nconst ClickToActivate = () => {\n return (\n <Ui.NoActiveElement>\n <SidebarEmptyState message={\"Select an element in the canvas to edit properties.\"} />\n </Ui.NoActiveElement>\n );\n};\n\nexport const DefaultEditorConfig = React.memo(() => {\n return (\n <>\n <CommandHandlers />\n <EditorConfig>\n <ElementInputRenderers />\n <ContentPreviewConfig />\n <Ui.Toolbar.Element\n name={\"insertElements\"}\n group={\"tabs\"}\n element={<InsertElementsTab />}\n />\n <Ui.Toolbar.Element name={\"navigator\"} group={\"tabs\"} element={<NavigatorTab />} />\n {/* Sidebar Groups */}\n <Ui.Sidebar.Group name={\"element\"} element={<ElementSettingsGroup />} />\n <Ui.Sidebar.Group name={\"style\"} element={<StyleSettingsGroup />} />\n {/* Style Settings Tab */}\n <Ui.Sidebar.Element\n name={\"styleSettings\"}\n group={\"style\"}\n element={\n <Ui.OnActiveElement>\n <StyleProperties />\n </Ui.OnActiveElement>\n }\n />\n <Ui.Sidebar.Element\n name={\"styleInactive\"}\n group={\"style\"}\n element={<ClickToActivate />}\n />\n {/* Element Settings Tab */}\n <Ui.Sidebar.Element\n name={\"elementInactive\"}\n group={\"element\"}\n element={<ClickToActivate />}\n />\n {/* This element renders element properties. */}\n <Ui.Sidebar.Element\n name={\"elementSettings\"}\n group={\"element\"}\n element={\n <Ui.OnActiveElement>\n <ElementSettings />\n </Ui.OnActiveElement>\n }\n />\n {/*<Ui.Sidebar.Element\n name={\"stateEditor\"}\n group={\"element\"}\n element={<DocumentStateEditor />}\n />*/}\n {/* Element Actions (dropdown menu items) */}\n <EditorConfig.ElementAction\n name={\"cloneElement\"}\n element={<CloneElementAction />}\n />\n <EditorConfig.ElementAction\n name={\"deleteElement\"}\n element={<DeleteElementAction />}\n after={\"cloneElement\"}\n />\n </EditorConfig>\n </>\n );\n});\n\nDefaultEditorConfig.displayName = \"DefaultEditorConfig\";\n"],"names":["Ui","EditorConfig","ClickToActivate","SidebarEmptyState","DefaultEditorConfig","React","CommandHandlers","ElementInputRenderers","ContentPreviewConfig","InsertElementsTab","NavigatorTab","ElementSettingsGroup","StyleSettingsGroup","StyleProperties","ElementSettings","CloneElementAction","DeleteElementAction"],"mappings":";;;;;;;;;;;;;;AAeA,MAAM,EAAEA,IAAAA,EAAE,EAAE,GAAGC;AAEf,MAAMC,kBAAkB,IACb,WAAP,GACI,oBAACF,GAAG,eAAe,sBACf,oBAACG,mBAAiBA;QAAC,SAAS;;AAKjC,MAAMC,sBAAsB,WAAHA,GAAGC,MAAAA,IAAU,CAAC,IACnC,WAAP,GACI,wDACI,oBAACC,iBAAeA,OAAAA,WAAAA,GAChB,oBAACL,cAAYA,MAAAA,WAAAA,GACT,oBAACM,uBAAqBA,OAAAA,WAAAA,GACtB,oBAACC,sBAAoBA,OAAAA,WAAAA,GACrB,oBAACR,GAAG,OAAO,CAAC,OAAO;QACf,MAAM;QACN,OAAO;QACP,uBAAS,oBAACS,mBAAiBA;sBAE/B,oBAACT,GAAG,OAAO,CAAC,OAAO;QAAC,MAAM;QAAa,OAAO;QAAQ,uBAAS,oBAACU,cAAYA;sBAE5E,oBAACV,GAAG,OAAO,CAAC,KAAK;QAAC,MAAM;QAAW,uBAAS,oBAACW,sBAAoBA;sBACjE,oBAACX,GAAG,OAAO,CAAC,KAAK;QAAC,MAAM;QAAS,uBAAS,oBAACY,oBAAkBA;sBAE7D,oBAACZ,GAAG,OAAO,CAAC,OAAO;QACf,MAAM;QACN,OAAO;QACP,uBACI,oBAACA,GAAG,eAAe,sBACf,oBAACa,iBAAeA;sBAI5B,oBAACb,GAAG,OAAO,CAAC,OAAO;QACf,MAAM;QACN,OAAO;QACP,uBAAS,oBAACE,iBAAeA;sBAG7B,oBAACF,GAAG,OAAO,CAAC,OAAO;QACf,MAAM;QACN,OAAO;QACP,uBAAS,oBAACE,iBAAeA;sBAG7B,oBAACF,GAAG,OAAO,CAAC,OAAO;QACf,MAAM;QACN,OAAO;QACP,uBACI,oBAACA,GAAG,eAAe,sBACf,oBAACc,iBAAeA;sBAU5B,oBAACb,aAAa,aAAa;QACvB,MAAM;QACN,uBAAS,oBAACc,oBAAkBA;sBAEhC,oBAACd,aAAa,aAAa;QACvB,MAAM;QACN,uBAAS,oBAACe,qBAAmBA;QAC7B,OAAO;;AAO3BZ,oBAAoB,WAAW,GAAG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import react, { useCallback } from "react";
|
|
2
|
+
import { DropdownMenu } from "@webiny/admin-ui";
|
|
3
|
+
import { ReactComponent } from "@webiny/icons/content_copy.svg";
|
|
4
|
+
import { useActiveElement } from "../../../hooks/useActiveElement.js";
|
|
5
|
+
import { useDocumentEditor } from "../../../../DocumentEditor/index.js";
|
|
6
|
+
import { Commands } from "../../../index.js";
|
|
7
|
+
const CloneElementAction = ()=>{
|
|
8
|
+
const [element] = useActiveElement();
|
|
9
|
+
const editor = useDocumentEditor();
|
|
10
|
+
const onClick = useCallback(()=>{
|
|
11
|
+
if (element) editor.executeCommand(Commands.CloneElement, {
|
|
12
|
+
id: element.id
|
|
13
|
+
});
|
|
14
|
+
}, [
|
|
15
|
+
element?.id
|
|
16
|
+
]);
|
|
17
|
+
return /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
|
|
18
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
|
|
19
|
+
text: "Clone",
|
|
20
|
+
onClick: onClick
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
export { CloneElementAction };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=CloneElementAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.js","sources":["../../../../../src/BaseEditor/defaultConfig/Sidebar/ElementActions/CloneElementAction.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { DropdownMenu } from \"@webiny/admin-ui\";\nimport { ReactComponent as ContentCopyIcon } from \"@webiny/icons/content_copy.svg\";\nimport { useActiveElement } from \"~/BaseEditor/hooks/useActiveElement.js\";\nimport { useDocumentEditor } from \"~/DocumentEditor/index.js\";\nimport { Commands } from \"~/BaseEditor/index.js\";\n\nexport const CloneElementAction = () => {\n const [element] = useActiveElement();\n const editor = useDocumentEditor();\n\n const onClick = useCallback(() => {\n if (element) {\n editor.executeCommand(Commands.CloneElement, { id: element.id });\n }\n }, [element?.id]);\n\n return <DropdownMenu.Item icon={<ContentCopyIcon />} text={\"Clone\"} onClick={onClick} />;\n};\n"],"names":["CloneElementAction","element","useActiveElement","editor","useDocumentEditor","onClick","useCallback","Commands","DropdownMenu","ContentCopyIcon"],"mappings":";;;;;;AAOO,MAAMA,qBAAqB;IAC9B,MAAM,CAACC,QAAQ,GAAGC;IAClB,MAAMC,SAASC;IAEf,MAAMC,UAAUC,YAAY;QACxB,IAAIL,SACAE,OAAO,cAAc,CAACI,SAAS,YAAY,EAAE;YAAE,IAAIN,QAAQ,EAAE;QAAC;IAEtE,GAAG;QAACA,SAAS;KAAG;IAEhB,OAAO,WAAP,GAAO,oBAACO,aAAa,IAAI;QAAC,oBAAM,oBAACC,gBAAeA;QAAK,MAAM;QAAS,SAASJ;;AACjF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import react, { useCallback } from "react";
|
|
2
|
+
import { DropdownMenu } from "@webiny/admin-ui";
|
|
3
|
+
import { ReactComponent } from "@webiny/icons/delete.svg";
|
|
4
|
+
import { useActiveElement } from "../../../hooks/useActiveElement.js";
|
|
5
|
+
import { useDocumentEditor } from "../../../../DocumentEditor/index.js";
|
|
6
|
+
import { Commands } from "../../../index.js";
|
|
7
|
+
const DeleteElementAction = ()=>{
|
|
8
|
+
const [element] = useActiveElement();
|
|
9
|
+
const editor = useDocumentEditor();
|
|
10
|
+
const onClick = useCallback(()=>{
|
|
11
|
+
if (element) editor.executeCommand(Commands.DeleteElement, {
|
|
12
|
+
id: element.id
|
|
13
|
+
});
|
|
14
|
+
}, [
|
|
15
|
+
element?.id
|
|
16
|
+
]);
|
|
17
|
+
return /*#__PURE__*/ react.createElement(DropdownMenu.Item, {
|
|
18
|
+
className: "text-destructive-primary [&_svg]:fill-destructive",
|
|
19
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
|
|
20
|
+
text: "Delete",
|
|
21
|
+
onClick: onClick
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
export { DeleteElementAction };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=DeleteElementAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.js","sources":["../../../../../src/BaseEditor/defaultConfig/Sidebar/ElementActions/DeleteElementAction.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { DropdownMenu } from \"@webiny/admin-ui\";\nimport { ReactComponent as DeleteIcon } from \"@webiny/icons/delete.svg\";\nimport { useActiveElement } from \"~/BaseEditor/hooks/useActiveElement.js\";\nimport { useDocumentEditor } from \"~/DocumentEditor/index.js\";\nimport { Commands } from \"~/BaseEditor/index.js\";\n\nexport const DeleteElementAction = () => {\n const [element] = useActiveElement();\n const editor = useDocumentEditor();\n\n const onClick = useCallback(() => {\n if (element) {\n editor.executeCommand(Commands.DeleteElement, { id: element.id });\n }\n }, [element?.id]);\n\n return (\n <DropdownMenu.Item\n className={\"text-destructive-primary [&_svg]:fill-destructive\"}\n icon={<DeleteIcon />}\n text={\"Delete\"}\n onClick={onClick}\n />\n );\n};\n"],"names":["DeleteElementAction","element","useActiveElement","editor","useDocumentEditor","onClick","useCallback","Commands","DropdownMenu","DeleteIcon"],"mappings":";;;;;;AAOO,MAAMA,sBAAsB;IAC/B,MAAM,CAACC,QAAQ,GAAGC;IAClB,MAAMC,SAASC;IAEf,MAAMC,UAAUC,YAAY;QACxB,IAAIL,SACAE,OAAO,cAAc,CAACI,SAAS,aAAa,EAAE;YAAE,IAAIN,QAAQ,EAAE;QAAC;IAEvE,GAAG;QAACA,SAAS;KAAG;IAEhB,OAAO,WAAP,GACI,oBAACO,aAAa,IAAI;QACd,WAAW;QACX,oBAAM,oBAACC,gBAAUA;QACjB,MAAM;QACN,SAASJ;;AAGrB"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import react from "react";
|
|
2
2
|
import { useComponent } from "../../hooks/useComponent.js";
|
|
3
|
-
import { Icon } from "@webiny/admin-ui";
|
|
3
|
+
import { DropdownMenu, Icon, IconButton } from "@webiny/admin-ui";
|
|
4
4
|
import { InlineSvg } from "../Toolbar/InsertElements/InlineSvg.js";
|
|
5
|
+
import { ReactComponent } from "@webiny/icons/more_vert.svg";
|
|
6
|
+
import { ElementActions } from "../../config/ElementAction.js";
|
|
5
7
|
const ElementPreview = ({ element })=>{
|
|
6
8
|
const component = useComponent(element.component.name);
|
|
7
9
|
return /*#__PURE__*/ react.createElement("div", {
|
|
10
|
+
className: "flex items-center justify-between"
|
|
11
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
8
12
|
className: "flex items-center gap-sm"
|
|
9
13
|
}, /*#__PURE__*/ react.createElement("div", {
|
|
10
14
|
className: "fill-accent-default"
|
|
@@ -16,7 +20,13 @@ const ElementPreview = ({ element })=>{
|
|
|
16
20
|
label: component.label ?? element.component.name
|
|
17
21
|
})), /*#__PURE__*/ react.createElement("span", {
|
|
18
22
|
className: "text-md font-semibold text-neutral-primary"
|
|
19
|
-
}, component.label ?? element.component.name))
|
|
23
|
+
}, component.label ?? element.component.name)), /*#__PURE__*/ react.createElement(DropdownMenu, {
|
|
24
|
+
trigger: /*#__PURE__*/ react.createElement(IconButton, {
|
|
25
|
+
variant: "ghost",
|
|
26
|
+
size: "sm",
|
|
27
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null)
|
|
28
|
+
})
|
|
29
|
+
}, /*#__PURE__*/ react.createElement(ElementActions, null)));
|
|
20
30
|
};
|
|
21
31
|
export { ElementPreview };
|
|
22
32
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEditor/defaultConfig/Sidebar/ElementPreview.js","sources":["../../../../src/BaseEditor/defaultConfig/Sidebar/ElementPreview.tsx"],"sourcesContent":["import React from \"react\";\nimport type { DocumentElement } from \"@webiny/website-builder-sdk\";\nimport { useComponent } from \"~/BaseEditor/hooks/useComponent.js\";\nimport { Icon } from \"@webiny/admin-ui\";\nimport { InlineSvg } from \"~/BaseEditor/defaultConfig/Toolbar/InsertElements/InlineSvg.js\";\n\ninterface ElementPreviewProps {\n element: DocumentElement;\n}\n\nexport const ElementPreview = ({ element }: ElementPreviewProps) => {\n const component = useComponent(element.component.name);\n\n return (\n <div className={\"flex items-center gap-sm\"}>\n
|
|
1
|
+
{"version":3,"file":"BaseEditor/defaultConfig/Sidebar/ElementPreview.js","sources":["../../../../src/BaseEditor/defaultConfig/Sidebar/ElementPreview.tsx"],"sourcesContent":["import React from \"react\";\nimport type { DocumentElement } from \"@webiny/website-builder-sdk\";\nimport { useComponent } from \"~/BaseEditor/hooks/useComponent.js\";\nimport { DropdownMenu, Icon, IconButton } from \"@webiny/admin-ui\";\nimport { InlineSvg } from \"~/BaseEditor/defaultConfig/Toolbar/InsertElements/InlineSvg.js\";\nimport { ReactComponent as MoreVerticalIcon } from \"@webiny/icons/more_vert.svg\";\nimport { ElementActions } from \"~/BaseEditor/config/ElementAction.js\";\n\ninterface ElementPreviewProps {\n element: DocumentElement;\n}\n\nexport const ElementPreview = ({ element }: ElementPreviewProps) => {\n const component = useComponent(element.component.name);\n\n return (\n <div className={\"flex items-center justify-between\"}>\n <div className={\"flex items-center gap-sm\"}>\n <div className={\"fill-accent-default\"}>\n {component.image && (\n <Icon\n icon={<InlineSvg src={component.image} />}\n size={\"md\"}\n label={component.label ?? element.component.name}\n />\n )}\n </div>\n <span className={\"text-md font-semibold text-neutral-primary\"}>\n {component.label ?? element.component.name}\n </span>\n </div>\n <DropdownMenu\n trigger={<IconButton variant={\"ghost\"} size={\"sm\"} icon={<MoreVerticalIcon />} />}\n >\n <ElementActions />\n </DropdownMenu>\n </div>\n );\n};\n"],"names":["ElementPreview","element","component","useComponent","Icon","InlineSvg","DropdownMenu","IconButton","MoreVerticalIcon","ElementActions"],"mappings":";;;;;;AAYO,MAAMA,iBAAiB,CAAC,EAAEC,OAAO,EAAuB;IAC3D,MAAMC,YAAYC,aAAaF,QAAQ,SAAS,CAAC,IAAI;IAErD,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW;qBACZ,oBAAC;QAAI,WAAW;qBACZ,oBAAC;QAAI,WAAW;OACXC,UAAU,KAAK,IAAI,WAAJ,GACZ,oBAACE,MAAIA;QACD,oBAAM,oBAACC,WAASA;YAAC,KAAKH,UAAU,KAAK;;QACrC,MAAM;QACN,OAAOA,UAAU,KAAK,IAAID,QAAQ,SAAS,CAAC,IAAI;uBAI5D,oBAAC;QAAK,WAAW;OACZC,UAAU,KAAK,IAAID,QAAQ,SAAS,CAAC,IAAI,kBAGlD,oBAACK,cAAYA;QACT,uBAAS,oBAACC,YAAUA;YAAC,SAAS;YAAS,MAAM;YAAM,oBAAM,oBAACC,gBAAgBA;;qBAE1E,oBAACC,gBAAcA;AAI/B"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { ElementFactory, generateElementId } from "@webiny/website-builder-sdk";
|
|
2
|
+
import { $getElementById } from "./$getElementById.js";
|
|
3
|
+
import { $addElementReferenceToParent } from "./$addElementReferenceToParent.js";
|
|
4
|
+
import { applyAncestorUpdates, executeOnChange } from "./executeOnChange.js";
|
|
5
|
+
function collectDescendants(document, elementId) {
|
|
6
|
+
const ids = [];
|
|
7
|
+
const bindings = document.bindings[elementId];
|
|
8
|
+
if (!bindings?.inputs) return ids;
|
|
9
|
+
for (const binding of Object.values(bindings.inputs)){
|
|
10
|
+
if ("slot" !== binding.type) continue;
|
|
11
|
+
const children = binding.list ? binding.static ?? [] : binding.static ? [
|
|
12
|
+
binding.static
|
|
13
|
+
] : [];
|
|
14
|
+
for (const childId of children){
|
|
15
|
+
ids.push(childId);
|
|
16
|
+
ids.push(...collectDescendants(document, childId));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return ids;
|
|
20
|
+
}
|
|
21
|
+
function remapBindings(bindings, idMap) {
|
|
22
|
+
const cloned = structuredClone(bindings);
|
|
23
|
+
if (cloned.inputs) {
|
|
24
|
+
for (const [key, binding] of Object.entries(cloned.inputs))if ("slot" === binding.type) {
|
|
25
|
+
if (binding.list && Array.isArray(binding.static)) cloned.inputs[key] = {
|
|
26
|
+
...binding,
|
|
27
|
+
static: binding.static.map((id)=>idMap.get(id) ?? id)
|
|
28
|
+
};
|
|
29
|
+
else if ("string" == typeof binding.static) {
|
|
30
|
+
const newId = idMap.get(binding.static);
|
|
31
|
+
if (newId) cloned.inputs[key] = {
|
|
32
|
+
...binding,
|
|
33
|
+
static: newId
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return cloned;
|
|
39
|
+
}
|
|
40
|
+
function getSlotIndex(document, element) {
|
|
41
|
+
const parent = element.parent;
|
|
42
|
+
if (!parent) return -1;
|
|
43
|
+
const parentBindings = document.bindings[parent.id];
|
|
44
|
+
if (!parentBindings?.inputs) return -1;
|
|
45
|
+
const slotBinding = parentBindings.inputs[parent.slot];
|
|
46
|
+
if (!slotBinding) return -1;
|
|
47
|
+
if (slotBinding.list && Array.isArray(slotBinding.static)) return slotBinding.static.indexOf(element.id);
|
|
48
|
+
return -1;
|
|
49
|
+
}
|
|
50
|
+
function $cloneElement(editor, id) {
|
|
51
|
+
const document = editor.getDocumentState().read();
|
|
52
|
+
const element = $getElementById(document, id);
|
|
53
|
+
if (!element || !element.parent) return;
|
|
54
|
+
const allIds = [
|
|
55
|
+
id,
|
|
56
|
+
...collectDescendants(document, id)
|
|
57
|
+
];
|
|
58
|
+
const idMap = new Map();
|
|
59
|
+
for (const oldId of allIds)idMap.set(oldId, generateElementId());
|
|
60
|
+
const originalIndex = getSlotIndex(document, element);
|
|
61
|
+
editor.updateDocument((doc)=>{
|
|
62
|
+
for (const oldId of allIds){
|
|
63
|
+
const original = doc.elements[oldId];
|
|
64
|
+
const newId = idMap.get(oldId);
|
|
65
|
+
const clonedElement = {
|
|
66
|
+
...structuredClone(original),
|
|
67
|
+
id: newId
|
|
68
|
+
};
|
|
69
|
+
if (clonedElement.parent) {
|
|
70
|
+
const newParentId = idMap.get(clonedElement.parent.id);
|
|
71
|
+
if (newParentId) clonedElement.parent = {
|
|
72
|
+
...clonedElement.parent,
|
|
73
|
+
id: newParentId
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
doc.elements[newId] = clonedElement;
|
|
77
|
+
const originalBindings = doc.bindings[oldId];
|
|
78
|
+
if (originalBindings) doc.bindings[newId] = remapBindings(originalBindings, idMap);
|
|
79
|
+
}
|
|
80
|
+
const rootNewId = idMap.get(id);
|
|
81
|
+
const insertIndex = originalIndex >= 0 ? originalIndex + 1 : originalIndex;
|
|
82
|
+
$addElementReferenceToParent(doc, {
|
|
83
|
+
elementId: rootNewId,
|
|
84
|
+
parentId: element.parent.id,
|
|
85
|
+
slot: element.parent.slot,
|
|
86
|
+
index: insertIndex
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
const componentsManifest = editor.getEditorState().read().components;
|
|
90
|
+
const editorState = editor.getEditorState().read();
|
|
91
|
+
const breakpointNames = editorState.viewport.breakpoints.map((bp)=>bp.name);
|
|
92
|
+
const baseBreakpoint = breakpointNames[0];
|
|
93
|
+
const elementFactory = new ElementFactory(componentsManifest);
|
|
94
|
+
for (const oldId of allIds){
|
|
95
|
+
const newId = idMap.get(oldId);
|
|
96
|
+
const ancestorUpdates = executeOnChange({
|
|
97
|
+
editor,
|
|
98
|
+
elementId: newId,
|
|
99
|
+
action: "create",
|
|
100
|
+
breakpointNames,
|
|
101
|
+
baseBreakpoint,
|
|
102
|
+
elementFactory
|
|
103
|
+
});
|
|
104
|
+
if (ancestorUpdates.length > 0) editor.updateDocument((doc)=>{
|
|
105
|
+
applyAncestorUpdates(doc, ancestorUpdates, breakpointNames, baseBreakpoint, elementFactory);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return idMap.get(id);
|
|
109
|
+
}
|
|
110
|
+
export { $cloneElement };
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=$cloneElement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editorSdk/utils/$cloneElement.js","sources":["../../../src/editorSdk/utils/$cloneElement.ts"],"sourcesContent":["import { generateElementId } from \"@webiny/website-builder-sdk\";\nimport type {\n Document,\n DocumentElement,\n DocumentElementBindings\n} from \"@webiny/website-builder-sdk\";\nimport { ElementFactory } from \"@webiny/website-builder-sdk\";\nimport type { Editor } from \"../Editor.js\";\nimport { $getElementById } from \"./$getElementById.js\";\nimport { $addElementReferenceToParent } from \"./$addElementReferenceToParent.js\";\nimport { executeOnChange, applyAncestorUpdates } from \"./executeOnChange.js\";\n\nfunction collectDescendants(document: Document, elementId: string): string[] {\n const ids: string[] = [];\n const bindings = document.bindings[elementId];\n if (!bindings?.inputs) {\n return ids;\n }\n\n for (const binding of Object.values(bindings.inputs)) {\n if (binding.type !== \"slot\") {\n continue;\n }\n\n const children = binding.list\n ? ((binding.static as string[] | undefined) ?? [])\n : binding.static\n ? [binding.static as string]\n : [];\n\n for (const childId of children) {\n ids.push(childId);\n ids.push(...collectDescendants(document, childId));\n }\n }\n\n return ids;\n}\n\nfunction remapBindings(\n bindings: DocumentElementBindings,\n idMap: Map<string, string>\n): DocumentElementBindings {\n const cloned = structuredClone(bindings);\n\n if (cloned.inputs) {\n for (const [key, binding] of Object.entries(cloned.inputs)) {\n if (binding.type !== \"slot\") {\n continue;\n }\n\n if (binding.list && Array.isArray(binding.static)) {\n cloned.inputs[key] = {\n ...binding,\n static: binding.static.map((id: string) => idMap.get(id) ?? id)\n };\n } else if (typeof binding.static === \"string\") {\n const newId = idMap.get(binding.static);\n if (newId) {\n cloned.inputs[key] = { ...binding, static: newId };\n }\n }\n }\n }\n\n return cloned;\n}\n\nfunction getSlotIndex(document: Document, element: DocumentElement): number {\n const parent = element.parent;\n if (!parent) {\n return -1;\n }\n\n const parentBindings = document.bindings[parent.id];\n if (!parentBindings?.inputs) {\n return -1;\n }\n\n const slotBinding = parentBindings.inputs[parent.slot];\n if (!slotBinding) {\n return -1;\n }\n\n if (slotBinding.list && Array.isArray(slotBinding.static)) {\n return slotBinding.static.indexOf(element.id);\n }\n\n return -1;\n}\n\nexport function $cloneElement(editor: Editor, id: string): string | undefined {\n const document = editor.getDocumentState().read();\n const element = $getElementById(document, id);\n\n if (!element || !element.parent) {\n return undefined;\n }\n\n const allIds = [id, ...collectDescendants(document, id)];\n const idMap = new Map<string, string>();\n for (const oldId of allIds) {\n idMap.set(oldId, generateElementId());\n }\n\n const originalIndex = getSlotIndex(document, element);\n\n editor.updateDocument(doc => {\n for (const oldId of allIds) {\n const original = doc.elements[oldId];\n const newId = idMap.get(oldId)!;\n\n const clonedElement: DocumentElement = {\n ...structuredClone(original),\n id: newId\n };\n\n if (clonedElement.parent) {\n const newParentId = idMap.get(clonedElement.parent.id);\n if (newParentId) {\n clonedElement.parent = {\n ...clonedElement.parent,\n id: newParentId\n };\n }\n }\n\n doc.elements[newId] = clonedElement;\n\n const originalBindings = doc.bindings[oldId];\n if (originalBindings) {\n doc.bindings[newId] = remapBindings(originalBindings, idMap);\n }\n }\n\n const rootNewId = idMap.get(id)!;\n const insertIndex = originalIndex >= 0 ? originalIndex + 1 : originalIndex;\n\n $addElementReferenceToParent(doc, {\n elementId: rootNewId,\n parentId: element.parent!.id,\n slot: element.parent!.slot,\n index: insertIndex\n });\n });\n\n const componentsManifest = editor.getEditorState().read().components;\n const editorState = editor.getEditorState().read();\n const breakpointNames = editorState.viewport.breakpoints.map(bp => bp.name);\n const baseBreakpoint = breakpointNames[0];\n const elementFactory = new ElementFactory(componentsManifest);\n\n for (const oldId of allIds) {\n const newId = idMap.get(oldId)!;\n const ancestorUpdates = executeOnChange({\n editor,\n elementId: newId,\n action: \"create\",\n breakpointNames,\n baseBreakpoint,\n elementFactory\n });\n\n if (ancestorUpdates.length > 0) {\n editor.updateDocument(doc => {\n applyAncestorUpdates(\n doc,\n ancestorUpdates,\n breakpointNames,\n baseBreakpoint,\n elementFactory\n );\n });\n }\n }\n\n return idMap.get(id);\n}\n"],"names":["collectDescendants","document","elementId","ids","bindings","binding","Object","children","childId","remapBindings","idMap","cloned","structuredClone","key","Array","id","newId","getSlotIndex","element","parent","parentBindings","slotBinding","$cloneElement","editor","$getElementById","allIds","Map","oldId","generateElementId","originalIndex","doc","original","clonedElement","newParentId","originalBindings","rootNewId","insertIndex","$addElementReferenceToParent","componentsManifest","editorState","breakpointNames","bp","baseBreakpoint","elementFactory","ElementFactory","ancestorUpdates","executeOnChange","applyAncestorUpdates"],"mappings":"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"}
|
package/editorSdk/utils/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/app-website-builder",
|
|
3
|
-
"version": "6.4.4-beta.
|
|
3
|
+
"version": "6.4.4-beta.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -21,28 +21,28 @@
|
|
|
21
21
|
"@monaco-editor/react": "4.7.0",
|
|
22
22
|
"@svgr/webpack": "8.1.0",
|
|
23
23
|
"@types/react": "18.3.31",
|
|
24
|
-
"@webiny/admin-ui": "6.4.4-beta.
|
|
25
|
-
"@webiny/app": "6.4.4-beta.
|
|
26
|
-
"@webiny/app-aco": "6.4.4-beta.
|
|
27
|
-
"@webiny/app-admin": "6.4.4-beta.
|
|
28
|
-
"@webiny/app-headless-cms-common": "6.4.4-beta.
|
|
29
|
-
"@webiny/app-trash-bin": "6.4.4-beta.
|
|
30
|
-
"@webiny/app-utils": "6.4.4-beta.
|
|
24
|
+
"@webiny/admin-ui": "6.4.4-beta.7",
|
|
25
|
+
"@webiny/app": "6.4.4-beta.7",
|
|
26
|
+
"@webiny/app-aco": "6.4.4-beta.7",
|
|
27
|
+
"@webiny/app-admin": "6.4.4-beta.7",
|
|
28
|
+
"@webiny/app-headless-cms-common": "6.4.4-beta.7",
|
|
29
|
+
"@webiny/app-trash-bin": "6.4.4-beta.7",
|
|
30
|
+
"@webiny/app-utils": "6.4.4-beta.7",
|
|
31
31
|
"@webiny/di": "1.0.2",
|
|
32
|
-
"@webiny/error": "6.4.4-beta.
|
|
33
|
-
"@webiny/feature": "6.4.4-beta.
|
|
34
|
-
"@webiny/form": "6.4.4-beta.
|
|
35
|
-
"@webiny/icons": "6.4.4-beta.
|
|
36
|
-
"@webiny/languages": "6.4.4-beta.
|
|
37
|
-
"@webiny/lexical-converter": "6.4.4-beta.
|
|
38
|
-
"@webiny/lexical-editor": "6.4.4-beta.
|
|
39
|
-
"@webiny/lexical-nodes": "6.4.4-beta.
|
|
40
|
-
"@webiny/lexical-theme": "6.4.4-beta.
|
|
41
|
-
"@webiny/react-composition": "6.4.4-beta.
|
|
42
|
-
"@webiny/react-properties": "6.4.4-beta.
|
|
43
|
-
"@webiny/utils": "6.4.4-beta.
|
|
44
|
-
"@webiny/validation": "6.4.4-beta.
|
|
45
|
-
"@webiny/website-builder-sdk": "6.4.4-beta.
|
|
32
|
+
"@webiny/error": "6.4.4-beta.7",
|
|
33
|
+
"@webiny/feature": "6.4.4-beta.7",
|
|
34
|
+
"@webiny/form": "6.4.4-beta.7",
|
|
35
|
+
"@webiny/icons": "6.4.4-beta.7",
|
|
36
|
+
"@webiny/languages": "6.4.4-beta.7",
|
|
37
|
+
"@webiny/lexical-converter": "6.4.4-beta.7",
|
|
38
|
+
"@webiny/lexical-editor": "6.4.4-beta.7",
|
|
39
|
+
"@webiny/lexical-nodes": "6.4.4-beta.7",
|
|
40
|
+
"@webiny/lexical-theme": "6.4.4-beta.7",
|
|
41
|
+
"@webiny/react-composition": "6.4.4-beta.7",
|
|
42
|
+
"@webiny/react-properties": "6.4.4-beta.7",
|
|
43
|
+
"@webiny/utils": "6.4.4-beta.7",
|
|
44
|
+
"@webiny/validation": "6.4.4-beta.7",
|
|
45
|
+
"@webiny/website-builder-sdk": "6.4.4-beta.7",
|
|
46
46
|
"apollo-cache": "1.3.5",
|
|
47
47
|
"apollo-client": "2.6.10",
|
|
48
48
|
"apollo-link": "1.2.14",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@types/deep-equal": "1.0.4",
|
|
71
71
|
"@types/is-hotkey": "0.1.10",
|
|
72
|
-
"@webiny/build-tools": "6.4.4-beta.
|
|
72
|
+
"@webiny/build-tools": "6.4.4-beta.7",
|
|
73
73
|
"execa": "5.1.1",
|
|
74
74
|
"rimraf": "6.1.3",
|
|
75
75
|
"typescript": "6.0.3",
|