clsx-ruby 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +8 -0
- data/CLAUDE.md +66 -0
- data/LICENSE.txt +21 -0
- data/README.md +160 -0
- data/lib/clsx/helper.rb +120 -0
- data/lib/clsx/version.rb +5 -0
- data/lib/clsx.rb +23 -0
- metadata +50 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b9a68c03880d32a04dc1c721e0ee3009ac8a276f906da830e4866e2afae6ce92
|
|
4
|
+
data.tar.gz: 24155294bbdca977a8358ef7f6296febfdc86c2ca61d4faaf5b7e49b7f6d0d2a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 34de1db1360cae0f43ac95c1c5e1cb65d53294a313d5ad232afd79fe2b785e9ffab14f5b6bec527058f0cacc13354a000db1ea3479f43f0f6e17e5240a245c90
|
|
7
|
+
data.tar.gz: 4236efda398f4977ebb215ef492fd3965eff434efe9a8bccb9da4fb06023bd0bf8f32c02fabc962129a0fce7cbae34950c7936e0b3334e5da48219ddb15dc7ea
|
data/CHANGELOG.md
ADDED
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
clsx-ruby is a Ruby gem that provides a utility (`clsx`/`cn`) for constructing CSS class strings conditionally. It's a Ruby port of the JavaScript [clsx](https://github.com/lukeed/clsx) package, adapted for Ruby conventions. Framework-agnostic — works with Rails, Sinatra, Hanami, or plain Ruby.
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Run all tests and linting (default rake task)
|
|
13
|
+
bundle exec rake
|
|
14
|
+
|
|
15
|
+
# Run tests only
|
|
16
|
+
bundle exec rake test
|
|
17
|
+
|
|
18
|
+
# Run a single test file
|
|
19
|
+
bundle exec ruby -Itest test/clsx/helper_test.rb
|
|
20
|
+
|
|
21
|
+
# Run a specific test method
|
|
22
|
+
bundle exec ruby -Itest test/clsx/helper_test.rb -n test_with_strings
|
|
23
|
+
|
|
24
|
+
# Run linter
|
|
25
|
+
bundle exec rake rubocop
|
|
26
|
+
|
|
27
|
+
# Run benchmark
|
|
28
|
+
bundle exec ruby benchmark/run.rb
|
|
29
|
+
|
|
30
|
+
# Install dependencies
|
|
31
|
+
bin/setup
|
|
32
|
+
|
|
33
|
+
# Release a new version (update version.rb first)
|
|
34
|
+
# Builds gem, creates git tag, pushes to rubygems.org
|
|
35
|
+
# OTP is fetched automatically from 1Password
|
|
36
|
+
bundle exec rake release
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Architecture
|
|
40
|
+
|
|
41
|
+
The gem has a minimal structure:
|
|
42
|
+
|
|
43
|
+
- `lib/clsx.rb` - Entry point; extends `Clsx` with `Helper`, defines `Clsx[]` and `Cn[]` shortcuts
|
|
44
|
+
- `lib/clsx/helper.rb` - Core implementation with `clsx` method and `cn` alias
|
|
45
|
+
- `lib/clsx/version.rb` - Version constant
|
|
46
|
+
|
|
47
|
+
### API
|
|
48
|
+
|
|
49
|
+
- **`Clsx['foo', bar: true]`** — primary bracket API via `self.[]`
|
|
50
|
+
- **`Cn['foo', bar: true]`** — short alias (defined only if `Cn` constant is not taken)
|
|
51
|
+
- **`Clsx.clsx(...)`** / **`Clsx.cn(...)`** — module methods
|
|
52
|
+
- **`include Clsx::Helper`** — mixin giving `clsx()` and `cn()` instance methods
|
|
53
|
+
|
|
54
|
+
The helper uses an optimized algorithm with fast-paths for common cases (single string, string array, simple hash) and Hash-based deduplication for complex inputs.
|
|
55
|
+
|
|
56
|
+
## Key Behaviors
|
|
57
|
+
|
|
58
|
+
- Returns `nil` (not empty string) when no classes apply — prevents rendering empty `class=""` attributes
|
|
59
|
+
- Eliminates duplicate classes automatically
|
|
60
|
+
- Ruby falsy values are only `false` and `nil` (unlike JS, `0`, `''`, `[]`, `{}` are truthy)
|
|
61
|
+
- Ignores `Proc`/lambda objects and boolean `true` values
|
|
62
|
+
- Supports complex hash keys like `{ %w[foo bar] => true }` which resolve recursively
|
|
63
|
+
|
|
64
|
+
## Commit Convention
|
|
65
|
+
|
|
66
|
+
Uses [Conventional Commits](https://www.conventionalcommits.org/): `feat`, `fix`, `perf`, `chore`, `docs`, `refactor`
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Leonid Svyatov
|
|
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.
|
data/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# clsx-ruby [](https://rubygems.org/gems/clsx-ruby) [](https://github.com/svyatov/clsx-ruby/actions?query=workflow%3ACI) [](LICENSE.txt)
|
|
2
|
+
|
|
3
|
+
> A tiny, framework-agnostic utility for constructing CSS class strings conditionally.
|
|
4
|
+
|
|
5
|
+
Ruby port of the JavaScript [clsx](https://github.com/lukeed/clsx) package. Works with Rails, Sinatra, Hanami, or plain Ruby.
|
|
6
|
+
|
|
7
|
+
For automatic Rails view helper integration, see [clsx-rails](https://github.com/svyatov/clsx-rails).
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
Ruby 3.2+. No runtime dependencies.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle add clsx-ruby
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or add it manually to the Gemfile:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
gem 'clsx-ruby', '~> 1.0'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Bracket API (recommended)
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
require 'clsx'
|
|
31
|
+
|
|
32
|
+
Clsx['foo', 'bar']
|
|
33
|
+
# => 'foo bar'
|
|
34
|
+
|
|
35
|
+
Clsx['foo', bar: true, baz: false]
|
|
36
|
+
# => 'foo bar'
|
|
37
|
+
|
|
38
|
+
Clsx['btn', 'btn-primary', active: is_active, disabled: is_disabled]
|
|
39
|
+
# => 'btn btn-primary active' (when is_active is truthy, is_disabled is falsy)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Short alias
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
Cn['foo', bar: true]
|
|
46
|
+
# => 'foo bar'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`Cn` is defined only if the constant is not already taken.
|
|
50
|
+
|
|
51
|
+
### Mixin
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
include Clsx::Helper
|
|
55
|
+
|
|
56
|
+
clsx('foo', 'bar')
|
|
57
|
+
# => 'foo bar'
|
|
58
|
+
|
|
59
|
+
cn(hidden: @hidden, 'text-bold': @bold)
|
|
60
|
+
# => 'hidden text-bold' (when both are truthy)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Module methods
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
Clsx.clsx('foo', 'bar')
|
|
67
|
+
# => 'foo bar'
|
|
68
|
+
|
|
69
|
+
Clsx.cn('foo', bar: true)
|
|
70
|
+
# => 'foo bar'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Input types
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
# Strings (variadic)
|
|
77
|
+
Clsx['foo', true && 'bar', 'baz']
|
|
78
|
+
# => 'foo bar baz'
|
|
79
|
+
|
|
80
|
+
# Hashes
|
|
81
|
+
Clsx[foo: true, bar: false, baz: a_truthy_method]
|
|
82
|
+
# => 'foo baz'
|
|
83
|
+
|
|
84
|
+
# Hashes (variadic)
|
|
85
|
+
Clsx[{ foo: true }, { bar: false }, nil, { '--foobar': 'hello' }]
|
|
86
|
+
# => 'foo --foobar'
|
|
87
|
+
|
|
88
|
+
# Arrays
|
|
89
|
+
Clsx[['foo', nil, false, 'bar']]
|
|
90
|
+
# => 'foo bar'
|
|
91
|
+
|
|
92
|
+
# Arrays (variadic)
|
|
93
|
+
Clsx[['foo'], ['', nil, false, 'bar'], [['baz', [['hello'], 'there']]]]
|
|
94
|
+
# => 'foo bar baz hello there'
|
|
95
|
+
|
|
96
|
+
# Kitchen sink (with nesting)
|
|
97
|
+
Clsx['foo', ['bar', { baz: false, bat: nil }, ['hello', ['world']]], 'cya']
|
|
98
|
+
# => 'foo bar hello world cya'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Framework examples
|
|
102
|
+
|
|
103
|
+
```erb
|
|
104
|
+
<%# Rails %>
|
|
105
|
+
<%= tag.div class: Clsx['foo', 'baz', 'is-active': @active] do %>
|
|
106
|
+
Hello, world!
|
|
107
|
+
<% end %>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
# Sinatra
|
|
112
|
+
erb :"<div class='#{Clsx['nav', active: @active]}'>...</div>"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Differences from JavaScript clsx
|
|
116
|
+
|
|
117
|
+
1. **Falsy values** — In Ruby only `false` and `nil` are falsy, so `0`, `''`, `[]`, `{}` are all truthy:
|
|
118
|
+
```ruby
|
|
119
|
+
Clsx['foo' => 0, bar: []] # => 'foo bar'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
2. **Complex hash keys** — Any valid `clsx` input works as a hash key:
|
|
123
|
+
```ruby
|
|
124
|
+
Clsx[[{ foo: true }, 'bar'] => true] # => 'foo bar'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
3. **Ignored values** — Boolean `true` and `Proc`/lambda objects are silently ignored:
|
|
128
|
+
```ruby
|
|
129
|
+
Clsx['', proc {}, -> {}, nil, false, true] # => nil
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
4. **Returns `nil`** when no classes apply (not an empty string). This prevents rendering empty `class=""` attributes in template engines that skip `nil`:
|
|
133
|
+
```ruby
|
|
134
|
+
Clsx[nil, false] # => nil
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
5. **Deduplication** — Duplicate classes are automatically removed:
|
|
138
|
+
```ruby
|
|
139
|
+
Clsx['foo', 'foo'] # => 'foo'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Development
|
|
143
|
+
|
|
144
|
+
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.
|
|
145
|
+
|
|
146
|
+
There is a benchmark suite in the `benchmark` directory. Run it with `bundle exec ruby benchmark/run.rb`.
|
|
147
|
+
|
|
148
|
+
## Conventional Commits
|
|
149
|
+
|
|
150
|
+
This project uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit messages.
|
|
151
|
+
|
|
152
|
+
Types: `feat`, `fix`, `perf`, `chore`, `docs`, `refactor`
|
|
153
|
+
|
|
154
|
+
## Contributing
|
|
155
|
+
|
|
156
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/svyatov/clsx-ruby.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/clsx/helper.rb
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# :nodoc:
|
|
4
|
+
module Clsx
|
|
5
|
+
# :nodoc:
|
|
6
|
+
module Helper
|
|
7
|
+
# The clsx function can take any number of arguments,
|
|
8
|
+
# each of which can be Hash, Array, Boolean, String, or Symbol.
|
|
9
|
+
#
|
|
10
|
+
# **Important**
|
|
11
|
+
# Any falsy values are discarded! Standalone Boolean values are discarded as well.
|
|
12
|
+
#
|
|
13
|
+
# @param [Mixed] args
|
|
14
|
+
#
|
|
15
|
+
# @return [String] the joined class names
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# clsx('foo', 'bar') # => 'foo bar'
|
|
19
|
+
# clsx(true, { bar: true }) # => 'bar'
|
|
20
|
+
# clsx('foo', { bar: false }) # => 'foo'
|
|
21
|
+
# clsx({ bar: true }, 'baz', { bat: false }) # => 'bar baz'
|
|
22
|
+
#
|
|
23
|
+
# @example within a view
|
|
24
|
+
# <div class="<%= clsx('foo', 'bar') %>">
|
|
25
|
+
# <div class="<%= clsx('foo', active: @is_active, 'another-class' => @condition) %>">
|
|
26
|
+
# <%= tag.div class: clsx(%w[foo bar], hidden: @condition) do ... end %>
|
|
27
|
+
#
|
|
28
|
+
# @note Implementation prioritizes performance over readability.
|
|
29
|
+
# Direct class comparisons and explicit conditionals are used
|
|
30
|
+
# instead of more idiomatic Ruby patterns for speed.
|
|
31
|
+
|
|
32
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
33
|
+
def clsx(*args)
|
|
34
|
+
return nil if args.empty?
|
|
35
|
+
|
|
36
|
+
# Fast path: single argument (most common cases)
|
|
37
|
+
if args.size == 1
|
|
38
|
+
arg = args[0]
|
|
39
|
+
klass = arg.class
|
|
40
|
+
|
|
41
|
+
if klass == String
|
|
42
|
+
return arg.empty? ? nil : arg
|
|
43
|
+
elsif klass == Symbol
|
|
44
|
+
return arg.name
|
|
45
|
+
elsif klass == Array && arg.all?(String)
|
|
46
|
+
seen = {}
|
|
47
|
+
arg.each { |s| seen[s] = true unless s.empty? || seen.key?(s) }
|
|
48
|
+
return seen.empty? ? nil : seen.keys.join(' ')
|
|
49
|
+
elsif klass == Hash
|
|
50
|
+
return clsx_simple_hash(arg)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
seen = {}
|
|
55
|
+
clsx_process(args, seen)
|
|
56
|
+
seen.empty? ? nil : seen.keys.join(' ')
|
|
57
|
+
end
|
|
58
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
59
|
+
|
|
60
|
+
alias cn clsx
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
65
|
+
def clsx_simple_hash(hash)
|
|
66
|
+
return nil if hash.empty?
|
|
67
|
+
|
|
68
|
+
seen = {}
|
|
69
|
+
hash.each do |key, value|
|
|
70
|
+
next unless value
|
|
71
|
+
|
|
72
|
+
klass = key.class
|
|
73
|
+
|
|
74
|
+
if klass == Symbol
|
|
75
|
+
seen[key.name] = true
|
|
76
|
+
elsif klass == String
|
|
77
|
+
seen[key] = true unless key.empty?
|
|
78
|
+
else
|
|
79
|
+
# Complex key - fall back to full processing
|
|
80
|
+
seen = {}
|
|
81
|
+
clsx_process([hash], seen)
|
|
82
|
+
return seen.empty? ? nil : seen.keys.join(' ')
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
seen.empty? ? nil : seen.keys.join(' ')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# rubocop:disable Style/MultipleComparison
|
|
90
|
+
def clsx_process(args, seen)
|
|
91
|
+
deferred = nil
|
|
92
|
+
|
|
93
|
+
args.each do |arg|
|
|
94
|
+
klass = arg.class
|
|
95
|
+
|
|
96
|
+
if klass == String
|
|
97
|
+
seen[arg] = true unless arg.empty? || seen.key?(arg)
|
|
98
|
+
elsif klass == Symbol
|
|
99
|
+
str = arg.name
|
|
100
|
+
seen[str] = true unless seen.key?(str)
|
|
101
|
+
elsif klass == Array
|
|
102
|
+
clsx_process(arg, seen)
|
|
103
|
+
elsif klass == Hash
|
|
104
|
+
arg.each { |key, value| (deferred ||= []) << key if value }
|
|
105
|
+
elsif klass == Integer || klass == Float
|
|
106
|
+
str = arg.to_s
|
|
107
|
+
seen[str] = true unless seen.key?(str)
|
|
108
|
+
elsif klass == NilClass || klass == FalseClass || klass == TrueClass || klass == Proc
|
|
109
|
+
next
|
|
110
|
+
else
|
|
111
|
+
str = arg.to_s
|
|
112
|
+
seen[str] = true unless str.empty? || seen.key?(str)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
clsx_process(deferred, seen) if deferred
|
|
117
|
+
end
|
|
118
|
+
# rubocop:enable Style/MultipleComparison, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
119
|
+
end
|
|
120
|
+
end
|
data/lib/clsx/version.rb
ADDED
data/lib/clsx.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'clsx/version'
|
|
4
|
+
require_relative 'clsx/helper'
|
|
5
|
+
|
|
6
|
+
# :nodoc:
|
|
7
|
+
module Clsx
|
|
8
|
+
extend Helper
|
|
9
|
+
|
|
10
|
+
def self.[](*)
|
|
11
|
+
clsx(*)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Short alias — only defined if `Cn` is not already taken
|
|
16
|
+
unless Object.const_defined?(:Cn)
|
|
17
|
+
# :nodoc:
|
|
18
|
+
module Cn
|
|
19
|
+
def self.[](*)
|
|
20
|
+
Clsx[*]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: clsx-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Leonid Svyatov
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: A tiny utility for constructing CSS class strings conditionally
|
|
13
|
+
email:
|
|
14
|
+
- leonid@svyatov.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- CHANGELOG.md
|
|
20
|
+
- CLAUDE.md
|
|
21
|
+
- LICENSE.txt
|
|
22
|
+
- README.md
|
|
23
|
+
- lib/clsx.rb
|
|
24
|
+
- lib/clsx/helper.rb
|
|
25
|
+
- lib/clsx/version.rb
|
|
26
|
+
homepage: https://github.com/svyatov/clsx-ruby
|
|
27
|
+
licenses:
|
|
28
|
+
- MIT
|
|
29
|
+
metadata:
|
|
30
|
+
source_code_uri: https://github.com/svyatov/clsx-ruby
|
|
31
|
+
changelog_uri: https://github.com/svyatov/clsx-ruby/blob/main/CHANGELOG.md
|
|
32
|
+
rubygems_mfa_required: 'true'
|
|
33
|
+
rdoc_options: []
|
|
34
|
+
require_paths:
|
|
35
|
+
- lib
|
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 3.2.0
|
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
requirements: []
|
|
47
|
+
rubygems_version: 4.0.4
|
|
48
|
+
specification_version: 4
|
|
49
|
+
summary: clsx / classnames for Ruby
|
|
50
|
+
test_files: []
|