lookbook 1.5.2 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -24
  3. data/app/assets/lookbook/css/lookbook.css +9 -0
  4. data/app/assets/lookbook/css/themes/blue.css +7 -0
  5. data/app/assets/lookbook/css/themes/green.css +7 -0
  6. data/app/assets/lookbook/css/themes/indigo.css +7 -0
  7. data/app/assets/lookbook/css/themes/rose.css +7 -0
  8. data/app/assets/lookbook/css/themes/zinc.css +7 -0
  9. data/app/assets/lookbook/css/tooltip.css +9 -6
  10. data/app/assets/lookbook/img/lucide-sprite.svg +4960 -0
  11. data/app/assets/lookbook/js/app.js +22 -4
  12. data/app/assets/lookbook/js/helpers/dom.js +4 -7
  13. data/app/assets/lookbook/js/helpers/string.js +4 -11
  14. data/app/assets/lookbook/js/{embed.js → iframe.js} +0 -0
  15. data/app/assets/lookbook/js/index.js +61 -0
  16. data/app/assets/lookbook/js/lib/lookbook.js +113 -0
  17. data/app/assets/lookbook/js/lib/tippy.js +1 -0
  18. data/app/assets/lookbook/js/lookbook-core.js +1 -0
  19. data/app/assets/lookbook/js/lookbook.js +2 -61
  20. data/app/components/lookbook/base_component.rb +3 -1
  21. data/app/components/lookbook/button/component.html.erb +13 -24
  22. data/app/components/lookbook/button/component.js +13 -3
  23. data/app/components/lookbook/button/component.rb +16 -25
  24. data/app/components/lookbook/code/component.rb +0 -2
  25. data/app/components/lookbook/copy_button/component.html.erb +4 -4
  26. data/app/components/lookbook/copy_button/component.rb +6 -3
  27. data/app/components/lookbook/debug_menu/component.html.erb +1 -0
  28. data/app/components/lookbook/debug_menu/component.rb +12 -1
  29. data/app/components/lookbook/display_options/editor/component.html.erb +1 -1
  30. data/app/components/lookbook/display_options/field/component.css +0 -26
  31. data/app/components/lookbook/display_options/field/component.html.erb +1 -1
  32. data/app/components/lookbook/embed/component.html.erb +6 -51
  33. data/app/components/lookbook/embed/component.rb +17 -16
  34. data/app/components/lookbook/embed/inspector/component.html.erb +102 -0
  35. data/app/components/lookbook/embed/inspector/component.js +46 -0
  36. data/app/components/lookbook/embed/inspector/component.rb +64 -0
  37. data/app/components/lookbook/embed_code_dropdown/component.css +12 -0
  38. data/app/components/lookbook/embed_code_dropdown/component.html.erb +19 -0
  39. data/app/components/lookbook/embed_code_dropdown/component.js +26 -0
  40. data/app/components/lookbook/embed_code_dropdown/component.rb +41 -0
  41. data/app/components/lookbook/header/component.html.erb +6 -5
  42. data/app/components/lookbook/header/component.rb +5 -1
  43. data/app/components/lookbook/icon/component.html.erb +1 -1
  44. data/app/components/lookbook/icon_button/component.html.erb +20 -0
  45. data/app/components/lookbook/icon_button/component.rb +46 -0
  46. data/app/components/lookbook/nav/component.html.erb +0 -1
  47. data/app/components/lookbook/nav/entity/component.rb +2 -2
  48. data/app/components/lookbook/nav/item/component.rb +1 -1
  49. data/app/components/lookbook/params/editor/component.rb +1 -0
  50. data/app/components/lookbook/prose/component.rb +1 -3
  51. data/app/components/lookbook/tabs/component.html.erb +2 -2
  52. data/app/components/lookbook/tabs/component.js +1 -1
  53. data/app/components/lookbook/tag_component.rb +2 -1
  54. data/app/components/lookbook/text_button/component.html.erb +26 -0
  55. data/app/components/lookbook/text_button/component.rb +42 -0
  56. data/app/components/lookbook/toolbar/component.html.erb +1 -1
  57. data/app/components/lookbook/viewport/component.rb +0 -4
  58. data/app/controllers/concerns/lookbook/targetable_concern.rb +24 -19
  59. data/app/controllers/concerns/lookbook/with_panels_concern.rb +30 -0
  60. data/app/controllers/concerns/lookbook/with_preview_controller_concern.rb +4 -3
  61. data/app/controllers/lookbook/application_controller.rb +9 -12
  62. data/app/controllers/lookbook/embeds_controller.rb +148 -0
  63. data/app/controllers/lookbook/inspector_controller.rb +3 -22
  64. data/app/controllers/lookbook/page_controller.rb +7 -6
  65. data/app/controllers/lookbook/pages_controller.rb +3 -4
  66. data/app/controllers/lookbook/preview_controller.rb +17 -0
  67. data/app/controllers/lookbook/previews_controller.rb +21 -20
  68. data/app/helpers/lookbook/application_helper.rb +3 -19
  69. data/app/views/layouts/lookbook/application.html.erb +85 -60
  70. data/app/views/layouts/lookbook/embed.html.erb +16 -0
  71. data/app/views/layouts/lookbook/shell.html.erb +1 -1
  72. data/app/views/layouts/lookbook/skeleton.html.erb +13 -8
  73. data/app/views/lookbook/embeds/show.html.erb +12 -0
  74. data/app/views/lookbook/inspector/panels/_notes.html.erb +1 -1
  75. data/app/views/lookbook/inspector/panels/_output.html.erb +3 -3
  76. data/app/views/lookbook/inspector/panels/_source.html.erb +6 -6
  77. data/app/views/lookbook/inspector/show.html.erb +130 -123
  78. data/app/views/lookbook/pages/show.html.erb +81 -34
  79. data/app/views/lookbook/partials/_iframe_content_scripts.html.erb +1 -0
  80. data/app/views/lookbook/partials/_user_styles.html.erb +5 -0
  81. data/app/views/lookbook/{preview.html.erb → previews/group.html.erb} +7 -7
  82. data/app/views/lookbook/previews/preview.html.erb +5 -0
  83. data/app/views/lookbook/previews/show.html.erb +1 -0
  84. data/config/app.yml +31 -16
  85. data/config/panels.yml +23 -25
  86. data/config/routes.rb +3 -1
  87. data/config/tags.yml +6 -2
  88. data/lib/lookbook/cable/cable.rb +53 -0
  89. data/{app/channels/lookbook → lib/lookbook/cable}/connection.rb +0 -0
  90. data/{app/channels/lookbook → lib/lookbook/cable}/reload_channel.rb +0 -0
  91. data/lib/lookbook/engine.rb +109 -87
  92. data/lib/lookbook/entities/collections/entity_collection.rb +11 -6
  93. data/lib/lookbook/entities/collections/page_collection.rb +33 -8
  94. data/lib/lookbook/entities/collections/preview_collection.rb +42 -17
  95. data/lib/lookbook/entities/collections/render_target_collection.rb +4 -0
  96. data/lib/lookbook/entities/collections/scenario_collection.rb +4 -0
  97. data/lib/lookbook/entities/concerns/{annotatable.rb → annotatable_entity.rb} +7 -6
  98. data/lib/lookbook/entities/concerns/{inspectable.rb → inspectable_entity.rb} +2 -1
  99. data/lib/lookbook/entities/concerns/{locatable.rb → locatable_entity.rb} +8 -14
  100. data/lib/lookbook/entities/concerns/navigable_entity.rb +44 -0
  101. data/lib/lookbook/entities/entity.rb +7 -2
  102. data/lib/lookbook/entities/{page.rb → page_entity.rb} +10 -6
  103. data/lib/lookbook/entities/{page_section.rb → page_section_entity.rb} +1 -1
  104. data/lib/lookbook/entities/preview_entity.rb +99 -0
  105. data/lib/lookbook/entities/renderable_entity.rb +50 -0
  106. data/lib/lookbook/entities/rendered_scenario_entity.rb +53 -0
  107. data/lib/lookbook/entities/scenario_entity.rb +116 -0
  108. data/lib/lookbook/entities/scenario_group_entity.rb +57 -0
  109. data/lib/lookbook/error.rb +5 -5
  110. data/lib/lookbook/file_watcher.rb +19 -35
  111. data/lib/lookbook/helpers/class_names_helper.rb +28 -0
  112. data/lib/lookbook/helpers/page_helper.rb +18 -0
  113. data/{app/helpers/lookbook → lib/lookbook/helpers}/preview_helper.rb +3 -0
  114. data/lib/lookbook/helpers/ui_elements_helper.rb +115 -0
  115. data/lib/lookbook/preview.rb +79 -0
  116. data/lib/lookbook/preview_controller_actions.rb +45 -0
  117. data/lib/lookbook/preview_parser.rb +4 -2
  118. data/lib/lookbook/reloaders.rb +71 -0
  119. data/lib/lookbook/runtime_context.rb +49 -0
  120. data/lib/lookbook/services/data/resolvers/data_resolver.rb +4 -6
  121. data/lib/lookbook/services/entities/entity_tree_builder.rb +6 -6
  122. data/lib/lookbook/services/list_resolver.rb +35 -0
  123. data/lib/lookbook/services/markdown_renderer.rb +12 -2
  124. data/lib/lookbook/services/priority_prefix_parser.rb +16 -0
  125. data/lib/lookbook/services/urls/search_param_encoder.rb +16 -0
  126. data/lib/lookbook/services/urls/search_param_parser.rb +7 -6
  127. data/lib/lookbook/stores/config_store.rb +16 -16
  128. data/lib/lookbook/stores/input_store.rb +1 -3
  129. data/lib/lookbook/stores/panel_store.rb +28 -50
  130. data/lib/lookbook/support/deprecation.rb +5 -0
  131. data/lib/lookbook/support/errors/preview_template_error.rb +7 -0
  132. data/lib/lookbook/support/evented_file_update_checker.rb +69 -0
  133. data/lib/lookbook/support/null_websocket.rb +9 -0
  134. data/lib/lookbook/support/store.rb +9 -0
  135. data/lib/lookbook/support/tree_node.rb +7 -7
  136. data/lib/lookbook/support/utils/path_utils.rb +7 -1
  137. data/lib/lookbook/support/utils/utils.rb +8 -0
  138. data/lib/lookbook/tags/{position_tag.rb → priority_tag.rb} +4 -4
  139. data/lib/lookbook/tags/renders_tag.rb +4 -0
  140. data/lib/lookbook/tags/tag_provider.rb +3 -0
  141. data/lib/lookbook/tags/type_tag.rb +7 -0
  142. data/lib/lookbook/tags/yard_tag.rb +1 -2
  143. data/lib/lookbook/version.rb +1 -1
  144. data/lib/lookbook/websocket.rb +6 -53
  145. data/lib/lookbook.rb +179 -53
  146. data/public/lookbook-assets/css/lookbook.css +137 -83
  147. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  148. data/public/lookbook-assets/css/themes/blue.css +7 -0
  149. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  150. data/public/lookbook-assets/css/themes/green.css +7 -0
  151. data/public/lookbook-assets/css/themes/green.css.map +1 -1
  152. data/public/lookbook-assets/css/themes/indigo.css +7 -0
  153. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  154. data/public/lookbook-assets/css/themes/rose.css +7 -0
  155. data/public/lookbook-assets/css/themes/rose.css.map +1 -1
  156. data/public/lookbook-assets/css/themes/zinc.css +7 -0
  157. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  158. data/public/lookbook-assets/img/lucide-sprite.svg +4960 -0
  159. data/public/lookbook-assets/js/embed.js +1363 -842
  160. data/public/lookbook-assets/js/embed.js.map +1 -1
  161. data/public/lookbook-assets/js/iframe.js +906 -0
  162. data/public/lookbook-assets/js/iframe.js.map +1 -0
  163. data/public/lookbook-assets/js/index.js +13567 -0
  164. data/public/lookbook-assets/js/index.js.map +1 -0
  165. data/public/lookbook-assets/js/lookbook-core.js +85 -0
  166. data/public/lookbook-assets/js/lookbook-core.js.map +1 -0
  167. data/public/lookbook-assets/js/lookbook.js +143 -12733
  168. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  169. data/public/lookbook-assets/lookbook-esm.js +1427 -0
  170. data/public/lookbook-assets/lookbook-esm.js.map +1 -0
  171. data/public/lookbook-assets/lookbook-global.js +1427 -0
  172. data/public/lookbook-assets/lookbook-global.js.map +1 -0
  173. data/public/lookbook-assets/lookbook.js +1427 -0
  174. data/public/lookbook-assets/lookbook.js.map +1 -0
  175. metadata +80 -72
  176. data/app/components/lookbook/embed/component.js +0 -39
  177. data/app/helpers/lookbook/component_helper.rb +0 -84
  178. data/app/helpers/lookbook/output_helper.rb +0 -19
  179. data/app/helpers/lookbook/page_helper.rb +0 -34
  180. data/app/views/layouts/lookbook/inspector.html.erb +0 -7
  181. data/app/views/layouts/lookbook/page.html.erb +0 -53
  182. data/app/views/layouts/lookbook/standalone.html.erb +0 -5
  183. data/lib/lookbook/entities/collections/component_collection.rb +0 -4
  184. data/lib/lookbook/entities/collections/preview_example_collection.rb +0 -4
  185. data/lib/lookbook/entities/component.rb +0 -31
  186. data/lib/lookbook/entities/concerns/navigable.rb +0 -43
  187. data/lib/lookbook/entities/preview.rb +0 -87
  188. data/lib/lookbook/entities/preview_example.rb +0 -104
  189. data/lib/lookbook/entities/preview_group.rb +0 -52
  190. data/lib/lookbook/preview_actions.rb +0 -43
  191. data/lib/lookbook/process.rb +0 -21
  192. data/lib/lookbook/rendered_example.rb +0 -37
  193. data/lib/lookbook/services/position_prefix_parser.rb +0 -16
  194. data/lib/lookbook/services/urls/search_param_builder.rb +0 -13
  195. data/lib/lookbook/tags/component_tag.rb +0 -13
@@ -1,43 +1,90 @@
1
- <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">
2
- <div class="w-full max-w-screen-lg mx-auto h-full flex flex-col">
3
- <% if @page.header? %>
4
- <header id="page-header" class="mb-8 prose max-w-none flex-none">
5
- <h1><%= @page.title %></h1>
6
- </header>
7
- <% end %>
1
+ <main
2
+ class="h-[calc(100vh_-_40px)]"
3
+ x-data="{}"
4
+ @navigation:complete.window="$refs.scroller.scrollTop = 0;"
5
+ @dom:update-complete.window="Lookbook.initEmbeds();">
6
+ <div class="h-full bg-lookbook-page-bg relative">
7
+ <% unless @error %>
8
+
9
+ <div class="absolute top-0 right-0 pt-1 pr-0 pl-1 pb-1 rounded-bl-md">
10
+ <div class="bg-lookbook-page-bg opacity-90 absolute inset-0 w-full h-full z-0"></div>
11
+ <div class="relative z-10 flex items-center">
12
+
13
+ <% if @previous_page %>
14
+ <%= lookbook_render :icon_button,
15
+ size: :lg,
16
+ icon: :chevron_left,
17
+ tooltip: "Previous page",
18
+ href: lookbook_page_path(@previous_page.lookup_path),
19
+ class: "pr-0.5 bg-transparent" %>
20
+ <% else %>
21
+ <%= lookbook_render :icon_button,
22
+ size: :lg,
23
+ icon: :chevron_left,
24
+ disabled: true,
25
+ class: "opacity-50 !cursor-default pr-0.5 bg-transparent" %>
26
+ <% end %>
8
27
 
9
- <%= lookbook_render :prose, id: "page-content", markdown: false, class: "max-w-none flex-none" do %>
10
- <%= @page_content %>
28
+ <% if @next_page %>
29
+ <%= lookbook_render :icon_button,
30
+ size: :lg,
31
+ icon: :chevron_right,
32
+ tooltip: "Next page",
33
+ href: lookbook_page_path(@next_page.lookup_path),
34
+ class: "pl-0.5 bg-transparent" %>
35
+ <% else %>
36
+ <%= lookbook_render :icon_button,
37
+ size: :lg,
38
+ icon: :chevron_right,
39
+ disabled: true,
40
+ class: "opacity-50 !cursor-default pl-0.5 bg-transparent" %>
41
+ <% end %>
42
+ </div>
43
+ </div>
11
44
  <% end %>
12
45
 
13
- <% if @page.sections.any? %>
14
- <%= lookbook_render :page_tabs, id: "page-tabbed-sections", markdown: false, class: "mt-6" do |page_tabs| %>
15
- <% @page.sections.each do |section| %>
16
- <% page_tabs.with_tab name: "page-section-#{section.name}", label: section.label do %>
17
- <%= page_controller.render_page(section) %>
18
- <% end %>
46
+ <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
+ <div class="w-full max-w-screen-lg mx-auto h-full flex flex-col">
48
+ <% if @page.header? %>
49
+ <header id="page-header" class="mb-8 prose max-w-none flex-none">
50
+ <h1><%= @page.title %></h1>
51
+ </header>
19
52
  <% end %>
20
- <% end %>
21
- <% end %>
22
53
 
23
- <% if @page.footer? && @pages.many? %>
24
- <footer id="page-footer" class="flex items-center justify-between border-t border-gray-300 mt-12 pt-8 pb-10 ">
25
- <% if @previous_page %>
26
- <a href="<%= lookbook_page_path @previous_page.lookup_path %>"
27
- class="flex items-center flex-none">
28
- <%= icon :arrow_left, size: 4, class: "hover:text-indigo-800" %>
29
- <span class="ml-2 underline"><%= @previous_page.title %></span>
30
- </a>
54
+ <%= lookbook_render :prose, id: "page-content", markdown: false, class: "max-w-none flex-none" do %>
55
+ <%= @page_content %>
31
56
  <% end %>
32
57
 
33
- <% if @next_page %>
34
- <a href="<%= lookbook_page_path @next_page.lookup_path %>"
35
- class="flex items-center flex-none ml-auto">
36
- <span class="mr-2 underline"><%= @next_page.title %></span>
37
- <%= icon :arrow_right, size: 4, class: "hover:text-indigo-800" %>
38
- </a>
58
+ <% if @page.sections.any? %>
59
+ <%= lookbook_render :page_tabs, id: "page-tabbed-sections", markdown: false, class: "mt-6" do |page_tabs| %>
60
+ <% @page.sections.each do |section| %>
61
+ <% page_tabs.tab name: "page-section-#{section.name}", label: section.label do %>
62
+ <%= page_controller.render_page(section) %>
63
+ <% end %>
64
+ <% end %>
65
+ <% end %>
39
66
  <% end %>
40
- </footer>
41
- <% end %>
67
+
68
+ <% if @page.footer? && @pages.many? %>
69
+ <footer id="page-footer" class="flex items-center justify-between border-t border-gray-300 mt-12 pt-8 pb-10 ">
70
+ <% if @previous_page %>
71
+ <a href="<%= lookbook_page_path @previous_page.lookup_path %>"
72
+ class="flex items-center flex-none">
73
+ <%= icon :arrow_left, size: 4, class: "hover:text-indigo-800" %>
74
+ <span class="ml-2 underline"><%= @previous_page.title %></span>
75
+ </a>
76
+ <% end %>
77
+
78
+ <% if @next_page %>
79
+ <a href="<%= lookbook_page_path @next_page.lookup_path %>"
80
+ class="flex items-center flex-none ml-auto">
81
+ <span class="mr-2 underline"><%= @next_page.title %></span>
82
+ <%= icon :arrow_right, size: 4, class: "hover:text-indigo-800" %>
83
+ </a>
84
+ <% end %>
85
+ </footer>
86
+ <% end %>
87
+ </div>
88
+ </div>
42
89
  </div>
43
- </div>
90
+ </main>
@@ -0,0 +1 @@
1
+ <script src="<%= lookbook_asset_path("/js/iframe.js") %>" defer></script>
@@ -0,0 +1,5 @@
1
+ <% if content_for? :user_styles %>
2
+ <style media="all" id="user-styles">
3
+ <%= content_for :user_styles -%>
4
+ </style>
5
+ <% end %>
@@ -1,14 +1,14 @@
1
- <% if examples.many? %>
2
- <%# Render a group of examples %>
3
- <% examples.each do |example| %>
1
+ <% if scenarios.many? %>
2
+ <%# Render a group of scenarios %>
3
+ <% scenarios.each do |scenario| %>
4
4
  <div style="margin-bottom: 30px !important; display: block !important;">
5
5
  <h6 style="all: unset; display: block; color: #555; font-family: sans-serif; font-size: 14px; margin-top: 0; margin-bottom: 10px;">
6
- <%= example.label %>
6
+ <%= scenario.label %>
7
7
  </h6>
8
- <%= example.output %>
8
+ <%= scenario.output %>
9
9
  </div>
10
10
  <% end %>
11
11
  <% else %>
12
- <%# Render a single example %>
13
- <%= examples.first.output %>
12
+ <%# Render a single scenario %>
13
+ <%= scenarios.first.output %>
14
14
  <% end %>
@@ -0,0 +1,5 @@
1
+ <% if @render_args[:component] %>
2
+ <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
3
+ <% else %>
4
+ <%= render(@render_args[:template], **@render_args[:locals], &@render_args[:block]) %>
5
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= @preview_html %>
data/config/app.yml CHANGED
@@ -1,14 +1,30 @@
1
1
  shared:
2
2
  project_name: Lookbook
3
- log_level: 2
4
- log_use_rails_logger: true
5
- auto_refresh: false
6
- components_path: app/components
7
- page_controller: Lookbook::PageController
3
+
4
+ preview_paths: [test/components/previews]
5
+ preview_display_options: {}
6
+ preview_controller: "Lookbook::PreviewController"
7
+ preview_template: lookbook/previews/preview
8
+ preview_inspector:
9
+ main_panels: [preview, output]
10
+ drawer_panels: [source, notes, params, "*"]
11
+ preview_embeds:
12
+ policy: "SAMEORIGIN"
13
+ panels: false
14
+ actions: []
15
+ scenarios: []
16
+ display_option_controls: true
17
+ preview_layout: ~
18
+ preview_disable_action_view_annotations: true
19
+ preview_type_default: view_component
20
+ preview_sort_scenarios: false
21
+
22
+ page_controller: "Lookbook::PageController"
8
23
  page_route: pages
9
24
  page_paths: [test/components/docs]
10
25
  page_extensions: [html.*, md.*]
11
26
  page_options: {}
27
+
12
28
  markdown_options:
13
29
  tables: true
14
30
  fenced_code_blocks: true
@@ -17,30 +33,29 @@ shared:
17
33
  highlight: true
18
34
  with_toc_data: true
19
35
  lax_spacing: true
36
+
20
37
  highlighter_options:
21
38
  theme: github
22
39
  dark: false
23
- sort_examples: false
24
- preview_paths: []
25
- preview_display_options: {}
26
- preview_disable_action_view_annotations: true
27
- preview_params_options_eval: false
28
- listen: false
40
+
41
+ component_paths: [app/views]
42
+
43
+ reload_on_change: ~
29
44
  listen_paths: []
30
45
  listen_extensions: [rb, html.*]
31
- listen_use_polling: false
46
+
32
47
  ui_theme: indigo
33
48
  ui_theme_overrides: {}
34
49
  ui_favicon: true
50
+
51
+ log_level: 2
52
+ log_use_rails_logger: true
53
+
35
54
  debug_menu: false
36
55
  experimental_features: false
37
56
 
38
57
  development:
39
- listen: true
40
- auto_refresh: true
41
58
  debug_menu: true
42
59
 
43
60
  test:
44
- listen: false
45
- auto_refresh: false
46
61
  debug_menu: true
data/config/panels.yml CHANGED
@@ -1,30 +1,28 @@
1
1
  shared:
2
- main:
3
- - name: preview
4
- partial: lookbook/inspector/panels/preview
5
- label: Preview
6
- hotkey: v
2
+ preview:
3
+ partial: lookbook/inspector/panels/preview
4
+ label: Preview
5
+ hotkey: v
7
6
 
8
- - name: output
9
- partial: lookbook/inspector/panels/output
10
- label: HTML
11
- hotkey: h
7
+ output:
8
+ partial: lookbook/inspector/panels/output
9
+ label: HTML
10
+ hotkey: h
12
11
 
13
- drawer:
14
- - name: source
15
- partial: lookbook/inspector/panels/source
16
- label: Source
17
- hotkey: s
18
- copy: "->(data) { data.examples.map { |e| e.source }.join(\n) }"
12
+ source:
13
+ partial: lookbook/inspector/panels/source
14
+ label: Source
15
+ hotkey: s
16
+ copy: "->(data) { data.scenarios.map { |e| e.source }.join(\n) }"
19
17
 
20
- - name: notes
21
- partial: lookbook/inspector/panels/notes
22
- label: Notes
23
- hotkey: n
24
- disabled: ->(data) { data.examples.select { |e| e.notes.present? }.none? }
18
+ notes:
19
+ partial: lookbook/inspector/panels/notes
20
+ label: Notes
21
+ hotkey: n
22
+ disabled: "->(data) { data.scenarios.select { |e| e.notes.present? }.none? }"
25
23
 
26
- - name: params
27
- partial: lookbook/inspector/panels/params
28
- label: Params
29
- hotkey: p
30
- disabled: ->(data) { data.context.params.none? }
24
+ params:
25
+ partial: lookbook/inspector/panels/params
26
+ label: Params
27
+ hotkey: p
28
+ disabled: "->(data) { data.context.params.none? }"
data/config/routes.rb CHANGED
@@ -10,7 +10,9 @@ Lookbook::Engine.routes.draw do
10
10
 
11
11
  get "/previews", to: "previews#index", as: :lookbook_previews
12
12
  get "/preview/*path", to: "previews#show", as: :lookbook_preview
13
+
13
14
  get "/inspect/*path", to: "inspector#show", as: :lookbook_inspect
14
15
 
15
- get "/*path", to: "inspector#show_legacy", as: :lookbook_inspect_legacy
16
+ get "/embed", to: "embeds#lookup", as: :lookbook_embed_lookup
17
+ get "/embed/*path", to: "embeds#show", as: :lookbook_embed
16
18
  end
data/config/tags.yml CHANGED
@@ -11,8 +11,8 @@ shared:
11
11
  label: Display
12
12
  opts: {}
13
13
 
14
- position:
15
- label: Position
14
+ priority:
15
+ label: Priority
16
16
  opts: {}
17
17
 
18
18
  id:
@@ -23,6 +23,10 @@ shared:
23
23
  label: Component
24
24
  opts: {}
25
25
 
26
+ renders:
27
+ label: Renders
28
+ opts: {}
29
+
26
30
  param:
27
31
  label: Param
28
32
  opts: {}
@@ -0,0 +1,53 @@
1
+ require "action_cable/engine"
2
+ require_relative "./connection"
3
+ require_relative "./reload_channel"
4
+
5
+ module Lookbook
6
+ class Cable
7
+ attr_reader :engine_mount_path, :server, :logger
8
+
9
+ def initialize(engine_mount_path, logger: Lookbook.logger)
10
+ @engine_mount_path = engine_mount_path
11
+ @logger = logger
12
+
13
+ logger.info "Initializing websocket"
14
+
15
+ if Gem::Version.new(Rails.version) >= Gem::Version.new(6.0)
16
+ @server = ActionCable::Server::Base.new config: cable_config
17
+ else
18
+ @server = ActionCable::Server::Base.new
19
+ @server.config = cable_config
20
+ end
21
+ end
22
+
23
+ def broadcast(message, payload = nil)
24
+ logger.debug message.to_s
25
+ server.broadcast(message.to_s, payload.to_h)
26
+ end
27
+
28
+ def mount_path
29
+ "/cable"
30
+ end
31
+
32
+ def full_mount_path
33
+ "#{engine_mount_path}/#{mount_path}".gsub("//", "/")
34
+ end
35
+
36
+ def mountable?
37
+ true
38
+ end
39
+
40
+ alias_method :mounted?, :mountable?
41
+
42
+ protected
43
+
44
+ def cable_config
45
+ cable = ActionCable::Server::Configuration.new
46
+ cable.cable = {adapter: "async"}.with_indifferent_access
47
+ cable.mount_path = nil
48
+ cable.connection_class = -> { Lookbook::Connection }
49
+ cable.logger = logger
50
+ cable
51
+ end
52
+ end
53
+ end
@@ -1,6 +1,3 @@
1
- require "view_component"
2
- require "action_cable/engine"
3
- require "listen"
4
1
  require "yard"
5
2
 
6
3
  module Lookbook
@@ -9,103 +6,66 @@ module Lookbook
9
6
 
10
7
  config.autoload_paths << File.expand_path(root.join("app/components"))
11
8
 
12
- config.before_configuration do
13
- config.lookbook = Lookbook.config
14
- end
15
-
16
- initializer "lookbook.viewcomponent.config_sync" do
17
- opts.preview_paths += config.view_component.preview_paths
18
- opts.preview_controller ||= config.view_component.preview_controller
19
-
20
- if config.view_component.view_component_path.present?
21
- opts.components_path = config.view_component.view_component_path
22
- end
23
- end
24
-
25
9
  initializer "lookbook.assets.serve" do
26
10
  config.app_middleware.use(
27
11
  Rack::Static,
28
- urls: ["/lookbook-assets"], root: root.join("public").to_s
12
+ urls: ["/lookbook-assets"],
13
+ root: root.join("public").to_s
29
14
  )
30
15
  end
31
16
 
32
- initializer "lookbook.file_watcher.paths" do
33
- opts.listen_paths += opts.preview_paths
34
- opts.listen_paths << opts.components_path
35
- end
17
+ config.before_configuration do
18
+ config.lookbook = Lookbook.config
36
19
 
37
- initializer "lookbook.file_watcher.previews" do
38
- file_watcher.watch(opts.listen_paths, opts.listen_extensions, wait_for_delay: 0.5) do |changes|
39
- parser.parse { run_hooks(:after_change, changes) }
20
+ if defined?(ViewComponent)
21
+ config.lookbook.using_view_component = true
22
+ else
23
+ require "view_component"
24
+ config.lookbook.using_view_component = false
40
25
  end
41
26
  end
42
27
 
43
- initializer "lookbook.file_watcher.pages" do
44
- file_watcher.watch(opts.page_paths, opts.page_extensions) do |changes|
45
- Engine.pages.load(Engine.page_paths)
46
- Engine.websocket.broadcast(:reload)
47
- run_hooks(:after_change, changes)
48
- end
49
- end
28
+ config.after_initialize do
29
+ if opts.using_view_component || Rails.env.test?
30
+ vc_config = Engine.host_config.view_component
50
31
 
51
- initializer "lookbook.parser.previews_load_callback" do
52
- parser.after_parse do |code_objects|
53
- Engine.previews.load(code_objects.all(:class))
54
- Engine.websocket.broadcast(:reload)
55
- end
56
- end
32
+ opts.preview_paths += vc_config.preview_paths
33
+ opts.preview_controller = vc_config.preview_controller
34
+ opts.preview_layout = vc_config.default_preview_layout
57
35
 
58
- # The preview controller handles the rendering of individual previews.
59
- #
60
- # Lookbook injects some actions into whichever controller has been
61
- # specified by the user in order to render previews within the context of
62
- # the particular controller class instance so that any before_action/after_action
63
- # callbacks will be correctly processed.
64
- config.after_initialize do
65
- @preview_controller = opts.preview_controller.constantize
66
- @preview_controller.class_eval { include Lookbook::PreviewActions }
67
- end
36
+ vc_config.show_previews = true
68
37
 
69
- config.after_initialize do
70
- if Rails.application.respond_to?(:server)
71
- Rails.application.server { file_watcher.start if listen? }
72
- elsif process.supports_listening?
73
- file_watcher.start if listen?
38
+ if vc_config.view_component_path.present?
39
+ opts.component_paths << vc_config.view_component_path
40
+ end
74
41
  end
42
+
43
+ opts.reload_on_change = host_config.reload_classes_only_on_change if opts.reload_on_change.nil?
75
44
  end
76
45
 
77
46
  config.after_initialize do
78
- Engine.pages.load(Engine.page_paths)
79
- parser.parse { run_hooks(:after_initialize) }
47
+ reloaders.add(:previews, Engine.preview_watch_paths, opts.listen_extensions, &Engine.method(:load_previews))
48
+ reloaders.add(:pages, Engine.page_watch_paths, opts.page_extensions, &Engine.method(:load_pages))
49
+ reloaders.execute
50
+
51
+ Engine.run_hooks(:after_initialize)
80
52
  end
81
53
 
82
54
  def opts
83
55
  Lookbook.config
84
56
  end
85
57
 
86
- def run_hooks(event_name, *args)
87
- Engine.hooks.for_event(event_name).each do |hook|
88
- hook.call(Lookbook, *args)
89
- end
90
- end
91
-
92
58
  def parser
93
59
  @_parser ||= PreviewParser.new(opts.preview_paths, Engine.tags)
94
60
  end
95
61
 
96
- def file_watcher
97
- @_file_watcher ||= FileWatcher.new(force_polling: opts.listen_use_polling)
98
- end
99
-
100
- def process
101
- @_process ||= Process.new(env: Rails.env)
102
- end
103
-
104
- def listen?
105
- opts.listen && process.supports_listening?
62
+ def reloaders
63
+ @_reloaders ||= Reloaders.new
106
64
  end
107
65
 
108
66
  class << self
67
+ delegate :app_name, to: :runtime_context
68
+
109
69
  def mount_path
110
70
  routes.find_script_name({})
111
71
  end
@@ -114,22 +74,24 @@ module Lookbook
114
74
  mount_path.present?
115
75
  end
116
76
 
117
- def app_name
118
- name = if Rails.application.class.respond_to?(:module_parent_name)
119
- Rails.application.class.module_parent_name
120
- else
121
- Rails.application.class.parent_name
122
- end
123
- name.underscore
77
+ def reloading?
78
+ opts.reload_on_change
79
+ end
80
+
81
+ def auto_refresh?
82
+ reloading? && runtime_context.web? && FileWatcher.evented?
124
83
  end
125
84
 
126
85
  def websocket
127
- if mounted?
128
- use_websocket = opts.auto_refresh && opts.listen && process.supports_listening?
129
- @websocket ||= use_websocket ? Websocket.new(mount_path, logger: Lookbook.logger) : Websocket.noop
130
- else
131
- Websocket.noop
132
- end
86
+ @_websocket ||= auto_refresh? ? Websocket.new(mount_path, logger: Lookbook.logger) : NullWebsocket.new
87
+ end
88
+
89
+ def runtime_context
90
+ @_runtime_context ||= RuntimeContext.new(env: Rails.env)
91
+ end
92
+
93
+ def theme
94
+ @_theme ||= Lookbook::Theme.new(opts.ui_theme, opts.ui_theme_overrides)
133
95
  end
134
96
 
135
97
  def panels
@@ -148,18 +110,50 @@ module Lookbook
148
110
  @_hooks ||= HookStore.init_from_config
149
111
  end
150
112
 
113
+ def run_hooks(event_name, *args)
114
+ hooks.for_event(event_name).each do |hook|
115
+ hook.call(Lookbook, *args)
116
+ end
117
+ end
118
+
119
+ def host_app_path
120
+ Rails.application.root.join("app")
121
+ end
122
+
123
+ def host_config
124
+ Rails.application.config
125
+ end
126
+
127
+ def view_paths
128
+ ActionView::ViewPaths.all_view_paths.flat_map do |view_path|
129
+ view_path.paths.map { |path| Pathname(path.to_s) }
130
+ end
131
+ end
132
+
151
133
  def component_paths
152
- @_component_paths ||= Array(PathUtils.to_absolute(opts.components_path))
134
+ @_component_paths ||= begin
135
+ paths = [*opts.component_paths, *Engine.view_paths, host_app_path]
136
+ PathUtils.normalize_paths(paths)
137
+ end
153
138
  end
154
139
 
155
140
  def page_paths
156
141
  @_page_paths ||= PathUtils.normalize_paths(opts.page_paths)
157
142
  end
158
143
 
144
+ alias_method :page_watch_paths, :page_paths
145
+
159
146
  def preview_paths
160
147
  @_preview_paths ||= PathUtils.normalize_paths(opts.preview_paths)
161
148
  end
162
149
 
150
+ def preview_watch_paths
151
+ return @_preview_watch_paths if @_preview_watch_paths
152
+
153
+ paths = [*opts.preview_paths, opts.components_path, *opts.listen_paths, *view_paths].uniq
154
+ @_preview_watch_paths ||= PathUtils.normalize_paths(paths)
155
+ end
156
+
163
157
  def pages
164
158
  @_pages ||= PageCollection.new
165
159
  end
@@ -168,12 +162,40 @@ module Lookbook
168
162
  @_previews ||= PreviewCollection.new
169
163
  end
170
164
 
171
- attr_reader :preview_controller
165
+ def preview_controller
166
+ return @_preview_controller if @_preview_controller
167
+
168
+ @_preview_controller = opts.preview_controller.constantize
169
+ @_preview_controller.include PreviewControllerActions
170
+ end
171
+
172
+ def load_previews(changes = nil)
173
+ changed_files = [*changes[:added], *changes[:modified]] if changes
174
+ parser.parse(changed_files) do |code_objects|
175
+ previews.load(code_objects.all(:class), changes)
176
+ end
177
+ end
178
+
179
+ def load_pages(changes = nil)
180
+ pages.load(Engine.page_paths, changes)
181
+ end
182
+
183
+ def notify_clients(changes = nil)
184
+ return unless changes.present?
185
+
186
+ websocket.broadcast(:reload)
187
+ run_hooks(:after_change, changes.to_h)
188
+ end
189
+
190
+ def files_changed(modified, added, removed)
191
+ changes = {modified: modified, added: added, removed: removed}
192
+ reloaders.register_changes(changes)
193
+ notify_clients(changes)
194
+ end
172
195
  end
173
196
 
174
197
  at_exit do
175
- file_watcher.stop
176
- run_hooks(:before_exit)
198
+ Engine.run_hooks(:before_exit)
177
199
  end
178
200
  end
179
201
  end