blob: 2249b5d78b9ac82fc07490b360529bfa560008cb [file] [log] [blame]
/**
* @license
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../gr-autocomplete/gr-autocomplete';
import {
AutocompleteQuery,
GrAutocomplete,
} from '../gr-autocomplete/gr-autocomplete';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, PropertyValues, html, css} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {
AddAccountEvent,
AutocompleteCommitEvent,
BindValueChangeEvent,
} from '../../../types/events';
import {SuggestedReviewerInfo} from '../../../types/common';
import {PaperInputElement} from '@polymer/paper-input/paper-input';
import {fire} from '../../../utils/event-util';
/**
* gr-account-entry is an element for entering account
* and/or group with autocomplete support.
*/
@customElement('gr-account-entry')
export class GrAccountEntry extends LitElement {
@query('#input') private input?: GrAutocomplete;
@property({type: Boolean})
allowAnyInput = false;
@property({type: Boolean})
borderless = false;
@property({type: String})
placeholder = '';
@property({type: Object})
querySuggestions: AutocompleteQuery<SuggestedReviewerInfo> = () =>
Promise.resolve([]);
@state() private inputText = '';
static override get styles() {
return [
sharedStyles,
css`
gr-autocomplete {
display: inline-block;
flex: 1;
overflow: hidden;
}
`,
];
}
override render() {
return html`
<gr-autocomplete
id="input"
.borderless=${this.borderless}
.placeholder=${this.placeholder}
.query=${this.querySuggestions}
allow-non-suggested-values=${this.allowAnyInput}
@commit=${this.handleInputCommit}
clear-on-commit
warn-uncommitted
.text=${this.inputText}
.verticalOffset=${24}
@text-changed=${this.handleTextChanged}
>
</gr-autocomplete>
`;
}
override willUpdate(changedProperties: PropertyValues) {
if (changedProperties.has('inputText')) {
this.inputTextChanged();
}
}
get focusStart(): PaperInputElement | undefined {
return this.input!.focusStart;
}
override focus() {
this.input!.focus();
}
clear() {
this.input!.clear();
}
setText(text: string) {
this.input!.setText(text);
}
getText() {
return this.input!.text;
}
private handleInputCommit(e: AutocompleteCommitEvent) {
fire(this, 'add', {value: e.detail.value});
this.input!.focus();
}
private inputTextChanged() {
if (this.inputText.length && this.allowAnyInput) {
fire(this, 'account-text-changed', {});
}
}
private handleTextChanged(e: BindValueChangeEvent) {
this.inputText = e.detail.value ?? '';
}
}
declare global {
interface HTMLElementTagNameMap {
'gr-account-entry': GrAccountEntry;
}
interface HTMLElementEventMap {
/** Fired when an account is entered. */
// prettier-ignore
'add': AddAccountEvent;
/**
* When allowAnyInput is true, account-text-changed is fired when input text
* changed. This is needed so that the reply dialog's save button can be
* enabled for arbitrary cc's, which don't need a 'commit'.
*/
'account-text-changed': CustomEvent<{}>;
}
}