umbraco / Umbraco.UI

Umbraco UI Components
MIT License
116 stars 39 forks source link

uui-input: throws warnings when running without ShadowDOM #639

Open iOvergaard opened 10 months ago

iOvergaard commented 10 months ago

Which exact UI Library version are you using? For example: 1.0.1 - don't just write v1.

1.5.0

Bug summary

In Umbraco V13, we had to disable the Shadow DOM for the time being in the uui-input component to make autofill and password managers work in Chromium browsers. However, this throws a warning that a duplicate #input ID is detected (one for each time you show the component on the page).

The question is if we can first of all make sure the uui-input can run without a ShadowDOM, and second of all avoid using ID's in the inner template (or allow a custom ID) just in case.

This issue is seen on the new login screen of Umbraco 13: https://github.com/umbraco/Umbraco-CMS/issues/15089

Specifics

No response

Steps to reproduce

This scenario can be replicated by extending UUIInputElement:

import { UUIInputElement } from '@umbraco-ui/uui';
import { customElement } from 'lit/decorators.js';

@customElement('umb-login-input')
export class UmbLoginInputElement extends UUIInputElement {
  protected createRenderRoot() {
    return this;
  }
  static styles = [...UUIInputElement.styles];
}
  1. Include uui-input two times on a page with disabled ShadowDOM

Expected result / actual result

No response

iOvergaard commented 10 months ago

This can be avoided locally by overwriting the getFormElement method as well as removing the id on firstUpdated, but ideally it would be possible to change the id:

import { UUIInputElement } from '@umbraco-ui/uui';
import { customElement } from 'lit/decorators.js';

@customElement('umb-login-input')
export class UmbLoginInputElement extends UUIInputElement {

  protected firstUpdated() {
    const innerInput = this.querySelector('input')
    innerInput?.removeAttribute('id');
  }

  protected getFormElement(): HTMLElement {
    const formElement = this.querySelector('input');

    if (!formElement) {
      throw new Error('Form element not found');
    }

    return formElement;
  }

  protected createRenderRoot() {
    return this;
  }

  static styles = [...UUIInputElement.styles];
}