@sequent-org/moodboard 1.4.55 → 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.
- package/package.json +1 -1
- package/src/core/commands/PasteObjectCommand.js +7 -1
- package/src/core/commands/UpdateContentCommand.js +49 -0
- package/src/core/flows/ObjectLifecycleFlow.js +10 -1
- package/src/initNoBundler.js +29 -5
- package/src/tools/object-tools/TextTool.js +9 -3
- package/src/tools/object-tools/selection/SelectInputRouter.js +1 -1
- package/src/tools/object-tools/selection/TextEditorInteractionController.js +86 -11
- package/src/tools/object-tools/selection/TextInlineEditorController.js +2 -2
- package/src/ui/FramePropertiesPanel.js +7 -0
- package/src/ui/HtmlTextLayer.js +79 -6
- package/src/ui/ImagePropertiesPanel.js +7 -0
- package/src/ui/TextPropertiesPanel.js +163 -3
- package/src/ui/styles/panels.css +471 -31
- package/src/ui/styles/workspace.css +31 -7
- package/src/ui/text-properties/TextFormatControls.js +351 -41
- package/src/ui/text-properties/TextLinkControl.js +255 -0
- package/src/ui/text-properties/TextLockMoreControls.js +173 -0
- package/src/ui/text-properties/TextPropertiesPanelBindings.js +105 -2
- package/src/ui/text-properties/TextPropertiesPanelMapper.js +23 -0
- package/src/ui/text-properties/TextPropertiesPanelRenderer.js +348 -56
- package/src/ui/text-properties/TextPropertiesPanelState.js +6 -0
- package/src/utils/styleLoader.js +1 -1
|
@@ -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.
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
line.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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();
|
|
@@ -99,54 +135,120 @@ export function updateCurrentBgColorButton(panelInstance, color) {
|
|
|
99
135
|
}
|
|
100
136
|
|
|
101
137
|
function createFontControls(panelInstance, panel) {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
const fontWrapper = document.createElement('div');
|
|
139
|
+
fontWrapper.className = 'font-select-wrapper';
|
|
140
|
+
|
|
141
|
+
const trigger = document.createElement('div');
|
|
142
|
+
trigger.className = 'font-select';
|
|
143
|
+
trigger.setAttribute('role', 'combobox');
|
|
144
|
+
trigger.setAttribute('tabindex', '0');
|
|
145
|
+
trigger.setAttribute('aria-haspopup', 'listbox');
|
|
146
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
147
|
+
|
|
148
|
+
const triggerLabel = document.createElement('span');
|
|
149
|
+
triggerLabel.className = 'font-select__label';
|
|
150
|
+
trigger.appendChild(triggerLabel);
|
|
151
|
+
|
|
152
|
+
const dropdown = document.createElement('div');
|
|
153
|
+
dropdown.id = `tpp-font-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
|
154
|
+
dropdown.className = 'font-dropdown';
|
|
155
|
+
dropdown.setAttribute('role', 'listbox');
|
|
156
|
+
|
|
157
|
+
const optionElements = [];
|
|
158
|
+
const optionRefs = FONT_OPTIONS.map((font) => {
|
|
159
|
+
const item = document.createElement('button');
|
|
160
|
+
item.type = 'button';
|
|
161
|
+
item.className = 'font-dropdown__item';
|
|
162
|
+
item.setAttribute('role', 'option');
|
|
163
|
+
item.dataset.value = font.value;
|
|
164
|
+
item.textContent = font.name;
|
|
165
|
+
item.style.fontFamily = font.value;
|
|
166
|
+
dropdown.appendChild(item);
|
|
167
|
+
optionElements.push(item);
|
|
168
|
+
return { value: font.value, textContent: font.name, element: item };
|
|
169
|
+
});
|
|
110
170
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
171
|
+
fontWrapper.appendChild(trigger);
|
|
172
|
+
fontWrapper.appendChild(dropdown);
|
|
173
|
+
panel.appendChild(fontWrapper);
|
|
174
|
+
|
|
175
|
+
let currentValue = FONT_OPTIONS[0].value;
|
|
176
|
+
const applyValue = (newValue) => {
|
|
177
|
+
currentValue = newValue;
|
|
178
|
+
const match = optionRefs.find((opt) => opt.value === newValue);
|
|
179
|
+
triggerLabel.textContent = match ? match.textContent : newValue;
|
|
180
|
+
triggerLabel.style.fontFamily = newValue;
|
|
181
|
+
optionRefs.forEach((opt) => {
|
|
182
|
+
opt.element.classList.toggle('is-active', opt.value === newValue);
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
applyValue(currentValue);
|
|
186
|
+
|
|
187
|
+
Object.defineProperty(trigger, 'value', {
|
|
188
|
+
configurable: true,
|
|
189
|
+
get() {
|
|
190
|
+
return currentValue;
|
|
191
|
+
},
|
|
192
|
+
set(newValue) {
|
|
193
|
+
applyValue(newValue);
|
|
194
|
+
},
|
|
117
195
|
});
|
|
196
|
+
Object.defineProperty(trigger, 'options', {
|
|
197
|
+
configurable: true,
|
|
198
|
+
get() {
|
|
199
|
+
return optionElements;
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
panelInstance.fontSelect = trigger;
|
|
204
|
+
panelInstance.fontDropdown = dropdown;
|
|
205
|
+
panelInstance._fontSelectWrapper = fontWrapper;
|
|
118
206
|
|
|
119
|
-
|
|
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);
|
|
120
210
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
sizeLabel.className = 'tpp-label tpp-label--spaced';
|
|
124
|
-
panel.appendChild(sizeLabel);
|
|
211
|
+
const fontSizeWrapper = document.createElement('div');
|
|
212
|
+
fontSizeWrapper.className = 'font-size-wrapper';
|
|
125
213
|
|
|
126
214
|
panelInstance.fontSizeSelect = document.createElement('select');
|
|
127
215
|
panelInstance.fontSizeSelect.className = 'font-size-select';
|
|
128
|
-
panelInstance.fontSizeSelect.className = 'font-size-select';
|
|
129
216
|
|
|
130
217
|
FONT_SIZE_OPTIONS.forEach((size) => {
|
|
131
218
|
const option = document.createElement('option');
|
|
132
219
|
option.value = size;
|
|
133
|
-
option.textContent =
|
|
220
|
+
option.textContent = String(size);
|
|
134
221
|
panelInstance.fontSizeSelect.appendChild(option);
|
|
135
222
|
});
|
|
136
223
|
|
|
137
|
-
|
|
224
|
+
const stepperContainer = document.createElement('div');
|
|
225
|
+
stepperContainer.className = 'font-size-steppers';
|
|
226
|
+
|
|
227
|
+
panelInstance.fontSizeUpBtn = document.createElement('button');
|
|
228
|
+
panelInstance.fontSizeUpBtn.type = 'button';
|
|
229
|
+
panelInstance.fontSizeUpBtn.className = 'font-size-stepper font-size-stepper--up';
|
|
230
|
+
panelInstance.fontSizeUpBtn.innerHTML = '<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" style="top: 1px;"><path d="M8.25 6.75L5 3.25L1.75 6.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
|
|
231
|
+
|
|
232
|
+
panelInstance.fontSizeDownBtn = document.createElement('button');
|
|
233
|
+
panelInstance.fontSizeDownBtn.type = 'button';
|
|
234
|
+
panelInstance.fontSizeDownBtn.className = 'font-size-stepper font-size-stepper--down';
|
|
235
|
+
panelInstance.fontSizeDownBtn.innerHTML = '<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="bottom: 1px;"><path d="M8.25 3.25L5 6.75L1.75 3.25"></path></svg>';
|
|
236
|
+
|
|
237
|
+
stepperContainer.appendChild(panelInstance.fontSizeUpBtn);
|
|
238
|
+
stepperContainer.appendChild(panelInstance.fontSizeDownBtn);
|
|
239
|
+
|
|
240
|
+
fontSizeWrapper.appendChild(panelInstance.fontSizeSelect);
|
|
241
|
+
fontSizeWrapper.appendChild(stepperContainer);
|
|
242
|
+
|
|
243
|
+
panel.appendChild(fontSizeWrapper);
|
|
138
244
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
panel.appendChild(colorLabel);
|
|
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);
|
|
143
248
|
|
|
144
249
|
createCompactColorSelector(panelInstance, panel);
|
|
145
250
|
|
|
146
|
-
|
|
147
|
-
bgColorLabel.textContent = 'Фон:';
|
|
148
|
-
bgColorLabel.className = 'tpp-label tpp-label--spaced';
|
|
149
|
-
panel.appendChild(bgColorLabel);
|
|
251
|
+
createCompactHighlightSelector(panelInstance, panel);
|
|
150
252
|
|
|
151
253
|
createCompactBackgroundSelector(panelInstance, panel);
|
|
152
254
|
|
|
@@ -172,6 +274,8 @@ function createFontControls(panelInstance, panel) {
|
|
|
172
274
|
panel.appendChild(mdLabel);
|
|
173
275
|
|
|
174
276
|
createTextFormatControls(panelInstance, panel);
|
|
277
|
+
|
|
278
|
+
createTextLockMoreControls(panelInstance, panel);
|
|
175
279
|
}
|
|
176
280
|
|
|
177
281
|
function createCompactColorSelector(panelInstance, panel) {
|
|
@@ -179,7 +283,6 @@ function createCompactColorSelector(panelInstance, panel) {
|
|
|
179
283
|
colorSelectorContainer.style.cssText = `
|
|
180
284
|
position: relative;
|
|
181
285
|
display: inline-block;
|
|
182
|
-
margin-left: 4px;
|
|
183
286
|
`;
|
|
184
287
|
panelInstance._colorSelectorContainer = colorSelectorContainer;
|
|
185
288
|
|
|
@@ -188,7 +291,26 @@ function createCompactColorSelector(panelInstance, panel) {
|
|
|
188
291
|
panelInstance.currentColorButton.title = 'Выбрать цвет';
|
|
189
292
|
panelInstance.currentColorButton.className = 'current-color-button';
|
|
190
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
|
+
|
|
191
312
|
panelInstance.colorDropdown = document.createElement('div');
|
|
313
|
+
panelInstance.colorDropdown.id = `tpp-color-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
|
192
314
|
panelInstance.colorDropdown.style.cssText = `
|
|
193
315
|
position: absolute;
|
|
194
316
|
top: 100%;
|
|
@@ -200,7 +322,7 @@ function createCompactColorSelector(panelInstance, panel) {
|
|
|
200
322
|
padding: 8px;
|
|
201
323
|
display: none;
|
|
202
324
|
z-index: 10000;
|
|
203
|
-
|
|
325
|
+
width: max-content;
|
|
204
326
|
`;
|
|
205
327
|
|
|
206
328
|
createColorGrid(panelInstance, panelInstance.colorDropdown);
|
|
@@ -301,6 +423,178 @@ function createColorGrid(panelInstance, container) {
|
|
|
301
423
|
container.appendChild(customContainer);
|
|
302
424
|
}
|
|
303
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
|
+
|
|
304
598
|
function createCompactBackgroundSelector(panelInstance, panel) {
|
|
305
599
|
const bgSelectorContainer = document.createElement('div');
|
|
306
600
|
bgSelectorContainer.style.cssText = `
|
|
@@ -316,6 +610,7 @@ function createCompactBackgroundSelector(panelInstance, panel) {
|
|
|
316
610
|
panelInstance.currentBgColorButton.className = 'current-bgcolor-button';
|
|
317
611
|
|
|
318
612
|
panelInstance.bgColorDropdown = document.createElement('div');
|
|
613
|
+
panelInstance.bgColorDropdown.id = `tpp-bgcolor-dropdown-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
|
319
614
|
panelInstance.bgColorDropdown.style.cssText = `
|
|
320
615
|
position: absolute;
|
|
321
616
|
top: 100%;
|
|
@@ -327,7 +622,7 @@ function createCompactBackgroundSelector(panelInstance, panel) {
|
|
|
327
622
|
padding: 8px;
|
|
328
623
|
display: none;
|
|
329
624
|
z-index: 10000;
|
|
330
|
-
|
|
625
|
+
width: max-content;
|
|
331
626
|
`;
|
|
332
627
|
|
|
333
628
|
createBackgroundColorGrid(panelInstance, panelInstance.bgColorDropdown);
|
|
@@ -373,14 +668,11 @@ function createBackgroundColorGrid(panelInstance, container) {
|
|
|
373
668
|
position: relative;
|
|
374
669
|
`;
|
|
375
670
|
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
transform: rotate(45deg);
|
|
382
|
-
`;
|
|
383
|
-
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);
|
|
384
676
|
} else {
|
|
385
677
|
colorButton.style.cssText = `
|
|
386
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
|
};
|
package/src/utils/styleLoader.js
CHANGED