Polish Mouse Click Response
This commit is contained in:
1 parent
3f33c0dfa5
commit
3a415a2525
3 files changed
+53
-14
No files matched your search
@@ -3,9 +3,9 @@
|
||||
<span class="material-symbols-outlined icon-24 prefix-icon">{{ icon() }}</span>
|
||||
}
|
||||
|
||||
<div #searchInput class="dropdown-input" [class.hidden]="!isOpen()"
|
||||
<div #searchInput class="dropdown-input" [class.hidden]="!isOpen()" [class.focus-mode]="inputFocusMode()"
|
||||
contenteditable="true" role="textbox" aria-multiline="false" [aria-placeholder]="translation.common.selectOption" tabindex="-1" spellcheck="false"
|
||||
(input)="onSearch($event)"></div>
|
||||
(input)="onSearch($event)" (click)="handleInputClick($event)" [attr.placeholder]="translation.common.selectOption"></div>
|
||||
|
||||
@if (!isOpen()) {
|
||||
<span class="placeholder">{{ selectedLabel() }}</span>
|
||||
|
||||
@@ -67,6 +67,17 @@ $default_animation_duration: 0.2s;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dropdown-input:empty:before {
|
||||
content: attr(placeholder);
|
||||
opacity: 50%;
|
||||
}
|
||||
|
||||
.dropdown-input:not(.focus-mode) {
|
||||
caret-color: transparent;
|
||||
user-select: none;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.dropdown-input.hidden {
|
||||
position: absolute;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ export interface DropdownOption {
|
||||
'[class.open]': 'isOpen()',
|
||||
tabindex: '0',
|
||||
'(click)': 'toggle()',
|
||||
'(mousedown)': 'onMouseDown($event)',
|
||||
'(keydown)': 'onKeyDown($event)',
|
||||
'(keydown.enter)': 'onEnter($event)',
|
||||
'(keydown.space)': 'onSpaceDown($event)',
|
||||
@@ -65,9 +66,10 @@ export class Dropdown implements OnInit {
|
||||
|
||||
private static nextId = 0;
|
||||
dropdownId = `dropdown-${Dropdown.nextId++}`;
|
||||
private wasInside = false;
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
effect(() => this.filteredOptions())
|
||||
effect(() => this.filteredOptions());
|
||||
|
||||
effect(() => {
|
||||
const isDropdownOpen = this.isOpen();
|
||||
@@ -122,10 +124,17 @@ export class Dropdown implements OnInit {
|
||||
|
||||
searchInputElement.focus();
|
||||
this.setCursorToEnd(searchInputElement);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private checkIfInputFocus(event: Event) {
|
||||
let triggerInputFocus = this.searchInput()!.nativeElement.contains(
|
||||
event.target! as HTMLElement,
|
||||
);
|
||||
return this.isOpen() && triggerInputFocus;
|
||||
}
|
||||
|
||||
close() {
|
||||
this.isOpen.set(false);
|
||||
this.focusedIndex.set(-1);
|
||||
@@ -138,7 +147,7 @@ export class Dropdown implements OnInit {
|
||||
}
|
||||
|
||||
onConfirm(event: Event) {
|
||||
event.preventDefault()
|
||||
event.preventDefault();
|
||||
|
||||
if (this.isOpen()) {
|
||||
const currentIndex = this.focusedIndex();
|
||||
@@ -151,11 +160,13 @@ export class Dropdown implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
onEnter(event: Event) { this.onConfirm(event) }
|
||||
onEnter(event: Event) {
|
||||
this.onConfirm(event);
|
||||
}
|
||||
|
||||
onSpaceDown(event: Event) {
|
||||
if (this.isOpen() && this.inputFocusMode()) return;
|
||||
this.onConfirm(event)
|
||||
this.onConfirm(event);
|
||||
}
|
||||
|
||||
onArrowDown(event: Event) {
|
||||
@@ -191,22 +202,39 @@ export class Dropdown implements OnInit {
|
||||
}
|
||||
|
||||
onKeyDown(event: KeyboardEvent) {
|
||||
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey || event.key == 'Tab') return;
|
||||
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey || event.key == 'Tab')
|
||||
return;
|
||||
if (!this.isOpen() || this.inputFocusMode()) return;
|
||||
|
||||
this.inputFocusMode.set(true);
|
||||
}
|
||||
|
||||
@HostListener('document:click', ['$event'])
|
||||
onDocumentClick(event: MouseEvent) {
|
||||
if (!this.element.nativeElement.contains(event.target)) {
|
||||
this.close();
|
||||
onMouseDown(event: MouseEvent) {
|
||||
this.wasInside = this.element.nativeElement.contains(event.target);
|
||||
|
||||
if (this.checkIfInputFocus(event)) {
|
||||
if (!this.inputFocusMode()) this.inputFocusMode.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
onSearch(event: Event) {
|
||||
const text = (event.target as HTMLElement).innerText;
|
||||
@HostListener('document:click', ['$event'])
|
||||
onDocumentClick(event: MouseEvent) {
|
||||
if (!this.element.nativeElement.contains(event.target) && !this.wasInside) {
|
||||
this.close();
|
||||
}
|
||||
this.wasInside = false;
|
||||
}
|
||||
|
||||
handleInputClick(event: MouseEvent) {
|
||||
event.stopPropagation();
|
||||
this.wasInside = false;
|
||||
}
|
||||
|
||||
onSearch(event: Event) {
|
||||
const element = event.target as HTMLElement;
|
||||
const text = element.innerText;
|
||||
|
||||
if (text.trim().length <= 0) element.innerHTML = '';
|
||||
this.focusedIndex.set(0);
|
||||
this.searchQuery.set(text);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user