ВАЖНО. Для работы с UI компонентами не обязательно использовать методологию БЭМ.
- Позволяет создавать переиспользуемые UI компоненты для приложений на Ruby on Rails.
- Предоставляет функционал для разработки приложений на Ruby on Rails с использованием методологии БЭМ.
- Статья на Хабре - Переиспользуемые UI компоненты в приложениях на Ruby on Rails.
bemer-simple_form
- Использование соглашений из БЭМ методологии в формахSimpleForm
.bemer-bootstrap
- переиспользуемые компоненты Bootstrap v3.- Пример приложения с использованием
bemer
иbemer-bootstrap
.
Добавить в Gemfile
:
gem 'bemer'
Выполнить в терминале команду:
$ bundle
Конфигурация для Bemer
:
# config/initializers/bemer.rb
Bemer.setup do |config|
config.bem = true
config.modifier_name_separator = '--'
config.path = 'app/frontend/components' # или Webpacker.config.source_path
# config.default_path_prefix = lambda { |path, view|
# view.controller.class.name.split('::')[0].underscore
# }
end
Если используется Webpacker
:
# config/webpacker.yml
default: &default
source_path: app/frontend/components
source_entry_path: ../packs
public_output_path: frontend/assets
# ...
development:
<<: *default
# ...
test:
<<: *default
# ...
production:
<<: *default
# ...
Пример файловой структуры при использовании Sprockets
:
app/
├── assets/
| ├── javascripts/
| | ├── admin_panel/
| | | ├── application.js
| | | └── ...
| | ├── landing/
| | | ├── application.js
| | | └── ...
| | ├── user_panel/
| | | ├── application.js
| | | └── ...
| | └── ...
| ├── stylesheets/
| | ├── admin_panel/
| | | ├── application.scss
| | | └── ...
| | ├── landing/
| | | ├── application.scss
| | | └── ...
| | ├── user_panel/
| | | ├── application.scss
| | | └── ...
| | └── ...
| └── ...
├── frontend/
| ├── components/
| | ├── common/
| | | ├── carousel/
| | | | ├── index.slim
| | | | ├── index.bemhtml.slim
| | | | ├── index.js
| | | | ├── index.scss
| | | | └── ...
| | | ├── form/
| | | | ├── error_messages_elem/
| | | | | ├── index.slim
| | | | | ├── index.js
| | | | | ├── index.scss
| | | | | └── ...
| | | | ├── locales/
| | | | | ├── en.yml
| | | | | └── ...
| | | | ├── index.slim
| | | | ├── base.rb
| | | | ├── index.js
| | | | ├── index.scss
| | | | └── ...
| | | └── ...
| | ├── admin_panel/
| | | └── ...
| | ├── landing/
| | | └── ...
| | ├── user_panel/
| | | └── ...
| | └── ...
| └── ...
└── ...
Пример файловой структуры при использовании Webpacker
:
app/
├── frontend/
| ├── components/
| | ├── common/
| | | ├── carousel/
| | | | ├── index.slim
| | | | ├── index.bemhtml.slim
| | | | ├── index.js
| | | | ├── index.scss
| | | | └── ...
| | | ├── form/
| | | | ├── error_messages_elem/
| | | | | ├── index.slim
| | | | | ├── index.js
| | | | | ├── index.scss
| | | | | └── ...
| | | | ├── locales/
| | | | | ├── en.yml
| | | | | └── ...
| | | | ├── index.slim
| | | | ├── base.rb
| | | | ├── index.js
| | | | ├── index.scss
| | | | └── ...
| | | └── ...
| | ├── admin_panel/
| | | └── ...
| | ├── landing/
| | | └── ...
| | ├── user_panel/
| | | └── ...
| | └── ...
| ├── packs/
| | ├── admin_panel/
| | | ├── application.js
| | | └── ...
| | ├── landing/
| | | ├── application.js
| | | └── ...
| | ├── user_panel/
| | | ├── application.js
| | | └── ...
| | └── ...
| └── ...
└── ...
Структура компонента Сarousel из Bootstrap:
/ app/frontend/components/common/carousel/index.slim
.carousel.slide data-ride="carousel" class=local_assigns[:cls]
ol.carousel-indicators
- image_urls.size.times do |i|
li data-target=".carousel" class=(:active if i.zero?) data-slide-to=i
.carousel-inner
- image_urls.each_with_index do |image_url, i|
.carousel-item class=(:active if i.zero?)
= image_tag image_url, class: 'd-block w-100'
a.carousel-control-prev data-slide="prev" data-target='.carousel' role="button"
span.carousel-control-prev-icon aria-hidden="true"
span.sr-only Предыдущий
a.carousel-control-next data-slide="next" data-target='.carousel' role="button"
span.carousel-control-next-icon aria-hidden="true"
span.sr-only Следующий
Вызов компонента carousel
в любом представлении или в других компонентах:
= render_component :carousel, prefix: :common, image_urls: image_urls, cls: 'carousel-fade'
Структура компонента Сarousel из Bootstrap:
/ app/frontend/components/common/carousel/index.slim
= define_component do |component|
= component.block :carousel, 'data-ride': :carousel, 'data-interval': false, cls: :slide do |carousel|
= carousel.elem :indicators, tag: :ol, cls: 'carousel-indicators'
- image_urls.size.times do |i|
= carousel.elem :indicator, tag: :li, 'data-slide-to': i, mods: (:active if i.zero?), 'data-target': '.carousel'
= carousel.elem :inner, cls: 'carousel-inner'
- image_urls.each_with_index do |image_url, i|
= carousel.elem :item, cls: 'carousel-item', mods: (:active if i.zero?)
= carousel.elem :image, tag: :img, cls: 'd-block w-100', src: image_url
= carousel.elem :control_prev, tag: :a, cls: 'carousel-control-prev', 'data-slide': :prev, role: :button, 'data-target': '.carousel'
span.carousel-control-prev-icon aria-hidden="true"
span.sr-only Предыдущий
= carousel.elem :control_next, tag: :a, cls: 'carousel-control-next', 'data-slide': :next, role: :button, 'data-target': '.carousel'
span.carousel-control-next-icon aria-hidden="true"
span.sr-only Следующий
/ app/frontend/components/common/carousel/index.bemhtml.slim
= define_templates do |template|
= template.elem(mods: :active).add_cls :active
Вызов компонента carousel
в любом представлении или в других компонентах с применением BEMHTML
шаблонов:
= render_component :carousel, prefix: :common, image_urls: image_urls do |template|
= template.block(:carousel).add_mix :carousel_fade
- Файловая структура
- Конфигурация
- Создание и использование UI компонент
- Хелперы для работы с компонентами
- Дополнительные хелперы для БЭМ методологии
- BEMHTML
- BEM methodology - https://bem.info/methodology/
- Minimal stack for coding client-side JavaScript and templating - https://github.com/bem/bem-core
- Declarative template engine for the browser and server with regular JS syntax - https://github.com/bem/bem-xjst
- BEM Forum - https://bem.info/forum/
Copyright (c) 2017 - 2020 Александр Григорьев. Более подробную информацию о лицензии можно получить в файле LICENSE.txt.