module Spark::Component::Attribute
Public Class Methods
All components and elements will support these attributes
# File lib/spark/component/attribute.rb, line 51 def self.included(base) base.extend(ClassMethods) end
# File lib/spark/component/attribute.rb, line 55 def initialize(*attrs) initialize_attributes(*attrs) end
Public Instance Methods
Easy reference a tag's aria attributes
# File lib/spark/component/attribute.rb, line 178 def aria tag_attrs.aria end
Accepts an array of instance variables and returns a hash of variables with their values, if they are set.
Example:
@a = 1 @b = nil attr_hash(:a, :b, :c) => { a: 1 }
Example use case:
<div data=“<%= attr_hash
(:remote, :method)) %>”>
# File lib/spark/component/attribute.rb, line 143 def attr_hash(*args) args.each_with_object({}) do |name, obj| val = instance_variable_get(:"@#{name}") next if val.nil? # Stringify true values to ensure the value is set in tag attributes # This helps tags write `data-foo="true"` instead of `data-foo` obj[name] = val == true ? val.to_s : val end end
# File lib/spark/component/attribute.rb, line 122 def attribute(name) attributes[name] end
# File lib/spark/component/attribute.rb, line 126 def attributes attr_hash(*self.class.attributes.keys) end
Easy reference a tag's classname
# File lib/spark/component/attribute.rb, line 168 def classname tag_attrs.classname end
Easy reference a tag's data attributes
# File lib/spark/component/attribute.rb, line 173 def data tag_attrs.data end
Takes attributes passed to a component or element and assigns values to other attributes as defined in their group.
For example, with an attribute group:
theme: { notice: { icon: "message", color: "blue" } error: { icon: "error", color: "red" } }
If the attributes include `theme: :notice`, the icon and color attributes would default to “message” and “blue”, but could be overriden if the user set values for them.
# File lib/spark/component/attribute.rb, line 91 def initialize_attribute_default_groups(attrs) self.class.attribute_default_groups.each do |group, group_options| # Determine what group name is set for this attribute. # In the above example the group would be `theme` and the name # would be the value passed for `theme`, or its default value. # # So `name` might be `:notice`. name = attrs[group] || self.class.attributes[group] # Normalize name for hash lookup. to_s.to_sym converts booleans as well. name = name.to_s.to_sym unless name.nil? # Get defaults to set from group name # In the above example, if the name were `notice` this would be the hash # `{ icon: "message", color: "blue" }` defaults = group_options[name] next unless defaults unless defaults.is_a?(Hash) raise("In argument group `:#{name}`, value `#{defaults}` must be a hash.") end defaults.each do |key, value| if attrs[key].nil? attrs[key] = value instance_variable_set(:"@#{key}", value) end end end end
Assign instance variables for attributes defined by the class
# File lib/spark/component/attribute.rb, line 60 def initialize_attributes(attrs = nil) attrs ||= {} # Filter out attributes which aren't defined by class method attrs.select! { |key, _value| self.class.attributes.keys.include?(key) } initialize_attribute_default_groups(attrs) self.class.attributes.each do |name, default| default = (!default.nil? ? default : nil) value = attrs[name].nil? ? default : attrs[name] if set?(value) instance_variable_set(:"@#{name}", value) end end end
Initialize tag attributes
If a component or element defines tag_attributes, aria_attributes, or data_attributes Automatically assign add arguments to tag_attrs
# File lib/spark/component/attribute.rb, line 158 def tag_attrs return @tag_attrs if @tag_attrs @tag_attrs = TagAttr.new.add(attr_hash(*self.class.tag_attributes)) @tag_attrs.add(aria: attr_hash(*self.class.aria_attributes)) @tag_attrs.add(data: attr_hash(*self.class.data_attributes)) @tag_attrs end
Private Instance Methods
Help filter out attributes with blank values. Not using `blank?` to avoid Rails requirement and because `false` is a valid value.
# File lib/spark/component/attribute.rb, line 187 def set?(value) !(value.nil? || value.respond_to?(:empty?) && value.empty?) end