class_variants 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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.