lookbook 1.2.1 → 1.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +47 -14
- data/app/assets/lookbook/css/themes/blue.css +4 -2
- data/app/assets/lookbook/css/themes/green.css +66 -0
- data/app/assets/lookbook/css/themes/indigo.css +4 -2
- data/app/assets/lookbook/css/themes/rose.css +66 -0
- data/app/assets/lookbook/css/themes/zinc.css +4 -2
- data/app/components/lookbook/base_component.rb +2 -2
- data/app/components/lookbook/code/component.css +2 -2
- data/app/components/lookbook/code/component.html.erb +3 -2
- data/app/components/lookbook/code/component.rb +13 -2
- data/app/components/lookbook/code/highlight_github.css +406 -0
- data/app/components/lookbook/header/component.html.erb +1 -1
- data/app/components/lookbook/inspector_panel/component.rb +4 -6
- data/app/components/lookbook/nav/component.rb +8 -15
- data/app/components/lookbook/nav/directory/component.html.erb +28 -0
- data/app/components/lookbook/nav/directory/component.rb +4 -0
- data/app/components/lookbook/nav/{item → entity}/component.html.erb +8 -8
- data/app/components/lookbook/nav/entity/component.rb +49 -0
- data/app/components/lookbook/nav/item/component.css +15 -0
- data/app/components/lookbook/nav/item/component.js +4 -0
- data/app/components/lookbook/nav/item/component.rb +13 -56
- data/app/components/lookbook/params/editor/component.html.erb +2 -2
- data/app/components/lookbook/params/editor/component.rb +3 -10
- data/app/components/lookbook/params/field/component.css +3 -3
- data/app/components/lookbook/params/field/component.html.erb +8 -8
- data/app/components/lookbook/params/field/component.rb +21 -72
- data/app/components/lookbook/split_layout/component.html.erb +1 -1
- data/app/components/lookbook/tabs/component.html.erb +1 -1
- data/app/components/lookbook/tabs/component.js +4 -0
- data/app/components/lookbook/tag_component.rb +1 -1
- data/app/components/lookbook/viewport/component.css +1 -1
- data/app/components/lookbook/viewport/component.html.erb +1 -1
- data/app/components/lookbook/viewport/component.rb +1 -1
- data/app/controllers/concerns/lookbook/targetable_concern.rb +131 -0
- data/app/controllers/concerns/lookbook/with_preview_controller_concern.rb +13 -0
- data/app/controllers/lookbook/application_controller.rb +21 -9
- data/app/controllers/lookbook/inspector_controller.rb +45 -0
- data/app/controllers/lookbook/page_controller.rb +13 -9
- data/app/controllers/lookbook/pages_controller.rb +9 -15
- data/app/controllers/lookbook/previews_controller.rb +4 -210
- data/app/helpers/lookbook/application_helper.rb +2 -2
- data/app/helpers/lookbook/output_helper.rb +5 -5
- data/app/helpers/lookbook/page_helper.rb +7 -4
- data/app/views/layouts/lookbook/application.html.erb +40 -38
- data/app/views/layouts/lookbook/page.html.erb +2 -2
- data/app/views/layouts/lookbook/shell.html.erb +3 -2
- data/app/views/layouts/lookbook/skeleton.html.erb +7 -7
- data/app/views/lookbook/index.html.erb +13 -2
- data/app/views/lookbook/{previews → inspector}/inputs/_color.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_range.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_select.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_text.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_textarea.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_toggle.html.erb +5 -5
- data/app/views/lookbook/{previews → inspector}/panels/_content.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/panels/_notes.html.erb +2 -2
- data/app/views/lookbook/{previews → inspector}/panels/_output.html.erb +0 -0
- data/app/views/lookbook/inspector/panels/_params.html.erb +15 -0
- data/app/views/lookbook/{previews → inspector}/panels/_preview.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/panels/_source.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/show.html.erb +5 -2
- data/config/app.yml +11 -1
- data/config/inputs.yml +12 -12
- data/config/languages.yml +41 -0
- data/config/panels.yml +6 -6
- data/config/routes.rb +5 -5
- data/config/tags.yml +8 -1
- data/lib/lookbook/engine.rb +103 -130
- data/lib/lookbook/entities/collections/component_collection.rb +4 -0
- data/lib/lookbook/entities/collections/concerns/hierarchical_collection.rb +23 -0
- data/lib/lookbook/entities/collections/entity_collection.rb +61 -0
- data/lib/lookbook/entities/collections/page_collection.rb +30 -0
- data/lib/lookbook/entities/collections/preview_collection.rb +41 -0
- data/lib/lookbook/entities/collections/preview_example_collection.rb +4 -0
- data/lib/lookbook/entities/component.rb +31 -0
- data/lib/lookbook/entities/concerns/annotatable.rb +58 -0
- data/lib/lookbook/entities/concerns/inspectable.rb +44 -0
- data/lib/lookbook/entities/concerns/locatable.rb +73 -0
- data/lib/lookbook/entities/concerns/navigable.rb +43 -0
- data/lib/lookbook/entities/entity.rb +53 -0
- data/lib/lookbook/entities/page.rb +80 -0
- data/lib/lookbook/entities/page_section.rb +43 -0
- data/lib/lookbook/entities/preview.rb +87 -0
- data/lib/lookbook/entities/preview_example.rb +100 -0
- data/lib/lookbook/entities/preview_group.rb +48 -0
- data/lib/lookbook/file_watcher.rb +47 -0
- data/lib/lookbook/lang.rb +12 -35
- data/lib/lookbook/param.rb +99 -0
- data/lib/lookbook/{preview_controller.rb → preview_actions.rb} +14 -3
- data/lib/lookbook/preview_parser.rb +53 -0
- data/lib/lookbook/process.rb +21 -0
- data/lib/lookbook/rendered_example.rb +37 -0
- data/lib/lookbook/services/code/code_beautifier.rb +21 -0
- data/lib/lookbook/services/code/code_highlighter.rb +69 -0
- data/lib/lookbook/services/code/code_indenter.rb +14 -0
- data/lib/lookbook/services/data/parsers/data_parser.rb +22 -0
- data/lib/lookbook/services/data/parsers/json_parser.rb +7 -0
- data/lib/lookbook/services/data/parsers/yaml_parser.rb +7 -0
- data/lib/lookbook/services/data/resolvers/data_resolver.rb +70 -0
- data/lib/lookbook/services/data/resolvers/eval_resolver.rb +10 -0
- data/lib/lookbook/services/data/resolvers/file_resolver.rb +28 -0
- data/lib/lookbook/services/data/resolvers/method_resolver.rb +10 -0
- data/lib/lookbook/services/data/resolvers/yaml_resolver.rb +18 -0
- data/lib/lookbook/services/entities/entity_tree_builder.rb +45 -0
- data/lib/lookbook/services/markdown_renderer.rb +29 -0
- data/lib/lookbook/services/position_prefix_parser.rb +16 -0
- data/lib/lookbook/services/string_value_caster.rb +60 -0
- data/lib/lookbook/services/tags/tag_options_parser.rb +62 -0
- data/lib/lookbook/services/templates/action_view_annotations_handler.rb +21 -0
- data/lib/lookbook/services/templates/action_view_annotations_stripper.rb +15 -0
- data/lib/lookbook/services/templates/frontmatter_extractor.rb +28 -0
- data/lib/lookbook/services/templates/styles_extractor.rb +38 -0
- data/lib/lookbook/services/{search_param_builder.rb → urls/search_param_builder.rb} +1 -1
- data/lib/lookbook/services/{search_param_parser.rb → urls/search_param_parser.rb} +1 -1
- data/lib/lookbook/stores/config_store.rb +12 -9
- data/lib/lookbook/stores/input_store.rb +7 -3
- data/lib/lookbook/stores/panel_store.rb +2 -2
- data/lib/lookbook/stores/tag_store.rb +3 -5
- data/lib/lookbook/support/null_object.rb +10 -0
- data/lib/lookbook/support/service.rb +2 -2
- data/lib/lookbook/support/store.rb +2 -35
- data/lib/lookbook/support/tree_node.rb +87 -0
- data/lib/lookbook/support/utils/path_utils.rb +32 -5
- data/lib/lookbook/support/utils/utils.rb +24 -0
- data/lib/lookbook/tags/component_tag.rb +13 -0
- data/lib/lookbook/tags/custom_tag.rb +61 -0
- data/lib/lookbook/tags/display_tag.rb +15 -0
- data/lib/lookbook/tags/hidden_tag.rb +13 -0
- data/lib/lookbook/tags/id_tag.rb +7 -0
- data/lib/lookbook/tags/label_tag.rb +4 -0
- data/lib/lookbook/tags/logical_path_tag.rb +7 -0
- data/lib/lookbook/tags/param_tag.rb +63 -0
- data/lib/lookbook/tags/position_tag.rb +16 -0
- data/lib/lookbook/tags/source_tag.rb +7 -0
- data/lib/lookbook/tags/tag_provider.rb +18 -0
- data/lib/lookbook/tags/yard_tag.rb +90 -0
- data/lib/lookbook/theme.rb +8 -0
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook/websocket.rb +60 -0
- data/lib/lookbook.rb +13 -8
- data/public/lookbook-assets/css/lookbook.css +487 -411
- data/public/lookbook-assets/css/lookbook.css.map +1 -1
- data/public/lookbook-assets/css/themes/blue.css +3 -1
- data/public/lookbook-assets/css/themes/blue.css.map +1 -1
- data/public/lookbook-assets/css/themes/green.css +68 -0
- data/public/lookbook-assets/css/themes/green.css.map +1 -0
- data/public/lookbook-assets/css/themes/indigo.css +3 -1
- data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
- data/public/lookbook-assets/css/themes/rose.css +68 -0
- data/public/lookbook-assets/css/themes/rose.css.map +1 -0
- data/public/lookbook-assets/css/themes/zinc.css +3 -1
- data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
- data/public/lookbook-assets/js/embed.js +10 -1
- data/public/lookbook-assets/js/embed.js.map +1 -1
- data/public/lookbook-assets/js/lookbook.js +358 -629
- data/public/lookbook-assets/js/lookbook.js.map +1 -1
- metadata +96 -44
- data/app/components/lookbook/code/highlight_github_light.css +0 -217
- data/app/views/lookbook/previews/panels/_params.html.erb +0 -15
- data/lib/lookbook/code_formatter.rb +0 -68
- data/lib/lookbook/collection.rb +0 -161
- data/lib/lookbook/component.rb +0 -34
- data/lib/lookbook/entity.rb +0 -47
- data/lib/lookbook/markdown.rb +0 -22
- data/lib/lookbook/page.rb +0 -195
- data/lib/lookbook/page_collection.rb +0 -19
- data/lib/lookbook/page_section.rb +0 -29
- data/lib/lookbook/params.rb +0 -157
- data/lib/lookbook/parser.rb +0 -42
- data/lib/lookbook/preview.rb +0 -174
- data/lib/lookbook/preview_collection.rb +0 -23
- data/lib/lookbook/preview_example.rb +0 -93
- data/lib/lookbook/preview_group.rb +0 -62
- data/lib/lookbook/source_inspector.rb +0 -95
- data/lib/lookbook/support/utils/attribute_utils.rb +0 -9
- data/lib/lookbook/tag.rb +0 -122
- data/lib/lookbook/tag_options.rb +0 -111
- data/lib/lookbook/tags.rb +0 -17
- data/lib/lookbook/template_parser.rb +0 -72
- data/lib/lookbook/utils.rb +0 -105
@@ -1,87 +1,44 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class Nav::Item::Component < Lookbook::BaseComponent
|
3
|
-
|
4
|
-
page: :file,
|
5
|
-
page_collection: :folder,
|
6
|
-
preview_collection: :folder,
|
7
|
-
preview: :layers,
|
8
|
-
example: :eye,
|
9
|
-
group: :eye,
|
10
|
-
collection: :folder
|
11
|
-
}.freeze
|
3
|
+
delegate :label, :depth, to: :node
|
12
4
|
|
13
|
-
|
5
|
+
attr_reader :node, :nav_id
|
14
6
|
|
15
|
-
def initialize(
|
16
|
-
|
17
|
-
nav_id:,
|
18
|
-
depth: 1,
|
19
|
-
collapse_singles: false,
|
20
|
-
**html_attrs
|
21
|
-
)
|
7
|
+
def initialize(node, nav_id:, **html_attrs)
|
8
|
+
@node = node
|
22
9
|
@nav_id = nav_id
|
23
|
-
@item = item
|
24
|
-
@depth = depth
|
25
|
-
@collapse_singles = collapse_singles
|
26
10
|
super(**html_attrs)
|
27
11
|
end
|
28
12
|
|
29
13
|
def id
|
30
|
-
"#{
|
14
|
+
"#{nav_id}-#{node.id}"
|
31
15
|
end
|
32
16
|
|
33
17
|
def left_pad
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
def href
|
38
|
-
if collapsed?
|
39
|
-
item.url_path
|
40
|
-
elsif !collection?
|
41
|
-
item.url_path
|
42
|
-
end
|
18
|
+
depth * 12
|
43
19
|
end
|
44
20
|
|
45
21
|
def children
|
46
|
-
@children ||=
|
47
|
-
item.non_empty_items.map do |item|
|
48
|
-
lookbook_render Lookbook::Nav::Item::Component.new item,
|
49
|
-
nav_id: @nav_id,
|
50
|
-
depth: (@depth + 1),
|
51
|
-
collapse_singles: @collapse_singles
|
52
|
-
end
|
53
|
-
else
|
54
|
-
[]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def item
|
59
|
-
collapsed? ? @item.first : @item
|
22
|
+
@children ||= node.sort.map { |node| render_item(node) }
|
60
23
|
end
|
61
24
|
|
62
25
|
def nav_icon
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
def collection?
|
67
|
-
@item.is_a? Lookbook::Collection
|
26
|
+
:folder
|
68
27
|
end
|
69
28
|
|
70
29
|
def children?
|
71
|
-
children.any?
|
30
|
+
children.any?
|
72
31
|
end
|
73
32
|
|
74
|
-
def
|
75
|
-
|
33
|
+
def render_item(node)
|
34
|
+
item_class = (node.type == :directory) ? Nav::Directory::Component : Nav::Entity::Component
|
35
|
+
lookbook_render item_class.new node, nav_id: nav_id
|
76
36
|
end
|
77
37
|
|
78
38
|
protected
|
79
39
|
|
80
40
|
def alpine_data
|
81
|
-
alpine_encode({
|
82
|
-
id: @item.id,
|
83
|
-
matchers: item.is_a?(Lookbook::Collection) ? nil : item.matchers
|
84
|
-
})
|
41
|
+
alpine_encode({id: node.id, matchers: []})
|
85
42
|
end
|
86
43
|
|
87
44
|
def alpine_component
|
@@ -1,5 +1,5 @@
|
|
1
|
-
<%= render_component_tag class: "
|
2
|
-
<div class="bg-
|
1
|
+
<%= render_component_tag class: "overflow-hidden" do %>
|
2
|
+
<div class="bg-lookbook-params-editor-bg border border-lookbook-divider rounded-md overflow-x-auto">
|
3
3
|
<table class="border-collapse w-full" :class="narrow && 'linear'">
|
4
4
|
<thead>
|
5
5
|
<tr>
|
@@ -1,20 +1,13 @@
|
|
1
1
|
module Lookbook
|
2
2
|
module Params
|
3
3
|
class Editor::Component < Lookbook::BaseComponent
|
4
|
-
renders_many :fields, ->(
|
4
|
+
renders_many :fields, ->(**attrs) do
|
5
5
|
@field_count += 1
|
6
|
-
|
7
|
-
input_config = @inputs[input.tr("-", "_").to_sym]
|
8
|
-
Lookbook::Params::Field::Component.new(input: input,
|
9
|
-
description: description,
|
10
|
-
index: @field_count,
|
11
|
-
config: input_config, **attrs)
|
6
|
+
Lookbook::Params::Field::Component.new(**attrs, index: @field_count)
|
12
7
|
end
|
13
8
|
|
14
|
-
def initialize(
|
15
|
-
@inputs = inputs.to_h
|
9
|
+
def initialize(**html_attrs)
|
16
10
|
@field_count = -1
|
17
|
-
@descriptions = false
|
18
11
|
@@input_styles = {}
|
19
12
|
super(**html_attrs)
|
20
13
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
table:not(.linear) {
|
4
4
|
thead {
|
5
5
|
tr {
|
6
|
-
@apply border-b border-
|
6
|
+
@apply border-b border-lookbook-divider;
|
7
7
|
}
|
8
8
|
|
9
9
|
th {
|
@@ -21,7 +21,7 @@
|
|
21
21
|
|
22
22
|
tbody {
|
23
23
|
tr + tr td {
|
24
|
-
@apply border-t border-
|
24
|
+
@apply border-t border-lookbook-divider;
|
25
25
|
}
|
26
26
|
|
27
27
|
td {
|
@@ -53,7 +53,7 @@
|
|
53
53
|
}
|
54
54
|
|
55
55
|
tr:not(:last-child) {
|
56
|
-
@apply border-b border-
|
56
|
+
@apply border-b border-lookbook-divider;
|
57
57
|
}
|
58
58
|
|
59
59
|
tr {
|
@@ -1,27 +1,27 @@
|
|
1
1
|
<%= render_component_tag :tr, "@keydown.stop": true do %>
|
2
2
|
<td class="param-label">
|
3
|
-
<label for="param-<%=
|
4
|
-
<span class="mr-0.5"><%==
|
5
|
-
<% if hint? %>
|
3
|
+
<label for="param-<%= param.name %>">
|
4
|
+
<span class="mr-0.5"><%== param.label %></span>
|
5
|
+
<% if param.hint.present? %>
|
6
6
|
<span x-data="tooltipComponent" class="inline-block cursor-help relative top-[2px]">
|
7
7
|
<%= icon :help_circle, size: 3.5, class: "opacity-40 hover:opacity-100 transition" %>
|
8
8
|
<div class="hidden" x-ref="tooltip">
|
9
|
-
<%=
|
9
|
+
<%= param.hint %>
|
10
10
|
</div>
|
11
11
|
</span>
|
12
12
|
<% end %>
|
13
13
|
</label>
|
14
14
|
</td>
|
15
|
-
<td class="param-description <%= "param-description-empty" unless description
|
16
|
-
<% if description
|
17
|
-
<p class="opacity-70"><%=
|
15
|
+
<td class="param-description <%= "param-description-empty" unless param.description %>">
|
16
|
+
<% if param.description %>
|
17
|
+
<p class="opacity-70"><%= param.description %></p>
|
18
18
|
<% else %>
|
19
19
|
<p class="italic opacity-40">—</p>
|
20
20
|
<% end %>
|
21
21
|
</td>
|
22
22
|
<td class="param-input">
|
23
23
|
<div class="param-input-wrapper">
|
24
|
-
<%=
|
24
|
+
<%= rendered_input %>
|
25
25
|
</div>
|
26
26
|
</td>
|
27
27
|
<% end %>
|
@@ -1,92 +1,41 @@
|
|
1
1
|
module Lookbook
|
2
2
|
module Params
|
3
3
|
class Field::Component < Lookbook::BaseComponent
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
@
|
8
|
-
@hint = hint
|
9
|
-
@description = description
|
10
|
-
@value = value
|
4
|
+
attr_reader :param, :rendered_input
|
5
|
+
|
6
|
+
def initialize(param:, index:, **html_attrs)
|
7
|
+
@param = param
|
11
8
|
@index = index
|
12
|
-
@input_options = input_options
|
13
|
-
@value_default = value_default
|
14
|
-
@value_type = value_type
|
15
|
-
@config = config || {}
|
16
9
|
@rendered_input = nil
|
17
10
|
super(**html_attrs)
|
18
11
|
end
|
19
12
|
|
20
|
-
def hint?
|
21
|
-
@hint.present?
|
22
|
-
end
|
23
|
-
|
24
|
-
def description?
|
25
|
-
@description.present?
|
26
|
-
end
|
27
|
-
|
28
|
-
def input
|
29
|
-
@rendered_input
|
30
|
-
end
|
31
|
-
|
32
13
|
def before_render
|
33
|
-
|
34
|
-
Editor::Component.add_styles(
|
14
|
+
styles, html = StylesExtractor.call(render_input)
|
15
|
+
Editor::Component.add_styles(param.input, styles)
|
35
16
|
|
17
|
+
escaped_value = json_escape(param.value.to_s)
|
36
18
|
wrapper_attrs = {
|
37
|
-
data: {"param-input":
|
38
|
-
"x-data": "paramsInputComponent({name: '#{
|
19
|
+
data: {"param-input": param.input},
|
20
|
+
"x-data": "paramsInputComponent({name: '#{param.name}', value: '#{escaped_value}'})"
|
39
21
|
}
|
40
|
-
|
41
|
-
@rendered_input = tag.div(**wrapper_attrs) do
|
42
|
-
tpl.content
|
43
|
-
end
|
22
|
+
@rendered_input = tag.div(**wrapper_attrs) { html.html_safe }
|
44
23
|
end
|
45
24
|
|
46
25
|
protected
|
47
26
|
|
48
|
-
def input_error(error)
|
49
|
-
tag.div error, class: "p-2 text-red-500 italic"
|
50
|
-
end
|
51
|
-
|
52
|
-
def value
|
53
|
-
val = @value.presence || @value_default
|
54
|
-
@value_type.downcase == "boolean" ? val == "true" || val == true : val
|
55
|
-
end
|
56
|
-
|
57
|
-
def escaped_value
|
58
|
-
json_escape(value.to_json)
|
59
|
-
end
|
60
|
-
|
61
|
-
def input_options
|
62
|
-
config_options = @config.fetch(:opts, {})
|
63
|
-
opts = config_options.merge(@input_options).symbolize_keys
|
64
|
-
opts[:id] = "param-#{@name}"
|
65
|
-
opts
|
66
|
-
end
|
67
|
-
|
68
|
-
def render_props
|
69
|
-
{
|
70
|
-
name: @name,
|
71
|
-
input: @input_name,
|
72
|
-
value: value,
|
73
|
-
value_type: @value_type,
|
74
|
-
value_default: @value_default,
|
75
|
-
input_options: input_options.except(:choices),
|
76
|
-
choices: input_options[:choices]
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
27
|
def render_input
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
28
|
+
input_options = param.input_options.to_h
|
29
|
+
input_options[:id] = "param-#{param.name}"
|
30
|
+
|
31
|
+
render(param.input_partial,
|
32
|
+
name: param.name,
|
33
|
+
input: param.input,
|
34
|
+
value: param.value.to_s,
|
35
|
+
value_type: param.value_type,
|
36
|
+
value_default: param.value_default,
|
37
|
+
input_options: input_options.except(:choices, :opts),
|
38
|
+
choices: input_options[:choices])
|
90
39
|
end
|
91
40
|
|
92
41
|
def alpine_component
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<% panes.each.with_index(1) do |pane, i| %>
|
3
3
|
<%= pane %>
|
4
4
|
<% if i < panes.size %>
|
5
|
-
<div class="bg-lookbook-divider relative" x-init="registerGutter">
|
5
|
+
<div class="bg-lookbook-divider relative z-50" x-init="registerGutter">
|
6
6
|
<div class="absolute z-10 bg-transparent hover:bg-lookbook-draggable-hint transition-all" :class="{
|
7
7
|
'w-[9px] h-full -translate-x-1/2 cursor-[col-resize]': vertical,
|
8
8
|
'h-[9px] w-full -translate-y-1/2 cursor-[row-resize]': horizontal
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<%= lookbook_render :button, icon: :menu, class: "-ml-3", "x-show": "visibleTabsCount === 0" %>
|
14
14
|
</div>
|
15
15
|
<div class="hidden">
|
16
|
-
<div x-ref="tabsDropdown"
|
16
|
+
<div x-ref="tabsDropdown" x-cloak>
|
17
17
|
<%= safe_join(dropdown_tabs) %>
|
18
18
|
</div>
|
19
19
|
</div>
|
@@ -33,6 +33,10 @@ export default function tabsComponent(store) {
|
|
33
33
|
|
34
34
|
init() {
|
35
35
|
this.$nextTick(() => {
|
36
|
+
if (this.$root.parentElement.offsetWidth === this.$root.offsetWidth) {
|
37
|
+
this.visibleTabsCount = this.tabs.length;
|
38
|
+
}
|
39
|
+
|
36
40
|
dropdown = tippy(this.$refs.dropdownTrigger, {
|
37
41
|
content: this.$refs.tabsDropdown,
|
38
42
|
theme: "menu",
|
@@ -19,7 +19,7 @@ module Lookbook
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.escape_attribute_key
|
22
|
-
@escape_attribute_key ||= Gem::Version.new(Rails.version) < Gem::Version.new("6.1.5.1") ? :escape_attributes : :escape
|
22
|
+
@escape_attribute_key ||= (Gem::Version.new(Rails.version) < Gem::Version.new("6.1.5.1")) ? :escape_attributes : :escape
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23f3f3f3' fill-opacity='1'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E");
|
5
5
|
|
6
6
|
.resize-handle {
|
7
|
-
@apply flex items-center justify-center h-full w-full border-lookbook-divider bg-lookbook-viewport-handle hover:bg-lookbook-
|
7
|
+
@apply flex items-center justify-center h-full w-full border-lookbook-divider bg-lookbook-viewport-handle hover:bg-lookbook-viewport-handle-hover hover:bg-opacity-20;
|
8
8
|
@apply text-lookbook-viewport-handle-icon-stroke hover:text-lookbook-viewport-handle-icon-stroke-hover transition select-none touch-none;
|
9
9
|
}
|
10
10
|
}
|
@@ -27,7 +27,7 @@
|
|
27
27
|
style="width: calc(100% + 2px); height: calc(100% + 1px); <%= "max-height: #{@max_height}px;" if @max_height.present? %>">
|
28
28
|
<iframe seamless<%= " id=#{@iframe_id}" if @iframe_id.present? %>
|
29
29
|
x-ref="iframe"
|
30
|
-
class="h-full w-full border border-lookbook-divider"
|
30
|
+
class="bg-lookbook-page-bg h-full w-full border border-lookbook-divider"
|
31
31
|
:class="{ 'pointer-events-none': reflowing }"
|
32
32
|
style="<%= "max-height: #{@max_height}px;" if @max_height.present? %>"
|
33
33
|
src="<%= @src %>"
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Lookbook
|
2
|
+
module TargetableConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_action :lookup_entities, only: [:show]
|
7
|
+
before_action :set_title
|
8
|
+
before_action :set_display_options
|
9
|
+
before_action :set_params
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_title
|
13
|
+
@title = @target.present? ? [@target&.label, @preview&.label].compact.join(" :: ") : "Not found"
|
14
|
+
end
|
15
|
+
|
16
|
+
def lookup_entities
|
17
|
+
@target = Lookbook.previews.find_example_by_path(params[:path])
|
18
|
+
if @target.present?
|
19
|
+
@preview = @target.preview
|
20
|
+
if params[:path] == @preview&.path
|
21
|
+
redirect_to lookbook_inspect_path("#{params[:path]}/#{@preview.default_example.name}", params.permit!)
|
22
|
+
end
|
23
|
+
else
|
24
|
+
@preview = Lookbook.previews.find_by_path(params[:path])
|
25
|
+
if @preview.present?
|
26
|
+
default_example = @preview.default_example
|
27
|
+
redirect_to lookbook_inspect_path(default_example.path, params.permit!) if default_example
|
28
|
+
else
|
29
|
+
@preview = Lookbook.previews.find_by_path(path_segments.slice(0, path_segments.size - 1).join("/"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_display_options
|
35
|
+
@dynamic_display_options = []
|
36
|
+
@static_display_options = []
|
37
|
+
|
38
|
+
if @target.present?
|
39
|
+
opts = @target.display_options
|
40
|
+
@dynamic_display_options = opts.select { _2.is_a?(Array) || _2.is_a?(Hash) }
|
41
|
+
@static_display_options = opts.except(*@dynamic_display_options.keys)
|
42
|
+
|
43
|
+
if params[:_display]
|
44
|
+
display_params = SearchParamParser.call(params[:_display])
|
45
|
+
display_params.each do |name, value|
|
46
|
+
if @dynamic_display_options.key?(name)
|
47
|
+
cookies["lookbook-display-#{name}"] = value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
@dynamic_display_options.each do |name, opts|
|
53
|
+
choices = opts.is_a?(Hash) ? opts[:choices].to_a : opts
|
54
|
+
@static_display_options[name] ||= cookies.fetch("lookbook-display-#{name}", choices.first)
|
55
|
+
end
|
56
|
+
|
57
|
+
unless params[:_display]
|
58
|
+
display_params = @dynamic_display_options.map do |name, opts|
|
59
|
+
[name, @static_display_options[name]]
|
60
|
+
end.to_h
|
61
|
+
request.query_parameters[:_display] = SearchParamBuilder.call(display_params)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def set_params
|
67
|
+
@params = []
|
68
|
+
|
69
|
+
if @target
|
70
|
+
@params = @target.tags("param").map do |param_tag|
|
71
|
+
Param.from_tag(
|
72
|
+
param_tag,
|
73
|
+
value: preview_controller.params[param_tag.name]
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
# cast known param values to correct type
|
78
|
+
@params.each do |param|
|
79
|
+
if preview_controller.params.key?(param.name)
|
80
|
+
preview_controller.params[param.name] = param.cast_value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# set display and data params for use in preview layouts
|
85
|
+
preview_controller.params[:lookbook] = {
|
86
|
+
display: @static_display_options,
|
87
|
+
data: Lookbook.data
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
preview_controller.params.permit!
|
92
|
+
end
|
93
|
+
|
94
|
+
def inspector_data
|
95
|
+
return @inspector_data if @inspector_data.present?
|
96
|
+
|
97
|
+
rendered_examples = @target.examples.map do |example|
|
98
|
+
output = preview_controller.process(:render_example_to_string, @preview, example.name)
|
99
|
+
RenderedExample.new(example, output, preview_controller.params)
|
100
|
+
end
|
101
|
+
|
102
|
+
@inspector_data ||= Lookbook::Store.new({
|
103
|
+
context: Store.new({params: @params, path: params[:path]}),
|
104
|
+
preview: @preview,
|
105
|
+
examples: rendered_examples,
|
106
|
+
target: @target,
|
107
|
+
data: Lookbook.data,
|
108
|
+
app: Lookbook
|
109
|
+
})
|
110
|
+
end
|
111
|
+
|
112
|
+
def show_404(layout: nil)
|
113
|
+
locals = if @preview
|
114
|
+
{
|
115
|
+
message: "Example not found",
|
116
|
+
description: "The '#{@preview.label}' preview does not have an example named '#{path_segments.last}'."
|
117
|
+
}
|
118
|
+
else
|
119
|
+
{
|
120
|
+
message: "Not found",
|
121
|
+
description: "Looked for '#{params[:path]}'.<br>The preview may have been renamed or deleted."
|
122
|
+
}
|
123
|
+
end
|
124
|
+
render_in_layout "lookbook/404", layout: layout, **locals
|
125
|
+
end
|
126
|
+
|
127
|
+
def path_segments
|
128
|
+
params[:path].split("/")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Lookbook
|
2
|
+
module WithPreviewControllerConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def preview_controller
|
6
|
+
return @preview_controller if @preview_controller
|
7
|
+
controller = Lookbook::Engine.preview_controller.new
|
8
|
+
controller.request = request
|
9
|
+
controller.response = response
|
10
|
+
@preview_controller ||= controller
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
-
if respond_to?(:content_security_policy)
|
4
|
-
content_security_policy false, if: -> { Rails.env.development? }
|
5
|
-
end
|
3
|
+
content_security_policy(false) if respond_to?(:content_security_policy)
|
6
4
|
|
7
5
|
protect_from_forgery with: :exception
|
8
6
|
|
@@ -11,16 +9,16 @@ module Lookbook
|
|
11
9
|
helper Lookbook::ComponentHelper
|
12
10
|
|
13
11
|
before_action :generate_theme_overrides
|
14
|
-
before_action :
|
12
|
+
before_action :assign_instance_vars
|
15
13
|
|
16
14
|
def self.controller_path
|
17
15
|
"lookbook"
|
18
16
|
end
|
19
17
|
|
20
18
|
def index
|
21
|
-
landing = Lookbook.pages.find(&:landing) || Lookbook.pages.first
|
19
|
+
landing = Lookbook.pages.find(&:landing?) || Lookbook.pages.first
|
22
20
|
if landing.present?
|
23
|
-
redirect_to lookbook_page_path(landing.
|
21
|
+
redirect_to lookbook_page_path(landing.path)
|
24
22
|
else
|
25
23
|
render "lookbook/index"
|
26
24
|
end
|
@@ -32,9 +30,11 @@ module Lookbook
|
|
32
30
|
@theme_overrides ||= Lookbook.theme.to_css
|
33
31
|
end
|
34
32
|
|
35
|
-
def
|
36
|
-
@previews =
|
37
|
-
@pages =
|
33
|
+
def assign_instance_vars
|
34
|
+
@previews = Lookbook.previews
|
35
|
+
@pages = Lookbook.pages
|
36
|
+
@config = Lookbook.config
|
37
|
+
@engine = Lookbook.engine
|
38
38
|
end
|
39
39
|
|
40
40
|
def feature_enabled?(feature)
|
@@ -45,5 +45,17 @@ module Lookbook
|
|
45
45
|
@error = locals[:error]
|
46
46
|
render path, layout: layout.presence || (params[:lookbook_embed] ? "lookbook/basic" : "lookbook/application"), locals: locals
|
47
47
|
end
|
48
|
+
|
49
|
+
def prettify_error(exception)
|
50
|
+
error_params = {}
|
51
|
+
if exception.is_a?(ViewComponent::PreviewTemplateError)
|
52
|
+
error_params = {
|
53
|
+
file_path: @preview&.file_path,
|
54
|
+
line_number: 0,
|
55
|
+
source_code: @target&.source
|
56
|
+
}
|
57
|
+
end
|
58
|
+
Lookbook::Error.new(exception, **error_params)
|
59
|
+
end
|
48
60
|
end
|
49
61
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class InspectorController < ApplicationController
|
3
|
+
include TargetableConcern
|
4
|
+
include WithPreviewControllerConcern
|
5
|
+
|
6
|
+
layout "lookbook/inspector"
|
7
|
+
helper Lookbook::PreviewHelper
|
8
|
+
|
9
|
+
def self.controller_path
|
10
|
+
"lookbook/inspector"
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
if @target
|
15
|
+
begin
|
16
|
+
@main_panels = main_panels
|
17
|
+
@drawer_panels = drawer_panels
|
18
|
+
rescue => exception
|
19
|
+
render_in_layout "lookbook/error", layout: "lookbook/inspector", error: prettify_error(exception)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
show_404
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def show_legacy
|
27
|
+
Lookbook.logger.warn("Legacy URL path detected. These paths are deprecated and will be removed in a future version")
|
28
|
+
redirect_to lookbook_inspect_path params[:path]
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def main_panels
|
34
|
+
Engine.panels.in_group(:main).map do |config|
|
35
|
+
PanelStore.resolve_config(config, inspector_data)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def drawer_panels
|
40
|
+
Engine.panels.in_group(:drawer).map do |config|
|
41
|
+
PanelStore.resolve_config(config, inspector_data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -11,15 +11,19 @@ module Lookbook
|
|
11
11
|
def render_page(page, locals = {})
|
12
12
|
@page = page
|
13
13
|
@pages = Lookbook.pages
|
14
|
-
@next_page = @pages.
|
15
|
-
@previous_page = @pages.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
@next_page = @pages.next(@page)
|
15
|
+
@previous_page = @pages.previous(@page)
|
16
|
+
|
17
|
+
content = ActionViewAnnotationsHandler.call(disable_annotations: true) do
|
18
|
+
render_to_string inline: @page.content, locals: {
|
19
|
+
page: @page,
|
20
|
+
next_page: @next_page,
|
21
|
+
previous_page: @previous_page,
|
22
|
+
pages: @pages
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
@page.markdown? ? MarkdownRenderer.call(content, Lookbook.config.markdown_options) : content
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|