react-text-forge 1.2.6 → 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 :
@@ -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;
@@ -5,18 +5,28 @@ export default ReactTextForge;
5
5
  * @param {object} props
6
6
  * @param {object} props.value - contenu textuel
7
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
8
10
  * @param {string} props.borderColor - couleur de bordure des éléments
9
11
  * @param {string} props.backgroundColor - couleur d'arrière-plan
10
12
  * @param {string} props.imageColor - couleur des images
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
11
16
  * @param {object} props.raccourcis - liste des raccourcis ajoutées
12
17
  *
13
18
  * @returns {JSX.Element }
14
19
  */
15
- declare function ReactTextForge({ value, setValue, borderColor, backgroundColor, imageColor, raccourcis }: {
20
+ declare function ReactTextForge({ value, setValue, fullScreen, showTheme, borderColor, backgroundColor, imageColor, borderDarkColor, backgroundDarkColor, imageDarkColor, toggleColor, raccourcis }: {
16
21
  value: object;
17
22
  setValue: Function;
23
+ fullScreen: object;
24
+ showTheme: object;
18
25
  borderColor: string;
19
26
  backgroundColor: string;
20
27
  imageColor: string;
28
+ borderDarkColor: string;
29
+ backgroundDarkColor: string;
30
+ imageDarkColor: string;
21
31
  raccourcis: object;
22
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}