mountain_view 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +64 -0
  3. data/Rakefile +12 -16
  4. data/app/assets/stylesheets/mountain_view/styleguide.css +1 -0
  5. data/app/helpers/mountain_view/styleguide_helper.rb +6 -2
  6. data/app/views/layouts/mountain_view.html.erb +4 -4
  7. data/app/views/mountain_view/styleguide/_example.html.erb +9 -5
  8. data/app/views/mountain_view/styleguide/index.html.erb +5 -5
  9. data/app/views/mountain_view/styleguide/show.html.erb +13 -9
  10. data/config/locales/en.yml +25 -0
  11. data/config/routes.rb +2 -1
  12. data/lib/generators/mountain_view/extra_pages_generator.rb +1 -0
  13. data/lib/mountain_view.rb +3 -0
  14. data/lib/mountain_view/component.rb +9 -1
  15. data/lib/mountain_view/engine.rb +5 -4
  16. data/lib/mountain_view/presenter.rb +5 -2
  17. data/lib/mountain_view/stub.rb +29 -0
  18. data/lib/mountain_view/version.rb +1 -1
  19. data/test/dummy/app/components/header/header.yml +4 -0
  20. data/test/dummy/app/components/meta_header/_meta_header.html.erb +6 -0
  21. data/test/dummy/app/components/meta_header/meta_header.css +32 -0
  22. data/test/dummy/app/components/meta_header/meta_header.js +0 -0
  23. data/test/dummy/app/components/meta_header/meta_header.yml +14 -0
  24. data/test/dummy/log/test.log +1076 -920
  25. data/test/generators/component_generator_test.rb +3 -3
  26. data/test/generators/extra_pages_generator_test.rb +1 -1
  27. data/test/mountain_view/component_test.rb +47 -61
  28. data/test/mountain_view/stub_test.rb +49 -0
  29. data/test/mountain_view_test.rb +1 -1
  30. data/test/test_helper.rb +31 -2
  31. metadata +60 -50
  32. data/test/dummy/log/development.log +0 -315
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 55b6e597fb1b7fd3358e9a8b958e9512611209fa
4
- data.tar.gz: f861adf78badf1bb7d551838d95d6df1d59b41e3
2
+ SHA256:
3
+ metadata.gz: eb536f64e62bb86266813a605c993539b180c588c20ff8fe6bfa2fa0c8fd17ad
4
+ data.tar.gz: 2ed24b72bea5282bd15a1bc71133a1324db520f1014da689a747f948577cc8cb
5
5
  SHA512:
6
- metadata.gz: 0c4b421cb8214663e41fa70fdea474b1bc7c0c6cc61166a77a042dec930084d0e3856dde4a684fb21a5c721d4c5839453bbe030ac7b845acc334880de3b9ae66
7
- data.tar.gz: c51ac8f31f4712e896606a0b0c4469abe981a79bdf811eeecd631b953a096fc5cf8f991fae5cfdd8e38d6452cdb65720f5d2a9c8d5d051243f623ecdaad3708a
6
+ metadata.gz: 3b78f8febf8e8a276a24497963a8196b55b13be7360ee820229e4d0b7e1df7c8c143c1fb85f452e9b88c64bbda4a1fe60767e8bea5f1197d19cc5859ac7a8fdc
7
+ data.tar.gz: 3406e1c7c5409f284d6ece57369cc0e71342bc334063438614305e8e4690b4d05cab2695effc57257ad1ba1a706e9c5af837fe78e077b1528f306977c6b5fee2
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  [![Build Status](https://travis-ci.org/devnacho/mountain_view.svg?branch=master)](https://travis-ci.org/devnacho/mountain_view)
5
5
  [![Code Climate](https://codeclimate.com/github/jgnatch/mountain_view/badges/gpa.svg)](https://codeclimate.com/github/jgnatch/mountain_view)
6
+ [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
6
7
 
7
8
 
8
9
  With Mountain View you create reusable components for your Rails frontend, while generating a living style guide.
@@ -234,6 +235,69 @@ MountainView.configure do |config|
234
235
  end
235
236
  ```
236
237
 
238
+ ## Customizing Look and Feel
239
+
240
+ ### Customizing the style guide
241
+
242
+ To customize the styleguide, override the style guide layout by adding `mountain_view.html.erb` (or mountain_view.html.haml if using haml) to your application layouts folder in views.
243
+
244
+ ### Custom meta data for stub examples
245
+
246
+ You can customize the title, description for each example in the stub, as well as the classes that surround the stub example. In order to override the default title, add a `title` key to the `mv_stub_meta` hash. Additional special keys include `description` which will add a description under the title for a given example and `classes` which will add classes for a specific example.
247
+
248
+ E.g: `app/components/card/card.yml`
249
+ ```yml
250
+ -
251
+ :mv_stub_meta:
252
+ :title: "Specific Example"
253
+ :description: "Instructions for use case or other UX considerations"
254
+ :classes: "black-background"
255
+ :title: "Aspen Snowmass"
256
+ :description: "Aspen Snowmass is a winter resort complex located in Pitkin County in western Colorado in the United States. Owned and operated by the Aspen Skiing Company it comprises four skiing/snowboarding areas on four adjacent mountains in the vicinity of the towns of Aspen and Snowmass Village."
257
+ :link: "http://google.com"
258
+ :image_url: "http://i.imgur.com/QzuIJTo.jpg"
259
+ :data:
260
+ -
261
+ :title: "Elevation"
262
+ :number: '7879ft'
263
+ -
264
+ :title: "Depth"
265
+ :number: '71"'
266
+ ```
267
+
268
+
269
+ ## Improving performance
270
+ Rendering a large amount of partials in a request can lead to a performance bottleneck, usually this is caused by the parsing and rendering of template code such as ERB or HAML.
271
+
272
+ Via a Mountain View component you can render your HTML without touching a template parsing engine, which is super performant! To do this, you'll need to override `render(context, &block)` method, which is inherited from `MountainView::Presenter` class.
273
+
274
+ For example, if you had a component called `blank_state` with the Erb of:
275
+
276
+ ```html
277
+ <!-- app/components/blank_state/_blank_state.html.erb -->
278
+ <div class="blank-state <%= properties[:class] %>"></div>
279
+ ```
280
+
281
+ You'd override the `render` method in `blank_state_component.rb` like so:
282
+
283
+ ```ruby
284
+ # app/components/blank_state/blank_state_component.rb
285
+ class BlankStateComponent < MountainView::Presenter
286
+ properties :class
287
+
288
+ # Override the inherited render method to not read partials from the file system.
289
+ def render(context, &block)
290
+ # context is the view we've being rendered from, so it has all Rails helpers
291
+ context.content_tag(:div, '', class: [
292
+ 'blank-state',
293
+ properties[:class]
294
+ ].compact.join(' '))
295
+ end
296
+ end
297
+ ```
298
+
299
+ Anecdotally, a request which had to render 50 partials and took a whopping 2000ms was reduced to 200ms using this technique.
300
+
237
301
  ## Contributing
238
302
 
239
303
  See the [contributing guide](./CONTRIBUTING.md).
data/Rakefile CHANGED
@@ -1,33 +1,29 @@
1
1
  begin
2
- require 'bundler/setup'
2
+ require "bundler/setup"
3
3
  rescue LoadError
4
- puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
5
  end
6
6
 
7
- require 'rdoc/task'
7
+ require "rdoc/task"
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
- rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'MountainView'
12
- rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.rdoc')
14
- rdoc.rdoc_files.include('lib/**/*.rb')
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "MountainView"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.rdoc")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
15
  end
16
16
 
17
-
18
-
19
-
20
17
  Bundler::GemHelper.install_tasks
21
18
 
22
- require 'rake/testtask'
19
+ require "rake/testtask"
23
20
 
24
21
  Rake::TestTask.new(:test) do |t|
25
- t.libs << 'lib'
26
- t.libs << 'test'
27
- t.pattern = 'test/**/*_test.rb'
22
+ t.libs << "lib"
23
+ t.libs << "test"
24
+ t.pattern = "test/**/*_test.rb"
28
25
  t.verbose = false
29
26
  t.warning = false
30
27
  end
31
28
 
32
-
33
29
  task default: :test
@@ -18,6 +18,7 @@ body{
18
18
  background: #777;
19
19
  padding: 20px;
20
20
  }
21
+
21
22
  .mv-header__logo{
22
23
  font-weight: bold;
23
24
  color: white;
@@ -1,7 +1,7 @@
1
1
  module MountainView
2
2
  module StyleguideHelper
3
3
  def method_missing(method, *args, &block)
4
- if method.to_s.end_with?("_path") || method.to_s.end_with?("_url")
4
+ if method.to_s.end_with?("_path", "_url")
5
5
  if main_app.respond_to?(method)
6
6
  main_app.send(method, *args)
7
7
  else
@@ -13,7 +13,7 @@ module MountainView
13
13
  end
14
14
 
15
15
  def respond_to?(method, include_all = false)
16
- if method.to_s.end_with?("_path") || method.to_s.end_with?("_url")
16
+ if method.to_s.end_with?("_path", "_url")
17
17
  if main_app.respond_to?(method, include_all)
18
18
  true
19
19
  else
@@ -24,6 +24,10 @@ module MountainView
24
24
  end
25
25
  end
26
26
 
27
+ def respond_to_missing?(method, include_all = false)
28
+ respond_to?(method, include_all)
29
+ end
30
+
27
31
  def prettify_word(word)
28
32
  word.to_s.split("_").map(&:capitalize).join(" ")
29
33
  end
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>Styleguide</title>
4
+ <title><%= t('mountain_view.layout.styleguide_title') %></title>
5
5
  <%= stylesheet_link_tag 'mountain_view/styleguide', media: 'all', 'data-turbolinks-track' => true %>
6
6
  <%= javascript_include_tag 'mountain_view/styleguide', 'data-turbolinks-track' => true %>
7
7
 
@@ -9,12 +9,12 @@
9
9
  </head>
10
10
  <body>
11
11
  <div class="mv-header">
12
- <div class="mv-header__logo">STYLEGUIDE</div>
12
+ <div class="mv-header__logo"><%= t('mountain_view.layout.styleguide_title') %></div>
13
13
  </div>
14
14
  <div class="mv-flex-wrapper">
15
15
  <div class="mv-sidebar">
16
16
  <% if extra_pages.any? %>
17
- <h3>EXTRA PAGES</h3>
17
+ <h3><%= t('mountain_view.layout.extra_pages') %></h3>
18
18
  <ul>
19
19
  <%- extra_pages.each do |extra_page| %>
20
20
  <li>
@@ -23,7 +23,7 @@
23
23
  <% end %>
24
24
  </ul>
25
25
  <% end %>
26
- <h3>COMPONENTS</h3>
26
+ <h3><%= t('mountain_view.layout.components') %></h3>
27
27
  <ul>
28
28
  <%- mv_components.each do |component| %>
29
29
  <li>
@@ -1,11 +1,15 @@
1
1
  <pre>
2
- :meta: 'information about the component <%= component_name %>' # Optional
3
- :stubs: # As many as you need
2
+ :meta: '<%= t('mountain_view.example.sample_meta', component_name: component_name) %>'
3
+ :stubs: <%= t('mountain_view.example.stubs_note') %>
4
4
  -
5
+ :mv_stub_meta:
6
+ :title: <%= t('mountain_view.example.meta_title') %>
7
+ :description: <%= t('mountain_view.example.meta_description') %>
8
+ :classes: <%= t('mountain_view.example.meta_classes') %>
5
9
  :id: 1
6
- :title: "Some title"
7
- :subtitle: "Some subtitle"
10
+ :title: <%= t('mountain_view.example.title_1') %>
11
+ :subtitle: <%= t('mountain_view.example.subtitle_1') %>
8
12
  -
9
13
  :id: 2
10
- :title: "Another subtitle"
14
+ :title: <%= t('mountain_view.example.title_2') %>
11
15
  </pre>
@@ -1,22 +1,22 @@
1
1
  <div class="mv-main__header">
2
- <h1>Styleguide</h1>
2
+ <h1><%= t('.mountain_view.layout.styleguide_title') %></h1>
3
3
  </div>
4
4
 
5
5
  <% if mv_components.any? %>
6
6
  <div class="mv-main__description">
7
- Select one of the components from the side to view its examples and documentation.
7
+ <%= t('mountain_view.index.description') %>
8
8
  </div>
9
9
  <% else %>
10
10
  <div class="mv-hint">
11
- <h2><span>Hint:</span>You haven't created any components yet</h2>
11
+ <h2><%= t('mountain_view.index.hint_component_html') %></h2>
12
12
  <ul>
13
13
  <li>
14
- You can generate your first component by running:
14
+ <%= t('mountain_view.index.tip_first_component_html') %>
15
15
  <br>
16
16
  <pre>rails generate mountain_view:component component-name</pre>
17
17
  </li>
18
18
  <li>
19
- Or manually create the following files:
19
+ <%= t('mountain_view.index.tip_second_component_html') %>
20
20
  <br>
21
21
  <pre>
22
22
  app/
@@ -10,17 +10,21 @@
10
10
  </div>
11
11
  <% end %>
12
12
  <% if @component.component_stubs? %>
13
- <% @component.component_stubs.each_with_index do |component_properties, index| %>
13
+ <% @component.component_stubs.each_with_index do |component_stub, index| %>
14
14
  <div class="mv-component">
15
- <div class="mv-component__item">
16
- <%= render_component @component.name, component_properties.clone %>
15
+ <div class="mv-component__item <%= component_stub.meta_classes %>">
16
+ <%= render_component @component.name, component_stub.properties.clone %>
17
17
  </div>
18
18
  <div class="mv-component__description">
19
- <h2><%= @component.title %> <%= index + 1 %></h2>
19
+ <h2><%= component_stub.meta_title(@component.title, index) %></h2>
20
+ <% unless component_stub.meta_description.blank? %>
21
+ <p><%= component_stub.meta_description %></p>
22
+ <br />
23
+ <% end %>
20
24
  <div class="mv-component__description__definition">
21
25
  <code class="language-ruby">&lt;%= render_component("<%= @component.name %>", {properties as below}) %&gt;</code>
22
26
  </div>
23
- <%- formatted = JSON.pretty_generate component_properties %>
27
+ <%- formatted = JSON.pretty_generate component_stub.properties %>
24
28
  <div class="mv-component__description__properties">
25
29
  <code class="language-ruby"><%= formatted.gsub(/\"(\S+)?\":/, '\1:') %></code>
26
30
  </div>
@@ -30,10 +34,10 @@
30
34
  <% end %>
31
35
  <% else %>
32
36
  <div class="mv-hint">
33
- <h2><span>Hint:</span>You have Stubs but they don't follow the correct format</h2>
37
+ <h2><%= t('mountain_view.show.hint_stub_format_html') %></h2>
34
38
  <ul>
35
39
  <li>
36
- You should write stub examples like this:
40
+ <%= t('mountain_view.show.tip_stub_format_html') %>
37
41
  <br>
38
42
  <div class="mv-component__description__properties">
39
43
  <code class="language-yaml"><%= render 'example', component_name: @component.name %></code>
@@ -44,10 +48,10 @@
44
48
  <% end %>
45
49
  <% else %>
46
50
  <div class="mv-hint">
47
- <h2><span>Hint:</span>To see your component make sure you've created stubs:</h2>
51
+ <h2><%= t('mountain_view.show.hint_stub_creation_html') %></h2>
48
52
  <ul>
49
53
  <li>
50
- You should write stub examples here:
54
+ <%= t('mountain_view.show.tip_stub_creation_html') %>
51
55
  <br>
52
56
  <strong><%= @component.stubs_file %></strong>
53
57
  <div class="mv-component__description__properties">
@@ -0,0 +1,25 @@
1
+ en:
2
+ mountain_view:
3
+ layout:
4
+ styleguide_title: Style Guide
5
+ extra_pages: Extra Pages
6
+ components: Components
7
+ show:
8
+ hint_stub_format_html: <span>Hint:</span>You have Stubs but they don't follow the correct format.
9
+ tip_stub_format_html: 'You should write stub examples like this:'
10
+ hint_stub_creation_html: <span>Hint:</span>To see your component make sure you've created stubs
11
+ tip_stub_creation_html: 'You should write stub examples here:'
12
+ index:
13
+ description: Select one of the components from the side to view its examples and documentation.
14
+ hint_component_html: <span>Hint:</span>You haven't created any components yet
15
+ tip_first_component_html: 'You can generate your first component by running:'
16
+ tip_second_component_html: 'Or manually create the following files:'
17
+ example:
18
+ sample_meta: "information about the component %{component_name} # Optional"
19
+ stubs_note: "# As many as you need"
20
+ meta_title: '"Example Title"'
21
+ meta_description: '"Example description that gives details on each component use case, or specific UX guidance."'
22
+ meta_classes: '"Classes that affect the container surrounding the component in the style guide."'
23
+ title_1: '"Some title"'
24
+ subtitle_1: '"Some subtitle"'
25
+ title_2: '"Another title"'
@@ -7,6 +7,7 @@ MountainView::Engine.routes.draw do
7
7
  as: "extra_pages"
8
8
  end
9
9
 
10
- resources :styleguide, only: [:index, :show], path: MountainView.configuration.styleguide_path
10
+ resources :styleguide, only: [:index, :show],
11
+ path: MountainView.configuration.styleguide_path
11
12
  extra_routes if MountainView.configuration.extra_pages.any?
12
13
  end
@@ -12,6 +12,7 @@ module MountainView
12
12
  extra_pages.each do |page|
13
13
  file_name = "#{views_folder}/#{page}.html.#{template_engine}"
14
14
  next if File.exist?(file_name)
15
+
15
16
  create_file file_name
16
17
  end
17
18
  end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "mountain_view/version"
2
4
  require "mountain_view/configuration"
3
5
  require "mountain_view/presenter"
4
6
  require "mountain_view/component"
7
+ require "mountain_view/stub"
5
8
 
6
9
  module MountainView
7
10
  def self.configuration
@@ -16,10 +16,12 @@ module MountainView
16
16
  {}
17
17
  end
18
18
 
19
- def component_stubs
19
+ def raw_stubs
20
20
  if styleguide_stubs.is_a?(Hash)
21
+ # Stub is coming from Style Guide example file
21
22
  styleguide_stubs[:stubs] || {}
22
23
  elsif styleguide_stubs.is_a?(Array)
24
+ # Stub is coming from use of component
23
25
  styleguide_stubs
24
26
  end
25
27
  end
@@ -28,6 +30,12 @@ module MountainView
28
30
  component_stubs.any?
29
31
  end
30
32
 
33
+ def component_stubs
34
+ @component_stubs ||= raw_stubs.map do |component_properties|
35
+ MountainView::Stub.new(component_properties)
36
+ end
37
+ end
38
+
31
39
  def stubs_file
32
40
  MountainView.configuration.components_path.join(name, "#{name}.yml")
33
41
  end
@@ -1,6 +1,7 @@
1
1
  require "rails"
2
2
 
3
3
  module MountainView
4
+ # :nodoc:
4
5
  class Engine < ::Rails::Engine
5
6
  isolate_namespace MountainView
6
7
 
@@ -16,14 +17,14 @@ module MountainView
16
17
  app.config.autoload_paths += Dir[component_paths]
17
18
  end
18
19
 
19
- initializer "mountain_view.assets" do |app|
20
+ initializer "mountain_view.assets" do |_app|
20
21
  Rails.application.config.assets.paths <<
21
22
  MountainView.configuration.components_path
22
- Rails.application.config.assets.precompile += %w( mountain_view/styleguide.css
23
- mountain_view/styleguide.js )
23
+ Rails.application.config.assets.precompile +=
24
+ %w[mountain_view/styleguide.css mountain_view/styleguide.js]
24
25
  end
25
26
 
26
- initializer "mountain_view.append_view_paths" do |app|
27
+ initializer "mountain_view.append_view_paths" do |_app|
27
28
  ActiveSupport.on_load :action_controller do
28
29
  append_view_path MountainView.configuration.components_path
29
30
  end
@@ -10,10 +10,10 @@ module MountainView
10
10
  @properties = default_properties.deep_merge(properties)
11
11
  end
12
12
 
13
- def render(context, &block)
13
+ def render(context)
14
14
  context.extend ViewContext
15
15
  context.inject_component_context self
16
- properties[:yield] ||= yield
16
+ properties[:yield] ||= yield if block_given?
17
17
  context.render partial, partial: partial
18
18
  end
19
19
 
@@ -53,6 +53,7 @@ module MountainView
53
53
  def define_property_methods(names = [])
54
54
  names.each do |name|
55
55
  next if method_defined?(name)
56
+
56
57
  define_method name do
57
58
  properties[name.to_sym]
58
59
  end
@@ -60,6 +61,7 @@ module MountainView
60
61
  end
61
62
  end
62
63
 
64
+ # :nodoc:
63
65
  module ViewContext
64
66
  attr_reader :_component
65
67
  delegate :properties, to: :_component
@@ -70,6 +72,7 @@ module MountainView
70
72
  methods = component.public_methods(false) - protected_methods
71
73
  methods.each do |meth|
72
74
  next if self.class.method_defined?(meth)
75
+
73
76
  self.class.delegate meth, to: :_component
74
77
  end
75
78
  end