JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-tokenfield/0.12.0/css/bootstrap-tokenfield.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Caret.js/0.3.1/jquery.caret.min.js"></script>
<body>
<div class="outerbox">
<input id="textbox" class="typeahead" type="text" placeholder="Enter a color"/>
</div>
<div class="outerbox">
<textarea id="textarea" class="typeahead" placeholder="Type @ to trigger color lookup"></textarea>
</div>
</body>
CSS
body
{
min-width: 400px;
padding: 2em;
}
.typeahead,
.tt-query,
.tt-hint {
width: 396px;
height: 30px;
padding: 8px 12px;
font-size: 24px;
line-height: 30px;
border: 2px solid #ccc;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
outline: none;
height: 2em;
}
.typeahead {
background-color: #fff;
}
.typeahead:focus {
border: 2px solid #0097cf;
}
.tt-query {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.tt-hint {
color: #999
}
.tt-menu {
/*width: 422px;*/
width: auto;
margin: 12px 0;
padding: 8px 0;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
}
.tt-suggestion {
padding: 3px 20px;
font-size: 18px;
line-height: 24px;
}
.tt-suggestion:hover {
cursor: pointer;
color: #fff;
background-color: #0097cf;
}
.tt-suggestion.tt-cursor {
color: #fff;
background-color: #0097cf;
}
.tt-suggestion p {
margin: 0;
}
.gist {
font-size: 14px;
}
.twitter-typeahead, .tt-hint, .tt-input
{
width: 100%;
}
.tt-menu
{
width: auto;
}
.outerbox
{
border: 2px dashed #ccc;
padding: 1em;
margin: 1em;
}
#textarea
{
height: 300px;
}
JavaScript
function MultiTypeahead(id, data, trigger, vertAdjustMenu)
{
trigger = (undefined !== trigger) ? trigger : '';
var validChars = /^[a-zA-Z]+$/;
function extractor(query)
{
var result = (new RegExp('([^,; \r\n]+)$')).exec(query);
if(result && result[1])
return result[1].trim();
return '';
}
var lastUpper = false;
function strMatcher(id, strs)
{
return function findMatches(q, sync, async)
{
var pos = $(id).caret('pos');
q = (0 < pos) ? extractor(q.substring(0, pos)) : '';
if (q.length <= trigger.length)
return;
if (trigger.length)
{
if(trigger != q.substr(0, trigger.length))
return;
q = q.substr(trigger.length);
}
if (!q.match(validChars))
return;
var firstChar = q.substr(0, 1);
lastUpper = (firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase());
var cpos = $(id).caret('position');
$(id).parent().find('.tt-menu').css('left', cpos.left + 'px');
if (vertAdjustMenu)
$(id).parent().find('.tt-menu').css('top', (cpos.top + cpos.height) + 'px');
var matches = [];
var matches = [], substrRegex = new RegExp(q, 'i');
$.each(strs, function(i, str)
{
if (str.length > q.length && substrRegex.test(str))
matches.push(str);
});
if (!matches.length)
return;
sync(matches);
};
};
var lastVal = '';
var lastPos = 0;
function beforeReplace(event, data)
{
lastVal = $(id).val();
lastPos = $(id).caret('pos');
return true;
}
function onReplace(event, data)
{
if (!data || !data.length)
return;
if (!lastVal.length)
return;
var root = lastVal.substr(0, lastPos);
var post = lastVal.substr(lastPos);
var typed = extractor(root);
if (!lastUpper && typed.length >= root.length && 0 >= post.length)
return;
var str = root.substr(0, root.length - typed.length);
str += lastUpper ? (data.substr(0,...