JSFiddle - React, Tailwind, and code Playground

by Sukanya Halder

HTML

<div class="container">
    <div id="div1">
        <p class="selectable">lorem</p>
        <p class="selectable">ipsum</p>
    </div>
    <div id="div2">
        <p class="selectable">dolor</p>
        <p class="selectable">sit</p>
        <p class="selectable">amet</p>
    </div>
</div>

CSS

.selected {
    background:red;
}
#container {
    user-select: none;
    /* CSS3 (little to no support) */
    -ms-user-select: none;
    /* IE 10+ */
    -moz-user-select: none;
    /* Gecko (Firefox) */
    -webkit-user-select: none;
    /* Webkit (Safari, Chrome) */
}

JavaScript

var $lastSelected = [],
    container = $('.container'),
    collection = $('.selectable');

container.on('click', '.selectable', function (e) {
    var that = $(this),
        $selected,
        direction;

    if (e.shiftKey) {

        if ($lastSelected.length > 0) {

            if (that[0] == $lastSelected[0]) {
                // The user has clicked on the same item, so do nothing.
                // Remember, `that` is our event target
                // You could also make this deselect everything except for this item
                return false;
            }
            if ($lastSelected.parent().attr("id") == that.parent().attr("id")) {
                direction = that.nextAll('.container .lastSelected').length > 0 ? 'forward' : 'back';

                if ('forward' == direction) {
                    // Last selected is after the current selection                
                    $selected = that.nextUntil($lastSelected, '.selectable');

                } else {
                    // Last selected is before the current selection                
                    $selected = $lastSelected.nextUntil(that, '.selectable');
                }

                //Add and remove classes as necessary
                collection.removeClass('selected');
                $selected.addClass('selected');
                $lastSelected.addClass('selected');
                that.addClass('selected');

            } else {
                $lastSelected = that;
                // Mark our previously selected item
                that.addClass('lastSelected');
                collection.removeClass('selected');
                that.addClass('selected');
            }
        } else {
            $lastSelected = that;
            // Mark our previously selected item
            that.addClass('lastSelected');
            collection.removeClass('selected');
            that.addClass('selected');
        }

    } else {
        // Not a shift select, so we'll just...