Skip to content

Instantly share code, notes, and snippets.

@hatemhosny
Created March 29, 2022 09:01
Show Gist options
  • Save hatemhosny/bd012a8708831a27dda06d2d78b76154 to your computer and use it in GitHub Desktop.
Save hatemhosny/bd012a8708831a27dda06d2d78b76154 to your computer and use it in GitHub Desktop.
CodeJar Code Editor
<main class="view">
<div class="logo"></div>
<h1 class="title">
CodeJar Code Editor
</h1>
<div class="window">
<div class="window-header">
<div class="action-buttons"></div>
<div class="controls">
<div>language: <a class="switch-language" href="">js</a></div>
<div>style: <a class="switch-style" href="">dracula</a></div>
</div>
</div>
<div class="window-body">
<div class="editor language-js" data-gramm="false"></div>
</div>
</div>
<div class="features">
<h2>Features</h2>
<ul>
<li>Lightweight (2 kB only)
<li>Preserves indentation on a new line
<li>Adds closing brackets, quotes
<li>Indents line with the Tab key
<li>Supports undo/redo
</ul>
</div>
</main>
import { CodeJar } from "https://medv.io/codejar/codejar.js";
const highlight = (editor) => {
// highlight.js does not trims old tags,
// let's do it by this hack.
editor.textContent = editor.textContent;
hljs.highlightBlock(editor);
};
const editor = document.querySelector(".editor");
const jar = new CodeJar(editor, highlight);
let currentStyle = 0;
const styles = [
"dracula",
"github",
"solarized-dark",
"solarized-light",
"railscasts",
"monokai-sublime",
"mono-blue",
"tomorrow",
"color-brewer",
"zenburn",
"agate",
"androidstudio",
"atom-one-light",
"rainbow",
"vs",
"atom-one-dark"
].map((name) => {
const link = document.createElement("link");
link.href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/${name}.min.css`;
link.rel = "stylesheet";
link.disabled = "true";
document.head.appendChild(link);
return link;
});
styles[currentStyle].removeAttribute("disabled");
const switchStyleButton = document.querySelector(".switch-style");
switchStyleButton.addEventListener("click", (event) => {
event.preventDefault();
styles[currentStyle].setAttribute("disabled", "true");
currentStyle = (currentStyle + 1) % styles.length;
styles[currentStyle].removeAttribute("disabled");
let [, name] = styles[currentStyle].href.match(
/highlight.js.+?\/styles\/(.+?)\.min\.css$/
);
switchStyleButton.textContent = name;
});
let currentLanguage = 0;
const languages = [
function () {
editor.className = "editor language-js";
jar.updateCode(`import {CodeJar} from '@medv/codejar';
import Prism from 'prismjs';
const editor = document.querySelector('#editor');
const jar = new CodeJar(editor, Prism.highlightElement, {tab: '\\t'});
// Update code
jar.updateCode('let foo = bar');
// Get code
let code = jar.toString();
// Listen to updates
jar.onUpdate(code => {
console.log(code);
});
`);
jar.updateOptions({ tab: " " });
},
function () {
editor.className = "editor language-md";
jar.updateCode(`# CodeJar
An embeddable code editor for the browser 🍯
## Features
* Lightweight (**2 kB** only)
* Preserves indentation on a new line
* Adds closing brackets, quotes
* Indents line with the \`Tab\` key
* Supports *undo*/*redo*
## Getting Started
\`\`\`bash
npm i @medv/codejar
\`\`\``);
jar.updateOptions({ tab: " " });
},
function () {
editor.className = "editor language-go";
jar.updateCode(`package main
import (
\t"fmt"
\t"github.com/antonmedv/expr"
)
func main() {
\tfmt.Println("Hello, CodeJar")
\toutput, err := expr.Eval("1+2")
\tif err != nil {
\t\tpanic(err)
\t}
}
`);
jar.updateOptions({ tab: "\t" });
},
function () {
editor.className = "editor language-ts";
jar.updateCode(`interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = {
firstName: "Jane",
lastName: "User"
};
document.body.textContent = greeter(user);`);
jar.updateOptions({ tab: " " });
},
function () {
editor.className = "editor language-rust";
jar.updateCode(`#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}`);
jar.updateOptions({ tab: " " });
},
function () {
editor.className = "editor language-html";
jar.updateCode(`<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CodeJar</title>
<meta name="author" content="Anton Medvedev">
<meta name="description" content="Micro Code Editor">
</head>
<body>
<h1>CodeJar — Micro Code Editor</h1>
</body>
</html>`);
jar.updateOptions({ tab: " " });
},
function () {
editor.className = "editor language-kotlin";
jar.updateCode(`suspend fun main() = coroutineScope {
for (i in 0 until 10) {
launch {
delay(1000L - i * 10)
print("❤️$i ")
}
}
}
val positiveNumbers = list.filter { it > 0 }
fun calculateTotal(obj: Any) {
if (obj is Invoice)
obj.calculateTotal()
}`);
jar.updateOptions({ tab: " " });
}
];
languages[currentLanguage]();
const switchLanguageButton = document.querySelector(".switch-language");
switchLanguageButton.addEventListener("click", (event) => {
event.preventDefault();
currentLanguage = (currentLanguage + 1) % languages.length;
languages[currentLanguage]();
const [, name] = editor.className.match(/language-(\w+)/);
switchLanguageButton.textContent = name;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
@import url("https://fonts.googleapis.com/css2?family=Lato:wght@300&family=PT+Mono&display=swap");
@import url("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/dracula.min.css");
body {
background-image: linear-gradient(
109.6deg,
rgba(253, 199, 141, 1) 11.3%,
rgba(249, 143, 253, 1) 100.2%
);
font-family: Lato, sans-serif;
font-weight: 300;
font-size: 15px;
margin: 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
*:focus {
outline: none;
}
a,
a:visited,
a:active {
color: black;
}
main {
min-height: 100vh;
display: flex;
align-items: center;
flex-direction: column;
}
.logo {
display: block;
margin: 30px auto 10px;
width: calc(145px / 2);
height: calc(185px / 2);
background: url(https://medv.io/codejar/codejar.svg) no-repeat;
background-size: contain;
}
.title {
color: #fff;
text-align: center;
font-weight: 300;
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
font-size: 34px;
margin-top: 20px;
}
.window {
width: 547px;
border-radius: 6px;
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.1);
overflow: hidden;
margin-bottom: 20px;
}
.window .window-header {
height: 25px;
background: Gainsboro;
position: relative;
}
.window .window-header .action-buttons {
position: absolute;
top: 50%;
left: 10px;
margin-top: -5px;
width: 10px;
height: 10px;
background: Crimson;
border-radius: 50%;
box-shadow: 15px 0 0 Orange, 30px 0 0 LimeGreen;
}
.editor {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),
0 3px 1px -2px rgba(0, 0, 0, 0.2);
font-family: "PT Mono", monospace;
font-size: 14px;
font-weight: 400;
min-height: 340px;
letter-spacing: normal;
line-height: 20px;
padding: 10px;
resize: none !important;
tab-size: 4;
}
.editor.hljs {
padding: 10px;
}
.controls {
font-size: 14px;
position: absolute;
top: 50%;
right: 10px;
margin-top: -10px;
display: flex;
}
.controls > div:first-child > a {
display: inline-block;
width: 40px;
}
.features {
width: 547px;
font-size: 16px;
margin-bottom: 30px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment