#Extending input

1 messages ยท Page 1 of 1 (latest)

fading matrix
#

I am trying to extend input behavior. Is there a way to tell that Host shall be the input or to pass all attributes to the input without applying it to the host?

For example, if I do <my-input class="bg-green-500 p-8" /> the style is applied to my-input and, depending on how I define it in my code, also applied to the input or not. But I want to only apply it to the input, not to my-input.

past ether
#

You can do it ... whether you should is another matter ๐Ÿ˜„

Here's some untested code to essentially copy all the host attributes to the inner input - (you could filter out the ones you care about).

  @Element() host: HTMLElement;
  @State() attrs: {[key: string]: string}[];
  private mo: MutationObserver;

  setAttrs() {
    this.attrs = Array.from(this.host.attributes).flatMap(att => att.specified ? {[att.nodeName]: att.nodeValue} : []);
  }
  attachSlotObserver() {
    if (!!this.mo || !window['MutationObserver']) return;
    this.mo = new MutationObserver(() => this.setAttrs());
    this.mo.observe(this.host, { attributes: true });
  }
  connectedCallback() {
    this.setAttrs();
    this.attachSlotObserver();
  }
  disconnectedCallback() {
    if (this.mo) this.mo.disconnect();
  }
  render() {
    return <input {...this.attrs} />
  }

Then to ignore all the host styling, do something like

  :host { display: contents; } 
fading matrix
#

With that solution, I could not use shadow dom, because it will not see css from outside the shadow dom.

The use or not of shadow dow is not realy a trouble in my case.
However, I am not able to apply :host { display: contents; } that have not impact on the input itself

fading matrix
#

The only way I currently have, is to ignore class and style attributes and use a cutsom attribute to set class and / or style of the input

past ether
#

if it's just about styling, I'd suggest adding

<input part="input" ... />

Within your component (with shadow: true).
Then users can style from outside:

my-input::part(input) {...}

You can style via tailwind using something like

<my-input class="[&::part(input)]:bg-green-500 [&::part(input)]:p-8"></my-input>
fading matrix
#

Yep, this work for tailwind, but if a user want to use other framework, like Bootstrap & Co, [&::part(input)]: will not work here

past ether
#

correct ๐Ÿ™‚ ... that's just how web-components with style encapsulation works - nothing else you can do.

There really isn't a 'nice' way to do what you're looking for.
Your option of adding inputStyle and inputClass as attributes on the custom element is probably the 'best'

One more option - force users to slot an input:

  <my-input><input slot=input" ... /></my-input>

But then, your custom-element is probably not adding much value.

fading matrix
#

Right ! ๐Ÿ˜…
I will keep my solution (about inputClass/Style) and see what I can do like this

#

thank's for your answers ๐Ÿ™