lookbook 2.0.0.beta.2 → 2.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/lookbook/css/fonts.css +33 -0
  3. data/app/assets/lookbook/css/lookbook.css +7 -0
  4. data/app/assets/lookbook/css/themes/blue.css +4 -1
  5. data/app/assets/lookbook/css/themes/green.css +4 -1
  6. data/app/assets/lookbook/css/themes/indigo.css +4 -1
  7. data/app/assets/lookbook/css/themes/rose.css +4 -1
  8. data/app/assets/lookbook/css/themes/zinc.css +4 -1
  9. data/app/assets/lookbook/fonts/Inter-italic.var.woff2 +0 -0
  10. data/app/assets/lookbook/fonts/Inter-roman.var.woff2 +0 -0
  11. data/app/assets/lookbook/fonts/SourceCodeVariable-Italic.ttf.woff2 +0 -0
  12. data/app/assets/lookbook/fonts/SourceCodeVariable-Roman.ttf.woff2 +0 -0
  13. data/app/assets/lookbook/img/lucide-sprite.svg +869 -869
  14. data/app/assets/lookbook/js/lib/lookbook.js +12 -2
  15. data/app/components/lookbook/code/highlight_github.css +16 -17
  16. data/app/components/lookbook/dimensions_display/component.js +4 -7
  17. data/app/components/lookbook/file_source/component.html.erb +9 -0
  18. data/app/components/lookbook/file_source/component.rb +73 -0
  19. data/app/components/lookbook/header/component.html.erb +11 -8
  20. data/app/components/lookbook/icon/component.css +1 -1
  21. data/app/components/lookbook/icon/component.html.erb +1 -1
  22. data/app/components/lookbook/icon/component.rb +4 -1
  23. data/app/components/lookbook/logo/component.html.erb +6 -0
  24. data/app/components/lookbook/logo/component.rb +15 -0
  25. data/app/components/lookbook/message/component.css +33 -0
  26. data/app/components/lookbook/message/component.html.erb +26 -0
  27. data/app/components/lookbook/message/component.rb +13 -0
  28. data/app/components/lookbook/nav/entity/component.html.erb +2 -2
  29. data/app/components/lookbook/nav/entity/component.rb +1 -1
  30. data/app/components/lookbook/page_tabs/component.html.erb +2 -2
  31. data/app/components/lookbook/params/field/component.css +3 -3
  32. data/app/components/lookbook/prose/component.css +8 -1
  33. data/app/components/lookbook/prose/component.html.erb +6 -1
  34. data/app/components/lookbook/prose/component.rb +2 -2
  35. data/app/controllers/concerns/lookbook/targetable_concern.rb +2 -16
  36. data/app/controllers/lookbook/application_controller.rb +38 -14
  37. data/app/controllers/lookbook/embeds_controller.rb +3 -4
  38. data/app/controllers/lookbook/inspector_controller.rb +4 -12
  39. data/app/controllers/lookbook/pages_controller.rb +15 -27
  40. data/app/controllers/lookbook/preview_controller.rb +30 -2
  41. data/app/controllers/lookbook/previews_controller.rb +13 -15
  42. data/app/views/layouts/lookbook/application.html.erb +1 -0
  43. data/app/views/layouts/lookbook/skeleton.html.erb +2 -2
  44. data/app/views/lookbook/errors/default.html.erb +40 -0
  45. data/app/views/lookbook/errors/not_found.html.erb +10 -0
  46. data/app/views/lookbook/index.html.erb +29 -24
  47. data/app/views/lookbook/pages/show.html.erb +9 -8
  48. data/app/views/lookbook/partials/_blank_slate.html.erb +7 -0
  49. data/config/app.yml +8 -0
  50. data/config/routes.rb +2 -0
  51. data/lib/lookbook/engine.rb +12 -5
  52. data/lib/lookbook/entities/concerns/annotatable_entity.rb +26 -1
  53. data/lib/lookbook/entities/concerns/inspectable_entity.rb +17 -2
  54. data/lib/lookbook/entities/concerns/locatable_entity.rb +51 -7
  55. data/lib/lookbook/entities/concerns/navigable_entity.rb +14 -1
  56. data/lib/lookbook/entities/entity.rb +34 -12
  57. data/lib/lookbook/entities/page_entity.rb +68 -10
  58. data/lib/lookbook/entities/page_section_entity.rb +4 -0
  59. data/lib/lookbook/entities/preview_entity.rb +107 -17
  60. data/lib/lookbook/entities/renderable_entity.rb +47 -9
  61. data/lib/lookbook/entities/rendered_scenario_entity.rb +17 -6
  62. data/lib/lookbook/entities/scenario_entity.rb +77 -16
  63. data/lib/lookbook/entities/scenario_group_entity.rb +82 -9
  64. data/lib/lookbook/helpers/page_helper.rb +26 -1
  65. data/lib/lookbook/helpers/ui_elements_helper.rb +0 -24
  66. data/lib/lookbook/param.rb +1 -1
  67. data/lib/lookbook/services/markdown_renderer.rb +2 -4
  68. data/lib/lookbook/stores/config_store.rb +0 -12
  69. data/lib/lookbook/support/errors/config_error.rb +1 -1
  70. data/lib/lookbook/support/errors/error.rb +64 -0
  71. data/lib/lookbook/support/errors/parser_error.rb +1 -1
  72. data/lib/lookbook/support/errors/preview_template_error.rb +1 -1
  73. data/lib/lookbook/support/errors/routing_error.rb +7 -0
  74. data/lib/lookbook/support/errors/template_error.rb +7 -0
  75. data/lib/lookbook/version.rb +1 -1
  76. data/public/lookbook-assets/Inter-italic.var.69eb0fe1.woff2 +0 -0
  77. data/public/lookbook-assets/Inter-italic.var.736a7044.woff2 +0 -0
  78. data/public/lookbook-assets/Inter-roman.var.b695afbe.woff2 +0 -0
  79. data/public/lookbook-assets/Inter-roman.var.fbdd51d0.woff2 +0 -0
  80. data/public/lookbook-assets/SourceCodeVariable-Italic.cad97b83.otf +0 -0
  81. data/public/lookbook-assets/SourceCodeVariable-Italic.ttf.09b4354a.woff2 +0 -0
  82. data/public/lookbook-assets/SourceCodeVariable-Italic.ttf.fcd7e9f4.woff2 +0 -0
  83. data/public/lookbook-assets/SourceCodeVariable-Roman.185ddb17.otf +0 -0
  84. data/public/lookbook-assets/SourceCodeVariable-Roman.ttf.118e9f22.woff2 +0 -0
  85. data/public/lookbook-assets/SourceCodeVariable-Roman.ttf.91043609.woff2 +0 -0
  86. data/public/lookbook-assets/css/lookbook.css +417 -58
  87. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  88. data/public/lookbook-assets/css/themes/blue.css +4 -1
  89. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  90. data/public/lookbook-assets/css/themes/green.css +4 -1
  91. data/public/lookbook-assets/css/themes/green.css.map +1 -1
  92. data/public/lookbook-assets/css/themes/indigo.css +4 -1
  93. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  94. data/public/lookbook-assets/css/themes/rose.css +4 -1
  95. data/public/lookbook-assets/css/themes/rose.css.map +1 -1
  96. data/public/lookbook-assets/css/themes/zinc.css +4 -1
  97. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  98. data/public/lookbook-assets/img/lucide-sprite.svg +869 -869
  99. data/public/lookbook-assets/js/index.js +173 -173
  100. data/public/lookbook-assets/js/index.js.map +1 -1
  101. data/public/lookbook-assets/js/lookbook-core.js +4 -2
  102. data/public/lookbook-assets/js/lookbook.js +4 -2
  103. metadata +31 -26
  104. data/app/views/layouts/lookbook/shell.html.erb +0 -25
  105. data/app/views/lookbook/404.html.erb +0 -15
  106. data/app/views/lookbook/error.html.erb +0 -46
  107. data/lib/lookbook/error.rb +0 -120
  108. data/lib/lookbook/support/errors/lookbook_error.rb +0 -21
  109. data/lib/tasks/lookbook_tasks.rake +0 -10
  110. data/public/lookbook-assets/css/app.css +0 -2341
  111. data/public/lookbook-assets/css/app.css.map +0 -11
  112. data/public/lookbook-assets/css/themes/zinc.css.map.91837.5 +0 -1
  113. data/public/lookbook-assets/feather-sprite.svg +0 -1
  114. data/public/lookbook-assets/js/app.js +0 -10862
  115. data/public/lookbook-assets/js/app.js.map +0 -2571
  116. data/public/lookbook-assets/js/embed.js +0 -1427
  117. data/public/lookbook-assets/js/embed.js.91837.6 +0 -0
  118. data/public/lookbook-assets/js/embed.js.map +0 -1
  119. data/public/lookbook-assets/js/lookbook-core.js.map +0 -1
  120. data/public/lookbook-assets/js/lookbook.js.map +0 -1
  121. data/public/lookbook-assets/lookbook-esm.js +0 -1427
  122. data/public/lookbook-assets/lookbook-esm.js.map +0 -1
  123. data/public/lookbook-assets/lookbook-global.js +0 -1427
  124. data/public/lookbook-assets/lookbook-global.js.map +0 -1
  125. data/public/lookbook-assets/lookbook.js +0 -1427
  126. data/public/lookbook-assets/lookbook.js.map +0 -1
@@ -57,18 +57,17 @@ module Lookbook
57
57
  end
58
58
  end
59
59
 
60
- show_404 layout: "lookbook/skeleton"
60
+ raise_not_found("Preview not found")
61
61
  end
62
62
 
63
63
  def show
64
64
  @embed = true
65
-
66
65
  unless @target
67
- @target = @scenario_choices.first || @preview.default_scenario
66
+ @target = @scenario_choices.first || @preview&.default_scenario
68
67
  if @target
69
68
  redirect_to lookbook_embed_path(@target.path, req_params)
70
69
  else
71
- show_404(layout: "lookbook/skeleton") unless @target
70
+ raise_not_found("Preview not found")
72
71
  end
73
72
  end
74
73
  end
@@ -4,23 +4,15 @@ module Lookbook
4
4
  include WithPanelsConcern
5
5
  include WithPreviewControllerConcern
6
6
 
7
- layout "lookbook/application"
8
-
9
7
  def self.controller_path
10
8
  "lookbook/inspector"
11
9
  end
12
10
 
13
11
  def show
14
- if @target
15
- begin
16
- @main_panels = main_panels
17
- @drawer_panels = drawer_panels
18
- rescue => exception
19
- render_in_layout "lookbook/error", layout: "lookbook/application", error: prettify_error(exception)
20
- end
21
- else
22
- show_404
23
- end
12
+ raise_not_found("Preview not found") unless @target
13
+
14
+ @main_panels = main_panels
15
+ @drawer_panels = drawer_panels
24
16
  end
25
17
  end
26
18
  end
@@ -1,6 +1,5 @@
1
1
  module Lookbook
2
2
  class PagesController < ApplicationController
3
- layout "lookbook/application"
4
3
  helper_method :page_controller
5
4
 
6
5
  def self.controller_path
@@ -9,40 +8,29 @@ module Lookbook
9
8
 
10
9
  def index
11
10
  landing = Engine.pages.find(&:landing?) || Engine.pages.first
12
- if landing.present?
13
- redirect_to lookbook_page_path(landing.path)
14
- else
15
- show_404
16
- end
11
+ raise_not_found("Page not found") unless landing.present?
12
+
13
+ redirect_to lookbook_page_path(landing.path)
17
14
  end
18
15
 
19
16
  def show
20
17
  @page = @pages.find_by_path(params[:path])
21
- if @page
22
- @next_page = @pages.next(@page)
23
- @previous_page = @pages.previous(@page)
24
- begin
25
- @page_content = page_controller.render_page(@page)
26
- @title = @page.title
27
- rescue => exception
28
- render_in_layout "lookbook/error",
29
- layout: "lookbook/application",
30
- error: Lookbook::Error.new(exception, file_path: @page.file_path, source_code: @page.content)
31
- end
32
- else
33
- show_404
34
- end
18
+ raise_not_found("Page not found") unless @page
19
+
20
+ @page_content = page_controller.render_page(@page)
21
+ @title = @page.title
22
+ @next_page = @pages.next(@page)
23
+ @previous_page = @pages.previous(@page)
24
+ rescue ActionView::Template::Error => err
25
+ raise Lookbook::TemplateError.new(
26
+ original: err,
27
+ file_path: @page.file_path,
28
+ source: @page.content
29
+ )
35
30
  end
36
31
 
37
32
  protected
38
33
 
39
- def show_404
40
- render "lookbook/404", locals: {
41
- message: "Page not found",
42
- description: "The page may have been removed or renamed."
43
- }
44
- end
45
-
46
34
  def page_controller
47
35
  controller_class = Lookbook.config.page_controller.constantize
48
36
  controller = controller_class.new
@@ -6,12 +6,40 @@ module Lookbook
6
6
 
7
7
  private
8
8
 
9
- [:determine_layout, :prepend_application_view_paths, :prepend_preview_examples_view_path].each do |method_name|
10
- define_method method_name, ViewComponentsController.instance_method(method_name)
9
+ def set_locale(&block)
10
+ I18n.with_locale(params[:locale] || I18n.default_locale, &block)
11
+ end
12
+
13
+ # Returns either {} or {layout: value} depending on configuration
14
+ def determine_layout(layout_override = nil, prepend_views: true)
15
+ return {} unless defined?(Rails.root)
16
+
17
+ layout_declaration = {}
18
+
19
+ if !layout_override.nil?
20
+ # Allow component-level override, even if false (thus no layout rendered)
21
+ layout_declaration[:layout] = layout_override
22
+ elsif default_preview_layout.present?
23
+ layout_declaration[:layout] = default_preview_layout
24
+ end
25
+
26
+ prepend_application_view_paths if layout_declaration[:layout].present? && prepend_views
27
+
28
+ layout_declaration
11
29
  end
12
30
 
13
31
  def default_preview_layout
14
32
  Lookbook.config.preview_layout
15
33
  end
34
+
35
+ def prepend_application_view_paths
36
+ prepend_view_path Rails.root.join("app/views") if defined?(Rails.root)
37
+ end
38
+
39
+ def prepend_preview_scenarios_view_path
40
+ prepend_view_path(Engine.preview_paths)
41
+ end
42
+
43
+ alias_method :prepend_preview_examples_view_path, :prepend_preview_scenarios_view_path
16
44
  end
17
45
  end
@@ -37,21 +37,15 @@ module Lookbook
37
37
  end
38
38
 
39
39
  def show
40
- if @target
41
- begin
42
- opts = {layout: @preview.layout}
43
- if embedded?
44
- opts[:append_html] = render_to_string("lookbook/partials/_iframe_content_scripts", layout: nil)
45
- end
46
- @preview_html = preview_controller.process(:render_in_layout_to_string, "lookbook/previews/group", inspector_data, **opts)
47
- rescue => exception
48
- render_in_layout "lookbook/error",
49
- layout: "lookbook/skeleton",
50
- error: prettify_error(exception)
51
- end
52
- else
53
- show_404
54
- end
40
+ raise_not_found("Preview not found") unless @target
41
+
42
+ @preview_html = preview_controller.process(
43
+ :render_in_layout_to_string,
44
+ "lookbook/previews/group",
45
+ inspector_data,
46
+ layout: @preview.layout,
47
+ append_html: (iframe_content_scripts if embedded?)
48
+ )
55
49
  end
56
50
 
57
51
  private
@@ -60,6 +54,10 @@ module Lookbook
60
54
  params[:lookbook_embed] == "true"
61
55
  end
62
56
 
57
+ def iframe_content_scripts
58
+ render_to_string("lookbook/partials/_iframe_content_scripts", layout: nil)
59
+ end
60
+
63
61
  def scenario_json(scenario)
64
62
  {
65
63
  name: scenario.name,
@@ -6,6 +6,7 @@
6
6
  @popstate.window="handleNavigation"
7
7
  @click.document="hijax"
8
8
  @navigation:start="closeMobileSidebar"
9
+ @dom:update-complete.window="Lookbook.initEmbeds()"
9
10
  class="w-screen h-screen grid grid-rows-[40px_1fr] relative">
10
11
 
11
12
  <%= render "lookbook/partials/user_styles" %>
@@ -17,11 +17,11 @@
17
17
  <% if @config.ui_favicon == true %>
18
18
  <link
19
19
  rel="icon"
20
- href="data:image/svg+xml,%3Csvg width='96' height='84' viewBox='0 0 96 84' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3CclipPath id='a'%3E%3Cpath d='M96 0v84H0V0h96Z'/%3E%3C/clipPath%3E%3CclipPath id='b'%3E%3Cpath d='M71.897 0a1.5 1.5 0 0 1 1.31.769l22.605 40.5a1.5 1.5 0 0 1 0 1.462l-22.605 40.5a1.5 1.5 0 0 1-1.31.769H49.481a1 1 0 0 1-.873-1.487L70.812 42.73a1.5 1.5 0 0 0 0-1.462L48.608 1.487A1 1 0 0 1 49.481 0ZM24.655.564l22.72 40.705a1.5 1.5 0 0 1 0 1.462l-22.72 40.705a1 1 0 0 1-1.746 0L.19 42.73a1.5 1.5 0 0 1 0-1.462L22.91.564a1 1 0 0 1 1.746 0Z'/%3E%3C/clipPath%3E%3C/defs%3E%3Cg clip-path='url(%23a)'%3E%3Cg clip-path='url(%23b)'%3E%3Cpath fill='<%= url_encode @theme.favicon_dark_mode %>' d='M0 0h96v84H0V0z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"
20
+ href="data:image/svg+xml,%3Csvg viewBox='0 0 167 204' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23FFF' fill-rule='nonzero'%3E%3Cpath d='M157 0c5.523 0 10 4.477 10 10v184c0 5.523-4.477 10-10 10H32.969C17 204 3.687 192.638.65 177.554A9.97 9.97 0 0 1 0 174c0-.512.011-1.017.033-1.516A33.115 33.115 0 0 1 0 171V33C0 14.778 14.758 0 32.969 0H157Zm-10 166H32.969c-8.292 0-12.22 2.22-12.871 6.606.79 6.424 6.253 11.394 12.87 11.394H147v-18Zm0-146H32.969c-7.056 0-12.8 5.65-12.965 12.689L20 33v114.762c3.932-1.167 8.3-1.762 12.969-1.762H147V20Z'/%3E%3Cpath d='M64.022 126c-4.107 0-7.304-1.143-9.591-3.428-2.287-2.285-3.431-5.48-3.431-9.583l.14-63.978c0-4.197 1.12-7.415 3.36-9.653C56.74 37.119 59.916 36 64.023 36c4.2 0 7.398 1.12 9.592 3.358 2.193 2.238 3.29 5.456 3.29 9.653l-.14 55.584h34.166c3.547 0 6.277.91 8.19 2.728 1.915 1.819 2.871 4.454 2.871 7.905 0 3.45-.956 6.109-2.87 7.974-1.914 1.865-4.644 2.798-8.191 2.798H64.022Z'/%3E%3C/g%3E%3C/svg%3E"
21
21
  media="(prefers-color-scheme: dark)">
22
22
  <link
23
23
  rel="icon"
24
- href="data:image/svg+xml,%3Csvg width='96' height='84' viewBox='0 0 96 84' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3CclipPath id='a'%3E%3Cpath d='M96 0v84H0V0h96Z'/%3E%3C/clipPath%3E%3CclipPath id='b'%3E%3Cpath d='M71.897 0a1.5 1.5 0 0 1 1.31.769l22.605 40.5a1.5 1.5 0 0 1 0 1.462l-22.605 40.5a1.5 1.5 0 0 1-1.31.769H49.481a1 1 0 0 1-.873-1.487L70.812 42.73a1.5 1.5 0 0 0 0-1.462L48.608 1.487A1 1 0 0 1 49.481 0ZM24.655.564l22.72 40.705a1.5 1.5 0 0 1 0 1.462l-22.72 40.705a1 1 0 0 1-1.746 0L.19 42.73a1.5 1.5 0 0 1 0-1.462L22.91.564a1 1 0 0 1 1.746 0Z'/%3E%3C/clipPath%3E%3C/defs%3E%3Cg clip-path='url(%23a)'%3E%3Cg clip-path='url(%23b)'%3E%3Cpath fill='<%= url_encode @theme.favicon_light_mode %>' d='M0 0h96v84H0V0z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"
24
+ href="data:image/svg+xml,%3Csvg viewBox='0 0 167 204' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%233730A3' fill-rule='nonzero'%3E%3Cpath d='M157 0c5.523 0 10 4.477 10 10v184c0 5.523-4.477 10-10 10H32.969C17 204 3.687 192.638.65 177.554A9.97 9.97 0 0 1 0 174c0-.512.011-1.017.033-1.516A33.115 33.115 0 0 1 0 171V33C0 14.778 14.758 0 32.969 0H157Zm-10 166H32.969c-8.292 0-12.22 2.22-12.871 6.606.79 6.424 6.253 11.394 12.87 11.394H147v-18Zm0-146H32.969c-7.056 0-12.8 5.65-12.965 12.689L20 33v114.762c3.932-1.167 8.3-1.762 12.969-1.762H147V20Z'/%3E%3Cpath d='M64.022 126c-4.107 0-7.304-1.143-9.591-3.428-2.287-2.285-3.431-5.48-3.431-9.583l.14-63.978c0-4.197 1.12-7.415 3.36-9.653C56.74 37.119 59.916 36 64.023 36c4.2 0 7.398 1.12 9.592 3.358 2.193 2.238 3.29 5.456 3.29 9.653l-.14 55.584h34.166c3.547 0 6.277.91 8.19 2.728 1.915 1.819 2.871 4.454 2.871 7.905 0 3.45-.956 6.109-2.87 7.974-1.914 1.865-4.644 2.798-8.191 2.798H64.022Z'/%3E%3C/g%3E%3C/svg%3E"
25
25
  media="(prefers-color-scheme: light)">
26
26
  <% end %>
27
27
 
@@ -0,0 +1,40 @@
1
+ <div class="bg-red-50 h-[calc(100vh_-_40px)] w-full overflow-y-auto">
2
+ <div>
3
+ <header class="px-8 py-6">
4
+ <h2 class="text-xl font-bold text-red-700"><%= @error.type %></h2>
5
+ </header>
6
+
7
+ <div class="px-8 py-6 mb-8 border-t border-b border-red-200 bg-red-100 text-base leading-relaxed">
8
+ <pre class="whitespace-pre-wrap font-sans leading-tight text-red-900"><%= @error.message %></pre>
9
+ </div>
10
+
11
+ <% if @error.file_path %>
12
+ <div class="text-sm mx-8 mb-3 font-mono">
13
+ <span><%= @error.relative_file_path %></span>
14
+ <% if @error.line_number %>
15
+ <span>[line <strong><%= @error.line_number %></strong>]</span>
16
+ <% end %>
17
+ </div>
18
+
19
+ <div class="px-8">
20
+ <%= lookbook_render :file_source,
21
+ file_path: @error.file_path,
22
+ highlight_lines: [@error.line_number],
23
+ lines_around_highlight: 5,
24
+ source: @error.source,
25
+ class: "border border-red-200" %>
26
+ </div>
27
+ <% end %>
28
+
29
+ <h3 class="font-bold mb-2 px-8 py-2 mt-8">Full stack trace:</h3>
30
+ <div class="text-xs font-mono w-full overflow-auto">
31
+ <div class="px-8 pb-10 text-gray-400 leading-relaxed whitespace-nowrap">
32
+ <% @error.backtrace.each do |line| %>
33
+ <div class="hover:text-gray-900 transition-colors duration-100">
34
+ <%= line %>
35
+ </div>
36
+ <% end %>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
@@ -0,0 +1,10 @@
1
+ <%= render "lookbook/partials/blank_slate" do %>
2
+ <%= lookbook_render :message,
3
+ id: "not-found-message",
4
+ title: @error.message,
5
+ icon: :file_x,
6
+ icon_position: :right,
7
+ theme: :error do %>
8
+ <%= @error.detail || "It may have been moved or deleted." %>
9
+ <% end %>
10
+ <% end %>
@@ -1,25 +1,30 @@
1
- <div id="landing" class="flex flex-col items-center justify-center h-full w-full">
2
- <div class="text-center" id="landing-<%= @previews.any? ? "with" : "no" %>-content">
3
- <% if @config.project_name.downcase == "lookbook" %>
4
- <div class="flex justify-center pb-4">
5
- <svg class="flex-none mx-auto w-[140px]" viewBox="0 0 275 36">
6
- <g fill-rule="nonzero" fill="none">
7
- <path d="M4.536 35c-1.408 0-2.504-.392-3.288-1.176-.784-.784-1.176-1.88-1.176-3.288V5.576c0-1.44.384-2.544 1.152-3.312.768-.768 1.856-1.152 3.264-1.152 1.44 0 2.536.384 3.288 1.152.752.768 1.128 1.872 1.128 3.312v22.08h11.712c1.216 0 2.152.312 2.808.936.656.624.984 1.528.984 2.712 0 1.184-.328 2.096-.984 2.736-.656.64-1.592.96-2.808.96H4.536ZM42.066.632c3.425 0 6.425.72 9 2.16 2.577 1.44 4.585 3.464 6.025 6.072 1.44 2.608 2.16 5.672 2.16 9.192 0 2.624-.408 5.008-1.224 7.152-.816 2.144-1.984 3.992-3.504 5.544-1.52 1.552-3.336 2.736-5.448 3.552-2.112.816-4.448 1.224-7.008 1.224-3.424 0-6.432-.728-9.024-2.184-2.592-1.456-4.6-3.496-6.024-6.12-1.424-2.624-2.136-5.68-2.136-9.168 0-2.624.408-5.008 1.224-7.152.816-2.144 1.984-3.984 3.504-5.52 1.52-1.536 3.336-2.712 5.448-3.528C37.17 1.04 39.507.632 42.067.632Zm0 7.392c-1.663 0-3.095.392-4.295 1.176-1.2.784-2.12 1.92-2.76 3.408-.64 1.488-.96 3.304-.96 5.448 0 3.168.704 5.64 2.112 7.416 1.408 1.776 3.376 2.664 5.904 2.664 1.696 0 3.136-.4 4.32-1.2 1.07-.723 1.917-1.733 2.543-3.031-.39-1.314-.934-2.855-2.087-5.286-.07-.147-.07-.233 0-.38l2.187-5.84a8.262 8.262 0 0 0-1.06-1.735c-1.407-1.76-3.375-2.64-5.903-2.64ZM80.27.632c3.424 0 6.424.72 9 2.16 2.576 1.44 4.584 3.464 6.024 6.072 1.44 2.608 2.16 5.672 2.16 9.192 0 2.624-.408 5.008-1.224 7.152-.816 2.144-1.984 3.992-3.504 5.544-1.52 1.552-3.336 2.736-5.448 3.552-2.112.816-4.448 1.224-7.008 1.224-3.424 0-6.432-.728-9.024-2.184-2.592-1.456-4.6-3.496-6.024-6.12-1.424-2.624-2.136-5.68-2.136-9.168 0-2.624.408-5.008 1.224-7.152.816-2.144 1.984-3.984 3.504-5.52 1.52-1.536 3.336-2.712 5.448-3.528C75.373 1.04 77.71.632 80.27.632Zm0 7.392c-1.664 0-3.096.392-4.296 1.176-1.2.784-2.12 1.92-2.76 3.408-.64 1.488-.96 3.304-.96 5.448 0 3.168.704 5.64 2.112 7.416 1.408 1.776 3.376 2.664 5.904 2.664 1.696 0 3.136-.4 4.32-1.2.999-.675 1.804-1.6 2.416-2.775-.395-1.37-.933-2.95-2.162-5.542-.07-.147-.07-.233 0-.38l2.276-6.08a8.166 8.166 0 0 0-.946-1.495c-1.408-1.76-3.376-2.64-5.904-2.64Zm26.299 27.408c-1.408 0-2.496-.392-3.264-1.176-.768-.784-1.152-1.88-1.152-3.288V5.192c0-1.472.384-2.584 1.152-3.336.768-.752 1.856-1.128 3.264-1.128 1.44 0 2.536.376 3.288 1.128.752.752 1.128 1.864 1.128 3.336v10.464h.096l11.664-12.864a7.705 7.705 0 0 1 1.944-1.512c.688-.368 1.464-.552 2.328-.552 1.344 0 2.312.344 2.904 1.032.592.688.864 1.488.816 2.4-.048.912-.424 1.752-1.128 2.52l-11.616 12.336v-3.6l12.192 13.776c.832.928 1.248 1.88 1.248 2.856s-.328 1.784-.984 2.424c-.656.64-1.624.96-2.904.96-1.088 0-1.96-.216-2.616-.648-.656-.432-1.368-1.08-2.136-1.944L111.08 19.736h-.096v11.232c0 1.408-.368 2.504-1.104 3.288-.736.784-1.84 1.176-3.312 1.176Z" fill="#919191"/>
8
- <path d="M140.403 35c-1.504 0-2.648-.392-3.432-1.176-.784-.784-1.176-1.912-1.176-3.384V5.72c0-1.472.392-2.6 1.176-3.384.784-.784 1.928-1.176 3.432-1.176h11.712c2.432 0 4.504.36 6.216 1.08 1.712.72 3.016 1.736 3.912 3.048.896 1.312 1.344 2.848 1.344 4.608 0 1.984-.568 3.68-1.704 5.088-1.136 1.408-2.68 2.368-4.632 2.88v-.768c2.304.416 4.088 1.344 5.352 2.784 1.264 1.44 1.896 3.28 1.896 5.52 0 2.976-1.064 5.32-3.192 7.032-2.128 1.712-5.032 2.568-8.712 2.568h-12.192Zm3.84-6.48h7.152c1.632 0 2.824-.312 3.576-.936.752-.624 1.128-1.56 1.128-2.808 0-1.248-.376-2.176-1.128-2.784-.752-.608-1.944-.912-3.576-.912h-7.152v7.44Zm0-13.92h6.288c1.6 0 2.776-.288 3.528-.864.752-.576 1.128-1.456 1.128-2.64 0-1.184-.376-2.056-1.128-2.616-.752-.56-1.928-.84-3.528-.84h-6.288v6.96Zm41.034 20.928c-3.424 0-6.432-.728-9.024-2.184-2.592-1.456-4.6-3.496-6.024-6.12-1.424-2.624-2.136-5.68-2.136-9.168 0-2.624.408-5.008 1.224-7.152.816-2.144 1.984-3.984 3.504-5.52 1.52-1.536 3.336-2.712 5.448-3.528 2.112-.816 4.448-1.224 7.008-1.224 3.424 0 6.424.72 9 2.16 2.576 1.44 4.584 3.464 6.024 6.072 1.44 2.608 2.16 5.672 2.16 9.192 0 2.624-.408 5.008-1.224 7.152-.816 2.144-1.984 3.992-3.504 5.544-1.52 1.552-3.336 2.736-5.448 3.552-2.112.816-4.448 1.224-7.008 1.224Zm0-7.392c1.696 0 3.136-.4 4.32-1.2 1.184-.8 2.096-1.952 2.736-3.456.64-1.504.96-3.312.96-5.424 0-3.168-.704-5.632-2.112-7.392-1.408-1.76-3.376-2.64-5.904-2.64-1.664 0-3.096.392-4.296 1.176-1.2.784-2.12 1.92-2.76 3.408-.64 1.488-.96 3.304-.96 5.448 0 3.168.704 5.64 2.112 7.416 1.408 1.776 3.376 2.664 5.904 2.664Zm38.203 7.392c-3.424 0-6.432-.728-9.024-2.184-2.592-1.456-4.6-3.496-6.024-6.12-1.424-2.624-2.136-5.68-2.136-9.168 0-2.624.408-5.008 1.224-7.152.816-2.144 1.984-3.984 3.504-5.52 1.52-1.536 3.336-2.712 5.448-3.528 2.112-.816 4.448-1.224 7.008-1.224 3.424 0 6.424.72 9 2.16 2.576 1.44 4.584 3.464 6.024 6.072 1.44 2.608 2.16 5.672 2.16 9.192 0 2.624-.408 5.008-1.224 7.152-.816 2.144-1.984 3.992-3.504 5.544-1.52 1.552-3.336 2.736-5.448 3.552-2.112.816-4.448 1.224-7.008 1.224Zm0-7.392c1.696 0 3.136-.4 4.32-1.2 1.184-.8 2.096-1.952 2.736-3.456.64-1.504.96-3.312.96-5.424 0-3.168-.704-5.632-2.112-7.392-1.408-1.76-3.376-2.64-5.904-2.64-1.664 0-3.096.392-4.296 1.176-1.2.784-2.12 1.92-2.76 3.408-.64 1.488-.96 3.304-.96 5.448 0 3.168.704 5.64 2.112 7.416 1.408 1.776 3.376 2.664 5.904 2.664Zm26.299 7.296c-1.408 0-2.496-.392-3.264-1.176-.768-.784-1.152-1.88-1.152-3.288V5.192c0-1.472.384-2.584 1.152-3.336.768-.752 1.856-1.128 3.264-1.128 1.44 0 2.536.376 3.288 1.128.752.752 1.128 1.864 1.128 3.336v10.464h.096l11.664-12.864a7.705 7.705 0 0 1 1.944-1.512c.688-.368 1.464-.552 2.328-.552 1.344 0 2.312.344 2.904 1.032.592.688.864 1.488.816 2.4-.048.912-.424 1.752-1.128 2.52l-11.616 12.336v-3.6l12.192 13.776c.832.928 1.248 1.88 1.248 2.856s-.328 1.784-.984 2.424c-.656.64-1.624.96-2.904.96-1.088 0-1.96-.216-2.616-.648-.656-.432-1.368-1.08-2.136-1.944L254.29 19.736h-.096v11.232c0 1.408-.368 2.504-1.104 3.288-.736.784-1.84 1.176-3.312 1.176Z" fill="#ABABAB"/>
9
- </g>
10
- </svg>
11
- </div>
12
- <% elsif @config.project_name != false %>
13
- <h5 class="text-base text-lookbook-blank-slate-title truncate uppercase font-black tracking-wide mb-2">
14
- <%= @config.project_name %>
15
- </h5>
1
+ <%= render "lookbook/partials/blank_slate" do %>
2
+ <% if @blank_slate %>
3
+ <%= lookbook_render :message,
4
+ id: "welcome-message",
5
+ title: "Welcome to your Lookbook!",
6
+ icon: :logo do %>
7
+ <p>
8
+ There isn't much to see yet, but
9
+ <%= link_to "component previews",
10
+ "#{@config.links.docs}/guide/previews",
11
+ target: "_blank"
12
+ %>
13
+ and
14
+ <%= link_to "content pages",
15
+ "#{@config.links.docs}/guide/pages",
16
+ target: "_blank"
17
+ %>
18
+ will show up here as soon as they are added.
19
+ </p>
20
+ <% end %>
21
+ <% else %>
22
+ <%= lookbook_render :message,
23
+ id: "get-started-message",
24
+ title: @config.project_name,
25
+ icon: :inspect,
26
+ icon_position: :right do %>
27
+ <p>Select a preview from the nav to get started.</p>
28
+ <% end %>
16
29
  <% end %>
17
- <div class="opacity-60">
18
- <% if @previews.any? %>
19
- <p>Select a preview from the nav to get started.</p>
20
- <% else %>
21
- <p><a class="underline" href="https://lookbook.build/guide/previews" target="_blank">Create a preview</a> to get started.</p>
22
- <% end %>
23
- </div>
24
- </div>
25
- </div>
30
+ <% end %>
@@ -1,15 +1,14 @@
1
1
  <main
2
2
  class="h-[calc(100vh_-_40px)]"
3
3
  x-data="{}"
4
- @navigation:complete.window="$refs.scroller.scrollTop = 0;"
5
- @dom:update-complete.window="Lookbook.initEmbeds();">
4
+ @navigation:complete.window="$refs.scroller.scrollTop = 0">
6
5
  <div class="h-full bg-lookbook-page-bg relative">
7
6
  <% unless @error %>
8
-
7
+
9
8
  <div class="absolute top-0 right-0 pt-1 pr-0 pl-1 pb-1 rounded-bl-md">
10
9
  <div class="bg-lookbook-page-bg opacity-90 absolute inset-0 w-full h-full z-0"></div>
11
10
  <div class="relative z-10 flex items-center">
12
-
11
+
13
12
  <% if @previous_page %>
14
13
  <%= lookbook_render :icon_button,
15
14
  size: :lg,
@@ -46,19 +45,21 @@
46
45
  <div class="px-4 md:px-10 pt-8 md:pt-10 overflow-auto scroll-smooth w-full max-h-full pb-12" x-ref="scroller">
47
46
  <div class="w-full max-w-screen-lg mx-auto h-full flex flex-col">
48
47
  <% if @page.header? %>
49
- <header id="page-header" class="mb-8 prose max-w-none flex-none">
50
- <h1><%= @page.title %></h1>
48
+ <header id="page-header" class="mb-7 pb-6 lg:mb-9 lg:pb-8 border-b border-lookbook-divider">
49
+ <%= lookbook_render :prose, size: :md, markdown: false, class: "max-w-none flex-none" do %>
50
+ <h1><%= @page.title %></h1>
51
+ <% end %>
51
52
  </header>
52
53
  <% end %>
53
54
 
54
- <%= lookbook_render :prose, id: "page-content", markdown: false, class: "max-w-none flex-none" do %>
55
+ <%= lookbook_render :prose, size: :md, id: "page-content", markdown: false, class: "max-w-none flex-none min-h-[50vh]" do %>
55
56
  <%= @page_content %>
56
57
  <% end %>
57
58
 
58
59
  <% if @page.sections.any? %>
59
60
  <%= lookbook_render :page_tabs, id: "page-tabbed-sections", markdown: false, class: "mt-6" do |page_tabs| %>
60
61
  <% @page.sections.each do |section| %>
61
- <% page_tabs.tab name: "page-section-#{section.name}", label: section.label do %>
62
+ <% page_tabs.with_tab name: "page-section-#{section.name}", label: section.label do %>
62
63
  <%= page_controller.render_page(section) %>
63
64
  <% end %>
64
65
  <% end %>
@@ -0,0 +1,7 @@
1
+ <div class="flex justify-center w-full h-full bg-checked">
2
+ <div class="px-4 py-6 xs:py-8 sm:p-8 md:p-12">
3
+ <div class="w-full xs:w-auto xs:mx-auto xs:min-w-[440px] xs:max-w-[680px]">
4
+ <%= yield %>
5
+ </div>
6
+ </div>
7
+ </div>
data/config/app.yml CHANGED
@@ -42,6 +42,7 @@ shared:
42
42
  component_paths: [app/views]
43
43
 
44
44
  reload_on_change: ~
45
+ live_updates: false
45
46
  listen_paths: []
46
47
  listen_extensions: [rb, html.*]
47
48
 
@@ -55,8 +56,15 @@ shared:
55
56
  debug_menu: false
56
57
  experimental_features: false
57
58
 
59
+ links:
60
+ docs: https://v2.lookbook.build
61
+ demo: https://v2-demo.lookbook.build
62
+ repo: https://github.com/ViewComponent/lookbook/tree/v2
63
+
58
64
  development:
59
65
  debug_menu: true
66
+ live_updates: true
60
67
 
61
68
  test:
62
69
  debug_menu: true
70
+ live_updates: false
data/config/routes.rb CHANGED
@@ -17,4 +17,6 @@ Lookbook::Engine.routes.draw do
17
17
  get "/embed", to: "embeds#lookup", as: :lookbook_embed_lookup
18
18
  get "/embed/*path", to: "embeds#show", as: :lookbook_embed
19
19
  end
20
+
21
+ get "/*path", to: "application#not_found", via: :all
20
22
  end
@@ -26,7 +26,7 @@ module Lookbook
26
26
  end
27
27
 
28
28
  config.after_initialize do
29
- if opts.using_view_component || Rails.env.test?
29
+ if opts.using_view_component
30
30
  vc_config = Engine.host_config.view_component
31
31
 
32
32
  opts.preview_paths += vc_config.preview_paths
@@ -79,7 +79,10 @@ module Lookbook
79
79
  end
80
80
 
81
81
  def auto_refresh?
82
- reloading? && runtime_context.web? && FileWatcher.evented?
82
+ opts.live_updates == true &&
83
+ reloading? &&
84
+ runtime_context.web? &&
85
+ FileWatcher.evented?
83
86
  end
84
87
 
85
88
  def preview_embeds_allowed?
@@ -129,14 +132,18 @@ module Lookbook
129
132
  end
130
133
 
131
134
  def view_paths
132
- ActionView::ViewPaths.all_view_paths.flat_map do |view_path|
133
- view_path.paths.map { |path| Pathname(path.to_s) }
135
+ # handle view path registry changes in Rails 7.1
136
+ paths = if defined?(ActionView::PathRegistry)
137
+ ActionView::PathRegistry.all_file_system_resolvers.map(&:path)
138
+ else
139
+ ActionView::ViewPaths.all_view_paths.flat_map(&paths)
134
140
  end
141
+ paths.map { |path| Pathname(path.to_s) }
135
142
  end
136
143
 
137
144
  def component_paths
138
145
  @_component_paths ||= begin
139
- paths = [*opts.component_paths, *Engine.view_paths, host_app_path]
146
+ paths = [*opts.component_paths, *view_paths, host_app_path]
140
147
  PathUtils.normalize_paths(paths)
141
148
  end
142
149
  end
@@ -1,23 +1,48 @@
1
1
  module Lookbook
2
- # @api private
3
2
  module AnnotatableEntity
4
3
  extend ActiveSupport::Concern
5
4
 
6
5
  included do
7
6
  delegate :has_tag?, to: :code_object
8
7
 
8
+ # @!group Annotations
9
+
10
+ # Any notes added to the entity.
11
+ # Returns the raw (unrendered) string which may contain markdown formatting.
12
+ #
13
+ # @return [String] The notes, or an empty string if none have been added
9
14
  def notes
10
15
  code_object.docstring.to_s.strip
11
16
  end
12
17
 
18
+ # All tags that have been added to the entity.
19
+ # Can be filtered by tag name by providing the name as an argument.
20
+ #
21
+ # @example :ruby
22
+ # all_tags = entity.tags
23
+ # display_tags = entity.tags(:display)
24
+ #
25
+ # @param name [Symbol] Optional tag type to filter by
26
+ # @return [Array<YardTag>] Array of tags
13
27
  def tags(name = nil)
14
28
  code_object.tags(name)
15
29
  end
16
30
 
31
+ # The first tag (optionally of a particular type)
32
+ # added to the entity.
33
+ #
34
+ # @example :ruby
35
+ # first_tag = entity.tag
36
+ # first_display_tag = entity.tag(:display)
37
+ #
38
+ # @param name [Symbol] Optional tag type to filter by
39
+ # @return [Array<YardTag>] Array of tags
17
40
  def tag(name = nil)
18
41
  tags(name).first
19
42
  end
20
43
 
44
+ # @!endgroup
45
+
21
46
  protected
22
47
 
23
48
  attr_reader :code_object
@@ -1,9 +1,13 @@
1
1
  module Lookbook
2
- # @api private
3
2
  module InspectableEntity
4
3
  extend ActiveSupport::Concern
5
4
 
6
5
  included do
6
+ # @!group Source
7
+
8
+ # Scenario method source code
9
+ #
10
+ # @return [String] The source code0
7
11
  def source
8
12
  source_code = if custom_source?
9
13
  File.read(source_file_path)
@@ -19,10 +23,21 @@ module Lookbook
19
23
  source_code.strip_heredoc.strip
20
24
  end
21
25
 
26
+ # Source code language info.
27
+ #
28
+ # Returns a Hash with `name`, `ext` & `label` entries.
29
+ #
30
+ # @example :ruby
31
+ # source_lang_name = entity.lang[:name]
32
+ #
33
+ # @return [Hash] Language info hash
22
34
  def source_lang
23
35
  custom_source? ? Lang.guess(source_file_path, :ruby) : Lang.find(:ruby)
24
36
  end
25
37
 
38
+ # @!endgroup
39
+
40
+ # @api private
26
41
  def custom_source?
27
42
  source_file_path.present?
28
43
  end
@@ -35,7 +50,7 @@ module Lookbook
35
50
  @_source_path ||= if code_object.has_tag?(:source)
36
51
  source_path = code_object.tag(:source).value
37
52
  unless source_path.present? && File.exist?(source_path)
38
- raise LookbookError, "Could not find source file '#{source_path}'"
53
+ raise Lookbook::Error, "Could not find source file '#{source_path}'"
39
54
  end
40
55
  source_path
41
56
  end