Tiget - Tags are better than folders
by joplomacedo
HTML
<div class="layer is-inactive">
<div class="box">
<p class="logo">Tiget</p>
<div class="box_content">
<div class="input_wrapper">
<input class="input input--suggest">
<input class="input input--real">
</div>
<div class="tags_box">
<span class="tag is-added">web-development</span>
<span class="tag is-added">web-developments</span>
<span class="tag">frontend</span>
<span class="tag">react</span>
<span class="tag">learn</span>
<span class="tag">vue</span>
<span class="tag">courses</span>
<span class="tag">backend</span>
<span class="tag">design</span>
<span class="tag">misc</span>
<span class="tag">...</span>
</div>
<button>Done</button>
</div>
<div class="shortcuts">
<p class="shortcuts__title">Shortcuts</p>
<table class="shortcuts__table">
<tr>
<td class="">
<span class="shortcuts__key">CMD</span> + <span class="shortcuts__key">T</span>
</td>
<td>
Open/Close Tiget
</td>
</tr>
<tr>
<td class="">
<span class="shortcuts__key">Esc</span>
</td>
<td>
Close Tiget
</td>
</tr>
<table>
</div>
</div>
</div>
CSS
*,
*:after,
*:before {
box-sizing: border-box;
font: inherit;
padding: 0;
margin: 0;
border: 0;
border-radius: 0;
background-color: transparent;
outline: none;
color: inherit;
text-decoration: none;
}
ul,
ol,
li {
list-style: none;
}
input,
select,
textarea {
max-width: 100%;
}
.layer {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
font-family: system-ui, sans-serif;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 2em;
background-color: rgba(0,0,0,.1);
}
.layer.is-inactive {
display: none;
}
.box {
max-width: 30em;
}
.logo {
font-size: 13px;
font-weight: 600;
margin-bottom: 3px;
}
.box_content {
border-radius: 3px;
}
.input_wrapper {
position: relative;
margin-bottom: 1em;
}
.input {
width: 100%;
border: 1px solid #ccc;
padding: 1em;
border-radius: 2px;
}
.input--suggest {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
color: #aaa;
}
.input--real {
position: relative;
background-color: transparent;
}
.tags_box {
line-height: 2.1;
}
.tag {
display: inline-block;
line-height: 1.4;
background: #eee;
padding: .1em .3em;
border-radius: 2px;
cursor: pointer;
margin-right: .1em;
}
.shortcuts {
position: fixed;
bottom: 3em;
right: 3em;
font-size: .8em;
}
.shortcuts__title {
font-weight: 600;
margin-bottom: .15em;
}
.shortcuts__key {
font-size: .84em;
padding: .15em .4em;
display: inline-block;
background: #cecece;
border-radius: 2px;
font-weight: 600;
color: black;
}
JavaScript
//TODO
// merge tags. and suggest merging tags when theyre very similar
//base
const w = window;
const d = document;
function isNodeList( $el ) {
return NodeList.prototype.isPrototypeOf($el);
}
function q( arg0, arg1 ) {
return (arg1 || d).querySelectorAll(arg0);
}
function qs( arg0, arg1 ) {
return (arg1 || d).querySelector(arg0);
}
function ael( $el, evt, cb, uc ) {
(isNodeList($el) ? $el : [$el]).forEach(node => {
node.addEventListener(evt, cb, uc);
});
}
function activate($el) {
(isNodeList($el) ? $el : [$el]).forEach(node => {
node.classList.remove('is-inactive');
node.classList.add('is-active');
});
}
function deactivate($el) {
(isNodeList($el) ? $el : [$el]).forEach(node => {
node.classList.remove('is-active');
node.classList.add('is-inactive');
});
}
function togglevate( $el ) {
(isNodeList($el) ? $el : [$el]).forEach(node => {
node.classList.toggle('is-active');
node.classList.toggle('is-inactive');
});
}
//code
const $layer = qs('.layer');
const key_space = 'Space';
const key_t = 'KeyT';
const key_tab = 'Tab';
const key_enter = 'Enter';
const key_escape = 'Escape';
const keydowned_keys = {};
ael(w, 'keydown', ( e ) => {
keydowned_keys[e.code] = 1;
if ( key_space in keydowned_keys &&
key_t in keydowned_keys
) {
togglevate($layer);
}
if ( e.code === key_escape ) {
deactivate($layer);
}
});
ael(w, 'keyup', ( e ) => {
delete keydowned_keys[e.code];
});
const tags = [
'web-development',
'web-developments',
'frontend',
'react',
'learn',
'vue',
'courses',
'backend',
'design',
'misc'
].sort();
let suggested_tag = '';
const selected_tags = [];
const $input = qs('.input--real');
const $suggest = qs('.input--suggest');
function clearSuggestion () {
suggested_tag = false;
$suggest.value = '';
}
ael($input, 'keydown', function ( e ) {
e.stopPropagation();
if ( e.code == key_tab ) {
e.preventDefault();
if ( suggested_tag ) {
$input.value =...