JSFiddle - React, Tailwind, and code Playground

HTML

<select id="myselectlist" multiple="multiple" data-limit="3">
  <option data-img-src="//placehold.it/30x30/ffee00" value="1">1 dude</option>
  <option data-img-src="//placehold.it/30x30/ff00ee" value="2">2 dude</option>
  <option data-img-src="//placehold.it/30x30/eeff00" value="3">3 dude</option>
  <option data-img-src="//placehold.it/30x30/fefe00" value="4">4 dude</option>
  <option data-img-src="//placehold.it/30x30/aaee00" value="5">5 dude</option>
  <option data-img-src="//placehold.it/30x30/99eecc" value="6">6 dude</option>
</select>

SCSS

$thumbnail_padding:         6px;
$thumbnail_margin:          12px;
$thumbnail_border:          1px solid #DDD;
$thumbnail_selected_color:  #08C;

ul.thumbnails.image_picker_selector
{
  overflow:             auto;
  list-style-image:     none;
  list-style-position:  outside;
  list-style-type:      none;
  padding:              0px;
  margin:               0px;

  li
  {
    margin:   0px $thumbnail_margin $thumbnail_margin 0px;
    float:    left;

    .thumbnail
    {
      padding:  $thumbnail_padding;
      border:   $thumbnail_border;

      img
      {

      }
    }

    .thumbnail.selected 
    { 
      background: $thumbnail_selected_color;
    }
  }
}

JavaScript

// Generated by CoffeeScript 1.6.2
var ImagePicker, ImagePickerOption, both_array_are_equal, sanitized_options, type,
  __indexOf = [].indexOf || function(item) {
    for (var i = 0, l = this.length; i < l; i++) {
      if (i in this && this[i] === item) return i;
    }
    return -1;
  };

type = function(obj) {
  var classToType, myClass, name, _i, _len, _ref;

  if (obj === void 0 || obj === null) {
    return String(obj);
  }
  classToType = new Object;
  _ref = "Boolean Number String Function Array Date RegExp".split(" ");
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    name = _ref[_i];
    classToType["[object " + name + "]"] = name.toLowerCase();
  }
  myClass = Object.prototype.toString.call(obj);
  if (myClass in classToType) {
    return classToType[myClass];
  }
  return "object";
};

jQuery.fn.extend({
  imagepicker: function(opts) {
    if (opts == null) {
      opts = {};
    }
    return this.each(function() {
      var select;

      select = jQuery(this);
      select.next("ul.image_picker_selector").remove();
      select.data("picker", new ImagePicker(this, sanitized_options(opts)));
      if (opts.initialized != null) {
        return opts.initialized();
      }
    });
  }
});

sanitized_options = function(opts) {
  var default_options;

  default_options = {
    hide_select: true,
    show_label: false,
    initialized: void 0,
    changed: void 0,
    clicked: void 0,
    selected: void 0,
    limit: 0,
    limit_reached: void 0
  };
  return jQuery.extend(default_options, opts);
};

both_array_are_equal = function(a, b) {
  return jQuery(a).not(b).length === 0 && jQuery(b).not(a).length === 0;
};

ImagePicker = (function() {
  function ImagePicker(select_element, opts) {
    this.opts = opts != null ? opts : {};
    this.select = jQuery(select_element);
    this.multiple = this.select.attr("multiple") === "multiple";
    this.limit = parseInt(this.select.data("limit")) || this.opts.limit;
    this.limit_reached =...