Let’s Go Native! Why You Shouldn’t Hide the Native Element in Your Angular Core Components
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!