README.md

effcss

EffCSS

license npm latest package minified size minzipped size install size

EffCSS is a self-confident CSS-in-TS 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,
  • TypeScript contract-based autocompletion of stylesheet selectors,
  • compatible with any rendering (CSR, SSR, SSG).

Links

Installation

Type in your terminal:

# npm
npm i effcss

# pnpm
pnpm add effcss

# yarn
yarn add effcss

Usage

Just declare stylesheet contract, implement it and apply ready selectors:

App.tsx

import {
    classNames, attributes,
    variable, variables,
    animation, animations
} from 'effcss';


// 1. declare

/**
 * Components stylesheet
 */
type Components = {
    /**
     * Is rounded
     */
    rounded: true;
    /**
     * Height
     */
    h: 'full' | 'half';
    /**
     * Card
     */
    card: {
        /**
         * Card background
         */
        bg: 'primary' | 'secondary';
        /**
         * Is card disabled
         */
        disabled: boolean;
        
    };
    /**
     * Spinner component
     */
    spinner: {};
};

/**
 * Utils stylesheet
 */
type Utils = {
    /**
     * Width
     */
    w: 's' | 'm' | 'l';
    /**
     * Spacing
     */
    spacing: 0 | 1 | 2;
    /**
     * Blink animation
     */
    blink: true;
};

// 2. implement

// single global variable
const shadowColor = variable('#58666d');

// multiple global variables
const widthVars = variables({
    s: '12px',
    m: '16px',
    l: '20px'
});

// single global animation
const spinAnimation = animation({
    from: {
        transform: 'rotate(0deg)',
    },
    to: {
        transform: 'rotate(360deg)',
    },
});

// creates a stylesheet with attribute selectors
const styleComponents = attributes<Components>((selectors) => {
    const { rounded, card, spinner } = selectors;

    // multiple local variables
    const colors = variables({
        primary: {
            inherits: false,
            initialValue: '#2192a7'
        },
        secondary: {
            inherits: false,
            initialValue: '#425158'
        }
    });
   
    return {
        [rounded.true]: {
            borderRadius: '50%'
        },
        [spinner]: {
            animation: `${spinAnimation} infinite 6s linear`,
        },
        [card]: {
            display: 'flex',
            justifyContent: 'center',
            ':hover': {
                filter: `drop-shadow(0 0 2em ${shadowColor()})`
            }
        },
        [card.bg.primary]: {
            background: colors.primary()
        },
        [card.bg.secondary]: {
            // with fallback value
            background: colors.secondary('')
        },
        '@media(prefers-color-scheme: dark)': {
            [card + ':hover']: {
                filter: `drop-shadow(0 0 2em #ffffff)`
            }
        },
        // ... and so on
    };
});

// creates a stylesheet with class selectors
const styleUtils = classNames<Utils>((selectors) => {
    const { w, spacing, blink } = selectors;

    // local animations
    const blinkAnimations = animations({
        simple: {
            '50%': {
                visibility: 'hidden'
            }
        },
        smooth: {
            '0%': {
                opacity: 1
            },
            '50%': {
                opacity: 0
            },
            '100%': {
                opacity: 1
            }
        }
    });

    return {
        [blink.true]: {
            animation: `${blinkAnimations.smooth} 2s infinite`
        },
        [w.s]: {
            width: widthVars.s()
        },
        [w.m]: {
            width: widthVars.s()
        },
        [w.l]: {
            width: widthVars.s()
        },
        // ... and so on
    };
});

// 3. apply

// returns an object as it is created using `attributes`
const cardAttrs = styleComponents({
    card: {
        bg: 'primary',
        disabled: true
    }
});

// returns a string as it is created using `classNames`
const utilsCls = styleUtils({
    w: 'm'
})

export const App = () => {
    return <div {...cardAttrs} className={utilsCls}>
        ...
    </div>
};

That's all. Enjoy simplicity.

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