├── ContactForm.js ├── ContactItem.js ├── ContactView.js ├── README.md ├── index.html ├── main.js └── style.css /ContactForm.js: -------------------------------------------------------------------------------- 1 | var ContactForm = React.createClass({ 2 | propTypes: { 3 | contact: React.PropTypes.object.isRequired 4 | }, 5 | 6 | render: function() { 7 | return ( 8 | React.createElement('form', {className: 'ContactForm'}, 9 | React.createElement('input', { 10 | type: 'text', 11 | placeholder: 'Name (required)', 12 | value: this.props.contact.name, 13 | }), 14 | React.createElement('input', { 15 | type: 'email', 16 | placeholder: 'Email', 17 | value: this.props.contact.email, 18 | }), 19 | React.createElement('textarea', { 20 | placeholder: 'Description', 21 | value: this.props.contact.description, 22 | }), 23 | React.createElement('button', {type: 'submit'}, "Add Contact") 24 | ) 25 | ) 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /ContactItem.js: -------------------------------------------------------------------------------- 1 | var ContactItem = React.createClass({ 2 | propTypes: { 3 | name: React.PropTypes.string.isRequired, 4 | email: React.PropTypes.string, 5 | description: React.PropTypes.string, 6 | }, 7 | 8 | render: function() { 9 | return ( 10 | React.createElement('div', {className: 'ContactItem'}, 11 | React.createElement('div', {className: 'ContactItem-name'}, this.props.name), 12 | React.createElement('div', {className: 'ContactItem-email'}, this.props.email), 13 | React.createElement('div', {className: 'ContactItem-description'}, this.props.description) 14 | ) 15 | ) 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /ContactView.js: -------------------------------------------------------------------------------- 1 | var ContactView = React.createClass({ 2 | propTypes: { 3 | contacts: React.PropTypes.array.isRequired, 4 | newContact: React.PropTypes.object.isRequired, 5 | }, 6 | 7 | render: function() { 8 | var contactItemElements = this.props.contacts 9 | .filter(function(contact) { return contact.email }) 10 | .map(function(contact) { return React.createElement(ContactItem, contact) }) 11 | 12 | return ( 13 | React.createElement('div', {className: 'ContactView'}, 14 | React.createElement('h1', {className: 'ContactView-title'}, "Contacts"), 15 | React.createElement('ul', {className: 'ContactView-list'}, contactItemElements), 16 | React.createElement(ContactForm, { 17 | contact: this.props.newContact, 18 | }) 19 | ) 20 | ) 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn Raw React 2 | 3 | This repository holds the solution for the final exercise of [Learn Raw React, part 1](http://jamesknelson.com/learn-raw-react-no-jsx-flux-es6-webpack/). 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | My CRM 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Data 3 | */ 4 | 5 | var contacts = [ 6 | {key: 1, name: "James K Nelson", email: "james@jamesknelson.com", description: "Front-end Unicorn"}, 7 | {key: 2, name: "Jim", email: "jim@example.com"}, 8 | {key: 3, name: "Joe"}, 9 | ] 10 | 11 | var newContact = {name: "", email: "", description: ""} 12 | 13 | 14 | /* 15 | * Entry point 16 | */ 17 | 18 | ReactDOM.render( 19 | React.createElement(ContactView, { 20 | contacts: contacts, 21 | newContact: newContact 22 | }), 23 | document.getElementById('react-app') 24 | ) 25 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Tahoma, sans-serif; 3 | margin: 0; 4 | } 5 | 6 | .ContactView-title { 7 | font-size: 24px; 8 | padding: 0 24px; 9 | } 10 | 11 | .ContactView-list { 12 | list-style: none; 13 | margin: 0; 14 | padding: 0; 15 | border-top: 1px solid #f0f0f0; 16 | } 17 | 18 | .ContactItem { 19 | margin: 0; 20 | padding: 8px 24px; 21 | border-bottom: 1px solid #f0f0f0; 22 | } 23 | .ContactItem-name { 24 | font-size: 16px; 25 | font-weight: bold; 26 | margin: 0; 27 | } 28 | .ContactItem-email { 29 | font-size: 14px; 30 | margin-top: 4px; 31 | font-style: italic; 32 | color: #888; 33 | } 34 | .ContactItem-description { 35 | font-size: 14px; 36 | margin-top: 4px; 37 | } 38 | 39 | 40 | .ContactForm { 41 | padding: 8px 24px; 42 | } 43 | .ContactForm > input, 44 | .ContactForm > textarea { 45 | display: block; 46 | width: 240px; 47 | padding: 4px 8px; 48 | margin-bottom: 8px; 49 | border-radius: 3px; 50 | border: 1px solid #888; 51 | font-size: 14px; 52 | } 53 | --------------------------------------------------------------------------------