diff --git a/deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx b/deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx index 1d6b4a5f0..39bd5012d 100644 --- a/deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx +++ b/deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx @@ -82,6 +82,8 @@ export class CloudXR2DUI { private startButton!: HTMLButtonElement; /** Input field for the CloudXR server IP address */ private serverIpInput!: HTMLInputElement; + /** Button to clear the prefilled server IP (re-enables the browser autocomplete dropdown) */ + private serverIpClearButton!: HTMLButtonElement; /** Input field for the CloudXR server port number */ private portInput!: HTMLInputElement; /** Input field for proxy URL configuration */ @@ -359,6 +361,7 @@ export class CloudXR2DUI { private initializeElements(): void { this.startButton = this.getElement('startButton'); this.serverIpInput = this.getElement('serverIpInput'); + this.serverIpClearButton = this.getElement('serverIpClearButton'); this.portInput = this.getElement('portInput'); this.proxyUrlInput = this.getElement('proxyUrl'); this.immersiveSelect = this.getElement('immersive'); @@ -545,6 +548,23 @@ export class CloudXR2DUI { addListener(this.serverTypeSelect, 'change', updateConfig); addListener(this.serverIpInput, 'input', updateConfig); addListener(this.serverIpInput, 'change', updateConfig); + + // Show the clear ("x") button only while the server IP field has a value, + // and clear the prefill (incl. localStorage) on click so the browser's + // autocomplete dropdown of previously connected servers can show again. + const updateServerIpClearButton = () => { + this.serverIpClearButton.classList.toggle('visible', this.serverIpInput.value.length > 0); + }; + addListener(this.serverIpInput, 'input', updateServerIpClearButton); + addListener(this.serverIpClearButton, 'click', () => { + this.serverIpInput.value = ''; + // 'input' updates the live config + clear-button state; 'change' persists + // the now-empty value via the enableLocalStorage handler. + this.serverIpInput.dispatchEvent(new Event('input', { bubbles: true })); + this.serverIpInput.dispatchEvent(new Event('change', { bubbles: true })); + this.serverIpInput.focus(); + }); + updateServerIpClearButton(); addListener(this.portInput, 'input', updateConfig); addListener(this.portInput, 'change', updateConfig); const updateResValidation = () => this.updateResolutionValidationMessage(); diff --git a/deps/cloudxr/webxr_client/src/index.html b/deps/cloudxr/webxr_client/src/index.html index 75407ae76..885c29e3b 100644 --- a/deps/cloudxr/webxr_client/src/index.html +++ b/deps/cloudxr/webxr_client/src/index.html @@ -137,6 +137,55 @@ color: #999; } + /* Server IP field paired with an inline clear ("x") button */ + .input-with-clear { + position: relative; + } + + .input-with-clear .ui-input { + /* leave room so the IP text never sits under the clear button */ + padding-right: 44px; + } + + .input-clear-btn { + position: absolute; + /* center on the 48px-tall input, ignoring its 16px margin-bottom */ + top: 24px; + right: 8px; + transform: translateY(-50%); + display: none; + align-items: center; + justify-content: center; + /* equal width/height + override the global button min-height so the + hover highlight is a circle, not a tall pill */ + width: 28px; + height: 28px; + min-height: 0; + padding: 0; + border: none; + border-radius: 50%; + background: transparent; + color: #999; + font-size: 1.25rem; + line-height: 1; + cursor: pointer; + } + + /* Shown only while the field has a value (toggled in CloudXR2DUI) */ + .input-clear-btn.visible { + display: flex; + } + + .input-clear-btn:hover { + background: rgba(0, 0, 0, 0.08); + color: var(--text-main); + } + + .input-clear-btn:focus-visible { + outline: none; + box-shadow: 0 0 0 3px rgba(118, 185, 0, 0.2); + } + .settings-table { width: 100%; margin-bottom: 24px; @@ -609,8 +658,12 @@

Settings

- +
+ + +