<div class="app">
<div class="input-container">
<input type="text" name="text" id="text" placeholder="Type Here" autocomplete="off">
<span class="suggestion-container"></span>
<div class="icons-container">
<div class="icon tab-key hidden">
<svg>
<use xlink:href="#tab-key"></use>
</svg>
</div>
<div class="icon enter-key hidden">
<svg>
<use xlink:href="#enter-key"></use>
</svg>
</div>
</div>
</div>
</div>
<svg class="icons">
<symbol id="tab-key" viewBox="0 0 448 448">
<polygon points="225.813,126.187 302.293,202.667 0,202.667 0,245.333 302.293,245.333 225.813,321.813 256,352 384,224 256,96
" />
<rect x="405.333" y="96" width="42.667" height="256" />
</symbol>
<symbol id="enter-key" viewBox="0 0 280.823 280.823">
<path d="m250.734 40.137-90.265-.02v20.059h90.265c5.534 0 10.029 4.515 10.029 10.049v80.216c0 5.534-4.496
10.029-10.029 10.029h-212.34l45.877-45.877-14.182-14.182-70.089 70.088 70.206 70.206
14.182-14.182-45.994-45.994h212.341c16.592 0 30.088-13.497
30.088-30.088v-80.216c0-16.592-13.497-30.088-30.089-30.088z" />
</symbol>
</svg>
<div class="support">
<a href="https://twitter.com/DevLoop01" target="_blank"><i class="fab fa-twitter-square"></i></a>
<a href="https://dribbble.com/devloop01" target="_blank"><i class="fab fa-dribbble"></i></a>
</div>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
$selection-color: #222;
$selection-background: rgba(0, 0, 0, 0.12);
::-moz-selection {
color: $selection-color;
background: $selection-background;
}
::selection {
color: $selection-color;
background: $selection-background;
}
$background-color: #52de97;
body {
width: 100%;
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
background: $background-color;
}
input {
outline: none;
border: 0;
}
.icons {
display: none;
}
$size: 400px;
$font-size: 18px;
$font-family: "Montserrat";
$padding: 0px 45px 0px 18px;
$text-field-width: 360px;
$text-field-height: 65px;
$border-radius: 10px;
.app {
width: $size;
height: $size;
display: grid;
place-items: center;
.input-container {
position: relative;
width: $text-field-width;
height: $text-field-height;
border-radius: $border-radius;
background: #fff;
box-shadow: 0 6.7px 5.3px rgba(0, 0, 0, 0.044), 0 22.3px 17.9px rgba(0, 0, 0, 0.066),
0 100px 80px rgba(0, 0, 0, 0.11);
backface-visibility: hidden;
transform: translateZ(0) scale(1, 1);
&.animate {
animation: stretch-animation 800ms ease;
}
[type="text"] {
position: absolute;
width: $text-field-width;
height: $text-field-height;
color: $background-color;
font-family: $font-family;
font-size: $font-size;
letter-spacing: 2px;
padding: $padding;
caret-color: #000;
background: transparent;
z-index: 5;
&::placeholder {
color: rgba(34, 34, 34, 0.55);
}
}
.suggestion-container {
width: $text-field-width;
height: $text-field-height;
position: absolute;
left: 0;
top: 0;
display: flex;
align-items: center;
color: #414856;
opacity: 0.65;
font-family: $font-family;
font-size: $font-size;
letter-spacing: 2px;
padding: $padding;
pointer-events: none;
z-index: 4;
}
.icon {
position: absolute;
width: 20px;
height: 20px;
right: 20px;
top: 50%;
transform: translateX(0%) translateY(-50%);
opacity: 1;
transition: all 180ms ease-in;
cursor: pointer;
pointer-events: all;
z-index: 10;
&.hidden {
transform: translateX(80%) translateY(-50%);
opacity: 0;
pointer-events: none;
}
svg {
width: 100%;
height: 100%;
fill: #222;
pointer-events: none;
}
}
}
}
@keyframes stretch-animation {
0% {
transform: scale(1, 1);
}
10% {
transform: scale(1.02, 0.98);
}
30% {
transform: scale(0.98, 1.02);
}
50% {
transform: scale(1.02, 0.98);
}
100% {
transform: scale(1, 1);
}
}
.support{
position: absolute;
right: 10px;
bottom: 10px;
padding: 10px;
display: flex;
a{
margin: 0 10px;
color: #e1f2fb;
font-size: 1.8rem;
backface-visibility: hidden;
transition: all 350ms cubic-bezier(0.38,-0.12, 0.24, 1.91);
&:hover{
transform: scale(1.1);
}
}
}
View Compiled
console.clear();
const inputContainerEl = document.querySelector(".input-container");
const textInputEl = document.querySelector("input#text");
const suggestionEl = document.querySelector(".suggestion-container");
const svgTabIcon = document.querySelector(".icon.tab-key");
const svgEnterIcon = document.querySelector(".icon.enter-key");
const ENTER_KEYCODE = 13;
const TAB_KEYCODE = 9;
const BACKSPACE_KEYCODE = 8;
const UP_ARROW_KEYCODE = 38;
const DOWN_ARROW_KEYCODE = 40;
const SPACE_KEYCODE = 32;
let wordsArray = [
"hello",
"world",
"what",
"are",
"you",
"doing",
"welloworld",
"minister",
"pot",
"science",
"rubbish",
"adjust",
"presentation",
"prediction",
"fate",
"scholar",
"pull",
"string",
"display",
"estate",
"reproduction",
"scandal",
"fun",
"attachment",
"sailor",
"queen",
"sleeve",
"electron",
"south",
"elbow",
"violation",
"response",
"commission",
"conservation",
"embryo",
"explode",
"car",
"incentive",
"snap",
"mathematics",
"moral",
"disco",
"cluster",
];
let suggestedWord = "";
let suggestedWordsArray = [];
let currentWordIndex = 0;
let insertText = false;
textInputEl.addEventListener("input", e => {
if (e.data != " ") {
insertText = true;
}
if (insertText == false) {
textInputEl.value = "";
}
let inputValue = e.target.value;
suggestedWordsArray = filterArray(wordsArray, inputValue);
suggestedWord = suggestedWordsArray[0];
if (suggestedWord != undefined) {
suggestionEl.innerHTML = suggestedWord;
}
if (inputValue.length == 0 || suggestedWordsArray.length == 0) {
suggestionEl.innerHTML = "";
}
if (suggestedWordsArray.length != 0) {
svgTabIcon.classList.remove("hidden");
svgEnterIcon.classList.add("hidden");
} else {
svgTabIcon.classList.add("hidden");
svgEnterIcon.classList.remove("hidden");
}
if (inputValue.length == 0 || inputValue == suggestedWord) {
svgTabIcon.classList.add("hidden");
svgEnterIcon.classList.add("hidden");
}
if (textInputEl.value.length == 0) {
insertText = false;
}
});
textInputEl.addEventListener("keydown", e => {
if (e.keyCode == ENTER_KEYCODE) {
if (textInputEl.value.length == 0) return;
appendTextToList();
}
if (textInputEl.value.length != 0 && suggestedWordsArray.length != 0) {
if (e.keyCode == UP_ARROW_KEYCODE) {
if (currentWordIndex == 0) return;
currentWordIndex--;
suggestionEl.innerHTML = suggestedWordsArray[currentWordIndex];
}
if (e.keyCode == DOWN_ARROW_KEYCODE) {
if (currentWordIndex == suggestedWordsArray.length - 1) return;
currentWordIndex++;
suggestionEl.innerHTML = suggestedWordsArray[currentWordIndex];
}
if(e.keyCode == UP_ARROW_KEYCODE || e.keyCode == DOWN_ARROW_KEYCODE){
if (textInputEl.value == suggestedWordsArray[currentWordIndex]) {
svgTabIcon.classList.add("hidden");
}else{
svgTabIcon.classList.remove("hidden");
}
}
if (e.keyCode == BACKSPACE_KEYCODE) {
currentWordIndex = 0;
}
}
if (suggestedWord != undefined && suggestedWord != "") {
if (e.keyCode == TAB_KEYCODE) {
e.preventDefault();
enterSuggestionToInputEl();
}
}
});
svgTabIcon.addEventListener('click', () => {
enterSuggestionToInputEl();
})
svgEnterIcon.addEventListener('click', () => {
appendTextToList();
})
removeClassAfterAnimationCompletes(inputContainerEl, "animate");
function appendTextToList(){
let inputValue = textInputEl.value;
let words = inputValue.split(" ");
for (let i in words) {
if (words[i].length != 0) {
wordsArray.push(words[i]);
textInputEl.value = "";
suggestionEl.innerHTML = "";
}
}
wordsArray = removeDuplicatesFromArray(wordsArray);
currentWordIndex = 0;
suggestedWordsArray = [];
inputContainerEl.classList.add("animate");
svgTabIcon.classList.add("hidden");
svgEnterIcon.classList.add("hidden");
removeClassAfterAnimationCompletes(inputContainerEl, "animate");
}
function enterSuggestionToInputEl(){
textInputEl.value = suggestedWordsArray[currentWordIndex];
suggestionEl.innerHTML = "";
svgTabIcon.classList.add("hidden");
svgEnterIcon.classList.add("hidden");
}
function removeClassAfterAnimationCompletes(el, className) {
let elStyles = window.getComputedStyle(inputContainerEl);
setTimeout(function() {
el.classList.remove(className);
}, +elStyles.animationDuration.replace("s", "") * 1000);
}
function filterArray(array, item, reverse = false) {
if (reverse) {
return array
.filter(word => returnSubstring(word, item))
.sort((a, b) => a.length - b.length);
} else {
return array
.filter(word => returnSubstring(word, item))
.sort((a, b) => b.length - a.length);
}
}
function removeDuplicatesFromArray(array) {
return [...new Set(array.map(i => i))];
}
function returnSubstring(string, subString) {
let temp = string.split("", subString.length).join("");
if (subString == temp) return subString;
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.