JSFiddle - React, Tailwind, and code Playground

HTML

<script type="text/x-template" id="template-popup">
	<div class="modal"></div>
    <div class="popup-body">
        {{text}}
        <button type="button">Новая игра</button>
    </div>
</script>

CSS

table{
	border-collapse: collapse;
}

td{
	width:28px;
	height: 28px;
	background-color: white;
	border: 1px solid;
	cursor: pointer;
	text-align: center;
}

.opened{
	background-color: gray;
}
.bomb:before{
	content: "⚈";
}
.exploded{
	background-color: red;
}

.modal{
	position:fixed;
	top:0px;
	left:0px;
	opacity: 0.3;
	background-color:gray;

	width:100%;
	height:100%;
}

.popup-body{
	position: fixed;
	border: 1px solid;
	background-color: white;
	padding: 10px 40px;
	left:40%;
	top:40%;
	z-index:9999;
}
.popup-body button{
	display: block;
}

.flagged:before{
	content: "⚑";
	color: red;
}

JavaScript

function MineField(options){
	var table = renderTable();
	var bombs = {};
	var template = options.template.innerHTML;
	var modal = document.createElement('div');
	var generated = false;
	self = this;
	
	function generate(bombsCount, firstClicked){
		for(var i = 0; i<bombsCount; i++){
			var x = Math.floor(Math.random()*9);
			var y = Math.floor(Math.random()*9);
			var concatenated = "" + x+ y;
			if(bombs[concatenated] || concatenated==firstClicked ){
				i--;
			}
			else{
				bombs[""+x+y] = [x, y];
			}
		}
	}
	
	table.onclick = function(event){
		leftClick(event.target);
	};
	
	table.oncontextmenu = function(event){
		rightClick(event.target);
		return false;
	};
	
	function leftClick(target){
		if(target.tagName!="TD" || target.classList.contains("opened")) return false;
		var x = target.cellIndex;
		var y = target.parentNode.rowIndex;
		if(!generated){
			var firstClicked = ""+x+y;
			generate(options.bombsCount, firstClicked);
			generated = true;
		}
		open(x,y);	
	}
	
	function rightClick(target){
		if(target.tagName!="TD" || target.classList.contains("opened")) return false;
		target.className = "flagged";
	}
	
	
	function open(x,y){
		var concatenated = ""+x+y;
		var cell = table.rows[y].cells[x];
		if(cell.classList.contains('opened')) return;
		if(bombs[concatenated]){
			cell.className = "bomb";
			openAll();
			cell.classList.add('exploded');
			}
		else{
			cell.className = "opened";
			checkWin();
			var bombsNearby = countBombsNearby(x,y);
			if(bombsNearby>0){
				cell.innerHTML = bombsNearby;
			}
			else{
				var neighbours = getNeighbours(x, y);
				for(var i = 0; i<neighbours.length; i++){
					open(neighbours[i][0], neighbours[i][1]);
				}
			}
		}	
	}
	
	function countBombsNearby(x,y){
		var count = 0;
		var neighbours = getNeighbours(x, y);
		var concatenated = null;
		for(var i = 0; i<neighbours.length; i++){
			concatenated =""+ neighbours[i][0]+neighbours[i][1];
			count+= bombs[concatenated]? 1:0;
		}
		return count;
	}
	
	function...