Войти с помощью github

Приветствую, балуюсь с новой библиотекой и видимо, что то с руками)

import * as React from 'react';
import { withBemMod, ModBody } from '@bem-react/core';
import { IButtonProps } from '../index';

const ButtonLink: ModBody<IButtonProps> = (Base, { text, className }) => (

  // className === 'Button Button_type_link'

  <a className={className}>{text}</a>
);

export const ButtonTypeLink = withBemMod<IButtonProps>('Button', { type: 'link' }, ButtonLink);

библиотеки обновил, но не понимаю почему там нет ModBody, ведь я так хочу менять не только стили )

и еще момент я так понимаю className основного блока должен сам приехать. Или я не прав?

Помогите пожалуйста советом, добрые люди.

Доброе время суток!

Помогите разобраться с подключением webpack-bem-loader, вроде делов то добавить в конфиг пару строк.

Делаю так:

overrides config

module.exports = function override(config, env) {
  // Add bem-loader in Babel scope
  const babelLoader = config.module.rules[2].oneOf[1];

  config.module.rules[2].oneOf[1] = {
    test: babelLoader.test,
    include: babelLoader.include,
    use: [
      {
        loader: require.resolve('webpack-bem-loader'),
        options: {
          naming: 'react',
          levels: ['./src/blocks'],
          techs: ['js', 'css'],
          techMap: {
              js : ['react.js']
          },
          langs: ['ru', 'en']
        }
      },
      {
        loader: babelLoader.loader,
        options: babelLoader.options
      }
    ]
  };

  return config;
}

Ну и пытаюсь в index.js проекта поймать свой блок App

import App from 'b:App';

который написан как

import React from 'react';
import { decl, Bem } from 'bem-react-core';

export default decl({
  block: 'App',
  content() {
    return (
      <Bem block='App'>asd</Bem>
    );
  }
});

вот мой package.json

{
  "name": "bemdev-plate",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "bem-react-core": "^2.2.3",
    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-scripts": "2.1.1"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "devDependencies": {
    "react-app-rewired": "^1.6.2",
    "webpack-bem-loader": "^0.7.0"
  }
}

Помогите разобраться где я не прав? или где читать внимательнее ?

Семантически правильно писать непосредственно в section заголовок. При этом считается, что для блока section нужно использовать тогда, когда ты можешь дать осмысленное название, т.е. по сути класс для section. Но бывают ситуации, когда есть логический блок, но в нем нужно несколько внешних оберток, как в этом случае

<div class="page-main__banner banner">
    <section class="banner__content">
      <h1 class="banner__title">Быстрая доставка цветов</h1>
      <ul class="banner__advantages">
        <li class="banner__advantage banner__advantage--rose">
          Ежедневный привоз свежих цветов
        </li>
        <li class="banner__advantage banner__advantage--ruble">
          Низкие цены за счет больших поставок
        </li>
        <li class="banner__advantage banner__advantage--car">
          Быстрая круглосуточная доставка
        </li>
      </ul>
    </section>
  </div>

Первая обертка - для фона на всю ширину страницы. Второе - собственно информация. Но у меня осмысленное название у обертки получается, а section - это уже по сути элемент блока. Но при этом я не могу сам section выделить в отдельный блок, т.к. фон тоже является частью блока. Извиняюсь, если не понятно написал. И прошу простить, если вопрос глупый.

Дайджест новостей по БЭМ. Выпуск №15

В этом полугодии ребята из команды БЭМ, как настоящие эссенциалисты, решили откинуть все неважное и сосредоточить усилия на первостепенных задачах. Поэтому этот выпуск дайджеста уместился на один экран :)

Итак, главные новости полугодия:

БЭМ и React

Антон Виноградов пожелал всем добра и сообщил, что bem-react-corе v3 влита в master и с этого момента становится основной рекомендованной версией библиотеки для работы с БЭМ в React мире. А вот версии v1 и v2 больше поддерживаться не будут, но еще какое-то время будут доступны в ветках.

Репозиторий bem-react-core переименован в bem-react для соответствия с npm неймспейсом @bem-react, где находятся все пакеты библиотеки.

Инструменты

  • Выпустили @bem-react/* пакеты.
  • Опубликовали пакет enb-js-browserify в npm. Используйте его, чтобы получить commonJs в своем клиентском коде.

Документация

Обновили документацию к пакетам bem-sdk с живыми примерами в RunKit:

БЭМ и DESIGN

Все актуальные новости и анонсы ребята публикуют в Telegram канале whitepaper.

Мероприятия

  • Провели митап по БЭМ, где рассказали о библиотеке bem-react-corе v3, которая помогает работать по БЭМ-методологии в мире React. На простых примерах показали, как использование библиотеки делает ваши React-проекты гибче и проще в поддержке. Для всех, кто пропустил, мы записали видео.
  • Продолжили эстафету встреч для новичков: на этот раз провели два в дневных интенсива. Видео опубликовано на сайте событий Яндекса. Чтобы не пропустить следующий интенсив, подписывайтесь на новости БЭМ-сообщества.

Видео со всех встреч мы публикуем в канале bem.info на YouTube.

Всех с наступающими и наступившими праздниками! Stay BEMed!

Добрый, возможно я хочу скрестить ежа с ужом, но.. У меня делается сайт , все по блокам и по полочкам, от БЭМ я хочу - уровни переопределения, блоки, элементы, модификаторы в стилях, в js пока будет слабая поддержка, к react команда не готова, ну и к i-bem тоже. Js будет пока свой. На js очень хотелось поддержки классов и всех других прелестей, поэтому собирал на webpack через babel, но сейчас нужно делать уровни переопределения, webpack из коробки не знает о них ничего, делать руками импорты - мракобесие. Нашел лоадер webpack-bem-loader, переписал импорты на более удобные, собрал, в итоге со стилями все ок, но js крашится с ошибкой: app.js:4 Uncaught TypeError: (webpack_require(...).default || webpack_require(...)).applyDecls is not a function. Если руками в бандле поудалять вызов .applyDecls(), то все работает как нужно. Как я понимаю, это из-за того, что лоадер заточен под react, может есть какие опции, которые мне помогут, или где поправить это? Я форкнул бы.

Приветствую! Когда будет доступен ресурс: https://ru.bem.info/platform/libs/bem-components/?

Вопрос 1: Вроде DI штука понятная, но пока не понятны паттерны её использования. В частности одна из фичь, про которую говорят — дешёвые эксперименты. Но чтобы эксперименты были максимально дешёвыми (через di), то получается, что во всех блоках нужно отказаться от "классических" импортов и всё делать через di? (чтобы при приходе эксперимента не нужно было переписывать блок на di)

Вопрос 1.1: Где должен храниться код/реестры экспериментов? Внутри компонентов или лежать где-то рядом с компонентами?

Вопрос 1.2: Как правильно накатывать реестры и использовать версии экспериментов?

Вопрос 2: Следующее... В di правильно будет в качестве registry.id указывать имя блока или можно указывать и модификатор?

// ProductCard
new Registry({ id : 'ProductCard' })

ProductCard.registry/desktop.js
ProductCard.registry/mobile.js

// Product/_layout
new Registry({ id : 'ProductCard_layout_grid' })

ProductCard_layout_grid.registry/desktop.js
ProductCard_layout_grid.registry/mobile.js

@awinogradov @tadatuta

23 ноября в 19:00 о московском офисе Яндексе пройдет очередной БЭМап.

Регистрируйтесь скорее!

Завсегдатаи БЭМапов помнят, что мы уже рассказывали о третьей версии библиотеки bem-react-core, которая помогает работать по БЭМ-методологии в мире React.

На этот раз мы хотим перейти от теории к практике и на простых примерах показать, как использование библиотеки делает ваши React-проекты гибче и проще в поддержке.

Мы рассмотрим все три пакета библиотеки:

  • classname — для генерации имен классов в соответствии с БЭМ-нотацией
  • core — для динамической работы с модификаторами
  • di — для реализации концепции уровней переопределения с помощью паттерна Dependency Injection

Во второй части встречи с радостью ответим на все ваши вопросы, как по bem-react-core, так и по любым другим вопросам, связанным с БЭМ или разработкой интерфейсов в Яндексе в целом.

Ноутбук приносить не обязательно. После встречи мы опубликуем все материалы, ссылки и видео.

Встречи по БЭМ всегда бесплатны, но нужно зарегистрироваться заранее: количество мест ограничено.

Stay BEMed!

https://5minreact.ru/49-bem-react-core/ — слушайте на здоровье!

Уважаемые коллеги, подскажите, пожалуйста, как правильно переопределять стили блока, например:

.article__text {color: blue;} /* стиль текста именно в блоке article*/
.text {color: red;} /* общий стиль текста блока text*/

<div class="article">
    <p class="text article__text">Текст все равно красный!</p>
</div>

Стиль текста article__text все равно не меняется, потому что .text расположен ниже (сборка стилей в main.css происходит по алфавиту). Считаю, что использование !important или дополнительную вложенность элементов - это не метод БЭМ, так как же правильно обходить такую ситуацию? Следить за алфавитным порядком стилей в большом проекте также объективно не имеется возможности.

Или я неправильно понимаю использование миксов? Укажите, пожалуйста, на ошибку.

Добрый, посмотрел множество вебинаров по bem и bem-react-core, есть вопросы:

  • посмотрел видео https://www.youtube.com/watch?v=pVzlkCidOYg, и теперь не пойму, v3 это улучшенная версия v2 или просто другой подход, в каких случаях нужно v2, в каких v3?
  • если имеем react, то как я понимаю мы забываем о шаблонизации классического БЭМ (bemjson + bemhtml -> html)?
  • кстати зачем нужен bemtree так до сих пор и не понял..
  • нужен ли i-bem js со всей портянкой зависимостей в bem react проектах?

Кто знает, почему в десктопном input нет подписки на change у input__control, зато ставится таймер и по нему проверяется значение контрола? https://github.com/bem/bem-components/blob/v6/desktop.blocks/input/input.js

Предполагаю, это связано с какой-нибудь багой в каком-нибудь старом ослике

Добрый день, есть вопросы:

  • как менять стили например control-group http://joxi.ru/J2bYWbxUXWeQgm их нужно переопределять ?
  • И мне кажется что слишком много стилей выходит на выходе, просто подключил control-group - http://joxi.ru/5md5L41IkLQbX2 на выходе в CSS добавилось 550 строк стилей, потом добавил еще menu http://joxi.ru/1A5vBdLcn76Bnr дополнительно к стилям 200 строк. - это нормально ? может можно отключить стили ?
  • Для чего тогда нужна Библиотека ?

Вопрос не про bem-components в целом про БЭМ:

  • БЭМ по методологии не запрещает использовать after, hover, focus можно их использовать ?

Добрый день, где прописывать media запросы в БЭМ'e?

Всем доброго времени суток не могу понять почему не работает POST CSS и плагин autoprefixer

make.js и почему версии CSS не минимализированы http://joxi.ru/eAOG9BECxjWo6A

const techs = {
        // essential
        fileProvider: require('enb/techs/file-provider'),
        fileMerge: require('enb/techs/file-merge'),

        // optimization
        borschik: require('enb-borschik/techs/borschik'),

        // css
        postcss: require('enb-postcss/techs/enb-postcss'),
        postcssPlugins: [
            require('postcss-import')(),
            require('postcss-each'),
            require('postcss-for'),
            require('postcss-simple-vars')(),
            require('postcss-calc')(),
            require('postcss-nested'),
            require('rebem-css'),
            require('postcss-url')({ url: 'rebase' }),
            require('autoprefixer')(),
            require('postcss-reporter')()
        ],

        // js
        browserJs: require('enb-js/techs/browser-js'),

        // bemtree
        // bemtree: require('enb-bemxjst/techs/bemtree'),

        // bemhtml
        bemhtml: require('enb-bemxjst/techs/bemhtml'),
        bemjsonToHtml: require('enb-bemxjst/techs/bemjson-to-html')
    },
    enbBemTechs = require('enb-bem-techs'),
    levels = [
        { path: 'node_modules/bem-core/common.blocks', check: false },
        { path: 'node_modules/bem-core/desktop.blocks', check: false },
        { path: 'node_modules/bem-components/common.blocks', check: false },
        { path: 'node_modules/bem-components/desktop.blocks', check: false },
        { path: 'node_modules/bem-components/design/common.blocks', check: false },
        { path: 'node_modules/bem-components/design/desktop.blocks', check: false },
        'common.blocks',
        'desktop.blocks'
    ];

module.exports = function(config) {
    const isProd = process.env.YENV === 'production';

    config.nodes('*.bundles/*', function(nodeConfig) {
        nodeConfig.addTechs([
            // essential
            [enbBemTechs.levels, { levels: levels }],
            [techs.fileProvider, { target: '?.bemjson.js' }],
            [enbBemTechs.bemjsonToBemdecl],
            [enbBemTechs.deps],
            [enbBemTechs.files],

            // css
            [techs.postcss, {
                target: '?.css',
                oneOfSourceSuffixes: ['post.css', 'css'],
                plugins: techs.postcssPlugins
            }],

            // bemtree
            // [techs.bemtree, { sourceSuffixes: ['bemtree', 'bemtree.js'] }],

            // bemhtml
            [techs.bemhtml, {
                sourceSuffixes: ['bemhtml', 'bemhtml.js'],
                forceBaseTemplates: true,
                engineOptions : { elemJsInstances : true }
            }],

            // html
            [techs.bemjsonToHtml],

            // client bemhtml
            [enbBemTechs.depsByTechToBemdecl, {
                target: '?.bemhtml.bemdecl.js',
                sourceTech: 'js',
                destTech: 'bemhtml'
            }],
            [enbBemTechs.deps, {
                target: '?.bemhtml.deps.js',
                bemdeclFile: '?.bemhtml.bemdecl.js'
            }],
            [enbBemTechs.files, {
                depsFile: '?.bemhtml.deps.js',
                filesTarget: '?.bemhtml.files',
                dirsTarget: '?.bemhtml.dirs'
            }],
            [techs.bemhtml, {
                target: '?.browser.bemhtml.js',
                filesTarget: '?.bemhtml.files',
                sourceSuffixes: ['bemhtml', 'bemhtml.js'],
                engineOptions : { elemJsInstances : true }
            }],

            // js
            [techs.browserJs, { includeYM: true }],
            [techs.fileMerge, {
                target: '?.js',
                sources: ['?.browser.js', '?.browser.bemhtml.js']
            }],

            // borschik
            [techs.borschik, { source: '?.js', target: '?.min.js', minify: isProd }],
            [techs.borschik, { source: '?.css', target: '?.min.css', minify: isProd }]
        ]);

        nodeConfig.addTargets([/* '?.bemtree.js', */ '?.html', '?.min.css', '?.min.js']);
    });
};

Заранее благодарю!

Вопрос Не могу понять как это сделать по БЭМ

Я не так давно пытаюсь в сборку с помощью Gulp. Конфиг project-stub показался мне слишком сложным для понимания, вдобавок мне нужно было настроить сборку HTML из файлов pug, поэтому было решено затрайхардить и написать свой конфиг. В итоге решения основной задачи я с горем пополам вроде как добился, сейчас в сборку подключаются блоки, которые майнятся из pug файлов, но теперь появилась другая потребность - добавлять в сборку блоки с учётом зависимостей. Конкретный пример - для того, чтобы добавить блок filter в сборку, необходим jquery, который также реализован отдельным блоком jquery с одной технологией jquery.js. По логике вещей я должен создать файл filter.deps.js, зависимости из которого также будут добавлены в сборку перед целевым блоком.

Очевидно, этого не происходит, иначе бы я сюда не написал :)

Ниже приведён код соответствующего таска Gulp:

gulp.task('deps', () => {
   return gulp.src('bundles/**/*.pug')
    .pipe(pug(pugConfig))
    .pipe(tobemjson())
    .pipe(builder({
        css: bundle => bundle.src('css')
          .pipe(autoprefixer(), {
            browsers: ['last 2 versions'],
            cascade: false
          })
          .pipe(concat(`${bundle.name+'/'+bundle.name}.css`)),
        js: bundle => bundle.src('js').pipe(concat(`${bundle.name+'/'+bundle.name}.js`))
    }))
    .pipe(gulp.dest('dist/'));
});

Содержимое deps.js:

module.exports = [{
    mustDeps : 'jquery'
}]

В результате конечный BemBundle.decl содержит все нужные блоки, кроме jquery, который должен быть подключен в качестве зависимости.

Вероятнее всего, я неверно понимаю принципы работы сборщика, поэтому прошу при возможности объяснить, где я налажал. Спрашиваю не от лени - просто дело в том, что документации у плагина сильно не хватает, что, ИМХО, является распространённой проблемой подобных инструментов "для БЭМ" и дополнительно повышает порог вхождения, так что большому счёту я пользовался материалами из вебинаров, васянских гайдов и пытался разобраться в исходниках.

Есть желание собирать css и из post.css и из .styl.

(По причине: (а) наличия legacy на stylus, (б) отсутствия в postcss жизненно необходимого вроде возможности проверить defined($variable) и nested-ancestors "сверху" -- от родителя -- stylus-аналог ^[0] etc, (в) всё-таки наличия большого кол-ва postcss вкусностей и полезностей.)

Сходу вижу вариант со сбором в отдельные промежуточные таржеты с последующей склейкой через file-merge. Будет не оч. хор., т.к. в итоге блоки с технолгиями stylus и postcss не смогут перекрывать друг друга в соответствии с уровнями переопределения. (С sourcemap file-merge вроде справляться должен.)

Есть ли иной способ?

UPD: enb/file-merge.js, похоже, всё-таки ожидает только js на входе. При попытке склеить css ругается на синтаксис. Т.е. всё пропало?

Съезжают настройки sourcemaps для технологий bemhtml.js и browser.js. Глядя на старые проекты (где всё как-то работало), кое-как восстанавливаю для browser.js (перадчей параметров из конфига enb/make + патчем модулей enb-source-map, source-map), для bemhtml.js пока вообще не могу найти, куда крутить?

Хелп? Как это делается? Или у всех из коробки работает? А почему у меня -- никогда (теперь; кажется)?

Текущий проект бутстрапил на последнем bem/project-stub (месяц назад) перстаскивал библиотеки/патчи из старых проектов.

Попробовал на "чистом" project-stub -- при минимальных изменениях (меняем в index.bemjson.js подключение скрипта index.js на последовательные: index.bemhtml.js и index.browser.js) -- И достигаем такого же эффекта: sourcemaps подтягиваются для browser.js, для bemhtml.js перебрасывает совсем в другие места общего бандла. Чего/куда крутить?

UP: Глянул на старые проекты ещё раз: там sourcemaps от шаблонов были вообще откручны. Т.е., дебажимся уже в собранном бандле. Т.е., видимо, так и дальше надо. Вывод: отключаем все sourcemaps от технологии bemhtml вообще, раз так.

Собственно, ситуация довольно сложная и вряд ли что-то измениться от этого поста, но свободное время нужно куда-то конвертировать, пусть это будет небольшой рассказ.

Чуть более года назад связался с БЭМ, до этого что-то умел в плане вёрстки сайтов, но знания были сумбурные. Фреймворк связал эти знания в единое целое и позволил заниматься этим более профессионально, а также подтолкнул к изучению NodeJS и npm. Конечно, путь был довольно тернист и первое время порог входа в БЭМ был слишком высок, но всё-таки преодолеть его удалось.

К этому моменту я довольно хорошо разобрался с методологией и документацией БЭМ и написанием собственных блоков, а также освоил и BEMExpress, который открыл мне доступ к полноценной разработке сайтов, включая несложную серверную часть (работа с MongoDB и пр.)

Пожалуй именно БЭМ выступил катализатором моего обучения (привёл на Github в том числе) и позволил мне создать парочку сайтов на заказ (например), но также именно БЭМ сделал нечто плохое. В какой-то из статей Яндекса о БЭМе была фраза "сначала вы его отрицаете, потом не можете без него жить". И оказалось, что для рядового разработчика это не так уж и хорошо, так могло казаться вначале.

БЭМ штука довольно непопулярная, особенно если вы пытаетесь работать фрилансером. Порой часами приходилось объяснять горе-заказчикам что это за зверь и для чего нужен, а после полностью выполненной работы (простой лендинг) я получил деньги и отрицательный отзыв вроде "хотел немного стиль select поправить, а там куча непонятного CSS и длиннющие классы, а JS-код вообще огромен, что это?". И что теперь всех заказчиков-самоучек учить писать по БЭМ и развертывать среду разработки? Увы, получить БЭМ-фрилансеру адекватный заказ оказалось довольно сложно, так как у людей ещё Вордпресс в голове и PHP, перемешанный с HTML в одном файле.

Получается либо искать человека, который хочет сайт под ключ и ему плевать на чём этот сайт работает, либо отказываться от БЭМ и "приземляться" к народу на 5-6 лет назад. А кто-то ещё сталкивался с такой дилеммой?

P.S. Открыт к любым предложениям, связанным с БЭМ (ещё есть куда расти) P.P.S. Извините за многобукв :)

Всем привет! Запаситесь терпением, пожалуйста, но мне правда нужен совет Есть компоненты формы (select, input, textarea) Так вышло, что в зависимости от страницы у элементов меняется вид и я думал, все эти блоки разные (по типу функциональности), но группы элементов имеют одинаковый вид и я поступил так Создал блок form-element, единственное назначение которого быть миксином для стилизации групп сущностей, т.к. мне показалось странным создавать одинаковые стили для каждого компонента, DRY наше всё После этого я стал искать различия между элементами и вышло что-то невероятное

7 различных значений высоты компонента 7 различных значений размера шрифта компонента 5 различных значения bg, включая отсутствие bg 2 значения border-radius, 1 на 10px, другое на 16 Есть или нет рамки 2 значения толщины рамки 3 значения цвета рамки 3 разных значения расположения тени

Сидел, сидел и сЕдел и думал, как я "люблю" дизайнеров, но делать что-то нужно и создал я 5 модификаторов, а именно: form-elementboder(normal || bold) отвечающие только за толщину рамки form-elementrounded(md || lg) отвечающие за значения 10 и 16 form-elementshadow(md || lg), отвечающие за тень form-elementsize(много значений) отвечающие за высоту и размер шрифта form-elementtheme(много значений) отвечающие за цвет фона, цвет шрифта, цвет рамки

Создал отдельно блок input, в итоге код выглядит примерно так

<div class="
    input form-element
    form-element_theme_first
    form-element_size_md
    form-element_rounded_md
    form-element_border_normal
">
    <input type="text" class="input__field">
</div>


.input__field {
    padding: 0 16px;
    margin: 0;
    height: 100%;
    width: 100%;
    border: none;
    outline: none;
    background: none;
    color: inherit;
}

И всё было бы ничего, но пришло время создавать select, который сейчас выглядит так

<div class="
    select
    select_opened
    form-element
    form-element_theme_first
    form-element_size_md
    form-element_rounded_md
    form-element_border_normal
">
     <select name=""></select>
     <div class="select__header">
         <p class="select__value">Product</p>
         <span class="arrow arrow_bottom select__arrow"></span>
      </div>
      <ul class="select__body">
          <li class="select__option">Product</li>
          <li class="select__option">Product</li>
      </ul>
</div>

И здесь я понял, что мне конец, ведь в зависимости от модификаторов form-element, мне нужно менять элементы компонента select, а это неправильно, потому что будут селекторы вида .class .class, но хуже всего, что модификатор одного блока будет влиять на элементы другого блока, совсем не относящегося к нему. Что я имею ввиду, в зависимости от form-element_size_md должен меняться размер select__option, в зависимости от рамки добавляться или уходить она, также про border-radius, да вообще хоть про что, плюсом идут немного разные стили, когда select развернут. В итоге, я в тупике и не знаю как быть, мои варианты были такими, создать все компоненты отдельно select, input, textarea и тупо для каждого были бы свои модификаторы, НО они были бы идентичны, т.к. select_size_md, input_size_md, textarea_size_md означали одно и тоже, это плохо, одинаковые реализации. Дальше я подумал, а что если вынести select из всей этой кучи и добавить модификаторы для него, я получил бы что-то типа select_size_md для селектов и form-element_size_md для input и textarea, но тогда мы всё равно имеем 2 одинаковых реализации. Я бы мог написать их так select_size_md, form-element_size_md, но тогда смысла в создании form-element как отдельной сущности вообще не стало.

И вопросов у меня ровно 3 1) Правильно ли я разбил на модификаторы все различия между элементами, просто их вышло так много и они по 1 строчке почти все, что я сомневаюсь в правильности? 2) Как мне быть с особенностями select компонента (описанию проблемы отдана большая часть текста)? 3) Могу ли я использовать блок так

<div class="block">
    <div class="block__elem1"></div>
    <div class="block__elem2"></div>
</div>

.block {color: #fff; position: relative}
.block__elem1 {position: absolute; right: 0}
.block__elem2{position: absolute; left: 0}

А в другом месте так

<div class="block">
    <div class="block__elem1"></div>
</div>

То-есть, я могу написать хоть 100 стилей для элементов, а потом взять и в блоке только 1 элемент использовать, это нормально?

P.S. Возможно я не совсем корректно написал название вопроса, но моя голова кипит. Заранее спасибо

Есть эл-т NavBar-MenuItem, добавляем модификатор _hasSubmenu. Примерно так:

//...
import INavBarMenuItemProps from '../NavBar-MenuItem';
export interface INavBarMenuItemHasSubmenuProps extends INavBarMenuItemProps {
  hasSubmenu?: boolean;
  menu?: Array<{}>;
}
export default class NavBarMenuItemHasSubmenu<P extends INavBarMenuItemHasSubmenuProps> extends Elem<P> {
  public block = 'NavBar';
  public elem = 'MenuItem';
  public static mod = ({ hasSubmenu }: INavBarMenuItemHasSubmenuProps) => hasSubmenu === true;
  public elemMods() {
    const {hasSubmenu} = this.props;
    return {
      ...super.mods(),
      hasSubmenu,
    };
  }
  // ...
}

Пробовал по-разному, напр., NavBarMenuItemHasSubmenu extends Elem<INavBarMenuItemHasSubmenuProps>, ещё как-то.

При использовании в родительском эл-те ругается на отсутствие свойств в определении props у родительского или модифицированного элемента. Напр.:

[tsl] ERROR in .../src/blocks/NavBar/Menu/NavBar-Menu.tsx(138,15)
      TS2339: Property 'no' does not exist on type '(IntrinsicAttributes & ClassAttributes<{} | EntityProps<INavBarMenuItemHasMenuProps>> & IBemProps...'.

(no -- свойство расширяемого NavBar-MenuItem.)

В NavBar-Menu Делаем так:

// ...
import MenuItem from '../MenuItem/NavBar-MenuItem';
import hasMenu from '../MenuItem/_hasMenu/NavBar-MenuItem_hasMenu';
const MenuItemWithMods = withMods(MenuItem, hasMenu);
// ...
export default class NavBarMenu extends Elem<INavBarMenuProps, INavBarMenuState> {
  public block = 'NavBar';
  public elem = 'Menu';
  // ...
  public content() {
    const {menuItems, selectedNo, showDebugMsg, debugMsg} = this.state;
    return (
      <MuiMenuList classes={{root: this.block + '-MenuContainer'}}>
        {Array.isArray(menuItems) && menuItems.map(({id, text, menu}, no) => {
          const hasMenu = Array.isArray(menu);
          return (
            <MenuItemWithMods
              hasMenu={hasMenu}
              menu={menu}
              key={no}
              no={String(no)}
              selected={selectedNo === no}
              onClick={this.handleClick}
            >{text}</MenuItemWithMods>
          );
        }, this)}
      </MuiMenuList>
    );
  }
}

Как правильно дополнять описания пропсов для модификатора элемента?

В react'е пока "плаваю". Наверняка глупый вопрос:

Не могу найти способ "примешать" чужой компонент к своему. Т.е., задача в том, чтобы на одном DOM-узле находилось два компонента. Последняя конкретная ситуация:

Блок NavBar имеет элемент Menu, в который вложен набор элементов MenuItem. Использую Material-UI: в Menu вкладываю MuiMenuList, в MenuItem -- MuiMenuItem.

В итоге получаю такую структуру:

<div class="NavBar-Menu">
  <div class="MuiList...">
    <div class="NavBar-MenuItem">
      <div class="MuiListItem...">...</div>
    </div>
    <!-- ... -->
  </div>
</div>

Могу ли примешивать для NavBar-Menu и NavBar-MenuItem примешивать соотв. MuiMenuList и MuiMenuItem, вместо вкладывания чилдренов в методе content()?

Т.е., чтобы в итоге получалось:

<div class="NavBar-Menu MuiList...">
  <div class="NavBar-MenuItem MuiListItem...">...</div>
  <!-- ... -->
</div>

Как?

UPD: На всякий случай: приходило в голову пытаться как-то наследовать помимо Elem, ещё и от MUI-шного класса, но абсолютно не понимаю, как подсовывать нужные параметры. Сейчас это выглядит так:

export default class NavBarMenuItem extends Elem<INavBarMenuItemProps, INavBarMenuItemState> {
  public block = 'NavBar';
  public elem = 'MenuItem';
  public content() {
    return (
      <MuiMenuItem
        id={String(this.props.no)}
        selected={this.props.selected}
        onClick={this.props.onClick}
        classes={{
          root: `${this.block}-${this.elem}Mui`,
          selected: `${this.block}-${this.elem}Mui_selected`,
        }}
      >{this.props.children}</MuiMenuItem>
    );
  }
}

(MenuItemMui* -- Это, чтобы иметь возможность стилизовать создаваемый компонент.

Добрый день.
Решили верстку в своих проектах реализовать с помощью БЭМ, а потом и JS
Что есть сейчас - на бекенде единый движок с моделями и контроллерами, и есть несколько сайтов - шкур, там схема урлов, статика, шаблоны, все на Django
Что мне нужно - единая организация пока что верстки в проектах
Какие я вижу проблемы:

  • не пойму как организовать уровни переопределения, у нас есть несколько сайтов, у нас есть мобильная верстка (а она применяется не только если девайс мобильный, но и когда экран < 768px)
  • что делать если шаблон для мобильной версии очень сильно отличается от десктопной? сейчас в DOM есть копии с префиксом "m-", но мне это уже не особо нравится, это все усложняет шаблоны и верстку
  • не пойму как и чем сейчас собирают, сам я за webpack/gulp (может все же удастся образумить заказчика сделать домен m.* и тогда буду в разные бандлы собирать), есть примеры сборки БЭМ на этих утилитах?
  • как это все должно выглядить в шаблонах?
    • каждый блок - templatetag?
    • в какой структуре хранить на фс?
    • как будет выглядеть разметка страницы? одни include блоков с указанием типов? с удовольствием бы посмотрел примеры
  • очень хотелось бы получить ссылки на вебинары/туториалы от вас по подводным камням и БЭМ в проде, так сказать квинтэссенцию материалов по теме
  • как не наломать дров? =)
  • что делать с JS, сейчас там везде применен паттерн "модуль", делать все в прототипах(классах) и на уровнях переопределения наследованием рулить?

Спасибо, очень надеюсь на помощь, чтобы получить долгожданный порядок во фронтенде

Расскажите, как вы тестируете проекты на bem-react-core, как пишите юнит и интерграционные тесты, используете ли тестирование скриншотами. Если есть видео на эту тему - киньте ссылкой.

Есть микс для параграфа .paragraph. Он используется для параграфов в различных элементах, в том числе для элементов-параграфов в блоке .article. Однако в этом блоке необходимо добваить еще стили для параграфа.

Как я понимаю это будет реализовыватся как то так (с добавлением элемента .article__paragraph):

<div class="article">
  <div class="article__paragraph paragraph"></div>
</div>

Это явлется правильным?

Может ли микс иметь модификаторы?

Допустим у нас есть класс .link который задает стили для всех ссылок на странице, есть элемент .navbar__link который должен унаследовать стили от класса .link.

Как это правильно реализовать?

P.S. Тут написно как нужно: https://ru.bem.info/methodology/css/#Стилизация-групп-блоков

Не могу понять, как теперь правильно работать со стилями модификаторов. Смотрю на bem-react-boilerplate@0.1.0. Вижу два модификатора для <ExampleWithMods mod1 mod2 />. Имен классов, как привычно (<Example class="Example Example_mod1 Example_mod2">) не добавляются. Пробую добавлять вручную через mods (bem-react-core/REFERENCE.md - mods):

  public mods() {
    return {mod1: this.props.mod1};
  }

-- при этом отрабатывается только один вызов mods для всех модификаторов.

Как правильно?

Вообще, ткните, пож., в актуальные примеры кода/кейсы по bem-react-core?

Ситуация: при сборке в enb в bundle хочется подключать модули из исходного кода для использования в самом make.js и внутри .bemhtml шаблонов. Например, для получения общих параметров конфигурации или утилит вроде форматирования дат и пр.

В одном из прошлых проектов решал путём возврата промиса из bemjson, который разрешался после запроса нужных зависимостей (вручную, по списку). Кажется, было что-то приличное. Где-то когда-то видел что-то (почти, кажется?) готовое, но вот никак не могу найти. Хелп?

UP: Вижу что-то похожее в API / 8.x / Шаблоны (BEMHTML, BEMTREE) / Платформа / БЭМ - Подключение-сторонних-библиотек.

Пробую поключить ym-модуль project (находится в уровнях переопределения):

В make.js:

            // bemhtml
            [techs.bemhtml, {
                sourceSuffixes: ['bemhtml', 'bemhtml.js'],
                forceBaseTemplates: true,
                engineOptions : {
                    elemJsInstances : true,
                    requires : {
                        project : {
                            globals: 'project',
                            ym: 'project',
                        },
                    },
                },
            }],

В common.blocks/test/test.bemhtml:

    def()(function(){
        var project = this.require('project');
        console.log('in test.bemhtml', project);
        return applyNext();
    }),

Как результат, в консоль получаю undefined.

При этом вижу, что в бандл .benhtml.js записывается:

if (typeof modules === "object") {
  modules.define("project",["project"],function(provide, ymlib) {
    provide(ymlib);
  });
  modules.define("project",function(provide, prev) {
    provide(glob["project"] || prev);
  });
  modules.define("BEMHTML",["project"],function(provide,dep0) {
    var engine = buildBemXjst({"project":dep0});
    engine.libs = {"project":dep0};
    provide(engine);
  });
} else {
  var _libs = {};
  typeof glob["project"] !== "undefined" && (_libs["project"] = glob["project"]);
  if (Object.keys(_libs).length) {
    BEMHTML = buildBemXjst(_libs);
    exp["BEMHTML"] = BEMHTML;
    exp["BEMHTML"].libs = _libs;
  } else {
    BEMHTML= buildBemXjst(glob);
    exp["BEMHTML"] = BEMHTML;exp["BEMHTML"].libs = glob;
  }
}

-- Тут щас буду разбираться, куда оно в итоге девается.

Модуль project находится в base.blocks/project/project.js, в test.js (в рантайм) подключается вполне нормально, вот так:

modules.define('test', ['i-bem-dom', 'project'], function(provide, bemDom, project) {
provide(bemDom.declBlock(this.name, {
    onSetMod: {
        js: {
            inited: function() {
                console.log('project module', project);
            }
        }
    }
}));
});

Уровни переопределения задаются в .bemrc.js:

    levels: {
        'libs.blocks': { scheme : 'nested' },
        'base.blocks': { scheme : 'nested' },
        'common.blocks': { scheme : 'nested' },
        'desktop.blocks': { scheme : 'nested' },
        // 'pages': {},
    },

В make.js импортируются:

    srcLevels = Object.keys(require('../.bemrc.js').levels),

Версии:

$npm list enb enb-bemxjst
+-- enb@1.5.1
`-- enb-bemxjst@8.10.4