blob: 0ddb87a5b418f18239f93c4e9c151f9478091152 [file] [log] [blame]
class EditableText extends ComponentBase {
constructor(text)
{
super('editable-text');
this._text = text;
this._inEditingMode = false;
this._updatingPromise = null;
this._actionLink = this.content().querySelector('.editable-text-action a');
this._label = this.content().querySelector('.editable-text-label');
}
didConstructShadowTree()
{
const button = this.content('action-button');
button.addEventListener('mousedown', this.createEventHandler(() => this._didClick()));
button.addEventListener('click', this.createEventHandler(() => this._didClick()));
this.element().addEventListener('blur',() => {
if (!this.content().activeElement)
this._endEditingMode();
});
}
editedText() { return this.content('text-field').value; }
text() { return this._text; }
setText(text)
{
this._text = text;
this.enqueueToRender();
}
render()
{
const label = this.content('label');
label.textContent = this._text;
label.style.display = this._inEditingMode ? 'none' : null;
const textField = this.content('text-field');
textField.style.display = this._inEditingMode ? null : 'none';
textField.readOnly = !!this._updatingPromise;
this.content('action-button').textContent = this._inEditingMode ? (this._updatingPromise ? '...' : 'Save') : 'Edit';
this.content('action-button-container').style.display = this._text ? null : 'none';
if (this._inEditingMode) {
if (!this._updatingPromise)
textField.focus();
}
}
_didClick()
{
if (this._updatingPromise)
return;
if (this._inEditingMode) {
const result = this.dispatchAction('update');
if (result instanceof Promise)
this._updatingPromise = result.then(() => this._endEditingMode());
else
this._endEditingMode();
} else {
this._inEditingMode = true;
const textField = this.content('text-field');
textField.value = this._text;
textField.style.width = (this._text.length / 1.5) + 'rem';
this.enqueueToRender();
}
}
_endEditingMode()
{
this._inEditingMode = false;
this._updatingPromise = null;
this.enqueueToRender();
}
static htmlTemplate()
{
return `
<span id="container">
<input id="text-field" type="text">
<span id="label"></span>
<span id="action-button-container">(<a id="action-button" href="#">Edit</a>)</span>
</span>`;
}
static cssTemplate()
{
return `
#container {
position: relative;
padding-right: 2.5rem;
}
#text-field {
background: transparent;
margin: 0;
padding: 0;
color: inherit;
font-weight: inherit;
font-size: inherit;
border: none;
}
#action-button-container {
position: absolute;
right: 0;
padding-left: 0.2rem;
color: #999;
font-size: 0.8rem;
top: 50%;
margin-top: -0.4rem;
vertical-align: middle;
}
#action-button {
color: inherit;
text-decoration: none;
}
`;
}
}
ComponentBase.defineElement('editable-text', EditableText);