JSFiddle - React, Tailwind, and code Playground
HTML
<p>※最低2文字入力する必要があります</p>
<p><input autofocus class="awesomplete" data-list="りんご, ごりら, らんでぶー, ぶるじょわ, わいるどだろ, ろーるすろいす, すとーりー" /></p>
<p>設定キーワードは<br>
「りんご, ごりら, らんでぶー, ぶるじょわ, わいるどだろ, <br>ろーるすろいす, すとーりー」</p>
CSS
[hidden] {
display: none;
}
div.awesomplete {
display: inline-block;
position: relative;
}
div.awesomplete > input {
display: block;
}
div.awesomplete > ul {
position: absolute;
left: 0;
z-index: 1;
min-width: 100%;
box-sizing: border-box;
list-style: none;
padding: 0;
border-radius: .3em;
margin: .2em 0 0;
background: hsla(0,0%,100%,.9);
background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));
border: 1px solid rgba(0,0,0,.3);
box-shadow: .05em .2em .6em rgba(0,0,0,.2);
text-shadow: none;
}
div.awesomplete > ul[hidden],
div.awesomplete > ul:empty {
display: none;
}
@supports (transform: scale(0)) {
div.awesomplete > ul {
transition: .3s cubic-bezier(.4,.2,.5,1.4);
transform-origin: 1.43em -.43em;
}
div.awesomplete > ul[hidden],
div.awesomplete > ul:empty {
opacity: 0;
transform: scale(0);
display: block;
transition-timing-function: ease;
}
}
/* Pointer */
div.awesomplete > ul:before {
content: "";
position: absolute;
top: -.43em;
left: 1em;
width: 0;
height: 0;
padding: .4em;
background: white;
border: inherit;
border-right: 0;
border-bottom: 0;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
div.awesomplete > ul > li {
position: relative;
padding: .2em .5em;
cursor: pointer;
}
div.awesomplete > ul > li:hover {
background: hsl(200, 40%, 80%);
color: black;
}
div.awesomplete > ul > li[aria-selected="true"] {
background: hsl(205, 40%, 40%);
color: white;
}
div.awesomplete mark {
background: hsl(65, 100%, 50%);
}
div.awesomplete li:hover mark {
background: hsl(68, 101%, 41%);
}
div.awesomplete li[aria-selected="true"] mark {
background: hsl(86, 102%, 21%);
color: inherit;
}
JavaScript
/**
* Simple, lightweight, usable local autocomplete library for modern browsers
* Because there weren’t enough autocomplete scripts in the world? Because I’m completely insane and have NIH syndrome? Probably both. :P
* @author Lea Verou http://leaverou.github.io/awesomplete
* MIT license
*/
(function() {
var _ = self.Awesomplete = function(input, o) {
var me = this;
// Setup
this.input = input;
input.setAttribute("aria-autocomplete", "list");
o = o || {};
configure.call(this, {
minChars: 2,
maxItems: 10,
autoFirst: false,
filter: _.FILTER_CONTAINS,
sort: _.SORT_BYLENGTH,
item: function(text, input) {
return $.create("li", {
innerHTML: text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>"),
"aria-selected": "false"
});
},
replace: function(text) {
this.input.value = text;
}
}, o);
this.index = -1;
// Create necessary elements
this.container = $.create("div", {
className: "awesomplete",
around: input
});
this.ul = $.create("ul", {
hidden: "",
inside: this.container
});
// Bind events
$.bind(this.input, {
"input": this.evaluate.bind(this),
"blur": this.close.bind(this),
"keydown": function(evt) {
var c = evt.keyCode;
if (c === 13 && me.selected) { // Enter
evt.preventDefault();
me.select();
} else if (c === 27) { // Esc
me.close();
} else if (c === 38 || c === 40) { // Down/Up arrow
evt.preventDefault();
me[c === 38 ? "previous" : "next"]();
}
...