Customize components
TL;DR
Components are customizable with the same TailwindCSS-classes
that they are build on (through thetw
-prop) Refer to the Prop-table for the particular component to see what is customizable Base components typically allow more customization Know the impact; customizing a property foregoes ALL styles for that particular property, including handling of any states or variants that may be associated with that property (e.g.:hover
,:active
,dark:
, ...)
One features of the component library is that you can customize components
using Tailwind-classes (p-2
, text-blue
, ...). For example, if we wanted
to change the background and the text color of the Badge
-component, we
could do it like this:
This would replace the original utils-classes (defined inside the Badge
-component)
associated with the color property. Note the phrasing her; you don't extend,
you REPLACE the util-classes define in component completely for that property.
This is perhaps be easier to understand when you se how the Badge
is
implemented in this example:
The helper-function twToClassNames(componentStyles, overrides)
is where the customization-logic is happening. This function combines
the style-properties defined in the component-props (tw
) and
the base style of the components itself; preferring the ones that comes
from the props.
As mention in the Introduction to Tailwind, the Tailwind-utils are considered design tokens of the design system. The components them selfs are just structured group of the same util-classes/tokens. This is why this method makes sense, because we customize with the same tokens that component them self are built on.
Example: Creating a Yezz! Button
Let's say that we need a special kind of branded button to use on the front-page. Normally, buttons are not branded1 because we want to convey intention, and not brand when we use colors on Button (e.g. the "primary action," or the "payment/purchase action," and so on). On the front page, however, we consider this OK since we show a group of branded buttons; denoting that they convey branding.
Ok, back to the Yezz!-button. In the following example we are customizing
the base Button
by adding bg-lipstick text-white
to the tw
-prop:
That was easy! Too easy, actually; try to hover the two buttons above. See the problem?
That's right, when you override a property you forego the associated
styles related to that property. In this case, the twColors
is removing
the styling for :hover
-state (since the button changes color on hover).
Hover state
Let's fix the missing hover-effect by adding hover:bg-lipstick-lighter
to our customization:
Disabled
Nice, almost there! The last thing we need to handle is the disabled
condition. Again, try to hover the following disabled button:
See? We don't want the hover-effect when the button is disabled; it sends mixed signals to the user. Is the button interactive or not? 🤔
Unlike the :hover
-state, which can be differentiated in Tailwind (e.g. hover:bg-lipstick-lighter
),
the disabled-state is toggled via the disabled
-prop on the Button-component.
So we need to remove the hover:
-property when the button is disabled:
Putting it all together
If you need to use your customize button multiple times, it probably a good idea to extract it into a thin wrapper.
☝️🤓 This is actually how the Primary, Secondary, Payment, and Square buttons are implemented.
Before you customize
- Component should in most cases be ready to use as-is; that's after all, a key part of a design system
- If you find yourself overriding many properties to accommodate sketches; make sure there is a rigid rationale behind it
- Don't hesitate to involve the design team early in the process!
- All components are unbranded, except the
Logo
-component (which uses the brand to resolve the logo-asset). See fundamentals for mor information on this. ⤴