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

Sign up to get free protection for your applications and to get access to all the features.
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,13 +1,28 @@
1
1
  module Lookbook
2
2
  # Represents a group of preview scenarios within a preview class
3
3
  #
4
- # @ignore methods
5
4
  # @api public
6
5
  class ScenarioGroupEntity < Entity
7
6
  include NavigableEntity
8
7
 
9
- attr_reader :scenarios, :preview
8
+ # @!group Scenarios
10
9
 
10
+ # Returns all scenarios within the group.
11
+ #
12
+ # @return [Array<ScenarioEntity>] All scenarios
13
+ attr_reader :scenarios
14
+
15
+ # @!endgroup
16
+
17
+ # The preview that this scenario belongs to.
18
+ #
19
+ # @return [PreviewEntity] The parent preview entity
20
+ attr_reader :preview
21
+
22
+ # @api private
23
+ alias_method :parent, :preview
24
+
25
+ # @api private
11
26
  def initialize(name, scenarios, preview)
12
27
  @name = Utils.name(name)
13
28
  @scenarios = ScenarioCollection.new(scenarios)
@@ -15,6 +30,14 @@ module Lookbook
15
30
  @lookup_path = "#{parent.lookup_path}/#{@name}"
16
31
  end
17
32
 
33
+ # @!group Display options
34
+
35
+ # Display options hash.
36
+ #
37
+ # Contains all display options defined via the `@display` tag
38
+ # for each scenario in the group, merged with any globally-defined options.
39
+ #
40
+ # @return [Hash] The resolved display options
18
41
  def display_options
19
42
  merged = {}
20
43
  scenarios.to_a.reverse.map do |scenario|
@@ -23,35 +46,85 @@ module Lookbook
23
46
  merged
24
47
  end
25
48
 
49
+ # @!endgroup
50
+
51
+ # @!group Render Targets
52
+
53
+ # Collection of render targets (components or partials)
54
+ # from each of the scenarios in the group.
55
+ #
56
+ # Render targets are guessed where possible (based on the preview class name)
57
+ # but can also be manually specified using the `@renders` tag.
58
+ #
59
+ # @example :ruby
60
+ # "This group renders: #{group.render_targets.map(&:label).join(", ")}"
61
+ #
62
+ # @return [Array<RenderableEntity>] Render target entities
26
63
  def render_targets
27
64
  @_render_targets ||= RenderTargetCollection.new(scenarios.flat_map(&:render_targets).uniq(&:lookup_path))
28
65
  end
29
66
 
30
- def search_terms
31
- [parent.label, label]
32
- end
67
+ alias_method :components, :render_targets
68
+
69
+ # @!endgroup
33
70
 
71
+ # @!group Annotations
72
+
73
+ # Collection of tags from each of the scenarios in the group.
74
+ # Can be filtered by tag name by providing the name as an argument.
75
+ #
76
+ # @example :ruby
77
+ # all_tags = group.tags
78
+ # display_tags = group.tags(:display)
79
+ #
80
+ # @param tag_name [Symbol] Optional tag type to filter by
81
+ # @return [Array<YardTag>] Array of tags
34
82
  def tags(tag_name = nil)
35
83
  scenarios.flat_map { |scenario| scenario.tags(tag_name) }
36
84
  end
37
85
 
86
+ # @api private
38
87
  def tag(tag_name = nil)
39
88
  tags(tag_name).first
40
89
  end
41
90
 
42
- def url_path
91
+ # @!endgroup
92
+
93
+ # @!group URLs
94
+
95
+ # The inspector URL path for this scenario group
96
+ #
97
+ # @return [String] URL path
98
+ def inspect_path
43
99
  lookbook_inspect_path(lookup_path)
44
100
  end
45
101
 
102
+ # The standalone preview URL path for this scenario group
103
+ #
104
+ # @return [String] URL path
46
105
  def preview_path
47
106
  lookbook_preview_path(lookup_path)
48
107
  end
49
108
 
109
+ alias_method :url_path, :inspect_path
110
+
111
+ # @!endgroup
112
+
113
+ # @!group Identity
114
+
115
+ # Entity type identifier.
116
+ # Returns `:scenario_group` for scenario groups.
117
+ #
118
+ # @return [Symbol] The entity type
50
119
  def type
51
- :group
120
+ :scenario_group
52
121
  end
53
122
 
54
- alias_method :parent, :preview
55
- alias_method :components, :render_targets
123
+ # @!endgroup
124
+
125
+ # @api private
126
+ def search_terms
127
+ [parent.label, label]
128
+ end
56
129
  end
57
130
  end
@@ -5,14 +5,39 @@ module Lookbook
5
5
  module PageHelper
6
6
  # Returns the URL path to a page.
7
7
  #
8
+ # @api private
8
9
  # @param id [String, PageEntity] The id or PageEntity instance to generate a URL path for
9
10
  def page_path(id)
10
11
  page = id.is_a?(PageEntity) ? id : Engine.pages.find_by_id(id)
11
12
  if page.present?
12
- lookbook_page_path page.lookup_path
13
+ page.docs_path
13
14
  else
14
15
  Lookbook.logger.warn "Could not find page with id ':#{id}'"
15
16
  end
16
17
  end
18
+
19
+ # Render a 'live' embed of a component preview.
20
+ #
21
+ # If no scenario name is provided then the default (first) preview
22
+ # scenario will be rendered in the embed.
23
+ #
24
+ # @param preview [String] Name of the preview class to embed
25
+ # @param scenario [String] Example method name
26
+ # @param opts [Hash] Options hash
27
+ def embed(preview, scenario = nil, **opts)
28
+ preview_entity = if preview.is_a?(Symbol)
29
+ Engine.previews.find_by_path(preview)
30
+ else
31
+ Engine.previews.find_by_preview_class(preview)
32
+ end
33
+ scenario_entity = scenario ? preview_entity&.scenario(scenario) : preview_entity&.default_scenario
34
+ opts[:actions] ||= ["inspect", "open"]
35
+
36
+ lookbook_render Embed::Component.new(
37
+ scenario: scenario_entity,
38
+ params: opts.fetch(:params, {}),
39
+ options: opts.except(:params)
40
+ )
41
+ end
17
42
  end
18
43
  end
@@ -34,30 +34,6 @@ module Lookbook
34
34
  lookbook_render :code, **opts, &block
35
35
  end
36
36
 
37
- # Render a 'live' embed of a component preview.
38
- #
39
- # If no scenario name is provided then the default (first) preview
40
- # scenario will be rendered in the embed.
41
- #
42
- # @param preview [String] Name of the preview class to embed
43
- # @param scenario [String] Example method name
44
- # @param opts [Hash] Options hash
45
- def embed(preview, scenario = nil, **opts)
46
- preview_entity = if preview.is_a?(Symbol)
47
- Engine.previews.find_by_path(preview)
48
- else
49
- Engine.previews.find_by_preview_class(preview)
50
- end
51
- scenario_entity = scenario ? preview_entity&.scenario(scenario) : preview_entity&.default_scenario
52
- opts[:actions] ||= ["inspect", "open"]
53
-
54
- lookbook_render Embed::Component.new(
55
- scenario: scenario_entity,
56
- params: opts.fetch(:params, {}),
57
- options: opts.except(:params)
58
- )
59
- end
60
-
61
37
  # @api private
62
38
  def prose(**opts, &block)
63
39
  lookbook_render :prose, **opts, &block
@@ -65,7 +65,7 @@ module Lookbook
65
65
 
66
66
  def input_config
67
67
  config = Lookbook::Engine.inputs.get_input(input)
68
- config || raise(LookbookError.new("Unknown input type '#{input}'"))
68
+ config || raise(Lookbook::Error.new("Unknown input type '#{input}'"))
69
69
  end
70
70
 
71
71
  def guess_input
@@ -27,22 +27,10 @@ module Lookbook
27
27
  store[:project_name] = (name == false) ? nil : name
28
28
  end
29
29
 
30
- def page_paths=(paths = nil)
31
- store[:page_paths].push(*paths.to_a)
32
- end
33
-
34
30
  def page_extensions=(extensions = nil)
35
31
  store[:page_extensions].push(*extensions.to_a).uniq!
36
32
  end
37
33
 
38
- def preview_paths=(paths = nil)
39
- store[:preview_paths].push(*paths.to_a)
40
- end
41
-
42
- def component_paths=(paths = nil)
43
- store[:component_paths].push(*paths.to_a)
44
- end
45
-
46
34
  def listen_extensions=(extensions = nil)
47
35
  store[:listen_extensions].push(*extensions.to_a).uniq!
48
36
  end
@@ -1,5 +1,5 @@
1
1
  module Lookbook
2
- class ConfigError < LookbookError
2
+ class ConfigError < Error
3
3
  def initialize(msg = nil, scope: "config", **kwargs)
4
4
  super(msg, scope: scope, **kwargs)
5
5
  end
@@ -0,0 +1,64 @@
1
+ module Lookbook
2
+ class Error < StandardError
3
+ attr_reader :scope, :original, :status, :detail, :source
4
+
5
+ def initialize(message = nil,
6
+ scope: nil, original: nil, status: nil, detail: nil,
7
+ file_path: nil, source: nil, line_number: nil, **kwargs)
8
+ @scope = scope
9
+ @original = original
10
+ @message = message
11
+ @status = status
12
+ @detail = detail
13
+ @file_path = file_path
14
+ @source = source
15
+ @line_number = line_number
16
+ super(message)
17
+ end
18
+
19
+ def message
20
+ @message || original&.message
21
+ end
22
+
23
+ def backtrace
24
+ original&.backtrace || super
25
+ end
26
+
27
+ def type
28
+ (original.presence || self).class.to_s
29
+ end
30
+
31
+ def file_path
32
+ return @file_path.to_s if @file_path.present?
33
+
34
+ parsed_backtrace[0][0] if parsed_backtrace.any?
35
+ end
36
+
37
+ def relative_file_path
38
+ file_path&.delete_prefix("#{Rails.root}/")
39
+ end
40
+
41
+ def line_number
42
+ return @line_number.to_i if @line_number.present?
43
+
44
+ if parsed_backtrace.any?
45
+ number = parsed_backtrace[0][1]
46
+ number.to_i if number.present?
47
+ end
48
+ end
49
+
50
+ def backtrace_lines
51
+ root = Rails.root.to_s
52
+ backtrace.map { |line| line.gsub(root, "") }
53
+ end
54
+
55
+ protected
56
+
57
+ def parsed_backtrace
58
+ backtrace.map do |line|
59
+ line =~ /^(.+?):(\d+)(|:in `(.+)')$/
60
+ [$1, $2, $4]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,5 +1,5 @@
1
1
  module Lookbook
2
- class ParserError < LookbookError
2
+ class ParserError < Error
3
3
  def initialize(msg = nil, scope: "parser", **kwargs)
4
4
  super(msg, scope: scope, **kwargs)
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Lookbook
2
- class PreviewTemplateError < LookbookError
2
+ class PreviewTemplateError < Error
3
3
  def initialize(msg = nil, scope: "preview", **kwargs)
4
4
  super(msg, scope: scope, **kwargs)
5
5
  end
@@ -0,0 +1,7 @@
1
+ module Lookbook
2
+ class RoutingError < Error
3
+ def initialize(msg = nil, scope: "request", **kwargs)
4
+ super(msg, scope: scope, status: :not_found, **kwargs)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Lookbook
2
+ class TemplateError < Error
3
+ def initialize(msg = nil, scope: "template", **kwargs)
4
+ super(msg, scope: scope, **kwargs)
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Lookbook
2
- VERSION = "2.0.0.beta.3"
2
+ VERSION = "2.0.0.beta.4"
3
3
  end