lookbook 0.9.0 → 1.0.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +90 -824
  3. data/app/assets/lookbook/css/lookbook.css +55 -0
  4. data/app/assets/lookbook/css/themes/blue.css +42 -0
  5. data/app/assets/lookbook/css/themes/indigo.css +42 -0
  6. data/app/assets/lookbook/css/themes/zinc.css +42 -0
  7. data/app/assets/lookbook/css/{tooltip_theme.css → tooltip.css} +14 -8
  8. data/app/assets/lookbook/js/app.js +64 -63
  9. data/app/assets/lookbook/js/components/clipboard.js +47 -0
  10. data/app/assets/lookbook/js/components/tooltip.js +30 -0
  11. data/app/assets/lookbook/js/config.js +7 -4
  12. data/app/assets/lookbook/js/helpers/build.js +22 -0
  13. data/app/assets/lookbook/js/helpers/dom.js +45 -0
  14. data/app/assets/lookbook/js/helpers/layout.js +21 -0
  15. data/app/assets/lookbook/js/helpers/request.js +16 -0
  16. data/app/assets/lookbook/js/helpers/string.js +11 -0
  17. data/app/assets/lookbook/js/lib/socket.js +4 -3
  18. data/app/assets/lookbook/js/lib/tippy.js +8 -0
  19. data/app/assets/lookbook/js/lookbook.js +61 -0
  20. data/app/assets/lookbook/js/plugins/logger.js +39 -0
  21. data/app/assets/lookbook/js/stores/filter.js +2 -2
  22. data/app/assets/lookbook/js/stores/inspector.js +23 -17
  23. data/app/assets/lookbook/js/stores/layout.js +101 -5
  24. data/app/assets/lookbook/js/stores/nav.js +17 -16
  25. data/app/assets/lookbook/js/stores/pages.js +4 -2
  26. data/app/assets/lookbook/js/stores/settings.js +7 -0
  27. data/app/assets/lookbook/js/stores/workbench.js +29 -0
  28. data/app/components/lookbook/button/component.html.erb +28 -0
  29. data/app/components/lookbook/button/component.js +55 -0
  30. data/app/components/lookbook/button/component.rb +39 -0
  31. data/app/components/lookbook/button_group/component.html.erb +3 -0
  32. data/app/components/lookbook/button_group/component.rb +18 -0
  33. data/app/components/lookbook/code/component.css +57 -0
  34. data/app/components/lookbook/code/component.html.erb +10 -0
  35. data/app/components/lookbook/code/component.js +3 -0
  36. data/app/components/lookbook/code/component.rb +56 -0
  37. data/app/components/lookbook/code/highlight_github_light.css +217 -0
  38. data/app/components/lookbook/component.rb +41 -0
  39. data/app/components/lookbook/copy_button/component.html.erb +11 -0
  40. data/app/components/lookbook/copy_button/component.js +16 -0
  41. data/app/components/lookbook/copy_button/component.rb +23 -0
  42. data/app/components/lookbook/dimensions_display/component.html.erb +11 -0
  43. data/app/components/lookbook/dimensions_display/component.js +37 -0
  44. data/app/components/lookbook/dimensions_display/component.rb +18 -0
  45. data/app/components/lookbook/embed/component.html.erb +50 -0
  46. data/app/components/lookbook/embed/component.js +39 -0
  47. data/app/components/lookbook/embed/component.rb +22 -0
  48. data/app/components/lookbook/filter/component.html.erb +17 -0
  49. data/app/components/lookbook/filter/component.js +21 -0
  50. data/app/components/lookbook/filter/component.rb +15 -0
  51. data/app/components/lookbook/header/component.html.erb +79 -0
  52. data/app/components/lookbook/header/component.rb +9 -0
  53. data/app/components/lookbook/icon/component.css +11 -0
  54. data/app/components/lookbook/icon/component.html.erb +5 -0
  55. data/app/components/lookbook/icon/component.js +5 -0
  56. data/app/components/lookbook/icon/component.rb +23 -0
  57. data/app/components/lookbook/nav/component.html.erb +33 -0
  58. data/app/components/lookbook/nav/component.js +52 -0
  59. data/app/components/lookbook/nav/component.rb +37 -0
  60. data/app/components/lookbook/nav/item/component.html.erb +23 -0
  61. data/app/components/lookbook/nav/item/component.js +66 -0
  62. data/app/components/lookbook/nav/item/component.rb +84 -0
  63. data/app/components/lookbook/page_tabs/component.html.erb +18 -0
  64. data/app/components/lookbook/page_tabs/component.rb +19 -0
  65. data/app/components/lookbook/params_editor/component.html.erb +3 -0
  66. data/app/components/lookbook/params_editor/component.js +12 -0
  67. data/app/components/lookbook/params_editor/component.rb +11 -0
  68. data/app/components/lookbook/params_editor/field/component.html.erb +50 -0
  69. data/app/components/lookbook/params_editor/field/component.js +36 -0
  70. data/app/components/lookbook/params_editor/field/component.rb +41 -0
  71. data/app/components/lookbook/prose/component.css +12 -0
  72. data/app/components/lookbook/prose/component.html.erb +3 -0
  73. data/app/components/lookbook/prose/component.rb +26 -0
  74. data/app/components/lookbook/split_layout/component.html.erb +13 -0
  75. data/app/components/lookbook/split_layout/component.js +151 -0
  76. data/app/components/lookbook/split_layout/component.rb +11 -0
  77. data/app/components/lookbook/tab_panels/component.html.erb +5 -0
  78. data/app/components/lookbook/tab_panels/component.js +25 -0
  79. data/app/components/lookbook/tab_panels/component.rb +20 -0
  80. data/app/components/lookbook/tab_panels/panel/component.html.erb +8 -0
  81. data/app/components/lookbook/tab_panels/panel/component.rb +9 -0
  82. data/app/components/lookbook/tabs/component.css +8 -0
  83. data/app/components/lookbook/tabs/component.html.erb +20 -0
  84. data/app/components/lookbook/tabs/component.js +115 -0
  85. data/app/components/lookbook/tabs/component.rb +28 -0
  86. data/app/components/lookbook/tabs/dropdown_tab/component.html.erb +20 -0
  87. data/app/components/lookbook/tabs/dropdown_tab/component.rb +17 -0
  88. data/app/components/lookbook/tabs/tab/component.html.erb +24 -0
  89. data/app/components/lookbook/tabs/tab/component.rb +17 -0
  90. data/app/components/lookbook/tag_component.rb +29 -0
  91. data/app/components/lookbook/toolbar/component.css +16 -0
  92. data/app/components/lookbook/toolbar/component.html.erb +5 -0
  93. data/app/components/lookbook/toolbar/component.rb +26 -0
  94. data/app/components/lookbook/viewport/component.css +11 -0
  95. data/app/components/lookbook/viewport/component.html.erb +57 -0
  96. data/app/{assets/lookbook/js/components/preview-window.js → components/lookbook/viewport/component.js} +57 -14
  97. data/app/components/lookbook/viewport/component.rb +21 -0
  98. data/app/controllers/lookbook/application_controller.rb +16 -5
  99. data/app/controllers/lookbook/pages_controller.rb +17 -8
  100. data/app/controllers/lookbook/previews_controller.rb +130 -89
  101. data/app/helpers/lookbook/application_helper.rb +6 -2
  102. data/app/helpers/lookbook/component_helper.rb +22 -10
  103. data/app/helpers/lookbook/output_helper.rb +8 -4
  104. data/app/helpers/lookbook/page_helper.rb +13 -21
  105. data/app/views/layouts/lookbook/application.html.erb +76 -28
  106. data/app/views/layouts/lookbook/inspector.html.erb +7 -0
  107. data/app/views/layouts/lookbook/page.html.erb +53 -0
  108. data/app/views/layouts/lookbook/shell.html.erb +64 -0
  109. data/app/views/layouts/lookbook/skeleton.html.erb +27 -10
  110. data/app/views/layouts/lookbook/standalone.html.erb +5 -0
  111. data/app/views/lookbook/404.html.erb +15 -0
  112. data/app/views/lookbook/error.html.erb +34 -34
  113. data/app/views/lookbook/index.html.erb +11 -6
  114. data/app/views/lookbook/pages/show.html.erb +37 -91
  115. data/app/views/{layouts/lookbook → lookbook}/preview.html.erb +6 -8
  116. data/app/views/lookbook/previews/panels/_content.html.erb +13 -0
  117. data/app/views/lookbook/previews/panels/_notes.html.erb +19 -25
  118. data/app/views/lookbook/previews/panels/_output.html.erb +7 -18
  119. data/app/views/lookbook/previews/panels/_params.html.erb +13 -15
  120. data/app/views/lookbook/previews/panels/_preview.html.erb +6 -52
  121. data/app/views/lookbook/previews/panels/_source.html.erb +6 -15
  122. data/app/views/lookbook/previews/show.html.erb +133 -24
  123. data/config/routes.rb +5 -5
  124. data/lib/lookbook/code_formatter.rb +37 -13
  125. data/lib/lookbook/collection.rb +19 -16
  126. data/lib/lookbook/config.rb +180 -0
  127. data/lib/lookbook/engine.rb +66 -59
  128. data/lib/lookbook/entity.rb +47 -0
  129. data/lib/lookbook/error.rb +1 -2
  130. data/lib/lookbook/features.rb +1 -1
  131. data/lib/lookbook/markdown.rb +3 -4
  132. data/lib/lookbook/page.rb +40 -34
  133. data/lib/lookbook/page_collection.rb +8 -0
  134. data/lib/lookbook/page_section.rb +31 -0
  135. data/lib/lookbook/params.rb +14 -3
  136. data/lib/lookbook/preview.rb +16 -7
  137. data/lib/lookbook/preview_collection.rb +8 -0
  138. data/lib/lookbook/preview_controller.rb +6 -2
  139. data/lib/lookbook/preview_example.rb +5 -6
  140. data/lib/lookbook/preview_group.rb +4 -9
  141. data/lib/lookbook/{code_inspector.rb → source_inspector.rb} +2 -2
  142. data/lib/lookbook/store.rb +36 -0
  143. data/lib/lookbook/theme.rb +29 -0
  144. data/lib/lookbook/utils.rb +10 -2
  145. data/lib/lookbook/version.rb +1 -1
  146. data/lib/lookbook.rb +6 -1
  147. data/lib/tasks/lookbook_tasks.rake +12 -0
  148. data/public/lookbook-assets/css/app.css +2340 -1
  149. data/public/lookbook-assets/css/app.css.map +11 -1
  150. data/public/lookbook-assets/css/lookbook.css +3069 -0
  151. data/public/lookbook-assets/css/lookbook.css.map +1 -0
  152. data/public/lookbook-assets/css/themes/blue.css +44 -0
  153. data/public/lookbook-assets/css/themes/blue.css.map +1 -0
  154. data/public/lookbook-assets/css/themes/indigo.css +44 -0
  155. data/public/lookbook-assets/css/themes/indigo.css.map +1 -0
  156. data/public/lookbook-assets/css/themes/zinc.css +44 -0
  157. data/public/lookbook-assets/css/themes/zinc.css.map +1 -0
  158. data/public/lookbook-assets/js/app.js +10861 -1
  159. data/public/lookbook-assets/js/app.js.map +2571 -1
  160. data/public/lookbook-assets/js/embed.js +895 -1
  161. data/public/lookbook-assets/js/embed.js.map +1 -1
  162. data/public/lookbook-assets/js/lookbook.js +13541 -0
  163. data/public/lookbook-assets/js/lookbook.js.map +1 -0
  164. metadata +133 -116
  165. data/app/assets/lookbook/css/app.css +0 -161
  166. data/app/assets/lookbook/css/code_theme.css +0 -214
  167. data/app/assets/lookbook/js/components/app.js +0 -55
  168. data/app/assets/lookbook/js/components/code.js +0 -5
  169. data/app/assets/lookbook/js/components/copy.js +0 -20
  170. data/app/assets/lookbook/js/components/embed.js +0 -89
  171. data/app/assets/lookbook/js/components/filter.js +0 -35
  172. data/app/assets/lookbook/js/components/inspector.js +0 -66
  173. data/app/assets/lookbook/js/components/nav-group.js +0 -47
  174. data/app/assets/lookbook/js/components/nav-item.js +0 -29
  175. data/app/assets/lookbook/js/components/nav.js +0 -28
  176. data/app/assets/lookbook/js/components/page-tabs.js +0 -9
  177. data/app/assets/lookbook/js/components/page.js +0 -25
  178. data/app/assets/lookbook/js/components/param.js +0 -34
  179. data/app/assets/lookbook/js/components/sidebar.js +0 -18
  180. data/app/assets/lookbook/js/components/sizes.js +0 -16
  181. data/app/assets/lookbook/js/components/splitter.js +0 -25
  182. data/app/assets/lookbook/js/components/tabs.js +0 -52
  183. data/app/assets/lookbook/js/lib/split.js +0 -15
  184. data/app/assets/lookbook/js/stores/sidebar.js +0 -26
  185. data/app/views/layouts/lookbook/basic.html.erb +0 -7
  186. data/app/views/lookbook/components/_branding.html.erb +0 -8
  187. data/app/views/lookbook/components/_code.html.erb +0 -17
  188. data/app/views/lookbook/components/_copy_button.html.erb +0 -11
  189. data/app/views/lookbook/components/_drawer.html.erb +0 -112
  190. data/app/views/lookbook/components/_embed.html.erb +0 -39
  191. data/app/views/lookbook/components/_errors.html.erb +0 -13
  192. data/app/views/lookbook/components/_filter.html.erb +0 -18
  193. data/app/views/lookbook/components/_header.html.erb +0 -6
  194. data/app/views/lookbook/components/_icon.html.erb +0 -5
  195. data/app/views/lookbook/components/_nav.html.erb +0 -16
  196. data/app/views/lookbook/components/_nav_collection.html.erb +0 -5
  197. data/app/views/lookbook/components/_nav_group.html.erb +0 -14
  198. data/app/views/lookbook/components/_nav_item.html.erb +0 -24
  199. data/app/views/lookbook/components/_nav_page.html.erb +0 -22
  200. data/app/views/lookbook/components/_nav_preview.html.erb +0 -13
  201. data/app/views/lookbook/components/_not_found.html.erb +0 -11
  202. data/app/views/lookbook/components/_param.html.erb +0 -21
  203. data/app/views/lookbook/components/_preview.html.erb +0 -77
  204. data/app/views/lookbook/components/_sidebar.html.erb +0 -69
  205. data/app/views/lookbook/pages/not_found.html.erb +0 -15
  206. data/app/views/lookbook/previews/error.html.erb +0 -1
  207. data/app/views/lookbook/previews/inputs/_select.html.erb +0 -7
  208. data/app/views/lookbook/previews/inputs/_text.html.erb +0 -8
  209. data/app/views/lookbook/previews/inputs/_textarea.html.erb +0 -8
  210. data/app/views/lookbook/previews/inputs/_toggle.html.erb +0 -13
  211. data/app/views/lookbook/previews/not_found.html.erb +0 -23
@@ -0,0 +1,180 @@
1
+ require "lookbook/markdown"
2
+ require "lookbook/theme"
3
+ require "lookbook/store"
4
+
5
+ module Lookbook
6
+ class Config
7
+ def initialize
8
+ @options = Store.new
9
+ foobar = "bax"
10
+ @options.set({
11
+ project_name: "Lookbook",
12
+ log_level: 2,
13
+ auto_refresh: true,
14
+
15
+ page_controller: "Lookbook::PageController",
16
+ page_route: "pages",
17
+ page_paths: ["test/components/docs"],
18
+ page_options: {},
19
+ markdown_options: Markdown::DEFAULT_OPTIONS,
20
+
21
+ preview_paths: [],
22
+ preview_display_params: {},
23
+ preview_options: {},
24
+ preview_srcdoc: false,
25
+ sort_examples: true,
26
+
27
+ listen: Rails.env.development?,
28
+ listen_paths: [],
29
+ listen_use_polling: false,
30
+
31
+ cable_mount_path: "/lookbook-cable",
32
+ cable_logger: Lookbook.logger,
33
+
34
+ runtime_parsing: !Rails.env.production?,
35
+ parser_registry_path: "tmp/storage/.yardoc",
36
+
37
+ ui_theme: "indigo",
38
+ ui_theme_overrides: {},
39
+
40
+ inspector_panels: {
41
+ preview: {
42
+ pane: :main,
43
+ position: 1,
44
+ partial: "lookbook/previews/panels/preview",
45
+ hotkey: "v",
46
+ panel_classes: "overflow-hidden"
47
+ },
48
+ output: {
49
+ pane: :main,
50
+ position: 2,
51
+ partial: "lookbook/previews/panels/output",
52
+ label: "HTML",
53
+ hotkey: "h",
54
+ },
55
+ source: {
56
+ pane: :drawer,
57
+ position: 1,
58
+ partial: "lookbook/previews/panels/source",
59
+ label: "Source",
60
+ hotkey: "s",
61
+ copy: ->(data) { data.examples.map { |e| e[:source] }.join("\n") }
62
+ },
63
+ notes: {
64
+ pane: :drawer,
65
+ position: 2,
66
+ partial: "lookbook/previews/panels/notes",
67
+ label: "Notes",
68
+ hotkey: "n",
69
+ disabled: ->(data) { data.examples.filter { |e| e.notes.present? }.none? }
70
+ },
71
+ params: {
72
+ pane: :drawer,
73
+ position: 3,
74
+ partial: "lookbook/previews/panels/params",
75
+ label: "Params",
76
+ hotkey: "p",
77
+ disabled: ->(data) { data.preview.params.none? }
78
+ }
79
+ },
80
+
81
+ inspector_panel_defaults: {
82
+ id: ->(data) { "inspector-panel-#{data.name}" },
83
+ partial: "lookbook/previews/panels/content",
84
+ content: nil,
85
+ label: ->(data) { data.name.titleize },
86
+ pane: :drawer,
87
+ position: ->(data) { data.index_position },
88
+ hotkey: nil,
89
+ disabled: false,
90
+ show: true,
91
+ copy: nil,
92
+ panel_classes: nil,
93
+ locals: {}
94
+ },
95
+
96
+ experimental_features: false,
97
+ })
98
+ end
99
+
100
+ def inspector_panels(&block)
101
+ if block_given?
102
+ yield get(:inspector_panels)
103
+ else
104
+ get(:inspector_panels)
105
+ end
106
+ end
107
+
108
+ def ui_theme=(name)
109
+ name = name.to_s
110
+ if Theme.valid_theme?(name)
111
+ @options[:ui_theme] = name
112
+ else
113
+ Lookbook.logger.warn "'#{name}' is not a valid Lookbook theme. Theme setting not changed."
114
+ end
115
+ end
116
+
117
+ def ui_theme_overrides(&block)
118
+ if block_given?
119
+ yield get(:ui_theme_overrides)
120
+ else
121
+ get(:ui_theme_overrides)
122
+ end
123
+ end
124
+
125
+ def [](key)
126
+ get(key.to_sym)
127
+ end
128
+
129
+ def []=(key, value)
130
+ @options[key.to_sym] = value
131
+ end
132
+
133
+ def to_h
134
+ @options.to_h
135
+ end
136
+
137
+ def to_json(*a)
138
+ to_h.to_json(*a)
139
+ end
140
+
141
+ protected
142
+
143
+ def get_inspector_panels(panels)
144
+ panels.filter! { |key, panel| panel }
145
+ panels
146
+ end
147
+
148
+ def get_project_name(name)
149
+ name == false ? nil : name
150
+ end
151
+
152
+ def normalize_paths(paths)
153
+ paths.map! { |path| absolute_path(path) }
154
+ paths.filter! { |path| Dir.exist?(path) }
155
+ paths
156
+ end
157
+
158
+ def absolute_path(path)
159
+ File.absolute_path(path.to_s, Rails.root)
160
+ end
161
+
162
+ alias_method :get_page_paths, :normalize_paths
163
+ alias_method :get_preview_paths, :normalize_paths
164
+ alias_method :get_listen_paths, :normalize_paths
165
+ alias_method :get_parser_registry_path, :absolute_path
166
+
167
+ def get(name)
168
+ getter_name = "get_#{name}".to_sym
169
+ respond_to?(getter_name, true) ? send(getter_name, @options[name]) : @options[name]
170
+ end
171
+
172
+ def set(name, *args)
173
+ @options.send(name, *args)
174
+ end
175
+
176
+ def method_missing(name, *args)
177
+ args.any? ? set(name, *args) : get(name)
178
+ end
179
+ end
180
+ end
@@ -4,64 +4,51 @@ require "action_cable/engine"
4
4
  require "listen"
5
5
 
6
6
  module Lookbook
7
+
8
+ autoload :Config, "lookbook/config"
9
+
7
10
  class << self
8
11
  def config
9
- @config ||= Engine.config.lookbook
12
+ @config ||= Config.new
10
13
  end
11
14
 
12
15
  def logger
13
- @logger ||= Rails.logger
16
+ @logger ||= Rails.env.development? ? Logger.new($stdout) : Rails.logger
14
17
  end
15
18
 
16
19
  def version
17
20
  Lookbook::VERSION
18
21
  end
22
+
23
+ def debug_data
24
+ {
25
+ version: version,
26
+ env: Rails.env.to_s,
27
+ config: config
28
+ }
29
+ end
30
+
31
+ def configure
32
+ yield(config)
33
+ end
19
34
  end
20
35
 
21
36
  class Engine < Rails::Engine
22
37
  isolate_namespace Lookbook
23
38
 
24
- config.lookbook = ActiveSupport::OrderedOptions.new
25
- config.lookbook.listen_paths ||= []
26
- config.lookbook.preview_paths ||= []
27
- config.lookbook.page_paths ||= ["test/components/docs"]
28
-
29
- initializer "view_component.set_configs" do
30
- options = config.lookbook
31
- vc_options = config.view_component
32
-
33
- options.project_name ||= options.project_name == false ? nil : options.project_name || "Lookbook"
34
- options.auto_refresh = true if options.auto_refresh.nil?
35
- options.sort_examples = false if options.sort_examples.nil?
36
- options.debug = false unless options.debug == true
39
+ config.lookbook = Lookbook.config
40
+ config.autoload_paths << File.expand_path(Lookbook::Engine.root.join("app/components"))
37
41
 
38
- options.preview_paths = options.preview_paths.map(&:to_s)
39
- options.preview_paths += vc_options.preview_paths
42
+ initializer "lookbook.viewcomponent.config" do
43
+ config.lookbook.preview_paths += config.view_component.preview_paths
44
+ config.lookbook.preview_controller ||= config.view_component.preview_controller
40
45
 
41
- options.page_paths = options.page_paths.map(&:to_s)
42
- options.page_controller = "Lookbook::PageController" if options.page_controller.nil?
43
- options.page_route ||= "pages"
44
- options.page_options ||= {}.with_indifferent_access
45
-
46
- options.markdown_options = Markdown::DEFAULT_OPTIONS.merge(options.markdown_options || {})
47
-
48
- options.preview_controller = vc_options.preview_controller if options.preview_controller.nil?
49
- options.preview_srcdoc = false if options.preview_srcdoc.nil?
50
- options.preview_display_params ||= {}.with_indifferent_access
51
-
52
- options.listen = Rails.env.development? if options.listen.nil?
53
- options.listen_paths = options.listen_paths.map(&:to_s)
54
- options.listen_paths += options.preview_paths
55
- options.listen_paths << (vc_options.view_component_path || Rails.root.join("app/components"))
56
- options.listen_paths.select! { |path| Dir.exist? path }
57
-
58
- options.cable_mount_path ||= "/lookbook-cable"
59
- options.cable_logger ||= Rails.logger
60
-
61
- options.runtime_parsing = !Rails.env.production? if options.runtime_parsing.nil?
62
- options.parser_registry_path ||= Rails.root.join("tmp/storage/.yardoc")
46
+ config.lookbook.listen_paths += config.lookbook.preview_paths
47
+ config.lookbook.listen_paths << (config.view_component.view_component_path.presence || "app/components")
48
+ end
63
49
 
64
- options.experimental_features = false unless options.experimental_features.present?
50
+ initializer "lookbook.logging.development" do
51
+ Lookbook.logger.level = Lookbook.config.log_level if Rails.env.development?
65
52
  end
66
53
 
67
54
  initializer "lookbook.parser.tags" do
@@ -80,30 +67,29 @@ module Lookbook
80
67
  @preview_controller.include(Lookbook::PreviewController)
81
68
 
82
69
  if config.lookbook.listen
83
- @preview_listener = Listen.to(*config.lookbook.listen_paths, only: /\.(rb|html.*)$/) do |modified, added, removed|
70
+ Listen.logger = Lookbook.logger
71
+ preview_listener = Listen.to(
72
+ *config.lookbook.listen_paths,
73
+ only: /\.(rb|html.*)$/,
74
+ force_polling: Lookbook.config.listen_use_polling
75
+ ) do |modified, added, removed|
84
76
  begin
85
77
  parser.parse
86
78
  rescue
87
79
  end
88
80
  Lookbook::Preview.clear_cache
89
- Lookbook::Engine.websocket&.broadcast("reload", {
90
- modified: modified,
91
- removed: removed,
92
- added: added
93
- })
81
+ Lookbook::Engine.websocket&.broadcast("reload", {})
94
82
  end
95
- @preview_listener.start
96
-
97
- if Lookbook::Features.enabled?(:pages)
98
- @page_listener = Listen.to(*config.lookbook.page_paths.select { |dir| Dir.exist? dir }, only: /\.(html.*|md.*)$/) do |modified, added, removed|
99
- Lookbook::Engine.websocket&.broadcast("reload", {
100
- modified: modified,
101
- removed: removed,
102
- added: added
103
- })
104
- end
105
- @page_listener.start
83
+ Lookbook::Engine.register_listener(preview_listener)
84
+
85
+ page_listener = Listen.to(
86
+ *config.lookbook.page_paths,
87
+ only: /\.(html.*|md.*)$/,
88
+ force_polling: Lookbook.config.listen_use_polling
89
+ ) do |modified, added, removed|
90
+ Lookbook::Engine.websocket&.broadcast("reload", {})
106
91
  end
92
+ Lookbook::Engine.register_listener(page_listener)
107
93
  end
108
94
 
109
95
  if config.lookbook.runtime_parsing
@@ -120,8 +106,12 @@ module Lookbook
120
106
  end
121
107
 
122
108
  at_exit do
123
- @preview_listener&.stop
124
- @page_listener&.stop
109
+ if config.lookbook.listen
110
+ Lookbook.logger.debug "Stopping listeners"
111
+ Lookbook::Engine.listeners.each do |listener|
112
+ listener.stop
113
+ end
114
+ end
125
115
  end
126
116
 
127
117
  class << self
@@ -155,6 +145,23 @@ module Lookbook
155
145
  @parser ||= Lookbook::Parser.new(config.lookbook.preview_paths, config.lookbook.parser_registry_path)
156
146
  end
157
147
 
148
+ def log_level
149
+ Lookbook.logger.level
150
+ end
151
+
152
+ def app_name
153
+ Rails.application.class.module_parent_name.underscore
154
+ end
155
+
156
+ def register_listener(listener)
157
+ listener.start
158
+ listeners << listener
159
+ end
160
+
161
+ def listeners
162
+ @listeners ||= []
163
+ end
164
+
158
165
  attr_reader :preview_controller
159
166
  end
160
167
  end
@@ -0,0 +1,47 @@
1
+ module Lookbook
2
+ class Entity
3
+ include Utils
4
+
5
+ def initialize(reference_path)
6
+ @refpath = reference_path
7
+ end
8
+
9
+ def id
10
+ generate_id(lookup_path)
11
+ end
12
+
13
+ def label
14
+ lookup_path.split("/").last.titleize
15
+ end
16
+
17
+ def type
18
+ :item
19
+ end
20
+
21
+ def path
22
+ @refpath
23
+ end
24
+
25
+ def lookup_path
26
+ @lookup_path ||= to_lookup_path(@refpath)
27
+ end
28
+
29
+ def hierarchy_depth
30
+ @refpath.present? ? @refpath.split("/").size : 0
31
+ end
32
+
33
+ def position
34
+ 0
35
+ end
36
+
37
+ def hidden?
38
+ false
39
+ end
40
+
41
+ def matchers
42
+ nil
43
+ end
44
+
45
+ alias_method :url_path, :lookup_path
46
+ end
47
+ end
@@ -34,8 +34,7 @@ module Lookbook
34
34
 
35
35
  {
36
36
  code: relevant_lines.join("\n").lstrip,
37
- start_line: start_line - empty_start_lines,
38
- end_line: end_line - empty_start_lines,
37
+ start_line: start_line,
39
38
  highlighted_line: highlighted_line - empty_start_lines
40
39
  }
41
40
  end
@@ -1,6 +1,6 @@
1
1
  module Lookbook
2
2
  module Features
3
- EXPERIMENTAL_FEATURES = [:pages]
3
+ EXPERIMENTAL_FEATURES = []
4
4
 
5
5
  def self.experimental_feature?(name)
6
6
  EXPERIMENTAL_FEATURES.include?(name.to_sym)
@@ -19,12 +19,11 @@ module Lookbook
19
19
  class Renderer < Redcarpet::Render::HTML
20
20
  def block_code(code, language = "ruby")
21
21
  line_numbers = language.to_s.end_with? "-numbered"
22
- ApplicationController.render "lookbook/components/_code", locals: {
23
- code: code,
22
+ ApplicationController.render(Lookbook::Code::Component.new(**{
23
+ source: code,
24
24
  language: language.to_s.chomp("-numbered"),
25
25
  line_numbers: line_numbers
26
- },
27
- layout: nil
26
+ }), layout: nil)
28
27
  end
29
28
  end
30
29
  end
data/lib/lookbook/page.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  module Lookbook
2
- class Page
3
- include Utils
2
+ class Page < Entity
4
3
 
5
4
  FRONTMATTER_FIELDS = [
6
5
  :id,
@@ -16,26 +15,22 @@ module Lookbook
16
15
  ]
17
16
 
18
17
  attr_reader :errors
19
- attr_accessor :tabs
18
+ attr_accessor :sections
20
19
 
21
20
  def initialize(path, base_path)
22
21
  @pathname = Pathname.new path
23
- @base_path = Pathname.new base_path
22
+ @base_path = base_path
24
23
  @options = nil
25
24
  @errors = []
26
- @tabs = []
27
- end
28
-
29
- def path
25
+ @sections = []
26
+ @page_name = remove_position_prefix(path_name)
30
27
  rel_path = @pathname.relative_path_from(@base_path)
31
-
32
- _path = (rel_path.dirname.to_s == "." ? name : "#{rel_path.dirname}/#{name}")
33
- _path.gsub!("[#{tab}]", "") if tab?
34
- _path
28
+ page_path = rel_path.dirname.to_s == "." ? @page_name : "#{rel_path.dirname}/#{@page_name}"
29
+ super(page_path)
35
30
  end
36
31
 
37
- def lookup_path
38
- @lookup_path ||= to_lookup_path(path)
32
+ def url_path
33
+ lookbook_page_path lookup_path
39
34
  end
40
35
 
41
36
  def full_path
@@ -43,7 +38,7 @@ module Lookbook
43
38
  end
44
39
 
45
40
  def name
46
- remove_position_prefix(path_name)
41
+ @page_name
47
42
  end
48
43
 
49
44
  def hidden?
@@ -74,25 +69,28 @@ module Lookbook
74
69
  normalize_matchers(label)
75
70
  end
76
71
 
77
- def hierarchy_depth
78
- path.split("/").size
79
- end
80
-
81
72
  def parent_collections_names
82
73
  File.dirname(path).split("/")
83
74
  end
84
75
 
85
76
  def type
86
- tab? ? :tab : :page
77
+ :page
78
+ end
79
+
80
+ def id
81
+ options[:id]
87
82
  end
88
83
 
89
- def tab
90
- matches = full_path.to_s.match(%r{\[(?<tab>\w+)\]})
91
- matches ? remove_position_prefix(matches[:tab]) : nil
84
+ def position
85
+ options[:position]
92
86
  end
93
87
 
94
- def tab?
95
- tab.present?
88
+ def hidden
89
+ options[:hidden]
90
+ end
91
+
92
+ def label
93
+ options[:label]
96
94
  end
97
95
 
98
96
  def method_missing(method_name, *args, &block)
@@ -128,7 +126,7 @@ module Lookbook
128
126
  end
129
127
  @options = Lookbook.config.page_options.deep_merge(frontmatter).with_indifferent_access
130
128
  @options[:id] = @options[:id] ? generate_id(@options[:id]) : generate_id(lookup_path)
131
- @options[:label] ||= (tab? ? tab : name).titleize
129
+ @options[:label] ||= name.titleize
132
130
  @options[:title] ||= @options[:label]
133
131
  @options[:hidden] ||= false
134
132
  @options[:landing] ||= false
@@ -157,10 +155,10 @@ module Lookbook
157
155
  end
158
156
 
159
157
  def all
160
- pages, tabs =
158
+ pages, sections =
161
159
  Array(page_paths).flat_map do |dir|
162
- Dir["#{dir}/**/*.html.*", "#{dir}/**/*.md.*"].sort.map do |page|
163
- page = Lookbook::Page.new(page, dir)
160
+ Dir["#{dir}/**/*.html.*", "#{dir}/**/*.md.*"].sort.map do |path|
161
+ create(path, dir)
164
162
  end
165
163
  end.partition { |page| page.type == :page }
166
164
 
@@ -169,17 +167,25 @@ module Lookbook
169
167
  .sort_by { |page| [page.position, page.label] }
170
168
 
171
169
  page_dict = sorted_pages.index_by(&:path)
172
- sorted_tabs = tabs.sort_by { |tab| [tab.position, tab.label] }
173
-
174
- sorted_tabs.each do |tab|
175
- page_dict[tab.path].tabs << tab
170
+ sorted_sections = sections.sort_by { |section| [section.position, section.label] }
171
+
172
+ sorted_sections.each do |section|
173
+ page_dict[section.path].sections << section
176
174
  end
177
175
 
178
176
  PageCollection.new(sorted_pages)
179
177
  end
180
178
 
181
179
  def page_paths
182
- Lookbook.config.page_paths.select { |dir| Dir.exist? dir }
180
+ Lookbook.config.page_paths.filter { |dir| Dir.exist? dir }
181
+ end
182
+
183
+ def section_path?(path)
184
+ !!path.match(%r{\[(.*?\w+)\]})
185
+ end
186
+
187
+ def create(path, base_path)
188
+ (section_path?(path) ? PageSection : Page).new(path, base_path)
183
189
  end
184
190
  end
185
191
  end
@@ -4,6 +4,14 @@ module Lookbook
4
4
  generate_id("page-collection", lookup_path || "root")
5
5
  end
6
6
 
7
+ def label
8
+ "Pages"
9
+ end
10
+
11
+ def type
12
+ :page_collection
13
+ end
14
+
7
15
  def self.describe_as
8
16
  "pages"
9
17
  end
@@ -0,0 +1,31 @@
1
+ module Lookbook
2
+ class PageSection < Page
3
+
4
+ def name
5
+ return @name if @name.present?
6
+ matches = full_path.to_s.match(%r{\[(?<name>\w+)\]})
7
+ @name ||= matches[:name]
8
+ end
9
+
10
+ def id
11
+ "#{super}-#{name}"
12
+ end
13
+
14
+ def url_path
15
+ nil
16
+ end
17
+
18
+ def path
19
+ super.gsub("[#{name}]", "")
20
+ end
21
+
22
+ def type
23
+ :page_section
24
+ end
25
+
26
+ def lookup_path
27
+ "#{super}/#{name}"
28
+ end
29
+
30
+ end
31
+ end
@@ -1,10 +1,21 @@
1
+ require "active_model"
2
+
1
3
  module Lookbook
2
4
  module Params
3
5
  class << self
4
- def build_param(param, default)
6
+ def build_param(param, default: nil, **opts)
5
7
  input, options_str = param.text.present? ? param.text.split(" ", 2) : [nil, ""]
6
8
  type = param.types&.first
7
- options = YAML.safe_load(options_str || "~")
9
+ options = if options_str.present? && options_str.end_with?(".json")
10
+ json_path = if options_str.start_with?(".")
11
+ File.expand_path(options_str, File.dirname(param.object.files.first[0]))
12
+ else
13
+ Rails.root.join(options_str)
14
+ end
15
+ JSON.parse(File.read(json_path))
16
+ else
17
+ YAML.safe_load(options_str || "~")
18
+ end
8
19
  input ||= guess_input(type, default)
9
20
  type ||= guess_type(input, default)
10
21
  {
@@ -93,7 +104,7 @@ module Lookbook
93
104
  "tel",
94
105
  "text",
95
106
  "url"
96
- ].include? input
107
+ ].include? input.to_s
97
108
  end
98
109
 
99
110
  def safe_parse_yaml(value, fallback)