1.0.0 • Published 6 years ago

gulp-typed-markup v1.0.0

Weekly downloads
1
License
MIT
Repository
github
Last release
6 years ago

gulp-typed-markup

This Gulp plugin takes CSS sources and generates Typescript files containing corresponding React element factories.

If you have the following element definition in CSS

/* Article.css */
.Article__caption {
    font-size: 28px;
}

the plugin will generate appropriate factory with binded CSS classes:

/* ArticleMarkup.ts */
import * as Markup from 'react-typed-markup';
declare var require: any; require('./Article.css');

export var caption: Markup.TagDIV<null> = Markup.bind(
    'div', 'Article', 'caption'
);

So, exported element factory can be used in React component's render code:

/* Article.ts */
import * as React from 'react';
import * as ArticleMarkup from './path-to-generated/ArticleMarkup';

export class Article extends React.Component<{}, {}> {
    render() {
        return ArticleMarkup.caption('Hello');
    }
}

No need to mess with string fragments to format CSS classes anymore. Just use autogenerated strictly typed factory functions.

Installation

$ npm install --save-dev gulp-typed-markup

Note that genearted markup modules also require react-typed-markup helper module. It exposes generic Typescirpt interfaces for element factories and contains wrapper function that invokes React.createElement under the hood. So install it too:

$ npm install --save react-typed-markup

BEM naming

We assume that you use BEM naming convention for CSS class names. But there is one exception: block is just a namespace for related elements, it must not contain any style props directly.

Instead of this:

/* wrong */
.Article {
    border: solid 2px;
}

always wrap block-level styles in a separated element:

/* ok */
.Article__article {
    border: solid 2px;
}

Second constraint: don't use dashes - in names, prefer camelCase style for Javascript compartibility.

Other things are the same, including, of course, modifiers.

Modifiers

Let's extend previously declared caption element with modifiers

.Article__caption {
    font-size: 28px;
}
.Article__caption_smallCaps {
    font-variant-caps: small-caps;
}
.Article__caption_type_info {
    color: blue;
}
.Article__caption_type_warning {
    color: red;
}

Generated Typescript fragment now looks like this

export var caption: Markup.TagDIV<CaptionMods> = Markup.bind(
    'div', 'Article', 'caption'
);
export type CaptionMods = {
    smallCaps?: boolean;
    type?: 'info' | 'warning';
}

Now modifiers can be used in your code

ArticleMarkup.caption({mods: {smallCaps: true, type: 'info'}}, 'Hello')

Passing React props to elements

It is also possible to pass regular React props within the first argrument:

ArticleMarkup.caption(
    {
        key: 42,
        onClick: () => (),
        mods: {smallCaps: true, type: 'info'}
    },
    'Hello'
)

Specifying tag name

Default generated tag is div. Just write specific tag name in css selector

h2.Article__caption {
    font-size: 28px;
}

Use empty rule, if you don't want to affect selector priority

h2.Article__caption {
}
.Article__caption {
    font-size: 28px;
}