Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions bench.rb
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "benchmark/ips"
require "class_variants"

module ClassVariants
end
RubyVM::YJIT.enable

require_relative "lib/class_variants/instance"
button_classes = ClassVariants.build(
base: "rounded border-2 focus:ring-blue-500",
variants: {
size: {
sm: "text-xs px-1.5 py-1",
base: "text-sm px-2 py-1.5",
lg: "text-base px-3 py-2"
},
color: {
white: "text-white bg-transparent border-white",
blue: "text-white bg-blue-500 border-blue-700 hover:bg-blue-600",
red: "text-white bg-red-500 border-red-700 hover:bg-red-600"
},
block: "justify-center w-full",
"!block": "justify-between"
},
defaults: {
size: :base,
color: :white,
block: false
}
)

Benchmark.ips do |x|
button_classes = ClassVariants::Instance.new(
"rounded border-2 focus:ring-blue-500",
variants: {
size: {
sm: "text-xs px-1.5 py-1",
base: "text-sm px-2 py-1.5",
lg: "text-base px-3 py-2"
},
color: {
white: "text-white bg-transparent border-white",
blue: "text-white bg-blue-500 border-blue-700 hover:bg-blue-600",
red: "text-white bg-red-500 border-red-700 hover:bg-red-600"
},
block: "justify-center w-full",
"!block": "justify-between"
},
defaults: {
size: :base,
color: :white,
block: false
}
)
x.warmup = 5
x.time = 20

x.report("rendering only defaults") do
button_classes.render
Expand Down
2 changes: 2 additions & 0 deletions lib/class_variants.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require "class_variants/version"
require "class_variants/action_view/helpers"
require "class_variants/configuration"
Expand Down
2 changes: 2 additions & 0 deletions lib/class_variants/action_view/helpers.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ClassVariants
module ActionView
module Helpers
Expand Down
2 changes: 2 additions & 0 deletions lib/class_variants/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ClassVariants
class Configuration
def process_classes_with(&block)
Expand Down
2 changes: 2 additions & 0 deletions lib/class_variants/helper.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ClassVariants
module Helper
module ClassMethods
Expand Down
30 changes: 20 additions & 10 deletions lib/class_variants/instance.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# frozen_string_literal: true

module ClassVariants
class Instance
def initialize(...)
@bases = []
@variants = []
@defaults = {}
@slots = nil

merge(...)
end
Expand All @@ -17,7 +20,7 @@ def dup
end

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

(base = options.fetch(:base, nil)) && @bases << {class: base, slot: :default}
@variants += [
Expand All @@ -26,7 +29,7 @@ def merge(**options, &block)
].inject(:+)
@defaults.merge!(options.fetch(:defaults, {}))

instance_eval(&block) if block_given?
instance_eval(&block) if block

self
end
Expand All @@ -46,9 +49,15 @@ def render(slot = :default, **overrides)
@variants.each do |candidate|
next unless candidate[:slot] == slot

if (candidate.keys - [:class, :slot]).all? { |key| criteria[key] == candidate[key] }
result << candidate[:class]
match = false

candidate.each_key do |key|
next if key == :class || key == :slot
match = criteria[key] == candidate[key]
break unless match
end

result << candidate[:class] if match
Comment on lines -49 to +60
Copy link
Contributor Author

@joeldrapper joeldrapper Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the most impactful change. I think this is hit quite a lot when rendering. Using each_key means we can avoid allocating an array of the keys.

end

# add the passed in classes to the result
Expand All @@ -64,9 +73,9 @@ def render(slot = :default, **overrides)
private

def base(klass = nil, &block)
raise ArgumentError, "Use of positional argument and code block is not supported" if klass && block_given?
raise ArgumentError, "Use of positional argument and code block is not supported" if klass && block

if block_given?
if block
with_slots(&block).each do |slot|
@bases << slot
end
Expand All @@ -76,9 +85,9 @@ def base(klass = nil, &block)
end

def variant(**options, &block)
raise ArgumentError, "Use of class option and code block is not supported" if options.key?(:class) && block_given?
raise ArgumentError, "Use of class option and code block is not supported" if options.key?(:class) && block

if block_given?
if block
with_slots(&block).each do |slot|
@variants << options.merge(slot)
end
Expand All @@ -98,9 +107,10 @@ def slot(name = :default, **options)
end

def with_slots
@slots = []
new_slots = []
@slots = new_slots
yield
@slots
new_slots
end

def expand_variants(variants)
Expand Down
2 changes: 2 additions & 0 deletions lib/class_variants/railtie.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require "rails/railtie"

module ClassVariants
Expand Down
4 changes: 3 additions & 1 deletion lib/class_variants/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ClassVariants
VERSION = "1.1.0".freeze
VERSION = "1.1.0"
end
2 changes: 2 additions & 0 deletions lib/generators/class_variants/install/install_generator.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ClassVariants
module Generators
class InstallGenerator < Rails::Generators::Base
Expand Down
Loading