From cf43f92e4ae60b7fd76e6ff98060b8314b4af0b4 Mon Sep 17 00:00:00 2001 From: ThibaultJanBeyer Date: Wed, 29 May 2024 17:03:05 +0000 Subject: [PATCH] deploy: a0288225b1d545a114ff75a270cdb710046befb4 --- 404.html | 4 ++-- assets/js/516d925c.361a4e3d.js | 1 + assets/js/516d925c.57c733c9.js | 1 - .../{runtime~main.6b833cde.js => runtime~main.25ba5c20.js} | 2 +- docs/API/CSS-Classes.html | 4 ++-- docs/API/Events.html | 4 ++-- docs/API/Methods.html | 4 ++-- docs/API/Overrides.html | 4 ++-- docs/API/Settings.html | 4 ++-- docs/category/api.html | 4 ++-- docs/category/guided-examples.html | 4 ++-- docs/guided-examples/Accessibility.html | 4 ++-- docs/guided-examples/Area.html | 4 ++-- docs/guided-examples/Custom-Selection-Filter-Override.html | 4 ++-- docs/guided-examples/CustomDnD.html | 4 ++-- docs/guided-examples/DropZones.html | 4 ++-- docs/guided-examples/Mobile-Touch.html | 4 ++-- docs/guided-examples/Publish-Subscribe.html | 4 ++-- docs/guided-examples/React.html | 4 ++-- docs/guided-examples/Simple.html | 4 ++-- docs/guided-examples/Updating-Settings.html | 4 ++-- docs/info.html | 6 +++--- docs/intro.html | 4 ++-- index.html | 6 +++--- licenses.html | 4 ++-- search.html | 4 ++-- 26 files changed, 50 insertions(+), 50 deletions(-) create mode 100644 assets/js/516d925c.361a4e3d.js delete mode 100644 assets/js/516d925c.57c733c9.js rename assets/js/{runtime~main.6b833cde.js => runtime~main.25ba5c20.js} (91%) diff --git a/404.html b/404.html index 46327be..d95a252 100644 --- a/404.html +++ b/404.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/assets/js/516d925c.361a4e3d.js b/assets/js/516d925c.361a4e3d.js new file mode 100644 index 0000000..5d48106 --- /dev/null +++ b/assets/js/516d925c.361a4e3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdrag_select_docs=self.webpackChunkdrag_select_docs||[]).push([[329],{5318:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var r=a(7378);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function n(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):n(n({},t),e)),a},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var a=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(a),d=o,m=u["".concat(l,".").concat(d)]||u[d]||h[d]||s;return a?r.createElement(m,n(n({ref:t},p),{},{components:a})):r.createElement(m,n({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=a.length,n=new Array(s);n[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,n[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var r=a(5773),o=(a(7378),a(5318)),s=a(7604);const n={sidebar_position:1,description:"More information about DragSelect. DragSelect is a JavaScript library that allows you to select elements by dragging a rectangle over them and allows you to drag the selected elements around. It is a lightweight alternative to jQuery UI's selectable and draggable widgets."},i="DragSelect",l={unversionedId:"info",id:"info",title:"DragSelect",description:"More information about DragSelect. DragSelect is a JavaScript library that allows you to select elements by dragging a rectangle over them and allows you to drag the selected elements around. It is a lightweight alternative to jQuery UI's selectable and draggable widgets.",source:"@site/docs/info.mdx",sourceDirName:".",slug:"/info",permalink:"/docs/info",draft:!1,editUrl:"https://github.com/ThibaultJanBeyer/DragSelect/docs/info.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,description:"More information about DragSelect. DragSelect is a JavaScript library that allows you to select elements by dragging a rectangle over them and allows you to drag the selected elements around. It is a lightweight alternative to jQuery UI's selectable and draggable widgets."},sidebar:"tutorialSidebar",next:{title:"Getting Started",permalink:"/docs/intro"}},c={},p=[{value:"Key-Features",id:"key-features",level:2},{value:"Why?",id:"why",level:2},{value:"Supporters",id:"supporters",level:2},{value:"Thanks to:",id:"thanks-to",level:3},{value:"LambdaTest",id:"lambdatest",level:4},{value:"BrowserStack",id:"browserstack",level:4},{value:"DigitalOcean",id:"digitalocean",level:4},{value:"You?",id:"you",level:4},{value:"Licenses",id:"licenses",level:3}],u={toc:p},h="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(h,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dragselect"},"DragSelect"),(0,o.kt)("picture",null,(0,o.kt)("source",{media:"(prefers-color-scheme: light)",srcset:"https://dragselect.com/img/dragselect-logo.png"}),(0,o.kt)("source",{media:"(prefers-color-scheme: dark)",srcset:"https://dragselect.com/img/dragselect-logo-alt.png"}),(0,o.kt)("img",{alt:"The DragSelect logo: a selection symbol, a hand, a drop symbol and a mouse within a selection square.",width:"300",src:"https://dragselect.com/img/dragselect-logo.png"})),(0,o.kt)("br",null),(0,o.kt)("a",{href:"https://github.com/ThibaultJanBeyer/DragSelect/actions"},(0,o.kt)("img",{alt:"Build Status",src:"https://github.com/ThibaultJanBeyer/DragSelect/actions/workflows/github-actions-build.yml/badge.svg"}))," ",(0,o.kt)("a",{href:"https://unpkg.com/dragselect@latest/dist/ds.min.js"},(0,o.kt)("img",{alt:"gzip size",src:"https://img.badgesize.io/https://dragselect.com/ds.min.js?compression=gzip"}))," ",(0,o.kt)("a",{href:"https://www.npmjs.com/package/dragselect"},(0,o.kt)("img",{alt:"npm downloads count",src:"https://img.shields.io/npm/dt/dragselect.svg"}))," ",(0,o.kt)("a",{href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/DragSelect/package.json"},(0,o.kt)("img",{alt:"No Dependency",src:"https://img.shields.io/badge/dependencies-none-informational"}))," ",(0,o.kt)("a",{href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/CONTRIBUTING.md"},(0,o.kt)("img",{alt:"Contributors Welcome",src:"https://img.shields.io/badge/contributors-welcome-blueviolet"}))," ",(0,o.kt)("a",{href:"https://github.com/sponsors/ThibaultJanBeyer"},(0,o.kt)("img",{alt:"Sponsors Welcome",src:"https://img.shields.io/badge/sponsors-welcome-blueviolet"})),(0,o.kt)("h2",{id:"key-features"},"Key-Features"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"No dependencies")," ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/package.json"},(0,o.kt)("img",{parentName:"a",src:"https://img.shields.io/badge/dependencies-none-informational",alt:"No Dependency"}))),(0,o.kt)("li",{parentName:"ul"},"Hyper customizable"),(0,o.kt)("li",{parentName:"ul"},"Replicates operating system drag-selection in the browser"),(0,o.kt)("li",{parentName:"ul"},"Accessibility (a11y)"),(0,o.kt)("li",{parentName:"ul"},"Use modifier keys to make multiple independent selections"),(0,o.kt)("li",{parentName:"ul"},"Select, Drag and Drop also also via keyboard"),(0,o.kt)("li",{parentName:"ul"},"Supports all major browsers"),(0,o.kt)("li",{parentName:"ul"},"Lightweight, only ",(0,o.kt)("img",{parentName:"li",src:"https://img.badgesize.io/https://dragselect.com/ds.min.js?compression=gzip",alt:"gzip size"})),(0,o.kt)("li",{parentName:"ul"},"Popular: ",(0,o.kt)("img",{parentName:"li",src:"https://img.shields.io/npm/dt/dragselect.svg",alt:"npm downloads count"})," on npm"),(0,o.kt)("li",{parentName:"ul"},"DragSelect was written with Performance in mind (can easily select >15.000 Elements)"),(0,o.kt)("li",{parentName:"ul"},"Supports SVG"),(0,o.kt)("li",{parentName:"ul"},"Supports mobile (touch interaction)"),(0,o.kt)("li",{parentName:"ul"},"Free & open source"),(0,o.kt)("li",{parentName:"ul"},"Easy to use")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"demo-gif",src:a(7490).Z,width:"1066",height:"696"})),(0,o.kt)("h2",{id:"why"},"Why?"),(0,o.kt)("p",null,"Because apparently there was nothing that does not require jquery out there.",(0,o.kt)("br",{parentName:"p"}),"\n","This is better than ",(0,o.kt)("a",{parentName:"p",href:"https://jqueryui.com/selectable/"},"https://jqueryui.com/selectable/")," or ",(0,o.kt)("a",{parentName:"p",href:"https://jqueryui.com/draggable/"},"https://jqueryui.com/draggable/")," and has no dependencies.\nWe use it currently in a professional rich interface application where we have a file management system. The user can select files to organize them and change their metadata, with this plugin our users are able to select multiple files and perform batch/bulk-operations (applying changes to multiple files at once). We also use it in production for another huge, graphical cloud hosting manager with millions of active users. Users can select multiple servers, storages, etc. on an artboard to perform multi-operations, re-organize them, move them on the UI or batch-delete. We\u2019re running it in production since January 18' it\u2019s super helpful and very stable, let\u2019s keep it that way. I can easily think of dozens other use-cases. We\u2019re really keen to know how you use it in your projects, please let us know."),(0,o.kt)("h2",{id:"supporters"},"Supporters"),(0,o.kt)(s.Z,{href:"https://github.com/sponsors/ThibaultJanBeyer","data-icon":"octicon-heart","aria-label":"Sponsor @ThibaultJanBeyer on GitHub",mdxType:"GitHubButton"},"Donate")," ",(0,o.kt)(s.Z,{href:"https://github.com/ThibaultJanBeyer/DragSelect","data-icon":"octicon-star","data-show-count":"true","aria-label":"Star ThibaultJanBeyer/DragSelect on GitHub",mdxType:"GitHubButton"},"Star"),(0,o.kt)("p",null,"Please donate to support the countless hours of hard work & support. Especially if your company makes money, then there is no excuse.\nIf you're broke, you can still support us with your time instead by ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/CONTRIBUTING.md"},"contributing to the code"),"!"),(0,o.kt)("p",null,"Thank you :)"),(0,o.kt)("h3",{id:"thanks-to"},"Thanks to:"),(0,o.kt)("h4",{id:"lambdatest"},"LambdaTest"),(0,o.kt)("a",{href:"https://www.lambdatest.com/"},(0,o.kt)("img",{src:"https://www.lambdatest.com/support/img/logo.svg",alt:"LambdaTest",width:"147",style:{background:"white"}})),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.lambdatest.com/"},"LambdaTest")," is a Next-Generation Mobile App and Cross Browser Testing Cloud. They support this open source projects by providing us with a free account and with a generous donation!"),(0,o.kt)("h4",{id:"browserstack"},"BrowserStack"),(0,o.kt)("a",{href:"https://www.browserstack.com/"},(0,o.kt)("img",{src:"https://cdn.worldvectorlogo.com/logos/browserstack.svg",alt:"Browserstack",width:"100px"})),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.browserstack.com/"},"BrowserStack")," is a service for cross-browser testing. They support this open source projects by providing us with a ",(0,o.kt)("a",{parentName:"p",href:"https://www.browserstack.com/open-source"},"free account"),"!"),(0,o.kt)("h4",{id:"digitalocean"},"DigitalOcean"),(0,o.kt)("a",{href:"https://www.digitalocean.com/"},(0,o.kt)("img",{src:"https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_vertical_blue.svg",alt:"DigitalOcean",width:"150px"})),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.digitalocean.com/"},"DigitalOcean")," is a cloud hosting service. They support this open source projects by providing us with ",(0,o.kt)("a",{parentName:"p",href:"https://www.digitalocean.com/open-source/credits-for-projects"},"free credits"),"!"),(0,o.kt)("h4",{id:"you"},"You?"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/sponsors/ThibaultJanBeyer"},"You?")),(0,o.kt)("p",null,"Show your appreciation and support with a donation! ",(0,o.kt)("a",{parentName:"p",href:"https://www.blockchain.com/btc/address/1LdweSpjgSeJC8XxX3swrohBMBLUzg6cmC"},"Direct Donation to DragSelect")," (via Bitcoin: ",(0,o.kt)("inlineCode",{parentName:"p"},"1LdweSpjgSeJC8XxX3swrohBMBLUzg6cmC"),"). Or sponsor via ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/sponsors/ThibaultJanBeyer"},"GitHub Sponsors")," or ",(0,o.kt)("a",{parentName:"p",href:"mailto:thibault.beyer@gmail.com"},"Get in touch"),"."),(0,o.kt)("p",null,"Donations are distributed with all project contributors proportionally to their involvement. We are grateful for any amount: we have more than ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/npm/dt/dragselect.svg",alt:"npm downloads count"}),", imagine how much we'd have if everyone would have had donated only 1$ \ud83e\udd29 (unfortunately this is just a dream). If you donate, we can display your logo here if you want, which will give you infinite fame, fortune and help you recruit great talent."),(0,o.kt)("h3",{id:"licenses"},"Licenses"),(0,o.kt)("p",null,"TL;DR: If your project makes money: ",(0,o.kt)("a",{href:"/licenses"},"Purchase a commercial license"),"."),(0,o.kt)("p",null,"DragSelect is, and will forever be, a free and open-source tool. ",(0,o.kt)("strong",null,"Free for any non-commercial project"),". However, this is a lot of work and hard work should be rewarded, so if you are using DragSelect for business and/or commercial sites, projects, and applications you\u2019ll have to ",(0,o.kt)("a",{href:"/licenses"},"get the commercial license")," to keep your source proprietary and the project alive."))}d.isMDXComponent=!0},7490:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/dragselect-b56e58466ecde6b4ce46d5e2297d22d7.gif"}}]); \ No newline at end of file diff --git a/assets/js/516d925c.57c733c9.js b/assets/js/516d925c.57c733c9.js deleted file mode 100644 index 498c370..0000000 --- a/assets/js/516d925c.57c733c9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdrag_select_docs=self.webpackChunkdrag_select_docs||[]).push([[329],{5318:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var r=a(7378);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function s(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var a=e.components,o=e.mdxType,n=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(a),d=o,m=u["".concat(l,".").concat(d)]||u[d]||h[d]||n;return a?r.createElement(m,s(s({ref:t},p),{},{components:a})):r.createElement(m,s({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=a.length,s=new Array(n);s[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>l,toc:()=>p});var r=a(5773),o=(a(7378),a(5318)),n=a(7604);const s={sidebar_position:1,description:"More information about DragSelect. DragSelect is a JavaScript library that allows you to select elements by dragging a rectangle over them and allows you to drag the selected elements around. It is a lightweight alternative to jQuery UI's selectable and draggable widgets."},i="DragSelect",l={unversionedId:"info",id:"info",title:"DragSelect",description:"More information about DragSelect. DragSelect is a JavaScript library that allows you to select elements by dragging a rectangle over them and allows you to drag the selected elements around. It is a lightweight alternative to jQuery UI's selectable and draggable widgets.",source:"@site/docs/info.mdx",sourceDirName:".",slug:"/info",permalink:"/docs/info",draft:!1,editUrl:"https://github.com/ThibaultJanBeyer/DragSelect/docs/info.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,description:"More information about DragSelect. DragSelect is a JavaScript library that allows you to select elements by dragging a rectangle over them and allows you to drag the selected elements around. It is a lightweight alternative to jQuery UI's selectable and draggable widgets."},sidebar:"tutorialSidebar",next:{title:"Getting Started",permalink:"/docs/intro"}},c={},p=[{value:"Key-Features",id:"key-features",level:2},{value:"Why?",id:"why",level:2},{value:"Supporters",id:"supporters",level:2},{value:"Thanks to:",id:"thanks-to",level:3},{value:"Licenses",id:"licenses",level:3}],u={toc:p},h="wrapper";function d(e){let{components:t,...s}=e;return(0,o.kt)(h,(0,r.Z)({},u,s,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"dragselect"},"DragSelect"),(0,o.kt)("picture",null,(0,o.kt)("source",{media:"(prefers-color-scheme: light)",srcset:"https://dragselect.com/img/dragselect-logo.png"}),(0,o.kt)("source",{media:"(prefers-color-scheme: dark)",srcset:"https://dragselect.com/img/dragselect-logo-alt.png"}),(0,o.kt)("img",{alt:"The DragSelect logo: a selection symbol, a hand, a drop symbol and a mouse within a selection square.",width:"300",src:"https://dragselect.com/img/dragselect-logo.png"})),(0,o.kt)("br",null),(0,o.kt)("a",{href:"https://github.com/ThibaultJanBeyer/DragSelect/actions"},(0,o.kt)("img",{alt:"Build Status",src:"https://github.com/ThibaultJanBeyer/DragSelect/actions/workflows/github-actions-build.yml/badge.svg"}))," ",(0,o.kt)("a",{href:"https://unpkg.com/dragselect@latest/dist/ds.min.js"},(0,o.kt)("img",{alt:"gzip size",src:"https://img.badgesize.io/https://dragselect.com/ds.min.js?compression=gzip"}))," ",(0,o.kt)("a",{href:"https://www.npmjs.com/package/dragselect"},(0,o.kt)("img",{alt:"npm downloads count",src:"https://img.shields.io/npm/dt/dragselect.svg"}))," ",(0,o.kt)("a",{href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/DragSelect/package.json"},(0,o.kt)("img",{alt:"No Dependency",src:"https://img.shields.io/badge/dependencies-none-informational"}))," ",(0,o.kt)("a",{href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/CONTRIBUTING.md"},(0,o.kt)("img",{alt:"Contributors Welcome",src:"https://img.shields.io/badge/contributors-welcome-blueviolet"}))," ",(0,o.kt)("a",{href:"https://github.com/sponsors/ThibaultJanBeyer"},(0,o.kt)("img",{alt:"Sponsors Welcome",src:"https://img.shields.io/badge/sponsors-welcome-blueviolet"})),(0,o.kt)("h2",{id:"key-features"},"Key-Features"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"No dependencies")," ",(0,o.kt)("a",{parentName:"li",href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/package.json"},(0,o.kt)("img",{parentName:"a",src:"https://img.shields.io/badge/dependencies-none-informational",alt:"No Dependency"}))),(0,o.kt)("li",{parentName:"ul"},"Hyper customizable"),(0,o.kt)("li",{parentName:"ul"},"Replicates operating system drag-selection in the browser"),(0,o.kt)("li",{parentName:"ul"},"Accessibility (a11y)"),(0,o.kt)("li",{parentName:"ul"},"Use modifier keys to make multiple independent selections"),(0,o.kt)("li",{parentName:"ul"},"Select, Drag and Drop also also via keyboard"),(0,o.kt)("li",{parentName:"ul"},"Supports all major browsers"),(0,o.kt)("li",{parentName:"ul"},"Lightweight, only ",(0,o.kt)("img",{parentName:"li",src:"https://img.badgesize.io/https://dragselect.com/ds.min.js?compression=gzip",alt:"gzip size"})),(0,o.kt)("li",{parentName:"ul"},"Popular: ",(0,o.kt)("img",{parentName:"li",src:"https://img.shields.io/npm/dt/dragselect.svg",alt:"npm downloads count"})," on npm"),(0,o.kt)("li",{parentName:"ul"},"DragSelect was written with Performance in mind (can easily select >15.000 Elements)"),(0,o.kt)("li",{parentName:"ul"},"Supports SVG"),(0,o.kt)("li",{parentName:"ul"},"Supports mobile (touch interaction)"),(0,o.kt)("li",{parentName:"ul"},"Free & open source"),(0,o.kt)("li",{parentName:"ul"},"Easy to use")),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"demo-gif",src:a(7490).Z,width:"1066",height:"696"})),(0,o.kt)("h2",{id:"why"},"Why?"),(0,o.kt)("p",null,"Because apparently there was nothing that does not require jquery out there.",(0,o.kt)("br",{parentName:"p"}),"\n","This is better than ",(0,o.kt)("a",{parentName:"p",href:"https://jqueryui.com/selectable/"},"https://jqueryui.com/selectable/")," or ",(0,o.kt)("a",{parentName:"p",href:"https://jqueryui.com/draggable/"},"https://jqueryui.com/draggable/")," and has no dependencies.\nWe use it currently in a professional rich interface application where we have a file management system. The user can select files to organize them and change their metadata, with this plugin our users are able to select multiple files and perform batch/bulk-operations (applying changes to multiple files at once). We also use it in production for another huge, graphical cloud hosting manager with millions of active users. Users can select multiple servers, storages, etc. on an artboard to perform multi-operations, re-organize them, move them on the UI or batch-delete. We\u2019re running it in production since January 18' it\u2019s super helpful and very stable, let\u2019s keep it that way. I can easily think of dozens other use-cases. We\u2019re really keen to know how you use it in your projects, please let us know."),(0,o.kt)("h2",{id:"supporters"},"Supporters"),(0,o.kt)(n.Z,{href:"https://github.com/sponsors/ThibaultJanBeyer","data-icon":"octicon-heart","aria-label":"Sponsor @ThibaultJanBeyer on GitHub",mdxType:"GitHubButton"},"Donate")," ",(0,o.kt)(n.Z,{href:"https://github.com/ThibaultJanBeyer/DragSelect","data-icon":"octicon-star","data-show-count":"true","aria-label":"Star ThibaultJanBeyer/DragSelect on GitHub",mdxType:"GitHubButton"},"Star"),(0,o.kt)("p",null,"Please donate to support the countless hours of hard work & support. Especially if your company makes money, then there is no excuse.\nIf you're broke, you can still support us with your time instead by ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ThibaultJanBeyer/DragSelect/blob/master/CONTRIBUTING.md"},"contributing to the code"),"!"),(0,o.kt)("p",null,"Thank you :)"),(0,o.kt)("h3",{id:"thanks-to"},"Thanks to:"),(0,o.kt)("table",null,(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("a",{href:"https://www.lambdatest.com/",target:"_blank"},(0,o.kt)("img",{src:"https://www.lambdatest.com/support/img/logo.svg",width:"147px"}))),(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("a",{href:"https://www.browserstack.com/"},(0,o.kt)("img",{src:"https://cdn.worldvectorlogo.com/logos/browserstack.svg",alt:"Browserstack",width:"100px"}))),(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("a",{href:"https://www.digitalocean.com/"},(0,o.kt)("img",{src:"https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_vertical_blue.svg",alt:"DigitalOcean",width:"150px"}))),(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"th",href:"https://github.com/sponsors/ThibaultJanBeyer"},"You?")))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"https://www.lambdatest.com/"},"LambdaTest")," is a Next-Generation Mobile App and Cross Browser Testing Cloud. They support this open source projects by providing us with a free account and with a generous donation!"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"https://www.browserstack.com/"},"BrowserStack")," is a service for cross-browser testing. They support this open source projects by providing us with a ",(0,o.kt)("a",{parentName:"td",href:"https://www.browserstack.com/open-source"},"free account"),"!"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("a",{parentName:"td",href:"https://www.digitalocean.com/"},"DigitalOcean")," is a cloud hosting service. They support this open source projects by providing us with ",(0,o.kt)("a",{parentName:"td",href:"https://www.digitalocean.com/open-source/credits-for-projects"},"free credits"),"!"),(0,o.kt)("td",{parentName:"tr",align:null},"Thank and support us by making a ",(0,o.kt)("a",{parentName:"td",href:"https://www.blockchain.com/btc/address/1LdweSpjgSeJC8XxX3swrohBMBLUzg6cmC"},"Direct Donation to DragSelect")," (via Bitcoin: ",(0,o.kt)("inlineCode",{parentName:"td"},"1LdweSpjgSeJC8XxX3swrohBMBLUzg6cmC"),"). Or sponsor via ",(0,o.kt)("a",{parentName:"td",href:"https://github.com/sponsors/ThibaultJanBeyer"},"GitHub Sponsors")," or ",(0,o.kt)("a",{parentName:"td",href:"mailto:thibault.beyer@gmail.com"},"Get in touch"),".")))),(0,o.kt)("p",null,"Donations are distributed with all project contributors proportionally to their involvement. We are grateful for any amount: we have more than ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/npm/dt/dragselect.svg",alt:"npm downloads count"}),", imagine how much we'd have if everyone would have had donated only 1$ \ud83e\udd29 (unfortunately this did not happen). If you donate, we can display your logo here if you want, which will give you fame, fortune and help you recruit great talent and boosting your SEO."),(0,o.kt)("h3",{id:"licenses"},"Licenses"),(0,o.kt)("p",null,"TL;DR: If your project makes money: ",(0,o.kt)("a",{href:"/licenses"},"Purchase a commercial license"),"."),(0,o.kt)("p",null,"DragSelect is, and will forever be, a free and open-source tool. ",(0,o.kt)("strong",null,"Free for any non-commercial project"),". However, this is a lot of work and hard work should be rewarded, so if you are using DragSelect for business and/or commercial sites, projects, and applications you\u2019ll have to ",(0,o.kt)("a",{href:"/licenses"},"get the commercial license")," to keep your source proprietary and the project alive."))}d.isMDXComponent=!0},7490:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/dragselect-b56e58466ecde6b4ce46d5e2297d22d7.gif"}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.6b833cde.js b/assets/js/runtime~main.25ba5c20.js similarity index 91% rename from assets/js/runtime~main.6b833cde.js rename to assets/js/runtime~main.25ba5c20.js index 629aeed..c1f00ef 100644 --- a/assets/js/runtime~main.6b833cde.js +++ b/assets/js/runtime~main.25ba5c20.js @@ -1 +1 @@ -(()=>{"use strict";var e,t,r,a,f,d={},o={};function c(e){var t=o[e];if(void 0!==t)return t.exports;var r=o[e]={id:e,loaded:!1,exports:{}};return d[e].call(r.exports,r,r.exports,c),r.loaded=!0,r.exports}c.m=d,c.c=o,e=[],c.O=(t,r,a,f)=>{if(!r){var d=1/0;for(l=0;l=f)&&Object.keys(c.O).every((e=>c.O[e](r[n])))?r.splice(n--,1):(o=!1,f0&&e[l-1][2]>f;l--)e[l]=e[l-1];e[l]=[r,a,f]},c.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return c.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var f=Object.create(null);c.r(f);var d={};t=t||[null,r({}),r([]),r(r)];for(var o=2&a&&e;"object"==typeof o&&!~t.indexOf(o);o=r(o))Object.getOwnPropertyNames(o).forEach((t=>d[t]=()=>e[t]));return d.default=()=>e,c.d(f,d),f},c.d=(e,t)=>{for(var r in t)c.o(t,r)&&!c.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((t,r)=>(c.f[r](e,t),t)),[])),c.u=e=>"assets/js/"+({3:"4022cc72",40:"b91564ff",53:"935f2afb",158:"009b9a4c",206:"f8409a7e",237:"1df93b7f",265:"1cd16d8e",329:"516d925c",335:"1d6fa843",391:"ef24aaad",406:"d004f1d9",422:"2777a583",481:"66990a94",493:"988781e2",514:"1be78505",537:"94c45520",625:"9596d493",638:"dfbf2a2a",656:"9eb7e184",682:"69e9432f",783:"a64269bf",817:"14eb3368",883:"698c490d",897:"56267c29",918:"17896441",920:"1a4e3797",928:"f06d3d6a",952:"950e315b",978:"82fcd85e"}[e]||e)+"."+{3:"99613e40",40:"c7c9f840",41:"9f26e2d0",53:"a161b6e0",127:"9f63bfa6",158:"b36af2df",206:"06d6335e",237:"16932c0f",265:"acb34b33",329:"57c733c9",335:"49495094",374:"99e70a06",391:"7c5dbd2e",406:"4f03ff40",422:"88f15133",481:"501af493",493:"2b6102fe",514:"33724dfa",537:"fc75be7d",604:"159b9e3e",625:"de41af1c",638:"bae044a8",656:"0a322e23",670:"63f7bee2",682:"537517fc",783:"1faa1b62",817:"6686f448",883:"19c112e0",889:"2bad9243",893:"216a4509",897:"6a6cce32",918:"d20e4110",920:"c0dbb825",928:"41c146e9",952:"5636b099",978:"7d47a6fd"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},f="drag-select-docs:",c.l=(e,t,r,d)=>{if(a[e])a[e].push(t);else{var o,n;if(void 0!==r)for(var i=document.getElementsByTagName("script"),l=0;l{o.onerror=o.onload=null,clearTimeout(s);var f=a[e];if(delete a[e],o.parentNode&&o.parentNode.removeChild(o),f&&f.forEach((e=>e(r))),t)return t(r)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=u.bind(null,o.onerror),o.onload=u.bind(null,o.onload),n&&document.head.appendChild(o)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/",c.gca=function(e){return e={17896441:"918","4022cc72":"3",b91564ff:"40","935f2afb":"53","009b9a4c":"158",f8409a7e:"206","1df93b7f":"237","1cd16d8e":"265","516d925c":"329","1d6fa843":"335",ef24aaad:"391",d004f1d9:"406","2777a583":"422","66990a94":"481","988781e2":"493","1be78505":"514","94c45520":"537","9596d493":"625",dfbf2a2a:"638","9eb7e184":"656","69e9432f":"682",a64269bf:"783","14eb3368":"817","698c490d":"883","56267c29":"897","1a4e3797":"920",f06d3d6a:"928","950e315b":"952","82fcd85e":"978"}[e]||e,c.p+c.u(e)},(()=>{var e={303:0,532:0};c.f.j=(t,r)=>{var a=c.o(e,t)?e[t]:void 0;if(0!==a)if(a)r.push(a[2]);else if(/^(303|532)$/.test(t))e[t]=0;else{var f=new Promise(((r,f)=>a=e[t]=[r,f]));r.push(a[2]=f);var d=c.p+c.u(t),o=new Error;c.l(d,(r=>{if(c.o(e,t)&&(0!==(a=e[t])&&(e[t]=void 0),a)){var f=r&&("load"===r.type?"missing":r.type),d=r&&r.target&&r.target.src;o.message="Loading chunk "+t+" failed.\n("+f+": "+d+")",o.name="ChunkLoadError",o.type=f,o.request=d,a[1](o)}}),"chunk-"+t,t)}},c.O.j=t=>0===e[t];var t=(t,r)=>{var a,f,d=r[0],o=r[1],n=r[2],i=0;if(d.some((t=>0!==e[t]))){for(a in o)c.o(o,a)&&(c.m[a]=o[a]);if(n)var l=n(c)}for(t&&t(r);i{"use strict";var e,t,r,a,f,d={},o={};function c(e){var t=o[e];if(void 0!==t)return t.exports;var r=o[e]={id:e,loaded:!1,exports:{}};return d[e].call(r.exports,r,r.exports,c),r.loaded=!0,r.exports}c.m=d,c.c=o,e=[],c.O=(t,r,a,f)=>{if(!r){var d=1/0;for(l=0;l=f)&&Object.keys(c.O).every((e=>c.O[e](r[n])))?r.splice(n--,1):(o=!1,f0&&e[l-1][2]>f;l--)e[l]=e[l-1];e[l]=[r,a,f]},c.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return c.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var f=Object.create(null);c.r(f);var d={};t=t||[null,r({}),r([]),r(r)];for(var o=2&a&&e;"object"==typeof o&&!~t.indexOf(o);o=r(o))Object.getOwnPropertyNames(o).forEach((t=>d[t]=()=>e[t]));return d.default=()=>e,c.d(f,d),f},c.d=(e,t)=>{for(var r in t)c.o(t,r)&&!c.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((t,r)=>(c.f[r](e,t),t)),[])),c.u=e=>"assets/js/"+({3:"4022cc72",40:"b91564ff",53:"935f2afb",158:"009b9a4c",206:"f8409a7e",237:"1df93b7f",265:"1cd16d8e",329:"516d925c",335:"1d6fa843",391:"ef24aaad",406:"d004f1d9",422:"2777a583",481:"66990a94",493:"988781e2",514:"1be78505",537:"94c45520",625:"9596d493",638:"dfbf2a2a",656:"9eb7e184",682:"69e9432f",783:"a64269bf",817:"14eb3368",883:"698c490d",897:"56267c29",918:"17896441",920:"1a4e3797",928:"f06d3d6a",952:"950e315b",978:"82fcd85e"}[e]||e)+"."+{3:"99613e40",40:"c7c9f840",41:"9f26e2d0",53:"a161b6e0",127:"9f63bfa6",158:"b36af2df",206:"06d6335e",237:"16932c0f",265:"acb34b33",329:"361a4e3d",335:"49495094",374:"99e70a06",391:"7c5dbd2e",406:"4f03ff40",422:"88f15133",481:"501af493",493:"2b6102fe",514:"33724dfa",537:"fc75be7d",604:"159b9e3e",625:"de41af1c",638:"bae044a8",656:"0a322e23",670:"63f7bee2",682:"537517fc",783:"1faa1b62",817:"6686f448",883:"19c112e0",889:"2bad9243",893:"216a4509",897:"6a6cce32",918:"d20e4110",920:"c0dbb825",928:"41c146e9",952:"5636b099",978:"7d47a6fd"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},f="drag-select-docs:",c.l=(e,t,r,d)=>{if(a[e])a[e].push(t);else{var o,n;if(void 0!==r)for(var i=document.getElementsByTagName("script"),l=0;l{o.onerror=o.onload=null,clearTimeout(s);var f=a[e];if(delete a[e],o.parentNode&&o.parentNode.removeChild(o),f&&f.forEach((e=>e(r))),t)return t(r)},s=setTimeout(b.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=b.bind(null,o.onerror),o.onload=b.bind(null,o.onload),n&&document.head.appendChild(o)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/",c.gca=function(e){return e={17896441:"918","4022cc72":"3",b91564ff:"40","935f2afb":"53","009b9a4c":"158",f8409a7e:"206","1df93b7f":"237","1cd16d8e":"265","516d925c":"329","1d6fa843":"335",ef24aaad:"391",d004f1d9:"406","2777a583":"422","66990a94":"481","988781e2":"493","1be78505":"514","94c45520":"537","9596d493":"625",dfbf2a2a:"638","9eb7e184":"656","69e9432f":"682",a64269bf:"783","14eb3368":"817","698c490d":"883","56267c29":"897","1a4e3797":"920",f06d3d6a:"928","950e315b":"952","82fcd85e":"978"}[e]||e,c.p+c.u(e)},(()=>{var e={303:0,532:0};c.f.j=(t,r)=>{var a=c.o(e,t)?e[t]:void 0;if(0!==a)if(a)r.push(a[2]);else if(/^(303|532)$/.test(t))e[t]=0;else{var f=new Promise(((r,f)=>a=e[t]=[r,f]));r.push(a[2]=f);var d=c.p+c.u(t),o=new Error;c.l(d,(r=>{if(c.o(e,t)&&(0!==(a=e[t])&&(e[t]=void 0),a)){var f=r&&("load"===r.type?"missing":r.type),d=r&&r.target&&r.target.src;o.message="Loading chunk "+t+" failed.\n("+f+": "+d+")",o.name="ChunkLoadError",o.type=f,o.request=d,a[1](o)}}),"chunk-"+t,t)}},c.O.j=t=>0===e[t];var t=(t,r)=>{var a,f,d=r[0],o=r[1],n=r[2],i=0;if(d.some((t=>0!==e[t]))){for(a in o)c.o(o,a)&&(c.m[a]=o[a]);if(n)var l=n(c)}for(t&&t(r);i - + @@ -18,7 +18,7 @@ note: you can change every class name via settings, see Settings section.

Selection

nametrigger
ds-selectedOn items that are selected
ds-hoverOn items that are currently hovered
ds-selectorOn the selector element
ds-selector-areaThe overlay where the selector resides in
ds-selectableOn items that can be selected

Drop

nametrigger
ds-droppableOn item that can be dropped into at least one zone
ds-droppable-${id}On item that can be dropped into a zone with specific identifier, ${id} will be replaced by the corresponding zone.id
ds-dropped-targetOn an item corresponding the target dropzone
ds-dropped-target-${id}On an item corresponding the target dropzone with specific identifier, ${id} will be replaced by the corresponding zone.id
ds-dropped-insideOn an item that is within its dropzone bounds after a drop
ds-dropped-inside-${id}On an item that is within its dropzone bounds after a drop with specific identifier, ${id} will be replaced by the corresponding zone.id

DropZone

nametrigger
ds-dropzoneOn each dropZone
ds-dropzone-readyOn corresponding dropZone when corresponding item is being dragged
ds-dropzone-targetOn dropZone when it was target of a successful drop
ds-dropzone-insideOn dropZone that has elements inside after any drop
- + \ No newline at end of file diff --git a/docs/API/Events.html b/docs/API/Events.html index d53dedc..20c6aa2 100644 --- a/docs/API/Events.html +++ b/docs/API/Events.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Events (Pub/sub)

DragSelect follows a PubSub pattern. It will emit useful events you can subscribe to like this:

const ds = new DragSelect({});
ds.subscribe('<event_name>', (callback_object) => {})

Public Events

event_namecallback_objectdescription
DS:end{ items, event, isDragging, isDraggingKeyboard, dropTarget, … }Fired after the selection (i.e. on mouse-up).
DS:start{ items, event, isDragging, isDraggingKeyboard, … }Fired when the selection starts (i.e. on mouse-down).
DS:update{ items, event, isDragging, isDraggingKeyboard, … }Fired when the mouse moves while dragging (i.e. on mouse-move).
DS:scroll{ items, isDragging, scroll_directions, scroll_multiplier, … }Fired when the area is auto-scrolled (i.e. cursor on a corner of the area).
DS:select{ items, item, isDragging, …}Fired when an element is added to the selection.
DS:unselect{ items, item, isDragging, … }Fired when an element is removed from the selection.
DS:added{ items, item, isDragging, … }Fired when an element is added from the list of selectable elements.
DS:removed{ items, item, isDragging, … }Fired when an element is removed from the list of selectable elements.

Note: all your callbacks subscribers will run after the internal code ran. If you want to run something before everything else, use the :pre postfix. I.e. DS:start:pre is an event that runs before any internal start logic.

Note: there are way more so called "internal events" but hooking to those is not recommended since they might change in future and break your implementation.

Callback Object

The callback object is made up of different parts depending of the event. All properties are not guaranteed so it is important to check for their availability before using them. I.e. like this:

const ds = new DragSelect({});
ds.subscribe('DS:end', (callback_object) => {
if(callback_object.items) {
// do something with the items
}
})
callback_object_keystypedescription
eventMouseEvent | TouchEvent | KeyboardEvent | anyThe native browser event, the type is depending on the situational context
items[ HTMLElement | SVGElement | any ]Current selected elements
itemHTMLElement | SVGElement | anyThe single element currently being interacted with if any
isDraggingbooleanIf true, the user is dragging the selected elements, if false the user is selecting
isDraggingKeyboardbooleanIf true, the user is dragging the selected elements with the keyboard
scroll_directions[ 'top' | 'bottom' | 'left' | 'right' | undefined ]The direction in which the event is happening (i.e. scroll direction)
scroll_multipliernumberThe scrolling speed
dropTarget{
  id: string,
  element: HTMLElement | SVGElement | any,
  droppables: [ HTMLElement | SVGElement | any ],
  itemsDropped: [ HTMLElement | SVGElement | any ],
  itemsInside: [ HTMLElement | SVGElement | * ]
}
dropZone in which the droppable elements were dropped into. id: is the identifier string of the zone. droppables: the elements that are assigned to this zone. itemsDropped: all items that were dropped on the target. itemsInside: all items that are within the bounds of the zone
keystringPressed key (lowercase)
settingsSettingsThe settings being updates/manipulated/passed, also holds the previous value. i.e. updating selectorClass will publish { settings: { selectorClass: 'newVal', 'selectorClass:pre': 'oldVal' } }

Note: all object keys are optional and might not be available, depending on the event type. So make sure to check for availability first

- + \ No newline at end of file diff --git a/docs/API/Methods.html b/docs/API/Methods.html index 541a58a..3dd4a15 100644 --- a/docs/API/Methods.html +++ b/docs/API/Methods.html @@ -9,7 +9,7 @@ - + @@ -18,7 +18,7 @@ When the function is saved into a variable const ds = new DragSelect() you have access to all its inner functions. You can simply use them like this:

const ds = new DragSelect({});
ds.methodName(method_props);

Methods

Functionality

methodpropertiesusage
stop/Will teardown/stop the whole functionality
start/Reset the functionality after a stop/teardown
break/Utility to override DragSelect internal functionality. Breaks out of current flow. Read Custom Drag and Drop for more info.

Pub/Sub

methodpropertiesusage
subscribe(event_name, callback:(callback_object) => void):numberSubscribes to an event, see the Events API for infos on the names and callback_object.
unsubscribe(event_name, callback, id)Unsubscribes from an event, either pass the exact same callback method as when subscribing or the ID which is returned from the subscribe method
publish(event_name, callback_object:any)Publishes an event, see the Events API for infos on the names and callback_object.

Read the Events API for more information

Settings

methodpropertiesusage
setSettingsSettingsUpdate any setting dynamically, see Updating Settings

Interaction

methodpropertiesusage
isDragging/Whether the user is currently drag n dropping elements (instead of selection)
isMultiSelectevent:KeyboardEventMouseEvent

Selection

methodpropertiesusage
getSelection/Returns all currently selected nodes
addSelectionelements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, dontAddToSelectables:booleanadds one or multiple elements to the selection. If boolean is set to true: callback will be called afterwards. Adds them to the selectables if they're not yet in the set (can be turned off by setting the last boolean to true)
removeSelectionelements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, removeFromSelectables:booleanremoves one or multiple elements to the selection. If boolean is set to true: callback will be called afterwards. If last boolean is set to true, it also removes them from the possible selectable nodes if they were.
toggleSelectionelements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, removeFromSelectables:booleantoggles one or multiple elements to the selection. If element is not in selection it will be added, if it is already selected, it will be removed. If triggerCallback is set to true: callback will be called afterward. If removeFromSelectables is set to true: will NOT add elements to the list of selectable elements but will remove elements from the selectables if they are toggled off. (By default the toggling will add elements to the list of selectables and will not remove them).
setSelectionelements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, dontAddToSelectables:booleansets the selection to one or multiple elements. If boolean is set to true: callback will be called afterwards. Adds them to the selectables if they're not yet in the set (can be turned off by setting the last boolean to true)
clearSelectionelements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:booleanRemoves all elements from the selection. If callback is set to true: callback will be called afterwards.
clearSelectiontriggerCallback:booleanUnselect / Deselect all current selected Nodes

Selectables

methodpropertiesusage
addSelectableselements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, addToSelection:booleanAdds elements that can be selected. Don’t worry, nodes are never added twice. addToSelection: elements will also be added to current selection.
removeSelectableselements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, removeFromSelection:booleanRemove elements from the set of elements that can be selected. removeFromSelection: elements will also be removed from current selection.
getSelectables/Returns array with all nodes that can be selected.

Pointer

methodpropertiesusage
getInitialCursorPosition/Returns the registered x, y coordinates the cursor had when first clicked
getCurrentCursorPosition/Returns current x, y coordinates of the cursor
getPreviousCursorPosition/Returns last registered x, y coordinates of the cursor (after last end callback)
getInitialCursorPositionArea/Returns the registered x, y coordinates relative to the area the cursor had when first clicked
getCurrentCursorPositionArea/Returns current x, y coordinates of the cursor relative to the area
getPreviousCursorPositionArea/Returns last registered x, y coordinates of the cursor relative to the area (after last end callback)

DropZones

methodpropertiesusage
getZoneByCoordinatescoordinates:{ x:number, y:number } (Optional)Returns the first drop target under the current mouse position, or, if provided at the coordinates.
getItemsDroppedByZoneIdzoneId:stringReturns the items dropped into a specific zone (by zone.id)
getItemsInsideByZoneIdzoneId:string, addClasses:booleanReturns the items that are visually inside a specific zone (by zone.id). addClasses: also add the respective CSS classes to those elements if they don’t have them yet.

Example

const ds = new DragSelect({});
ds.setSettings({ selectables: document.querySelectorAll('.selectable') });
ds.getSelection();
- + \ No newline at end of file diff --git a/docs/API/Overrides.html b/docs/API/Overrides.html index a380269..69c396f 100644 --- a/docs/API/Overrides.html +++ b/docs/API/Overrides.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Overrides & Exposed Methods (Advanced)

Disclaimer: By hooking into the selection you’re modifying internal behavior. Don’t expect support for any misbehaving caused by hooking in. We will try our best to not introduce breaking changes the overrideable methods but if you use them, it’s best if you double check each time before updating the library even on minor changes.

DragSelect exposes some internal methods that are available to override. It is not recommended to use them unless Methods or Events are not possible for your use-case and you know what you are doing.

For a concrete example on how to use the overrides see CustomSelectionFilter.

.Selection

methodpropertiesreturnsusage
filterSelected{
select: Map<DSElement, DSBoundingRect>,
unselect: Map<DSElement, DSBoundingRect>,
selectorRect: DSBoundingRect
}
{
select: Map<DSElement, DSBoundingRect>,
unselect: Map<DSElement, DSBoundingRect>
}
Can be overridden to apply further filtering logic after the items to select are identified but before they actually get selected. Is expected to return the select / unselect maps in the same shape as passed in

Example

const ds = new DragSelect({});
ds.Selection.filterSelected = (obj) => obj;

.Drag

methodpropertiesreturnsusage
filterDragElements{
elements: DSElement[],
direction: { x: number, y: number },
}
{
elements: DSElement[],
direction: { x: number, y: number },
}
Can be overridden to apply further filtering logic after the items to move are identified but before they actually get moved. Is expected to return the elements in the same shape as passed in.

Example

const ds = new DragSelect({});
ds.Drag.filterDragElements = (obj) => obj;

Exposed Helper Methods

methodpropertiesusage
isCollisionel1: { left:number, right:number, top:number, bottom:number }, el2: { left:number, right:number, top:number, bottom:number }, percent:numberAxis-Aligned Bounding Box Collision Detection. (Docs)

Example

DragSelect.isCollision(
document.querySelector("#foo").getBoundingClientRect(),
document.querySelector("#bar").getBoundingClientRect(),
1
);

Example

const ds = new DragSelect({});
ds.Selection.filterSelected = (obj) => {
// do something here
console.log("filterSelected", obj);
// you can also use helper methods:
if (
DragSelect.isCollision(
document.querySelector("#foo").getBoundingClientRect(),
obj.selectorRect,
1
)
) {
console.log("#foo is inside the selector");
}
// return what needs to be returned
return obj;
};

Something is missing?

Feel free to open a feature request for more overrides.

- + \ No newline at end of file diff --git a/docs/API/Settings.html b/docs/API/Settings.html index 6a3a4f7..0363b81 100644 --- a/docs/API/Settings.html +++ b/docs/API/Settings.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Settings

aka Constructor Properties aka Properties aka options.

const ds = new DragSelect({
selectables: document.querySelectorAll('.selectable'),
});

DragSelect is hyper customizable: all properties are optional, you can totally just pass an empty object and set the settings later. See updating-settings

Selecting

propertytypedefaultdescription
selectables[HTMLElement | SVGElement] | HTMLElement | SVGElement[]The elements that can be selected
areaHTMLElement | SVGElement | DocumentdocumentThe square in which you are able to select the elements
selectorHTMLElementIs Auto-CreatedThe square that will be used to draw the selection.
selectionThresholdnumber0How much % of the element has to be selected to be considered selected (0 = just touching, 1 = fully inside the selection)
multiSelectModebooleanfalseAdd newly selected elements to the selection instead of replacing them
multiSelectTogglingbooleantrueWhether or not to toggle already active elements while multi-selecting (default mimics MacOS behavior)
multiSelectKeys['Shift'|'Control'|'Meta'|string]['Control', 'Shift', 'Meta']Keys for multi-selection. Any key value is possible (see MDN docs). The best support is given for Control, Shift and Meta. Provide an empty array [] if you want to turn off the functionality.

AutoScroll

propertytypedefaultdescription
autoScrollSpeednumber5The speed in which the area scrolls while selecting (if available). The unit is arbitrary (aims for 30fps). Set to 0.0001 to disable auto-scrolling
overflowTolerance{ x:number, y:number }{ x: 25, y: 25 }Tolerance for autoScroll (how close one has to be near an edges for autoScroll to start)

Dragging

propertytypedefaultdescription
draggabilitybooleantrueWhen a user is dragging on an already selected element, the selection is dragged.
useTransformbooleantrueWhether to use the more performant hardware accelerated css transforms when dragging instead of the top/left positions.
immediateDragbooleantrueWhether a selectable element is draggable before being selected or needs to be selected first
keyboardDragbooleantrueWhether or not the user can drag with the keyboard (Accessibility).
dragKeys{ up:string[], down:string[], left:string[], right:string[] }{ up:['ArrowUp'], down: ['ArrowDown'], left: ['ArrowLeft'], right: ['ArrowRight'] }The keys available to drag element using the keyboard. Any key value is possible (see MDN docs).
keyboardDragSpeednumber10The speed at which elements are dragged using the keyboard. In pixels per keyDown.

Dropping

propertytypedefaultdescription
dropZones[{ id:string, element:HTMLElement, droppables?: [HTMLElement | SVGElement] | HTMLElement | SVGElement }][]Zones with association of droppable items that can be dropped into them. id: any unique identifying string. element: is the dropzone itself. droppables: the elements that can be dropped into that zone. This is optional, by default it is all selectables
dropInsideThresholdnumber1How much % of the item has to be inside the dropzone to be considered inside (0 = barely touching, 1 = completely inside)
dropTargetThresholdnumber0How much % of the zone does the pointer has to be in to be considered a target (0 = anywhere in the zone, max: 0.5 = has to point at the center of the zone)

Styling

propertytypedefaultdescription
customStylesbooleanfalseIf true, no styles will be automatically applied to the selector element (except position: absolute)
selectedClassstringds-selectedThe class name assigned to the selected items.
hoverClassstringds-hoverThe class name assigned to the mouse hovered items.
selectorClassstringds-selectorThe class name assigned to the square selector helper.
selectableClassstringds-selectableThe class name assigned to the elements that can be selected.
selectorAreaClassstringds-selector-areaThe class assigned to the square in which the selector resides. By default it's invisible
droppedTargetClassstringds-dropped-target & ds-dropped-target-${zone.id}On an item corresponding the target dropzone. This is also the prefix for ds-dropped-target-${zone.id}.
droppedInsideClassstringds-dropped-inside & ds-dropped-inside-${zone.id}On an item that is within its dropzone bounds after a drop. This is also the prefix for ds-dropped-inside-${zone.id}
droppableClassstringds-droppable & ds-droppable-${zone.id}On element that can be dropped into at least one container. This is also the prefix for ds-droppable-${zone.id}
dropZoneClassstringds-dropzoneOn each dropZone
dropZoneReadyClassstringds-dropzone-readyOn corresponding dropZone when element is dragged
dropZoneTargetClassstringds-dropzone-targetOn dropZone that has elements from any successful target drop
dropZoneInsideClassstringds-dropzone-insideOn dropZone that has elements inside after any drop

Miscellaneous

propertytypedefaultdescription
refreshMemoryRatenumber (milliseconds)80Refresh rate on memoization, higher numbers mean better performance but more lag if elements are moving while interacting/selecting, lower numbers mean less lag but worse performance. If none of your DOMNodes are moving, you can set it to a very high number to increase performance
usePointerEventsbooleanfalseWhether to use Pointer Events to replace traditional Mouse or Touch Events. Useful for tools like Google Blockly.
zoomnumber1Zoom scale factor (in case of using CSS style transform: scale() which messes with real positions). Unit scale zoom. (deprecated)

DragSelect Example with all Props

Here is an example using all available settings for your convenience:

new DragSelect({
selectables: document.querySelectorAll('.selectable'),
area: document.querySelector('#area'),
selector: document.querySelector('#selector'),
selectionThreshold: 0,
multiSelectMode: false,
multiSelectToggling: true,
multiSelectKeys: ['Control', 'Shift', 'Meta'],
autoScrollSpeed: 5,
overflowTolerance: { x: 25, y: 25 },
draggability: true,
useTransform: true,
immediateDrag: true,
keyboardDrag: true,
dragKeys: { up:['ArrowUp'], down: ['ArrowDown'], left: ['ArrowLeft'], right: ['ArrowRight'] },
keyboardDragSpeed: 10,
dropZones: [{ id: 'foo', element: document.querySelector('#zone') }],
dropInsideThreshold: 1,
dropTargetThreshold: 0,
customStyles: false,
selectedClass: 'ds-selected',
hoverClass: 'ds-hover',
selectorClass: 'ds-selector',
selectableClass: 'ds-selectable',
selectorAreaClass: 'ds-selector-area',
droppedTargetClass: 'ds-dropped-target',
droppedInsideClass: 'ds-dropped-inside',
droppableClass: 'ds-droppable',
dropZoneClass: 'ds-dropzone',
dropZoneReadyClass: 'ds-dropzone-ready',
dropZoneTargetClass: 'ds-dropzone-target',
dropZoneInsideClass: 'ds-dropzone-inside',
refreshMemoryRate: 80,
usePointerEvents: false,
zoom: 1,
});
- + \ No newline at end of file diff --git a/docs/category/api.html b/docs/category/api.html index 4d23247..15fdb06 100644 --- a/docs/category/api.html +++ b/docs/category/api.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@ - + \ No newline at end of file diff --git a/docs/category/guided-examples.html b/docs/category/guided-examples.html index 30ba2b5..fd82320 100644 --- a/docs/category/guided-examples.html +++ b/docs/category/guided-examples.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Guided Examples

Hand-holding you through some code examples using DragSelect.

- + \ No newline at end of file diff --git a/docs/guided-examples/Accessibility.html b/docs/guided-examples/Accessibility.html index 8dd973b..6904ef1 100644 --- a/docs/guided-examples/Accessibility.html +++ b/docs/guided-examples/Accessibility.html @@ -9,7 +9,7 @@ - + @@ -19,7 +19,7 @@ => ArrowKeys are used for keyboard dragging.

Obviously, keyboard users won’t get the full visual experience but it works similarly to the OS default behavior.

  1. Selection: You can select items using the default select keys (usually space or enter) and also multi-select when using a modifier key at the same time. There is one little thing you have to do tho’: the selectables have to be pressable (clickable)! To achieve this, they should be of type <button type="button"></button>.

  2. Drag: You can drag elements using the keyboard arrow keys, this will also scroll the area by default. You can press Shift in combination with an arrow i.e. Shift+ArrowRight to move the element 4x faster and also not scroll the area.

Try it out with your keyboard:

- + \ No newline at end of file diff --git a/docs/guided-examples/Area.html b/docs/guided-examples/Area.html index e797127..c5560e5 100644 --- a/docs/guided-examples/Area.html +++ b/docs/guided-examples/Area.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

With an Area

  • You can restrict DragSelect to only operate within a certain area
  • This Area will also be auto-scrollable by default

For example:

new DragSelect({
selectables: document.getElementsByClassName('selectable'),
area: document.getElementById('area'),
});

^ given this example you can only use the selection/drag inside of the container with the ID area.

Example

Try it out yourself:

- + \ No newline at end of file diff --git a/docs/guided-examples/Custom-Selection-Filter-Override.html b/docs/guided-examples/Custom-Selection-Filter-Override.html index 41fb311..1fa443f 100644 --- a/docs/guided-examples/Custom-Selection-Filter-Override.html +++ b/docs/guided-examples/Custom-Selection-Filter-Override.html @@ -9,7 +9,7 @@ - + @@ -22,7 +22,7 @@ we can use it:

// initialize like you do before
const ds = new DragSelect({})

// then you can override the exposed internal method
ds.Selection.filterSelected = ({ selectorRect, select: _select, unselect: _unselect }: {
select:Map<DSElement,DSBoundingRect>,
unselect:Map<DSElement,DSBoundingRect>,
selectorRect:DSBoundingRect
}) => {
// here we just re-assign the maps to new variables so we can modify them without changing the original ones
const select = new Map(_select), unselect = new Map(_unselect)
// now we can do whatever, in this example we just filter out all elements that have a red color style if there is more than five selected elements in total
select.forEach((boundingRect, element) => {
if(element.style.color === 'red' && select.size > 5) {
select.delete(element)
unselect.set(element, boundingRect)
}
})
// we return the modified maps
return { select, unselect }
}

That’s it, you’ve successfully overwritten a method to add your custom filter to the selection logic. Now go celebrate that you’ve just learned something new! 🎉

- + \ No newline at end of file diff --git a/docs/guided-examples/CustomDnD.html b/docs/guided-examples/CustomDnD.html index 018398b..dc74a82 100644 --- a/docs/guided-examples/CustomDnD.html +++ b/docs/guided-examples/CustomDnD.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Custom Drag and Drop

Note: this functionality is still a work in progress. If you find what you want to do is not working, please give your use-case and feedback in the Discussions section and we’ll try to support it.

DragSelect comes with a build-in Drag and Drop functionality. However, the ideal is to be as extensible as possible. So the usage of other libraries in combination with DragSelect is definitively welcome! There is multiple ways to achieve this:

Using .stop()

// 1. Setup DragSelect:
const ds = new DragSelect({
// if your library can not handle keyboard dragging
keyboardDragSpeed: 0,
keyboardDrag: false,
// …your other settings…
})

// 2. Setup the other library. Here we call it MyCustomDrag
const myCustomDrag = new MyCustomDrag({/* …your settings… */})

// 3. Stop DragSelect dragging
ds.subscribe('DS:start:pre', ({ items, isDragging, isDraggingKeyboard }) => {
if(isDragging) {
ds.stop(false, false)
// if anything is necessary in MyCustomDrag, here is the place
myCustomDrag.start(items)
}
})

// 4. ReStart DragSelect when the other library is done dragging
myCustomDrag.subscribe('finished', () => ds.start())

If your library has no callback you could try to disable, then re-enable directly:

ds.subscribe('DS:start:pre', ({ isDragging, isDraggingKeyboard }) => {
if(isDragging) {
ds.stop(false, false)
setTimeout(ds.start)
}
})

Note: it is important to debounce (i.e. with setTimeout(ds.start)) the start function if it's called within a single subscriber so that all the scheduled callbacks finish triggering before we start again.

Using .break()

/!\ only use break when you know what you're doing

In case you want to build something completely custom on top of DragSelect, we got you covered! You can use .break for this.

This utility to override DragSelects internal functionality allowing you to write it all yourself: You can write your own drag and drop, if you want, you can even write your own selection:

ds.subscribe('DS:update:pre', ({ isDragging, isDraggingKeyboard }) => {
if(isDragging || isDraggingKeyboard) {
ds.break()
/* your custom logic for drag handling here. */
} else {
ds.break()
/* your custom logic for selection handling here. */
}
}
- + \ No newline at end of file diff --git a/docs/guided-examples/DropZones.html b/docs/guided-examples/DropZones.html index 75c7de4..0aecd5a 100644 --- a/docs/guided-examples/DropZones.html +++ b/docs/guided-examples/DropZones.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

With DropZones

DropZones are areas where you can drop the selected elements into.

  • Set it up via Settings.
  • When dropped you’ll find a dropTarget in the DS:end event callback.
  • You can also use some useful methods related to DropZones.
  • Using DropZones will also automatically add respective classes.

Here is an example:

The Setup

Setting up is easy, here is an example:

const ds = new DragSelect({

// 1. Add DropZones settings
dropZones: [
// 2. By default all selectables can be dropped into a zone
{ element: document.querySelector('#zone-1'), id: 'zone-1' },
// 3. However, if you want to restrict that, add the `droppables` key to the zone
{ element: document.querySelector('#zone-2'), id: 'zone-2', droppables: document.querySelectorAll('#item-2,#item-4') }, // here, only items 2 & 4 are droppable into zone 2
],
// 4. There are also other customization you can do, for example:
dropInsideThreshold: 1, // 1 = has to be 100% inside the dropzone, 0.5 = 50% inside, 0 = just touching is fine
});

Find all possible keys in the DropZone Settings section.

The DS:end callback

Now you will see the dropTarget in the DS:end callback, which represents the topmost Zone that was targeted by the mouse on drag release. Here is an example on how you could use it:

ds.subscribe('DS:end', ({
// 4. If successfully drop by mouse, you’ll find a dropTarget key
dropTarget: {
// 5. It is an object with following keys
id: "zone-1", // The ID of the zone
element: <node />, // The DropZone element itself
droppables: [ <node />,], // The elements that can potentially be dropped into that zone
itemsDropped: [ <node />,], // elements that were selected when the mouse targeted the zone on drop
itemsInside: [ <node />,] // elements that are actually inside the bounds of the dropzone
}) => {

// 6. We can check which items are dropped into the zone and do something
if(dropTarget?.itemsDropped?.length) {
console.log('Dropped', dropTarget.itemsDropped, 'into', dropTarget.id);
}
})

Check out the callback object API for more information.

The methods

You can also anytime use the DropZone specific methods to get what you need. For example:

console.log('items dropped into zone-1', ds.getItemsDroppedByZoneId('zone-1'))
console.log('items inside zone-2', ds.getItemsInsideByZoneId('zone-1'))

Check out the DropZone specific methods for more information.

Example

Try it out yourself:

- + \ No newline at end of file diff --git a/docs/guided-examples/Mobile-Touch.html b/docs/guided-examples/Mobile-Touch.html index 91dfd55..7eabece 100644 --- a/docs/guided-examples/Mobile-Touch.html +++ b/docs/guided-examples/Mobile-Touch.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Mobile/Touch usage

Congratulations, DragSelect can be used on a mobile by default 🎉

Keep in mind that using DragSelect on a mobile/touch device will also turn off the default scroll behavior (on click + drag interaction).

In 99% of the use-cases, this is what you want.

However, if DragSelect is only one part of a website, and you still want to be able to scroll the page on mobile, you can use an area see settings. This way the default scroll behavior remains intact for the rest of the page.

For example like this:

const ds = new DragSelect({
selectables: document.querySelectorAll('.selectable'),
area: document.querySelector('#area'),
});
- + \ No newline at end of file diff --git a/docs/guided-examples/Publish-Subscribe.html b/docs/guided-examples/Publish-Subscribe.html index fef8e8f..f72b163 100644 --- a/docs/guided-examples/Publish-Subscribe.html +++ b/docs/guided-examples/Publish-Subscribe.html @@ -9,7 +9,7 @@ - + @@ -19,7 +19,7 @@ If you are familiar with .addEventListener in the browser, this is the same concept.

Here is an Example on how you would use it:

const ds = new DragSelect({})
// Subscribe to an event
const subscriptionId = ds.subscribe('DS:end', (callback_object) => { /* do something */ })
// If you stored the ID of that handler you can just unsubscribe by passing the ID
ds.unsubscribe('DS:end', null, subscriptionId)
// If you want to publish some event yourself, you can totally do that aswell
ds.publish('DS:end', { foo: 'bar' })

Let’s say you can’t store the subsciptionId, then you can also pass in the handler like so:

const ds = new DragSelect({})
const callbackHandler = (callback_object) => { /* do something */ }
ds.subscribe('DS:end', callbackHandler) // starts listening to the events
ds.unsubscribe('DS:end', callbackHandler) // stops listening to the events

So to unsubscribe you have to either pass in the exact same method or the ID that the subscriber returns. Protip: passing the ID is more performant!

You can find a list of all public event_names as well as all potential callback_object properties in the Events documentation

- + \ No newline at end of file diff --git a/docs/guided-examples/React.html b/docs/guided-examples/React.html index 60cb731..e993639 100644 --- a/docs/guided-examples/React.html +++ b/docs/guided-examples/React.html @@ -9,7 +9,7 @@ - + @@ -18,7 +18,7 @@ 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

- + \ No newline at end of file diff --git a/docs/guided-examples/Simple.html b/docs/guided-examples/Simple.html index d47fa08..6d010a0 100644 --- a/docs/guided-examples/Simple.html +++ b/docs/guided-examples/Simple.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Simple

The simplest possible use-case. Is to choose which elements can be selected:

new DragSelect({
selectables: document.getElementsByClassName('selectable-nodes')
});

That’s it. Check it out:

- + \ No newline at end of file diff --git a/docs/guided-examples/Updating-Settings.html b/docs/guided-examples/Updating-Settings.html index 312dbca..dc814fe 100644 --- a/docs/guided-examples/Updating-Settings.html +++ b/docs/guided-examples/Updating-Settings.html @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@

Updating Settings

DragSelect is hyper customizable: all properties are optional, you can totally just pass an empty object and set the settings later.

setSettings

Any setting can be updated/added after the initialization by using the setSettings method. Here is an example updating the area and the selectables:

const ds = new DragSelect({})
// And set any settings at any point in time
ds.setSettings({
selectables: document.getElementsByClassName('selectable-nodes'),
area: document.getElementById('area')
})

See the Settings page for a list of all possible options.

- + \ No newline at end of file diff --git a/docs/info.html b/docs/info.html index 1963b75..0c71ad9 100644 --- a/docs/info.html +++ b/docs/info.html @@ -9,7 +9,7 @@ - + @@ -17,10 +17,10 @@

DragSelect

The DragSelect logo: a selection symbol, a hand, a drop symbol and a mouse within a selection square.
Build Status gzip size npm downloads count No Dependency Contributors Welcome Sponsors Welcome

Key-Features

  • No dependencies No Dependency
  • Hyper customizable
  • Replicates operating system drag-selection in the browser
  • Accessibility (a11y)
  • Use modifier keys to make multiple independent selections
  • Select, Drag and Drop also also via keyboard
  • Supports all major browsers
  • Lightweight, only gzip size
  • Popular: npm downloads count on npm
  • DragSelect was written with Performance in mind (can easily select >15.000 Elements)
  • Supports SVG
  • Supports mobile (touch interaction)
  • Free & open source
  • Easy to use

demo-gif

Why?

Because apparently there was nothing that does not require jquery out there.
This is better than https://jqueryui.com/selectable/ or https://jqueryui.com/draggable/ and has no dependencies. We use it currently in a professional rich interface application where we have a file management system. The user can select files to organize them and change their metadata, with this plugin our users are able to select multiple files and perform batch/bulk-operations (applying changes to multiple files at once). We also use it in production for another huge, graphical cloud hosting manager with millions of active users. Users can select multiple servers, storages, etc. on an artboard to perform multi-operations, re-organize them, move them on the UI or batch-delete. We’re running it in production since January 18' it’s super helpful and very stable, let’s keep it that way. I can easily think of dozens other use-cases. We’re really keen to know how you use it in your projects, please let us know.

Supporters

Donate Star

Please donate to support the countless hours of hard work & support. Especially if your company makes money, then there is no excuse. -If you're broke, you can still support us with your time instead by contributing to the code!

Thank you :)

Thanks to:

BrowserstackDigitalOceanYou?
LambdaTest is a Next-Generation Mobile App and Cross Browser Testing Cloud. They support this open source projects by providing us with a free account and with a generous donation!BrowserStack is a service for cross-browser testing. They support this open source projects by providing us with a free account!DigitalOcean is a cloud hosting service. They support this open source projects by providing us with free credits!Thank and support us by making a Direct Donation to DragSelect (via Bitcoin: 1LdweSpjgSeJC8XxX3swrohBMBLUzg6cmC). Or sponsor via GitHub Sponsors or Get in touch.

Donations are distributed with all project contributors proportionally to their involvement. We are grateful for any amount: we have more than npm downloads count, imagine how much we'd have if everyone would have had donated only 1$ 🤩 (unfortunately this did not happen). If you donate, we can display your logo here if you want, which will give you fame, fortune and help you recruit great talent and boosting your SEO.

Licenses

TL;DR: If your project makes money: Purchase a commercial license.

DragSelect is, and will forever be, a free and open-source tool. Free for any non-commercial project. However, this is a lot of work and hard work should be rewarded, so if you are using DragSelect for business and/or commercial sites, projects, and applications you’ll have to get the commercial license to keep your source proprietary and the project alive.