JSFiddle - React, Tailwind, and code Playground

by Simonwep

HTML

<script src="https://cdn.jsdelivr.net/npm/@simonwep/selection-js/lib/selection.min.js"></script>
<div class="block">
  <div contenteditable>
    test test test
  </div>
</div>
<div class="block">
  <div contenteditable>
    test test test
  </div>
</div>
<div class="block">
  <div contenteditable>
    test test test
  </div>
</div>
<div class="block">
  <div contenteditable>
    test test test
  </div>
</div>
<div class="block">
  <div contenteditable>
    test test test
  </div>
</div>
<div class="block">
  <div contenteditable>
    test test test
  </div>
</div>

CSS

html,
body {
  height: 100%
}

.selection-area {
  background: rgba(46, 115, 252, 0.11);
  border: 1px solid rgba(98, 155, 255, 0.85);
  border-radius: 0.15em;
}

.selected {
  background-color: rgba(46, 115, 252, 0.11);
}

.block {
  padding: 0.25rem;
}

JavaScript

// Initialize selectionjs
const selection = new SelectionArea({

    // All elements in this container can be selected
    selectables: ['.block'],

    // The container is also the boundary in this case
    boundaries: ['html']
}).on('beforestart', ({ store, event }) => {
      // Use this event to decide whether a selection should take place or not.
      // For example if the user should be able to normally interact with input-elements you
      // may want to prevent a selection if the user clicks such a element:
      // console.log('beforestart', store, event)

      // Remove class if the user isn't pressing the shift key
      if (!event.shiftKey && !event.ctrlKey && !event.metaKey) {
        // Unselect all elements
        for (const el of store.stored) {
          el.classList.remove('selected')
        }

        // Clear previous selection
        selection.clearSelection()
      }

      // Returning false prevents a selection
      if (event.target.parentNode.classList.contains('block')) return false
    }).on('start', ({ store, event }) => {
      // console.log('start', store, event)
    }).on('move', (evt) => {      
      const { store: { changed: { added, removed } } } = evt
      // Add a custom class to the elements that where selected.
      for (const el of added) {
        el.classList.add('selected')
      }

      // Remove the class from elements that where removed
      // since the last selection
      for (const el of removed) {
        el.classList.remove('selected')
      }
    }).on('stop', (evt) => {
       // console.log('stop', evt)
    
      selection.keepSelection()  
    })
    
  console.log(SelectionArea.version);