Class: ViewComponent::Preview

Inherits:
Object
  • Object
show all
Extended by:
ActiveSupport::DescendantsTracker
Includes:
ActionView::Helpers::AssetTagHelper, ActionView::Helpers::TagHelper
Defined in:
lib/view_component/preview.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.allObject

Returns all component preview classes.



32
33
34
35
36
# File 'lib/view_component/preview.rb', line 32

def all
  load_previews

  descendants
end

.examplesObject

Returns all of the available examples for the component preview.



50
51
52
# File 'lib/view_component/preview.rb', line 50

def examples
  public_instance_methods(false).map(&:to_s).sort
end

.exists?(preview) ⇒ Boolean

Returns true if the preview exists.

Returns:

  • (Boolean)


55
56
57
# File 'lib/view_component/preview.rb', line 55

def exists?(preview)
  all.any? { |p| p.preview_name == preview }
end

.find(preview) ⇒ Object

Find a component preview by its underscored class name.



60
61
62
# File 'lib/view_component/preview.rb', line 60

def find(preview)
  all.find { |p| p.preview_name == preview }
end

.layout(layout_name) ⇒ Object

rubocop:disable Style/TrivialAccessors Setter for layout name.



71
72
73
# File 'lib/view_component/preview.rb', line 71

def layout(layout_name)
  @layout = layout_name
end

.load_previewsObject



104
105
106
107
108
# File 'lib/view_component/preview.rb', line 104

def load_previews
  Array(preview_paths).each do |preview_path|
    Dir["#{preview_path}/**/*_preview.rb"].sort.each { |file| require_dependency file }
  end
end

.preview_example_template_path(example) ⇒ Object

Returns the relative path (from preview_path) to the preview example template if the template exists



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/view_component/preview.rb', line 77

def preview_example_template_path(example)
  preview_path =
    Array(preview_paths).detect do |path|
      Dir["#{path}/#{preview_name}_preview/#{example}.html.*"].first
    end

  if preview_path.nil?
    raise(
      PreviewTemplateError,
      "A preview template for example #{example} doesn't exist.\n\n" \
      "To fix this issue, create a template for the example."
    )
  end

  path = Dir["#{preview_path}/#{preview_name}_preview/#{example}.html.*"].first
  Pathname.new(path)
    .relative_path_from(Pathname.new(preview_path))
    .to_s
    .sub(/\..*$/, "")
end

.preview_nameObject

Returns the underscored name of the component preview without the suffix.



65
66
67
# File 'lib/view_component/preview.rb', line 65

def preview_name
  name.chomp("Preview").underscore
end

.preview_source(example) ⇒ Object

Returns the method body for the example from the preview file.



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

def preview_source(example)
  source = instance_method(example.to_sym).source.split("\n")
  source[1...(source.size - 1)].join("\n")
end

.render_args(example, params: {}) ⇒ Object

Returns the arguments for rendering of the component in its layout



39
40
41
42
43
44
45
46
47
# File 'lib/view_component/preview.rb', line 39

def render_args(example, params: {})
  example_params_names = instance_method(example).parameters.map(&:last)
  provided_params = params.slice(*example_params_names).to_h.symbolize_keys
  result = provided_params.empty? ? new.public_send(example) : new.public_send(example, **provided_params)
  result ||= {}
  result[:template] = preview_example_template_path(example) if result[:template].nil?
  @layout = nil unless defined?(@layout)
  result.merge(layout: @layout)
end

Instance Method Details

#render(component, **args, &block) ⇒ Object Also known as: render_component



11
12
13
14
15
16
17
18
19
# File 'lib/view_component/preview.rb', line 11

def render(component, **args, &block)
  {
    args: args,
    block: block,
    component: component,
    locals: {},
    template: "view_components/preview"
  }
end

#render_with_template(template: nil, locals: {}) ⇒ Object



21
22
23
24
25
26
# File 'lib/view_component/preview.rb', line 21

def render_with_template(template: nil, locals: {})
  {
    template: template,
    locals: locals
  }
end