@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,575 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.HtmlTooltip = void 0;
7
+ var _I18nContext = require("../../contexts/I18nContext");
8
+ var _LayerPanel = _interopRequireDefault(require("./LayerPanel"));
9
+ var _store = require("../../store");
10
+ var _block = require("../../utils/block");
11
+ var _Apps = _interopRequireDefault(require("@mui/icons-material/Apps"));
12
+ var _Delete = _interopRequireDefault(require("@mui/icons-material/Delete"));
13
+ var _FileCopy = _interopRequireDefault(require("@mui/icons-material/FileCopy"));
14
+ var _LayersOutlined = _interopRequireDefault(require("@mui/icons-material/LayersOutlined"));
15
+ var _Box = _interopRequireDefault(require("@mui/material/Box/Box.js"));
16
+ var _Button = _interopRequireDefault(require("@mui/material/Button/Button.js"));
17
+ var _Dialog = _interopRequireDefault(require("@mui/material/Dialog/Dialog.js"));
18
+ var _DialogActions = _interopRequireDefault(require("@mui/material/DialogActions/DialogActions.js"));
19
+ var _DialogContent = _interopRequireDefault(require("@mui/material/DialogContent/DialogContent.js"));
20
+ var _DialogContentText = _interopRequireDefault(require("@mui/material/DialogContentText/DialogContentText.js"));
21
+ var _DialogTitle = _interopRequireDefault(require("@mui/material/DialogTitle/DialogTitle.js"));
22
+ var _Divider = _interopRequireDefault(require("@mui/material/Divider/Divider.js"));
23
+ var _Grid = _interopRequireDefault(require("@mui/material/Grid/Grid.js"));
24
+ var _Icon = _interopRequireDefault(require("@mui/material/Icon/Icon.js"));
25
+ var _ListItemIcon = _interopRequireDefault(require("@mui/material/ListItemIcon/ListItemIcon.js"));
26
+ var _ListItemText = _interopRequireDefault(require("@mui/material/ListItemText/ListItemText.js"));
27
+ var _Menu = _interopRequireDefault(require("@mui/material/Menu/Menu.js"));
28
+ var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem/MenuItem.js"));
29
+ var _Tab = _interopRequireDefault(require("@mui/material/Tab/Tab.js"));
30
+ var _Tabs = _interopRequireDefault(require("@mui/material/Tabs/Tabs.js"));
31
+ var _Typography = _interopRequireDefault(require("@mui/material/Typography/Typography.js"));
32
+ var _styled = _interopRequireDefault(require("@mui/material/styles/styled.js"));
33
+ var _useTheme = _interopRequireDefault(require("@mui/material/styles/useTheme.js"));
34
+ var _Tooltip = _interopRequireWildcard(require("@mui/material/Tooltip"));
35
+ var _react = _interopRequireWildcard(require("react"));
36
+ var _uuid = require("uuid");
37
+ var _jsxRuntime = require("react/jsx-runtime");
38
+ 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); }
39
+ 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; }
40
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
41
+ const HtmlTooltip = exports.HtmlTooltip = (0, _styled.default)(({
42
+ className,
43
+ ...props
44
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, {
45
+ ...props,
46
+ classes: {
47
+ popper: className
48
+ }
49
+ }))(({
50
+ theme
51
+ }) => ({
52
+ [`& .${_Tooltip.tooltipClasses.tooltip}`]: {
53
+ backgroundColor: '#f5f5f9',
54
+ color: 'rgba(0, 0, 0, 0.87)',
55
+ maxWidth: 220,
56
+ fontSize: theme.typography.pxToRem(12),
57
+ border: '1px solid #dadde9'
58
+ }
59
+ }));
60
+ const DefaultType = 'Custom';
61
+
62
+ // Add cloneBlockWithChildren helper function
63
+ const cloneBlockWithChildren = block => {
64
+ const newBlock = {
65
+ ...block,
66
+ id: (0, _uuid.v4)(),
67
+ meta: {
68
+ ...block.meta,
69
+ created: Date.now(),
70
+ changed: Date.now()
71
+ }
72
+ };
73
+
74
+ // If there are child nodes, recursively clone them
75
+ if (block.data.subBlocks) {
76
+ newBlock.data = {
77
+ ...block.data,
78
+ subBlocks: block.data.subBlocks.map(child => cloneBlockWithChildren(child))
79
+ };
80
+ }
81
+ return newBlock;
82
+ };
83
+ const BlocksBar = ({
84
+ onChange
85
+ }) => {
86
+ const theme = (0, _useTheme.default)();
87
+ const t = (0, _I18nContext.useT)();
88
+ const [keyword, setKeyword] = (0, _react.useState)('');
89
+ const [columnsCount, setColumnsCount] = (0, _react.useState)(3); // Default 3 columns
90
+ const [tabValue, setTabValue] = (0, _react.useState)(0);
91
+ const containerRef = (0, _react.useRef)(null);
92
+ const categoryRefs = (0, _react.useRef)({});
93
+ const [tooltipStates, setTooltipStates] = (0, _react.useState)({});
94
+
95
+ // add menu related states
96
+ const [menuAnchorEl, setMenuAnchorEl] = (0, _react.useState)(null);
97
+ const [activeBlockId, setActiveBlockId] = (0, _react.useState)(null);
98
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, _react.useState)(false);
99
+ const {
100
+ blockTypes,
101
+ data,
102
+ setData,
103
+ setSelectedBlockId,
104
+ setEditingBlockId,
105
+ isMp
106
+ } = (0, _store.useEditorStore)(state => state);
107
+ const dataRef = (0, _react.useRef)(data);
108
+ dataRef.current = data;
109
+ (0, _react.useEffect)(() => {
110
+ if (!containerRef.current) return;
111
+ const resizeObserver = new ResizeObserver(entries => {
112
+ const {
113
+ width
114
+ } = entries[0].contentRect;
115
+ if (width < 300) {
116
+ setColumnsCount(2);
117
+ } else if (width < 450) {
118
+ setColumnsCount(3);
119
+ } else if (width < 600) {
120
+ setColumnsCount(4);
121
+ } else {
122
+ setColumnsCount(6);
123
+ }
124
+ });
125
+ resizeObserver.observe(containerRef.current);
126
+
127
+ // eslint-disable-next-line consistent-return
128
+ return () => {
129
+ resizeObserver.disconnect();
130
+ };
131
+ }, []);
132
+ const updateData = (0, _react.useCallback)(cb => {
133
+ const newData = cb(dataRef.current);
134
+ setData(newData);
135
+ }, [setData]);
136
+ const filteredBlockTypes = (0, _react.useMemo)(() => {
137
+ return [...(isMp ? blockTypes.filter(block => (0, _block.blockFilteredMPNav)(block, false, 'id')) : blockTypes)];
138
+ }, [isMp, blockTypes]);
139
+ const getBlockTypes = () => {
140
+ if (keyword.length === 0) {
141
+ return filteredBlockTypes;
142
+ }
143
+ return filteredBlockTypes.filter(item => {
144
+ return item.label.toLowerCase().includes(keyword.toLowerCase());
145
+ });
146
+ };
147
+ const handleAddBlock = (0, _react.useCallback)(blockType => {
148
+ const block = (0, _block.createBlock)(blockType);
149
+ updateData(prevData => [...prevData, block]);
150
+ onChange?.([...data, block]);
151
+ // Set the new block as selected and editing
152
+ setSelectedBlockId(block.id);
153
+ setEditingBlockId(block.id);
154
+ }, [updateData, setSelectedBlockId, onChange, data, setEditingBlockId]);
155
+
156
+ // add menu related handlers
157
+ const handleMenuOpen = (event, blockId) => {
158
+ event.stopPropagation();
159
+ setMenuAnchorEl(event.currentTarget);
160
+ setActiveBlockId(blockId);
161
+ };
162
+ const handleMenuClose = () => {
163
+ setMenuAnchorEl(null);
164
+ setActiveBlockId(null);
165
+ };
166
+ const handleClone = () => {
167
+ if (!activeBlockId) {
168
+ handleMenuClose();
169
+ return;
170
+ }
171
+ let lastClonedId = null;
172
+ const cloneIntoChildren = (blocks, targetId) => {
173
+ let changed = false;
174
+ let clonedId;
175
+ const next = blocks.map(block => {
176
+ const subBlocks = block.data?.subBlocks;
177
+ if (subBlocks && subBlocks.length > 0) {
178
+ const idx = subBlocks.findIndex(child => child.id === targetId);
179
+ if (idx !== -1) {
180
+ const cloned = cloneBlockWithChildren(subBlocks[idx]);
181
+ const newChildren = [...subBlocks.slice(0, idx + 1), cloned, ...subBlocks.slice(idx + 1)];
182
+ changed = true;
183
+ clonedId = cloned.id;
184
+ return {
185
+ ...block,
186
+ meta: {
187
+ ...block.meta,
188
+ changed: Date.now()
189
+ },
190
+ data: {
191
+ ...block.data,
192
+ subBlocks: newChildren
193
+ }
194
+ };
195
+ }
196
+ const res = cloneIntoChildren(subBlocks, targetId);
197
+ if (res.changed) {
198
+ changed = true;
199
+ clonedId = res.clonedId;
200
+ return {
201
+ ...block,
202
+ meta: {
203
+ ...block.meta,
204
+ changed: Date.now()
205
+ },
206
+ data: {
207
+ ...block.data,
208
+ subBlocks: res.blocks
209
+ }
210
+ };
211
+ }
212
+ }
213
+ return block;
214
+ });
215
+ return {
216
+ blocks: next,
217
+ clonedId,
218
+ changed
219
+ };
220
+ };
221
+ const updated = setData(prev => {
222
+ // Root-level clone
223
+ const rootIndex = prev.findIndex(b => b.id === activeBlockId);
224
+ if (rootIndex !== -1) {
225
+ const cloned = cloneBlockWithChildren(prev[rootIndex]);
226
+ lastClonedId = cloned.id;
227
+ return [...prev, cloned];
228
+ }
229
+ // Nested clone
230
+ const res = cloneIntoChildren(prev, activeBlockId);
231
+ if (res.clonedId) {
232
+ lastClonedId = res.clonedId;
233
+ }
234
+ return res.blocks;
235
+ });
236
+ onChange?.(updated);
237
+ if (lastClonedId) {
238
+ setSelectedBlockId(lastClonedId);
239
+ setEditingBlockId(lastClonedId);
240
+ }
241
+ handleMenuClose();
242
+ };
243
+ const handleDeleteClick = () => {
244
+ setDeleteDialogOpen(true);
245
+ setMenuAnchorEl(null);
246
+ };
247
+ const handleDeleteCancel = () => {
248
+ setDeleteDialogOpen(false);
249
+ setActiveBlockId(null);
250
+ };
251
+ const handleDeleteConfirm = () => {
252
+ if (activeBlockId) {
253
+ // Check if it's a root node
254
+ const rootIndex = data.findIndex(block => block.id === activeBlockId);
255
+ if (rootIndex !== -1) {
256
+ // If it's a root node, remove directly from array
257
+ const newData = data.filter(block => block.id !== activeBlockId);
258
+ setData(newData);
259
+ onChange?.(newData);
260
+ setSelectedBlockId('');
261
+ setEditingBlockId('');
262
+ } else {
263
+ // If it's not a root node, handle child node deletion
264
+ const updateBlocksWithDelete = blocks => {
265
+ return blocks.map(block => {
266
+ if (block.data.subBlocks) {
267
+ const filteredChildren = block.data.subBlocks.filter(child => child.id !== activeBlockId);
268
+ if (filteredChildren.length !== block.data.subBlocks.length) {
269
+ return {
270
+ ...block,
271
+ meta: {
272
+ ...block.meta,
273
+ changed: Date.now()
274
+ },
275
+ data: {
276
+ ...block.data,
277
+ subBlocks: filteredChildren
278
+ }
279
+ };
280
+ }
281
+ const newChildren = updateBlocksWithDelete(block.data.subBlocks);
282
+ if (JSON.stringify(newChildren) !== JSON.stringify(block.data.subBlocks)) {
283
+ return {
284
+ ...block,
285
+ meta: {
286
+ ...block.meta,
287
+ changed: Date.now()
288
+ },
289
+ data: {
290
+ ...block.data,
291
+ subBlocks: newChildren
292
+ }
293
+ };
294
+ }
295
+ }
296
+ return block;
297
+ });
298
+ };
299
+ const newData = updateBlocksWithDelete([...data]);
300
+ setData(newData);
301
+ onChange?.(newData);
302
+ }
303
+ }
304
+ setDeleteDialogOpen(false);
305
+ setActiveBlockId(null);
306
+ };
307
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
308
+ className: "BlocksBar",
309
+ sx: {
310
+ borderRight: '1px solid #ccc',
311
+ height: '100%',
312
+ bgcolor: theme.palette.background.default
313
+ },
314
+ ref: containerRef,
315
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
316
+ sx: {
317
+ p: 2.5,
318
+ pb: 0,
319
+ height: '100%',
320
+ display: 'flex',
321
+ flexDirection: 'column'
322
+ },
323
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Tabs.default, {
324
+ value: tabValue,
325
+ onChange: (_, newValue) => setTabValue(newValue),
326
+ sx: {
327
+ borderBottom: 1,
328
+ borderColor: 'divider'
329
+ },
330
+ variant: "fullWidth",
331
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Tab.default, {
332
+ label: t('editor.components'),
333
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Apps.default, {
334
+ fontSize: "small"
335
+ }),
336
+ sx: {
337
+ textTransform: 'none',
338
+ '& .MuiTab-iconWrapper': {
339
+ marginBottom: '4px'
340
+ }
341
+ }
342
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tab.default, {
343
+ label: t('editor.layers'),
344
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_LayersOutlined.default, {
345
+ fontSize: "small"
346
+ }),
347
+ sx: {
348
+ textTransform: 'none',
349
+ '& .MuiTab-iconWrapper': {
350
+ marginBottom: '4px'
351
+ }
352
+ }
353
+ })]
354
+ }), tabValue === 0 ?
355
+ /*#__PURE__*/
356
+ // Component list panel
357
+ (0, _jsxRuntime.jsxs)(_Box.default, {
358
+ sx: {
359
+ display: 'flex',
360
+ flexDirection: 'column',
361
+ height: '100%',
362
+ overflow: 'hidden'
363
+ },
364
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
365
+ sx: {
366
+ py: 2
367
+ },
368
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
369
+ type: "search",
370
+ style: {
371
+ width: '100%',
372
+ border: '1px solid #ccc',
373
+ outline: 'none',
374
+ padding: 8,
375
+ borderRadius: 4
376
+ },
377
+ placeholder: "Search components name",
378
+ autoComplete: "off",
379
+ onChange: e => setKeyword(e.target.value),
380
+ value: keyword
381
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Divider.default, {
382
+ sx: {
383
+ mt: 2
384
+ }
385
+ })]
386
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
387
+ sx: {
388
+ overflowY: 'auto',
389
+ height: 'calc(100% - 88px)',
390
+ pb: 2
391
+ },
392
+ children: (() => {
393
+ const items = getBlockTypes();
394
+ const groupedBlocks = {};
395
+ items.forEach(blockType => {
396
+ const category = blockType.category || DefaultType;
397
+ if (!groupedBlocks[category]) {
398
+ groupedBlocks[category] = [];
399
+ }
400
+ groupedBlocks[category].push(blockType);
401
+ });
402
+ const categories = Object.keys(groupedBlocks);
403
+ const sortedCategories = categories.filter(cat => cat !== DefaultType);
404
+ if (categories.includes(DefaultType)) {
405
+ sortedCategories.push(DefaultType);
406
+ }
407
+ return sortedCategories.map(category => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
408
+ ref: el => {
409
+ categoryRefs.current[category] = el;
410
+ },
411
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
412
+ sx: {
413
+ py: 2,
414
+ fontWeight: 'bold'
415
+ },
416
+ children: category
417
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, {
418
+ container: true,
419
+ rowGap: 2,
420
+ columnSpacing: 2,
421
+ children: groupedBlocks[category].map(blockType => /*#__PURE__*/(0, _jsxRuntime.jsx)(_Grid.default, {
422
+ item: true,
423
+ xs: 12 / columnsCount,
424
+ onClick: () => handleAddBlock(blockType),
425
+ draggable: true,
426
+ onMouseEnter: () => {
427
+ setTooltipStates(prev => ({
428
+ ...prev,
429
+ [blockType.id]: true
430
+ }));
431
+ },
432
+ onMouseLeave: () => {
433
+ setTooltipStates(prev => ({
434
+ ...prev,
435
+ [blockType.id]: false
436
+ }));
437
+ },
438
+ onDragStart: e => {
439
+ e.dataTransfer.setData('blockType', JSON.stringify(blockType));
440
+ console.log('onDragStart');
441
+ setTooltipStates(prev => ({
442
+ ...prev,
443
+ [blockType.id]: false
444
+ }));
445
+ },
446
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(HtmlTooltip, {
447
+ placement: "right-start",
448
+ PopperProps: {
449
+ anchorEl: categoryRefs.current[category]
450
+ },
451
+ open: tooltipStates[blockType.id] || false,
452
+ title: /*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
453
+ src: blockType.preview ?? `https://placehold.co/400x300?text=${encodeURIComponent(blockType.label)}`,
454
+ alt: blockType.label,
455
+ width: 400,
456
+ height: 300
457
+ }),
458
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
459
+ sx: {
460
+ display: 'flex',
461
+ aspectRatio: '104/80',
462
+ justifyContent: 'center',
463
+ flexDirection: 'column',
464
+ alignItems: 'center',
465
+ textAlign: 'center',
466
+ cursor: 'pointer',
467
+ borderRadius: '8px',
468
+ gap: 1,
469
+ border: '1px solid #D8D8D8',
470
+ lineHeight: '1.2',
471
+ padding: '10px',
472
+ '&:hover': {
473
+ backgroundColor: '#f2f2f2'
474
+ }
475
+ },
476
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
477
+ style: {
478
+ fontSize: 16
479
+ },
480
+ children: blockType.icon || 'drag_handle'
481
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("small", {
482
+ style: {
483
+ fontSize: 12
484
+ },
485
+ children: blockType.label
486
+ })]
487
+ })
488
+ })
489
+ }, blockType.id))
490
+ })]
491
+ }, category));
492
+ })()
493
+ })]
494
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
495
+ sx: {
496
+ flex: 1,
497
+ py: 2,
498
+ overflow: 'auto'
499
+ },
500
+ children: data.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
501
+ variant: "body2",
502
+ color: "text.secondary",
503
+ sx: {
504
+ textAlign: 'center',
505
+ py: 4
506
+ },
507
+ children: t('editor.noLayers')
508
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_LayerPanel.default, {
509
+ onMenuOpen: handleMenuOpen,
510
+ onChange: onChange
511
+ })
512
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Menu.default, {
513
+ anchorEl: menuAnchorEl,
514
+ open: Boolean(menuAnchorEl),
515
+ onClose: handleMenuClose,
516
+ anchorOrigin: {
517
+ vertical: 'top',
518
+ horizontal: 'right'
519
+ },
520
+ transformOrigin: {
521
+ vertical: 'top',
522
+ horizontal: 'left'
523
+ },
524
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
525
+ onClick: handleClone,
526
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemIcon.default, {
527
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FileCopy.default, {
528
+ fontSize: "small"
529
+ })
530
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemText.default, {
531
+ children: t('editor.clone')
532
+ })]
533
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_MenuItem.default, {
534
+ onClick: handleDeleteClick,
535
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemIcon.default, {
536
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Delete.default, {
537
+ fontSize: "small"
538
+ })
539
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListItemText.default, {
540
+ children: t('editor.delete')
541
+ })]
542
+ })]
543
+ })]
544
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Dialog.default, {
545
+ open: deleteDialogOpen,
546
+ onClose: handleDeleteCancel,
547
+ "aria-labelledby": "delete-dialog-title",
548
+ "aria-describedby": "delete-dialog-description",
549
+ keepMounted: true,
550
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_DialogTitle.default, {
551
+ id: "delete-dialog-title",
552
+ children: [t('editor.delete'), ' ', "Block"]
553
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialogContent.default, {
554
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialogContentText.default, {
555
+ id: "delete-dialog-description",
556
+ children: "Are you sure you want to delete this block?"
557
+ })
558
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_DialogActions.default, {
559
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
560
+ onClick: handleDeleteCancel,
561
+ variant: "outlined",
562
+ children: t('editor.cancel')
563
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
564
+ onClick: handleDeleteConfirm,
565
+ variant: "contained",
566
+ color: "error",
567
+ startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Delete.default, {}),
568
+ autoFocus: true,
569
+ children: t('editor.delete')
570
+ })]
571
+ })]
572
+ })]
573
+ });
574
+ };
575
+ var _default = exports.default = BlocksBar;
@@ -0,0 +1,16 @@
1
+ import { Block, BlockType } from '../../types';
2
+ import React from 'react';
3
+ type BlockViewProps = {
4
+ block: Block;
5
+ blockTypes: BlockType[];
6
+ onChange?(block: Block): void;
7
+ onDelete?(): void;
8
+ onMoveUp?(): void;
9
+ onMoveDown?(): void;
10
+ onCopy?(block: Block): void;
11
+ context?: Record<string, any>;
12
+ isEditMode?: boolean;
13
+ isNested?: boolean;
14
+ };
15
+ declare const _default: React.NamedExoticComponent<BlockViewProps>;
16
+ export default _default;