├── .gitignore ├── .watchmanconfig ├── App.js ├── app.json ├── assets ├── icon.png └── splash.png ├── babel.config.js ├── components ├── Header.js ├── InputBar.js └── TodoItem.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p12 6 | *.key 7 | *.mobileprovision 8 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Platform, StyleSheet, Text, View, FlatList } from 'react-native'; 3 | import Header from './components/Header'; 4 | import InputBar from './components/InputBar'; 5 | import TodoItem from './components/TodoItem'; 6 | 7 | export default class App extends React.Component { 8 | constructor () { 9 | super(); 10 | 11 | this.state = { 12 | todoInput: '', 13 | todos: [ 14 | { id: 0, title: 'Take out the trash', done: false }, 15 | { id: 1, title: 'Cook dinner', done: false } 16 | ] 17 | } 18 | } 19 | 20 | addNewTodo () { 21 | let todos = this.state.todos; 22 | 23 | todos.unshift({ 24 | id: todos.length + 1, 25 | title: this.state.todoInput, 26 | done: false 27 | }); 28 | 29 | this.setState({ 30 | todos: todos, 31 | todoInput: '' 32 | }); 33 | } 34 | 35 | toggleDone (item) { 36 | let todos = this.state.todos; 37 | 38 | todos = todos.map((todo) => { 39 | if (todo.id == item.id) { 40 | todo.done = !todo.done; 41 | } 42 | 43 | return todo; 44 | }) 45 | 46 | this.setState({todos}); 47 | } 48 | 49 | removeTodo (item) { 50 | let todos = this.state.todos; 51 | 52 | todos = todos.filter((todo) => todo.id !== item.id); 53 | 54 | this.setState({todos}); 55 | } 56 | 57 | render() { 58 | const statusbar = (Platform.OS == 'ios') ? : ; 59 | 60 | return ( 61 | 62 | {statusbar} 63 | 64 |
65 | 66 | this.addNewTodo()} 68 | textChange={todoInput => this.setState({ todoInput })} 69 | todoInput={this.state.todoInput} 70 | /> 71 | 72 | index.toString()} 76 | renderItem={({item, index}) => { 77 | return ( 78 | this.toggleDone(item)} removeTodo={() => this.removeTodo(item)} /> 79 | ) 80 | }} 81 | /> 82 | 83 | ); 84 | } 85 | } 86 | 87 | const styles = StyleSheet.create({ 88 | container: { 89 | flex: 1, 90 | backgroundColor: '#fff', 91 | }, 92 | statusbar: { 93 | backgroundColor: '#FFCE00', 94 | height: 20 95 | } 96 | }); 97 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "React Native Todo application", 4 | "slug": "todo-app", 5 | "privacy": "public", 6 | "sdkVersion": "32.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android" 10 | ], 11 | "version": "1.0.0", 12 | "orientation": "portrait", 13 | "icon": "./assets/icon.png", 14 | "splash": { 15 | "image": "./assets/splash.png", 16 | "resizeMode": "contain", 17 | "backgroundColor": "#ffffff" 18 | }, 19 | "updates": { 20 | "fallbackToCacheTimeout": 0 21 | }, 22 | "assetBundlePatterns": [ 23 | "**/*" 24 | ], 25 | "ios": { 26 | "supportsTablet": true 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TylerPottsDev/react-native-todo-app/a25c7d57672258d8868602c1185bd5b91c5bb2cd/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TylerPottsDev/react-native-todo-app/a25c7d57672258d8868602c1185bd5b91c5bb2cd/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /components/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, View } from 'react-native'; 3 | 4 | const Header = (props) => { 5 | return ( 6 | 7 | { props.title } 8 | 9 | ) 10 | } 11 | 12 | const styles = StyleSheet.create({ 13 | header: { 14 | backgroundColor: '#171717', 15 | height: 60, 16 | alignItems: 'center', 17 | justifyContent: 'center' 18 | }, 19 | title: { 20 | color: '#F3F3F3', 21 | fontSize: 28, 22 | fontWeight: '900', 23 | textTransform: 'uppercase' 24 | } 25 | }); 26 | 27 | export default Header; -------------------------------------------------------------------------------- /components/InputBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native'; 3 | 4 | const InputBar = (props) => { 5 | return ( 6 | 7 | props.textChange(todoInput)} 10 | value={props.todoInput} 11 | /> 12 | 13 | ADD 14 | 15 | 16 | ) 17 | } 18 | 19 | const styles = StyleSheet.create({ 20 | inputContainer: { 21 | flexDirection: 'row', 22 | justifyContent: 'space-between', 23 | shadowOffset: { width: 0, height: 3 }, 24 | shadowColor: '#171717', 25 | shadowOpacity: .1 26 | }, 27 | input: { 28 | backgroundColor: '#F3F3F3', 29 | flex: 1, 30 | fontSize: 18, 31 | height: 35 32 | }, 33 | addButton: { 34 | width: 100, 35 | backgroundColor: '#FFCE00', 36 | alignItems: 'center', 37 | justifyContent: 'center' 38 | }, 39 | addButtonText: { 40 | color: '#171717', 41 | fontSize: 18, 42 | fontWeight: '700' 43 | } 44 | }) 45 | 46 | export default InputBar; -------------------------------------------------------------------------------- /components/TodoItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, Button, TouchableOpacity } from 'react-native'; 3 | 4 | export default class TodoItem extends React.Component { 5 | constructor (props) { 6 | super(props); 7 | } 8 | 9 | render () { 10 | const todoItem = this.props.todoItem; 11 | 12 | return ( 13 | this.props.toggleDone()} 16 | > 17 | 18 | { todoItem.title } 19 | 20 | 21 |