babel-plugin-transform-jsx-abem

1.2.0 • Public • Published

babel-plugin-transform-jsx-abem

Build Status Coverage Status Standard - JavaScript Style Guide npm downloads

Babel plugin for ABEM class names generation in JSX.

Install

Require it as any other babel plugin and add the abem package to your dependencies (so Webpack/Rollbar/etc. can use it in the frontend).

$ npm install babel-plugin-transform-jsx-abem --save-dev
$ npm install abem --save
{
  plugins: ['transform-jsx-abem']
}

Usage

Add ABEM properties in your tags and the plugin will generate the className for you.

The plugin will try to resolve the className during the compilation (className="block") and fallback to runtime if not possible (className={_abem("block")} - helper will be included automatically)

If the tag already have a className, then it'll be skipped.

Properties

name type
block string
elem string
mods string | array | object | expression*
mix string | array | object | expression*

* must return a string, an array or an object

Scopes

The block property creates a scope and should only be used at the top-level of the JSX tag. It will be automatically generated if it's inside a class or a function (if the class/function name is prefixed by a A, O or M, then it'll add the prefix 'a-', 'o-', or 'm-')

Examples

Input

<div block="m-main" mix="panel" mods={{ warning: true }}>
  <div elem="header" mods="header">Title</div>
  <div elem="body">Text</div>
</div>

Output

<div className="m-main -warning panel">
  <div className="m-main__header -header">Title</div>
  <div className="m-main__body">Text</div>
</div>

Input

const Message = ({ title, text }) => {
  return <div>
    <div elem="header">{title }</div>
    <div elem="body">{text}</div>
  </div>
}

Output

const Message = ({ title, text }) => {
  return <div className="message">
    <div className="message__header">{title}</div>
    <div className="message__body">{text}</div>
  </div>;
};

Input

class OMessage extends Component {
  ...
  render() {
    ...
    return <div mods={this.getMods()}>
      <div elem="header">{title}</div>
      <div elem="body">{text}</div>
    </div>
  }
}

Output

class OMessage extends Component {
  ...
  render() {
    ...
    return <div className={_abem("o-message", null, this.getMods())}>
      <div className="o-message__header">{title}</div>
      <div className="o-message__body">{text}</div>
    </div>;
  }
}

Input

function OEmailMessage ({ title, html }) {
  return <Wrapper>
    <div mods={{ disabled: true }}>
      <div elem="header">{title}</div>
      <div elem="bodyHtml">{html}</div>
    </div>
  </Wrapper>
}

Output

function OEmailMessage ({ title, html }) {
  return <Wrapper>
    <div className="o-emailMessage -disabled">
      <div className="o-emailMessage__header">{title}</div>
      <div className="o-emailMessage__bodyHtml">{html}</div>
    </div>
  </Wrapper>
}

Options

properties

Set custom naming properties. Default values:

properties: {
  block: 'block',
  element: 'elem',
  modifiers: 'mods',
  mixin: 'mix'
}

separators

Set custom abem separators. Default values:

separators: {
  element: '__',
  modifier: '-',
}

Limitations

Passing options with spread operator won't work as expected. In this example, html modifier won't be added.

const OMessage = ({ title, text, ...props }) => {
  return <div {...props}>
    <div elem="header">{title}</div>
    <div elem="body">{text}</div>
  </div>
}
 
[...]
 
const html = true
<OMessage title="Hello" text="World" mods={{ html }} />

ABEM propetrties shouldn't be passed this way anyway. Instead, you should do:

const OMessage = ({ title, text, html }) => {
  return <div mods={{ html }}>
    <div elem="header">{title}</div>
    <div elem="body">{text}</div>
  </div>
}
 
[...]
 
const html = true
<OMessage title="Hello" text="World" html={html} />

Send some love

You like this package?

Buy me a coffee

Package Sidebar

Install

npm i babel-plugin-transform-jsx-abem

Weekly Downloads

4

Version

1.2.0

License

MIT

Unpacked Size

23 kB

Total Files

11

Last publish

Collaborators

  • gtournie