module Spark::Component::Attribute

Public Class Methods

included(base) click to toggle source

All components and elements will support these attributes

# File lib/spark/component/attribute.rb, line 51
def self.included(base)
  base.extend(ClassMethods)
end
new(*attrs) click to toggle source
# File lib/spark/component/attribute.rb, line 55
def initialize(*attrs)
  initialize_attributes(*attrs)
end

Public Instance Methods

aria() click to toggle source

Easy reference a tag's aria attributes

# File lib/spark/component/attribute.rb, line 178
def aria
  tag_attrs.aria
end
attr_hash(*args) click to toggle source

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
attribute(name) click to toggle source
# File lib/spark/component/attribute.rb, line 122
def attribute(name)
  attributes[name]
end
attributes() click to toggle source
# File lib/spark/component/attribute.rb, line 126
def attributes
  attr_hash(*self.class.attributes.keys)
end
classname() click to toggle source

Easy reference a tag's classname

# File lib/spark/component/attribute.rb, line 168
def classname
  tag_attrs.classname
end
data() click to toggle source

Easy reference a tag's data attributes

# File lib/spark/component/attribute.rb, line 173
def data
  tag_attrs.data
end
initialize_attribute_default_groups(attrs) click to toggle source

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
initialize_attributes(attrs = nil) click to toggle source

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
tag_attrs() click to toggle source

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

set?(value) click to toggle source

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