lookbook 1.0.0.beta.0 → 1.0.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +231 -9
  3. data/app/assets/lookbook/js/stores/inspector.js +4 -4
  4. data/app/components/lookbook/{component.rb → base_component.rb} +1 -1
  5. data/app/components/lookbook/button/component.rb +1 -1
  6. data/app/components/lookbook/button_group/component.rb +1 -1
  7. data/app/components/lookbook/code/component.rb +1 -1
  8. data/app/components/lookbook/copy_button/component.html.erb +1 -1
  9. data/app/components/lookbook/copy_button/component.rb +1 -1
  10. data/app/components/lookbook/dimensions_display/component.html.erb +2 -1
  11. data/app/components/lookbook/dimensions_display/component.js +19 -12
  12. data/app/components/lookbook/dimensions_display/component.rb +1 -1
  13. data/app/components/lookbook/embed/component.html.erb +6 -5
  14. data/app/components/lookbook/embed/component.rb +1 -1
  15. data/app/components/lookbook/filter/component.html.erb +1 -1
  16. data/app/components/lookbook/filter/component.rb +1 -1
  17. data/app/components/lookbook/header/component.html.erb +7 -12
  18. data/app/components/lookbook/header/component.rb +1 -1
  19. data/app/components/lookbook/icon/component.rb +1 -1
  20. data/app/components/lookbook/nav/component.rb +1 -1
  21. data/app/components/lookbook/nav/item/component.html.erb +2 -2
  22. data/app/components/lookbook/nav/item/component.rb +1 -1
  23. data/app/components/lookbook/page_tabs/component.html.erb +18 -0
  24. data/app/components/lookbook/page_tabs/component.rb +19 -0
  25. data/app/components/lookbook/params_editor/component.rb +1 -1
  26. data/app/components/lookbook/params_editor/field/component.rb +1 -1
  27. data/app/components/lookbook/prose/component.rb +1 -1
  28. data/app/components/lookbook/split_layout/component.rb +1 -1
  29. data/app/components/lookbook/tab_panels/component.html.erb +5 -0
  30. data/app/components/lookbook/tab_panels/component.js +25 -0
  31. data/app/components/lookbook/tab_panels/component.rb +20 -0
  32. data/app/components/lookbook/{tabbed_content/section → tab_panels/panel}/component.html.erb +2 -2
  33. data/app/components/lookbook/tab_panels/panel/component.rb +9 -0
  34. data/app/components/lookbook/tabs/component.html.erb +8 -2
  35. data/app/components/lookbook/tabs/component.js +14 -6
  36. data/app/components/lookbook/tabs/component.rb +9 -11
  37. data/app/components/lookbook/tabs/dropdown_tab/component.html.erb +8 -2
  38. data/app/components/lookbook/tabs/dropdown_tab/component.rb +5 -4
  39. data/app/components/lookbook/tabs/tab/component.html.erb +9 -3
  40. data/app/components/lookbook/tabs/tab/component.rb +5 -4
  41. data/app/components/lookbook/toolbar/component.css +1 -1
  42. data/app/components/lookbook/toolbar/component.rb +1 -1
  43. data/app/components/lookbook/viewport/component.rb +1 -1
  44. data/app/controllers/lookbook/application_controller.rb +2 -2
  45. data/app/controllers/lookbook/pages_controller.rb +2 -1
  46. data/app/controllers/lookbook/previews_controller.rb +90 -91
  47. data/app/helpers/lookbook/application_helper.rb +8 -2
  48. data/app/helpers/lookbook/component_helper.rb +4 -0
  49. data/app/helpers/lookbook/page_helper.rb +2 -2
  50. data/app/views/layouts/lookbook/application.html.erb +1 -1
  51. data/app/views/layouts/lookbook/page.html.erb +2 -2
  52. data/app/views/layouts/lookbook/shell.html.erb +1 -1
  53. data/app/views/layouts/lookbook/skeleton.html.erb +7 -1
  54. data/app/views/lookbook/404.html.erb +1 -1
  55. data/app/views/lookbook/index.html.erb +1 -1
  56. data/app/views/lookbook/pages/show.html.erb +15 -5
  57. data/app/views/lookbook/preview.html.erb +3 -3
  58. data/app/views/lookbook/previews/panels/_content.html.erb +13 -0
  59. data/app/views/lookbook/previews/panels/_notes.html.erb +5 -5
  60. data/app/views/lookbook/previews/panels/_output.html.erb +3 -3
  61. data/app/views/lookbook/previews/panels/_params.html.erb +2 -2
  62. data/app/views/lookbook/previews/panels/_preview.html.erb +2 -2
  63. data/app/views/lookbook/previews/panels/_source.html.erb +6 -6
  64. data/app/views/lookbook/previews/show.html.erb +39 -36
  65. data/config/routes.rb +6 -6
  66. data/lib/lookbook/collection.rb +1 -1
  67. data/lib/lookbook/component.rb +31 -0
  68. data/lib/lookbook/config.rb +133 -33
  69. data/lib/lookbook/engine.rb +72 -12
  70. data/lib/lookbook/page.rb +34 -11
  71. data/lib/lookbook/page_section.rb +31 -0
  72. data/lib/lookbook/parser.rb +1 -4
  73. data/lib/lookbook/preview.rb +25 -8
  74. data/lib/lookbook/preview_example.rb +2 -2
  75. data/lib/lookbook/preview_group.rb +1 -1
  76. data/lib/lookbook/source_inspector.rb +10 -0
  77. data/lib/lookbook/store.rb +36 -0
  78. data/lib/lookbook/theme.rb +7 -0
  79. data/lib/lookbook/utils.rb +3 -3
  80. data/lib/lookbook/version.rb +1 -1
  81. data/lib/lookbook.rb +3 -12
  82. data/public/lookbook-assets/css/lookbook.css +34 -5
  83. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  84. data/public/lookbook-assets/js/lookbook.js +84 -71
  85. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  86. metadata +14 -8
  87. data/app/components/lookbook/tabbed_content/component.html.erb +0 -5
  88. data/app/components/lookbook/tabbed_content/component.js +0 -21
  89. data/app/components/lookbook/tabbed_content/component.rb +0 -20
  90. data/app/components/lookbook/tabbed_content/section/component.rb +0 -9
@@ -8,11 +8,17 @@
8
8
  <link href="/lookbook-assets/css/lookbook.css?v=<%= Lookbook::VERSION %>" rel="stylesheet">
9
9
  <link href="/lookbook-assets/css/themes/<%= config.ui_theme %>.css?v=<%= Lookbook::VERSION %>" rel="stylesheet">
10
10
  <% if @theme_overrides.present? %>
11
- <style>
11
+ <style media="all">
12
12
  <%== @theme_overrides %>
13
13
  </style>
14
14
  <% end %>
15
15
 
16
+ <% if content_for? :styles %>
17
+ <style media="all">
18
+ <%= content_for :styles %>
19
+ </style>
20
+ <% end %>
21
+
16
22
  <% if config.ui_favicon != false %>
17
23
  <link rel="icon" href="<%= config.ui_favicon || "data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👀</text></svg>" %>">
18
24
  <% end %>
@@ -1,6 +1,6 @@
1
1
  <div class="bg-white flex flex-col items-center justify-center h-screen w-full">
2
2
  <div class="px-4 text-center max-w-sm">
3
- <%= render_component :icon, name: :alert_triangle, size: 10, class: "text-red-300 mx-auto" %>
3
+ <%= icon :alert_triangle, size: 10, class: "text-red-300 mx-auto" %>
4
4
  <div class="mt-3">
5
5
  <h5 class="text-base">
6
6
  <%== message %>
@@ -1,7 +1,7 @@
1
1
  <div id="welcome-message" class="flex flex-col h-full w-full">
2
2
  <div class="flex flex-col items-center justify-center h-full">
3
3
  <div class="p-4 text-center mx-auto">
4
- <%= render_component :icon, name: :layers, size: 10, class: "opacity-30 mx-auto" %>
4
+ <%= icon :layers, size: 10, class: "opacity-30 mx-auto" %>
5
5
  <div class="mt-6 text-base opacity-40">
6
6
  <% if Lookbook.previews.any? %>
7
7
  <h5>Select a preview to get started</h5>
@@ -9,22 +9,32 @@
9
9
  <%= render_component :prose, markdown: false, class: "max-w-none flex-none" do %>
10
10
  <%= @page_content %>
11
11
  <% end %>
12
-
12
+
13
+ <% if @page.sections.any? %>
14
+ <%= render_component :page_tabs, markdown: false, class: "mt-6" do |page_tabs| %>
15
+ <% @page.sections.each do |section| %>
16
+ <% page_tabs.tab name: "page-section-#{section.name}", label: section.label do %>
17
+ <%= page_controller.render_page(section) %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ <% end %>
22
+
13
23
  <% if @page.footer? && @pages.many? %>
14
24
  <footer class="flex items-center justify-between border-t border-gray-300 mt-12 pt-8 pb-10 ">
15
25
  <% if @previous_page %>
16
- <a href="<%= page_path @previous_page.lookup_path %>"
26
+ <a href="<%= lookbook_page_path @previous_page.lookup_path %>"
17
27
  class="flex items-center flex-none">
18
- <%= render_component :icon, name: :arrow_left, size: 4, class: "hover:text-indigo-800" %>
28
+ <%= icon :arrow_left, size: 4, class: "hover:text-indigo-800" %>
19
29
  <span class="ml-2 underline"><%= @previous_page.title %></span>
20
30
  </a>
21
31
  <% end %>
22
32
 
23
33
  <% if @next_page %>
24
- <a href="<%= page_path @next_page.lookup_path %>"
34
+ <a href="<%= lookbook_page_path @next_page.lookup_path %>"
25
35
  class="flex items-center flex-none ml-auto">
26
36
  <span class="mr-2 underline"><%= @next_page.title %></span>
27
- <%= render_component :icon, name: :arrow_right, size: 4, class: "hover:text-indigo-800" %>
37
+ <%= icon :arrow_right, size: 4, class: "hover:text-indigo-800" %>
28
38
  </a>
29
39
  <% end %>
30
40
  </footer>
@@ -3,12 +3,12 @@
3
3
  <% examples.each do |example| %>
4
4
  <div style="all: unset; margin-bottom: 30px; display: block;">
5
5
  <h6 style="all: unset; display: block; color: #999; font-family: sans-serif; font-size: 14px; margin-top: 0; margin-bottom: 10px;">
6
- <%= example[:label] %>
6
+ <%= example.label %>
7
7
  </h6>
8
- <%= example[:html] %>
8
+ <%= example.output %>
9
9
  </div>
10
10
  <% end %>
11
11
  <% else %>
12
12
  <%# Render a single example %>
13
- <%= examples.first[:html] %>
13
+ <%= examples.first.output %>
14
14
  <% end %>
@@ -0,0 +1,13 @@
1
+ <div class="p-4 bg-lookbook-prose h-full">
2
+ <% if panel.content.present? %>
3
+ <%= render_component :prose, markdown: true do %>
4
+ <%== panel.content %>
5
+ <% end %>
6
+ <% else %>
7
+ <% if Rails.env.development? %>
8
+ <%= render_component :prose do %>
9
+ <em class='opacity-50'>No content has been defined for this panel.</em>
10
+ <% end %>
11
+ <% end %>
12
+ <% end %>
13
+ </div>
@@ -1,19 +1,19 @@
1
- <% items = rendered_examples.filter { |example| example[:notes].present? } %>
1
+ <% items = examples.select { |example| example.notes.present? } %>
2
2
  <% if items.many? %>
3
3
  <div class="divide-y divide-dashed divide-lookbook-divider bg-lookbook-prose h-full w-full">
4
4
  <% items.each do |item| %>
5
5
  <div class="px-4 py-6 relative">
6
6
  <h6 class="italic font-mono mb-4 opacity-40">
7
- # <%= item[:label] %>
7
+ # <%= item.label %>
8
8
  </h6>
9
- <%= render_component :prose, content: item[:notes] %>
9
+ <%= render_component :prose, content: item.notes %>
10
10
  </div>
11
11
  <% end %>
12
12
  </div>
13
13
  <% else %>
14
- <div class="p-4 py-4 bg-lookbook-prose w-full h-full">
14
+ <div class="p-4 bg-lookbook-prose w-full h-full">
15
15
  <%= render_component :prose do %>
16
- <%== items.any? ? items.first[:notes] : "<em class='opacity-50'>No notes provided.</em>" %>
16
+ <%== items.any? ? items.first.notes : "<em class='opacity-50'>No notes provided.</em>" %>
17
17
  <% end %>
18
18
  </div>
19
19
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= render_component :code, line_numbers: true, full_height: true do -%>
2
- <% if rendered_examples.many? -%>
3
- <% rendered_examples.each do |example| -%><%== "<!-- #{example[:label]} -->\n#{beautify(example[:html])}\n\n" -%><% end %>
2
+ <% if examples.many? -%>
3
+ <% examples.each do |example| -%><%== "<!-- #{example.label} -->\n#{beautify(example.output)}\n\n" -%><% end %>
4
4
  <%- else -%>
5
- <%== beautify(rendered_examples.first[:html]) -%>
5
+ <%== beautify(examples.first.output) -%>
6
6
  <%- end %>
7
7
  <% end %>
@@ -1,4 +1,4 @@
1
- <% if @example.params.none? %>
1
+ <% if preview.params.none? %>
2
2
  <div class="p-4 w-full h-full bg-lookbook-prose">
3
3
  <%= render_component :prose do %>
4
4
  <em class='opacity-50'>No params configured.</em>
@@ -7,7 +7,7 @@
7
7
  <% else %>
8
8
  <div class="py-3 h-full">
9
9
  <%= render_component :params_editor do |editor| %>
10
- <% @example.params.each do |param| %>
10
+ <% preview.params.each do |param| %>
11
11
  <% editor.field **param, value: params[param[:name]] %>
12
12
  <% end %>
13
13
  <% end %>
@@ -1,6 +1,6 @@
1
1
  <%= render_component :viewport,
2
- src: lookbook.preview_path(request.query_parameters.merge(lookbook_timestamp: Time.now)),
3
- alpine_data: "$store.inspector.preview",
2
+ src: lookbook_preview_path(request.query_parameters.merge(lookbook_timestamp: Time.now)),
3
+ alpine_data: "$store.inspector.main",
4
4
  class: "-inset-px relative",
5
5
  style: "width: calc(100% + 2px); height: calc(100% + 2px)"
6
6
  %>
@@ -1,11 +1,11 @@
1
1
  <div class="h-full">
2
- <% if rendered_examples.many? %>
3
- <%= render_component :code, language: rendered_examples.first[:source_lang][:name], line_numbers: true, full_height: true do -%>
4
- <%- rendered_examples.each.with_index(1) do |example, i| -%>
5
- <%== "#{sprintf example[:source_lang][:comment], example[:label]}\n#{example[:source]}\n#{"\n" if i < rendered_examples.size}" %><% end %>
2
+ <% if examples.many? %>
3
+ <%= render_component :code, language: examples.first.source_lang[:name], line_numbers: true, full_height: true do -%>
4
+ <%- examples.each.with_index(1) do |example, i| -%>
5
+ <%== "#{sprintf example.source_lang[:comment], example.label}\n#{example.source}\n#{"\n" if i < examples.size}" %><% end %>
6
6
  <% end %>
7
7
  <% else %>
8
- <% example = rendered_examples.first %>
9
- <%= render_component :code, language: example[:source_lang][:name], line_numbers: true, full_height: true do %><%== example[:source] %><% end %>
8
+ <% example = examples.first %>
9
+ <%= render_component :code, language: example.source_lang[:name], line_numbers: true, full_height: true do %><%== example.source %><% end %>
10
10
  <% end %>
11
11
  </div>
@@ -1,20 +1,23 @@
1
1
  <%= render_component :split_layout,
2
2
  alpine_data: "$store.layout.inspector",
3
- ":class": "$store.inspector.drawer.hidden && '!grid-rows-[1fr] !grid-cols-[1fr]'" do |layout| %>
3
+ ":class": "($store.inspector.drawer.hidden || #{@drawer_panels.none?}) && '!grid-rows-[1fr] !grid-cols-[1fr]'" do |layout| %>
4
4
 
5
5
  <%= layout.pane class: "flex flex-col h-full overflow-hidden",
6
6
  x_effect: "forceOrientation = (layoutWidth < $store.inspector.minVerticalSplitWidth) ? 'horizontal' : null" do %>
7
7
 
8
8
  <%= render_component :toolbar do |toolbar| %>
9
9
  <% toolbar.section ":class": "layoutResizing && 'overflow-hidden'" do %>
10
- <%= render_component :tabs, alpine_data: "$store.inspector.preview" do |tabs| %>
11
- <%= @preview_panels.each do |key, panel| %>
12
- <% tabs.tab ref: key, **panel.extract!(:label, :hotkey, :disabled) %>
10
+ <%= render_component :tabs, alpine_data: "$store.inspector.main" do |tabs| %>
11
+ <%= @main_panels.each do |panel| %>
12
+ <% tabs.tab name: panel.name,
13
+ label: panel.label,
14
+ hotkey: panel.hotkey,
15
+ disabled: panel.disabled %>
13
16
  <% end %>
14
17
  <% end %>
15
18
  <% end %>
16
19
 
17
- <% toolbar.section align: :right, padded: true, class: "flex-none min-w-[140px]", ":class": "{invisible: $store.inspector.preview.activeTab !== 'preview'}" do %>
20
+ <% toolbar.section align: :right, padded: true, class: "flex-none min-w-[140px]", ":class": "{invisible: $store.inspector.main.activeTab !== 'preview'}" do %>
18
21
  <%= render_component :dimensions_display,
19
22
  target: "[data-component=viewport] iframe",
20
23
  class: "ml-auto opacity-30 hover:opacity-100" %>
@@ -35,7 +38,7 @@
35
38
  "@click.stop": "startSpin(); $dispatch('viewport:reload'); stopSpin(500);" %>
36
39
 
37
40
  <% group.button icon: :external_link,
38
- href: lookbook.preview_path(@example.lookup_path),
41
+ href: lookbook_preview_path(@example.lookup_path),
39
42
  tooltip: "Open preview in new window",
40
43
  target: "_blank" %>
41
44
 
@@ -47,53 +50,57 @@
47
50
  cloak: true %>
48
51
  <% end %>
49
52
  <% end %>
50
- <% end %>
53
+ <% end %>
51
54
 
52
55
  <div class="h-full relative overflow-auto">
53
- <%= render_component :tabbed_content, alpine_data: "$store.inspector.preview" do |content| %>
54
- <%= @preview_panels.each do |key, panel| %>
55
- <% content.section ref: key, class: "overflow-hidden" do %>
56
- <%= render panel[:template],
57
- preview: @preview,
58
- example: @example,
59
- rendered_examples: @rendered_examples,
60
- **panel %>
56
+ <%= render_component :tab_panels, alpine_data: "$store.inspector.main" do |tabs| %>
57
+ <% @main_panels.each do |panel| %>
58
+ <% tabs.panel id: panel.id, name: panel.name, class: [panel.panel_classes, { "p-4": panel.padded, "prose": panel.prose }] do %>
59
+ <%= render panel.partial, **@inspector_data, panel: panel, **panel.locals %>
61
60
  <% end %>
62
61
  <% end %>
63
62
  <% end %>
64
63
  </div>
65
64
  <% end %>
66
65
 
67
- <%= layout.pane class: "flex flex-col h-full overflow-hidden bg-lookbook-drawer", x_show: "!$store.inspector.drawer.hidden" do %>
66
+ <%= layout.pane class: "flex flex-col h-full overflow-hidden bg-lookbook-drawer",
67
+ x_show: "!$store.inspector.drawer.hidden && #{@drawer_panels.any?}" do %>
68
68
 
69
69
  <%= render_component :toolbar do |toolbar| %>
70
70
  <% toolbar.section ":class": "layoutResizing && 'overflow-hidden'" do %>
71
71
  <%= render_component :tabs, alpine_data: "$store.inspector.drawer" do |tabs| %>
72
- <%= @drawer_panels.each do |key, panel| %>
73
- <% tabs.tab ref: key, **panel.extract!(:label, :hotkey, :disabled) %>
72
+ <%= @drawer_panels.each do |panel| %>
73
+ <% tabs.tab name: panel.name,
74
+ label: panel.label,
75
+ hotkey: panel.hotkey,
76
+ disabled: panel.disabled %>
74
77
  <% end %>
75
78
  <% end %>
76
79
  <% end %>
77
80
 
78
- <% toolbar.section align: :right, divide: :left, class: "flex-none relative z-10" do %>
81
+ <% toolbar.section align: :right, class: "flex-none relative z-10" do %>
79
82
  <%= render_component :button_group do |group| %>
80
-
81
- <%= @drawer_panels.each do |key, panel| %>
82
- <% group.button icon: :clipboard,
83
- tooltip: "Copy to clipboard",
84
- copy: !!panel[:copy],
85
- disabled: panel[:disabled] || !panel[:copy],
86
- x_show: "$store.inspector.drawer.activeTab === '#{key}'",
83
+ <%= @drawer_panels.select { |p| !p.disabled && p.copy }.each do |panel| %>
84
+ <% group.button icon: :copy,
85
+ tooltip: "Copy panel contents",
86
+ copy: !!panel.copy,
87
+ x_show: "$store.inspector.drawer.activeTab === '#{panel.name}'",
87
88
  cloak: true do %>
88
- <%== panel[:copy] ? panel[:copy] : "" %>
89
+ <%== panel.copy ? panel.copy : "" %>
89
90
  <% end %>
90
- <% end %>
91
+ <% end %>
92
+ <% end %>
93
+ <% end %>
94
+
95
+ <% toolbar.section divide: :left, class: "flex-none relative z-10" do %>
96
+ <%= render_component :button_group do |group| %>
91
97
 
92
98
  <% group.button icon: :corner_up_right,
93
99
  tooltip: "Move drawer to right",
94
100
  "@click": "switchOrientation",
95
101
  x_show: "horizontal && layoutWidth > $store.inspector.minVerticalSplitWidth",
96
102
  cloak: true %>
103
+
97
104
  <% group.button icon: :corner_up_right,
98
105
  x_show: "horizontal && layoutWidth <= $store.inspector.minVerticalSplitWidth",
99
106
  disabled: true,
@@ -114,14 +121,10 @@
114
121
  <% end %>
115
122
 
116
123
  <div class="h-full overflow-auto">
117
- <%= render_component :tabbed_content, alpine_data: "$store.inspector.drawer" do |content| %>
118
- <% @drawer_panels.each do |key, panel| %>
119
- <% content.section ref: key do %>
120
- <%= render panel[:template],
121
- preview: @preview,
122
- example: @example,
123
- rendered_examples: @rendered_examples,
124
- **panel %>
124
+ <%= render_component :tab_panels, alpine_data: "$store.inspector.drawer" do |tabs| %>
125
+ <% @drawer_panels.each do |panel| %>
126
+ <% tabs.panel id: panel.id, name: panel.name, class: [panel.panel_classes, { "p-4": panel.padded, "prose": panel.prose }] do %>
127
+ <%= render panel.partial, **@inspector_data, panel: panel, **panel.locals %>
125
128
  <% end %>
126
129
  <% end %>
127
130
  <% end %>
data/config/routes.rb CHANGED
@@ -3,13 +3,13 @@ Lookbook::Engine.routes.draw do
3
3
  mount Lookbook::Engine.websocket => Lookbook.config.cable_mount_path
4
4
  end
5
5
 
6
- root to: "application#index", as: :home
6
+ root to: "application#index", as: :lookbook_home
7
7
 
8
- get "/#{Lookbook.config.page_route}", to: "pages#index", as: :page_index
9
- get "/#{Lookbook.config.page_route}/*path", to: "pages#show", as: :page
8
+ get "/#{Lookbook.config.page_route}", to: "pages#index", as: :lookbook_page_index
9
+ get "/#{Lookbook.config.page_route}/*path", to: "pages#show", as: :lookbook_page
10
10
 
11
- get "/preview/*path", to: "previews#preview", as: :preview
12
- get "/inspect/*path", to: "previews#show", as: :inspect
11
+ get "/preview/*path", to: "previews#preview", as: :lookbook_preview
12
+ get "/inspect/*path", to: "previews#show", as: :lookbook_inspect
13
13
 
14
- get "/*path", to: "previews#show_legacy", as: :inspect_legacy
14
+ get "/*path", to: "previews#show_legacy", as: :lookbook_inspect_legacy
15
15
  end
@@ -42,7 +42,7 @@ module Lookbook
42
42
  end
43
43
 
44
44
  def non_empty_items
45
- items.filter do |item|
45
+ items.select do |item|
46
46
  !item.is_a?(Lookbook::Collection) || item.items.any?
47
47
  end
48
48
  end
@@ -0,0 +1,31 @@
1
+ module Lookbook
2
+ class Component < Entity
3
+
4
+ attr_accessor :name
5
+
6
+ def initialize(name)
7
+ @name = name
8
+ super(path)
9
+ end
10
+
11
+ def path
12
+ name.underscore
13
+ end
14
+
15
+ def full_path
16
+ Pathname.new("#{Lookbook.config.components_path}/#{path}.rb")
17
+ end
18
+
19
+ def dir_path
20
+ full_path.dirname
21
+ end
22
+
23
+ def template_path
24
+ Dir.glob("#{Lookbook.config.components_path}/#{path}.*.erb").first
25
+ end
26
+
27
+ def inline?
28
+ template_path.present?
29
+ end
30
+ end
31
+ end
@@ -1,37 +1,28 @@
1
1
  require "lookbook/markdown"
2
+ require "lookbook/theme"
3
+ require "lookbook/store"
2
4
 
3
5
  module Lookbook
4
- class ConfigOptions < ActiveSupport::OrderedOptions
5
- def initialize(**data)
6
- super()
7
- data.keys.each { |key| self[key.to_sym] = data[key] }
8
- end
9
-
10
- def [](key)
11
- super(key.to_sym)
12
- end
13
-
14
- def []=(key, value)
15
- super(key.to_sym, value)
16
- end
17
- end
18
-
19
6
  class Config
20
7
  def initialize
21
- @store = ConfigOptions.new(**{
8
+ @options = Store.new
9
+ foobar = "bax"
10
+ @options.set({
22
11
  project_name: "Lookbook",
23
12
  log_level: 2,
24
13
  auto_refresh: true,
14
+
15
+ components_path: "app/components",
25
16
 
26
17
  page_controller: "Lookbook::PageController",
27
18
  page_route: "pages",
28
19
  page_paths: ["test/components/docs"],
29
- page_options: ConfigOptions.new,
30
- markdown_options: ConfigOptions.new(**Markdown::DEFAULT_OPTIONS),
20
+ page_options: {},
21
+ markdown_options: Markdown::DEFAULT_OPTIONS,
31
22
 
32
23
  preview_paths: [],
33
- preview_display_params: ConfigOptions.new,
34
- preview_options: ConfigOptions.new,
24
+ preview_display_params: {},
25
+ preview_options: {},
35
26
  preview_srcdoc: false,
36
27
  sort_examples: true,
37
28
 
@@ -46,22 +37,122 @@ module Lookbook
46
37
  parser_registry_path: "tmp/storage/.yardoc",
47
38
 
48
39
  ui_theme: "indigo",
49
- ui_theme_overrides: ConfigOptions.new,
40
+ ui_theme_overrides: {},
41
+
42
+ hooks: {
43
+ after_initialize: [],
44
+ before_exit: [],
45
+ after_change: [],
46
+ },
47
+
50
48
  experimental_features: false,
49
+
50
+ inspector_panels: {
51
+ preview: {
52
+ pane: :main,
53
+ position: 1,
54
+ partial: "lookbook/previews/panels/preview",
55
+ hotkey: "v",
56
+ panel_classes: "overflow-hidden",
57
+ padded: false
58
+ },
59
+ output: {
60
+ pane: :main,
61
+ position: 2,
62
+ partial: "lookbook/previews/panels/output",
63
+ label: "HTML",
64
+ hotkey: "h",
65
+ padded: false
66
+ },
67
+ source: {
68
+ pane: :drawer,
69
+ position: 1,
70
+ partial: "lookbook/previews/panels/source",
71
+ label: "Source",
72
+ hotkey: "s",
73
+ copy: ->(data) { data.examples.map { |e| e.source }.join("\n") },
74
+ padded: false
75
+ },
76
+ notes: {
77
+ pane: :drawer,
78
+ position: 2,
79
+ partial: "lookbook/previews/panels/notes",
80
+ label: "Notes",
81
+ hotkey: "n",
82
+ disabled: ->(data) { data.examples.select { |e| e.notes.present? }.none? },
83
+ padded: false
84
+ },
85
+ params: {
86
+ pane: :drawer,
87
+ position: 3,
88
+ partial: "lookbook/previews/panels/params",
89
+ label: "Params",
90
+ hotkey: "p",
91
+ disabled: ->(data) { data.preview.params.none? },
92
+ padded: false
93
+ }
94
+ },
95
+
96
+ inspector_panel_defaults: {
97
+ id: ->(data) { "inspector-panel-#{data.name}" },
98
+ partial: "lookbook/previews/panels/content",
99
+ content: nil,
100
+ label: ->(data) { data.name.titleize },
101
+ pane: :drawer,
102
+ position: ->(data) { data.index_position },
103
+ hotkey: nil,
104
+ disabled: false,
105
+ show: true,
106
+ copy: nil,
107
+ panel_classes: nil,
108
+ locals: {},
109
+ padded: true
110
+ },
51
111
  })
52
112
  end
53
113
 
54
- def ui_theme=(name)
55
- name = name.to_s
56
- if ["indigo", "zinc", "blue"].include?(name)
57
- @store[:ui_theme] = name
114
+ def inspector_panels(&block)
115
+ if block_given?
116
+ yield get(:inspector_panels)
58
117
  else
59
- Lookbook.logger.warn "'#{name}' is not a valid Lookbook theme. Falling back to default."
118
+ get(:inspector_panels)
60
119
  end
61
120
  end
62
121
 
63
- def ui_theme_overrides=(theme)
64
- @store[:ui_theme_overrides] = ConfigOptions.new(theme)
122
+ def define_inspector_panel(name, opts = {})
123
+ inspector_panels[name] = opts
124
+ if opts[:position].present?
125
+ pane = inspector_panels[name].pane.presence || :drawer
126
+ siblings = inspector_panels.select do |key, panel|
127
+ panel.pane == pane && key != name.to_sym
128
+ end
129
+ siblings.each do |key, panel|
130
+ if panel.position >= opts[:position]
131
+ panel.position += 1
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ def amend_inspector_panel(name, opts = {})
138
+ if opts == false
139
+ inspector_panels[name] = false
140
+ else
141
+ inspector_panels[name].merge!(opts)
142
+ end
143
+ end
144
+
145
+ def remove_inspector_panel(name)
146
+ amend_inspector_panel(name, false)
147
+ end
148
+
149
+ def ui_theme=(name)
150
+ name = name.to_s
151
+ if Theme.valid_theme?(name)
152
+ @options[:ui_theme] = name
153
+ else
154
+ Lookbook.logger.warn "'#{name}' is not a valid Lookbook theme. Theme setting not changed."
155
+ end
65
156
  end
66
157
 
67
158
  def ui_theme_overrides(&block)
@@ -77,11 +168,11 @@ module Lookbook
77
168
  end
78
169
 
79
170
  def []=(key, value)
80
- @store[key.to_sym] = value
171
+ @options[key.to_sym] = value
81
172
  end
82
173
 
83
174
  def to_h
84
- @store.to_h
175
+ @options.to_h
85
176
  end
86
177
 
87
178
  def to_json(*a)
@@ -90,13 +181,22 @@ module Lookbook
90
181
 
91
182
  protected
92
183
 
184
+ def get_inspector_panels(panels)
185
+ panels.select! { |key, panel| panel }
186
+ panels
187
+ end
188
+
93
189
  def get_project_name(name)
94
190
  name == false ? nil : name
95
191
  end
96
192
 
193
+ def get_components_path(path)
194
+ absolute_path(path)
195
+ end
196
+
97
197
  def normalize_paths(paths)
98
198
  paths.map! { |path| absolute_path(path) }
99
- paths.filter! { |path| Dir.exist?(path) }
199
+ paths.select! { |path| Dir.exist?(path) }
100
200
  paths
101
201
  end
102
202
 
@@ -111,11 +211,11 @@ module Lookbook
111
211
 
112
212
  def get(name)
113
213
  getter_name = "get_#{name}".to_sym
114
- respond_to?(getter_name, true) ? send(getter_name, @store[name]) : @store[name]
214
+ respond_to?(getter_name, true) ? send(getter_name, @options[name]) : @options[name]
115
215
  end
116
216
 
117
217
  def set(name, *args)
118
- @store.send(name, *args)
218
+ @options.send(name, *args)
119
219
  end
120
220
 
121
221
  def method_missing(name, *args)