{"id":13459134,"url":"https://github.com/aurbano/react-ds","last_synced_at":"2025-04-05T13:02:36.742Z","repository":{"id":22670744,"uuid":"96993283","full_name":"aurbano/react-ds","owner":"aurbano","description":":fire: React Drag To Select component (tiny, touch friendly, and no dependencies!)","archived":false,"fork":false,"pushed_at":"2024-04-22T23:29:35.000Z","size":2300,"stargazers_count":165,"open_issues_count":10,"forks_count":17,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-30T15:44:43.347Z","etag":null,"topics":["drag","react","react-component","reactjs","select","touch-compatible"],"latest_commit_sha":null,"homepage":"https://aurbano.github.io/react-ds/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aurbano.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-12T10:03:51.000Z","updated_at":"2025-03-13T19:37:36.000Z","dependencies_parsed_at":"2024-01-13T17:58:45.983Z","dependency_job_id":"d8238ece-d069-4cde-8f14-e0ff70173d10","html_url":"https://github.com/aurbano/react-ds","commit_stats":{"total_commits":90,"total_committers":7,"mean_commits":"12.857142857142858","dds":0.0888888888888889,"last_synced_commit":"80c92e3d149787f056f44aeeae7406c1f2d60801"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurbano%2Freact-ds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurbano%2Freact-ds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurbano%2Freact-ds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurbano%2Freact-ds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aurbano","download_url":"https://codeload.github.com/aurbano/react-ds/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339148,"owners_count":20923013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["drag","react","react-component","reactjs","select","touch-compatible"],"created_at":"2024-07-31T09:01:05.717Z","updated_at":"2025-04-05T13:02:36.718Z","avatar_url":"https://github.com/aurbano.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# React DS\n\u003e Tiny (7KB) React Drag-to-Select component (with no dependencies! with support for touch devices!\n\n[![Travis](https://img.shields.io/travis/aurbano/react-ds.svg)](https://travis-ci.org/aurbano/react-ds)\n[![npm](https://img.shields.io/npm/v/react-ds.svg)](https://www.npmjs.com/package/react-ds)\n[![Coverage Status](https://coveralls.io/repos/github/aurbano/react-ds/badge.svg?branch=master)](https://coveralls.io/github/aurbano/react-ds?branch=master)\n[![npm](https://img.shields.io/npm/dm/react-ds.svg)](https://www.npmjs.com/package/react-ds)\n[![npm](https://img.shields.io/npm/l/react-ds.svg)](https://www.npmjs.com/package/react-ds)\n[![Codacy grade](https://img.shields.io/codacy/grade/e2589a609bdc4c56bd49c232a65dab4e.svg)](https://www.codacy.com/app/aurbano/react-ds)\n\n[![react-ds gif](https://thumbs.gfycat.com/FatYellowKid-size_restricted.gif)](https://gfycat.com/gifs/detail/fatyellowkid)\n\nI wrote this library because I couldn't find any existing one to do selections without having to wrap the items in their component.\n\nIn some cases you really need an unobtrusive way to make items selectable, this will do just that.\n\n\n## Installation\n\n```console\n$ npm i react-ds\n```\nOr if you prefer yarn\n```console\n$ yarn add react-ds\n```\n\n## Usage\n\n```jsx\nimport Selection from 'react-ds';\n\n// target (ref) is the parent component (so that selects only happen when clicking and dragging on it)\n// elements (refs[]) is an array of refs to the components that are selectable\n\u003cSelection\n    target={ ref }\n    elements={ refs[] }\n    onSelectionChange={ this.handleSelection }\n/\u003e\n```\n\n### Props\n\n#### `target`\n\nElement where the selection should be applied to. This is to scope the mouse/touch event handlers and make sure that it doesn't affect your whole web app.\n\nIt must be a React `ref`, it should also exist, so you may want to check if it's already initialized before rendering the `Selection` component.\n\n#### `elements`\n\nArray of refs to the elements that are selectable. The `Selection` component will use this to get their location and sizes to determine whether they are within the selection area.\n\nThe should exist before rendering the `Selection` component.\n\n#### `onSelectionChange`\n\nFunction that will be executed when the selection changes. An array of element indexes will be passed (with the same indexes as the `elements` prop).\n\nThis is where you want to update your state, to highlight them as selected for example.\n\n#### `onHighlightChange`\n\nWhile dragging, `onHighlightChange` is called only when the highlighted elements have changed.\n\nWhen the mouse is released, it will be called with an empty array.\n\n![onHighlightChange Example](https://user-images.githubusercontent.com/1640952/61724315-0269b280-ad6e-11e9-899c-4466e090cb13.gif)\n\n#### `offset` *(Optional)*\n\nThis is used to calculate the coordinates of the mouse when drawing the Selection box, since the mouse events gives coordinates relative to the document, but the Selection box may have a different parent.\n\nEssentially you need to pass the offset of the parent element where the Selection is being rendered. If it's rendered in the same component as the items to be selected then the default value will work fine.\n\nIf passing your own offset keep in mind that `getBoundingClientRect()` depends on the scroll, so you may want to do something like this:\n\n```js\nconst boundingBox = target.getBoundingClientRect();\nconst offset = {\n  top: boundingBox.top + window.scrollY,\n  left: boundingBox.left + window.scrollX,\n};\n```\n\n#### `style` *(Optional)*\n\nIf you want to override the styles for the selection area, you can either pass any styles here, or use css and declare any styles on the `.react-ds-border` class.\n\nThe styles are merged, so you can override just one property if you need (typically the `zIndex`).\n\nThe default styles are:\n\n```js\nconst style = {\n  position: 'absolute',\n  background: 'rgba(159, 217, 255, 0.3)',\n  border: 'solid 1px rgba(123, 123, 123, 0.61)',\n  zIndex: 9,\n  cursor: 'crosshair',\n}\n```\n\n#### `ignoreTargets` *(Optional)*\n\nSpecify an array of CSS3 selectors for DOM targets that should be ignored when initiating a selection. i.e. `['div', 'div \u003e p', '#someId']`\n\n\u003eThis is specially useful because `react-ds` uses native browser events that bypass React's event queue, so you won't be able to `stopPropagation` as usual.\n\n```jsx\n\u003cSelection\n    target={ this.state.ref}\n    elements={ this.state.elRefs }\n    onSelectionChange={ this.handleSelection }\n    ignoreTargets={ ['.handle'] }\n/\u003e\n```\n\n## Example\n\nThis example was taken from [`example/app/src/Example.js`](https://github.com/aurbano/react-ds/blob/master/example/app/src/Example.js) which you can see running at https://aurbano.eu/react-ds/\n\n```jsx\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport Selection from 'react-ds';\n\nexport default class Example extends React.PureComponent {\n\n  constructor() {\n    super();\n\n    this.state = {\n      ref: null,\n      elRefs: [],\n      selectedElements: [], // track the elements that are selected\n    };\n  }\n\n  handleSelection = (indexes) =\u003e {\n    this.setState({\n      selectedElements: indexes,\n    });\n  };\n\n  getStyle = (index) =\u003e {\n    if (this.state.selectedElements.indexOf(index) \u003e -1) {\n      // Selected state\n      return {\n        background: '#2185d0',\n        borderColor: '#2185d0',\n        color: 'white',\n      };\n    }\n    return {};\n  };\n\n  addElementRef = (ref) =\u003e {\n    const elRefs = this.state.elRefs;\n    elRefs.push(ref);\n    this.setState({\n      elRefs,\n    });\n  };\n\n  renderSelection() {\n    if (!this.state.ref || !this.state.elRefs) {\n      return null;\n    }\n    return (\n      \u003cSelection\n        target={ this.state.ref}\n        elements={ this.state.elRefs }\n        onSelectionChange={ this.handleSelection }\n        style={ this.props.style }\n      /\u003e\n    );\n  }\n\n  render() {\n    const selectableElements = [\n      'one',\n      'another',\n      'hey there',\n      'item',\n      'two',\n      'three',\n      'something longer?',\n      'last'\n    ];\n    return (\n      \u003cdiv ref={ (ref) =\u003e { this.setState({ ref }); } } className='item-container'\u003e\n        { selectableElements.map((el, index) =\u003e (\n          \u003cdiv\n            key={ el }\n            ref={ this.addElementRef }\n            style={ this.getStyle(index) }\n            className='item'\n          \u003e\n            { el }\n          \u003c/div\u003e\n        )) }\n        { this.renderSelection() }\n      \u003c/div\u003e\n    );\n  }\n}\n\nExample.PropTypes = {\n  style: PropTypes.object,\n};\n```\n\n## Contributing\n\nOnly edit the files in the `src` folder. I'll update `dist` manually before publishing new versions to npm.\n\nTo run the tests simply run `npm test`. Add tests as you see fit to the `test` folder, they must be called `{string}.test.js`.\n\n## Meta\n\nCopyright \u0026copy; [Alejandro U. Alvarez](https:/aurbano.eu) 2017. MIT Licensed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faurbano%2Freact-ds","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faurbano%2Freact-ds","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faurbano%2Freact-ds/lists"}