JSFiddle - React, Tailwind, and code Playground
by neonDog
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<div class="col-6">
<h4>Autocomplete</h4>
<div class="neon-autocomplete"></div>
<h4>Select</h4>
<div class="neon-autocomplete"></div>
<h4>Tags</h4>
<div class="neon-autocomplete"></div>
</div>
SCSS
.neon-autocomplete {
position: relative;
}
.neon-dropdown-item.hidden {
display:none;
}
.neon-dropdown-menu {
&.hidden {
display:none;
}
}
.neon-autocomplete-main + .neon-dropdown-menu {
display: block;
position: absolute;
opacity: 0;
transform: translateY(-15px);
height: 1px;
min-width: 100%;
transition: transform .2s ease, opacity .1s ease-out;
overflow-y: auto;
max-height: 300px;
}
.neon-autocomplete-main:focus + .neon-dropdown-menu,
.neon-dropdown-menu:focus-within,
.neon-dropdown-menu.show {
opacity: 1;
transform: translateY(0px);
height: auto;
z-index: 1;
}
JavaScript
const textHighlight = function(string, search, addClass='text-highlight') {
if (!search) return string;
if (typeof string !== 'string') return string;
let returnString = string;
const regex = new RegExp("(" + search + ")(?![^<]*>|[^<>]*</)", "i"); // explanation: http://stackoverflow.com/a/18622606/1147859
const match = string.match(regex)
if (match) {
// Get to highlighting
var matchStartPosition = string.match(regex).index;
var matchEndPosition = matchStartPosition + string.match(regex)[0].toString().length;
var originalTextFoundByRegex = string.substring(matchStartPosition, matchEndPosition);
returnString = returnString.replace(regex, `<mark class="${ addClass }">${originalTextFoundByRegex}</mark>`);
}
return returnString;
};
class NeonDropdown {
constructor(element, settings = {}) {
const defaults = {
//addEventListeners:false
class:'dropdown-menu',
itemClass:'dropdown-item',
activeClass:'active',
loop: true,
onSelect: function(element){}
};
this.options = Object.assign({}, defaults, settings);
this.element = element;
this.element.classList.add('neon-dropdown-menu');
this.element.setAttribute('tabindex', '0');
if (this.options.class) {
this.element.classList.add(this.options.class);
}
this.activeOption = null;
this._click = this._click.bind(this);
this._keydown = this._keydown.bind(this);
this._mouseover = this._mouseover.bind(this);
this.eventListenersActive = false;
this.eventListeners(true);
}
showHide(show = true) {
this.element.classList.toggle('hidden', !show);
}
scroll(down = true) {
const selector = 'neon-dropdown-item';
let newH = this.activeOption ? getNextPrevSibling(this.activeOption, '.' + selector, down) : this.element.getElementsByClassName(selector)[0];
if (!newH && this.options.loop) { // Logic for looping back to top or going to the bottom if enabled
const...