JSFiddle - React, Tailwind, and code Playground

by Daniel Lizik

HTML

<super-tokens id="tags"></super-tokens>

CSS

super-tokens {
	width: 400px;
}

super-tokens textarea {
	width: inherit;	
}

super-tokens div {
	border: 1px solid black;
	width: inherit;		
}

super-tokens ul {
	list-style-type: none;
	margin: 0;
	padding: 0;	
}

JavaScript

var superTokens = (function(init, model, view, controller, testCollector, setDefaults) {
	'use strict';

	//cache instances to prevent double instantiation on same element
	var collector = [];
	
	return function(config) {
	  var defaults = setDefaults(config); 
		testCollector(defaults.querySelector, collector);
		init(defaults);
	};
})(

/**
 * @init - appends dom elements inside custom selector
 * @param conf {object} - hash of options
 */

function init(conf) {
	var component = document.querySelector(conf.querySelector);
	var input = document.createElement(conf.elem);
	var dropdown = document.createElement('div');
	var ul = document.createElement('ul');
	var i = 1;
	var li;
	input.placeholder = conf.placeholder;
	for (i; i < conf.maxList + 1; i++) {
		li = document.createElement('li');
		li.setAttribute('st-index', i);
		li.style.visibility = 'hidden';
		ul.appendChild(li);
	}
	dropdown.style.visibility = 'hidden';
	dropdown.appendChild(ul);
	component.appendChild(input);
	component.appendChild(dropdown);
},

function model(conf) {

},

function view(conf) {

},

function controller() {

},

function testCollector(qs, collector) {
	if (collector.indexOf(qs) > -1)
		throw new Error('Cannot instantiate multiple SuperTokens on the same element.')
	else
		collector.push(qs);
},

function setDefaults(conf) {
	if (conf.placeholder && typeof conf.placeholder !== 'string')
		throw new Error('Placeholder option must be a string.');
	if (conf.elem && typeof conf.elem !== 'string')
		throw new Error('Elem option must be a string.');
	if (conf.maxList && typeof conf.maxList !== 'number')
		throw new Error('maxList option must be a number.');
	if (conf.display && typeof conf.display !== 'string')
		throw new Error('display must be a string');
	if (conf.id && typeof conf.id !== 'string')
		throw new Error('element id must be a string')
  return {	
	  placeholder: conf.placeholder || 'search',
		elem: conf.elem || 'input',
		maxList: conf.maxList || 10,
		querySelector:...