From 9f7eca2f265cc9b7b76467b20cc337d9899099f1 Mon Sep 17 00:00:00 2001 From: Jiwen Cai Date: Sat, 13 Jun 2026 06:53:10 +0000 Subject: [PATCH] webxr: add clear button to Server IP field The Server IP field prefills from the last connected server with no way to clear it, which suppressed the browser's autocomplete dropdown of previously used servers. Add an inline circular 'x' button that appears when the field has a value; clicking it clears the value (including the persisted localStorage entry) and refocuses the field so the dropdown can show again. --- deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx | 20 +++++++ deps/cloudxr/webxr_client/src/index.html | 57 ++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) 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

- +
+ + +