From 7e8c86d16bc6a51062e10a94b46f2ea63d89a73e Mon Sep 17 00:00:00 2001 From: Javier Aranda Date: Thu, 7 Dec 2023 12:58:47 +0100 Subject: [PATCH] Implements compound variants --- lib/class_variants/instance.rb | 18 +++++++++++++----- readme.md | 25 ++++++++++++++++++++++++- test/class_variants_test.rb | 16 ++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/class_variants/instance.rb b/lib/class_variants/instance.rb index c60d25e..bca5f97 100644 --- a/lib/class_variants/instance.rb +++ b/lib/class_variants/instance.rb @@ -3,9 +3,10 @@ class ClassVariants::Instance attr_reader :variants attr_reader :defaults - def initialize(classes = "", variants: {}, defaults: {}) + def initialize(classes = "", variants: {}, compoundVariants: [], defaults: {}) @classes = classes @variants = expand_boolean_variants(variants) + @compoundVariants = compoundVariants @defaults = defaults end @@ -14,11 +15,18 @@ def render(**overrides) result = [@classes] # Then merge the passed in overrides on top of the defaults - @defaults.merge(overrides) - .each do |variant_type, variant| - # dig the classes out and add them to the result - result << @variants.dig(variant_type, variant) + selected = @defaults.merge(overrides) + + selected.each do |variant_type, variant| + # dig the classes out and add them to the result + result << @variants.dig(variant_type, variant) + end + + @compoundVariants.each do |compound_variant| + if (compound_variant.keys - [:class]).all? { |key| selected[key] == compound_variant[key] } + result << compound_variant[:class] end + end # Compact out any nil values we may have dug up result.compact! diff --git a/readme.md b/readme.md index 1a160aa..0c7a8bc 100644 --- a/readme.md +++ b/readme.md @@ -31,10 +31,11 @@ $ gem install class_variants ## Usage -We create an object from the class or helper where we define the configuration using three arguments: +We create an object from the class or helper where we define the configuration using four arguments: 1. The default classes that should be applied to each variant 1. The `variants` keyword argument where we declare the variants with their option and classes +1. The `compoundVariants` keyword argument where we declare the compound variants with their conditions and classes 1. The `defaults` keyword argument (optional) where we declare the default value for each variant. ## Example @@ -77,6 +78,28 @@ button_classes.render button_classes.render(color: :red, size: :xl, icon: true) ``` +### Compound Variants + +```ruby +button_classes = ClassVariants.build( + "inline-flex items-center rounded", + variants: { + color: { + red: "bg-red-600", + blue: "bg-blue-600", + }, + border: "border" + }, + compoundVariants: [ + { color: :red, border: true, class: "border-red-800" }, + { color: :blue, border: true, class: "border-blue-800" } + ] +) + +button_classes.render(color: :red) # => "inline-flex items-center rounded bg-red-600" +button_classes.render(color: :red, border: true) # => "inline-flex items-center rounded bg-red-600 border border-red-600" +``` + ## Use with Rails ```ruby diff --git a/test/class_variants_test.rb b/test/class_variants_test.rb index 4fcf61d..c801df8 100644 --- a/test/class_variants_test.rb +++ b/test/class_variants_test.rb @@ -13,9 +13,14 @@ def setup red: "text-red", green: "text-green" }, + ring: "focus:ring-2", visible: "inline-block", "!visible": "hidden" }, + compoundVariants: [ + { ring: true, color: :red, class: "focus:ring-red-600" }, + { ring: true, color: :green, class: "focus:ring-green-600" } + ], defaults: { size: :md } @@ -38,4 +43,15 @@ def test_boolean_variants assert_equal "rounded border text-md inline-block", @cv.render(visible: true) assert_equal "rounded border text-md hidden", @cv.render(visible: false) end + + def test_compound_variants + assert_equal( + "rounded border text-md focus:ring-2 text-red focus:ring-red-600", + @cv.render(ring: true, color: :red) + ) + assert_equal( + "rounded border text-md focus:ring-2 text-green focus:ring-green-600", + @cv.render(ring: true, color: :green) + ) + end end