Skip to content

Commit 45f3b59

Browse files
feat: add outside click event configuration to ng-select component (ng-select#2715)
* feat: update Angular dependencies to version 20.3.6 * fix: update Angular ESLint and other dependencies to latest versions * fix: update Node engine compatibility in package.json * fix: update Node engine compatibility in package.json * fix: update Node version in CI configuration to 22 * feat: add outside click event configuration to ng-select component - Introduced a new property `outsideClickEvent` to control the DOM event used for detecting outside clicks, defaulting to 'click'. - Updated `NgDropdownPanelComponent` to utilize the new `outsideClickEvent` for improved outside click detection. - Modified the HTML template to bind the `outsideClickEvent` property, enhancing flexibility in dropdown behavior. This change improves the usability of the dropdown by allowing customization of the event used for closing the dropdown on outside interactions. * docs: add documentation for outside click event type configuration in README - Added a new entry for `outsideClickEventType` in the README to document its purpose and default value. - This update enhances the clarity of the dropdown component's configuration options, providing users with better guidance on customizing outside click detection behavior. --------- Co-authored-by: Pavan Kumar Jadda <17564080+pavankjadda@users.noreply.github.com>
1 parent 827fb85 commit 45f3b59

File tree

5 files changed

+16
-3
lines changed

5 files changed

+16
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ map: {
241241
| [selectOnTab] | `boolean` | `false` | no | Select marked dropdown item using tab. Default `false` |
242242
| [tabFocusOnClearButton] | `boolean` | `true` | no | Control tab navigation behavior for the clear button. Default `true` |
243243
| [openOnEnter] | `boolean` | `true` | no | Open dropdown using enter. Default `true` |
244+
| outsideClickEventType | `'click'` \| `'mousedown'` | `'click'` | no | Configure which DOM event type is used for outside click detection. Use `'mousedown'` to fix issues with backdrop/loading overlays that appear on dropdown open |
244245
| [typeahead] | `Subject` | `-` | no | Custom autocomplete or advanced filter. |
245246
| [minTermLength] | `number` | `0` | no | Minimum term length to start a search. Should be used with `typeahead` |
246247
| typeToSearchText | `string` | `Type to search` | no | Set custom text when using Typeahead |

src/ng-select/lib/config.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ export class NgSelectConfig {
1818
clearSearchOnAdd: boolean;
1919
deselectOnClick: boolean;
2020
tabFocusOnClear = true;
21+
/**
22+
* Controls which DOM event is used to detect outside clicks for closing the dropdown.
23+
* Defaults to 'click'. Set to 'mousedown' to handle early outside interactions
24+
* (useful when backdrops load on click and would otherwise close the dropdown).
25+
*/
26+
outsideClickEvent: 'click' | 'mousedown' = 'click';
2127
}

src/ng-select/lib/ng-dropdown-panel.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
7070
readonly footerTemplate = input<TemplateRef<any>>(undefined);
7171
readonly filterValue = input<string>(null);
7272
readonly ariaLabelDropdown = input<string | null>(null);
73+
/**
74+
* Which DOM event to listen to for outside click detection
75+
*/
76+
readonly outsideClickEvent = input<'click' | 'mousedown'>('click');
7377

7478
readonly update = output<any[]>();
7579
readonly scroll = output<{
@@ -229,7 +233,7 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy {
229233
}
230234

231235
this._zone.runOutsideAngular(() => {
232-
fromEvent(this._document, 'click', { capture: true })
236+
fromEvent(this._document, this.outsideClickEvent(), { capture: true })
233237
.pipe(takeUntil(this._destroy$))
234238
.subscribe(($event) => this._checkToClose($event));
235239
});

src/ng-select/lib/ng-select.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
[bufferAmount]="bufferAmount()"
9292
[appendTo]="appendToValue"
9393
[position]="dropdownPosition()"
94+
[outsideClickEvent]="outsideClickEvent()"
9495
[headerTemplate]="headerTemplate()"
9596
[footerTemplate]="footerTemplate()"
9697
[filterValue]="searchTerm"

src/ng-select/lib/ng-select.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import {
44
ChangeDetectionStrategy,
55
ChangeDetectorRef,
66
Component,
7-
effect,
7+
computed,
88
contentChild,
99
contentChildren,
10-
computed,
10+
effect,
1111
ElementRef,
1212
forwardRef,
1313
HostAttributeToken,
@@ -116,6 +116,7 @@ export class NgSelectComponent implements OnDestroy, OnChanges, OnInit, AfterVie
116116
readonly clearAllText = input<string>(undefined);
117117
readonly dropdownPosition = input<DropdownPosition>('auto');
118118
readonly appendTo = input<string>(undefined);
119+
readonly outsideClickEvent = input<'click' | 'mousedown'>(this.config.outsideClickEvent);
119120
readonly loading = input(false, { transform: booleanAttribute });
120121
readonly closeOnSelect = input(true, { transform: booleanAttribute });
121122
readonly hideSelected = input(false, { transform: booleanAttribute });

0 commit comments

Comments
 (0)