Skip to content

Commit

Permalink
Merge baa5315 into 8a61f6f
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-brousse committed Feb 2, 2019
2 parents 8a61f6f + baa5315 commit 6767e6d
Show file tree
Hide file tree
Showing 44 changed files with 588 additions and 49 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
@@ -0,0 +1,14 @@
; top-most EditorConfig file
root = true

; Unix-style newlines
[*]
end_of_line = LF
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
6 changes: 3 additions & 3 deletions .rubocop.yml
Expand Up @@ -54,9 +54,6 @@ Naming/PredicateName:
Naming/VariableName:
Enabled: true

Lint/DeprecatedClassMethods:
Enabled: true

Layout/AlignParameters:
Enabled: true

Expand Down Expand Up @@ -117,3 +114,6 @@ Layout/SpaceInsideParens:

Layout/TrailingWhitespace:
Enabled: true

Lint/DeprecatedClassMethods:
Enabled: true
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,10 @@

**Enhancements:**
- Komponent now reports component stats when you run `bin/rails stats`
- Komponent now includes a styleguide engine that you can mount to your project
to document your components, and 2 new generators:
- `rails g komponent:styleguide` to set it up
- `rails g komponent:examples` to generate an `examples` file for each existing component

**Bug fixes:**
- Removed redundant `class` attribute in HAML templates
Expand Down
29 changes: 29 additions & 0 deletions README.md
Expand Up @@ -34,6 +34,7 @@ This gem has been inspired by our Rails development practices at [Ouvrages](http
- [Stimulus integration](#stimulus-integration)
- [Internationalization](#internationalization)
- [Available locales configuration](#available-locales-configuration)
- [Styleguide](#styleguide)
- [Configuration](#configuration)
- [Change default root path](#change-default-root-path)
- [Default options for the generators](#default-options-for-the-generators)
Expand Down Expand Up @@ -313,6 +314,34 @@ I18n.available_locales = [:en, :fr]
> If you have the `rails-i18n` gem in your `Gemfile`, you should whitelist locales to prevent creating a lot of
> locale files when you generate a new component.
### Styleguide

Komponent includes a basic styleguide engine that you can use in your project to document your components.

![Komponent styleguide UI](https://user-images.githubusercontent.com/38524/41193700-45909330-6c10-11e8-87b7-59e628529200.png)

To set it up, you can use the generator:

```sh
rails generate komponent:styleguide
```

This command will:

* copy the styleguide components (`komponent/container`, `komponent/footer`, `komponent/header` and `komponent/sidebar`) to your components folder, so you can customize them
* add a new `komponent.js` pack to your packs folder
* mount the engine in your routes

Then, for each component, you can describe it and render examples for each state in the `_example.html.slim` file from the component folder. The engine will then render it on the component page.

If you have existing components, you can generate all their example files at once with:

```sh
rails generate komponent:examples
```

Finally, visit `http://localhost:3000/styleguide` to access your styleguide.

### Configuration

#### Change default root path
Expand Down
20 changes: 20 additions & 0 deletions app/controllers/komponent/styleguide_controller.rb
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Komponent
class StyleguideController < ::ApplicationController
layout 'komponent'
rescue_from ActionView::MissingTemplate, with: :missing_template

def index; end

def show
@component = Komponent::Component.find(params[:id])
end

private

def missing_template
render 'komponent/styleguide/missing_template', status: :not_found
end
end
end
9 changes: 9 additions & 0 deletions app/views/komponent/styleguide/index.html.erb
@@ -0,0 +1,9 @@
<h1>Styleguide</h1>

<% if components.any? %>
<p>Select one of the components from the side to view its examples and documentation.</p>
<% else %>
<p><<strong>Hint:</strong> You haven't created any component yet</h2>
<p>You can generate your first component by running:</p>
<pre>rails generate component component-name</pre>
<% end %>
3 changes: 3 additions & 0 deletions app/views/komponent/styleguide/missing_template.html.erb
@@ -0,0 +1,3 @@
<h1>Examples missing</h1>

<p>Please create <code><%= @component.path %>/_examples.html.<%= Rails.application.config.app_generators.rails[:template_engine] || :erb %></code> file.</p>
1 change: 1 addition & 0 deletions app/views/komponent/styleguide/show.html.erb
@@ -0,0 +1 @@
<%= render partial: @component.examples_view %>
17 changes: 17 additions & 0 deletions app/views/layouts/komponent.html.erb
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>Styleguide</title>
<%= javascript_pack_tag 'komponent' %>
<%= stylesheet_pack_tag 'komponent', media: 'all' %>
<%= csrf_meta_tags %>
</head>
<body>
<%= c 'komponent/header' %>
<%= c 'komponent/sidebar' %>
<%= c 'komponent/container' do %>
<%= yield %>
<% end %>
<%= c 'komponent/footer' %>
</body>
</html>
5 changes: 5 additions & 0 deletions config/routes.rb
@@ -0,0 +1,5 @@
# frozen_string_literal: true

Komponent::Engine.routes.draw do
resources :styleguide, only: %i[index show]
end
5 changes: 5 additions & 0 deletions features/component_generator.feature
Expand Up @@ -11,6 +11,7 @@ Feature: Component generator
| awesome_button/awesome_button.css |
| awesome_button/awesome_button.js |
| awesome_button/awesome_button_component.rb |
| awesome_button/_examples.html.erb |
And the file named "index.js" should contain:
"""
import "components/awesome_button/awesome_button";
Expand All @@ -30,6 +31,7 @@ Feature: Component generator
| admin/sub_admin/awesome_button/admin_sub_admin_awesome_button.css |
| admin/sub_admin/awesome_button/admin_sub_admin_awesome_button.js |
| admin/sub_admin/awesome_button/admin_sub_admin_awesome_button_component.rb |
| admin/sub_admin/awesome_button/_examples.html.erb |
And the file named "index.js" should contain:
"""
import "components/admin";
Expand Down Expand Up @@ -117,6 +119,7 @@ Feature: Component generator
When I run `rails generate component AwesomeButton`
And I cd to "frontend/components/awesome_button"
Then a file named "_awesome_button.html.erb" should exist
And a file named "_examples.html.erb" should exist

Scenario: Generate component with custom template engine defined to `haml`
Given a file named "config/initializers/custom_configuration.rb" with:
Expand All @@ -126,6 +129,7 @@ Feature: Component generator
When I run `rails generate component AwesomeButton`
And I cd to "frontend/components/awesome_button"
Then a file named "_awesome_button.html.haml" should exist
And a file named "_examples.html.haml" should exist

Scenario: Generate component with custom template engine defined to `slim`
Given a file named "config/initializers/custom_configuration.rb" with:
Expand All @@ -135,6 +139,7 @@ Feature: Component generator
When I run `rails generate component AwesomeButton`
And I cd to "frontend/components/awesome_button"
Then a file named "_awesome_button.html.slim" should exist
And a file named "_examples.html.slim" should exist

Scenario: Generate component with custom stylesheet engine defined to `scss`
Given a file named "config/initializers/custom_configuration.rb" with:
Expand Down
4 changes: 4 additions & 0 deletions lib/generators/component/component_generator.rb
Expand Up @@ -34,6 +34,10 @@ def create_locale_files
end
end

def create_examples_view_file
template "examples.html.#{template_engine}.erb", component_path + "_examples.html.#{template_engine}"
end

def import_to_packs
root_path = default_path
base_path = root_path + "components"
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/component/templates/examples.html.erb.erb
@@ -0,0 +1,3 @@
<h1><%= @component_name %></h1>

<%%= cdoc "<%= component_name %>" %>
3 changes: 3 additions & 0 deletions lib/generators/component/templates/examples.html.haml.erb
@@ -0,0 +1,3 @@
%h1 <%= @component_name %>

= cdoc "<%= component_name %>"
3 changes: 3 additions & 0 deletions lib/generators/component/templates/examples.html.slim.erb
@@ -0,0 +1,3 @@
h1 <%= @component_name %>

= cdoc "<%= component_name %>"
40 changes: 40 additions & 0 deletions lib/generators/komponent/examples_generator.rb
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require 'komponent/component'
require File.expand_path('../utils', __FILE__)

module Komponent
module Generators
class ExamplesGenerator < Rails::Generators::Base
include Utils

source_root File.expand_path('../../component/templates', __FILE__)

def create_examples_files
Komponent::Component.all.each do |name, component|
create_examples_view_file(name)
end
end

protected

def split_name(name)
name.split(/[:,::,\/]/).reject(&:blank?).map(&:underscore)
end

def component_path(component_name)
path_parts = [default_path, 'components', *split_name(component_name)]

Pathname.new(path_parts.join('/'))
end

private

def create_examples_view_file(component_name)
@component_name = split_name(component_name).last.underscore

template "examples.html.#{template_engine}.erb", component_path(component_name) + "_examples.html.#{template_engine}"
end
end
end
end
40 changes: 3 additions & 37 deletions lib/generators/komponent/install_generator.rb
@@ -1,8 +1,11 @@
# frozen_string_literal: true
require File.expand_path('../utils', __FILE__)

module Komponent
module Generators
class InstallGenerator < Rails::Generators::Base
include Utils

class_option :stimulus, type: :boolean, default: false

def check_webpacker_dependency
Expand Down Expand Up @@ -80,14 +83,6 @@ def application_pack_path
komponent_root_directory.join("packs", "application.js")
end

def komponent_root_directory
default_path
end

def components_directory
Rails.root.join(komponent_root_directory, "components")
end

def webpacker_configuration_file
Rails.root.join("config", "webpacker.yml")
end
Expand All @@ -96,10 +91,6 @@ def webpacker_default_structure
Rails.root.join("app", "javascript")
end

def komponent_already_installed?
File.directory?(relative_path_from_rails)
end

def dependencies_not_met_error_message
"Seems you don't have webpacker installed in your project. Please install webpacker, and follow instructions at https://github.com/rails/webpacker"
end
Expand All @@ -108,31 +99,6 @@ def stimulus?
return options[:stimulus] if options[:stimulus]
komponent_configuration[:stimulus]
end

def default_path
rails_configuration.komponent.root
end

def relative_path_from_rails
default_path.relative_path_from(Rails.root)
end

private

def komponent_configuration
{
stimulus: nil,
locale: nil,
}.merge(app_generators.komponent)
end

def rails_configuration
Rails.application.config
end

def app_generators
rails_configuration.app_generators
end
end
end
end
41 changes: 41 additions & 0 deletions lib/generators/komponent/styleguide_generator.rb
@@ -0,0 +1,41 @@
# frozen_string_literal: true

require File.expand_path('../utils', __FILE__)

module Komponent
module Generators
class StyleguideGenerator < Rails::Generators::Base
include Utils

source_root File.expand_path('../templates/styleguide', __FILE__)

def check_komponent_dependency
unless komponent_already_installed?
raise Thor::Error, dependencies_not_met_error_message
end
end

def copy_styleguide_components
directory 'components', components_directory.join('komponent')
end

def create_komponent_pack
template 'packs/komponent.js', komponent_pack_path
end

def append_to_application_routes
route 'mount Komponent::Engine => \'/\' if Rails.env.development?'
end

protected

def komponent_pack_path
komponent_root_directory.join('packs', 'komponent.js')
end

def dependencies_not_met_error_message
'Seems you don\'t have komponent installed in your project. Please install komponent, and follow instructions at https://github.com/komposable/komponent'
end
end
end
end
@@ -0,0 +1,3 @@
<div class="komponent-container">
<%= yield %>
</div>
@@ -0,0 +1,17 @@
/* stylelint-disable value-list-comma-newline-after */

.komponent-container {
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
margin: 40px 60px 0 300px;

.komponent-code {
background-color: #333;
color: #fff;
margin: 10px 0;
padding: 10px;
}
}

/* stylelint-enable */
@@ -0,0 +1 @@
import "./komponent_container.css";
@@ -0,0 +1,5 @@
# frozen_string_literal: true

module KomponentContainerComponent
extend ComponentHelper
end
@@ -0,0 +1,3 @@
<div class="komponent-footer">
Built with <%= link_to "Komponent", "http://komponent.io", target: "_blank" %>
</div>

0 comments on commit 6767e6d

Please sign in to comment.