Filtering Tab control with animated indicator

by HugeHugh

HTML

<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<ul class="list-unstyled list-inline nav-tab-filter-anim">
  <li data-filter="None" class="active">All</li>
  <li data-filter="Content">Content</li>
  <li data-filter="NewsArticle">News</li>
  <li data-filter="Slideshow">Slideshow</li>
  <li data-filter="Extension">Extension</li>
</ul>

CSS

ul.nav-tab-filter-anim {
  border-bottom: 1px solid #E0E0E0;
  margin: 0 0 1px 0;
}
ul.nav-tab-filter-anim > li {
  padding: 10px 16px;
  cursor: pointer;
  color: #8B8E93;
}
ul.nav-tab-filter-anim > li:hover {
  background: #fbfbfb;
}
ul.nav-tab-filter-anim > li.active {
  padding: 10px 15px;
  font-weight: bold;
  color: #383D53;
}
.nav-tab-filter-anim-wrapper {
  position: relative;
  overflow: hidden;
}
.nav-tab-filter-anim-line {
  position: absolute;
  bottom: 0;
  height: 3px;
  background: #383D53;
  left: -40px;
  width: 40px;
  transition: left 200ms ease, width 200ms ease;
}

JavaScript

;(function ( $, window, document, undefined ) {
	"use strict";
		// Create the defaults once
		var pluginName = "NavTabFilterAnim",
				defaults = {
				propertyName: "value"
		};

		// The actual plugin constructor
		function Plugin ( element, options ) {
				this.ul = $(element);
				// jQuery has an extend method which merges the contents of two or
				// more objects, storing the result in the first object. The first object
				// is generally empty as we don't want to alter the default options for
				// future instances of the plugin
				this.settings = $.extend( {}, defaults, options );
				this._defaults = defaults;
				this._name = pluginName;
				this.init();
		}

		// Avoid Plugin.prototype conflicts
		$.extend(Plugin.prototype, {
				init: function () {
        	var self = this;
          this.wrapper = this.ul.wrap('<div class="nav-tab-filter-anim-wrapper"/>').parent();
          this.slider = $('<div class="nav-tab-filter-anim-line"/>');
          this.wrapper.append(this.slider);
          
          $('>li', this.ul).on('click.navtab', function(e) {
            e.preventDefault();
            var li = $(this);
            li.siblings().removeClass('active');
            li.addClass('active').trigger('anim.navtab');
          }).on('anim.navtab', function() {
            var li = $(this);
            self.slider.css({
              width: li.outerWidth() + 'px',
              left: li.position().left + 'px'
            });
            li.parent().trigger('filter-change', [li.data('filter')]);
          }).filter('.active').trigger('anim.navtab');
				},
        destroy: function() {
        	$('>li', this.ul).off('click.navtab anim.navtab');
          this.slider.remove();
          this.ul.unwrap();
        }
		});

		// A really lightweight plugin wrapper around the constructor,
		// preventing against multiple instantiations
		$.fn[ pluginName ] = function ( options ) {
// get the arguments 
    var args = $.makeArray(arguments),
        after =...