Skip to content

Commit

Permalink
Merge branch '2.0.0.pre.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
florentferry committed Apr 12, 2018
2 parents b1f1f7c + 74568b7 commit cc961e6
Show file tree
Hide file tree
Showing 47 changed files with 391 additions and 105 deletions.
7 changes: 7 additions & 0 deletions .simplecov
@@ -0,0 +1,7 @@
SimpleCov.minimum_coverage 90

SimpleCov.start do
add_filter "/fixtures/"
add_filter "/test/"
add_filter "/features/"
end
3 changes: 1 addition & 2 deletions .travis.yml
Expand Up @@ -29,5 +29,4 @@ install:
- yarn

script:
- bundle exec rubocop
- bundle exec rake test
- bundle exec rake test:all_with_coverage
13 changes: 12 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,10 +2,21 @@

## Upcoming release

## v1.1.4 (2018-03-05)
## v2.0.0.pre.1 (2018-04-12)

**Breaking changes:**
- Removed deprecated `render_partial` method
- Removed rendering of namespaced component with the old naming convention

**Enhancements:**
- Changed `@block_given_to_component` from an instance variable to a method `block_given_to_component` available in the view context
- Implemented component caching with the `cached: true` option
- Added a `stylesheet_engine` option to Komponent configuration
- When generating a new component, the `frozen_string_literal: true` magic comment is prepended to Ruby files

## v1.1.4 (2018-03-05)

**Enhancements:**
- Added `frozen_string_literal` option to optimize performance
- Removed useless `autoload_paths` config definition (it was not taken into account)
- Install generator can be ran several times in order to enable features
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Expand Up @@ -14,4 +14,6 @@ gem "rubocop", require: false
group :test do
gem "aruba"
gem "cucumber"
gem "simplecov", require: false
gem "coveralls", require: false
end
47 changes: 41 additions & 6 deletions README.md
@@ -1,7 +1,9 @@
# <img alt="Komponent" src="https://raw.github.com/ouvrages/komponent/master/logo.svg?sanitize=true" width="200" height="40" />
[![Build Status](https://travis-ci.org/komposable/komponent.svg?branch=master)](https://travis-ci.org/komposable/komponent)
[![Gem](https://img.shields.io/gem/v/komponent.svg)](https://github.com/komposable/komponent)
[![Dependency Status](https://beta.gemnasium.com/badges/github.com/komposable/komponent.svg)](https://beta.gemnasium.com/projects/github.com/komposable/komponent) [![Maintainability](https://api.codeclimate.com/v1/badges/36d6dcf883df8f63893a/maintainability)](https://codeclimate.com/github/komposable/komponent/maintainability)
[![Dependency Status](https://beta.gemnasium.com/badges/github.com/komposable/komponent.svg)](https://beta.gemnasium.com/projects/github.com/komposable/komponent)
[![Maintainability](https://api.codeclimate.com/v1/badges/36d6dcf883df8f63893a/maintainability)](https://codeclimate.com/github/komposable/komponent/maintainability)
[![Coverage Status](https://coveralls.io/repos/github/komposable/komponent/badge.svg?branch=master)](https://coveralls.io/github/komposable/komponent?branch=master)

**Komponent** implements an opinionated way of organizing front-end code in Ruby on Rails, based on _components_.

Expand All @@ -22,6 +24,8 @@ This gem has been inspired by our Rails development practices at [Ouvrages](http
- [Getting started](#getting-started)
- [Usage](#usage)
- [Passing variables](#passing-variables)
- [Passing options](#passing-options)
- [Component caching](#component-caching)
- [Passing a block](#passing-a-block)
- [Properties](#properties)
- [Helpers](#helpers)
Expand All @@ -33,6 +37,7 @@ This gem has been inspired by our Rails development practices at [Ouvrages](http
- [Configuration](#configuration)
- [Change default root path](#change-default-root-path)
- [Default options for the generators](#default-options-for-the-generators)
- [Change default stylesheet engine](#change-default-stylesheet-engine)
- [Force default templating engine](#force-default-templating-engine)
- [Additional paths](#additional-paths)
- [Contributing](#contributing)
Expand Down Expand Up @@ -116,6 +121,25 @@ You can pass `locals` to the helper. They are accessible within the component pa
= @text
```

### Passing options

#### Component caching

Komponent relies on [Rails Low-level caching](http://guides.rubyonrails.org/caching_with_rails.html#low-level-caching).

You can cache the component by passing the `cached: true` option. The cache will expire when the locals, options or block change.
If you want better control of the cache expiration, you can provide a custom `cache_key`. When the `cache_key` changes, the cache will be cleared.

```slim
/ app/views/pages/home.html.slim
/ Cache the component based on its locals
= component "button", { text: "Click here" }, cached: true
/ or cache the component with a specific key, such as the last update of a model
= component "button", { text: "Click here" }, cached: true, cache_key: @product.updated_at
```

### Passing a block

The component also accepts a `block`. To render the block, just use the standard `yield`.
Expand Down Expand Up @@ -196,7 +220,8 @@ You can also choose to split your component into partials. In this case, we can
a.button(href=@href)
= @text
= render("suffix", text: "external link") if external_link?
- if external_link?
= render "suffix", text: "external link"
```

```slim
Expand All @@ -215,7 +240,6 @@ rails generate component admin/header

This will create the component in an `admin` folder, and name its Ruby module `AdminHeaderComponent`.


### Stimulus integration

Komponent supports [stimulus](https://github.com/stimulusjs/stimulus) 1.0.
Expand Down Expand Up @@ -275,8 +299,19 @@ You can whitelist the locales you use by setting this into an initializer, as ex
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.
### Configuration

#### Change default root path

You can change the default root path (`frontend`) to another path where Komponent should be installed and components generated. You need to change `komponent.root` in an initializer.

```rb
Rails.application.config.komponent.root = Rails.root.join("app/frontend")
```

#### Default options for the generators

You can configure the generators in an initializer or in `application.rb`, so you don't have to add `--locale` and/or `--stimulus` flags every time you generate a fresh component.
Expand All @@ -287,12 +322,12 @@ config.generators do |g|
end
```

#### Change default root path
#### Change default stylesheet engine

You can change the default root path (`frontend`) to another path where Komponent should be installed and components generated. You need to change `komponent.root` in an initializer.
You can configure the stylesheet engine used for generate stylesheet file, values allowed are ':css', ':scss', ':sass'.

```rb
Rails.application.config.komponent.root = Rails.root.join("app/frontend")
Rails.application.config.komponent.stylesheet_engine = :css # default value is :css
```

#### Force default templating engine
Expand Down
16 changes: 12 additions & 4 deletions Rakefile
@@ -1,25 +1,33 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require "rubocop/rake_task"
require "rake/testtask"
require 'cucumber'
require 'cucumber/rake/task'
require "cucumber"
require "cucumber/rake/task"
require "coveralls/rake/task"

namespace :test do
task all: [:unit, :cucumber]
task all: [:rubocop, :unit, :cucumber]
task all_with_coverage: [:all, "coveralls:push"]

RuboCop::RakeTask.new

Rake::TestTask.new(:unit) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/*_test.rb"]
t.verbose = true
t.warning = false
end

Cucumber::Rake::Task.new(:cucumber) do |t|
t.cucumber_opts = "--format pretty"
end

Coveralls::RakeTask.new
end

task test: 'test:all'
task test: "test:all"

task default: :test
25 changes: 25 additions & 0 deletions features/component_generator.feature
Expand Up @@ -15,6 +15,10 @@ Feature: Component generator
"""
import "components/awesome_button/awesome_button";
"""
And the file named "awesome_button/awesome_button_component.rb" should contain:
"""
# frozen_string_literal: true
"""

Scenario: Generate namespaced component
When I run `rails generate component admin/sub_admin/AwesomeButton`
Expand Down Expand Up @@ -68,6 +72,9 @@ Feature: Component generator
Then the file named "index.js" should contain:
"""
import "components/all/all";
import "components/bar/bar";
import "components/namespaced";
import "components/required/required";
import "components/some_example/some_example";
import "components/world/world";
"""
Expand Down Expand Up @@ -95,6 +102,24 @@ Feature: Component generator
And I cd to "frontend/components/awesome_button"
Then a file named "_awesome_button.html.slim" should exist

Scenario: Generate component with custom stylesheet engine defined to `scss`
Given a file named "config/initializers/custom_configuration.rb" with:
"""
Rails.application.config.komponent.stylesheet_engine = :scss
"""
When I run `rails generate component AwesomeButton`
And I cd to "frontend/components/awesome_button"
Then a file named "awesome_button.scss" should exist

Scenario: Generate component with custom template engine defined to `sass`
Given a file named "config/initializers/custom_configuration.rb" with:
"""
Rails.application.config.komponent.stylesheet_engine = :sass
"""
When I run `rails generate component AwesomeButton`
And I cd to "frontend/components/awesome_button"
Then a file named "awesome_button.sass" should exist

Scenario: Generate component with `--locale` option
When I run `rails generate component AwesomeButton --locale`
And I cd to "frontend/components"
Expand Down
3 changes: 3 additions & 0 deletions features/support/env.rb
@@ -0,0 +1,3 @@
# frozen_string_literal: true

require 'simplecov'
1 change: 1 addition & 0 deletions fixtures/my_app/config/application.rb
Expand Up @@ -12,5 +12,6 @@

module MyApp
class Application < Rails::Application
config.i18n.load_path += Dir[config.root.join('frontend/components/**/*.yml')]
end
end
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/bar/_bar.html.erb
@@ -0,0 +1 @@
<div class="bar"><%= yield %></div>
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/bar/bar.css
@@ -0,0 +1 @@
.bar {}
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/bar/bar.js
@@ -0,0 +1 @@
import "./bar.css";
3 changes: 3 additions & 0 deletions fixtures/my_app/frontend/components/bar/bar_component.rb
@@ -0,0 +1,3 @@
module BarComponent
extend ComponentHelper
end
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/foo/_foo.html.erb
@@ -0,0 +1 @@
<div class="foo"><%= properties[:bar] %></div>
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/foo/foo.js
@@ -0,0 +1 @@
import "./foo.scss";
2 changes: 2 additions & 0 deletions fixtures/my_app/frontend/components/foo/foo.scss
@@ -0,0 +1,2 @@
.foo {
}
5 changes: 5 additions & 0 deletions fixtures/my_app/frontend/components/foo/foo_component.rb
@@ -0,0 +1,5 @@
module FooComponent
extend ComponentHelper

property :bar, default: "Foobar"
end
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/hello/_hello.html.erb
@@ -0,0 +1 @@
<div class="hello"><%= t(".hello") %></div>
3 changes: 3 additions & 0 deletions fixtures/my_app/frontend/components/hello/hello.en.yml
@@ -0,0 +1,3 @@
en:
hello_component:
hello: "Hello"
3 changes: 3 additions & 0 deletions fixtures/my_app/frontend/components/hello/hello.fr.yml
@@ -0,0 +1,3 @@
fr:
hello_component:
hello: "Bonjour"
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/hello/hello.js
@@ -0,0 +1 @@
import "./hello.scss";
2 changes: 2 additions & 0 deletions fixtures/my_app/frontend/components/hello/hello.scss
@@ -0,0 +1,2 @@
.hello {
}
3 changes: 3 additions & 0 deletions fixtures/my_app/frontend/components/hello/hello_component.rb
@@ -0,0 +1,3 @@
module HelloComponent
extend ComponentHelper
end
3 changes: 3 additions & 0 deletions fixtures/my_app/frontend/components/index.js
@@ -1,2 +1,5 @@
import "components/all/all";
import "components/bar/bar";
import "components/namespaced";
import "components/required/required";
import "components/world/world";
@@ -0,0 +1 @@
<div class="namespaced-button">namespaced_button_component</div>
@@ -0,0 +1 @@
.namespaced-button {}
@@ -0,0 +1 @@
import "./namespaced_button.css";
@@ -0,0 +1,3 @@
module NamespacedButtonComponent
extend ComponentHelper
end
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/namespaced/index.js
@@ -0,0 +1 @@
import "components/namespaced/button/namespaced_button";
@@ -0,0 +1,3 @@
<div class="required">
required_component
</div>
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/required/required.css
@@ -0,0 +1 @@
.required {}
1 change: 1 addition & 0 deletions fixtures/my_app/frontend/components/required/required.js
@@ -0,0 +1 @@
import "./required.css";
@@ -0,0 +1,5 @@
module RequiredComponent
extend ComponentHelper

property :required, required: true
end
1 change: 1 addition & 0 deletions komponent.gemspec
Expand Up @@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.required_ruby_version = '>= 2.2.0'

spec.add_dependency "actionview", ">= 4.2"
spec.add_dependency "activesupport", ">= 4.2"
spec.add_dependency "railties", ">= 4.2"
spec.add_dependency "webpacker", ">= 3.0.0"
Expand Down
6 changes: 1 addition & 5 deletions lib/generators/component/component_generator.rb
Expand Up @@ -134,11 +134,7 @@ def template_engine
end

def stylesheet_engine
if sass = rails_configuration.try(:sass)
sass[:preferred_syntax]
else
:css
end
rails_configuration.komponent.stylesheet_engine
end

def default_path
Expand Down
2 changes: 2 additions & 0 deletions lib/generators/component/templates/rb.erb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module <%= module_name %>
extend ComponentHelper
end
Expand Up @@ -9,10 +9,5 @@ def property(name, options = {})

def self.extended(component)
component.properties = {}
component.class_eval do
def block_given_to_component?
@block_given_to_component.present?
end
end
end
end
File renamed without changes.

0 comments on commit cc961e6

Please sign in to comment.