JSFiddle - React, Tailwind, and code Playground

HTML

<div>
<select id="ms" multiple="multiple">
    <optgroup label="グループ1を一括選択">
        <option value="1">りんご</option>
        <option value="2">みかん</option>
        <option value="3">桃</option>
        </optgroup>
    <optgroup label="グループ2を一括選択">
        <option value="4">2月</option>
        <option value="5">7月</option>
        <option value="6">10月</option>
    </optgroup>
    <optgroup label="グループ3を一括選択">
        <option value="7">東京</option>
        <option value="8">名古屋</option>
        <option value="9">大阪</option>
    </optgroup>
    <optgroup label="グループ4を一括選択">
        <option value="10">IE</option>
        <option value="11">Chrome</option>
        <option value="12">Firefox</option>
</optgroup>
    </select>
</div>

CSS

/**
 * @author zhixin wen <wenzhixin2010@gmail.com>
 */

#ms{width:200px;}

.ms-parent {
    display: inline-block;
    position: relative;
    vertical-align: middle;

}

.ms-choice {
    display: block;
    height: 26px;
    padding: 0;
    overflow: hidden;
    cursor: pointer;
    border: 1px solid #aaa;
    text-align: left;
    white-space: nowrap;
    line-height: 26px;
    color: #444;
    text-decoration: none;
    background-color: #fff;

}

.ms-choice.disabled {
    background-color: #f4f4f4;
    background-image: none;
    border: 1px solid #ddd;
    cursor: default;
}

.ms-choice > span {
    position: absolute;
    top: 0;
    left: 0;
    right: 20px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    padding-left: 8px;
}

.ms-choice > span.placeholder {
    color: #999;
}

.ms-choice > div {
    position: absolute;
    top: 0;
    right: 0;
    width: 20px;
    height: 25px;
}


.ms-drop {
    overflow: hidden;
    display: none;
    margin-top: -1px;
    padding: 0;
    position: absolute;
    z-index: 1000;
    background: #fff;
    color: #000;
    border: 1px solid #aaa;
}

.ms-drop.bottom {
    top: 100%;
}

.ms-drop.top {
    bottom: 100%;
}

.ms-search {
    display: inline-block;
    margin: 0;
    min-height: 26px;
    padding: 4px;
    position: relative;
    white-space: nowrap;
    width: 100%;
    z-index: 10000;
}

.ms-search input {
    width: 100%;
    height: auto !important;
    min-height: 24px;
    padding: 0 20px 0 5px;
    margin: 0;
    outline: 0;
    font-family: sans-serif;
    font-size: 1em;
    border: 1px solid #aaa;
    border-radius: 0;
}

.ms-search, .ms-search input {
    -webkit-box-sizing: border-box;
    -khtml-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
}

.ms-drop ul {
    overflow: auto;
    margin: 0;
    padding: 5px 8px;
}

.ms-drop ul > li {
    list-style: none;
    display:...

JavaScript

/**
 * @author zhixin wen <wenzhixin2010@gmail.com>
 * @version 1.0.7
 * 
 * http://wenzhixin.net.cn/p/multiple-select/
 */

(function($) {

    'use strict';

    function MultipleSelect($el, options) {
        var that = this,
            elWidth = $el.width();

        this.$el = $el.hide();
        this.options = options;

        this.$parent = $('<div class="ms-parent"></div>');
        this.$choice = $('<button type="button" class="ms-choice"><span class="placeholder">' + options.placeholder + '</span><div></div></button>');
        this.$drop = $('<div class="ms-drop ' + options.position + '"></div>');
        this.$el.after(this.$parent);
        this.$parent.append(this.$choice);
        this.$parent.append(this.$drop);

        if (this.$el.prop('disabled')) {
            this.$choice.addClass('disabled');
        }
        this.$choice.css('width', elWidth + 'px');
        this.$drop.css({
            width: (options.width || elWidth) + 'px'
        });

        $('body').click(function(e) {
            if ($(e.target)[0] === that.$choice[0] || $(e.target).parents('.ms-choice')[0] === that.$choice[0]) {
                return;
            }
            if (($(e.target)[0] === that.$drop[0] || $(e.target).parents('.ms-drop')[0] !== that.$drop[0]) && that.options.isOpen) {
                that.close();
            }
        });

        if (this.options.isOpen) {
            this.open();
        }
    }

    MultipleSelect.prototype = {
        constructor: MultipleSelect,

        init: function() {
            var that = this,
                html = [];
            if (this.options.filter) {
                html.push('<div class="ms-search">', '<input type="text" autocomplete="off" autocorrect="off" autocapitilize="off" spellcheck="false">', '</div>');
            }
            html.push('<ul>');
            if (this.options.selectAll && !this.options.single) {
                html.push('<li>', '<label>', '<input type="checkbox" name="selectAll" /> ',...