### Example Usage Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md A basic example demonstrating how to implement and use the RichEditor component in a React Native application. ```APIDOC ## Example Usage ```javascript this.richtext = r} initialContentHTML={'Hello World

this is a new paragraph

this is another new paragraph

'} editorInitializedCallback={() => this.onEditorInitialized()} /> ``` ``` -------------------------------- ### Complete Functional Component Example for Rich Editor Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md This snippet demonstrates a full implementation of a functional component using RichEditor and RichToolbar. It includes necessary imports and basic setup for text input and formatting. ```javascript import React from "react"; import { Text, Platform, KeyboardAvoidingView, SafeAreaView, ScrollView } from "react-native"; import {actions, RichEditor, RichToolbar} from "react-native-pell-rich-editor"; const handleHead = ({tintColor}) => H1 const TempScreen = () => { const richText = React.useRef(); return ( Description: { console.log("descriptionText:", descriptionText); }} /> ); }; export default TempScreen; ``` -------------------------------- ### Basic RichEditor Component Setup Source: https://context7.com/wxik/react-native-rich-editor/llms.txt Demonstrates the basic setup of the RichEditor component, including handling content changes and cursor position. Ensure to import necessary components and hooks. ```jsx import React, { useRef, useCallback } from 'react'; import { SafeAreaView, ScrollView, StyleSheet } from 'react-native'; import { RichEditor } from 'react-native-pell-rich-editor'; function BasicEditor() { const richText = useRef(); const scrollRef = useRef(); const handleChange = useCallback((html) => { console.log('Editor content:', html); }, []); const handleCursorPosition = useCallback((scrollY) => { // Keep cursor visible when typing scrollRef.current?.scrollTo({ y: scrollY - 30, animated: true }); }, []); return ( console.log('Editor focused')} onBlur={() => console.log('Editor blurred')} editorStyle={{ backgroundColor: '#ffffff', color: '#000033', placeholderColor: '#a9a9a9', caretColor: '#007AFF', contentCSSText: 'font-size: 16px; min-height: 200px;' }} /> ); } const styles = StyleSheet.create({ container: { flex: 1 }, scroll: { flex: 1, backgroundColor: '#fff' } }); ``` -------------------------------- ### Install React Native Pell Rich Editor and WebView Source: https://context7.com/wxik/react-native-rich-editor/llms.txt Install the package and its peer dependency for WebView support using yarn or npm. ```bash yarn add react-native-pell-rich-editor react-native-webview ``` ```bash npm install react-native-pell-rich-editor react-native-webview ``` -------------------------------- ### Using Custom Fonts Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md This section guides you through the process of using custom fonts within the Rich Editor component by leveraging the `initialCSSText` prop. ```APIDOC ## Using Custom Fonts To use custom fonts, you need to utilize the `initialCSSText` property within the `editorStyle` prop. ### Steps: 1. **Font Preparation**: Upload your font files to a service like Transfonter.org, ensuring the 'base64' option is selected. Download the generated zip file, which will contain a `stylesheet.css` file. 2. **Stylesheet Conversion**: Create a `stylesheet.js` file and copy the content from the `stylesheet.css` file into it. Define an export for the font family, including the base64 encoded font data or a web URL. ```javascript const FontFamilyStylesheet = ` @font-face { font-family: 'Your Font Family'; src: url('data:font/ttf;charset=utf-8;base64,...............'); // Or a web URL font-weight: normal; } `; export default FontFamilyStylesheet; ``` 3. **Integration**: Import the `stylesheet.js` file into your component where `RichEditor` is used. Define the font family name and construct the `initialCSSText` object. ```javascript import FontFamilyStylesheet from 'stylesheet.js'; const fontFamily = 'Your_Font_Family'; const initialCSSText = { initialCSSText: `${FontFamilyStylesheet}`, contentCSSText: `font-family: ${fontFamily}` }; ``` 4. **Reload**: After implementing these steps, reload your application to see the Rich Editor content rendered with your custom font. For more detailed information, refer to the [PR #111](https://github.com/wxik/react-native-rich-editor/pull/111) and [issue comment #70](https://github.com/wxik/react-native-rich-editor/issues/70#issuecomment-759441101). ``` -------------------------------- ### Install React Native Rich Text Editor Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md Use either Yarn or npm to add the react-native-pell-rich-editor package to your project. Ensure you also follow instructions for the react-native-webview dependency. ```bash yarn add react-native-pell-rich-editor or npm i react-native-pell-rich-editor ``` -------------------------------- ### Image Click Event Handling Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md An example of an `onclick` event handler for an `img` tag within the RichEditor's HTML content, which sends an event using `_.sendEvent`. ```html ``` -------------------------------- ### Handle Editor Events in React Native Source: https://context7.com/wxik/react-native-rich-editor/llms.txt Use useCallback hooks to manage various editor events such as content changes, focus, blur, paste, keyboard input, link clicks, cursor position, and custom messages. Ensure proper setup for event handlers. ```jsx import React, { useRef, useCallback } from 'react'; import { Alert, ScrollView, SafeAreaView } from 'react-native'; import { RichEditor, RichToolbar } from 'react-native-pell-rich-editor'; function EditorWithEvents() { const richText = useRef(); const scrollRef = useRef(); const contentRef = useRef(''); // Content change handler const handleChange = useCallback((html) => { contentRef.current = html; console.log('Content updated:', html.substring(0, 100)); }, []); // Height change handler (useful for dynamic sizing) const handleHeightChange = useCallback((height) => { console.log('Editor height:', height); }, []); // Focus and blur handlers const handleFocus = useCallback(() => { console.log('Editor gained focus'); }, []); const handleBlur = useCallback(() => { console.log('Editor lost focus, content:', contentRef.current); }, []); // Paste handler (use with pasteAsPlainText prop) const handlePaste = useCallback((data) => { console.log('Pasted content:', data); }, []); // Keyboard event handlers const handleKeyUp = useCallback(({ keyCode, key }) => { console.log('Key up:', key, keyCode); }, []); const handleKeyDown = useCallback(({ keyCode, key }) => { console.log('Key down:', key, keyCode); }, []); // Input handler const handleInput = useCallback(({ data, inputType }) => { console.log('Input:', inputType, data); }, []); // Link click handler const handleLink = useCallback((url) => { Alert.alert('Link Clicked', url, [ { text: 'Open', onPress: () => console.log('Opening:', url) }, { text: 'Cancel', style: 'cancel' } ]); }, []); // Cursor position handler (for scroll management) const handleCursorPosition = useCallback((scrollY) => { scrollRef.current?.scrollTo({ y: scrollY - 30, animated: true }); }, []); // Custom message handler (for onclick events in HTML content) const handleMessage = useCallback(({ type, id, data }) => { switch (type) { case 'ImageClick': Alert.alert('Image clicked', `Element ID: ${id}`); break; case 'CustomAction': richText.current?.commandDOM(`$('#${id}').style.border = '2px solid red'`); break; default: console.log('Message received:', type, id, data); } }, []); return ( Click the image below:

`} onChange={handleChange} onHeightChange={handleHeightChange} onFocus={handleFocus} onBlur={handleBlur} onPaste={handlePaste} onKeyUp={handleKeyUp} onKeyDown={handleKeyDown} onInput={handleInput} onLink={handleLink} onCursorPosition={handleCursorPosition} onMessage={handleMessage} pasteAsPlainText={true} useContainer={true} initialHeight={400} />
); } ``` -------------------------------- ### Handle Scroll Positioning in ScrollView Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md When using `usecontainer = {true}` within a ScrollView, implement the `oncursorPosition` callback to manage scroll bar positioning. This example shows how to programmatically scroll to a specific Y offset. ```javascript this.scrollRef.current.scrollTo({y: scrollY - 30, animated: true}); ``` -------------------------------- ### Executing Command in RichEditor Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md Execute a JavaScript command within the RichEditor's DOM context using the `commandDOM` method. This example inserts an HTML break tag. ```javascript this.richText.current?.commandDOM('$.execCommand(\'insertHTML\', false, "
")'); ``` -------------------------------- ### Manipulating DOM Element Style in RichEditor Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md Use the `commandDOM` method to directly manipulate the DOM within the RichEditor. This example changes the color of an element with the ID 'title'. ```javascript this.richText.current?.commandDOM(`$('#title').style.color='${color}'`); ``` -------------------------------- ### Initialize Rich Editor Source: https://github.com/wxik/react-native-rich-editor/blob/master/web/index.html Initializes the Rich Editor by creating HTML content and writing it to the webview. It sets up event listeners for messages from the webview. ```javascript import {actions, messages} from '../src/const.js'; import {createHTML} from '../src/editor.js'; const HTML = createHTML({ cssText: 'html {overflow-y: auto;}', pasteAsPlainText: false, useContainer: false, }); window.actions = actions; const initHTML =
Rich Editor
React Native And Flutter



; const selectionChangeListeners = [] const webview = document.querySelector('#editor'); const childDoc = webview.contentWindow.document; childDoc.open(); childDoc.write(HTML); childDoc.close(); // toolbar selected selectionChangeListeners.push({ routeKey: function (items) { const icons = document.querySelectorAll('.toolbar .icon'); icons.forEach(da => { if (items.indexOf(da.id) !== -1) { da.classList.add('selected'); } else { da.classList.remove('selected'); } }); }, }); window.editor = (function () { const editor = { _sendAction(type, action, data) { let jsonString = JSON.stringify({type, name: action, data}); webview.contentWindow.postMessage(jsonString); }, focusContentEditor() { this._sendAction(actions.content, 'focus'); }, setContentHTML(html) { this._sendAction(actions.content, 'setHtml', html); }, init() { webview.contentWindow.addEventListener('click', () => this.focusContentEditor(), false); webview.contentWindow.document.body.addEventListener('click', event => event.stopPropagation(), false); editor.setContentHTML(initHTML); }, onPressAddImage() { this._sendAction( actions.insertImage, 'result', 'https://pbs.twimg.com/profile_images/1242293847918391296/6uUsvfJZ.png', ); }, onToolbarClick(action) { switch (action) { case actions.insertLink: case actions.setBold: case actions.setItalic: case actions.heading1: case actions.heading2: case actions.insertBulletsList: case actions.insertOrderedList: case actions.checkboxList: case actions.indent: case actions.outdent: case actions.code: case actions.line: case actions.blockquote: case actions.setStrikethrough: case actions.setUnderline: case actions.removeFormat: editor._sendAction(action, 'result'); break; case actions.insertImage: this.onPressAddImage(); break; default: break; } }, }; webview.onload = function () { editor.init(); }; window.addEventListener( 'message', function (event) { if (typeof event.data === 'object') return; const message = JSON.parse(event.data); // console.log('webview', message) switch (message.type) { case messages.SELECTION_CHANGE: { const items = message.data; selectionChangeListeners.map(listener => listener(items)); break; } case messages.CONTENT_CHANGE: { // console.log(message.data) break; } case messages.OFFSET_HEIGHT: // this.setWebHeight(message.data); break; } }, false, ); return editor; })(); +(function () { const time = document.querySelector('.time'); function dtTime() { const date = new Date(); const m = date.getMinutes(); time.innerText = ${date.getHours()}:${m < 10 ? '0' + m : m} ; } setInterval(dtTime, 500); dtTime(); })(); ``` -------------------------------- ### Basic RichEditor Initialization Source: https://github.com/wxik/react-native-rich-editor/blob/master/README.md Initialize the RichEditor component with initial HTML content and an editor initialization callback. ```javascript this.richtext = r} initialContentHTML={'Hello World

this is a new paragraph

this is another new paragraph

'} editorInitializedCallback={() => this.onEditorInitialized()} /> ``` -------------------------------- ### Available Formatting Actions Source: https://context7.com/wxik/react-native-rich-editor/llms.txt Import and use these actions to apply formatting or manipulate content programmatically. They cover text styling, headings, lists, alignment, content insertion, color, font, and history management. ```jsx import { actions } from 'react-native-pell-rich-editor'; // Text formatting actions.setBold // Bold text actions.setItalic // Italic text actions.setUnderline // Underline text actions.setStrikethrough // Strikethrough text actions.setSubscript // Subscript text actions.setSuperscript // Superscript text actions.removeFormat // Remove all formatting // Headings actions.heading1 // H1 heading actions.heading2 // H2 heading actions.heading3 // H3 heading actions.heading4 // H4 heading actions.heading5 // H5 heading actions.heading6 // H6 heading actions.setParagraph // Normal paragraph // Lists actions.insertBulletsList // Unordered list actions.insertOrderedList // Ordered list actions.checkboxList // Checkbox/todo list actions.indent // Increase indent actions.outdent // Decrease indent // Alignment actions.alignLeft // Left align actions.alignCenter // Center align actions.alignRight // Right align actions.alignFull // Justify // Insert content actions.insertImage // Insert image actions.insertVideo // Insert video actions.insertLink // Insert hyperlink actions.insertHTML // Insert raw HTML actions.insertText // Insert plain text actions.line // Insert horizontal rule actions.blockquote // Blockquote actions.code // Code block // Colors and fonts actions.foreColor // Text color actions.hiliteColor // Background/highlight color actions.fontSize // Font size (1-7) actions.fontName // Font family // History actions.undo // Undo last action actions.redo // Redo last action // Utility actions.keyboard // Toggle keyboard ``` -------------------------------- ### Apply Editor Styling and Theming Source: https://context7.com/wxik/react-native-rich-editor/llms.txt Configure the editor's appearance using the `editorStyle` prop, which accepts properties like background color, text color, and caret color. Custom CSS can be applied via `contentCSSText` and `cssText`. ```jsx import React, { useState, useMemo } from 'react'; import { SafeAreaView, Button, StyleSheet } from 'react-native'; import { RichEditor, RichToolbar } from 'react-native-pell-rich-editor'; function ThemedEditor() { const [isDark, setIsDark] = useState(false); const richText = React.useRef(); const editorStyle = useMemo(() => ({ // Background color of the editor backgroundColor: isDark ? '#1a1a2e' : '#ffffff', // Text color color: isDark ? '#eaeaea' : '#000033', // Cursor/caret color caretColor: isDark ? '#00ff88' : '#007AFF', // Placeholder text color placeholderColor: isDark ? '#666666' : '#a9a9a9', // CSS applied to editor content area contentCSSText: ' font-size: 16px; min-height: 200px; padding: 12px; line-height: 1.6; ', // Global CSS (applied to entire editor) cssText: ' #editor { border-radius: 8px; } a { color: ${isDark ? '#4da6ff' : '#0066cc'}; } ', // Initial CSS (useful for @font-face declarations) initialCSSText: ' @font-face { font-family: "CustomFont"; src: url("data:font/ttf;base64,..."); } ' }), [isDark]); const toolbarStyle = useMemo(() => ({ backgroundColor: isDark ? '#2d2d44' : '#f5f5f5', borderTopWidth: 1, borderColor: isDark ? '#444' : '#e0e0e0' }), [isDark]); return (