@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.
- 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 +28 -4
- package/src/tools/object-tools/selection/SelectInputRouter.js +1 -1
- package/src/tools/object-tools/selection/TextEditorInteractionController.js +25 -11
- package/src/tools/object-tools/selection/TextInlineEditorController.js +2 -2
- package/src/ui/FramePropertiesPanel.js +7 -0
- package/src/ui/HtmlTextLayer.js +73 -6
- package/src/ui/ImagePropertiesPanel.js +7 -0
- package/src/ui/TextPropertiesPanel.js +158 -2
- package/src/ui/styles/panels.css +240 -19
- package/src/ui/styles/workspace.css +30 -6
- package/src/ui/text-properties/TextFormatControls.js +132 -21
- 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 +37 -0
- package/src/ui/text-properties/TextPropertiesPanelMapper.js +23 -0
- package/src/ui/text-properties/TextPropertiesPanelRenderer.js +263 -26
- package/src/ui/text-properties/TextPropertiesPanelState.js +6 -0
package/src/ui/styles/panels.css
CHANGED
|
@@ -206,10 +206,27 @@
|
|
|
206
206
|
height: 36px;
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
.text-properties-panel.is-locked {
|
|
210
|
+
min-width: 0;
|
|
211
|
+
padding: 0 6px;
|
|
212
|
+
gap: 4px;
|
|
213
|
+
}
|
|
214
|
+
|
|
209
215
|
.text-properties-panel * {
|
|
210
216
|
max-height: 36px;
|
|
211
217
|
}
|
|
212
218
|
|
|
219
|
+
.text-properties-panel [id^="tpp-color-dropdown"],
|
|
220
|
+
.text-properties-panel [id^="tpp-color-dropdown"] *,
|
|
221
|
+
.text-properties-panel [id^="tpp-bgcolor-dropdown"],
|
|
222
|
+
.text-properties-panel [id^="tpp-bgcolor-dropdown"] *,
|
|
223
|
+
.text-properties-panel [id^="tpp-highlight-dropdown"],
|
|
224
|
+
.text-properties-panel [id^="tpp-highlight-dropdown"] *,
|
|
225
|
+
.text-properties-panel .tpp-more-dropdown,
|
|
226
|
+
.text-properties-panel .tpp-more-dropdown * {
|
|
227
|
+
max-height: none;
|
|
228
|
+
}
|
|
229
|
+
|
|
213
230
|
/* Frame properties toolbar — mirror image toolbar look */
|
|
214
231
|
.frame-properties-panel {
|
|
215
232
|
position: absolute;
|
|
@@ -615,10 +632,10 @@
|
|
|
615
632
|
|
|
616
633
|
.text-properties-panel .font-select {
|
|
617
634
|
box-sizing: border-box;
|
|
618
|
-
min-width:
|
|
619
|
-
width:
|
|
635
|
+
min-width: 70px;
|
|
636
|
+
width: 70px;
|
|
620
637
|
height: 38px;
|
|
621
|
-
padding: 4px
|
|
638
|
+
padding: 4px 0px;
|
|
622
639
|
font-size: 13px;
|
|
623
640
|
background-color: #fff;
|
|
624
641
|
border: none;
|
|
@@ -741,12 +758,12 @@
|
|
|
741
758
|
border: none;
|
|
742
759
|
padding: 0;
|
|
743
760
|
cursor: pointer;
|
|
744
|
-
color: #
|
|
761
|
+
color: #6B7280;
|
|
745
762
|
}
|
|
746
763
|
|
|
747
764
|
.text-properties-panel .font-size-stepper:hover {
|
|
748
765
|
background: #f5f5f5;
|
|
749
|
-
color: #
|
|
766
|
+
color: #111827;
|
|
750
767
|
}
|
|
751
768
|
|
|
752
769
|
.text-properties-panel .font-size-stepper--down {
|
|
@@ -754,11 +771,10 @@
|
|
|
754
771
|
margin-top: -2px;
|
|
755
772
|
}
|
|
756
773
|
|
|
757
|
-
.text-properties-panel .current-color-button,
|
|
758
774
|
.text-properties-panel .current-bgcolor-button {
|
|
759
|
-
width:
|
|
760
|
-
height:
|
|
761
|
-
border:
|
|
775
|
+
width: 20px;
|
|
776
|
+
height: 20px;
|
|
777
|
+
border: none;
|
|
762
778
|
border-radius: 50%;
|
|
763
779
|
background-color: #000;
|
|
764
780
|
cursor: pointer;
|
|
@@ -769,6 +785,54 @@
|
|
|
769
785
|
position: relative;
|
|
770
786
|
}
|
|
771
787
|
|
|
788
|
+
.text-properties-panel .current-color-button {
|
|
789
|
+
width: 28px;
|
|
790
|
+
height: 28px;
|
|
791
|
+
border: 1px solid transparent;
|
|
792
|
+
border-radius: 4px;
|
|
793
|
+
background-color: transparent;
|
|
794
|
+
cursor: pointer;
|
|
795
|
+
margin: 0;
|
|
796
|
+
padding: 0;
|
|
797
|
+
display: flex;
|
|
798
|
+
flex-direction: column;
|
|
799
|
+
align-items: center;
|
|
800
|
+
justify-content: center;
|
|
801
|
+
box-sizing: border-box;
|
|
802
|
+
position: relative;
|
|
803
|
+
transition: background 0.15s;
|
|
804
|
+
color: #6B7280;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
.text-properties-panel .current-color-button:hover {
|
|
808
|
+
background: #f0f0f0;
|
|
809
|
+
color: #111827;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
.text-properties-panel .current-highlight-button {
|
|
813
|
+
width: 28px;
|
|
814
|
+
height: 28px;
|
|
815
|
+
border: 1px solid transparent;
|
|
816
|
+
border-radius: 4px;
|
|
817
|
+
background-color: transparent;
|
|
818
|
+
cursor: pointer;
|
|
819
|
+
margin: 0;
|
|
820
|
+
padding: 0;
|
|
821
|
+
display: flex;
|
|
822
|
+
flex-direction: column;
|
|
823
|
+
align-items: center;
|
|
824
|
+
justify-content: center;
|
|
825
|
+
box-sizing: border-box;
|
|
826
|
+
position: relative;
|
|
827
|
+
transition: background 0.15s;
|
|
828
|
+
color: #6B7280;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
.text-properties-panel .current-highlight-button:hover {
|
|
832
|
+
background: #f0f0f0;
|
|
833
|
+
color: #111827;
|
|
834
|
+
}
|
|
835
|
+
|
|
772
836
|
.text-properties-panel .tpp-format-btn {
|
|
773
837
|
height: 28px;
|
|
774
838
|
min-width: 28px;
|
|
@@ -780,17 +844,29 @@
|
|
|
780
844
|
display: inline-flex;
|
|
781
845
|
align-items: center;
|
|
782
846
|
justify-content: center;
|
|
783
|
-
color: #
|
|
847
|
+
color: #6B7280;
|
|
784
848
|
flex-shrink: 0;
|
|
785
|
-
transition: background 0.15s;
|
|
849
|
+
transition: background 0.15s, color 0.15s;
|
|
786
850
|
}
|
|
787
|
-
.text-properties-panel .tpp-format-btn:hover { background: #f0f0f0; }
|
|
851
|
+
.text-properties-panel .tpp-format-btn:hover { background: #f0f0f0; color: #111827; }
|
|
788
852
|
.text-properties-panel .tpp-format-btn.is-active {
|
|
789
853
|
background: #e8eaff;
|
|
790
854
|
border-color: #6155F5;
|
|
791
855
|
color: #6155F5;
|
|
792
856
|
}
|
|
793
857
|
|
|
858
|
+
.text-properties-panel .tpp-format-btns-wrapper {
|
|
859
|
+
width: 24px;
|
|
860
|
+
height: 24px;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
.text-properties-panel .tpp-format-btn.tpp-format-trigger {
|
|
864
|
+
width: 24px;
|
|
865
|
+
min-width: 24px;
|
|
866
|
+
height: 24px;
|
|
867
|
+
padding: 0;
|
|
868
|
+
}
|
|
869
|
+
|
|
794
870
|
.text-properties-panel .tpp-list-btns {
|
|
795
871
|
display: flex;
|
|
796
872
|
gap: 2px;
|
|
@@ -817,6 +893,21 @@
|
|
|
817
893
|
z-index: 4000;
|
|
818
894
|
}
|
|
819
895
|
|
|
896
|
+
.text-properties-panel .tpp-format-modal {
|
|
897
|
+
max-height: none;
|
|
898
|
+
position: absolute;
|
|
899
|
+
top: calc(100% + 4px);
|
|
900
|
+
left: 0;
|
|
901
|
+
flex-direction: row;
|
|
902
|
+
gap: 2px;
|
|
903
|
+
background: #ffffff;
|
|
904
|
+
border: 1px solid #E5E7EB;
|
|
905
|
+
border-radius: 6px;
|
|
906
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
907
|
+
padding: 4px;
|
|
908
|
+
z-index: 4000;
|
|
909
|
+
}
|
|
910
|
+
|
|
820
911
|
.text-properties-panel .tpp-list-modal-option {
|
|
821
912
|
display: flex;
|
|
822
913
|
align-items: center;
|
|
@@ -833,6 +924,26 @@
|
|
|
833
924
|
flex-shrink: 0;
|
|
834
925
|
}
|
|
835
926
|
|
|
927
|
+
.text-properties-panel .tpp-format-modal-option {
|
|
928
|
+
display: flex;
|
|
929
|
+
align-items: center;
|
|
930
|
+
justify-content: center;
|
|
931
|
+
width: 28px;
|
|
932
|
+
height: 28px;
|
|
933
|
+
padding: 0;
|
|
934
|
+
border: none;
|
|
935
|
+
background: transparent;
|
|
936
|
+
border-radius: 4px;
|
|
937
|
+
cursor: pointer;
|
|
938
|
+
color: #374151;
|
|
939
|
+
transition: background 0.1s;
|
|
940
|
+
flex-shrink: 0;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.text-properties-panel .tpp-format-modal-option:hover {
|
|
944
|
+
background: #f3f4f6;
|
|
945
|
+
}
|
|
946
|
+
|
|
836
947
|
.text-properties-panel .tpp-list-modal-option:hover {
|
|
837
948
|
background: #f3f4f6;
|
|
838
949
|
}
|
|
@@ -887,6 +998,34 @@
|
|
|
887
998
|
background: #f3f4f6;
|
|
888
999
|
}
|
|
889
1000
|
|
|
1001
|
+
.text-properties-panel .tpp-lh-control {
|
|
1002
|
+
display: flex;
|
|
1003
|
+
align-items: center;
|
|
1004
|
+
position: relative;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
.text-properties-panel .tpp-lh-control svg {
|
|
1008
|
+
width: 22px;
|
|
1009
|
+
height: 22px;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.text-properties-panel .tpp-lh-modal {
|
|
1013
|
+
max-height: none;
|
|
1014
|
+
position: absolute;
|
|
1015
|
+
top: calc(100% + 4px);
|
|
1016
|
+
left: 50%;
|
|
1017
|
+
transform: translateX(-50%);
|
|
1018
|
+
flex-direction: row;
|
|
1019
|
+
align-items: center;
|
|
1020
|
+
justify-content: center;
|
|
1021
|
+
background: #ffffff;
|
|
1022
|
+
border: 1px solid #E5E7EB;
|
|
1023
|
+
border-radius: 6px;
|
|
1024
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
1025
|
+
padding: 8px 12px;
|
|
1026
|
+
z-index: 4000;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
890
1029
|
.text-properties-panel .tpp-lh-slider {
|
|
891
1030
|
width: 68px;
|
|
892
1031
|
accent-color: #6155F5;
|
|
@@ -1091,7 +1230,7 @@
|
|
|
1091
1230
|
}
|
|
1092
1231
|
|
|
1093
1232
|
/* More Dropdown */
|
|
1094
|
-
.ipp-more-dropdown {
|
|
1233
|
+
.ipp-more-dropdown, .tpp-more-dropdown {
|
|
1095
1234
|
position: absolute;
|
|
1096
1235
|
top: calc(100% + 6px);
|
|
1097
1236
|
right: 0;
|
|
@@ -1106,11 +1245,15 @@
|
|
|
1106
1245
|
z-index: 1001;
|
|
1107
1246
|
}
|
|
1108
1247
|
|
|
1109
|
-
.ipp-more-dropdown.is-open {
|
|
1248
|
+
.ipp-more-dropdown.is-open, .tpp-more-dropdown.is-open {
|
|
1110
1249
|
display: flex;
|
|
1250
|
+
position: fixed;
|
|
1251
|
+
min-width: 0;
|
|
1252
|
+
max-width: 214px;
|
|
1253
|
+
width: 214px;
|
|
1111
1254
|
}
|
|
1112
1255
|
|
|
1113
|
-
.ipp-dropdown-item {
|
|
1256
|
+
.ipp-dropdown-item, .tpp-dropdown-item {
|
|
1114
1257
|
display: flex;
|
|
1115
1258
|
align-items: center;
|
|
1116
1259
|
padding: 6px 8px;
|
|
@@ -1127,7 +1270,7 @@
|
|
|
1127
1270
|
width: 100%;
|
|
1128
1271
|
}
|
|
1129
1272
|
|
|
1130
|
-
.ipp-dropdown-item:hover {
|
|
1273
|
+
.ipp-dropdown-item:hover, .tpp-dropdown-item:hover {
|
|
1131
1274
|
background: #F3F4F6;
|
|
1132
1275
|
}
|
|
1133
1276
|
|
|
@@ -1137,19 +1280,19 @@
|
|
|
1137
1280
|
font-size: 12px;
|
|
1138
1281
|
}
|
|
1139
1282
|
|
|
1140
|
-
.ipp-dropdown-item-shortcut {
|
|
1283
|
+
.ipp-dropdown-item-shortcut, .tpp-dropdown-item-shortcut {
|
|
1141
1284
|
margin-left: auto;
|
|
1142
1285
|
color: #9CA3AF;
|
|
1143
1286
|
font-size: 12px;
|
|
1144
1287
|
}
|
|
1145
1288
|
|
|
1146
|
-
.ipp-dropdown-divider {
|
|
1289
|
+
.ipp-dropdown-divider, .tpp-dropdown-divider {
|
|
1147
1290
|
height: 1px;
|
|
1148
1291
|
background: #E5E7EB;
|
|
1149
1292
|
margin: 4px 2px;
|
|
1150
1293
|
}
|
|
1151
1294
|
|
|
1152
|
-
.ipp-dropdown-icon {
|
|
1295
|
+
.ipp-dropdown-icon, .tpp-dropdown-icon {
|
|
1153
1296
|
width: 16px;
|
|
1154
1297
|
height: 16px;
|
|
1155
1298
|
display: inline-flex;
|
|
@@ -1585,3 +1728,81 @@
|
|
|
1585
1728
|
opacity: 1;
|
|
1586
1729
|
}
|
|
1587
1730
|
|
|
1731
|
+
/* ── Кнопка «Ссылка» в панели свойств текста ────────────────── */
|
|
1732
|
+
.tpp-link-btn:disabled,
|
|
1733
|
+
.tpp-link-btn--disabled {
|
|
1734
|
+
opacity: 0.35;
|
|
1735
|
+
cursor: not-allowed;
|
|
1736
|
+
pointer-events: none;
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
/* ── Форма ввода URL ─────────────────────────────────────────── */
|
|
1740
|
+
.tpp-link-form {
|
|
1741
|
+
position: fixed;
|
|
1742
|
+
z-index: 10010;
|
|
1743
|
+
display: flex;
|
|
1744
|
+
flex-direction: column;
|
|
1745
|
+
gap: 6px;
|
|
1746
|
+
background: #ffffff;
|
|
1747
|
+
border: 1px solid #E5E7EB;
|
|
1748
|
+
border-radius: 10px;
|
|
1749
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.07);
|
|
1750
|
+
padding: 10px 12px;
|
|
1751
|
+
min-width: 260px;
|
|
1752
|
+
max-width: 340px;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
.tpp-link-form-label {
|
|
1756
|
+
font-size: 11px;
|
|
1757
|
+
color: #6B7280;
|
|
1758
|
+
white-space: nowrap;
|
|
1759
|
+
overflow: hidden;
|
|
1760
|
+
text-overflow: ellipsis;
|
|
1761
|
+
max-width: 100%;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
.tpp-link-form-row {
|
|
1765
|
+
display: flex;
|
|
1766
|
+
gap: 6px;
|
|
1767
|
+
align-items: center;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
.tpp-link-input {
|
|
1771
|
+
flex: 1;
|
|
1772
|
+
height: 30px;
|
|
1773
|
+
padding: 0 8px;
|
|
1774
|
+
border: 1px solid #D1D5DB;
|
|
1775
|
+
border-radius: 6px;
|
|
1776
|
+
font-size: 13px;
|
|
1777
|
+
font-family: inherit;
|
|
1778
|
+
outline: none;
|
|
1779
|
+
color: #111827;
|
|
1780
|
+
transition: border-color 0.15s;
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
.tpp-link-input:focus {
|
|
1784
|
+
border-color: #6366F1;
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
.tpp-link-input--error {
|
|
1788
|
+
border-color: #EF4444;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
.tpp-link-form-ok {
|
|
1792
|
+
height: 30px;
|
|
1793
|
+
padding: 0 12px;
|
|
1794
|
+
background: #6366F1;
|
|
1795
|
+
color: #ffffff;
|
|
1796
|
+
border: none;
|
|
1797
|
+
border-radius: 6px;
|
|
1798
|
+
font-size: 13px;
|
|
1799
|
+
font-family: inherit;
|
|
1800
|
+
cursor: pointer;
|
|
1801
|
+
flex-shrink: 0;
|
|
1802
|
+
transition: background 0.15s;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
.tpp-link-form-ok:hover {
|
|
1806
|
+
background: #4F46E5;
|
|
1807
|
+
}
|
|
1808
|
+
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
|
289
289
|
font-size: 13px;
|
|
290
290
|
font-family: 'Roboto', Arial, sans-serif;
|
|
291
|
-
min-width:
|
|
291
|
+
min-width: auto;
|
|
292
292
|
height: 36px;
|
|
293
293
|
}
|
|
294
294
|
|
|
@@ -321,6 +321,21 @@
|
|
|
321
321
|
letter-spacing: normal;
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
+
/* Веб-ссылка внутри текстового объекта. pointer-events: auto переопределяет
|
|
325
|
+
pointer-events: none у родительского .mb-text и .moodboard-html-layer,
|
|
326
|
+
чтобы по ссылке можно было реально перейти. */
|
|
327
|
+
.mb-text-link {
|
|
328
|
+
color: #2563EB;
|
|
329
|
+
text-decoration: underline;
|
|
330
|
+
text-underline-offset: 2px;
|
|
331
|
+
pointer-events: auto;
|
|
332
|
+
cursor: pointer;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.mb-text-link:hover {
|
|
336
|
+
color: #1D4ED8;
|
|
337
|
+
}
|
|
338
|
+
|
|
324
339
|
/* Markdown-режим текстового объекта: блочный рендер, перенос по словам */
|
|
325
340
|
.mb-text--md {
|
|
326
341
|
white-space: normal;
|
|
@@ -688,9 +703,6 @@
|
|
|
688
703
|
|
|
689
704
|
.text-properties-panel .current-color-button,
|
|
690
705
|
.text-properties-panel .current-bgcolor-button {
|
|
691
|
-
width: 28px;
|
|
692
|
-
height: 20px;
|
|
693
|
-
border: 1px solid #ddd;
|
|
694
706
|
border-radius: 4px;
|
|
695
707
|
background-color: #000;
|
|
696
708
|
cursor: pointer;
|
|
@@ -700,6 +712,18 @@
|
|
|
700
712
|
box-sizing: border-box;
|
|
701
713
|
position: relative;
|
|
702
714
|
}
|
|
715
|
+
|
|
716
|
+
.text-properties-panel .current-color-button {
|
|
717
|
+
width: 20px;
|
|
718
|
+
height: 20px;
|
|
719
|
+
border: 1px solid #ddd;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.text-properties-panel .current-bgcolor-button {
|
|
723
|
+
width: 20px;
|
|
724
|
+
height: 20px;
|
|
725
|
+
border: none;
|
|
726
|
+
}
|
|
703
727
|
/* MoodBoard Workspace Styles */
|
|
704
728
|
|
|
705
729
|
/* Основные контейнеры */
|
|
@@ -1548,8 +1572,8 @@
|
|
|
1548
1572
|
transition: all 0.2s ease;
|
|
1549
1573
|
outline: none;
|
|
1550
1574
|
outline-offset: 0;
|
|
1551
|
-
padding-top:
|
|
1552
|
-
padding-bottom:
|
|
1575
|
+
padding-top: 1px;
|
|
1576
|
+
padding-bottom: 1px;
|
|
1553
1577
|
}
|
|
1554
1578
|
|
|
1555
1579
|
.moodboard-text-input:focus {
|
|
@@ -6,10 +6,11 @@ import {
|
|
|
6
6
|
} from './TextPropertiesPanelMapper.js';
|
|
7
7
|
|
|
8
8
|
// Статичные SVG-строки (lucide-style). innerHTML допустим — это доверенные константы, не пользовательский ввод.
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
9
|
+
const SVG_TEXT_FORMAT = '<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" type="text-format" size="24"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.54459 15.3341C7.52012 15.4823 7.52819 15.634 7.56823 15.7787C7.60828 15.9234 7.67935 16.0576 7.77651 16.1721C7.87366 16.2866 7.99458 16.3786 8.13085 16.4416C8.26712 16.5047 8.41548 16.5373 8.56563 16.5372H11.9587C12.8918 16.5372 13.6811 16.3966 14.3277 16.1141C14.9742 15.8286 15.4822 15.4417 15.8505 14.9566C16.2229 14.4662 16.4608 13.9138 16.5674 13.2993C16.6656 12.6755 16.6242 12.1469 16.4432 11.7124C16.2632 11.2779 16.0005 10.9417 15.657 10.7069C15.3354 10.4746 14.9536 10.3399 14.5574 10.319L14.5801 10.201C14.9567 10.1079 15.3146 9.9569 15.656 9.74897C15.9974 9.54207 16.287 9.2669 16.526 8.92552C16.7691 8.58414 16.9315 8.16414 17.0142 7.66241C17.1156 7.06655 17.0691 6.53172 16.8725 6.05793C16.676 5.58 16.3201 5.20138 15.8029 4.9231C15.2898 4.64069 14.607 4.5 13.7515 4.5H10.2208C9.97593 4.50011 9.73904 4.58708 9.55227 4.74544C9.3655 4.9038 9.24096 5.12328 9.2008 5.36483L7.54563 15.3341H7.54459ZM12.0415 14.9803H9.42011L10.0667 11.1238H12.7522C13.2384 11.1238 13.6418 11.2179 13.9625 11.4062C14.2884 11.5945 14.5201 11.8469 14.6567 12.1645C14.7974 12.4821 14.8387 12.8307 14.7808 13.2114C14.6898 13.7162 14.428 14.1372 13.9925 14.4745C13.5622 14.8117 12.9115 14.9803 12.0415 14.9803ZM12.7346 9.70759H10.3077L10.9077 6.04552H13.3874C14.1042 6.04552 14.608 6.21414 14.8977 6.55138C15.1915 6.88448 15.296 7.30138 15.2091 7.8031C15.1511 8.1869 15.0022 8.52207 14.7632 8.80862C14.5274 9.09414 14.2315 9.31552 13.8756 9.47276C13.5229 9.62897 13.1422 9.70759 12.7346 9.70759ZM6.56908 17.9483C6.3633 17.9483 6.16596 18.03 6.02046 18.1755C5.87496 18.321 5.79321 18.5184 5.79321 18.7241C5.79321 18.9299 5.87496 19.1273 6.02046 19.2728C6.16596 19.4183 6.3633 19.5 6.56908 19.5H17.4311C17.6369 19.5 17.8343 19.4183 17.9798 19.2728C18.1253 19.1273 18.207 18.9299 18.207 18.7241C18.207 18.5184 18.1253 18.321 17.9798 18.1755C17.8343 18.03 17.6369 17.9483 17.4311 17.9483H6.56908Z"></path></svg>';
|
|
10
|
+
const SVG_BOLD = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6.92188 12H13.1719C14.8978 12 16.2969 10.6009 16.2969 8.875C16.2969 7.14911 14.8978 5.75 13.1719 5.75H6.92188V12ZM6.92188 12H13.9531C15.679 12 17.0781 13.3991 17.0781 15.125C17.0781 16.8509 15.679 18.25 13.9531 18.25H6.92188V12Z"></path></svg>';
|
|
11
|
+
const SVG_ITALIC = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M17.4688 5.75H10.4375M13.5625 18.25H6.53125M14.3438 5.75L9.65625 18.25"></path></svg>';
|
|
12
|
+
const SVG_UNDERLINE = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" y1="20" x2="20" y2="20"/></svg>';
|
|
13
|
+
const SVG_STRIKE = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M7.3125 15.125C7.3125 16.8509 8.71161 18.25 10.4375 18.25H13.5625C15.2884 18.25 16.6875 16.8509 16.6875 15.125C16.6875 13.3991 15.2884 12 13.5625 12M16.6875 8.875C16.6875 7.14911 15.2884 5.75 13.5625 5.75H10.4375C8.71161 5.75 7.3125 7.14911 7.3125 8.875M4.96875 12H19.0312"></path></svg>';
|
|
13
14
|
|
|
14
15
|
const SVG_ALIGN_LEFT = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><path d="M4.75 5.73633H19.25"/><path d="M4.75 18.2637H13.25"/><path d="M4.75 14.0879H19.25"/><path d="M4.75 9.91211L13.25 9.91211"/></svg>';
|
|
15
16
|
const SVG_ALIGN_CENTER = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><path d="M4.75 5.73633H19.25"/><path d="M7.75 18.2637H16.25"/><path d="M4.75 14.0879H19.25"/><path d="M7.75 9.91211L16.25 9.91211"/></svg>';
|
|
@@ -19,6 +20,7 @@ const SVG_ALIGN_JUSTIFY = '<svg width="24" height="24" viewBox="0 0 24 24" fill=
|
|
|
19
20
|
const SVG_LIST_BULLET = '<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8.28516 5.49609H19.2852M8.28516 11H19.2852M8.28516 16.4961H19.2852M4.21484 17.25C4.62906 17.25 4.96484 16.9142 4.96484 16.5C4.96484 16.0858 4.62906 15.75 4.21484 15.75C3.80063 15.75 3.46484 16.0858 3.46484 16.5C3.46484 16.9142 3.80063 17.25 4.21484 17.25ZM4.21484 11.75C4.62906 11.75 4.96484 11.4142 4.96484 11C4.96484 10.5858 4.62906 10.25 4.21484 10.25C3.80063 10.25 3.46484 10.5858 3.46484 11C3.46484 11.4142 3.80063 11.75 4.21484 11.75ZM4.21484 6.24609C4.62906 6.24609 4.96484 5.91031 4.96484 5.49609C4.96484 5.08188 4.62906 4.74609 4.21484 4.74609C3.80063 4.74609 3.46484 5.08188 3.46484 5.49609C3.46484 5.91031 3.80063 6.24609 4.21484 6.24609Z"/></svg>';
|
|
20
21
|
const SVG_LIST_NUMBERED = '<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M8.28516 5.49505H19.2852M8.28516 10.999H19.2852M8.28516 16.4951H19.2852M3.30078 5.32812L4.67578 4.64062V9.45312M3.39531 13.2839C3.45867 13.1269 3.55438 12.9853 3.67622 12.8678C3.79808 12.7505 3.9433 12.6602 4.10242 12.6027C4.26156 12.5453 4.43101 12.5221 4.59972 12.5345C4.76844 12.547 4.93262 12.595 5.08156 12.6752C5.23049 12.7555 5.36082 12.8662 5.46407 13.0002C5.56729 13.1343 5.6411 13.2885 5.68067 13.453C5.72022 13.6175 5.72466 13.7885 5.69366 13.9549C5.66266 14.1211 5.59693 14.279 5.50078 14.4182L3.30078 17.3573H5.70703"/></svg>';
|
|
21
22
|
const SVG_LIST_CHECK = '<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M8.28516 5.49609H19.2852M8.28516 11H19.2852M8.28516 16.4961H19.2852M2.9 5.2L3.9 6.2L5.7 4.2M2.9 10.7L3.9 11.7L5.7 9.7M2.9 16.2L3.9 17.2L5.7 15.2"/></svg>';
|
|
23
|
+
const SVG_LINE_HEIGHT = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" type="line-height-2" size="24"><path d="M6.02009 5.35419V18.6459M6.02009 5.35419L8.77156 8.10419M6.02009 5.35419L3.27156 8.10419M6.02009 18.6459L3.26862 15.8959M6.02009 18.6459L8.76862 15.8959" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"></path><path d="M13.6112 13.2205H18.9513M11.8311 17.481L15.633 7.47121C15.839 6.92904 15.9419 6.65795 16.0846 6.57385C16.2086 6.50077 16.3539 6.50077 16.4779 6.57385C16.6206 6.65795 16.7235 6.92904 16.9295 7.47121L20.7314 17.481" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
|
|
22
24
|
|
|
23
25
|
function makeSep() {
|
|
24
26
|
const d = document.createElement('div');
|
|
@@ -57,6 +59,7 @@ function makeListButtons() {
|
|
|
57
59
|
triggerBtn.innerHTML = SVG_LIST_BULLET;
|
|
58
60
|
|
|
59
61
|
const modal = document.createElement('div');
|
|
62
|
+
modal.id = `tpp-list-modal-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
|
60
63
|
modal.className = 'tpp-list-modal';
|
|
61
64
|
modal.style.display = 'none';
|
|
62
65
|
|
|
@@ -161,6 +164,7 @@ function makeAlignButtons() {
|
|
|
161
164
|
|
|
162
165
|
// Модальный попап
|
|
163
166
|
const modal = document.createElement('div');
|
|
167
|
+
modal.id = `tpp-align-modal-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
|
164
168
|
modal.className = 'tpp-align-modal';
|
|
165
169
|
modal.style.display = 'none';
|
|
166
170
|
|
|
@@ -248,33 +252,86 @@ function makeAlignButtons() {
|
|
|
248
252
|
return proxy;
|
|
249
253
|
}
|
|
250
254
|
|
|
251
|
-
|
|
252
|
-
|
|
255
|
+
function makeFormatButtons(panelInstance) {
|
|
256
|
+
const container = document.createElement('div');
|
|
257
|
+
container.className = 'tpp-format-btns-wrapper';
|
|
258
|
+
container.style.position = 'relative';
|
|
259
|
+
container.style.display = 'flex';
|
|
260
|
+
|
|
261
|
+
const triggerBtn = document.createElement('button');
|
|
262
|
+
triggerBtn.type = 'button';
|
|
263
|
+
triggerBtn.title = 'Форматирование текста';
|
|
264
|
+
triggerBtn.className = 'tpp-format-btn tpp-format-trigger';
|
|
265
|
+
triggerBtn.innerHTML = SVG_TEXT_FORMAT;
|
|
266
|
+
|
|
267
|
+
const modal = document.createElement('div');
|
|
268
|
+
modal.id = `tpp-format-modal-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
|
|
269
|
+
modal.className = 'tpp-format-modal';
|
|
270
|
+
modal.style.display = 'none';
|
|
253
271
|
|
|
254
272
|
panelInstance.boldBtn = makeToggleBtn(SVG_BOLD, 'Жирный', 'bold');
|
|
255
273
|
panelInstance.italicBtn = makeToggleBtn(SVG_ITALIC, 'Курсив', 'italic');
|
|
256
274
|
panelInstance.underlineBtn = makeToggleBtn(SVG_UNDERLINE, 'Подчёркнутый', 'underline');
|
|
257
275
|
panelInstance.strikethroughBtn = makeToggleBtn(SVG_STRIKE, 'Зачёркнутый', 'strikethrough');
|
|
258
276
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
277
|
+
const btns = [
|
|
278
|
+
panelInstance.boldBtn,
|
|
279
|
+
panelInstance.italicBtn,
|
|
280
|
+
panelInstance.underlineBtn,
|
|
281
|
+
panelInstance.strikethroughBtn
|
|
282
|
+
];
|
|
262
283
|
|
|
263
|
-
|
|
284
|
+
btns.forEach((btn) => {
|
|
285
|
+
btn.classList.add('tpp-format-modal-option');
|
|
286
|
+
modal.appendChild(btn);
|
|
287
|
+
});
|
|
264
288
|
|
|
265
|
-
|
|
266
|
-
|
|
289
|
+
container.appendChild(triggerBtn);
|
|
290
|
+
container.appendChild(modal);
|
|
267
291
|
|
|
268
|
-
|
|
269
|
-
|
|
292
|
+
function openModal() {
|
|
293
|
+
modal.style.display = 'flex';
|
|
294
|
+
setTimeout(() => {
|
|
295
|
+
document.addEventListener('click', closeOnOutside);
|
|
296
|
+
}, 0);
|
|
297
|
+
}
|
|
270
298
|
|
|
271
|
-
|
|
299
|
+
function closeModal() {
|
|
300
|
+
modal.style.display = 'none';
|
|
301
|
+
document.removeEventListener('click', closeOnOutside);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function closeOnOutside(e) {
|
|
305
|
+
if (!container.contains(e.target)) {
|
|
306
|
+
closeModal();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
triggerBtn.addEventListener('click', (e) => {
|
|
311
|
+
e.stopPropagation();
|
|
312
|
+
if (modal.style.display === 'none') {
|
|
313
|
+
openModal();
|
|
314
|
+
} else {
|
|
315
|
+
closeModal();
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
return container;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function makeLineHeightControl(panelInstance) {
|
|
323
|
+
const container = document.createElement('div');
|
|
324
|
+
container.className = 'tpp-lh-control';
|
|
325
|
+
|
|
326
|
+
const triggerBtn = document.createElement('button');
|
|
327
|
+
triggerBtn.type = 'button';
|
|
328
|
+
triggerBtn.title = 'Межстрочный интервал';
|
|
329
|
+
triggerBtn.className = 'tpp-format-btn';
|
|
330
|
+
triggerBtn.innerHTML = SVG_LINE_HEIGHT;
|
|
272
331
|
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
lhLabel.textContent = '↕';
|
|
277
|
-
panel.appendChild(lhLabel);
|
|
332
|
+
const modal = document.createElement('div');
|
|
333
|
+
modal.className = 'tpp-lh-modal';
|
|
334
|
+
modal.style.display = 'none';
|
|
278
335
|
|
|
279
336
|
panelInstance.lineHeightSlider = document.createElement('input');
|
|
280
337
|
panelInstance.lineHeightSlider.type = 'range';
|
|
@@ -283,5 +340,59 @@ export function createTextFormatControls(panelInstance, panel) {
|
|
|
283
340
|
panelInstance.lineHeightSlider.max = String(LINE_HEIGHT_MAX);
|
|
284
341
|
panelInstance.lineHeightSlider.step = String(LINE_HEIGHT_STEP);
|
|
285
342
|
panelInstance.lineHeightSlider.value = String(LINE_HEIGHT_DEFAULT);
|
|
286
|
-
|
|
343
|
+
|
|
344
|
+
modal.appendChild(panelInstance.lineHeightSlider);
|
|
345
|
+
container.appendChild(triggerBtn);
|
|
346
|
+
container.appendChild(modal);
|
|
347
|
+
|
|
348
|
+
function openModal() {
|
|
349
|
+
modal.style.display = 'flex';
|
|
350
|
+
triggerBtn.classList.add('is-active');
|
|
351
|
+
setTimeout(() => {
|
|
352
|
+
document.addEventListener('click', closeOnOutside);
|
|
353
|
+
}, 0);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function closeModal() {
|
|
357
|
+
modal.style.display = 'none';
|
|
358
|
+
triggerBtn.classList.remove('is-active');
|
|
359
|
+
document.removeEventListener('click', closeOnOutside);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function closeOnOutside(e) {
|
|
363
|
+
if (!container.contains(e.target)) {
|
|
364
|
+
closeModal();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
triggerBtn.addEventListener('click', (e) => {
|
|
369
|
+
e.stopPropagation();
|
|
370
|
+
if (modal.style.display === 'none') {
|
|
371
|
+
openModal();
|
|
372
|
+
} else {
|
|
373
|
+
closeModal();
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
return container;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export function createTextFormatControls(panelInstance, panel) {
|
|
381
|
+
panel.appendChild(makeSep());
|
|
382
|
+
|
|
383
|
+
const formatButtonsWrapper = makeFormatButtons(panelInstance);
|
|
384
|
+
panel.appendChild(formatButtonsWrapper);
|
|
385
|
+
|
|
386
|
+
panelInstance.alignControl = makeAlignButtons();
|
|
387
|
+
panel.appendChild(panelInstance.alignControl._container);
|
|
388
|
+
|
|
389
|
+
panelInstance.listControl = makeListButtons();
|
|
390
|
+
panel.appendChild(panelInstance.listControl._container);
|
|
391
|
+
|
|
392
|
+
panel.appendChild(makeSep());
|
|
393
|
+
|
|
394
|
+
const lhControl = makeLineHeightControl(panelInstance);
|
|
395
|
+
panel.appendChild(lhControl);
|
|
396
|
+
|
|
397
|
+
panel.appendChild(makeSep());
|
|
287
398
|
}
|