diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..0ad438d
--- /dev/null
+++ b/.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
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89a9e56..cebd21c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## Upcoming release
+**Enhancements:**
+
+- Implement a styleguide view
+
## v2.1.0 (2018-05-31)
**Enhancements:**
diff --git a/README.md b/README.md
index 377f6c1..092daac 100644
--- a/README.md
+++ b/README.md
@@ -313,6 +313,23 @@ 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
+
+Update your routes to mount the Komponent engine.
+
+```ruby
+# config/routes.rb
+Rails.application.routes.draw do
+ mount Komponent::Engine => "/" if Rails.env.development?
+
+ # ...
+end
+```
+
+Then you need to update the `_example.html.slim` file you have inside your components. This file is used to render the examples.
+
+Finally just visit to `http://localhost:3000/styleguide`.
+
### Configuration
#### Change default root path
diff --git a/app/controllers/komponent/styleguide_controller.rb b/app/controllers/komponent/styleguide_controller.rb
new file mode 100644
index 0000000..58ad027
--- /dev/null
+++ b/app/controllers/komponent/styleguide_controller.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "komponent/component"
+
+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"
+ end
+ end
+end
diff --git a/app/views/komponent/styleguide/index.html.erb b/app/views/komponent/styleguide/index.html.erb
new file mode 100644
index 0000000..aff5aa1
--- /dev/null
+++ b/app/views/komponent/styleguide/index.html.erb
@@ -0,0 +1,15 @@
+
+
+<% if komponent_components.any? %>
+
+ Select one of the components from the side to view its examples and documentation.
+
+<% else %>
+
+
Hint:You haven't created any components yet
+
You can generate your first component by running:
+
rails generate component component-name
+
+<% end %>
diff --git a/app/views/komponent/styleguide/missing_template.html.erb b/app/views/komponent/styleguide/missing_template.html.erb
new file mode 100644
index 0000000..6fa0d09
--- /dev/null
+++ b/app/views/komponent/styleguide/missing_template.html.erb
@@ -0,0 +1,3 @@
+Example missing
+
+Please create <%= @component.path %>/_example.html.<%= Rails.application.config.app_generators.rails[:template_engine] || :erb %>
file.
diff --git a/app/views/komponent/styleguide/show.html.erb b/app/views/komponent/styleguide/show.html.erb
new file mode 100644
index 0000000..af5083e
--- /dev/null
+++ b/app/views/komponent/styleguide/show.html.erb
@@ -0,0 +1 @@
+<%= render partial: @component.example_view %>
diff --git a/app/views/layouts/komponent.html.erb b/app/views/layouts/komponent.html.erb
new file mode 100644
index 0000000..9fdaec4
--- /dev/null
+++ b/app/views/layouts/komponent.html.erb
@@ -0,0 +1,17 @@
+
+
+
+ Styleguide
+ <%= javascript_pack_tag "komponent" %>
+ <%= stylesheet_pack_tag "komponent", media: "all" %>
+ <%= csrf_meta_tags %>
+
+
+ <%=c 'komponent/header' %>
+ <%=c 'komponent/sidebar' %>
+ <%=c 'komponent/container' do %>
+ <%= yield %>
+ <% end %>
+ <%=c 'komponent/footer' %>
+
+
diff --git a/config/routes.rb b/config/routes.rb
new file mode 100644
index 0000000..e63dcaf
--- /dev/null
+++ b/config/routes.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+Komponent::Engine.routes.draw do
+ resources :styleguide, only: %i[index show] #, path: Komponent.configuration.styleguide_path
+end
diff --git a/features/component_generator.feature b/features/component_generator.feature
index e9541bf..113a3ae 100644
--- a/features/component_generator.feature
+++ b/features/component_generator.feature
@@ -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/_example.html.erb |
And the file named "index.js" should contain:
"""
import "components/awesome_button/awesome_button";
@@ -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/_example.html.erb |
And the file named "index.js" should contain:
"""
import "components/admin";
@@ -84,6 +86,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 "_example.html.erb" should exist
Scenario: Generate component with custom template engine defined to `haml`
Given a file named "config/initializers/custom_configuration.rb" with:
@@ -93,6 +96,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 "_example.html.haml" should exist
Scenario: Generate component with custom template engine defined to `slim`
Given a file named "config/initializers/custom_configuration.rb" with:
@@ -102,6 +106,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 "_example.html.slim" should exist
Scenario: Generate component with custom stylesheet engine defined to `scss`
Given a file named "config/initializers/custom_configuration.rb" with:
diff --git a/frontend/components/komponent/container/_komponent_container.html.erb b/frontend/components/komponent/container/_komponent_container.html.erb
new file mode 100644
index 0000000..31dc85d
--- /dev/null
+++ b/frontend/components/komponent/container/_komponent_container.html.erb
@@ -0,0 +1,3 @@
+
+ <%= yield %>
+
diff --git a/frontend/components/komponent/container/komponent_container.css b/frontend/components/komponent/container/komponent_container.css
new file mode 100644
index 0000000..c020b26
--- /dev/null
+++ b/frontend/components/komponent/container/komponent_container.css
@@ -0,0 +1,4 @@
+.komponent-container {
+ margin-left: 24rem;
+ margin-top: 4rem;
+}
diff --git a/frontend/components/komponent/container/komponent_container.js b/frontend/components/komponent/container/komponent_container.js
new file mode 100644
index 0000000..70b1a82
--- /dev/null
+++ b/frontend/components/komponent/container/komponent_container.js
@@ -0,0 +1 @@
+import "./komponent_container.css";
diff --git a/frontend/components/komponent/container/komponent_container_component.rb b/frontend/components/komponent/container/komponent_container_component.rb
new file mode 100644
index 0000000..3a2362d
--- /dev/null
+++ b/frontend/components/komponent/container/komponent_container_component.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module KomponentContainerComponent
+ extend ComponentHelper
+end
diff --git a/frontend/components/komponent/footer/_komponent_footer.html.erb b/frontend/components/komponent/footer/_komponent_footer.html.erb
new file mode 100644
index 0000000..c3a1fae
--- /dev/null
+++ b/frontend/components/komponent/footer/_komponent_footer.html.erb
@@ -0,0 +1,3 @@
+
diff --git a/frontend/components/komponent/footer/komponent_footer.css b/frontend/components/komponent/footer/komponent_footer.css
new file mode 100644
index 0000000..60555fc
--- /dev/null
+++ b/frontend/components/komponent/footer/komponent_footer.css
@@ -0,0 +1,21 @@
+.komponent-footer {
+ font-size: 1.4rem;
+ position: absolute;
+ bottom: 4rem;
+ right: 4rem;
+ text-align: center;
+
+ &,
+ a {
+ color: #999;
+ }
+
+ a {
+ text-decoration: none;
+
+ &:hover,
+ &:focus {
+ color: #0038ea;
+ }
+ }
+}
diff --git a/frontend/components/komponent/footer/komponent_footer.js b/frontend/components/komponent/footer/komponent_footer.js
new file mode 100644
index 0000000..c1d61e6
--- /dev/null
+++ b/frontend/components/komponent/footer/komponent_footer.js
@@ -0,0 +1 @@
+import "./komponent_footer.css";
diff --git a/frontend/components/komponent/footer/komponent_footer_component.rb b/frontend/components/komponent/footer/komponent_footer_component.rb
new file mode 100644
index 0000000..9f64ef8
--- /dev/null
+++ b/frontend/components/komponent/footer/komponent_footer_component.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module KomponentFooterComponent
+ extend ComponentHelper
+end
diff --git a/frontend/components/komponent/header/_komponent_header.html.erb b/frontend/components/komponent/header/_komponent_header.html.erb
new file mode 100644
index 0000000..e4feb12
--- /dev/null
+++ b/frontend/components/komponent/header/_komponent_header.html.erb
@@ -0,0 +1,3 @@
+
diff --git a/frontend/components/komponent/header/komponent_header.css b/frontend/components/komponent/header/komponent_header.css
new file mode 100644
index 0000000..6d0e637
--- /dev/null
+++ b/frontend/components/komponent/header/komponent_header.css
@@ -0,0 +1,9 @@
+.komponent-header {
+ align-items: center;
+ background-color: #0038ea;
+ color: white;
+ display: flex;
+ font-size: 1.8rem;
+ height: 8rem;
+ padding: 2rem;
+}
diff --git a/frontend/components/komponent/header/komponent_header.js b/frontend/components/komponent/header/komponent_header.js
new file mode 100644
index 0000000..b013393
--- /dev/null
+++ b/frontend/components/komponent/header/komponent_header.js
@@ -0,0 +1 @@
+import "./komponent_header.css";
diff --git a/frontend/components/komponent/header/komponent_header_component.rb b/frontend/components/komponent/header/komponent_header_component.rb
new file mode 100644
index 0000000..7d3d6b6
--- /dev/null
+++ b/frontend/components/komponent/header/komponent_header_component.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module KomponentHeaderComponent
+ extend ComponentHelper
+end
diff --git a/frontend/components/komponent/index.js b/frontend/components/komponent/index.js
new file mode 100644
index 0000000..878e312
--- /dev/null
+++ b/frontend/components/komponent/index.js
@@ -0,0 +1,4 @@
+import "components/komponent/container/komponent_container";
+import "components/komponent/footer/komponent_footer";
+import "components/komponent/header/komponent_header";
+import "components/komponent/sidebar/komponent_sidebar";
diff --git a/frontend/components/komponent/sidebar/_komponent_sidebar.html.erb b/frontend/components/komponent/sidebar/_komponent_sidebar.html.erb
new file mode 100644
index 0000000..0979f30
--- /dev/null
+++ b/frontend/components/komponent/sidebar/_komponent_sidebar.html.erb
@@ -0,0 +1,10 @@
+
diff --git a/frontend/components/komponent/sidebar/komponent_sidebar.css b/frontend/components/komponent/sidebar/komponent_sidebar.css
new file mode 100644
index 0000000..c4d308a
--- /dev/null
+++ b/frontend/components/komponent/sidebar/komponent_sidebar.css
@@ -0,0 +1,35 @@
+.komponent-sidebar {
+ background-color: #dbe1f3;
+ bottom: 0;
+ left: 0;
+ padding: 4rem 2rem;
+ position: absolute;
+ top: 8rem;
+ width: 20rem;
+
+ &-title {
+ color: #0038ea;
+ font-size: 1.4rem;
+ font-weight: bold;
+ letter-spacing: 0.2rem;
+ margin: 0 0 2rem;
+ text-transform: uppercase;
+ }
+
+ &-items {
+ line-height: 1.25;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ }
+
+ &-item + &-item {
+ margin-top: 0.5rem;
+ }
+
+ a {
+ color: #333;
+ display: block;
+ text-decoration: none;
+ }
+}
diff --git a/frontend/components/komponent/sidebar/komponent_sidebar.js b/frontend/components/komponent/sidebar/komponent_sidebar.js
new file mode 100644
index 0000000..2b3af41
--- /dev/null
+++ b/frontend/components/komponent/sidebar/komponent_sidebar.js
@@ -0,0 +1 @@
+import "./komponent_sidebar.css";
diff --git a/frontend/components/komponent/sidebar/komponent_sidebar_component.rb b/frontend/components/komponent/sidebar/komponent_sidebar_component.rb
new file mode 100644
index 0000000..3395063
--- /dev/null
+++ b/frontend/components/komponent/sidebar/komponent_sidebar_component.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module KomponentSidebarComponent
+ extend ComponentHelper
+end
diff --git a/lib/generators/component/component_generator.rb b/lib/generators/component/component_generator.rb
index e419cf1..add4aa7 100644
--- a/lib/generators/component/component_generator.rb
+++ b/lib/generators/component/component_generator.rb
@@ -34,6 +34,10 @@ def create_locale_files
end
end
+ def create_example_view_file
+ template "#{template_prefix}example.html.#{template_engine}.erb", component_path + "_example.html.#{template_engine}"
+ end
+
def import_to_packs
root_path = default_path
base_path = root_path + "components"
diff --git a/lib/generators/component/templates/example.html.erb.erb b/lib/generators/component/templates/example.html.erb.erb
new file mode 100644
index 0000000..bbedc2a
--- /dev/null
+++ b/lib/generators/component/templates/example.html.erb.erb
@@ -0,0 +1,3 @@
+<%= component_name %>
+
+<%%= component "<%= component_name %>" %>
diff --git a/lib/generators/component/templates/example.html.haml.erb b/lib/generators/component/templates/example.html.haml.erb
new file mode 100644
index 0000000..e3f98fa
--- /dev/null
+++ b/lib/generators/component/templates/example.html.haml.erb
@@ -0,0 +1,3 @@
+%h1 <%= component_name %>
+
+= component "<%= component_name %>"
diff --git a/lib/generators/component/templates/example.html.slim.erb b/lib/generators/component/templates/example.html.slim.erb
new file mode 100644
index 0000000..ed536ad
--- /dev/null
+++ b/lib/generators/component/templates/example.html.slim.erb
@@ -0,0 +1,3 @@
+h1 <%= component_name %>
+
+= component "<%= component_name %>"
diff --git a/lib/komponent.rb b/lib/komponent.rb
index 3d737e6..965007c 100644
--- a/lib/komponent.rb
+++ b/lib/komponent.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require "komponent/version"
+require 'komponent/version'
module Komponent
- require 'komponent/railtie' if defined?(Rails)
+ require 'komponent/engine' if defined?(Rails)
end
diff --git a/lib/komponent/component.rb b/lib/komponent/component.rb
new file mode 100644
index 0000000..3c988fe
--- /dev/null
+++ b/lib/komponent/component.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module Komponent
+ class Component
+ class << self
+ def all
+ component_dirs = components_root.join('*/**/')
+
+ components = {}
+
+ # TODO: list only components directories
+ # use ComponentPathResolver?
+ Dir.glob(component_dirs).sort.each do |component_dir|
+ component_path = Pathname.new(component_dir).relative_path_from(components_root).to_s
+
+ next unless File.exist?(components_root.join(component_path)
+ .join("#{File.basename(component_path)}_component.rb"))
+
+ components[component_path] = Component.new(component_path)
+ end
+
+ components
+ end
+
+ def find(id)
+ components = all
+
+ raise Exception, "Component with ID=#{id} not found" unless components.keys.include? id
+ components.fetch(id)
+ end
+
+ def components_root
+ @components_root ||= Rails.application.config.komponent.root.join('components')
+ end
+ end
+
+ attr_reader :id
+
+ def initialize(id)
+ @id = id
+ end
+
+ def title
+ id.titleize
+ end
+
+ def path
+ Komponent::ComponentPathResolver.new.resolve(@id)
+ end
+
+ def example_view
+ "components/#{id}/example"
+ end
+ end
+end
diff --git a/lib/komponent/railtie.rb b/lib/komponent/engine.rb
similarity index 64%
rename from lib/komponent/railtie.rb
rename to lib/komponent/engine.rb
index 283e750..f971744 100644
--- a/lib/komponent/railtie.rb
+++ b/lib/komponent/engine.rb
@@ -7,7 +7,9 @@
require 'komponent/translation'
module Komponent
- class Railtie < Rails::Railtie
+ class Engine < Rails::Engine
+ isolate_namespace Komponent
+
config.komponent = ActiveSupport::OrderedOptions.new
config.komponent.root = nil
config.komponent.component_paths = []
@@ -22,6 +24,9 @@ class Railtie < Rails::Railtie
app.config.komponent.component_paths.prepend(
app.config.komponent.root.join("components")
)
+ app.config.komponent.component_paths.append(
+ Komponent::Engine.root.join('frontend/components')
+ )
ActiveSupport.on_load :action_view do
require 'komponent/komponent_helper'
@@ -34,5 +39,15 @@ class Railtie < Rails::Railtie
)
end
end
+
+ initializer "my_engine.action_dispatch" do |app|
+ ActiveSupport.on_load :action_controller do
+ ActionController::Base.prepend_view_path Komponent::Engine.root.join("frontend")
+ end
+ end
+
+ initializer 'komponent.autoload', before: :set_autoload_paths do |app|
+ app.config.autoload_paths << Komponent::Engine.root.join('frontend')
+ end
end
end
diff --git a/lib/komponent/komponent_helper.rb b/lib/komponent/komponent_helper.rb
index fb90302..a7c53a4 100644
--- a/lib/komponent/komponent_helper.rb
+++ b/lib/komponent/komponent_helper.rb
@@ -13,4 +13,8 @@ def component(component_name, locals = {}, options = {}, &block)
)
end
alias :c :component
+
+ def komponent_components
+ Komponent::Component.all
+ end
end