diff --git a/README.md b/README.md index c71a2d6..581f8f9 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ The `` component accepts a few optional props: - `mixedDeselect` (Boolean) When enabled items can be selected and deselected with selectbox at the same time, `enableDeselect` should be set to `true`. - `scrollContainer` (String) Selector of scroll container which will be used to calculate selectbox position. If not specified SelectableGroup element will be used as scroll container. - `ignoreList` (Array) Array of ignored selectors. +- `disableSelectStartList` (Array) Array of selectors where select lasso can not be started by dragging mouse. Useful if you want to enable drag of selectables. - `clickableClassName` (String) On elements with specified selector click item containing this element will be selected. - `tolerance` (Number) The amount of buffer to add around your `` container, in pixels. - `className` (String) Class of selectable group element. diff --git a/src/SelectableGroup.tsx b/src/SelectableGroup.tsx index f72e78c..83d50ad 100644 --- a/src/SelectableGroup.tsx +++ b/src/SelectableGroup.tsx @@ -36,6 +36,7 @@ type TProcessItemOptions = TSelectItemsOptions & { export type TSelectableGroupProps = { globalMouse?: boolean ignoreList?: string[] + disableSelectStartList?: string[] scrollSpeed?: number minimumSpeedFactor?: number allowClickWithoutSelected?: boolean @@ -92,6 +93,7 @@ class SelectableGroup extends Component { tolerance: 0, globalMouse: false, ignoreList: [], + disableSelectStartList: [], scrollSpeed: 0.25, minimumSpeedFactor: 60, duringSelection: noop, @@ -146,6 +148,12 @@ class SelectableGroup extends Component { ignoreListNodes: HTMLElement[] = [] + disableSelectStartCheckCache = new Map() + + disableSelectStartList = this.props.disableSelectStartList! + + disableSelectStartListNodes: HTMLElement[] = [] + selectbox: Maybe = null selectableGroup: Maybe = null @@ -471,10 +479,36 @@ class SelectableGroup extends Component { return shouldBeIgnored } + isInDisableSelectStartList(target: HTMLElement | null) { + if (!target) { + return + } + + if (this.disableSelectStartCheckCache.get(target) !== undefined) { + return this.disableSelectStartCheckCache.get(target) + } + + const shouldBeIgnored = this.disableSelectStartListNodes.some( + disableSelectStartNode => + target === disableSelectStartNode || disableSelectStartNode.contains(target) + ) + + this.disableSelectStartCheckCache.set(target, shouldBeIgnored) + + return shouldBeIgnored + } + updateWhiteListNodes() { this.ignoreListNodes = Array.from(document.querySelectorAll(this.ignoreList.join(', '))) } + updateDisableSelectStartListNodes() { + this.disableSelectStartListNodes = + this.disableSelectStartList.length > 0 + ? Array.from(document.querySelectorAll(this.disableSelectStartList.join(', '))) + : [] + } + mouseDown = (e: Event) => { const isNotLeftButtonClick = !e.type.includes('touch') && @@ -489,6 +523,7 @@ class SelectableGroup extends Component { } this.updateWhiteListNodes() + this.updateDisableSelectStartListNodes() if (this.isInIgnoreList(e.target as HTMLElement)) { this.mouseDownStarted = false @@ -496,6 +531,12 @@ class SelectableGroup extends Component { return } + if (this.isInDisableSelectStartList(e.target as HTMLElement)) { + this.mouseDownStarted = false + + return + } + if (this.props.resetOnStart) { this.clearSelection() } diff --git a/website/index.html b/website/index.html index c46db8e..2ca04e4 100644 --- a/website/index.html +++ b/website/index.html @@ -226,6 +226,10 @@

scroll container.
  • ignoreList (Array) Array of ignored selectors.
  • +
  • + disableSelectStartList (Array) Array of selectors where select lasso can not + be started by dragging mouse. Useful if you want to enable drag of selectables. +
  • clickableClassName (String) On element with specified selector click item cotaining this element will be selected.