lookbook 1.5.5 → 2.0.0.beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -31
  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/index.js +61 -0
  15. data/app/assets/lookbook/js/lib/lookbook.js +113 -0
  16. data/app/assets/lookbook/js/lib/tippy.js +1 -0
  17. data/app/assets/lookbook/js/lookbook-core.js +1 -0
  18. data/app/assets/lookbook/js/lookbook.js +2 -61
  19. data/app/components/lookbook/base_component.rb +3 -1
  20. data/app/components/lookbook/button/component.html.erb +13 -24
  21. data/app/components/lookbook/button/component.js +13 -3
  22. data/app/components/lookbook/button/component.rb +16 -25
  23. data/app/components/lookbook/code/component.rb +0 -2
  24. data/app/components/lookbook/copy_button/component.html.erb +5 -5
  25. data/app/components/lookbook/copy_button/component.rb +6 -3
  26. data/app/components/lookbook/debug_menu/component.html.erb +1 -0
  27. data/app/components/lookbook/debug_menu/component.rb +12 -1
  28. data/app/components/lookbook/display_options/editor/component.html.erb +1 -1
  29. data/app/components/lookbook/display_options/field/component.css +0 -26
  30. data/app/components/lookbook/display_options/field/component.html.erb +1 -1
  31. data/app/components/lookbook/embed/component.html.erb +6 -51
  32. data/app/components/lookbook/embed/component.rb +17 -16
  33. data/app/components/lookbook/embed/inspector/component.html.erb +102 -0
  34. data/app/components/lookbook/embed/inspector/component.js +46 -0
  35. data/app/components/lookbook/embed/inspector/component.rb +64 -0
  36. data/app/components/lookbook/embed_code_dropdown/component.css +12 -0
  37. data/app/components/lookbook/embed_code_dropdown/component.html.erb +19 -0
  38. data/app/components/lookbook/embed_code_dropdown/component.js +26 -0
  39. data/app/components/lookbook/embed_code_dropdown/component.rb +41 -0
  40. data/app/components/lookbook/header/component.html.erb +7 -6
  41. data/app/components/lookbook/header/component.rb +5 -1
  42. data/app/components/lookbook/icon/component.html.erb +1 -1
  43. data/app/components/lookbook/icon_button/component.html.erb +20 -0
  44. data/app/components/lookbook/icon_button/component.rb +46 -0
  45. data/app/components/lookbook/nav/component.html.erb +0 -1
  46. data/app/components/lookbook/nav/entity/component.rb +2 -2
  47. data/app/components/lookbook/nav/item/component.rb +1 -1
  48. data/app/components/lookbook/page_tabs/component.html.erb +2 -2
  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 +26 -22
  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 +10 -30
  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/404.html.erb +2 -2
  74. data/app/views/lookbook/embeds/show.html.erb +12 -0
  75. data/app/views/lookbook/inspector/panels/_notes.html.erb +1 -1
  76. data/app/views/lookbook/inspector/panels/_output.html.erb +3 -3
  77. data/app/views/lookbook/inspector/panels/_source.html.erb +6 -6
  78. data/app/views/lookbook/inspector/show.html.erb +130 -123
  79. data/app/views/lookbook/pages/show.html.erb +81 -34
  80. data/app/views/lookbook/partials/_iframe_content_scripts.html.erb +1 -0
  81. data/app/views/lookbook/partials/_user_styles.html.erb +5 -0
  82. data/app/views/lookbook/previews/group.html.erb +14 -0
  83. data/app/views/lookbook/previews/preview.html.erb +5 -0
  84. data/app/views/lookbook/previews/show.html.erb +1 -0
  85. data/config/app.yml +31 -16
  86. data/config/panels.yml +23 -25
  87. data/config/routes.rb +3 -1
  88. data/config/tags.yml +6 -2
  89. data/lib/lookbook/cable/cable.rb +53 -0
  90. data/lib/lookbook/engine.rb +105 -93
  91. data/lib/lookbook/entities/collections/entity_collection.rb +11 -6
  92. data/lib/lookbook/entities/collections/page_collection.rb +33 -8
  93. data/lib/lookbook/entities/collections/preview_collection.rb +42 -17
  94. data/lib/lookbook/entities/collections/render_target_collection.rb +4 -0
  95. data/lib/lookbook/entities/collections/scenario_collection.rb +4 -0
  96. data/lib/lookbook/entities/concerns/{annotatable.rb → annotatable_entity.rb} +7 -6
  97. data/lib/lookbook/entities/concerns/{inspectable.rb → inspectable_entity.rb} +2 -1
  98. data/lib/lookbook/entities/concerns/{locatable.rb → locatable_entity.rb} +8 -14
  99. data/lib/lookbook/entities/concerns/navigable_entity.rb +44 -0
  100. data/lib/lookbook/entities/entity.rb +7 -2
  101. data/lib/lookbook/entities/{page.rb → page_entity.rb} +10 -6
  102. data/lib/lookbook/entities/{page_section.rb → page_section_entity.rb} +1 -1
  103. data/lib/lookbook/entities/preview_entity.rb +99 -0
  104. data/lib/lookbook/entities/renderable_entity.rb +50 -0
  105. data/lib/lookbook/entities/rendered_scenario_entity.rb +53 -0
  106. data/lib/lookbook/entities/scenario_entity.rb +112 -0
  107. data/lib/lookbook/entities/scenario_group_entity.rb +53 -0
  108. data/lib/lookbook/error.rb +5 -5
  109. data/lib/lookbook/file_watcher.rb +19 -35
  110. data/lib/lookbook/helpers/class_names_helper.rb +28 -0
  111. data/lib/lookbook/helpers/page_helper.rb +18 -0
  112. data/{app/helpers/lookbook → lib/lookbook/helpers}/preview_helper.rb +3 -0
  113. data/lib/lookbook/helpers/ui_elements_helper.rb +115 -0
  114. data/lib/lookbook/preview.rb +79 -0
  115. data/lib/lookbook/preview_controller_actions.rb +50 -0
  116. data/lib/lookbook/preview_parser.rb +4 -2
  117. data/lib/lookbook/reloaders.rb +71 -0
  118. data/lib/lookbook/runtime_context.rb +49 -0
  119. data/lib/lookbook/services/data/resolvers/data_resolver.rb +4 -6
  120. data/lib/lookbook/services/entities/entity_tree_builder.rb +6 -6
  121. data/lib/lookbook/services/list_resolver.rb +35 -0
  122. data/lib/lookbook/services/markdown_renderer.rb +12 -2
  123. data/lib/lookbook/services/priority_prefix_parser.rb +16 -0
  124. data/lib/lookbook/services/urls/search_param_encoder.rb +16 -0
  125. data/lib/lookbook/services/urls/search_param_parser.rb +7 -6
  126. data/lib/lookbook/stores/config_store.rb +16 -16
  127. data/lib/lookbook/stores/input_store.rb +1 -3
  128. data/lib/lookbook/stores/panel_store.rb +28 -50
  129. data/lib/lookbook/support/deprecation.rb +5 -0
  130. data/lib/lookbook/support/errors/preview_template_error.rb +7 -0
  131. data/lib/lookbook/support/evented_file_update_checker.rb +69 -0
  132. data/lib/lookbook/support/null_websocket.rb +9 -0
  133. data/lib/lookbook/support/store.rb +9 -0
  134. data/lib/lookbook/support/tree_node.rb +7 -7
  135. data/lib/lookbook/support/utils/path_utils.rb +7 -1
  136. data/lib/lookbook/support/utils/utils.rb +8 -0
  137. data/lib/lookbook/tags/{position_tag.rb → priority_tag.rb} +4 -4
  138. data/lib/lookbook/tags/renders_tag.rb +4 -0
  139. data/lib/lookbook/tags/tag_provider.rb +3 -0
  140. data/lib/lookbook/tags/type_tag.rb +7 -0
  141. data/lib/lookbook/tags/yard_tag.rb +1 -2
  142. data/lib/lookbook/version.rb +1 -1
  143. data/lib/lookbook/websocket.rb +6 -53
  144. data/lib/lookbook.rb +179 -53
  145. data/public/lookbook-assets/css/lookbook.css +432 -376
  146. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  147. data/public/lookbook-assets/css/themes/blue.css +7 -0
  148. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  149. data/public/lookbook-assets/css/themes/green.css +7 -0
  150. data/public/lookbook-assets/css/themes/green.css.map +1 -1
  151. data/public/lookbook-assets/css/themes/indigo.css +7 -0
  152. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  153. data/public/lookbook-assets/css/themes/rose.css +7 -0
  154. data/public/lookbook-assets/css/themes/rose.css.map +1 -1
  155. data/public/lookbook-assets/css/themes/zinc.css +7 -0
  156. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  157. data/public/lookbook-assets/img/lucide-sprite.svg +4960 -0
  158. data/public/lookbook-assets/js/embed.js +1363 -843
  159. data/public/lookbook-assets/js/embed.js.map +1 -1
  160. data/public/lookbook-assets/js/iframe.js +906 -0
  161. data/public/lookbook-assets/js/iframe.js.map +1 -0
  162. data/public/lookbook-assets/js/index.js +13567 -0
  163. data/public/lookbook-assets/js/index.js.map +1 -0
  164. data/public/lookbook-assets/js/lookbook-core.js +85 -0
  165. data/public/lookbook-assets/js/lookbook-core.js.map +1 -0
  166. data/public/lookbook-assets/js/lookbook.js +151 -12726
  167. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  168. data/public/lookbook-assets/lookbook-esm.js +1427 -0
  169. data/public/lookbook-assets/lookbook-esm.js.map +1 -0
  170. data/public/lookbook-assets/lookbook-global.js +1427 -0
  171. data/public/lookbook-assets/lookbook-global.js.map +1 -0
  172. data/public/lookbook-assets/lookbook.js +1427 -0
  173. data/public/lookbook-assets/lookbook.js.map +1 -0
  174. metadata +85 -77
  175. data/app/components/lookbook/embed/component.js +0 -39
  176. data/app/helpers/lookbook/component_helper.rb +0 -84
  177. data/app/helpers/lookbook/output_helper.rb +0 -19
  178. data/app/helpers/lookbook/page_helper.rb +0 -34
  179. data/app/views/layouts/lookbook/inspector.html.erb +0 -7
  180. data/app/views/layouts/lookbook/page.html.erb +0 -53
  181. data/app/views/layouts/lookbook/standalone.html.erb +0 -5
  182. data/app/views/lookbook/preview.html.erb +0 -14
  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
  196. /data/app/assets/lookbook/js/{embed.js → iframe.js} +0 -0
  197. /data/{app/channels/lookbook → lib/lookbook/cable}/connection.rb +0 -0
  198. /data/{app/channels/lookbook → lib/lookbook/cable}/reload_channel.rb +0 -0
@@ -1,51 +1,6 @@
1
- <% if @target.present? %>
2
- <%= render_component_tag class: "not-prose border-b border-lookbook-divider rounded-sm overflow-hidden", "@navigation:start.window": "cleanup" do %>
3
-
4
- <%= lookbook_render :toolbar, class: "border border-b-0 border-lookbook-divider" do |toolbar| %>
5
- <% toolbar.with_section padded: true do %>
6
- <h3>
7
- <%= @target.preview.label %> (<%= @target.label %>)
8
- </h3>
9
- <% end %>
10
- <% toolbar.with_section align: :right, divide: :left do %>
11
- <%= lookbook_render :button_group do |group| %>
12
- <% group.with_button icon: :eye,
13
- href: lookbook_inspect_path(@target.path, @params),
14
- tooltip: "View in Inspector" %>
15
- <% group.with_button icon: :external_link,
16
- href: lookbook_preview_path(@target.path, @params),
17
- tooltip: "Open in new window",
18
- target: "_blank" %>
19
- <% end %>
20
- <% end %>
21
- <% end %>
22
-
23
- <div
24
- x-show="tab === 'preview'"
25
- @viewport:loaded="loadResizer"
26
- @dom:update-complete="loadResizer"
27
- @viewport:resize-progress="resizeIframe"
28
- @viewport:resize-complete="resizeIframe"
29
- @tabs:change.window="resizeIframe">
30
- <%= lookbook_render :viewport,
31
- src: lookbook_preview_path(@target.path, @params.merge(lookbook_embed: true)),
32
- alpine_data: "store",
33
- resize_height: false,
34
- max_height: @max_height,
35
- class: "mb-[-2px]" %>
36
- </div>
37
-
38
- <% end %>
39
- <% else %>
40
- <%= render_component_tag class: "bg-white flex flex-col items-center justify-center border-2 border-dashed border-gray-200 p-6 rounded-md not-prose" do %>
41
- <div class="px-4 text-center">
42
- <%= icon :alert_triangle, size: 6, class: "text-red-300 mx-auto" %>
43
- <div class="mt-2 max-w-xs">
44
- <h5 class="text-base">Preview not found</h5>
45
- <p class="mt-1 opacity-50 text-sm">
46
- The preview may have been renamed or deleted
47
- </p>
48
- </div>
49
- </div>
50
- <% end %>
51
- <% end %>
1
+ <lookbook-embed
2
+ app="<%= lookbook_home_url %>"
3
+ preview="<%= preview_class %>"
4
+ scenario="<%= scenario.name %>"
5
+ <%= params_attrs_str %> panels="<%= panels.join(",") %>"
6
+ actions="<%= actions.join(",") %>"></lookbook-embed>
@@ -1,30 +1,31 @@
1
1
  module Lookbook
2
2
  class Embed::Component < Lookbook::BaseComponent
3
- def initialize(id:, example:, params: {}, opts: {}, max_height: nil, **html_attrs)
4
- @id = id
5
- @target = example
6
- @params = params
7
- @opts = opts
8
- @max_height = max_height
3
+ ACTIONS = [:inspect, :open]
4
+
5
+ attr_reader :preview, :scenario, :params, :options
6
+
7
+ def initialize(scenario:, params: {}, options: {}, **html_attrs)
8
+ @scenario = scenario
9
+ @preview = scenario.preview
10
+ @params = params.to_h
11
+ @options = options.to_h
9
12
  super(**html_attrs)
10
13
  end
11
14
 
12
- protected
13
-
14
- def lookbook_inspect_path(*args)
15
- Lookbook::Engine.routes.url_helpers.lookbook_inspect_path(*args)
15
+ def preview_class
16
+ preview.preview_class.name
16
17
  end
17
18
 
18
- def lookbook_preview_path(*args)
19
- Lookbook::Engine.routes.url_helpers.lookbook_preview_path(*args)
19
+ def panels
20
+ options.fetch(:panels, []).map(&:to_s)
20
21
  end
21
22
 
22
- def alpine_data
23
- [alpine_encode(@id), "$store.pages.embeds"].join(",")
23
+ def actions
24
+ options.fetch(:actions, ACTIONS).map(&:to_s)
24
25
  end
25
26
 
26
- def alpine_component
27
- "embedComponent"
27
+ def params_attrs_str
28
+ params.map { |key, value| "param-#{key}=\"#{value}\"" }.join(" ").strip.html_safe
28
29
  end
29
30
  end
30
31
  end
@@ -0,0 +1,102 @@
1
+ <%= render_component_tag id: id,
2
+ class: "border-b border-lookbook-divider rounded-md overflow-hidden",
3
+ cloak: true do %>
4
+
5
+ <%= lookbook_render :toolbar,
6
+ class: "border border-b-0 border-lookbook-divider",
7
+ style: "border-top-left-radius: 6px; border-top-right-radius: 6px;" do |toolbar| %>
8
+ <% toolbar.with_section padded: true do %>
9
+ <h3 class="flex items-center space-x-1">
10
+ <strong class="text-lookbook-embed-title"><%= target.preview.label %></strong>
11
+ <% if scenarios.many? %>
12
+ <%= select_tag("target", options_for_select(scenario_select_options, helpers.lookbook_embed_path(target.path)), "x-model": "targetPath", class: "!ml-2 compact") %>
13
+ <% else %>
14
+ <span>(<%= target.label %>) </span>
15
+ <% end %>
16
+ </h3>
17
+ <% end %>
18
+
19
+ <% toolbar.with_section align: :right, class: "flex-none" do %>
20
+ <% if display_option_controls? && dynamic_display_options.any? %>
21
+ <%= lookbook_render "display_options/editor" do |editor| %>
22
+ <% dynamic_display_options.each do |key, opts| %>
23
+ <% editor.with_field name: key, opts: opts, value: static_display_options[key] %>
24
+ <% end %>
25
+ <% end %>
26
+ <% end %>
27
+ <% end %>
28
+
29
+ <% if actions.any? %>
30
+ <% toolbar.with_section divide: :left do %>
31
+ <%= lookbook_render :button_group do |group| %>
32
+ <% if display_action?(:inspect) %>
33
+ <% group.with_button icon: :eye,
34
+ href: helpers.lookbook_inspect_url(target.path, params),
35
+ tooltip: "View in Inspector",
36
+ target: "_top" %>
37
+ <% end %>
38
+ <% if display_action?(:open) %>
39
+ <% group.with_button icon: :external_link,
40
+ href: helpers.lookbook_preview_url(target.path, params),
41
+ tooltip: "Open in new window",
42
+ target: "_blank" %>
43
+ <% end %>
44
+ <% end %>
45
+ <% end %>
46
+ <% end %>
47
+ <% end %>
48
+
49
+ <section
50
+ x-ref="viewport"
51
+ <% unless drawer? %>
52
+ style="border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; overflow: hidden;"
53
+ <% end %>>
54
+ <div
55
+ @viewport:resize-progress="resizeIframe"
56
+ @viewport:resize-complete="resizeIframe"
57
+ x-ref="viewportWrapper">
58
+ <%= lookbook_render :viewport,
59
+ iframe_id: "#{id}-viewport",
60
+ src: helpers.lookbook_preview_path(target.path, params.merge(lookbook_embed: true)),
61
+ alpine_data: "store",
62
+ resize_height: false,
63
+ class: "mb-[-2px] transition-[height] duration-150",
64
+ ":style": "`height: ${viewportCssHeight}`"
65
+ %>
66
+ </div>
67
+ </section>
68
+
69
+ <% if drawer? %>
70
+ <section
71
+ class="relative top-[-1px] border border-b-0 border-lookbook-divider overflow-hidden"
72
+ style="border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;"
73
+ x-cloak>
74
+ <%= lookbook_render :toolbar, id: "#{id}-drawer-toolbar" do |toolbar| %>
75
+ <% toolbar.with_section do %>
76
+ <%= lookbook_render :tabs, alpine_data: "store", id: "#{id}-drawer-tabs" do |tabs| %>
77
+ <%= panels.each do |panel| %>
78
+ <% tabs.with_tab name: panel.name,
79
+ label: panel.label,
80
+ hotkey: panel.hotkey,
81
+ disabled: panel.disabled %>
82
+ <% end %>
83
+ <% end %>
84
+ <% end %>
85
+ <% end %>
86
+
87
+ <div class="bg-lookbook-drawer-bg">
88
+ <%= lookbook_render :tab_panels, alpine_data: "store", id: "{id}-drawer-panels" do |tabs| %>
89
+ <% panels.each do |panel| %>
90
+ <% tabs.with_panel name: panel.name do %>
91
+ <%= lookbook_render :inspector_panel, name: panel.name do %>
92
+ <%= render panel.partial, **data, panel: panel, **panel.locals %>
93
+ <% end %>
94
+ <% end %>
95
+ <% end %>
96
+ <% end %>
97
+ </div>
98
+ </section>
99
+ <% end %>
100
+ <% end %>
101
+
102
+
@@ -0,0 +1,46 @@
1
+ import "iframe-resizer/js/iframeResizer";
2
+
3
+ export default function embedInspectorComponent(id, embedStore) {
4
+ if (!embedStore[id]) {
5
+ embedStore[id] = { width: "100%", height: "100%" };
6
+ }
7
+
8
+ return {
9
+ iframe: null,
10
+
11
+ viewportHeight: 0,
12
+
13
+ targetPath: window.location.pathname,
14
+
15
+ get viewportCssHeight() {
16
+ return this.viewportHeight ? `${this.viewportHeight}px` : "100%";
17
+ },
18
+
19
+ get store() {
20
+ return embedStore[id];
21
+ },
22
+
23
+ init() {
24
+ const onResized = this.onResized.bind(this);
25
+
26
+ this.iframe = this.$el.querySelector("iframe");
27
+ window.iFrameResize({ onResized, checkOrigin: false }, this.iframe);
28
+
29
+ this.$watch("targetPath", (value) => this.switchTarget(value));
30
+ },
31
+
32
+ switchTarget(newTargetPath) {
33
+ this.navigateTo(`${newTargetPath}${window.location.search}`);
34
+ },
35
+
36
+ onResized({ height }) {
37
+ if (height) {
38
+ this.viewportHeight = height;
39
+ }
40
+ },
41
+
42
+ resizeIframe() {
43
+ this.iframe.iFrameResizer.resize();
44
+ },
45
+ };
46
+ }
@@ -0,0 +1,64 @@
1
+ module Lookbook
2
+ class Embed::Inspector::Component < Lookbook::BaseComponent
3
+ attr_reader :target, :context, :scenarios, :panels, :options, :actions
4
+
5
+ def initialize(target:, context: nil, options: nil, scenarios: nil, panels: nil, actions: nil, **html_attrs)
6
+ @target = target
7
+ @context = context.to_h
8
+ @options = options.to_h
9
+ @panels = Array(panels)
10
+ @actions = Array(actions).map(&:to_sym)
11
+ @scenarios = Array(scenarios)
12
+ super(**html_attrs)
13
+ end
14
+
15
+ def id
16
+ Utils.id(
17
+ "embed-inspector",
18
+ "#{scenarios.map(&:name).join}#{options.to_json}#{actions.to_json}#{panels.to_json}".hash
19
+ )
20
+ end
21
+
22
+ def data
23
+ context.fetch(:data, Store.new)
24
+ end
25
+
26
+ def params
27
+ context.fetch(:params, {}).to_h
28
+ end
29
+
30
+ def dynamic_display_options
31
+ context.fetch(:dynamic_display_options, {}).to_h
32
+ end
33
+
34
+ def static_display_options
35
+ context.fetch(:static_display_options, {}).to_h
36
+ end
37
+
38
+ def display_action?(name)
39
+ actions.include?(name)
40
+ end
41
+
42
+ def scenario_select_options
43
+ scenarios.map { |scenario| [scenario.label, helpers.lookbook_embed_path(scenario.path)] }
44
+ end
45
+
46
+ def display_option_controls?
47
+ options.fetch(:display_option_controls, true)
48
+ end
49
+
50
+ def drawer?
51
+ panels.any?
52
+ end
53
+
54
+ protected
55
+
56
+ def alpine_data
57
+ [alpine_encode(id), "$store.pages.embeds"].join(",")
58
+ end
59
+
60
+ def alpine_component
61
+ "embedInspectorComponent"
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,12 @@
1
+ @layer components {
2
+ [data-component="embed-code-dropdown"] {
3
+ & [data-component="code"] {
4
+ @apply p-0;
5
+ }
6
+
7
+ & pre.code.highlight {
8
+ @apply overflow-hidden whitespace-normal p-0;
9
+ font-size: 11px;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,19 @@
1
+ <%= render_component_tag class:"p-3 w-[320px]" do %>
2
+ <h4 class="text-[11px] uppercase tracking-wider mb-2 font-bold">Preview embed code</h4>
3
+
4
+ <p class="text-xs text-gray-600 mb-3">This code can be used to embed this preview in Lookbook pages or on external sites.</p>
5
+
6
+ <div class="border-t border-lookbook-dropdown-divider pt-3 pb-3">
7
+ <%= code :html do %><%= embed_code %><% end %>
8
+ </div>
9
+
10
+ <%= lookbook_render :text_button, "@click.stop.prevent": "copyEmbedCode", ":disabled": "copied" do |button| %>
11
+ <% button.with_icon name: :copy, size: 3, "x-show": "!copied", "x-cloak": true %>
12
+ <% button.with_icon name: :check, size: 3, "x-show": "copied", "x-cloak": true %>
13
+ <span x-text="copied ? 'Copied!' : 'Copy embed code'"></span>
14
+ <% end %>
15
+
16
+ <div class="hidden" x-ref="copyTarget">
17
+ <%= escape_once embed_code %>
18
+ </div>
19
+ <% end %>
@@ -0,0 +1,26 @@
1
+ import { decodeEntities } from "@helpers/string";
2
+
3
+ export default function embedCodeDropdownComponent() {
4
+ let copyTimeout = null;
5
+
6
+ return {
7
+ copied: false,
8
+
9
+ copyEmbedCode() {
10
+ this.$nextTick(async () => {
11
+ const content = decodeEntities(this.$refs.copyTarget.innerHTML.trim());
12
+
13
+ await window.navigator.clipboard.writeText(content);
14
+ this.copied = true;
15
+
16
+ if (copyTimeout) {
17
+ clearTimeout(copyTimeout);
18
+ }
19
+
20
+ copyTimeout = setTimeout(() => {
21
+ this.copied = false;
22
+ }, 2000);
23
+ });
24
+ },
25
+ };
26
+ }
@@ -0,0 +1,41 @@
1
+ module Lookbook
2
+ class EmbedCodeDropdown::Component < Lookbook::BaseComponent
3
+ attr_reader :preview, :pages, :params, :target
4
+
5
+ def initialize(preview:, target:, pages:, params:, **html_attrs)
6
+ @preview = preview
7
+ @target = target
8
+ @pages = pages
9
+ @params = params.deep_symbolize_keys
10
+ super(**html_attrs)
11
+ end
12
+
13
+ def app_path
14
+ helpers.lookbook_home_url
15
+ end
16
+
17
+ def preview_name
18
+ preview.preview_class_name
19
+ end
20
+
21
+ def external_embed_params
22
+ permitted = params.select { |key, val| key.to_s != "_display" }
23
+ permitted.transform_keys! { |key| "param-#{key}" }
24
+ end
25
+
26
+ def embed_code
27
+ embed_tag = content_tag("lookbook-embed",
28
+ app: app_path,
29
+ preview: preview_name,
30
+ scenario: target.name,
31
+ **external_embed_params) { "" }
32
+ escape_once embed_tag
33
+ end
34
+
35
+ private
36
+
37
+ def alpine_component
38
+ "embedCodeDropdownComponent"
39
+ end
40
+ end
41
+ end
@@ -1,6 +1,6 @@
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
- <% toolbar.with_section padded: true do %>
3
+ <% toolbar.with_section class: "mt-[-2px]", padded: true do %>
4
4
  <% if branding.present? %>
5
5
  <a
6
6
  <% if landing_path %>href="<%= landing_path %>"<% end %>
@@ -10,8 +10,7 @@
10
10
  <% end %>
11
11
  <% end %>
12
12
 
13
- <% toolbar.with_section padded: false, align: :right, class: "flex items-center" do %>
14
-
13
+ <% toolbar.with_section padded: false, align: :right, class: "flex items-center -mt-px" do %>
15
14
  <div x-show="loading" x-cloak>
16
15
  <svg class="animate-spin h-3.5 w-3.5 text-lookbook-header-text opacity-60" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
17
16
  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
@@ -21,14 +20,16 @@
21
20
 
22
21
  <%= lookbook_render :button_group do |group| %>
23
22
  <% if @debug_menu %>
24
- <% group.with_button icon: :help_circle, class: "opacity-50 hover:opacity-100 transition !text-lookbook-header-text", "x-show": "!loading" do |button| %>
23
+ <% group.with_button id: "debug-menu-button",
24
+ icon: :help_circle,
25
+ class: "opacity-50 hover:opacity-100 transition !text-lookbook-header-text", "x-show": "!loading" do |button| %>
25
26
  <% menu = lookbook_render :debug_menu,
26
27
  version: Lookbook::VERSION,
27
28
  docs_url: "https://lookbook.build/guide",
28
29
  repo_url: "https://github.com/ViewComponent/lookbook" do %>
29
- <%= helpers.pretty_json(Lookbook.debug_data) %>
30
+ <%= debug_data %>
30
31
  <% end %>
31
- <% button.with_dropdown({}).with_content(menu) %>
32
+ <% button.with_dropdown.with_content(menu) %>
32
33
  <% end %>
33
34
  <% end %>
34
35
 
@@ -8,7 +8,11 @@ module Lookbook
8
8
  end
9
9
 
10
10
  def landing_path
11
- helpers.landing_path if defined? helpers.landing_path
11
+ helpers.lookbook_landing_path if defined? helpers.lookbook_landing_path
12
+ end
13
+
14
+ def debug_data
15
+ JSON.pretty_generate(Lookbook.debug_data)
12
16
  end
13
17
  end
14
18
  end
@@ -1,5 +1,5 @@
1
1
  <%= render_component_tag :i, style: "height: #{size_rems}; width: #{size_rems}; #{@html_attrs[:style]}" do %>
2
2
  <svg>
3
- <use :href="`/lookbook-assets/feather-sprite.svg#${iconName}`" x-cloak />
3
+ <use :href="`/lookbook-assets/img/lucide-sprite.svg#${iconName}`" x-cloak />
4
4
  </svg>
5
5
  <% end %>
@@ -0,0 +1,20 @@
1
+ <%= render_component_tag tag_name,
2
+ id: id,
3
+ href: href,
4
+ class: [
5
+ "block text-lookbook-icon-button-stroke focus:outline-none focus-visible:outline-none #{padding}",
6
+ {
7
+ "hover:text-lookbook-icon-button-stroke-hover": !disabled,
8
+ "cursor-[not-allowed] opacity-50": disabled
9
+ }
10
+ ],
11
+ disabled: disabled,
12
+ aria: { label: tooltip } do %>
13
+ <span x-ref="icon">
14
+ <%= icons.present? ? safe_join(icons) : (lookbook_render(:icon, name: icon, size: icon_size, ":class": "{'animate-spin': _spinning}") if icon) %>
15
+ </span>
16
+ <% if tooltip %>
17
+ <label class="hidden" x-ref="tooltip"><%= tooltip %></label>
18
+ <% end %>
19
+ <%= content %>
20
+ <% end %>
@@ -0,0 +1,46 @@
1
+ module Lookbook
2
+ class IconButton::Component < Lookbook::BaseComponent
3
+ renders_many :icons, Icon::Component
4
+
5
+ ICON_SIZES = {
6
+ xs: 3,
7
+ sm: 3.5,
8
+ md: 4,
9
+ lg: 6
10
+ }
11
+
12
+ attr_reader :icon, :tooltip, :disabled, :size, :href
13
+
14
+ def initialize(id: nil, icon: nil, tooltip: nil, disabled: false, size: :md, href: nil, **html_attrs)
15
+ @id = id
16
+ @icon = icon
17
+ @tooltip = tooltip
18
+ @disabled = disabled
19
+ @size = size
20
+ @href = href
21
+ super(**html_attrs)
22
+ end
23
+
24
+ def id
25
+ @id ||= Utils.temp_id(prefix: "button")
26
+ end
27
+
28
+ def icon_size
29
+ ICON_SIZES[size]
30
+ end
31
+
32
+ def padding
33
+ [:xs, :sm].include?(size) ? "p-1" : "p-2"
34
+ end
35
+
36
+ def tag_name
37
+ href.present? ? :a : :button
38
+ end
39
+
40
+ protected
41
+
42
+ def alpine_component
43
+ "buttonComponent"
44
+ end
45
+ end
46
+ end
@@ -25,5 +25,4 @@
25
25
  </div>
26
26
  <% end %>
27
27
  </div>
28
-
29
28
  <% end %>
@@ -3,7 +3,7 @@ module Lookbook
3
3
  ICONS = {
4
4
  page: :file,
5
5
  preview: :layers,
6
- example: :eye,
6
+ scenario: :eye,
7
7
  group: :eye
8
8
  }.freeze
9
9
 
@@ -24,7 +24,7 @@ module Lookbook
24
24
  end
25
25
 
26
26
  def type
27
- collapsed? ? :example : node.type
27
+ collapsed? ? :scenario : node.type
28
28
  end
29
29
 
30
30
  def collapsed?
@@ -1,6 +1,6 @@
1
1
  module Lookbook
2
2
  class Nav::Item::Component < Lookbook::BaseComponent
3
- delegate :label, :depth, to: :node
3
+ delegate :label, :depth, :priority, to: :node
4
4
 
5
5
  attr_reader :node, :nav_id
6
6
 
@@ -2,13 +2,13 @@
2
2
  <div class="flex w-full border-b border-lookbook-divider mb-6">
3
3
  <%= lookbook_render :tabs, theme: :page do |t| %>
4
4
  <% @tabs.each do |props| %>
5
- <%= t.with_tab **props %>
5
+ <%= t.tab **props %>
6
6
  <% end %>
7
7
  <% end %>
8
8
  </div>
9
9
  <%= lookbook_render :tab_panels do |t| %>
10
10
  <% @tabs.each do |props| %>
11
- <% t.with_panel name: props[:name] do %>
11
+ <% t.panel name: props[:name] do %>
12
12
  <%= lookbook_render :prose, markdown: props[:markdown], class: "max-w-none flex-none" do %>
13
13
  <%== props[:tab_content] %>
14
14
  <% end %>
@@ -23,6 +23,7 @@ module Lookbook
23
23
  end
24
24
 
25
25
  def self.add_styles(input, styles)
26
+ @@input_styles = {} unless defined?(@@input_styles)
26
27
  @@input_styles[input] ||= styles
27
28
  end
28
29
 
@@ -1,7 +1,5 @@
1
1
  module Lookbook
2
2
  class Prose::Component < Lookbook::BaseComponent
3
- include Lookbook::OutputHelper
4
-
5
3
  def initialize(size: :md, markdown: true, **html_attrs)
6
4
  @size = size
7
5
  @markdown = markdown
@@ -9,7 +7,7 @@ module Lookbook
9
7
  end
10
8
 
11
9
  def rendered_content
12
- @markdown ? markdown(content.strip_heredoc) : helpers.raw(content)
10
+ @markdown ? MarkdownRenderer.call(content.strip_heredoc) : helpers.raw(content)
13
11
  end
14
12
 
15
13
  def size_class
@@ -9,8 +9,8 @@
9
9
  <%= safe_join(tabs) %>
10
10
  </div>
11
11
  <div x-ref="dropdownTrigger" class="absolute" x-show="hasHiddenTabs" :style="{left: `${triggerLeft}px`}">
12
- <%= lookbook_render :button, icon: :chevrons_right, "x-show": "visibleTabsCount > 0" %>
13
- <%= lookbook_render :button, icon: :menu, class: "-ml-3", "x-show": "visibleTabsCount === 0" %>
12
+ <%= lookbook_render :icon_button, icon: :chevrons_right, "x-show": "visibleTabsCount > 0" %>
13
+ <%= lookbook_render :icon_button, icon: :menu, class: "-ml-3", "x-show": "visibleTabsCount === 0" %>
14
14
  </div>
15
15
  <div class="hidden">
16
16
  <div x-ref="tabsDropdown" x-cloak>
@@ -49,7 +49,7 @@ export default function tabsComponent(store) {
49
49
  const initialTab = initial
50
50
  ? this.tabs.find((t) => this._getRef(t) === initial)
51
51
  : this.tabs[0];
52
- this.selectTab(initialTab, true);
52
+ this.selectTab(initialTab || this.tabs[0], true);
53
53
 
54
54
  this.parentObserver = observeSize(
55
55
  this.$root.parentElement,
@@ -1,6 +1,7 @@
1
1
  module Lookbook
2
2
  class TagComponent < ViewComponent::Base
3
- include Lookbook::ComponentHelper
3
+ include Lookbook::UiElementsHelper
4
+ include Lookbook::ClassNamesHelper if Engine.runtime_context.rails_older_than?("6.1.0")
4
5
 
5
6
  def initialize(tag: :div, name: nil, cloak: false, **html_attrs)
6
7
  @tag = tag