Keep CSS in TypeScript.
Currently in a deep beta!
npm install @ngx-kit/styler --save
import { StylerModule } from '@ngx-kit/styler';
...
@NgModule({
imports: [
...
StylerModule.forRoot(),
...Use import with .forRoot() only once on the top level.
...
@Component({
...
viewProviders: [StylerComponent]
...
constructor(private styler: StylerComponent) {
this.styler.register({
wrapper: {
background: '#ffffff',
color: 'red',
},
inside: {
color: 'yellow',
fontSize: '2rem',
}
});
...<div styler="wrapper">
<div styler="inside">
</div>
</div>Just define host element:
this.styler.register({
host: {
display: 'flex',
flexDirection: 'column',
},
});this.styler.register({
wrapper: {
$nest: {
'&:hover': {
background: 'grey',
},
'& a': {
textDecoration: 'none',
},
},
},
});this.styler.register({
wrapper: {
display: 'flex',
flexDirection: 'row',
$media: [
[{maxWidth: 600}, {
flexDirection: 'column',
}],
],
},
});Define element states:
constructor(private def: StylerDefService)
...
this.styler.register({
host: {
...
},
panel: (state) => {
border: '1px solid green',
// multi-state
...this.def.pick(state.size, {
small: {
padding: 2,
},
medium: {
padding: 4,
},
large: {
padding: 8,
},
}, 'medium'),
// bool-state
...this.def.toggle(state.disabled, {
color: '#666',
background: '#999'
}),
},
...
});Set state via service for host:
this.styler.host.applyState({size: 'small'});Or set state with styler directive:
<div styler="panel" [stylerState]="{size: 'small'}"></div>Provide styler view built-it module method:
@Component({
...
viewProviders: [StylerModule.forComponent(ThisComponentStyle)],Define style injectable:
import { Injectable } from '@angular/core';
import { ComponentStyle, StylerDefService, StyleDef } from '@ngx-kit/styler';
@Injectable()
export class ThisComponentStyle implements ComponentStyle {
constructor(private def: StylerDefService) {
}
host(): StyleDef {
return {
display: 'block',
};
}
wrapper(): StyleDef {
return {
background: '#ffffff',
color: 'red',
};
}
// state handling
panel(state): StyleDef {
return {
border: '1px solid green',
// multi-state
...this.def.pick(state.size, {
small: {
padding: 2,
},
medium: {
padding: 4,
},
large: {
padding: 8,
},
}, 'medium'),
// bool-state
...this.def.toggle(state.disabled, {
color: '#666',
background: '#999'
}),
};
};
}Styles deep-merged from left to right.
this.styler.register([
{
host: {
background: '#ffffff',
color: 'yellow'
},
},
{
host: {
color: 'red',
fontSize: '1.1rem',
},
},
]);Similar to:
this.styler.register([
{
host: {
background: '#ffffff',
color: 'red',
fontSize: '1.1rem',
},
},
]);Provide few separated styles to component:
viewProviders: [
StylerModule.forComponent(LayoutStyle),
StylerModule.forComponent(ThisComponentStyle),
],TBD
padding: [10, 20] => padding: '10px 20px'padding: {top: 10, left: 30} => paddingTop: '10px', paddingLeft: '30px'margin: [10, 20, 30] => padding: '10px 20px 30px'border: [1, 'solid', 'blue'] => border: '1px solid blue'
TBD
constructor(private styler: StylerComponent) {
this.styler.register({
host: {
animationDuration: '1s',
animationName: this.styler.keyframes({
'0%': {
transform: 'rotate(0deg)',
},
'100%': {
transform: 'rotate(360deg)',
},
}),
animationTimingFunction: 'linear',
animationIterationCount: 'infinite',
},
});
}Styler can add classes to elements. Class attribute based on component name (should be setted), element name and element state.
Provide BemClassGenStrategy:
providers: [
{
provide: ClassGenStategy,
useClass: BemClassGenStrategy,
},
],Set component name:
constructor(private styler: StylerComponent) {
this.styler.classPrefix = 'component-name';
}defPick(state: string, styles: StyleDef, default?: string)- returns styles[state|default]defToggle(state: boolean, styles: StyleDef, falseStyles?: StyleDef)- returns styles if state is truedefMerge(styles: StyleDef[])- js deepMerge, needed if states have $nest props
Helpers for color manipulating.
...
background: darken(0.2, someColorVar),adjustHuecomplementdarkendesaturategrayscalehslhslainvertlightenmixopacifyrgbrgbasaturatesetHuesetLightnesssetSaturationshadetinttoColorStringtransparentize