Module: Spark::Component::Attribute

Included in:
Element::Base
Defined in:
lib/spark/component/attribute.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

All components and elements will support these attributes



51
52
53
# File 'lib/spark/component/attribute.rb', line 51

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#ariaObject

Easy reference a tag’s aria attributes



178
179
180
# File 'lib/spark/component/attribute.rb', line 178

def aria
  tag_attrs.aria
end

#attr_hash(*args) ⇒ Object

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)) %>”>



143
144
145
146
147
148
149
150
151
152
# 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) ⇒ Object



122
123
124
# File 'lib/spark/component/attribute.rb', line 122

def attribute(name)
  attributes[name]
end

#attributesObject



126
127
128
# File 'lib/spark/component/attribute.rb', line 126

def attributes
  attr_hash(*self.class.attributes.keys)
end

#classnameObject

Easy reference a tag’s classname



168
169
170
# File 'lib/spark/component/attribute.rb', line 168

def classname
  tag_attrs.classname
end

#dataObject

Easy reference a tag’s data attributes



173
174
175
# File 'lib/spark/component/attribute.rb', line 173

def data
  tag_attrs.data
end

#initialize(*attrs) ⇒ Object



55
56
57
# File 'lib/spark/component/attribute.rb', line 55

def initialize(*attrs)
  initialize_attributes(*attrs)
end

#initialize_attribute_default_groups(attrs) ⇒ Object

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.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 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) ⇒ Object

Assign instance variables for attributes defined by the class



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 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_attrsObject

Initialize tag attributes

If a component or element defines tag_attributes, aria_attributes, or data_attributes Automatically assign add arguments to tag_attrs



158
159
160
161
162
163
164
165
# 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