mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-11-04 09:57:26 +03:00 
			
		
		
		
	feat(redux-devtools-slider-monitor): convert example to TypeScript (#632)
This commit is contained in:
		
							parent
							
								
									89917320e5
								
							
						
					
					
						commit
						ec75d3a4b6
					
				| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
    "@types/node": "^14.6.0",
 | 
					    "@types/node": "^14.6.0",
 | 
				
			||||||
    "@types/webpack": "^4.41.21",
 | 
					    "@types/webpack": "^4.41.21",
 | 
				
			||||||
    "@types/webpack-dev-server": "^3.11.0",
 | 
					    "@types/webpack-dev-server": "^3.11.0",
 | 
				
			||||||
 | 
					    "@types/webpack-env": "^1.15.2",
 | 
				
			||||||
    "@typescript-eslint/eslint-plugin": "^3.9.0",
 | 
					    "@typescript-eslint/eslint-plugin": "^3.9.0",
 | 
				
			||||||
    "@typescript-eslint/parser": "^3.9.0",
 | 
					    "@typescript-eslint/parser": "^3.9.0",
 | 
				
			||||||
    "babel-eslint": "^10.1.0",
 | 
					    "babel-eslint": "^10.1.0",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,9 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  "presets": ["@babel/preset-env", "@babel/preset-react"],
 | 
					  "presets": [
 | 
				
			||||||
 | 
					    "@babel/preset-env",
 | 
				
			||||||
 | 
					    "@babel/preset-react",
 | 
				
			||||||
 | 
					    "@babel/preset-typescript"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
  "plugins": [
 | 
					  "plugins": [
 | 
				
			||||||
    "@babel/plugin-proposal-class-properties",
 | 
					    "@babel/plugin-proposal-class-properties",
 | 
				
			||||||
    "react-hot-loader/babel"
 | 
					    "react-hot-loader/babel"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
					  extends: '../../../../.eslintrc',
 | 
				
			||||||
 | 
					  overrides: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      files: ['*.ts', '*.tsx'],
 | 
				
			||||||
 | 
					      extends: '../../../../eslintrc.ts.react.base.json',
 | 
				
			||||||
 | 
					      parserOptions: {
 | 
				
			||||||
 | 
					        tsconfigRootDir: __dirname,
 | 
				
			||||||
 | 
					        project: ['./tsconfig.json'],
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      files: ['webpack.config.ts'],
 | 
				
			||||||
 | 
					      extends: '../../../../eslintrc.ts.base.json',
 | 
				
			||||||
 | 
					      parserOptions: {
 | 
				
			||||||
 | 
					        tsconfigRootDir: __dirname,
 | 
				
			||||||
 | 
					        project: ['./tsconfig.webpack.json'],
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1,42 +0,0 @@
 | 
				
			||||||
import * as types from '../constants/ActionTypes';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function addTodo(text) {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    type: types.ADD_TODO,
 | 
					 | 
				
			||||||
    text,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function deleteTodo(id) {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    type: types.DELETE_TODO,
 | 
					 | 
				
			||||||
    id,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function editTodo(id, text) {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    type: types.EDIT_TODO,
 | 
					 | 
				
			||||||
    id,
 | 
					 | 
				
			||||||
    text,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function markTodo(id) {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    type: types.MARK_TODO,
 | 
					 | 
				
			||||||
    id,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function markAll() {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    type: types.MARK_ALL,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function clearMarked() {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    type: types.CLEAR_MARKED,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					import * as types from '../constants/ActionTypes';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface AddTodoAction {
 | 
				
			||||||
 | 
					  type: typeof types.ADD_TODO;
 | 
				
			||||||
 | 
					  text: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function addTodo(text: string): AddTodoAction {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: types.ADD_TODO,
 | 
				
			||||||
 | 
					    text,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface DeleteTodoAction {
 | 
				
			||||||
 | 
					  type: typeof types.DELETE_TODO;
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function deleteTodo(id: number): DeleteTodoAction {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: types.DELETE_TODO,
 | 
				
			||||||
 | 
					    id,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface EditTodoAction {
 | 
				
			||||||
 | 
					  type: typeof types.EDIT_TODO;
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					  text: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function editTodo(id: number, text: string): EditTodoAction {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: types.EDIT_TODO,
 | 
				
			||||||
 | 
					    id,
 | 
				
			||||||
 | 
					    text,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface MarkTodoAction {
 | 
				
			||||||
 | 
					  type: typeof types.MARK_TODO;
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function markTodo(id: number): MarkTodoAction {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: types.MARK_TODO,
 | 
				
			||||||
 | 
					    id,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface MarkAllAction {
 | 
				
			||||||
 | 
					  type: typeof types.MARK_ALL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function markAll(): MarkAllAction {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: types.MARK_ALL,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ClearMarkedAction {
 | 
				
			||||||
 | 
					  type: typeof types.CLEAR_MARKED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function clearMarked(): ClearMarkedAction {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: types.CLEAR_MARKED,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type TodoAction =
 | 
				
			||||||
 | 
					  | AddTodoAction
 | 
				
			||||||
 | 
					  | DeleteTodoAction
 | 
				
			||||||
 | 
					  | EditTodoAction
 | 
				
			||||||
 | 
					  | MarkTodoAction
 | 
				
			||||||
 | 
					  | MarkAllAction
 | 
				
			||||||
 | 
					  | ClearMarkedAction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface TodoActions {
 | 
				
			||||||
 | 
					  addTodo(text: string): AddTodoAction;
 | 
				
			||||||
 | 
					  deleteTodo(id: number): DeleteTodoAction;
 | 
				
			||||||
 | 
					  editTodo(id: number, text: string): EditTodoAction;
 | 
				
			||||||
 | 
					  markTodo(id: number): MarkTodoAction;
 | 
				
			||||||
 | 
					  markAll(): MarkAllAction;
 | 
				
			||||||
 | 
					  clearMarked(): ClearMarkedAction;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,12 @@
 | 
				
			||||||
import React, { Component } from 'react';
 | 
					import React, { Component, MouseEventHandler } from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import classnames from 'classnames';
 | 
					import classnames from 'classnames';
 | 
				
			||||||
import { SHOW_ALL, SHOW_MARKED, SHOW_UNMARKED } from '../constants/TodoFilters';
 | 
					import {
 | 
				
			||||||
 | 
					  SHOW_ALL,
 | 
				
			||||||
 | 
					  SHOW_MARKED,
 | 
				
			||||||
 | 
					  SHOW_UNMARKED,
 | 
				
			||||||
 | 
					  TodoFilter,
 | 
				
			||||||
 | 
					} from '../constants/TodoFilters';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FILTER_TITLES = {
 | 
					const FILTER_TITLES = {
 | 
				
			||||||
  [SHOW_ALL]: 'All',
 | 
					  [SHOW_ALL]: 'All',
 | 
				
			||||||
| 
						 | 
					@ -9,7 +14,15 @@ const FILTER_TITLES = {
 | 
				
			||||||
  [SHOW_MARKED]: 'Completed',
 | 
					  [SHOW_MARKED]: 'Completed',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Footer extends Component {
 | 
					interface Props {
 | 
				
			||||||
 | 
					  markedCount: number;
 | 
				
			||||||
 | 
					  unmarkedCount: number;
 | 
				
			||||||
 | 
					  filter: TodoFilter;
 | 
				
			||||||
 | 
					  onClearMarked: MouseEventHandler<HTMLButtonElement>;
 | 
				
			||||||
 | 
					  onShow: (filter: TodoFilter) => void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class Footer extends Component<Props> {
 | 
				
			||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    markedCount: PropTypes.number.isRequired,
 | 
					    markedCount: PropTypes.number.isRequired,
 | 
				
			||||||
    unmarkedCount: PropTypes.number.isRequired,
 | 
					    unmarkedCount: PropTypes.number.isRequired,
 | 
				
			||||||
| 
						 | 
					@ -23,7 +36,7 @@ export default class Footer extends Component {
 | 
				
			||||||
      <footer className="footer">
 | 
					      <footer className="footer">
 | 
				
			||||||
        {this.renderTodoCount()}
 | 
					        {this.renderTodoCount()}
 | 
				
			||||||
        <ul className="filters">
 | 
					        <ul className="filters">
 | 
				
			||||||
          {[SHOW_ALL, SHOW_UNMARKED, SHOW_MARKED].map((filter) => (
 | 
					          {([SHOW_ALL, SHOW_UNMARKED, SHOW_MARKED] as const).map((filter) => (
 | 
				
			||||||
            <li key={filter}>{this.renderFilterLink(filter)}</li>
 | 
					            <li key={filter}>{this.renderFilterLink(filter)}</li>
 | 
				
			||||||
          ))}
 | 
					          ))}
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
| 
						 | 
					@ -43,7 +56,7 @@ export default class Footer extends Component {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderFilterLink(filter) {
 | 
					  renderFilterLink(filter: TodoFilter) {
 | 
				
			||||||
    const title = FILTER_TITLES[filter];
 | 
					    const title = FILTER_TITLES[filter];
 | 
				
			||||||
    const { filter: selectedFilter, onShow } = this.props;
 | 
					    const { filter: selectedFilter, onShow } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,12 +2,16 @@ import React, { Component } from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import TodoTextInput from './TodoTextInput';
 | 
					import TodoTextInput from './TodoTextInput';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Header extends Component {
 | 
					interface Props {
 | 
				
			||||||
 | 
					  addTodo: (text: string) => void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class Header extends Component<Props> {
 | 
				
			||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    addTodo: PropTypes.func.isRequired,
 | 
					    addTodo: PropTypes.func.isRequired,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleSave = (text) => {
 | 
					  handleSave = (text: string) => {
 | 
				
			||||||
    if (text.length !== 0) {
 | 
					    if (text.length !== 0) {
 | 
				
			||||||
      this.props.addTodo(text);
 | 
					      this.props.addTodo(text);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1,38 +1,49 @@
 | 
				
			||||||
import React, { Component } from 'react';
 | 
					import React, { Component, MouseEventHandler } from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import TodoItem from './TodoItem';
 | 
					import TodoItem from './TodoItem';
 | 
				
			||||||
import Footer from './Footer';
 | 
					import Footer from './Footer';
 | 
				
			||||||
import { SHOW_ALL, SHOW_MARKED, SHOW_UNMARKED } from '../constants/TodoFilters';
 | 
					import {
 | 
				
			||||||
 | 
					  SHOW_ALL,
 | 
				
			||||||
 | 
					  SHOW_MARKED,
 | 
				
			||||||
 | 
					  SHOW_UNMARKED,
 | 
				
			||||||
 | 
					  TodoFilter,
 | 
				
			||||||
 | 
					} from '../constants/TodoFilters';
 | 
				
			||||||
 | 
					import { Todo } from '../reducers/todos';
 | 
				
			||||||
 | 
					import { TodoActions } from '../actions/TodoActions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TODO_FILTERS = {
 | 
					const TODO_FILTERS = {
 | 
				
			||||||
  [SHOW_ALL]: () => true,
 | 
					  [SHOW_ALL]: () => true,
 | 
				
			||||||
  [SHOW_UNMARKED]: (todo) => !todo.marked,
 | 
					  [SHOW_UNMARKED]: (todo: Todo) => !todo.marked,
 | 
				
			||||||
  [SHOW_MARKED]: (todo) => todo.marked,
 | 
					  [SHOW_MARKED]: (todo: Todo) => todo.marked,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class MainSection extends Component {
 | 
					interface State {
 | 
				
			||||||
 | 
					  filter: TodoFilter;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  todos: Todo[];
 | 
				
			||||||
 | 
					  actions: TodoActions;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class MainSection extends Component<Props, State> {
 | 
				
			||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    todos: PropTypes.array.isRequired,
 | 
					    todos: PropTypes.array.isRequired,
 | 
				
			||||||
    actions: PropTypes.object.isRequired,
 | 
					    actions: PropTypes.object.isRequired,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(props, context) {
 | 
					  state: State = { filter: SHOW_ALL };
 | 
				
			||||||
    super(props, context);
 | 
					 | 
				
			||||||
    this.handleClearMarked = this.handleClearMarked.bind(this);
 | 
					 | 
				
			||||||
    this.handleShow = this.handleShow.bind(this);
 | 
					 | 
				
			||||||
    this.state = { filter: SHOW_ALL };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleClearMarked() {
 | 
					  handleClearMarked: MouseEventHandler<HTMLButtonElement> = () => {
 | 
				
			||||||
    const atLeastOneMarked = this.props.todos.some((todo) => todo.marked);
 | 
					    const atLeastOneMarked = this.props.todos.some((todo) => todo.marked);
 | 
				
			||||||
    if (atLeastOneMarked) {
 | 
					    if (atLeastOneMarked) {
 | 
				
			||||||
      this.props.actions.clearMarked();
 | 
					      this.props.actions.clearMarked();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleShow(filter) {
 | 
					  handleShow = (filter: TodoFilter) => {
 | 
				
			||||||
    this.setState({ filter });
 | 
					    this.setState({ filter });
 | 
				
			||||||
  }
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render() {
 | 
					  render() {
 | 
				
			||||||
    const { todos, actions } = this.props;
 | 
					    const { todos, actions } = this.props;
 | 
				
			||||||
| 
						 | 
					@ -57,7 +68,7 @@ export default class MainSection extends Component {
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderToggleAll(markedCount) {
 | 
					  renderToggleAll(markedCount: number) {
 | 
				
			||||||
    const { todos, actions } = this.props;
 | 
					    const { todos, actions } = this.props;
 | 
				
			||||||
    if (todos.length > 0) {
 | 
					    if (todos.length > 0) {
 | 
				
			||||||
      return (
 | 
					      return (
 | 
				
			||||||
| 
						 | 
					@ -65,6 +76,7 @@ export default class MainSection extends Component {
 | 
				
			||||||
          className="toggle-all"
 | 
					          className="toggle-all"
 | 
				
			||||||
          type="checkbox"
 | 
					          type="checkbox"
 | 
				
			||||||
          checked={markedCount === todos.length}
 | 
					          checked={markedCount === todos.length}
 | 
				
			||||||
 | 
					          // eslint-disable-next-line @typescript-eslint/unbound-method
 | 
				
			||||||
          onChange={actions.markAll}
 | 
					          onChange={actions.markAll}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
| 
						 | 
					@ -72,7 +84,7 @@ export default class MainSection extends Component {
 | 
				
			||||||
    return null;
 | 
					    return null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderFooter(markedCount) {
 | 
					  renderFooter(markedCount: number) {
 | 
				
			||||||
    const { todos } = this.props;
 | 
					    const { todos } = this.props;
 | 
				
			||||||
    const { filter } = this.state;
 | 
					    const { filter } = this.state;
 | 
				
			||||||
    const unmarkedCount = todos.length - markedCount;
 | 
					    const unmarkedCount = todos.length - markedCount;
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,23 @@ import React, { Component } from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import classnames from 'classnames';
 | 
					import classnames from 'classnames';
 | 
				
			||||||
import TodoTextInput from './TodoTextInput';
 | 
					import TodoTextInput from './TodoTextInput';
 | 
				
			||||||
 | 
					import { Todo } from '../reducers/todos';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class TodoItem extends Component {
 | 
					interface State {
 | 
				
			||||||
 | 
					  editing: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  todo: Todo;
 | 
				
			||||||
 | 
					  addTodo: (text: string) => void;
 | 
				
			||||||
 | 
					  deleteTodo: (id: number) => void;
 | 
				
			||||||
 | 
					  editTodo: (id: number, text: string) => void;
 | 
				
			||||||
 | 
					  markTodo: (id: number) => void;
 | 
				
			||||||
 | 
					  markAll: () => void;
 | 
				
			||||||
 | 
					  clearMarked: () => void;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class TodoItem extends Component<Props, State> {
 | 
				
			||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    todo: PropTypes.object.isRequired,
 | 
					    todo: PropTypes.object.isRequired,
 | 
				
			||||||
    editTodo: PropTypes.func.isRequired,
 | 
					    editTodo: PropTypes.func.isRequired,
 | 
				
			||||||
| 
						 | 
					@ -11,18 +26,15 @@ export default class TodoItem extends Component {
 | 
				
			||||||
    markTodo: PropTypes.func.isRequired,
 | 
					    markTodo: PropTypes.func.isRequired,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(props, context) {
 | 
					  state: State = {
 | 
				
			||||||
    super(props, context);
 | 
					 | 
				
			||||||
    this.state = {
 | 
					 | 
				
			||||||
    editing: false,
 | 
					    editing: false,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleDoubleClick = () => {
 | 
					  handleDoubleClick = () => {
 | 
				
			||||||
    this.setState({ editing: true });
 | 
					    this.setState({ editing: true });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleSave = (id, text) => {
 | 
					  handleSave = (id: number, text: string) => {
 | 
				
			||||||
    if (text.length === 0) {
 | 
					    if (text.length === 0) {
 | 
				
			||||||
      this.props.deleteTodo(id);
 | 
					      this.props.deleteTodo(id);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,25 @@
 | 
				
			||||||
import React, { Component } from 'react';
 | 
					import React, {
 | 
				
			||||||
 | 
					  ChangeEventHandler,
 | 
				
			||||||
 | 
					  Component,
 | 
				
			||||||
 | 
					  FocusEventHandler,
 | 
				
			||||||
 | 
					  KeyboardEventHandler,
 | 
				
			||||||
 | 
					} from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import classnames from 'classnames';
 | 
					import classnames from 'classnames';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class TodoTextInput extends Component {
 | 
					interface State {
 | 
				
			||||||
 | 
					  text: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  onSave: (text: string) => void;
 | 
				
			||||||
 | 
					  text?: string;
 | 
				
			||||||
 | 
					  placeholder?: string;
 | 
				
			||||||
 | 
					  editing?: boolean;
 | 
				
			||||||
 | 
					  newTodo?: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class TodoTextInput extends Component<Props, State> {
 | 
				
			||||||
  static propTypes = {
 | 
					  static propTypes = {
 | 
				
			||||||
    onSave: PropTypes.func.isRequired,
 | 
					    onSave: PropTypes.func.isRequired,
 | 
				
			||||||
    text: PropTypes.string,
 | 
					    text: PropTypes.string,
 | 
				
			||||||
| 
						 | 
					@ -18,15 +35,12 @@ export default class TodoTextInput extends Component {
 | 
				
			||||||
    newTodo: false,
 | 
					    newTodo: false,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(props, context) {
 | 
					  state = {
 | 
				
			||||||
    super(props, context);
 | 
					 | 
				
			||||||
    this.state = {
 | 
					 | 
				
			||||||
    text: this.props.text || '',
 | 
					    text: this.props.text || '',
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleSubmit = (e) => {
 | 
					  handleSubmit: KeyboardEventHandler<HTMLInputElement> = (e) => {
 | 
				
			||||||
    const text = e.target.value.trim();
 | 
					    const text = e.currentTarget.value.trim();
 | 
				
			||||||
    if (e.which === 13) {
 | 
					    if (e.which === 13) {
 | 
				
			||||||
      this.props.onSave(text);
 | 
					      this.props.onSave(text);
 | 
				
			||||||
      if (this.props.newTodo) {
 | 
					      if (this.props.newTodo) {
 | 
				
			||||||
| 
						 | 
					@ -35,11 +49,11 @@ export default class TodoTextInput extends Component {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleChange = (e) => {
 | 
					  handleChange: ChangeEventHandler<HTMLInputElement> = (e) => {
 | 
				
			||||||
    this.setState({ text: e.target.value });
 | 
					    this.setState({ text: e.target.value });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleBlur = (e) => {
 | 
					  handleBlur: FocusEventHandler<HTMLInputElement> = (e) => {
 | 
				
			||||||
    if (!this.props.newTodo) {
 | 
					    if (!this.props.newTodo) {
 | 
				
			||||||
      this.props.onSave(e.target.value);
 | 
					      this.props.onSave(e.target.value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,8 @@
 | 
				
			||||||
export const SHOW_ALL = 'show_all';
 | 
					export const SHOW_ALL = 'show_all';
 | 
				
			||||||
export const SHOW_MARKED = 'show_marked';
 | 
					export const SHOW_MARKED = 'show_marked';
 | 
				
			||||||
export const SHOW_UNMARKED = 'show_unmarked';
 | 
					export const SHOW_UNMARKED = 'show_unmarked';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type TodoFilter =
 | 
				
			||||||
 | 
					  | typeof SHOW_ALL
 | 
				
			||||||
 | 
					  | typeof SHOW_MARKED
 | 
				
			||||||
 | 
					  | typeof SHOW_UNMARKED;
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import { createDevTools } from 'redux-devtools';
 | 
					import { createDevTools } from 'redux-devtools';
 | 
				
			||||||
import DockMonitor from 'redux-devtools-dock-monitor';
 | 
					import DockMonitor from 'redux-devtools-dock-monitor';
 | 
				
			||||||
import SliderMonitor from 'redux-devtools-slider-monitor'; // eslint-disable-line
 | 
					import SliderMonitor from 'redux-devtools-slider-monitor';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default createDevTools(
 | 
					export default createDevTools(
 | 
				
			||||||
  <DockMonitor
 | 
					  <DockMonitor
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,17 @@ import { hot } from 'react-hot-loader/root';
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import { Provider } from 'react-redux';
 | 
					import { Provider } from 'react-redux';
 | 
				
			||||||
 | 
					import { Store } from 'redux';
 | 
				
			||||||
import TodoApp from './TodoApp';
 | 
					import TodoApp from './TodoApp';
 | 
				
			||||||
import DevTools from './DevTools';
 | 
					import DevTools from './DevTools';
 | 
				
			||||||
 | 
					import { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					import { TodoAction } from '../actions/TodoActions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Root = ({ store }) => (
 | 
					interface Props {
 | 
				
			||||||
 | 
					  store: Store<TodoState, TodoAction>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Root: React.FunctionComponent<Props> = ({ store }) => (
 | 
				
			||||||
  <Provider store={store}>
 | 
					  <Provider store={store}>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      <TodoApp />
 | 
					      <TodoApp />
 | 
				
			||||||
| 
						 | 
					@ -15,7 +22,7 @@ const Root = ({ store }) => (
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Root.propTypes = {
 | 
					Root.propTypes = {
 | 
				
			||||||
  store: PropTypes.object.isRequired,
 | 
					  store: PropTypes.any.isRequired,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default hot(Root);
 | 
					export default hot(Root);
 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
/* eslint-disable global-require */
 | 
					 | 
				
			||||||
if (process.env.NODE_ENV === 'production') {
 | 
					 | 
				
			||||||
  module.exports = require('./Root.prod');
 | 
					 | 
				
			||||||
} else {
 | 
					 | 
				
			||||||
  module.exports = require('./Root.dev');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,19 +0,0 @@
 | 
				
			||||||
import { hot } from 'react-hot-loader/root';
 | 
					 | 
				
			||||||
import React from 'react';
 | 
					 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					 | 
				
			||||||
import { Provider } from 'react-redux';
 | 
					 | 
				
			||||||
import TodoApp from './TodoApp';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const Root = ({ store }) => (
 | 
					 | 
				
			||||||
  <Provider store={store}>
 | 
					 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <TodoApp />
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </Provider>
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Root.propTypes = {
 | 
					 | 
				
			||||||
  store: PropTypes.object.isRequired,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default hot(Root);
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					import { hot } from 'react-hot-loader/root';
 | 
				
			||||||
 | 
					import React, { FunctionComponent } from 'react';
 | 
				
			||||||
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
 | 
					import { Provider } from 'react-redux';
 | 
				
			||||||
 | 
					import TodoApp from './TodoApp';
 | 
				
			||||||
 | 
					import { Store } from 'redux';
 | 
				
			||||||
 | 
					import { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					import { TodoAction } from '../actions/TodoActions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  store: Store<TodoState, TodoAction>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Root: FunctionComponent<Props> = ({ store }) => (
 | 
				
			||||||
 | 
					  <Provider store={store}>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <TodoApp />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </Provider>
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Root.propTypes = {
 | 
				
			||||||
 | 
					  store: PropTypes.any.isRequired,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default hot(Root);
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					import { Store } from 'redux';
 | 
				
			||||||
 | 
					import { ComponentType } from 'react';
 | 
				
			||||||
 | 
					import { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					import { TodoAction } from '../actions/TodoActions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  store: Store<TodoState, TodoAction>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					const Root: ComponentType<Props> =
 | 
				
			||||||
 | 
					  process.env.NODE_ENV === 'production'
 | 
				
			||||||
 | 
					    ? // eslint-disable-next-line @typescript-eslint/no-var-requires
 | 
				
			||||||
 | 
					      require('./Root.prod').default
 | 
				
			||||||
 | 
					    : // eslint-disable-next-line @typescript-eslint/no-var-requires
 | 
				
			||||||
 | 
					      require('./Root.dev').default;
 | 
				
			||||||
 | 
					export default Root;
 | 
				
			||||||
| 
						 | 
					@ -1,33 +0,0 @@
 | 
				
			||||||
import React from 'react';
 | 
					 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					 | 
				
			||||||
import { connect } from 'react-redux';
 | 
					 | 
				
			||||||
import { bindActionCreators } from 'redux';
 | 
					 | 
				
			||||||
import Header from '../components/Header';
 | 
					 | 
				
			||||||
import MainSection from '../components/MainSection';
 | 
					 | 
				
			||||||
import * as TodoActions from '../actions/TodoActions';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const TodoApp = ({ todos, actions }) => (
 | 
					 | 
				
			||||||
  <div>
 | 
					 | 
				
			||||||
    <Header addTodo={actions.addTodo} />
 | 
					 | 
				
			||||||
    <MainSection todos={todos} actions={actions} />
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TodoApp.propTypes = {
 | 
					 | 
				
			||||||
  todos: PropTypes.array.isRequired,
 | 
					 | 
				
			||||||
  actions: PropTypes.object.isRequired,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function mapState(state) {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    todos: state.todos,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function mapDispatch(dispatch) {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    actions: bindActionCreators(TodoActions, dispatch),
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default connect(mapState, mapDispatch)(TodoApp);
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					import React, { FunctionComponent } from 'react';
 | 
				
			||||||
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
 | 
					import { bindActionCreators, Dispatch } from 'redux';
 | 
				
			||||||
 | 
					import Header from '../components/Header';
 | 
				
			||||||
 | 
					import MainSection from '../components/MainSection';
 | 
				
			||||||
 | 
					import * as TodoActions from '../actions/TodoActions';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  TodoAction,
 | 
				
			||||||
 | 
					  TodoActions as TodoActionsType,
 | 
				
			||||||
 | 
					} from '../actions/TodoActions';
 | 
				
			||||||
 | 
					import { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					import { Todo } from '../reducers/todos';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  todos: Todo[];
 | 
				
			||||||
 | 
					  actions: TodoActionsType;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TodoApp: FunctionComponent<Props> = ({ todos, actions }) => (
 | 
				
			||||||
 | 
					  <div>
 | 
				
			||||||
 | 
					    {/* eslint-disable-next-line @typescript-eslint/unbound-method */}
 | 
				
			||||||
 | 
					    <Header addTodo={actions.addTodo} />
 | 
				
			||||||
 | 
					    <MainSection todos={todos} actions={actions} />
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TodoApp.propTypes = {
 | 
				
			||||||
 | 
					  todos: PropTypes.array.isRequired,
 | 
				
			||||||
 | 
					  actions: PropTypes.any.isRequired,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function mapState(state: TodoState) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    todos: state.todos,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function mapDispatch(dispatch: Dispatch<TodoAction>) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    actions: bindActionCreators(TodoActions, dispatch),
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default connect(mapState, mapDispatch)(TodoApp);
 | 
				
			||||||
| 
						 | 
					@ -1,23 +0,0 @@
 | 
				
			||||||
import 'todomvc-app-css/index.css';
 | 
					 | 
				
			||||||
import React from 'react';
 | 
					 | 
				
			||||||
import ReactDOM from 'react-dom';
 | 
					 | 
				
			||||||
import { AppContainer } from 'react-hot-loader';
 | 
					 | 
				
			||||||
import configureStore from './store/configureStore';
 | 
					 | 
				
			||||||
import Root from './containers/Root';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const store = configureStore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const rootEl = document.getElementById('root');
 | 
					 | 
				
			||||||
const render = () => {
 | 
					 | 
				
			||||||
  ReactDOM.render(
 | 
					 | 
				
			||||||
    <AppContainer>
 | 
					 | 
				
			||||||
      <Root store={store} />
 | 
					 | 
				
			||||||
    </AppContainer>,
 | 
					 | 
				
			||||||
    rootEl
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
render(Root);
 | 
					 | 
				
			||||||
if (module.hot) {
 | 
					 | 
				
			||||||
  module.hot.accept('./containers/Root', render);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					import 'todomvc-app-css/index.css';
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
 | 
					import { AppContainer } from 'react-hot-loader';
 | 
				
			||||||
 | 
					import configureStore from './store/configureStore';
 | 
				
			||||||
 | 
					import Root from './containers/Root';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const store = configureStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const rootEl = document.getElementById('root');
 | 
				
			||||||
 | 
					ReactDOM.render(
 | 
				
			||||||
 | 
					  <AppContainer>
 | 
				
			||||||
 | 
					    <Root store={store} />
 | 
				
			||||||
 | 
					  </AppContainer>,
 | 
				
			||||||
 | 
					  rootEl
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (module.hot) {
 | 
				
			||||||
 | 
					  module.hot.accept('./containers/Root', () => {
 | 
				
			||||||
 | 
					    // eslint-disable-next-line @typescript-eslint/no-var-requires
 | 
				
			||||||
 | 
					    const RootContainer = require('./containers/Root').default;
 | 
				
			||||||
 | 
					    ReactDOM.render(
 | 
				
			||||||
 | 
					      <AppContainer>
 | 
				
			||||||
 | 
					        <RootContainer store={store} />
 | 
				
			||||||
 | 
					      </AppContainer>,
 | 
				
			||||||
 | 
					      rootEl
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,22 +2,23 @@
 | 
				
			||||||
  "name": "slider-todomvc",
 | 
					  "name": "slider-todomvc",
 | 
				
			||||||
  "version": "0.0.2",
 | 
					  "version": "0.0.2",
 | 
				
			||||||
  "description": "TodoMVC example for redux",
 | 
					  "description": "TodoMVC example for redux",
 | 
				
			||||||
  "private": true,
 | 
					  "license": "MIT",
 | 
				
			||||||
  "main": "index.js",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "start": "webpack-dev-server",
 | 
					 | 
				
			||||||
    "build": "webpack --config webpack.config.prod.js"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "repository": {
 | 
					  "repository": {
 | 
				
			||||||
    "type": "git",
 | 
					    "type": "git",
 | 
				
			||||||
    "url": "https://github.com/calesce/redux-slider-monitor.git"
 | 
					    "url": "https://github.com/calesce/redux-slider-monitor.git"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "license": "MIT",
 | 
					  "scripts": {
 | 
				
			||||||
 | 
					    "start": "webpack-dev-server",
 | 
				
			||||||
 | 
					    "lint": "eslint . --ext .ts,.tsx",
 | 
				
			||||||
 | 
					    "lint:fix": "eslint . --ext .ts,.tsx --fix",
 | 
				
			||||||
 | 
					    "type-check": "tsc --noEmit",
 | 
				
			||||||
 | 
					    "type-check:watch": "npm run type-check -- --watch"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "classnames": "^2.2.6",
 | 
					    "classnames": "^2.2.6",
 | 
				
			||||||
    "react-hot-loader": "^4.12.21",
 | 
					 | 
				
			||||||
    "react": "^16.13.1",
 | 
					    "react": "^16.13.1",
 | 
				
			||||||
    "react-dom": "^16.13.1",
 | 
					    "react-dom": "^16.13.1",
 | 
				
			||||||
 | 
					    "react-hot-loader": "^4.12.21",
 | 
				
			||||||
    "react-redux": "^7.2.1",
 | 
					    "react-redux": "^7.2.1",
 | 
				
			||||||
    "redux": "^4.0.5",
 | 
					    "redux": "^4.0.5",
 | 
				
			||||||
    "redux-devtools": "^3.7.0",
 | 
					    "redux-devtools": "^3.7.0",
 | 
				
			||||||
| 
						 | 
					@ -25,5 +26,12 @@
 | 
				
			||||||
    "redux-devtools-log-monitor": "^2.1.0",
 | 
					    "redux-devtools-log-monitor": "^2.1.0",
 | 
				
			||||||
    "redux-devtools-slider-monitor": "^2.0.0-5",
 | 
					    "redux-devtools-slider-monitor": "^2.0.0-5",
 | 
				
			||||||
    "todomvc-app-css": "^2.3.0"
 | 
					    "todomvc-app-css": "^2.3.0"
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "@types/classnames": "^2.2.10",
 | 
				
			||||||
 | 
					    "@types/react": "^16.9.46",
 | 
				
			||||||
 | 
					    "@types/react-dom": "^16.9.8",
 | 
				
			||||||
 | 
					    "@types/react-redux": "^7.1.9"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "private": true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,9 @@
 | 
				
			||||||
import { combineReducers } from 'redux';
 | 
					import { combineReducers } from 'redux';
 | 
				
			||||||
import todos from './todos';
 | 
					import todos, { Todo } from './todos';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface TodoState {
 | 
				
			||||||
 | 
					  todos: Todo[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const rootReducer = combineReducers({
 | 
					const rootReducer = combineReducers({
 | 
				
			||||||
  todos,
 | 
					  todos,
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,15 @@ import {
 | 
				
			||||||
  MARK_ALL,
 | 
					  MARK_ALL,
 | 
				
			||||||
  CLEAR_MARKED,
 | 
					  CLEAR_MARKED,
 | 
				
			||||||
} from '../constants/ActionTypes';
 | 
					} from '../constants/ActionTypes';
 | 
				
			||||||
 | 
					import { TodoAction } from '../actions/TodoActions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initialState = [
 | 
					export interface Todo {
 | 
				
			||||||
 | 
					  text: string;
 | 
				
			||||||
 | 
					  marked: boolean;
 | 
				
			||||||
 | 
					  id: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const initialState: Todo[] = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    text: 'Use Redux',
 | 
					    text: 'Use Redux',
 | 
				
			||||||
    marked: false,
 | 
					    marked: false,
 | 
				
			||||||
| 
						 | 
					@ -15,7 +22,7 @@ const initialState = [
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function todos(state = initialState, action) {
 | 
					export default function todos(state = initialState, action: TodoAction) {
 | 
				
			||||||
  switch (action.type) {
 | 
					  switch (action.type) {
 | 
				
			||||||
    case ADD_TODO:
 | 
					    case ADD_TODO:
 | 
				
			||||||
      return [
 | 
					      return [
 | 
				
			||||||
| 
						 | 
					@ -48,7 +55,7 @@ export default function todos(state = initialState, action) {
 | 
				
			||||||
      }));
 | 
					      }));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case CLEAR_MARKED:
 | 
					    case CLEAR_MARKED:
 | 
				
			||||||
      return state.filter((todo) => todo.marked === false);
 | 
					      return state.filter((todo) => !todo.marked);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      return state;
 | 
					      return state;
 | 
				
			||||||
| 
						 | 
					@ -1,19 +0,0 @@
 | 
				
			||||||
import { createStore, compose } from 'redux';
 | 
					 | 
				
			||||||
import { persistState } from 'redux-devtools';
 | 
					 | 
				
			||||||
import rootReducer from '../reducers';
 | 
					 | 
				
			||||||
import DevTools from '../containers/DevTools';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const finalCreateStore = compose(
 | 
					 | 
				
			||||||
  DevTools.instrument(),
 | 
					 | 
				
			||||||
  persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
 | 
					 | 
				
			||||||
)(createStore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function configureStore(initialState) {
 | 
					 | 
				
			||||||
  const store = finalCreateStore(rootReducer, initialState);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (module.hot) {
 | 
					 | 
				
			||||||
    module.hot.accept('../reducers', () => store.replaceReducer(rootReducer));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return store;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					import { createStore, compose, PreloadedState } from 'redux';
 | 
				
			||||||
 | 
					import { persistState } from 'redux-devtools';
 | 
				
			||||||
 | 
					import rootReducer, { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					import DevTools from '../containers/DevTools';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getDebugSessionKey() {
 | 
				
			||||||
 | 
					  const matches = /[?&]debug_session=([^&#]+)\b/.exec(window.location.href);
 | 
				
			||||||
 | 
					  return matches && matches.length > 0 ? matches[1] : null;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const enhancer = compose(
 | 
				
			||||||
 | 
					  DevTools.instrument(),
 | 
				
			||||||
 | 
					  persistState(getDebugSessionKey())
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function configureStore(
 | 
				
			||||||
 | 
					  initialState?: PreloadedState<TodoState>
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  const store = createStore(rootReducer, initialState, enhancer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (module.hot) {
 | 
				
			||||||
 | 
					    module.hot.accept('../reducers', () => store.replaceReducer(rootReducer));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return store;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
/* eslint-disable global-require */
 | 
					 | 
				
			||||||
if (process.env.NODE_ENV === 'production') {
 | 
					 | 
				
			||||||
  module.exports = require('./configureStore.prod');
 | 
					 | 
				
			||||||
} else {
 | 
					 | 
				
			||||||
  module.exports = require('./configureStore.dev');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
import { createStore } from 'redux';
 | 
					 | 
				
			||||||
import rootReducer from '../reducers';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function configureStore(initialState) {
 | 
					 | 
				
			||||||
  return createStore(rootReducer, initialState);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					import { createStore, PreloadedState } from 'redux';
 | 
				
			||||||
 | 
					import rootReducer, { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function configureStore(
 | 
				
			||||||
 | 
					  initialState?: PreloadedState<TodoState>
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  return createStore(rootReducer, initialState);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					import { PreloadedState, Store } from 'redux';
 | 
				
			||||||
 | 
					import { TodoState } from '../reducers';
 | 
				
			||||||
 | 
					import { TodoAction } from '../actions/TodoActions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const configureStore: (
 | 
				
			||||||
 | 
					  initialState?: PreloadedState<TodoState>
 | 
				
			||||||
 | 
					) => Store<TodoState, TodoAction> =
 | 
				
			||||||
 | 
					  process.env.NODE_ENV === 'production'
 | 
				
			||||||
 | 
					    ? // eslint-disable-next-line @typescript-eslint/no-var-requires
 | 
				
			||||||
 | 
					      require('./configureStore.prod').default
 | 
				
			||||||
 | 
					    : // eslint-disable-next-line @typescript-eslint/no-var-requires
 | 
				
			||||||
 | 
					      require('./configureStore.dev').default;
 | 
				
			||||||
 | 
					export default configureStore;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "extends": "../../../../tsconfig.react.base.json",
 | 
				
			||||||
 | 
					  "include": ["."]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "extends": "../../../../tsconfig.base.json",
 | 
				
			||||||
 | 
					  "include": ["webpack.config.ts"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,8 +0,0 @@
 | 
				
			||||||
// NOTE: This config is used for deploy to gh-pages
 | 
					 | 
				
			||||||
const webpack = require('webpack');
 | 
					 | 
				
			||||||
const devConfig = require('./webpack.config');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
devConfig.entry = './index';
 | 
					 | 
				
			||||||
devConfig.plugins = [new webpack.NoEmitOnErrorsPlugin()];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = devConfig;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,8 @@
 | 
				
			||||||
const path = require('path');
 | 
					import * as path from 'path';
 | 
				
			||||||
const webpack = require('webpack');
 | 
					import * as webpack from 'webpack';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
  devtool: 'eval-source-map',
 | 
					  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
 | 
				
			||||||
  devServer: {
 | 
					 | 
				
			||||||
    contentBase: path.join(__dirname, 'dist'),
 | 
					 | 
				
			||||||
    host: 'localhost',
 | 
					 | 
				
			||||||
    port: process.env.PORT || 3000,
 | 
					 | 
				
			||||||
    historyApiFallback: true,
 | 
					 | 
				
			||||||
    hot: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  entry: [
 | 
					  entry: [
 | 
				
			||||||
    'webpack-dev-server/client?http://localhost:3000',
 | 
					    'webpack-dev-server/client?http://localhost:3000',
 | 
				
			||||||
    'webpack/hot/only-dev-server',
 | 
					    'webpack/hot/only-dev-server',
 | 
				
			||||||
| 
						 | 
					@ -19,14 +12,13 @@ module.exports = {
 | 
				
			||||||
    path: path.join(__dirname, 'dist'),
 | 
					    path: path.join(__dirname, 'dist'),
 | 
				
			||||||
    filename: 'bundle.js',
 | 
					    filename: 'bundle.js',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  plugins: [new webpack.HotModuleReplacementPlugin()],
 | 
					 | 
				
			||||||
  module: {
 | 
					  module: {
 | 
				
			||||||
    rules: [
 | 
					    rules: [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        test: /\.js$/,
 | 
					        test: /\.(js|ts)x?$/,
 | 
				
			||||||
        use: ['babel-loader'],
 | 
					        use: ['babel-loader'],
 | 
				
			||||||
        exclude: /node_modules/,
 | 
					        exclude: /node_modules/,
 | 
				
			||||||
        include: [__dirname, path.join(__dirname, '../../src')],
 | 
					        include: __dirname,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        test: /\.css?$/,
 | 
					        test: /\.css?$/,
 | 
				
			||||||
| 
						 | 
					@ -42,4 +34,16 @@ module.exports = {
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  resolve: {
 | 
				
			||||||
 | 
					    extensions: ['.js', '.jsx', '.ts', '.tsx'],
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  plugins: [new webpack.HotModuleReplacementPlugin()],
 | 
				
			||||||
 | 
					  devServer: {
 | 
				
			||||||
 | 
					    contentBase: path.join(__dirname, 'dist'),
 | 
				
			||||||
 | 
					    host: 'localhost',
 | 
				
			||||||
 | 
					    port: process.env.PORT || 3000,
 | 
				
			||||||
 | 
					    historyApiFallback: true,
 | 
				
			||||||
 | 
					    hot: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  devtool: 'eval-source-map',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import { Store } from 'redux';
 | 
					import { Store } from 'redux';
 | 
				
			||||||
 | 
					import { ComponentType } from 'react';
 | 
				
			||||||
import { TodoState } from '../reducers';
 | 
					import { TodoState } from '../reducers';
 | 
				
			||||||
import { TodoAction } from '../actions/TodoActions';
 | 
					import { TodoAction } from '../actions/TodoActions';
 | 
				
			||||||
import { ComponentType } from 'react';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Props {
 | 
					interface Props {
 | 
				
			||||||
  store: Store<TodoState, TodoAction>;
 | 
					  store: Store<TodoState, TodoAction>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,8 +48,7 @@
 | 
				
			||||||
    "@types/prop-types": "^15.7.3",
 | 
					    "@types/prop-types": "^15.7.3",
 | 
				
			||||||
    "@types/react": "^16.9.46",
 | 
					    "@types/react": "^16.9.46",
 | 
				
			||||||
    "@types/react-dom": "^16.9.8",
 | 
					    "@types/react-dom": "^16.9.8",
 | 
				
			||||||
    "@types/react-redux": "^7.1.9",
 | 
					    "@types/react-redux": "^7.1.9"
 | 
				
			||||||
    "@types/webpack-env": "^1.15.2"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "private": true
 | 
					  "private": true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user