README.md

effcss

EffCSS

license npm latest package minified size minzipped size install size

EffCSS is a self-confident CSS-in-JS library based only on the browser APIs. Use the full power of JS and TS to create styles.

Some features

  • zero-dependency,
  • framework agnostic,
  • selectors isolation and minification out of the box,
  • flexible stylesheets types that can suggest available selectors (BEM and Atomic CSS compatible),
  • compatible with any rendering (CSR, SSR, SSG).

Links

Devtools

Examples

Installation

Type in your terminal:

# npm
npm i effcss

# pnpm
pnpm add effcss

# yarn
yarn add effcss

Quick start

Just call useStyleProvider in your code:

main.js

import { useStyleProvider } from "effcss";
import { App } from "./App.tsx";

const styleProvider = useStyleProvider({
    attrs: {
        min: true // to create minified selectors
    }
});

const root = createRoot(document.getElementById("root"));
root.render(<App styleProvider={styleProvider} />);

Each CSS stylesheet corresponds to a single Stylesheet maker. Stylesheet maker is a JS function that should return object or string with style rules:

maker.ts

import { TStyleSheetMaker } from 'effcss';

// you can describe your styles
// so that other people can use them via TypeScript generics
export type TMyMaker = {
    /**
     * Font-size utility
     */
    fsz: 16 | 20 | 24;
    /**
     * Card scope
     */
    card: {
        /**
         * Card border radius
         */
        rounded: '';
        /**
         * Card height
         */
        h: 'full' | 'half';
    };
}

export const myMaker: TStyleSheetMaker = ({
    select, merge,
    pseudo: {h},
    at: { keyframes, property },
    theme: { neutral, size },
    units: { px }
}) = {
    // specify selector variants via generic
    const selector = select<TCardMaker>;
    // create property with unique identifier
    const widthProperty = property({
        ini: px(200),
        inh: false,
        def: px(200) // will be used as fallback value in `var()` expression
    });
    // create keyframes with unique identifier
    const spin = keyframes({
        from: {
            transform: 'rotate(0deg)',
        },
        to: {
            transform: 'rotate(360deg)',
        },
    });
    // deeply merge objects
    const cardLogoStyles = merge({
        width: widthProperty,
        animation: `20s linear infinite ${spin}`,
        ...h({
            filter: "drop-shadow(0 0 2em #61dafbaa)",
        })
    }, {
        border: 'none',
        background: neutral,
        aspectRatio: 1,
        ...h({
            opacity: 0.5
        })
    });
    return {
        // add @property rule
        ...sizeProperty,
        // add @keyframes rule
        ...spin,
        // add rules according to the TMyMaker contract
        [selector('fsz:16')]: {
            // rule content
        },
        [selector('card')]: {
            // rule content
        },
        [selector('card.rounded:')]: {
            // rule content
        },
        [selector('card.h:full')]: {
            // rule content
        },
        // ... and so on
    };
};

To use Stylesheet maker just pass it to cx (creates classnames string) or dx (creates data attributes object) methods of Style provider:

App.tsx

import { useRef } from 'react';
import { useStyleProvider } from 'effcss';
import type { TMyMaker } from './maker';
import { myMaker } from './maker';

export const App = (props: {
    styleProvider: IStyleProvider;
}) => {
    const stylesRef = useRef();
    // put it inside ref to avoid recalculations
    if (!stylesRef.current) {
        // thanks to the TMyMaker contract type,
        // you don't need to look at the implementation - just pass the necessary selectors
        stylesRef.current = {
            // you can apply list of selectors
            card: styleProvider.dx<TMyMaker>(myMaker, ['card.h:full', 'fsz:16']),
            // or you can apply object with selectors
            another: styleProvider.dx<TMyMaker>(myMaker, {
                fsz: 16,
                card: {
                    h: 'full'
                }
            })
        };
    }
    const styles = stylesRef.current;
    // just apply attributes to appropriate elements
    return (
        <div {...styles.card}>
            <div {...styles.another}>...</div>
        </div>
    );
};

That’s all. Enjoy simplicity.

Описание
Self-confident CSS-in-JS
Конвейеры
0 успешных
0 с ошибкой
Разработчики