lookbook 0.6.1 → 0.7.2.beta.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +233 -5
- data/app/assets/lookbook/css/app.css +15 -3
- data/app/assets/lookbook/js/app.js +8 -0
- data/app/assets/lookbook/js/components/app.js +55 -0
- data/app/assets/lookbook/js/components/embed.js +89 -0
- data/app/assets/lookbook/js/components/filter.js +13 -2
- data/app/assets/lookbook/js/components/nav-group.js +3 -6
- data/app/assets/lookbook/js/components/nav-item.js +3 -1
- data/app/assets/lookbook/js/components/nav.js +8 -15
- data/app/assets/lookbook/js/components/page.js +19 -41
- data/app/assets/lookbook/js/components/sidebar.js +16 -1
- data/app/assets/lookbook/js/components/splitter.js +1 -1
- data/app/assets/lookbook/js/components/tabs.js +3 -1
- data/app/assets/lookbook/js/embed.js +1 -0
- data/app/assets/lookbook/js/lib/split.js +0 -6
- data/app/assets/lookbook/js/stores/layout.js +3 -0
- data/app/assets/lookbook/js/stores/pages.js +5 -0
- data/app/assets/lookbook/js/stores/sidebar.js +2 -1
- data/app/controllers/lookbook/application_controller.rb +28 -0
- data/app/controllers/lookbook/page_controller.rb +20 -0
- data/app/controllers/lookbook/pages_controller.rb +47 -0
- data/app/controllers/lookbook/{app_controller.rb → previews_controller.rb} +39 -70
- data/app/helpers/lookbook/application_helper.rb +8 -61
- data/app/helpers/lookbook/component_helper.rb +40 -0
- data/app/helpers/lookbook/output_helper.rb +15 -0
- data/app/helpers/lookbook/page_helper.rb +46 -0
- data/app/helpers/lookbook/preview_helper.rb +1 -1
- data/app/views/layouts/lookbook/application.html.erb +30 -0
- data/app/views/layouts/lookbook/basic.html.erb +7 -0
- data/app/views/layouts/lookbook/preview.html.erb +5 -1
- data/app/views/layouts/lookbook/skeleton.html.erb +28 -0
- data/app/views/lookbook/components/_branding.html.erb +8 -0
- data/app/views/lookbook/components/_code.html.erb +2 -2
- data/app/views/lookbook/components/_copy_button.html.erb +11 -0
- data/app/views/lookbook/components/_drawer.html.erb +4 -16
- data/app/views/lookbook/components/_embed.html.erb +39 -0
- data/app/views/lookbook/components/_errors.html.erb +13 -0
- data/app/views/lookbook/components/_filter.html.erb +8 -5
- data/app/views/lookbook/components/_header.html.erb +2 -4
- data/app/views/lookbook/components/_icon.html.erb +2 -2
- data/app/views/lookbook/components/_nav.html.erb +7 -8
- data/app/views/lookbook/components/_nav_group.html.erb +1 -1
- data/app/views/lookbook/components/_nav_item.html.erb +4 -3
- data/app/views/lookbook/components/_nav_page.html.erb +22 -0
- data/app/views/lookbook/components/_nav_preview.html.erb +1 -1
- data/app/views/lookbook/components/_not_found.html.erb +11 -0
- data/app/views/lookbook/components/_param.html.erb +1 -1
- data/app/views/lookbook/components/_preview.html.erb +17 -11
- data/app/views/lookbook/components/_sidebar.html.erb +69 -0
- data/app/views/lookbook/error.html.erb +31 -1
- data/app/views/lookbook/pages/not_found.html.erb +15 -0
- data/app/views/lookbook/pages/show.html.erb +71 -0
- data/app/views/lookbook/previews/error.html.erb +1 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_select.html.erb +0 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_text.html.erb +0 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_textarea.html.erb +0 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_toggle.html.erb +0 -0
- data/app/views/lookbook/{not_found.html.erb → previews/not_found.html.erb} +2 -2
- data/app/views/lookbook/{panels → previews/panels}/_notes.html.erb +2 -2
- data/app/views/lookbook/{panels → previews/panels}/_output.html.erb +0 -0
- data/app/views/lookbook/{panels → previews/panels}/_params.html.erb +0 -0
- data/app/views/lookbook/{panels → previews/panels}/_preview.html.erb +0 -0
- data/app/views/lookbook/{panels → previews/panels}/_source.html.erb +0 -0
- data/app/views/lookbook/{show.html.erb → previews/show.html.erb} +0 -0
- data/config/routes.rb +9 -4
- data/lib/lookbook/code_formatter.rb +22 -1
- data/lib/lookbook/code_inspector.rb +73 -0
- data/lib/lookbook/collection.rb +110 -8
- data/lib/lookbook/engine.rb +63 -37
- data/lib/lookbook/error.rb +52 -0
- data/lib/lookbook/features.rb +1 -1
- data/lib/lookbook/markdown.rb +31 -0
- data/lib/lookbook/page.rb +158 -0
- data/lib/lookbook/page_collection.rb +11 -0
- data/lib/lookbook/parser.rb +2 -0
- data/lib/lookbook/preview.rb +111 -57
- data/lib/lookbook/preview_collection.rb +15 -0
- data/lib/lookbook/preview_example.rb +27 -29
- data/lib/lookbook/preview_group.rb +12 -6
- data/lib/lookbook/utils.rb +74 -0
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook.rb +19 -1
- data/public/lookbook-assets/css/app.css +1 -1
- data/public/lookbook-assets/css/app.css.map +1 -1
- data/public/lookbook-assets/js/app.js +1 -1
- data/public/lookbook-assets/js/app.js.map +1 -1
- data/public/lookbook-assets/js/embed.js +2 -0
- data/public/lookbook-assets/js/embed.js.map +1 -0
- metadata +48 -19
- data/app/assets/lookbook/js/lib/utils.js +0 -3
- data/app/views/layouts/lookbook/app.html.erb +0 -60
- data/lib/lookbook/taggable.rb +0 -46
@@ -0,0 +1,158 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class Page
|
3
|
+
include Utils
|
4
|
+
|
5
|
+
FRONTMATTER_FIELDS = [
|
6
|
+
:id,
|
7
|
+
:label,
|
8
|
+
:title,
|
9
|
+
:hidden,
|
10
|
+
:landing,
|
11
|
+
:position,
|
12
|
+
:markdown,
|
13
|
+
:header,
|
14
|
+
:footer,
|
15
|
+
:data
|
16
|
+
]
|
17
|
+
|
18
|
+
attr_reader :errors
|
19
|
+
|
20
|
+
def initialize(path, base_path)
|
21
|
+
@pathname = Pathname.new path
|
22
|
+
@base_path = base_path
|
23
|
+
@errors = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def path
|
27
|
+
rel_path = @pathname.relative_path_from(@base_path)
|
28
|
+
(rel_path.dirname.to_s == "." ? name : "#{rel_path.dirname}/#{name}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def lookup_path
|
32
|
+
@lookup_path ||= to_lookup_path(path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def full_path
|
36
|
+
Rails.root.join(@pathname.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def name
|
40
|
+
remove_position_prefix(path_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def hidden?
|
44
|
+
options[:hidden] == true
|
45
|
+
end
|
46
|
+
|
47
|
+
def markdown?
|
48
|
+
options[:markdown] == true
|
49
|
+
end
|
50
|
+
|
51
|
+
def header?
|
52
|
+
options[:header] == true
|
53
|
+
end
|
54
|
+
|
55
|
+
def footer?
|
56
|
+
options[:footer] == true
|
57
|
+
end
|
58
|
+
|
59
|
+
def get(key)
|
60
|
+
options[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
def content
|
64
|
+
@content ||= strip_frontmatter(file_contents)
|
65
|
+
end
|
66
|
+
|
67
|
+
def matchers
|
68
|
+
normalize_matchers(label)
|
69
|
+
end
|
70
|
+
|
71
|
+
def hierarchy_depth
|
72
|
+
path.split("/").size
|
73
|
+
end
|
74
|
+
|
75
|
+
def parent_collections_names
|
76
|
+
File.dirname(path).split("/")
|
77
|
+
end
|
78
|
+
|
79
|
+
def type
|
80
|
+
:page
|
81
|
+
end
|
82
|
+
|
83
|
+
def method_missing(method_name, *args, &block)
|
84
|
+
if args.none? && !block
|
85
|
+
options[method_name]
|
86
|
+
else
|
87
|
+
super
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def respond_to_missing?(method_name, include_private = false)
|
92
|
+
FRONTMATTER_FIELDS.include? method_name
|
93
|
+
end
|
94
|
+
|
95
|
+
protected
|
96
|
+
|
97
|
+
def file_contents
|
98
|
+
File.read(full_path)
|
99
|
+
end
|
100
|
+
|
101
|
+
def options
|
102
|
+
return @options if @options
|
103
|
+
begin
|
104
|
+
frontmatter = (get_frontmatter(file_contents) || {}).deep_symbolize_keys
|
105
|
+
rescue => exception
|
106
|
+
frontmatter = {}
|
107
|
+
@errors.push(Lookbook::Error.new(exception, {
|
108
|
+
title: "YAML frontmatter parsing error",
|
109
|
+
file_name: @pathname.to_s,
|
110
|
+
line_number: nil
|
111
|
+
}))
|
112
|
+
end
|
113
|
+
options = Lookbook.config.page_options.deep_merge(frontmatter).with_indifferent_access
|
114
|
+
options[:id] = options[:id] ? generate_id(options[:id]) : generate_id(lookup_path)
|
115
|
+
options[:label] ||= name.titleize
|
116
|
+
options[:title] ||= options[:label]
|
117
|
+
options[:hidden] ||= false
|
118
|
+
options[:landing] ||= false
|
119
|
+
options[:position] = options[:position] ? options[:position].to_i : get_position_prefix(path_name)
|
120
|
+
options[:markdown] ||= markdown_file?
|
121
|
+
options[:header] = true unless options.key? :header
|
122
|
+
options[:footer] = true unless options.key? :footer
|
123
|
+
@options ||= options
|
124
|
+
end
|
125
|
+
|
126
|
+
def path_name
|
127
|
+
@pathname.basename(@pathname.extname).to_s.gsub(/\.(html|md)$/, "")
|
128
|
+
end
|
129
|
+
|
130
|
+
def markdown_file?
|
131
|
+
@pathname.basename(@pathname.extname).to_s.end_with?(".md")
|
132
|
+
end
|
133
|
+
|
134
|
+
class << self
|
135
|
+
def find(path)
|
136
|
+
all.find { |p| p.lookup_path == path }
|
137
|
+
end
|
138
|
+
|
139
|
+
def exists?(path)
|
140
|
+
!!find(path)
|
141
|
+
end
|
142
|
+
|
143
|
+
def all
|
144
|
+
pages = Array(page_paths).map do |dir|
|
145
|
+
Dir["#{dir}/**/*.html.*", "#{dir}/**/*.md.*"].sort.map do |page|
|
146
|
+
Lookbook::Page.new(page, dir)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
sorted_pages = pages.flatten.uniq { |p| p.path }.sort_by { |page| [page.position, page.label] }
|
150
|
+
PageCollection.new(sorted_pages)
|
151
|
+
end
|
152
|
+
|
153
|
+
def page_paths
|
154
|
+
Lookbook.config.page_paths.filter { |dir| Dir.exist? dir }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/lookbook/parser.rb
CHANGED
@@ -28,6 +28,8 @@ module Lookbook
|
|
28
28
|
YARD::Tags::Library.define_tag("Hidden status", :hidden)
|
29
29
|
YARD::Tags::Library.define_tag("Label", :label)
|
30
30
|
YARD::Tags::Library.define_tag("Display", :display)
|
31
|
+
YARD::Tags::Library.define_tag("Position", :position)
|
32
|
+
YARD::Tags::Library.define_tag("ID", :id)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/lookbook/preview.rb
CHANGED
@@ -1,113 +1,167 @@
|
|
1
1
|
module Lookbook
|
2
|
-
|
3
|
-
include
|
2
|
+
class Preview
|
3
|
+
include Utils
|
4
|
+
|
5
|
+
delegate :name, :render_args, to: :@preview
|
6
|
+
delegate :position, :group, :notes, :hidden?, to: :@preview_inspector
|
7
|
+
|
8
|
+
def initialize(preview)
|
9
|
+
@preview = preview
|
10
|
+
@preview_inspector = CodeInspector.new(@preview.name)
|
11
|
+
end
|
4
12
|
|
5
13
|
def id
|
6
|
-
|
14
|
+
@preview_inspector&.id || generate_id(lookup_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def preview_class
|
18
|
+
@preview.name
|
7
19
|
end
|
8
20
|
|
9
|
-
|
10
|
-
|
11
|
-
super.presence || lookbook_path.split("/").last.titleize
|
21
|
+
def label
|
22
|
+
@preview_inspector&.label&.presence || lookup_path.split("/").last.titleize
|
12
23
|
end
|
13
24
|
|
14
|
-
def
|
25
|
+
def type
|
15
26
|
:preview
|
16
27
|
end
|
17
28
|
|
18
|
-
def
|
19
|
-
|
29
|
+
def example(example_name)
|
30
|
+
examples.find { |m| m.name == example_name.to_s }
|
20
31
|
end
|
21
32
|
|
22
|
-
def
|
23
|
-
return @
|
24
|
-
public_methods = public_instance_methods(false)
|
25
|
-
public_method_objects =
|
26
|
-
examples = public_method_objects.map { |m| PreviewExample.new(m.name.to_s, self) }
|
33
|
+
def examples
|
34
|
+
return @examples if @examples.present?
|
35
|
+
public_methods = @preview.public_instance_methods(false)
|
36
|
+
public_method_objects = @preview_inspector&.methods&.filter { |m| public_methods.include?(m.name) }
|
37
|
+
examples = (public_method_objects || []).map { |m| PreviewExample.new(m.name.to_s, self) }
|
27
38
|
sorted = Lookbook.config.sort_examples ? examples.sort_by(&:label) : examples
|
28
|
-
@
|
29
|
-
if
|
39
|
+
@examples = []
|
40
|
+
if @preview_inspector&.groups&.any?
|
30
41
|
sorted.group_by { |m| m.group }.each do |name, examples|
|
31
42
|
if name.nil?
|
32
|
-
@
|
43
|
+
@examples += examples
|
33
44
|
else
|
34
|
-
name =
|
35
|
-
@
|
45
|
+
name = label if name.strip == ""
|
46
|
+
@examples << PreviewGroup.new(name.underscore, self, examples)
|
36
47
|
end
|
37
48
|
end
|
38
49
|
else
|
39
|
-
@
|
50
|
+
@examples = sorted
|
40
51
|
end
|
41
|
-
@
|
52
|
+
@examples = @examples.compact
|
42
53
|
end
|
43
54
|
|
44
|
-
|
45
|
-
|
46
|
-
def lookbook_name
|
47
|
-
name.chomp("ComponentPreview").chomp("Component::Preview").chomp("::Preview").chomp("::")
|
55
|
+
def default_example
|
56
|
+
examples.first
|
48
57
|
end
|
49
58
|
|
50
|
-
|
51
|
-
|
52
|
-
def lookbook_path
|
53
|
-
lookbook_name.underscore
|
59
|
+
def path
|
60
|
+
preview_class_name(preview_class_basename(name))
|
54
61
|
end
|
55
62
|
|
56
|
-
|
57
|
-
# Examples::FooBarComponent::Preview -> "/Users/myname/myapp/test/components/previews/examples/foo_bar/component_preview.rb"
|
58
|
-
def lookbook_full_path
|
63
|
+
def full_path
|
59
64
|
base_path = Array(preview_paths).detect do |preview_path|
|
60
65
|
Dir["#{preview_path}/#{name.underscore}.rb"].first
|
61
66
|
end
|
62
67
|
Pathname.new(Dir["#{base_path}/#{name.underscore}.rb"].first)
|
63
68
|
end
|
64
69
|
|
65
|
-
def
|
66
|
-
|
70
|
+
def preview_paths
|
71
|
+
ViewComponent::Preview.preview_paths
|
67
72
|
end
|
68
73
|
|
69
|
-
def
|
70
|
-
|
74
|
+
def parent_collections_names
|
75
|
+
File.dirname(path).split("/")
|
71
76
|
end
|
72
77
|
|
73
|
-
def
|
74
|
-
|
78
|
+
def hierarchy_depth
|
79
|
+
path.split("/").size
|
75
80
|
end
|
76
81
|
|
77
|
-
def
|
78
|
-
|
82
|
+
def layout
|
83
|
+
@preview.instance_variable_get(:@layout)
|
79
84
|
end
|
80
85
|
|
81
86
|
def display_params
|
82
|
-
Lookbook.config.preview_display_params.deep_merge(
|
87
|
+
Lookbook.config.preview_display_params.deep_merge(@preview_inspector&.display_params)
|
83
88
|
end
|
84
89
|
|
85
90
|
class << self
|
86
|
-
def all
|
87
|
-
ViewComponent::Preview.all.sort_by(&:label)
|
88
|
-
end
|
89
|
-
|
90
91
|
def find(path)
|
91
|
-
all.find { |p| p.
|
92
|
+
all.find { |p| p.lookup_path == path }
|
92
93
|
end
|
93
94
|
|
94
95
|
def exists?(path)
|
95
96
|
!!find(path)
|
96
97
|
end
|
97
|
-
end
|
98
98
|
|
99
|
-
|
99
|
+
def all
|
100
|
+
previews = load_previews.map do |p|
|
101
|
+
new(p)
|
102
|
+
rescue
|
103
|
+
Rails.logger.error "[lookbook] error instantiating preview\n#{exception.full_message}"
|
104
|
+
end
|
105
|
+
|
106
|
+
sorted_previews = previews.compact.sort_by { |preview| [preview.position, preview.label] }
|
107
|
+
PreviewCollection.new(sorted_previews)
|
108
|
+
end
|
109
|
+
|
110
|
+
def errors
|
111
|
+
@errors || []
|
112
|
+
end
|
100
113
|
|
101
|
-
|
102
|
-
|
114
|
+
def reload
|
115
|
+
load_previews
|
116
|
+
end
|
117
|
+
|
118
|
+
protected
|
119
|
+
|
120
|
+
def reset_files_data
|
121
|
+
@loaded_files = []
|
122
|
+
@errors = []
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_previews
|
126
|
+
reset_files_data if @loaded_files.nil?
|
127
|
+
require_preview_files if @errors.any?
|
128
|
+
|
129
|
+
preview_classes = ViewComponent::Preview.descendants
|
130
|
+
if preview_files.size > preview_classes.size
|
131
|
+
require_preview_files
|
132
|
+
end
|
133
|
+
|
134
|
+
ViewComponent::Preview.descendants.filter { |klass| @loaded_files.include? "#{klass.name.underscore}.rb" }
|
135
|
+
end
|
136
|
+
|
137
|
+
def require_preview_files
|
138
|
+
reset_files_data
|
139
|
+
preview_files.each do |file|
|
140
|
+
require_dependency(file[:path])
|
141
|
+
@loaded_files.push(file[:rel_path])
|
142
|
+
rescue => exception
|
143
|
+
Rails.logger.error "[lookbook] preview error\n#{exception.full_message}\n"
|
144
|
+
@errors.push(Lookbook::Error.new(exception, {
|
145
|
+
title: "Preview #{exception.class}",
|
146
|
+
file_name: file[:rel_path]
|
147
|
+
}))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def preview_files
|
152
|
+
files = Array(Lookbook.config.preview_paths).map do |preview_path|
|
153
|
+
Dir["#{preview_path}/**/*_preview.rb"].map do |path|
|
154
|
+
{
|
155
|
+
path: path,
|
156
|
+
base_path: preview_path,
|
157
|
+
rel_path: Pathname(path).relative_path_from(preview_path).to_s
|
158
|
+
}
|
159
|
+
end
|
160
|
+
end
|
161
|
+
files.flatten
|
162
|
+
end
|
103
163
|
end
|
104
164
|
|
105
|
-
alias_method :
|
106
|
-
alias_method :notes, :lookbook_notes
|
107
|
-
alias_method :hidden?, :lookbook_hidden?
|
108
|
-
alias_method :type, :lookbook_type
|
109
|
-
alias_method :example, :lookbook_example
|
110
|
-
alias_method :get_examples, :lookbook_examples
|
111
|
-
alias_method :hierarchy_depth, :lookbook_hierarchy_depth
|
165
|
+
alias_method :lookup_path, :path
|
112
166
|
end
|
113
167
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class PreviewCollection < Collection
|
3
|
+
def id
|
4
|
+
generate_id("preview-collection", lookup_path || "root")
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_example(path)
|
8
|
+
Lookbook::PreviewExample.all.find { |e| e.lookup_path == path }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.describe_as
|
12
|
+
"previews"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,38 +1,34 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class PreviewExample
|
3
|
-
include
|
3
|
+
include Utils
|
4
4
|
|
5
|
-
attr_reader :name
|
5
|
+
attr_reader :name, :preview
|
6
|
+
delegate :params, :position, :group, :notes, :hidden?, to: :@example_inspector
|
6
7
|
|
7
8
|
def initialize(name, preview)
|
8
9
|
@name = name
|
9
10
|
@preview = preview
|
11
|
+
@example_inspector = CodeInspector.new("#{@preview.name}##{name}")
|
10
12
|
end
|
11
13
|
|
12
14
|
def id
|
13
|
-
|
15
|
+
generate_id(@preview.id, name)
|
14
16
|
end
|
15
17
|
|
16
18
|
def path
|
17
|
-
"#{@preview.
|
19
|
+
"#{@preview.path}/#{name}"
|
18
20
|
end
|
19
21
|
|
20
22
|
def label
|
21
|
-
|
23
|
+
@example_inspector.label.presence || name.titleize
|
22
24
|
end
|
23
25
|
|
24
26
|
def display_params
|
25
|
-
@preview.display_params.merge(
|
26
|
-
end
|
27
|
-
|
28
|
-
def params
|
29
|
-
@params || code_object&.tags("param")&.map do |param|
|
30
|
-
Lookbook::Params.build_param(param, parameter_defaults[param.name])
|
31
|
-
end
|
27
|
+
@preview.display_params.merge(@example_inspector.display_params)
|
32
28
|
end
|
33
29
|
|
34
30
|
def method_source
|
35
|
-
|
31
|
+
@example_inspector.source.split("\n")[1..-2].join("\n").strip_heredoc
|
36
32
|
end
|
37
33
|
|
38
34
|
def source_lang
|
@@ -52,24 +48,14 @@ module Lookbook
|
|
52
48
|
end
|
53
49
|
|
54
50
|
def matchers
|
55
|
-
|
51
|
+
normalize_matchers(@preview.label, label)
|
56
52
|
end
|
57
53
|
|
58
54
|
def hierarchy_depth
|
59
|
-
@preview.
|
55
|
+
@preview.hierarchy_depth + 1
|
60
56
|
end
|
61
57
|
|
62
|
-
|
63
|
-
|
64
|
-
def parameter_defaults
|
65
|
-
@parameter_defaults || code_object&.parameters&.map do |param_str|
|
66
|
-
Lookbook::Params.parse_method_param_str(param_str)
|
67
|
-
end&.compact&.to_h
|
68
|
-
end
|
69
|
-
|
70
|
-
def taggable_object_path
|
71
|
-
"#{@preview.name}##{name}"
|
72
|
-
end
|
58
|
+
protected
|
73
59
|
|
74
60
|
def full_template_path(template_path)
|
75
61
|
base_path = Array(Lookbook.config.preview_paths).detect do |p|
|
@@ -78,8 +64,20 @@ module Lookbook
|
|
78
64
|
Pathname.new(Dir["#{base_path}/#{template_path}.html.*"].first)
|
79
65
|
end
|
80
66
|
|
81
|
-
|
82
|
-
|
83
|
-
|
67
|
+
class << self
|
68
|
+
def all
|
69
|
+
Preview.all.map { |preview| preview.examples }.flatten
|
70
|
+
end
|
71
|
+
|
72
|
+
def find(path)
|
73
|
+
all.find { |p| p.lookup_path == path }
|
74
|
+
end
|
75
|
+
|
76
|
+
def exists?(path)
|
77
|
+
!!find(path)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
alias_method :lookup_path, :path
|
84
82
|
end
|
85
83
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class PreviewGroup
|
3
|
-
include
|
3
|
+
include Utils
|
4
4
|
|
5
|
-
attr_reader :name, :examples
|
5
|
+
attr_reader :name, :examples, :preview
|
6
6
|
|
7
7
|
def initialize(name, preview, examples)
|
8
8
|
@name = name
|
@@ -11,11 +11,11 @@ module Lookbook
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def id
|
14
|
-
|
14
|
+
generate_id(lookup_path)
|
15
15
|
end
|
16
16
|
|
17
17
|
def path
|
18
|
-
"#{@preview.
|
18
|
+
"#{@preview.path}/#{name}"
|
19
19
|
end
|
20
20
|
|
21
21
|
def label
|
@@ -38,12 +38,18 @@ module Lookbook
|
|
38
38
|
false
|
39
39
|
end
|
40
40
|
|
41
|
+
def position
|
42
|
+
10000
|
43
|
+
end
|
44
|
+
|
41
45
|
def matchers
|
42
|
-
|
46
|
+
normalize_matchers(@preview.label, label)
|
43
47
|
end
|
44
48
|
|
45
49
|
def hierarchy_depth
|
46
|
-
@preview.
|
50
|
+
@preview.hierarchy_depth + 1
|
47
51
|
end
|
52
|
+
|
53
|
+
alias_method :lookup_path, :path
|
48
54
|
end
|
49
55
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Lookbook
|
2
|
+
module Utils
|
3
|
+
POSITION_PREFIX_REGEX = /^(\d+?)[-_]/
|
4
|
+
FRONTMATTER_REGEX = /\A---(.|\n)*?---/
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
def generate_id(*args)
|
9
|
+
parts = args.map { |arg| arg.to_s.parameterize.underscore }
|
10
|
+
parts.join("-").tr("/", "-").tr("_", "-").delete_prefix("-").delete_suffix("-").gsub("--", "-")
|
11
|
+
end
|
12
|
+
|
13
|
+
def preview_class_basename(klass)
|
14
|
+
class_name(klass).to_s.chomp("ComponentPreview").chomp("Component::Preview").chomp("::Preview").chomp("Component").chomp("::")
|
15
|
+
end
|
16
|
+
|
17
|
+
def preview_class_name(klass)
|
18
|
+
preview_class_basename(klass).underscore
|
19
|
+
end
|
20
|
+
|
21
|
+
def class_name(klass)
|
22
|
+
klass.is_a?(Class) ? klass.name : klass
|
23
|
+
end
|
24
|
+
|
25
|
+
def normalize_matchers(*matchers)
|
26
|
+
matchers.flatten.map { |m| m.gsub(/\s/, "").downcase }
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_position_prefix(str)
|
30
|
+
parse_position_prefix(str).first
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_position_prefix(str)
|
34
|
+
parse_position_prefix(str).last
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_frontmatter(str)
|
38
|
+
parse_frontmatter(str).first
|
39
|
+
end
|
40
|
+
|
41
|
+
def strip_frontmatter(str)
|
42
|
+
parse_frontmatter(str).last
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_lookup_path(path)
|
46
|
+
path.split("/").map { |segment| remove_position_prefix(segment) }.join("/")
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_preview_path(*args)
|
50
|
+
args.flatten.map { |arg| preview_class_name(arg) }.join("/")
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def parse_frontmatter(content)
|
56
|
+
frontmatter = content.match(FRONTMATTER_REGEX)
|
57
|
+
if frontmatter.nil?
|
58
|
+
[{}, content]
|
59
|
+
else
|
60
|
+
[YAML.safe_load(frontmatter[0]), content.gsub(FRONTMATTER_REGEX, "")]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_position_prefix(str)
|
65
|
+
pos = str.match(POSITION_PREFIX_REGEX)
|
66
|
+
if pos.nil?
|
67
|
+
[10000, str]
|
68
|
+
else
|
69
|
+
cleaned_str = str.gsub(POSITION_PREFIX_REGEX, "")
|
70
|
+
[pos[1].to_i, cleaned_str]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/lookbook/version.rb
CHANGED
data/lib/lookbook.rb
CHANGED
@@ -5,16 +5,34 @@ require "lookbook/version"
|
|
5
5
|
module Lookbook
|
6
6
|
extend ActiveSupport::Autoload
|
7
7
|
|
8
|
+
autoload :Error, "lookbook/error"
|
9
|
+
autoload :Utils, "lookbook/utils"
|
8
10
|
autoload :Lang, "lookbook/lang"
|
9
11
|
autoload :Params, "lookbook/params"
|
12
|
+
autoload :Page, "lookbook/page"
|
13
|
+
autoload :PageCollection, "lookbook/page_collection"
|
10
14
|
autoload :Features, "lookbook/features"
|
11
15
|
autoload :Collection, "lookbook/collection"
|
12
16
|
autoload :Parser, "lookbook/parser"
|
13
17
|
autoload :Preview, "lookbook/preview"
|
18
|
+
autoload :PreviewCollection, "lookbook/preview_collection"
|
14
19
|
autoload :PreviewController, "lookbook/preview_controller"
|
15
20
|
autoload :PreviewExample, "lookbook/preview_example"
|
16
21
|
autoload :PreviewGroup, "lookbook/preview_group"
|
17
|
-
autoload :
|
22
|
+
autoload :CodeInspector, "lookbook/code_inspector"
|
18
23
|
autoload :NullLogger, "lookbook/null_logger"
|
19
24
|
autoload :CodeFormatter, "lookbook/code_formatter"
|
25
|
+
autoload :Markdown, "lookbook/markdown"
|
26
|
+
|
27
|
+
class << self
|
28
|
+
include Utils
|
29
|
+
|
30
|
+
def previews
|
31
|
+
Preview.all
|
32
|
+
end
|
33
|
+
|
34
|
+
def pages
|
35
|
+
Page.all
|
36
|
+
end
|
37
|
+
end
|
20
38
|
end
|