General problem
I want to style reusable Angular components to match the style of the specific client project.
I maintain the reusable components in a separate project and generate an npm package out of it. That package is published to a private NPM repository (Sinopia) and then installed into multiple client projects.
The general styling is - of course - specific to the component, but color and font - for example - should match the client project.
How can I best apply styles such as color and font, defined in the client project, to the reusable components?
Current implementation
At the moment I am using https://github.com/jvandemo/generator-angular2-library to scaffold the reusable component library. It generates some Gulp tasks which let me build a dist version. Publishing that dist and using the published package works just fine but the built code makes it hard for me to figure out a working theming strategy.
The Gulp build task will inline both the HTML and CSS resources in the final code.
A sample Component
@Component({
selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.scss'],
})
export class MessagesComponent {
constructor(private messagesService: MessagesService) {
}
}
Gets 'flattened' during build to
var MessagesComponent = (function () {
/**
* @param {?} messagesService
*/
function MessagesComponent(messagesService) {
this.messagesService = messagesService;
}
...
return MessagesComponent;
}());
MessagesComponent.decorators = [
{ type: Component, args: [{
selector: 'app-messages',
template: "<div *ngFor=\"let message of messages\"> <div class=\"message {{message.type}}-message\"> {{message.message}} <i class=\"fa fa-remove\" (click)=\"removeMessage(message)\">x</i> </div> </div>",
styles: [".message { line-height: 36px; padding: 4px 20px; margin: 2px; position: relative; } .message .fa-remove { position: absolute; right: 20px; cursor: pointer; } .info-message { background-color: #005CAB; color: white; } .error-message { background-color: red; color: white; } "],
},] },
];
The MessagesComponent.decorators now contains the styling in-line.
Concrete questions
Is using the https://github.com/jvandemo/generator-angular2-library generator a good choice for creating component libraries? Or are there better ways?
How do I have to 'override' the color and font styling of my reusable components?
I had hoped to be able to use scss variables in the component library which could be (re-)defined in the client project. Something like
Reusable component messages.component.scss:
.info-message {
background-color: $primary-color;
color: white;
}
Client project /style/_style-vars.scss:
$primary-color: #005CAB;
Any ideas on how to tackle this?
FOLLOW UP
I got one step further:
I now use CSS3 variables and that gets me almost there:
In the reusable component, I define my SCSS variables as follows:
$primary-color: var(--ang-ux-primary-color, #5FB0FD);
.ang-ux-primary {
background-color: $primary-color;
}
and in my client project I define the styles like this (style.scss):
// styling reusable components
:root {
--ang-ux-primary-color: #666666;
}
This works, but it seems I cannot use SCSS variables in the definition of my CSS variable:
$primary-color: #666666;
// styling reusable components
:root {
--ang-ux-primary-color: $primary-color;
}
results in an empty $primary-color in the reusable component. I opened a separate thread for this issue: Using SCSS variable inside CSS3 variable definition not working?