sync-device-name.mjs (3917B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; 6 import { html } from "chrome://global/content/vendor/lit.all.mjs"; 7 8 /** 9 * A custom element that manages the display and editing of a Device name 10 * in Firefox Sync settings section. 11 * 12 * @tagname sync-device-name 13 * @property {string} value - The current value of the device name. 14 * @property {string} defaultValue - Default device name shown in the input field when empty. 15 * @property {boolean} disabled - The disabled state of the device name component. 16 * @property {boolean} _isInEditMode - Whether the component is currently in edit mode. 17 */ 18 class SyncDeviceName extends MozLitElement { 19 static properties = { 20 value: { type: String }, 21 defaultValue: { type: String }, 22 disabled: { type: Boolean }, 23 _isInEditMode: { type: Boolean, state: true }, 24 }; 25 26 static queries = { 27 inputTextEl: "#fxaSyncComputerName", 28 changeBtnEl: "#fxaChangeDeviceName", 29 }; 30 31 constructor() { 32 super(); 33 34 /** @type {string} */ 35 this.value = ""; 36 37 /** @type {string} */ 38 this.defaultValue = ""; 39 40 /** @type {boolean} */ 41 this.disabled = false; 42 43 /** @type {boolean} */ 44 this._isInEditMode = false; 45 } 46 47 setFocus() { 48 this.updateComplete.then(() => { 49 const targetEl = this._isInEditMode ? this.inputTextEl : this.changeBtnEl; 50 targetEl?.focus(); 51 }); 52 } 53 54 onDeviceNameChange() { 55 this._isInEditMode = true; 56 this.setFocus(); 57 } 58 59 onDeviceNameCancel() { 60 this._isInEditMode = false; 61 this.setFocus(); 62 } 63 64 onDeviceNameSave() { 65 const inputVal = this.inputTextEl.value?.trim(); 66 this.value = inputVal === "" ? this.defaultValue : inputVal; 67 this._isInEditMode = false; 68 this.setFocus(); 69 70 this.dispatchEvent(new Event("change", { bubbles: true })); 71 } 72 73 /** 74 * Handles key presses in the device name input. 75 * Pressing Enter saves the name, pressing Escape cancels editing. 76 * 77 * @param {KeyboardEvent} event 78 */ 79 onDeviceNameKeyDown(event) { 80 switch (event.key) { 81 case "Enter": 82 event.preventDefault(); 83 this.onDeviceNameSave(); 84 break; 85 case "Escape": 86 event.preventDefault(); 87 this.onDeviceNameCancel(); 88 break; 89 } 90 } 91 92 displayDeviceNameTemplate() { 93 return html`<moz-button 94 id="fxaChangeDeviceName" 95 data-l10n-id="sync-device-name-change-2" 96 data-l10n-attrs="accesskey" 97 slot="actions" 98 @click=${this.onDeviceNameChange} 99 ?disabled=${this.disabled} 100 ></moz-button>`; 101 } 102 103 editDeviceNameTemplate() { 104 return html`<moz-input-text 105 id="fxaSyncComputerName" 106 data-l10n-id="sync-device-name-input" 107 data-l10n-args=${JSON.stringify({ placeholder: this.defaultValue })} 108 .value=${this.value} 109 @keydown=${this.onDeviceNameKeyDown} 110 ></moz-input-text> 111 <moz-button 112 id="fxaCancelChangeDeviceName" 113 data-l10n-id="sync-device-name-cancel" 114 data-l10n-attrs="accesskey" 115 slot="actions" 116 @click=${this.onDeviceNameCancel} 117 ></moz-button> 118 <moz-button 119 id="fxaSaveChangeDeviceName" 120 data-l10n-id="sync-device-name-save" 121 data-l10n-attrs="accesskey" 122 slot="actions" 123 @click=${this.onDeviceNameSave} 124 ></moz-button>`; 125 } 126 127 render() { 128 let label = ""; 129 if (!this._isInEditMode) { 130 label = this.value == "" ? this.defaultValue : this.value; 131 } 132 return html` 133 <moz-box-item label=${label}> 134 ${this._isInEditMode 135 ? this.editDeviceNameTemplate() 136 : this.displayDeviceNameTemplate()} 137 </moz-box-item> 138 `; 139 } 140 } 141 customElements.define("sync-device-name", SyncDeviceName);