JSFiddle - React, Tailwind, and code Playground
by William Green
HTML
<div id="menu">
<div class="menuItem">
<div class="menuOpenButton">File</div>
<div class="subMenu">
<div class="selectItem">Open<span class="modifierKeys"><span data-control></span>+O</span>
</div>
<div class="selectItem" onclick="editorObj.save();">Save<span class="modifierKeys"><span data-control></span>+S</span>
</div>
<div class="selectItem">New<span class="modifierKeys"><span data-control></span>+N</span>
</div>
<div class="selectItem">Print<span class="modifierKeys"><span data-control></span>+P</span>
</div>
<div class="selectItem" onclick="editorObj.saveAs();">Save As<span class="modifierKeys"><span data-alt></span>+S</div>
<div class="selectItem" onclick="editorObj.uploadFile();">Upload File<span class="modifierKeys"><span data-alt></span>+O</span>
</div>
</div>
</div>
<div class="menuItem">
<div class="menuOpenButton">Edit</div>
<div class="subMenu">
<div class="selectItem">Copy<span class="modifierKeys"><span data-control></span>+C</span>
</div>
<div class="selectItem">Paste<span class="modifierKeys"><span data-control></span>+V</span>
</div>
<div class="selectItem">Select All<span class="modifierKeys"><span data-control></span>+A</span>
</div>
</div>
</div>
<div class="menuItem">
<div class="menuOpenButton">Settings</div>
</div>
<div class="menuItem">
<div class="menuOpenButton">View</div>
<div class="subMenu">
<div class="selectItem">Theme</div>
<div class="selectItem">Font</div>
</div>
</div>
<div class="menuItem">
<div class="menuOpenButton">Live</div>
<div class="subMenu">
<div class="selectItem">Open Live Preview<span class="modifierKeys"><span data-control></span>+L</span>
</div>
<div class="selectItem">Run<span class="modifierKeys"><span data-control></span>+R</span>
</div>
<hr>
<div class="selectItem">Share</div>
</div>
...
CSS
/*@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro);*/
/*@import url(../fonts/DejaVuSansMono.ttf);*/
/* latin-ext */
@font-face {
font-family: code;
font-weight: 200;
src: url('../../fonts/DejaVuSansMono.ttf');
}
#menu {
width: 100%;
display: table;
position: relative;
z-index: 10000;
font-size: 0;
background-color: #333;
}
#menu .menuItem .menuOpenButton {
padding-left: 6px;
padding-right: 6px;
padding-bottom: 6px;
padding-top: 6px;
font-size: 0.8rem;
position: relative;
z-index: 900000000000000000;
background-color: #333;
}
#menu .menuItem {
color: #fff;
display: inline-block;
cursor: default;
}
#menu .menuItem .subMenu {
display: none;
background-color: #333;
position: absolute;
background-color: #eee;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
min-width: 150px;
}
#menu .menuItem .subMenu .selectItem:last-child {
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
}
#menu .menuItem .subMenu .selectItem {
color: #333;
padding: 8px 5px;
font-size: 0.8rem;
-o-box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
#menu .menuItem .subMenu .selectItem:hover {
/*box-shadow:0px 0px 10px #9BCDFF inset;*/
box-shadow: 0px 0px 10px #ddd inset;
}
[menuActive] {
background-color: #ddd !important;
color: #333 !important;
}
#menu hr {
border-bottom: 1px inset #ddd;
}
.modifierKeys {
float: right;
padding-left: 50px;
}
#documentStatus {
color: #fff;
position: absolute;
top: 0;
font-size: 1rem;
-o-box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
padding: 4px 6px;
height: 100%;
left: 50%;
-o-transform: translate(-50%, 0%);
-moz-transform: translate(-50%, 0%);
-webkit-transform: translate(-50%, 0%);
-ms-transform:...
JavaScript
/*editor method calls and object*/
var editorObj = {
focus: false,
theme: "dark",
highlighted: false,
forceFocus: false,
tabLength: 3,
lineHeight: 20,
fontSize: 20,
autoChars: [
[39, 39, '#FF645F'],
[123, 125, '#B473FF'],
[91, 93, '#91FF69'],
[60, 62, '#FFCE46'],
[40, 41, '#FF8450'],
[34, 34, '#3240FF']
], //opening code followed by closing code (sub arrays)
//autoColors:['#FF645F','#B473FF','#91FF69','#FFCE46','#FF8450','#3240FF'],auto complete color highlighting
pairId: 0,
saved: true,
transferring: false,
hasFocus: function() {
editorCaret.style.display = 'inline-block';
},
noFocus: function() {
editorCaret.style.display = 'none';
},
removeHighlight: function() {
var contentElem = editorContent.querySelectorAll('[data-highlight]');
for (var i = 0; i < contentElem.length; i++) {
contentElem[i].removeAttribute('data-highlight');
}
},
countLines: function() {
var fontSize = editorObj.fontSize;
var codeHeight = editorContent.scrollHeight;
var lineNum = Math.floor(codeHeight / fontSize);
var currentLines = parseInt(lineNumbers.getAttribute('data-lines'));
var numberLag = lineNum - currentLines;
if (numberLag > 0) {
//new number
var number = document.createElement('span');
number.innerHTML = currentLines + 1;
lineNumbers.appendChild(number);
lineNumbers.setAttribute('data-lines', currentLines + 1);
}
if (numberLag < 0 && lineNumbers.children.length > 1) {
//remove number
lineNumbers.removeChild(lineNumbers.lastChild);
lineNumbers.setAttribute('data-lines', currentLines - 1);
}
resizeEditor();
},
scrollToChar: function() {
if (editorCaret.previousElementSibling) {
editorCaret.previousElementSibling.scrollIntoView('smooth');
}
},
save: function() {
editorObj.saved = false;
if (!editorObj.transferring) {
//transferring flag
editorObj.transferring =...