├── .github └── workflows │ └── main.yml ├── .gitignore ├── .overcommit.yml ├── CHANGELOG.md ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── clsx.gemspec ├── lib ├── clsx.rb └── clsx │ ├── railtie.rb │ └── version.rb ├── sig └── clsx.rbs └── test ├── test_clsx.rb └── test_helper.rb /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Ruby 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | lint: 12 | timeout-minutes: 10 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up Ruby 20 | uses: ruby/setup-ruby@v1 21 | with: 22 | ruby-version: 3.3.0 23 | bundler-cache: true 24 | 25 | - name: Lint code for consistent style 26 | run: bundle exec standardrb 27 | 28 | test: 29 | runs-on: ubuntu-latest 30 | name: Ruby ${{ matrix.ruby }} 31 | strategy: 32 | matrix: 33 | ruby: ['3.1', '3.2', '3.3'] 34 | 35 | steps: 36 | - uses: actions/checkout@v4 37 | - name: Set up Ruby 38 | uses: ruby/setup-ruby@v1 39 | with: 40 | ruby-version: ${{ matrix.ruby }} 41 | bundler-cache: true 42 | - name: Run the default task 43 | run: bundle exec rake 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | 10 | # Releases 11 | clsx-*.gem 12 | .ruby-version 13 | -------------------------------------------------------------------------------- /.overcommit.yml: -------------------------------------------------------------------------------- 1 | PreCommit: 2 | StandardRB: 3 | enabled: true 4 | required: true 5 | command: ['bundle', 'exec', 'standardrb'] 6 | flags: ['--fix'] 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | ## [0.1.3] - 2024-03-02 3 | PUBLIC RELEASE 4 | remove github actions to publish to rubygems, easier to run rake release 5 | 6 | ## [0.1.2] - 2024-03-02 7 | add github actions to publish to rubygems 8 | 9 | ## [0.1.1] - 2024-03-03 10 | ### Changed 11 | - Changed `clsx` to `CLSX` 12 | 13 | 14 | ## [0.1.0] - 2024-03-02 15 | 16 | - Initial release 17 | 18 | These examples should be working 19 | 20 | Strings (variadic) 21 | ```ruby 22 | clsx("foo", true && "bar", "baz") 23 | #=> "foo bar baz" 24 | ``` 25 | 26 | Objects 27 | ```ruby 28 | clsx({ foo:true, bar:false, baz:is_true? }) 29 | #=> "foo baz" 30 | ``` 31 | 32 | Objects (variadic) 33 | ```ruby 34 | clsx({ foo:true }, { bar:false }, null, { "--foobar":"hello" }) 35 | #=> "foo --foobar" 36 | ``` 37 | 38 | Arrays 39 | ```ruby 40 | clsx(["foo", 0, false, "bar"]) 41 | #=> "foo bar" 42 | ``` 43 | 44 | Arrays (variadic) 45 | ```ruby 46 | clsx(["foo"], ["", 0, false, "bar"], [["baz", [["hello"], "there"]]]) 47 | #=> "foo bar baz hello there" 48 | ``` 49 | 50 | Kitchen sink (with nesting) 51 | ```ruby 52 | clsx("foo", [1 && "bar", { baz:false, bat:null }, ["hello", ["world"]]], "cya") 53 | #=> "foo bar hello world cya" 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in clsx.gemspec 6 | gemspec 7 | 8 | gem "rake", "~> 13.0" 9 | 10 | gem "minitest", "~> 5.16" 11 | 12 | gem "standard" 13 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | clsx (0.1.3) 5 | 6 | GEM 7 | remote: https://rubygems.org/ 8 | specs: 9 | ast (2.4.2) 10 | json (2.7.1) 11 | language_server-protocol (3.17.0.3) 12 | lint_roller (1.1.0) 13 | minitest (5.22.2) 14 | parallel (1.24.0) 15 | parser (3.3.0.5) 16 | ast (~> 2.4.1) 17 | racc 18 | racc (1.7.3) 19 | rainbow (3.1.1) 20 | rake (13.1.0) 21 | regexp_parser (2.9.0) 22 | rexml (3.2.6) 23 | rubocop (1.61.0) 24 | json (~> 2.3) 25 | language_server-protocol (>= 3.17.0) 26 | parallel (~> 1.10) 27 | parser (>= 3.3.0.2) 28 | rainbow (>= 2.2.2, < 4.0) 29 | regexp_parser (>= 1.8, < 3.0) 30 | rexml (>= 3.2.5, < 4.0) 31 | rubocop-ast (>= 1.30.0, < 2.0) 32 | ruby-progressbar (~> 1.7) 33 | unicode-display_width (>= 2.4.0, < 3.0) 34 | rubocop-ast (1.31.1) 35 | parser (>= 3.3.0.4) 36 | rubocop-performance (1.20.2) 37 | rubocop (>= 1.48.1, < 2.0) 38 | rubocop-ast (>= 1.30.0, < 2.0) 39 | ruby-progressbar (1.13.0) 40 | standard (1.34.0) 41 | language_server-protocol (~> 3.17.0.2) 42 | lint_roller (~> 1.0) 43 | rubocop (~> 1.60) 44 | standard-custom (~> 1.0.0) 45 | standard-performance (~> 1.3) 46 | standard-custom (1.0.2) 47 | lint_roller (~> 1.0) 48 | rubocop (~> 1.50) 49 | standard-performance (1.3.1) 50 | lint_roller (~> 1.1) 51 | rubocop-performance (~> 1.20.2) 52 | unicode-display_width (2.5.0) 53 | 54 | PLATFORMS 55 | arm64-darwin-23 56 | ruby 57 | 58 | DEPENDENCIES 59 | clsx! 60 | minitest (~> 5.16) 61 | rake (~> 13.0) 62 | standard 63 | 64 | BUNDLED WITH 65 | 2.5.3 66 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Seth Horsley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Clsx 2 | ## A gem for constructing HTML class strings conditionally 3 | 4 | Ruby utility for constructing HTML class strings conditionally with the provided syntax, you can define a module named Clsx that includes a method to handle each case: strings, objects (hashes), arrays, and a combination of these with nested structures. This method will recursively process each argument, filter out falsy values, and concatenate the truthy values into a single string. 5 | 6 | ## Installation 7 | 8 | Install the gem and add to the application's Gemfile by executing: 9 | 10 | $ bundle add "clsx" 11 | 12 | 13 | ## Usage 14 | Strings (variadic) 15 | ```ruby 16 | clsx("foo", true && "bar", "baz") 17 | #=> "foo bar baz" 18 | ``` 19 | 20 | Objects 21 | ```ruby 22 | clsx({ foo:true, bar:false, baz:is_true? }) 23 | #=> "foo baz" 24 | ``` 25 | 26 | Objects (variadic) 27 | ```ruby 28 | clsx({ foo:true }, { bar:false }, null, { "--foobar":"hello" }) 29 | #=> "foo --foobar" 30 | ``` 31 | 32 | Arrays 33 | ```ruby 34 | clsx(["foo", 0, false, "bar"]) 35 | #=> "foo bar" 36 | ``` 37 | 38 | Arrays (variadic) 39 | ```ruby 40 | clsx(["foo"], ["", 0, false, "bar"], [["baz", [["hello"], "there"]]]) 41 | #=> "foo bar baz hello there" 42 | ``` 43 | 44 | Kitchen sink (with nesting) 45 | ```ruby 46 | clsx("foo", [1 && "bar", { baz:false, bat:null }, ["hello", ["world"]]], "cya") 47 | #=> "foo bar hello world cya" 48 | ``` 49 | 50 | You can also use clsx in rails views like this: 51 | ```ruby 52 |