lookbook 2.0.0.beta.4 → 2.0.0.beta.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/lookbook/button/component.js +2 -2
  3. data/app/components/lookbook/copy_button/component.js +1 -1
  4. data/app/components/lookbook/display_options/field/component.js +1 -1
  5. data/app/components/lookbook/header/component.css +12 -0
  6. data/app/components/lookbook/header/component.html.erb +13 -9
  7. data/app/components/lookbook/header/component.rb +4 -2
  8. data/app/components/lookbook/icon/component.css +8 -0
  9. data/app/components/lookbook/icon/component.html.erb +2 -4
  10. data/app/components/lookbook/icon/component.rb +16 -4
  11. data/app/components/lookbook/nav/directory/component.html.erb +4 -4
  12. data/app/components/lookbook/nav/entity/component.html.erb +4 -4
  13. data/app/components/lookbook/tabs/component.js +1 -1
  14. data/app/views/layouts/lookbook/application.html.erb +40 -42
  15. data/app/views/layouts/lookbook/skeleton.html.erb +3 -9
  16. data/app/views/lookbook/inspector/panels/_preview.html.erb +1 -0
  17. data/app/views/lookbook/inspector/show.html.erb +10 -2
  18. data/config/app.yml +2 -1
  19. data/lib/lookbook/engine.rb +20 -18
  20. data/lib/lookbook/entities/concerns/navigable_entity.rb +6 -1
  21. data/lib/lookbook/entities/preview_entity.rb +24 -4
  22. data/lib/lookbook/entities/scenario_group_entity.rb +5 -0
  23. data/lib/lookbook/preview.rb +4 -0
  24. data/lib/lookbook/services/urls/data_uri_encoder.rb +14 -0
  25. data/lib/lookbook/services/urls/file_data_uri_encoder.rb +24 -0
  26. data/lib/lookbook/stores/config_store.rb +46 -1
  27. data/lib/lookbook/stores/hook_store.rb +0 -10
  28. data/lib/lookbook/stores/input_store.rb +7 -1
  29. data/lib/lookbook/stores/panel_store.rb +4 -1
  30. data/lib/lookbook/stores/tag_store.rb +6 -5
  31. data/lib/lookbook/version.rb +1 -1
  32. data/lib/lookbook.rb +3 -3
  33. data/public/lookbook-assets/css/lookbook.css +125 -6
  34. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  35. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  36. data/public/lookbook-assets/css/themes/green.css.map +1 -1
  37. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  38. data/public/lookbook-assets/css/themes/rose.css.map +1 -1
  39. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  40. data/public/lookbook-assets/js/iframe.js +2 -1
  41. data/public/lookbook-assets/js/iframe.js.map +1 -1
  42. data/public/lookbook-assets/js/index.js +322 -350
  43. data/public/lookbook-assets/js/index.js.map +1 -1
  44. data/public/lookbook-assets/js/lookbook-core.js +21 -21
  45. data/public/lookbook-assets/js/lookbook.js +30 -29
  46. metadata +10 -43
  47. data/app/assets/lookbook/css/fonts.css +0 -33
  48. data/app/assets/lookbook/css/lookbook.css +0 -145
  49. data/app/assets/lookbook/css/themes/blue.css +0 -76
  50. data/app/assets/lookbook/css/themes/green.css +0 -76
  51. data/app/assets/lookbook/css/themes/indigo.css +0 -76
  52. data/app/assets/lookbook/css/themes/rose.css +0 -76
  53. data/app/assets/lookbook/css/themes/zinc.css +0 -76
  54. data/app/assets/lookbook/css/tooltip.css +0 -53
  55. data/app/assets/lookbook/img/lucide-sprite.svg +0 -4960
  56. data/app/assets/lookbook/js/app.js +0 -112
  57. data/app/assets/lookbook/js/components/clipboard.js +0 -47
  58. data/app/assets/lookbook/js/components/params_input.js +0 -23
  59. data/app/assets/lookbook/js/components/tooltip.js +0 -30
  60. data/app/assets/lookbook/js/config.js +0 -24
  61. data/app/assets/lookbook/js/helpers/build.js +0 -22
  62. data/app/assets/lookbook/js/helpers/dom.js +0 -42
  63. data/app/assets/lookbook/js/helpers/layout.js +0 -21
  64. data/app/assets/lookbook/js/helpers/request.js +0 -16
  65. data/app/assets/lookbook/js/helpers/string.js +0 -26
  66. data/app/assets/lookbook/js/iframe.js +0 -1
  67. data/app/assets/lookbook/js/index.js +0 -61
  68. data/app/assets/lookbook/js/lib/lookbook.js +0 -123
  69. data/app/assets/lookbook/js/lib/socket.js +0 -28
  70. data/app/assets/lookbook/js/lib/tippy.js +0 -9
  71. data/app/assets/lookbook/js/lookbook-core.js +0 -1
  72. data/app/assets/lookbook/js/lookbook.js +0 -2
  73. data/app/assets/lookbook/js/plugins/logger.js +0 -39
  74. data/app/assets/lookbook/js/stores/filter.js +0 -11
  75. data/app/assets/lookbook/js/stores/inspector.js +0 -31
  76. data/app/assets/lookbook/js/stores/layout.js +0 -111
  77. data/app/assets/lookbook/js/stores/nav.js +0 -22
  78. data/app/assets/lookbook/js/stores/pages.js +0 -7
  79. data/app/assets/lookbook/js/stores/settings.js +0 -7
  80. data/app/assets/lookbook/js/stores/workbench.js +0 -29
  81. data/app/components/lookbook/icon/component.js +0 -5
  82. data/config/hooks.yml +0 -4
  83. /data/{app/assets/lookbook/fonts/Inter-italic.var.woff2 → public/lookbook-assets/Inter-italic.var.53a0de5f.woff2} +0 -0
  84. /data/{app/assets/lookbook/fonts/Inter-roman.var.woff2 → public/lookbook-assets/Inter-roman.var.d4f9805a.woff2} +0 -0
  85. /data/{app/assets/lookbook/fonts/SourceCodeVariable-Italic.ttf.woff2 → public/lookbook-assets/SourceCodeVariable-Italic.ttf.a93fa22f.woff2} +0 -0
  86. /data/{app/assets/lookbook/fonts/SourceCodeVariable-Roman.ttf.woff2 → public/lookbook-assets/SourceCodeVariable-Roman.ttf.f1c8fcce.woff2} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32b443cd8b8590f1378d66d6ff64cb95a6ab1d6ff771dfc40bb9cbe5b3a13236
4
- data.tar.gz: 26cafffae7ed01a3fd19be32e13f805a8e819a5984e2f178cdff66502f4989f5
3
+ metadata.gz: bfe0ace7c0c83d2cb22ac89815ccb492dd5c8fc16ad4b33c905caae04f942fec
4
+ data.tar.gz: f8c0fd31b102ab2e6846c9990574f0b1404025eec8b9d5670e61404d0590a83d
5
5
  SHA512:
6
- metadata.gz: 31d790b457c4fbc1584d1fa81201a635a857ba02e3b6e9693d42589a1facc08ef72dcf90987426062ed0a5ce0b72ba7ad395a1739324a4d8f896c09d1e10629c
7
- data.tar.gz: be0770e93e0ab89028a0669e6a63073374f420b9d93b59aa1364c21a06cbf79f9f274ca0ed33b48bdd5a80c86a04161748c701c4e27020f5bb2f1f3454064b8f
6
+ metadata.gz: 70b9c6dec1a29fbc3a2287377f9f69010c6fafac082478db74690b0ca1a746f617046f0f02b0edecc557d6aef7e8e572a73e03a9acd119f8ee3cfd7b5ba79f01
7
+ data.tar.gz: 6a1870ef7600be6280e7d26c4337c99bc60bc3ffd47998ee313386d6d259a14e0e00fcff6e85a232f6f7120cb3b2b6d6df5a6b0b1383d8154f4d46d195890013
@@ -1,5 +1,5 @@
1
- import tippy from "~/app/assets/lookbook/js/lib/tippy";
2
- import { initTooltip } from "~/app/assets/lookbook/js/components/tooltip";
1
+ import tippy from "~/assets/js/lib/tippy";
2
+ import { initTooltip } from "~/assets/js/components/tooltip";
3
3
 
4
4
  export default function buttonComponent() {
5
5
  let tooltip = null;
@@ -1,4 +1,4 @@
1
- import { initClipboard } from "~/app/assets/lookbook/js/components/clipboard";
1
+ import { initClipboard } from "~/assets/js/components/clipboard";
2
2
  import buttonComponent from "@components/button/component";
3
3
 
4
4
  export default function copyButtonComponent() {
@@ -2,7 +2,7 @@ import Cookies from "js-cookie";
2
2
  import {
3
3
  parseSearchParamValue,
4
4
  buildSearchParamValue,
5
- } from "~/app/assets/lookbook/js/helpers/string";
5
+ } from "~/assets/js/helpers/string";
6
6
 
7
7
  export default function displayOptionsFieldComponent({ name, value }) {
8
8
  return {
@@ -0,0 +1,12 @@
1
+ @layer components {
2
+ [data-component="header"] {
3
+ .header-project-icon {
4
+ @apply h-5 inline-block flex-none;
5
+ width: min-content;
6
+
7
+ svg {
8
+ @apply h-full w-auto;
9
+ }
10
+ }
11
+ }
12
+ }
@@ -1,16 +1,20 @@
1
1
  <%= render_component_tag :header do %>
2
2
  <%= lookbook_render :toolbar, class: "!bg-lookbook-header-bg !text-lookbook-header-text !border-lookbook-header-border" do |toolbar| %>
3
3
  <% toolbar.with_section padded: true do %>
4
- <div class="flex items-center space-x-3">
5
- <%= lookbook_render :logo, size: 4 %>
6
- <% if branding.present? %>
7
- <a
8
- <% if landing_path %>href="<%= landing_path %>"<% end %>
9
- class="text-sm truncate uppercase font-black tracking-wider text-lookbook-branding-text">
10
- <%= branding %>
11
- </a>
4
+ <a <% if landing_path %>href="<%= landing_path %>"<% end %> class="flex items-center space-x-3">
5
+ <% if project_logo.present? %>
6
+ <i class="header-project-icon">
7
+ <%== project_logo %>
8
+ </i>
9
+ <% elsif project_logo != false %>
10
+ <%= lookbook_render :logo, size: 3.7 %>
12
11
  <% end %>
13
- </div>
12
+ <% if project_name.present? %>
13
+ <span class="text-sm truncate uppercase font-black tracking-wider text-lookbook-branding-text">
14
+ <%= project_name %>
15
+ </span>
16
+ <% end %>
17
+ </a>
14
18
  <% end %>
15
19
 
16
20
  <% toolbar.with_section padded: false, align: :right, class: "flex items-center -mt-px" do %>
@@ -1,9 +1,11 @@
1
1
  module Lookbook
2
2
  class Header::Component < Lookbook::BaseComponent
3
- renders_one :branding
3
+ attr_reader :project_logo, :project_name
4
4
 
5
- def initialize(debug_menu: false, **html_attrs)
5
+ def initialize(debug_menu: false, project_name: nil, project_logo: nil, **html_attrs)
6
6
  @debug_menu = debug_menu
7
+ @project_logo = project_logo
8
+ @project_name = project_name
7
9
  super(**html_attrs)
8
10
  end
9
11
 
@@ -7,5 +7,13 @@
7
7
  stroke-linecap: round;
8
8
  stroke-linejoin: round;
9
9
  }
10
+
11
+ &.icon-stroke-2 svg {
12
+ stroke-width: 2;
13
+ }
14
+
15
+ &.icon-stroke-1 svg {
16
+ stroke-width: 1;
17
+ }
10
18
  }
11
19
  }
@@ -1,5 +1,3 @@
1
- <%= render_component_tag :i, style: "height: #{size_rems}; width: #{size_rems}; #{@html_attrs[:style]}" do %>
2
- <svg stroke-width="<%= stroke %>">
3
- <use :href="`/lookbook-assets/img/lucide-sprite.svg#${iconName}`" x-cloak />
4
- </svg>
1
+ <%= render_component_tag :i, style: "height: #{size_rems}; width: #{size_rems}; #{@html_attrs[:style]}", class: "icon-stroke-#{stroke}" do %>
2
+ <%= svg %>
5
3
  <% end %>
@@ -1,9 +1,11 @@
1
1
  module Lookbook
2
2
  class Icon::Component < Lookbook::BaseComponent
3
+ ICON_CACHE = {}
4
+
3
5
  attr_reader :stroke
4
6
 
5
7
  def initialize(name:, size: 4, stroke: 2, **html_attrs)
6
- @alpine_data = name.is_a?(Symbol) ? alpine_encode(name.to_s.tr("_", "-")) : name
8
+ @icon_name = name.to_s.tr("_", "-")
7
9
  @size = size || 4
8
10
  @stroke = stroke
9
11
  super(**html_attrs)
@@ -13,10 +15,20 @@ module Lookbook
13
15
  "#{@size * 0.25}rem"
14
16
  end
15
17
 
16
- protected
18
+ def svg
19
+ ICON_CACHE[@icon_name] ||= read_svg
20
+ end
21
+
22
+ def read_svg
23
+ File.read(svg_path).html_safe
24
+ rescue
25
+ if Rails.env.development? || Rails.env.test?
26
+ raise "`#{@icon_name}` is not a valid icon name"
27
+ end
28
+ end
17
29
 
18
- def alpine_component
19
- "iconComponent"
30
+ def svg_path
31
+ Lookbook::Engine.root.join("assets/icons/#{@icon_name}.svg")
20
32
  end
21
33
  end
22
34
  end
@@ -11,10 +11,10 @@
11
11
  style: "padding-left: #{left_pad}px",
12
12
  "x-bind": "bindings.toggle" do %>
13
13
  <div class="nav-action-inner">
14
- <%= icon nil,
15
- size: 3,
16
- class: "nav-toggle-icon",
17
- "x-effect": "iconName = open ? 'chevron-down' : 'chevron-right'" if children? %>
14
+ <% if children? %>
15
+ <%= icon "chevron-down", size: 3, class: "nav-toggle-icon", "x-show": "open", "x-cloak": "true" %>
16
+ <%= icon "chevron-right", size: 3, class: "nav-toggle-icon", "x-show": "!open", "x-cloak": "true" %>
17
+ <% end %>
18
18
  <%= icon nav_icon, size: 3.5, class: "mr-1.5 text-lookbook-nav-icon-stroke" %>
19
19
  <span class="truncate"><%= label %></span>
20
20
  </div>
@@ -12,10 +12,10 @@
12
12
  style: "padding-left: #{left_pad}px",
13
13
  "x-bind": "bindings.#{href.present? ? "link" : "toggle"}" do %>
14
14
  <div class="nav-action-inner">
15
- <%= icon nil,
16
- size: 3,
17
- class: "nav-toggle-icon",
18
- "x-effect": "iconName = open ? 'chevron-down' : 'chevron-right'" if children? %>
15
+ <% if children? %>
16
+ <%= icon "chevron-down", size: 3, class: "nav-toggle-icon", "x-show": "open", "x-cloak": "true" %>
17
+ <%= icon "chevron-right", size: 3, class: "nav-toggle-icon", "x-show": "!open", "x-cloak": "true" %>
18
+ <% end %>
19
19
  <%= icon nav_icon, size: 3.5, class: "mr-1.5 text-lookbook-nav-icon-stroke" %>
20
20
  <span class="truncate <% if node.type == :preview %>font-semibold<% end %>"><%= label %></span>
21
21
  </div>
@@ -1,5 +1,5 @@
1
1
  import { debounce } from "throttle-debounce";
2
- import tippy from "~/app/assets/lookbook/js/lib/tippy";
2
+ import tippy from "~/assets/js/lib/tippy";
3
3
  import { observeSize } from "@helpers/layout";
4
4
  import { getElementSize } from "@helpers/dom";
5
5
 
@@ -11,9 +11,11 @@
11
11
 
12
12
  <%= render "lookbook/partials/user_styles" %>
13
13
 
14
- <%= lookbook_render :header, id: "app-header", debug_menu: @config.debug_menu do |header| %>
15
- <% header.with_branding { @config.project_name } %>
16
- <% end %>
14
+ <%= lookbook_render :header,
15
+ id: "app-header",
16
+ debug_menu: @config.debug_menu,
17
+ project_name: @config.project_name,
18
+ project_logo: @config.project_logo %>
17
19
 
18
20
  <% if @previews.any? || @pages.any? %>
19
21
 
@@ -30,58 +32,54 @@
30
32
  "@click.outside": "closeMobileSidebar",
31
33
  cloak: true do %>
32
34
 
33
- <% cache @engine.last_changed do %>
34
-
35
- <%= lookbook_render :split_layout,
36
- alpine_data: "$store.layout.#{@pages.any? && @previews.any? ? "sidebar" : "singleSectionSidebar"}",
37
- style: "height: calc(100vh - 2.5rem);" do |layout| %>
35
+ <%= lookbook_render :split_layout,
36
+ alpine_data: "$store.layout.#{@pages.any? && @previews.any? ? "sidebar" : "singleSectionSidebar"}",
37
+ style: "height: calc(100vh - 2.5rem);" do |layout| %>
38
38
 
39
- <% if @previews.any? %>
40
- <% layout.with_pane class: "overflow-hidden" do %>
41
- <%= lookbook_render :nav,
42
- id: "previews-nav",
43
- tree: @previews.to_tree,
44
- alpine_data: "$store.nav.previews" do |nav| %>
45
- <%= nav.with_toolbar do |toolbar| %>
46
- <% toolbar.with_section padded: true do %>
47
- <h4 class="pt-1">Previews</h4>
48
- <% end %>
49
- <% toolbar.with_section align: :right, padded: false do %>
50
- <%= lookbook_render :button_group, size: :xs do |group| %>
51
- <% group.with_button icon: :minus_square,
52
- tooltip: "Collapse all",
53
- "@click": "closeAll" %>
54
- <% end %>
39
+ <% if @previews.any? %>
40
+ <% layout.with_pane class: "overflow-hidden" do %>
41
+ <%= lookbook_render :nav,
42
+ id: "previews-nav",
43
+ tree: @previews.to_tree,
44
+ alpine_data: "$store.nav.previews" do |nav| %>
45
+ <%= nav.with_toolbar do |toolbar| %>
46
+ <% toolbar.with_section padded: true do %>
47
+ <h4 class="pt-1">Previews</h4>
48
+ <% end %>
49
+ <% toolbar.with_section align: :right, padded: false do %>
50
+ <%= lookbook_render :button_group, size: :xs do |group| %>
51
+ <% group.with_button icon: :minus_square,
52
+ tooltip: "Collapse all",
53
+ "@click": "closeAll" %>
55
54
  <% end %>
56
55
  <% end %>
57
- <% nav.with_filter store: "$store.nav.previews.filter", placeholder: "Filter previews by name&hellip;" %>
58
56
  <% end %>
57
+ <% nav.with_filter store: "$store.nav.previews.filter", placeholder: "Filter previews by name&hellip;" %>
59
58
  <% end %>
60
59
  <% end %>
60
+ <% end %>
61
61
 
62
- <% if @pages.any? %>
63
- <% layout.with_pane class: "overflow-hidden" do %>
64
- <%= lookbook_render :nav,
65
- id: "pages-nav",
66
- tree: @pages.to_tree,
67
- alpine_data: "$store.nav.pages" do |nav| %>
68
- <%= nav.with_toolbar do |toolbar| %>
69
- <% toolbar.with_section padded: true do %>
70
- <h4 class="pt-1">Pages</h4>
71
- <% end %>
72
- <% toolbar.with_section align: :right, padded: false do %>
73
- <%= lookbook_render :button_group, size: :xs do |group| %>
74
- <% group.with_button icon: :minus_square,
75
- tooltip: "Collapse all",
76
- "@click": "closeAll" %>
77
- <% end %>
62
+ <% if @pages.any? %>
63
+ <% layout.with_pane class: "overflow-hidden" do %>
64
+ <%= lookbook_render :nav,
65
+ id: "pages-nav",
66
+ tree: @pages.to_tree,
67
+ alpine_data: "$store.nav.pages" do |nav| %>
68
+ <%= nav.with_toolbar do |toolbar| %>
69
+ <% toolbar.with_section padded: true do %>
70
+ <h4 class="pt-1">Pages</h4>
71
+ <% end %>
72
+ <% toolbar.with_section align: :right, padded: false do %>
73
+ <%= lookbook_render :button_group, size: :xs do |group| %>
74
+ <% group.with_button icon: :minus_square,
75
+ tooltip: "Collapse all",
76
+ "@click": "closeAll" %>
78
77
  <% end %>
79
78
  <% end %>
80
79
  <% end %>
81
80
  <% end %>
82
81
  <% end %>
83
82
  <% end %>
84
-
85
83
  <% end %>
86
84
  <% end %>
87
85
 
@@ -14,15 +14,9 @@
14
14
  </style>
15
15
  <% end %>
16
16
 
17
- <% if @config.ui_favicon == true %>
18
- <link
19
- rel="icon"
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
- media="(prefers-color-scheme: dark)">
22
- <link
23
- rel="icon"
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
- media="(prefers-color-scheme: light)">
17
+ <% unless @config.ui_favicon == false %>
18
+ <link rel="icon" href="<%= @config.ui_favicon_dark %>" media="(prefers-color-scheme: dark)">
19
+ <link rel="icon" href="<%= @config.ui_favicon_light %>" media="(prefers-color-scheme: light)">
26
20
  <% end %>
27
21
 
28
22
  <script>
@@ -1,5 +1,6 @@
1
1
  <div class="overflow-hidden h-full w-full">
2
2
  <%= lookbook_render :viewport,
3
+ key: (lookbook_preview_path(request.query_parameters).parameterize unless Rails.env.test?),
3
4
  iframe_id: "preview-iframe",
4
5
  src: lookbook_preview_path(request.query_parameters.merge(lookbook_timestamp: Time.now)),
5
6
  alpine_data: "$store.inspector.main",
@@ -63,11 +63,19 @@
63
63
  target: "_blank" %>
64
64
 
65
65
  <% group.with_button id: "show-drawer-button",
66
- icon: "vertical ? 'sidebar' : 'credit-card'",
66
+ icon: "sidebar",
67
67
  tooltip: "Show drawer",
68
68
  "@click": "$store.inspector.drawer.hidden = false",
69
69
  class: "rotate-180",
70
- "x-show": "$store.inspector.drawer.hidden",
70
+ "x-show": "$store.inspector.drawer.hidden && vertical",
71
+ cloak: true %>
72
+
73
+ <% group.with_button id: "show-drawer-button",
74
+ icon: "credit-card",
75
+ tooltip: "Show drawer",
76
+ "@click": "$store.inspector.drawer.hidden = false",
77
+ class: "rotate-180",
78
+ "x-show": "$store.inspector.drawer.hidden && !vertical",
71
79
  cloak: true %>
72
80
  <% end %>
73
81
  <% end %>
data/config/app.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  shared:
2
- project_name: Lookbook
2
+ project_name: ~
3
+ project_logo: ~
3
4
 
4
5
  preview_paths: [test/components/previews]
5
6
  preview_display_options: {}
@@ -14,14 +14,21 @@ module Lookbook
14
14
  )
15
15
  end
16
16
 
17
+ initializer "lookbook.set_autoload_paths" do
18
+ unless opts.preview_paths.empty?
19
+ paths_to_add = opts.preview_paths - ActiveSupport::Dependencies.autoload_paths
20
+ ActiveSupport::Dependencies.autoload_paths.concat(paths_to_add) if paths_to_add.any?
21
+ end
22
+ end
23
+
17
24
  config.before_configuration do
18
25
  config.lookbook = Lookbook.config
19
26
 
20
27
  if defined?(ViewComponent)
21
- config.lookbook.using_view_component = true
28
+ config.lookbook.using_view_component ||= true
22
29
  else
23
30
  require "view_component"
24
- config.lookbook.using_view_component = false
31
+ config.lookbook.using_view_component ||= false
25
32
  end
26
33
  end
27
34
 
@@ -114,7 +121,7 @@ module Lookbook
114
121
  end
115
122
 
116
123
  def hooks
117
- @_hooks ||= HookStore.init_from_config
124
+ @_hooks ||= HookStore.new
118
125
  end
119
126
 
120
127
  def run_hooks(event_name, *args)
@@ -159,10 +166,10 @@ module Lookbook
159
166
  end
160
167
 
161
168
  def preview_watch_paths
162
- return @_preview_watch_paths if @_preview_watch_paths
163
-
164
- paths = [*opts.preview_paths, *opts.component_paths, *opts.listen_paths, *view_paths].uniq
165
- @_preview_watch_paths ||= PathUtils.normalize_paths(paths)
169
+ @_preview_watch_paths ||= begin
170
+ paths = [*opts.preview_paths, *opts.component_paths, *opts.listen_paths, *view_paths].uniq
171
+ PathUtils.normalize_paths(paths)
172
+ end
166
173
  end
167
174
 
168
175
  def pages
@@ -184,13 +191,17 @@ module Lookbook
184
191
  changed_files = [*changes[:added], *changes[:modified]] if changes
185
192
  parser.parse(changed_files) do |code_objects|
186
193
  previews.load(code_objects.all(:class), changes)
187
- mark_changed
188
194
  end
195
+ rescue => e
196
+ Lookbook.logger.error(e)
197
+ raise e
189
198
  end
190
199
 
191
200
  def load_pages(changes = nil)
192
201
  pages.load(Engine.page_paths, changes)
193
- mark_changed
202
+ rescue => e
203
+ Lookbook.logger.error(e)
204
+ raise e
194
205
  end
195
206
 
196
207
  def notify_clients(changes = nil)
@@ -205,15 +216,6 @@ module Lookbook
205
216
  reloaders.register_changes(changes)
206
217
  notify_clients(changes)
207
218
  end
208
-
209
- def mark_changed
210
- @_last_changed = (Time.now.to_f * 1000).to_i
211
- end
212
-
213
- def last_changed
214
- mark_changed unless @_last_changed
215
- @_last_changed
216
- end
217
219
  end
218
220
 
219
221
  at_exit do
@@ -31,7 +31,12 @@ module Lookbook
31
31
  fetch_config(:priority, default_priority)
32
32
  end
33
33
 
34
- @_priority ||= pos.to_i
34
+ @_priority ||= @_fallback_priority || pos.to_i
35
+ end
36
+
37
+ # @api private
38
+ def default_priority=(i)
39
+ @default_priority = i.to_i
35
40
  end
36
41
 
37
42
  # @api private
@@ -173,11 +173,31 @@ module Lookbook
173
173
  protected
174
174
 
175
175
  def load_scenarios
176
- return scenario_entities unless code_object.groups.any?
177
-
178
- scenario_entities.group_by(&:group).flat_map do |group_name, grouped_scenarios|
179
- group_name.nil? ? grouped_scenarios : ScenarioGroupEntity.new(group_name.presence || label.pluralize, grouped_scenarios, self)
176
+ code_object.groups.any? ? grouped_scenario_entities : scenario_entities
177
+ end
178
+
179
+ def grouped_scenario_entities
180
+ scenarios = []
181
+ scenario_entities.each.with_index(1) do |entity, i|
182
+ if entity.group.nil?
183
+ entity.default_priority = i
184
+ scenarios << entity
185
+ else
186
+ group_name = entity.group.presence || entity.parent.name.pluralize
187
+ group = scenarios.find do |s|
188
+ s.is_a?(ScenarioGroupEntity) && s.name == Utils.name(group_name)
189
+ end
190
+
191
+ if group
192
+ group.add_scenario(entity)
193
+ else
194
+ group = ScenarioGroupEntity.new(group_name, [entity], self)
195
+ group.default_priority = i
196
+ scenarios << group
197
+ end
198
+ end
180
199
  end
200
+ scenarios
181
201
  end
182
202
 
183
203
  def scenario_entities
@@ -126,5 +126,10 @@ module Lookbook
126
126
  def search_terms
127
127
  [parent.label, label]
128
128
  end
129
+
130
+ # @api private
131
+ def add_scenario(scenario)
132
+ @scenarios.add(scenario)
133
+ end
129
134
  end
130
135
  end
@@ -35,6 +35,10 @@ module Lookbook
35
35
  alias_method :render_component, :render
36
36
 
37
37
  class << self
38
+ def preview_name
39
+ name.chomp("Preview").underscore
40
+ end
41
+
38
42
  # Returns the arguments for rendering of the component in its layout
39
43
  def render_args(scenario, params: {})
40
44
  scenario_params_names = instance_method(scenario).parameters.map(&:last)
@@ -0,0 +1,14 @@
1
+ module Lookbook
2
+ class DataUriEncoder < Service
3
+ attr_reader :str, :mime_type
4
+
5
+ def initialize(str, mime_type)
6
+ @str = str
7
+ @mime_type = mime_type
8
+ end
9
+
10
+ def call
11
+ "data:#{mime_type},#{ERB::Util.url_encode(str)}"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require "marcel"
2
+
3
+ module Lookbook
4
+ class FileDataUriEncoder < Service
5
+ attr_reader :path
6
+
7
+ def initialize(path, mime_type = nil)
8
+ @path = path
9
+ @mime_type = mime_type
10
+ end
11
+
12
+ def content
13
+ File.read(path)
14
+ end
15
+
16
+ def mime_type
17
+ @mime_type || Marcel::MimeType.for(Pathname.new(path))
18
+ end
19
+
20
+ def call
21
+ DataUriEncoder.call(content, mime_type)
22
+ end
23
+ end
24
+ end
@@ -15,6 +15,10 @@ module Lookbook
15
15
  # @api public
16
16
  class ConfigStore
17
17
  CONFIG_FILE = "config/app.yml"
18
+ DEFAULT_FAVICONS = {
19
+ light: "assets/img/favicon_light.svg",
20
+ dark: "assets/img/favicon_dark.svg"
21
+ }
18
22
 
19
23
  delegate_missing_to :store
20
24
  attr_reader :store
@@ -23,8 +27,20 @@ module Lookbook
23
27
  @store = Store.new(config, recursive: true)
24
28
  end
25
29
 
30
+ def project_name
31
+ if store[:project_name].nil?
32
+ if store[:project_logo].nil?
33
+ Rails.application.class.module_parent.name.titleize
34
+ else
35
+ false
36
+ end
37
+ else
38
+ store[:project_name]
39
+ end
40
+ end
41
+
26
42
  def project_name=(name)
27
- store[:project_name] = (name == false) ? nil : name
43
+ store[:project_name] = name
28
44
  end
29
45
 
30
46
  def page_extensions=(extensions = nil)
@@ -52,6 +68,14 @@ module Lookbook
52
68
  end
53
69
  end
54
70
 
71
+ def ui_favicon_light
72
+ @_ui_favicon_light ||= get_favicon(:light)
73
+ end
74
+
75
+ def ui_favicon_dark
76
+ @_ui_favicon_dark ||= get_favicon(:dark)
77
+ end
78
+
55
79
  def ui_theme_overrides(&block)
56
80
  if block
57
81
  yield store[:ui_theme_overrides]
@@ -67,5 +91,26 @@ module Lookbook
67
91
  def self.default_config(env: Rails.env)
68
92
  ConfigLoader.call(CONFIG_FILE, env: env)
69
93
  end
94
+
95
+ private
96
+
97
+ def get_favicon(theme)
98
+ default_favicon_path = Engine.root.join(DEFAULT_FAVICONS[theme])
99
+ default_favicon = FileDataUriEncoder.call(default_favicon_path)
100
+
101
+ if ui_favicon.present?
102
+ if ui_favicon.is_a?(Hash)
103
+ if ui_favicon[theme].is_a?(String)
104
+ DataUriEncoder.call(ui_favicon[theme], "image/svg+xml")
105
+ else
106
+ default_favicon
107
+ end
108
+ elsif ui_favicon.is_a?(String)
109
+ DataUriEncoder.call(ui_favicon, "image/svg+xml")
110
+ else
111
+ default_favicon
112
+ end
113
+ end
114
+ end
70
115
  end
71
116
  end