JSFiddle - React, Tailwind, and code Playground
HTML
<div id="debug">current filter: <input type="text" id="debugoutput" /> (debug)</div>
<input type="radio" name="method" value="filter" checked="checked" id="method_filter" />
<label for="method_filter">Filter</label>
<input type="radio" name="method" value="select" id="method_select" />
<label for="method_select">Select</label>
<div class="selectable">
<span>Choose Language</span>
<ul>
<li><a href="#af">Afrikaans</a></li>
<li><a href="#sq">Albanian</a></li>
<li><a href="#ca">Catalan</a></li>
<li><a href="#cn">Chinese</a></li>
<li><a href="#cs">Czech</a></li>
<li><a href="#da">Danish</a></li>
<li><a href="#nl">Dutch</a></li>
<li><a href="#en">English</a></li>
<li><a href="#fr">French</a></li>
<li><a href="#de">German</a></li>
<li><a href="#hi">Hindi</a></li>
<li><a href="#iw">Hebrew</a></li>
<li><a href="#it">Italian</a></li>
<li><a href="#pt">Portuguese</a></li>
<li><a href="#es">Spanish</a></li>
<li><a href="#vi">Vietnamese</a></li>
</ul>
<br clear="left" />
</div>
CSS
#debug {
margin-bottom: 20px;
}
#debug input {
border: 1px dotted #888;
border-top: 0;
background: #eee;
}
label {
cursor: pointer;
}
.selectable {
margin-top: 20px;
border: 1px solid #000000;
border-radius: 8px;
background: #558BE3;
width: 182px;
padding: 2px 0px;
text-align: center;
cursor: pointer;
outline: none;
}
.selectable ul {
display: none;
width: 160px;
margin: 0 10px;
}
.selectable ul li {
float: left;
width: 80px;
list-style: none;
}
.selectable ul li a {
display: block;
color: #fff;
float: left;
width: 74px;
text-decoration: none;
padding: 1px;
outline: none;
}
.selectable ul li a:hover {
background: #fff;
color: #558BE3;
}
.selectable ul li.highlight a{
padding: 0;
border: 1px solid #fff;
}
JavaScript
// how to use this demo:
// click/select the "choose" div and type
jQuery.extend(
jQuery.expr[':'], {
regex: function(a, i, m, r) {
var r = new RegExp(m[3], 'i');
return r.test(jQuery(a).text());
}
});
jQuery(".selectable").attr("tabindex", 0).bind("keydown", function(e) {
var filter = $(this).data("filter");
switch (e.which) {
case 27:
// esc
$(this).data("filter", "").trigger("customFilter");
break;
case 8:
// backspace
if (filter.length > 0) {
filter = filter.substr(0, filter.length - 1);
$(this).data("filter", filter).trigger("customFilter");
}
return false;
break;
case 13:
// enter
var items = $("li:visible", this);
if ($("#method_filter").is(":checked")) {
// filter
} else {
// select
items = items.filter(".highlight");
}
if (items.size() == 1) {
items.find("a").click();
}
break;
case 37:
// left
case 38:
// up
if ($("#method_select").is(":checked")) {
var prev = $("li.highlight", this);
if (prev.is($("li:first", this)))
prev = $("li:last", this);
else
prev = prev.prev();
if (prev.size() == 0)
prev = $("li:first", this);
prev.addClass("highlight");
$("li", this).not(prev).removeClass("highlight");
$(this).data("filter", "");
$("#debugoutput").val("");
}
break;
case 39:
// right
case 40:
// down
if ($("#method_select").is(":checked")) {
var next = $("li.highlight:first ~ li", this).filter(":first");
if (next.size() == 0)
next = $("li:first", this);
next.addClass("highlight");
$("li",...