2 дня назад
История
README.md
EffCSS
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
- Docs
- SourceCraft
- GitHub
- NPM
- vite-plugin-effcss - CSR tool injecting generated CSS into HTML. It allows to eliminate FOUC and speed up the first rendering due to style hydration just like for SSR/SSG.
Examples
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 {
className, classNames,
attribute, attributes,
variable, variables,
animation, animations
} from 'effcss';
// you can create independent rules
// returns classname string
const bgCls = className({
background: 'white',
'&:hover': {
borderRadius: '1em'
}
});
// returns object with data-attribute
const fontAttr = attribute({
fontWeight: 'bold'
});
// single global variable
// shadowColor() => var(--unique-variable-name)
const shadowColor = variable('#58666d');
// multiple global variables
// widthVars.s() => var(--unique-variable-name)
const widthVars = variables({
s: '12px',
m: '16px',
l: '20px'
});
// single global animation
// spinAnimation = unique-animation-name
const spinAnimation = animation({
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
});
// also you can create isolated stylesheets
// 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
// creates a stylesheet with attribute selectors
// styleComponents({rounded: true}) => {[data-unique-key]: 'some values'}
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('cyan')
},
'@media(prefers-color-scheme: dark)': {
[card + ':hover']: {
filter: `drop-shadow(0 0 2em #ffffff)`
}
},
// ... and so on
};
});
// creates a stylesheet with class selectors
// styleUtils({w: 's'}) => 'string with classnames'
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.m()
},
[w.l]: {
width: widthVars.l()
},
// ... 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}>
<p {...fontAttr} className={bgCls}>...</p>
</div>
};
That’s all. Enjoy simplicity.
Описание
Self-confident CSS-in-JS
Конвейеры
0
успешных
0
с ошибкой