Class: SparkComponents::Element

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Validations
Defined in:
lib/spark_components/element.rb

Direct Known Subclasses

Component

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(view, attributes = nil, &block) ⇒ Element

Returns a new instance of Element.



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/spark_components/element.rb', line 138

def initialize(view, attributes = nil, &block)
  @view = view
  attributes ||= {}
  initialize_tag_attributes
  assign_tag_attributes(attributes)
  initialize_attributes(attributes)
  initialize_elements
  extend_view_methods
  after_init
  @yield = block_given? ? @view.capture(self, &block) : nil
  validate!
end

Instance Attribute Details

#attrObject (readonly)

Returns the value of attribute attr.



8
9
10
# File 'lib/spark_components/element.rb', line 8

def attr
  @attr
end

#parentsObject (readonly)

Returns the value of attribute parents.



8
9
10
# File 'lib/spark_components/element.rb', line 8

def parents
  @parents
end

#yieldObject

Returns the value of attribute yield.



7
8
9
# File 'lib/spark_components/element.rb', line 7

def yield
  @yield
end

Class Method Details

.add_class(*args) ⇒ Object



48
49
50
# File 'lib/spark_components/element.rb', line 48

def self.add_class(*args)
  tag_attributes[:class].add(*args)
end

.aria_attr(*args) ⇒ Object



56
57
58
# File 'lib/spark_components/element.rb', line 56

def self.aria_attr(*args)
  set_attr(:aria, *args)
end

.attribute(*args) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/spark_components/element.rb', line 22

def self.attribute(*args)
  args.each_with_object({}) do |arg, obj|
    if arg.is_a?(Hash)
      arg.each do |attr, default|
        obj[attr.to_sym] = default
        set_attribute(attr.to_sym, default: default)
      end
    else
      obj[arg.to_sym] = nil
      set_attribute(arg.to_sym)
    end
  end
end

.attributesObject



14
15
16
# File 'lib/spark_components/element.rb', line 14

def self.attributes
  @attributes ||= {}
end

.base_class(name) ⇒ Object



44
45
46
# File 'lib/spark_components/element.rb', line 44

def self.base_class(name)
  tag_attributes[:class].base = name
end

.data_attr(*args) ⇒ Object



52
53
54
# File 'lib/spark_components/element.rb', line 52

def self.data_attr(*args)
  set_attr(:data, *args)
end

.element(name, multiple: false, component: nil, &config) ⇒ Object

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/MethodLength rubocop:disable Metrics/PerceivedComplexity



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/spark_components/element.rb', line 81

def self.element(name, multiple: false, component: nil, &config)
  plural_name = name.to_s.pluralize.to_sym if multiple

  # Extend components by string or class; e.g., "core/header" or Core::HeaderComponent
  component = "#{component}_component".classify.constantize if component.is_a?(String)

  elements[name] = {
    multiple: plural_name || false, class: Class.new(component || Element, &config)
  }

  define_method_or_raise(name) do |attributes = nil, &block|
    return get_instance_variable(multiple ? plural_name : name) unless attributes || block

    element = self.class.elements[name][:class].new(@view, attributes, &block)
    element.parent = self

    if element.respond_to?(:render)
      element.before_render
      element.yield = element.render
    end

    if multiple
      get_instance_variable(plural_name) << element
    else
      set_instance_variable(name, element)
    end
  end

  return if !multiple || name == plural_name

  define_method_or_raise(plural_name) do
    get_instance_variable(plural_name)
  end
end

.elementsObject



18
19
20
# File 'lib/spark_components/element.rb', line 18

def self.elements
  @elements ||= {}
end

.inherited(subclass) ⇒ Object



129
130
131
132
133
134
135
136
# File 'lib/spark_components/element.rb', line 129

def self.inherited(subclass)
  attributes.each { |name, options| subclass.set_attribute(name, options.dup) }
  elements.each   { |name, options| subclass.elements[name] = options.dup }

  subclass.tag_attributes.merge!(tag_attributes.each_with_object({}) do |(k, v), obj|
    obj[k] = v.dup
  end)
end

.model_nameObject



10
11
12
# File 'lib/spark_components/element.rb', line 10

def self.model_name
  ActiveModel::Name.new(SparkComponents::Element)
end

.set_attr(name, *args) ⇒ Object



64
65
66
# File 'lib/spark_components/element.rb', line 64

def self.set_attr(name, *args)
  tag_attributes[name].add(attribute(*args))
end

.set_attribute(name, default: nil) ⇒ Object



36
37
38
39
40
41
42
# File 'lib/spark_components/element.rb', line 36

def self.set_attribute(name, default: nil)
  attributes[name] = { default: default }

  define_method_or_raise(name) do
    get_instance_variable(name)
  end
end

.tag_attr(*args) ⇒ Object



60
61
62
# File 'lib/spark_components/element.rb', line 60

def self.tag_attr(*args)
  set_attr(:tag, *args)
end

.tag_attributesObject



68
69
70
71
72
73
74
75
# File 'lib/spark_components/element.rb', line 68

def self.tag_attributes
  @tag_attributes ||= {
    class: SparkComponents::Attributes::Classname.new,
    data: SparkComponents::Attributes::Data.new,
    aria: SparkComponents::Attributes::Aria.new,
    tag: SparkComponents::Attributes::Hash.new
  }
end

Instance Method Details

#add_class(*args) ⇒ Object



172
173
174
# File 'lib/spark_components/element.rb', line 172

def add_class(*args)
  classnames.add(*args)
end

#after_initObject



151
# File 'lib/spark_components/element.rb', line 151

def after_init; end

#aria_attr(*args) ⇒ Object



184
185
186
# File 'lib/spark_components/element.rb', line 184

def aria_attr(*args)
  @tag_attributes[:aria].add(*args)
end

#attrs(add_class: true) ⇒ Object



192
193
194
195
196
197
198
199
200
201
# File 'lib/spark_components/element.rb', line 192

def attrs(add_class: true)
  atr = Attributes::Hash.new
  # attrtiubte order: id, class, data-, aria-, misc tag attributes
  atr[:id] = tag_attr.delete(:id)
  atr[:class] = classnames if add_class
  atr.merge!(data_attr.collapse)
  atr.merge!(aria_attr.collapse)
  atr.merge!(tag_attr)
  atr
end

#base_class(name = nil) ⇒ Object



167
168
169
170
# File 'lib/spark_components/element.rb', line 167

def base_class(name = nil)
  classnames.base = name unless name.nil?
  classnames.base
end

#before_renderObject



153
# File 'lib/spark_components/element.rb', line 153

def before_render; end

#classnamesObject



163
164
165
# File 'lib/spark_components/element.rb', line 163

def classnames
  @tag_attributes[:class]
end

#data_attr(*args) ⇒ Object



180
181
182
# File 'lib/spark_components/element.rb', line 180

def data_attr(*args)
  @tag_attributes[:data].add(*args)
end

#join_class(name, separator: "-") ⇒ Object



176
177
178
# File 'lib/spark_components/element.rb', line 176

def join_class(name, separator: "-")
  [base_class, name].join(separator) unless base_class.nil?
end

#parentObject



159
160
161
# File 'lib/spark_components/element.rb', line 159

def parent
  @parents.last
end

#parent=(obj) ⇒ Object



155
156
157
# File 'lib/spark_components/element.rb', line 155

def parent=(obj)
  @parents = [obj.parents, obj].flatten.compact
end

#tag_attr(*args) ⇒ Object



188
189
190
# File 'lib/spark_components/element.rb', line 188

def tag_attr(*args)
  @tag_attributes[:tag].add(*args)
end

#to_sObject



203
204
205
# File 'lib/spark_components/element.rb', line 203

def to_s
  @yield
end