Skip to content

Instantly share code, notes, and snippets.

@alessandro-fazzi
Created November 23, 2022 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alessandro-fazzi/42afda7c689466b80631771c9799f4f2 to your computer and use it in GitHub Desktop.
Save alessandro-fazzi/42afda7c689466b80631771c9799f4f2 to your computer and use it in GitHub Desktop.
avo-qh/class_variants without the gem
ButtonClasses = Struct.new(:classes, :variants, :defaults, keyword_init: true) do |klass|
def render(**settings)
result = []
# Add the default classes if any provided
result << classes if classes
# Keep the applied variants so we can later apply the defaults
applied_options = []
# Go through each keys provided
settings
.filter { |key, _value| variants.keys.include? key }
.each do |key, value|
applied_options << key
result << variants[key][value]
end
result.join " " unless defaults.present?
defaults
.reject { |key, _value| applied_options.include? key }
.each do |key, key_to_use|
result << variants[key][key_to_use] if variants[key].present?
end
result.join " "
end
end
button_classes = ButtonClasses.new(
classes: "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",
variants: {
size: {
sm: "px-2.5 py-1.5 text-xs",
md: "px-3 py-2 text-sm",
lg: "px-4 py-2 text-sm",
xl: "px-4 py-2 text-base",
},
color: {
indigo: "bg-indigo-600 hover:bg-indigo-700 focus:ring-indigo-500",
red: "bg-red-600 hover:bg-red-700 focus:ring-red-500",
blue: "bg-blue-600 hover:bg-blue-700 focus:ring-blue-500",
},
},
defaults: {
size: :md,
color: :indigo,
}
)
p button_classes.render(color: :blue, size: :sm)
# "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 bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 px-2.5 py-1.5 text-xs"
p button_classes.render
# "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 px-3 py-2 text-sm bg-indigo-600 hover:bg-indigo-700 focus:ring-indigo-500"
p button_classes.render(color: :red, size: :xl)
# "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 bg-red-600 hover:bg-red-700 focus:ring-red-500 px-4 py-2 text-base"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment