JSFiddle - React, Tailwind, and code Playground
by waxwing
HTML
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.4/typeahead.bundle.min.js"></script>
<p></p>
<div class="booltar">
<button id="not">Not</button>
<button id="and">And _</button>
<button id="or">Or _</button>
<button id="gt">> _</button>
<button id="lt">< _</button>
<button id="plus">+ _</button>
<button id="minus">- _</button>
<button id="match">Matches _</button>
<button id="equals">Equals _</button>
</div>
<div class="outer">
<div class="toolbar"> <i class="fa fa-magic toggler toggly" title="Assisted mode"></i>
<i class="fa fa-code toggler toggly" title="Raw mode"></i>
<i class="fa favorite fa-star-o" title="Favorite"></i>
</div>
<textarea class="advanced toggly">(FieldA > 0 AND FieldA < 100) OR (matches(TextField, '\d+'))</textarea>
<div class="holder toggly" tabindex="0">
<span class="box focus">value</span>
<!--
<span class="box or">
<span class="box and">
<span class="box gt">
<span class="box field">value</span>
> <span class="box constant">0</span>
</span>and <span class="box lt">
<span class="box field">FieldA</span>
< <span class="box constant">100</span>
</span>
</span>or <span class="box expandable">
<span class="box field">TextField</span>
is numeric</span>
</span>
-->
</div>
</div>
CSS
.outer {
position: relative;
}
.advanced, .fa-magic {
display: none;
}
.toolbar {
position: absolute;
top: 5px;
right: 5px;
}
.booltar {
background-color: #dadada;
padding: 2px;
border: 1px solid black;
border-bottom: none;
}
.booltar button {
border: 1px solid #aaa;
background: transparent;
padding: 2px;
}
.booltar button:hover {
border: 1px solid black;
background: #fff;
}
textarea {
height: 100px;
width: 100%;
}
.holder {
border: 1px solid black;
padding: 5px;
margin-left: 0;
}
div {
margin-left: 1em;
}
.expanded {
display: none;
}
.box {
border: 1px solid transparent;
border-radius: 2px;
padding: 1px;
}
.box.focus {
border: 1px solid gray;
}
.regexp {
background-color: #ffdada;
}
.field {
color: #090;
}
.fa:hover {
border: 1px solid #dadada;
}
.fa {
cursor: pointer;
padding: 2px;
border-radius: 2px;
border: 1px solid transparent;
}
.editable {
padding: 2px;
border: 1px solid transparent;
border-radius: 2px;
}
.editing {
background-color: #ccc;
}
.editable .fa {
visibility: hidden;
}
.editable:hover .fa {
visibility: visible;
}
.editable:hover {
border: 1px solid #ccc;
}
.empty {
padding-left: .25em;
padding-right: .25em;
}
.parens .and::before,
.parens .or:before,
.parens .not::before{
content: '(';
}
.parens .and::after,
.parens .or::after,
.parens .not::after{
content: ')';
}
#fakeinput {
}
.tt-input, /* UPDATE: newer versions use tt-input instead of tt-query */
.tt-hint {
}
.tt-input { /* UPDATE: newer versions use tt-input instead of tt-query */
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.tt-hint {
display: none;
}
.tt-dropdown-menu {
width: 422px;
margin-top: 12px;
padding: 2px 0;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.tt-suggestion {
padding: 3px 20px;
}
.tt-suggestion.tt-cursor { /* UPDATE: newer...
JavaScript
//$('span').attr('tabindex', 0);
$('.expander').click(function () {
$(this).closest('.expandable').children('.compact, .expanded').toggle();
});
$('.toggler').click(function () {
$('.toggly').toggle();
});
$('.favorite').click(function () {
$(this).toggleClass('fa-star fa-star-o');
$('.holder').toggleClass('parens');
});
$('.holder').on('click', '.box', function (event) {
$('.focus').removeClass('focus');
$(event.target).addClass('focus');
});
$.fn.walk = function(visit, selector, post_order) {
if(this.length === 0) { return; }
this.each(function(i) {
if (!post_order) {
if (visit.call(this, i, this) === false) { return false; }
}
$(this).children(selector).walk(visit, selector, post_order);
if (post_order) { return visit.call(this, i, this); }
});
}
var fakeinput = $('<input id="fakeinput">');
function startEdit(node) {
var current = $(node).text();
$(node).empty().addClass('editing').append(fakeinput);
}
function stopEdit() {
var val = fakeinput.val();
$('.editing').removeClass('.editing').remove(fakeinput).text(val);
}
$('.holder').on('keyup', function (event) {
if (event.keyCode === 39) {
var current = $('.focus').removeClass('focus')[0];
var focusNext = false;
$('.holder').walk(function (i) {
if (focusNext) {
$(this).addClass('focus');
focusNext = false;
return false;
}
if (this === current) {
focusNext = true;
}
}, '.box', true);
stopEdit();
}
if (event.keyCode === 37) {
var current = $('.focus').removeClass('focus')[0];
var previous = current;
$('.holder').walk(function (i) {
if (this === current) {
$(previous).addClass('focus');
return false;
}
previous = this;
}, '.box', true);
...