creativetimofficial / material-tailwind

@material-tailwind is an easy-to-use components library for Tailwind CSS and Material Design.
https://material-tailwind.com/
MIT License
3.51k stars 306 forks source link

Overriding certain classes on `Input` requires `!` (important tag) #663

Open Remscar opened 2 months ago

Remscar commented 2 months ago

I've experienced this behavior on the Input component but i'm sure it exists on other components as well.

Let's say I am making an Input component:

<Input />

There are a handful of different elements that created, the container, the input itself, and the label. You are given ways of customizing these elements as described in the docs (https://www.material-tailwind.com/docs/react/input#input-custom-styles) with className labelProps and containerProps

The documentation however leaves out that there isn't a way to customize certain parts of these elements without using an important css tag, which I think is dangerous to use in the first place.

For instance if I wanted to reduce the padding inside of the input element I would think to add the classes px-0 py-0 to className, however that results in no effect.

We can see the complete list of css classes for this component:

<Input className="px-0 py-0" />
peer w-full h-full bg-transparent text-blue-gray-700 font-sans font-normal
outline outline-0 focus:outline-0 disabled:bg-blue-gray-50 disabled:border-0
disabled:cursor-not-allowed transition-all placeholder-shown:border
placeholder-shown:border-blue-gray-200 placeholder-shown:border-t-blue-gray-200
border focus:border-2 border-t-transparent focus:border-t-transparent placeholder:opacity-0
focus:placeholder:opacity-100 text-sm px-3 py-2.5 rounded-[7px]
border-blue-gray-200 focus:border-gray-900 px-0 py-0

Note that the px-0 py-0 are at the end, therefore they are overridden by px-3 py-2.5 which are the defaults.

If we look at the source code for the component we can see why this is happening: https://github.com/creativetimofficial/material-tailwind/blob/a2d0d9b8d0383300fddd3e32b1a4305590c944d5/packages/material-tailwind-react/src/components/Input/index.tsx#L111C8-L121C7

The user provided classes are getting added to the end of the class list.

This means to override the padding we would have to use ! ie;

<Input className="!px-0 !py-0" />

Which will create the desired effect since ! makes the css "important" overriding anything else.

I think that it's bad practice for this library to require users to use ! to override default classes in components for two reasons; the first being it is bad practice in general to use !important and the second being unintuitive behavior. A new user (such as myself) will look at the documentation and think "Oh I can just override certain classes of this component by using className or containerProps.className" and then discover that there is no effect. The logical behavior of className would be that it overrides anything that's already there.

The fix to this is very easy, moving className from line 120 to 112 in https://github.com/creativetimofficial/material-tailwind/blob/main/packages/material-tailwind-react/src/components/Input/index.tsx#L111C8-L121C7 And in any other similar places such as in the labelClasses or containerClasses clause. This eliminates the need of using ! and makes the behavior more reasonable.