Skip to content

Commit

Permalink
Merge pull request #23 from javierav/add-merge
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianthedev authored Nov 19, 2024
2 parents d5bc1a9 + f34a069 commit c9f7a2f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## Unreleased
- Add support for merging ([#23](https://github.com/avo-hq/class_variants/pull/23))

## 1.0.0 (2024-11-13)
- Add support for slots ([#15](https://github.com/avo-hq/class_variants/pull/15))
- Allow passing additional classes when render ([#17](https://github.com/avo-hq/class_variants/pull/17))
Expand Down
30 changes: 23 additions & 7 deletions lib/class_variants/instance.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
module ClassVariants
class Instance
def initialize(**options, &block)
def initialize(...)
@bases = []
@variants = []
@defaults = {}

merge(...)
end

def merge(**options, &block)
raise ArgumentError, "Use of hash config and code block is not supported" if !options.empty? && block_given?

@base = options.empty? ? {} : {default: options.fetch(:base, nil)}
@variants = expand_variants(options.fetch(:variants, {})) + expand_compound_variants(options.fetch(:compound_variants, []))
@defaults = options.fetch(:defaults, {})
(base = options.fetch(:base, nil)) && @bases << {class: base, slot: :default}
@variants += [
expand_variants(options.fetch(:variants, {})),
expand_compound_variants(options.fetch(:compound_variants, []))
].inject(:+)
@defaults.merge!(options.fetch(:defaults, {}))

instance_eval(&block) if block_given?

self
end

def render(slot = :default, **overrides)
classes = overrides.delete(:class)
result = []

# Start with our default classes
result = [@base[slot]]
@bases.each do |base|
result << base[:class] if base[:slot] == slot
end

# Then merge the passed in overrides on top of the defaults
criteria = @defaults.merge(overrides)
Expand Down Expand Up @@ -44,10 +60,10 @@ def base(klass = nil, &block)

if block_given?
with_slots(&block).each do |slot|
@base[slot[:slot]] = slot[:class]
@bases << slot
end
else
@base[:default] = klass
@bases << {slot: :default, class: klass}
end
end

Expand Down
71 changes: 71 additions & 0 deletions test/merge_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require "test_helper"

class MergeTest < Minitest::Test
def test_hash_merge
cv = ClassVariants.build(
base: "rounded",
variants: {
color: {
primary: "bg-blue-500",
secondary: "bg-purple-500",
success: "bg-green-500"
}
},
default: {
color: :primary
}
)
cv.merge(
base: "border",
variants: {
color: {
primary: "bg-blue-700",
secondary: "bg-purple-700"
}
},
defaults: {
color: :secondary
}
)

assert_equal "rounded border bg-purple-500 bg-purple-700", cv.render
end

def test_block_merge
cv = ClassVariants.build do
base do
slot :root, class: "rounded"
slot :title, class: "font-bold"
end

variant variant: :outlined do
slot :root, class: "border-red-700"
slot :title, class: "text-red-700"
end

variant variant: :filled do
slot :root, class: "bg-red-100"
slot :title, class: "text-red-900"
end

defaults variant: :outlined
end

cv.merge do
base do
slot :root, class: "mb-4"
slot :title, class: "mb-1"
end

variant variant: :filled do
slot :root, class: "dark:bg-red-800"
slot :title, class: "dark:text-red-50"
end

defaults variant: :filled
end

assert_equal "rounded mb-4 bg-red-100 dark:bg-red-800", cv.render(:root)
assert_equal "font-bold mb-1 text-red-900 dark:text-red-50", cv.render(:title)
end
end

0 comments on commit c9f7a2f

Please sign in to comment.