lookbook 1.1.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/lookbook/js/helpers/string.js +23 -1
  3. data/app/assets/lookbook/js/lookbook.js +0 -1
  4. data/app/components/lookbook/button/component.html.erb +2 -1
  5. data/app/components/lookbook/button/component.js +9 -0
  6. data/app/components/lookbook/display_options/editor/component.html.erb +13 -0
  7. data/app/components/lookbook/display_options/editor/component.rb +7 -0
  8. data/app/components/lookbook/display_options/field/component.css +33 -0
  9. data/app/components/lookbook/display_options/field/component.html.erb +8 -0
  10. data/app/components/lookbook/display_options/field/component.js +30 -0
  11. data/app/components/lookbook/display_options/field/component.rb +28 -0
  12. data/app/components/lookbook/inspector_panel/component.html.erb +1 -1
  13. data/app/components/lookbook/inspector_panel/component.rb +10 -11
  14. data/app/components/lookbook/params/editor/component.rb +6 -3
  15. data/app/components/lookbook/params/field/component.rb +1 -5
  16. data/app/components/lookbook/tab_panels/panel/component.html.erb +1 -1
  17. data/app/components/lookbook/tab_panels/panel/component.rb +1 -2
  18. data/app/components/lookbook/tabs/dropdown_tab/component.html.erb +1 -0
  19. data/app/components/lookbook/tabs/tab/component.html.erb +1 -0
  20. data/app/components/lookbook/viewport/component.html.erb +1 -1
  21. data/app/components/lookbook/viewport/component.rb +2 -1
  22. data/app/controllers/lookbook/previews_controller.rb +40 -29
  23. data/app/helpers/lookbook/preview_helper.rb +1 -1
  24. data/app/views/lookbook/previews/panels/_params.html.erb +1 -1
  25. data/app/views/lookbook/previews/panels/_preview.html.erb +9 -6
  26. data/app/views/lookbook/previews/show.html.erb +29 -11
  27. data/config/app.yml +36 -0
  28. data/config/hooks.yml +4 -0
  29. data/config/inputs.yml +48 -0
  30. data/config/panels.yml +30 -0
  31. data/config/routes.rb +1 -1
  32. data/config/tags.yml +29 -0
  33. data/lib/lookbook/engine.rb +40 -20
  34. data/lib/lookbook/markdown.rb +1 -11
  35. data/lib/lookbook/page.rb +1 -1
  36. data/lib/lookbook/params.rb +0 -7
  37. data/lib/lookbook/parser.rb +3 -10
  38. data/lib/lookbook/preview.rb +7 -3
  39. data/lib/lookbook/preview_example.rb +7 -3
  40. data/lib/lookbook/preview_group.rb +2 -2
  41. data/lib/lookbook/services/config_loader.rb +20 -0
  42. data/lib/lookbook/services/search_param_builder.rb +13 -0
  43. data/lib/lookbook/services/search_param_parser.rb +15 -0
  44. data/lib/lookbook/services/tags/key_value_tag_parser.rb +24 -0
  45. data/lib/lookbook/source_inspector.rb +10 -16
  46. data/lib/lookbook/stores/config_store.rb +80 -0
  47. data/lib/lookbook/stores/hook_store.rb +28 -0
  48. data/lib/lookbook/stores/input_store.rb +58 -0
  49. data/lib/lookbook/stores/panel_store.rb +141 -0
  50. data/lib/lookbook/stores/tag_store.rb +46 -0
  51. data/lib/lookbook/support/errors/config_error.rb +7 -0
  52. data/lib/lookbook/support/errors/lookbook_error.rb +21 -0
  53. data/lib/lookbook/support/errors/parser_error.rb +7 -0
  54. data/lib/lookbook/support/service.rb +7 -0
  55. data/lib/lookbook/support/store.rb +77 -0
  56. data/lib/lookbook/support/utils/attribute_utils.rb +9 -0
  57. data/lib/lookbook/support/utils/path_utils.rb +19 -0
  58. data/lib/lookbook/tags.rb +5 -14
  59. data/lib/lookbook/version.rb +1 -1
  60. data/lib/lookbook.rb +43 -12
  61. data/public/lookbook-assets/css/lookbook.css +33 -0
  62. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  63. data/public/lookbook-assets/js/lookbook.js +145 -4
  64. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  65. metadata +29 -6
  66. data/lib/lookbook/config.rb +0 -278
  67. data/lib/lookbook/hooks.rb +0 -21
  68. data/lib/lookbook/panels.rb +0 -25
  69. data/lib/lookbook/store.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4a0e938511079a03ed87c74edf15d65798789ed6f149cfe25d528a4a9a8b329
4
- data.tar.gz: 4d47a5e24f65b5d04beb904cb4c52589547999c20c195c2eed48c9394e3a9a72
3
+ metadata.gz: 746247239c9d22b8537a0327dfa40e3d4a2b687a9d48e0a4b61819cba7766bec
4
+ data.tar.gz: c288e6e752520bb2b4b90b5e1f682cd68c99961939496b5d698abf2604962efc
5
5
  SHA512:
6
- metadata.gz: ce7cd4e60c085c02a631694278b2d64a905aaf8f4d7e636f0fb683842f7efac46c9fe88466a75fc6b2b085bbbb87da9df152a6d81d38cb0a49328d0083bec9d2
7
- data.tar.gz: 9c8b2e22243e48d56ae592d2bca443ae17bb0b47e08eece6d9620425f2d36e3397e93a61192ca6a921dcfd4f1fa046f25b28f35dcfd0ff9ac04366a025e47eb1
6
+ metadata.gz: 6b0aae039cf5d29f2d9f93aca8f2fd62996ecbce1ad9cc9ab8c8b19e82343f71a3dc6694406182e5ebd41b0a6ad97c160a7c156e51463cda51f522b186a25a1d
7
+ data.tar.gz: cf44c51bfa10e5eabc5dc6c88931d3e1676e5b72599e00304c83aca343d6a080ef31afa0044e39383d1c4b4ccc179260832afb5951d5427858767b09ff749a4a
@@ -8,4 +8,26 @@ function prefixString(string, prefix = null) {
8
8
  return prefix ? `${prefix}-${string}` : string;
9
9
  }
10
10
 
11
- export { prefixString, decodeEntities };
11
+ function parseSearchParamValue(value) {
12
+ const params = {};
13
+ value.split("|").forEach((pair_str) => {
14
+ const [key, value] = pair_str.split(":").map((part) => part.trim());
15
+ params[key] = value;
16
+ });
17
+ return params;
18
+ }
19
+
20
+ function buildSearchParamValue(data) {
21
+ const pairs = [];
22
+ for (const [key, value] of Object.entries(data)) {
23
+ pairs.push(`${key}:${value}`);
24
+ }
25
+ return pairs.join("|");
26
+ }
27
+
28
+ export {
29
+ prefixString,
30
+ decodeEntities,
31
+ parseSearchParamValue,
32
+ buildSearchParamValue,
33
+ };
@@ -50,7 +50,6 @@ Alpine.data("app", app);
50
50
  [components, subComponents, jsComponents].forEach((scripts) => {
51
51
  const components = getComponents(scripts);
52
52
  Object.keys(components).forEach((name) => {
53
- console.log(name);
54
53
  Alpine.data(`${name}Component`, components[name]);
55
54
  });
56
55
  });
@@ -8,7 +8,8 @@
8
8
  }
9
9
  ],
10
10
  disabled: @disabled,
11
- "@keydown.esc.stop": "hideDropdown" do %>
11
+ "@keydown.esc.stop": "hideDropdown",
12
+ "@navigation:complete.window": "updateDropdown" do %>
12
13
  <span x-ref="icon">
13
14
  <%= icon || lookbook_render(:icon, name: @icon, size: icon_size, ":class": "{'animate-spin': _spinning}") %>
14
15
  </span>
@@ -38,6 +38,15 @@ export default function buttonComponent() {
38
38
  }
39
39
  },
40
40
 
41
+ updateDropdown() {
42
+ if (dropdown) {
43
+ dropdown.hide();
44
+ this.$nextTick(() => {
45
+ dropdown.setContent(this.$refs.dropdown.innerHTML);
46
+ });
47
+ }
48
+ },
49
+
41
50
  startSpin() {
42
51
  this._spinning = true;
43
52
  },
@@ -0,0 +1,13 @@
1
+ <%= render_component_tag class: "px-2" do %>
2
+ <% if fields.many? %>
3
+ <%= lookbook_render :button, icon: :settings, tooltip: "Display options" do |button| %>
4
+ <% button.dropdown do %>
5
+ <div class="p-3 space-y-3">
6
+ <%= safe_join(fields) %>
7
+ </div>
8
+ <% end %>
9
+ <% end %>
10
+ <% else %>
11
+ <%= safe_join(fields) %>
12
+ <% end %>
13
+ <% end %>
@@ -0,0 +1,7 @@
1
+ module Lookbook
2
+ module DisplayOptions
3
+ class Editor::Component < Lookbook::BaseComponent
4
+ renders_many :fields, Lookbook::DisplayOptions::Field::Component
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ @layer components {
2
+ [data-component="display-options-field"] {
3
+ [type="text"],
4
+ [type="email"],
5
+ [type="url"],
6
+ [type="password"],
7
+ [type="number"],
8
+ [type="date"],
9
+ [type="datetime-local"],
10
+ [type="month"],
11
+ [type="search"],
12
+ [type="tel"],
13
+ [type="time"],
14
+ [type="week"],
15
+ textarea,
16
+ select {
17
+ padding: 0.26rem 0.6rem;
18
+ font-size: 0.8rem;
19
+ line-height: 1.1rem;
20
+ }
21
+
22
+ label {
23
+ @apply text-[0.82rem] text-lookbook-input-text cursor-pointer;
24
+ }
25
+
26
+ select {
27
+ border-radius: 0.375rem;
28
+ padding-right: 1.5rem;
29
+ background-size: 1.2em 1.2em;
30
+ background-position: right 0.4rem center;
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,8 @@
1
+ <%= render_component_tag do %>
2
+ <div class="flex items-center space-x-1.5">
3
+ <label for="<%= name %>">
4
+ <%= name.to_s.titleize %>:
5
+ </label>
6
+ <%= select_tag(name, options_for_select(choices, value), "x-model": "value") %>
7
+ </div>
8
+ <% end %>
@@ -0,0 +1,30 @@
1
+ import Cookies from "js-cookie";
2
+ import {
3
+ parseSearchParamValue,
4
+ buildSearchParamValue,
5
+ } from "~/app/assets/lookbook/js/helpers/string";
6
+
7
+ export default function displayOptionsFieldComponent({ name, value }) {
8
+ return {
9
+ name,
10
+ value,
11
+
12
+ init() {
13
+ this.$watch("value", () => this.update());
14
+ },
15
+
16
+ update() {
17
+ Cookies.set(`lookbook-display-${name}`, this.value);
18
+
19
+ const searchParams = new URLSearchParams(window.location.search);
20
+ const display = searchParams.get("_display");
21
+
22
+ const displayParams = display ? parseSearchParamValue(display) : {};
23
+ displayParams[this.name] = this.value;
24
+ searchParams.set("_display", buildSearchParamValue(displayParams));
25
+
26
+ const path = location.href.replace(location.search, "");
27
+ this.navigateTo(`${path}?${searchParams.toString()}`);
28
+ },
29
+ };
30
+ }
@@ -0,0 +1,28 @@
1
+ module Lookbook
2
+ module DisplayOptions
3
+ class Field::Component < Lookbook::BaseComponent
4
+ attr_reader :name, :value
5
+
6
+ def initialize(name:, opts:, value:, **html_attrs)
7
+ @name = name
8
+ @opts = opts
9
+ @value = value
10
+ super(**html_attrs)
11
+ end
12
+
13
+ def choices
14
+ @opts.is_a?(Hash) ? @opts[:choices].to_a : @opts
15
+ end
16
+
17
+ protected
18
+
19
+ def alpine_data
20
+ "{name: '#{name}', value: '#{value}'}"
21
+ end
22
+
23
+ def alpine_component
24
+ "displayOptionsFieldComponent"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,4 @@
1
- <%= render_component_tag :div, class: "h-full" do %>
1
+ <%= render_component_tag :div, id: id, class: "h-full", "data-panel": @name do %>
2
2
  <%= panel_html %>
3
3
  <% end %>
4
4
 
@@ -2,22 +2,21 @@ require "css_parser"
2
2
 
3
3
  module Lookbook
4
4
  class InspectorPanel::Component < Lookbook::BaseComponent
5
- attr_reader :panel_styles, :panel_html, :id
5
+ attr_reader :panel_styles, :panel_html
6
6
 
7
- def initialize(id:, name:, **attrs)
8
- @id = id
7
+ def initialize(name:, **attrs)
9
8
  @name = name
10
- @system = attrs[:system] || false
11
- super(**attrs.except(:system))
9
+ super(**attrs)
10
+ end
11
+
12
+ def id
13
+ AttributeUtils.dom_id("panel", @name)
12
14
  end
13
15
 
14
16
  def before_render
15
- if @system == false
16
- tpl = TemplateParser.new(content)
17
- @panel_styles = tpl.styles.map { |s| "##{id} #{s}" }.join("\n")
18
- @panel_html = tpl.content
19
- end
20
- @panel_html ||= content
17
+ tpl = TemplateParser.new(content)
18
+ @panel_styles = tpl.styles.map { |s| "##{id} #{s}" }.join("\n")
19
+ @panel_html = tpl.content
21
20
  end
22
21
  end
23
22
  end
@@ -5,11 +5,14 @@ module Lookbook
5
5
  @field_count += 1
6
6
  @descriptions = true if description.present?
7
7
  input_config = @inputs[input.tr("-", "_").to_sym]
8
- Lookbook::Params::Field::Component.new(input: input, description: description, index: @field_count, config: input_config, **attrs)
8
+ Lookbook::Params::Field::Component.new(input: input,
9
+ description: description,
10
+ index: @field_count,
11
+ config: input_config, **attrs)
9
12
  end
10
13
 
11
- def initialize(inputs: {}, **html_attrs)
12
- @inputs = inputs
14
+ def initialize(inputs: nil, **html_attrs)
15
+ @inputs = inputs.to_h
13
16
  @field_count = -1
14
17
  @descriptions = false
15
18
  @@input_styles = {}
@@ -59,7 +59,7 @@ module Lookbook
59
59
  end
60
60
 
61
61
  def input_options
62
- config_options = @config.fetch(:input_options, {})
62
+ config_options = @config.fetch(:opts, {})
63
63
  opts = config_options.merge(@input_options).symbolize_keys
64
64
  opts[:id] = "param-#{@name}"
65
65
  opts
@@ -79,7 +79,6 @@ module Lookbook
79
79
 
80
80
  def render_input
81
81
  target = @config[:partial]
82
-
83
82
  if target
84
83
  render(target, **render_props)
85
84
  else
@@ -88,9 +87,6 @@ module Lookbook
88
87
  rescue ::ActionView::MissingTemplate => exception
89
88
  Lookbook.logger.error exception
90
89
  input_error "Param input partial '#{@config[:partial]}' could not be found."
91
- rescue => exception
92
- Lookbook.logger.error exception
93
- input_error exception.message
94
90
  end
95
91
 
96
92
  def alpine_component
@@ -1,6 +1,6 @@
1
1
  <%= render_component_tag :section,
2
- id: @id,
3
2
  "x-ref": @name,
3
+ "data-tab-panel": @name,
4
4
  cloak: true,
5
5
  class: "h-full",
6
6
  ":class": "{ hidden: !isActive($el) }" do %>
@@ -1,8 +1,7 @@
1
1
  module Lookbook
2
2
  class TabPanels::Panel::Component < Lookbook::BaseComponent
3
- def initialize(name:, id: nil, **html_attrs)
3
+ def initialize(name:, **html_attrs)
4
4
  @name = name
5
- @id = (id || "panel-#{name}").to_s
6
5
  super(**html_attrs)
7
6
  end
8
7
  end
@@ -1,5 +1,6 @@
1
1
  <%= render_component_tag :button,
2
2
  "x-ref": @name,
3
+ "data-tab": @name,
3
4
  class: [
4
5
  "whitespace-nowrap px-4 border-l-2 cursor-pointer block w-full text-left",
5
6
  {
@@ -1,6 +1,7 @@
1
1
  <%= render_component_tag :button,
2
2
  id: @id,
3
3
  "x-ref": @name,
4
+ "data-tab": @name,
4
5
  class: [
5
6
  "whitespace-nowrap cursor-pointer pt-2.5 pb-1.5 border-b-2",
6
7
  {
@@ -25,7 +25,7 @@
25
25
  <div
26
26
  class="grid bg-white relative -inset-px <%= "grid-cols-[1fr_17px]" if @resize_width %> <%= "grid-rows-[1fr_17px]" if @resize_height %>"
27
27
  style="width: calc(100% + 2px); height: calc(100% + 1px); <%= "max-height: #{@max_height}px;" if @max_height.present? %>">
28
- <iframe seamless
28
+ <iframe seamless<%= " id=#{@iframe_id}" if @iframe_id.present? %>
29
29
  x-ref="iframe"
30
30
  class="h-full w-full border border-lookbook-divider"
31
31
  :class="{ 'pointer-events-none': reflowing }"
@@ -1,10 +1,11 @@
1
1
  module Lookbook
2
2
  class Viewport::Component < Lookbook::BaseComponent
3
- def initialize(src:, resize_height: true, resize_width: true, max_height: nil, **html_attrs)
3
+ def initialize(src:, resize_height: true, resize_width: true, max_height: nil, iframe_id: nil, **html_attrs)
4
4
  @src = src
5
5
  @resize_height = resize_height
6
6
  @resize_width = resize_width
7
7
  @max_height = max_height
8
+ @iframe_id = iframe_id
8
9
  super(**html_attrs)
9
10
  end
10
11
 
@@ -10,6 +10,7 @@ module Lookbook
10
10
 
11
11
  before_action :lookup_entities, only: [:preview, :show]
12
12
  before_action :set_title
13
+ before_action :set_display_options
13
14
  before_action :set_params
14
15
 
15
16
  def preview
@@ -92,6 +93,38 @@ module Lookbook
92
93
  @title = @target.present? ? [@target&.label, @preview&.label].compact.join(" :: ") : "Not found"
93
94
  end
94
95
 
96
+ def set_display_options
97
+ @dynamic_display_options = []
98
+ @static_display_options = []
99
+
100
+ if @target.present?
101
+ opts = @target.display_options
102
+ @dynamic_display_options = opts.select { _2.is_a?(Array) || _2.is_a?(Hash) }
103
+ @static_display_options = opts.except(*@dynamic_display_options.keys)
104
+
105
+ if params[:_display]
106
+ display_params = SearchParamParser.call(params[:_display])
107
+ display_params.each do |name, value|
108
+ if @dynamic_display_options.key?(name)
109
+ cookies["lookbook-display-#{name}"] = value
110
+ end
111
+ end
112
+ end
113
+
114
+ @dynamic_display_options.each do |name, opts|
115
+ choices = opts.is_a?(Hash) ? opts[:choices].to_a : opts
116
+ @static_display_options[name] ||= cookies.fetch("lookbook-display-#{name}", choices.first)
117
+ end
118
+
119
+ unless params[:_display]
120
+ display_params = @dynamic_display_options.map do |name, opts|
121
+ [name, @static_display_options[name]]
122
+ end.to_h
123
+ request.query_parameters[:_display] = SearchParamBuilder.call(display_params)
124
+ end
125
+ end
126
+ end
127
+
95
128
  def set_params
96
129
  if @target
97
130
  # cast known params to type
@@ -103,7 +136,7 @@ module Lookbook
103
136
  # set display and data params
104
137
  preview_controller.params.merge!({
105
138
  lookbook: {
106
- display: @target.display_params,
139
+ display: @static_display_options,
107
140
  data: Lookbook.data
108
141
  }
109
142
  })
@@ -156,38 +189,16 @@ module Lookbook
156
189
  })
157
190
  end
158
191
 
159
- def panels
160
- return @panels if @panels.present?
161
- inspector_data_hash = inspector_data.to_h
162
- panel_counts = {}
163
-
164
- @panels = Lookbook.config.inspector_panels.map do |name, config|
165
- config_with_defaults = Lookbook.config.inspector_panel_defaults.merge(config)
166
- panel_counts[config_with_defaults[:pane].to_sym] ||= 0
167
- panel_counts[config_with_defaults[:pane].to_sym] += 1
168
-
169
- callable_data = {
170
- name: name.to_s,
171
- index_position: panel_counts[config_with_defaults[:pane].to_sym],
172
- **inspector_data_hash
173
- }
174
-
175
- resolved_config = config_with_defaults.transform_values do |value|
176
- value.instance_of?(Proc) ? value.call(Lookbook::Store.new(callable_data)) : value
177
- end
178
- resolved_config[:name] = name.to_s
179
- Store.new(resolved_config)
180
- end
181
-
182
- @panels = @panels.select(&:show).sort_by { |p| [p.position, p.label] }
183
- end
184
-
185
192
  def main_panels
186
- panels.select { |panel| panel.pane == :main }
193
+ Engine.panels.in_group(:main).map do |config|
194
+ PanelStore.resolve_config(config, inspector_data)
195
+ end
187
196
  end
188
197
 
189
198
  def drawer_panels
190
- panels.select { |panel| panel.pane == :drawer }
199
+ Engine.panels.in_group(:drawer).map do |config|
200
+ PanelStore.resolve_config(config, inspector_data)
201
+ end
191
202
  end
192
203
 
193
204
  def preview_controller
@@ -5,7 +5,7 @@ module Lookbook
5
5
  end
6
6
 
7
7
  def lookbook_data(key, fallback = nil)
8
- Lookbook.data.fetch(key, fallback)
8
+ Lookbook.data.fetch(key.to_sym, fallback)
9
9
  end
10
10
  end
11
11
  end
@@ -6,7 +6,7 @@
6
6
  </div>
7
7
  <% else %>
8
8
  <div class="h-full overflow-x-hidden">
9
- <%= lookbook_render "params/editor", inputs: Lookbook::Params.inputs do |editor| %>
9
+ <%= lookbook_render "params/editor", inputs: Lookbook::Engine.inputs do |editor| %>
10
10
  <% preview.params.each do |param| %>
11
11
  <% editor.field **param, value: params[param[:name]] %>
12
12
  <% end %>
@@ -1,6 +1,9 @@
1
- <%= lookbook_render :viewport,
2
- src: lookbook_preview_path(request.query_parameters.merge(lookbook_timestamp: Time.now)),
3
- alpine_data: "$store.inspector.main",
4
- class: "-inset-px relative",
5
- style: "width: calc(100% + 2px); height: calc(100% + 2px)"
6
- %>
1
+ <div class="overflow-hidden h-full w-full">
2
+ <%= lookbook_render :viewport,
3
+ iframe_id: "preview-iframe",
4
+ src: lookbook_preview_path(request.query_parameters.merge(lookbook_timestamp: Time.now)),
5
+ alpine_data: "$store.inspector.main",
6
+ class: "-inset-px relative",
7
+ style: "width: calc(100% + 2px); height: calc(100% + 2px)"
8
+ %>
9
+ </div>
@@ -5,9 +5,9 @@
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
- <%= lookbook_render :toolbar do |toolbar| %>
8
+ <%= lookbook_render :toolbar, id: "main-toolbar" do |toolbar| %>
9
9
  <% toolbar.section ":class": "layoutResizing && 'overflow-hidden'" do %>
10
- <%= lookbook_render :tabs, alpine_data: "$store.inspector.main" do |tabs| %>
10
+ <%= lookbook_render :tabs, alpine_data: "$store.inspector.main", id: "inspector-tabs-main" do |tabs| %>
11
11
  <%= @main_panels.each do |panel| %>
12
12
  <% tabs.tab name: panel.name,
13
13
  label: panel.label,
@@ -17,8 +17,24 @@
17
17
  <% end %>
18
18
  <% end %>
19
19
 
20
- <% toolbar.section divide: :left, align: :right, class: "flex-none relative z-10" do %>
20
+ <% toolbar.section align: :right, class: "flex-none" do %>
21
+ <% if @dynamic_display_options.any? %>
22
+ <%= lookbook_render "display_options/editor" do |editor| %>
23
+ <% @dynamic_display_options.each do |key, opts| %>
24
+ <% editor.field name: key, opts: opts, value: @static_display_options[key] %>
25
+ <% end %>
26
+ <% end %>
27
+ <% end %>
28
+ <% end %>
29
+
30
+ <% toolbar.section divide: :left, class: "flex-none relative z-10" do %>
21
31
  <%= lookbook_render :button_group do |group| %>
32
+ <% group.button icon: :link,
33
+ tooltip: "Copy preview URL",
34
+ copy: true do %>
35
+ <%= lookbook_inspect_url(@target.lookup_path, request.query_parameters) %>
36
+ <% end %>
37
+
22
38
  <% if @pages.any? %>
23
39
  <% group.button icon: :code,
24
40
  tooltip: "Copy page embed code",
@@ -47,10 +63,12 @@
47
63
  <% end %>
48
64
 
49
65
  <div class="h-full relative overflow-auto">
50
- <%= lookbook_render :tab_panels, alpine_data: "$store.inspector.main" do |tabs| %>
66
+ <%= lookbook_render :tab_panels, alpine_data: "$store.inspector.main", id: "inspector-panels-main" do |tabs| %>
51
67
  <% @main_panels.each do |panel| %>
52
- <% tabs.panel id: panel.id, name: panel.name, class: panel.panel_classes do %>
53
- <%= render panel.partial, **@inspector_data, panel: panel, **panel.locals %>
68
+ <% tabs.panel name: panel.name do %>
69
+ <%= lookbook_render :inspector_panel, name: panel.name do %>
70
+ <%= render panel.partial, **@inspector_data, panel: panel, **panel.locals %>
71
+ <% end %>
54
72
  <% end %>
55
73
  <% end %>
56
74
  <% end %>
@@ -60,9 +78,9 @@
60
78
  <%= layout.pane class: "flex flex-col h-full overflow-hidden bg-lookbook-drawer-bg",
61
79
  "x-show": "!$store.inspector.drawer.hidden && #{@drawer_panels.any?}" do %>
62
80
 
63
- <%= lookbook_render :toolbar do |toolbar| %>
81
+ <%= lookbook_render :toolbar, id: "drawer-toolbar" do |toolbar| %>
64
82
  <% toolbar.section ":class": "layoutResizing && 'overflow-hidden'" do %>
65
- <%= lookbook_render :tabs, alpine_data: "$store.inspector.drawer" do |tabs| %>
83
+ <%= lookbook_render :tabs, alpine_data: "$store.inspector.drawer", id: "inspector-tabs-drawer" do |tabs| %>
66
84
  <%= @drawer_panels.each do |panel| %>
67
85
  <% tabs.tab name: panel.name,
68
86
  label: panel.label,
@@ -115,10 +133,10 @@
115
133
  <% end %>
116
134
 
117
135
  <div class="h-full overflow-auto">
118
- <%= lookbook_render :tab_panels, alpine_data: "$store.inspector.drawer" do |tabs| %>
136
+ <%= lookbook_render :tab_panels, alpine_data: "$store.inspector.drawer", id: "inspector-panels-drawer" do |tabs| %>
119
137
  <% @drawer_panels.each do |panel| %>
120
- <% tabs.panel id: panel.id, name: panel.name, class: panel.panel_classes do %>
121
- <%= lookbook_render :inspector_panel, **panel.slice(:id, :name, :system) do %>
138
+ <% tabs.panel name: panel.name do %>
139
+ <%= lookbook_render :inspector_panel, name: panel.name do %>
122
140
  <%= render panel.partial, **@inspector_data, panel: panel, **panel.locals %>
123
141
  <% end %>
124
142
  <% end %>
data/config/app.yml ADDED
@@ -0,0 +1,36 @@
1
+ shared:
2
+ project_name: Lookbook
3
+ log_level: 2
4
+ log_use_rails_logger: true
5
+ auto_refresh: true
6
+ components_path: app/components
7
+ page_controller: Lookbook::PageController
8
+ page_route: pages
9
+ page_paths: [test/components/docs]
10
+ page_options: {}
11
+ markdown_options:
12
+ tables: true
13
+ fenced_code_blocks: true
14
+ disable_indented_code_blocks: true
15
+ strikethrough: true
16
+ highlight: true
17
+ with_toc_data: true
18
+ lax_spacing: true
19
+ sort_examples: false
20
+ preview_paths: []
21
+ preview_display_options: {}
22
+ preview_disable_action_view_annotations: true
23
+ preview_params_options_eval: false
24
+ listen: false
25
+ listen_paths: []
26
+ listen_extensions: [rb, html.*]
27
+ listen_use_polling: false
28
+ ui_theme: indigo
29
+ ui_theme_overrides: {}
30
+ ui_favicon: true
31
+ debug_menu: false
32
+ experimental_features: false
33
+
34
+ development:
35
+ listen: true
36
+ debug_menu: true
data/config/hooks.yml ADDED
@@ -0,0 +1,4 @@
1
+ shared:
2
+ after_initialize: []
3
+ before_exit: []
4
+ after_change: []
data/config/inputs.yml ADDED
@@ -0,0 +1,48 @@
1
+ shared:
2
+ select:
3
+ partial: lookbook/previews/inputs/select
4
+ opts: {}
5
+
6
+ textarea:
7
+ partial: lookbook/previews/inputs/textarea
8
+ opts: {}
9
+
10
+ toggle:
11
+ partial: lookbook/previews/inputs/toggle
12
+ opts: {}
13
+
14
+ color:
15
+ partial: lookbook/previews/inputs/color
16
+ opts: {}
17
+
18
+ range:
19
+ partial: lookbook/previews/inputs/range
20
+ opts: {}
21
+
22
+ text:
23
+ partial: lookbook/previews/inputs/text
24
+ opts: {}
25
+
26
+ email:
27
+ partial: lookbook/previews/inputs/text
28
+ opts: {}
29
+
30
+ number:
31
+ partial: lookbook/previews/inputs/text
32
+ opts: {}
33
+
34
+ tel:
35
+ partial: lookbook/previews/inputs/text
36
+ opts: {}
37
+
38
+ url:
39
+ partial: lookbook/previews/inputs/text
40
+ opts: {}
41
+
42
+ date:
43
+ partial: lookbook/previews/inputs/text
44
+ opts: {}
45
+
46
+ datetime_local:
47
+ partial: lookbook/previews/inputs/text
48
+ opts: {}