bemer 0.1.0 → 0.2.0

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.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/{LICENSE-RU → LICENSE-RU.txt} +0 -0
  3. data/{LICENSE → LICENSE.txt} +5 -5
  4. data/README.md +47 -16
  5. data/docs/BEMHTML.md +5 -0
  6. data/docs//320/232/320/276/320/275/321/202/320/265/320/272/321/201/321/202-/321/203/320/267/320/273/320/260.md +275 -0
  7. data/docs//320/232/320/276/320/275/321/204/320/270/320/263/321/203/321/200/320/260/321/206/320/270/321/217.md +158 -0
  8. data/docs//320/237/321/200/320/265/320/264/320/270/320/272/320/260/321/202/321/213.md +205 -0
  9. data/docs//320/240/320/265/320/266/320/270/320/274/321/213.md +274 -0
  10. data/docs//320/241/320/276/320/267/320/264/320/260/320/275/320/270/320/265-/320/270-/320/270/321/201/320/277/320/276/320/273/321/214/320/267/320/276/320/262/320/260/320/275/320/270/320/265-UI-/320/272/320/276/320/274/320/277/320/276/320/275/320/265/320/275/321/202.md +173 -0
  11. data/docs//320/244/320/260/320/270/314/206/320/273/320/276/320/262/320/260/321/217-/321/201/321/202/321/200/321/203/320/272/321/202/321/203/321/200/320/260.md +167 -0
  12. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mix.md +62 -0
  13. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mods.md +63 -0
  14. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-block_tag.md +215 -0
  15. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_asset_path.md +71 -0
  16. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_pack.md +101 -0
  17. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-component_partial_path.md +28 -0
  18. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-define_component.md +154 -0
  19. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-define_templates.md +96 -0
  20. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-elem_tag.md +38 -0
  21. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-refine_component.md +114 -0
  22. data/docs//320/245/320/265/320/273/320/277/320/265/321/200-render_component.md +108 -0
  23. data/docs//320/250/320/260/320/261/320/273/320/276/320/275/321/213.md +44 -0
  24. data/lib/bemer.rb +3 -1
  25. data/lib/bemer/builders.rb +8 -0
  26. data/lib/bemer/builders/tree.rb +0 -8
  27. data/lib/bemer/configuration.rb +3 -1
  28. data/lib/bemer/context_extentions/structure.rb +2 -3
  29. data/lib/bemer/entity.rb +2 -2
  30. data/lib/bemer/entity_builder.rb +5 -9
  31. data/lib/bemer/helpers.rb +10 -0
  32. data/lib/bemer/mixin_list.rb +1 -1
  33. data/lib/bemer/modifier_list.rb +2 -2
  34. data/lib/bemer/path_resolver.rb +23 -0
  35. data/lib/bemer/pipeline/handler.rb +4 -6
  36. data/lib/bemer/railtie.rb +22 -9
  37. data/lib/bemer/renderer.rb +1 -1
  38. data/lib/bemer/template_list.rb +2 -4
  39. data/lib/bemer/tree.rb +3 -3
  40. data/lib/bemer/tree/node.rb +5 -7
  41. data/lib/bemer/version.rb +1 -1
  42. data/spec/bemer/railtie_spec.rb +95 -0
  43. data/spec/dummy/config/application.rb +30 -12
  44. data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -5
  45. data/spec/dummy/config/initializers/bemer.rb +1 -3
  46. data/spec/rails_helper.rb +5 -9
  47. metadata +87 -129
  48. data/.gitignore +0 -17
  49. data/.overcommit.yml +0 -59
  50. data/.rspec +0 -4
  51. data/.rubocop.yml +0 -21
  52. data/.rubocop_todo.yml +0 -11
  53. data/Gemfile +0 -12
  54. data/Rakefile +0 -12
  55. data/bemer.gemspec +0 -43
  56. data/spec/dummy/Rakefile +0 -8
  57. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  58. data/spec/dummy/app/helpers/application_helper.rb +0 -4
  59. data/spec/dummy/app/jobs/application_job.rb +0 -4
  60. data/spec/dummy/app/mailers/application_mailer.rb +0 -6
  61. data/spec/dummy/app/models/application_record.rb +0 -5
  62. data/spec/dummy/app/models/concerns/.keep +0 -0
  63. data/spec/dummy/app/views/layouts/mailer.html.erb +0 -13
  64. data/spec/dummy/app/views/layouts/mailer.text.erb +0 -1
  65. data/spec/dummy/bin/bundle +0 -5
  66. data/spec/dummy/bin/rails +0 -6
  67. data/spec/dummy/bin/rake +0 -6
  68. data/spec/dummy/bin/setup +0 -39
  69. data/spec/dummy/bin/update +0 -31
  70. data/spec/dummy/bin/yarn +0 -13
  71. data/spec/dummy/config/cable.yml +0 -10
  72. data/spec/dummy/config/database.yml +0 -25
  73. data/spec/dummy/config/environments/development.rb +0 -51
  74. data/spec/dummy/config/environments/production.rb +0 -84
  75. data/spec/dummy/config/environments/test.rb +0 -44
  76. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -7
  77. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -7
  78. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -6
  79. data/spec/dummy/config/initializers/inflections.rb +0 -17
  80. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  81. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  82. data/spec/dummy/config/locales/en.yml +0 -33
  83. data/spec/dummy/config/puma.rb +0 -58
  84. data/spec/dummy/config/routes.rb +0 -5
  85. data/spec/dummy/config/secrets.yml +0 -32
  86. data/spec/dummy/config/spring.rb +0 -8
  87. data/spec/dummy/lib/assets/.keep +0 -0
  88. data/spec/dummy/log/.keep +0 -0
  89. data/spec/dummy/package.json +0 -5
  90. data/spec/dummy/public/404.html +0 -67
  91. data/spec/dummy/public/422.html +0 -67
  92. data/spec/dummy/public/500.html +0 -66
  93. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  94. data/spec/dummy/public/apple-touch-icon.png +0 -0
  95. data/spec/dummy/public/favicon.ico +0 -0
@@ -0,0 +1,173 @@
1
+ # Создание и использование UI компонент
2
+
3
+ **ВАЖНО**. *Только для компонент, структура (дерево) которых была создана с помощью [хелпера `define_component`](Хелпер-define_component.md) доступно использование [BEMHTML шаблонов](Шаблоны.md).*
4
+
5
+ Для всех примеров используется следующая файловая структура:
6
+
7
+ ```
8
+ app/
9
+ ├── assets/
10
+ | ├── javascripts/
11
+ | | └── application.js
12
+ | └── stylesheets/
13
+ | └── application.css
14
+ ├── bemer_components/
15
+ | ├── panel/
16
+ | | ├── index.html.slim
17
+ | | ├── index.js
18
+ | | └── index.css
19
+ | └── ...
20
+ └── ...
21
+ ```
22
+ Подключение технологий JavaScript и CSS компонента `panel` при использование Sprockets:
23
+
24
+ ```js
25
+ // Файл app/assets/javascripts/application.js
26
+ //= require panel
27
+ ```
28
+
29
+ ```scss
30
+ // Файл app/assets/stylesheets/application.css
31
+ //= require panel
32
+ ```
33
+ В качестве структуры компонента `panel` будет взят [компонент `panel` из библиотеки Twitter Bootstrap](https://getbootstrap.com/docs/3.3/components/#panels):
34
+
35
+ ```html
36
+ <!-- Исходная HTML структура компонента panel из библиотеки Twitter Bootstrap -->
37
+ <div class="panel panel-default">
38
+ <div class="panel-heading">
39
+ <h3 class="panel-title">Panel title</h3>
40
+ </div>
41
+ <div class="panel-body">Panel content</div>
42
+ <div class="panel-footer">Panel footer</div>
43
+ </div>
44
+ ```
45
+ ## Компонент без использования шаблонизатора
46
+
47
+ ```html
48
+ <!-- Содержимое файла index.html компонента panel -->
49
+ <div class="panel panel-default">
50
+ <div class="panel-heading">
51
+ <h3 class="panel-title">Panel title</h3>
52
+ </div>
53
+ <div class="panel-body">Panel content</div>
54
+ <div class="panel-footer">Panel footer</div>
55
+ </div>
56
+ ```
57
+ получение HTML кода компонента в представлениях и/или хелперах:
58
+ ```slim
59
+ / Шаблонизатор Slim
60
+ = render_component :panel
61
+
62
+ / =>
63
+ / <div class="panel panel-default">
64
+ / <div class="panel-heading">
65
+ / <h3 class="panel-title">Panel title</h3>
66
+ / </div>
67
+ / <div class="panel-body">Panel content</div>
68
+ / <div class="panel-footer">Panel footer</div>
69
+ / </div>
70
+ ```
71
+
72
+ ## Компонент с использованием шаблонизатора
73
+
74
+ ```slim
75
+ / Содержимое файла index.html.slim компонента panel
76
+ .panel.panel-default
77
+ .panel-heading
78
+ h3.panel-title Panel title
79
+ .panel-body Panel content
80
+ .panel-footer Panel footer
81
+ ```
82
+ получение HTML кода компонента в представлениях и/или хелперах:
83
+ ```slim
84
+ / Шаблонизатор Slim
85
+ = render_component :panel
86
+
87
+ / =>
88
+ / <div class="panel panel-default">
89
+ / <div class="panel-heading">
90
+ / <h3 class="panel-title">Panel title</h3>
91
+ / </div>
92
+ / <div class="panel-body">Panel content</div>
93
+ / <div class="panel-footer">Panel footer</div>
94
+ / </div>
95
+ ```
96
+
97
+ ## Компонент с помощью `block_tag`
98
+
99
+ ```slim
100
+ / Содержимое файла index.html.slim компонента panel
101
+ = block_tag :panel, bem_cascade: false, tag: :div, cls: 'panel panel-default' do |panel|
102
+ = panel.elem :heading, tag: :div, cls: 'panel-heading'
103
+ = panel.elem :title, tag: :h3, cls: 'panel-title', content: 'Panel title'
104
+ = panel.elem :body, tag: :div, cls: 'panel-body', content: 'Panel content'
105
+ = panel.elem :footer, tag: :div, cls: 'panel-footer', content: 'Panel footer'
106
+ ```
107
+ получение HTML кода компонента в представлениях и/или хелперах:
108
+ ```slim
109
+ / Шаблонизатор Slim
110
+ = render_component :panel
111
+
112
+ / =>
113
+ / <div class="panel panel-default">
114
+ / <div class="panel-heading">
115
+ / <h3 class="panel-title">Panel title</h3>
116
+ / </div>
117
+ / <div class="panel-body">Panel content</div>
118
+ / <div class="panel-footer">Panel footer</div>
119
+ / </div>
120
+ ```
121
+
122
+ ## Компонент с помощью `define_component`
123
+
124
+ **ВАЖНО**. *Доступно использование [BEMHTML шаблонов](Шаблоны.md).*
125
+
126
+ ```slim
127
+ / Содержимое файла index.html.slim компонента panel
128
+ = define_component bem_cascade: false, tag: :div do |component|
129
+ = component.block :panel, cls: 'panel panel-default' do |panel|
130
+ = panel.elem :heading, cls: 'panel-heading'
131
+ = panel.elem :title, tag: :h3, cls: 'panel-title', content: 'Panel title'
132
+ = panel.elem :body, cls: 'panel-body', content: 'Panel content'
133
+ = panel.elem :footer, cls: 'panel-footer', content: 'Panel footer'
134
+ ```
135
+ получение HTML кода компонента в представлениях и/или хелперах:
136
+ ```slim
137
+ / Шаблонизатор Slim
138
+ = render_component :panel
139
+
140
+ / =>
141
+ / <div class="panel panel-default">
142
+ / <div class="panel-heading">
143
+ / <h3 class="panel-title">Panel title</h3>
144
+ / </div>
145
+ / <div class="panel-body">Panel content</div>
146
+ / <div class="panel-footer">Panel footer</div>
147
+ / </div>
148
+ ```
149
+
150
+ ## Передача локальных переменных в индексный файл технологии HTML
151
+
152
+ ```slim
153
+ / Содержимое файла index.html.slim компонента panel
154
+ .panel.panel-default
155
+ .panel-heading
156
+ h3.panel-title = local_assigns.fetch(:title, 'Default title')
157
+ .panel-body = local_assigns.fetch(:content, 'Default content')
158
+ .panel-footer = local_assigns.fetch(:footer, 'Default footer')
159
+ ```
160
+ получение HTML кода компонента в представлениях и/или хелперах:
161
+ ```slim
162
+ / Шаблонизатор Slim
163
+ = render_component :panel, title: 'Title', content: 'Content', footer: 'Footer'
164
+
165
+ / =>
166
+ / <div class="panel panel-default">
167
+ / <div class="panel-heading">
168
+ / <h3 class="panel-title">Title</h3>
169
+ / </div>
170
+ / <div class="panel-body">Content</div>
171
+ / <div class="panel-footer">Footer</div>
172
+ / </div>
173
+ ```
@@ -0,0 +1,167 @@
1
+ # Файловая структура
2
+
3
+ В общем случае структура каталогов и файлов может выглядеть следующим образом:
4
+
5
+ ```
6
+ app/
7
+ ├── bemer_components/
8
+ | ├── modal/
9
+ | | ├── index.html
10
+ | | ├── index.js
11
+ | | ├── index.scss
12
+ | | └── ...
13
+ | ├── top_navbar/
14
+ | | ├── index.html.slim
15
+ | | ├── index.bemhtml.slim
16
+ | | ├── index.js
17
+ | | ├── index.scss
18
+ | | └── ...
19
+ | └── ...
20
+ └── ...
21
+ ```
22
+
23
+ Название каталога это название компонента, которое будет использоваться в представлениях (`views`) и/или хелперах (`helpers`) приложения. Каталог может содержать любые файлы (технологии) которые необходимы для компонента, например такие, как `js`, `css`, `md` и т.д.
24
+
25
+ Соглашения о файлах (технологиях):
26
+
27
+ 1. Каталог **обязательно** должен содержать индексный файл для технологии HTML (это может быть: `index.html`, `index.html.slim`, `index.html.erb` и т.д.), который [описывает структуру компонента](Создание-и-использование-UI-компонент.md), используя для этого любой шаблонизатор (`ERB`, `Slim`, `HAML` и др.) или только HTML код.
28
+
29
+ 1. Если индексный файл технологии HTML для создания структуры (дерева) компонента [использует хелпер `define_component`](Хелпер-define_component.md), тогда каталог может содержать индексный файл для [шаблонов по умолчанию](Хелпер-define_templates.md) (технология `bemhtml`), он должен называться `index.bemhtml` с обязательным указанием шаблонизатора например: `index.bemhtml.erb`, `index.bemhtml.slim` и т.д.
30
+
31
+ 1. Все остальные технологии (`js`, `css`, `md` и т.д.) считаются дополнительными и их можно добавлять по мере необходимости, имена файлов могут быть любыми но для единообразия и удобства лучше использовать `index` в качестве имени:
32
+
33
+ В случае если используется [Sprockets](https://github.com/rails/sprockets-rails), тогда подключение `JS` и `CSS` файлов компонента может быть таким:
34
+
35
+ ```coffeescript
36
+ # Файл application.coffee
37
+ #= require modal
38
+ ```
39
+
40
+ ```js
41
+ // Файл application.js
42
+ //= require modal
43
+ ```
44
+
45
+ ```scss
46
+ // Файл application.css или application.scss
47
+ //= require modal
48
+ ```
49
+
50
+ Возможно всё-таки появится поддержка индексных файлов и у [SASS](https://github.com/sass/sass/issues/690).
51
+
52
+ При использовании [Webpacker](https://github.com/rails/webpacker) для JavaScript также можно не указывать `index.js`:
53
+ ```js
54
+ import 'modal'
55
+ ```
56
+
57
+
58
+ Структуру каталогов можно организовывать по-разному в зависимости от вида приложений и решаемых задач.
59
+
60
+ ## Пример №1
61
+
62
+ Компоненты разделены для использования в разных частях приложения, пользовательской (`user`), административной (`admin`) и общие (`common`) можно использовать/переопределять везде:
63
+
64
+ ```
65
+ app/
66
+ ├── bemer_components/
67
+ | ├── common/
68
+ | | ├── modal/
69
+ | | | ├── index.html.slim
70
+ | | | ├── index.bemhtml.slim
71
+ | | | ├── index.js
72
+ | | | ├── index.scss
73
+ | | | └── ...
74
+ | | ├── top_navbar/
75
+ | | | ├── index.html.slim
76
+ | | | ├── index.bemhtml.slim
77
+ | | | ├── index.js
78
+ | | | ├── index.scss
79
+ | | | └── ...
80
+ | | └── ...
81
+ | ├── admin/
82
+ | | ├── top_navbar/
83
+ | | | ├── index.html.slim
84
+ | | | ├── index.bemhtml.slim
85
+ | | | ├── index.js
86
+ | | | ├── index.scss
87
+ | | | └── ...
88
+ | | └── ...
89
+ | ├── user/
90
+ | | ├── top_navbar/
91
+ | | | ├── index.html.slim
92
+ | | | ├── index.bemhtml.slim
93
+ | | | ├── index.js
94
+ | | | ├── index.scss
95
+ | | | └── ...
96
+ | | └── ...
97
+ | └── ...
98
+ └── ...
99
+ ```
100
+
101
+ ## Пример №2
102
+
103
+ Приложение, в котором компоненты разделены для поддержки различных устройств:
104
+
105
+ ```
106
+ app/
107
+ ├── bemer_components/
108
+ | ├── common/
109
+ | | ├── modal/
110
+ | | | ├── index.html.slim
111
+ | | | ├── index.bemhtml.slim
112
+ | | | ├── index.js
113
+ | | | ├── index.scss
114
+ | | | └── ...
115
+ | | ├── top_navbar/
116
+ | | | ├── index.html.slim
117
+ | | | ├── index.bemhtml.slim
118
+ | | | ├── index.js
119
+ | | | ├── index.scss
120
+ | | | └── ...
121
+ | | └── ...
122
+ | ├── desktop/
123
+ | | ├── top_navbar/
124
+ | | | ├── index.html.slim
125
+ | | | ├── index.bemhtml.slim
126
+ | | | ├── index.js
127
+ | | | ├── index.scss
128
+ | | | └── ...
129
+ | | └── ...
130
+ | ├── touch_pad/
131
+ | | ├── top_navbar/
132
+ | | | ├── index.html.slim
133
+ | | | ├── index.bemhtml.slim
134
+ | | | ├── index.js
135
+ | | | ├── index.scss
136
+ | | | └── ...
137
+ | | └── ...
138
+ | └── ...
139
+ └── ...
140
+ ```
141
+
142
+ ## Пример №3
143
+
144
+ Альтернативный способ структуры каталогов и файлов для поддержки различных устройств в приложениях начиная с `Rails 4.1` это использовать [Variants](http://guides.rubyonrails.org/4_1_release_notes.html#action-pack-variants):
145
+
146
+ ```
147
+ app/
148
+ ├── bemer_components/
149
+ | ├── modal/
150
+ | | ├── index.html.slim
151
+ | | ├── index.html+phone.slim
152
+ | | ├── index.html+tablet.slim
153
+ | | ├── index.bemhtml.slim
154
+ | | ├── index.js
155
+ | | ├── index.scss
156
+ | | └── ...
157
+ | ├── top_navbar/
158
+ | | ├── index.html.slim
159
+ | | ├── index.html+phone.slim
160
+ | | ├── index.html+tablet.slim
161
+ | | ├── index.bemhtml.slim
162
+ | | ├── index.js
163
+ | | ├── index.scss
164
+ | | └── ...
165
+ | └── ...
166
+ └── ...
167
+ ```
@@ -0,0 +1,62 @@
1
+ # Хелпер bem_mix
2
+
3
+ **ВАЖНО**. *Для сущностей у которых не указано название, не будут созданы css классы из методологии БЭМ*.
4
+
5
+ Позволяет создавать миксы по методологии БЭМ.
6
+
7
+ Все передаваемые аргументы типа `Symbol` создают миксы блоков, аргументы типа `Hash` создают миксы элементов (исключение хеш у которого значение `nil`, см. пример ниже).
8
+
9
+ У ВСЕХ аргументов переданных как тип:
10
+ * `Symbol` ВСЕ символы нижнего подчеркивания будут преобразованы в тире
11
+ * `String` возвращаются без модификации (включая ключи и/или значения хешей)
12
+
13
+ ```ruby
14
+ bem_mix :block_name, block_name: :elem_name # => 'block-name block-name__elem-name'
15
+ ```
16
+
17
+ эквивалентная запись:
18
+
19
+ ```ruby
20
+ bem_mix [:block_name, block_name: :elem_name] # => 'block-name block-name__elem-name'
21
+ ```
22
+ С помощью хеша можно создать микс блока если значение передать как `nil`
23
+ ```ruby
24
+ bem_mix block_name: nil # => 'block-name'
25
+ ```
26
+
27
+ если значение хеша указано как `''` или `false` микс создан не будет:
28
+ ```ruby
29
+ bem_mix block_name: false # => ''
30
+ bem_mix block_name: '' # => ''
31
+ ```
32
+ Если у нескольких элементов название блока одинаковое, чтобы не переопределить предыдущее значение следующим, можно каждый элемент передавать как отдельный хеш:
33
+
34
+ ```ruby
35
+ bem_mix({ block: :elem1 }, { block: :elem2 }) # => 'block__elem1 block__elem2'
36
+ ```
37
+ или эквивалентная и более компактная запись используя массив:
38
+
39
+ ```ruby
40
+ bem_mix block: [:elem1, :elem2] # => 'block__elem1 block__elem2'
41
+ ```
42
+ **ВАЖНО.** *Будьте ВНИМАТЕЛЬНЫ при использование аргументов с типом `String`, а также ключей и/или значений хеша с типом `String` это может привести к неправильному результату согласно методологии БЭМ*:
43
+
44
+ ```ruby
45
+ bem_mix 'block_name' => 'elem_name' # => 'block_name__elem_name'
46
+ ```
47
+ Аргументы переданные как тип `String` ВСЕГДА остаются неизменными:
48
+
49
+ ```ruby
50
+ bem_mix 'block_name', 'block_name__elem' # => 'block_name block_name__elem'
51
+ ```
52
+
53
+ эквивалентная запись:
54
+
55
+ ```ruby
56
+ bem_mix 'block_name block_name__elem' # => 'block_name block_name__elem'
57
+ ```
58
+
59
+ Пустые аргументы возвращают пустую строку
60
+ ```ruby
61
+ bem_mix nil, '', {} # => ''
62
+ ```
@@ -0,0 +1,63 @@
1
+ # Хелпер bem_mods
2
+
3
+ **ВАЖНО**. *Для сущностей у которых не указано название, не будут созданы css классы из методологии БЭМ*.
4
+
5
+ Позволяет создавать модификаторы по методологии БЭМ.
6
+
7
+ Действуют такие же правила трансформации для символов нижнего подчеркивания в символы тире как и у [хелпера `bem_mix`](Хелпер-bem_mix.md).
8
+
9
+ `bem_mods` принимает название блока, название элемента (которые не могут быть `''`, `false` или `nil`) и параметры модификаторов которые могут быть массивом, хешем, символом или строкой.
10
+
11
+ Модификаторы для блока:
12
+
13
+ ```ruby
14
+ bem_mods :block_name, theme: :green_islands # => 'block-name_theme_green-islands'
15
+ ```
16
+
17
+ Модификаторы для элемента:
18
+
19
+ ```ruby
20
+ bem_mods :block_name, :elem_name, has_tail: true # => 'block-name__elem-name_has-tail'
21
+ ```
22
+
23
+ Единственный модификатор с значением `true`:
24
+
25
+ ```ruby
26
+ # Эквивалентные записи
27
+ bem_mods :block_name, :has_tail # => 'block-name_has-tail'
28
+ bem_mods :block_name, has_tail: true # => 'block-name_has-tail'
29
+ bem_mods :block_name, [:has_tail] # => 'block-name_has-tail'
30
+ bem_mods :block_name, [has_tail: true] # => 'block-name_has-tail'
31
+ bem_mods :block_name, [{ has_tail: true }] # => 'block-name_has-tail'
32
+ ```
33
+
34
+ Список модификаторов:
35
+
36
+ ```ruby
37
+ # Эквивалентные записи
38
+ bem_mods :block, enabled: true, size: :small # => 'block_enabled block_size_small'
39
+ bem_mods :block, [enabled: true, size: :small] # => 'block_enabled block_size_small'
40
+ bem_mods :block, [{ enabled: true, size: :small }] # => 'block_enabled block_size_small'
41
+ bem_mods :block, [{ enabled: true }, { size: :small }] # => 'block_enabled block_size_small'
42
+ bem_mods :block, [:enabled, size: :small] # => 'block_enabled block_size_small'
43
+ ```
44
+ **ВАЖНО.** *Будьте ВНИМАТЕЛЬНЫ при использование аргументов с типом `String`, а также ключей и/или значений хеша с типом `String` это может привести к неправильному результату согласно методологии БЭМ*:
45
+
46
+ ```ruby
47
+ bem_mods :block_name, 'has_tail' # => 'block-name_has_tail'
48
+ bem_mods :block_name, 'has_tail' => true # => 'block-name_has_tail'
49
+ bem_mods :block_name, 'mod_name' => 'mod_value' # => 'block-name_mod_name_mod_value'
50
+ ```
51
+ те же самые модификаторы при использовании типа `Symbol`:
52
+ ```ruby
53
+ bem_mods :block_name, :has_tail # => 'block-name_has-tail'
54
+ bem_mods :block_name, has_tail: true # => 'block-name_has-tail'
55
+ bem_mods :block_name, mod_name: :mod_value # => 'block-name_mod-name_mod-value'
56
+ ```
57
+ Модификаторы у которых значение `false`, `nil` или `''`:
58
+ ```ruby
59
+ # Эквивалентные записи
60
+ bem_mods :block_name, enabled: false, size: :small # => 'block-name_size_small'
61
+ bem_mods :block_name, enabled: '', size: :small # => 'block-name_size_small'
62
+ bem_mods :block_name, enabled: nil, size: :small # => 'block-name_size_small'
63
+ ```