Skip to content
This repository has been archived by the owner on Jun 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #55 from abscess/master
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
peterp authored Sep 5, 2020
2 parents d5616b3 + d973dc0 commit 49ae7ff
Show file tree
Hide file tree
Showing 35 changed files with 14,871 additions and 5,680 deletions.
33 changes: 33 additions & 0 deletions Tags/Input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import { View, TextInput } from "react-native";

import styles from "./styles";

const Input = (props) => {

const {
value,
onChangeText,
onSubmitEditing,
inputStyle,
inputContainerStyle,
textInputProps
} = props;

return (
<View style={[styles.textInputContainer, inputContainerStyle]}>
<TextInput
{...textInputProps}
style={[styles.textInput, inputStyle]}
value={value}
onChangeText={onChangeText}
onSubmitEditing={onSubmitEditing}
underlineColorAndroid="transparent"
/>
</View>
);

};

export {Input};
export default Input;
20 changes: 10 additions & 10 deletions Tags/__tests__/Tags_enzyme-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe("Tags", () => {
wrapper
.find("Tag")
.at(1)
.simulate("press");
.simulate("press", { persist: jest.fn()});

expect(wrapper.find("Tag").length).toEqual(3);
});
Expand All @@ -32,18 +32,18 @@ describe("Tags", () => {
wrapper
.find("Tag")
.at(0)
.simulate("press");
.simulate("press", { persist: jest.fn()});

expect(wrapper.find("Tag").length).toEqual(4);
});
});

describe("TextInput", () => {
describe("Input", () => {
describe("onChangeText", () => {
it("should add a new tag when a space, or comma is detected", () => {
const onChangeTags = jest.fn();
const wrapper = shallow(<Tags onChangeTags={onChangeTags} />).find(
"TextInput"
"Input"
);
wrapper.simulate("ChangeText", "dog ");
expect(onChangeTags.mock.calls).toEqual([[["dog"]]]);
Expand All @@ -55,7 +55,7 @@ describe("Tags", () => {
const onChangeTags = jest.fn();
const wrapper = shallow(
<Tags createTagOnReturn onChangeTags={onChangeTags} />
).find("TextInput");
).find("Input");
wrapper.simulate("ChangeText", "dog");
wrapper.simulate("SubmitEditing");
expect(onChangeTags.mock.calls).toEqual([[["dog"]]]);
Expand All @@ -64,7 +64,7 @@ describe("Tags", () => {
it("should remove a tag when the text is empty", () => {
const onChangeTags = jest.fn();
const wrapper = shallow(<Tags onChangeTags={onChangeTags} />).find(
"TextInput"
"Input"
);
wrapper.simulate("ChangeText", "dog ");
expect(onChangeTags.mock.calls).toEqual([[["dog"]]]);
Expand All @@ -73,16 +73,16 @@ describe("Tags", () => {
});

it("text input should not be available if it's readyonly", () => {
const wrapper = shallow(<Tags readonly />).find("TextInput");
const wrapper = shallow(<Tags readonly />).find("Input");
expect(wrapper.length).toEqual(0);
});

it("textinput should dissapear after maxNumberOfTags is reached", () => {
it("input should dissapear after maxNumberOfTags is reached", () => {
const wrapper = shallow(
<Tags initialTags={["love"]} maxNumberOfTags={2} />
);
wrapper.find("TextInput").simulate("ChangeText", "dog ");
expect(wrapper.find("TextInput").length).toEqual(0);
wrapper.find("Input").simulate("ChangeText", "dog ");
expect(wrapper.find("Input").length).toEqual(0);
});
});
});
Expand Down
12 changes: 12 additions & 0 deletions Tags/__tests__/__snapshots__/Tags-tests.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ exports[` 1`] = `
>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down Expand Up @@ -52,7 +54,9 @@ exports[` 1`] = `
</View>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down Expand Up @@ -88,7 +92,9 @@ exports[` 1`] = `
</View>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down Expand Up @@ -246,7 +252,9 @@ exports[`Tags should render props correctly 1`] = `
>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down Expand Up @@ -282,7 +290,9 @@ exports[`Tags should render props correctly 1`] = `
</View>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down Expand Up @@ -318,7 +328,9 @@ exports[`Tags should render props correctly 1`] = `
</View>
<View
accessible={true}
focusable={true}
isTVSelectable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down
98 changes: 46 additions & 52 deletions Tags/index.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,49 @@
import React from "react";
import PropTypes from "prop-types";
import { View, TextInput } from "react-native";
import { View } from "react-native";

import Tag from "./Tag";
import Input from "./Input";
import styles from "./styles";

class Tags extends React.Component {

constructor(props) {
super(props);

this.state = {
tags: props.initialTags,
text: props.initialText
};
}

componentWillReceiveProps(props) {
const { initialTags = [], initialText = " " } = props;
};

this.setState({
tags: initialTags,
text: initialText
});
}
showLastTag = () => {
this.setState(state =>
({
tags: state.tags.slice(0, -1),
text: state.tags.slice(-1)[0] || " "
}),
() =>
this.props.onChangeTags && this.props.onChangeTags(this.state.tags)
);
};

addTag = text => {
this.setState(
{
tags: [...this.state.tags, text.trim()],
this.setState(state =>
({
tags: [...state.tags, text.trim()],
text: " "
},
}),
() => this.props.onChangeTags && this.props.onChangeTags(this.state.tags)
);
};

onChangeText = text => {
if (text.length === 0) {
// `onKeyPress` isn't currently supported on Android; I've placed an extra
// space character at the start of `TextInput` which is used to determine if the
// user is erasing.
this.setState(
{
tags: this.state.tags.slice(0, -1),
text: this.state.tags.slice(-1)[0] || " "
},
() =>
this.props.onChangeTags && this.props.onChangeTags(this.state.tags)
);
this.showLastTag();
} else if (
text.length > 1 &&
this.props.createTagOnString.includes(text.slice(-1)) &&
!text.match(new RegExp(`^[${this.props.createTagOnString.join("")}]+$`, 'g')) &&
!(this.state.tags.indexOf(text.slice(0, -1).trim()) > -1)
) {
this.addTag(text.slice(0, -1));
Expand All @@ -62,50 +56,50 @@ class Tags extends React.Component {
if (!this.props.createTagOnReturn) {
return;
}

this.addTag(this.state.text);
};

render() {

const {
containerStyle,
style,
readonly,
maxNumberOfTags,
tagContainerStyle,
tagTextStyle,
deleteTagOnPress,
onTagPress,
readonly,
maxNumberOfTags,
inputStyle,
inputContainerStyle,
textInputProps,
renderTag
} = this.props;

return (
<View style={[styles.container, containerStyle, style]}>

{this.state.tags.map((tag, index) => {

const tagProps = {
tag,
index,
deleteTagOnPress,
onPress: e => {
onPress: event => {
event.persist();
if (deleteTagOnPress && !readonly) {
this.setState(
{
this.setState(state =>
({
tags: [
...this.state.tags.slice(0, index),
...this.state.tags.slice(index + 1)
...state.tags.slice(0, index),
...state.tags.slice(index + 1)
]
},
}),
() => {
this.props.onChangeTags &&
this.props.onChangeTags(this.state.tags);
onTagPress && onTagPress(index, tag, e, true);
onTagPress && onTagPress(index, tag, event, true);
}
);
} else {
onTagPress && onTagPress(index, tag, e, false);
onTagPress && onTagPress(index, tag, event, false);
}
},
tagContainerStyle,
Expand All @@ -115,21 +109,21 @@ class Tags extends React.Component {
return renderTag(tagProps);
})}

{!readonly && maxNumberOfTags > this.state.tags.length && (
<View style={[styles.textInputContainer, inputContainerStyle]}>
<TextInput
{...textInputProps}
{!readonly
&& maxNumberOfTags > this.state.tags.length
&&
<Input
value={this.state.text}
style={[styles.textInput, inputStyle]}
onChangeText={this.onChangeText}
onChangeText={this.onChangeText}
onSubmitEditing={this.onSubmitEditing}
underlineColorAndroid="transparent"
{...this.props}
/>
</View>
)}
}

</View>
);
}
};

}

Tags.defaultProps = {
Expand Down Expand Up @@ -165,5 +159,5 @@ Tags.propTypes = {
textInputProps: PropTypes.object
};

export { Tag };
export default Tags;
export { Tags };
export default Tags;
4 changes: 4 additions & 0 deletions examples/ReactNativeTagsDemo/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: '@react-native-community',
};
Loading

0 comments on commit 49ae7ff

Please sign in to comment.