Let’s Go Native! Why You Shouldn’t Hide the Native Element in Your Angular Core Components

Netanel Basal
Netanel Basal
Published in
3 min readApr 6, 2021

--

In this article, I’ll discuss a pattern used by developers when building a core components library. When designing components such as text inputs, checkboxes, radio and action buttons, etc., they tend to hide the native DOM element inside the component. Doing so isn’t the best approach for two reasons:

  • We want to give the component’s consumers the ability to directly handle the native element API, such as defining event handlers or attributes without exposing and managing them from the component.
  • We want to use the native Angular value accessor support for these elements and not create a redundant custom value accessor for each element.

Let’s see three examples of strategies we can use to create components without hiding the native element:

Input Component

The typical text input design usually includes elements such as a clear button, icon postfix, etc. Let’s create a core input component that supports these elements:

Now we can use our component, project the native input element, and provide a suffix if we need to:

The missing piece in our puzzle is to find a way to interact with the FormControl from the InputComponent so that we can do things such as make the clear button work.

To do so, first, we’ll create a directive that exposes a reference to the underline FormControl. Next, we’ll use ContentChild to grab a reference to this directive from our InputComponent:

This is only one example of something we can do with FormControl; however, it can be taken further to create whatever is needed.

Checkbox Component

Next, I want to show a technique we can use when creating a custom-designed checkbox, radio, or switch buttons. Note that we’ll skip the styling part because this isn’t about styling. Our final result will be similar to the input component:

In these types of elements, we usually want to associate a label with the element. This is done by using the label element for attribute. Let’s create the TogglerRef directive that’ll expose a setId() method that sets the id attribute on the host element:

Now let’s use it in our CheckboxComponent:

And that’s all. More examples can be found at CodePen that show how to create a custom checkbox with CSS. It is possible to use the same technique with a radio and switch buttons:

Button Component

When it comes to buttons, I always prefer to use CSS classes to style them based on the design. I can also use these classes on an anchor element when I need to have a button redirecting to another location.

However, as we know, it doesn’t end here. There are cases when we need to add an icon or some spinner next to the button’s text. To do so, we’ll create a component.

Wait a minute. You said that we don’t want to hide the native element. That’s right, so we’ll create a component that uses an attribute selector:

Now we can choose to use the component when we need a spinner or an icon or to use the CSS class when we only need a styled button:

🚀 In Case You Missed It

Here are a few of my open source projects:

  • Akita: State Management Tailored-Made for JS Applications
  • Spectator: A Powerful Tool to Simplify Your Angular Tests
  • Transloco: The Internationalization library Angular
  • Error-tailor — Seamless form errors for Angular applications
  • Forms Manager: The Foundation for Proper Form Management in Angular
  • Cashew: A flexible and straightforward library that caches HTTP requests
  • Error Tailor — Seamless form errors for Angular applications

And many more!

Follow me on Medium or Twitter to read more about Angular, Akita and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.