bemer 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ ```