Class: Component

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Attributes, ActiveModel::Model
Defined in:
app/lib/component.rb

Overview

The Ancestral Component

All components descend from this class. It provides:

  • ActiveModel::Attributes for declarative attribute definitions

  • Named slots via the ‘slot` class macro

  • The ‘render_in` contract: block capture, HTML safety, dev annotations

See: specs/the-holy-view-spec.md, specs/the-holy-slot-spec.md

Constant Summary collapse

HTML_OPTIONS =

HTML pass-through keys that bypass ActiveModel attributes

%i[id class data style role tabindex title aria target rel].to_set.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**kwargs) ⇒ Component

Returns a new instance of Component.



21
22
23
24
# File 'app/lib/component.rb', line 21

def initialize(**kwargs)
  @html_options = kwargs.extract!(*HTML_OPTIONS)
  super(**kwargs)
end

Class Method Details

.default(**overrides) ⇒ Object



26
27
28
29
30
31
# File 'app/lib/component.rb', line 26

def self.default(**overrides)
  overrides.each do |name, value|
    type = attribute_types.fetch(name.to_s).type
    attribute name, type, default: value
  end
end

.slot(name) ⇒ Object



33
34
35
36
37
38
39
# File 'app/lib/component.rb', line 33

def self.slot(name)
  self.slot_names = slot_names + [ name ]

  define_method(name) { |&block|
    @slots[name] = @view_context.capture(&block)
  }
end

Instance Method Details

#render_in(context, &block) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/lib/component.rb', line 41

def render_in(context, &block)
  @view_context = context
  @slots = {}
  @content = context.capture(self, &block) if block
  @content = ERB::Util.html_escape(@content) unless @content.nil? || @content.html_safe?

  if Rails.env.development?
    "<!-- BEGIN #{self.class.name} -->#{self}<!-- END #{self.class.name} -->".html_safe
  else
    to_s
  end
end

#to_sObject

Raises:

  • (NotImplementedError)


54
55
56
# File 'app/lib/component.rb', line 54

def to_s
  raise NotImplementedError
end