lookbook 2.0.0.beta.3 → 2.0.0.beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/lookbook/css/lookbook.css +6 -0
  3. data/app/assets/lookbook/css/themes/blue.css +4 -1
  4. data/app/assets/lookbook/css/themes/green.css +4 -1
  5. data/app/assets/lookbook/css/themes/indigo.css +4 -1
  6. data/app/assets/lookbook/css/themes/rose.css +4 -1
  7. data/app/assets/lookbook/css/themes/zinc.css +4 -1
  8. data/app/assets/lookbook/img/lucide-sprite.svg +869 -869
  9. data/app/components/lookbook/code/highlight_github.css +16 -17
  10. data/app/components/lookbook/dimensions_display/component.js +4 -7
  11. data/app/components/lookbook/file_source/component.html.erb +9 -0
  12. data/app/components/lookbook/file_source/component.rb +73 -0
  13. data/app/components/lookbook/header/component.html.erb +11 -8
  14. data/app/components/lookbook/icon/component.css +1 -1
  15. data/app/components/lookbook/icon/component.html.erb +1 -1
  16. data/app/components/lookbook/icon/component.rb +4 -1
  17. data/app/components/lookbook/logo/component.html.erb +6 -0
  18. data/app/components/lookbook/logo/component.rb +15 -0
  19. data/app/components/lookbook/message/component.css +33 -0
  20. data/app/components/lookbook/message/component.html.erb +26 -0
  21. data/app/components/lookbook/message/component.rb +13 -0
  22. data/app/components/lookbook/nav/entity/component.html.erb +1 -1
  23. data/app/components/lookbook/nav/entity/component.rb +1 -1
  24. data/app/components/lookbook/params/field/component.css +3 -3
  25. data/app/components/lookbook/prose/component.css +8 -1
  26. data/app/components/lookbook/prose/component.html.erb +6 -1
  27. data/app/components/lookbook/prose/component.rb +2 -2
  28. data/app/controllers/concerns/lookbook/targetable_concern.rb +2 -16
  29. data/app/controllers/lookbook/application_controller.rb +38 -14
  30. data/app/controllers/lookbook/embeds_controller.rb +3 -4
  31. data/app/controllers/lookbook/inspector_controller.rb +4 -12
  32. data/app/controllers/lookbook/pages_controller.rb +15 -27
  33. data/app/controllers/lookbook/preview_controller.rb +30 -2
  34. data/app/controllers/lookbook/previews_controller.rb +13 -15
  35. data/app/views/layouts/lookbook/application.html.erb +1 -0
  36. data/app/views/layouts/lookbook/skeleton.html.erb +2 -2
  37. data/app/views/lookbook/errors/default.html.erb +40 -0
  38. data/app/views/lookbook/errors/not_found.html.erb +10 -0
  39. data/app/views/lookbook/index.html.erb +29 -24
  40. data/app/views/lookbook/pages/show.html.erb +6 -5
  41. data/app/views/lookbook/partials/_blank_slate.html.erb +7 -0
  42. data/config/app.yml +8 -0
  43. data/config/routes.rb +2 -0
  44. data/lib/lookbook/engine.rb +6 -3
  45. data/lib/lookbook/entities/concerns/annotatable_entity.rb +26 -1
  46. data/lib/lookbook/entities/concerns/inspectable_entity.rb +17 -2
  47. data/lib/lookbook/entities/concerns/locatable_entity.rb +51 -7
  48. data/lib/lookbook/entities/concerns/navigable_entity.rb +14 -1
  49. data/lib/lookbook/entities/entity.rb +34 -12
  50. data/lib/lookbook/entities/page_entity.rb +68 -10
  51. data/lib/lookbook/entities/page_section_entity.rb +4 -0
  52. data/lib/lookbook/entities/preview_entity.rb +107 -17
  53. data/lib/lookbook/entities/renderable_entity.rb +47 -9
  54. data/lib/lookbook/entities/rendered_scenario_entity.rb +17 -6
  55. data/lib/lookbook/entities/scenario_entity.rb +77 -16
  56. data/lib/lookbook/entities/scenario_group_entity.rb +82 -9
  57. data/lib/lookbook/helpers/page_helper.rb +26 -1
  58. data/lib/lookbook/helpers/ui_elements_helper.rb +0 -24
  59. data/lib/lookbook/param.rb +1 -1
  60. data/lib/lookbook/stores/config_store.rb +0 -12
  61. data/lib/lookbook/support/errors/config_error.rb +1 -1
  62. data/lib/lookbook/support/errors/error.rb +64 -0
  63. data/lib/lookbook/support/errors/parser_error.rb +1 -1
  64. data/lib/lookbook/support/errors/preview_template_error.rb +1 -1
  65. data/lib/lookbook/support/errors/routing_error.rb +7 -0
  66. data/lib/lookbook/support/errors/template_error.rb +7 -0
  67. data/lib/lookbook/version.rb +1 -1
  68. data/public/lookbook-assets/css/lookbook.css +374 -53
  69. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  70. data/public/lookbook-assets/css/themes/blue.css +4 -1
  71. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  72. data/public/lookbook-assets/css/themes/green.css +4 -1
  73. data/public/lookbook-assets/css/themes/green.css.map +1 -1
  74. data/public/lookbook-assets/css/themes/indigo.css +4 -1
  75. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  76. data/public/lookbook-assets/css/themes/rose.css +4 -1
  77. data/public/lookbook-assets/css/themes/rose.css.map +1 -1
  78. data/public/lookbook-assets/css/themes/zinc.css +4 -1
  79. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  80. data/public/lookbook-assets/img/lucide-sprite.svg +869 -869
  81. data/public/lookbook-assets/js/index.js +125 -125
  82. data/public/lookbook-assets/js/index.js.map +1 -1
  83. metadata +15 -7
  84. data/app/views/layouts/lookbook/shell.html.erb +0 -25
  85. data/app/views/lookbook/404.html.erb +0 -15
  86. data/app/views/lookbook/error.html.erb +0 -46
  87. data/lib/lookbook/error.rb +0 -120
  88. data/lib/lookbook/support/errors/lookbook_error.rb +0 -21
@@ -1,27 +1,57 @@
1
1
  module Lookbook
2
2
  # Base entity class
3
3
  #
4
- # @api private
4
+ # @api public
5
5
  class Entity
6
6
  include Comparable
7
7
  send(:include, Lookbook::Engine.routes.url_helpers) # YARD parsing workaround: https://github.com/lsegal/yard/issues/546
8
8
 
9
+ # @api private
9
10
  def initialize(lookup_path = nil)
10
11
  @lookup_path = lookup_path
11
12
  end
12
13
 
14
+ # @!group Identity
15
+
16
+ # Human-readable unique ID for the entity
17
+ #
18
+ # @return [String] The ID
13
19
  def id
14
20
  Utils.id(fetch_config(:id) { lookup_path.tr("/", "-") })
15
21
  end
16
22
 
23
+ # Parameter-safe entity name.
24
+ #
25
+ # @return [String] The name
17
26
  def name
18
27
  @_name ||= Utils.name(File.basename(@lookup_path))
19
28
  end
20
29
 
30
+ # Titlized name for use in navigation etc.
31
+ #
32
+ # Can be customized using the `@label` tag where supported.
33
+ #
34
+ # @return [String] The label
21
35
  def label
22
36
  @_label ||= fetch_config(:label) { name.titleize }
23
37
  end
24
38
 
39
+ # Entity type identifier
40
+ #
41
+ # @return [Symbol] The entity type
42
+ def type
43
+ @_type ||= self.class.name.gsub("Entity", "").demodulize.underscore.downcase.to_sym
44
+ end
45
+
46
+ # @!endgroup
47
+
48
+ # @!group Paths
49
+
50
+ # Canonical reference path.
51
+ #
52
+ # Used for generating URL paths and looking up entities.
53
+ #
54
+ # @return [String] The lookup path
25
55
  def lookup_path
26
56
  return @_lookup_path if @_lookup_path
27
57
 
@@ -32,23 +62,15 @@ module Lookbook
32
62
  @_lookup_path ||= PathUtils.strip_slashes(PathUtils.to_path(directory, name))
33
63
  end
34
64
 
35
- def url_path
36
- nil
37
- end
65
+ alias_method :path, :lookup_path
66
+ deprecate path: :lookup_path, deprecator: Deprecation
38
67
 
39
- def type
40
- @_type ||= self.class.name.gsub("Entity", "").demodulize.underscore.downcase.to_sym
41
- end
68
+ # @!endgroup
42
69
 
43
70
  def <=>(other)
44
71
  label <=> other.label
45
72
  end
46
73
 
47
- alias_method :path, :lookup_path
48
- alias_method :logical_path, :lookup_path
49
-
50
- deprecate path: :lookup_path, deprecator: Deprecation
51
-
52
74
  protected
53
75
 
54
76
  def fetch_config(key, fallback = nil, &block)
@@ -1,14 +1,18 @@
1
1
  module Lookbook
2
2
  # Represents a documentation page
3
3
  #
4
- # @ignore methods
5
4
  # @api public
6
5
  class PageEntity < Entity
7
6
  include LocatableEntity
8
7
  include NavigableEntity
9
8
 
10
- attr_reader :content, :sections
9
+ # @api private
10
+ attr_reader :content
11
11
 
12
+ # @api private
13
+ attr_reader :sections
14
+
15
+ # @api private
12
16
  def initialize(file_path)
13
17
  @file_path = Pathname(file_path)
14
18
  @base_directories = Engine.page_paths
@@ -18,50 +22,104 @@ module Lookbook
18
22
  @sections = []
19
23
  end
20
24
 
25
+ # @!group Identity
26
+
27
+ # Page title, as defined in frontmatter.
28
+ # Defaults to the page `label` if not provided.
29
+ #
30
+ # @return [String] The title
21
31
  def title
22
32
  @_title ||= fetch_config(:title, label)
23
33
  end
24
34
 
35
+ # @!endgroup
36
+
37
+ # @!group Frontmatter
38
+
39
+ # Merged data hash. Combines `data` set in frontmatter
40
+ # with any global default values.
41
+ #
42
+ # @return [Hash] The resolved data hash
43
+ def data
44
+ return @_data if @_data
45
+
46
+ config_data = fetch_config(:data, {})
47
+ @_data ||= config_data.is_a?(Hash) ? Store.new(config_data) : config_data
48
+ end
49
+
50
+ # @!endgroup
51
+
52
+ # @!group Predicates
53
+
54
+ # Whether the page is the default landing page.
55
+ #
56
+ # Set via the `landing` frontmatter property.
57
+ #
58
+ # @return [Boolean]
25
59
  def landing?
26
60
  @_landing ||= fetch_config(:landing, false)
27
61
  end
28
62
 
63
+ # Whether the page content should be rendered
64
+ # with the Markdown renderer.
65
+ #
66
+ # Set via the `markdown` frontmatter property.
67
+ #
68
+ # @return [Boolean]
29
69
  def markdown?
30
70
  @_markdown ||= fetch_config(:markdown) { file_path.to_s.match?(/(.*)\.md\.(.*)$/) }
31
71
  end
32
72
 
73
+ # Whether the page header will be shown.
74
+ #
75
+ # Set via the `header` frontmatter property.
76
+ #
77
+ # @return [Boolean]
33
78
  def header?
34
79
  @_header ||= fetch_config(:header, true)
35
80
  end
36
81
 
82
+ # Whether the page footer will be shown.
83
+ #
84
+ # Set via the `footer` frontmatter property.
85
+ #
86
+ # @return [Boolean]
37
87
  def footer?
38
88
  @_footer ||= fetch_config(:footer, true)
39
89
  end
40
90
 
41
- def data
42
- return @_data if @_data
91
+ # @!endgroup
43
92
 
44
- config_data = fetch_config(:data, {})
45
- @_data ||= config_data.is_a?(Hash) ? Store.new(config_data) : config_data
93
+ # @!group URLs
94
+
95
+ # The docs URL path for this page.
96
+ #
97
+ # @return [String] URL path
98
+ def docs_path
99
+ lookbook_page_path(lookup_path)
46
100
  end
47
101
 
102
+ alias_method :url_path, :docs_path
103
+
104
+ # @!endgroup
105
+
106
+ # @api private
48
107
  def search_terms
49
108
  label
50
109
  end
51
110
 
52
- def url_path
53
- lookbook_page_path(lookup_path)
54
- end
55
-
111
+ # @api private
56
112
  def add_section(section)
57
113
  @sections << section
58
114
  @sections.sort_by! { |section| [section.priority, section.label] }
59
115
  end
60
116
 
117
+ # @api private
61
118
  def method_missing(method_name, *args, &block)
62
119
  method_name.to_s.end_with?("=") ? super : frontmatter.fetch(method_name, nil)
63
120
  end
64
121
 
122
+ # @api private
65
123
  def respond_to_missing?(method_name, include_private = false)
66
124
  frontmatter.key?(method_name) || super
67
125
  end
@@ -1,4 +1,8 @@
1
1
  module Lookbook
2
+ # Represents a documentation page section.
3
+ #
4
+ # @ignore methods
5
+ # @api private
2
6
  class PageSectionEntity < PageEntity
3
7
  attr_accessor :parent
4
8
 
@@ -1,7 +1,6 @@
1
1
  module Lookbook
2
2
  # Represents a preview class
3
3
  #
4
- # @ignore methods
5
4
  # @api public
6
5
  class PreviewEntity < Entity
7
6
  include AnnotatableEntity
@@ -10,8 +9,10 @@ module Lookbook
10
9
 
11
10
  delegate :render_args, to: :preview_class
12
11
 
12
+ # @api private
13
13
  attr_reader :preview_class
14
14
 
15
+ # @api private
15
16
  def initialize(code_object)
16
17
  @code_object = code_object
17
18
  @preview_class = code_object.path.constantize
@@ -25,61 +26,150 @@ module Lookbook
25
26
  @lookup_path = PathUtils.to_lookup_path(cleaned_path)
26
27
  end
27
28
 
29
+ # @!group Scenarios
30
+
31
+ # Get all scenarios defined in the preview class.
32
+ #
33
+ # @example :ruby
34
+ # scenario_names = preview.scenarios.map(&:name)
35
+ #
36
+ # @return [Array<ScenarioEntity>] All scenarios for the preview
28
37
  def scenarios
29
38
  @_scenarios ||= ScenarioCollection.new(load_scenarios)
30
39
  end
31
40
 
41
+ alias_method :examples, :scenarios
42
+ deprecate examples: :scenarios, deprecator: Deprecation
43
+
44
+ # Find a specific scenario by (i.e. method) name
45
+ #
46
+ # @example :ruby
47
+ # default_scenario_preview_path = preview.scenario(:default).preview_path
48
+ #
49
+ # @param scenario_name [Symbol, String] Name of the scenario
50
+ # @return [ScenarioEntity] The matching scenario, if found
51
+ # @return [nil] if no matching scenario was found
32
52
  def scenario(scenario_name)
33
53
  scenarios.find { |m| m.name == scenario_name.to_s }
34
54
  end
35
55
 
56
+ alias_method :example, :scenario
57
+ deprecate example: :scenario, deprecator: Deprecation
58
+
59
+ # Get all scenarios defined in the preview class that
60
+ # have not been hidden (by using the `@hidden` tag).
61
+ #
62
+ # @example :ruby
63
+ # visible_scenario_names = preview.visible_scenarios.map(&:name)
64
+ #
65
+ # @return [Array<ScenarioEntity>] All visible scenarios for the preview
36
66
  def visible_scenarios
37
67
  @_visible_scenarios ||= ScenarioCollection.new(scenarios.select(&:visible?))
38
68
  end
39
69
 
70
+ # Get all scenarios defined in the preview class
71
+ # that are hidden (using the `@hidden` tag) and so
72
+ # will not show up in the navigation.
73
+ #
74
+ # @example :ruby
75
+ # hidden_scenario_names = preview.hidden_scenarios.map(&:name)
76
+ #
77
+ # @return [Array<ScenarioEntity>] All hidden scenarios for the preview
78
+ def hidden_scenarios
79
+ @_hidden_scenarios ||= ScenarioCollection.new(scenarios.select(&:hidden?))
80
+ end
81
+
82
+ # The scenario used when a preview is rendered
83
+ # without explicity specifying a scenario.
84
+ #
85
+ # @example :ruby
86
+ # default_scenario_name = preview.default_scenario.name
87
+ #
88
+ # @return [ScenarioEntity] The default scenario for this preview
40
89
  def default_scenario
41
90
  visible_scenarios.first
42
91
  end
43
92
 
93
+ # @!endgroup
94
+
95
+ # @!group Render Targets
96
+
97
+ # All 'render targets' (i.e. components or partials) that are known
98
+ # to be rendered within the scenarios defined within this preview.
99
+ #
100
+ # Render targets are guessed where possible (based on the preview class name)
101
+ # but can also be manually specified using the `@renders` tag.
102
+ #
103
+ # @example :ruby
104
+ # "This preview renders: #{preview.render_targets.map(&:label).join(", ")}"
105
+ #
106
+ # @return [Array<RenderableEntity>] All known render targets used in the preview
44
107
  def render_targets
45
108
  @_render_targets ||= RenderTargetCollection.new(scenarios.flat_map(&:render_targets).uniq(&:lookup_path))
46
109
  end
47
110
 
111
+ alias_method :components, :render_targets
112
+
113
+ # @api private
48
114
  def render_target
49
115
  render_targets.first
50
116
  end
51
117
 
52
- def display_options
53
- global_options = Lookbook.config.preview_display_options
54
- global_options.deep_merge(fetch_config(:display_options, {}))
55
- end
118
+ # @api private
119
+ alias_method :component, :render_target
56
120
 
57
- def layout
58
- preview_class.instance_variable_get(:@layout)
59
- end
121
+ # @!endgroup
60
122
 
61
- def url_path
123
+ # @!group URLs
124
+
125
+ # The inspector URL path for this preview
126
+ #
127
+ # @return [String] URL path
128
+ def inspect_path
62
129
  lookbook_inspect_path(lookup_path)
63
130
  end
64
131
 
132
+ alias_method :url_path, :inspect_path
133
+
134
+ # The standalone preview URL path for this preview
135
+ #
136
+ # @return [String] URL path
137
+ def preview_path
138
+ lookbook_preview_path(lookup_path)
139
+ end
140
+
141
+ # @!endgroup
142
+
143
+ # The name of the associated preview class
144
+ #
145
+ # @return [String] Class name
65
146
  def preview_class_name
66
147
  preview_class.name
67
148
  end
68
149
 
150
+ # @api private
151
+ def file_name_base
152
+ @_file_name_slug ||= file_name(true).gsub(/(_component_preview|component_preview|preview)$/, "")
153
+ end
154
+
155
+ # @api private
156
+ def display_options
157
+ global_options = Lookbook.config.preview_display_options
158
+ global_options.deep_merge(fetch_config(:display_options, {}))
159
+ end
160
+
161
+ # @api private
162
+ def layout
163
+ preview_class.instance_variable_get(:@layout)
164
+ end
165
+
166
+ # @api private
69
167
  def guess_render_targets
70
168
  [preview_class.name.chomp("Preview").constantize&.name]
71
169
  rescue
72
170
  []
73
171
  end
74
172
 
75
- alias_method :components, :render_targets
76
- alias_method :component, :render_target
77
- alias_method :examples, :scenarios
78
- alias_method :example, :scenario
79
-
80
- deprecate examples: :scenarios, deprecator: Deprecation
81
- deprecate example: :scenario, deprecator: Deprecation
82
-
83
173
  protected
84
174
 
85
175
  def load_scenarios
@@ -2,49 +2,87 @@ module Lookbook
2
2
  # Represents the component or view template partial
3
3
  # that is being rendered in a preview.
4
4
  #
5
- # @ignore methods
6
5
  # @api public
7
6
  class RenderableEntity < Entity
8
7
  include LocatableEntity
9
8
 
9
+ # @api private
10
10
  def initialize(identifier)
11
11
  @identifier = identifier
12
12
  @base_directories = Engine.component_paths
13
13
  @file_path = PathUtils.determine_full_path(component? ? "#{name}.rb" : identifier, @base_directories)
14
14
  unless @file_path && File.exist?(@file_path)
15
- raise LookbookError, "The render target #{@identifier} was not found."
15
+ raise Lookbook::Error, "The render target #{@identifier} was not found."
16
16
  end
17
17
  @lookup_path = PathUtils.to_lookup_path(relative_file_path)
18
18
  end
19
19
 
20
- def component_class
21
- @identifier.constantize if component?
22
- end
20
+ # @!group Identity
23
21
 
22
+ # Parameter-safe entity name.
23
+ #
24
+ # @return [String]
24
25
  def name
25
26
  component? ? component_class.name.underscore : @identifier
26
27
  end
27
28
 
28
- def template_file_path
29
- component? ? Dir.glob("#{directory_path}/#{file_name(true)}.*.erb").first : file_path
29
+ # Entity type identifier.
30
+ # Returns `:component` for components and
31
+ # `:template` for view templates/partials.
32
+ #
33
+ # @return [Symbol] The entity type
34
+ def type
35
+ component? ? :component : :template
36
+ end
37
+
38
+ # @!endgroup
39
+
40
+ # @!group Components
41
+
42
+ # The associated component class (if the renderable is a component).
43
+ #
44
+ # @return [Class] The component class
45
+ def component_class
46
+ @identifier.constantize if component?
30
47
  end
31
48
 
49
+ # Whether or not the renderable is a component without a template.
50
+ #
51
+ # @return [Boolean] True if no template is present
32
52
  def inline?
33
53
  component? ? template_file_path.present? : false
34
54
  end
35
55
 
56
+ # Whether or not the renderable is a component
57
+ # (as opposed to a view template/partial).
58
+ #
59
+ # @return [Boolean] True if component
36
60
  def component?
37
61
  @identifier.first.upcase == @identifier.first &&
38
62
  !@identifier.include?(".") &&
39
63
  !@identifier.include?("/")
40
64
  end
41
65
 
66
+ # Whether or not the renderable is a view template/partial
67
+ # (as opposed to a component).
68
+ #
69
+ # @return [Boolean] True if component
42
70
  def template?
43
71
  !component?
44
72
  end
45
73
 
46
- def type
47
- component? ? :component : :template
74
+ # @!endgroup
75
+
76
+ # @!group Paths
77
+
78
+ # Full path to the component template (if present)
79
+ # or view template/partial.
80
+ #
81
+ # @return [Class] The component class
82
+ def template_file_path
83
+ component? ? Dir.glob("#{directory_path}/#{file_name(true)}.*.erb").first : file_path
48
84
  end
85
+
86
+ # @!endgroup
49
87
  end
50
88
  end
@@ -1,31 +1,42 @@
1
1
  module Lookbook
2
- # Represents a **rendered** preview scenario
2
+ # Represents a **rendered** preview scenario.
3
+ #
4
+ # Extends ScenarioEntity with an `output`
5
+ # method that returns the rendered HTML output.
6
+ #
7
+ # See the [ScenarioEntity](./scenario_entity) docs for other available methods.
3
8
  #
4
- # @ignore methods
5
9
  # @api public
6
10
  class RenderedScenarioEntity
7
11
  delegate_missing_to :scenario
8
12
 
13
+ # @api private
9
14
  attr_reader :scenario
10
15
 
16
+ # @api private
11
17
  def initialize(scenario, output, params)
12
18
  @scenario = scenario
13
19
  @params = params
14
20
  @output = output
15
21
  end
16
22
 
23
+ # HTML output of the rendered scenario.
24
+ #
25
+ # @return [String] Rendered output
26
+ def output
27
+ @_output ||= CodeBeautifier.call(@output)
28
+ end
29
+
30
+ # @api private
17
31
  def source
18
32
  has_custom_template? ? template_source(template) : scenario.source
19
33
  end
20
34
 
35
+ # @api private
21
36
  def source_lang
22
37
  has_custom_template? ? template_lang(template) : scenario.source_lang
23
38
  end
24
39
 
25
- def output
26
- @_output ||= CodeBeautifier.call(@output)
27
- end
28
-
29
40
  protected
30
41
 
31
42
  attr_reader :params
@@ -1,7 +1,6 @@
1
1
  module Lookbook
2
2
  # Represents a preview scenario method within a preview class
3
3
  #
4
- # @ignore methods
5
4
  # @api public
6
5
  class ScenarioEntity < Entity
7
6
  include InspectableEntity
@@ -10,8 +9,15 @@ module Lookbook
10
9
 
11
10
  delegate :group, to: :code_object
12
11
 
12
+ # The preview that this scenario belongs to.
13
+ #
14
+ # @return [PreviewEntity] The parent preview entity
13
15
  attr_reader :preview
14
16
 
17
+ # @api private
18
+ alias_method :parent, :preview
19
+
20
+ # @api private
15
21
  def initialize(code_object, preview, priority: nil)
16
22
  @code_object = code_object
17
23
  @preview = preview
@@ -19,61 +25,116 @@ module Lookbook
19
25
  @lookup_path = "#{parent.lookup_path}/#{name}"
20
26
  end
21
27
 
28
+ # @!group Identity
29
+
30
+ # Human-readable unique scenario ID
31
+ #
32
+ # @return [String] The ID
22
33
  def id
23
34
  @_id ||= Utils.id(fetch_config(:id) { "#{parent.id}-#{code_object.name}" })
24
35
  end
25
36
 
37
+ # Parameter-safe scenario name.
38
+ #
39
+ # @return [String] The name
26
40
  def name
27
41
  @_name ||= Utils.name(code_object.name)
28
42
  end
29
43
 
44
+ # Entity type identifier.
45
+ # Returns `:scenario` for scenarios.
46
+ #
47
+ # @return [Symbol] The entity type
48
+ def type
49
+ :scenario
50
+ end
51
+
52
+ # @!endgroup
53
+
54
+ # @!group Display options
55
+
56
+ # Display options hash.
57
+ #
58
+ # Contains all display options defined via the `@display` tag
59
+ # merged with any globally-defined options.
60
+ #
61
+ # @return [Hash] The resolved display options
30
62
  def display_options
31
63
  parent.display_options.merge(fetch_config(:display_options, {}))
32
64
  end
33
65
 
66
+ # @!endgroup
67
+
68
+ # @!group Render Targets
69
+
70
+ # @api private
34
71
  def render_targets
35
72
  @_render_targets ||= RenderTargetCollection.new(load_render_targets)
36
73
  end
37
74
 
75
+ # @api private
76
+ alias_method :components, :render_targets
77
+
78
+ # The item (component or partial) that the scenario renders.
79
+ #
80
+ # The render target is guessed where possible (based on the preview class name)
81
+ # but can also be manually specified using the `@renders` tag.
82
+ #
83
+ # @example :ruby
84
+ # "This scenario renders: #{scenario.render_target.label}"
85
+ #
86
+ # @return [RenderableEntity] The render target
38
87
  def render_target
39
88
  render_targets.first
40
89
  end
41
90
 
91
+ alias_method :component, :render_target
92
+
93
+ # @!endgroup
94
+
95
+ # @!group URLs
96
+
97
+ # The inspector URL path for this preview
98
+ #
99
+ # @return [String] URL path
100
+ def inspect_path
101
+ lookbook_inspect_path(lookup_path)
102
+ end
103
+
104
+ # The standalone preview URL path for this preview
105
+ #
106
+ # @return [String] URL path
107
+ def preview_path
108
+ lookbook_preview_path(lookup_path)
109
+ end
110
+
111
+ # @!endgroup
112
+
113
+ # @api private
42
114
  def scenarios
43
115
  [self]
44
116
  end
45
117
 
118
+ # @api private
46
119
  def template_source(template_path)
47
120
  source_path = template_file_path(template_path)
48
121
  source_path ? File.read(source_path) : nil
49
122
  end
50
123
 
124
+ # @api private
51
125
  def template_lang(template_path)
52
126
  path = template_file_path(template_path)
53
127
  Lookbook::Lang.guess(path) || Lookbook::Lang.find(:html)
54
128
  end
55
129
 
130
+ # @api private
56
131
  def search_terms
57
132
  [parent.label, label]
58
133
  end
59
134
 
60
- def url_path
61
- lookbook_inspect_path(lookup_path)
62
- end
63
-
64
- def preview_path
65
- lookbook_preview_path(lookup_path)
66
- end
67
-
68
- def type
69
- :scenario
70
- end
71
-
72
- alias_method :parent, :preview
73
- alias_method :components, :render_targets
74
- alias_method :component, :render_target
75
135
  alias_method :lang, :source_lang
76
136
  alias_method :examples, :scenarios
137
+ alias_method :url_path, :inspect_path
77
138
 
78
139
  deprecate lang: :source_lang, deprecator: Deprecation
79
140
  deprecate examples: :scenarios, deprecator: Deprecation