@sequent-org/moodboard 1.4.56 → 1.4.57

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.
@@ -5,6 +5,7 @@ import {
5
5
  TEXT_COLOR_PRESETS,
6
6
  } from './TextPropertiesPanelMapper.js';
7
7
  import { createTextFormatControls } from './TextFormatControls.js';
8
+ import { createTextLockMoreControls } from './TextLockMoreControls.js';
8
9
 
9
10
  export function createTextPropertiesPanelRenderer(panelInstance) {
10
11
  const panel = document.createElement('div');
@@ -36,7 +37,9 @@ export function hideColorDropdown(panelInstance) {
36
37
 
37
38
  export function updateCurrentColorButton(panelInstance, color) {
38
39
  if (panelInstance.currentColorButton) {
39
- panelInstance.currentColorButton.style.backgroundColor = color;
40
+ if (panelInstance.colorIndicator) {
41
+ panelInstance.colorIndicator.style.backgroundColor = color;
42
+ }
40
43
  panelInstance.currentColorButton.title = `Текущий цвет: ${color}`;
41
44
  }
42
45
  if (panelInstance.colorInput) {
@@ -44,6 +47,36 @@ export function updateCurrentColorButton(panelInstance, color) {
44
47
  }
45
48
  }
46
49
 
50
+ export function toggleHighlightDropdown(panelInstance) {
51
+ if (!panelInstance.highlightDropdown) {
52
+ return;
53
+ }
54
+
55
+ if (panelInstance.highlightDropdown.style.display === 'none') {
56
+ panelInstance.highlightDropdown.style.display = 'block';
57
+ } else {
58
+ panelInstance.highlightDropdown.style.display = 'none';
59
+ }
60
+ }
61
+
62
+ export function hideHighlightDropdown(panelInstance) {
63
+ if (panelInstance.highlightDropdown) {
64
+ panelInstance.highlightDropdown.style.display = 'none';
65
+ }
66
+ }
67
+
68
+ export function updateCurrentHighlightButton(panelInstance, color) {
69
+ if (panelInstance.currentHighlightButton) {
70
+ if (panelInstance.highlightIndicator) {
71
+ panelInstance.highlightIndicator.style.backgroundColor = color === 'transparent' ? 'transparent' : color;
72
+ }
73
+ panelInstance.currentHighlightButton.title = color === 'transparent' ? 'Без фона текста' : `Цвет фона текста: ${color}`;
74
+ }
75
+ if (panelInstance.highlightInput) {
76
+ panelInstance.highlightInput.value = color === 'transparent' ? '#ffff99' : color;
77
+ }
78
+ }
79
+
47
80
  export function toggleBgColorDropdown(panelInstance) {
48
81
  if (!panelInstance.bgColorDropdown) {
49
82
  return;
@@ -68,24 +101,27 @@ export function updateCurrentBgColorButton(panelInstance, color) {
68
101
  panelInstance.currentBgColorButton.style.backgroundColor = 'white';
69
102
  panelInstance.currentBgColorButton.title = 'Без выделения';
70
103
 
71
- if (!panelInstance.currentBgColorButton.querySelector('div')) {
72
- const line = document.createElement('div');
73
- line.style.cssText = `
74
- width: 20px;
75
- height: 1px;
76
- background: #ff0000;
77
- transform: rotate(45deg);
78
- position: absolute;
79
- top: 50%;
80
- left: 50%;
81
- transform-origin: center;
82
- transform: translate(-50%, -50%) rotate(45deg);
83
- `;
84
- panelInstance.currentBgColorButton.appendChild(line);
104
+ const line = panelInstance.currentBgColorButton.querySelector('div');
105
+ if (line) {
106
+ line.remove();
107
+ }
108
+
109
+ if (!panelInstance.currentBgColorButton.querySelector('img.no-color-icon')) {
110
+ const img = document.createElement('img');
111
+ img.src = '/icons/no-color.svg';
112
+ img.className = 'no-color-icon';
113
+ img.style.cssText = 'width: 20px; height: 20px; pointer-events: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);';
114
+ panelInstance.currentBgColorButton.appendChild(img);
85
115
  }
86
116
  } else {
87
117
  panelInstance.currentBgColorButton.style.backgroundColor = color;
88
118
  panelInstance.currentBgColorButton.title = `Цвет выделения: ${color}`;
119
+
120
+ const img = panelInstance.currentBgColorButton.querySelector('img.no-color-icon');
121
+ if (img) {
122
+ img.remove();
123
+ }
124
+
89
125
  const line = panelInstance.currentBgColorButton.querySelector('div');
90
126
  if (line) {
91
127
  line.remove();
@@ -114,6 +150,7 @@ function createFontControls(panelInstance, panel) {
114
150
  trigger.appendChild(triggerLabel);
115
151
 
116
152
  const dropdown = document.createElement('div');
153
+ dropdown.id = `tpp-font-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
117
154
  dropdown.className = 'font-dropdown';
118
155
  dropdown.setAttribute('role', 'listbox');
119
156
 
@@ -167,6 +204,10 @@ function createFontControls(panelInstance, panel) {
167
204
  panelInstance.fontDropdown = dropdown;
168
205
  panelInstance._fontSelectWrapper = fontWrapper;
169
206
 
207
+ const fontSeparator = document.createElement('div');
208
+ fontSeparator.style.cssText = 'width:1px;height:18px;background:#e0e0e0;margin:0 6px;flex-shrink:0;';
209
+ panel.appendChild(fontSeparator);
210
+
170
211
  const fontSizeWrapper = document.createElement('div');
171
212
  fontSizeWrapper.className = 'font-size-wrapper';
172
213
 
@@ -201,8 +242,14 @@ function createFontControls(panelInstance, panel) {
201
242
 
202
243
  panel.appendChild(fontSizeWrapper);
203
244
 
245
+ const colorSeparator = document.createElement('div');
246
+ colorSeparator.style.cssText = 'width:1px;height:18px;background:#e0e0e0;margin:0 6px;flex-shrink:0;';
247
+ panel.appendChild(colorSeparator);
248
+
204
249
  createCompactColorSelector(panelInstance, panel);
205
250
 
251
+ createCompactHighlightSelector(panelInstance, panel);
252
+
206
253
  createCompactBackgroundSelector(panelInstance, panel);
207
254
 
208
255
  const mdSeparator = document.createElement('div');
@@ -227,6 +274,8 @@ function createFontControls(panelInstance, panel) {
227
274
  panel.appendChild(mdLabel);
228
275
 
229
276
  createTextFormatControls(panelInstance, panel);
277
+
278
+ createTextLockMoreControls(panelInstance, panel);
230
279
  }
231
280
 
232
281
  function createCompactColorSelector(panelInstance, panel) {
@@ -234,7 +283,6 @@ function createCompactColorSelector(panelInstance, panel) {
234
283
  colorSelectorContainer.style.cssText = `
235
284
  position: relative;
236
285
  display: inline-block;
237
- margin-left: 4px;
238
286
  `;
239
287
  panelInstance._colorSelectorContainer = colorSelectorContainer;
240
288
 
@@ -243,7 +291,26 @@ function createCompactColorSelector(panelInstance, panel) {
243
291
  panelInstance.currentColorButton.title = 'Выбрать цвет';
244
292
  panelInstance.currentColorButton.className = 'current-color-button';
245
293
 
294
+ const colorIcon = document.createElement('span');
295
+ colorIcon.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5636 13.9875L12 5L15.4364 13.9875"></path><path d="M9.88525 10.8155H14.1147"></path></svg>';
296
+ colorIcon.style.cssText = 'width: 24px; height: 24px; pointer-events: none; display: flex; align-items: center; justify-content: center;';
297
+
298
+ panelInstance.colorIndicator = document.createElement('div');
299
+ panelInstance.colorIndicator.style.cssText = `
300
+ width: 18px;
301
+ height: 5px;
302
+ position: absolute;
303
+ bottom: 2px;
304
+ background: rgb(255, 235, 164);
305
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 0px 1px inset;
306
+ border-radius: 2px;
307
+ `;
308
+
309
+ panelInstance.currentColorButton.appendChild(colorIcon);
310
+ panelInstance.currentColorButton.appendChild(panelInstance.colorIndicator);
311
+
246
312
  panelInstance.colorDropdown = document.createElement('div');
313
+ panelInstance.colorDropdown.id = `tpp-color-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
247
314
  panelInstance.colorDropdown.style.cssText = `
248
315
  position: absolute;
249
316
  top: 100%;
@@ -255,7 +322,7 @@ function createCompactColorSelector(panelInstance, panel) {
255
322
  padding: 8px;
256
323
  display: none;
257
324
  z-index: 10000;
258
- min-width: 200px;
325
+ width: max-content;
259
326
  `;
260
327
 
261
328
  createColorGrid(panelInstance, panelInstance.colorDropdown);
@@ -356,6 +423,178 @@ function createColorGrid(panelInstance, container) {
356
423
  container.appendChild(customContainer);
357
424
  }
358
425
 
426
+ function createCompactHighlightSelector(panelInstance, panel) {
427
+ const highlightSelectorContainer = document.createElement('div');
428
+ highlightSelectorContainer.style.cssText = `
429
+ position: relative;
430
+ display: inline-block;
431
+ margin-left: 4px;
432
+ `;
433
+ panelInstance._highlightSelectorContainer = highlightSelectorContainer;
434
+
435
+ panelInstance.currentHighlightButton = document.createElement('button');
436
+ panelInstance.currentHighlightButton.type = 'button';
437
+ panelInstance.currentHighlightButton.title = 'Выбрать цвет фона текста';
438
+ panelInstance.currentHighlightButton.className = 'current-highlight-button';
439
+
440
+ const highlightIcon = document.createElement('span');
441
+ highlightIcon.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.431 13.4828L17.5 6.27586L15.2241 4L8.01724 10.069M11.431 13.4828L6.5 15L8.01724 10.069M11.431 13.4828L8.01724 10.069" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
442
+ highlightIcon.style.cssText = 'width: 24px; height: 24px; pointer-events: none; display: flex; align-items: center; justify-content: center;';
443
+
444
+ panelInstance.highlightIndicator = document.createElement('div');
445
+ panelInstance.highlightIndicator.style.cssText = `
446
+ width: 18px;
447
+ height: 5px;
448
+ position: absolute;
449
+ bottom: 2px;
450
+ background: transparent;
451
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 0px 1px inset;
452
+ border-radius: 2px;
453
+ `;
454
+
455
+ panelInstance.currentHighlightButton.appendChild(highlightIcon);
456
+ panelInstance.currentHighlightButton.appendChild(panelInstance.highlightIndicator);
457
+
458
+ panelInstance.highlightDropdown = document.createElement('div');
459
+ panelInstance.highlightDropdown.id = `tpp-highlight-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
460
+ panelInstance.highlightDropdown.style.cssText = `
461
+ position: absolute;
462
+ top: 100%;
463
+ left: 0;
464
+ background: white;
465
+ border: 1px solid #ddd;
466
+ border-radius: 6px;
467
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
468
+ padding: 8px;
469
+ display: none;
470
+ z-index: 10000;
471
+ width: max-content;
472
+ `;
473
+
474
+ createHighlightColorGrid(panelInstance, panelInstance.highlightDropdown);
475
+
476
+ highlightSelectorContainer.appendChild(panelInstance.currentHighlightButton);
477
+ highlightSelectorContainer.appendChild(panelInstance.highlightDropdown);
478
+ panel.appendChild(highlightSelectorContainer);
479
+ }
480
+
481
+ function createHighlightColorGrid(panelInstance, container) {
482
+ const presetsGrid = document.createElement('div');
483
+ presetsGrid.style.cssText = `
484
+ display: grid;
485
+ grid-template-columns: repeat(6, 28px);
486
+ gap: 6px;
487
+ margin-bottom: 8px;
488
+ align-items: center;
489
+ justify-items: center;
490
+ `;
491
+
492
+ panelInstance._highlightPresetButtons = [];
493
+
494
+ BACKGROUND_COLOR_PRESETS.forEach((preset) => {
495
+ const colorButton = document.createElement('button');
496
+ colorButton.type = 'button';
497
+ colorButton.title = preset.name;
498
+ colorButton.dataset.colorValue = preset.color;
499
+
500
+ if (preset.color === 'transparent') {
501
+ colorButton.style.cssText = `
502
+ width: 28px;
503
+ height: 28px;
504
+ border: 1px solid #ddd;
505
+ border-radius: 50%;
506
+ background: white;
507
+ cursor: pointer;
508
+ margin: 0;
509
+ padding: 0;
510
+ display: flex;
511
+ align-items: center;
512
+ justify-content: center;
513
+ box-sizing: border-box;
514
+ position: relative;
515
+ `;
516
+
517
+ const img = document.createElement('img');
518
+ img.src = '/icons/no-color.svg';
519
+ img.className = 'no-color-icon';
520
+ img.style.cssText = 'width: 20px; height: 20px; pointer-events: none;';
521
+ colorButton.appendChild(img);
522
+ } else {
523
+ colorButton.style.cssText = `
524
+ width: 28px;
525
+ height: 28px;
526
+ border: 1px solid #ddd;
527
+ border-radius: 50%;
528
+ background-color: ${preset.color};
529
+ cursor: pointer;
530
+ margin: 0;
531
+ padding: 0;
532
+ display: block;
533
+ box-sizing: border-box;
534
+ ${preset.color === '#ffffff' ? 'border-color: #ccc;' : ''}
535
+ position: relative;
536
+ `;
537
+
538
+ const tick = document.createElement('i');
539
+ tick.style.cssText = `
540
+ position: absolute;
541
+ left: 50%;
542
+ top: 50%;
543
+ width: 8px;
544
+ height: 5px;
545
+ transform: translate(-50%, -50%) rotate(315deg) scaleX(-1);
546
+ border-right: 2px solid #111;
547
+ border-bottom: 2px solid #111;
548
+ display: none;
549
+ pointer-events: none;
550
+ `;
551
+ colorButton.appendChild(tick);
552
+ }
553
+
554
+ presetsGrid.appendChild(colorButton);
555
+ panelInstance._highlightPresetButtons.push(colorButton);
556
+ });
557
+
558
+ container.appendChild(presetsGrid);
559
+
560
+ const separator = document.createElement('div');
561
+ separator.style.cssText = `
562
+ height: 1px;
563
+ background: #eee;
564
+ margin: 8px 0;
565
+ `;
566
+ container.appendChild(separator);
567
+
568
+ const customContainer = document.createElement('div');
569
+ customContainer.style.cssText = `
570
+ display: flex;
571
+ align-items: center;
572
+ gap: 8px;
573
+ `;
574
+
575
+ const customLabel = document.createElement('span');
576
+ customLabel.textContent = 'Свой цвет:';
577
+ customLabel.style.cssText = `
578
+ font-size: 12px;
579
+ color: #666;
580
+ `;
581
+
582
+ panelInstance.highlightInput = document.createElement('input');
583
+ panelInstance.highlightInput.type = 'color';
584
+ panelInstance.highlightInput.style.cssText = `
585
+ width: 32px;
586
+ height: 24px;
587
+ border: 1px solid #ddd;
588
+ border-radius: 3px;
589
+ cursor: pointer;
590
+ padding: 0;
591
+ `;
592
+
593
+ customContainer.appendChild(customLabel);
594
+ customContainer.appendChild(panelInstance.highlightInput);
595
+ container.appendChild(customContainer);
596
+ }
597
+
359
598
  function createCompactBackgroundSelector(panelInstance, panel) {
360
599
  const bgSelectorContainer = document.createElement('div');
361
600
  bgSelectorContainer.style.cssText = `
@@ -371,6 +610,7 @@ function createCompactBackgroundSelector(panelInstance, panel) {
371
610
  panelInstance.currentBgColorButton.className = 'current-bgcolor-button';
372
611
 
373
612
  panelInstance.bgColorDropdown = document.createElement('div');
613
+ panelInstance.bgColorDropdown.id = `tpp-bgcolor-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
374
614
  panelInstance.bgColorDropdown.style.cssText = `
375
615
  position: absolute;
376
616
  top: 100%;
@@ -382,7 +622,7 @@ function createCompactBackgroundSelector(panelInstance, panel) {
382
622
  padding: 8px;
383
623
  display: none;
384
624
  z-index: 10000;
385
- min-width: 200px;
625
+ width: max-content;
386
626
  `;
387
627
 
388
628
  createBackgroundColorGrid(panelInstance, panelInstance.bgColorDropdown);
@@ -428,14 +668,11 @@ function createBackgroundColorGrid(panelInstance, container) {
428
668
  position: relative;
429
669
  `;
430
670
 
431
- const line = document.createElement('div');
432
- line.style.cssText = `
433
- width: 20px;
434
- height: 1px;
435
- background: #ff0000;
436
- transform: rotate(45deg);
437
- `;
438
- colorButton.appendChild(line);
671
+ const img = document.createElement('img');
672
+ img.src = '/icons/no-color.svg';
673
+ img.className = 'no-color-icon';
674
+ img.style.cssText = 'width: 20px; height: 20px; pointer-events: none;';
675
+ colorButton.appendChild(img);
439
676
  } else {
440
677
  colorButton.style.cssText = `
441
678
  width: 28px;
@@ -9,6 +9,9 @@ export function createTextPropertiesPanelState() {
9
9
  currentColorButton: null,
10
10
  colorDropdown: null,
11
11
  colorInput: null,
12
+ currentHighlightButton: null,
13
+ highlightDropdown: null,
14
+ highlightInput: null,
12
15
  currentBgColorButton: null,
13
16
  bgColorDropdown: null,
14
17
  bgColorInput: null,
@@ -24,10 +27,13 @@ export function createTextPropertiesPanelState() {
24
27
  _eventBridgeAttached: false,
25
28
  _eventBridgeHandlers: null,
26
29
  _colorSelectorContainer: null,
30
+ _highlightSelectorContainer: null,
27
31
  _bgSelectorContainer: null,
28
32
  _colorPresetButtons: [],
33
+ _highlightPresetButtons: [],
29
34
  _bgPresetButtons: [],
30
35
  _onColorDocumentClick: null,
36
+ _onHighlightDocumentClick: null,
31
37
  _onBgDocumentClick: null,
32
38
  _docMouseDownAttached: false,
33
39
  };