Skip to content

Утилиты

Использовать утилиты не обязательно, но в некоторых случаях они упрощают жизнь. Каждая функция StyleSheet maker принимает в качестве аргумента объект с утилитами.

dash

Объединяет примитивы с помощью дефиса.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ dash }) => {
    const width = {
        none: '0',
        half: '50%',
        full: '100%'
    };
    const widthRules = Object.entries(width).reduce((acc, [key, val]) => {
        const selector = dash('w', key);
        acc[selector] = {
            width: val,
        };
        return acc;
    }, {});
    return {
        ...widthRules
    };
};

comma

Объединяет примитивы с помощью запятой.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ comma }) => {
    const fonts = ['Georgia', 'serif'];
    return {
        html: {
            fontFamily: comma(...fonts)
        }
    };
};

space

Объединяет примитивы с помощью пробела.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ space }) => {
    const borderStyle = 'solid';
    const borderWidth = {
        s: '2px',
        l: '4px'
    };
    return {
        '.container': {
            border: space(borderWidth.s, borderStyle)
        }
    };
};

range

Выполняет итерацию по последовательности чисел заданной длины.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ range }) => {
    const rules = range(5, (sz) => {
        return {
            [`.h-${sz}`]: {
                height: sz + 'rem'
            }
        };
    });
    return {
        ...rules
    };
};

each

Выполняет итерацию по парам "ключ-значение" объекта или значениям массива.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ each }) => {
    const rules = range(5, (sz) => {
        return {
            [`.h-${sz}`]: {
                height: sz + 'rem'
            }
        };
    });
    return {
        ...rules
    };
};

merge

Выполняет глубокое слияние объектов.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ merge }) => {
    const base = {
        body: {
            width: '100%'
        },
        div: {
            width: '100%',
            span: {
                width: '100%'
            }
        }
    };
    const custom = {
        body: {
            width: '100vw',
            height: '100%'
        },
        div: {
            span: {
                background: 'transparent'
            }
        }
    };
    return merge(base, custom);
};

when

Возвращает второй аргумент, если первый равен true.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ when }) => {
    const values = [1, 2, 3, 4, 5, 6];
    const rules = values.reduce((acc, value) => {
        return {
            ...acc,
            ...when(!(value % 2), {
                [`sz-${value}`]: {
                    width: value + 'rem',
                    aspectRatio: 1
                }
            })
        }
    }, {})
    return {
        ...rules
    };
};

themeVar

Формирует выражение var() с глобальными переменными темы.

Example
ts
import { TStyleSheetMaker } from 'effcss';

type TGlobalVars = {
    sz: {
        m: string;
        l: string
    }
};

export const maker: TStyleSheetMaker = ({ themeVar }) => {
    return {
        '.sz-m': {
            width: themeVar<TGlobalVars>('sz.m', '100px') // '100px' - fallback value
        }
    };
};

time

Вычисляет значение времени в зависимости от глобальной переменной времени.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ time }) => {
    return {
        '.dur-2': {
            // if global root time is 200ms (by default),
            // then result will be 400ms
            transitionDuration: time(2)
        }
    };
};

size

Вычисляет значение размера в зависимости от глобальной переменной размера.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ size }) => {
    return {
        '.w-2': {
            // if global root size is 16px (by default),
            // then result will be 32px
            width: size(2)
        }
    };
};

angle

Вычисляет значение угла в зависимости от глобальной переменной угла.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ angle }) => {
    return {
        '.w-2': {
            // if global root angle is 30deg (by default),
            // then result will be 60deg
            transform: `skew(${angle(2)})`
        }
    };
};

easing (^4.4.0)

Вычисляет значение типа <easing-function>. При вызове без аргумента возвращает глобальное значение, при вызове с аргументом - настроенное значение фнукции cubic-bezier.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ easing }) => {
    return {
        [`.cust`]: {
            transitionTimingFunction: easing({
                x1: 0.42,
                x2: 0.58
            }) // transition-timing-function:cubic-bezier(0.42,0,0.58,1)
        },
        [`.global`]: {
            transitionTimingFunction: easing() // transition-timing-function:var(--f0-easing)
        },
    };
};

bem

Формирует BEM-селектор с областью действия таблицы стилей.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export type TStyleSheet = {
    block: {
        '': {
            hidden: '';
        };
        elem: {
            sz: 's' | 'm';
        };
    };
};

export const maker: TStyleSheetMaker = ({ bem }) => {
    const block = bem<TStyleSheet>('block');
    const blockHidden = bem<TStyleSheet>('block..hidden');
    const elementSzS = bem<TStyleSheet>('block.elem.sz.s');
    const elementSzM = bem<TStyleSheet>('block.elem.sz.m');
    return {
        [block]: {
            overflow: 'hidden'
        },
        [blockHidden]: {
            visibility: 'hidden'
        },
        [elementSzS]: {
            width: '2rem'
        },
        [elementSzM]: {
            width: '5rem'
        }
    };
};

units

Группа функций CSS-units.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ units }) => {
    const { px, rem } = units;
    return {
        '.custom': {
            width: px(100),
            height: rem(1.5)
        }
    };
};

pseudo

Группа функций псевдоклассов/псевдоэлементов.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ pseudo }) => {
    const { h, aft, has, is } = pseudo;
    return {
        // .custom::after:hover
        [h(aft('.custom'))]: {
            color: 'transparent'
        },
        // .custom:hover
        ['.custom' + h]: {
            border: '2px solid gray'
        },
        // button:is(.custom):has(image)
        [has('image', is('.custom', 'button'))]: {
            cursor: 'pointer'
        }
    };
};

color

Группа функций для работы с цветом.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ units }) => {
    const { fadeout, darken } = color;
    const baseColor = 'green';
    const additionalColor = fadeOut(baseColor);
    return {
        '.custom': {
            background: additionalColor,
            color: darken(baseColor)
        }
    };
};

palette

Экземпляр класса палитры. Он позволяет использовать цвета в формате oklch с предопределенными значениями яркости, цветности и оттенка, которые берутся из переменных темы.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ palette }) => {
    // `palette.fg` возвращает цвет переднего плана, в то время как `palette.bg" возвращает цвет фона.
    // Фон и передний план имеют разные значения яркости и цветности для каждого варианта.
    // Вариантами оттенков являются `pri`, `sec`, `suc`, `inf`, `war`, `dan`.
    // Вариантами цветности являются `grey`, `pale`, `base`, `rich`
    // Вариантами яркости являются `xs`, `s`, `m`, `l`, `xl`.
    // Параметры яркости увеличиваются по мере приближения к контрасту (0 в светлом режиме и 1 в темном режиме), поэтому "xs" = .48, "xl" = 0.24 на темном фоне и "xs" = 0.78, "xl" = 0.98 на светлом фоне
    return {
        '.palette-complex': {
            color: palette.fg.gray.inf.l,
            backgroundColor: palette.bg.pale.sec.xl,
            borderColor: palette.fg.rich.xs.suc.alpha(0.75)
        }
    };
};

coef

Экземпляр класса коэффициентов. Позволяет использовать диапазоны коэффициентов с предопределенными значениями, которые берутся из переменных темы.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ coef, size }) => {
    return each(coef.$m.short, (k, v) => ({
        [`.size-` + k]: {
            width: size(v)
        }
    }));
};

at.property

Формирует правило @property для области видимости таблицы.

Example
ts
import { TStyleSheetMaker } from 'effcss';
// все имена @property не имеют никакого смысла - провайдер создаст их уникальными для каждого вызова утилиты
export const maker: TStyleSheetMaker = ({ at: { property } }) => {
    const firstProperty = property();
    const secondProperty = property({
        ini: '25px',
        inh: false,
        def: '10px' // будет использоваться в качестве резервного значения в выражении `var()`
    });
    const thirdProperty = property();
    return {
        ...firstProperty, // => @property --first-property-name {...}
        ...secondProperty,
        '.mod': firstProperty('150px'), // => '.mod': {'--first-property-name': '150px'}
        '.full': {
            ...secondProperty('100px'),
            ...thirdProperty('red'),
            aspectRatio: 1
        },
        '.cls': {
            width: firstProperty, // => width: `var(--first-property-name)`
            height: `calc(2 * ${secondProperty})` // => height: `calc(2 * var(--second-property-name,10px))`
        },
        '.cls2': {
            height: `calc(2 * ${secondProperty.fallback('35px')})`
        }
    };
};

at.keyframes

Формирует правило @keyframes для области видимости таблицы.

Example
ts
import { TStyleSheetMaker } from 'effcss';
// все имена @keyframes не имеют никакого смысла - провайдер создаст их уникальными для каждого вызова утилиты
export const maker: TStyleSheetMaker = ({ at: { keyframes } }) => {
    const widthKf = keyframes({
        from: { width: '10px' },
        to: { width: '20px' }
    });
    const heightKf = keyframes({
        from: { height: '10px' },
        to: { height: '20px' }
    });
    return {
        ...widthKf, // => `@keyframes width-kf-name`: {...}
        ...heightKf,
        '.cls1': {
            ...widthKf()
        }, // => `.cls1`: {animationName: 'width-kf-name'}
        '.cls2': {
            animation: `3s linear 1s ${heightKf}` // => animation: `3s linear 1s height-kf-name`
        },
        '.cls3': heightKf({
            dur: '300ms',
            tf: 'ease'
        }) // => `.cls3`: {animation: `300ms ease height-kf-name`}
    };
};

at.scope

Формирует правило @scope.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { scope } }) => {
    // установим корневой селектор
    const baseScope = scope.root('.base');
    // установим граничный селектор
    const limitedScope = baseScope.limit('.limit');
    return {
        // поместим правила в базовую область видимости
        ...baseScope({
            span: {
                textOverflow: 'hidden'
            }
        }),
        // поместим правила в ограниченную область видимости
        ...limitedScope({
            div: {
                width: '100%'
            }
        }),
        // поместим правила в ограниченную область видимости, исключая обе границы
        ...limitedScope.none()({
            p: {
                fontSize: '1.5rem'
            }
        }),
        // поместим правила в ограниченную область видимости, включая нижнюю границу
        ...limitedScope.low()({
            p: {
                fontSize: '2rem'
            }
        }),
        // поместим правила в ограниченную область видимости, включая обе границы
        ...limitedScope.both()({
            p: {
                fontSize: '0.5rem'
            }
        })
    };
};

at.media

Формирует правило @media.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { media } }) => {
    const firstCondition = or('width < 600px', 'width > 1000px');
    const firstQuery = media(firstCondition);
    const secondQuery = media.where(and(firstCondition, 'orientation: landscape'));
    return {
        // @media (width < 600px) or (width > 1000px) {...}
        ...firstQuery({
            '.cls': {
                width: '100%'
            }
        }),
        // @media ((width < 600px) or (width > 1000px)) and (orientation: landscape) {...}
        ...secondQuery({
            '.cls': {
                width: '50%'
            }
        })
    };
};

at.container

Формирует правило @container.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { container, $logic: {or} } }) => {
    const firstQuery = container.where(or('width < 600px', 'width > 1000px'));
    const secondQuery = container.named.where('width > 100px');
    return {
        '.container': {
            ...secondQuery // container: cust-cq-1 / normal 
        },
        // @container (width < 600px) or (width > 1000px) {...}
        ...firstQuery({
            '.cls': {
                width: '100%'
            }
        }),
        // @container cust-cq-1 (width > 100px) {...}
        ...secondQuery({
            '.cls': {
                width: '50%'
            }
        })
    };
};

at.startingStyle

Формирует правило @starting-style.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { startingStyle } }) => {
    return {
        '.target': {
            transition: 'background-color 1.5s',
            backgroundColor: 'green',
            ...startingStyle({opacity: 0})
        },
        ...startingStyle({
            '.target': {
                backgroundColor: 'transparent'
            }
        })
    };
};

at.supports

Формирует правило @supports.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { supports } }) => {
    const supportsRule = supports.where('not (text-align-last:justify)');
    return supportsRule({
        div: {
            textAlignLast: 'justify'
        }
    });
};

at.layer

Формирует правило @layer.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { layer } }) => {
    const layer1 = layer.named;
    const layer2 = layer.named;
    return {
        ...layer.list(layer1, layer2), // @layer cust-lay-1, cust-lay-2;
        ...layer1({ // @layer cust-lay-1{
            '.padding-sm': {
                padding: '0.5rem'
            }
        }),
        ...layer2({ // @layer cust-lay-2{
            '.padding-sm': {
                padding: '0.75rem'
            }
        })
    };
};

at.$logic

Набор функций для задания сложных логических условий @container и @media.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { media, $logic: {and, or, not} } }) => {
    const logic1 = and('prefers-reduced-motion: reduce', 'hover');
    const query = media.where(or(logic1, 'width > 600px'));
    return {
        ...query12({ // @media (prefers-reduced-motion: reduce) and (hover) or (width > 600px)
            '.cls': {
                maxWidth: '130px'
            }
        })
    };
};

at.$width, at.$height, at.$inline, at.$block

Набор функций для задания условий ширины/высоты/инлайнового размера/блочного размера @container и @media.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { media, $width: {between} } }) => {
    return media.where(between(30,80))({ // @media (min-width:30rem) and (max-width:80rem)
        '.cls': {
            flexShrink: 0
        }
    });
};

Опубликовано под лицензией Apache License 2.0