JSFiddle - React, Tailwind, and code Playground

by soulwire

HTML

<div class="info">
    <h2>Examples:</h2>
    <ul>
        <li>cats</li>
        <li>@soulwire</li>
        <li>@soulwire cats</li>
        <li>http://www.youtube.com/watch?v=9xfbu3hGN18</li>
        <li>http://vimeo.com/20396587</li>
        <li>youtube cats</li>
    </ul>
</div>
<form id="search">
    <input id="omnibar" type="text" placeholder="URL, Instagram user, YouTube URL, Search term...">
    <ol class="options">
    </ol>
</form>

CSS

html, body {
    font-family: “Helvetica Neue”, Arial, Helvetica, sans-serif;
    background: #f2f2f2;
    padding: 0;
    margin: 0;
}
#search {
    margin: 40px auto;
    padding: 0;
    width: 80%;
}
.info {
    color: #999;
    margin: 20px;
    font-size: 14px;
}
.info h2 {
    margin: 5px 0;
    font-style: italic;
}
.info li {
    margin: 0 10px;
    line-height: 18px;
}
.info li:before {
    margin-right: 5px;
    content: '-';
    color: #ccc;
}
#omnibar {
    margin: 0;
    width: 100%;
    background: #fff;
    display: block;
    border-radius: 8px;
    font-size: 28px;
    line-height: 40px;
    padding: 20px;
    border: 2px solid #ccc;
    margin-left: -20px;
    color: #222;
}
#omnibar:focus {
    outline: none;
    box-shadow: 0px 0px 10px rgba(0,255,255,0.5);
}
.options {
    list-style: none;
    position: relative;
    left: -20px;
    top: -6px;
}
.options li {
    border: 2px solid #ccc;
    margin-top: -2px;
    font-size: 18px;
    line-height: 20px;
    padding: 20px;
    background: #fff;
    width: 100%;
    color: #999;
}

.options li em {
    color: #222;
}

.options li span {
    border-bottom: 1px solid #ccc;
}

JavaScript

var omnibar = $( '#omnibar' );
var options = $( 'ol.options' );

omnibar.bind( 'keyup', update );

// http://www.youtube.com/watch?v=9xfbu3hGN18&feature=fvst
// http://vimeo.com/20396587

function update() {
    
    var val = omnibar.val();
    
    options.empty();
    
    var suggestions = [];
    
    if ( val.length > 1 && val.match( /^@/ ) && !val.match( /[\.\s]/ ) ) {
        suggestions.push( 'Get <span>Instagram</span> photos from <em>"{q}"</em>' );
        suggestions.push( 'Get <span>Twitpics</span> from <em>"{q}"</em>' );
    }
    
    if ( val.length > 1 && val.match( /^@/ ) && val.match( /[\.\s]/ ) ) {
        suggestions.push( 'Search <em>' + val.match( /^@(\w+)/ )[0] + '\'s</em> <span>Instagram</span> photos for <em>' + val.match( /\s(.+)/ )[0].replace( /^\s+/, '' ) + '</em>"' );
    }
    
    if ( val.match( /^http\:\/\//i ) || val.match( /\.(\w){2,}/ ) ) {
        if ( val.match( /youtube\.com/gi ) ) {
            suggestions.push( 'Grab the <span>YouTube</span> video <em>"' + ( val.match( /v\=(\w+)/ )[1] ) + '"</em>' );            
        } else if ( val.match( /vimeo\.com/gi ) ) {
            suggestions.push( 'Grab the <span>Vimeo</span> video <em>"' + ( val.match( /\d{8}/ )[0] ) + '"</em>' );  
        } else {
            suggestions.push( 'Grab media from <em>"{q}"</em>' );
        }
    }
    
    if ( val.length > 0 && !val.match( /^@/ ) && !val.match( /^(http)/ ) ) {
        
        if ( val.match( /flickr/i ) && val.match( /\s\w/ ) ) {
            suggestions.push( 'Search <span>Flickr</span> for <em>"' + val.replace( /flickr/i, '' ) + '"</em>' );
        } else if ( !val.match( /youtube|vimeo/ ) ) {
            suggestions.push( 'Search <span>images</span> for <em>"{q}"</em>' );
        }
        
        if ( val.match( /vimeo/i ) && val.match( /\s\w/ ) ) {
            suggestions.push( 'Search <span>Vimeo</span> for <em>"' + val.replace( /vimeo/i, '' ) + '"</em>' );
        } else if ( val.match( /youtube/i ) && val.match(...