nean

js framework for neat and lean components

Usage no npm install needed!

<script type="module">
  import nean from 'https://cdn.skypack.dev/nean';
</script>

README

nean

npm version types size coverage vulnerabilities dependencies devDependencies License

js framework for neat and lean components

Installation

$ npm i nean

Usage

import react, {Fragment} from 'react';
import nean from 'nean';

const Button = nean({
    type: 'button',
    className: 'btn',
    style: ({rounded, primary}) => ({
        'btn--rounded': rounded,
        'btn--primary': primary,
    }),
    extend: ({md}) => ({
        'data-size': md,
    }),
    render: ({children, prefix}) => (
        <Fragment>
            {prefix}{children}
        </Fragment>
    ),
});

<Button
    prefix="foo"
    md={2}
    rounded
    primary
>
    bar
</Button>

// ===

<button 
    className="btn btn--rounded btn--primary" 
    data-size="2"
>
    foobar
</button>

API

Library

nean(config: Factory)

Factory

type default description
type string type of element e.g. span, div, button
className string? base className of the element
style Function? props provides an object with all consumed props for translation
extend Function? props allows extending or aliasing of props
render Function? {children} overwrite of default render function
type

Pass type button to create a plain button component.

import nean from 'nean';

const Button = nean({
    type: 'button',
});

className

By adding className, the component receives a base className.

import nean from 'nean';

const Button = nean({
    type: 'button',
    className: 'btn',
});

style(props)

To bind props to css classNames of the chosen framework, return an object with the new classNames with props as values. style is powered by the @thomann/classnames library and recursively evaluates every property/value by its truthiness and keeps its key.

import nean from 'nean';

const Button = nean({
    type: 'button',
    style: (({primary}) => ({
        'btn-primary': primary
    })),
});

extend(props)

Sometimes, css frameworks have components which rely on data attributes. These can be set via extend. This function allows the extension of the original props.

import nean from 'nean';

const Button = nean({
    type: 'button',
    extend: (({badges}) => ({
        'data-badges': badges
    })),
});

render(props)

It's possible to overwrite the render output via the render function. This allows to wrap your components children with other components.

import React from 'react';
import nean from 'nean';

const Link = nean({
    type: 'a',
    render: (({children}) => (
        <Button>
            {children}
        </Button>
    )),
});

interceptHook(use[, destructive = false])

nean components accept custom tailored hooks which can be addressed individually later on render.

  • use (array of hooks)
  • optional destructive (shift used hook from array of hooks)

createHook(name, hook)

hooks can extend a component via provided props.

  • name (name of the hook)
  • hook (hook function)
import React from 'react';
import nean, {interceptHook, createHook} from 'nean';

// definition
const Button = nean({
    render: ({children, use}) => {
        const icon = interceptHook(use)('icon');

        return (
            <Fragment>
                {icon('left')} {children} {icon('right')}
            </Fragment>
        );
    },
});

const useIcon = (type, side = 'left') => createHook('icon', (check) => {
    if (check !== side) {
        return null;
    }

    return (
        <Icon type={type}/>
    );
});

// usage
const App = () => (
    <Button use={[
        useIcon('hamburger', 'right')
    ]}>
        hello world
    </Button>
)

useType(type)

It's possible to overwrite the component type on runtime via the custom useType hook.

  • type (type or tag name of the element)
import React from 'react';
import nean, {useType} from 'nean';

const App = () => (
    <Button use={[useType('span')]}>
        hello world, I am a span
    </Button>
);

Licence

MIT License, see LICENSE