I have seen many people struggling with customising NativeBase's components but worry no more because I got your back. In this article, I share everything you need to know, in order to effectively customise the components as per your will.
But before we actually start customising our components let's get familiarised with a few NativeBase concepts.
- Types of component theme
- Different types of pseudo props
- Pseudo props and their specificity
There are 4 properties using which you can update a component's theme, namely defaultProps, sizes, variants, and baseStyle. Let's understand each of them one by one.
- baseStyle: The basic styling for the component can be defined here.
- variants: It takes an object and each key of the object will hold a variant-specific style. And it can be used by passing the
variantprop on the component.
NOTE: any styles defined here will overwrite the baseStyle (in case of conflict).
- sizes: Similar to variants, it'll hold sizes related styles and can be used by passing the
sizeprop on the component.
NOTE: any styles defined here will overwrite the baseStyle and variants style (in case of conflict).
- defaultProps: Default props have the highest priority and they can be considered equivalent to inline components props. It'll override all the above styles, so use it wisely. (analogous to !important in CSS)
A simple diagram to show the specificity
Props starting with
_are pseudo props. Broadly pseudo props are categorised into 2 types:
- state-driven pseudo props: These props respond to some state change and will be applied based on that. For example,
_disabledprop will be used when
isDisbledprop is true. These are further classified into 2 types namely platform props and interaction props but let's not dive that deep.
- internal pseudo props: These are used internally by the component, to access the unreachable sections of the code. The best example for this kind of pseudo prop is the
_textin the Box component.
Pseudo Props specificity behaviour is very much analogous to CSS Selectors. Pseudo props can be nested inside each other and that will increase the specificity of the nested props the same way CSS Selector does.
Now state-driven pseudo props have a well-defined order of precedence. And I'll share with you what it is.
Specificity decreases as we go down, meaning higher pseudo props will overwrite the below ones in case of conflict.
NOTE: pseudo props like _web, _ios, _android, _light and _dark have the least specificity among all pseudo props.
You can check out this if you're still curious. (At your own risk)
Now let's go through an interview-type question to better understand this concept.
What will be the applied bg based on the above image?
If you're thinking
amber.500, you fell for it. The correct answer is
red.500(just kidding). It'll be
To do so, let's customise the
Step 1: Visit docs.nativebase.io/button#styling
It provides 2 main things, a link to the default theme and a template to customise the theme. Let's open the link for reference, copy the template and open Button's Basic example on snack and use the template here.
Button's theme might look overwhelming. So let us simplify by only focusing on those 4 styles (namely, defaultProps, sizes, variants and baseStyle)
After looking at the default props we can conclude that the default
solidand the default
md. For now, let's just focus on the
- size (
• variant (
We'll need all these styles for reference.
I have updated the basic example snack by adding the template code shown in the styling section of the docs.
Let's have some dummy requirements to get started.
- The default button is too big.
- Solid Variant should have a Border of 2px, which responds to the existing colorScheme. And hovering over it should change its shade along with the button.
- By default, the disabled button should have yellow color 😝. For all variants 🤯.
So, the first one can be done in 2 ways:
- Updating the default size form
sm. (easy and recommended)
- Updating the style for
mdsize. (For obvious reasons we'll do it this way)
Secondly, let's update the solid variant as per the requirements.
Lastly, updating the default disabled state. Initially, you would have thought that since it's for all variants the ideal spot for the style will be baseStyle. So let's do it.
Why it didn't work? 😰
Let's create a GitHub issue for it. 😡
Wait Wait Wait, Let's think about the specificity first (to be precise type specificity).🧐
Oooh, so the _disabled declared in the solid variant style is overwriting the style I just defined. 🤩
This can be done in 2 ways.
- Go to each variant and add the style. (cumbersome but this is the only recommended way)
- Increase the specificity in the baseStyle itself so that variants style won't be able to override it.
NOTE: It's a hack, not recommended, never do it, never ever do it, nooooo just no. But I feel you should know.