@sequent-org/moodboard 1.4.23 → 1.4.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequent-org/moodboard",
3
- "version": "1.4.23",
3
+ "version": "1.4.25",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
@@ -221,6 +221,9 @@ export function bindTextEditorInteractions(controller, {
221
221
  export function closeTextEditorFromState(controller, commit) {
222
222
  const textarea = controller.textEditor.textarea;
223
223
  if (!textarea) return;
224
+ const wrapper = controller.textEditor.wrapper || null;
225
+ const removeDomListeners = controller.textEditor._removeDomListeners || null;
226
+ const placeholderStyleEl = controller.textEditor._phStyle || null;
224
227
  const value = textarea.value.trim();
225
228
  const commitValue = commit && value.length > 0;
226
229
  const objectType = controller.textEditor.objectType || 'text';
@@ -252,7 +255,17 @@ export function closeTextEditorFromState(controller, commit) {
252
255
  }
253
256
  }
254
257
 
255
- textarea.remove();
258
+ if (typeof removeDomListeners === 'function') {
259
+ try { removeDomListeners(); } catch (_) {}
260
+ }
261
+ if (placeholderStyleEl && typeof placeholderStyleEl.remove === 'function') {
262
+ try { placeholderStyleEl.remove(); } catch (_) {}
263
+ }
264
+ if (wrapper && typeof wrapper.remove === 'function') {
265
+ wrapper.remove();
266
+ } else {
267
+ textarea.remove();
268
+ }
256
269
  controller.textEditor = { active: false, objectId: null, textarea: null, world: null, objectType: 'text' };
257
270
  if (!commitValue) {
258
271
  if (shouldDeleteEmptyNewCreation) {
@@ -6,32 +6,28 @@ export function createRegularTextAutoSize({
6
6
  wrapper,
7
7
  minWBound,
8
8
  minHBound,
9
- effectiveFontPx,
10
- computeLineHeightPx,
9
+ onSizeChange,
11
10
  }) {
12
11
  const MAX_AUTO_WIDTH = 360;
13
- const BASELINE_FIX = 2;
14
12
 
15
13
  return () => {
16
14
  textarea.style.width = 'auto';
17
15
  textarea.style.height = 'auto';
18
16
 
19
- const naturalW = textarea.scrollWidth + 1;
20
- const targetW = Math.min(MAX_AUTO_WIDTH, Math.max(minWBound, naturalW));
17
+ const naturalW = Math.max(1, Math.ceil(textarea.scrollWidth + 1));
18
+ const targetW = Math.round(Math.min(MAX_AUTO_WIDTH, Math.max(minWBound, naturalW)));
21
19
  textarea.style.width = `${targetW}px`;
22
20
  wrapper.style.width = `${targetW}px`;
23
21
 
24
22
  textarea.style.height = 'auto';
25
- const adjust = BASELINE_FIX;
26
- const computed = (typeof window !== 'undefined') ? window.getComputedStyle(textarea) : null;
27
- const lineH = (computed ? parseFloat(computed.lineHeight) : computeLineHeightPx(effectiveFontPx)) + 10;
28
- const rawH = textarea.scrollHeight;
29
- const lines = lineH > 0 ? Math.max(1, Math.round(rawH / lineH)) : 1;
30
- const targetH = lines <= 1
31
- ? Math.max(minHBound, Math.max(1, lineH - BASELINE_FIX))
32
- : Math.max(minHBound, Math.max(1, rawH - adjust));
23
+ const naturalH = Math.max(1, Math.ceil(textarea.scrollHeight));
24
+ const targetH = Math.round(Math.max(minHBound, naturalH));
33
25
  textarea.style.height = `${targetH}px`;
34
26
  wrapper.style.height = `${targetH}px`;
27
+
28
+ if (typeof onSizeChange === 'function') {
29
+ onSizeChange({ widthPx: targetW, heightPx: targetH });
30
+ }
35
31
  };
36
32
  }
37
33
 
@@ -143,6 +143,8 @@ export function openTextEditor(object, create = false) {
143
143
  // Базовые стили вынесены в CSS (.moodboard-text-editor)
144
144
 
145
145
  const textarea = createTextEditorTextarea(content || '');
146
+ // Без доступного статичного HTML-элемента (часто при create) не оставляем Caveat как fallback.
147
+ textarea.style.fontFamily = isNote ? 'Caveat, Arial, cursive' : 'Roboto, Arial, sans-serif';
146
148
 
147
149
  // Вычисляем межстрочный интервал; подгоняем к реальным значениям HTML-отображения
148
150
  let lhInitial = computeTextEditorLineHeightPx(effectiveFontPx);
@@ -380,7 +382,7 @@ export function openTextEditor(object, create = false) {
380
382
  }
381
383
 
382
384
  // Для записок размеры уже установлены выше, пропускаем эту логику
383
- if (!isNote) {
385
+ if (!isNote && !create) {
384
386
  if (initialWpx) {
385
387
  textarea.style.width = `${initialWpx}px`;
386
388
  wrapper.style.width = `${initialWpx}px`;
@@ -391,13 +393,29 @@ export function openTextEditor(object, create = false) {
391
393
  }
392
394
  }
393
395
  // Автоподгон
396
+ const syncRegularTextSizeToObject = !isNote && objectId
397
+ ? ({ widthPx, heightPx }) => {
398
+ try {
399
+ const scaleX = (worldLayerRef?.scale?.x) || 1;
400
+ const widthWorld = Math.max(1, Math.round(widthPx * viewRes / scaleX));
401
+ const heightWorld = Math.max(1, Math.round(heightPx * viewRes / scaleX));
402
+ const posReq = { objectId, position: null };
403
+ this.eventBus.emit(Events.Tool.GetObjectPosition, posReq);
404
+ this.eventBus.emit(Events.Tool.ResizeUpdate, {
405
+ object: objectId,
406
+ size: { width: widthWorld, height: heightWorld },
407
+ position: posReq.position || { x: position.x, y: position.y },
408
+ });
409
+ } catch (_) {}
410
+ }
411
+ : null;
412
+
394
413
  const autoSize = createRegularTextAutoSize({
395
414
  textarea,
396
415
  wrapper,
397
416
  minWBound,
398
417
  minHBound,
399
- effectiveFontPx,
400
- computeLineHeightPx: computeTextEditorLineHeightPx,
418
+ onSizeChange: syncRegularTextSizeToObject,
401
419
  });
402
420
 
403
421
  // Вызываем autoSize только для обычного текста