bem / bem-react

A set of tools for developing user interfaces using the BEM methodology in React
http://bem.github.io/bem-react
Other
440 stars 64 forks source link

Add complex example of levels redefinition #192

Closed ilyar closed 6 years ago

ilyar commented 6 years ago

В bem-react-core возможно такое переопределение https://goo.gl/XWUM6W

[
    { 
        block: 'foo',
        content: {
            elem: 'bar',
            content: 'baz'
        }
    },
    { 
        block: 'foo',
        mods: { project: 'mod' },
        content: {
            elem: 'bar',
            content: 'baz'
        }
    }
]

// lib level
block('foo')(
  tag()('a')
);
block('foo').elem('bar')(
  tag()('span')
);

// project level
block('foo').mod('project', 'mod')(
    content()(function () {
        return [
            {
                elem : 'quz',
                tag : 'span',
                content : 'quz'
            },
            applyNext()
        ];
    })
);
// lib level
<a class="foo">
    <span class="foo__bar">baz</span>
</a>

// project level
<a class="foo foo_project_mod">
    <span class="foo__quz">quz</span>
    <span class="foo__bar">baz</span>
</a>

Будет очень полезен пример этого же на реакте с bem-react-core.

awinogradov commented 6 years ago

https://jsfiddle.net/awinogradov/5a4yrkvj/1/

<div id="root">
  <a class="Foo">
    <span class="Foo-Bar">baz</span>
  </a>
  <a class="Foo Foo_project_mod">
     <span class="Foo-Quz">quz</span>
     <span class="Foo-Bar">baz</span>
  </a>
</div>
ilyar commented 6 years ago

@awinogradov Спасибо за ответ, кажется что-то не обновилось в песочнице, вижу там:

const { Bem, decl, declMod } = BemReactCore

const MyBlock = (
    decl({
        block: 'MyBlock',
        content: 'Hello'
    }),

    declMod({ mod: true }, {
        block: 'MyBlock',
        content(props) {
            return [
                'Modified ',
                this.__base(...arguments)
            ]
        }
    }))
    .applyDecls()

const Root = () =>
    <Bem block="Wrapper">
        <MyBlock/>
        <MyBlock mod/>
    </Bem>

ReactDOM.render(<Root/>, document.getElementById('root'))
<div id="root">
  <div class="Wrapper">
    <div class="MyBlock">Hello</div>
    <div class="MyBlock MyBlock_mod">Modified Hello</div>
  </div>
</div>

Да это определенно показывает доопределение, но остается не понятно, как сделать тоже что в примере на xjst, а именно добавить элемент в структуру блока.

awinogradov commented 6 years ago

Продублирую сюда

const { Bem, decl, declMod } = BemReactCore

const Foo = (
    decl({ 
    block: 'Foo', 
        tag: 'a' 
  }),

  declMod({ project: '*' }, { 
    block: 'Foo',
        content() {
            return [
          <Bem elem="Quz" tag="span">quz</Bem>,
              this.__base(...arguments)
           ]
       }
  })
).applyDecls()

const FooBar = (
    decl({ 
            block: 'Foo', 
            elem: 'Bar', 
            tag: 'span' 
        })
).applyDecls()

const Root = () => ([
    <Foo>
            <FooBar>baz</FooBar>
    </Foo>,
        <Foo project="mod">
             <FooBar>baz</FooBar>
    </Foo>
])

ReactDOM.render(<Root/>, document.getElementById('root'))
ilyar commented 6 years ago

@awinogradov отлично, спасибо, остается не понятно, как это в реальном проекте может быть, как это на два файла может быть разделено (реализация на уровне библиотеки и проектного доопределения)? И непонятно почему переменная MyBlock не используется явно это магия реакта?

awinogradov commented 6 years ago

Какая переменная еще?) Посмотри в код внимательно) Разделение по файлам точно такое же как и всегда было.

ilyar commented 6 years ago

*И непонятно почему переменная Foo, FooBar и Root не используется явно это магия реакта (JSX в них преобразуется)?

Разделение по файлам точно такое же как и всегда было.

Это все таки не понятно.

awinogradov commented 6 years ago

Посмотри еще раз на код)

awinogradov commented 6 years ago
// lib/blocks/Foo/Foo.js
import { decl } from 'bem-react-core'

export default decl({ 
  block: 'Foo', 
  tag: 'a' 
})
// lib/blocks/Foo/Bar/Foo-Bar.js
import { decl } from 'bem-react-core'

export default decl({ 
  block: 'Foo', 
  elem: 'Bar', 
  tag: 'span' 
})
// project/blocks/Foo/_project/Foo_project.js
import { decl } from 'bem-react-core'

export default declMod({ project: '*' }, { 
  block: 'Foo',
  content() {
            return [
          <Bem elem="Quz" tag="span">quz</Bem>,
              this.__base(...arguments)
           ]
       }
  })