Improve demo (REPL, sandbox) on the main page (#1615)

* Improve demo (REPL, sandbox) on the main page

* Update button label

* Update textarea styles

* Change input event listeners to change

* Stack editor/render views vertically

* Add animation to options panel

* Open options panel and maximize view when hash is `demo`

* Fix clipboard text building

* Add -ms prefix to flex-direction

* Set width for [type="color"]

* Add macro example to the demo
This commit is contained in:
ylemkimon
2018-08-17 22:59:16 +09:00
committed by GitHub
parent 062cfb17a5
commit 0687dd431a
3 changed files with 246 additions and 14 deletions

View File

@@ -1,5 +1,6 @@
/* eslint-disable no-var */
/* global katex: false */
/* global ClipboardJS: false */
(function() {
var tex = document.getElementsByClassName("tex");
Array.prototype.forEach.call(tex, function(el) {
@@ -8,12 +9,72 @@
var demoInput = document.getElementById("demo-input");
var demoOutput = document.getElementById("demo-output");
var optionsButton = document.getElementById("options");
var optionsPanel = document.getElementById("options-panel");
var maximize = document.getElementById("maximize");
var copyCode = document.getElementById("code");
var copyPermalink = document.getElementById("permalink");
if (window.location.hash === '#demo') {
optionsPanel.classList.add('opened');
document.body.classList.add("maximized");
maximize.innerHTML = 'Minimize editor';
}
var match = window.location.search.match(/[?&]data=([^&]*)/);
var data = {};
if (match) {
try {
data = JSON.parse(decodeURIComponent(match[1]));
} catch (e) {
// eslint-disable-next-line no-console
console.warn(e);
}
}
if (data.code) {
demoInput.value = data.code;
}
var katexOptions = ["displayMode", "throwOnError", "errorColor", "strict",
"macros"].map(function(id) {
var el = document.getElementById(id);
if (el.type === "checkbox") {
if (typeof data[id] === "boolean") {
el.checked = data[id];
}
} else if (data[id]) {
if (el.placeholder === "JSON") {
el.value = JSON.stringify(data[id]);
} else {
el.value = data[id];
}
}
return el;
});
function getOptions(withCode) {
var options = katexOptions.reduce(function(options, el) {
var val;
if (el.type === "checkbox") {
val = el.checked;
} else if (el.placeholder === "JSON") {
val = el.value ? JSON.parse(el.value) : undefined;
} else {
val = el.value;
}
options[el.id] = val;
return options;
}, {});
if (withCode) {
options.code = demoInput.value;
}
return options;
}
function doDemo() {
try {
katex.render(demoInput.value, demoOutput, {
displayMode: true,
});
katex.render(demoInput.value, demoOutput, getOptions());
} catch (err) {
while (demoOutput.lastChild) {
demoOutput.removeChild(demoOutput.lastChild);
@@ -26,8 +87,46 @@
}
}
demoInput.addEventListener("input", function() {
doDemo();
demoInput.addEventListener("input", doDemo);
optionsButton.addEventListener("click", function() {
if (!optionsPanel.classList.contains('opened')) {
optionsPanel.classList.remove('closed');
optionsPanel.classList.add('opened');
} else {
optionsPanel.classList.remove('opened');
optionsPanel.classList.add('closed');
}
});
maximize.addEventListener("click", function() {
if (!document.body.classList.contains("maximized")) {
document.body.classList.add("maximized");
maximize.innerHTML = 'Minimize editor';
} else {
document.body.classList.remove("maximized");
maximize.innerHTML = 'Maximize editor';
}
});
katexOptions.map(function(el) {
el.addEventListener("change", doDemo);
});
// eslint-disable-next-line no-new
new ClipboardJS(copyCode, {
text: function() {
return 'katex.render(' + JSON.stringify(demoInput.value) +
', /* element */, ' + JSON.stringify(getOptions()) + ')';
},
});
// eslint-disable-next-line no-new
new ClipboardJS(copyPermalink, {
text: function() {
return location.protocol + '//' + location.host + location.pathname +
'?data=' + encodeURIComponent(JSON.stringify(getOptions(true)));
},
});
doDemo();

View File

@@ -7,6 +7,21 @@ b {
font-weight: bolder;
}
textarea {
margin: 0;
overflow: auto;
resize: none;
width: 100%;
}
[type="color"] {
width: 60px;
}
.maximized {
overflow: hidden;
}
.container {
margin: 0 auto;
width: 100%;
@@ -74,10 +89,22 @@ b {
margin: 50px 0 0;
}
.maximized .demo {
-ms-flex-direction: column;
flex-direction: column;
position: fixed;
top: 0;
left: 260px;
right: 0;
height: 100%;
margin: 0;
z-index: 1000;
}
.demo-left,
.demo-right {
box-sizing: border-box;
padding: 20px 30px;
padding: 20px 30px 30px;
height: 260px;
width: 100%;
}
@@ -90,6 +117,10 @@ b {
.demo-left {
background: #444;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
}
.demo-left textarea {
@@ -98,12 +129,20 @@ b {
box-sizing: border-box;
color: #fff;
font: 14px Menlo, monospace;
height: 160px;
margin: 0;
overflow: auto;
padding: 10px;
resize: none;
width: 100%;
-ms-flex-positive: 1;
flex-grow: 1;
}
#options {
cursor: pointer;
float: right;
font-size: 20px;
color: white;
}
.maximized #options {
display: none;
}
.demo-right {
@@ -220,6 +259,35 @@ b {
color: red;
}
#options-panel {
background: #fafafa;
box-shadow: 3px 0 3px rgba(50, 50, 50, 0.3);
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 200px;
transform: translateX(-110%);
-webkit-transform: translateX(-110%);
z-index: 2000;
padding: 10px 30px;
overflow: auto;
}
.opened {
animation: slide-right 0.5s forwards;
-webkit-animation: slide-right 0.5s forwards;
}
.closed {
animation: slide-left 0.5s forwards;
-webkit-animation: slide-left 0.5s forwards;
}
#macros {
height: 150px;
}
@media only screen and (min-width: 736px) {
.demo-left,
.demo-right {
@@ -235,6 +303,10 @@ b {
display: block;
margin-bottom: 10px;
}
#options {
display: none;
}
}
.svg-inline--fa {
@@ -253,3 +325,21 @@ b {
.svg-inline--fa.fa-w-16 {
width: 1em;
}
@keyframes slide-right {
100% { transform: translateX(0%); }
}
@-webkit-keyframes slide-right {
100% { -webkit-transform: translateX(0%); }
}
@keyframes slide-left {
0% { transform: translateX(0%); }
100% { transform: translateX(-110%); }
}
@-webkit-keyframes slide-left {
0% { -webkit-transform: translateX(0%); }
100% { -webkit-transform: translateX(-110%); }
}