react-text-forge 1.2.11 → 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.
- package/dist/react-text-forge.css +1 -1
- package/dist/react-text-forge.js +201 -122
- package/dist/react-text-forge.umd.cjs +9 -9
- package/dist/src/components/functions/deserialize.d.ts +6 -1
- package/dist/src/components/functions/serialize.d.ts +6 -1
- package/dist/src/components/useToolbar.d.ts +2 -1
- package/dist/src/components/utils/CustomEditor.d.ts +142 -130
- package/dist/src/components/utils/Images.d.ts +1 -1
- package/dist/src/components/utils/Tooltip.d.ts +1 -1
- package/dist/src/components/utils/dropdown/ContainerDropdown.d.ts +2 -6
- package/dist/src/components/utils/dropdown/{TableDropdown.d.ts → TableButtons.d.ts} +2 -2
- package/dist/src/components/utils/elements/BlockquoteElement.d.ts +1 -1
- package/dist/src/components/utils/elements/CodeElement.d.ts +1 -1
- package/dist/src/components/utils/elements/DefaultElement.d.ts +1 -1
- package/dist/src/components/utils/elements/ListElement.d.ts +1 -1
- package/dist/src/components/utils/form/BulletTypeSelector.d.ts +3 -3
- package/dist/src/components/utils/form/NumeredTypeSelector.d.ts +3 -3
- package/dist/types/react-text-forge.d.ts +90 -0
- package/package.json +4 -1
package/dist/react-text-forge.js
CHANGED
|
@@ -879,7 +879,7 @@ const CodeElement = ({ attributes, children, element }) => {
|
|
|
879
879
|
const CustomEditor = {
|
|
880
880
|
/**
|
|
881
881
|
* Permet de définir si le format défini est actif
|
|
882
|
-
* @param {
|
|
882
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
883
883
|
* @param {string} format - format défini (ex: gras, italique, etc...)
|
|
884
884
|
* @returns {boolean}
|
|
885
885
|
*/
|
|
@@ -889,7 +889,7 @@ const CustomEditor = {
|
|
|
889
889
|
},
|
|
890
890
|
/**
|
|
891
891
|
* Permet de gérer l'application et la désapplication du format défini
|
|
892
|
-
* @param {
|
|
892
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
893
893
|
* @param {string} format - format défini (ex: gras, italique, etc...)
|
|
894
894
|
* @returns {void}
|
|
895
895
|
*/
|
|
@@ -908,7 +908,7 @@ const CustomEditor = {
|
|
|
908
908
|
},
|
|
909
909
|
/**
|
|
910
910
|
* Permet de définir si le bloc défini est actif
|
|
911
|
-
* @param {
|
|
911
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
912
912
|
* @param {string} blockType - élément défini (ex: p, h1, h2...)
|
|
913
913
|
* @returns {boolean}
|
|
914
914
|
*/
|
|
@@ -920,7 +920,7 @@ const CustomEditor = {
|
|
|
920
920
|
},
|
|
921
921
|
/**
|
|
922
922
|
* Permet de définir si le bloc défini est dans une liste à puces (non-ordonnée ou numérotée)
|
|
923
|
-
* @param {
|
|
923
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
924
924
|
* @returns {boolean}
|
|
925
925
|
*/
|
|
926
926
|
isSelectionInList(editor) {
|
|
@@ -931,7 +931,7 @@ const CustomEditor = {
|
|
|
931
931
|
},
|
|
932
932
|
/**
|
|
933
933
|
* Permet de définir la puce utilisée dans une liste à puces (non-ordonnée ou numérotée)
|
|
934
|
-
* @param {
|
|
934
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
935
935
|
* @returns {string}
|
|
936
936
|
*/
|
|
937
937
|
getListStyleType(editor) {
|
|
@@ -940,9 +940,31 @@ const CustomEditor = {
|
|
|
940
940
|
});
|
|
941
941
|
return match[0].listStyleType;
|
|
942
942
|
},
|
|
943
|
+
/**
|
|
944
|
+
* Permet de récupérer le type de bloc utilisé
|
|
945
|
+
* @param {Editor} editor
|
|
946
|
+
* @param {Range | Point | null} selection
|
|
947
|
+
*/
|
|
948
|
+
getCurrentBlock(editor, selection) {
|
|
949
|
+
if (!selection) {
|
|
950
|
+
return null;
|
|
951
|
+
}
|
|
952
|
+
const [currentNodeEntry] = Editor.nodes(editor, {
|
|
953
|
+
match: (node) => {
|
|
954
|
+
return Element$1.isElement(node);
|
|
955
|
+
},
|
|
956
|
+
// Limiter la recherche au chemin de la sélection
|
|
957
|
+
at: selection
|
|
958
|
+
});
|
|
959
|
+
if (currentNodeEntry) {
|
|
960
|
+
const [node] = currentNodeEntry;
|
|
961
|
+
return node.type;
|
|
962
|
+
}
|
|
963
|
+
return null;
|
|
964
|
+
},
|
|
943
965
|
/**
|
|
944
966
|
* Permet de gérer l'application et la désapplication du bloc défini
|
|
945
|
-
* @param {
|
|
967
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
946
968
|
* @param {string} blockType - format défini (ex: gras, italique, etc...)
|
|
947
969
|
* @param {string} bulletType - puces définies dans
|
|
948
970
|
* @returns {void}
|
|
@@ -989,7 +1011,7 @@ const CustomEditor = {
|
|
|
989
1011
|
},
|
|
990
1012
|
/**
|
|
991
1013
|
* Permet de définir si le bloc défini possède un alignement
|
|
992
|
-
* @param {
|
|
1014
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
993
1015
|
* @param {string} align - alignement défini (ex: left, right ou center.)
|
|
994
1016
|
* @returns {boolean}
|
|
995
1017
|
*/
|
|
@@ -1001,7 +1023,7 @@ const CustomEditor = {
|
|
|
1001
1023
|
},
|
|
1002
1024
|
/**
|
|
1003
1025
|
* Permet de gérer l'alignement du bloc sélectionné
|
|
1004
|
-
* @param {
|
|
1026
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1005
1027
|
* @param {string} alignement - alignement défini (ex: left, right ou center)
|
|
1006
1028
|
* @returns {void}
|
|
1007
1029
|
*/
|
|
@@ -1016,7 +1038,7 @@ const CustomEditor = {
|
|
|
1016
1038
|
},
|
|
1017
1039
|
/**
|
|
1018
1040
|
* Permet de définir si le bloc sélectionné peut être indenté
|
|
1019
|
-
* @param {
|
|
1041
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1020
1042
|
* @param {string} mark - indentation sélectionné
|
|
1021
1043
|
* @returns {boolean}
|
|
1022
1044
|
*/
|
|
@@ -1041,7 +1063,7 @@ const CustomEditor = {
|
|
|
1041
1063
|
},
|
|
1042
1064
|
/**
|
|
1043
1065
|
* Permet de gérer l'indentation du bloc sélectionné
|
|
1044
|
-
* @param {
|
|
1066
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1045
1067
|
* @returns {void}
|
|
1046
1068
|
*/
|
|
1047
1069
|
handleIndent(editor) {
|
|
@@ -1074,7 +1096,7 @@ const CustomEditor = {
|
|
|
1074
1096
|
},
|
|
1075
1097
|
/**
|
|
1076
1098
|
* Permet de gérer l'désindentation du bloc sélectionné
|
|
1077
|
-
* @param {
|
|
1099
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1078
1100
|
* @returns {void}
|
|
1079
1101
|
*/
|
|
1080
1102
|
handleOutdent(editor) {
|
|
@@ -1106,7 +1128,7 @@ const CustomEditor = {
|
|
|
1106
1128
|
},
|
|
1107
1129
|
/**
|
|
1108
1130
|
* Permet de définir si le bloc sélectionné est un lien
|
|
1109
|
-
* @param {
|
|
1131
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1110
1132
|
* @returns {boolean}
|
|
1111
1133
|
*/
|
|
1112
1134
|
isLinkActive(editor) {
|
|
@@ -1119,7 +1141,7 @@ const CustomEditor = {
|
|
|
1119
1141
|
},
|
|
1120
1142
|
/**
|
|
1121
1143
|
* Permet de ajouter ou mettre à jour un lien
|
|
1122
|
-
* @param {
|
|
1144
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1123
1145
|
* @param {string} url - url défini
|
|
1124
1146
|
* @param {string} openInNewTab - attribut pour définir si le lien ouvre dans un nouvel onglet
|
|
1125
1147
|
* @returns {void}
|
|
@@ -1159,7 +1181,7 @@ const CustomEditor = {
|
|
|
1159
1181
|
},
|
|
1160
1182
|
/**
|
|
1161
1183
|
* Permet de supprimer le lien
|
|
1162
|
-
* @param {
|
|
1184
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1163
1185
|
* @returns {void}
|
|
1164
1186
|
*/
|
|
1165
1187
|
removeLink(editor) {
|
|
@@ -1185,7 +1207,7 @@ const CustomEditor = {
|
|
|
1185
1207
|
},
|
|
1186
1208
|
/**
|
|
1187
1209
|
* Permet de gérer la couleur de fond du bloc sélectionné
|
|
1188
|
-
* @param {
|
|
1210
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1189
1211
|
* @param {string} coulor - couleur définie
|
|
1190
1212
|
* @returns {void}
|
|
1191
1213
|
*/
|
|
@@ -1197,7 +1219,7 @@ const CustomEditor = {
|
|
|
1197
1219
|
},
|
|
1198
1220
|
/**
|
|
1199
1221
|
* Permet de gérer la couleur de texte du bloc sélectionné
|
|
1200
|
-
* @param {
|
|
1222
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1201
1223
|
* @param {string} coulor - couleur définie
|
|
1202
1224
|
* @returns {void}
|
|
1203
1225
|
*/
|
|
@@ -1209,7 +1231,7 @@ const CustomEditor = {
|
|
|
1209
1231
|
},
|
|
1210
1232
|
/**
|
|
1211
1233
|
* Permet de gérer la taille de police bloc sélectionné
|
|
1212
|
-
* @param {
|
|
1234
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1213
1235
|
* @param {string} size - taille définie
|
|
1214
1236
|
* @returns {void}
|
|
1215
1237
|
*/
|
|
@@ -1221,7 +1243,7 @@ const CustomEditor = {
|
|
|
1221
1243
|
},
|
|
1222
1244
|
/**
|
|
1223
1245
|
* Permet de gérer la police d'écriture bloc sélectionné
|
|
1224
|
-
* @param {
|
|
1246
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1225
1247
|
* @param {string} fontFamily - police définie
|
|
1226
1248
|
* @returns {void}
|
|
1227
1249
|
*/
|
|
@@ -1234,7 +1256,7 @@ const CustomEditor = {
|
|
|
1234
1256
|
/**
|
|
1235
1257
|
* Permet de vérifier si la sélection se situe dans un code
|
|
1236
1258
|
*
|
|
1237
|
-
* @param {
|
|
1259
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1238
1260
|
* @returns {boolean}
|
|
1239
1261
|
*/
|
|
1240
1262
|
isSelectionInCode(editor) {
|
|
@@ -1246,7 +1268,7 @@ const CustomEditor = {
|
|
|
1246
1268
|
/**
|
|
1247
1269
|
* Permet de récupérer le langage actuel
|
|
1248
1270
|
*
|
|
1249
|
-
* @param {
|
|
1271
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1250
1272
|
* @returns {boolean}
|
|
1251
1273
|
*/
|
|
1252
1274
|
getCurrentCodeLanguage(editor) {
|
|
@@ -1257,7 +1279,7 @@ const CustomEditor = {
|
|
|
1257
1279
|
},
|
|
1258
1280
|
/**
|
|
1259
1281
|
* Gère l'ajout, l'édition et la suppression d'un bloc de code
|
|
1260
|
-
* @param {
|
|
1282
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1261
1283
|
* @param {string} language - langage défini (ex: cpp(C++), php, etc...)
|
|
1262
1284
|
* @returns {void}
|
|
1263
1285
|
*/
|
|
@@ -1329,7 +1351,7 @@ const CustomEditor = {
|
|
|
1329
1351
|
/**
|
|
1330
1352
|
* Insère un bloc de code
|
|
1331
1353
|
*
|
|
1332
|
-
* @param {
|
|
1354
|
+
* @param {ReactEditor} editor
|
|
1333
1355
|
* @param {string} text
|
|
1334
1356
|
* @return {void}
|
|
1335
1357
|
*/
|
|
@@ -1352,7 +1374,7 @@ const CustomEditor = {
|
|
|
1352
1374
|
},
|
|
1353
1375
|
/**
|
|
1354
1376
|
* Permet de gérer les images
|
|
1355
|
-
* @param {
|
|
1377
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1356
1378
|
* @param {string} url - url définie
|
|
1357
1379
|
* @returns {void}
|
|
1358
1380
|
*/
|
|
@@ -1372,7 +1394,7 @@ const CustomEditor = {
|
|
|
1372
1394
|
/**
|
|
1373
1395
|
* Permet de gérer l'upload d'un fichier
|
|
1374
1396
|
* @param {Event} event
|
|
1375
|
-
* @param {
|
|
1397
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1376
1398
|
* @returns {void}
|
|
1377
1399
|
*/
|
|
1378
1400
|
handleFileChange(event, editor) {
|
|
@@ -1426,7 +1448,7 @@ const CustomEditor = {
|
|
|
1426
1448
|
},
|
|
1427
1449
|
/**
|
|
1428
1450
|
* Permet de créer un tableau
|
|
1429
|
-
* @param {
|
|
1451
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1430
1452
|
* @param {number} rows - nombre de lignes
|
|
1431
1453
|
* @param {number} columns - nombre de colonnes
|
|
1432
1454
|
* @returns {void}
|
|
@@ -1446,7 +1468,7 @@ const CustomEditor = {
|
|
|
1446
1468
|
},
|
|
1447
1469
|
/**
|
|
1448
1470
|
* Permet de définir si l'élément sélectionné est dans un tableau
|
|
1449
|
-
* @param {
|
|
1471
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1450
1472
|
* @returns {boolean}
|
|
1451
1473
|
*/
|
|
1452
1474
|
isSelectionInTable(editor) {
|
|
@@ -1457,7 +1479,7 @@ const CustomEditor = {
|
|
|
1457
1479
|
},
|
|
1458
1480
|
/**
|
|
1459
1481
|
* Permet d'obtenir le tableau sélectionné
|
|
1460
|
-
* @param {
|
|
1482
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1461
1483
|
* @returns {void}
|
|
1462
1484
|
*/
|
|
1463
1485
|
getTableFromSelection(editor) {
|
|
@@ -1468,7 +1490,7 @@ const CustomEditor = {
|
|
|
1468
1490
|
},
|
|
1469
1491
|
/**
|
|
1470
1492
|
* Permet d'ajouter une ligne au tableau sélectionné
|
|
1471
|
-
* @param {
|
|
1493
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1472
1494
|
* @returns {void}
|
|
1473
1495
|
*/
|
|
1474
1496
|
addRow(editor) {
|
|
@@ -1493,7 +1515,7 @@ const CustomEditor = {
|
|
|
1493
1515
|
},
|
|
1494
1516
|
/**
|
|
1495
1517
|
* Permet d'ajouter une colonne au tableau sélectionné
|
|
1496
|
-
* @param {
|
|
1518
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1497
1519
|
* @returns {void}
|
|
1498
1520
|
*/
|
|
1499
1521
|
addColumn(editor) {
|
|
@@ -1530,7 +1552,7 @@ const CustomEditor = {
|
|
|
1530
1552
|
},
|
|
1531
1553
|
/**
|
|
1532
1554
|
* Permet de supprimer une ligne du tableau sélectionné
|
|
1533
|
-
* @param {
|
|
1555
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1534
1556
|
* @returns {void}
|
|
1535
1557
|
*/
|
|
1536
1558
|
deleteRow(editor) {
|
|
@@ -1552,7 +1574,7 @@ const CustomEditor = {
|
|
|
1552
1574
|
},
|
|
1553
1575
|
/**
|
|
1554
1576
|
* Permet de supprimer une colonne du tableau sélectionné
|
|
1555
|
-
* @param {
|
|
1577
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1556
1578
|
* @returns {void}
|
|
1557
1579
|
*/
|
|
1558
1580
|
deleteColumn(editor) {
|
|
@@ -1588,7 +1610,7 @@ const CustomEditor = {
|
|
|
1588
1610
|
},
|
|
1589
1611
|
/**
|
|
1590
1612
|
* Permet de supprimer le tableau sélectionné
|
|
1591
|
-
* @param {
|
|
1613
|
+
* @param {ReactEditor} editor - éditeur de texte
|
|
1592
1614
|
* @returns {void}
|
|
1593
1615
|
*/
|
|
1594
1616
|
deleteTable(editor) {
|
|
@@ -1734,6 +1756,7 @@ const ListElement = ({ attributes, children, element }) => {
|
|
|
1734
1756
|
textAlign: element.align || "left",
|
|
1735
1757
|
listStyleType: element.listStyleType || "disc"
|
|
1736
1758
|
};
|
|
1759
|
+
console.log(element.type);
|
|
1737
1760
|
switch (element.type) {
|
|
1738
1761
|
case "bullet-list":
|
|
1739
1762
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "rtf", style, ...attributes, children });
|
|
@@ -1841,6 +1864,7 @@ const ThemeProvider = ({ showTheme, backgroundDarkColor, borderDarkColor, imageD
|
|
|
1841
1864
|
const useTheme = () => useContext(ThemeContext);
|
|
1842
1865
|
const ReactTextForgeContext = createContext();
|
|
1843
1866
|
const ReactTextForgeProvider = ({ backgroundColor, borderColor, imageColor, editor, children }) => {
|
|
1867
|
+
const [dropdownActive, setDropdownActive] = useState(null);
|
|
1844
1868
|
const { showTheme, isDarkTheme, backgroundDarkColor, borderDarkColor, imageDarkColor } = useTheme();
|
|
1845
1869
|
const resolvedBackgroundColor = showTheme && isDarkTheme ? backgroundDarkColor : backgroundColor;
|
|
1846
1870
|
const resolvedBorderColor = showTheme && isDarkTheme ? borderDarkColor : borderColor;
|
|
@@ -1850,12 +1874,20 @@ const ReactTextForgeProvider = ({ backgroundColor, borderColor, imageColor, edit
|
|
|
1850
1874
|
document.documentElement.style.setProperty("--border-color", resolvedBorderColor);
|
|
1851
1875
|
document.documentElement.style.setProperty("--image-color", resolvedImageColor);
|
|
1852
1876
|
}, [resolvedBackgroundColor, resolvedBorderColor, resolvedImageColor]);
|
|
1853
|
-
|
|
1877
|
+
const value = {
|
|
1878
|
+
backgroundColor: resolvedBackgroundColor,
|
|
1879
|
+
borderColor: resolvedBorderColor,
|
|
1880
|
+
editor,
|
|
1881
|
+
imageColor: resolvedImageColor,
|
|
1882
|
+
dropdownActive,
|
|
1883
|
+
setDropdownActive
|
|
1884
|
+
};
|
|
1885
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(ReactTextForgeContext.Provider, { value, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rtf react-text-forge", style: { backgroundColor: resolvedBackgroundColor, borderColor: resolvedBorderColor }, children }) });
|
|
1854
1886
|
};
|
|
1855
1887
|
const useReactTextForgeContext = () => {
|
|
1856
1888
|
return useContext(ReactTextForgeContext);
|
|
1857
1889
|
};
|
|
1858
|
-
const BulletTypeSelector = ({ onChange, selectStyle,
|
|
1890
|
+
const BulletTypeSelector = ({ onChange, selectStyle, onClose }) => {
|
|
1859
1891
|
const bulletTypes = [
|
|
1860
1892
|
{ value: "disc", label: "Disque" },
|
|
1861
1893
|
{ value: "circle", label: "Cercle" },
|
|
@@ -1866,7 +1898,7 @@ const BulletTypeSelector = ({ onChange, selectStyle, toggleForm }) => {
|
|
|
1866
1898
|
{ value: "'➔'", label: "Flèche épaisse" }
|
|
1867
1899
|
];
|
|
1868
1900
|
const { editor } = useReactTextForgeContext();
|
|
1869
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { onMouseLeave:
|
|
1901
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { onMouseLeave: onClose, style: selectStyle, className: "rtf dropdown-menu", children: bulletTypes.map((type) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1870
1902
|
"li",
|
|
1871
1903
|
{
|
|
1872
1904
|
value: type.value,
|
|
@@ -1877,7 +1909,7 @@ const BulletTypeSelector = ({ onChange, selectStyle, toggleForm }) => {
|
|
|
1877
1909
|
type.value
|
|
1878
1910
|
)) });
|
|
1879
1911
|
};
|
|
1880
|
-
const NumeredTypeSelector = ({ onChange, selectStyle,
|
|
1912
|
+
const NumeredTypeSelector = ({ onChange, selectStyle, onClose }) => {
|
|
1881
1913
|
const numeredTypes = [
|
|
1882
1914
|
{ value: "decimal", label: "Décimal" },
|
|
1883
1915
|
{ value: "upper-roman", label: "Lettres Romaines majuscules" },
|
|
@@ -1886,7 +1918,7 @@ const NumeredTypeSelector = ({ onChange, selectStyle, toggleForm }) => {
|
|
|
1886
1918
|
{ value: "lower-greek", label: "Lettres Grecques minuscules" }
|
|
1887
1919
|
];
|
|
1888
1920
|
const { editor } = useReactTextForgeContext();
|
|
1889
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { onMouseLeave:
|
|
1921
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { onMouseLeave: onClose, style: selectStyle, className: "rtf dropdown-menu", children: numeredTypes.map((type) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1890
1922
|
"li",
|
|
1891
1923
|
{
|
|
1892
1924
|
value: type.value,
|
|
@@ -2003,15 +2035,21 @@ function Images({ format, imageColor }) {
|
|
|
2003
2035
|
return returnImage();
|
|
2004
2036
|
}
|
|
2005
2037
|
const BlockListDropdown = ({ format, isActive, onMouseDown }) => {
|
|
2006
|
-
const { backgroundColor, editor, imageColor } = useReactTextForgeContext();
|
|
2007
|
-
const [showBulletOptions, setShowBulletOptions] = useState(false);
|
|
2038
|
+
const { backgroundColor, editor, imageColor, dropdownActive, setDropdownActive } = useReactTextForgeContext();
|
|
2008
2039
|
const selectStyle = {
|
|
2009
2040
|
backgroundColor,
|
|
2010
2041
|
color: imageColor
|
|
2011
2042
|
};
|
|
2012
2043
|
const handleBulletTypeChange = (bulletType) => {
|
|
2013
2044
|
CustomEditor.toggleBlock(editor, format === "bulletList" ? "bullet-list" : "numbered-list", bulletType);
|
|
2014
|
-
|
|
2045
|
+
setDropdownActive(null);
|
|
2046
|
+
};
|
|
2047
|
+
const toggleDropDown = () => {
|
|
2048
|
+
if (dropdownActive !== format) {
|
|
2049
|
+
setDropdownActive(format);
|
|
2050
|
+
} else {
|
|
2051
|
+
setDropdownActive(null);
|
|
2052
|
+
}
|
|
2015
2053
|
};
|
|
2016
2054
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2017
2055
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -2028,42 +2066,47 @@ const BlockListDropdown = ({ format, isActive, onMouseDown }) => {
|
|
|
2028
2066
|
{
|
|
2029
2067
|
className: "rtf tool tool--arrow",
|
|
2030
2068
|
style: { color: selectStyle.color },
|
|
2031
|
-
onClick:
|
|
2032
|
-
children:
|
|
2069
|
+
onClick: toggleDropDown,
|
|
2070
|
+
children: dropdownActive === format ? "↑" : "↓"
|
|
2033
2071
|
}
|
|
2034
2072
|
)
|
|
2035
2073
|
]
|
|
2036
2074
|
}
|
|
2037
2075
|
),
|
|
2038
|
-
|
|
2076
|
+
dropdownActive === "bulletList" && format === "bulletList" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2039
2077
|
BulletTypeSelector,
|
|
2040
2078
|
{
|
|
2041
2079
|
selectStyle,
|
|
2042
2080
|
onChange: handleBulletTypeChange,
|
|
2043
|
-
|
|
2081
|
+
onClose: () => setDropdownActive(null)
|
|
2044
2082
|
}
|
|
2045
|
-
)
|
|
2083
|
+
),
|
|
2084
|
+
dropdownActive === "numberedList" && format === "numberedList" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2046
2085
|
NumeredTypeSelector,
|
|
2047
2086
|
{
|
|
2048
2087
|
selectStyle,
|
|
2049
2088
|
onChange: handleBulletTypeChange,
|
|
2050
|
-
|
|
2089
|
+
onClose: () => setDropdownActive(null)
|
|
2051
2090
|
}
|
|
2052
|
-
)
|
|
2091
|
+
)
|
|
2053
2092
|
] });
|
|
2054
2093
|
};
|
|
2055
|
-
function ContainerDropdown({ disabled = false, elements, elementSelected, format,
|
|
2056
|
-
const { backgroundColor, imageColor } = useReactTextForgeContext();
|
|
2094
|
+
function ContainerDropdown({ disabled = false, elements, elementSelected, format, onClick }) {
|
|
2095
|
+
const { backgroundColor, imageColor, dropdownActive, setDropdownActive } = useReactTextForgeContext();
|
|
2057
2096
|
const toggleForm = () => {
|
|
2058
|
-
|
|
2097
|
+
if (dropdownActive !== null && dropdownActive === format) {
|
|
2098
|
+
setDropdownActive(null);
|
|
2099
|
+
} else {
|
|
2100
|
+
setDropdownActive(format);
|
|
2101
|
+
}
|
|
2059
2102
|
};
|
|
2060
2103
|
const selectElement = (element) => {
|
|
2061
2104
|
onClick(element);
|
|
2062
|
-
|
|
2105
|
+
setDropdownActive(null);
|
|
2063
2106
|
};
|
|
2064
2107
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rtf dropdown tool", children: [
|
|
2065
2108
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: toggleForm, className: "rtf dropdown-toggle", disabled, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format, imageColor }) }),
|
|
2066
|
-
|
|
2109
|
+
dropdownActive === format && /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { style: { backgroundColor, color: imageColor }, className: "rtf dropdown-menu", onMouseLeave: toggleForm, children: elements.map((element, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2067
2110
|
"li",
|
|
2068
2111
|
{
|
|
2069
2112
|
style: { backgroundColor: `${elementSelected && element === elementSelected ? `color-mix(in srgb, ${backgroundColor} 80%, ${isDarkColor(backgroundColor) ? "white" : "black"})` : backgroundColor}` },
|
|
@@ -2075,7 +2118,6 @@ function ContainerDropdown({ disabled = false, elements, elementSelected, format
|
|
|
2075
2118
|
] });
|
|
2076
2119
|
}
|
|
2077
2120
|
const FontSizeDropdown = ({ disabled, sizeSelected, onSelectSize }) => {
|
|
2078
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
2079
2121
|
const fontSizes = ["10px", "12px", "14px", "16px", "18px", "20px", "24px", "28px", "36px"];
|
|
2080
2122
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2081
2123
|
ContainerDropdown,
|
|
@@ -2084,14 +2126,11 @@ const FontSizeDropdown = ({ disabled, sizeSelected, onSelectSize }) => {
|
|
|
2084
2126
|
elements: fontSizes,
|
|
2085
2127
|
elementSelected: sizeSelected,
|
|
2086
2128
|
format: "size",
|
|
2087
|
-
isOpen,
|
|
2088
|
-
setIsOpen,
|
|
2089
2129
|
onClick: onSelectSize
|
|
2090
2130
|
}
|
|
2091
2131
|
);
|
|
2092
2132
|
};
|
|
2093
2133
|
const FontFamilyDropdown = ({ fontFamilySelected, onSelectFontFamily }) => {
|
|
2094
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
2095
2134
|
const fontFamilies = ["Arial", "Arial Black", "Bookman", "Comic Sans MS", "Courier", "Courier New", "Garamond", "Georgia", "Helvetica", "Impact", "Palatino", "Times", "Times New Roman", "Trebuchet MS", "Verdana"];
|
|
2096
2135
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2097
2136
|
ContainerDropdown,
|
|
@@ -2099,8 +2138,6 @@ const FontFamilyDropdown = ({ fontFamilySelected, onSelectFontFamily }) => {
|
|
|
2099
2138
|
elements: fontFamilies,
|
|
2100
2139
|
elementSelected: fontFamilySelected,
|
|
2101
2140
|
format: "fontFamily",
|
|
2102
|
-
isOpen,
|
|
2103
|
-
setIsOpen,
|
|
2104
2141
|
onClick: onSelectFontFamily
|
|
2105
2142
|
}
|
|
2106
2143
|
);
|
|
@@ -2207,29 +2244,21 @@ const LinkForm = ({ onClose, initialUrl = "", isOpenInNewTab }) => {
|
|
|
2207
2244
|
*
|
|
2208
2245
|
* For any questions or suggestions, please contact: administrateur@nhumeria.fr
|
|
2209
2246
|
*/
|
|
2210
|
-
function useToolbar(editor) {
|
|
2247
|
+
function useToolbar(editor, setDropdownActive) {
|
|
2211
2248
|
const [selectedLink, setSelectedLink] = useState("");
|
|
2212
2249
|
const [colorMode, setColorMode] = useState("");
|
|
2213
2250
|
const [openInNewTab, setOpenInNewTab] = useState(false);
|
|
2214
2251
|
const [selectedColor, setSelectedColor] = useState("");
|
|
2215
2252
|
const [selectedBackgroundColor, setSelectedBackgroundColor] = useState("");
|
|
2216
2253
|
const [activeBlock, setActiveBlock] = useState("paragraph");
|
|
2217
|
-
const [showColorPicker, setShowColorPicker] = useState(false);
|
|
2218
2254
|
const [selectedLanguage, setSelectedLanguage] = useState("");
|
|
2219
|
-
const [showLinkForm, setShowLinkForm] = useState(false);
|
|
2220
|
-
const toggleLinkForm = () => {
|
|
2221
|
-
setShowLinkForm(!showLinkForm);
|
|
2222
|
-
};
|
|
2223
|
-
const toggleColorPicker = () => {
|
|
2224
|
-
setShowColorPicker(!showColorPicker);
|
|
2225
|
-
};
|
|
2226
2255
|
const handleColorChange = (color) => {
|
|
2227
2256
|
CustomEditor.applyTextColor(editor, color);
|
|
2228
|
-
|
|
2257
|
+
setDropdownActive(null);
|
|
2229
2258
|
};
|
|
2230
2259
|
const handleBackgroundColorChange = (color) => {
|
|
2231
2260
|
CustomEditor.applyBackgroundTextColor(editor, color);
|
|
2232
|
-
|
|
2261
|
+
setDropdownActive(null);
|
|
2233
2262
|
};
|
|
2234
2263
|
const handleBlockTypeChange = (blockType) => {
|
|
2235
2264
|
CustomEditor.toggleBlock(editor, blockType);
|
|
@@ -2250,6 +2279,7 @@ function useToolbar(editor) {
|
|
|
2250
2279
|
};
|
|
2251
2280
|
return {
|
|
2252
2281
|
activeBlock,
|
|
2282
|
+
setActiveBlock,
|
|
2253
2283
|
colorMode,
|
|
2254
2284
|
setColorMode,
|
|
2255
2285
|
openInNewTab,
|
|
@@ -2262,13 +2292,8 @@ function useToolbar(editor) {
|
|
|
2262
2292
|
setSelectedLanguage,
|
|
2263
2293
|
selectedLink,
|
|
2264
2294
|
setSelectedLink,
|
|
2265
|
-
showColorPicker,
|
|
2266
|
-
showLinkForm,
|
|
2267
|
-
setShowLinkForm,
|
|
2268
2295
|
// Fonctions utiles
|
|
2269
2296
|
detectCurrentLanguage,
|
|
2270
|
-
toggleLinkForm,
|
|
2271
|
-
toggleColorPicker,
|
|
2272
2297
|
handleColorChange,
|
|
2273
2298
|
handleBackgroundColorChange,
|
|
2274
2299
|
handleBlockTypeChange
|
|
@@ -2276,6 +2301,7 @@ function useToolbar(editor) {
|
|
|
2276
2301
|
}
|
|
2277
2302
|
function ColorPickerPopup({ selectedColor, onSelectColor, onClose }) {
|
|
2278
2303
|
const [color, setColor] = useState("#ffffff");
|
|
2304
|
+
const { theme } = useTheme();
|
|
2279
2305
|
const { editor, backgroundColor, borderColor, imageColor } = useReactTextForgeContext();
|
|
2280
2306
|
const style = {
|
|
2281
2307
|
backgroundColor,
|
|
@@ -2318,8 +2344,18 @@ function ColorPickerPopup({ selectedColor, onSelectColor, onClose }) {
|
|
|
2318
2344
|
setColor(selectedColor);
|
|
2319
2345
|
}
|
|
2320
2346
|
}, [selectedColor]);
|
|
2347
|
+
useEffect(() => {
|
|
2348
|
+
const inputs = document.querySelectorAll(".sketch-picker input");
|
|
2349
|
+
const labels = document.querySelectorAll(".sketch-picker label");
|
|
2350
|
+
inputs.forEach((input, index) => {
|
|
2351
|
+
input.style.border = "2px solid " + borderColor;
|
|
2352
|
+
input.style.background = backgroundColor;
|
|
2353
|
+
input.style.color = imageColor;
|
|
2354
|
+
labels[index].style.color = imageColor;
|
|
2355
|
+
});
|
|
2356
|
+
}, [theme]);
|
|
2321
2357
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { onMouseLeave: onClose, className: "rtf color-picker-popup", children: [
|
|
2322
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(SketchPicker, { styles: pickerStyles, color, onChangeComplete: handleChangeComplete }),
|
|
2358
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SketchPicker, { className: "rtf sketch-picker", styles: pickerStyles, color, onChangeComplete: handleChangeComplete }),
|
|
2323
2359
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style, className: "rtf link-form-actions", children: [
|
|
2324
2360
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "rtf", style: confirmStyle, onClick: handleApplyColor, disabled: !color, children: "Appliquer" }),
|
|
2325
2361
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "rtf", style: cancelStyle, onClick: handleCancel, children: "Annuler" })
|
|
@@ -2327,13 +2363,14 @@ function ColorPickerPopup({ selectedColor, onSelectColor, onClose }) {
|
|
|
2327
2363
|
] });
|
|
2328
2364
|
}
|
|
2329
2365
|
const BlockquoteButton = () => {
|
|
2330
|
-
const { editor, backgroundColor, imageColor } = useReactTextForgeContext();
|
|
2366
|
+
const { editor, backgroundColor, imageColor, setDropdownActive } = useReactTextForgeContext();
|
|
2331
2367
|
const isActive = CustomEditor.isBlockquoteActive(editor);
|
|
2332
2368
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2333
2369
|
"button",
|
|
2334
2370
|
{
|
|
2335
2371
|
onMouseDown: (event) => {
|
|
2336
2372
|
event.preventDefault();
|
|
2373
|
+
setDropdownActive(null);
|
|
2337
2374
|
CustomEditor.toggleBlockquote(editor);
|
|
2338
2375
|
},
|
|
2339
2376
|
style: { backgroundColor: isActive ? `color-mix(in srgb, ${backgroundColor} 80%, ${isDarkColor(backgroundColor) ? "white" : "black"})` : "" },
|
|
@@ -2375,7 +2412,7 @@ const Tooltip = ({ text, children, position = "top" }) => {
|
|
|
2375
2412
|
};
|
|
2376
2413
|
const FormatButton = ({ activeMarks, format, isActive, tooltip }) => {
|
|
2377
2414
|
const [selectedFontFamily, setSelectedFontFamily] = useState("");
|
|
2378
|
-
const { backgroundColor, editor, imageColor } = useReactTextForgeContext();
|
|
2415
|
+
const { backgroundColor, editor, imageColor, dropdownActive, setDropdownActive } = useReactTextForgeContext();
|
|
2379
2416
|
const {
|
|
2380
2417
|
activeBlock,
|
|
2381
2418
|
colorMode,
|
|
@@ -2390,13 +2427,8 @@ const FormatButton = ({ activeMarks, format, isActive, tooltip }) => {
|
|
|
2390
2427
|
selectedColor,
|
|
2391
2428
|
setSelectedColor,
|
|
2392
2429
|
selectedLink,
|
|
2393
|
-
setSelectedLink
|
|
2394
|
-
|
|
2395
|
-
showLinkForm,
|
|
2396
|
-
setShowLinkForm,
|
|
2397
|
-
toggleColorPicker,
|
|
2398
|
-
toggleLinkForm
|
|
2399
|
-
} = useToolbar(editor);
|
|
2430
|
+
setSelectedLink
|
|
2431
|
+
} = useToolbar(editor, setDropdownActive);
|
|
2400
2432
|
const isHeading = activeBlock === "h1" || activeBlock === "h2";
|
|
2401
2433
|
const alignList = ["left", "center", "right"];
|
|
2402
2434
|
const handleFontSizeChange = (size) => {
|
|
@@ -2430,7 +2462,10 @@ const FormatButton = ({ activeMarks, format, isActive, tooltip }) => {
|
|
|
2430
2462
|
{
|
|
2431
2463
|
title: tooltip,
|
|
2432
2464
|
className: "rtf tool",
|
|
2433
|
-
onClick: () =>
|
|
2465
|
+
onClick: () => {
|
|
2466
|
+
setDropdownActive(null);
|
|
2467
|
+
format === "indent" ? CustomEditor.handleIndent(editor) : CustomEditor.handleOutdent(editor);
|
|
2468
|
+
},
|
|
2434
2469
|
disabled: !isActive,
|
|
2435
2470
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format, imageColor: isActive ? imageColor : `color-mix(in srgb, ${imageColor} 40%, black)` })
|
|
2436
2471
|
}
|
|
@@ -2450,18 +2485,18 @@ const FormatButton = ({ activeMarks, format, isActive, tooltip }) => {
|
|
|
2450
2485
|
{
|
|
2451
2486
|
onMouseDown: (event) => {
|
|
2452
2487
|
event.preventDefault();
|
|
2488
|
+
setDropdownActive("href");
|
|
2453
2489
|
handleMouseDown();
|
|
2454
|
-
toggleLinkForm();
|
|
2455
2490
|
},
|
|
2456
2491
|
title: tooltip,
|
|
2457
2492
|
className: `rtf tool tool--${isActive ? "active" : "inactive"}`,
|
|
2458
2493
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format, imageColor })
|
|
2459
2494
|
}
|
|
2460
2495
|
),
|
|
2461
|
-
|
|
2496
|
+
dropdownActive === "href" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2462
2497
|
LinkForm,
|
|
2463
2498
|
{
|
|
2464
|
-
onClose: () =>
|
|
2499
|
+
onClose: () => setDropdownActive(null),
|
|
2465
2500
|
initialUrl: selectedLink,
|
|
2466
2501
|
isOpenInNewTab: openInNewTab
|
|
2467
2502
|
}
|
|
@@ -2475,25 +2510,25 @@ const FormatButton = ({ activeMarks, format, isActive, tooltip }) => {
|
|
|
2475
2510
|
event.preventDefault();
|
|
2476
2511
|
handleMouseDown();
|
|
2477
2512
|
if (format === "color") {
|
|
2513
|
+
setDropdownActive("color");
|
|
2478
2514
|
setSelectedColor(activeMarks[format]);
|
|
2479
2515
|
setColorMode("color");
|
|
2480
|
-
toggleColorPicker();
|
|
2481
2516
|
} else {
|
|
2517
|
+
setDropdownActive("bgColor");
|
|
2482
2518
|
setSelectedBackgroundColor(activeMarks[format]);
|
|
2483
2519
|
setColorMode("bgColor");
|
|
2484
|
-
toggleColorPicker();
|
|
2485
2520
|
}
|
|
2486
2521
|
},
|
|
2487
2522
|
className: `rtf tool tool--${isActive ? "active" : "inactive"}`,
|
|
2488
2523
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format, imageColor })
|
|
2489
2524
|
}
|
|
2490
2525
|
),
|
|
2491
|
-
|
|
2526
|
+
dropdownActive === format && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2492
2527
|
ColorPickerPopup,
|
|
2493
2528
|
{
|
|
2494
2529
|
selectedColor: colorMode === "color" ? selectedColor : selectedBackgroundColor,
|
|
2495
2530
|
onSelectColor: colorMode === "color" ? handleColorChange : handleBackgroundColorChange,
|
|
2496
|
-
onClose:
|
|
2531
|
+
onClose: () => setDropdownActive(null)
|
|
2497
2532
|
}
|
|
2498
2533
|
)
|
|
2499
2534
|
] }) : format === "blockquote" ? /* @__PURE__ */ jsxRuntimeExports.jsx(BlockquoteButton, { tooltip }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -2501,6 +2536,7 @@ const FormatButton = ({ activeMarks, format, isActive, tooltip }) => {
|
|
|
2501
2536
|
{
|
|
2502
2537
|
onMouseDown: (event) => {
|
|
2503
2538
|
event.preventDefault();
|
|
2539
|
+
setDropdownActive(null);
|
|
2504
2540
|
if (alignList.includes(format)) {
|
|
2505
2541
|
CustomEditor.toggleAlign(editor, format);
|
|
2506
2542
|
} else {
|
|
@@ -2519,8 +2555,12 @@ const BlockTypeDropdown = forwardRef(({ tooltip }, ref) => {
|
|
|
2519
2555
|
const { editor } = useReactTextForgeContext();
|
|
2520
2556
|
const {
|
|
2521
2557
|
activeBlock,
|
|
2558
|
+
setActiveBlock,
|
|
2522
2559
|
handleBlockTypeChange
|
|
2523
2560
|
} = useToolbar(editor);
|
|
2561
|
+
useEffect(() => {
|
|
2562
|
+
setActiveBlock(CustomEditor.getCurrentBlock(editor, editor.selection));
|
|
2563
|
+
}, [editor.selection]);
|
|
2524
2564
|
const blockTypes = [
|
|
2525
2565
|
{
|
|
2526
2566
|
type: "paragraph",
|
|
@@ -2547,7 +2587,7 @@ const BlockTypeDropdown = forwardRef(({ tooltip }, ref) => {
|
|
|
2547
2587
|
});
|
|
2548
2588
|
const LanguageDropdown = forwardRef((props, ref) => {
|
|
2549
2589
|
const [isOpen, setIsOpen] = useState(false);
|
|
2550
|
-
const { backgroundColor, editor, imageColor } = useReactTextForgeContext();
|
|
2590
|
+
const { backgroundColor, editor, imageColor, dropdownActive, setDropdownActive } = useReactTextForgeContext();
|
|
2551
2591
|
const {
|
|
2552
2592
|
selectedLanguage,
|
|
2553
2593
|
setSelectedLanguage
|
|
@@ -2573,6 +2613,11 @@ const LanguageDropdown = forwardRef((props, ref) => {
|
|
|
2573
2613
|
};
|
|
2574
2614
|
const toggleForm = () => {
|
|
2575
2615
|
setIsOpen(!isOpen);
|
|
2616
|
+
if (!isOpen === true) {
|
|
2617
|
+
setDropdownActive("code");
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
setDropdownActive(null);
|
|
2576
2621
|
};
|
|
2577
2622
|
const handleLanguageChange = (language) => {
|
|
2578
2623
|
setSelectedLanguage(language);
|
|
@@ -2581,7 +2626,7 @@ const LanguageDropdown = forwardRef((props, ref) => {
|
|
|
2581
2626
|
};
|
|
2582
2627
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref, className: `rtf dropdown tool ${selectedLanguage && selectedLanguage !== "init" && selectedLanguage !== "" ? "tool--active" : ""}`, children: [
|
|
2583
2628
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "rtf dropdown-toggle", onClick: toggleForm, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format: "blockCode", imageColor }) }),
|
|
2584
|
-
isOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { style: dropdownStyle, onMouseLeave: toggleForm, className: "rtf dropdown-menu", children: [
|
|
2629
|
+
isOpen && dropdownActive === "code" && /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { style: dropdownStyle, onMouseLeave: toggleForm, className: "rtf dropdown-menu", children: [
|
|
2585
2630
|
selectedLanguage && /* @__PURE__ */ jsxRuntimeExports.jsx("li", { onClick: () => handleLanguageChange("init"), children: "Réinitialiser" }),
|
|
2586
2631
|
Object.keys(languages).map((lang) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2587
2632
|
"li",
|
|
@@ -2600,7 +2645,7 @@ const LanguageDropdown = forwardRef((props, ref) => {
|
|
|
2600
2645
|
] });
|
|
2601
2646
|
});
|
|
2602
2647
|
const ImageForm = forwardRef((props, ref) => {
|
|
2603
|
-
const { editor, imageColor } = useReactTextForgeContext();
|
|
2648
|
+
const { editor, imageColor, setDropdownActive } = useReactTextForgeContext();
|
|
2604
2649
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rtf tool image-upload-container", ref, children: [
|
|
2605
2650
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2606
2651
|
"input",
|
|
@@ -2612,7 +2657,7 @@ const ImageForm = forwardRef((props, ref) => {
|
|
|
2612
2657
|
className: "rtf hidden-file-input"
|
|
2613
2658
|
}
|
|
2614
2659
|
),
|
|
2615
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "file-input", className: "rtf image-upload-label", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format: "image", imageColor }) })
|
|
2660
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "file-input", className: "rtf image-upload-label", onClick: () => setDropdownActive(null), children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format: "image", imageColor }) })
|
|
2616
2661
|
] });
|
|
2617
2662
|
});
|
|
2618
2663
|
const TableForm = ({ onClose }) => {
|
|
@@ -2662,8 +2707,8 @@ const TableForm = ({ onClose }) => {
|
|
|
2662
2707
|
] })
|
|
2663
2708
|
] });
|
|
2664
2709
|
};
|
|
2665
|
-
const
|
|
2666
|
-
const { editor, imageColor } = useReactTextForgeContext();
|
|
2710
|
+
const TableButtons = forwardRef(({ allButtons, hiddenButtons }, ref) => {
|
|
2711
|
+
const { editor, imageColor, setDropdownActive } = useReactTextForgeContext();
|
|
2667
2712
|
const isTableSelected = CustomEditor.isSelectionInTable(editor);
|
|
2668
2713
|
const buttons = [
|
|
2669
2714
|
{ name: "deleteTable", alt: "Supprimer le tableau", onClick: CustomEditor.deleteTable },
|
|
@@ -2672,6 +2717,10 @@ const TableDropdown = forwardRef(({ allButtons, hiddenButtons }, ref) => {
|
|
|
2672
2717
|
{ name: "deleteRow", alt: "Supprimer une ligne", onClick: CustomEditor.deleteRow },
|
|
2673
2718
|
{ name: "deleteColumn", alt: "Supprimer une colonne", onClick: CustomEditor.deleteColumn }
|
|
2674
2719
|
];
|
|
2720
|
+
const handleClick = (button) => {
|
|
2721
|
+
setDropdownActive(null);
|
|
2722
|
+
button.onClick(editor);
|
|
2723
|
+
};
|
|
2675
2724
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: buttons.map((button, index) => {
|
|
2676
2725
|
var _a, _b;
|
|
2677
2726
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: allButtons.find((action) => action.format === button.name).tooltip, position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -2680,7 +2729,7 @@ const TableDropdown = forwardRef(({ allButtons, hiddenButtons }, ref) => {
|
|
|
2680
2729
|
ref: (el) => ref.current[button.name] = el,
|
|
2681
2730
|
className: "rtf tool",
|
|
2682
2731
|
style: { display: hiddenButtons.includes(button.name) ? "none" : "inline-block" },
|
|
2683
|
-
onClick: () => button
|
|
2732
|
+
onClick: () => handleClick(button),
|
|
2684
2733
|
disabled: !isTableSelected,
|
|
2685
2734
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2686
2735
|
Images,
|
|
@@ -2698,7 +2747,8 @@ const Toolbar = ({ activeMarks }) => {
|
|
|
2698
2747
|
const [hiddenButtons, setHiddenButtons] = useState([]);
|
|
2699
2748
|
const toolbarRef = useRef(null);
|
|
2700
2749
|
const buttonsRef = useRef({});
|
|
2701
|
-
const
|
|
2750
|
+
const modalRef = useRef(null);
|
|
2751
|
+
const { editor, imageColor, backgroundColor, dropdownActive, setDropdownActive } = useReactTextForgeContext();
|
|
2702
2752
|
const allButtons = [
|
|
2703
2753
|
{ format: "blockType", tooltip: "Insérer un bloc de texte" },
|
|
2704
2754
|
{ format: "bold", tooltip: "Gras (Ctrl+B)" },
|
|
@@ -2732,26 +2782,40 @@ const Toolbar = ({ activeMarks }) => {
|
|
|
2732
2782
|
{ format: "redo", tooltip: "Rétablir (Ctrl+Y)" }
|
|
2733
2783
|
];
|
|
2734
2784
|
const [showTableForm, setShowTableForm] = useState(false);
|
|
2785
|
+
const [toolbarGap, setToolbarGap] = useState(0);
|
|
2735
2786
|
const tablesActions = ["deleteTable", "addRow", "addColumn", "deleteRow", "deleteColumn"];
|
|
2736
2787
|
const toggleTableForm = () => {
|
|
2737
2788
|
setShowTableForm(!showTableForm);
|
|
2789
|
+
if (!showTableForm === true) {
|
|
2790
|
+
setDropdownActive("table");
|
|
2791
|
+
return;
|
|
2792
|
+
}
|
|
2793
|
+
setDropdownActive(null);
|
|
2738
2794
|
};
|
|
2739
2795
|
const handleBlur = () => {
|
|
2740
2796
|
document.querySelector(".rtf.toolbar").blur();
|
|
2741
2797
|
};
|
|
2742
|
-
const toggleModal = () =>
|
|
2798
|
+
const toggleModal = () => {
|
|
2799
|
+
setShowModal((prev) => !prev);
|
|
2800
|
+
};
|
|
2743
2801
|
const handleResize = () => {
|
|
2744
2802
|
if (toolbarRef.current) {
|
|
2745
2803
|
const toolbar = toolbarRef.current;
|
|
2746
2804
|
const toolbarWidth = toolbar.clientWidth - 15;
|
|
2747
|
-
|
|
2805
|
+
let totalWidth = 0;
|
|
2806
|
+
allButtons.forEach((button, index) => {
|
|
2807
|
+
const buttonElement = buttonsRef.current[button.format];
|
|
2808
|
+
if (buttonElement) {
|
|
2809
|
+
totalWidth += (index === 0 ? buttonElement.clientWidth : buttonsRef.current[allButtons[1].format].clientWidth) + 5;
|
|
2810
|
+
}
|
|
2811
|
+
});
|
|
2748
2812
|
if (totalWidth > toolbarWidth) {
|
|
2749
2813
|
let currentWidth = 0;
|
|
2750
2814
|
const visibleButtons = [];
|
|
2751
|
-
allButtons.forEach((button) => {
|
|
2815
|
+
allButtons.forEach((button, index) => {
|
|
2752
2816
|
const buttonElement = buttonsRef.current[button.format];
|
|
2753
2817
|
if (buttonElement) {
|
|
2754
|
-
currentWidth += (
|
|
2818
|
+
currentWidth += (index === 0 ? buttonElement.clientWidth : buttonsRef.current[allButtons[1].format].clientWidth) + 5;
|
|
2755
2819
|
if (currentWidth <= toolbarWidth) {
|
|
2756
2820
|
visibleButtons.push(button.format);
|
|
2757
2821
|
}
|
|
@@ -2774,7 +2838,14 @@ const Toolbar = ({ activeMarks }) => {
|
|
|
2774
2838
|
resizeObserver.disconnect();
|
|
2775
2839
|
};
|
|
2776
2840
|
}, []);
|
|
2777
|
-
|
|
2841
|
+
useEffect(() => {
|
|
2842
|
+
if (modalRef.current) {
|
|
2843
|
+
setToolbarGap(modalRef.current.clientHeight);
|
|
2844
|
+
} else {
|
|
2845
|
+
setToolbarGap(0);
|
|
2846
|
+
}
|
|
2847
|
+
}, [showModal]);
|
|
2848
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rtf toolbar-container", style: { marginBottom: toolbarGap }, children: [
|
|
2778
2849
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rtf toolbar", onClick: handleBlur, ref: toolbarRef, children: [
|
|
2779
2850
|
/* @__PURE__ */ jsxRuntimeExports.jsx(BlockTypeDropdown, { ref: (el) => buttonsRef.current["blockType"] = el, tooltip: allButtons.find((button) => button.format === "blockType").tooltip }),
|
|
2780
2851
|
Object.keys(activeMarks).map((format, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -2797,7 +2868,7 @@ const Toolbar = ({ activeMarks }) => {
|
|
|
2797
2868
|
)),
|
|
2798
2869
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rtf dropdown tool", style: { display: hiddenButtons.includes("table") ? "none" : "flex", padding: hiddenButtons.includes("table") ? 0 : 5 }, children: [
|
|
2799
2870
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: allButtons.find((action) => action.format === "table").tooltip, position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { ref: (el) => buttonsRef.current["table"] = el, onClick: toggleTableForm, className: "rtf dropdown-toggle", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format: "table", imageColor }) }) }),
|
|
2800
|
-
showTableForm && !hiddenButtons.includes("table") && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2871
|
+
showTableForm && !hiddenButtons.includes("table") && dropdownActive === "table" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2801
2872
|
TableForm,
|
|
2802
2873
|
{
|
|
2803
2874
|
onClose: toggleTableForm
|
|
@@ -2805,16 +2876,16 @@ const Toolbar = ({ activeMarks }) => {
|
|
|
2805
2876
|
)
|
|
2806
2877
|
] }),
|
|
2807
2878
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2808
|
-
|
|
2879
|
+
TableButtons,
|
|
2809
2880
|
{
|
|
2810
2881
|
allButtons,
|
|
2811
2882
|
hiddenButtons,
|
|
2812
2883
|
ref: buttonsRef
|
|
2813
2884
|
}
|
|
2814
2885
|
),
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
["undo", "redo"].map((historyAction) =>
|
|
2886
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rtf dropdown tool", style: { display: hiddenButtons.includes("image") ? "none" : "flex", padding: 0 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: allButtons.find((button) => button.format === "image").tooltip, position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ImageForm, { ref: (el) => buttonsRef.current["image"] = el }) }) }),
|
|
2887
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rtf dropdown tool", style: { display: hiddenButtons.includes("code") ? "none" : "flex", padding: 0 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: allButtons.find((button) => button.format === "code").tooltip, position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LanguageDropdown, { ref: (el) => buttonsRef.current["code"] = el }) }) }),
|
|
2888
|
+
["undo", "redo"].map((historyAction) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rtf dropdown tool", style: { display: hiddenButtons.includes(historyAction) ? "none" : "flex", padding: 0 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: allButtons.find((button) => button.format === historyAction).tooltip, position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2818
2889
|
"button",
|
|
2819
2890
|
{
|
|
2820
2891
|
ref: (el) => buttonsRef.current[historyAction] = el,
|
|
@@ -2833,21 +2904,29 @@ const Toolbar = ({ activeMarks }) => {
|
|
|
2833
2904
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format: historyAction, imageColor: editor.history[historyAction + "s"].length === 0 ? `color-mix(in srgb, ${imageColor} 40%, ${isDarkColor(imageColor) ? "white" : "black"})` : imageColor })
|
|
2834
2905
|
},
|
|
2835
2906
|
historyAction
|
|
2836
|
-
) }, historyAction)),
|
|
2907
|
+
) }) }, historyAction)),
|
|
2837
2908
|
hiddenButtons.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: "Voir plus", position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "rtf tool toolbar-more-button", onClick: toggleModal, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format: "more", imageColor }) }) })
|
|
2838
2909
|
] }),
|
|
2839
|
-
showModal && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rtf toolbar-modal", style: { backgroundColor }, onMouseLeave: () => setShowModal(false), children: hiddenButtons.map((format) => {
|
|
2910
|
+
showModal && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rtf toolbar-modal", ref: modalRef, style: { backgroundColor }, onMouseLeave: () => setShowModal(false), children: hiddenButtons.map((format) => {
|
|
2840
2911
|
if (format === "image" || format === "code" || format === "table" || format === "deleteTable" || format === "addRow" || format === "addColumn" || format === "deleteRow" || format === "deleteColumn") {
|
|
2841
|
-
return format === "image" ? /* @__PURE__ */ jsxRuntimeExports.jsx(ImageForm, { ref: (el) => buttonsRef.current["image"] = el }, format) : format === "code" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LanguageDropdown, { ref: (el) => buttonsRef.current["code"] = el }, format) : format === "table" ? /* @__PURE__ */ jsxRuntimeExports.
|
|
2842
|
-
"
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2912
|
+
return format === "image" ? /* @__PURE__ */ jsxRuntimeExports.jsx(ImageForm, { ref: (el) => buttonsRef.current["image"] = el }, format) : format === "code" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LanguageDropdown, { ref: (el) => buttonsRef.current["code"] = el }, format) : format === "table" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rtf dropdown tool", children: [
|
|
2913
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: allButtons.find((action) => action.format === format).tooltip, position: "bottom", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2914
|
+
"button",
|
|
2915
|
+
{
|
|
2916
|
+
className: "rtf dropdown-toggle",
|
|
2917
|
+
ref: (el) => buttonsRef.current[format] = el,
|
|
2918
|
+
onClick: toggleTableForm,
|
|
2919
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Images, { format, imageColor })
|
|
2920
|
+
}
|
|
2921
|
+
) }),
|
|
2922
|
+
showTableForm && dropdownActive === "table" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2923
|
+
TableForm,
|
|
2924
|
+
{
|
|
2925
|
+
onClose: toggleTableForm
|
|
2926
|
+
}
|
|
2927
|
+
)
|
|
2928
|
+
] }, format) : tablesActions.includes(format) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2929
|
+
TableButtons,
|
|
2851
2930
|
{
|
|
2852
2931
|
allButtons,
|
|
2853
2932
|
hiddenButtons: tablesActions.filter((tablesAction) => tablesAction !== format),
|