@sequent-org/moodboard 1.2.119 → 1.3.0

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 (122) hide show
  1. package/package.json +11 -1
  2. package/src/assets/icons/rotate-icon.svg +1 -1
  3. package/src/core/HistoryManager.js +16 -16
  4. package/src/core/KeyboardManager.js +48 -539
  5. package/src/core/PixiEngine.js +9 -9
  6. package/src/core/SaveManager.js +56 -31
  7. package/src/core/bootstrap/CoreInitializer.js +65 -0
  8. package/src/core/commands/DeleteObjectCommand.js +8 -0
  9. package/src/core/commands/GroupDeleteCommand.js +75 -0
  10. package/src/core/commands/GroupRotateCommand.js +6 -0
  11. package/src/core/commands/UpdateContentCommand.js +52 -0
  12. package/src/core/commands/UpdateFramePropertiesCommand.js +98 -0
  13. package/src/core/commands/UpdateFrameTypeCommand.js +85 -0
  14. package/src/core/commands/UpdateNoteStyleCommand.js +88 -0
  15. package/src/core/commands/UpdateTextStyleCommand.js +90 -0
  16. package/src/core/commands/index.js +6 -0
  17. package/src/core/events/Events.js +6 -0
  18. package/src/core/flows/ClipboardFlow.js +553 -0
  19. package/src/core/flows/LayerAndViewportFlow.js +283 -0
  20. package/src/core/flows/ObjectLifecycleFlow.js +336 -0
  21. package/src/core/flows/SaveFlow.js +34 -0
  22. package/src/core/flows/TransformFlow.js +277 -0
  23. package/src/core/flows/TransformFlowResizeHelpers.js +83 -0
  24. package/src/core/index.js +41 -1773
  25. package/src/core/keyboard/KeyboardClipboardImagePaste.js +190 -0
  26. package/src/core/keyboard/KeyboardContextGuards.js +35 -0
  27. package/src/core/keyboard/KeyboardEventRouter.js +92 -0
  28. package/src/core/keyboard/KeyboardSelectionActions.js +103 -0
  29. package/src/core/keyboard/KeyboardShortcutMap.js +31 -0
  30. package/src/core/keyboard/KeyboardToolSwitching.js +26 -0
  31. package/src/core/rendering/ObjectRenderer.js +3 -7
  32. package/src/grid/BaseGrid.js +26 -0
  33. package/src/grid/CrossGrid.js +7 -6
  34. package/src/grid/DotGrid.js +89 -33
  35. package/src/grid/DotGridZoomPhases.js +42 -0
  36. package/src/grid/LineGrid.js +22 -21
  37. package/src/moodboard/MoodBoard.js +31 -532
  38. package/src/moodboard/bootstrap/MoodBoardInitializer.js +47 -0
  39. package/src/moodboard/bootstrap/MoodBoardManagersFactory.js +38 -0
  40. package/src/moodboard/bootstrap/MoodBoardUiFactory.js +109 -0
  41. package/src/moodboard/integration/MoodBoardEventBindings.js +65 -0
  42. package/src/moodboard/integration/MoodBoardLoadApi.js +82 -0
  43. package/src/moodboard/integration/MoodBoardScreenshotApi.js +33 -0
  44. package/src/moodboard/integration/MoodBoardScreenshotCanvas.js +98 -0
  45. package/src/moodboard/lifecycle/MoodBoardDestroyer.js +97 -0
  46. package/src/objects/FileObject.js +17 -6
  47. package/src/objects/FrameObject.js +50 -10
  48. package/src/objects/NoteObject.js +5 -4
  49. package/src/services/BoardService.js +42 -2
  50. package/src/services/FrameService.js +83 -42
  51. package/src/services/ResizePolicyService.js +152 -0
  52. package/src/services/SettingsApplier.js +7 -2
  53. package/src/services/ZoomPanController.js +35 -9
  54. package/src/tools/ToolManager.js +30 -537
  55. package/src/tools/board-tools/PanTool.js +5 -11
  56. package/src/tools/manager/ToolActivationController.js +49 -0
  57. package/src/tools/manager/ToolEventRouter.js +396 -0
  58. package/src/tools/manager/ToolManagerGuards.js +33 -0
  59. package/src/tools/manager/ToolManagerLifecycle.js +110 -0
  60. package/src/tools/manager/ToolRegistry.js +33 -0
  61. package/src/tools/object-tools/DrawingTool.js +48 -14
  62. package/src/tools/object-tools/PlacementTool.js +50 -1049
  63. package/src/tools/object-tools/PlacementToolV2.js +88 -0
  64. package/src/tools/object-tools/SelectTool.js +174 -2681
  65. package/src/tools/object-tools/placement/GhostController.js +504 -0
  66. package/src/tools/object-tools/placement/PlacementCoordinateResolver.js +20 -0
  67. package/src/tools/object-tools/placement/PlacementEventsBridge.js +91 -0
  68. package/src/tools/object-tools/placement/PlacementInputRouter.js +267 -0
  69. package/src/tools/object-tools/placement/PlacementPayloadFactory.js +111 -0
  70. package/src/tools/object-tools/placement/PlacementSessionStore.js +18 -0
  71. package/src/tools/object-tools/selection/BoxSelectController.js +0 -5
  72. package/src/tools/object-tools/selection/CloneFlowController.js +71 -0
  73. package/src/tools/object-tools/selection/CoordinateMapper.js +10 -0
  74. package/src/tools/object-tools/selection/CursorController.js +78 -0
  75. package/src/tools/object-tools/selection/FileNameInlineEditorController.js +184 -0
  76. package/src/tools/object-tools/selection/HitTestService.js +102 -0
  77. package/src/tools/object-tools/selection/InlineEditorController.js +24 -0
  78. package/src/tools/object-tools/selection/InlineEditorDomFactory.js +50 -0
  79. package/src/tools/object-tools/selection/InlineEditorListenersRegistry.js +14 -0
  80. package/src/tools/object-tools/selection/InlineEditorPositioningService.js +25 -0
  81. package/src/tools/object-tools/selection/NoteInlineEditorController.js +113 -0
  82. package/src/tools/object-tools/selection/SelectInputRouter.js +267 -0
  83. package/src/tools/object-tools/selection/SelectToolLifecycleController.js +128 -0
  84. package/src/tools/object-tools/selection/SelectToolSetup.js +134 -0
  85. package/src/tools/object-tools/selection/SelectionOverlayService.js +81 -0
  86. package/src/tools/object-tools/selection/SelectionStateController.js +91 -0
  87. package/src/tools/object-tools/selection/TextEditorDomFactory.js +65 -0
  88. package/src/tools/object-tools/selection/TextEditorInteractionController.js +266 -0
  89. package/src/tools/object-tools/selection/TextEditorLifecycleRegistry.js +90 -0
  90. package/src/tools/object-tools/selection/TextEditorPositioningService.js +158 -0
  91. package/src/tools/object-tools/selection/TextEditorSyncService.js +110 -0
  92. package/src/tools/object-tools/selection/TextInlineEditorController.js +457 -0
  93. package/src/tools/object-tools/selection/TransformInteractionController.js +466 -0
  94. package/src/ui/FilePropertiesPanel.js +61 -32
  95. package/src/ui/FramePropertiesPanel.js +176 -101
  96. package/src/ui/HtmlHandlesLayer.js +121 -999
  97. package/src/ui/MapPanel.js +12 -7
  98. package/src/ui/NotePropertiesPanel.js +17 -2
  99. package/src/ui/TextPropertiesPanel.js +124 -738
  100. package/src/ui/Toolbar.js +71 -1180
  101. package/src/ui/Topbar.js +23 -25
  102. package/src/ui/ZoomPanel.js +16 -5
  103. package/src/ui/handles/GroupSelectionHandlesController.js +29 -0
  104. package/src/ui/handles/HandlesDomRenderer.js +278 -0
  105. package/src/ui/handles/HandlesEventBridge.js +102 -0
  106. package/src/ui/handles/HandlesInteractionController.js +772 -0
  107. package/src/ui/handles/HandlesPositioningService.js +206 -0
  108. package/src/ui/handles/SingleSelectionHandlesController.js +22 -0
  109. package/src/ui/styles/toolbar.css +2 -0
  110. package/src/ui/styles/workspace.css +13 -6
  111. package/src/ui/text-properties/TextPropertiesPanelBindings.js +92 -0
  112. package/src/ui/text-properties/TextPropertiesPanelEventBridge.js +77 -0
  113. package/src/ui/text-properties/TextPropertiesPanelMapper.js +173 -0
  114. package/src/ui/text-properties/TextPropertiesPanelRenderer.js +434 -0
  115. package/src/ui/text-properties/TextPropertiesPanelState.js +39 -0
  116. package/src/ui/toolbar/ToolbarActionRouter.js +193 -0
  117. package/src/ui/toolbar/ToolbarDialogsController.js +186 -0
  118. package/src/ui/toolbar/ToolbarPopupsController.js +662 -0
  119. package/src/ui/toolbar/ToolbarRenderer.js +97 -0
  120. package/src/ui/toolbar/ToolbarStateController.js +79 -0
  121. package/src/ui/toolbar/ToolbarTooltipController.js +52 -0
  122. package/src/utils/emojiLoaderNoBundler.js +1 -1
@@ -0,0 +1,97 @@
1
+ import { Events } from '../../core/events/Events.js';
2
+
3
+ export class ToolbarRenderer {
4
+ constructor(toolbar) {
5
+ this.toolbar = toolbar;
6
+ }
7
+
8
+ createToolbar() {
9
+ this.toolbar.element = document.createElement('div');
10
+ this.toolbar.element.className = `moodboard-toolbar moodboard-toolbar--${this.toolbar.theme}`;
11
+
12
+ const newTools = [
13
+ { id: 'select', iconName: 'select', title: 'Инструмент выделения (V)', type: 'activate-select' },
14
+ { id: 'pan', iconName: 'pan', title: 'Панорамирование (Пробел)', type: 'activate-pan' },
15
+ { id: 'divider', type: 'divider' },
16
+ { id: 'text-add', iconName: 'text-add', title: 'Добавить текст', type: 'text-add' },
17
+ { id: 'note', iconName: 'note', title: 'Добавить записку', type: 'note-add' },
18
+ { id: 'image', iconName: 'image', title: 'Добавить картинку', type: 'image-add' },
19
+ // { id: 'image2', iconName: 'image', title: 'Добавить картинку', type: 'image2-add' },
20
+ { id: 'shapes', iconName: 'shapes', title: 'Фигуры', type: 'custom-shapes' },
21
+ { id: 'pencil', iconName: 'pencil', title: 'Рисование', type: 'custom-draw' },
22
+ { id: 'attachments', iconName: 'attachments', title: 'Файлы', type: 'custom-attachments' },
23
+ { id: 'emoji', iconName: 'emoji', title: 'Эмоджи', type: 'custom-emoji' }
24
+ ];
25
+
26
+ const existingTools = [
27
+ { id: 'frame', iconName: 'frame', title: 'Добавить фрейм', type: 'frame' },
28
+ { id: 'divider', type: 'divider' },
29
+ { id: 'undo', iconName: 'undo', title: 'Отменить (Ctrl+Z)', type: 'undo', disabled: true },
30
+ { id: 'redo', iconName: 'redo', title: 'Повторить (Ctrl+Y)', type: 'redo', disabled: true }
31
+ ];
32
+
33
+ [...newTools, ...existingTools].forEach((tool) => {
34
+ if (tool.type === 'divider') {
35
+ const divider = document.createElement('div');
36
+ divider.className = 'moodboard-toolbar__divider';
37
+ this.toolbar.element.appendChild(divider);
38
+ } else {
39
+ const button = this.createButton(tool);
40
+ this.toolbar.element.appendChild(button);
41
+ }
42
+ });
43
+
44
+ this.toolbar.container.appendChild(this.toolbar.element);
45
+ this.toolbar.createShapesPopup();
46
+ this.toolbar.createDrawPopup();
47
+ this.toolbar.createEmojiPopup();
48
+ this.toolbar.createFramePopup();
49
+
50
+ this.toolbar.eventBus.on(Events.Tool.Activated, this.toolbar._toolActivatedHandler);
51
+
52
+ this.toolbar.currentDrawTool = 'pencil';
53
+ }
54
+
55
+ createButton(tool) {
56
+ const button = document.createElement('button');
57
+ button.className = `moodboard-toolbar__button moodboard-toolbar__button--${tool.id}`;
58
+ button.dataset.tool = tool.type;
59
+ button.dataset.toolId = tool.id;
60
+
61
+ if (tool.disabled) {
62
+ button.disabled = true;
63
+ button.classList.add('moodboard-toolbar__button--disabled');
64
+ }
65
+
66
+ if (tool.title) {
67
+ this.toolbar.createTooltip(button, tool.title);
68
+ }
69
+
70
+ if (tool.iconName) {
71
+ this.createSvgIcon(button, tool.iconName);
72
+ }
73
+
74
+ return button;
75
+ }
76
+
77
+ createSvgIcon(button, iconName) {
78
+ if (this.toolbar.icons[iconName]) {
79
+ const tempDiv = document.createElement('div');
80
+ tempDiv.innerHTML = this.toolbar.icons[iconName];
81
+ const svg = tempDiv.querySelector('svg');
82
+
83
+ if (svg) {
84
+ svg.removeAttribute('width');
85
+ svg.removeAttribute('height');
86
+ svg.style.display = 'block';
87
+ button.appendChild(svg);
88
+ }
89
+ } else {
90
+ const fallbackIcon = document.createElement('span');
91
+ fallbackIcon.textContent = iconName.charAt(0).toUpperCase();
92
+ fallbackIcon.style.fontSize = '14px';
93
+ fallbackIcon.style.fontWeight = 'bold';
94
+ button.appendChild(fallbackIcon);
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,79 @@
1
+ import { Events } from '../../core/events/Events.js';
2
+
3
+ export class ToolbarStateController {
4
+ constructor(toolbar) {
5
+ this.toolbar = toolbar;
6
+ }
7
+
8
+ setActiveToolbarButton(toolName) {
9
+ if (!this.toolbar.element) return;
10
+
11
+ this.toolbar.element.querySelectorAll('.moodboard-toolbar__button--active').forEach((el) => {
12
+ el.classList.remove('moodboard-toolbar__button--active');
13
+ });
14
+
15
+ const map = {
16
+ select: 'select',
17
+ pan: 'pan',
18
+ draw: 'pencil',
19
+ text: 'text-add'
20
+ };
21
+
22
+ let btnId = map[toolName];
23
+
24
+ if (!btnId && toolName === 'place') {
25
+ const placeButtonMap = {
26
+ text: 'text-add',
27
+ note: 'note',
28
+ frame: 'frame',
29
+ 'frame-tool': 'frame',
30
+ comments: 'comments',
31
+ attachments: 'attachments',
32
+ shapes: 'shapes',
33
+ emoji: 'emoji',
34
+ null: 'image'
35
+ };
36
+ btnId = placeButtonMap[this.toolbar.placeSelectedButtonId] || 'shapes';
37
+ }
38
+
39
+ if (!btnId) return;
40
+
41
+ const btn = this.toolbar.element.querySelector(`.moodboard-toolbar__button--${btnId}`);
42
+ if (btn) {
43
+ btn.classList.add('moodboard-toolbar__button--active');
44
+ }
45
+ }
46
+
47
+ setupHistoryEvents() {
48
+ this.toolbar.eventBus.on(Events.UI.UpdateHistoryButtons, (data) => {
49
+ this.updateHistoryButtons(data.canUndo, data.canRedo);
50
+ });
51
+ }
52
+
53
+ updateHistoryButtons(canUndo, canRedo) {
54
+ const undoButton = this.toolbar.element.querySelector('[data-tool="undo"]');
55
+ const redoButton = this.toolbar.element.querySelector('[data-tool="redo"]');
56
+
57
+ if (undoButton) {
58
+ undoButton.disabled = !canUndo;
59
+ if (canUndo) {
60
+ undoButton.classList.remove('moodboard-toolbar__button--disabled');
61
+ undoButton.title = 'Отменить последнее действие (Ctrl+Z)';
62
+ } else {
63
+ undoButton.classList.add('moodboard-toolbar__button--disabled');
64
+ undoButton.title = 'Нет действий для отмены';
65
+ }
66
+ }
67
+
68
+ if (redoButton) {
69
+ redoButton.disabled = !canRedo;
70
+ if (canRedo) {
71
+ redoButton.classList.remove('moodboard-toolbar__button--disabled');
72
+ redoButton.title = 'Повторить отмененное действие (Ctrl+Y)';
73
+ } else {
74
+ redoButton.classList.add('moodboard-toolbar__button--disabled');
75
+ redoButton.title = 'Нет действий для повтора';
76
+ }
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,52 @@
1
+ export class ToolbarTooltipController {
2
+ constructor(toolbar) {
3
+ this.toolbar = toolbar;
4
+ }
5
+
6
+ createTooltip(button, text) {
7
+ const tooltip = document.createElement('div');
8
+ tooltip.className = 'moodboard-tooltip';
9
+ tooltip.textContent = text;
10
+ document.body.appendChild(tooltip);
11
+
12
+ let showTimeout;
13
+ let hideTimeout;
14
+
15
+ button.addEventListener('mouseenter', () => {
16
+ clearTimeout(hideTimeout);
17
+ showTimeout = setTimeout(() => {
18
+ this.showTooltip(tooltip, button);
19
+ }, 300);
20
+ });
21
+
22
+ button.addEventListener('mouseleave', () => {
23
+ clearTimeout(showTimeout);
24
+ hideTimeout = setTimeout(() => {
25
+ this.hideTooltip(tooltip);
26
+ }, 100);
27
+ });
28
+
29
+ button.addEventListener('click', () => {
30
+ clearTimeout(showTimeout);
31
+ this.hideTooltip(tooltip);
32
+ });
33
+
34
+ button._tooltip = tooltip;
35
+ }
36
+
37
+ showTooltip(tooltip, button) {
38
+ const buttonRect = button.getBoundingClientRect();
39
+ const left = buttonRect.right + 8;
40
+ const top = buttonRect.top + (buttonRect.height / 2) - (tooltip.offsetHeight / 2);
41
+ const maxLeft = window.innerWidth - tooltip.offsetWidth - 8;
42
+ const adjustedLeft = Math.min(left, maxLeft);
43
+
44
+ tooltip.style.left = `${adjustedLeft}px`;
45
+ tooltip.style.top = `${top}px`;
46
+ tooltip.classList.add('moodboard-tooltip--show');
47
+ }
48
+
49
+ hideTooltip(tooltip) {
50
+ tooltip.classList.remove('moodboard-tooltip--show');
51
+ }
52
+ }
@@ -99,7 +99,7 @@ export class EmojiLoaderNoBundler {
99
99
  async generateEmojiIndex() {
100
100
  // Эта функция может быть вызвана только в dev среде с bundler
101
101
  if (typeof import.meta !== 'undefined' && import.meta.glob) {
102
- const modules = import.meta.glob('../assets/emodji/**/*.{png,PNG}', { eager: true, as: 'url' });
102
+ const modules = import.meta.glob('../assets/emodji/**/*.{png,PNG}', { eager: true, query: '?url', import: 'default' });
103
103
  const index = {};
104
104
 
105
105
  Object.keys(modules).forEach(path => {