Coder Social home page Coder Social logo

angular-bem's Introduction

angular-bem

A set of directives to simplify your workflow with BEM-markup in Angular (v2+) applications.

ANGULAR 1.X VERSION IS HERE

Changelog

2.1.0

  • Support for Angular v6+
  • Refactoring

2.0.0

  • Initial release for Angular v2+

Install

$ npm install angular-bem

Example

Import this module to your app:

import { BemModule } from 'angular-bem';

@NgModule({
  imports: [ BemModule ]
})
export class AppModule {}

Now anywhere in your app you can use following syntax:

<div block="my-block" mod="modName">
  <div elem="my-element" mod="modName secondModName"></div>
</div>

or

<div block="my-block" [mod]="{ modName: true }">
  <div elem="my-element" [mod]="{ modName: true, secondModName: true }"></div>
</div>

Instead of true you can use any property from the component. Value true will add mod to the block (or elem) and false will remove it.

As a result of module's work the following markup may be produced:

<div class="my-block my-block--mod-name">
  <div class="my-block__my-element my-block__my-element--mod-name my-block__my-element--second-mod-name"></div>
</div>

If you use string or number as a value then this value will be used as addition for the mod class like my-block__my-element--mod-name-value.

Configuration

You can change module behaviour with BemConfig:

import { BemModule } from 'angular-bem';

BemModule.config({
  separators: ['__', '--', '-'], // el / mod / val separators
  modCase: 'kebab', // case of modifiers names
  ignoreValues: false // cast mod values to booleans
}); // method returns BemModule

It is recommended to set ignoreValues to true but it is set to false by default to support traditional bem-syntax.

Need to know

  • These directives don't affect scope or other directives. So you can use them at ease wherever you want.
  • You can only specify one element or block on single node. This limitation greatly simplify code of module and your app.
  • There is no way to create an element of parent block inside nested block. It's not a component-way. So please avoid it.

License

MIT © Andrey Yamanov

angular-bem's People

Contributors

baskins avatar gitter-badger avatar nicksp avatar tenphi 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

Watchers

 avatar  avatar  avatar

angular-bem's Issues

classList.add not supported on svg elements in IE

Apparently classList.add is not supported on svg elements in IE.
Reference: http://caniuse.com/#feat=classlist
This has been fixed in edge but there's apparently no work to implement this in IE 11 or below.

I started making a pull request to drop classList entirely. I see you have function for addClass for browsers that don't support classList and you have a clissListSupport check. What's the reasoning for the two sets of functions. Does classList have better performance?

I'm open to input on ways to address this issue. I'll submit a pull request. Take a look and let me know what you want to do.

Need conditional modifier support

Could we get something to where, if we have value disabled in the provider config, then the thing after the colon could be a condition to evaluate as to whether to add a modifier or not?

example <div elem="button" mod="disabled: $ctrl.isDisabled">

So button--disabled would only be applied if $ctrl.isDisabled was true.

EDIT: Ok, looking at the code, this looks like it might already be the case, but I can't tell from the docs.

support for other naming cases

snakeCase
kebabCase
camelCase

In case developer uses other approach in class naming.

It would be nice to define this behaviour in class generation function but it can slow down overall performance.

support for mixes

I'm starting to run into some structural issues that can only be handled with BEM mixes, however, there's no current support for them in Angular Bem.

For reference: https://en.bem.info/forum/4/

Basically, it's having two blocks on the same DOM node. I understand that this is inherently difficult, based on the way you have the thing set up, which is why I would suggest adding a new directive, instead of modifying the existing base.

Something like this

<input block="my-specific-form" mod="active" mix-block="my-generic-form: {mod1: true; mod2: false; mod3: true}">
   <span elem="text"></span>
</input>

And the outputted html would be

<input class="my-specific-form--active my-generic-form--mod1 my-generic-form--mod3">
  <span class="my-specific-form__text"></span>
</input>

The use cases for mixes listed on the BEM faq are as follows:

A single DOM node can represent:

  • several blocks <div class="menu head-menu"></div>
  • a block and an element of the same block <div class="menu menu__layout"></div>
  • a block and an element of another block <div class="link menu__link"></div>
  • elements of different blocks <div class="menu__item head-menu__item"></div>
  • a block with a modifier and another block <div class="menu menu_layout_horiz head-menu">
  • several different blocks with modifiers <div class="menu menu_layout_horiz head-toolbar head-toolbar_theme_black"><div>

My suggestion doesn't account for mixing elements, but that seems substantially less useful than mixing blocks. That would require some deeper thought, I suppose.

Need a way to rescope to elements to a block without actually applying the block css class.

For directives using transclusion, the block hierarchy can often be broken by the directive transcluding content, even when we still want the transcluded content to be a part of our current components scope.

Example:

<outer-component block="outer-component">
      <custom-expander block="custom-expander">
            <div elem="expanding-content">
                    I want to use the expanding functionality of my parent directive,
                    but I don't really belong to it's block. I belong to outer-component!
            </div>
      </custom-expander>
</outer-component>

Now, of course, you could rescope it like this:

<outer-component block="outer-component">
      <custom-expander block="custom-expander">
            <div block="outer-component" elem="expanding-content">
                    I want to use the expanding functionality of my parent directive,
                    but I don't really belong to it's block. I belong to outer-component!
            </div>
      </custom-expander>
</outer-component>

But now any style I applied to outer-component are applied to expanding-content as well.

Currently I use this work-around:

<outer-component block="outer-component">
      <div elem="wrapper">
          <custom-expander block="custom-expander">
                <div block="outer-component" elem="expanding-content">
                    I want to use the expanding functionality of my parent directive,
                    but I don't really belong to it's block. I belong to outer-component!
                </div>
          </custom-expander>
      </div>
</outer-component>

And leave the block element unstyled so that I can rescope to a particular block without
messing up the flow of the page, however, I think this would be much cleaner and relatively simple
to implement:

<outer-component block="outer-component">
      <custom-expander block="custom-expander">
            <div block-scope="outer-component" elem="expanding-content">
                    I want to use the expanding functionality of my parent directive, 
                    but I don't really belong to it's block. I belong to outer-component!
            </div>
      </custom-expander>
</outer-component>

If this sounds reasonable, but you're really not interested in implementing it, I'd consider submitting a pull-request. Just let me know.

Wrong class for block which is also element of parent block

Template markup:

<div block="header">
  <div block="switch-control" elem="control">
  </div>
</div>

Result markup:

<div _ngcontent-lkp-c176="" block="header" class="header">
  <div _ngcontent-lkp-c176="" block="switch-control" elem="control" class="switch-control switch-control__control">
  </div>
</div>

Expected markup:

<div _ngcontent-lkp-c176="" block="header" class="header">
  <div _ngcontent-lkp-c176="" block="switch-control" elem="control" class="switch-control header__control">
  </div>
</div>

Изменение класса из контроллера

Андрей привет отличный модуль для ускорения верстки где нет возмоности полного стека бем, подскажи есть ли возможность изменения класа из контроллера простым изменением модифиатора елемента?
Я тут сделал не большой пример о чем идет речь.... может я просто ни так что то делаю?
http://plnkr.co/edit/0IL848VCL2lGCBKngtrl?p=info

Заранее спасибо за ответ

Uncaught ReferenceError: __decorate is not defined

Here is a stack trace:

    at eval (bem.js:101)
    at Object../node_modules/angular-bem/dist/bem.js (vendor.bundle.js:47)
    at __webpack_require__ (inline.bundle.js:55)
    at eval (app.module.ts:3)
    at Object../src/app/app.module.ts (main.bundle.js:75)
    at __webpack_require__ (inline.bundle.js:55)
    at eval (main.ts:4)
    at Object../src/main.ts (main.bundle.js:135)
    at __webpack_require__ (inline.bundle.js:55)
    at Object.0 (main.bundle.js:159)

My OS and versions:

Angular CLI: 1.7.4
Node: 6.11.2
OS: darwin x64
Angular: 5.2.10
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.7.4
@angular-devkit/build-optimizer: 0.3.2
@angular-devkit/core: 0.3.2
@angular-devkit/schematics: 0.3.2
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 1.10.2
@schematics/angular: 0.3.2
@schematics/package-update: 0.3.2
typescript: 2.5.3
webpack: 3.11.0

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.