Komponent implements an opinionated way of organizing front-end code in Ruby on Rails, based on components.
Each component has its own folder, containing a Ruby module, a slim partial, a PostCSS stylesheet and a JavaScript file.
Komponent relies heavily on webpacker to manage dependencies and generate the production JS and CSS files.
This gem has been inspired by our Rails development practices at Ouvrages and Etamin Studio, and the (excellent) Modern Front-end in Rails article from Evil Martians.
# Gemfile
gem "komponent"
Run the following command to set up your project instantly:
rails generate komponent:install
This command will:
- check that the dependencies (currently, webpacker) are installed
- rename the
app/javascript
folder tofrontend
and modify webpacker config accordingly - create the
frontend/components
folder where you will put your component - create the
frontend/components/index.js
file that will list your components andimport
it infrontend/packs/application.js
Generate a new component with the component
generator:
rails generate component button
Then, render it in your views with the component
helper (or its alias c
).
/ app/views/pages/home.html.slim
= component "button"
= c "button"
You can pass locals
to the helper. They are accessible within the component partial, as instance variables.
/ app/views/pages/home.html.slim
= component "button", text: "My button"
/ frontend/components/button/_button.html.slim
.button
= @text
The component also accepts a block
. To render the block, just use the standard yield
.
/ app/views/pages/home.html.slim
= component "button"
span= "My button"
/ frontend/components/button/_button.html.slim
.button
= yield
Each component comes with a Ruby module
. You can use it to set properties:
# frontend/components/button/button_component.rb
module ButtonComponent
property :href, required: true
property :text, default: "My button"
end
/ frontend/components/button/_button.html.slim
a.button(href=@href)
= @text
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:
# frontend/components/button/button_component.rb
module ButtonComponent
property :href, required: true
property :text, default: "My button"
def external_link?
@href.starts_with? "http"
end
end
/ frontend/components/button/_button.html.slim
a.button(href=@href)
= @text
= " (external link)" if external_link?
/ app/views/pages/home.html.slim
= component "button", text: "My button", href: "http://github.com"
Bug reports and pull requests are welcome on GitHub at https://github.com/ouvrages/komponent.
The gem is available as open source under the terms of the MIT License.