From de94e56da835014bdef74230ff38ae0822ccff2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0rfan=20=C5=9Eener?= <2094635+irfansener@users.noreply.github.com> Date: Tue, 4 Sep 2018 14:54:21 +0300 Subject: [PATCH 1/3] Init --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74c4ebe..f5a6d1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-mentions", - "version": "1.1.4", + "version": "0.0.1", "description": "Mentions textbox for React Native. Works on both ios and android", "main": "index.js", "scripts": { From 51b76e517906302584d0b5e6b71297aa6d8a427c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0rfan=20=C5=9Eener?= <2094635+irfansener@users.noreply.github.com> Date: Tue, 4 Sep 2018 14:54:42 +0300 Subject: [PATCH 2/3] Init --- index.js | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6772d30..293235c 100644 --- a/index.js +++ b/index.js @@ -1,2 +1,177 @@ -import MentionsTextInput from './src/MentionsTextInput'; -export default MentionsTextInput; +import React, { Component } from 'react'; +import { + Text, + View, + Animated, + TextInput, + FlatList, + ViewPropTypes +} from 'react-native'; +import PropTypes from 'prop-types'; + +export class MentionsTextInput extends Component { + constructor() { + super(); + this.state = { + textInputHeight: "", + isTrackingStarted: false, + suggestionRowHeight: new Animated.Value(0), + + } + this.isTrackingStarted = false; + this.previousChar = " "; + } + + componentWillMount() { + this.setState({ + textInputHeight: this.props.textInputMinHeight + }) + } + + componentWillReceiveProps(nextProps) { + if (!nextProps.value) { + this.resetTextbox(); + } else if (this.isTrackingStarted && !nextProps.horizontal && nextProps.suggestionsData.length !== 0) { + const numOfRows = nextProps.MaxVisibleRowCount >= nextProps.suggestionsData.length ? nextProps.suggestionsData.length : nextProps.MaxVisibleRowCount; + const height = numOfRows * nextProps.suggestionRowHeight; + this.openSuggestionsPanel(height); + } + } + + startTracking() { + this.isTrackingStarted = true; + this.openSuggestionsPanel(); + this.setState({ + isTrackingStarted: true + }) + } + + stopTracking() { + this.isTrackingStarted = false; + this.closeSuggestionsPanel(); + this.setState({ + isTrackingStarted: false + }) + } + + openSuggestionsPanel(height) { + Animated.timing(this.state.suggestionRowHeight, { + toValue: height ? height : this.props.suggestionRowHeight, + duration: 100, + }).start(); + } + + closeSuggestionsPanel() { + Animated.timing(this.state.suggestionRowHeight, { + toValue: 0, + duration: 100, + }).start(); + } + + updateSuggestions(lastKeyword) { + this.props.triggerCallback(lastKeyword); + } + + identifyKeyword(val) { + if (this.isTrackingStarted) { + const boundary = this.props.triggerLocation === 'new-word-only' ? 'B' : ''; + const pattern = new RegExp(`\\${boundary}${this.props.trigger}[a-z0-9_-]+|\\${boundary}${this.props.trigger}`, `gi`); + const keywordArray = val.match(pattern); + if (keywordArray && !!keywordArray.length) { + const lastKeyword = keywordArray[keywordArray.length - 1]; + this.updateSuggestions(lastKeyword); + } + } + } + + onChangeText(val) { + this.props.onChangeText(val); // pass changed text back + const lastChar = val.substr(val.length - 1); + const wordBoundry = (this.props.triggerLocation === 'new-word-only') ? this.previousChar.trim().length === 0 : true; + if (lastChar === this.props.trigger && wordBoundry) { + this.startTracking(); + } else if (lastChar === ' ' && this.state.isTrackingStarted || val === "") { + this.stopTracking(); + } + this.previousChar = lastChar; + this.identifyKeyword(val); + } + + resetTextbox() { + this.previousChar = " "; + this.stopTracking(); + this.setState({ textInputHeight: this.props.textInputMinHeight }); + } + + render() { + return ( + + + { return this.props.renderSuggestionsRow(rowData, this.stopTracking.bind(this)) }} + /> + + { + this.setState({ + textInputHeight: this.props.textInputMinHeight >= event.nativeEvent.contentSize.height ? this.props.textInputMinHeight : event.nativeEvent.contentSize.height + 10, + }); + }} + ref={input => this.props.refer(input)} + onChangeText={this.onChangeText.bind(this)} + multiline={this.props.multiline || false} + value={this.props.value} + style={[{ ...this.props.textInputStyle }]} + placeholder={this.props.placeholder ? this.props.placeholder : 'Write a comment...'} + /> + + ) + } +} + +MentionsTextInput.propTypes = { + textInputStyle: TextInput.propTypes.style, + suggestionsPanelStyle: ViewPropTypes.style, + loadingComponent: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.element, + ]), + textInputMinHeight: PropTypes.number, + textInputMaxHeight: PropTypes.number, + trigger: PropTypes.string.isRequired, + triggerLocation: PropTypes.oneOf(['new-word-only', 'anywhere']).isRequired, + value: PropTypes.string.isRequired, + onChangeText: PropTypes.func.isRequired, + triggerCallback: PropTypes.func.isRequired, + renderSuggestionsRow: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.element, + ]).isRequired, + suggestionsData: PropTypes.array.isRequired, + keyExtractor: PropTypes.func.isRequired, + horizontal: PropTypes.bool, + suggestionRowHeight: PropTypes.number.isRequired, + MaxVisibleRowCount: function(props, propName, componentName) { + if(!props.horizontal && !props.MaxVisibleRowCount) { + return new Error( + `Prop 'MaxVisibleRowCount' is required if horizontal is set to false.` + ); + } + } +}; + +MentionsTextInput.defaultProps = { + textInputStyle: { borderColor: '#ebebeb', borderWidth: 1, fontSize: 15 }, + suggestionsPanelStyle: { backgroundColor: 'rgba(100,100,100,0.1)' }, + loadingComponent: () => Loading..., + textInputMinHeight: 30, + textInputMaxHeight: 80, + horizontal: true, +} From aaa81633c08da5a8ddb5fc8df2c804397fc73f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0rfan=20=C5=9Eener?= <2094635+irfansener@users.noreply.github.com> Date: Tue, 4 Sep 2018 14:54:57 +0300 Subject: [PATCH 3/3] Delete MentionsTextInput.js --- src/MentionsTextInput.js | 177 --------------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 src/MentionsTextInput.js diff --git a/src/MentionsTextInput.js b/src/MentionsTextInput.js deleted file mode 100644 index 41d9d6b..0000000 --- a/src/MentionsTextInput.js +++ /dev/null @@ -1,177 +0,0 @@ -import React, { Component } from 'react'; -import { - Text, - View, - Animated, - TextInput, - FlatList, - ViewPropTypes -} from 'react-native'; -import PropTypes from 'prop-types'; - -export default class MentionsTextInput extends Component { - constructor() { - super(); - this.state = { - textInputHeight: "", - isTrackingStarted: false, - suggestionRowHeight: new Animated.Value(0), - - } - this.isTrackingStarted = false; - this.previousChar = " "; - } - - componentWillMount() { - this.setState({ - textInputHeight: this.props.textInputMinHeight - }) - } - - componentWillReceiveProps(nextProps) { - if (!nextProps.value) { - this.resetTextbox(); - } else if (this.isTrackingStarted && !nextProps.horizontal && nextProps.suggestionsData.length !== 0) { - const numOfRows = nextProps.MaxVisibleRowCount >= nextProps.suggestionsData.length ? nextProps.suggestionsData.length : nextProps.MaxVisibleRowCount; - const height = numOfRows * nextProps.suggestionRowHeight; - this.openSuggestionsPanel(height); - } - } - - startTracking() { - this.isTrackingStarted = true; - this.openSuggestionsPanel(); - this.setState({ - isTrackingStarted: true - }) - } - - stopTracking() { - this.isTrackingStarted = false; - this.closeSuggestionsPanel(); - this.setState({ - isTrackingStarted: false - }) - } - - openSuggestionsPanel(height) { - Animated.timing(this.state.suggestionRowHeight, { - toValue: height ? height : this.props.suggestionRowHeight, - duration: 100, - }).start(); - } - - closeSuggestionsPanel() { - Animated.timing(this.state.suggestionRowHeight, { - toValue: 0, - duration: 100, - }).start(); - } - - updateSuggestions(lastKeyword) { - this.props.triggerCallback(lastKeyword); - } - - identifyKeyword(val) { - if (this.isTrackingStarted) { - const boundary = this.props.triggerLocation === 'new-word-only' ? 'B' : ''; - const pattern = new RegExp(`\\${boundary}${this.props.trigger}[a-z0-9_-]+|\\${boundary}${this.props.trigger}`, `gi`); - const keywordArray = val.match(pattern); - if (keywordArray && !!keywordArray.length) { - const lastKeyword = keywordArray[keywordArray.length - 1]; - this.updateSuggestions(lastKeyword); - } - } - } - - onChangeText(val) { - this.props.onChangeText(val); // pass changed text back - const lastChar = val.substr(val.length - 1); - const wordBoundry = (this.props.triggerLocation === 'new-word-only') ? this.previousChar.trim().length === 0 : true; - if (lastChar === this.props.trigger && wordBoundry) { - this.startTracking(); - } else if (lastChar === ' ' && this.state.isTrackingStarted || val === "") { - this.stopTracking(); - } - this.previousChar = lastChar; - this.identifyKeyword(val); - } - - resetTextbox() { - this.previousChar = " "; - this.stopTracking(); - this.setState({ textInputHeight: this.props.textInputMinHeight }); - } - - render() { - return ( - - - { return this.props.renderSuggestionsRow(rowData, this.stopTracking.bind(this)) }} - /> - - { - this.setState({ - textInputHeight: this.props.textInputMinHeight >= event.nativeEvent.contentSize.height ? this.props.textInputMinHeight : event.nativeEvent.contentSize.height + 10, - }); - }} - ref={component => this._textInput = component} - onChangeText={this.onChangeText.bind(this)} - multiline={true} - value={this.props.value} - style={[{ ...this.props.textInputStyle }, { height: Math.min(this.props.textInputMaxHeight, this.state.textInputHeight) }]} - placeholder={this.props.placeholder ? this.props.placeholder : 'Write a comment...'} - /> - - ) - } -} - -MentionsTextInput.propTypes = { - textInputStyle: TextInput.propTypes.style, - suggestionsPanelStyle: ViewPropTypes.style, - loadingComponent: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.element, - ]), - textInputMinHeight: PropTypes.number, - textInputMaxHeight: PropTypes.number, - trigger: PropTypes.string.isRequired, - triggerLocation: PropTypes.oneOf(['new-word-only', 'anywhere']).isRequired, - value: PropTypes.string.isRequired, - onChangeText: PropTypes.func.isRequired, - triggerCallback: PropTypes.func.isRequired, - renderSuggestionsRow: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.element, - ]).isRequired, - suggestionsData: PropTypes.array.isRequired, - keyExtractor: PropTypes.func.isRequired, - horizontal: PropTypes.bool, - suggestionRowHeight: PropTypes.number.isRequired, - MaxVisibleRowCount: function(props, propName, componentName) { - if(!props.horizontal && !props.MaxVisibleRowCount) { - return new Error( - `Prop 'MaxVisibleRowCount' is required if horizontal is set to false.` - ); - } - } -}; - -MentionsTextInput.defaultProps = { - textInputStyle: { borderColor: '#ebebeb', borderWidth: 1, fontSize: 15 }, - suggestionsPanelStyle: { backgroundColor: 'rgba(100,100,100,0.1)' }, - loadingComponent: () => Loading..., - textInputMinHeight: 30, - textInputMaxHeight: 80, - horizontal: true, -}