Reputation: 6117
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?
Upvotes: 5
Views: 2279
Reputation: 61
What I've tried in this context (note that I'm using Angular v6):
For example you are calling in app.component.html
If your app.component.css or app.component.scss contains the styling that should be applied in ,
Set the viewEncapsulation for the component to none in your app.component.ts:
import { ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
Which will allow all your styling that you have in your app.component.(s)css to flow beyond to reach the library you are using.
This quick fix is what made component styling go beyond the current component and be applied to the libraries used.
Upvotes: 1
Reputation: 2146
Try this way:
Upvotes: 2