https://github.com/svyatov/clsx-rails
clsx / classnames for Rails views
https://github.com/svyatov/clsx-rails
actionview classnames clsx conditional-rendering rails-helper ruby-gem ruby-gems ruby-on-rails
Last synced: 3 months ago
JSON representation
clsx / classnames for Rails views
- Host: GitHub
- URL: https://github.com/svyatov/clsx-rails
- Owner: svyatov
- License: mit
- Created: 2024-03-03T12:52:27.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-16T23:48:06.000Z (10 months ago)
- Last Synced: 2025-02-24T22:51:22.466Z (8 months ago)
- Topics: actionview, classnames, clsx, conditional-rendering, rails-helper, ruby-gem, ruby-gems, ruby-on-rails
- Language: Ruby
- Homepage:
- Size: 67.4 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# clsx-rails [](https://rubygems.org/gems/clsx-rails) [](https://app.codecov.io/gh/svyatov/clsx-rails) [](https://github.com/svyatov/clsx-rails/actions?query=workflow%3ACI) [](LICENSE.txt)
> A tiny Rails view helper for constructing CSS class strings conditionally.
This gem is essentially a clone if the [clsx](https://github.com/lukeed/clsx) npm package.
It provides a simple way to conditionally apply classes to HTML elements in Rails views.
It is especially useful when you have a lot of conditional classes and you want to keep your views clean and readable.## Supported Ruby and Rails versions
Ruby 3.1+ and Rails 7.0+ are supported.
## Installation
Install the gem and add to the application's Gemfile by executing:
```bash
bundle add clsx-rails
```Or add it manually to the Gemfile:
```ruby
gem 'clsx-rails', '~> 1.0'
```## Usage
The `clsx` helper method can be used in views to conditionally apply classes to HTML elements.
You can also use a slightly more conise `cn` alias.
It accepts a variety of arguments and returns a string of unique classes.```ruby
# Strings (variadic)
clsx('foo', true && 'bar', 'baz')
# => 'foo bar baz'# Hashes
cn({ foo: true, bar: false, baz: a_method_that_returns_true })
# => 'foo baz'# Hashes (variadic)
clsx({ foo: true }, { bar: false }, nil, { '--foobar': 'hello' })
# => 'foo --foobar'# Arrays
cn(['foo', nil, false, 'bar'])
# => 'foo bar'# Arrays (variadic)
clsx(['foo'], ['', nil, false, 'bar'], [['baz', [['hello'], 'there']]])
# => 'foo bar baz hello there'# Kitchen sink (with nesting)
cn('foo', ['bar', { baz: false, bat: nil }, ['hello', ['world']]], 'cya');
# => 'foo bar hello world cya'
``````erb
<%= tag.div class: clsx('foo', 'baz', 'is-active' => @active) do %>
Hello, world!
<% end %>
Hello, world!
``````haml
%div{class: clsx('foo', 'baz', 'is-active' => @active)}
Hello, world!
``````slim
div class=clsx('foo', 'baz', 'is-active' => @active)
| Hello, world!
```So the basic idea is to get rid of constructions like this in your views:
```erb
<% classes = ['foo', 'baz'] %>
<% classes << 'is-active' if @active %>
Hello, world!
```or like this:
```erb
Hello, world!
```or like this:
```erb
```## Differences from the original `clsx` package
This gem reproduces the functionality of the original `clsx` package, but with nuances of Ruby and Rails in mind.
The main differences are:
1. falsy values in Ruby are only `false` and `nil`, so the `clsx` method will not accept `0`, `''`, `[]`, `{}`, etc. as falsy values.
```ruby
clsx('foo' => 0, bar: []) # => 'foo bar'
```
2. `clsx-rails` supports complex hash keys, like `{ %[foo bar] => true }`, which will be converted to `foo bar` in the resulting string.
Meaning, if it's a valid input for the `clsx-rails`, it's a valid hash key.
```ruby
clsx([{ foo: true }, 'bar'] => true) # => 'foo bar'
```
3. `clsx-rails` will ignore objects that are `blank?`, boolean (`true` or `false`), or an instance of `Proc` (so, procs and lambdas).
```ruby
clsx('', [], {}, proc {}, -> {}, nil, false, true) # => nil
```
4. `clsx-rails` returns `nil` if there are no classes to apply, instead of an empty string.
The reason for that is not to pollute the HTML with empty `class` attributes when using Rails tag helpers: Rails will not render the `class` attribute if it's `nil`.
```ruby
clsx(nil, false) # => nil
```
Although, it won't help if you're using it directly in erb:
```erb
Hello, world!
```
This code will render `Hello, world!` anyway.
5. `clsx-rails` eliminates duplicate classes:
```ruby
clsx('foo', 'foo') # => 'foo'
```## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run
`rake test` to run the tests. You can also run `bin/console` for an interactive
prompt that will allow you to experiment.To install this gem onto your local machine, run `bundle exec rake install`. To
release a new version, update the version number in `version.rb`, and then run
`bundle exec rake release`, which will create a git tag for the version, push
git commits and the created tag, and push the `.gem` file to
[rubygems.org](https://rubygems.org).There is a simple benchmark script in the `benchmark` directory.
You can run it with `bundle exec ruby benchmark/run.rb`.
I've added it for easier performance testing when making changes to the gem.## Conventional Commits
This project uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit messages.
Types of commits are:
- `feat`: a new feature
- `fix`: a bug fix
- `perf`: code that improves performance
- `chore`: updating build tasks, configs, formatting etc; no code change
- `docs`: changes to documentation
- `refactor`: refactoring code## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/svyatov/clsx-rails.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).