Update Dropdown to Maintain Input Format Consistency
This commit is contained in:
1 parent
9c7f3cf542
commit
dceac30c39
2 files changed
+26
-5
No files matched your search
@@ -6,7 +6,7 @@
|
|||||||
<div #searchInput class="dropdown-input" [class.hidden]="!isOpen()" [class.focus-mode]="inputFocusMode()"
|
<div #searchInput class="dropdown-input" [class.hidden]="!isOpen()" [class.focus-mode]="inputFocusMode()"
|
||||||
contenteditable="true" role="textbox" aria-multiline="false" [aria-placeholder]="translation.common.selectOption"
|
contenteditable="true" role="textbox" aria-multiline="false" [aria-placeholder]="translation.common.selectOption"
|
||||||
[attr.placeholder]="translation.common.selectOption" tabindex="-1" spellcheck="false"
|
[attr.placeholder]="translation.common.selectOption" tabindex="-1" spellcheck="false"
|
||||||
(input)="onSearch($event)" (click)="handleInputClick($event)" (mousedown)="handleInputMouseDown()"></div>
|
(input)="onSearch($event)" (click)="handleInputClick($event)" (mousedown)="handleInputMouseDown()" (beforeinput)="preprocessInputContent($event)"></div>
|
||||||
|
|
||||||
@if (!isOpen()) {
|
@if (!isOpen()) {
|
||||||
<span class="placeholder">{{ selectedLabel() }}</span>
|
<span class="placeholder">{{ selectedLabel() }}</span>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
viewChild,
|
viewChild,
|
||||||
untracked,
|
untracked,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common'
|
import { CommonModule } from '@angular/common';
|
||||||
import { TranslationService } from '../../services/translation.service';
|
import { TranslationService } from '../../services/translation.service';
|
||||||
|
|
||||||
export interface DropdownOption {
|
export interface DropdownOption {
|
||||||
@@ -106,7 +106,7 @@ export class Dropdown implements OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
filteredOptions = computed(() => {
|
filteredOptions = computed(() => {
|
||||||
const query = this.searchQuery().toLowerCase().trim().normalize("NFKD");
|
const query = this.searchQuery().toLowerCase().trim().normalize('NFKD');
|
||||||
const opts = this.normalizedOptions();
|
const opts = this.normalizedOptions();
|
||||||
|
|
||||||
if (!this.inputFocusMode()) return opts;
|
if (!this.inputFocusMode()) return opts;
|
||||||
@@ -170,6 +170,8 @@ export class Dropdown implements OnInit {
|
|||||||
const options = this.filteredOptions();
|
const options = this.filteredOptions();
|
||||||
if (currentIndex >= 0 && currentIndex < options.length) {
|
if (currentIndex >= 0 && currentIndex < options.length) {
|
||||||
this.selectOption(options[currentIndex]);
|
this.selectOption(options[currentIndex]);
|
||||||
|
} else if (options.length === 0) {
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.toggle();
|
this.toggle();
|
||||||
@@ -218,8 +220,9 @@ export class Dropdown implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onKeyDown(event: KeyboardEvent) {
|
onKeyDown(event: KeyboardEvent) {
|
||||||
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey || event.key == 'Tab')
|
const textArrowKeys = ['ArrowLeft', 'ArrowRight'];
|
||||||
return;
|
|
||||||
|
if (!textArrowKeys.includes(event.key)) return;
|
||||||
if (!this.isOpen() || this.inputFocusMode()) return;
|
if (!this.isOpen() || this.inputFocusMode()) return;
|
||||||
|
|
||||||
this.inputFocusMode.set(true);
|
this.inputFocusMode.set(true);
|
||||||
@@ -257,6 +260,9 @@ export class Dropdown implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSearch(event: Event) {
|
onSearch(event: Event) {
|
||||||
|
if (!this.isOpen()) return;
|
||||||
|
if (!this.inputFocusMode()) this.inputFocusMode.set(true);
|
||||||
|
|
||||||
const element = event.target as HTMLElement;
|
const element = event.target as HTMLElement;
|
||||||
const text = element.innerText;
|
const text = element.innerText;
|
||||||
|
|
||||||
@@ -265,6 +271,21 @@ export class Dropdown implements OnInit {
|
|||||||
this.searchQuery.set(text);
|
this.searchQuery.set(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preprocessInputContent(event: InputEvent) {
|
||||||
|
if (event.inputType === 'insertLineBreak' || event.inputType === 'insertParagraph') {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.inputType === 'insertFromPaste') {
|
||||||
|
const originalText = event.dataTransfer!.getData('text/plain');
|
||||||
|
const modifiedText = originalText.replace(/[\r\n]+/g, '');
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// noinspection JSDeprecatedSymbols
|
||||||
|
document.execCommand('insertText', false, modifiedText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
selectedLabel = computed(() => {
|
selectedLabel = computed(() => {
|
||||||
const selected = this.normalizedOptions().find((o) => o.value === this.value());
|
const selected = this.normalizedOptions().find((o) => o.value === this.value());
|
||||||
return selected ? selected.label : this.placeholder();
|
return selected ? selected.label : this.placeholder();
|
||||||
|
|||||||
Reference in new issue
Block a user