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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49bd1e590f8faf9b5eb6a2ca87b556144bf0333d
4
- data.tar.gz: aff68306564d0e94d963e1de3fb28f13d33f714e
3
+ metadata.gz: 40e0a4ef6174624542dbc86dd1c6e4013458f5c5
4
+ data.tar.gz: 6107b8a0dce15687071b2acc798fb88e4a704a46
5
5
  SHA512:
6
- metadata.gz: e37992a8d7e267a8d056db03e77dd3a23f8e8e6b7e2a3b96a32d950e2370e646e889ba5e982f736938b7ed481fba4d34aa299eb262b507033f2f8792b9b7ec52
7
- data.tar.gz: 753ce8aba84b0410f406ac691a7294b7f0e4badad58b67907ac31811ab40329ffd3212506546cc84a4fb16c760e1ad944e6f141c7a457d023fb95e0205b8071f
6
+ metadata.gz: 287bfee2642a337f11bec08f8b9c30c1dddcab28679eef865bd4411653a57d4f3d8235a2f720b46ae210f0344fbdc6bf896dd91859fff35d9ce95fefa6f6195c
7
+ data.tar.gz: 5ecb567ec3c60cca672aaddc42a5bfe23c9051fc74e76ac1ff8c08618e75448baaf467fed9d49ed264d38f632430847ab2273a0ff968a1bcdb693afaaf7dbb27
data/README.md CHANGED
@@ -1,59 +1,128 @@
1
1
  # Komponent
2
2
 
3
- ## Installation
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
- gem 'komponent'
15
+ # Gemfile
16
+
17
+ gem "komponent"
7
18
  ```
8
19
 
9
- Modify your webpacker config to:
20
+ Run the following command to set up your project instantly:
10
21
 
22
+ ```sh
23
+ rails generate komponent:install
11
24
  ```
12
- # config/webpacker.yml
13
- source_path: frontend
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
- `rails generate component button`
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
- And use it in your views with helper. You can pass `locals`, or `block` to component helper.
43
+ ```slim
44
+ / app/views/pages/home.html.slim
23
45
 
24
- `= component('button')`
46
+ = component "button"
47
+ = c "button"
48
+ ```
25
49
 
26
- Locals passed in to component are accessible as instance variables.
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
- = component('button', color: :red)
57
+
58
+ ```slim
59
+ / frontend/components/button/_button.html.slim
30
60
 
31
61
  .button
32
- = @color
62
+ = @text
33
63
  ```
34
64
 
35
- You can define custom helpers in `ButtonComponent`:
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
- class ButtonComponent
39
- def bar
40
- "foo"
41
- end
42
- end
73
+
74
+ ```slim
75
+ / frontend/components/button/_button.html.slim
43
76
 
44
77
  .button
45
- = bar
78
+ = yield
46
79
  ```
47
80
 
48
- You can set properties in `ButtonComponent` too:
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
- class ButtonComponent
52
- property :foo, default: "bar", required: true
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
- .button
56
- = @foo
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.slim.erb", component_path + "_#{component}.html.slim"
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 + "#{component}.css"
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 + "#{component}.js"
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 + "#{component}_component.rb"
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/#{component}/#{component}\";"
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/#{component}/"
41
+ "frontend/components/#{component_name}/"
32
42
  end
33
43
 
34
44
  def module_name
35
- "#{component}_component".camelize
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
- .<%= component %> {}
1
+ .<%= component_name.dasherize %> {}
@@ -1 +1 @@
1
- import "./<%= component %>.css";
1
+ import "./<%= component_name %>.css";
@@ -0,0 +1,3 @@
1
+ <%= @locale %>:
2
+ <%= component_name %>:
3
+ component_name: <%= component_name %>
@@ -0,0 +1,3 @@
1
+ <div class="<%= component_name.dasherize %>">
2
+ <%= component_name %>
3
+ </div>
@@ -0,0 +1 @@
1
+ .<%= component_name.dasherize %> <%= component_name %>
@@ -1 +1 @@
1
- .<%= component %> <%= component %>
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
@@ -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.helper" do |app|
7
- ActionView::Base.send :include, KomponentHelper
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.controller" do |app|
11
- ActionController::Base.prepend_view_path "#{app.config.root}/frontend"
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|
@@ -1,3 +1,3 @@
1
1
  module Komponent
2
- VERSION = "1.0.0.pre.1"
2
+ VERSION = "1.0.0.pre.2"
3
3
  end
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.1
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-07 00:00:00.000000000 Z
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: []