class ViewComponent::Storybook::StoryConfig

Attributes

component_class[R]
id[R]
name[R]

Public Class Methods

new(id, name, component_class, layout) click to toggle source
# File lib/view_component/storybook/story_config.rb, line 14
def initialize(id, name, component_class, layout)
  @id = id
  @name = name
  @component_class = component_class
  @layout = layout
  @slots ||= {}
end

Public Instance Methods

constructor(*args, **kwargs, &block) click to toggle source
# File lib/view_component/storybook/story_config.rb, line 22
def constructor(*args, **kwargs, &block)
  @constructor_args = MethodArgs::ControlMethodArgs.new(
    component_constructor,
    *args,
    **kwargs
  )
  content(nil, &block)

  self
end
controls(&block) click to toggle source

Once deprecated block version is removed make this a private getter

# File lib/view_component/storybook/story_config.rb, line 34
def controls(&block)
  if block_given?
    ActiveSupport::Deprecation.warn("`controls` will be removed in v1.0.0. Use `#constructor` instead.")
    controls_dsl = Dsl::LegacyControlsDsl.new
    controls_dsl.instance_eval(&block)

    controls_hash = controls_dsl.controls.index_by(&:param)
    constructor(**controls_hash)
  else
    list = constructor_args.controls.dup
    list << content_control if content_control
    list += slots.flat_map(&:controls) if slots
    list
  end
end
layout(layout = nil) click to toggle source
# File lib/view_component/storybook/story_config.rb, line 50
def layout(layout = nil)
  @layout = layout unless layout.nil?
  @layout
end
method_missing(method_name, *args, **kwargs, &block) click to toggle source
Calls superclass method
# File lib/view_component/storybook/story_config.rb, line 60
def method_missing(method_name, *args, **kwargs, &block)
  if component_class.slot_type(method_name)
    slot(method_name, *args, **kwargs, &block)
  else
    super
  end
end
parameters(parameters = nil) click to toggle source
# File lib/view_component/storybook/story_config.rb, line 55
def parameters(parameters = nil)
  @parameters = parameters unless parameters.nil?
  @parameters
end
respond_to_missing?(method_name, _include_private = false) click to toggle source
# File lib/view_component/storybook/story_config.rb, line 68
def respond_to_missing?(method_name, _include_private = false)
  component_class.slot_type(method_name).present?
end
story(params) click to toggle source

Build a Story from this config

  • Resolves the values of the constructor args from the params

  • constructs the component

  • resolve the content_control and content_block to a single block

  • builds a list of Slots by resolving their args from the params

# File lib/view_component/storybook/story_config.rb, line 92
def story(params)
  # constructor_args.target_method is UnboundMethod so can't call it directly
  component = constructor_args.call(params) do |*args, **kwargs|
    component_class.new(*args, **kwargs)
  end

  story_content_block = resolve_content_block(params)

  story_slots = slots.map do |slot_config|
    slot_config.slot(component, params)
  end

  Storybook::Story.new(component, story_content_block, story_slots, layout)
end
to_csf_params() click to toggle source
# File lib/view_component/storybook/story_config.rb, line 72
def to_csf_params
  validate!
  csf_params = { name: name, parameters: { server: { id: id } } }
  csf_params.deep_merge!(parameters: parameters) if parameters.present?
  controls.each do |control|
    csf_params.deep_merge!(control.to_csf_params)
  end
  csf_params
end
validate!() click to toggle source
# File lib/view_component/storybook/story_config.rb, line 82
def validate!
  valid? || raise(ValidationError, self)
end

Private Instance Methods

component_constructor() click to toggle source
# File lib/view_component/storybook/story_config.rb, line 123
def component_constructor
  component_class.instance_method(:initialize)
end
constructor_args() click to toggle source
# File lib/view_component/storybook/story_config.rb, line 119
def constructor_args
  @constructor_args ||= MethodArgs::ControlMethodArgs.new(component_constructor)
end
slot(slot_name, *args, **kwargs, &block) click to toggle source
# File lib/view_component/storybook/story_config.rb, line 138
def slot(slot_name, *args, **kwargs, &block)
  # if the name is a slot then build a SlotConfig with slot_name and param the same
  if component_class.slot_type(slot_name) == :collection_item
    # generate a unique param generated by the count of slots with this name already added
    @slots[slot_name] ||= []
    slot_index = @slots[slot_name].count + 1
    slot_config = Slots::SlotConfig.from_component(
      component_class,
      slot_name,
      "#{slot_name}#{slot_index}".to_sym,
      *args,
      **kwargs,
      &block
    )
    @slots[slot_name] << slot_config
  else
    slot_config = Slots::SlotConfig.from_component(
      component_class,
      slot_name,
      slot_name,
      *args,
      **kwargs,
      &block
    )
    @slots[slot_name] = slot_config
  end
  slot_config
end
slots() click to toggle source
# File lib/view_component/storybook/story_config.rb, line 127
def slots
  @slots.values.flatten
end
validate_constructor_args() click to toggle source
# File lib/view_component/storybook/story_config.rb, line 131
def validate_constructor_args
  return if constructor_args.valid?

  constructor_args_errors = constructor_args.errors.full_messages.join(', ')
  errors.add(:constructor_args, :invalid, errors: constructor_args_errors)
end