React

by Neeraj Yadav

HTML

<div id="app"></div>

CSS

h1,
p {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
    Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

body {
  box-sizing: border-box;
}

.box {
  display: flex;
  flex-flow: row wrap;
  border: 1px solid yellow;
}

.container {
  display: grid;
  margin: 15px;
  grid-template-columns: auto auto auto;
  width: 94px;
  gap: 2px;
  outline: 1px solid orange;
  padding: 22px;
}

.slot {
  border: 0;
  width: 30px;
  height: 30px;
  cursor: pointer;
  pointer-events: none;
}

.slot.bdr {
  border: 1px solid grey;
  pointer-events: all;
}

.slot.bg {
  background-color: cornflowerblue;
}

React

let boxes = [];
let disableClick = false;

function App() {
  React.useEffect(() => {
    for (let i = 0; i < 9; i++) {
      boxes.push({
        total: null,
        checked: null,
      });
    }

    return () => {
      boxes = [];
    };
  }, []);

  const handleClick = (e) => {
  if (disableClick) return;
    const currentTarget = e.target;
    const _classList = currentTarget.classList;
    console.log(_classList);
    if (_classList.contains('bg')) return;

    const parentElem = currentTarget.parentElement;

    if (!boxes[parentElem.dataset.idx].total) {
      boxes[parentElem.dataset.idx].total =
        parentElem.querySelectorAll('.bdr').length;
      boxes[parentElem.dataset.idx].checked = 1;
      parentElem.setAttribute(
        'data-order',
        parseInt(currentTarget.dataset.pos)
      );
      _classList.add('bg');
    } else {
      const oldOrder = parentElem.dataset.order;
      parentElem.setAttribute(
        'data-order',
        oldOrder + ',' + parseInt(currentTarget.dataset.pos)
      );
      boxes[parentElem.dataset.idx].checked += 1;
      _classList.add('bg');

      if (
        boxes[parentElem.dataset.idx].checked ===
        boxes[parentElem.dataset.idx].total
      ) {
        // start removing bg color
				disableClick = true;
        const list = parentElem.dataset.order.split(',');
        const len = list.length;
        console.log('all boxes checked, about to start reverting');
        list.forEach((pos, idx) => {
          var interval = setTimeout(() => {
            parentElem.childNodes[pos].classList.remove('bg');
            
            if (idx === len - 1) disableClick = false;
          }, [(idx + 1) * 250]);
        });

        parentElem.removeAttribute('data-order');
        boxes[parentElem.dataset.idx].total = null;
        boxes[parentElem.dataset.idx].checked = null;
      }
    }
  };

  console.log('rendering....');
  return (
    <React.Fragment>
      <div className="box">
        <div...