GithubHelp home page GithubHelp logo

imnapo / react-native-cn-richtext-editor Goto Github PK

View Code? Open in Web Editor NEW
217.0 11.0 115.0 2.25 MB

Richtext editor for react native

License: MIT License

JavaScript 100.00%
react-native rich-text-editor

react-native-cn-richtext-editor's Introduction

react-native-cn-richtext-editor

Deprecated. Use react-native-cn-quill instead.

Richtext editor for react native

Installation

Install using npm:

npm i react-native-cn-richtext-editor

Install using yarn:

yarn add react-native-cn-richtext-editor

Usage

Here is a simple overview of our components usage.

import React, { Component } from 'react';
import { View, StyleSheet, Keyboard
, TouchableWithoutFeedback, Text
, KeyboardAvoidingView } from 'react-native';

import  CNRichTextEditor , { CNToolbar, getInitialObject , getDefaultStyles } from "react-native-cn-richtext-editor";

const defaultStyles = getDefaultStyles();

class App extends Component {
 
    constructor(props) {
        super(props);
        
        this.state = {
            selectedTag : 'body',
            selectedStyles : [],
            value: [getInitialObject()]
        };

        this.editor = null;
    }

    onStyleKeyPress = (toolType) => {
        this.editor.applyToolbar(toolType);
    }

    onSelectedTagChanged = (tag) => {
        this.setState({
            selectedTag: tag
        })
    }

    onSelectedStyleChanged = (styles) => { 
        this.setState({
            selectedStyles: styles,
        })
    }

    onValueChanged = (value) => {
        this.setState({
            value: value
        });
    }


    render() {
        return (
            <KeyboardAvoidingView 
            behavior="padding" 
            enabled
            keyboardVerticalOffset={0}
            style={{
                flex: 1,
                paddingTop: 20,
                backgroundColor:'#eee',
                flexDirection: 'column', 
                justifyContent: 'flex-end', 
            }}
            >
                <TouchableWithoutFeedback onPress={Keyboard.dismiss} >             
                    <View style={styles.main}>
                        <CNRichTextEditor                   
                            ref={input => this.editor = input}
                            onSelectedTagChanged={this.onSelectedTagChanged}
                            onSelectedStyleChanged={this.onSelectedStyleChanged}
                            value={this.state.value}
                            style={{ backgroundColor : '#fff'}}
                            styleList={defaultStyles}
                            onValueChanged={this.onValueChanged}
                        />                        
                    </View>
                </TouchableWithoutFeedback>

                <View style={{
                    minHeight: 35
                }}>

                    <CNToolbar
                                style={{
                                    height: 35,
                                }}
                                iconSetContainerStyle={{
                                    flexGrow: 1,
                                    justifyContent: 'space-evenly',
                                    alignItems: 'center',
                                }}
                                size={30}
                                iconSet={[
                                    {
                                        type: 'tool',
                                        iconArray: [{
                                            toolTypeText: 'image',
                                            iconComponent:
                                                <Text style={styles.toolbarButton}>
                                                image
                                                </Text>
                                        }]
                                    },
                                    {
                                        type: 'tool',
                                        iconArray: [{
                                            toolTypeText: 'bold',
                                            buttonTypes: 'style',
                                            iconComponent:
                                                <Text style={styles.toolbarButton}>
                                                bold
                                                </Text>
                                        }]
                                    },
                                    {
                                        type: 'seperator'
                                    },
                                    {
                                        type: 'tool',
                                        iconArray: [
                                            {
                                                toolTypeText: 'body',
                                                buttonTypes: 'tag',
                                                iconComponent:
                                                    <Text style={styles.toolbarButton}>
                                                    body
                                                    </Text>
                                            },
                                        ]
                                    },
                                    {
                                        type: 'tool',
                                        iconArray: [
                                            {
                                                toolTypeText: 'ul',
                                                buttonTypes: 'tag',
                                                iconComponent:
                                                    <Text style={styles.toolbarButton}>
                                                    ul
                                                    </Text>
                                            }
                                        ]
                                    },
                                    {
                                        type: 'tool',
                                        iconArray: [
                                            {
                                                toolTypeText: 'ol',
                                                buttonTypes: 'tag',
                                                iconComponent:
                                                    <Text style={styles.toolbarButton}>
                                                    ol
                                                    </Text>
                                            }
                                        ]
                                    },
                                ]}
                                selectedTag={this.state.selectedTag}
                                selectedStyles={this.state.selectedStyles}
                                onStyleKeyPress={this.onStyleKeyPress}
                            />
                </View>
        </KeyboardAvoidingView>
        );
    }

}

var styles = StyleSheet.create({
    main: {
        flex: 1,
        marginTop: 10,
        paddingLeft: 30,
        paddingRight: 30,
        paddingBottom: 1,
        alignItems: 'stretch',
    },
    toolbarButton: {
        fontSize: 20,
        width: 28,
        height: 28,
        textAlign: 'center'
    },
    italicButton: {
        fontStyle: 'italic'
    },
    boldButton: {
        fontWeight: 'bold'
    },
    underlineButton: {
        textDecorationLine: 'underline'
    },
    lineThroughButton: {
        textDecorationLine: 'line-through'
    },
});


export default App;

More Advanced TextEditor

You need to put more effort :) to use more advanced features of CNRichTextEditor such as:

  • Image Uploading
  • Highlighting Text
  • Change Text Color

Actually we did not implement 'Toolbar buttons and menus' and 'Image Uploading Process' because it totally depends on using expo or pure react-native and also what other packages you prefer to use.

To see an example of how to implement more advanced feature of this editor please check this Link.

Also be noticed that this example is writen with expo and required 'react-native-popup-menu' package.

API

CNRichTextEditor

Props

Name Description Required
onSelectedTagChanged this event triggers when selected tag of editor is changed. No
onSelectedStyleChanged this event triggers when selected style of editor is changed. No
onValueChanged this event triggers when value of editor is changed. No
onRemoveImage this event triggers when an image is removed. Callback param in the form { url, id }. No
value an array object which keeps value of the editor Yes
styleList an object consist of styles name and values (use getDefaultStyles function) Yes
ImageComponent a React component (class or functional) which will be used to render images. Will be passed style and source props. No
style Styles applied to the outermost component. No
textInputStyle TextInput style No
contentContainerStyle Styles applied to the scrollview content. No
onFocus Callback that is called when one of text inputs are focused. No
onBlur Callback that is called when one of text inputs are blurred. No
placeholder The string that will be rendered before text input has been entered. No
textInputProps An object containing additional props to be passed to the TextInput component No

Instance methods

Name Params Description
applyToolbar toolType Apply the given transformation to selected text.
insertImage uri, id?, height?, width? Insert the provided image where cursor is positionned.
focus Focus to the last TextInput

CNToolbar

Props

Name Required Description
selectedTag Yes selected tag of the editor
selectedStyles Yes selected style of the editor
onStyleKeyPress Yes this event triggers when user press one of toolbar keys
size No font size of toolbar buttons
bold No a component which renders as bold button (as of 1.0.41, this prop is deprecated)
italic No a component which renders as italic button (as of 1.0.41, this prop is deprecated)
underline No a component which renders as underline button (as of 1.0.41, this prop is deprecated)
lineThrough No a component which renders as lineThrough button (as of 1.0.41, this prop is deprecated)
body No a component which renders as body button (as of 1.0.41, this prop is deprecated)
title No a component which renders as title button (as of 1.0.41, this prop is deprecated)
ul No a component which renders as ul button (as of 1.0.41, this prop is deprecated)
ol No a component which renders as ol button (as of 1.0.41, this prop is deprecated)
image No a component which renders as image button (as of 1.0.41, this prop is deprecated)
highlight No a component which renders as highlight button (as of 1.0.41, this prop is deprecated)
foreColor No a component which renders as foreColor button (as of 1.0.41, this prop is deprecated)
style No style applied to container
color No default color passed to icon
backgroundColor No default background color passed to icon
selectedColor No color applied when icon is selected
selectedBackgroundColor No background color applied when icon is selected
iconContainerStyle No a style prop assigned to icon container
iconSet Yes array of icons to display
iconSetContainerStyle No a style props assigned to icon set container

CNRichTextView

Props

Name Required Description
text Yes html string (created by convertToHtmlString function
style No style applied to container (req. {flex:1})
styleList No an object consist of styles name and values (use getDefaultStyles function)

Functions

Name Param Returns Description
getInitialObject - javascript object create a initial value for the editor.
convertToHtmlString array string this function converts value of editor to html string (use it to keep value as html in db)
convertToObject string array converts html back to array for RichTextEditor value (use this function only for html string created by convertToHtmlString function)
getDefaultStyles - javascript object creates required styles for the editor.

Expo Demo App

Checkout the expo-demo App on Expo which uses react-native-cn-richtext-editor components. If you are looking to test and run expo-demo App locally, click here to view the implementation & run it locally.

License

MIT

react-native-cn-richtext-editor's People

Contributors

achubai avatar aliazizi avatar dependabot[bot] avatar imnapo avatar jsamr avatar kristinetrona avatar mqtik avatar nnnnnoel avatar ohpax avatar pacozaa avatar raajnadar avatar richgilbank avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-cn-richtext-editor's Issues

Checkbox list

Hello, I'd like to build a todo list with something like this wysiwyg rich text editor.

Could you provide pointers on where to add this? Or if this would even be a welcome PR?

Also when we add support for checkbox lists how might one get an id for this list item? I need to associate task details to this list item as well.

Scroll position not updating well when using line break on iOS

When using line break on iOS I have the following behavior :

keyboard-ios-nok

Scroll position is not updating except if I type something from keyboard.

I removed ScrollView component in the CNRichTextEditor.js file and I also removed the scrollEnabled TextInput prop in CNTextInput.js file and I have the following behavior :

keyboard-ios-ok

Do you think the ScrollView component can be removed to keep the default scroll behavior of TextInput ?

Note : on Android everything works fine for both cases

HTML tags input

Is this repo still on going? well I want to know if you handle HTML tags. And I see there's convertToHtmlString and convertToObject i don'at know if this two handle html tags. Could you help me or show me how to use it ?

[Question] Suggestions on how to save to db the content with images

I'd like to save to database (mongodb) the content of the text editor with images.
Using the convertToHtmlString method it converts the whole document in html, using file:// for the images.
Do you have any idea on how to save the images in order to retrieve them later and convert it back to Object (using the convertToObject method) and let the user edit the document again?
Should I have to save the images separately, edit the html keeping track of the new images url?

Demo code not working

Hi I just copy paste the USAGE

import React, { Component } from 'react';
import {
	View, StyleSheet, Keyboard
	, TouchableWithoutFeedback
	, KeyboardAvoidingView, Platform
} from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons'
import CNRichTextEditor, { CNToolbar, getInitialObject } from "react-native-cn-richtext-editor";

export default class SendEmail extends Component {

	constructor(props) {
		super(props);

		this.state = {
			selectedTag: 'body',
			selectedStyles: [],
			value: [getInitialObject()]
		};

		this.editor = null;
	}

	onStyleKeyPress = (toolType) => {
		if (toolType !== 'image') {
			this.editor.applyToolbar(toolType);
		}
		else {
			// Handling image ...
		}
	}

	onSelectedTagChanged = (tag) => {
		this.setState({
			selectedTag: tag
		})
	}

	onSelectedStyleChanged = (styles) => {
		this.setState({
			selectedStyles: styles
		})
	}

	onValueChanged = (value) => {
		this.setState({
			value: value
		});
	}

	render() {
		return (
			<KeyboardAvoidingView
				behavior="padding"
				enabled
				keyboardVerticalOffset={0}
				style={{
					flex: 1,
					paddingTop: Platform.OS == 'ios' ? 20 : 0,
					backgroundColor: '#eee',
					flexDirection: 'column',
					justifyContent: 'flex-end'
				}}>
				<TouchableWithoutFeedback onPress={Keyboard.dismiss} >
					<View style={styles.main}>
						<CNRichTextEditor
							ref={input => this.editor = input}
							onSelectedTagChanged={this.onSelectedTagChanged}
							onSelectedStyleChanged={this.onSelectedStyleChanged}
							value={this.state.value}
							onValueChanged={this.onValueChanged}
							style={{ backgroundColor: '#fff', padding: 10 }}
						/>
					</View>
				</TouchableWithoutFeedback>

				<View style={{
					minHeight: 35
				}}>
					<CNToolbar
						selectedTag={this.state.selectedTag}
						selectedStyles={this.state.selectedStyles}
						onStyleKeyPress={this.onStyleKeyPress}
						size={28}
						bold={<MaterialCommunityIcons name="format-bold" />}
						italic={<MaterialCommunityIcons name="format-italic" />}
						underline={<MaterialCommunityIcons name="format-underline" />}
						lineThrough={<MaterialCommunityIcons name="format-strikethrough-variant" />}
						body={<MaterialCommunityIcons name="format-text" />}
						title={<MaterialCommunityIcons name="format-header-1" />}
						heading={<MaterialCommunityIcons name="format-header-3" />}
						ul={<MaterialCommunityIcons name="format-list-bulleted" />}
						ol={<MaterialCommunityIcons name="format-list-numbers" />}
						image={this.renderImageSelector()}
						foreColor={this.renderColorSelector()}
						highlight={this.renderHighlight()}
					/>
				</View>
			</KeyboardAvoidingView>
		);
	}
}

var styles = StyleSheet.create({
	main: {
		flex: 1,
		paddingTop: 0,
		paddingLeft: 30,
		paddingRight: 30,
		paddingBottom: 1,
		alignItems: 'stretch',

	},
});

Image -- this is the error

it saying is undefiend bold, when im trying to use it

Editor shows text starting from the end rather than the beginning

Hi,
Thank you for this amazing library, is very useful.
Sometimes I have a long string of text as the initial value of the editor. But when the text surpasses the height of the screen, the editor goes right to the end of the text rather than the start. I would like the editor to initially show the top or start of the text to give the user a clear idea of where he is at. This is an iOS app.
I found a related post in stackoverflow but still doesn't work. Is there a way to do that?

react-native-web support

Is it possible to gain compatibility with react-native-web?

At the moment it just renders a textarea with [object Object] as value, the problem seems to be rendering children in textarea. Or do you have a recommendation for a web editor who works nice with the html output?

Thanks for the great work

Custom style not working for Unordered list

I'm using the latest version of the package. The unordered list doesn't have the custom style I applied when I create a new line. however, it works if I add a backspace after creating this line. You can find the interaction below:

interaction-demo

Initial Styles doesn't work

Hi, I can not make styles work

this.state.value = convertToObject(html)

this not works, editor does not getting styles from html

however, if user edits text than styles are working fine,
but cant make initial styles work

html is like

<div><p><span style="font-weight: bold">This should be a bold text</span></p></div>

and convertToObject(html) not attaching styles to it :(

Alt Text

Without expo

Does this package works without expo?

P.s. Sorry for second question, Iโ€™m really interested in this package, good job ๐Ÿ‘

Default Font Size of Editor

I've set the body style inside styleList to { fontSize:12 }.
But when I open the view which contains the editor,
the default fontSize of the input field is much larger than 12.

I checked into the source code, it seems that the initial fontSize of the editor is hardcoded to 20.

Will there be any enhancement on this?

copy paste does not update value in text

Hello there.

When i copy text to clipboard and paste it in the text editor, the editor records the length of text as 0 and text as nothing. I initially wanted to validate if the text editor is empty and so if you can help me with this on how i can validate it as empty or if i can override the copy paste method to add text to the value

CNRichTextView no Number of Lines

Hello, thank you for this awsome library first of all,

I saw 3 properties of CNRichTextView (Text, style, styleList). I want to make preview in a list like this
Screenshot_2019-08-14-09-58-30-581_host exp exponent

But unfortunately I can't limit the number of lines to make it good. Is it possible to limit the amount of text / container height to make the preview not too big?

Thanks

Typescript migration ?

First of all ; thanks so much for this amazing work!

If you're interested in migrating this repo to Typescript, I would be glad to participate.
I was also thinking about using a linter, as the source code is sometimes missing style consistency and a bit difficult to read.

Feature request: add tag & @someone

First of all, this project is awesome and enlighten me with new idea about how to handle rich text editor in react native.
In social app, we may like to add tag( linking to different topic such as #fancy movie, #beauty), or @Someone to notify someone whoever user like to.
The basic logic is:

  1. user click a button(hash btn or @ICON), new page opened where user can choose whatever the tag or user's name they like,
  2. once choose, navigate back to editor page, the tag or @Someone will be automatically attached to the content with highlighted color(like blue), people certainly can press backspace to remove it(one backspace and remove it, not letter by letter)

After all, the key is an API to attach a tag to content, and support to delete it with only one backspace.

Appreciate it!

CNRichTextView showing nothing

I'm trying to use <CNRichTextView text={text} /> but it doesn't seem to work.
I set text as simple html (<div><h1><span style="font-weight: bold;">Heading 1</span></h1></div> for example - that is produced by convertToHtmlString() ) but it just shows nothing at all.

If I convertToObject() and set it into CNRichTextEditor it works properly and shows up good.

I'm using a simple rendering without anything else in the screen.

Any idea what I'm doing wrong?

P.S.
It would be very useful to have a doc about CNRichTextView, since I discovered it exploring the src directory.

Text alignment

Is there a way to play with text alignment (align left, align right, center and justify) in your library ?

Editor is not checking existence of some optional props

The CNRichTextEditor props onSelectedTagChanged and onSelectedStyleChanged are listed in the README as optional. However, in CNRichTextEditor, it assumes these props exist.

e.g.

onSelectedStyleChanged = (styles) => {
    this.props.onSelectedStyleChanged(styles);
}

In CNTextInput, the props are checked:

if (this.props.onSelectedStyleChanged) {
    this.props.onSelectedStyleChanged(styles);
}

But if the props don't exist, it fails before it gets here, in CNRichTextEditor

Issue: How can I center the icons?

image

<CNToolbar .... style={{ alignItems: "center", flexDirection: "row" }} iconContainerStyle={{ alignItems: "center", flexDirection: "row" }}

CN toolbar not showing when keyboard is active

First I have to thank you all for the great work.

The example app works just fine. but when I copied the example as is to my app (which is expo tabs app) I only change "app" to "EditorScreen" issues emerged like:
1- The toolbar not showing when keyboard is active
2- Unable to select text

What have I missed?

code and screenshots:

import React, { Component } from 'react';
import { View, StyleSheet, Keyboard
, TouchableWithoutFeedback, Text, Dimensions
, KeyboardAvoidingView, Platform } from 'react-native';
import { Permissions, ImagePicker } from 'expo';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import CNRichTextEditor , { CNToolbar, getInitialObject , getDefaultStyles } from "react-native-cn-richtext-editor";

import {
Menu,
MenuOptions,
MenuOption,
MenuTrigger,
MenuContext,
MenuProvider,
renderers
} from 'react-native-popup-menu';

const { SlideInMenu } = renderers;

const IS_IOS = Platform.OS === 'ios';
const { width, height } = Dimensions.get('window');
const defaultStyles = getDefaultStyles();

class EditorScreen extends React.Component {

constructor(props) {
    super(props);


    this.state = {
        selectedTag : 'body',
        selectedColor : 'default',
        selectedHighlight: 'default',
        colors : ['red', 'green', 'blue'],
        highlights:['yellow_hl','pink_hl', 'orange_hl', 'green_hl','purple_hl','blue_hl'],
        selectedStyles : [],
        value: [getInitialObject]
    };

    this.state.value = [getInitialObject()];

    this.editor = null;

}

onStyleKeyPress = (toolType) => {

    if (toolType == 'image') {
        return;
    }
    else {
        this.editor.applyToolbar(toolType);
    }

}

onSelectedTagChanged = (tag) => {

    this.setState({
        selectedTag: tag
    })
}

onSelectedStyleChanged = (styles) => {
    const colors = this.state.colors;
    const highlights = this.state.highlights;
    let sel = styles.filter(x=> colors.indexOf(x) >= 0);

    let hl = styles.filter(x=> highlights.indexOf(x) >= 0);
    this.setState({
        selectedStyles: styles,
        selectedColor : (sel.length > 0) ? sel[sel.length - 1] : 'default',
        selectedHighlight : (hl.length > 0) ? hl[hl.length - 1] : 'default',
    })

}

onValueChanged = (value) => {
    this.setState({
        value: value
    });
}

insertImage(url) {

    this.editor.insertImage(url);
}

askPermissionsAsync = async () => {
    const camera = await Permissions.askAsync(Permissions.CAMERA);
    const cameraRoll = await Permissions.askAsync(Permissions.CAMERA_ROLL);

    this.setState({
    hasCameraPermission: camera.status === 'granted',
    hasCameraRollPermission: cameraRoll.status === 'granted'
    });
};

useLibraryHandler = async () => {
    await this.askPermissionsAsync();
    let result = await ImagePicker.launchImageLibraryAsync({
    allowsEditing: true,
    aspect: [4, 4],
    base64: false,
    });

    this.insertImage(result.uri);
};

useCameraHandler = async () => {
    await this.askPermissionsAsync();
    let result = await ImagePicker.launchCameraAsync({
    allowsEditing: true,
    aspect: [4, 4],
    base64: false,
    });
    console.log(result);

    this.insertImage(result.uri);
};

onImageSelectorClicked = (value) => {
    if(value == 1) {
        this.useCameraHandler();
    }
    else if(value == 2) {
        this.useLibraryHandler();
    }

}

onColorSelectorClicked = (value) => {

    if(value === 'default') {
        this.editor.applyToolbar(this.state.selectedColor);
    }
    else {
        this.editor.applyToolbar(value);

    }

    this.setState({
        selectedColor: value
    });
}

onHighlightSelectorClicked = (value) => {
    if(value === 'default') {
        this.editor.applyToolbar(this.state.selectedHighlight);
    }
    else {
        this.editor.applyToolbar(value);

    }

    this.setState({
        selectedHighlight: value
    });
}

renderImageSelector() {
    return (
        <Menu renderer={SlideInMenu} onSelect={this.onImageSelectorClicked}>
        <MenuTrigger>
            <MaterialCommunityIcons name="image" size={28} color="#737373" />
        </MenuTrigger>
        <MenuOptions>
            <MenuOption value={1}>
                <Text style={styles.menuOptionText}>
                    Take Photo
                </Text>
            </MenuOption>
            <View style={styles.divider}/>
            <MenuOption value={2} >
                <Text style={styles.menuOptionText}>
                    Photo Library
                </Text>
            </MenuOption>
            <View style={styles.divider}/>
            <MenuOption value={3}>
                <Text style={styles.menuOptionText}>
                    Cancel
                </Text>
            </MenuOption>
        </MenuOptions>
        </Menu>
    );

}

renderColorMenuOptions = () => {

    let lst = [];

    if(defaultStyles[this.state.selectedColor]) {
         lst = this.state.colors.filter(x => x !== this.state.selectedColor);
         lst.push('default');
        lst.push(this.state.selectedColor);
    }
    else {
        lst = this.state.colors.filter(x=> true);
        lst.push('default');
    }

    return (

        lst.map( (item) => {
            let color = defaultStyles[item] ? defaultStyles[item].color : 'black';
            return (
                <MenuOption value={item} key={item}>
                    <MaterialCommunityIcons name="format-color-text" color={color}
                    size={28} />
                </MenuOption>
            );
        })

    );
}

renderHighlightMenuOptions = () => {
    let lst = [];

    if(defaultStyles[this.state.selectedHighlight]) {
         lst = this.state.highlights.filter(x => x !== this.state.selectedHighlight);
         lst.push('default');
        lst.push(this.state.selectedHighlight);
    }
    else {
        lst = this.state.highlights.filter(x=> true);
        lst.push('default');
    }



    return (

        lst.map( (item) => {
            let bgColor = defaultStyles[item] ? defaultStyles[item].backgroundColor : 'black';
            return (
                <MenuOption value={item} key={item}>
                    <MaterialCommunityIcons name="marker" color={bgColor}
                    size={26} />
                </MenuOption>
            );
        })

    );
}

renderColorSelector() {

    let selectedColor = '#737373';
    if(defaultStyles[this.state.selectedColor])
    {
        selectedColor = defaultStyles[this.state.selectedColor].color;
    }


    return (
        <Menu renderer={SlideInMenu} onSelect={this.onColorSelectorClicked}>
        <MenuTrigger>
            <MaterialCommunityIcons name="format-color-text" color={selectedColor}
                    size={28} style={{
                        top:2
                    }} />
        </MenuTrigger>
        <MenuOptions customStyles={optionsStyles}>
            {this.renderColorMenuOptions()}
        </MenuOptions>
        </Menu>
    );
}

renderHighlight() {
    let selectedColor = '#737373';
    if(defaultStyles[this.state.selectedHighlight])
    {
        selectedColor = defaultStyles[this.state.selectedHighlight].backgroundColor;
    }
    return (
        <Menu renderer={SlideInMenu} onSelect={this.onHighlightSelectorClicked}>
        <MenuTrigger>
            <MaterialCommunityIcons name="marker" color={selectedColor}
                    size={24} style={{
                    }} />
        </MenuTrigger>
        <MenuOptions customStyles={highlightOptionsStyles}>
            {this.renderHighlightMenuOptions()}
        </MenuOptions>
        </Menu>
    );
}

render() {
    return (
        <KeyboardAvoidingView
        behavior="padding"
        enabled
        keyboardVerticalOffset={IS_IOS ? 0 : 0}
        style={{
            flex: 1,
            paddingTop: 20,
            backgroundColor:'#eee',
            flexDirection: 'column',
            justifyContent: 'flex-end',
        }}
        >
        <MenuProvider style={{flex: 1}}>
            <TouchableWithoutFeedback onPress={Keyboard.dismiss} >
                <View style={styles.main}>
                    <CNRichTextEditor
                        ref={input => this.editor = input}
                        onSelectedTagChanged={this.onSelectedTagChanged}
                        onSelectedStyleChanged={this.onSelectedStyleChanged}
                        value={this.state.value}
                        style={{ backgroundColor : '#fff'}}
                        styleList={defaultStyles}
                        //foreColor=''
                        onValueChanged={this.onValueChanged}
                        //onRemoveImage={this.onRemoveImage}
                    />
                </View>
            </TouchableWithoutFeedback>

            <View style={{
                minHeight: 35
            }}>

                <CNToolbar
                    size={28}
                    bold={<MaterialCommunityIcons name="format-bold" />}
                    italic={<MaterialCommunityIcons name="format-italic" />}
                    underline={<MaterialCommunityIcons name="format-underline" />}
                    lineThrough={<MaterialCommunityIcons name="format-strikethrough-variant" />}
                    body={<MaterialCommunityIcons name="format-text" />}
                    title={<MaterialCommunityIcons name="format-header-1" />}
                    heading={<MaterialCommunityIcons name="format-header-3" />}
                    ul={<MaterialCommunityIcons name="format-list-bulleted" />}
                    ol={<MaterialCommunityIcons name="format-list-numbers" />}
                    image={this.renderImageSelector()}
                    foreColor={this.renderColorSelector()}
                    highlight={this.renderHighlight()}
                    selectedTag={this.state.selectedTag}
                    selectedStyles={this.state.selectedStyles}
                    onStyleKeyPress={this.onStyleKeyPress} />
            </View>
        </MenuProvider>
    </KeyboardAvoidingView>
    );
}

}

var styles = StyleSheet.create({
main: {
flex: 1,
marginTop: 10,
paddingLeft: 30,
paddingRight: 30,
paddingBottom: 1,
alignItems: 'stretch',
},
menuOptionText: {
textAlign: 'center',
paddingTop: 5,
paddingBottom: 5
},
divider: {
marginVertical: 0,
marginHorizontal: 0,
borderBottomWidth: 1,
borderColor: '#eee'
}
});

const optionsStyles = {
optionsContainer: {
backgroundColor: 'yellow',
padding: 0,
width: 40,
marginLeft: width - 40 - 30,
alignItems: 'flex-end',
},
optionsWrapper: {
//width: 40,
backgroundColor: 'white',
},
optionWrapper: {
//backgroundColor: 'yellow',
margin: 2,
},
optionTouchable: {
underlayColor: 'gold',
activeOpacity: 70,
},
// optionText: {
// color: 'brown',
// },
};

const highlightOptionsStyles = {
optionsContainer: {
backgroundColor: 'transparent',
padding: 0,
width: 40,
marginLeft: width - 40,

alignItems: 'flex-end',

},
optionsWrapper: {
//width: 40,
backgroundColor: 'white',
},
optionWrapper: {
//backgroundColor: 'yellow',
margin: 2,
},
optionTouchable: {
underlayColor: 'gold',
activeOpacity: 70,
},
// optionText: {
// color: 'brown',
// },
};

export default EditorScreen;

a1
a2

How to manage videos?

Hi,
I want to upload videos from this text editor in react native expo, every other thing is working fine, but I am unable to work on how to add/embed videos.
Can anyone help me who has modified this library?

Change Color of Icons

<CNToolbar
size={28}

                    bold={<MaterialCommunityIcons 
                        name="format-bold"
                        size={12}
                        color="#0120c1" />}
                    italic={<MaterialCommunityIcons 
                        name="format-italic"
                        color="#ffffff"  />}
                    underline={
                        <MaterialCommunityIcons 
                        name="format-underline"
                        color="#ffffff"  />
                    }
                    lineThrough={
                        <MaterialCommunityIcons 
                        name="format-strikethrough-variant"
                        color="#ffffff"  />
                    }
                    body={<MaterialCommunityIcons name="format-text" />}
                    title={
                        <MaterialCommunityIcons name="format-header-1" />
                    }
                    heading={
                        <MaterialCommunityIcons name="format-header-3" />
                    }
                    ul={
                        <MaterialCommunityIcons name="format-list-bulleted" />
                    }
                    ol={
                        <MaterialCommunityIcons name="format-list-numbers" />
                    }
                    indent={
                        <MaterialCommunityIcons name="format-list-numbers" />
                    }
                    foreColor={this.renderColorSelector()}
                    highlight={this.renderHighlight()}
                    selectedTag={this.state.selectedTag}
                    selectedStyles={this.state.selectedStyles}
                    onStyleKeyPress={this.onStyleKeyPress}
                />

This code should change the color of the first 4 icons (and the size of the first) but they stay the same size and color, regardless of what i make the values

Bug: CNRichTextView failed to render normal text

I play around the basic logic that convert editor value to html by convertToHtmlString (assuming to save it in db), and directly convert the result back to object by convertToObject, render the result through CNRichTextView. There is error that stop it from rendering anything.
Here are some snapshots and piece of demo code.
{this.state.back && <CNRichTextView text={this.state.back} />}

  demo = () => {
    const res = convertToHtmlString(this.state.value);
    console.log(res);
    const back = convertToObject(res);
    console.log(back);
    this.setState({ back });
  };

screen shot 2019-03-08 at 11 25 27 am

screen shot 2019-03-08 at 11 25 38 am

screen shot 2019-03-08 at 11 25 51 am

Serious bug when input Chinese or other word in such case(see the pic)

When input Chinese
screen shot 2019-02-19 at 3 00 12 am

When input English
screen shot 2019-02-19 at 3 03 25 am

When you type the word and see the light blue background behind unfinished, and then you will get bug when you press next button from soft keyboard: changing new line and the word just typed will be changed a little bit like from 'Googleed' to 'Googled'

Initial Value for Editor

If I edit the state.value, (changing it from getInitialObject()), the editor will no longer work

Keyboard Opens while scrolling through editor

When there is a lot of information in the editor, trying to scroll to the bottom and then place the cursor there brings up the keyboard right away. Is there a way to not trigger the keyboard onScroll, and only on the onPress?

How to change value programmatically

I am using react-native-cn-richtext-editor in my React Native app for Android. I am able to change the value of text input programmatically, but after value is updated on input field the value keeps repeating if i do any changes from UI(means even if i don't press submit button, pressSubmit is executing). I am pretty sure that i haven't done any mistake in calling the pressSubmit function. I also have tried the same using Modal(instead of Dialog), but that too didn't worked. I am sharing my code and versions i am using. Please tell me if my approach is correct or not. If not, then how can i make it work?

RN: 0.58.6
React: 16.6.3

pressSubmit = () => {
console.log('pressSubmit reached');
if(this.state.visible) {
this.editor.textInputs[0].props.items[0].text = this.editor.textInputs[0].props.items[0].text + ' : ' + this.state.modalValue;
} else {
this.editor.textInputs[0].props.items[0].text = this.editor.textInputs[0].props.items[0].text ;
}
this.setState({
visible : false,
});
}

render() {
return (
<Dialog.Container visible={this.state.visible}>
<Dialog.Title>Add Concept</Dialog.Title>
<Dialog.Input
value={this.state.modalValue}
onChangeText={(text) => this.setState({modalValue : text})}>
</Dialog.Input>
<Dialog.Button label="CANCEL" onPress={()=>{this.onCancelPress()}}/>
<Dialog.Button label="SUBMIT" onPress={()=>{this.pressSubmit()}}/>
</Dialog.Container>
)
}

Thanks in advance.

Place for title?

Is there a component which can serve as a place to put a title?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.