Class: ViewComponent::Slot

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent) ⇒ Slot

Returns a new instance of Slot.



11
12
13
# File 'lib/view_component/slot.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

for example

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



94
95
96
# File 'lib/view_component/slot.rb', line 94

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

Instance Attribute Details

#__vc_component_instance=(value) ⇒ Object (writeonly)

Sets the attribute __vc_component_instance

Parameters:

  • value

    the value to set the attribute __vc_component_instance to.



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

def __vc_component_instance=(value)
  @__vc_component_instance = value
end

#__vc_content=(value) ⇒ Object (writeonly)

Sets the attribute __vc_content

Parameters:

  • value

    the value to set the attribute __vc_content to.



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

def __vc_content=(value)
  @__vc_content = value
end

#__vc_content_block=(value) ⇒ Object (writeonly)

Sets the attribute __vc_content_block

Parameters:

  • value

    the value to set the attribute __vc_content_block to.



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

def __vc_content_block=(value)
  @__vc_content_block = value
end

Instance Method Details

#content?Boolean

Returns:

  • (Boolean)


15
16
17
18
19
20
21
22
# File 'lib/view_component/slot.rb', line 15

def content?
  return true if defined?(@__vc_content) && @__vc_content.present?
  return true if defined?(@__vc_content_set_by_with_content) && @__vc_content_set_by_with_content.present?
  return true if defined?(@__vc_content_block) && @__vc_content_block.present?
  return false if !__vc_component_instance?

  @__vc_component_instance.content?
end

#html_safe?Boolean

Returns:

  • (Boolean)


99
100
101
102
103
# File 'lib/view_component/slot.rb', line 99

def html_safe?
  # :nocov:
  to_s.html_safe?
  # :nocov:
end

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

Returns:

  • (Boolean)


105
106
107
# File 'lib/view_component/slot.rb', line 105

def respond_to_missing?(symbol, include_all = false)
  __vc_component_instance? && @__vc_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’s set as ‘@__vc_content` and is returned directly.

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



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/view_component/slot.rb', line 45

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

  view_context = @parent.send(:view_context)

  if defined?(@__vc_content_block) && defined?(@__vc_content_set_by_with_content)
    raise DuplicateSlotContentError.new(self.class.name)
  end

  @content =
    if __vc_component_instance?
      @__vc_component_instance.__vc_original_view_context = @parent.__vc_original_view_context

      if defined?(@__vc_content_block)
        # render_in is faster than `parent.render`
        @__vc_component_instance.render_in(view_context, &@__vc_content_block)
      else
        @__vc_component_instance.render_in(view_context)
      end
    elsif defined?(@__vc_content)
      @__vc_content
    elsif defined?(@__vc_content_block)
      view_context.capture(&@__vc_content_block)
    elsif defined?(@__vc_content_set_by_with_content)
      @__vc_content_set_by_with_content
    end

  @content = @content.to_s
end

#with_content(args) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/view_component/slot.rb', line 24

def with_content(args)
  if __vc_component_instance?
    @__vc_component_instance.with_content(args)
  else
    super
  end
end