JSFiddle - React, Tailwind, and code Playground
by john_s
HTML
<div id="editor-container">
<div id="editor" tabindex="1"></div>
</div>
CSS
#editor-container {
position: relative;
margin: 0;
padding: 0;
border: 1px solid black;
width: 412px;
height: 72px;
}
#editor {
position: relative;
margin: 0;
border: 2px solid white;
width: 400px;
height: 60px;
padding: 5px;
}
#editor:focus {
border: 2px dashed black;
}
.caret {
padding-top: 12px;
display: inline-block;
text-align: center;
width: 12px;
height: 50px;
position: absolute;
left: 0;
top: 0;
}
.letter {
display: inline-block;
text-align: center;
border: 1px solid black;
width: 20px;
height: 50px;
position: absolute;
left: 0;
top: 0;
}
.letter>.letter-char {
display: block;
font-size: 140%;
}
.letter>.letter-hidden {
display: block;
}
JavaScript
var LETTER_TEMPLATE = '<div class="letter">'
+ '<div class="letter-char"></div>'
+ '<div class="letter-hidden">'
+ '<input type="checkbox"/>'
+ '</div>'
+ '</div>';
var CARET_TEMPLATE = '<div class="caret">></div>';
var EDITOR_MAX = 16;
var $editor = $('#editor');
var letters = [];
var caretPos = 0;
function createLetterBox(letter, index) {
var $letter = $(LETTER_TEMPLATE);
$letter.data('index', index);
$letter.find('.letter-char').text(letter.char);
$letter.find('.letter-hidden').children('input:checkbox').prop('checked', letter.hidden);
return $letter;
}
function updateDisplay() {
var blocks = [];
var i = 0;
var left = 0;
while (i < caretPos) {
blocks.push(createLetterBox(letters[i], i).css('left', left + 'px'));
i++;
left += 22;
}
blocks.push($(CARET_TEMPLATE).css('left', left + 'px'));
left += 10;
while (i < letters.length) {
blocks.push(createLetterBox(letters[i], i).css('left', left + 'px'));
i++;
left += 22;
}
$editor.html(blocks);
}
$editor.on('click', '.letter', function(e) {
if (!$(e.target).is('input')) {
caretPos = $(this).data('index');
updateDisplay();
}
});
$editor.on('change', '.letter>.letter-hidden>input:checkbox', function() {
var $checkbox = $(this);
console.log('change: ' + $checkbox.prop('checked'));
var index = $checkbox.closest('.letter').data('index');
letters[index].hidden = $checkbox.prop('checked');
$editor.focus();
});
$editor.keydown(function(e) {
var ch = e.which;
if (ch == 8) { // Backspace
return false;
}
});
$editor.keyup(function(e) {
var ch = e.which;
if ((ch >= 65) && (ch <= 90) || (ch == 32)) {
console.log('char: ' + ch);
if (letters.length < EDITOR_MAX) {
letters.push({
char: String.fromCharCode(ch),
hidden: false
});
caretPos++;
...