module ViewComponent::Slotable
def define_slot(slot_name, collection:, callable:)
def define_slot(slot_name, collection:, callable:) slot = {collection: collection} return slot unless callable # If callable responds to `render_in`, we set it on the slot as a renderable if callable.respond_to?(:method_defined?) && callable.method_defined?(:render_in) slot[:renderable] = callable elsif callable.is_a?(String) # If callable is a string, we assume it's referencing an internal class slot[:renderable_class_name] = callable elsif callable.respond_to?(:call) # If slot doesn't respond to `render_in`, we assume it's a proc, # define a method, and save a reference to it to call when setting method_name = :"_call_#{slot_name}" define_method method_name, &callable slot[:renderable_function] = instance_method(method_name) else raise(InvalidSlotDefinitionError) end slot end