CheckboxList.jsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import {Component} from 'react';
  2. import s from './CheckboxList.css';
  3. import CheckboxListItem from './CheckboxListItem';
  4. const ALL_ITEM = Symbol('ALL_ITEM');
  5. export default class CheckboxList extends Component {
  6. static ALL_ITEM = ALL_ITEM;
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. checkedItems: props.checkedItems || props.items,
  11. };
  12. }
  13. componentWillReceiveProps(newProps) {
  14. if (newProps.items !== this.props.items) {
  15. if (this.isAllChecked()) {
  16. // Preserving `all checked` state
  17. this.setState({checkedItems: newProps.items});
  18. this.informAboutChange(newProps.items);
  19. } else if (this.state.checkedItems.length) {
  20. // Checking only items that are in the new `items` array
  21. const checkedItems = newProps.items.filter(item =>
  22. this.state.checkedItems.find(checkedItem => checkedItem.label === item.label)
  23. );
  24. this.setState({checkedItems});
  25. this.informAboutChange(checkedItems);
  26. }
  27. } else if (newProps.checkedItems !== this.props.checkedItems) {
  28. this.setState({checkedItems: newProps.checkedItems});
  29. }
  30. }
  31. render() {
  32. const {label, items, renderLabel} = this.props;
  33. return (
  34. <div className={s.container}>
  35. <div className={s.label}>{label}:</div>
  36. <div>
  37. <CheckboxListItem
  38. item={ALL_ITEM}
  39. checked={this.isAllChecked()}
  40. onChange={this.handleToggleAllCheck}
  41. >
  42. {renderLabel}
  43. </CheckboxListItem>
  44. {items.map(item => (
  45. <CheckboxListItem
  46. key={item.label}
  47. item={item}
  48. checked={this.isItemChecked(item)}
  49. onChange={this.handleItemCheck}
  50. >
  51. {renderLabel}
  52. </CheckboxListItem>
  53. ))}
  54. </div>
  55. </div>
  56. );
  57. }
  58. handleToggleAllCheck = () => {
  59. const checkedItems = this.isAllChecked() ? [] : this.props.items;
  60. this.setState({checkedItems});
  61. this.informAboutChange(checkedItems);
  62. };
  63. handleItemCheck = item => {
  64. let checkedItems;
  65. if (this.isItemChecked(item)) {
  66. checkedItems = this.state.checkedItems.filter(checkedItem => checkedItem !== item);
  67. } else {
  68. checkedItems = [...this.state.checkedItems, item];
  69. }
  70. this.setState({checkedItems});
  71. this.informAboutChange(checkedItems);
  72. };
  73. isItemChecked(item) {
  74. return this.state.checkedItems.includes(item);
  75. }
  76. isAllChecked() {
  77. return this.props.items.length === this.state.checkedItems.length;
  78. }
  79. informAboutChange(checkedItems) {
  80. setTimeout(() => this.props.onChange(checkedItems));
  81. }
  82. }