react-text-forge 1.2.5 → 1.2.7

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/LICENSE.txt CHANGED
File without changes
package/README.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ReactTextForge est un éditeur de texte basé sur React et Slate.js.
4
4
 
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-4.9+-blue.svg)](https://www.typescriptlang.org/)
7
+ [![Slate.js](https://img.shields.io/badge/Slate.js-0.94+-brightgreen.svg)](https://docs.slatejs.org/)
8
+
9
+ ---
10
+
11
+ ## **📌 Pourquoi ReactTextForge ?**
12
+ ReactTextForge est conçu pour offrir une expérience d'édition de texte riche, **légère**, **modulaire** et **facile à intégrer** dans des applications React/TypeScript. Contrairement à CKEditor, il est optimisé pour :
13
+ - Une **intégration transparente** avec les projets modernes (React 18+, TypeScript).
14
+ - Une **personnalisation poussée** (toolbar, styles, raccourcis clavier).
15
+ - Une **architecture extensible** pour ajouter des fonctionnalités spécifiques.
16
+
17
+ ---
18
+
19
+ ## **⚙️ Prérequis**
20
+ - Node.js **v25+**
21
+ - React **v19+**
22
+ - TypeScript **v4.9+**
23
+ - Slate.js **v0.112+**
24
+
5
25
  ## Installation
6
26
 
7
27
  Pour installer ReactTextForge, utilisez la commande suivante :
@@ -43,6 +63,29 @@ export default function App() {
43
63
  }
44
64
  ```
45
65
 
66
+ Vous pouvez si vous le désirez ajouter vos propres raccourcis claviers comme ceci:
67
+
68
+ ```jsx
69
+ import React, { useState } from "react";
70
+ import ReactTextForge from "./components/ReactTextForge";
71
+
72
+ export default function App() {
73
+ const [value, setValue] = useState({});
74
+
75
+ /**
76
+ * Indiquer en clé le raccourci définit et en valeur la fonction appliqué
77
+ */
78
+ const raccourcis = {
79
+ 'Ctrl+Shift+A': () => alert('Vous avez pressé Ctrl+Shift+A !'),
80
+ 'Alt+S': () => alert('Vous avez pressé Alt+S !')
81
+ };
82
+
83
+ return (
84
+ <ReactTextForge value={value} setValue={setValue} raccourcis={raccourcis} />
85
+ );
86
+ }
87
+ ```
88
+
46
89
  ## Licence
47
90
  Ce projet est sous licence MIT.
48
91
 
@@ -3,13 +3,10 @@ export default FormatButton;
3
3
  * Ce composant permet d'afficher la liste des boutons de fonctionnalité
4
4
  *
5
5
  * @param {object} props
6
- * @param {string} props.activeMarks - Liste des marques appliquées
7
- * @param {string} props.format - format de texte sélectionné
8
- * @param {bool} props.isActive - état du format (actif ou non)
6
+ * @property {string} props.activeMarks - Liste des marques appliquées
7
+ * @property {string} props.format - format de texte sélectionné
8
+ * @property {bool} props.isActive - état du format (actif ou non)
9
+ * @property {bool} props.tooltip - Infobulle
9
10
  * @returns {JSX.Element}
10
11
  */
11
- declare function FormatButton({ activeMarks, format, isActive }: {
12
- activeMarks: string;
13
- format: string;
14
- isActive: bool;
15
- }): JSX.Element;
12
+ declare function FormatButton({ activeMarks, format, isActive, tooltip }: object): JSX.Element;
@@ -4,17 +4,29 @@ export default ReactTextForge;
4
4
  *
5
5
  * @param {object} props
6
6
  * @param {object} props.value - contenu textuel
7
+ * @param {function} props.setValue - change l'état du contenu
8
+ * @param {object} props.fullScreen - Gestion du plein écran
9
+ * @param {object} props.showTheme - Gestion du thème
7
10
  * @param {string} props.borderColor - couleur de bordure des éléments
8
11
  * @param {string} props.backgroundColor - couleur d'arrière-plan
9
12
  * @param {string} props.imageColor - couleur des images
10
- * @param {function} props.setValue - change l'état du contenu
13
+ * @param {string} props.borderDarkColor - couleur de bordure des éléments pour le thème sombre
14
+ * @param {string} props.backgroundDarkColor - couleur d'arrière-plan pour le thème sombre
15
+ * @param {string} props.imageDarkColor - couleur des images pour le thème sombre
16
+ * @param {object} props.raccourcis - liste des raccourcis ajoutées
11
17
  *
12
18
  * @returns {JSX.Element }
13
19
  */
14
- declare function ReactTextForge({ value, setValue, borderColor, backgroundColor, imageColor }: {
20
+ declare function ReactTextForge({ value, setValue, fullScreen, showTheme, borderColor, backgroundColor, imageColor, borderDarkColor, backgroundDarkColor, imageDarkColor, toggleColor, raccourcis }: {
15
21
  value: object;
22
+ setValue: Function;
23
+ fullScreen: object;
24
+ showTheme: object;
16
25
  borderColor: string;
17
26
  backgroundColor: string;
18
27
  imageColor: string;
19
- setValue: Function;
28
+ borderDarkColor: string;
29
+ backgroundDarkColor: string;
30
+ imageDarkColor: string;
31
+ raccourcis: object;
20
32
  }): JSX.Element;
@@ -0,0 +1,5 @@
1
+ export default ThemeToggleButton;
2
+ declare function ThemeToggleButton({ toggleColor, fullScreen }: {
3
+ toggleColor: any;
4
+ fullScreen: any;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ export function FullscreenProvider({ children }: {
2
+ children: any;
3
+ }): import("react/jsx-runtime").JSX.Element;
4
+ export function useFullscreen(): {
5
+ isFullscreen: boolean;
6
+ toggleFullscreen: () => void;
7
+ };
@@ -0,0 +1,6 @@
1
+ export function ThemeProvider({ showTheme, backgroundDarkColor, borderDarkColor, imageDarkColor, children }: object): import("react/jsx-runtime").JSX.Element;
2
+ export function useTheme(): {
3
+ theme: string;
4
+ toggleTheme: () => void;
5
+ isDarkTheme: boolean;
6
+ };
@@ -0,0 +1 @@
1
+ export function withHighlight(editor: any): any;
@@ -1,3 +1,5 @@
1
+ import { ReactEditor } from 'slate-react';
2
+ import { Path } from 'slate';
1
3
  export default CustomEditor;
2
4
  declare namespace CustomEditor {
3
5
  /**
@@ -122,6 +124,20 @@ declare namespace CustomEditor {
122
124
  * @returns {void}
123
125
  */
124
126
  function applyFontFamily(editor: object, fontFamily: string): void;
127
+ /**
128
+ * Permet de vérifier si la sélection se situe dans un code
129
+ *
130
+ * @param {object} editor - éditeur de texte
131
+ * @returns {boolean}
132
+ */
133
+ function isSelectionInCode(editor: object): boolean;
134
+ /**
135
+ * Permet de récupérer le langage actuel
136
+ *
137
+ * @param {object} editor - éditeur de texte
138
+ * @returns {boolean}
139
+ */
140
+ function getCurrentCodeLanguage(editor: object): boolean;
125
141
  /**
126
142
  * Gère l'ajout, l'édition et la suppression d'un bloc de code
127
143
  * @param {object} editor - éditeur de texte
@@ -129,6 +145,28 @@ declare namespace CustomEditor {
129
145
  * @returns {void}
130
146
  */
131
147
  function handleCode(editor: object, language: string): void;
148
+ /**
149
+ * Affiche un bloc de citation
150
+ *
151
+ * @param {ReactEditor} editor
152
+ * @returns {void}
153
+ */
154
+ function toggleBlockquote(editor: ReactEditor): void;
155
+ /**
156
+ * Vérifie si la sélection est un bloc de citation
157
+ *
158
+ * @param {ReactEditor} editor
159
+ * @returns {boolean}
160
+ */
161
+ function isBlockquoteActive(editor: ReactEditor): boolean;
162
+ /**
163
+ * Insère un bloc de code
164
+ *
165
+ * @param {object} editor
166
+ * @param {string} text
167
+ * @return {void}
168
+ */
169
+ function insertCodeBlock(editor: object, text: string): void;
132
170
  /**
133
171
  * Permet de gérer les images
134
172
  * @param {object} editor - éditeur de texte
@@ -193,4 +231,11 @@ declare namespace CustomEditor {
193
231
  * @returns {void}
194
232
  */
195
233
  function deleteTable(editor: object): void;
234
+ function findNearestTable(editor: any): (import("slate").BaseElement | import("slate").BaseText | Path)[];
235
+ /**
236
+ * Insère un paragraphe avant le tableau sélectionné.
237
+ * @param {ReactEditor} editor L'éditeur Slate.
238
+ */
239
+ function insertParagraphBeforeTable(editor: ReactEditor): void;
240
+ function insertParagraphAfterTable(editor: any): void;
196
241
  }
@@ -0,0 +1,2 @@
1
+ export default FullscreenButton;
2
+ declare function FullscreenButton(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,3 @@
1
+ export function FullscreenWrapper({ children }: {
2
+ children: any;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export function Tooltip({ text, children, position }: {
2
+ text: any;
3
+ children: any;
4
+ position?: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -2,7 +2,9 @@ export default BlockTypeDropdown;
2
2
  /**
3
3
  * Ce composant affiche le formulaire de changement de type de bloc (paragraphe, titre ou sous-titre)
4
4
  *
5
+ * @param {object} props
6
+ * @param {object} props.tooltip - Infobulle
5
7
  *
6
- * @returns {JSX.Element}
8
+ * @returns {JSX.Element }
7
9
  */
8
- declare function BlockTypeDropdown(): JSX.Element;
10
+ declare const BlockTypeDropdown: import('react').ForwardRefExoticComponent<import('react').RefAttributes<any>>;
@@ -0,0 +1,7 @@
1
+ export default BlockquoteButton;
2
+ /**
3
+ * Permet d'afficher le bouton de génération de citation
4
+ *
5
+ * @returns {JSX.ReactElement}
6
+ */
7
+ declare function BlockquoteButton(): JSX.ReactElement;
@@ -4,4 +4,4 @@ export default LanguageDropdown;
4
4
  *
5
5
  * @returns {JSX.Element}
6
6
  */
7
- declare function LanguageDropdown(): JSX.Element;
7
+ declare const LanguageDropdown: import('react').ForwardRefExoticComponent<import('react').RefAttributes<any>>;
@@ -2,6 +2,9 @@ export default TableDropdown;
2
2
  /**
3
3
  * Ce composant permet de gérer l'affichage du formulaire de création de tableau
4
4
  *
5
+ * @param {object} props
6
+ * @property {object} allButtons - Tous les boutons
7
+ * @property {object} hiddenButtons - Boutons non visibles
5
8
  * @returns {JSX.Element}
6
9
  */
7
- declare function TableDropdown(): JSX.Element;
10
+ declare const TableDropdown: import('react').ForwardRefExoticComponent<import('react').RefAttributes<any>>;
@@ -0,0 +1,3 @@
1
+ export default function TableElement({ children }: {
2
+ children: any;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -4,4 +4,4 @@ export default ImageForm;
4
4
  *
5
5
  * @returns {JSX.Element}
6
6
  */
7
- declare function ImageForm(): JSX.Element;
7
+ declare const ImageForm: import('react').ForwardRefExoticComponent<import('react').RefAttributes<any>>;
File without changes
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { default as ReactTextForge } from './components/ReactTextForge';
2
2
  import { default as serialize } from './components/functions/serialize';
3
3
  import { default as deserialize } from './components/functions/deserialize';
4
- import { default as HtmlDisplay } from './components/HtmlDisplay';
5
4
  export default ReactTextForge;
6
- export { serialize, deserialize, HtmlDisplay };
5
+ export { serialize, deserialize };
@@ -1,8 +1 @@
1
- pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
2
- Theme: Tokyo-night-Dark
3
- origin: https://github.com/enkia/tokyo-night-vscode-theme
4
- Description: Original highlight.js style
5
- Author: (c) Henri Vandersleyen <hvandersleyen@gmail.com>
6
- License: see project LICENSE
7
- Touched: 2022
8
- */.hljs-meta,.hljs-comment{color:#565f89}.hljs-tag,.hljs-doctag,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-template-tag,.hljs-selector-pseudo,.hljs-selector-attr,.hljs-variable.language_,.hljs-deletion{color:#f7768e}.hljs-variable,.hljs-template-variable,.hljs-number,.hljs-literal,.hljs-type,.hljs-params,.hljs-link{color:#ff9e64}.hljs-built_in,.hljs-attribute{color:#e0af68}.hljs-selector-tag{color:#2ac3de}.hljs-keyword,.hljs-title.function_,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-subst,.hljs-property{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-quote,.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-name,.hljs-keyword,.hljs-operator,.hljs-char.escape_,.hljs-attr{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{background:#1a1b26;color:#9aa5ce}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.toolbar{display:flex;gap:5px;margin-bottom:10px;flex-wrap:wrap}.toolbar>div{display:flex}.toolbar>select,.toolbar>select:focus{outline:none;border:none;background:none}.toolbar>select option,.toolbar>select:focus option{border:none;outline:none;background:none;padding:0}.tool{padding:5px;display:flex;justify-content:center;align-items:center;border:none;border-radius:3px;background:none;cursor:pointer;outline:none}.tool--arrow{background:none;border:none;cursor:pointer;font-size:12px;margin-left:4px;position:relative;bottom:4px;height:18px;padding:0}.tool img,.tool svg{cursor:pointer;width:15px;height:15px}.react-text-forge{width:80%;margin:0 auto;border:1px solid;padding:10px;border-radius:5px;position:relative}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}.react-text-forge .editor{min-height:200px;border:1px solid #ddd;padding:10px;border-radius:5px;outline:none}.react-text-forge .editor a{pointer-events:auto;cursor:pointer}.react-text-forge .editor img{max-height:200px}.react-text-forge .editor table{width:100%;table-layout:fixed;border-collapse:collapse}.react-text-forge .editor table tr{display:flex;width:100%}.react-text-forge .editor table th,.react-text-forge .editor table td{display:block;flex-grow:1;height:40px;max-height:40px;border:1px solid;border-color:inherit;padding:8px;overflow-y:scroll}.react-text-forge .color-picker-popup{position:absolute;top:100%}.react-text-forge .color-picker-popup .sketch-picker{position:relative;z-index:2}.react-text-forge .bullet-type-selector{display:inline-block;margin-left:8px}.react-text-forge .bullet-type-option{background:#f0f0f0;border:1px solid #ccc;border-radius:4px;padding:4px 8px;margin:2px;cursor:pointer}.react-text-forge .bullet-type-option:hover{background:#e0e0e0}.react-text-forge .dropdown{position:relative;display:flex}.react-text-forge .dropdown-toggle{background:none;border:none;cursor:pointer;padding:0}.react-text-forge .dropdown-menu{position:absolute;top:100%;background:#fff;border:1px solid #ccc;box-shadow:0 2px 8px #0000001a;list-style:none;height:100px;overflow-y:scroll;padding:10px 0;margin:5px 0;z-index:1000}.react-text-forge .dropdown-menu li{min-width:200px;width:max-content;height:20px;padding:5px 10px;line-height:20px;cursor:pointer}.react-text-forge .dropdown-menu li:hover{background:#f0f0f0}.react-text-forge pre{background-color:#6e6565;border:1px solid #ddd;border-radius:4px;padding:10px;overflow-x:auto;font-family:Consolas,Monaco,Courier New,monospace;font-size:14px;line-height:1.4;margin:1em 0}.react-text-forge .link-form{position:absolute;top:40px;left:0;background-color:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 10px #0000001a;padding:16px;z-index:10}.react-text-forge .link-form input[type=text]{width:calc(100% - 22px);padding:8px;margin-bottom:10px;border:1px solid #ccc;border-radius:4px}.react-text-forge .link-form label{display:flex;align-items:center;margin-bottom:10px}.react-text-forge .link-form label input[type=checkbox]{margin-right:8px}.react-text-forge .link-form-actions{display:flex;justify-content:flex-end;padding:10px;gap:8px}.react-text-forge .link-form-actions button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer}.react-text-forge .image-upload-container{position:relative}.react-text-forge .hidden-file-input{display:none}.react-text-forge .table-grid-form{display:flex;flex-direction:column;align-items:center;height:fit-content;width:fit-content;overflow:visible;padding:0;border:0}.react-text-forge .table-grid-form .grid-container{display:grid;grid-template-columns:repeat(5,20px);grid-template-rows:repeat(5,20px);gap:2px}.react-text-forge .table-grid-form .grid-cell{width:20px;height:20px;background-color:#ddd;border:1px solid #ccc}.react-text-forge .table-grid-form .grid-cell.hovered{background-color:#007bff}.react-text-forge .table-grid-form .table-size-indicator{margin-top:10px;font-size:14px}.react-text-forge ::selection{background:#0078d74d;color:#000}.react-text-forge ::-moz-selection{background:#0078d74d;color:#000}.react-text-forge a{font-weight:500;color:#646cff;text-decoration:inherit}.react-text-forge a:hover{color:#535bf2}
1
+ .tooltip-container{position:relative;display:inline-block}.tooltip{position:absolute;padding:10px 8px;border-radius:5px;font-size:14px;border:1px solid;white-space:nowrap;z-index:100;opacity:0;transition:opacity .2s;pointer-events:none;box-shadow:0 2px 4px #0000001a}.tooltip--visible{opacity:1}.tooltip--bottom{top:100%;left:50%;transform:translate(-50%);margin-top:8px}.rtf.toolbar-container{position:relative;width:100%}.rtf.toolbar{display:flex;gap:5px;margin-bottom:10px;white-space:nowrap}.rtf.toolbar>div.rtf{display:flex}.rtf.toolbar select.rtf,.rtf.toolbar select:focus.rtf{outline:none;border:none;background:none}.rtf.toolbar select.rtf option.rtf,.rtf.toolbar select:focus.rtf option.rtf{border:none;outline:none;background:none;padding:0}.rtf.toolbar-more-button{background:none;border:none;cursor:pointer;padding:0 8px;font-size:16px}.rtf.toolbar-modal{position:absolute;top:100%;right:0;z-index:1000;max-width:500px;border-radius:4px;padding:8px;box-shadow:0 2px 8px #0000001a;display:flex;flex-wrap:wrap;gap:4px}.rtf.toolbar-modal .color-picker-popup{left:0%}.rtf.toolbar-modal-item{margin:4px}.rtf.tool{padding:5px;display:flex;justify-content:center;align-items:center;border:none;border-radius:3px;background:none;cursor:pointer;outline:none}.rtf.tool--arrow{background:none;border:none;cursor:pointer;font-size:12px;margin-left:4px;position:relative;bottom:4px;height:18px;padding:0}.rtf.tool img.rtf,.rtf.tool svg.rtf{cursor:pointer;width:15px;height:15px}.rtf.toggle-switch{position:absolute;bottom:15px;display:inline-block;width:70px;height:34px}.rtf.toggle-switch input.rtf{opacity:0;width:0;height:0}.rtf.toggle-switch .rtf.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:none;transition:.4s;border-radius:34px;border:1px solid}.rtf.toggle-switch .rtf.icon{position:absolute;display:flex;justify-content:center;align-items:center;border-radius:50%;width:25px;height:25px;top:50%;left:17px;transform:translate(-50%,-50%);font-size:16px;color:#ff9800;transition:.4s}.rtf.toggle-switch input:checked.rtf+.rtf.slider{background-color:none}.rtf.toggle-switch input:checked.rtf+.rtf.slider .rtf.icon{color:#fff;left:calc(100% - 17px)}.rtf.toggle-switch .rtf.slider.round{border-radius:34px}.rtf.fullscreen-wrapper{transition:all .3s ease;width:100%;height:auto}.rtf.fullscreen-wrapper--active{position:fixed;top:0;left:0;right:0;bottom:0;width:100vw;height:100vh;background-color:var(--background-color);z-index:1000;padding:20px;box-sizing:border-box;overflow-y:auto}.rtf.fullscreen-wrapper--active .rtf.toolbar{position:sticky;top:0;background-color:var(--toolbar-background);z-index:1001;padding:10px;border-radius:0 0 8px 8px;box-shadow:0 2px 4px #0000001a}.rtf.fullscreen-wrapper--active .rtf.react-text-forge{min-height:calc(100vh - 100px);margin:20px auto;width:100%}.rtf.fullscreen-wrapper--active .rtf.rtf__editor{flex-grow:1}.rtf.fullscreen-button{position:absolute;bottom:10px;right:20px}.rtf.fullscreen-button .rtf.tool{width:30px;height:30px}.rtf.fullscreen-button .rtf.tool svg.rtf{width:30px;height:30px}code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.rtf.react-text-forge{position:relative;display:flex;flex-direction:column;max-width:80%;margin:0 auto;border:1px solid;padding:10px;border-radius:5px}@media (max-width: 768px){.rtf.react-text-forge{max-width:70%}}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}.rtf.react-text-forge .rtf.rtf__editor{min-height:50px;border:1px solid #ddd;padding:10px;border-radius:5px;outline:none;overflow:scroll}.rtf.react-text-forge .rtf.rtf__editor a{pointer-events:auto;cursor:pointer}.rtf.react-text-forge .rtf.rtf__editor img.rtf{max-height:200px}.rtf.react-text-forge .rtf.rtf__editor table.rtf{width:100%;table-layout:fixed;border-collapse:collapse}.rtf.react-text-forge .rtf.rtf__editor table.rtf tr.rtf{display:flex;width:100%}.rtf.react-text-forge .rtf.rtf__editor table.rtf th.rtf,.rtf.react-text-forge .rtf.rtf__editor table.rtf td.rtf{display:block;width:100%;height:40px;max-height:40px;border:1px solid;border-color:inherit;padding:8px;overflow-y:scroll}.rtf.react-text-forge .rtf.color-picker-popup{position:absolute;top:100%}@media (max-width: 768px){.rtf.react-text-forge .rtf.color-picker-popup{right:0}}.rtf.react-text-forge .rtf.color-picker-popup .sketch-picker{position:relative;z-index:2}.rtf.react-text-forge .rtf.dropdown{position:relative;display:flex}.rtf.react-text-forge .rtf.dropdown-toggle{background:none;border:none;cursor:pointer;padding:0}.rtf.react-text-forge .rtf.dropdown-menu{position:absolute;top:100%;background:#fff;border:1px solid #ccc;box-shadow:0 2px 8px #0000001a;list-style:none;height:100px;overflow-y:scroll;padding:10px 0;margin:5px 0;z-index:1000}.rtf.react-text-forge .rtf.dropdown-menu li{min-width:200px;width:max-content;height:20px;padding:5px 10px;line-height:20px;cursor:pointer}.rtf.react-text-forge .rtf.dropdown-menu li:hover{background:#f0f0f0}.rtf.react-text-forge pre.rtf{background-color:#1a1a1a;border:1px solid #3b3737;border-radius:4px;padding:10px;overflow-x:auto;font-family:Consolas,Monaco,Courier New,monospace;font-size:14px;line-height:1.4;margin:1em 0}.rtf.react-text-forge pre.rtf .code-language{color:#fff;border:1px solid;width:fit-content;margin-left:auto;border-bottom-left-radius:5px;padding:3px;position:relative;top:-11px;right:-11px}.rtf.react-text-forge .rtf.link-form{position:absolute;top:40px;left:0;background-color:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 10px #0000001a;padding:16px;z-index:10}.rtf.react-text-forge .rtf.link-form input[type=text].rtf{width:calc(100% - 22px);padding:8px;margin-bottom:10px;border:1px solid #ccc;border-radius:4px}.rtf.react-text-forge .rtf.link-form label.rtf{display:flex;align-items:center;margin-bottom:10px}.rtf.react-text-forge .rtf.link-form label.rtf input[type=checkbox].rtf{margin-right:8px}.rtf.react-text-forge .rtf.link-form-actions{display:flex;justify-content:flex-end;padding:10px;gap:8px}.rtf.react-text-forge .rtf.link-form-actions button.rtf{padding:8px 16px;border:none;border-radius:4px;cursor:pointer}.rtf.react-text-forge .rtf.image-upload-container{position:relative}.rtf.react-text-forge .rtf.hidden-file-input{display:none}.rtf.react-text-forge .rtf.table-grid-form{display:flex;flex-direction:column;align-items:center;height:fit-content;width:fit-content;overflow:visible;padding:0;border:0}.rtf.react-text-forge .rtf.table-grid-form .rtf.grid-container{display:grid;grid-template-columns:repeat(5,20px);grid-template-rows:repeat(5,20px);gap:2px}.rtf.react-text-forge .rtf.table-grid-form .rtf.grid-cell{width:20px;height:20px;background-color:#ddd;border:1px solid #ccc}.rtf.react-text-forge .rtf.table-grid-form .rtf.grid-cell.hovered{background-color:#007bff}.rtf.react-text-forge .rtf.table-grid-form .rtf.table-size-indicator{margin-top:10px;font-size:14px}.rtf.react-text-forge ::selection{background:#0078d74d;color:#000}.rtf.react-text-forge ::-moz-selection{background:#0078d74d;color:#000}.rtf.react-text-forge a{font-weight:500;color:#646cff;text-decoration:inherit}.rtf.react-text-forge a:hover{color:#535bf2}