JSFiddle - React, Tailwind, and code Playground

by Travis Almand

HTML

<main>
  <div>
    <button data-console="clear">clear()</button>
  </div>
  <div>
    <section class="slide current"></section>
    <section class="slide"></section>
  </div>
  <div id="panel">
    <button id="prev" type="button" disabled>prev</button>
    <button id="next" type="button">next</button>
  </div>
</main>

<template id="console">
<h2>The Console Object</h2>
<p>The developer’s debugging console has been available in one form or another in web browsers for many years now. Starting out as a means for errors to be reported to the developer, its capabilities have increased in many different ways. Useful features of the console are automatically logging information such as network requests, network responses, security errors or warnings, and more.</p>
<p>There is also a way for the website’s JavaScript to trigger various commands that output to the console for debugging purposes. These commands are contained in a console object available in almost every browser.</p>

<pre><code>console.log(console);</code></pre>

<button data-console="console">log the console object</button>
</template>

<template id="common">
<h2>The Five Basic Commands</h2>
<p>We shall start with five commands that at first glance do much the same thing. Which, technically, they do. But the browsers provide additional features tied to the five commands to give each their own distinct benefit.</p>

  <pre><code>console.debug('console.debug()');
console.error('console.error()');
console.info('console.info()');
console.log('console.log()');
console.warn('console.warn()');</code></pre>

<button data-console="common">show the five commands</button>
</template>

CSS

@import url('https://fonts.googleapis.com/css?family=Open+Sans:700&display=swap');

:root {
  --background-color: #21262d;
  --color: #F5F5F5;
}

html {
  box-sizing: border-box;
  font-size: 10px;
}
*, *:before, *:after {
  box-sizing: inherit;
}

html,
body {
  contain: content;
  height: 100%;
  margin: 0;
  padding: 0;
}

main {
  align-items: center;
  background-color: var(--background-color);
  color: var(--color);
  display: flex;
  flex-direction: column;
  font-family: 'Open Sans', sans-serif;
  font-size: 2rem;
  font-weight: 700;
  height: 100%;
  justify-content: space-between;
}

#title {
  font-family: 'Open Sans', cursive;
  font-size: 3rem;
  text-align: center;
}

.slide {
  background-color: var(--background-color);
  contain: content;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: auto;
  opacity: 0;
  padding: 2rem;
  position: absolute;
  transition: opacity 1000ms;
  width: calc(100% - 5rem);
  z-index: -1;
}
.slide.current {
  opacity: 1;
  position: static;
  z-index: 1;
}
.slide h2 {
  font-size: 2.4rem;
  margin: 1rem 0;
  text-decoration: underline;
}
.slide p {
  margin: 1rem 0;
}
.slide pre {
  background-color: #000;
  color: var(--color);
  line-height: 1.5em;
  padding: 1rem;
}
.slide .button button {
  font-size: 2rem;
}

#panel {
  align-items: stretch;
  display: flex;
  justify-content: center;
  width: 100%;
}
#panel button {
  margin: 2rem;
  padding: 1rem 0;
  width: 50%;
}

[data-console="clear"] {
  font-size: 1.4rem;
  margin: 0;
  position: absolute;
  right: 0;
  top: 0;
  width: auto;
}

button {
  background-color: var(--background-color);
  border: 2px solid var(--color);
  border-radius: 0.5rem;
  color: var(--color);
  cursor: pointer;
  font-family: 'Open Sans', cursive;
  font-size: 2rem;
  font-weight: 700;
  padding: 0.5rem 2rem;
  transition: transform 100ms;
  user-select: none;
  width: auto;
}
button:active {
  transform: scale3d(0.95, 0.95, 1);
}
button[disabled] {
 ...

JavaScript

let main = document.querySelector('main');
let slides = document.querySelectorAll('.slide');
let panel = document.querySelector('#panel');
let templates = document.querySelectorAll('template');

let currentSlide = 0;

let consoles = {
	clear: () => {
  	console.clear();
  },
  console: () =>{
  	console.log(console);
  },
  common: () => {
    console.debug('console.debug()');
    console.error('console.error()');
    console.info('console.info()');
    console.log('console.log()');
    console.warn('console.warn()');
  }
};

main.addEventListener('click', e => {
	if (e.target.dataset.console) {
	  consoles[e.target.dataset.console](e);
  }
});

panel.addEventListener('click', function (e) {
	if (e.target.type !== 'button') {
  	return;
  }
  
	let current = slides[0].classList.contains('current') ? slides[0] : slides[1];
  let hidden = !slides[0].classList.contains('current') ? slides[0] : slides[1];
  
  consoles['clear']();
  
  currentSlide = e.target.id === 'next' ? currentSlide + 1 : currentSlide - 1;
  
  hidden.innerHTML = templates[currentSlide].innerHTML;
  
  current.classList.remove('current');
  hidden.classList.add('current');
  
  this.querySelector('#prev').disabled = currentSlide === 0 ? true : false;
	this.querySelector('#next').disabled = currentSlide === templates.length - 1 ? true : false;
});

main.querySelector('.slide.current').innerHTML = templates[currentSlide].innerHTML;
consoles['clear']();