Customising components in NativeBase

Customising components in NativeBase

ยท

5 min read

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

Types of component theme

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 variant prop 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 size prop 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

Screenshot 2022-01-06 at 12.41.55 PM.png

Different types of pseudo props

Props starting with _ is pseudo props. Broadly pseudo props are categorised into 2 type

  • state-driven pseudo props: These props respond to some state change and will be applied based on that. For example, _disabled prop will be applied when isDisbled prop 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 _text in the Box component.

Pseudo props and the specificity

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.

Screenshot 2022-01-05 at 3.52.23 AM.png 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.

Screenshot 2022-01-05 at 4.35.24 AM.png

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 gray.500

Let's address some of the most common confusions now.

To do so, let's customise the Button component.

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.

Step 2: Simplify

Button's theme might look overwhelming. So let us simplify by only focusing on those 4 styles (namely, defaultProps, sizes, variants and baseStyle)

  • defaultProps

Screenshot 2021-12-22 at 7.27.22 PM.png

After looking at the default props we can conclude that the default variant is solid and the default size is md. For now, let's just focus on the solid Button on md size.

  • size (md)

Screenshot 2022-01-06 at 12.58.35 PM.png

  • variant (solid)

Screenshot 2022-01-06 at 12.59.13 PM.png

  • baseStyle

Screenshot 2022-01-06 at 12.59.13 PM.png

We'll need all these styles for reference.

Step 3: Setup

I have updated the basic example snack by adding the template code shown in the styling section of the docs. Screenshot 2022-01-06 at 1.30.10 PM.png

Step 4: Implementation

Let's have some dummy requirements to get started.

  • Default button is too big.
  • Solid Variant should have a Border of 2px, which response 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:

  1. Updating the default size form md to sm. (easy and recommended)
  2. Updating the style for md size. (For obvious reasons we'll do it this way)

Screenshot 2022-01-06 at 2.24.42 PM.png

Secondly, let's update the solid variant as per the requirements.

Screenshot 2022-01-06 at 2.24.21 PM.png

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.

Screenshot 2022-01-06 at 2.23.25 PM.png

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.

  1. Go to each variant and add the style. (cumbersome but this is the only recommended way)
  2. 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.

Screenshot 2022-01-06 at 2.38.15 PM.png

Voila we did it ๐ŸŽ‰ ๐ŸŽ‰ ๐ŸŽ‰

minion.gif

ย