@it-consultis/page-builder 1.1.34

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 (124) hide show
  1. package/Editor.d.ts +77 -0
  2. package/Editor.js +312 -0
  3. package/LICENSE.txt +674 -0
  4. package/README.md +248 -0
  5. package/assets/svg/mp.d.ts +2 -0
  6. package/assets/svg/mp.js +37 -0
  7. package/assets/svg/status-bar.d.ts +2 -0
  8. package/assets/svg/status-bar.js +38 -0
  9. package/constants/index.d.ts +11 -0
  10. package/constants/index.js +17 -0
  11. package/contexts/I18nContext.d.ts +15 -0
  12. package/contexts/I18nContext.js +56 -0
  13. package/controls/AlignmentControl/AlignmentControl.d.ts +5 -0
  14. package/controls/AlignmentControl/AlignmentControl.js +58 -0
  15. package/controls/AlignmentControl/index.d.ts +3 -0
  16. package/controls/AlignmentControl/index.js +9 -0
  17. package/controls/DeviceSwitcher/DeviceSwitcher.d.ts +10 -0
  18. package/controls/DeviceSwitcher/DeviceSwitcher.js +64 -0
  19. package/controls/DeviceSwitcher/index.d.ts +2 -0
  20. package/controls/DeviceSwitcher/index.js +9 -0
  21. package/controls/GradientColorPicker/GradientColorPicker.d.ts +8 -0
  22. package/controls/GradientColorPicker/GradientColorPicker.js +81 -0
  23. package/controls/GradientColorPicker/index.d.ts +2 -0
  24. package/controls/GradientColorPicker/index.js +9 -0
  25. package/controls/HeadingControl/HeadingControl.d.ts +14 -0
  26. package/controls/HeadingControl/HeadingControl.js +251 -0
  27. package/controls/HeadingControl/HeadingView.d.ts +21 -0
  28. package/controls/HeadingControl/HeadingView.js +43 -0
  29. package/controls/HeadingControl/index.d.ts +4 -0
  30. package/controls/HeadingControl/index.js +16 -0
  31. package/controls/MediaLibraryControl/FileBrowserDialog.d.ts +14 -0
  32. package/controls/MediaLibraryControl/FileBrowserDialog.js +138 -0
  33. package/controls/MediaLibraryControl/MediaLibraryControl.d.ts +38 -0
  34. package/controls/MediaLibraryControl/MediaLibraryControl.js +537 -0
  35. package/controls/MediaLibraryControl/index.d.ts +3 -0
  36. package/controls/MediaLibraryControl/index.js +9 -0
  37. package/controls/PaddingMarginControl/PaddingMarginControl.d.ts +30 -0
  38. package/controls/PaddingMarginControl/PaddingMarginControl.js +88 -0
  39. package/controls/PaddingMarginControl/PaddingMarginForm.d.ts +8 -0
  40. package/controls/PaddingMarginControl/PaddingMarginForm.js +109 -0
  41. package/controls/PaddingMarginControl/index.d.ts +4 -0
  42. package/controls/PaddingMarginControl/index.js +16 -0
  43. package/controls/PaddingMarginControl/utils.d.ts +3 -0
  44. package/controls/PaddingMarginControl/utils.js +21 -0
  45. package/controls/SelectableControl/SelectableControl.d.ts +5 -0
  46. package/controls/SelectableControl/SelectableControl.js +35 -0
  47. package/controls/SelectableControl/index.d.ts +3 -0
  48. package/controls/SelectableControl/index.js +9 -0
  49. package/hooks/ui-optimizations/useDebounce.d.ts +3 -0
  50. package/hooks/ui-optimizations/useDebounce.js +23 -0
  51. package/hooks/ui-optimizations/useThrottle.d.ts +3 -0
  52. package/hooks/ui-optimizations/useThrottle.js +22 -0
  53. package/hooks/useMediaImageQuery.d.ts +10 -0
  54. package/hooks/useMediaImageQuery.js +51 -0
  55. package/hooks/useSortable.d.ts +20 -0
  56. package/hooks/useSortable.js +70 -0
  57. package/index.d.ts +7 -0
  58. package/index.js +54 -0
  59. package/layouts/BlocksBar/LayerPanel.d.ts +8 -0
  60. package/layouts/BlocksBar/LayerPanel.js +299 -0
  61. package/layouts/BlocksBar/index.d.ts +7 -0
  62. package/layouts/BlocksBar/index.js +575 -0
  63. package/layouts/EditorPreview/BlockView.d.ts +16 -0
  64. package/layouts/EditorPreview/BlockView.js +435 -0
  65. package/layouts/EditorPreview/index.d.ts +9 -0
  66. package/layouts/EditorPreview/index.js +463 -0
  67. package/layouts/Header/index.d.ts +18 -0
  68. package/layouts/Header/index.js +202 -0
  69. package/layouts/Header/menus/ExportDataDialog.d.ts +4 -0
  70. package/layouts/Header/menus/ExportDataDialog.js +95 -0
  71. package/layouts/Header/menus/ImportDataDialog.d.ts +4 -0
  72. package/layouts/Header/menus/ImportDataDialog.js +100 -0
  73. package/layouts/Header/menus/LeftMenu.d.ts +9 -0
  74. package/layouts/Header/menus/LeftMenu.js +369 -0
  75. package/layouts/Header/menus/RightMenu.d.ts +14 -0
  76. package/layouts/Header/menus/RightMenu.js +91 -0
  77. package/layouts/Header/menus/SaveTemplateDialog.d.ts +4 -0
  78. package/layouts/Header/menus/SaveTemplateDialog.js +203 -0
  79. package/layouts/MessageBus.d.ts +13 -0
  80. package/layouts/MessageBus.js +76 -0
  81. package/layouts/Sidebar/AddBlockButton.d.ts +12 -0
  82. package/layouts/Sidebar/AddBlockButton.js +267 -0
  83. package/layouts/Sidebar/BlockForm.d.ts +20 -0
  84. package/layouts/Sidebar/BlockForm.js +517 -0
  85. package/layouts/Sidebar/BlocksControl.d.ts +21 -0
  86. package/layouts/Sidebar/BlocksControl.js +190 -0
  87. package/layouts/Sidebar/index.d.ts +10 -0
  88. package/layouts/Sidebar/index.js +451 -0
  89. package/layouts/Snackbar.d.ts +3 -0
  90. package/layouts/Snackbar.js +43 -0
  91. package/package.json +133 -0
  92. package/store/Provider.d.ts +15 -0
  93. package/store/Provider.js +71 -0
  94. package/store/editor-store-core.d.ts +4 -0
  95. package/store/editor-store-core.js +271 -0
  96. package/store/index.d.ts +112 -0
  97. package/store/index.js +178 -0
  98. package/theme.d.ts +10 -0
  99. package/theme.js +9 -0
  100. package/translation/cn.json +29 -0
  101. package/translation/en.json +29 -0
  102. package/translation/fr.json +31 -0
  103. package/translation/index.d.ts +6 -0
  104. package/translation/index.js +23 -0
  105. package/translation/types.d.ts +13 -0
  106. package/translation/types.js +5 -0
  107. package/types/Block.d.ts +22 -0
  108. package/types/Block.js +5 -0
  109. package/types/BlockType.d.ts +50 -0
  110. package/types/BlockType.js +5 -0
  111. package/types/ConfigStorageAdapter.d.ts +11 -0
  112. package/types/ConfigStorageAdapter.js +5 -0
  113. package/types/ObjectStorageAdapter.d.ts +68 -0
  114. package/types/ObjectStorageAdapter.js +5 -0
  115. package/types/index.d.ts +5 -0
  116. package/types/index.js +100 -0
  117. package/types/throttle-and-debounce.d.ts +2 -0
  118. package/types/throttle-and-debounce.js +5 -0
  119. package/utils/block.d.ts +16 -0
  120. package/utils/block.js +41 -0
  121. package/utils/helpers.d.ts +5 -0
  122. package/utils/helpers.js +22 -0
  123. package/utils/strings.d.ts +1 -0
  124. package/utils/strings.js +11 -0
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _styled = _interopRequireDefault(require("@mui/material/styles/styled.js"));
8
+ var _colors = require("@mui/material/colors");
9
+ var _clsx = _interopRequireDefault(require("clsx"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
+ var _uuid = require("uuid");
12
+ var _AddBlockButton = _interopRequireDefault(require("./AddBlockButton"));
13
+ var _block = require("../../utils/block");
14
+ var _BlockForm = _interopRequireDefault(require("./BlockForm"));
15
+ var _jsxRuntime = require("react/jsx-runtime");
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
18
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
19
+ const PREFIX = 'BlockControl';
20
+ const classes = {
21
+ root: `${PREFIX}-root`,
22
+ label: `${PREFIX}-label`,
23
+ body: `${PREFIX}-body`,
24
+ footer: `${PREFIX}-footer`
25
+ };
26
+ const Root = (0, _styled.default)('div')(({
27
+ theme
28
+ }) => ({
29
+ border: '1px solid #eee',
30
+ [`.${classes.label}`]: {
31
+ padding: theme.spacing(1),
32
+ borderBottom: '1px solid #eee'
33
+ },
34
+ [`.${classes.footer}`]: {
35
+ justifyContent: 'center',
36
+ display: 'flex'
37
+ },
38
+ '& .sortable-item .sortable-handle': {
39
+ cursor: 'grab',
40
+ flex: 1
41
+ },
42
+ '& .sortable-item.sortable-chosen': {
43
+ cursor: 'grabbing',
44
+ background: _colors.yellow[100]
45
+ }
46
+ }));
47
+ const BlocksControl = props => {
48
+ const {
49
+ label,
50
+ data,
51
+ classes: propsClasses = {},
52
+ onChange,
53
+ blockTypes,
54
+ cardinality = -1,
55
+ addBlockProps = {},
56
+ addBlockLabel,
57
+ isNested = true
58
+ } = props;
59
+ const blocksWrapperRef = (0, _react.useRef)(null);
60
+ const dataRef = (0, _react.useRef)(data);
61
+ dataRef.current = data;
62
+ const isAllowToSort = dataRef.current.every(block => !block.collapse);
63
+ const updateData = (0, _react.useCallback)(cb => {
64
+ const newData = cb(dataRef.current);
65
+ onChange(newData);
66
+ }, [onChange]);
67
+ (0, _react.useEffect)(() => {
68
+ if (!blocksWrapperRef.current) {
69
+ return undefined;
70
+ }
71
+ let active = true;
72
+ let timeoutId = -1;
73
+ let sortable = null;
74
+ (async () => {
75
+ const Sortable = (await Promise.resolve().then(() => _interopRequireWildcard(require('sortablejs')))).default;
76
+ timeoutId = window.setTimeout(() => {
77
+ if (!blocksWrapperRef.current) {
78
+ return;
79
+ }
80
+ if (!active) {
81
+ return;
82
+ }
83
+ sortable = new Sortable(blocksWrapperRef.current, {
84
+ animation: 150,
85
+ draggable: '.sortable-item',
86
+ handle: '.sortable-handle',
87
+ disabled: !isAllowToSort,
88
+ onUpdate: () => {
89
+ updateData(prevData => {
90
+ if (!sortable || !active) {
91
+ return prevData;
92
+ }
93
+ const newData = sortable.toArray().map(id => prevData.find(block => block.id === id));
94
+ return newData;
95
+ });
96
+ }
97
+ });
98
+ }, 200);
99
+ })();
100
+ return () => {
101
+ active = false;
102
+ window.clearTimeout(timeoutId);
103
+ if (sortable) {
104
+ sortable.destroy();
105
+ }
106
+ };
107
+ }, [updateData, isAllowToSort]);
108
+ const handleAddBlock = blockType => {
109
+ updateData(prevData => {
110
+ return [...prevData, (0, _block.createBlock)(blockType)];
111
+ });
112
+ };
113
+ const handleClone = id => (withData = true) => {
114
+ updateData(prevData => {
115
+ const block = prevData.find(b => b.id === id);
116
+ const blockType = blockTypes.find(bt => bt.id === block.type);
117
+ if (!blockType) {
118
+ return prevData;
119
+ }
120
+ return [...prevData, {
121
+ ...block,
122
+ id: (0, _uuid.v4)(),
123
+ data: withData ? block.data : blockType.defaultData,
124
+ meta: {
125
+ ...block.meta,
126
+ created: Date.now(),
127
+ changed: Date.now()
128
+ }
129
+ }];
130
+ });
131
+ };
132
+ const handleChange = id => newBlockOrFn => {
133
+ updateData(prevData => {
134
+ const prevBlock = prevData.find(b => b.id === id);
135
+ const newBlock = typeof newBlockOrFn === 'function' ? newBlockOrFn(prevBlock) : newBlockOrFn;
136
+ return prevData.map(block => {
137
+ if (block.id !== newBlock.id) {
138
+ return block;
139
+ }
140
+ return newBlock;
141
+ });
142
+ });
143
+ };
144
+ const handleDeleteBlock = id => () => {
145
+ updateData(prevData => {
146
+ return prevData.filter(block => block.id !== id);
147
+ });
148
+ };
149
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Root, {
150
+ className: (0, _clsx.default)(classes.root, propsClasses.root),
151
+ children: [label && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
152
+ className: classes.label,
153
+ children: label
154
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
155
+ ref: blocksWrapperRef,
156
+ className: (0, _clsx.default)(classes.body, propsClasses.body),
157
+ children: data.map(block => {
158
+ const {
159
+ type,
160
+ id,
161
+ meta
162
+ } = block;
163
+ const blockType = blockTypes.find(bt => bt.id === type);
164
+ if (!blockType) {
165
+ return null;
166
+ }
167
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_BlockForm.default, {
168
+ blockType: blockType,
169
+ block: block,
170
+ onChange: handleChange(id),
171
+ onDelete: handleDeleteBlock(id),
172
+ onClone: handleClone(id),
173
+ isNested: isNested
174
+ }, block.id);
175
+ })
176
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("footer", {
177
+ className: (0, _clsx.default)('blocks-control-footer', classes.footer, propsClasses.footer),
178
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_AddBlockButton.default, {
179
+ label: addBlockLabel,
180
+ displayFormat: "drawer",
181
+ ...addBlockProps,
182
+ data: data,
183
+ blockTypes: blockTypes,
184
+ onAddBlock: handleAddBlock,
185
+ disabled: cardinality >= 0 && data.length >= cardinality
186
+ })
187
+ })]
188
+ });
189
+ };
190
+ var _default = exports.default = BlocksControl;
@@ -0,0 +1,10 @@
1
+ import { Block } from '../../types';
2
+ import { type FC } from 'react';
3
+ export interface SidebarProps {
4
+ title: string;
5
+ open?: boolean;
6
+ onBack?(): void;
7
+ onChange?(data: Block[]): void;
8
+ }
9
+ declare const Sidebar: FC<SidebarProps>;
10
+ export default Sidebar;
@@ -0,0 +1,451 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _I18nContext = require("../../contexts/I18nContext");
8
+ var _BlocksControl = _interopRequireDefault(require("./BlocksControl"));
9
+ var _store = require("../../store");
10
+ var _block = require("../../utils/block");
11
+ var _Delete = _interopRequireDefault(require("@mui/icons-material/Delete"));
12
+ var _FileCopy = _interopRequireDefault(require("@mui/icons-material/FileCopy"));
13
+ var _Button = _interopRequireDefault(require("@mui/material/Button"));
14
+ var _Dialog = _interopRequireDefault(require("@mui/material/Dialog"));
15
+ var _DialogActions = _interopRequireDefault(require("@mui/material/DialogActions"));
16
+ var _DialogContent = _interopRequireDefault(require("@mui/material/DialogContent"));
17
+ var _DialogContentText = _interopRequireDefault(require("@mui/material/DialogContentText"));
18
+ var _DialogTitle = _interopRequireDefault(require("@mui/material/DialogTitle"));
19
+ var _ListItemIcon = _interopRequireDefault(require("@mui/material/ListItemIcon"));
20
+ var _ListItemText = _interopRequireDefault(require("@mui/material/ListItemText"));
21
+ var _Menu = _interopRequireDefault(require("@mui/material/Menu"));
22
+ var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem"));
23
+ var _styles = require("@mui/material/styles");
24
+ var _Typography = _interopRequireDefault(require("@mui/material/Typography"));
25
+ var _clsx = _interopRequireDefault(require("clsx"));
26
+ var _react = require("react");
27
+ var _jsxRuntime = require("react/jsx-runtime");
28
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
29
+ const PREFIX = 'Sidebar';
30
+ const classes = {
31
+ root: `${PREFIX}-root`,
32
+ headerBtn: `${PREFIX}-headerBtn`,
33
+ title: `${PREFIX}-title`,
34
+ header: `${PREFIX}-header`,
35
+ body: `${PREFIX}-body`,
36
+ footer: `${PREFIX}-footer`,
37
+ emptyState: `${PREFIX}-emptyState`
38
+ };
39
+ const Root = (0, _styles.styled)('div')(({
40
+ theme
41
+ }) => ({
42
+ [`&.${classes.root}`]: {
43
+ width: '100%',
44
+ height: '100%',
45
+ background: theme.palette.background.default,
46
+ boxShadow: '-1px 0 2px rgba(0,0,0,0.2)',
47
+ transform: 'translateX(100%)',
48
+ transitionDuration: '.2s',
49
+ transitionProperty: 'transform',
50
+ top: 0,
51
+ left: 0,
52
+ zIndex: 10,
53
+ minHeight: '100%',
54
+ maxHeight: '100%',
55
+ position: 'absolute',
56
+ borderLeft: `2px solid ${theme.palette.grey[100]}`,
57
+ '&.open': {
58
+ transform: 'translateX(0%)'
59
+ }
60
+ },
61
+ [`& .${classes.headerBtn}`]: {
62
+ height: '100%',
63
+ borderRadius: 0,
64
+ boxShadow: 'none'
65
+ },
66
+ [`& .${classes.title}`]: {
67
+ padding: theme.spacing(2),
68
+ cursor: 'pointer'
69
+ },
70
+ [`& .${classes.header}`]: {
71
+ borderBottom: `1px solid ${theme.palette.grey[100]}`,
72
+ display: 'flex',
73
+ alignItems: 'center',
74
+ height: 56
75
+ },
76
+ [`& .${classes.body}`]: {
77
+ border: 'none',
78
+ display: 'flex',
79
+ flexDirection: 'column',
80
+ height: '100%',
81
+ overflowY: 'auto'
82
+ },
83
+ [`& .${classes.footer}`]: {
84
+ marginTop: 'auto',
85
+ borderTop: '1px solid #eee',
86
+ display: 'none',
87
+ opacity: 0,
88
+ zIndex: -10
89
+ },
90
+ [`& .${classes.emptyState}`]: {
91
+ display: 'flex',
92
+ flexDirection: 'column',
93
+ alignItems: 'center',
94
+ justifyContent: 'center',
95
+ height: '100%',
96
+ color: theme.palette.text.secondary,
97
+ '& .MuiSvgIcon-root': {
98
+ fontSize: 48,
99
+ marginBottom: theme.spacing(2),
100
+ opacity: 0.5
101
+ }
102
+ }
103
+ }));
104
+ const Sidebar = props => {
105
+ const t = (0, _I18nContext.useT)();
106
+ const {
107
+ onBack,
108
+ title = 'Blocks',
109
+ open = true,
110
+ onChange
111
+ } = props;
112
+ const [mounted, setMounted] = (0, _react.useState)(false);
113
+ const [closing, setClosing] = (0, _react.useState)(false);
114
+ const {
115
+ cardinality,
116
+ selectedBlockId,
117
+ setSelectedBlockId,
118
+ blockTypes,
119
+ isMp,
120
+ data,
121
+ setData,
122
+ setEditingBlockId
123
+ } = (0, _store.useEditorStore)(state => state);
124
+ const [dragOverId, setDragOverId] = (0, _react.useState)(null);
125
+ const [dragPosition, setDragPosition] = (0, _react.useState)(null);
126
+ const [menuAnchorEl, setMenuAnchorEl] = (0, _react.useState)(null);
127
+ const [activeBlockId, setActiveBlockId] = (0, _react.useState)(null);
128
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, _react.useState)(false);
129
+
130
+ // Recursively clone blocks and their child nodes, generating new IDs for each node
131
+ const cloneBlockWithChildren = block => {
132
+ const newBlock = {
133
+ ...block,
134
+ id: `${block.type}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
135
+ meta: {
136
+ ...block.meta,
137
+ created: Date.now(),
138
+ changed: Date.now()
139
+ }
140
+ };
141
+
142
+ // If there are child nodes, recursively clone them
143
+ if (block.data.subBlocks) {
144
+ newBlock.data = {
145
+ ...block.data,
146
+ subBlocks: block.data.subBlocks.map(child => cloneBlockWithChildren(child))
147
+ };
148
+ }
149
+ return newBlock;
150
+ };
151
+ const updateData = newData => {
152
+ if (newData.length !== data.length) {
153
+ setSelectedBlockId('');
154
+ setEditingBlockId('');
155
+ }
156
+ setData(newData);
157
+ if (onChange) {
158
+ onChange(newData);
159
+ }
160
+ };
161
+ (0, _react.useEffect)(() => {
162
+ requestAnimationFrame(() => {
163
+ setMounted(true);
164
+ });
165
+ return () => {
166
+ setMounted(false);
167
+ };
168
+ }, []);
169
+
170
+ // Not in use
171
+ // const handleBack = () => {
172
+ // setClosing(true);
173
+ // setTimeout(() => {
174
+ // requestAnimationFrame(() => {
175
+ // if (!onBack) {
176
+ // return;
177
+ // }
178
+ // onBack();
179
+ // });
180
+ // }, 200);
181
+ // };
182
+
183
+ // Not in use
184
+ /* const selectedBlockName = useMemo(() => {
185
+ const selectedBlock = data.find((block) => block.id === selectedBlockId);
186
+ if (!selectedBlock) return '';
187
+ return selectedBlock.data.blockName || selectedBlock.id;
188
+ }, [selectedBlockId, data]); */
189
+
190
+ const selectedBlock = (0, _react.useMemo)(() => {
191
+ // If there's a selected block, return it
192
+ if (selectedBlockId) {
193
+ const findBlock = data.find(block => block.id === selectedBlockId);
194
+ const findBlockInSubBlocks = data.find(block => block?.data?.subBlocks?.find(child => child.id === selectedBlockId));
195
+ return findBlock || findBlockInSubBlocks;
196
+ }
197
+ // If no block is selected and we have blocks, return the last one
198
+ if (data.length > 0) {
199
+ return data[data.length - 1];
200
+ }
201
+ // If no blocks exist, return null
202
+ return null;
203
+ }, [selectedBlockId, data]);
204
+
205
+ // Update selectedBlockId when data changes and no block is selected
206
+ (0, _react.useEffect)(() => {
207
+ const firstBlock = data[0];
208
+ const lastBlock = data[data.length - 1];
209
+ if (data.length > 0) {
210
+ if (!selectedBlockId) {
211
+ const isMpPage = (0, _block.blockFilteredMPNav)(firstBlock, true) && isMp;
212
+ const isNormalPage = (0, _block.blockFilteredMPNav)(lastBlock) && !isMp;
213
+ if (isMpPage || isNormalPage) {
214
+ setSelectedBlockId(firstBlock.id);
215
+ setEditingBlockId(firstBlock.id);
216
+ }
217
+ }
218
+ // Set the selected block from mp-nav to the second one (if it has) when the device switches from mp to others
219
+ if ((0, _block.blockFilteredMPNav)(firstBlock, true) && firstBlock.id === selectedBlockId && !isMp && data.length > 1) {
220
+ const secondBlock = data[1];
221
+ setSelectedBlockId(secondBlock.id);
222
+ setEditingBlockId(secondBlock.id);
223
+ }
224
+ }
225
+ }, [data, selectedBlockId, isMp, setSelectedBlockId, setEditingBlockId]);
226
+ const handleMenuOpen = (event, blockId) => {
227
+ event.stopPropagation();
228
+ setMenuAnchorEl(event.currentTarget);
229
+ setActiveBlockId(blockId);
230
+ };
231
+ const handleMenuClose = () => {
232
+ setMenuAnchorEl(null);
233
+ setActiveBlockId(null);
234
+ };
235
+ const handleClone = () => {
236
+ if (activeBlockId) {
237
+ // Check if it's a root node
238
+ const rootBlock = data.find(block => block.id === activeBlockId);
239
+ if (rootBlock) {
240
+ // If it's a root node, clone and add to the end
241
+ const clonedBlock = cloneBlockWithChildren(rootBlock);
242
+ const newData = [...data, clonedBlock];
243
+ setData(newData);
244
+ if (onChange) {
245
+ onChange(newData);
246
+ }
247
+ setSelectedBlockId(clonedBlock.id);
248
+ setEditingBlockId(clonedBlock.id);
249
+ } else {
250
+ // If it's not a root node, handle child node cloning
251
+ const updateBlocksWithClone = blocks => {
252
+ return blocks.map(block => {
253
+ if (block.data.subBlocks) {
254
+ const targetIndex = block.data.subBlocks.findIndex(child => child.id === activeBlockId);
255
+ if (targetIndex !== -1) {
256
+ const clonedBlock = cloneBlockWithChildren(block.data.subBlocks[targetIndex]);
257
+ const newChildren = [...block.data.subBlocks.slice(0, targetIndex + 1), clonedBlock, ...block.data.subBlocks.slice(targetIndex + 1)];
258
+ return {
259
+ ...block,
260
+ meta: {
261
+ ...block.meta,
262
+ changed: Date.now()
263
+ },
264
+ data: {
265
+ ...block.data,
266
+ subBlocks: newChildren
267
+ }
268
+ };
269
+ }
270
+ const newChildren = updateBlocksWithClone(block.data.subBlocks);
271
+ if (JSON.stringify(newChildren) !== JSON.stringify(block.data.subBlocks)) {
272
+ return {
273
+ ...block,
274
+ meta: {
275
+ ...block.meta,
276
+ changed: Date.now()
277
+ },
278
+ data: {
279
+ ...block.data,
280
+ subBlocks: newChildren
281
+ }
282
+ };
283
+ }
284
+ }
285
+ return block;
286
+ });
287
+ };
288
+ const newData = updateBlocksWithClone([...data]);
289
+ setData(newData);
290
+ if (onChange) {
291
+ onChange(newData);
292
+ }
293
+ }
294
+ }
295
+ handleMenuClose();
296
+ };
297
+ const handleDeleteClick = () => {
298
+ setDeleteDialogOpen(true);
299
+ setMenuAnchorEl(null); // Only close the menu but keep activeBlockId
300
+ };
301
+ const handleDeleteCancel = () => {
302
+ setDeleteDialogOpen(false);
303
+ setActiveBlockId(null); // Clear activeBlockId only when canceling
304
+ };
305
+ const handleDeleteConfirm = () => {
306
+ if (activeBlockId) {
307
+ // Check if it's a root node
308
+ const rootIndex = data.findIndex(block => block.id === activeBlockId);
309
+ if (rootIndex !== -1) {
310
+ // If it's a root node, remove directly from array
311
+ const newData = data.filter(block => block.id !== activeBlockId);
312
+ setData(newData);
313
+ if (onChange) {
314
+ onChange(newData);
315
+ }
316
+ setSelectedBlockId('');
317
+ setEditingBlockId('');
318
+ } else {
319
+ // If it's not a root node, handle child node deletion
320
+ const updateBlocksWithDelete = blocks => {
321
+ return blocks.map(block => {
322
+ if (block.data.subBlocks) {
323
+ const filteredChildren = block.data.subBlocks.filter(child => child.id !== activeBlockId);
324
+ if (filteredChildren.length !== block.data.subBlocks.length) {
325
+ return {
326
+ ...block,
327
+ meta: {
328
+ ...block.meta,
329
+ changed: Date.now()
330
+ },
331
+ data: {
332
+ ...block.data,
333
+ subBlocks: filteredChildren
334
+ }
335
+ };
336
+ }
337
+ const newChildren = updateBlocksWithDelete(block.data.subBlocks);
338
+ if (JSON.stringify(newChildren) !== JSON.stringify(block.data.subBlocks)) {
339
+ return {
340
+ ...block,
341
+ meta: {
342
+ ...block.meta,
343
+ changed: Date.now()
344
+ },
345
+ data: {
346
+ ...block.data,
347
+ subBlocks: newChildren
348
+ }
349
+ };
350
+ }
351
+ }
352
+ return block;
353
+ });
354
+ };
355
+ const newData = updateBlocksWithDelete([...data]);
356
+ setData(newData);
357
+ if (onChange) {
358
+ onChange(newData);
359
+ }
360
+ }
361
+ }
362
+ setDeleteDialogOpen(false);
363
+ setActiveBlockId(null);
364
+ };
365
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Root, {
366
+ className: (0, _clsx.default)(classes.root, {
367
+ open: !closing && open && mounted
368
+ }),
369
+ children: [selectedBlock ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_BlocksControl.default, {
370
+ blockTypes: blockTypes,
371
+ data: [selectedBlock],
372
+ onChange: newData => {
373
+ const updatedData = data.map(block => block.id === selectedBlock.id ? newData[0] : block);
374
+ updateData(updatedData);
375
+ },
376
+ cardinality: cardinality,
377
+ classes: {
378
+ root: classes.body,
379
+ footer: classes.footer
380
+ },
381
+ isNested: false
382
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
383
+ className: classes.emptyState,
384
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
385
+ variant: "body1",
386
+ color: "textSecondary",
387
+ children: t('editor.noBlockSelected')
388
+ })
389
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Menu.default, {
390
+ anchorEl: menuAnchorEl,
391
+ open: Boolean(menuAnchorEl),
392
+ onClose: handleMenuClose,
393
+ anchorOrigin: {
394
+ vertical: 'top',
395
+ horizontal: 'right'
396
+ },
397
+ transformOrigin: {
398
+ vertical: 'top',
399
+ horizontal: 'left'
400
+ },
401
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
402
+ onClick: handleClone,
403
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemIcon.default, {
404
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FileCopy.default, {
405
+ fontSize: "small"
406
+ })
407
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemText.default, {
408
+ children: "Clone"
409
+ })]
410
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
411
+ onClick: handleDeleteClick,
412
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemIcon.default, {
413
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Delete.default, {
414
+ fontSize: "small"
415
+ })
416
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemText.default, {
417
+ children: "Delete"
418
+ })]
419
+ })]
420
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Dialog.default, {
421
+ open: deleteDialogOpen,
422
+ onClose: handleDeleteCancel,
423
+ "aria-labelledby": "delete-dialog-title",
424
+ "aria-describedby": "delete-dialog-description",
425
+ keepMounted: true,
426
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_DialogTitle.default, {
427
+ id: "delete-dialog-title",
428
+ children: "Delete Block"
429
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialogContent.default, {
430
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialogContentText.default, {
431
+ id: "delete-dialog-description",
432
+ children: "Are you sure you want to delete this block?"
433
+ })
434
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_DialogActions.default, {
435
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
436
+ onClick: handleDeleteCancel,
437
+ variant: "outlined",
438
+ children: "Cancel"
439
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
440
+ onClick: handleDeleteConfirm,
441
+ variant: "contained",
442
+ color: "primary",
443
+ startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Delete.default, {}),
444
+ autoFocus: true,
445
+ children: "Delete"
446
+ })]
447
+ })]
448
+ })]
449
+ });
450
+ };
451
+ var _default = exports.default = Sidebar;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const Snackbar: React.FC;
3
+ export default Snackbar;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _Alert = _interopRequireDefault(require("@mui/material/Alert/Alert.js"));
9
+ var _Box = _interopRequireDefault(require("@mui/material/Box/Box.js"));
10
+ var _Snackbar = _interopRequireDefault(require("@mui/material/Snackbar/Snackbar.js"));
11
+ var _store = require("../store");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ const Snackbar = () => {
15
+ const alertMessages = (0, _store.useEditorStore)(state => state.alertMessages);
16
+ const removeMessage = (0, _store.useEditorStore)(state => state.removeAlertMessage);
17
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
18
+ children: alertMessages.map(m => {
19
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Snackbar.default, {
20
+ open: true,
21
+ onClose: () => {
22
+ removeMessage(m.id);
23
+ },
24
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Alert.default, {
25
+ severity: m.severity,
26
+ children: [Array.isArray(m.message) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
27
+ component: "ul",
28
+ sx: {
29
+ marginTop: 0,
30
+ marginBottom: 0,
31
+ padding: 0,
32
+ listStylePosition: 'inside'
33
+ },
34
+ children: m.message.map(line => /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
35
+ children: line
36
+ }))
37
+ }), typeof m.message === 'string' && m.message]
38
+ })
39
+ }, m.id);
40
+ })
41
+ });
42
+ };
43
+ var _default = exports.default = Snackbar;