vaadin / flow-components

Java counterpart of Vaadin Web Components
100 stars 66 forks source link

API for setting attributes on input field components' <input> elements #3337

Open rolfsmeds opened 2 years ago

rolfsmeds commented 2 years ago

Describe your motivation

Html <input> elements support various attributes that improve e.g. autocomplete and accessibility, such as

The Flow API currently only allows the developer to set html attributes on components' root elements, but provides no access to the (automatically generated) <input> elements, which is where they need to be in order to work correctly.

Describe the solution you'd like

Provide a Flow API for setting attributes on the elements, e.g. something like textfield.setInputAttribute("id", "foobar");

Describe alternatives you've considered

  1. We could simply provide dedicated APIs for each of these attributes separately. This is already planned to be done partially for the most important attributes, such as [aria-label] (https://github.com/vaadin/flow-components/issues/2946). Perhaps the HasLabel interface could be further enhanced by the addition of a setAriaLabelledBy() method, and even corresponding methods for aria-description and possibly aria-describedby. A separate API could be further added for the autocomplete settings.
  2. As suggested in https://github.com/vaadin/web-components/issues/3767, we could automatically propagate certain attributes from the root element to the <input> element. This could work well for some attributes (like id, with an auto-appended suffix to distinguish it from the root element), but might end up confusing browsers and assistive technologies for some others.
  3. Instead provide an API for setting a custom <input> element to the component, instead of the autogenerated one. Flow already provides classes for instantiating <input> elements and adding attributes to them. This would be analogous to what the Web Component API allows, and might provide maximum flexibility, but at the cost of convenience for Java developers for the most common use cases.
  4. For aria-labelledby specifically, we should in any case either fix or deprecate the currently broken Label::setFor(Component) API intended to create an appropriate semantic association between a <label> and an input field.

Additional context

No response

cyberoblivion commented 1 year ago

Any further discussion on this?

Legioth commented 1 year ago

Could be mentioned here as well that as a workaround, one can use executeJs to set attributes.

As an example, the id attribute can be set like this:

someTextField.getElement().executeJs("this.inputElement.setAttribute('id', $0)", "someId");
cyberoblivion commented 1 year ago

It looks like you would need to do this Js onAttach because the attribute is lost after detached and reattached. Does that sound right?

knoobie commented 1 year ago

Yes, that's correct.

rolfsmeds commented 1 year ago

Update to this: decided to do https://github.com/vaadin/platform/issues/3803 instead for now. This still leaves some use cases unsolved, so those will need to be tackled separately.