Allow more precise typing for gr-autocomplete
Change-Id: I88326e104ba1bac91799b2a04d1a3ce5dfad60a5
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
index 3f52650..9918f39 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
@@ -29,6 +29,7 @@
import {CustomKeyboardEvent} from '../../../types/events';
import {fireEvent} from '../../../utils/event-util';
import {debounce, DelayedTask} from '../../../utils/async-util';
+import {PropertyType} from '../../../types/common';
const TOKENIZE_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
const DEBOUNCE_WAIT_MS = 200;
@@ -40,9 +41,9 @@
};
}
-export type AutocompleteQuery = (
+export type AutocompleteQuery<T = string> = (
text: string
-) => Promise<AutocompleteSuggestion[]>;
+) => Promise<Array<AutocompleteSuggestion<T>>>;
declare global {
interface HTMLElementTagNameMap {
@@ -50,11 +51,11 @@
}
}
-export interface AutocompleteSuggestion {
+export interface AutocompleteSuggestion<T = string> {
name?: string;
label?: string;
- value?: string;
- text?: string;
+ value?: T;
+ text?: T;
}
export interface AutocompleteCommitEventDetail {
@@ -102,7 +103,7 @@
*
*/
@property({type: Object})
- query: AutocompleteQuery = () => Promise.resolve([]);
+ query?: AutocompleteQuery = () => Promise.resolve([]);
/**
* The number of characters that must be typed before suggestions are
@@ -298,6 +299,12 @@
if (this._disableSuggestions) {
return;
}
+
+ const query = this.query;
+ if (!query) {
+ return;
+ }
+
if (text.length < threshold) {
this.value = '';
return;
@@ -308,7 +315,7 @@
}
const update = () => {
- this.query(text).then(suggestions => {
+ query(text).then(suggestions => {
if (text !== this.text) {
// Late response.
return;
@@ -505,3 +512,24 @@
return showSearchIcon ? 'showSearchIcon' : '';
}
}
+
+/**
+ * Often gr-autocomplete is used for BranchName, RepoName, etc...
+ * GrTypedAutocomplete allows to define more precise typing in templates.
+ * For example, instead of
+ * $: {
+ * branchSelect: GrAutocomplete
+ * }
+ * you can write
+ * $: {
+ * branchSelect: GrTypedAutocomplete<BranchName>
+ * }
+ * And later user $.branchSelect.text without type conversion to BranchName.
+ */
+export interface GrTypedAutocomplete<
+ T extends PropertyType<GrAutocomplete, 'text'>
+> extends GrAutocomplete {
+ text: T;
+ value: T;
+ query?: AutocompleteQuery<T>;
+}