Skip to content

Utilidades

No es necesario usar utilidades, pero en algunos casos facilitan el trabajo. Cada función StyleSheet maker recibe como argumento un objeto con utilidades.

dash

Combina primitivas usando un guion.

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

Combina primitivas usando una coma.

Example
ts
import { TStyleSheetMaker } from 'effcss';

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

space

Combina primitivas utilizando el espacio.

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

Itera sobre una secuencia de números de una longitud específica.

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

Itera sobre los pares clave-valor de un objeto o los valores de una matriz.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ each }) => {
    const rules = each(
        {
            '.sz-1': '1rem',
            '.sz-2': '2rem',
            '.sz-3': '3rem',
            '.sz-4': '4rem',
            '.sz-5': '5rem'
        },
        (k, v) => {
            return {
                [k]: {
                    width: v
                }
            };
        }
    );
    return rules;
};

merge

Realiza una fusión profunda de objetos.

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

Devuelve el segundo argumento si el primero es verdadero; de lo contrario, devuelve un objeto vacío.

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
    };
};

select (^4.6.0)

Genera un selector único con el prefijo de esta hoja de estilos.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export type TCustomStyles = {
    w: 's' | 'm';
    full: '';
    rad: 12 | 16;
    header: Record<string, never>;
    footer: {
        empty: '';
        lh: 24 | 28;
        left: {
            ext: Record<string, never>;
        };
        right: {
            full: '';
        }
    };
};

export const maker: TStyleSheetMaker = ({select}) => {
    const selector = select<TCustomStyles>;
    return {
        [selector('w:s')]: {
            width: '12px'
        },
        [selector('header')]: {
            order: 1
        },
        [selector('footer.empty:')]: {
            display: 'none'
        }
    };
};

theme (^4.12.0)

Un conjunto de utilidades para recuperar el valor de las variables de tema CSS:

Example
ts
import { TStyleSheetMaker } from 'effcss';

type TMakerTunings = {
    size: string;
    card: {
        color: string;
    }
};

export const maker: TStyleSheetMaker = ({ theme }) => {
    const {
        size, space, angle, radius,
        time, easing, neutral,
        color, contrast, variable, tuning,
        sans, serif, mono
    } = theme;
    // only tuning variables are available to external code
    // so they can configure the stylesheet from the outside 
    const tune = tuning<TMakerTunings>; // ^4.13.0
    return {
        '.base': {
            background: neutral, // var(--f-neutral);
            borderColor: contrast, // var(--f-contrast);
            color, // var(--f-color);
            // measurable variables add units automatically
            width: size, // calc(var(--f-size) * 1px);
            padding: space, // calc(var(--f-space) * 1px);
            transform: `skew(${angle})`, // skew(calc(var(--f-angle) * 1deg));
            transitionDuration: time, // calc(var(--f-time) * 1ms);
            transitionTimingFunction: easing, // var(--f-easing);
            borderRadius: radius, // var(--f-radius);
            fontFamily: sans // var(--f-sans);
        },
        '.scalable': {
            // the second argument of `variable` is fallback value
            opacity: variable('opacity.main', 0.5), // var(--f-opacity-main,0.5);
            // measurable variables are scalable
            width: size(10), // calc(var(--f-size) * 10px);
            padding: space(2), // calc(var(--f-space) * 2px);
            transform: `skew(${angle(2)})`, // skew(calc(var(--f-angle) * 2deg));
            transitionDuration: time(1.5),
            fontFamily: serif // var(--f-serif);
        },
        '.indexed': {
            // this is how you can access array values
            // with zero index value as fallback
            background: neutral[2],
            borderColor: contrast[5],
            color: color[3], // var(--f-color-3,var(--f-color));
            width: size[5], // calc(var(--f-size-5,var(--f-size)) * 1px);
            padding: space[2], // calc(var(--f-space-2,var(--f-space)) * 1px);
            transform: `skew(${angle[1]})`,
            transitionDuration: time[8],
            transitionTimingFunction: easing[2],
            fontFamily: mono // var(--f-mono);
        },
        '.scalable-indexed': {
            opacity: variable('opacity.main.2', variable('opacity.main', 1)), // var(--f-opacity-main-2,var(--f-opacity-main,1));
            // you can also scale indexed values
            width: size[5](10), // calc(var(--f-size-5,var(--f-size)) * 10px);
            padding: space[2](3), // calc(var(--f-space-2,var(--f-space)) * 3px);
            transform: `skew(${angle[1](5)})`, // skew(calc(var(--f-angle-1,var(--f-angle)) * 5deg));
            transitionDuration: time[8](3) // calc(var(--f-time-8,var(--f-time)) * 3ms);
        },
        '.with-tuning': {
            background: tune('card.color', 'aqua'), // background:var(--f1-card-color,aqua);
            width: tune('size', '16px') // width: var(--f1-size,16px);
        }
    };
};

units

Grupo de funciones de unidades CSS.

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

Grupo de funciones de pseudoclase/pseudoelemento.

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'
        },
        // you can pass styles as arg
        '.custom': {
            // &:hover {...}
            ...h({
                background: 'white'
            })
        },
        // button:is(.custom):has(image)
        [has('image', is('.custom', 'button'))]: {
            cursor: 'pointer'
        },
        // you can pass styles as arg
        button: {
            ...is('.custom', {
                ...has('image', {
                    cursor: 'pointer'
                })
            })
        } // -> button{&:is(.custom){&:has(image){cursor:pointer;}}}
    };
};

color

Un conjunto de funciones para trabajar con el 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

Una instancia de la clase paleta. Permite usar colores en formato oklch con valores predefinidos de brillo, cromaticidad y tono que se toman de las variables del tema.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ palette }) => {
    // `palette.fg` returns the foreground color, while `palette.bg" returns the background color.
    // The background and foreground have different brightness and chromaticity values for each option.
    // The options for shades are `pri`, `sec`, `suc`, `inf`, `war`, `dan`.
    // The options for chromaticity are `grey`, `pale`, `base`, `rich`
    // The options for brightness are `xs`, `s`, `m`, `l`, `xl`.
    // The brightness settings increase as you approach the contrast (0 in light mode and 1 in dark mode), so "xs" = .48, "xl" = 0.24 on a dark background, and "xs" = 0.78, "xl" = 0.98 on a light background
    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

Una instancia de la clase de coeficiente. Permite utilizar rangos de coeficientes con valores predefinidos que se obtienen de variables temáticas.

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

Crea una regla @property con ámbito definido.

Example
ts
import { TStyleSheetMaker } from 'effcss';
// all the @property names don't make any sense - the provider will create them unique for each utility call
export const maker: TStyleSheetMaker = ({ at: { property } }) => {
    const firstProperty = property();
    const secondProperty = property({
        ini: '25px',
        inh: false,
        def: '10px' // will be used as reserve value in `var()` expression
    });
    const thirdProperty = property();
    // you can create a non-inherited variable by passing only the default value
    const fourthProperty = property('20px');
    return {
        ...firstProperty, // => @property --first-property-name {...}
        ...secondProperty,
        ...fourthProperty,
        '.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')})`,
            width: fourthProperty
        }
    };
};

at.keyframes

Crea una regla @keyframes con ámbito definido.

Example
ts
import { TStyleSheetMaker } from 'effcss';
// all the @keyframes names don't make any sense - the provider will create them unique for each utility call
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

Crea una regla @scope.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { scope } }) => {
    // set root selector
    const baseScope = scope.root('.base');
    // set limit selector
    const limitedScope = baseScope.limit('.limit');
    return {
        // put rules in base scope
        ...baseScope({
            span: {
                textOverflow: 'hidden'
            }
        }),
        // let's put the rules in a limited field of view
        ...limitedScope({
            div: {
                width: '100%'
            }
        }),
        // let's put the rules in a limited area of visibility, excluding both borders
        ...limitedScope.none()({
            p: {
                fontSize: '1.5rem'
            }
        }),
        // put rules in limited scope including low bound
        ...limitedScope.low()({
            p: {
                fontSize: '2rem'
            }
        }),
        // put rules in limited scope including both bounds
        ...limitedScope.both()({
            p: {
                fontSize: '0.5rem'
            }
        })
    };
};

at.media

Crea la regla @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

Crea la regla @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

Crea una regla @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

Crea la regla @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

Crea la regla @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

Un conjunto de funciones para especificar condiciones lógicas complejas utilizando @container y @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

Un conjunto de funciones para crear las condiciones de ancho/alto/tamaño en línea/tamaño de bloque de @container y @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
        }
    });
};

bem (deprecated)

Esta utilidad ha quedado obsoleta y se eliminará en la próxima versión principal. Utilice la utilidad select en su lugar.

Resuelve el selector BEM con ámbito.

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'
        }
    };
};

themeVar (deprecated)

Esta utilidad ha quedado obsoleta y se eliminará en la próxima versión principal. Para obtener el valor de una variable, utilice la utilidad theme.variable.

Crea una expresión var() con variables de tema globales.

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 (deprecated)

Esta utilidad ha quedado obsoleta y se eliminará en la próxima versión principal. Para obtener el valor de esta variable, utilice la utilidad theme.time.

Calcula el valor del tiempo en función de la variable global 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 (deprecated)

Esta utilidad ha quedado obsoleta y se eliminará en la próxima versión principal. Para obtener el valor de esta variable, utilice la utilidad theme.size.

Calcula el valor del tamaño en función de la variable global 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 (deprecated)

Esta utilidad ha quedado obsoleta y se eliminará en la próxima versión principal. Para obtener el valor de esta variable, utilice la utilidad theme.angle.

Calcula el valor del ángulo en función de la variable global 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) (deprecated)

Esta utilidad ha quedado obsoleta y se eliminará en la próxima versión principal. Para obtener el valor de esta variable, utilice la utilidad theme.easing.

Calcula un valor de tipo <función de suavizado>. Si se llama sin argumentos, devuelve el valor global; si se llama con argumentos, devuelve el valor configurado de la función 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(--f-easing)
        },
    };
};

Publicado bajo la Licencia Apache 2.0