class ViewComponent::Slot
def __vc_component_instance?
def __vc_component_instance? defined?(@__vc_component_instance) end
def content?
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
def html_safe?
def html_safe? # :nocov: to_s.html_safe? # :nocov: end
def initialize(parent)
def initialize(parent) @parent = parent end
def method_missing(symbol, *args, &block)
end
end
end
@name
def name
class HeaderComponent < ViewComponent::Base
has_one :header, HeaderComponent
class MyComponent < ViewComponent::Base
Where the component may look like:
on the `HeaderComponent` instance.
calling `header.name` (where `header` is a slot) will call `name`
for example
Allow access to public component methods via the wrapper
def method_missing(symbol, *args, &block) @__vc_component_instance.public_send(symbol, *args, &block) end
def respond_to_missing?(symbol, include_all = false)
def respond_to_missing?(symbol, include_all = false) __vc_component_instance? && @__vc_component_instance.respond_to?(symbol, include_all) end
def to_s
If there is no slot renderable, we evaluate the block passed to
set as `@__vc_content` and is returned directly.
If the slot renderable is a function and returns a string, it's
component instance, returning the string.
component, or a function that returns a component, we render that
If the slot renderable is a component, the string class name of a
There's currently 3 different values that may be set, that we can render.
Used to render the slot content in the template
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) do |*args| return @__vc_content_block.call(*args) if @__vc_content_block&.source_location.nil? block_context = @__vc_content_block.binding.receiver if block_context.class < ActionView::Base block_context.capture(*args, &@__vc_content_block) else @__vc_content_block.call(*args) end end 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
def with_content(args)
def with_content(args) if __vc_component_instance? @__vc_component_instance.with_content(args) else super end end