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.
- checksums.yaml +4 -4
- data/app/assets/lookbook/js/helpers/string.js +23 -1
- data/app/assets/lookbook/js/lookbook.js +0 -1
- data/app/components/lookbook/button/component.html.erb +2 -1
- data/app/components/lookbook/button/component.js +9 -0
- data/app/components/lookbook/display_options/editor/component.html.erb +13 -0
- data/app/components/lookbook/display_options/editor/component.rb +7 -0
- data/app/components/lookbook/display_options/field/component.css +33 -0
- data/app/components/lookbook/display_options/field/component.html.erb +8 -0
- data/app/components/lookbook/display_options/field/component.js +30 -0
- data/app/components/lookbook/display_options/field/component.rb +28 -0
- data/app/components/lookbook/inspector_panel/component.html.erb +1 -1
- data/app/components/lookbook/inspector_panel/component.rb +10 -11
- data/app/components/lookbook/params/editor/component.rb +6 -3
- data/app/components/lookbook/params/field/component.rb +1 -5
- data/app/components/lookbook/tab_panels/panel/component.html.erb +1 -1
- data/app/components/lookbook/tab_panels/panel/component.rb +1 -2
- data/app/components/lookbook/tabs/dropdown_tab/component.html.erb +1 -0
- data/app/components/lookbook/tabs/tab/component.html.erb +1 -0
- data/app/components/lookbook/viewport/component.html.erb +1 -1
- data/app/components/lookbook/viewport/component.rb +2 -1
- data/app/controllers/lookbook/previews_controller.rb +40 -29
- data/app/helpers/lookbook/preview_helper.rb +1 -1
- data/app/views/lookbook/previews/panels/_params.html.erb +1 -1
- data/app/views/lookbook/previews/panels/_preview.html.erb +9 -6
- data/app/views/lookbook/previews/show.html.erb +29 -11
- data/config/app.yml +36 -0
- data/config/hooks.yml +4 -0
- data/config/inputs.yml +48 -0
- data/config/panels.yml +30 -0
- data/config/routes.rb +1 -1
- data/config/tags.yml +29 -0
- data/lib/lookbook/engine.rb +40 -20
- data/lib/lookbook/markdown.rb +1 -11
- data/lib/lookbook/page.rb +1 -1
- data/lib/lookbook/params.rb +0 -7
- data/lib/lookbook/parser.rb +3 -10
- data/lib/lookbook/preview.rb +7 -3
- data/lib/lookbook/preview_example.rb +7 -3
- data/lib/lookbook/preview_group.rb +2 -2
- data/lib/lookbook/services/config_loader.rb +20 -0
- data/lib/lookbook/services/search_param_builder.rb +13 -0
- data/lib/lookbook/services/search_param_parser.rb +15 -0
- data/lib/lookbook/services/tags/key_value_tag_parser.rb +24 -0
- data/lib/lookbook/source_inspector.rb +10 -16
- data/lib/lookbook/stores/config_store.rb +80 -0
- data/lib/lookbook/stores/hook_store.rb +28 -0
- data/lib/lookbook/stores/input_store.rb +58 -0
- data/lib/lookbook/stores/panel_store.rb +141 -0
- data/lib/lookbook/stores/tag_store.rb +46 -0
- data/lib/lookbook/support/errors/config_error.rb +7 -0
- data/lib/lookbook/support/errors/lookbook_error.rb +21 -0
- data/lib/lookbook/support/errors/parser_error.rb +7 -0
- data/lib/lookbook/support/service.rb +7 -0
- data/lib/lookbook/support/store.rb +77 -0
- data/lib/lookbook/support/utils/attribute_utils.rb +9 -0
- data/lib/lookbook/support/utils/path_utils.rb +19 -0
- data/lib/lookbook/tags.rb +5 -14
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook.rb +43 -12
- data/public/lookbook-assets/css/lookbook.css +33 -0
- data/public/lookbook-assets/css/lookbook.css.map +1 -1
- data/public/lookbook-assets/js/lookbook.js +145 -4
- data/public/lookbook-assets/js/lookbook.js.map +1 -1
- metadata +29 -6
- data/lib/lookbook/config.rb +0 -278
- data/lib/lookbook/hooks.rb +0 -21
- data/lib/lookbook/panels.rb +0 -25
- data/lib/lookbook/store.rb +0 -34
data/config/panels.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
shared:
|
2
|
+
main:
|
3
|
+
- name: preview
|
4
|
+
partial: lookbook/previews/panels/preview
|
5
|
+
label: Preview
|
6
|
+
hotkey: v
|
7
|
+
|
8
|
+
- name: output
|
9
|
+
partial: lookbook/previews/panels/output
|
10
|
+
label: HTML
|
11
|
+
hotkey: h
|
12
|
+
|
13
|
+
drawer:
|
14
|
+
- name: source
|
15
|
+
partial: lookbook/previews/panels/source
|
16
|
+
label: Source
|
17
|
+
hotkey: s
|
18
|
+
copy: "->(data) { data.examples.map { |e| e.source }.join(\n) }"
|
19
|
+
|
20
|
+
- name: notes
|
21
|
+
partial: lookbook/previews/panels/notes
|
22
|
+
label: Notes
|
23
|
+
hotkey: n
|
24
|
+
disabled: ->(data) { data.examples.select { |e| e.notes.present? }.none? }
|
25
|
+
|
26
|
+
- name: params
|
27
|
+
partial: lookbook/previews/panels/params
|
28
|
+
label: Params
|
29
|
+
hotkey: p
|
30
|
+
disabled: ->(data) { data.preview.params.none? }
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Lookbook::Engine.routes.draw do
|
2
2
|
if Lookbook::Engine.websocket?
|
3
|
-
mount Lookbook::Engine.websocket =>
|
3
|
+
mount Lookbook::Engine.websocket => "/cable", :as => :cable
|
4
4
|
end
|
5
5
|
|
6
6
|
root to: "application#index", as: :lookbook_home
|
data/config/tags.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
shared:
|
2
|
+
hidden:
|
3
|
+
label: Hidden status
|
4
|
+
opts: {}
|
5
|
+
|
6
|
+
label:
|
7
|
+
label: Label
|
8
|
+
opts: {}
|
9
|
+
|
10
|
+
display:
|
11
|
+
label: Display
|
12
|
+
opts: {}
|
13
|
+
|
14
|
+
position:
|
15
|
+
label: Position
|
16
|
+
opts: {}
|
17
|
+
|
18
|
+
id:
|
19
|
+
label: Id
|
20
|
+
opts: {}
|
21
|
+
|
22
|
+
component:
|
23
|
+
label: Component
|
24
|
+
opts: {}
|
25
|
+
|
26
|
+
param:
|
27
|
+
label: Param
|
28
|
+
yard_parser: with_name
|
29
|
+
opts: {}
|
data/lib/lookbook/engine.rb
CHANGED
@@ -6,30 +6,33 @@ module Lookbook
|
|
6
6
|
class Engine < Rails::Engine
|
7
7
|
isolate_namespace Lookbook
|
8
8
|
|
9
|
-
config.autoload_paths << File.expand_path(
|
10
|
-
config.lookbook = Lookbook.config
|
9
|
+
config.autoload_paths << File.expand_path(root.join("app/components"))
|
11
10
|
|
12
11
|
initializer "lookbook.viewcomponent.config" do
|
13
|
-
config.
|
14
|
-
config.
|
12
|
+
Lookbook.config.preview_paths += config.view_component.preview_paths
|
13
|
+
Lookbook.config.preview_controller ||= config.view_component.preview_controller
|
15
14
|
|
16
|
-
config.
|
15
|
+
Lookbook.config.components_path = config.view_component.view_component_path if config.view_component.view_component_path.present?
|
17
16
|
|
18
|
-
config.
|
19
|
-
config.
|
17
|
+
Lookbook.config.listen_paths += Lookbook.config.preview_paths
|
18
|
+
Lookbook.config.listen_paths << Lookbook.config.components_path
|
20
19
|
end
|
21
20
|
|
22
21
|
initializer "lookbook.parser.tags" do
|
23
|
-
Lookbook::Parser.define_tags(
|
22
|
+
Lookbook::Parser.define_tags(Engine.tags)
|
24
23
|
end
|
25
24
|
|
26
25
|
initializer "lookbook.assets.serve" do
|
27
26
|
config.app_middleware.use(
|
28
27
|
Rack::Static,
|
29
|
-
urls: ["/lookbook-assets"], root:
|
28
|
+
urls: ["/lookbook-assets"], root: root.join("public").to_s
|
30
29
|
)
|
31
30
|
end
|
32
31
|
|
32
|
+
config.before_configuration do
|
33
|
+
config.lookbook = Lookbook.config
|
34
|
+
end
|
35
|
+
|
33
36
|
config.after_initialize do
|
34
37
|
@preview_controller = Lookbook.config.preview_controller.constantize
|
35
38
|
@preview_controller.include(Lookbook::PreviewController)
|
@@ -46,22 +49,22 @@ module Lookbook
|
|
46
49
|
end
|
47
50
|
else
|
48
51
|
# Fallback for older Rails versions - don't start listeners if running in a rake task.
|
49
|
-
unless
|
52
|
+
unless prevent_listening?
|
50
53
|
init_listeners
|
51
54
|
end
|
52
55
|
end
|
53
56
|
|
54
57
|
parser.parse do
|
55
|
-
|
58
|
+
run_hooks(:after_initialize)
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
59
62
|
at_exit do
|
60
|
-
if
|
63
|
+
if listeners.any?
|
61
64
|
Lookbook.logger.debug "Stopping listeners"
|
62
|
-
|
65
|
+
stop_listeners
|
63
66
|
end
|
64
|
-
|
67
|
+
run_hooks(:before_exit)
|
65
68
|
end
|
66
69
|
|
67
70
|
class << self
|
@@ -69,7 +72,7 @@ module Lookbook
|
|
69
72
|
config = Lookbook.config
|
70
73
|
return unless config.listen == true
|
71
74
|
|
72
|
-
listen_paths = config.listen_paths
|
75
|
+
listen_paths = PathUtils.normalize_all(config.listen_paths)
|
73
76
|
if listen_paths.any?
|
74
77
|
preview_listener = Listen.to(*listen_paths,
|
75
78
|
only: /\.(#{config.listen_extensions.join("|")})$/,
|
@@ -82,7 +85,7 @@ module Lookbook
|
|
82
85
|
register_listener(preview_listener)
|
83
86
|
end
|
84
87
|
|
85
|
-
page_paths = config.page_paths
|
88
|
+
page_paths = PathUtils.normalize_all(config.page_paths)
|
86
89
|
if page_paths.any?
|
87
90
|
page_listener = Listen.to(*page_paths,
|
88
91
|
only: /\.(html.*|md.*)$/,
|
@@ -117,7 +120,7 @@ module Lookbook
|
|
117
120
|
end
|
118
121
|
|
119
122
|
def websocket_mount_path
|
120
|
-
"#{mounted_path}
|
123
|
+
"#{mounted_path}/cable".gsub("//", "/") if websocket?
|
121
124
|
end
|
122
125
|
|
123
126
|
def websocket?
|
@@ -125,11 +128,12 @@ module Lookbook
|
|
125
128
|
end
|
126
129
|
|
127
130
|
def mounted_path
|
128
|
-
|
131
|
+
routes.find_script_name({})
|
129
132
|
end
|
130
133
|
|
131
134
|
def parser
|
132
|
-
|
135
|
+
preview_paths = PathUtils.normalize_all(Lookbook.config.preview_paths)
|
136
|
+
@parser ||= Lookbook::Parser.new(preview_paths)
|
133
137
|
end
|
134
138
|
|
135
139
|
def log_level
|
@@ -159,7 +163,7 @@ module Lookbook
|
|
159
163
|
end
|
160
164
|
|
161
165
|
def run_hooks(event_name, *args)
|
162
|
-
|
166
|
+
hooks.for_event(event_name).each do |hook|
|
163
167
|
hook.call(Lookbook, *args)
|
164
168
|
end
|
165
169
|
end
|
@@ -180,6 +184,22 @@ module Lookbook
|
|
180
184
|
end
|
181
185
|
end
|
182
186
|
|
187
|
+
def panels
|
188
|
+
@panels ||= PanelStore.init_from_config
|
189
|
+
end
|
190
|
+
|
191
|
+
def inputs
|
192
|
+
@inputs ||= InputStore.init_from_config
|
193
|
+
end
|
194
|
+
|
195
|
+
def tags
|
196
|
+
@tags ||= TagStore.init_from_config
|
197
|
+
end
|
198
|
+
|
199
|
+
def hooks
|
200
|
+
@hooks ||= HookStore.init_from_config
|
201
|
+
end
|
202
|
+
|
183
203
|
attr_reader :preview_controller
|
184
204
|
end
|
185
205
|
end
|
data/lib/lookbook/markdown.rb
CHANGED
@@ -2,19 +2,9 @@ require "redcarpet"
|
|
2
2
|
|
3
3
|
module Lookbook
|
4
4
|
class Markdown
|
5
|
-
DEFAULT_OPTIONS = {
|
6
|
-
tables: true,
|
7
|
-
fenced_code_blocks: true,
|
8
|
-
disable_indented_code_blocks: true,
|
9
|
-
strikethrough: true,
|
10
|
-
highlight: true,
|
11
|
-
with_toc_data: true,
|
12
|
-
lax_spacing: true
|
13
|
-
}
|
14
|
-
|
15
5
|
def self.render(text)
|
16
6
|
Utils.strip_action_view_annotations!(text)
|
17
|
-
markdown = Redcarpet::Markdown.new(Renderer, Lookbook.config.markdown_options)
|
7
|
+
markdown = Redcarpet::Markdown.new(Renderer, Lookbook.config.markdown_options.to_h)
|
18
8
|
markdown.render(text).html_safe
|
19
9
|
end
|
20
10
|
|
data/lib/lookbook/page.rb
CHANGED
data/lib/lookbook/params.rb
CHANGED
@@ -117,13 +117,6 @@ module Lookbook
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
def inputs
|
121
|
-
@inputs ||= Lookbook.config.preview_param_inputs.map do |name, config|
|
122
|
-
config = {partial: config} if config.is_a?(String)
|
123
|
-
[name, {input_options: {}}.merge(config)]
|
124
|
-
end.to_h
|
125
|
-
end
|
126
|
-
|
127
120
|
private
|
128
121
|
|
129
122
|
def guess_input(value_type, default)
|
data/lib/lookbook/parser.rb
CHANGED
@@ -32,16 +32,9 @@ module Lookbook
|
|
32
32
|
end
|
33
33
|
|
34
34
|
class << self
|
35
|
-
def define_tags(
|
36
|
-
|
37
|
-
|
38
|
-
YARD::Tags::Library.define_tag("Display", :display)
|
39
|
-
YARD::Tags::Library.define_tag("Position", :position)
|
40
|
-
YARD::Tags::Library.define_tag("ID", :id)
|
41
|
-
YARD::Tags::Library.define_tag("Component", :component)
|
42
|
-
YARD::Tags::Library.define_tag("Param", :param, :with_name)
|
43
|
-
custom.each do |name, opts|
|
44
|
-
YARD::Tags::Library.define_tag(name.to_s.titleize, name)
|
35
|
+
def define_tags(tags = nil)
|
36
|
+
tags.to_h.each do |name, tag|
|
37
|
+
YARD::Tags::Library.define_tag(tag[:label], name, tag[:yard_parser])
|
45
38
|
end
|
46
39
|
end
|
47
40
|
end
|
data/lib/lookbook/preview.rb
CHANGED
@@ -70,7 +70,7 @@ module Lookbook
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def full_path
|
73
|
-
base_path =
|
73
|
+
base_path = preview_paths.detect do |preview_path|
|
74
74
|
Dir["#{preview_path}/#{rel_path}"].first
|
75
75
|
end
|
76
76
|
Pathname.new(Dir["#{base_path}/#{rel_path}"].first)
|
@@ -92,8 +92,8 @@ module Lookbook
|
|
92
92
|
@preview.instance_variable_get(:@layout)
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
Lookbook.config.
|
95
|
+
def display_options
|
96
|
+
Lookbook.config.preview_display_options.deep_merge(@preview_inspector&.display_options)
|
97
97
|
end
|
98
98
|
|
99
99
|
def collapsible?
|
@@ -111,6 +111,10 @@ module Lookbook
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
def preview_paths
|
115
|
+
PathUtils.normalize_all(Lookbook.config.preview_paths)
|
116
|
+
end
|
117
|
+
|
114
118
|
protected
|
115
119
|
|
116
120
|
@preview_objects = nil
|
@@ -22,8 +22,8 @@ module Lookbook
|
|
22
22
|
@example_inspector.label.presence || name.titleize
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
@preview.
|
25
|
+
def display_options
|
26
|
+
@preview.display_options.merge(@example_inspector.display_options)
|
27
27
|
end
|
28
28
|
|
29
29
|
def method_source
|
@@ -63,13 +63,17 @@ module Lookbook
|
|
63
63
|
|
64
64
|
def full_template_path(template_path)
|
65
65
|
template_path = strip_ext template_path
|
66
|
-
base_path =
|
66
|
+
base_path = preview_paths.detect do |p|
|
67
67
|
Dir["#{p}/#{template_path}.html.*"].first
|
68
68
|
end
|
69
69
|
path = Dir["#{base_path}/#{template_path}.html.*"].first
|
70
70
|
path ? Pathname.new(path) : nil
|
71
71
|
end
|
72
72
|
|
73
|
+
def preview_paths
|
74
|
+
PathUtils.normalize_all(Lookbook.config.preview_paths)
|
75
|
+
end
|
76
|
+
|
73
77
|
class << self
|
74
78
|
def all
|
75
79
|
Preview.all.map { |preview| preview.examples }.flatten
|
@@ -25,10 +25,10 @@ module Lookbook
|
|
25
25
|
examples.map(&:params).flatten.uniq { |param| param[:name] }
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def display_options
|
29
29
|
merged = {}
|
30
30
|
examples.reverse.map do |example|
|
31
|
-
merged.merge! example.
|
31
|
+
merged.merge! example.display_options
|
32
32
|
end
|
33
33
|
merged
|
34
34
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class ConfigLoader < Service
|
3
|
+
attr_reader :file, :env
|
4
|
+
|
5
|
+
def initialize(path, env: Rails.env)
|
6
|
+
@file = Engine.root.join(path)
|
7
|
+
@env = env.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
if file.exist?
|
12
|
+
config = YAML.load_file(file).deep_symbolize_keys
|
13
|
+
env_config = config[:shared].to_h.deep_merge(config[env].to_h)
|
14
|
+
Store.new(env_config)
|
15
|
+
else
|
16
|
+
raise ConfigError.new("Could not load configuration. No such file - #{file}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class SearchParamParser < Service
|
3
|
+
attr_reader :param_value
|
4
|
+
|
5
|
+
def initialize(param_value)
|
6
|
+
@param_value = param_value.strip
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
pairs_str = param_value.split("|")
|
11
|
+
pairs = pairs_str.map { [*_1.split(":").map(&:strip)] }
|
12
|
+
pairs.to_h.symbolize_keys
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class KeyValueTagParser < Service
|
3
|
+
KEY_VALUE_REGEX = /^([^\s]+)\s+(.+)$/
|
4
|
+
|
5
|
+
attr_reader :text
|
6
|
+
|
7
|
+
def initialize(text)
|
8
|
+
@text = text.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
text.strip.match(KEY_VALUE_REGEX) do |matches|
|
13
|
+
key = matches[1]
|
14
|
+
value = begin
|
15
|
+
YAML.safe_load(matches[2] || "~")
|
16
|
+
rescue ::Psych::SyntaxError => exception
|
17
|
+
raise ParserError.new("Invalid YAML in tag text '#{@text}'", scope: "key_value_tag.parser", original: exception)
|
18
|
+
end
|
19
|
+
return [key, value]
|
20
|
+
end
|
21
|
+
raise ParserError.new("Could not parse key:value pair from '#{@text}'", scope: "key_value_tag.parser")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -52,22 +52,16 @@ module Lookbook
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
56
|
-
return @
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
Lookbook.logger.error("\n👀 [Lookbook] Invalid JSON in @display tag.\n👀 [Lookbook] (#{err})\n")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
@display_params
|
55
|
+
def display_options
|
56
|
+
return @display_options unless @display_options.nil?
|
57
|
+
tags = code_object.tags(:display).to_a
|
58
|
+
pairs = tags.map { KeyValueTagParser.call(_1.text) }
|
59
|
+
|
60
|
+
# dynamic params set at the entity level are
|
61
|
+
# not (yet) supported so filter them out.
|
62
|
+
pairs.select! { |pair| !pair[1].is_a?(Array) && !pair[1].is_a?(Hash) }
|
63
|
+
|
64
|
+
pairs.to_h.symbolize_keys
|
71
65
|
end
|
72
66
|
|
73
67
|
def parameter_defaults
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class ConfigStore
|
3
|
+
CONFIG_FILE = "config/app.yml"
|
4
|
+
|
5
|
+
delegate_missing_to :store
|
6
|
+
attr_reader :store
|
7
|
+
|
8
|
+
def initialize(config = nil)
|
9
|
+
@store = Store.new(config, recursive: true)
|
10
|
+
end
|
11
|
+
|
12
|
+
def project_name=(name)
|
13
|
+
store[:project_name] = name == false ? nil : name
|
14
|
+
end
|
15
|
+
|
16
|
+
def page_paths=(paths = nil)
|
17
|
+
store[:page_paths] ||= []
|
18
|
+
store[:page_paths] += paths.to_a
|
19
|
+
end
|
20
|
+
|
21
|
+
def preview_paths=(paths = nil)
|
22
|
+
store[:preview_paths] ||= []
|
23
|
+
store[:preview_paths] += paths.to_a
|
24
|
+
end
|
25
|
+
|
26
|
+
def preview_display_params
|
27
|
+
Lookbook.logger.warn "The `preview_display_params` config option has been renamed to `preview_display_options` and will be removed in v2.0"
|
28
|
+
store[:preview_display_options]
|
29
|
+
end
|
30
|
+
|
31
|
+
def preview_display_params=(options)
|
32
|
+
Lookbook.logger.warn "The `preview_display_params` config option has been renamed to `preview_display_options` and will be removed in v2.0"
|
33
|
+
store[:preview_display_options] = options.to_h
|
34
|
+
end
|
35
|
+
|
36
|
+
def listen_extensions=(extensions = nil)
|
37
|
+
store[:listen_extensions] ||= []
|
38
|
+
store[:listen_extensions] += extensions.to_a
|
39
|
+
store[:listen_extensions].uniq!
|
40
|
+
end
|
41
|
+
|
42
|
+
def markdown_options=(options = nil)
|
43
|
+
store[:markdown_options] ||= {}
|
44
|
+
store[:markdown_options].merge!(options.to_h)
|
45
|
+
end
|
46
|
+
|
47
|
+
def ui_theme=(name)
|
48
|
+
name = name.to_s
|
49
|
+
if Theme.valid_theme?(name)
|
50
|
+
store[:ui_theme] = name
|
51
|
+
else
|
52
|
+
raise ConfigError.new("'#{name}' is not a valid Lookbook theme. ", scope: "app.config")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def ui_theme_overrides(&block)
|
57
|
+
if block
|
58
|
+
yield store[:ui_theme_overrides]
|
59
|
+
else
|
60
|
+
store[:ui_theme_overrides]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def runtime_parsing=(value)
|
65
|
+
Lookbook.logger.warn "The `runtime_parsing` config option has been deprecated and will be removed in v2.0"
|
66
|
+
end
|
67
|
+
|
68
|
+
def preview_srcdoc=(enable)
|
69
|
+
Lookbook.logger.warn "The `preview_srcdoc` config option is deprecated and will be removed in v2.0"
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.init_from_config(env: Rails.env)
|
73
|
+
new(default_config(env: env))
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.default_config(env: Rails.env)
|
77
|
+
ConfigLoader.call(CONFIG_FILE, env: env)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class HookStore
|
3
|
+
CONFIG_FILE = "config/hooks.yml"
|
4
|
+
|
5
|
+
attr_reader :store
|
6
|
+
delegate :to_h, to: :store
|
7
|
+
|
8
|
+
def initialize(config = nil)
|
9
|
+
@store = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_hook(event_name, callback)
|
13
|
+
for_event(event_name) << callback
|
14
|
+
end
|
15
|
+
|
16
|
+
def for_event(event_name)
|
17
|
+
store[event_name.to_sym] ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.init_from_config
|
21
|
+
new(default_config)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.default_config
|
25
|
+
ConfigLoader.call(CONFIG_FILE)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class InputStore
|
3
|
+
CONFIG_FILE = "config/inputs.yml"
|
4
|
+
|
5
|
+
DEFAULTS = {
|
6
|
+
# TODO
|
7
|
+
}
|
8
|
+
|
9
|
+
attr_reader :store
|
10
|
+
delegate :to_h, to: :store
|
11
|
+
|
12
|
+
def initialize(config = nil)
|
13
|
+
@store = {}
|
14
|
+
|
15
|
+
config.to_h.each do |name, opts|
|
16
|
+
add_input(name, opts[:partial], opts.except(:partial))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_input(input, *args)
|
21
|
+
store[input.to_sym] = build_config(input, *args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_input(input)
|
25
|
+
store[input.to_sym]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.init_from_config
|
29
|
+
new(default_config)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.default_config
|
33
|
+
ConfigLoader.call(CONFIG_FILE)
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def build_config(name, *args)
|
39
|
+
partial = nil
|
40
|
+
opts = nil
|
41
|
+
if args.many? && args.last.is_a?(Hash)
|
42
|
+
partial = args.first
|
43
|
+
opts = args.last
|
44
|
+
elsif args.first.is_a?(String)
|
45
|
+
partial = args.first
|
46
|
+
end
|
47
|
+
if partial.present?
|
48
|
+
Store.new({
|
49
|
+
name: name.to_sym,
|
50
|
+
partial: partial,
|
51
|
+
opts: DEFAULTS.merge(opts.to_h)
|
52
|
+
})
|
53
|
+
else
|
54
|
+
raise ConfigError.new("inputs must define a partial path", scope: "inputs.config")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|