Skip to main content

React

DragSelect works well with any library out of the box. But for your convenience we created this example page to see how we use it in the "react way"!

PS: We are looking into creating custom wrappers for libraries. We will update this guide as soon as available.

1. Create a context

Feel free to copy+paste the code:

import React, { createContext, useState, useEffect, useContext } from "react";
import DragSelect, { DSInputElement } from "dragselect";

type ProviderProps = {
children: React.ReactNode;
settings?: ConstructorParameters<typeof DragSelect<DSInputElement>>[0];
};

const Context = createContext<DragSelect<DSInputElement> | undefined>(
undefined
);

function DragSelectProvider({ children, settings = {} }: ProviderProps) {
const [ds, setDS] = useState<DragSelect<DSInputElement>>();

useEffect(() => {
setDS((prevState) => {
if (prevState) return prevState;
return new DragSelect({});
});
return () => {
if (ds) {
ds.stop();
setDS(undefined);
}
};
}, [ds]);

useEffect(() => {
ds?.setSettings(settings);
}, [ds, settings]);

return <Context.Provider value={ds}>{children}</Context.Provider>;
}

function useDragSelect() {
return useContext(Context);
}

export { DragSelectProvider, useDragSelect };

2. Wrap it

import React from "react";

import { DragSelectProvider } from "./DragSelectContext";

export const MyComponent = () => (
// you can add initial settings by passing a settings object
<DragSelectProvider settings={{ selectorClass: styles.selector }}>
<SomeOtherComponentsThatNeedsDragSelect />
</DragSelectProvider>
);

3. Use it

import React, { useEffect, useRef } from "react";
import { useDragSelect } from "./DragSelectContext";

export const SomeOtherComponentsThatNeedsDragSelect = () => {
const ds = useDragSelect();
const inputEl = useRef(null);

// adding a selectable element
useEffect(() => {
const element = inputEl.current as unknown as HTMLElement;
if (!element || !ds) return;
ds.addSelectables(element);
}, [ds, inputEl]);

// subscribing to a callback
useEffect(() => {
if (!ds) return;
const id = ds.subscribe("DS:end", (e) => {
// do something
console.log(e);
});

return () => ds.unsubscribe("DS:end", null, id!);
}, [ds]);

return (
<button ref={inputEl} aria-labelledby="Selectable">
Selectable
</button>
);
};

DragSelect also exports some helper types for type safety, i.e. DSPubCallback which you can pass in the subscriber for the callback type safety:

import { DSPubCallback } from "dragselect";
const cb: DSPubCallback<"DS:end"> = ({ items = [] }) => {
console.log("CALLBACK", items);
setSelectedAmount(items.length);
};

You can see this example in use within this docusaurus project. I.e. the context provider here and a random useage example here