komponent 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +112 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +45 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/README.md +163 -7
- data/komponent.gemspec +5 -4
- data/lib/generators/component/component_generator.rb +46 -10
- data/lib/generators/component/templates/js.erb +11 -1
- data/lib/generators/component/templates/locale.erb +2 -2
- data/lib/generators/component/templates/sass.erb +1 -0
- data/lib/generators/component/templates/scss.erb +1 -0
- data/lib/generators/component/templates/stimulus_controller_js.erb +9 -0
- data/lib/generators/component/templates/stimulus_view.html.erb.erb +7 -0
- data/lib/generators/component/templates/stimulus_view.html.haml.erb +6 -0
- data/lib/generators/component/templates/stimulus_view.html.slim.erb +6 -0
- data/lib/generators/component/templates/view.html.erb.erb +5 -1
- data/lib/generators/component/templates/view.html.haml.erb +6 -1
- data/lib/generators/component/templates/view.html.slim.erb +6 -1
- data/lib/generators/komponent/install_generator.rb +43 -1
- data/lib/komponent/core/component_path_resolver.rb +52 -0
- data/lib/komponent/core/translation.rb +22 -0
- data/lib/komponent/komponent_helper.rb +32 -19
- data/lib/komponent/railtie.rb +12 -1
- data/lib/komponent/version.rb +1 -1
- metadata +56 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4658a034e4427f5870e308f64d0699e9b588b198
|
4
|
+
data.tar.gz: ef78a5b00c52b95676b15741765c8d221d12c697
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e362c8e4e277a68bfbf469c27c15f47a2544925710c16901b94eaf4b3d56a7359237f2b747a9b157ec68cc256476d11212456a37bc89e151b2d6aa6b8c823e2d
|
7
|
+
data.tar.gz: d8d8e23f3b219769d250cb58c46428bcc6344bbc68c18b300b39ef3d75d7d2ad8935ae44920da98d0a756dfd4efa08073d45f6e79222d492ff799454b027b5d2
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.4
|
3
|
+
DisabledByDefault: true
|
4
|
+
Exclude:
|
5
|
+
- 'node_modules/**/*'
|
6
|
+
- 'vendor/**/*'
|
7
|
+
- 'tmp/**/*'
|
8
|
+
|
9
|
+
Gemspec/OrderedDependencies:
|
10
|
+
Enabled: true
|
11
|
+
|
12
|
+
Style/BlockDelimiters:
|
13
|
+
Enabled: true
|
14
|
+
|
15
|
+
Style/BracesAroundHashParameters:
|
16
|
+
Enabled: true
|
17
|
+
EnforcedStyle: no_braces
|
18
|
+
|
19
|
+
Style/Dir:
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Style/Encoding:
|
23
|
+
Enabled: true
|
24
|
+
|
25
|
+
Style/For:
|
26
|
+
Enabled: true
|
27
|
+
EnforcedStyle: each
|
28
|
+
|
29
|
+
Style/MethodCallWithoutArgsParentheses:
|
30
|
+
Enabled: true
|
31
|
+
|
32
|
+
Style/MethodDefParentheses:
|
33
|
+
Enabled: true
|
34
|
+
|
35
|
+
Naming/ConstantName:
|
36
|
+
Enabled: true
|
37
|
+
|
38
|
+
Naming/FileName:
|
39
|
+
Enabled: true
|
40
|
+
|
41
|
+
Naming/MethodName:
|
42
|
+
Enabled: true
|
43
|
+
|
44
|
+
Naming/PredicateName:
|
45
|
+
Enabled: true
|
46
|
+
|
47
|
+
Naming/VariableName:
|
48
|
+
Enabled: true
|
49
|
+
|
50
|
+
Lint/BlockAlignment:
|
51
|
+
Enabled: true
|
52
|
+
EnforcedStyleAlignWith: start_of_block
|
53
|
+
|
54
|
+
Lint/ConditionPosition:
|
55
|
+
Enabled: true
|
56
|
+
|
57
|
+
Lint/DefEndAlignment:
|
58
|
+
Enabled: true
|
59
|
+
|
60
|
+
Lint/DeprecatedClassMethods:
|
61
|
+
Enabled: true
|
62
|
+
|
63
|
+
Layout/AlignParameters:
|
64
|
+
Enabled: true
|
65
|
+
|
66
|
+
Layout/BlockEndNewline:
|
67
|
+
Enabled: true
|
68
|
+
|
69
|
+
Layout/CaseIndentation:
|
70
|
+
Enabled: true
|
71
|
+
|
72
|
+
Layout/ClosingParenthesisIndentation:
|
73
|
+
Enabled: true
|
74
|
+
|
75
|
+
Layout/DotPosition:
|
76
|
+
Enabled: true
|
77
|
+
|
78
|
+
Layout/ElseAlignment:
|
79
|
+
Enabled: true
|
80
|
+
|
81
|
+
Layout/EmptyLines:
|
82
|
+
Enabled: true
|
83
|
+
|
84
|
+
Layout/EmptyLinesAroundAccessModifier:
|
85
|
+
Enabled: true
|
86
|
+
|
87
|
+
Layout/SpaceAroundBlockParameters:
|
88
|
+
Enabled: true
|
89
|
+
|
90
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
91
|
+
Enabled: true
|
92
|
+
|
93
|
+
Layout/SpaceAroundOperators:
|
94
|
+
Enabled: true
|
95
|
+
|
96
|
+
Layout/SpaceBeforeBlockBraces:
|
97
|
+
Enabled: true
|
98
|
+
|
99
|
+
Layout/SpaceBeforeComma:
|
100
|
+
Enabled: true
|
101
|
+
|
102
|
+
Layout/SpaceInsideArrayLiteralBrackets:
|
103
|
+
Enabled: true
|
104
|
+
|
105
|
+
Layout/SpaceInsideHashLiteralBraces:
|
106
|
+
Enabled: true
|
107
|
+
|
108
|
+
Layout/SpaceInsideParens:
|
109
|
+
Enabled: true
|
110
|
+
|
111
|
+
Layout/TrailingWhitespace:
|
112
|
+
Enabled: true
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## Upcoming release
|
4
|
+
|
5
|
+
## v1.1.0 (2018-01-12)
|
6
|
+
|
7
|
+
**Enhancements:**
|
8
|
+
- [stimulus](https://github.com/stimulusjs/stimulus) integration
|
9
|
+
- Component generator supports `css`, `scss`, `sass` stylesheet engine
|
10
|
+
- Add a component path resolver
|
11
|
+
|
12
|
+
**Bug fixes**
|
13
|
+
- Make `content_for` work in component
|
14
|
+
- Fix issue with wrong stylesheet extension being used when
|
15
|
+
imported in JavaScript files
|
16
|
+
|
17
|
+
**Deprecation**
|
18
|
+
- `render_partial` is deprecated in favor of default `render`
|
19
|
+
- The file naming convention will be changed in the next major version, for namespaced components, to include the namespace:
|
20
|
+
- `frontend/components/admin/button/_button.html.slim` -> `frontend/components/admin/button/_admin_button.html.slim`
|
21
|
+
- `frontend/components/admin/button/button.js` -> `frontend/components/admin/button/admin_button.js`
|
22
|
+
- `frontend/components/admin/button/button.css` -> `frontend/components/admin/button/admin_button.css`
|
23
|
+
|
24
|
+
## v1.0.0 (2018-01-01)
|
25
|
+
|
26
|
+
**Enhancements:**
|
27
|
+
|
28
|
+
- Components namespacing
|
29
|
+
- Implement basic features
|
30
|
+
- Implement `render_partial` helper
|
31
|
+
|
32
|
+
## v1.0.0.pre.2 (2017-12-09)
|
33
|
+
|
34
|
+
**Enhancements:**
|
35
|
+
|
36
|
+
- Lazy-load helpers and configuration
|
37
|
+
- Add an install generator (`rails g komponent:install`)
|
38
|
+
- Standardize components name (underscore for all except css classes are dasherized)
|
39
|
+
- Support `erb`, `slim`, and `haml` template engines
|
40
|
+
- Add an `--locale` option to component generator
|
41
|
+
- Documentation improvements
|
42
|
+
|
43
|
+
## v1.0.0.pre.1 (2017-12-09)
|
44
|
+
|
45
|
+
First pre-release
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6
|
+
|
7
|
+
## Our Standards
|
8
|
+
|
9
|
+
Examples of behavior that contributes to creating a positive environment include:
|
10
|
+
|
11
|
+
* Using welcoming and inclusive language
|
12
|
+
* Being respectful of differing viewpoints and experiences
|
13
|
+
* Gracefully accepting constructive criticism
|
14
|
+
* Focusing on what is best for the community
|
15
|
+
* Showing empathy towards other community members
|
16
|
+
|
17
|
+
Examples of unacceptable behavior by participants include:
|
18
|
+
|
19
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
20
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
21
|
+
* Public or private harassment
|
22
|
+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
23
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
24
|
+
|
25
|
+
## Our Responsibilities
|
26
|
+
|
27
|
+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
28
|
+
|
29
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
30
|
+
|
31
|
+
## Scope
|
32
|
+
|
33
|
+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
34
|
+
|
35
|
+
## Enforcement
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@komposable.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
38
|
+
|
39
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
40
|
+
|
41
|
+
## Attribution
|
42
|
+
|
43
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
44
|
+
|
45
|
+
[homepage]: http://contributor-covenant.org
|
46
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/README.md
CHANGED
@@ -1,15 +1,37 @@
|
|
1
1
|
# <img alt="Komponent" src="https://raw.github.com/ouvrages/komponent/master/logo.svg?sanitize=true" width="200" height="40" />
|
2
2
|
[![Build Status](https://travis-ci.org/komposable/komponent.svg?branch=master)](https://travis-ci.org/komposable/komponent)
|
3
|
-
|
3
|
+
[![Gem](https://img.shields.io/gem/v/komponent.svg)](https://github.com/komposable/komponent)
|
4
4
|
|
5
5
|
**Komponent** implements an opinionated way of organizing front-end code in Ruby on Rails, based on _components_.
|
6
6
|
|
7
|
-
Each component has its own folder, containing a Ruby module, a
|
7
|
+
Each component has its own folder, containing a Ruby module, a partial, a stylesheet and a JavaScript file.
|
8
8
|
|
9
9
|
Komponent relies heavily on webpacker to manage dependencies and generate the production JS and CSS files.
|
10
10
|
|
11
|
+
This README examples are written in Slim, but Komponent is compatible with:
|
12
|
+
|
13
|
+
- your preferred templating language (Slim, Haml, erb)
|
14
|
+
- your stylesheet language of choice (Sass, SCSS, CSS, PostCSS)
|
15
|
+
|
11
16
|
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.
|
12
17
|
|
18
|
+
## Table of contents
|
19
|
+
|
20
|
+
- [Getting started](#getting-started)
|
21
|
+
- [Usage](#usage)
|
22
|
+
- [Passing variables](#passing-variables)
|
23
|
+
- [Passing a block](#passing-a-block)
|
24
|
+
- [Properties](#properties)
|
25
|
+
- [Helpers](#helpers)
|
26
|
+
- [Component partials](#component-partials)
|
27
|
+
- [Namespacing components](#namespacing-components)
|
28
|
+
- [Stimulus integration](#stimulus-integration)
|
29
|
+
- [Internationalization](#internationalization)
|
30
|
+
- [Configuration](#configuration)
|
31
|
+
- [Default options for the generators](#default-options-for-the-generators)
|
32
|
+
- [Additional paths](#additional-paths)
|
33
|
+
- [Contributing](#contributing)
|
34
|
+
- [License](#license)
|
13
35
|
|
14
36
|
## Getting started
|
15
37
|
|
@@ -137,19 +159,18 @@ a.button(href=@href)
|
|
137
159
|
|
138
160
|
### Component partials
|
139
161
|
|
140
|
-
You can also choose to split your component into partials. In this case, use the `
|
162
|
+
You can also choose to split your component into partials. In this case, we can use the default `render` helper to render a partial, stored inside the component directory.
|
141
163
|
|
142
164
|
```slim
|
143
165
|
/ frontend/components/button/_button.html.slim
|
144
166
|
|
145
167
|
= a.button(href=@href)
|
146
168
|
= @text
|
147
|
-
|
148
|
-
= render_partial("suffix", text: "external link") if external_link?
|
169
|
+
= render("suffix", text: "external link") if external_link?
|
149
170
|
```
|
150
171
|
|
151
172
|
```slim
|
152
|
-
/ frontend/components/button/
|
173
|
+
/ frontend/components/button/_suffix.html.slim
|
153
174
|
|
154
175
|
= " (#{text})"
|
155
176
|
```
|
@@ -165,9 +186,144 @@ rails generate component admin/header
|
|
165
186
|
This will create the component in an `admin` folder, and name its Ruby module `AdminHeaderComponent`.
|
166
187
|
|
167
188
|
|
189
|
+
### Stimulus integration
|
190
|
+
|
191
|
+
You can pass `--stimulus` to both generators to use [stimulus](https://github.com/stimulusjs/stimulus) in your components.
|
192
|
+
|
193
|
+
```sh
|
194
|
+
rails generate komponent:install --stimulus
|
195
|
+
```
|
196
|
+
|
197
|
+
This will yarn `stimulus` package, and create a `stimulus_application.js` in the `frontend` folder.
|
198
|
+
|
199
|
+
```sh
|
200
|
+
rails generate component button --stimulus
|
201
|
+
```
|
202
|
+
|
203
|
+
This will create a component with an additional `button_controller.js` file, and define a `data-controller` in the generated view.
|
204
|
+
|
205
|
+
### Internationalization
|
206
|
+
|
207
|
+
In case your component will contain text strings you want to localize, you can pass the `--locale` option to generate localization files in your component directory.
|
208
|
+
|
209
|
+
```sh
|
210
|
+
rails generate component button --locale
|
211
|
+
```
|
212
|
+
|
213
|
+
This will create a `yml` file for each locale (using `I18n.available_locales`). In your component, the `t` helper will use the same ["lazy" lookup](http://guides.rubyonrails.org/i18n.html#lazy-lookup) as Rails.
|
214
|
+
|
215
|
+
```slim
|
216
|
+
/ frontend/components/button/_button.html.slim
|
217
|
+
= a.button(href=@href)
|
218
|
+
= @text
|
219
|
+
= render("suffix", text: t(".external_link")) if external_link?
|
220
|
+
```
|
221
|
+
|
222
|
+
```yml
|
223
|
+
/ frontend/components/button/button.en.yml
|
224
|
+
en:
|
225
|
+
button_component:
|
226
|
+
external_link: "external link"
|
227
|
+
```
|
228
|
+
|
229
|
+
```yml
|
230
|
+
/ frontend/components/button/button.fr.yml
|
231
|
+
fr:
|
232
|
+
button_component:
|
233
|
+
external_link: "lien externe"
|
234
|
+
```
|
235
|
+
|
236
|
+
### Configuration
|
237
|
+
|
238
|
+
#### Default options for the generators
|
239
|
+
|
240
|
+
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.
|
241
|
+
|
242
|
+
```rb
|
243
|
+
config.generators do |g|
|
244
|
+
g.komponent stimulus: true, locale: true # both are false by default
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
#### Additional paths
|
249
|
+
|
250
|
+
You may want to use components in a gem, or a Rails engine, and expose them to the main app. In order to do that, you just have to configure the paths where Komponent will look for components.
|
251
|
+
|
252
|
+
From a gem:
|
253
|
+
|
254
|
+
```rb
|
255
|
+
module MyGem
|
256
|
+
class Railtie < Rails::Railtie
|
257
|
+
config.after_initialize do |app|
|
258
|
+
app.config.komponent.component_paths.append(self.root.join("frontend/components"))
|
259
|
+
end
|
260
|
+
|
261
|
+
initializer "my_gem.action_dispatch" do |app|
|
262
|
+
ActiveSupport.on_load :action_controller do
|
263
|
+
ActionController::Base.prepend_view_path self.root.join("frontend")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
initializer 'my_gem.autoload', before: :set_autoload_paths do |app|
|
268
|
+
app.config.autoload_paths << self.root.join("frontend")
|
269
|
+
end
|
270
|
+
|
271
|
+
private
|
272
|
+
|
273
|
+
def self.root
|
274
|
+
Pathname.new(File.dirname(__dir__))
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
```
|
279
|
+
|
280
|
+
or from an engine:
|
281
|
+
|
282
|
+
|
283
|
+
```rb
|
284
|
+
module MyEngine
|
285
|
+
class Engine < Rails::Engine
|
286
|
+
isolate_namespace MyEngine
|
287
|
+
|
288
|
+
config.after_initialize do |app|
|
289
|
+
app.config.komponent.component_paths.append(MyEngine::Engine.root.join("frontend/components"))
|
290
|
+
end
|
291
|
+
|
292
|
+
initializer "my_engine.action_dispatch" do |app|
|
293
|
+
ActiveSupport.on_load :action_controller do
|
294
|
+
ActionController::Base.prepend_view_path MyEngine::Engine.root.join("frontend")
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
initializer 'my_engine.autoload', before: :set_autoload_paths do |app|
|
299
|
+
app.config.autoload_paths << MyEngine::Engine.root.join("frontend")
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
```
|
304
|
+
|
305
|
+
Make sure you add `komponent` to the runtime dependencies in your `gemspec`.
|
306
|
+
|
307
|
+
In order to compile packs from engine, and to use `javascript_pack_tag 'engine'`, you need to:
|
308
|
+
|
309
|
+
- Create a pack file in main app
|
310
|
+
|
311
|
+
```js
|
312
|
+
// frontend/packs/engine.js
|
313
|
+
|
314
|
+
import 'packs/engine';
|
315
|
+
```
|
316
|
+
|
317
|
+
- Append engine frontend folder to `resolved_paths` in `config/webpacker.yml` from your main app
|
318
|
+
|
319
|
+
```yml
|
320
|
+
resolved_paths:
|
321
|
+
- engine/frontend
|
322
|
+
```
|
323
|
+
|
168
324
|
## Contributing
|
169
325
|
|
170
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
326
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/komposable/komponent.
|
171
327
|
|
172
328
|
## License
|
173
329
|
|
data/komponent.gemspec
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require "komponent/version"
|
@@ -21,10 +20,12 @@ Gem::Specification.new do |spec|
|
|
21
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
21
|
spec.require_paths = ["lib"]
|
23
22
|
|
23
|
+
spec.add_development_dependency "aruba"
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.15"
|
25
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
-
|
27
25
|
spec.add_development_dependency "cucumber"
|
28
|
-
spec.add_development_dependency "aruba"
|
29
26
|
spec.add_development_dependency "rails", ">= 5.0"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rubocop", '~> 0.52.1'
|
29
|
+
|
30
|
+
spec.add_runtime_dependency "webpacker", ">= 3.0.0"
|
30
31
|
end
|
@@ -2,17 +2,21 @@ class ComponentGenerator < Rails::Generators::NamedBase
|
|
2
2
|
source_root File.expand_path('../templates', __FILE__)
|
3
3
|
|
4
4
|
class_option :locale, type: :boolean, default: false
|
5
|
+
class_option :stimulus, type: :boolean, default: false
|
5
6
|
|
6
7
|
def create_view_file
|
7
|
-
template "view.html.#{template_engine}.erb", component_path + "_#{
|
8
|
+
template "#{template_prefix}view.html.#{template_engine}.erb", component_path + "_#{name_with_namespace.underscore}.html.#{template_engine}"
|
8
9
|
end
|
9
10
|
|
10
11
|
def create_css_file
|
11
|
-
template "
|
12
|
+
template "#{stylesheet_engine}.erb", component_path + "#{name_with_namespace}.#{stylesheet_engine}"
|
12
13
|
end
|
13
14
|
|
14
15
|
def create_js_file
|
15
|
-
template "js.erb", component_path + "#{
|
16
|
+
template "js.erb", component_path + "#{name_with_namespace}.js"
|
17
|
+
if stimulus?
|
18
|
+
template "stimulus_controller_js.erb", component_path + "#{name_with_namespace}_controller.js"
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
def create_rb_file
|
@@ -24,7 +28,7 @@ class ComponentGenerator < Rails::Generators::NamedBase
|
|
24
28
|
|
25
29
|
I18n.available_locales.each do |locale|
|
26
30
|
@locale = locale
|
27
|
-
template "locale.erb", component_path + "#{
|
31
|
+
template "locale.erb", component_path + "#{name_with_namespace}.#{locale}.yml"
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -37,7 +41,7 @@ class ComponentGenerator < Rails::Generators::NamedBase
|
|
37
41
|
split_name[0..-2].each do |split|
|
38
42
|
base_path += split
|
39
43
|
file_path = base_path + "index.js"
|
40
|
-
create_file(file_path) unless File.
|
44
|
+
create_file(file_path) unless File.exist?(file_path)
|
41
45
|
imports << base_path.relative_path_from(root_path)
|
42
46
|
end
|
43
47
|
|
@@ -54,12 +58,16 @@ class ComponentGenerator < Rails::Generators::NamedBase
|
|
54
58
|
end
|
55
59
|
|
56
60
|
append_to_file(base_path + "index.js") do
|
57
|
-
"import \"#{base_path.relative_path_from(root_path)}/#{component_name}/#{
|
58
|
-
end
|
61
|
+
"import \"#{base_path.relative_path_from(root_path)}/#{component_name}/#{name_with_namespace.underscore}\";\n"
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
65
|
protected
|
62
66
|
|
67
|
+
def template_prefix
|
68
|
+
stimulus? ? "stimulus_" : ""
|
69
|
+
end
|
70
|
+
|
63
71
|
def split_name
|
64
72
|
name.split(/[:,::,\/]/).reject(&:blank?).map(&:underscore)
|
65
73
|
end
|
@@ -81,16 +89,44 @@ class ComponentGenerator < Rails::Generators::NamedBase
|
|
81
89
|
def component_class_name
|
82
90
|
name_with_namespace.dasherize
|
83
91
|
end
|
84
|
-
|
92
|
+
|
85
93
|
def component_name
|
86
94
|
split_name.last.underscore
|
87
95
|
end
|
88
96
|
|
89
97
|
def template_engine
|
90
|
-
|
98
|
+
app_generators.rails[:template_engine] || :erb
|
99
|
+
end
|
100
|
+
|
101
|
+
def stylesheet_engine
|
102
|
+
if sass = rails_configuration.try(:sass)
|
103
|
+
sass[:preferred_syntax]
|
104
|
+
else
|
105
|
+
:css
|
106
|
+
end
|
91
107
|
end
|
92
108
|
|
93
109
|
def locale?
|
94
|
-
options[:locale]
|
110
|
+
return options[:locale] if options[:locale]
|
111
|
+
komponent_configuration[:locale]
|
112
|
+
end
|
113
|
+
|
114
|
+
def stimulus?
|
115
|
+
return options[:stimulus] if options[:stimulus]
|
116
|
+
komponent_configuration[:stimulus]
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def komponent_configuration
|
122
|
+
{ stimulus: nil, locale: nil }.merge app_generators.komponent
|
123
|
+
end
|
124
|
+
|
125
|
+
def rails_configuration
|
126
|
+
Rails.application.config
|
127
|
+
end
|
128
|
+
|
129
|
+
def app_generators
|
130
|
+
rails_configuration.app_generators
|
95
131
|
end
|
96
132
|
end
|
@@ -1 +1,11 @@
|
|
1
|
-
|
1
|
+
<%- if stimulus? -%>
|
2
|
+
import application from 'stimulus_application';
|
3
|
+
import { autoload } from "stimulus/webpack-helpers";
|
4
|
+
|
5
|
+
import "./<%= name_with_namespace %>.<%= stylesheet_engine %>";
|
6
|
+
|
7
|
+
const context = require.context('./', true, /_controller\.js$/);
|
8
|
+
autoload(context, application);
|
9
|
+
<%- else -%>
|
10
|
+
import "./<%= name_with_namespace %>.<%= stylesheet_engine %>";
|
11
|
+
<%- end -%>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<%= @locale %>:
|
2
|
-
<%=
|
3
|
-
component_name: <%=
|
2
|
+
<%= module_name.underscore %>:
|
3
|
+
component_name: <%= module_name.underscore %>
|
@@ -0,0 +1 @@
|
|
1
|
+
.<%= component_class_name %>
|
@@ -0,0 +1 @@
|
|
1
|
+
.<%= component_class_name %> {}
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module Komponent
|
2
2
|
module Generators
|
3
3
|
class InstallGenerator < Rails::Generators::Base
|
4
|
+
class_option :stimulus, type: :boolean, default: false
|
5
|
+
|
4
6
|
def check_webpacker_dependency
|
5
|
-
unless File.
|
7
|
+
unless File.exist?(webpacker_configuration_file) and File.directory?(webpacker_default_structure)
|
6
8
|
raise Thor::Error, dependencies_not_met_error_message
|
7
9
|
end
|
8
10
|
end
|
@@ -24,12 +26,33 @@ module Komponent
|
|
24
26
|
create_file(components_directory.join("index.js"))
|
25
27
|
end
|
26
28
|
|
29
|
+
def create_stimulus_file
|
30
|
+
template = <<-eos
|
31
|
+
import { Application } from "stimulus";
|
32
|
+
const application = Application.start();
|
33
|
+
export default application;
|
34
|
+
eos
|
35
|
+
create_file(stimulus_application_path, stimulus? ? template : "")
|
36
|
+
end
|
37
|
+
|
27
38
|
def append_to_application_pack
|
28
39
|
append_to_file(application_pack_path, "import 'components';")
|
29
40
|
end
|
30
41
|
|
42
|
+
def install_stimulus
|
43
|
+
if stimulus?
|
44
|
+
in_root do
|
45
|
+
run("yarn add stimulus")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
31
50
|
private
|
32
51
|
|
52
|
+
def stimulus_application_path
|
53
|
+
komponent_root_directory.join("stimulus_application.js")
|
54
|
+
end
|
55
|
+
|
33
56
|
def application_pack_path
|
34
57
|
komponent_root_directory.join("packs", "application.js")
|
35
58
|
end
|
@@ -53,6 +76,25 @@ module Komponent
|
|
53
76
|
def dependencies_not_met_error_message
|
54
77
|
"Seems you don't have webpacker installed in your project. Please install webpacker, and follow instructions at https://github.com/rails/webpacker"
|
55
78
|
end
|
79
|
+
|
80
|
+
def stimulus?
|
81
|
+
return options[:stimulus] if options[:stimulus]
|
82
|
+
komponent_configuration[:stimulus]
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def komponent_configuration
|
88
|
+
{ stimulus: nil, locale: nil }.merge app_generators.komponent
|
89
|
+
end
|
90
|
+
|
91
|
+
def rails_configuration
|
92
|
+
Rails.application.config
|
93
|
+
end
|
94
|
+
|
95
|
+
def app_generators
|
96
|
+
rails_configuration.app_generators
|
97
|
+
end
|
56
98
|
end
|
57
99
|
end
|
58
100
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Komponent
|
2
|
+
class ComponentPathResolver
|
3
|
+
def resolve(component_name)
|
4
|
+
root_path = component_paths.find do |path|
|
5
|
+
path_has_component?(path, component_name)
|
6
|
+
end
|
7
|
+
|
8
|
+
if root_path.nil?
|
9
|
+
raise ComponentPathResolver::MissingComponentError.new(
|
10
|
+
component_name,
|
11
|
+
component_paths,
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
root_path.join(*component_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def path_has_component?(path, component_name)
|
21
|
+
file_name = path.join(*[
|
22
|
+
component_name,
|
23
|
+
"#{component_name.split("/").join("_")}_component.rb",
|
24
|
+
])
|
25
|
+
File.exist?(file_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def component_paths
|
29
|
+
komponent_configuration.component_paths.map do |path|
|
30
|
+
Pathname.new(path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def komponent_configuration
|
35
|
+
app_configuration.komponent
|
36
|
+
end
|
37
|
+
|
38
|
+
def app_configuration
|
39
|
+
Rails.application.config
|
40
|
+
end
|
41
|
+
|
42
|
+
class MissingComponentError < StandardError
|
43
|
+
def initialize(component_name, paths)
|
44
|
+
message = "Component `#{component_name}` not found in:\n"
|
45
|
+
paths.each do |path|
|
46
|
+
message += " * #{path}\n"
|
47
|
+
end
|
48
|
+
super(message)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Komponent
|
2
|
+
module Translation
|
3
|
+
def translate(key, options = {})
|
4
|
+
virtual_path = @virtual_path
|
5
|
+
|
6
|
+
is_component = key.to_s.first == "." and
|
7
|
+
virtual_path =~ /^components/
|
8
|
+
|
9
|
+
if is_component
|
10
|
+
path = virtual_path.match(/^components\/.+\/_(.+)/)[1]
|
11
|
+
path += "_component"
|
12
|
+
defaults = [:"#{path}#{key}"]
|
13
|
+
defaults << options[:default] if options[:default]
|
14
|
+
options[:default] = defaults.flatten
|
15
|
+
key = "#{path}.#{key}"
|
16
|
+
end
|
17
|
+
|
18
|
+
super(key, options)
|
19
|
+
end
|
20
|
+
alias :t :translate
|
21
|
+
end
|
22
|
+
end
|
@@ -1,16 +1,25 @@
|
|
1
1
|
module KomponentHelper
|
2
2
|
def component(component, locals = {}, &block)
|
3
|
-
|
3
|
+
component_path = Komponent::ComponentPathResolver.new.resolve(component)
|
4
4
|
|
5
5
|
parts = component.split("/")
|
6
|
-
component_path = components_path.join(*parts)
|
7
6
|
component_name = parts.join("_")
|
8
7
|
component_path = component_path.join("#{component_name}_component")
|
8
|
+
|
9
9
|
require_dependency(component_path)
|
10
10
|
|
11
11
|
component_module = "#{component_name}_component".camelize.constantize
|
12
12
|
context = controller.view_context.dup
|
13
|
+
|
14
|
+
context.view_flow = view_flow
|
15
|
+
|
16
|
+
view_renderer = context.view_renderer = context.view_renderer.dup
|
17
|
+
lookup_context = view_renderer.lookup_context = view_renderer.lookup_context.dup
|
18
|
+
lookup_context.prefixes = ["components/#{component}"]
|
19
|
+
|
13
20
|
context.class_eval { prepend component_module }
|
21
|
+
context.class_eval { prepend Komponent::Translation }
|
22
|
+
|
14
23
|
capture_block = proc { capture(&block) } if block
|
15
24
|
|
16
25
|
context.instance_eval do
|
@@ -36,33 +45,37 @@ module KomponentHelper
|
|
36
45
|
if context.respond_to?(custom_method)
|
37
46
|
context.public_send(custom_method, locals, &capture_block)
|
38
47
|
else
|
39
|
-
|
48
|
+
begin
|
49
|
+
context.render("components/#{component}/#{parts.join('_')}", &capture_block)
|
50
|
+
rescue ActionView::MissingTemplate
|
51
|
+
warn "[DEPRECATION WARNING] `#{parts.last}` filename in namespace is deprecated in favor of `#{parts.join('_')}`."
|
52
|
+
context.render("components/#{component}/#{parts.last}", &capture_block)
|
53
|
+
end
|
40
54
|
end
|
41
55
|
end
|
42
|
-
|
43
56
|
alias :c :component
|
44
57
|
|
45
58
|
def render_partial(partial_name, locals = {}, &block)
|
46
|
-
|
47
|
-
context = controller.view_context
|
48
|
-
view_paths = context.lookup_context.view_paths.dup
|
49
|
-
components_path = Rails.root.join "frontend/components"
|
50
|
-
|
51
|
-
capture_block = proc { capture(&block) } if block
|
59
|
+
warn "[DEPRECATION WARNING] `render_partial` is deprecated. Please use default `render` instead."
|
52
60
|
|
53
|
-
|
61
|
+
context = controller.view_context
|
62
|
+
view_paths = context.lookup_context.view_paths.dup
|
63
|
+
components_path = Rails.root.join "frontend/components"
|
54
64
|
|
55
|
-
|
56
|
-
context.lookup_context.view_paths.unshift components_path
|
65
|
+
capture_block = proc { capture(&block) } if block
|
57
66
|
|
58
|
-
|
59
|
-
context.render partial_name, locals, &capture_block
|
60
|
-
end
|
67
|
+
current_dir = Pathname.new(@virtual_path).dirname
|
61
68
|
|
62
|
-
|
63
|
-
|
69
|
+
context.lookup_context.prefixes.prepend current_dir
|
70
|
+
context.lookup_context.view_paths.unshift components_path
|
64
71
|
|
65
|
-
|
72
|
+
rendered_partial = capture do
|
73
|
+
context.render partial_name, locals, &capture_block
|
66
74
|
end
|
75
|
+
|
76
|
+
context.lookup_context.prefixes.delete current_dir
|
77
|
+
context.lookup_context.view_paths = view_paths
|
78
|
+
|
79
|
+
rendered_partial
|
67
80
|
end
|
68
81
|
end
|
data/lib/komponent/railtie.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
|
+
require 'webpacker'
|
1
2
|
require 'komponent/core/component_helper'
|
3
|
+
require 'komponent/core/translation'
|
4
|
+
require 'komponent/core/component_path_resolver'
|
2
5
|
|
3
6
|
module Komponent
|
4
7
|
class Railtie < Rails::Railtie
|
8
|
+
config.komponent = ActiveSupport::OrderedOptions.new
|
9
|
+
config.komponent.component_paths = []
|
10
|
+
|
11
|
+
config.before_configuration do |app|
|
12
|
+
app.config.komponent = config.komponent
|
13
|
+
app.config.komponent.component_paths.append(app.config.root.join("frontend/components"))
|
14
|
+
end
|
15
|
+
|
5
16
|
initializer "komponent.action_view" do |app|
|
6
17
|
ActiveSupport.on_load :action_view do
|
7
18
|
require 'komponent/komponent_helper'
|
@@ -17,7 +28,7 @@ module Komponent
|
|
17
28
|
|
18
29
|
initializer "komponent.i18n" do |app|
|
19
30
|
ActiveSupport.on_load :i18n do
|
20
|
-
I18n.load_path.concat(Dir["#{app.config.root}/frontend/components
|
31
|
+
I18n.load_path.concat(Dir["#{app.config.root}/frontend/components/**/*.yml"])
|
21
32
|
end
|
22
33
|
end
|
23
34
|
|
data/lib/komponent/version.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: komponent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ouvrages
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: aruba
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.15'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.15'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: cucumber
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,33 +53,61 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rails
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '5.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
68
|
+
version: '5.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '10.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.52.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.52.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webpacker
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
79
100
|
requirements:
|
80
101
|
- - ">="
|
81
102
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
103
|
+
version: 3.0.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 3.0.0
|
83
111
|
description: An opinionated way of organizing front-end code in Ruby on Rails, based
|
84
112
|
on components
|
85
113
|
email:
|
@@ -89,7 +117,10 @@ extensions: []
|
|
89
117
|
extra_rdoc_files: []
|
90
118
|
files:
|
91
119
|
- ".gitignore"
|
120
|
+
- ".rubocop.yml"
|
92
121
|
- ".travis.yml"
|
122
|
+
- CHANGELOG.md
|
123
|
+
- CODE_OF_CONDUCT.md
|
93
124
|
- Gemfile
|
94
125
|
- LICENSE.txt
|
95
126
|
- README.md
|
@@ -103,12 +134,20 @@ files:
|
|
103
134
|
- lib/generators/component/templates/js.erb
|
104
135
|
- lib/generators/component/templates/locale.erb
|
105
136
|
- lib/generators/component/templates/rb.erb
|
137
|
+
- lib/generators/component/templates/sass.erb
|
138
|
+
- lib/generators/component/templates/scss.erb
|
139
|
+
- lib/generators/component/templates/stimulus_controller_js.erb
|
140
|
+
- lib/generators/component/templates/stimulus_view.html.erb.erb
|
141
|
+
- lib/generators/component/templates/stimulus_view.html.haml.erb
|
142
|
+
- lib/generators/component/templates/stimulus_view.html.slim.erb
|
106
143
|
- lib/generators/component/templates/view.html.erb.erb
|
107
144
|
- lib/generators/component/templates/view.html.haml.erb
|
108
145
|
- lib/generators/component/templates/view.html.slim.erb
|
109
146
|
- lib/generators/komponent/install_generator.rb
|
110
147
|
- lib/komponent.rb
|
111
148
|
- lib/komponent/core/component_helper.rb
|
149
|
+
- lib/komponent/core/component_path_resolver.rb
|
150
|
+
- lib/komponent/core/translation.rb
|
112
151
|
- lib/komponent/komponent_helper.rb
|
113
152
|
- lib/komponent/railtie.rb
|
114
153
|
- lib/komponent/version.rb
|