Skip to content

Bike-JS/posthtml-bike

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Oleksandr KhyrenkoOleksandr Khyrenko
Oleksandr Khyrenko
and
Oleksandr Khyrenko
Oct 16, 2017
aface83 · Oct 16, 2017

History

14 Commits
Oct 15, 2017
Oct 15, 2017
Oct 15, 2017
Oct 2, 2017
Oct 2, 2017
Oct 1, 2017
Oct 1, 2017
Oct 1, 2017
Oct 16, 2017
Oct 15, 2017

Repository files navigation

Bike plugin

NPM Build

This plugin transform custom tags to BEM-like HTML

Install

npm i -D posthtml-bike

Usage

const { readFileSync } = require('fs');
const posthtml = require('posthtml');
const bike = require('posthtml-bike');

const html = readFileSync('index.html');

posthtml([ bike() ]).process(html).then((result) => console.log(result.html));

Example

Default

<component name="example">
    <header></header>
    <main></main>
    <footer></footer>
</component>

Transformed to:

<section class="example">
    <header class="example__header"></header>
    <article class="example__main"></article>
    <footer class="example__footer"></footer>
</section>

With mods

<component name="example" mod-theme="dark" mod-active>
    <header></header>
    <main mod-hidden></main>
    <footer></footer>
</component>

Transformed to:

<section class="example example_theme_dark example_active">
    <header class="example__header"></header>
    <article class="example__main example__main_hidden"></article>
    <footer class="example__footer"></footer>
</section>

With tag attr

<component name="button" tag="button">
    <main tag="span"></main>
</component>

Transformed to:

<button class="button">
    <span class="button__main"></span>
</button>

Options

{
    /**
    * Component root tag name
    * @default
    */
    tag: 'component',
    
    /**
    * Default component root HTML tag
    * @default
    */
    replaceComponentTag: 'section',
    
    /**
    * Default element HTML tag
    * @default
    */
    replaceElemTag: 'div',
    
    /**
    * Skip HTML tags list
    * @default
    */
    skipTags: ['b', 'strong', 'i', 'span', 'div', 'section'],
    
    /**
    * These elements will be replaced to defined HTML tags
    * @default
    */
    autoTags: {
        header: 'header',
        main: 'article',
        footer: 'footer',
        title: 'h2',
        list: 'ul',
        'list-item': 'li',
        link: 'a'
    },
    
    /**
    * Config for generated custom element name by HTML tag
    * @default
    */
    autoClasses: {
      li: () => {}, // Generate element name for `li` tag
      a: () => {}, // Generate element name for `a` tag
    },
   
    /**
    * Config for process styles in component 
    * @default
    */
    postcss: false,
}

Use with postcss-bike

Example for use with postcss-bike

<style type="text/postcss">
    @component app {
      display: flex;
      flex-flow: column nowrap;
      justify-content: space-between;
    
      @elem header {
        flex: 0 0 40px;
      }
    }
</style>
<component name="app" mod-theme="dark"></component>

Transformed to:

<style type="text/css">
    .app {
      display: flex;
      flex-flow: column nowrap;
      justify-content: space-between;
    }
    .app__header {
      flex: 0 0 40px;
    }
</style>
<section class="app app_theme_dark"></section>

Options

{
  postcss: {
    match: 'text/postcss', // Match `style` tag by type
    plugins: [], // Postcss plugins
    process: (css, node) => { // Save processed css function
      node.attrs.type = 'text/css';
      node.content = ['\n', css];
      return node;
    }
  }
}

Example for save all components styles in one file:

import { appendFileSync } from 'fs';
import gulp from 'gulp';
import gulpPosthtml from 'gulp-posthtml';
import gulpClean from 'gulp-clean';

import postCssBike from 'postcss-bike';

gulp.task('clean', () => (
  gulp.src('examples/dist/components.css').pipe(gulpClean())
));

gulp.task('html', ['clean'], () => {
  gulp.src('/components/*.html')
    .pipe(gulpPosthtml([
      bike({
        postcss: {
          match: 'text/postcss',
          plugins: [ postCssBike() ],
          appendTo: '/dist/components.css',
          process(css, node, options) {
            appendFileSync(options.postcss.appendTo, css);
            node.tag = false;
            node.content = [''];
            return node;
          }
        },
      }),
    ]))
    .pipe(gulp.dest('/dist'))
});

Auto classes

Example config for li tag, result class - ${componentName}__${parentElementName}-item

{
  li: ({ component }) => (`${component.elem}-item`)
}
<component name="example">
    <list>
      <li>Item 1</li>
      <li>Item 2</li>
    </list>
</component>

Transformed to:

<section class="example">
    <ul class="example__list">
      <li class="example__list-item">Item 1</li>
      <li class="example__list-item">Item 2</li>
    </ul>
</section>

Auto class function args:

  • parent - Parent node object
    • component - { name, elem, parent } Custom item with plugin info
  • options - Plugin options

For example:

import bike, { AUTO_TAGS, AUTO_CLASSES } from 'posthtml-bike';

const options = {
  autoTags: {
    ...AUTO_TAGS,
    'my-tag': 'p'
  },
  autoClasses: {
    ...AUTO_CLASSES,
    i: ({ component }) => (`${component.elem}-icon`)
  }
}