mountain_view 0.13.0 → 0.14.0

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.
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