lookbook 1.1.1 → 1.2.1

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 (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: {}