komponent 1.0.0.pre.1 → 1.0.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +94 -25
- data/komponent.gemspec +3 -3
- data/lib/generators/component/component_generator.rb +29 -7
- data/lib/generators/component/templates/css.erb +1 -1
- data/lib/generators/component/templates/js.erb +1 -1
- data/lib/generators/component/templates/locale.erb +3 -0
- data/lib/generators/component/templates/view.html.erb.erb +3 -0
- data/lib/generators/component/templates/view.html.haml.erb +1 -0
- data/lib/generators/component/templates/view.html.slim.erb +1 -1
- data/lib/generators/komponent/install_generator.rb +58 -0
- data/lib/komponent/railtie.rb +15 -5
- data/lib/komponent/version.rb +1 -1
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40e0a4ef6174624542dbc86dd1c6e4013458f5c5
|
4
|
+
data.tar.gz: 6107b8a0dce15687071b2acc798fb88e4a704a46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 287bfee2642a337f11bec08f8b9c30c1dddcab28679eef865bd4411653a57d4f3d8235a2f720b46ae210f0344fbdc6bf896dd91859fff35d9ce95fefa6f6195c
|
7
|
+
data.tar.gz: 5ecb567ec3c60cca672aaddc42a5bfe23c9051fc74e76ac1ff8c08618e75448baaf467fed9d49ed264d38f632430847ab2273a0ff968a1bcdb693afaaf7dbb27
|
data/README.md
CHANGED
@@ -1,59 +1,128 @@
|
|
1
1
|
# Komponent
|
2
2
|
|
3
|
-
|
3
|
+
**Komponent** implements an opinionated way of organizing front-end code in Ruby on Rails, based on _components_.
|
4
|
+
|
5
|
+
Each component has its own folder, containing a Ruby module, a slim partial, a PostCSS stylesheet and a JavaScript file.
|
6
|
+
|
7
|
+
Komponent relies heavily on webpacker to manage dependencies and generate the production JS and CSS files.
|
8
|
+
|
9
|
+
This gem has been inspired by our Rails development practices at [Ouvrages](https://ouvrages-web.fr) and [Etamin Studio](https://etaminstudio.com), and the (excellent) [_Modern Front-end in Rails_](https://evilmartians.com/chronicles/evil-front-part-1) article from Evil Martians.
|
10
|
+
|
11
|
+
|
12
|
+
## Getting started
|
4
13
|
|
5
14
|
```ruby
|
6
|
-
|
15
|
+
# Gemfile
|
16
|
+
|
17
|
+
gem "komponent"
|
7
18
|
```
|
8
19
|
|
9
|
-
|
20
|
+
Run the following command to set up your project instantly:
|
10
21
|
|
22
|
+
```sh
|
23
|
+
rails generate komponent:install
|
11
24
|
```
|
12
|
-
|
13
|
-
|
14
|
-
|
25
|
+
|
26
|
+
This command will:
|
27
|
+
|
28
|
+
* check that the dependencies (currently, webpacker) are installed
|
29
|
+
* rename the `app/javascript` folder to `frontend` and modify webpacker config accordingly
|
30
|
+
* create the `frontend/components` folder where you will put your component
|
31
|
+
* create the `frontend/components/index.js` file that will list your components and `import` it in `frontend/packs/application.js`
|
15
32
|
|
16
33
|
## Usage
|
17
34
|
|
18
|
-
Generate new component with `component` generator:
|
35
|
+
Generate a new component with the `component` generator:
|
19
36
|
|
20
|
-
|
37
|
+
```sh
|
38
|
+
rails generate component button
|
39
|
+
```
|
40
|
+
|
41
|
+
Then, render it in your views with the `component` helper (or its alias `c`).
|
21
42
|
|
22
|
-
|
43
|
+
```slim
|
44
|
+
/ app/views/pages/home.html.slim
|
23
45
|
|
24
|
-
|
46
|
+
= component "button"
|
47
|
+
= c "button"
|
48
|
+
```
|
25
49
|
|
26
|
-
|
50
|
+
You can pass `locals` to the helper. They are accessible within the component partial, as instance variables.
|
27
51
|
|
52
|
+
```slim
|
53
|
+
/ app/views/pages/home.html.slim
|
54
|
+
|
55
|
+
= component "button", text: "My button"
|
28
56
|
```
|
29
|
-
|
57
|
+
|
58
|
+
```slim
|
59
|
+
/ frontend/components/button/_button.html.slim
|
30
60
|
|
31
61
|
.button
|
32
|
-
= @
|
62
|
+
= @text
|
33
63
|
```
|
34
64
|
|
35
|
-
|
65
|
+
The component also accepts a `block`. To render the block, just use the standard `yield`.
|
36
66
|
|
67
|
+
```slim
|
68
|
+
/ app/views/pages/home.html.slim
|
69
|
+
|
70
|
+
= component "button"
|
71
|
+
span= "My button"
|
37
72
|
```
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
73
|
+
|
74
|
+
```slim
|
75
|
+
/ frontend/components/button/_button.html.slim
|
43
76
|
|
44
77
|
.button
|
45
|
-
=
|
78
|
+
= yield
|
46
79
|
```
|
47
80
|
|
48
|
-
You can
|
81
|
+
Each component comes with a Ruby `module`. You can use it to set properties:
|
49
82
|
|
83
|
+
```ruby
|
84
|
+
# frontend/components/button/button_component.rb
|
85
|
+
|
86
|
+
module ButtonComponent
|
87
|
+
property :href, required: true
|
88
|
+
property :text, default: "My button"
|
89
|
+
end
|
50
90
|
```
|
51
|
-
|
52
|
-
|
91
|
+
|
92
|
+
```slim
|
93
|
+
/ frontend/components/button/_button.html.slim
|
94
|
+
|
95
|
+
a.button(href=@href)
|
96
|
+
= @text
|
97
|
+
```
|
98
|
+
|
99
|
+
If your partial becomes a too complex and you want to remove logic from it, you may want to define custom helpers in the `ButtonComponent` module:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
# frontend/components/button/button_component.rb
|
103
|
+
|
104
|
+
module ButtonComponent
|
105
|
+
property :href, required: true
|
106
|
+
property :text, default: "My button"
|
107
|
+
|
108
|
+
def external_link?
|
109
|
+
@href.starts_with? "http"
|
110
|
+
end
|
53
111
|
end
|
112
|
+
```
|
54
113
|
|
55
|
-
|
56
|
-
|
114
|
+
```slim
|
115
|
+
/ frontend/components/button/_button.html.slim
|
116
|
+
|
117
|
+
a.button(href=@href)
|
118
|
+
= @text
|
119
|
+
= " (external link)" if external_link?
|
120
|
+
```
|
121
|
+
|
122
|
+
```slim
|
123
|
+
/ app/views/pages/home.html.slim
|
124
|
+
|
125
|
+
= component "button", text: "My button", href: "http://github.com"
|
57
126
|
```
|
58
127
|
|
59
128
|
## Contributing
|
data/komponent.gemspec
CHANGED
@@ -9,9 +9,9 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Ouvrages"]
|
10
10
|
spec.email = ["contact@ouvrages-web.fr"]
|
11
11
|
|
12
|
-
spec.summary = ""
|
13
|
-
spec.description = ""
|
14
|
-
spec.homepage = ""
|
12
|
+
spec.summary = "An opinionated way of organizing front-end code in Ruby on Rails, based on components"
|
13
|
+
spec.description = "An opinionated way of organizing front-end code in Ruby on Rails, based on components"
|
14
|
+
spec.homepage = "http://komponent.io"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
@@ -2,36 +2,58 @@ class ComponentGenerator < Rails::Generators::Base
|
|
2
2
|
source_root File.expand_path('../templates', __FILE__)
|
3
3
|
|
4
4
|
argument :component, required: true, desc: "Component name, e.g: button"
|
5
|
+
class_option :locale, type: :boolean, default: false
|
5
6
|
|
6
7
|
def create_view_file
|
7
|
-
template "view.html.
|
8
|
+
template "view.html.#{template_engine}.erb", component_path + "_#{component_name}.html.#{template_engine}"
|
8
9
|
end
|
9
10
|
|
10
11
|
def create_css_file
|
11
|
-
template "css.erb", component_path + "#{
|
12
|
+
template "css.erb", component_path + "#{component_name}.css"
|
12
13
|
end
|
13
14
|
|
14
15
|
def create_js_file
|
15
|
-
template "js.erb", component_path + "#{
|
16
|
+
template "js.erb", component_path + "#{component_name}.js"
|
16
17
|
end
|
17
18
|
|
18
19
|
def create_rb_file
|
19
|
-
template "rb.erb", component_path + "#{
|
20
|
+
template "rb.erb", component_path + "#{component_name}_component.rb"
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_locale_files
|
24
|
+
return unless locale?
|
25
|
+
|
26
|
+
I18n.available_locales.each do |locale|
|
27
|
+
@locale = locale
|
28
|
+
template "locale.erb", component_path + "#{component_name}.#{locale}.yml"
|
29
|
+
end
|
20
30
|
end
|
21
31
|
|
22
32
|
def append_frontend_packs
|
23
33
|
append_to_file "frontend/components/index.js" do
|
24
|
-
"import \"components/#{
|
34
|
+
"import \"components/#{component_name}/#{component_name}\";"
|
25
35
|
end
|
26
36
|
end
|
27
37
|
|
28
38
|
protected
|
29
39
|
|
30
40
|
def component_path
|
31
|
-
"frontend/components/#{
|
41
|
+
"frontend/components/#{component_name}/"
|
32
42
|
end
|
33
43
|
|
34
44
|
def module_name
|
35
|
-
"#{
|
45
|
+
"#{component_name}_component".camelize
|
46
|
+
end
|
47
|
+
|
48
|
+
def component_name
|
49
|
+
component.underscore
|
50
|
+
end
|
51
|
+
|
52
|
+
def template_engine
|
53
|
+
Rails.application.config.app_generators.rails[:template_engine] || :erb
|
54
|
+
end
|
55
|
+
|
56
|
+
def locale?
|
57
|
+
options[:locale]
|
36
58
|
end
|
37
59
|
end
|
@@ -1 +1 @@
|
|
1
|
-
.<%=
|
1
|
+
.<%= component_name.dasherize %> {}
|
@@ -1 +1 @@
|
|
1
|
-
import "./<%=
|
1
|
+
import "./<%= component_name %>.css";
|
@@ -0,0 +1 @@
|
|
1
|
+
.<%= component_name.dasherize %> <%= component_name %>
|
@@ -1 +1 @@
|
|
1
|
-
.<%=
|
1
|
+
.<%= component_name.dasherize %> <%= component_name %>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Komponent
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
def check_webpacker_dependency
|
5
|
+
unless File.exists?(webpacker_configuration_file) and File.directory?(webpacker_default_structure)
|
6
|
+
raise Thor::Error, dependencies_not_met_error_message
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_root_directory
|
11
|
+
empty_directory(komponent_root_directory)
|
12
|
+
end
|
13
|
+
|
14
|
+
def modify_webpacker_configuration
|
15
|
+
gsub_file(webpacker_configuration_file, /source_path: app\/javascript$/, "source_path: frontend")
|
16
|
+
end
|
17
|
+
|
18
|
+
def move_webpacker_default_structure
|
19
|
+
run("mv #{webpacker_default_structure}/* #{komponent_root_directory}")
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_komponent_default_structure
|
23
|
+
empty_directory(components_directory)
|
24
|
+
create_file(components_directory.join("index.js"))
|
25
|
+
end
|
26
|
+
|
27
|
+
def append_to_application_pack
|
28
|
+
append_to_file(application_pack_path, "import 'components';")
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def application_pack_path
|
34
|
+
komponent_root_directory.join("packs", "application.js")
|
35
|
+
end
|
36
|
+
|
37
|
+
def komponent_root_directory
|
38
|
+
Rails.root.join("frontend")
|
39
|
+
end
|
40
|
+
|
41
|
+
def components_directory
|
42
|
+
Rails.root.join(komponent_root_directory, "components")
|
43
|
+
end
|
44
|
+
|
45
|
+
def webpacker_configuration_file
|
46
|
+
Rails.root.join("config", "webpacker.yml")
|
47
|
+
end
|
48
|
+
|
49
|
+
def webpacker_default_structure
|
50
|
+
Rails.root.join("app", "javascript")
|
51
|
+
end
|
52
|
+
|
53
|
+
def dependencies_not_met_error_message
|
54
|
+
"Seems you don't have webpacker installed in your project. Please install webpacker, and follow instructions at https://github.com/rails/webpacker"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/komponent/railtie.rb
CHANGED
@@ -1,14 +1,24 @@
|
|
1
|
-
require 'komponent/komponent_helper'
|
2
1
|
require 'komponent/core/component_helper'
|
3
2
|
|
4
3
|
module Komponent
|
5
4
|
class Railtie < Rails::Railtie
|
6
|
-
initializer "komponent.
|
7
|
-
|
5
|
+
initializer "komponent.action_view" do |app|
|
6
|
+
ActiveSupport.on_load :action_view do
|
7
|
+
require 'komponent/komponent_helper'
|
8
|
+
include KomponentHelper
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
|
-
initializer "komponent.
|
11
|
-
|
12
|
+
initializer "komponent.action_dispatch" do |app|
|
13
|
+
ActiveSupport.on_load :action_controller do
|
14
|
+
ActionController::Base.prepend_view_path "#{app.config.root}/frontend"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer "komponent.i18n" do |app|
|
19
|
+
ActiveSupport.on_load :i18n do
|
20
|
+
I18n.load_path.concat(Dir["#{app.config.root}/frontend/components/*/*.yml"])
|
21
|
+
end
|
12
22
|
end
|
13
23
|
|
14
24
|
initializer 'komponent.autoload', before: :set_autoload_paths do |app|
|
data/lib/komponent/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: komponent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ouvrages
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,7 +38,8 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
description:
|
41
|
+
description: An opinionated way of organizing front-end code in Ruby on Rails, based
|
42
|
+
on components
|
42
43
|
email:
|
43
44
|
- contact@ouvrages-web.fr
|
44
45
|
executables: []
|
@@ -57,14 +58,18 @@ files:
|
|
57
58
|
- lib/generators/component/component_generator.rb
|
58
59
|
- lib/generators/component/templates/css.erb
|
59
60
|
- lib/generators/component/templates/js.erb
|
61
|
+
- lib/generators/component/templates/locale.erb
|
60
62
|
- lib/generators/component/templates/rb.erb
|
63
|
+
- lib/generators/component/templates/view.html.erb.erb
|
64
|
+
- lib/generators/component/templates/view.html.haml.erb
|
61
65
|
- lib/generators/component/templates/view.html.slim.erb
|
66
|
+
- lib/generators/komponent/install_generator.rb
|
62
67
|
- lib/komponent.rb
|
63
68
|
- lib/komponent/core/component_helper.rb
|
64
69
|
- lib/komponent/komponent_helper.rb
|
65
70
|
- lib/komponent/railtie.rb
|
66
71
|
- lib/komponent/version.rb
|
67
|
-
homepage:
|
72
|
+
homepage: http://komponent.io
|
68
73
|
licenses:
|
69
74
|
- MIT
|
70
75
|
metadata: {}
|
@@ -87,5 +92,6 @@ rubyforge_project:
|
|
87
92
|
rubygems_version: 2.6.13
|
88
93
|
signing_key:
|
89
94
|
specification_version: 4
|
90
|
-
summary:
|
95
|
+
summary: An opinionated way of organizing front-end code in Ruby on Rails, based on
|
96
|
+
components
|
91
97
|
test_files: []
|