class_variants 0.0.6 → 0.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2012fb19a3b94a62a3278f1256167126ef85e203a967cc20f8cb67d6fc94bfcb
4
- data.tar.gz: ec7bf120843ba12c34f7bfbef26f5170fac8bd4e7f40d7717c6a478bf0116cbf
3
+ metadata.gz: 35b8ff14e7d3dfe7319d4fb4f09b78aec128422de09402e3504809ef5a0adacf
4
+ data.tar.gz: f4b9bd0eec1427ba964d6affd2d3ec0e84126070faadd60cb7b6e51e7979a2ba
5
5
  SHA512:
6
- metadata.gz: fceccde2ac9e59dad730915436bd9d8fc2193316c8ce494e76227ac6f64de4bbffa448adc06f70f811a3c869c4b767d489ad750aff41e942ecc4afdc3545b4cd
7
- data.tar.gz: b881d68c49c2e9cccea155e021aafcaad68ec2df3d48c9c78afac833b96e8c0cc325c174bf34660733ed64570501477351f8b8bf5672290fdd1ed10cf1ab41f3
6
+ metadata.gz: 75f8bb22dafa4d3e67bcc198b804ce85a76705696d0f46f7d9a22fe7c2c97e7af9174304778c808cf00e502cac9f403d8b25d3c9be825b3e963bb042e24d593c
7
+ data.tar.gz: 201be369574e67efe1557b2e396fb2aa1e09faad3415d0b88efe9467d6a9137ede50c7b072d3859c09e5ed63eb1df6369748a1fb247146fca451a1a823878948
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Adrian Marin
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -6,4 +6,4 @@ module ClassVariants
6
6
  end
7
7
  end
8
8
  end
9
- end
9
+ end
@@ -1,45 +1,67 @@
1
- class ClassVariants::Instance
2
- attr_reader :classes
3
- attr_reader :variants
4
- attr_reader :defaults
5
-
6
- def initialize(classes = "", variants: {}, defaults: {})
7
- @classes = classes
8
- @variants = expand_boolean_variants(variants)
9
- @defaults = defaults
10
- end
1
+ module ClassVariants
2
+ class Instance
3
+ attr_reader :base, :variants, :compound_variants, :defaults
4
+
5
+ # rubocop:disable Naming/VariableName
6
+ def initialize(classes = nil, base: nil, variants: {}, compoundVariants: [], compound_variants: [], defaults: {})
7
+ warn <<~MSG if classes
8
+ (ClassVariants) DEPRECATION WARNING: Use of positional argument for default classes is deprecated
9
+ and will be removed in the next version. Use the `base` keyword argument instead.
10
+ MSG
11
+
12
+ warn <<~MSG unless compoundVariants.empty?
13
+ (ClassVariants) DEPRECATION WARNING: Use of `compoundVariants` keyword argument is deprecated
14
+ and will be removed in the next version. Use the `compound_variant` instead.
15
+ MSG
16
+
17
+ @base = base || classes
18
+ @variants = expand_boolean_variants(variants)
19
+ @compound_variants = compound_variants.empty? ? compoundVariants : compound_variants
20
+ @defaults = defaults
21
+ end
22
+ # rubocop:enable Naming/VariableName
23
+
24
+ def render(**overrides)
25
+ # Start with our default classes
26
+ result = [@base]
11
27
 
12
- def render(**overrides)
13
- # Start with our default classes
14
- result = [@classes]
28
+ # Then merge the passed in overrides on top of the defaults
29
+ selected = @defaults.merge(overrides)
15
30
 
16
- # Then merge the passed in overrides on top of the defaults
17
- @defaults.merge(overrides)
18
- .each do |variant_type, variant|
31
+ selected.each do |variant_type, variant|
19
32
  # dig the classes out and add them to the result
20
33
  result << @variants.dig(variant_type, variant)
21
34
  end
22
35
 
23
- # Compact out any nil values we may have dug up
24
- result.compact!
36
+ @compound_variants.each do |compound_variant|
37
+ if (compound_variant.keys - [:class]).all? { |key| selected[key] == compound_variant[key] }
38
+ result << compound_variant[:class]
39
+ end
40
+ end
25
41
 
26
- # Return the final token list
27
- result.join " "
28
- end
42
+ # Compact out any nil values we may have dug up
43
+ result.compact!
44
+
45
+ # Return the final token list
46
+ result.join " "
47
+ end
48
+
49
+ private
29
50
 
30
- private
51
+ def expand_boolean_variants(variants)
52
+ expanded = variants.map do |key, value|
53
+ case value
54
+ when String
55
+ s_key = key.to_s
56
+ {s_key.delete_prefix("!").to_sym => {!s_key.start_with?("!") => value}}
57
+ else
58
+ {key => value}
59
+ end
60
+ end
31
61
 
32
- def expand_boolean_variants(variants)
33
- variants.each.map { |key, value|
34
- case value
35
- when String
36
- s_key = key.to_s
37
- { s_key.delete_prefix("!").to_sym => { !s_key.start_with?("!") => value } }
38
- else
39
- { key => value }
62
+ expanded.reduce do |output, next_variant|
63
+ output.merge!(next_variant) { |_key, v1, v2| v1.merge!(v2) }
40
64
  end
41
- }.reduce do |variants, more_variants|
42
- variants.merge!(more_variants) { |_key, v1, v2| v1.merge!(v2) }
43
65
  end
44
66
  end
45
67
  end
@@ -1,12 +1,12 @@
1
- require 'rails/railtie'
1
+ require "rails/railtie"
2
2
 
3
3
  module ClassVariants
4
4
  class Railtie < ::Rails::Railtie
5
- initializer "class_variants.action_view" do |app|
5
+ initializer "class_variants.action_view" do
6
6
  ActiveSupport.on_load :action_view do
7
7
  require "class_variants/action_view/helpers"
8
8
  include ClassVariants::ActionView::Helpers
9
9
  end
10
10
  end
11
11
  end
12
- end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module ClassVariants
2
- VERSION = "0.0.6" unless const_defined?(:VERSION)
2
+ VERSION = "0.0.8".freeze
3
3
  end
@@ -5,8 +5,8 @@ require "class_variants/railtie" if defined?(Rails)
5
5
 
6
6
  module ClassVariants
7
7
  class << self
8
- def build(classes, **args)
9
- Instance.new classes, **args
8
+ def build(...)
9
+ Instance.new(...)
10
10
  end
11
11
  end
12
- end
12
+ end
data/readme.md ADDED
@@ -0,0 +1,178 @@
1
+ # Class variants
2
+
3
+ We ❤️ Tailwind CSS but sometimes it's difficult to manage the state of some elements using conditionals. `class_variants` is a tiny helper that should enable you to create, configure, and apply different variants of elements as classes.
4
+
5
+ Inspired by [variant-classnames](https://github.com/mattvalleycodes/variant-classnames) ✌️
6
+
7
+ ## Quicklinks
8
+
9
+ * [DRY up your tailwind CSS using this awesome gem](https://www.youtube.com/watch?v=cFcwNH6x77g)
10
+
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'class_variants'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ ```
23
+ $ bundle
24
+ ```
25
+
26
+ Or install it yourself as:
27
+
28
+ ```
29
+ $ gem install class_variants
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ We create an object from the class or helper where we define the configuration using four arguments:
35
+
36
+ 1. The `base` keyword argument with default classes that should be applied to each variant.
37
+ 1. The `variants` keyword argument where we declare the variants with their option and classes.
38
+ 1. The `compound_variants` keyword argument where we declare the compound variants with their conditions and classes
39
+ 1. The `defaults` keyword argument (optional) where we declare the default value for each variant.
40
+
41
+ ## Example
42
+
43
+ Below we implement the [button component](https://tailwindui.com/components/application-ui/elements/buttons) from Tailwind UI.
44
+
45
+ ```ruby
46
+ # Define the variants and defaults
47
+ button_classes = ClassVariants.build(
48
+ base: "inline-flex items-center rounded border border-transparent font-medium text-white hover:text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2",
49
+ variants: {
50
+ size: {
51
+ sm: "px-2.5 py-1.5 text-xs",
52
+ md: "px-3 py-2 text-sm",
53
+ lg: "px-4 py-2 text-sm",
54
+ xl: "px-4 py-2 text-base",
55
+ },
56
+ color: {
57
+ indigo: "bg-indigo-600 hover:bg-indigo-700 focus:ring-indigo-500",
58
+ red: "bg-red-600 hover:bg-red-700 focus:ring-red-500",
59
+ blue: "bg-blue-600 hover:bg-blue-700 focus:ring-blue-500",
60
+ },
61
+ # A variant whose value is a string will be expanded into a hash that looks
62
+ # like { true => "classes" }
63
+ block: "w-full justify-center",
64
+ # Unless the key starts with !, in which case it will expand into
65
+ # { false => "classes" }
66
+ "!block": "w-auto",
67
+ },
68
+ defaults: {
69
+ size: :md,
70
+ color: :indigo,
71
+ icon: false
72
+ }
73
+ )
74
+
75
+ # Call it with our desired variants
76
+ button_classes.render(color: :blue, size: :sm)
77
+ button_classes.render
78
+ button_classes.render(color: :red, size: :xl, icon: true)
79
+ ```
80
+
81
+ ### Compound Variants
82
+
83
+ ```ruby
84
+ button_classes = ClassVariants.build(
85
+ base: "inline-flex items-center rounded",
86
+ variants: {
87
+ color: {
88
+ red: "bg-red-600",
89
+ blue: "bg-blue-600",
90
+ },
91
+ border: "border"
92
+ },
93
+ compound_variants: [
94
+ { color: :red, border: true, class: "border-red-800" },
95
+ { color: :blue, border: true, class: "border-blue-800" }
96
+ ]
97
+ )
98
+
99
+ button_classes.render(color: :red) # => "inline-flex items-center rounded bg-red-600"
100
+ button_classes.render(color: :red, border: true) # => "inline-flex items-center rounded bg-red-600 border border-red-600"
101
+ ```
102
+
103
+ ## Use with Rails
104
+
105
+ ```ruby
106
+ # Somewhere in your helpers
107
+ def button_classes(classes, **args)
108
+ class_variants(
109
+ base: "inline-flex items-center rounded border border-transparent font-medium text-white hover:text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2",
110
+ variants: {
111
+ size: {
112
+ sm: "px-2.5 py-1.5 text-xs",
113
+ md: "px-3 py-2 text-sm",
114
+ lg: "px-4 py-2 text-sm",
115
+ xl: "px-4 py-2 text-base",
116
+ },
117
+ color: {
118
+ indigo: "bg-indigo-600 hover:bg-indigo-700 focus:ring-indigo-500",
119
+ red: "bg-red-600 hover:bg-red-700 focus:ring-red-500",
120
+ blue: "bg-blue-600 hover:bg-blue-700 focus:ring-blue-500",
121
+ },
122
+ },
123
+ defaults: {
124
+ size: :md,
125
+ color: :indigo,
126
+ }
127
+ )
128
+ end
129
+ ```
130
+
131
+ ```erb
132
+ <!-- In your views -->
133
+ <%= link_to :Avo, "https://avohq.io", class: button_classes.render(color: :blue, size: :sm) %>
134
+ <%= link_to :Avo, "https://avohq.io", class: button_classes.render %>
135
+ <%= link_to :Avo, "https://avohq.io", class: button_classes.render(color: :red, size: :xl) %>
136
+ ```
137
+
138
+ ### Output
139
+
140
+ ![](sample.jpg)
141
+
142
+ ## Other packages
143
+
144
+ - [`active_storage-blurhash`](https://github.com/avo-hq/active_storage-blurhash) - A plug-n-play [blurhash](https://blurha.sh/) integration for images stored in ActiveStorage
145
+ - [`avo`](https://github.com/avo-hq/avo) - Build Content management systems with Ruby on Rails
146
+ - [`prop_initializer`](https://github.com/avo-hq/prop_initializer) - A flexible tool for defining properties on Ruby classes.
147
+ - [`stimulus-confetti`](https://github.com/avo-hq/stimulus-confetti) - The easiest way to add confetti to your StimulusJS app
148
+
149
+ ## Try Avo ⭐️
150
+
151
+ If you enjoyed this gem try out [Avo](https://github.com/avo-hq/avo). It helps developers build Internal Tools, Admin Panels, CMSes, CRMs, and any other type of Business Apps 10x faster on top of Ruby on Rails.
152
+
153
+ [![](./logo-on-white.png)](https://github.com/avo-hq/avo)
154
+
155
+ ## Contributing
156
+
157
+ 1. Fork it `git clone https://github.com/avo-hq/class_variants`
158
+ 1. Create your feature branch `git checkout -b my-new-feature`
159
+ 1. Commit your changes `git commit -am 'Add some feature'`
160
+ 1. Push to the branch `git push origin my-new-feature`
161
+ 1. Create new Pull Request
162
+
163
+ ## License
164
+ This package is available as open source under the terms of the MIT License.
165
+
166
+ ## Cutting a release
167
+
168
+ ```bash
169
+ # Build
170
+ gem build class_variants.gemspec -o latest.gem
171
+ # Publish
172
+ gem push --host https://rubygems.org/ ./latest.gem
173
+ # Cut a tag
174
+ git tag v0.0.6 -a -m "Version 0.0.6"
175
+ # Push tag to repo
176
+ git push --follow-tags
177
+ # Go to the repo and generate release from tag
178
+ ```
metadata CHANGED
@@ -1,47 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class_variants
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Marin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-21 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: benchmark-ips
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
+ dependencies: []
27
13
  description: Easily configure styles and apply them as classes.
28
14
  email: adrian@adrianthedev.com
29
15
  executables: []
30
16
  extensions: []
31
17
  extra_rdoc_files: []
32
18
  files:
19
+ - LICENSE
33
20
  - lib/class_variants.rb
34
21
  - lib/class_variants/action_view/helpers.rb
35
22
  - lib/class_variants/instance.rb
36
23
  - lib/class_variants/railtie.rb
37
24
  - lib/class_variants/version.rb
25
+ - readme.md
38
26
  homepage: https://github.com/avo-hq/class_variants
39
27
  licenses:
40
28
  - MIT
41
29
  metadata:
42
- bug_tracker_uri: https://github.com/avo-hq/class_variants/issues
43
30
  homepage_uri: https://github.com/avo-hq/class_variants
44
31
  source_code_uri: https://github.com/avo-hq/class_variants
32
+ bug_tracker_uri: https://github.com/avo-hq/class_variants/issues
33
+ changelog_uri: https://github.com/avo-hq/class_variants/releases
45
34
  post_install_message:
46
35
  rdoc_options: []
47
36
  require_paths:
@@ -50,14 +39,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
50
39
  requirements:
51
40
  - - ">="
52
41
  - !ruby/object:Gem::Version
53
- version: '0'
42
+ version: '3.0'
54
43
  required_rubygems_version: !ruby/object:Gem::Requirement
55
44
  requirements:
56
45
  - - ">="
57
46
  - !ruby/object:Gem::Version
58
47
  version: '0'
59
48
  requirements: []
60
- rubygems_version: 3.3.3
49
+ rubygems_version: 3.4.10
61
50
  signing_key:
62
51
  specification_version: 4
63
52
  summary: Easily configure styles and apply them as classes.