Class: ViewComponent::SlotV2

Inherits:
Object
  • Object
show all
Includes:
WithContentHelper
Defined in:
lib/view_component/slot_v2.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from WithContentHelper

#with_content

Constructor Details

#initialize(parent) ⇒ SlotV2

Returns a new instance of SlotV2.



11
12
13
# File 'lib/view_component/slot_v2.rb', line 11

def initialize(parent)
  @parent = parent
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object

Allow access to public component methods via the wrapper

e.g.

calling `header.name` (where `header` is a slot) will call `name` on the `HeaderComponent` instance.

Where the component may look like:

class MyComponent < ViewComponent::Base

has_one :header, HeaderComponent

class HeaderComponent < ViewComponent::Base
  def name
    @name
  end
end

end



82
83
84
# File 'lib/view_component/slot_v2.rb', line 82

def method_missing(symbol, *args, &block)
  @_component_instance.public_send(symbol, *args, &block)
end

Instance Attribute Details

#_component_instance=(value) ⇒ Object (writeonly)

Sets the attribute _component_instance

Parameters:

  • value

    the value to set the attribute _component_instance to.



9
10
11
# File 'lib/view_component/slot_v2.rb', line 9

def _component_instance=(value)
  @_component_instance = value
end

#_content=(value) ⇒ Object (writeonly)

Sets the attribute _content

Parameters:

  • value

    the value to set the attribute _content to.



9
10
11
# File 'lib/view_component/slot_v2.rb', line 9

def _content=(value)
  @_content = value
end

#_content_block=(value) ⇒ Object (writeonly)

Sets the attribute _content_block

Parameters:

  • value

    the value to set the attribute _content_block to.



9
10
11
# File 'lib/view_component/slot_v2.rb', line 9

def _content_block=(value)
  @_content_block = value
end

Instance Method Details

#html_safe?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/view_component/slot_v2.rb', line 86

def html_safe?
  to_s.html_safe?
end

#respond_to_missing?(symbol, include_all = false) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/view_component/slot_v2.rb', line 90

def respond_to_missing?(symbol, include_all = false)
  defined?(@_component_instance) && @_component_instance.respond_to?(symbol, include_all)
end

#to_sObject

Used to render the slot content in the template

There's currently 3 different values that may be set, that we can render.

If the slot renderable is a component, the string class name of a component, or a function that returns a component, we render that component instance, returning the string.

If the slot renderable is a function and returns a string, it is set as `@_content` and is returned directly.

If there is no slot renderable, we evaluate the block passed to the slot and return it.

Raises:

  • (ArgumentError)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/view_component/slot_v2.rb', line 28

def to_s
  return @content if defined?(@content)

  view_context = @parent.send(:view_context)

  raise ArgumentError.new("Block provided after calling `with_content`. Use one or the other.") if defined?(@_content_block) && defined?(@_content_set_by_with_content)

  @content = if defined?(@_component_instance)
    if defined?(@_content_set_by_with_content)
      @_component_instance.with_content(@_content_set_by_with_content)

      view_context.capture do
        @_component_instance.render_in(view_context)
      end
    elsif defined?(@_content_block)
      view_context.capture do
        # render_in is faster than `parent.render`
        @_component_instance.render_in(view_context, &@_content_block)
      end
    else
      view_context.capture do
        @_component_instance.render_in(view_context)
      end
    end
  elsif defined?(@_content)
    @_content
  elsif defined?(@_content_block)
    view_context.capture(&@_content_block)
  elsif defined?(@_content_set_by_with_content)
    @_content_set_by_with_content
  end

  @content
end