GithubHelp home page GithubHelp logo

bem / bem-react Goto Github PK

View Code? Open in Web Editor NEW
437.0 35.0 64.0 2.71 MB

A set of tools for developing user interfaces using the BEM methodology in React

Home Page: http://bem.github.io/bem-react

License: Other

JavaScript 24.47% TypeScript 74.73% CSS 0.80%
react bem declarative react-components bem-methodology

bem-react's Introduction

bem-react · github (ci)

A set of tools for developing user interfaces using the BEM methodology in React. BEM React supports TypeScript type annotations.

Packages

Package Version Size
@bem-react/classname npm (scoped) npm bundle size (minified + gzip)
@bem-react/classnames npm (scoped) npm bundle size (minified + gzip)
@bem-react/core npm (scoped) npm bundle size (minified + gzip)
@bem-react/di npm (scoped) npm bundle size (minified + gzip)
@bem-react/eslint-plugin npm (scoped)

Contribute

Bem React Core is an open source library that is under active development and is also used within Yandex.

If you have suggestions for improving the API, you can send us a Pull Request.

If you found a bug, you can create an issue describing the problem.

For a detailed guide to making suggestions, see: CONTRIBUTING.md.

License

© 2018 Yandex. Code released under Mozilla Public License 2.0.

bem-react's People

Contributors

alexbaumgertner avatar artems avatar awinogradov avatar belozer avatar denisbalyko avatar dfilatov avatar fiberthrone avatar fresk-nc avatar glazomer avatar godfreyd avatar gridsane avatar ilyar avatar isqua avatar ivandashk avatar lisbon11 avatar mayton avatar nodejsgirl avatar plotnikovn avatar qfox avatar rifler avatar selnapenek avatar sergcen avatar stenin-nikita avatar tadatuta avatar vbagmut avatar veged avatar vithar avatar vittly avatar yarastqt avatar yeti-or avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bem-react's Issues

Webpack build config + Babel plugin

If we have file system structure:

node_modules/my-lib/blocks/
  OtherBlock/OtherBlock.js
blocks/
  OtherBlock/OtherBlock.js
  MyBlock/
    _myMod/MyBlock_myMod.js
    MyBlock.js
pages/
  index/index.js

and files content:

// node_modules/my-lib/blocks/OtherBlock/OtherBlock.js
import { Bem } from 'bem-react-core';
export default Bem.decl(/* ... */);
// blocks/OtherBlock/OtherBlock.js
import { Bem } from 'bem-react-core';
export default Bem.decl(/* ... */);
// blocks/MyBlock/MyBlock.js
import { Bem } from 'bem-react-core';
import OtherBlock from 'bem:OtherBlock';
export default Bem.decl(/* ... */)
// blocks/MyBlock/_myMod/MyBlock_myMod.js
import { Bem } from 'bem-react-core';
import MyBlock from 'bem:MyBlock';
export default MyBlock.declMod(/* ... */);
// pages/index/index.js
import React from 'react';
import ReactDom from 'react-dom';
import MyBlock from 'bem:MyBlock';

ReactDom.render(<MyBlock/>, document.getElementById('root'));

It should become:

// node_modules/my-lib/blocks/OtherBlock/OtherBlock.js
var Bem = require('bem-react-core').Bem;
module.exports = Bem.decl(/* ... */);
// blocks/OtherBlock/OtherBlock.js
require('../../node_modules/my-lib/blocks/OtherBlock/OtherBlock'); // NOTE: how will it work with tree-shaking?
var Bem = require('bem-react-core').Bem;
module.exports = Bem.decl(/* ... */);
// blocks/MyBlock/MyBlock.js
var Bem = require('bem-react-core').Bem;
var OtherBlock = require('../blocks/OtherBlock/OtherBlock');
module.exports = Bem.decl(/* ... */);
// pages/index/index.js
var React = require('react');
var ReactDom = require('react-dom');
var MyBlock = require('../../blocks/MyBlock/MyBlock');

ReactDom.render(React.createElement(MyBlock), document.getElementById('root'));

Add test-suits

  • - CSS classes generation (mods, mix, cls)
  • - attrs, content, wrap (not function too)
  • - lifecycleHooks?
  • - base (inheritance and mixins) in declaration
  • - declMod
  • - support propTypes and defaultProps inherit #13

Duplicated mixes in case of declared entity

При миксировании сущности в JSX, происходит дублирование микса.
Пример:

payment-scenario.react.js

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

export default decl({
    block: 'payment-scenario'
});

Вызов

<PaymentScenario mix={{ block: 'island', elem: 'section' }} />

=>

Получаемый HTML

<div class="payment-scenario island__section island__section"></div>

fix linters

@awinogradov did you see these msgs?

/Users/yeti-or/Projects/Y/BEM/bem-react-core/__tests__/propTypes.spec.js
   6:20  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types
  14:27  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types
  21:20  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types

/Users/yeti-or/Projects/Y/BEM/bem-react-core/lib/decls.js
  22:29  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types
  22:71  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types
  48:44  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types
  65:34  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types
  65:85  error  Using another component's propTypes is forbidden  react/forbid-foreign-prop-types

Order of files in case of block importing self modifier

Допустим у меня есть блок button.
Внутри я использую модификатор, который должен быть подключен всегда вместе с button. Например button_disable_yes.

Если я напишу в файле button.js

import Button from "b:button m:disable=yes";

То файл button_disable_yes.js подключится раньше button.js. Получится что button переопределяет button_disable_yes, а не наоборот.

replace() mod

Guys didn't you think about replace mod?

It will be useful when I want to return array of nodes:

// App.react.js
import React from 'react';
import {decl} from 'bem';

import AppContent from 'e:Content';

export default decl({
 block: 'App',
 content: (<AppContent />)
})

// App__Content.react.js
import React from 'react';
import {decl} from 'bem';

export  default decl({
 block: 'App',
 elem: 'Content',
 content: (
  <div class="Stupid-Wrapper>
    <span>One</span>
    <span>Two</span>
    <span>Three</span>
  </div>
})

With replace() mod I could return array so there is no need to wrap it in unnecessary <div>.

npm test is not working after npm install

Reproducing steps:

  1. git clone https://github.com/bem/bem-react-core
  2. cd bem-react-core
  3. npm i
  4. npm test

Result:

all tests fail with:

  ● Test suite failed to run

    Cannot find module 'babel-template'

After install dependencies with yarn it works correctly(thats why Travis CI works – it uses yarn).

Problem with mod inside block

// block.js

import 'm:mod';
// require('block_mod.js').applyDecl();

export default decl({
  block: 'name',
  content: 'hello '
});
// block_mod.js

export default declMod({
  block: 'name',
  content() {
    return this.__base(...arguments) + 'world';
  }
})

Here we enter in block.js,
then require block_mod.js and apply it's decl.
but at this moment block's decl wasn't executed, so ./lib/decls.js fails here:
https://github.com/bem/bem-react-core/blob/master/lib/decls.js#L47

Can't resolve decl in required self mod

TypeError: Cannot read property 'prototype' of null

      at Object.applyEntityDecls [as applyDecls] (lib/decls.js:48:32)
      at Object.<anonymous> (__tests__/fixtures1.blocks/BlockWithRequiredMod/BlockWithRequiredMod.js:3:132)
      at Object.<anonymous> (__tests__/orderOfMod.spec.js:3:57)
      at process._tickCallback (internal/process/next_tick.js:103:7)

Make code examples in README.md more illustrative

In my opinion, existing code examples are too formal. MyBlock_myMod1_myVal1 isn't very illustrative and related to real world use cases. What about making those examples more developer-friendly? We could use examples such as Button, Input or something like that instead of abstract MyBlock.

Initial scope

  • BEM-entities declaration
    • with modifiers
    • on redefinition levels
    • inheritance
  • creating
    • with JS classes
    • without JS classes
  • html templates
    • tag
    • attrs
    • cls
    • mods
  • React lifecycle methods
  • mix
  • mixin (TBD)
  • jsx
  • deps
  • build #2
// MyBlock.js

import Bem from 'bem:Bem';
import MyElem from 'bem:MyBlock-MyElem';
import OtherBlock from 'bem:OtherBlock';
import WrapBlock from 'bem:WrapBlock';

export default Bem.decl({
    block : 'MyBlock',
    tag : 'a', 
    mods({ disabled }) {
        return { disabled };
    },
    // ... etc. about html
    attrs({ disabled, onChange }) {
        return {
            disabled,
            onChange,
            onFocus: this.onFocus,
        }
    },

    content() { // children?
        return [
            <Bem block={this} elem="MyElem" tag="span"/>,
            <OtherBlock>{ this.props.children }</OtherBlock>,
            <Bem block="OtherBlock" elem="OtherElem" tag="span"/>,
            <MyElem .../>,
            // ...
        ]
    },

    render() {
        return WrapBlock({}, [this.__base()]);
    },

    componentWillMount,
    componentDidMount,
    componentWillReceiveProps,
    shouldComponentUpdate,
    // ... all React lifecycle methods
});

// MyBlock_myMod.js

import MyBlock from 'bem:MyBlock'

export default MyBlock.decl({
    block : 'MyBlock',
    mod : ({ myMod }) => myMod /* some predicate */, 
    tag : 'span',
    // ... any other methods will be guarded by modifier predicate
});

Update docs

  • - mix by default
  • - cls by default
  • - mods helpers
  • - development section
  • - wrappedDecl

The way for base elements on blocks

Sometimes we need base elems on blocks. For example menu__item. It must provide all states from control: hover, focus and etc. In current realization, we have different block menu-item (it can be based on control) or we are copy and paste code from control to menu__item. If we would base elems on blocks this problem will be solved.

New release

Please release new version of bem-react-core via npm.

Add helper for most common cases of `declMod`

  • declMod({ modName : ‘modVal’ }, …) — for declaration of _modName_modVal with automatically adding of props.modName to mods
  • declMod({ modName : ‘*’ }, …) — for common declaration for any value of modName (and auto adding to mods)
  • declMod({ modName : ({ modName }) => ... }) — for declaration additional custom matching for modName (and auto adding to mods)
  • current declMod(({ modName }) => …, { mods() { … } }) — for completely manual control of modifiers

export baseComponent

Sometimes we need extend base component. Yes, I know about the base property, but it'll look like copy and paste of code for baseComponent for one or two new methods.

Use context to omit block={this}

We can use context to get the parent block for element. So instead of writing

    return (
      <Bem block={this} elem='Wrapper'>
        <Bem block={this} elem='Content'>
          <Bem block={this} elem='Title'>title</Bem>
          <Bem block={this} elem='Body' />
        </Bem>
      </Bem>
    );

we can just write:

    return (
      <Bem elem='Wrapper'>
        <Bem elem='Content'>
          <Bem elem='Title'>title</Bem>
          <Bem elem='Body' />
        </Bem>
      </Bem>
    );

It looks much more elegant and cleaner.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.