JedWatson / classnames

A simple javascript utility for conditionally joining classNames together
MIT License
17.61k stars 562 forks source link

Feature Request: Enhanced Responsive Classnames Support #407

Closed guinnod closed 4 months ago

guinnod commented 4 months ago

Feature Request: Enhanced Responsive Classnames Support

Description

I am a developer who heavily utilizes classNames along with Tailwind CSS for my projects. The combination of classNames and Tailwind CSS is incredibly useful for managing dynamic class names. However, I have found that writing responsive Tailwind class names can be cumbersome and less readable.

Current Practice

Currently, I write responsive Tailwind class names like this:

className={classNames(
  "bg-[#2A2A2A] rounded-[16px] py-[24px] px-[16px]",
  "sm:px-[54px] sm:py-[40px] sm:rounded-[16px]",   
  "md:px-[70px] md:py-[40px] md:rounded-[26px]", 
)}

This approach works, but it can become difficult to manage and read as the number of responsive breakpoints increases.

Proposed Feature

I propose adding support for a more readable and isolated approach to responsive class names, similar to the following:

className={classNames(
  "bg-[#2A2A2A] rounded-[16px] py-[24px] px-[16px]",
  {"px-[54px] py-[40px] rounded-[16px]": "sm"},   
  {"px-[70px] py-[40px] rounded-[26px]": "md"}, 
)}

or

className={classNames(
  "bg-[#2A2A2A] rounded-[16px] py-[24px] px-[16px]",
  "sm:{px-[54px] py-[40px] rounded-[16px]}",
  "md:{px-[70px] py-[40px] rounded-[26px]}"
)}

Such formats would allow developers to isolate responsive class names and make the code more readable and maintainable. I recognize that the maintainers have a deep understanding of the library’s architecture and may know of even more efficient ways to integrate this functionality.

Benefits

Thank you for considering this feature request. I believe it would be a valuable addition to classNames, especially for developers who use Tailwind CSS extensively.

Best regards, Abzal Slamkozha

jonkoops commented 4 months ago

Thanks for your proposal. I can understand the need to reduce complexity when working with a lot of classnames that should be applied only at certain breakpoints, especially with Tailwind. However, classnames is intended as a minimal API to conditionally apply classes and join them together, and parsing these kinds of specific expressions introduces a complexity and performance overhead that we don't want to incur.

The proposal here also breaks current API expectations, as currently a truthy value being passed as the value of an object will apply the key of said object to the class-list. If we were to adopt the proposal to accept a value that should be used as some kind of prefix then this would have to be considered a breaking change.

The prefixing itself is also problematic, as this is a syntax specific to Tailwind, so in order to remain portable we'd have to make this configurable, further complicating the existing API.

I would instead recommend you write your own utility function on top of classnames to handle this Tailwind specific optimization, it should not be more than ~10 LOC to carry in your own project. Perhaps even open-source it, as it might be useful for other Tailwind users.