Creating radio buttons in Shadow DOM
Asked Answered
A

1

8

The problem arises when we are going to create a custom radio button as a web component using Shadow Dom.

Normally when we are using radio buttons, we usually give the same name to the grouped radio boxes, like this.

<input type="radio" name="size" id="small" value="small">
<input type="radio" name="size" id="large" value="large">

But if we define some custom element (like let's say cus-radio) -> we would do it in a way to take the name and id as a input (from parent) and place them in the custom element. That would perfectly work on normal context.

But my problem is with the shadow dom! When we are creating elements inside shadow dom, attributes inside of it is accessible or connected with the outer dom (main dom). So how can we develop a custom radio button, if the name and id properties of it is not accessible or common in the parent dom?

Example:-

We will develop our custom element like this (pseudo code like in angular elements)

radio.html:-

<input type="radio" [name]="name" [id]="id" ...>

TS/Logic file:-

...
component cus-radio {
@Input() name: string;
@Input() id: string;
...

Wherever we are using that:-

<cus-radio [id]="'small'" [name]="'size'" value="small">
<cus-radio [id]="'large'" [name]="'size'" value="large">

The expected behavior should be (as happens in a normal dom), these two radio inputs must co-relate and exists with the mutual understanding of two like it one got checked other one must uncheck etc. But in shadow dom it doesn't. Because those name and id are changed in the shadow dom which have no reference to the parent dom (main dom).

How can we actually create radio inputs in the shadow dom?

Alister answered 3/9, 2019 at 11:43 Comment(3)
Can you please provide a minimal reproducible example that actually reproduces the problem?Timberhead
FWIW I tried to see if it's possible for my custom element to extend HTMLInputElement (or something similar) but I gave up after trying to get that to work for a while. If I need to go about this, rather than an extra input element per radio (as Emiel's answer suggested) I might go for a custom radiogroup element which is capable of artificially managing my custom radio elements (so all I would need is an extra wrapper element). Still feels really hacky tho.Nissa
Create a <radio-group> component instead.Darren
C
-1

Use the <slot> element in your Shadow DOM template. This way you can inject the input in your custom element and access it in the parent DOM and in the Shadow DOM.

In your Shadow DOM add a <slot> element. This element can have a name attribute if you would have multiple slots and want to assign a specific element to a specific slot. But unnamed slots are also an option. This means that each direct child of the custom element will be placed inside the unnamed slot.

this.shadowRoot.innerHTML = `

    <style>
        ::slotted(input[type="radio"]) {
            /**
             * Styles of the input.
             * The input can also be styled from the parent DOM.
             */
        }
    </style>

    <slot></slot>

`;

Now that your Shadow DOM has a <slot> element you can inject the <input> element inside of it. With the ::slotted pseudo selector you can style each element which is now inside the slot and even specify multiple styles by selecting a specific element, class or id inside the ::slotted selector.

Add your <input> as a direct child inside your custom element and it will be slotted inside the Shadow DOM.

<cus-radio id="small">
    <input type="radio" name="size" value="small"/>
</cus-radio>

Javascript.info has some great documentation of how to use slots inside custom elements. I recommend you check it out.

Cud answered 16/9, 2019 at 17:16 Comment(2)
Good solution to go what actually not i needed. I needed to make a radio button component which wraps everything where use don't need to care about adding another input element, so the slot thing doesn't actually work for this.Alister
What you really need is coming soon in the form of form-associated custom elements. WHATWG has an example of the implementation. But support is almost non existent, for now.Cud

© 2022 - 2024 — McMap. All rights reserved.