@viselect/vue
TypeScript icon, indicating that this package has built-in type declarations

3.5.1 • Public • Published

Logo

Viselect - Vue

License MIT No dependencies Support me Buy me a coffee Build Status gzip size brotli size Vue support Preact support React support Svelte support Lit-Element support Lit-Element support


Installation

Install using your package manager of choice:

npm install @viselect/vue

Last but not least you'll need to add some basic styles to make your selection-area visible:

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

Additionally, to not interfere with text-selection, selection-js won't prevent any default events anymore (as of v2.0.3). This however can cause problems with the actual selection ("introduced" by #99, reported in #103). If you don't care about text-selection, add the following to the container where all your selectables are located:

.container {
    user-select: none;
}

Usage

Events are handled using props because you cannot return a value in events synchronously.

<template>
  <SelectionArea class="container"
                 :options="{selectables: '.selectable'}"
                 :on-move="onMove"
                 :on-start="onStart">
    <div v-for="id of range(42)"
         class="selectable"
         :key="id" 
         :data-key="id"
         :class="{selected: selected.has(id)}"/>
  </SelectionArea>
</template>

<script lang="ts" setup>
import {SelectionArea, SelectionEvent} from '@viselect/vue';
import {reactive} from 'vue';

const selected = reactive<Set<number>>(new Set());

const range = (to: number, offset = 0): number[] => {
  return new Array(to).fill(0).map((_, i) => offset + i);
};

const extractIds = (els: Element[]): number[] => {
  return els.map(v => v.getAttribute('data-key'))
      .filter(Boolean)
      .map(Number);
}

const onStart = ({event, selection}: SelectionEvent) => {
  if (!event?.ctrlKey && !event?.metaKey) {
    selection.clearSelection();
    selected.clear();
  }
}

const onMove = ({store: {changed: {added, removed}}}: SelectionEvent) => {
  extractIds(added).forEach(id => selected.add(id));
  extractIds(removed).forEach(id => selected.delete(id));
}
</script>

Component exposed API

selection

It's possible to get the current SelectionArea-instance via [template refs](https://vuejs. org/guide/essentials/template-refs.html).

<template>
  <SelectionArea 
    class="container"
    :options="{selectables: '.selectable'}"
    ref="selectionAreaRef"
  >
    <div 
        v-for="id of 42"
        class="selectable"
        :key="id" 
        :data-key="id"
        :class="{selected: selected.has(id)}"
    />
  </SelectionArea>
</template>

<script lang="ts" setup>
import type {SelectionAreaInstance} from '@viselect/vue';
import {ref, reactive, onMounted} from 'vue';

const selected = reactive<Set<number>>(new Set());
const selectionAreaRef = ref<SelectionAreaInstance>()

onMounted(() => {
    // log current selection
    console.log(selectionAreaRef.value?.selection)
})
</script>

Package Sidebar

Install

npm i @viselect/vue

Weekly Downloads

131

Version

3.5.1

License

MIT

Unpacked Size

18.4 kB

Total Files

11

Last publish

Collaborators

  • simonwep