@viselect/preact

Preact wrapper around the viselect vanilla library

Usage no npm install needed!

<script type="module">
  import viselectPreact from 'https://cdn.skypack.dev/@viselect/preact';
</script>

README

Logo

Viselect - Preact

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

Via package manager

$ npm install @viselect/preact
# or 
$ yarn add @viselect/preact

Via script tags


<script src="https://cdn.jsdelivr.net/npm/@viselect/preact/lib/viselect.min.js"></script>
Via ES6 import
import SelectionArea from 'https://cdn.jsdelivr.net/npm/@viselect/preact/lib/viselect.min.mjs';

Getting started

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

All options are exposed as props. They're a one-to-one mapping of the original options found in the vanilla version!

import SelectionArea, {SelectionEvent} from '@viselect/preact';
import {FunctionalComponent} from 'preact';
import {useState} from 'preact/hooks';

const App: FunctionComponent = () => {
    const [selected, setSelected] = useState<Set<number>>(() => new Set());
    const extractIds = (els: Element[]): number[] =>
        els.map(v => v.getAttribute('data-key'))
            .filter(Boolean)
            .map(Number);

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

    const onMove = ({store: {changed: {added, removed}}}: SelectionEvent) => {
        setSelected(prev => {
            const next = new Set(prev);
            extractIds(added).forEach(id => next.add(id));
            extractIds(removed).forEach(id => next.delete(id));
            return next;
        });
    };

    return (
        <>
            <SelectionArea className="container"
                           onStart={onStart}
                           onMove={onMove}
                           selectables=".selectable">
                {new Array(42).fill(0).map((_, index) => (
                    <div className={selected.has(index) ? 'selected selectable' : 'selectable'}
                         data-key={index}
                         key={index}/>
                ))}
            </SelectionArea>
        </>
    );
}

Accessing the vanilla version

It's better to access the underlying vanilla version than installing the @viselect/vanilla package separately.

import {VanillaSelectionArea} from '@viselect/preact';
// ...