Polish Mouse Click Response
This commit is contained in:
1 parent
3f33c0dfa5
commit
3a415a2525
3 files changed
+49
-10
No files matched your search
@@ -3,9 +3,9 @@
|
|||||||
<span class="material-symbols-outlined icon-24 prefix-icon">{{ icon() }}</span>
|
<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"
|
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()) {
|
@if (!isOpen()) {
|
||||||
<span class="placeholder">{{ selectedLabel() }}</span>
|
<span class="placeholder">{{ selectedLabel() }}</span>
|
||||||
|
|||||||
@@ -67,6 +67,17 @@ $default_animation_duration: 0.2s;
|
|||||||
outline: none;
|
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 {
|
.dropdown-input.hidden {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export interface DropdownOption {
|
|||||||
'[class.open]': 'isOpen()',
|
'[class.open]': 'isOpen()',
|
||||||
tabindex: '0',
|
tabindex: '0',
|
||||||
'(click)': 'toggle()',
|
'(click)': 'toggle()',
|
||||||
|
'(mousedown)': 'onMouseDown($event)',
|
||||||
'(keydown)': 'onKeyDown($event)',
|
'(keydown)': 'onKeyDown($event)',
|
||||||
'(keydown.enter)': 'onEnter($event)',
|
'(keydown.enter)': 'onEnter($event)',
|
||||||
'(keydown.space)': 'onSpaceDown($event)',
|
'(keydown.space)': 'onSpaceDown($event)',
|
||||||
@@ -65,9 +66,10 @@ export class Dropdown implements OnInit {
|
|||||||
|
|
||||||
private static nextId = 0;
|
private static nextId = 0;
|
||||||
dropdownId = `dropdown-${Dropdown.nextId++}`;
|
dropdownId = `dropdown-${Dropdown.nextId++}`;
|
||||||
|
private wasInside = false;
|
||||||
|
|
||||||
constructor(private element: ElementRef) {
|
constructor(private element: ElementRef) {
|
||||||
effect(() => this.filteredOptions())
|
effect(() => this.filteredOptions());
|
||||||
|
|
||||||
effect(() => {
|
effect(() => {
|
||||||
const isDropdownOpen = this.isOpen();
|
const isDropdownOpen = this.isOpen();
|
||||||
@@ -122,10 +124,17 @@ export class Dropdown implements OnInit {
|
|||||||
|
|
||||||
searchInputElement.focus();
|
searchInputElement.focus();
|
||||||
this.setCursorToEnd(searchInputElement);
|
this.setCursorToEnd(searchInputElement);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private checkIfInputFocus(event: Event) {
|
||||||
|
let triggerInputFocus = this.searchInput()!.nativeElement.contains(
|
||||||
|
event.target! as HTMLElement,
|
||||||
|
);
|
||||||
|
return this.isOpen() && triggerInputFocus;
|
||||||
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.isOpen.set(false);
|
this.isOpen.set(false);
|
||||||
this.focusedIndex.set(-1);
|
this.focusedIndex.set(-1);
|
||||||
@@ -138,7 +147,7 @@ export class Dropdown implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onConfirm(event: Event) {
|
onConfirm(event: Event) {
|
||||||
event.preventDefault()
|
event.preventDefault();
|
||||||
|
|
||||||
if (this.isOpen()) {
|
if (this.isOpen()) {
|
||||||
const currentIndex = this.focusedIndex();
|
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) {
|
onSpaceDown(event: Event) {
|
||||||
if (this.isOpen() && this.inputFocusMode()) return;
|
if (this.isOpen() && this.inputFocusMode()) return;
|
||||||
this.onConfirm(event)
|
this.onConfirm(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onArrowDown(event: Event) {
|
onArrowDown(event: Event) {
|
||||||
@@ -191,22 +202,39 @@ export class Dropdown implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onKeyDown(event: KeyboardEvent) {
|
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;
|
if (!this.isOpen() || this.inputFocusMode()) return;
|
||||||
|
|
||||||
this.inputFocusMode.set(true);
|
this.inputFocusMode.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMouseDown(event: MouseEvent) {
|
||||||
|
this.wasInside = this.element.nativeElement.contains(event.target);
|
||||||
|
|
||||||
|
if (this.checkIfInputFocus(event)) {
|
||||||
|
if (!this.inputFocusMode()) this.inputFocusMode.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@HostListener('document:click', ['$event'])
|
@HostListener('document:click', ['$event'])
|
||||||
onDocumentClick(event: MouseEvent) {
|
onDocumentClick(event: MouseEvent) {
|
||||||
if (!this.element.nativeElement.contains(event.target)) {
|
if (!this.element.nativeElement.contains(event.target) && !this.wasInside) {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
this.wasInside = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInputClick(event: MouseEvent) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.wasInside = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearch(event: Event) {
|
onSearch(event: Event) {
|
||||||
const text = (event.target as HTMLElement).innerText;
|
const element = event.target as HTMLElement;
|
||||||
|
const text = element.innerText;
|
||||||
|
|
||||||
|
if (text.trim().length <= 0) element.innerHTML = '';
|
||||||
this.focusedIndex.set(0);
|
this.focusedIndex.set(0);
|
||||||
this.searchQuery.set(text);
|
this.searchQuery.set(text);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user