├── 14-ParcelJs
├── src
│ ├── App.css
│ ├── index.js
│ └── App.js
└── index.html
├── 17-React.Children
├── src
│ ├── App.css
│ ├── index.js
│ ├── SlideShow.js
│ ├── App.js
│ ├── SlideShow.css
│ └── SlideShow-Finished.js
└── index.html
├── 15-Fetching
├── src
│ ├── App.css
│ ├── index.js
│ ├── SearchBar.js
│ ├── App.js
│ ├── Users.css
│ ├── Users.js
│ ├── UserList.js
│ └── App-Finished.js
└── index.html
├── 16-Higher-Order-Component
├── src
│ ├── App.css
│ ├── index.js
│ ├── Loading.js
│ ├── SearchBar.js
│ ├── Users.css
│ ├── Loading-Finished.js
│ ├── Users.js
│ ├── UserList.js
│ ├── App.js
│ └── Loading.css
└── index.html
├── .babelrc
├── 12-create-react-app
├── src
│ ├── index.css
│ ├── index.js
│ ├── List.js
│ ├── Todo.js
│ └── Todo.css
├── public
│ ├── favicon.ico
│ └── index.html
├── .gitignore
└── package.json
├── 13-Firebase-rebase
├── src
│ ├── index.css
│ ├── index.js
│ ├── re-base.js
│ ├── List.js
│ ├── Todo.js
│ ├── Todo-Finished.js
│ └── Todo.css
├── public
│ ├── favicon.ico
│ └── index.html
├── .gitignore
└── package.json
├── 24-Lazy
├── src
│ ├── index.js
│ ├── User.js
│ └── App.js
└── index.html
├── 18-Toggler
├── src
│ ├── index.js
│ ├── Toggle.js
│ ├── Toggle-Finished.js
│ ├── Switch.js
│ └── App.css
└── index.html
├── 21-Context
├── src
│ ├── index.js
│ ├── Switch.js
│ ├── Toggle.js
│ ├── Toggle-Finished.js
│ └── App.css
└── index.html
├── 22-Render-Props
├── src
│ ├── index.js
│ ├── Toggle.js
│ ├── Toggle-Finished.js
│ ├── Switch.js
│ └── App.css
└── index.html
├── 19-Toggler-Composed
├── src
│ ├── index.js
│ ├── Toggle.js
│ ├── Switch.js
│ ├── Toggle-Finished.js
│ └── App.css
└── index.html
├── 20-Compound-Components
├── src
│ ├── index.js
│ ├── Switch.js
│ ├── Toggle.js
│ ├── Toggle-Finished.js
│ └── App.css
└── index.html
├── HELP.md
├── 23-HOC-Vs-RenderProps
├── src
│ ├── index.js
│ ├── App.js
│ ├── App-HOC.js
│ ├── App-RenderProps.js
│ └── App-Cool.js
└── index.html
├── 01-Hello-World
├── index-start.html
└── index-finished.html
├── 06-Rerender
├── index-start.html
└── index-finished.html
├── 05-Conditional-Render
├── index-start.html
└── index-finished.html
├── 02-JSX
├── index-start.html
└── index-finished.html
├── 04-propTypes
├── index-start.html
└── index-finished.html
├── 03-Functional-Components
├── index-start.html
└── index-finished.html
├── 10-Todo-App
├── index-start.js
├── index.html
├── index-finished.js
└── css
│ └── styles.css
├── package.json
├── .gitignore
├── Requirements.md
├── 09-Event-Handling
├── index-start.html
└── index-finished.html
├── 11-Component-Patterns
├── index.html
├── index-start.js
├── index-finished.js
└── css
│ └── styles.css
├── 07-Styling
└── index.html
├── 08-Component & Lifecycle
└── index.html
├── .eslintrc
└── README.md
/14-ParcelJs/src/App.css:
--------------------------------------------------------------------------------
1 | .Main {
2 | color: rebeccapurple;
3 | }
--------------------------------------------------------------------------------
/17-React.Children/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
--------------------------------------------------------------------------------
/15-Fetching/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | width: 400px;
3 | margin: auto;
4 | }
5 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | width: 400px;
3 | margin: auto;
4 | }
5 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "react", "stage-2"],
3 | "plugins": ["transform-decorators-legacy"]
4 | }
5 |
--------------------------------------------------------------------------------
/12-create-react-app/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vigzmv/Into-the-ReactJs/HEAD/13-Firebase-rebase/public/favicon.ico
--------------------------------------------------------------------------------
/12-create-react-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vigzmv/Into-the-ReactJs/HEAD/12-create-react-app/public/favicon.ico
--------------------------------------------------------------------------------
/24-Lazy/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render( , document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/14-ParcelJs/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render( , document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/15-Fetching/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render( , document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/17-React.Children/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render( , document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render( , document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/18-Toggler/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Toggle from './Toggle';
4 | import './App.css';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/21-Context/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Toggle from './Toggle';
4 | import './App.css';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/12-create-react-app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import Todo from './Todo';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import Todo from './Todo';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/22-Render-Props/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Toggle from './Toggle';
4 | import './App.css';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/19-Toggler-Composed/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Toggle from './Toggle';
4 | import './App.css';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/20-Compound-Components/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Toggle from './Toggle';
4 | import './App.css';
5 |
6 | ReactDOM.render( , document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/HELP.md:
--------------------------------------------------------------------------------
1 | #### Browser-sync server with live reloading
2 |
3 | ```sh
4 | # Install browser-sync
5 | $ sudo npm i -g browser-sync
6 |
7 | # Run browser-sync server
8 | $ browser-sync start --server --files "**/**" --no-notify --directory
9 | ```
10 |
--------------------------------------------------------------------------------
/14-ParcelJs/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import './App.css';
3 |
4 | class App extends Component {
5 | render() {
6 | return
Hello World!
;
7 | }
8 | }
9 |
10 | export default App;
11 |
--------------------------------------------------------------------------------
/18-Toggler/src/Toggle.js:
--------------------------------------------------------------------------------
1 | // state changing, defaultProps
2 |
3 | import React from 'react';
4 | import Switch from './Switch';
5 |
6 | class Toggle extends React.Component {
7 | render() {
8 | return ;
9 | }
10 | }
11 | export default Toggle;
12 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/Loading.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import './Loading.css';
3 |
4 | const isEmpty = prop =>
5 | prop === null ||
6 | prop === undefined ||
7 | (prop.hasOwnProperty('length') && prop.length === 0) ||
8 | (prop.constructor === Object && Object.keys(prop).length === 0);
9 |
--------------------------------------------------------------------------------
/23-HOC-Vs-RenderProps/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | // import App from './App-HOC';
6 | // import App from './App-RenderProps';
7 | // import App from './App-Cool';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 |
--------------------------------------------------------------------------------
/17-React.Children/src/SlideShow.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children } from 'react';
2 | // import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
3 | import './SlideShow.css';
4 |
5 | class SlideShow extends Component {
6 | render() {
7 | return {this.props.children}
;
8 | }
9 | }
10 |
11 | export default SlideShow;
12 |
--------------------------------------------------------------------------------
/15-Fetching/src/SearchBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const getInput = event => event.target.value;
4 |
5 | const SearchBar = ({ filterText, onUserInput }) => (
6 | onUserInput(getInput(event))}
11 | />
12 | );
13 |
14 | export default SearchBar;
15 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/SearchBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const getInput = event => event.target.value;
4 |
5 | const SearchBar = ({ filterText, onUserInput }) => (
6 | onUserInput(getInput(event))}
11 | />
12 | );
13 |
14 | export default SearchBar;
15 |
--------------------------------------------------------------------------------
/18-Toggler/src/Toggle-Finished.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Switch from './Switch';
3 |
4 | class Toggle extends React.Component {
5 | state = { on: false };
6 |
7 | toggle = () => this.setState({ on: !this.state.on });
8 |
9 | render() {
10 | const { on } = this.state;
11 | return ;
12 | }
13 | }
14 |
15 | export default Toggle;
16 |
--------------------------------------------------------------------------------
/12-create-react-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/15-Fetching/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | User List
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/17-React.Children/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Slideshow
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | User List
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/15-Fetching/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Users from './Users';
3 | import './App.css';
4 |
5 | class App extends Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = { users: [] };
9 | }
10 |
11 | render() {
12 | return (
13 |
14 |
15 |
16 | );
17 | }
18 | }
19 |
20 | export default App;
21 |
--------------------------------------------------------------------------------
/12-create-react-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "11-create-react-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.5.2",
7 | "react-dom": "^16.5.2",
8 | "react-scripts": "2.0.4"
9 | },
10 | "scripts": {
11 | "start": "react-scripts start",
12 | "build": "react-scripts build",
13 | "test": "react-scripts test --env=jsdom",
14 | "eject": "react-scripts eject"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/14-ParcelJs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React App
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "11-create-react-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "re-base": "^3.2.1",
7 | "react": "^16.5.2",
8 | "react-dom": "^16.5.2",
9 | "react-scripts": "2.0.4"
10 | },
11 | "scripts": {
12 | "start": "react-scripts start",
13 | "build": "react-scripts build",
14 | "test": "react-scripts test --env=jsdom",
15 | "eject": "react-scripts eject"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/19-Toggler-Composed/src/Toggle.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Switch from './Switch';
3 |
4 | class Toggle extends React.Component {
5 | state = { on: false };
6 |
7 | toggle = () => this.setState({ on: !this.state.on });
8 |
9 | render() {
10 | const { on } = this.state;
11 | return (
12 |
13 | {' '}
14 |
15 | );
16 | }
17 | }
18 |
19 | export default Toggle;
20 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/re-base.js:
--------------------------------------------------------------------------------
1 | const Rebase = require('re-base');
2 | const firebase = require('firebase/app');
3 | const database = require('firebase/database');
4 |
5 | const app = firebase.initializeApp({
6 | apiKey: 'AIzaSyA3qzYSGdBHYJc2O7tDAIhal3f1L14qd-s',
7 | authDomain: 'into-the-react.firebaseio.com',
8 | databaseURL: 'https://into-the-react.firebaseio.com/'
9 | });
10 | const db = firebase.database(app);
11 | const base = Rebase.createClass(db);
12 |
13 | export default base;
14 |
--------------------------------------------------------------------------------
/18-Toggler/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Toggler
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/21-Context/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Toggler
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/22-Render-Props/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Toggler
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/19-Toggler-Composed/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Toggler
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/20-Compound-Components/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Toggler
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/List.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function List(props) {
4 | return props.list.map((item, i) => (
5 |
6 | props.onRemove(i)}>
7 |
8 |
9 | props.onComplete(i)}>
10 |
11 |
12 | {item.content}
13 |
14 | ));
15 | }
16 |
17 | export default List;
18 |
--------------------------------------------------------------------------------
/12-create-react-app/src/List.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function List(props) {
4 | return props.list.map((item, i) => (
5 |
6 | props.onRemove(i)}>
7 |
8 |
9 | props.onComplete(i)}>
10 |
11 |
12 | {item.content}
13 |
14 | ));
15 | }
16 |
17 | export default List;
18 |
--------------------------------------------------------------------------------
/22-Render-Props/src/Toggle.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Switch from './Switch';
3 |
4 | class Toggle extends React.Component {
5 | state = { on: false };
6 |
7 | toggle = () => this.setState({ on: !this.state.on });
8 |
9 | render() {
10 | const { on } = this.state;
11 | return (
12 |
13 |
14 |
15 | );
16 | }
17 | }
18 |
19 | function ToggleApp() {
20 | return ;
21 | }
22 |
23 | export default ToggleApp;
24 |
--------------------------------------------------------------------------------
/17-React.Children/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import SlideShow from './SlideShow';
3 | import './App.css';
4 |
5 | class App extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | );
16 | }
17 | }
18 |
19 | export default App;
20 |
--------------------------------------------------------------------------------
/15-Fetching/src/Users.css:
--------------------------------------------------------------------------------
1 | .userApp {
2 | width: 400px;
3 | }
4 |
5 | .userApp > *{
6 | width: 100%;
7 | }
8 |
9 | ul {
10 | padding: 0;
11 | }
12 |
13 | li {
14 | list-style: none;
15 | margin: 5px;
16 | background:rgb(213, 218, 248);
17 |
18 | }
19 |
20 | .userData {
21 | padding: 10px;
22 | height: 95px;
23 | border: solid rgb(177, 227, 247) 1px;
24 | text-transform: capitalize;
25 | }
26 |
27 | li img{
28 | /* border-radius: 50%; */
29 | margin-right: 20px;
30 | margin-left: 5px;
31 | margin-bottom: 5px;
32 | margin-top: 5px;
33 | float: left;
34 | }
35 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/Users.css:
--------------------------------------------------------------------------------
1 | .userApp {
2 | width: 400px;
3 | }
4 |
5 | .userApp > *{
6 | width: 100%;
7 | }
8 |
9 | ul {
10 | padding: 0;
11 | }
12 |
13 | li {
14 | list-style: none;
15 | margin: 5px;
16 | background:rgb(213, 218, 248);
17 |
18 | }
19 |
20 | .userData {
21 | padding: 10px;
22 | height: 95px;
23 | border: solid rgb(177, 227, 247) 1px;
24 | text-transform: capitalize;
25 | }
26 |
27 | li img{
28 | /* border-radius: 50%; */
29 | margin-right: 20px;
30 | margin-left: 5px;
31 | margin-bottom: 5px;
32 | margin-top: 5px;
33 | float: left;
34 | }
35 |
--------------------------------------------------------------------------------
/24-Lazy/src/User.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const User = props => {
4 | const { user } = props;
5 | return (
6 |
18 | );
19 | };
20 |
21 | export default User;
22 |
--------------------------------------------------------------------------------
/17-React.Children/src/SlideShow.css:
--------------------------------------------------------------------------------
1 | .example-enter {
2 | opacity: 0.01;
3 | }
4 |
5 | .example-enter.example-enter-active {
6 | opacity: 1;
7 | transition: opacity 800ms ease-in;
8 | }
9 |
10 | .example-leave {
11 | opacity: 1;
12 | }
13 |
14 | .example-leave.example-leave-active {
15 | opacity: 0.01;
16 | transition: opacity 800ms ease-in;
17 | }
18 |
19 | .group {
20 | display: block;
21 | position: relative;
22 | width: 100%;
23 | height: 100%;
24 | }
25 |
26 | .group > * {
27 | position: absolute;
28 | top: 10px;
29 | left:0;
30 | right:0;
31 | margin-left:auto;
32 | margin-right:auto;
33 | }
34 |
--------------------------------------------------------------------------------
/23-HOC-Vs-RenderProps/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class Mouse extends React.Component {
4 | state = { x: 0, y: 0 };
5 |
6 | handleMouseMove(event) {
7 | this.setState({
8 | x: event.clientX,
9 | y: event.clientY
10 | });
11 | }
12 |
13 | render() {
14 | const { x, y } = this.state;
15 |
16 | return (
17 |
18 |
19 | The mouse position is ({x}, {y})
20 |
21 |
22 | );
23 | }
24 | }
25 |
26 | function App() {
27 | return ;
28 | }
29 |
30 | export default App;
31 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/Loading-Finished.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import './Loading.css';
3 |
4 | const isEmpty = prop =>
5 | prop === null ||
6 | prop === undefined ||
7 | (prop.hasOwnProperty('length') && prop.length === 0) ||
8 | (prop.constructor === Object && Object.keys(prop).length === 0);
9 |
10 | const Loading = loadingProp => WrappedComponent =>
11 | class Loading extends Component {
12 | render() {
13 | return isEmpty(this.props[loadingProp]) ? (
14 |
15 | ) : (
16 |
17 | );
18 | }
19 | };
20 |
21 | export default Loading;
22 |
--------------------------------------------------------------------------------
/01-Hello-World/index-start.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
--------------------------------------------------------------------------------
/06-Rerender/index-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
24 |
--------------------------------------------------------------------------------
/15-Fetching/src/Users.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import SearchBar from './SearchBar';
3 | import UserList from './UserList';
4 | import './Users.css';
5 |
6 | class Users extends Component {
7 | state = {
8 | filterText: ''
9 | };
10 |
11 | handleUserInput = searchTerm => {
12 | this.setState({ filterText: searchTerm });
13 | };
14 |
15 | render() {
16 | return (
17 |
18 |
22 |
23 |
24 | );
25 | }
26 | }
27 |
28 | export default Users;
29 |
--------------------------------------------------------------------------------
/05-Conditional-Render/index-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
24 |
--------------------------------------------------------------------------------
/02-JSX/index-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
--------------------------------------------------------------------------------
/23-HOC-Vs-RenderProps/src/App-HOC.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const withMouse = Component =>
4 | class Mouse extends React.Component {
5 | state = { x: 0, y: 0 };
6 |
7 | handleMouseMove(event) {
8 | this.setState({
9 | x: event.clientX,
10 | y: event.clientY
11 | });
12 | }
13 |
14 | render() {
15 | return (
16 |
17 |
18 |
19 | );
20 | }
21 | };
22 |
23 | function App(props) {
24 | return (
25 |
26 |
27 | The mouse position is {props.mouse.x}, {props.mouse.y}
28 |
29 |
30 | );
31 | }
32 |
33 | export default withMouse(App);
34 |
--------------------------------------------------------------------------------
/23-HOC-Vs-RenderProps/src/App-RenderProps.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class Mouse extends React.Component {
4 | state = { x: 0, y: 0 };
5 |
6 | handleMouseMove(event) {
7 | this.setState({
8 | x: event.clientX,
9 | y: event.clientY
10 | });
11 | }
12 |
13 | render() {
14 | const { x, y } = this.state;
15 |
16 | return (
17 |
18 | {this.props.render(this.state)}
19 |
20 | );
21 | }
22 | }
23 |
24 | function App() {
25 | return (
26 | (
28 |
29 |
30 | The mouse position is {x}, {y}
31 |
32 |
33 | )}
34 | />
35 | );
36 | }
37 |
38 | export default App;
39 |
--------------------------------------------------------------------------------
/04-propTypes/index-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
26 |
27 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/Users.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import SearchBar from './SearchBar';
3 | import UserList from './UserList';
4 | import './Users.css';
5 | // import Loading from './Loading';
6 |
7 | class Users extends Component {
8 | state = {
9 | filterText: ''
10 | };
11 |
12 | handleUserInput = searchTerm => {
13 | this.setState({ filterText: searchTerm });
14 | };
15 |
16 | render() {
17 | return (
18 |
19 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | export default Users;
30 | // export default Loading('users')(Users);
31 |
--------------------------------------------------------------------------------
/15-Fetching/src/UserList.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const UserList = ({ users, filterText }) => {
4 | const filteredUsers = users.filter(
5 | user => user.name.indexOf(filterText) !== -1
6 | );
7 |
8 | return (
9 |
10 | {filteredUsers.map(user => (
11 |
12 |
13 |
14 |
{user.name}
15 |
16 |
{user.username}
17 |
18 |
{user.email}
19 |
20 |
{user.phone}
21 |
22 |
23 | {user.city}, {user.state}
24 |
25 |
26 |
27 | ))}
28 |
29 | );
30 | };
31 |
32 | export default UserList;
33 |
--------------------------------------------------------------------------------
/23-HOC-Vs-RenderProps/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React App
9 |
10 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/22-Render-Props/src/Toggle-Finished.js:
--------------------------------------------------------------------------------
1 | // renderSwitch(), make it pure and move, inline it
2 |
3 | import React from 'react';
4 | import Switch from './Switch';
5 |
6 | class Toggle extends React.Component {
7 | state = { on: false };
8 |
9 | toggle = () => this.setState({ on: !this.state.on });
10 |
11 | render() {
12 | const { on } = this.state;
13 | return this.props.render({ on, toggle: this.toggle });
14 | }
15 | }
16 |
17 | // const renderSwitch = ({ on, toggle }) => ;
18 |
19 | function ToggleApp() {
20 | return (
21 | (
24 |
25 | {on ? 'It is Night' : 'It is Day'}
26 |
27 |
28 | )}
29 | />
30 | );
31 | }
32 |
33 | export default ToggleApp;
34 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/UserList.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const UserList = ({ users, filterText }) => {
4 | const filteredUsers = users.filter(
5 | user => user.name.indexOf(filterText) !== -1
6 | );
7 |
8 | return (
9 |
10 | {filteredUsers.map(user => (
11 |
12 |
13 |
14 |
{user.name}
15 |
16 |
{user.username}
17 |
18 |
{user.email}
19 |
20 |
{user.phone}
21 |
22 |
23 | {user.city}, {user.state}
24 |
25 |
26 |
27 | ))}
28 |
29 | );
30 | };
31 |
32 | export default UserList;
33 |
--------------------------------------------------------------------------------
/18-Toggler/src/Switch.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Switch({ on, ...props }) {
4 | return (
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default Switch;
31 |
--------------------------------------------------------------------------------
/21-Context/src/Switch.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Switch({ on, ...props }) {
4 | return (
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default Switch;
31 |
--------------------------------------------------------------------------------
/22-Render-Props/src/Switch.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Switch({ on, ...props }) {
4 | return (
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default Switch;
31 |
--------------------------------------------------------------------------------
/19-Toggler-Composed/src/Switch.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Switch({ on, ...props }) {
4 | return (
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default Switch;
31 |
--------------------------------------------------------------------------------
/20-Compound-Components/src/Switch.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Switch({ on, ...props }) {
4 | return (
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 |
30 | export default Switch;
31 |
--------------------------------------------------------------------------------
/20-Compound-Components/src/Toggle.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Switch from './Switch';
3 |
4 | class Toggle extends React.Component {
5 | state = { on: false };
6 |
7 | toggle = () => this.setState({ on: !this.state.on });
8 |
9 | render() {
10 | const { on } = this.state;
11 | const { textPosition } = this.props;
12 |
13 | if (textPosition === 'top')
14 | return (
15 |
16 | It is {on ? 'Starry' : 'Sunny'}
17 |
18 |
19 | );
20 | else if (textPosition === 'bottom')
21 | return (
22 |
23 |
24 | It is {on ? 'Starry' : 'Sunny'}
25 |
26 | );
27 | }
28 | }
29 |
30 | function ToggleApp() {
31 | return ;
32 | }
33 |
34 | export default ToggleApp;
35 |
--------------------------------------------------------------------------------
/19-Toggler-Composed/src/Toggle-Finished.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Switch from './Switch';
3 |
4 | class Toggle extends React.Component {
5 | state = { on: false };
6 |
7 | toggle = () => this.setState({ on: !this.state.on });
8 |
9 | render() {
10 | const { on } = this.state;
11 | const { textPosition } = this.props;
12 |
13 | if (textPosition === 'top')
14 | return (
15 |
16 | It is {on ? 'Starry' : 'Sunny'}
17 |
18 |
19 | );
20 | else if (textPosition === 'bottom')
21 | return (
22 |
23 |
24 | It is {on ? 'Starry' : 'Sunny'}
25 |
26 | );
27 | }
28 | }
29 |
30 | function ToggleApp() {
31 | return ;
32 | }
33 |
34 | export default ToggleApp;
35 |
--------------------------------------------------------------------------------
/03-Functional-Components/index-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
30 |
31 |
--------------------------------------------------------------------------------
/10-Todo-App/index-start.js:
--------------------------------------------------------------------------------
1 | const root = document.getElementById('root');
2 |
3 | class Todo extends React.Component {
4 | render() {
5 | return (
6 |
7 |
8 |
9 |
Things To Do
10 |
11 |
17 |
28 |
29 |
30 | );
31 | }
32 | }
33 |
34 | ReactDOM.render( , root);
35 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Users from './Users';
3 |
4 | import './App.css';
5 |
6 | class App extends Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = { users: [] };
10 | }
11 |
12 | componentDidMount() {
13 | fetch('https://api.randomuser.me/?nat=us,gb&results=50')
14 | .then(response => response.json())
15 | .then(parsedResponse =>
16 | parsedResponse.results.map(user => ({
17 | name: `${user.name.first} ${user.name.last}`,
18 | email: user.email,
19 | username: user.login.username,
20 | phone: user.phone,
21 | thumbnail: user.picture.medium,
22 | city: user.location.city,
23 | state: user.location.state
24 | }))
25 | )
26 | .then(users => this.setState({ users }));
27 | }
28 |
29 | render() {
30 | return (
31 |
32 |
33 |
34 | );
35 | }
36 | }
37 |
38 | export default App;
39 |
--------------------------------------------------------------------------------
/15-Fetching/src/App-Finished.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Users from './Users';
3 | import './App.css';
4 |
5 | class App extends Component {
6 | constructor(props) {
7 | super(props);
8 | this.state = { users: [] };
9 | }
10 |
11 | // Fetching Data from api
12 | componentDidMount() {
13 | fetch('https://api.randomuser.me/?nat=us,gb&results=50')
14 | .then(response => response.json())
15 | .then(parsedResponse =>
16 | parsedResponse.results.map(user => ({
17 | name: `${user.name.first} ${user.name.last}`,
18 | email: user.email,
19 | username: user.login.username,
20 | phone: user.phone,
21 | thumbnail: user.picture.medium,
22 | city: user.location.city,
23 | state: user.location.state
24 | }))
25 | )
26 | .then(users => this.setState({ users }));
27 | }
28 |
29 | render() {
30 | return (
31 |
32 |
33 |
34 | );
35 | }
36 | }
37 |
38 | export default App;
39 |
--------------------------------------------------------------------------------
/24-Lazy/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | const User = React.lazy(() => import('./User'));
4 |
5 | const fetchRandomUser = () =>
6 | fetch('https://randomuser.me/api/')
7 | .then(res => res.json())
8 | .then(res => res.results[0]);
9 |
10 | class App extends Component {
11 | state = {
12 | user: null
13 | };
14 |
15 | loadUser = () => {
16 | this.setState(
17 | {
18 | loading: true
19 | },
20 | async () =>
21 | this.setState({ user: await fetchRandomUser(), loading: false })
22 | );
23 | };
24 |
25 | render() {
26 | const { user, loading } = this.state;
27 |
28 | return (
29 |
30 | Loading Component...
}>
31 | {user && }
32 | {loading ? (
33 | Loading User...
34 | ) : (
35 | !user && Press Me!!
36 | )}
37 |
38 |
39 | );
40 | }
41 | }
42 |
43 | export default App;
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Into-the-ReactJs",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "repository": "git@github.com:vigzmv/Into-the-ReactJs.git",
6 | "author": "vigzmv ",
7 | "license": "MIT",
8 | "scripts": {
9 | "start": "parcel index.html"
10 | },
11 | "dependencies": {
12 | "prop-types": "^15.7.2",
13 | "react": "^16.10.2",
14 | "react-addons-css-transition-group": "^15.6.2",
15 | "react-dom": "^16.10.2"
16 | },
17 | "devDependencies": {
18 | "babel-eslint": "^8.0.3",
19 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
20 | "babel-preset-env": "^1.6.1",
21 | "babel-preset-react": "^6.24.1",
22 | "babel-preset-stage-2": "^6.24.1",
23 | "eslint": "^4.13.1",
24 | "eslint-config-airbnb": "^16.1.0",
25 | "eslint-config-prettier": "^2.9.0",
26 | "eslint-plugin-html": "^4.0.1",
27 | "eslint-plugin-import": "^2.8.0",
28 | "eslint-plugin-jsx-a11y": "^6.0.3",
29 | "eslint-plugin-prettier": "^2.4.0",
30 | "eslint-plugin-react": "^7.5.1",
31 | "parcel-bundler": "^1.10.2",
32 | "prettier-eslint": "^8.3.1"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | .cache
3 |
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 |
24 | # nyc test coverage
25 | .nyc_output
26 |
27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
28 | .grunt
29 |
30 | # Bower dependency directory (https://bower.io/)
31 | bower_components
32 |
33 | # node-waf configuration
34 | .lock-wscript
35 |
36 | # Compiled binary addons (http://nodejs.org/api/addons.html)
37 | build/Release
38 |
39 | # Dependency directories
40 | node_modules/
41 | jspm_packages/
42 |
43 | # Typescript v1 declaration files
44 | typings/
45 |
46 | # Optional npm cache directory
47 | .npm
48 |
49 | # Optional eslint cache
50 | .eslintcache
51 |
52 | # Optional REPL history
53 | .node_repl_history
54 |
55 | # Output of 'npm pack'
56 | *.tgz
57 |
58 | # Yarn Integrity file
59 | .yarn-integrity
60 |
61 | # dotenv environment variables file
62 | .env
63 |
64 |
--------------------------------------------------------------------------------
/Requirements.md:
--------------------------------------------------------------------------------
1 | # Please make sure you have the following requirements installed on your systems before the event.
2 |
3 | ## 1. Chrome: Latest or at least > 62
4 |
5 | [Get Chrome](https://www.google.com/chrome/browser/features.html)
6 |
7 | ## 2. Node: Latest or at least > 9.2 and (npm > 5.5 and/or yarn > 1.3)
8 |
9 | [Get Node](https://nodejs.org/en/download/package-manager/)
10 |
11 | [Check your node version](https://stackoverflow.com/questions/14888471/node-js-version-on-the-command-line-not-the-repl)
12 |
13 | ## 3. Git: Latest or at least > 2.1
14 |
15 | [Get git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
16 |
17 | [Check your git version](https://superuser.com/questions/347728/terminal-command-to-find-what-version-of-git-i-have-installed)
18 |
19 | ## 4. A Nice code editor (VsCode, Sublime, Atom)
20 |
21 | ## 5. Node dependencies
22 |
23 | * http-server
24 | * browser-sync
25 | * create-react-app
26 | * parcel-bundler
27 |
28 | Install these node dependencies by doing
29 |
30 | ```sh
31 | # For Mac/Linux
32 | sudo npm install -g http-server browser-sync create-react-app parcel-bundler
33 |
34 | # For Windows
35 | npm install -g http-server browser-sync create-react-app parcel-bundler
36 | ```
37 |
--------------------------------------------------------------------------------
/09-Event-Handling/index-start.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
43 |
--------------------------------------------------------------------------------
/20-Compound-Components/src/Toggle-Finished.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Switch from './Switch';
3 |
4 | function ToggleDay({ on, children }) {
5 | return on ? children : null;
6 | }
7 |
8 | function ToggleNight({ on, children }) {
9 | return on ? null : children;
10 | }
11 |
12 | function ToggleButton({ on, toggle, ...props }) {
13 | return ;
14 | }
15 |
16 | class Toggle extends React.Component {
17 | static Day = ToggleDay;
18 | static Night = ToggleNight;
19 | static Button = ToggleButton;
20 |
21 | state = { on: false };
22 |
23 | toggle = () => this.setState({ on: !this.state.on });
24 |
25 | render() {
26 | const children = React.Children.map(this.props.children, child =>
27 | React.cloneElement(child, {
28 | on: this.state.on,
29 | toggle: this.toggle
30 | })
31 | );
32 |
33 | return {children}
;
34 | }
35 | }
36 |
37 | function ToggleApp() {
38 | return (
39 |
40 |
41 | It is Sunny
42 |
43 |
44 |
45 | It is Night
46 |
47 |
48 | );
49 | }
50 |
51 | export default ToggleApp;
52 |
--------------------------------------------------------------------------------
/21-Context/src/Toggle.js:
--------------------------------------------------------------------------------
1 | // context, proptyles,
2 |
3 | import React from 'react';
4 | import Switch from './Switch';
5 |
6 | function ToggleDay({ on, children }) {
7 | return on ? children : null;
8 | }
9 |
10 | function ToggleNight({ on, children }) {
11 | return on ? null : children;
12 | }
13 |
14 | function ToggleButton({ on, toggle, ...props }) {
15 | return ;
16 | }
17 |
18 | class Toggle extends React.Component {
19 | static Day = ToggleDay;
20 | static Night = ToggleNight;
21 | static Button = ToggleButton;
22 |
23 | state = { on: false };
24 |
25 | toggle = () => this.setState({ on: !this.state.on });
26 |
27 | render() {
28 | const children = React.Children.map(this.props.children, child =>
29 | React.cloneElement(child, {
30 | on: this.state.on,
31 | toggle: this.toggle
32 | })
33 | );
34 |
35 | return {children}
;
36 | }
37 | }
38 |
39 | function ToggleApp() {
40 | return (
41 |
42 |
43 | It is Sunny
44 |
45 |
46 |
47 | It is Night
48 |
49 |
50 | );
51 | }
52 |
53 | export default ToggleApp;
54 |
--------------------------------------------------------------------------------
/01-Hello-World/index-finished.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
35 |
36 |
--------------------------------------------------------------------------------
/10-Todo-App/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Todo App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
--------------------------------------------------------------------------------
/11-Component-Patterns/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Todo App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
--------------------------------------------------------------------------------
/17-React.Children/src/SlideShow-Finished.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children } from 'react';
2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
3 | import './SlideShow.css';
4 |
5 | class SlideShow extends Component {
6 | state = {
7 | total: 0,
8 | current: 0
9 | };
10 |
11 | componentDidMount() {
12 | const { children } = this.props;
13 | this.setState({ total: Children.count(children) });
14 | this.interval = setInterval(this.showNext, 3000);
15 | }
16 |
17 | componentWillUnmount() {
18 | clearInterval(this.interval);
19 | }
20 |
21 | showNext = () => {
22 | const { total, current } = this.state;
23 | this.setState({
24 | current: current + 1 === total ? 0 : current + 1
25 | });
26 | };
27 |
28 | render() {
29 | const { children } = this.props;
30 | const bullets = Array(this.state.total).fill('○');
31 | bullets[this.state.current] = '●';
32 |
33 | return (
34 |
35 |
{bullets}
36 |
42 | {Children.toArray(children)[this.state.current]}
43 |
44 |
45 | );
46 | }
47 | }
48 |
49 | export default SlideShow;
50 |
--------------------------------------------------------------------------------
/05-Conditional-Render/index-finished.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
54 |
--------------------------------------------------------------------------------
/02-JSX/index-finished.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
39 |
40 |
--------------------------------------------------------------------------------
/16-Higher-Order-Component/src/Loading.css:
--------------------------------------------------------------------------------
1 | .loader {
2 | position: absolute;
3 | top: 50%;
4 | left: 50%;
5 | -webkit-transform: translateX(-50%) translateY(-50%);
6 | -ms-transform: translateX(-50%) translateY(-50%);
7 | transform: translateX(-50%) translateY(-50%);
8 | }
9 |
10 | /* Static Shape */
11 |
12 | .loader:before {
13 | position: absolute;
14 | content: '';
15 | top: 0%;
16 | left: 50%;
17 | width: 100%;
18 | height: 100%;
19 | border-radius: 500rem;
20 | border: 0.2em solid rgba(0, 0, 0, 0.1);
21 | }
22 |
23 | /* Active Shape */
24 |
25 | .loader:after {
26 | position: absolute;
27 | content: '';
28 | top: 0%;
29 | left: 50%;
30 | width: 100%;
31 | height: 100%;
32 | animation: loader 0.6s linear;
33 | animation-iteration-count: infinite;
34 | border-radius: 500rem;
35 | border-color: #767676 transparent transparent;
36 | border-style: solid;
37 | border-width: 0.2em;
38 | box-shadow: 0px 0px 0px 1px transparent;
39 | }
40 |
41 | /* Active Animation */
42 |
43 | @-webkit-keyframes loader {
44 | from {
45 | -webkit-transform: rotate(0deg);
46 | transform: rotate(0deg);
47 | }
48 |
49 | to {
50 | -webkit-transform: rotate(360deg);
51 | transform: rotate(360deg);
52 | }
53 | }
54 |
55 | @keyframes loader {
56 | from {
57 | -webkit-transform: rotate(0deg);
58 | transform: rotate(0deg);
59 | }
60 |
61 | to {
62 | -webkit-transform: rotate(360deg);
63 | transform: rotate(360deg);
64 | }
65 | }
66 |
67 | .loader:before,
68 | .loader:after {
69 | width: 2.28571429rem;
70 | height: 2.28571429rem;
71 | margin: 0em;
72 | }
73 |
--------------------------------------------------------------------------------
/07-Styling/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
28 |
29 |
68 |
--------------------------------------------------------------------------------
/11-Component-Patterns/index-start.js:
--------------------------------------------------------------------------------
1 | const root = document.getElementById('root');
2 |
3 | class Todo extends React.Component {
4 | constructor(props) {
5 | super(props);
6 |
7 | this.state = {
8 | todoList: [],
9 | inputValue: ''
10 | };
11 | }
12 |
13 | addTodo = () => {
14 | this.setState({
15 | todoList: [...this.state.todoList, { content: this.state.inputValue }],
16 | inputValue: ''
17 | });
18 | };
19 |
20 | handleInputChange = e => {
21 | this.setState({
22 | inputValue: e.target.value
23 | });
24 | };
25 |
26 | render() {
27 | return (
28 |
29 |
30 |
31 |
Things To Do
32 |
33 |
44 |
45 | {this.state.todoList.map(todo => (
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | {todo.content}
54 |
55 | ))}
56 |
57 |
58 |
59 | );
60 | }
61 | }
62 |
63 | ReactDOM.render( , root);
64 |
--------------------------------------------------------------------------------
/24-Lazy/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React App
8 |
9 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/08-Component & Lifecycle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
59 |
--------------------------------------------------------------------------------
/23-HOC-Vs-RenderProps/src/App-Cool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class Mouse extends React.Component {
4 | state = { x: 0, y: 0 };
5 |
6 | handleMouseMove(event) {
7 | const hero = document.querySelector('.hero');
8 | let x = event.nativeEvent.offsetX;
9 | let y = event.nativeEvent.offsetY;
10 |
11 | if (hero !== event.target) {
12 | x += event.target.offsetLeft;
13 | y += event.target.offsetTop;
14 | }
15 |
16 | this.setState({
17 | x,
18 | y
19 | });
20 | console.log(event.nativeEvent.offsetX, event.nativeEvent.offsetY);
21 | }
22 |
23 | render() {
24 | const { x, y } = this.state;
25 |
26 | return (
27 |
28 | {this.props.render(this.state)}
29 |
30 | );
31 | }
32 | }
33 |
34 | function App() {
35 | const walk = 300; // 100px
36 |
37 | return (
38 | {
40 | const hero = document.querySelector('.hero');
41 | const { offsetWidth: width, offsetHeight: height } = hero || {
42 | offsetWidth: 0,
43 | offsetHeight: 0
44 | };
45 | const xWalk = Math.round(x / width * walk - walk / 2);
46 | const yWalk = Math.round(y / height * walk - walk / 2);
47 | return (
48 |
49 |
57 | React!!
58 |
59 |
60 | );
61 | }}
62 | />
63 | );
64 | }
65 |
66 | export default App;
67 |
--------------------------------------------------------------------------------
/21-Context/src/Toggle-Finished.js:
--------------------------------------------------------------------------------
1 | // context, PropTypes, childContextTypes, getChildContext, render only children, contextTypes to all children components, toggle in variable
2 |
3 | import React from 'react';
4 | import PropTypes from 'prop-types';
5 | import Switch from './Switch';
6 |
7 | function ToggleDay({ children }, context) {
8 | const { on } = context.toggle;
9 | return on ? children : null;
10 | }
11 | ToggleDay.contextTypes = {
12 | toggle: PropTypes.object.isRequired
13 | };
14 |
15 | function ToggleNight({ children }, context) {
16 | const { on } = context.toggle;
17 | return on ? null : children;
18 | }
19 | ToggleNight.contextTypes = {
20 | toggle: PropTypes.object.isRequired
21 | };
22 |
23 | function ToggleButton(props, context) {
24 | const { on, toggle } = context.toggle;
25 | return ;
26 | }
27 | ToggleButton.contextTypes = {
28 | toggle: PropTypes.object.isRequired
29 | };
30 |
31 | class Toggle extends React.Component {
32 | static Day = ToggleDay;
33 | static Night = ToggleNight;
34 | static Button = ToggleButton;
35 |
36 | static childContextTypes = {
37 | toggle: PropTypes.object.isRequired
38 | };
39 |
40 | state = { on: false };
41 |
42 | getChildContext() {
43 | return {
44 | toggle: {
45 | on: this.state.on,
46 | toggle: this.toggle
47 | }
48 | };
49 | }
50 |
51 | toggle = () => this.setState({ on: !this.state.on });
52 |
53 | render() {
54 | return {this.props.children}
;
55 | }
56 | }
57 |
58 | function ToggleApp() {
59 | return (
60 |
61 |
62 | It is Sunny
63 |
64 |
65 |
66 |
67 |
68 | It is Night
69 |
70 |
71 | );
72 | }
73 |
74 | export default ToggleApp;
75 |
--------------------------------------------------------------------------------
/12-create-react-app/src/Todo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import List from './List';
3 | import './Todo.css';
4 |
5 | class Todo extends Component {
6 | constructor(props) {
7 | super(props);
8 |
9 | this.state = {
10 | todoList: [],
11 | inputValue: ''
12 | };
13 | }
14 |
15 | addTodo = () => {
16 | this.setState({
17 | todoList: [
18 | ...this.state.todoList,
19 | { content: this.state.inputValue, completed: false }
20 | ],
21 | inputValue: ''
22 | });
23 | };
24 |
25 | handleInputChange = e => {
26 | this.setState({
27 | inputValue: e.target.value
28 | });
29 | };
30 |
31 | removeTodo = index => {
32 | const newTotoList = this.state.todoList.filter((item, i) => i !== index);
33 | this.setState({ todoList: newTotoList });
34 | };
35 |
36 | markCompleteTodo = index => {
37 | const newTotoList = this.state.todoList.map((item, i) => {
38 | if (index === i) {
39 | item.completed = !item.completed;
40 | }
41 | return item;
42 | });
43 |
44 | this.setState({ todoList: newTotoList });
45 | };
46 |
47 | render() {
48 | return (
49 |
50 |
51 |
52 |
Things To Do
53 |
54 |
65 |
70 |
71 |
72 | );
73 | }
74 | }
75 |
76 | export default Todo;
77 |
--------------------------------------------------------------------------------
/04-propTypes/index-finished.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
72 |
--------------------------------------------------------------------------------
/10-Todo-App/index-finished.js:
--------------------------------------------------------------------------------
1 | // Notes: styling, state, static state, setState, map, react dev tool
2 |
3 | const root = document.getElementById('root');
4 |
5 | class Todo extends React.Component {
6 | constructor(props) {
7 | super(props);
8 |
9 | // static state
10 |
11 | // this.state = {
12 | // todoList: [
13 | // {
14 | // content: 'Complete This',
15 | // },
16 | // ],
17 | // };
18 |
19 | this.state = {
20 | todoList: [],
21 | inputValue: ''
22 | };
23 | }
24 |
25 | addTodo = () => {
26 | this.setState({
27 | todoList: [...this.state.todoList, { content: this.state.inputValue }],
28 | inputValue: ''
29 | });
30 | };
31 |
32 | handleInputChange = e => {
33 | const inputValue = e.target.value;
34 | this.setState({
35 | inputValue
36 | });
37 | };
38 |
39 | render() {
40 | return (
41 |
42 |
43 |
44 |
Things To Do
45 |
46 |
57 |
58 | {this.state.todoList.map(todo => (
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | {todo.content}
67 |
68 | ))}
69 |
70 |
71 |
72 | );
73 | }
74 | }
75 |
76 | ReactDOM.render( , root);
77 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/Todo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import List from './List';
3 | import './Todo.css';
4 | import base from './re-base';
5 |
6 | class Todo extends Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | todoList: [],
12 | inputValue: ''
13 | };
14 | }
15 |
16 | addTodo = () => {
17 | this.setState({
18 | todoList: [
19 | ...this.state.todoList,
20 | { content: this.state.inputValue, completed: false }
21 | ],
22 | inputValue: ''
23 | });
24 | };
25 |
26 | handleInputChange = e => {
27 | this.setState({
28 | inputValue: e.target.value
29 | });
30 | };
31 |
32 | removeTodo = index => {
33 | const newTotoList = this.state.todoList.filter((item, i) => i !== index);
34 | this.setState({ todoList: newTotoList });
35 | };
36 |
37 | markCompleteTodo = index => {
38 | const newTotoList = this.state.todoList.map((item, i) => {
39 | if (index === i) {
40 | item.completed = !item.completed;
41 | }
42 | return item;
43 | });
44 |
45 | this.setState({ todoList: newTotoList });
46 | };
47 |
48 | render() {
49 | return (
50 |
51 |
52 |
53 |
Things To Do
54 |
55 |
66 |
71 |
72 |
73 | );
74 | }
75 | }
76 |
77 | export default Todo;
78 |
--------------------------------------------------------------------------------
/09-Event-Handling/index-finished.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
68 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["airbnb", "prettier", "prettier/react"],
3 | "parser": "babel-eslint",
4 | "parserOptions": {
5 | "ecmaVersion": 8,
6 | "ecmaFeatures": {
7 | "experimentalObjectRestSpread": true,
8 | "impliedStrict": true,
9 | "classes": true
10 | }
11 | },
12 | "env": {
13 | "browser": true,
14 | "node": true,
15 | "jquery": true
16 | },
17 | "rules": {
18 | "no-unused-vars": [
19 | 1,
20 | {
21 | "argsIgnorePattern": "res|next|^err"
22 | }
23 | ],
24 | "arrow-body-style": [2, "as-needed"],
25 | "no-param-reassign": [
26 | 2,
27 | {
28 | "props": false
29 | }
30 | ],
31 | "no-console": "off",
32 | "import": "off",
33 | "func-names": "off",
34 | "space-before-function-paren": "off",
35 | "comma-dangle": "off",
36 | "max-len": "off",
37 | "import/extensions": "off",
38 | "no-underscore-dangle": "off",
39 | "consistent-return": "off",
40 | "react/display-name": 1,
41 | "react/react-in-jsx-scope": "off",
42 | "react/forbid-prop-types": "off",
43 | "react/no-unescaped-entities": "off",
44 | "react/prefer-stateless-function": "off",
45 | "react/prop-types": "off",
46 | "react/jsx-filename-extension": [
47 | 1,
48 | {
49 | "extensions": [".js", ".jsx"]
50 | }
51 | ],
52 | "radix": "off",
53 | "no-shadow": [
54 | 2,
55 | {
56 | "hoist": "all",
57 | "allow": ["resolve", "reject", "done", "next", "err", "error"]
58 | }
59 | ],
60 | "quotes": [
61 | 2,
62 | "single",
63 | {
64 | "avoidEscape": true,
65 | "allowTemplateLiterals": true
66 | }
67 | ],
68 | "prettier/prettier": [
69 | "error",
70 | {
71 | "singleQuote": true,
72 | "printWidth": 80
73 | }
74 | ],
75 | "jsx-a11y/href-no-hash": "off",
76 | "jsx-a11y/anchor-is-valid": [
77 | "warn",
78 | {
79 | "aspects": ["invalidHref"]
80 | }
81 | ]
82 | },
83 | "plugins": ["eslint-plugin-html", "prettier"]
84 | }
85 |
--------------------------------------------------------------------------------
/06-Rerender/index-finished.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
79 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/Todo-Finished.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import List from './List';
3 | import './Todo.css';
4 | import base from './re-base';
5 |
6 | class Todo extends Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | todoList: [],
12 | inputValue: ''
13 | };
14 | }
15 |
16 | // re-base ing
17 | componentDidMount() {
18 | base.syncState(`todoList`, {
19 | context: this,
20 | state: 'todoList',
21 | asArray: true
22 | });
23 | }
24 |
25 | addTodo = () => {
26 | this.setState({
27 | todoList: [
28 | ...this.state.todoList,
29 | { content: this.state.inputValue, completed: false }
30 | ],
31 | inputValue: ''
32 | });
33 | };
34 |
35 | handleInputChange = e => {
36 | this.setState({
37 | inputValue: e.target.value
38 | });
39 | };
40 |
41 | removeTodo = index => {
42 | const newTotoList = this.state.todoList.filter((item, i) => i !== index);
43 | this.setState({ todoList: newTotoList });
44 | };
45 |
46 | markCompleteTodo = index => {
47 | const newTotoList = this.state.todoList.map((item, i) => {
48 | if (index === i) {
49 | item.completed = !item.completed;
50 | }
51 | return item;
52 | });
53 |
54 | this.setState({ todoList: newTotoList });
55 | };
56 |
57 | render() {
58 | return (
59 |
60 |
61 |
62 |
Things To Do
63 |
64 |
75 |
80 |
81 |
82 | );
83 | }
84 | }
85 |
86 | export default Todo;
87 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
28 | Todo
29 |
30 |
31 |
32 |
33 | You need to enable JavaScript to run this app.
34 |
35 |
36 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/12-create-react-app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
28 | Todo App
29 |
30 |
31 |
32 |
33 | You need to enable JavaScript to run this app.
34 |
35 |
36 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Into-the-ReactJs
2 |
3 | Code content for my Session/Workshop on React.
4 |
5 | ## Agenda
6 |
7 | A deep dive into the React. Starting from the very basics, exploring what? why? how? the APIs work and levelling up to its advanced patterns.
8 |
9 | 1. **Introduction**: What is and Why should one do React?
10 | 1. **The Basics**: Exploring the basic elements of React with just one single HTML file. Building few core React APIs ourself and learning how they work.
11 | 1. **Thinking in React**: Setup and building simple React Front End. Create react App. Life Cycles. Synthetic Events. Lifting State. Dropping Props. Some Styling. Some Tooling. Different Component Patterns. Data Fetching. Data persistence with Firebase re-base. Deploying builds.
12 | 1. **Advanced Patterns**: Declarative Development, Compound Components, HOCs, Refs, Context, Portals and More! Learning by building real-world usages.
13 |
14 | ## Slides
15 |
16 | [Vignesh M - React](http://slides.com/vigzmv/react/)
17 |
18 | ## Requirements
19 |
20 | See [Requirements](./Requirements.md)
21 |
22 | ## How to run
23 |
24 | Execute `npm install` once in root folder and switch to the respective project folder to run the examples.
25 |
26 | * **01 to 09**
27 | Use any http-server and to open index\*.html
28 | The starter code is in index-start.html and finished code is in index-finished.html
29 |
30 | * **10 to 11**
31 | Use any http-server (http-server/browser-sync) to open index\*.html
32 | The starter code is in index-start.js and finished code is in index-finished.js
33 | You will have to swap out the src of js file in index.html
34 |
35 | * **12 to 13**
36 | These are created with create-react-app.
37 | Install node dependencies with `npm install` and then start development server using `npm start`.
38 |
39 | * **14 to 24**
40 | These are created as parceljs projects.
41 | Install parceljs globally using `sudo npm install -g parcel-bundler` once and run start the server using `parcel index.html`.
42 |
43 | ## More Resources
44 |
45 | * [The Beginner's Guide to ReactJS - Kent C. Dodds](https://egghead.io/courses/the-beginner-s-guide-to-reactjs)
46 | * [ReactJs](https://reactjs.org/)
47 | * [Create React App](https://github.com/facebook/create-react-app)
48 | * [ParcelJs](https://parceljs.org/)
49 | * [Rebase](https://github.com/tylermcginnis/re-base)
--------------------------------------------------------------------------------
/03-Functional-Components/index-finished.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/11-Component-Patterns/index-finished.js:
--------------------------------------------------------------------------------
1 | // Component Patterns.
2 | // Statefull, Controlling, Smart Component
3 | // Stateless, Presentational, Dumb Component
4 | // Components, Containers
5 | // state lifted to top
6 | // handlers
7 |
8 | const root = document.getElementById('root');
9 |
10 | // functional presentational component
11 | function List(props) {
12 | return props.list.map((item, i) => (
13 |
14 | props.onRemove(i)}>
15 |
16 |
17 | props.onComplete(i)}>
18 |
19 |
20 | {item.content}
21 |
22 | ));
23 | }
24 |
25 | // class based stateful component
26 | class Todo extends React.Component {
27 | constructor(props) {
28 | super(props);
29 |
30 | this.state = {
31 | todoList: [],
32 | inputValue: ''
33 | };
34 | }
35 |
36 | addTodo = () => {
37 | this.setState({
38 | todoList: [
39 | ...this.state.todoList,
40 | { content: this.state.inputValue, completed: false }
41 | ],
42 | inputValue: ''
43 | });
44 | };
45 |
46 | handleInputChange = e => {
47 | this.setState({
48 | inputValue: e.target.value
49 | });
50 | };
51 |
52 | removeTodo = index => {
53 | const newTotoList = this.state.todoList.filter((item, i) => i !== index);
54 | this.setState({ todoList: newTotoList });
55 | };
56 |
57 | markCompleteTodo = index => {
58 | const newTotoList = this.state.todoList;
59 | newTotoList[index].completed = !newTotoList[index].completed;
60 |
61 | // immutable method
62 | // const newTotoList = this.state.todoList.map((item, i) => {
63 | // if (index === i) {
64 | // item.completed = !item.completed;
65 | // }
66 | // return item;
67 | // });
68 |
69 | this.setState({ todoList: newTotoList });
70 | };
71 |
72 | render() {
73 | return (
74 |
75 |
76 |
77 |
Things To Do
78 |
79 |
90 |
95 |
96 |
97 | );
98 | }
99 | }
100 |
101 | ReactDOM.render( , root);
102 |
--------------------------------------------------------------------------------
/10-Todo-App/css/styles.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | -webkit-box-sizing: border-box;
3 | box-sizing: border-box;
4 | }
5 |
6 | p {
7 | color: #eee;
8 | text-align: center;
9 | margin: 60px 0 30px 0;
10 | }
11 |
12 | li {
13 | list-style: none;
14 | }
15 |
16 | body {
17 | font-family: 'Open Sans', sans-serif;
18 | background: #34495e;
19 | font-size: 14px;
20 | -webkit-font-smoothing: antialiased;
21 | -moz-osx-font-smoothing: grayscale;
22 | text-rendering: optimizeLegibility;
23 | }
24 |
25 | .container {
26 | background: #2c3e50;
27 | overflow: hidden;
28 | width: 360px;
29 | margin: 10% auto;
30 | color: #FFF;
31 | border-radius: 3px 3px 0 0;
32 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
33 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
34 | }
35 |
36 | .container .title {
37 | background: #3498db;
38 | }
39 |
40 | .container h1 {
41 | font-size: 20px;
42 | font-weight: 600;
43 | padding: 10px 15px;
44 | text-transform: uppercase;
45 | }
46 |
47 | .add {
48 | float: right;
49 | border-radius: 3px;
50 | margin-right: 20px;
51 | margin-top: 5px;
52 | padding: 8px 10px;
53 | background: #2980b9;
54 | }
55 |
56 | .add:hover {
57 | background: rgba(0, 0, 0, 0.3);
58 | cursor: pointer;
59 | }
60 |
61 | .row {
62 | color: #333;
63 | background: #FFF;
64 | width: 100%;
65 | height: 40px;
66 | padding-left: 10px;
67 | line-height: 2.8;
68 | }
69 |
70 | .row:hover a {
71 | width: 40px;
72 | opacity: 1;
73 | }
74 |
75 | .row:nth-child(2n) {
76 | background: #f7f7f7;
77 | }
78 |
79 | .row:hover {
80 | background: #eee;
81 | }
82 |
83 | .remove, .completed {
84 | float: right;
85 | text-align: center;
86 | height: 40px;
87 | width: 0;
88 | background: #2ecc71;
89 | color: #FFF;
90 | opacity: 0;
91 | text-decoration: none;
92 | display: inline-block;
93 | -webkit-transition: all .2s ease;
94 | transition: all .2s ease;
95 | }
96 |
97 | .remove:hover, .completed:hover {
98 | background: #27ae60;
99 | }
100 |
101 | .remove {
102 | background: #e74c3c;
103 | }
104 |
105 | .remove:hover {
106 | background: #c0392b;
107 | }
108 |
109 | .done {
110 | text-decoration: line-through;
111 | color: #ccc;
112 | }
113 |
114 | .add-new {
115 | float: right;
116 | height: 40px;
117 | width: 40px;
118 | text-align: center;
119 | background: #2ecc71;
120 | color: #FFF;
121 | line-height: 2.8;
122 | -webkit-transition: all .3s linear;
123 | transition: all .3s linear;
124 | }
125 |
126 | .add-new:hover {
127 | background: #27ae60;
128 | }
129 |
130 | .new-task {
131 | /* display: none; */
132 | }
133 |
134 | .new-task input {
135 | -webkit-appearance: none;
136 | -moz-appearance: none;
137 | border-radius: 0;
138 | background: #ecf0f1;
139 | font-size: 14px;
140 | font-family: 'Open Sans', sans-serif;
141 | width: 320px;
142 | padding: 5px 10px;
143 | height: 40px;
144 | border: none;
145 | outline: none;
146 | }
147 |
148 | .ui-sortable-helper {
149 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
150 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
151 | }
152 |
--------------------------------------------------------------------------------
/13-Firebase-rebase/src/Todo.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | -webkit-box-sizing: border-box;
3 | box-sizing: border-box;
4 | }
5 |
6 | p {
7 | color: #eee;
8 | text-align: center;
9 | margin: 60px 0 30px 0;
10 | }
11 |
12 | li {
13 | list-style: none;
14 | }
15 |
16 | body {
17 | font-family: 'Open Sans', sans-serif;
18 | background: #34495e;
19 | font-size: 14px;
20 | -webkit-font-smoothing: antialiased;
21 | -moz-osx-font-smoothing: grayscale;
22 | text-rendering: optimizeLegibility;
23 | }
24 |
25 | .container {
26 | background: #2c3e50;
27 | overflow: hidden;
28 | width: 360px;
29 | margin: 10% auto;
30 | color: #FFF;
31 | border-radius: 3px 3px 0 0;
32 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
33 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
34 | }
35 |
36 | .container .title {
37 | background: #3498db;
38 | }
39 |
40 | .container h1 {
41 | font-size: 20px;
42 | font-weight: 600;
43 | padding: 10px 15px;
44 | text-transform: uppercase;
45 | }
46 |
47 | .add {
48 | float: right;
49 | border-radius: 3px;
50 | margin-right: 20px;
51 | margin-top: 5px;
52 | padding: 8px 10px;
53 | background: #2980b9;
54 | }
55 |
56 | .add:hover {
57 | background: rgba(0, 0, 0, 0.3);
58 | cursor: pointer;
59 | }
60 |
61 | .row {
62 | color: #333;
63 | background: #FFF;
64 | width: 100%;
65 | height: 40px;
66 | padding-left: 10px;
67 | line-height: 2.8;
68 | }
69 |
70 | .row:hover a {
71 | width: 40px;
72 | opacity: 1;
73 | }
74 |
75 | .row:nth-child(2n) {
76 | background: #f7f7f7;
77 | }
78 |
79 | .row:hover {
80 | background: #eee;
81 | }
82 |
83 | .remove, .completed {
84 | float: right;
85 | text-align: center;
86 | height: 40px;
87 | width: 0;
88 | background: #2ecc71;
89 | color: #FFF;
90 | opacity: 0;
91 | text-decoration: none;
92 | display: inline-block;
93 | -webkit-transition: all .2s ease;
94 | transition: all .2s ease;
95 | }
96 |
97 | .remove:hover, .completed:hover {
98 | background: #27ae60;
99 | }
100 |
101 | .remove {
102 | background: #e74c3c;
103 | }
104 |
105 | .remove:hover {
106 | background: #c0392b;
107 | }
108 |
109 | .done {
110 | text-decoration: line-through;
111 | color: #ccc;
112 | }
113 |
114 | .add-new {
115 | float: right;
116 | height: 40px;
117 | width: 40px;
118 | text-align: center;
119 | background: #2ecc71;
120 | color: #FFF;
121 | line-height: 2.8;
122 | -webkit-transition: all .3s linear;
123 | transition: all .3s linear;
124 | }
125 |
126 | .add-new:hover {
127 | background: #27ae60;
128 | }
129 |
130 | .new-task {
131 | /* display: none; */
132 | }
133 |
134 | .new-task input {
135 | -webkit-appearance: none;
136 | -moz-appearance: none;
137 | border-radius: 0;
138 | background: #ecf0f1;
139 | font-size: 14px;
140 | font-family: 'Open Sans', sans-serif;
141 | width: 320px;
142 | padding: 5px 10px;
143 | height: 40px;
144 | border: none;
145 | outline: none;
146 | }
147 |
148 | .ui-sortable-helper {
149 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
150 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
151 | }
152 |
--------------------------------------------------------------------------------
/11-Component-Patterns/css/styles.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | -webkit-box-sizing: border-box;
3 | box-sizing: border-box;
4 | }
5 |
6 | p {
7 | color: #eee;
8 | text-align: center;
9 | margin: 60px 0 30px 0;
10 | }
11 |
12 | li {
13 | list-style: none;
14 | }
15 |
16 | body {
17 | font-family: 'Open Sans', sans-serif;
18 | background: #34495e;
19 | font-size: 14px;
20 | -webkit-font-smoothing: antialiased;
21 | -moz-osx-font-smoothing: grayscale;
22 | text-rendering: optimizeLegibility;
23 | }
24 |
25 | .container {
26 | background: #2c3e50;
27 | overflow: hidden;
28 | width: 360px;
29 | margin: 10% auto;
30 | color: #FFF;
31 | border-radius: 3px 3px 0 0;
32 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
33 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
34 | }
35 |
36 | .container .title {
37 | background: #3498db;
38 | }
39 |
40 | .container h1 {
41 | font-size: 20px;
42 | font-weight: 600;
43 | padding: 10px 15px;
44 | text-transform: uppercase;
45 | }
46 |
47 | .add {
48 | float: right;
49 | border-radius: 3px;
50 | margin-right: 20px;
51 | margin-top: 5px;
52 | padding: 8px 10px;
53 | background: #2980b9;
54 | }
55 |
56 | .add:hover {
57 | background: rgba(0, 0, 0, 0.3);
58 | cursor: pointer;
59 | }
60 |
61 | .row {
62 | color: #333;
63 | background: #FFF;
64 | width: 100%;
65 | height: 40px;
66 | padding-left: 10px;
67 | line-height: 2.8;
68 | }
69 |
70 | .row:hover a {
71 | width: 40px;
72 | opacity: 1;
73 | }
74 |
75 | .row:nth-child(2n) {
76 | background: #f7f7f7;
77 | }
78 |
79 | .row:hover {
80 | background: #eee;
81 | }
82 |
83 | .remove, .completed {
84 | float: right;
85 | text-align: center;
86 | height: 40px;
87 | width: 0;
88 | background: #2ecc71;
89 | color: #FFF;
90 | opacity: 0;
91 | text-decoration: none;
92 | display: inline-block;
93 | -webkit-transition: all .2s ease;
94 | transition: all .2s ease;
95 | }
96 |
97 | .remove:hover, .completed:hover {
98 | background: #27ae60;
99 | }
100 |
101 | .remove {
102 | background: #e74c3c;
103 | }
104 |
105 | .remove:hover {
106 | background: #c0392b;
107 | }
108 |
109 | .done {
110 | text-decoration: line-through;
111 | color: #ccc;
112 | }
113 |
114 | .add-new {
115 | float: right;
116 | height: 40px;
117 | width: 40px;
118 | text-align: center;
119 | background: #2ecc71;
120 | color: #FFF;
121 | line-height: 2.8;
122 | -webkit-transition: all .3s linear;
123 | transition: all .3s linear;
124 | }
125 |
126 | .add-new:hover {
127 | background: #27ae60;
128 | }
129 |
130 | .new-task {
131 | /* display: none; */
132 | }
133 |
134 | .new-task input {
135 | -webkit-appearance: none;
136 | -moz-appearance: none;
137 | border-radius: 0;
138 | background: #ecf0f1;
139 | font-size: 14px;
140 | font-family: 'Open Sans', sans-serif;
141 | width: 320px;
142 | padding: 5px 10px;
143 | height: 40px;
144 | border: none;
145 | outline: none;
146 | }
147 |
148 | .ui-sortable-helper {
149 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
150 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
151 | }
152 |
--------------------------------------------------------------------------------
/12-create-react-app/src/Todo.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | -webkit-box-sizing: border-box;
3 | box-sizing: border-box;
4 | }
5 |
6 | p {
7 | color: #eee;
8 | text-align: center;
9 | margin: 60px 0 30px 0;
10 | }
11 |
12 | li {
13 | list-style: none;
14 | }
15 |
16 | body {
17 | font-family: 'Open Sans', sans-serif;
18 | background: #34495e;
19 | font-size: 14px;
20 | -webkit-font-smoothing: antialiased;
21 | -moz-osx-font-smoothing: grayscale;
22 | text-rendering: optimizeLegibility;
23 | }
24 |
25 | .container {
26 | background: #2c3e50;
27 | overflow: hidden;
28 | width: 360px;
29 | margin: 10% auto;
30 | color: #FFF;
31 | border-radius: 3px 3px 0 0;
32 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
33 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
34 | }
35 |
36 | .container .title {
37 | background: #3498db;
38 | }
39 |
40 | .container h1 {
41 | font-size: 20px;
42 | font-weight: 600;
43 | padding: 10px 15px;
44 | text-transform: uppercase;
45 | }
46 |
47 | .add {
48 | float: right;
49 | border-radius: 3px;
50 | margin-right: 20px;
51 | margin-top: 5px;
52 | padding: 8px 10px;
53 | background: #2980b9;
54 | }
55 |
56 | .add:hover {
57 | background: rgba(0, 0, 0, 0.3);
58 | cursor: pointer;
59 | }
60 |
61 | .row {
62 | color: #333;
63 | background: #FFF;
64 | width: 100%;
65 | height: 40px;
66 | padding-left: 10px;
67 | line-height: 2.8;
68 | }
69 |
70 | .row:hover a {
71 | width: 40px;
72 | opacity: 1;
73 | }
74 |
75 | .row:nth-child(2n) {
76 | background: #f7f7f7;
77 | }
78 |
79 | .row:hover {
80 | background: #eee;
81 | }
82 |
83 | .remove, .completed {
84 | float: right;
85 | text-align: center;
86 | height: 40px;
87 | width: 0;
88 | background: #2ecc71;
89 | color: #FFF;
90 | opacity: 0;
91 | text-decoration: none;
92 | display: inline-block;
93 | -webkit-transition: all .2s ease;
94 | transition: all .2s ease;
95 | }
96 |
97 | .remove:hover, .completed:hover {
98 | background: #27ae60;
99 | }
100 |
101 | .remove {
102 | background: #e74c3c;
103 | }
104 |
105 | .remove:hover {
106 | background: #c0392b;
107 | }
108 |
109 | .done {
110 | text-decoration: line-through;
111 | color: #ccc;
112 | }
113 |
114 | .add-new {
115 | float: right;
116 | height: 40px;
117 | width: 40px;
118 | text-align: center;
119 | background: #2ecc71;
120 | color: #FFF;
121 | line-height: 2.8;
122 | -webkit-transition: all .3s linear;
123 | transition: all .3s linear;
124 | }
125 |
126 | .add-new:hover {
127 | background: #27ae60;
128 | }
129 |
130 | .new-task {
131 | /* display: none; */
132 | }
133 |
134 | .new-task input {
135 | -webkit-appearance: none;
136 | -moz-appearance: none;
137 | border-radius: 0;
138 | background: #ecf0f1;
139 | font-size: 14px;
140 | font-family: 'Open Sans', sans-serif;
141 | width: 320px;
142 | padding: 5px 10px;
143 | height: 40px;
144 | border: none;
145 | outline: none;
146 | }
147 |
148 | .ui-sortable-helper {
149 | -webkit-box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
150 | box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
151 | }
152 |
--------------------------------------------------------------------------------
/21-Context/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #1E314F;
3 | font-family: 'Helvetica Rounded', 'Arial Rounded MT Bold', 'Montserrat', sans-serif;
4 | color: #fff;
5 | }
6 |
7 | .toggleWrapper {
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | transform: translate3d(-50%, -50%, 0);
12 | }
13 |
14 | .toggleWrapper>span {
15 | text-align: center;
16 | display: block;
17 | }
18 |
19 | .toggleWrapper input {
20 | position: absolute;
21 | left: -99em;
22 | }
23 |
24 | .toggle {
25 | cursor: pointer;
26 | display: inline-block;
27 | position: relative;
28 | width: 90px;
29 | height: 50px;
30 | background-color: #83D8FF;
31 | border-radius: 84px;
32 | transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
33 | margin: 2px;
34 | }
35 |
36 | .toggle:before {
37 | position: absolute;
38 | left: -50px;
39 | top: 15px;
40 | font-size: 18px;
41 | }
42 |
43 | .toggle:after {
44 | position: absolute;
45 | right: -48px;
46 | top: 15px;
47 | font-size: 18px;
48 | color: #749ED7;
49 | }
50 |
51 | .toggle__handler {
52 | display: inline-block;
53 | position: relative;
54 | z-index: 1;
55 | top: 3px;
56 | left: 3px;
57 | width: 44px;
58 | height: 44px;
59 | background-color: #FFCF96;
60 | border-radius: 50px;
61 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
62 | transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
63 | transform: rotate(-45deg);
64 | }
65 |
66 | .toggle__handler .crater {
67 | position: absolute;
68 | background-color: #E8CDA5;
69 | opacity: 0;
70 | transition: opacity 200ms ease-in-out;
71 | border-radius: 100%;
72 | }
73 |
74 | .toggle__handler .crater--1 {
75 | top: 18px;
76 | left: 10px;
77 | width: 4px;
78 | height: 4px;
79 | }
80 |
81 | .toggle__handler .crater--2 {
82 | top: 28px;
83 | left: 22px;
84 | width: 6px;
85 | height: 6px;
86 | }
87 |
88 | .toggle__handler .crater--3 {
89 | top: 10px;
90 | left: 25px;
91 | width: 8px;
92 | height: 8px;
93 | }
94 |
95 | .star {
96 | position: absolute;
97 | background-color: #ffffff;
98 | transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
99 | border-radius: 50%;
100 | }
101 |
102 | .star--1 {
103 | top: 10px;
104 | left: 35px;
105 | z-index: 0;
106 | width: 30px;
107 | height: 3px;
108 | }
109 |
110 | .star--2 {
111 | top: 18px;
112 | left: 28px;
113 | z-index: 1;
114 | width: 30px;
115 | height: 3px;
116 | }
117 |
118 | .star--3 {
119 | top: 27px;
120 | left: 40px;
121 | z-index: 0;
122 | width: 30px;
123 | height: 3px;
124 | }
125 |
126 | .star--4,
127 | .star--5,
128 | .star--6 {
129 | opacity: 0;
130 | transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95);
131 | }
132 |
133 | .star--4 {
134 | top: 16px;
135 | left: 11px;
136 | z-index: 0;
137 | width: 2px;
138 | height: 2px;
139 | transform: translate3d(3px, 0, 0);
140 | }
141 |
142 | .star--5 {
143 | top: 32px;
144 | left: 17px;
145 | z-index: 0;
146 | width: 3px;
147 | height: 3px;
148 | transform: translate3d(3px, 0, 0);
149 | }
150 |
151 | .star--6 {
152 | top: 36px;
153 | left: 28px;
154 | z-index: 0;
155 | width: 2px;
156 | height: 2px;
157 | transform: translate3d(3px, 0, 0);
158 | }
159 |
160 | input:checked+.toggle {
161 | background-color: #749DD6;
162 | }
163 |
164 | input:checked+.toggle:before {
165 | color: #749ED7;
166 | }
167 |
168 | input:checked+.toggle:after {
169 | color: #ffffff;
170 | }
171 |
172 | input:checked+.toggle .toggle__handler {
173 | background-color: #FFE5B5;
174 | transform: translate3d(40px, 0, 0) rotate(0);
175 | }
176 |
177 | input:checked+.toggle .toggle__handler .crater {
178 | opacity: 1;
179 | }
180 |
181 | input:checked+.toggle .star--1 {
182 | width: 2px;
183 | height: 2px;
184 | }
185 |
186 | input:checked+.toggle .star--2 {
187 | width: 4px;
188 | height: 4px;
189 | transform: translate3d(-5px, 0, 0);
190 | }
191 |
192 | input:checked+.toggle .star--3 {
193 | width: 2px;
194 | height: 2px;
195 | transform: translate3d(-7px, 0, 0);
196 | }
197 |
198 | input:checked+.toggle .star--4,
199 | input:checked+.toggle .star--5,
200 | input:checked+.toggle .star--6 {
201 | opacity: 1;
202 | transform: translate3d(0, 0, 0);
203 | }
204 |
205 | input:checked+.toggle .star--4 {
206 | transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
207 | }
208 |
209 | input:checked+.toggle .star--5 {
210 | transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
211 | }
212 |
213 | input:checked+.toggle .star--6 {
214 | transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
215 | }
--------------------------------------------------------------------------------
/22-Render-Props/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #1E314F;
3 | font-family: 'Helvetica Rounded', 'Arial Rounded MT Bold', 'Montserrat', sans-serif;
4 | color: #fff;
5 | }
6 |
7 | .toggleWrapper {
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | transform: translate3d(-50%, -50%, 0);
12 | }
13 |
14 | .toggleWrapper>span {
15 | text-align: center;
16 | display: block;
17 | }
18 |
19 | .toggleWrapper input {
20 | position: absolute;
21 | left: -99em;
22 | }
23 |
24 | .toggle {
25 | cursor: pointer;
26 | display: inline-block;
27 | position: relative;
28 | width: 90px;
29 | height: 50px;
30 | background-color: #83D8FF;
31 | border-radius: 84px;
32 | transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
33 | margin: 2px;
34 | }
35 |
36 | .toggle:before {
37 | position: absolute;
38 | left: -50px;
39 | top: 15px;
40 | font-size: 18px;
41 | }
42 |
43 | .toggle:after {
44 | position: absolute;
45 | right: -48px;
46 | top: 15px;
47 | font-size: 18px;
48 | color: #749ED7;
49 | }
50 |
51 | .toggle__handler {
52 | display: inline-block;
53 | position: relative;
54 | z-index: 1;
55 | top: 3px;
56 | left: 3px;
57 | width: 44px;
58 | height: 44px;
59 | background-color: #FFCF96;
60 | border-radius: 50px;
61 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
62 | transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
63 | transform: rotate(-45deg);
64 | }
65 |
66 | .toggle__handler .crater {
67 | position: absolute;
68 | background-color: #E8CDA5;
69 | opacity: 0;
70 | transition: opacity 200ms ease-in-out;
71 | border-radius: 100%;
72 | }
73 |
74 | .toggle__handler .crater--1 {
75 | top: 18px;
76 | left: 10px;
77 | width: 4px;
78 | height: 4px;
79 | }
80 |
81 | .toggle__handler .crater--2 {
82 | top: 28px;
83 | left: 22px;
84 | width: 6px;
85 | height: 6px;
86 | }
87 |
88 | .toggle__handler .crater--3 {
89 | top: 10px;
90 | left: 25px;
91 | width: 8px;
92 | height: 8px;
93 | }
94 |
95 | .star {
96 | position: absolute;
97 | background-color: #ffffff;
98 | transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
99 | border-radius: 50%;
100 | }
101 |
102 | .star--1 {
103 | top: 10px;
104 | left: 35px;
105 | z-index: 0;
106 | width: 30px;
107 | height: 3px;
108 | }
109 |
110 | .star--2 {
111 | top: 18px;
112 | left: 28px;
113 | z-index: 1;
114 | width: 30px;
115 | height: 3px;
116 | }
117 |
118 | .star--3 {
119 | top: 27px;
120 | left: 40px;
121 | z-index: 0;
122 | width: 30px;
123 | height: 3px;
124 | }
125 |
126 | .star--4,
127 | .star--5,
128 | .star--6 {
129 | opacity: 0;
130 | transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95);
131 | }
132 |
133 | .star--4 {
134 | top: 16px;
135 | left: 11px;
136 | z-index: 0;
137 | width: 2px;
138 | height: 2px;
139 | transform: translate3d(3px, 0, 0);
140 | }
141 |
142 | .star--5 {
143 | top: 32px;
144 | left: 17px;
145 | z-index: 0;
146 | width: 3px;
147 | height: 3px;
148 | transform: translate3d(3px, 0, 0);
149 | }
150 |
151 | .star--6 {
152 | top: 36px;
153 | left: 28px;
154 | z-index: 0;
155 | width: 2px;
156 | height: 2px;
157 | transform: translate3d(3px, 0, 0);
158 | }
159 |
160 | input:checked+.toggle {
161 | background-color: #749DD6;
162 | }
163 |
164 | input:checked+.toggle:before {
165 | color: #749ED7;
166 | }
167 |
168 | input:checked+.toggle:after {
169 | color: #ffffff;
170 | }
171 |
172 | input:checked+.toggle .toggle__handler {
173 | background-color: #FFE5B5;
174 | transform: translate3d(40px, 0, 0) rotate(0);
175 | }
176 |
177 | input:checked+.toggle .toggle__handler .crater {
178 | opacity: 1;
179 | }
180 |
181 | input:checked+.toggle .star--1 {
182 | width: 2px;
183 | height: 2px;
184 | }
185 |
186 | input:checked+.toggle .star--2 {
187 | width: 4px;
188 | height: 4px;
189 | transform: translate3d(-5px, 0, 0);
190 | }
191 |
192 | input:checked+.toggle .star--3 {
193 | width: 2px;
194 | height: 2px;
195 | transform: translate3d(-7px, 0, 0);
196 | }
197 |
198 | input:checked+.toggle .star--4,
199 | input:checked+.toggle .star--5,
200 | input:checked+.toggle .star--6 {
201 | opacity: 1;
202 | transform: translate3d(0, 0, 0);
203 | }
204 |
205 | input:checked+.toggle .star--4 {
206 | transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
207 | }
208 |
209 | input:checked+.toggle .star--5 {
210 | transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
211 | }
212 |
213 | input:checked+.toggle .star--6 {
214 | transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
215 | }
--------------------------------------------------------------------------------
/19-Toggler-Composed/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #1E314F;
3 | font-family: 'Helvetica Rounded', 'Arial Rounded MT Bold', 'Montserrat', sans-serif;
4 | color: #fff;
5 | }
6 |
7 | .toggleWrapper {
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | transform: translate3d(-50%, -50%, 0);
12 | }
13 |
14 | .toggleWrapper>span {
15 | text-align: center;
16 | display: block;
17 | }
18 |
19 | .toggleWrapper input {
20 | position: absolute;
21 | left: -99em;
22 | }
23 |
24 | .toggle {
25 | cursor: pointer;
26 | display: inline-block;
27 | position: relative;
28 | width: 90px;
29 | height: 50px;
30 | background-color: #83D8FF;
31 | border-radius: 84px;
32 | transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
33 | margin: 2px;
34 | }
35 |
36 | .toggle:before {
37 | position: absolute;
38 | left: -50px;
39 | top: 15px;
40 | font-size: 18px;
41 | }
42 |
43 | .toggle:after {
44 | position: absolute;
45 | right: -48px;
46 | top: 15px;
47 | font-size: 18px;
48 | color: #749ED7;
49 | }
50 |
51 | .toggle__handler {
52 | display: inline-block;
53 | position: relative;
54 | z-index: 1;
55 | top: 3px;
56 | left: 3px;
57 | width: 44px;
58 | height: 44px;
59 | background-color: #FFCF96;
60 | border-radius: 50px;
61 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
62 | transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
63 | transform: rotate(-45deg);
64 | }
65 |
66 | .toggle__handler .crater {
67 | position: absolute;
68 | background-color: #E8CDA5;
69 | opacity: 0;
70 | transition: opacity 200ms ease-in-out;
71 | border-radius: 100%;
72 | }
73 |
74 | .toggle__handler .crater--1 {
75 | top: 18px;
76 | left: 10px;
77 | width: 4px;
78 | height: 4px;
79 | }
80 |
81 | .toggle__handler .crater--2 {
82 | top: 28px;
83 | left: 22px;
84 | width: 6px;
85 | height: 6px;
86 | }
87 |
88 | .toggle__handler .crater--3 {
89 | top: 10px;
90 | left: 25px;
91 | width: 8px;
92 | height: 8px;
93 | }
94 |
95 | .star {
96 | position: absolute;
97 | background-color: #ffffff;
98 | transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
99 | border-radius: 50%;
100 | }
101 |
102 | .star--1 {
103 | top: 10px;
104 | left: 35px;
105 | z-index: 0;
106 | width: 30px;
107 | height: 3px;
108 | }
109 |
110 | .star--2 {
111 | top: 18px;
112 | left: 28px;
113 | z-index: 1;
114 | width: 30px;
115 | height: 3px;
116 | }
117 |
118 | .star--3 {
119 | top: 27px;
120 | left: 40px;
121 | z-index: 0;
122 | width: 30px;
123 | height: 3px;
124 | }
125 |
126 | .star--4,
127 | .star--5,
128 | .star--6 {
129 | opacity: 0;
130 | transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95);
131 | }
132 |
133 | .star--4 {
134 | top: 16px;
135 | left: 11px;
136 | z-index: 0;
137 | width: 2px;
138 | height: 2px;
139 | transform: translate3d(3px, 0, 0);
140 | }
141 |
142 | .star--5 {
143 | top: 32px;
144 | left: 17px;
145 | z-index: 0;
146 | width: 3px;
147 | height: 3px;
148 | transform: translate3d(3px, 0, 0);
149 | }
150 |
151 | .star--6 {
152 | top: 36px;
153 | left: 28px;
154 | z-index: 0;
155 | width: 2px;
156 | height: 2px;
157 | transform: translate3d(3px, 0, 0);
158 | }
159 |
160 | input:checked+.toggle {
161 | background-color: #749DD6;
162 | }
163 |
164 | input:checked+.toggle:before {
165 | color: #749ED7;
166 | }
167 |
168 | input:checked+.toggle:after {
169 | color: #ffffff;
170 | }
171 |
172 | input:checked+.toggle .toggle__handler {
173 | background-color: #FFE5B5;
174 | transform: translate3d(40px, 0, 0) rotate(0);
175 | }
176 |
177 | input:checked+.toggle .toggle__handler .crater {
178 | opacity: 1;
179 | }
180 |
181 | input:checked+.toggle .star--1 {
182 | width: 2px;
183 | height: 2px;
184 | }
185 |
186 | input:checked+.toggle .star--2 {
187 | width: 4px;
188 | height: 4px;
189 | transform: translate3d(-5px, 0, 0);
190 | }
191 |
192 | input:checked+.toggle .star--3 {
193 | width: 2px;
194 | height: 2px;
195 | transform: translate3d(-7px, 0, 0);
196 | }
197 |
198 | input:checked+.toggle .star--4,
199 | input:checked+.toggle .star--5,
200 | input:checked+.toggle .star--6 {
201 | opacity: 1;
202 | transform: translate3d(0, 0, 0);
203 | }
204 |
205 | input:checked+.toggle .star--4 {
206 | transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
207 | }
208 |
209 | input:checked+.toggle .star--5 {
210 | transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
211 | }
212 |
213 | input:checked+.toggle .star--6 {
214 | transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
215 | }
216 |
--------------------------------------------------------------------------------
/20-Compound-Components/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #1E314F;
3 | font-family: 'Helvetica Rounded', 'Arial Rounded MT Bold', 'Montserrat', sans-serif;
4 | color: #fff;
5 | }
6 |
7 | .toggleWrapper {
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | transform: translate3d(-50%, -50%, 0);
12 | }
13 |
14 | .toggleWrapper>span {
15 | text-align: center;
16 | display: block;
17 | }
18 |
19 | .toggleWrapper input {
20 | position: absolute;
21 | left: -99em;
22 | }
23 |
24 | .toggle {
25 | cursor: pointer;
26 | display: inline-block;
27 | position: relative;
28 | width: 90px;
29 | height: 50px;
30 | background-color: #83D8FF;
31 | border-radius: 84px;
32 | transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
33 | margin: 2px;
34 | }
35 |
36 | .toggle:before {
37 | position: absolute;
38 | left: -50px;
39 | top: 15px;
40 | font-size: 18px;
41 | }
42 |
43 | .toggle:after {
44 | position: absolute;
45 | right: -48px;
46 | top: 15px;
47 | font-size: 18px;
48 | color: #749ED7;
49 | }
50 |
51 | .toggle__handler {
52 | display: inline-block;
53 | position: relative;
54 | z-index: 1;
55 | top: 3px;
56 | left: 3px;
57 | width: 44px;
58 | height: 44px;
59 | background-color: #FFCF96;
60 | border-radius: 50px;
61 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
62 | transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
63 | transform: rotate(-45deg);
64 | }
65 |
66 | .toggle__handler .crater {
67 | position: absolute;
68 | background-color: #E8CDA5;
69 | opacity: 0;
70 | transition: opacity 200ms ease-in-out;
71 | border-radius: 100%;
72 | }
73 |
74 | .toggle__handler .crater--1 {
75 | top: 18px;
76 | left: 10px;
77 | width: 4px;
78 | height: 4px;
79 | }
80 |
81 | .toggle__handler .crater--2 {
82 | top: 28px;
83 | left: 22px;
84 | width: 6px;
85 | height: 6px;
86 | }
87 |
88 | .toggle__handler .crater--3 {
89 | top: 10px;
90 | left: 25px;
91 | width: 8px;
92 | height: 8px;
93 | }
94 |
95 | .star {
96 | position: absolute;
97 | background-color: #ffffff;
98 | transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
99 | border-radius: 50%;
100 | }
101 |
102 | .star--1 {
103 | top: 10px;
104 | left: 35px;
105 | z-index: 0;
106 | width: 30px;
107 | height: 3px;
108 | }
109 |
110 | .star--2 {
111 | top: 18px;
112 | left: 28px;
113 | z-index: 1;
114 | width: 30px;
115 | height: 3px;
116 | }
117 |
118 | .star--3 {
119 | top: 27px;
120 | left: 40px;
121 | z-index: 0;
122 | width: 30px;
123 | height: 3px;
124 | }
125 |
126 | .star--4,
127 | .star--5,
128 | .star--6 {
129 | opacity: 0;
130 | transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95);
131 | }
132 |
133 | .star--4 {
134 | top: 16px;
135 | left: 11px;
136 | z-index: 0;
137 | width: 2px;
138 | height: 2px;
139 | transform: translate3d(3px, 0, 0);
140 | }
141 |
142 | .star--5 {
143 | top: 32px;
144 | left: 17px;
145 | z-index: 0;
146 | width: 3px;
147 | height: 3px;
148 | transform: translate3d(3px, 0, 0);
149 | }
150 |
151 | .star--6 {
152 | top: 36px;
153 | left: 28px;
154 | z-index: 0;
155 | width: 2px;
156 | height: 2px;
157 | transform: translate3d(3px, 0, 0);
158 | }
159 |
160 | input:checked+.toggle {
161 | background-color: #749DD6;
162 | }
163 |
164 | input:checked+.toggle:before {
165 | color: #749ED7;
166 | }
167 |
168 | input:checked+.toggle:after {
169 | color: #ffffff;
170 | }
171 |
172 | input:checked+.toggle .toggle__handler {
173 | background-color: #FFE5B5;
174 | transform: translate3d(40px, 0, 0) rotate(0);
175 | }
176 |
177 | input:checked+.toggle .toggle__handler .crater {
178 | opacity: 1;
179 | }
180 |
181 | input:checked+.toggle .star--1 {
182 | width: 2px;
183 | height: 2px;
184 | }
185 |
186 | input:checked+.toggle .star--2 {
187 | width: 4px;
188 | height: 4px;
189 | transform: translate3d(-5px, 0, 0);
190 | }
191 |
192 | input:checked+.toggle .star--3 {
193 | width: 2px;
194 | height: 2px;
195 | transform: translate3d(-7px, 0, 0);
196 | }
197 |
198 | input:checked+.toggle .star--4,
199 | input:checked+.toggle .star--5,
200 | input:checked+.toggle .star--6 {
201 | opacity: 1;
202 | transform: translate3d(0, 0, 0);
203 | }
204 |
205 | input:checked+.toggle .star--4 {
206 | transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
207 | }
208 |
209 | input:checked+.toggle .star--5 {
210 | transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
211 | }
212 |
213 | input:checked+.toggle .star--6 {
214 | transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
215 | }
216 |
--------------------------------------------------------------------------------
/18-Toggler/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #1E314F;
3 | font-family: 'Helvetica Rounded', 'Arial Rounded MT Bold', 'Montserrat', sans-serif;
4 | color: #fff;
5 | }
6 |
7 | .toggleWrapper {
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | overflow: hidden;
12 | transform: translate3d(-50%, -50%, 0);
13 | }
14 |
15 | .toggleWrapper input {
16 | position: absolute;
17 | left: -99em;
18 | }
19 |
20 | .toggle {
21 | cursor: pointer;
22 | display: inline-block;
23 | position: relative;
24 | width: 90px;
25 | height: 50px;
26 | background-color: #83D8FF;
27 | border-radius: 84px;
28 | transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
29 | margin: 2px;
30 | }
31 |
32 | .toggle:before {
33 | position: absolute;
34 | left: -50px;
35 | top: 15px;
36 | font-size: 18px;
37 | }
38 |
39 | .toggle:after {
40 | position: absolute;
41 | right: -48px;
42 | top: 15px;
43 | font-size: 18px;
44 | color: #749ED7;
45 | }
46 |
47 | .toggle__handler {
48 | display: inline-block;
49 | position: relative;
50 | z-index: 1;
51 | top: 3px;
52 | left: 3px;
53 | width: 44px;
54 | height: 44px;
55 | background-color: #FFCF96;
56 | border-radius: 50px;
57 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
58 | transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
59 | transform: rotate(-45deg);
60 | }
61 |
62 | .toggle__handler .crater {
63 | position: absolute;
64 | background-color: #E8CDA5;
65 | opacity: 0;
66 | transition: opacity 200ms ease-in-out;
67 | border-radius: 100%;
68 | }
69 |
70 | .toggle__handler .crater--1 {
71 | top: 18px;
72 | left: 10px;
73 | width: 4px;
74 | height: 4px;
75 | }
76 |
77 | .toggle__handler .crater--2 {
78 | top: 28px;
79 | left: 22px;
80 | width: 6px;
81 | height: 6px;
82 | }
83 |
84 | .toggle__handler .crater--3 {
85 | top: 10px;
86 | left: 25px;
87 | width: 8px;
88 | height: 8px;
89 | }
90 |
91 | .star {
92 | position: absolute;
93 | background-color: #ffffff;
94 | transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
95 | border-radius: 50%;
96 | }
97 |
98 | .star--1 {
99 | top: 10px;
100 | left: 35px;
101 | z-index: 0;
102 | width: 30px;
103 | height: 3px;
104 | }
105 |
106 | .star--2 {
107 | top: 18px;
108 | left: 28px;
109 | z-index: 1;
110 | width: 30px;
111 | height: 3px;
112 | }
113 |
114 | .star--3 {
115 | top: 27px;
116 | left: 40px;
117 | z-index: 0;
118 | width: 30px;
119 | height: 3px;
120 | }
121 |
122 | .star--4,
123 | .star--5,
124 | .star--6 {
125 | opacity: 0;
126 | transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95);
127 | }
128 |
129 | .star--4 {
130 | top: 16px;
131 | left: 11px;
132 | z-index: 0;
133 | width: 2px;
134 | height: 2px;
135 | transform: translate3d(3px, 0, 0);
136 | }
137 |
138 | .star--5 {
139 | top: 32px;
140 | left: 17px;
141 | z-index: 0;
142 | width: 3px;
143 | height: 3px;
144 | transform: translate3d(3px, 0, 0);
145 | }
146 |
147 | .star--6 {
148 | top: 36px;
149 | left: 28px;
150 | z-index: 0;
151 | width: 2px;
152 | height: 2px;
153 | transform: translate3d(3px, 0, 0);
154 | }
155 |
156 | input:checked+.toggle {
157 | background-color: #749DD6;
158 | }
159 |
160 | input:checked+.toggle:before {
161 | color: #749ED7;
162 | }
163 |
164 | input:checked+.toggle:after {
165 | color: #ffffff;
166 | }
167 |
168 | input:checked+.toggle .toggle__handler {
169 | background-color: #FFE5B5;
170 | transform: translate3d(40px, 0, 0) rotate(0);
171 | }
172 |
173 | input:checked+.toggle .toggle__handler .crater {
174 | opacity: 1;
175 | }
176 |
177 | input:checked+.toggle .star--1 {
178 | width: 2px;
179 | height: 2px;
180 | }
181 |
182 | input:checked+.toggle .star--2 {
183 | width: 4px;
184 | height: 4px;
185 | transform: translate3d(-5px, 0, 0);
186 | }
187 |
188 | input:checked+.toggle .star--3 {
189 | width: 2px;
190 | height: 2px;
191 | transform: translate3d(-7px, 0, 0);
192 | }
193 |
194 | input:checked+.toggle .star--4,
195 | input:checked+.toggle .star--5,
196 | input:checked+.toggle .star--6 {
197 | opacity: 1;
198 | transform: translate3d(0, 0, 0);
199 | }
200 |
201 | input:checked+.toggle .star--4 {
202 | transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
203 | }
204 |
205 | input:checked+.toggle .star--5 {
206 | transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
207 | }
208 |
209 | input:checked+.toggle .star--6 {
210 | transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
211 | }
212 |
213 | #root>div>label:active {
214 | animation: shake 0.1s cubic-bezier(.36, .07, .19, .97) both;
215 | transform: translate3d(0, 0, 0);
216 | backface-visibility: hidden;
217 | perspective: 1000px;
218 | }
219 |
220 | @keyframes shake {
221 | 10%,
222 | 90% {
223 | transform: translate3d(-1px, 0, 0);
224 | }
225 | 20%,
226 | 80% {
227 | transform: translate3d(1px, 0, 0);
228 | }
229 | 30%,
230 | 50%,
231 | 70% {
232 | transform: translate3d(-1px, 0, 0);
233 | }
234 | 40%,
235 | 60% {
236 | transform: translate3d(1px, 0, 0);
237 | }
238 | }
--------------------------------------------------------------------------------