komponent 1.0.0.pre.1 → 1.0.0.pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []