Dynamic CSS loading - css

i have 2 styles
Style1.scss and Style2.scss
Style1
#import "~bootstrap/dist/css/bootstrap.css";
#import "assets/css/aos/styles.css";
#import "assets/css/aos/aos.css";
#import "assets/css/layout.css";
#import "assets/css/theme-brand-1.css";
some css files and one theme file
Style2
some css files and one theme file like style 1
The theme file is different.
Based on the url param for example http:\\localhost:4000\login?section=x
i need to load style 1 and for other http:\\localhost:4000\login?section=y need to load style2.
Method-1 - not worked
Component
this._activatedRoute.queryParams.subscribe(params => {
this.param1 = params.brand;
switch(params.brand){
case 'x': this.cssUrl = '/src/styles1.scss';
break;
case 'y': this.cssUrl = '/src/styles2.scss';
break;
}
});
Html
<link rel="stylesheet" type="text/html" [href]='sanitizer.bypassSecurityTrustResourceUrl(cssUrl)'>

Create a canonical link dynamically using directive and move the link to head declaration in directive load
Directive
#Directive({
selector: '[appMoveToHead]'
})
export class MoveToHeadDirective implements OnDestroy, OnInit {
constructor(private renderer: Renderer2,
private elRef: ElementRef,
#Inject(DOCUMENT) private document: Document) {
}
ngOnInit(): void {
this.renderer.appendChild(this.document.head, this.elRef.nativeElement);
this.renderer.removeAttribute(this.elRef.nativeElement, 'appmovetohead');
}
ngOnDestroy(): void {
this.renderer.removeChild(this.document.head, this.elRef.nativeElement);
}
}
component.ts
canonicalLink:string;
constructor(private sanitizer: DomSanitizer) { }
//In oninit or when your data is ready, generate canonical link
ngOnInit() {
let canLink = "styles1.scss"; // set style here based on your condition
// You can use pipe for sanitizing but lets do it here
this.canonicalLink = this.sanitizer.bypassSecurityTrustResourceUrl(canLink);
}
component.html
<div *ngIf="canonicalLink">
<link rel="canonical" appMoveToHead [attr.href]="canonicalLink" />
</div>

Related

Importing css from a node module required in a plugin file with nuxt js

To add the fullscreen button to my leaflet map into nuxt i have installed leaflet.fullscreen package and i have edited my plugin leaflet.js like so:
import Vue from "vue";
import { LMap, LTileLayer, LMarker, LPolyline } from "vue2-leaflet";
require("leaflet-routing-machine");
require("lrm-graphhopper");
require("leaflet.fullscreen");
So i can use it in my main template:
<template>
<div>
<section class="search__page">
<div id="map-wrap" class="map__wrapper"></div>
</section>
</div>
</template>
<script>
import Tmap from "#/utils/TripMap.js";
export default {
mounted() {
this.initTmap();
},
data() {
return {
mainMap: null,
},
methods: {
initTmap() {
this.mainMap = new Tmap();
this.mainMap.load();
}
}
}
</script>
My class looks like that :
export default class Tmap {
constructor() {
this.map = null;
}
load) {
this.map = L.map("map-wrap", {
fullscreenControl: true,
fullscreenControlOptions: {
position: "topleft"
}).setView([46.7227062, 2.5046503], 6);
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
maxZoom: 18,
attribution: '© OpenStreetMap, ©TRIP'
}).addTo(this.map);
}
addMarkerOnClick() {
this.map.addEventListener("click", ev => {
L.marker(ev.latlng).addTo(this.map);
});
}
getBounds() {
return this.map.getBounds();
}
}
So in my main component i don't know how to import the css associated to this fullscreen plugin. I tried :
<style>
#import "~/node_modules/leaflet.fullscreen/Control.FullScreen.css";
</style>
That works but it's obviously not the good way to do that. Any idea how to that properly ?
From a quick web research i would say you should be able to access the styles like this:
#import "~leaflet/dist/leaflet.css";
When you register a global style in your nuxt.config.js the app will load it just once. I assume your build is taking more time than normal due to the node_modules path.
// nuxt.config.js
css: ['~/assets/styles/global.css'],
You could also give the nuxt resource loader a try.

rollup 'rollup-plugin-postcss' dont inject css into head

I want to create an HTML web component and i need to import CSS file but I want to inject it into my shadow dom. I have some code like below:
import introHTML from './Intro.html';
import introCss from './Intro.css';
class IntroWebComponent extends HTMLElement{
constructor(){
super();
this.defineClassProp();
}
defineClassProp(){
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._html = introHTML
this._element = document.createElement('template');
this._element.innerHTML = this._html;
this._element.append(`<style>${introCss}</style>`)
this._shadowRoot.appendChild(this._element.content.cloneNode(true));
}
}
window.customElements.define('index-intro', IntroWebComponent);
but 'rollup-plugin-postcss' keep injecting css to my main html head and i dont know how to stop it
just config your rollup to stop inject style in your js module:
the default config is:
postcss({
inject: { insertAt: 'top' }
})
you must change it to:
postcss({
inject:false
})

separate styles for separate module in Angular 5

My project has two main parts. One for public web pages and the other for admin control panel. Each of them has separate CSS and javascript files for their template.
If I define all CSS and js files in index.html, all files load in the first meet of the web page, and also maybe have a conflict between CSS classes.
How can I handle this problem?
app.component:
<router-outlet></router-outlet>
app-routing.module:
import { NgModule } from "#angular/core";
import { Routes, RouterModule } from "#angular/router";
import { FirstComponent } from './first/first.component';
const appRoutes: Routes = [
{ path: 'first', component: FirstComponent },
{
path: 'controlpanel',
loadChildren: 'app/control-panel/control-panel.module#ControlPanelModule'
},
{
path: 'publicpanel',
loadChildren: 'app/public-panel/public-panel.module#PublicPanelModule'
}
];
each module has its submodules. Can I separate their styles?
Use sass and create a class flag for public and admin components
like this
theme/_public.scss
.public{
label {
color:red;
}
}
theme/_admin.scss
.admin {
label {
color:green;
}
}
and this in main style.scc
#import "theme/_public.scss";
#import "theme/_admin.scss";
this is much better for app performance you will have one style file with public and admin pages style
stackblitz example
I found the solution. We can disable or enable css files in component.
document.styleSheets[2].disabled = false;
or
document.styleSheets[2].disabled = true;
that's it.

StencilJS Component Styles

What is the proper way to use the styles option/property of the ComponentDecorator? Using the styles property with the default my-name component from the repository stencil-component-starter doesn't seem to affect the styles of the respective component nor generate something like a <style> tag in the <head>. How is styles intended to work? Or has it not been implemented yet? If the goal is to avoid having a separate CSS asset that needs to be loaded, but provide styles for the component, would styles be the right choice or is there another property such as host would need to be used?
Below is a sample component generated from the stencil-component-starter]1 with stylesUrl #Component property replaced with a styles property and setting font-size property. No errors are generated during dev or build tasks.
import { Component, Prop } from '#stencil/core';
#Component({
tag: 'my-name',
styles: `my-name { font-size: 24px; }`
})
export class MyName {
#Prop() first: string;
render() {
return (
<div>
Hello, my name is {this.first}
</div>
);
}
}
ComponentDecorator is defined as:
export interface ComponentOptions {
tag: string;
styleUrl?: string;
styleUrls?: string[] | ModeStyles;
styles?: string;
shadow?: boolean;
host?: HostMeta;
assetsDir?: string;
assetsDirs?: string[];
}
Thank you for any help you can provide!
I just tried with latest version 0.0.6-22, and it seems to work completely now.
While compiling, it will tell you if your styles contents is valid or not (mainly looking for valid selectors).
Here is a working example (with a simple string):
import { Component, Prop } from "#stencil/core";
#Component({
tag: "inline-css-example",
styles: 'inline-css-example { font-size: 24px; }'
})
export class InlineCSSExampleComponent {
#Prop() first: string;
render() {
return <div>Hello, my name is {this.first}</div>;
}
}
This one works too, with ES6 Template Strings (just showing multiline):
import { Component, Prop } from "#stencil/core";
#Component({
tag: "inline-templatestring-css-example",
styles: `
inline-templatestring-css-example {
font-size: 24px;
}
`
})
export class InlineCSSExampleComponent {
#Prop() first: string;
render() {
return <div>Hello, my name is {this.first}</div>;
}
}
(EDITed to show evolution since 0.0.6-13)

React: Inline CSS modules in JSX with Webpack

I have a minimal React component which consists of two files: button.jsx and button.less. The styles are imported and the class names are appended with a hash to make all styles local to the component.
This is great, but i'd like to have all component code in one file. Is it possible to inline the styles in jsx file without losing css modularity?
Current Code
button.jsx
import React from 'react';
import styles from './button.less'
export default class Button extends React.Component {
render() {
return <button className={styles.primary}>{this.props.text}</button>;
}
}
button.less
#import '~semantic-ui/src/definitions/elements/button.less';
.common {
composes: ui button;
}
.primary {
composes: common primary;
}
webpack.config.js (relevant bits)
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'babel'
},
{
test: /\.less$/,
loader: "style!css?modules&importLoaders=1!less"
}
]
},
What i'd like to write instead
button.jsx
<style lang="less" modules>
#import '~semantic-ui/src/definitions/elements/button.less';
.common {
composes: ui button;
}
.primary {
composes: common primary;
}
</style>
import React from 'react';
export default class Button extends React.Component {
render() {
return <button className={styles.primary}>{this.props.text}</button>;
}
}
Inspired by vue.js and vue-loader.
I believe this is a duplicate of this unanswered question:
Using css-loader inline with Webpack + React
I wrote a Webpack loader for this very purpose:
https://github.com/chrisdavies/stylextract-loader
It allows you to write a single style tag per JSX file and it supports webpack CSS modules, too, if you want.
At build time, it extracts the rules from your style tag and moves them out to an external CSS file.
I should note that because it simply extracts your rules out to an external CSS file, it plays nice with SASS, autoprefixer, etc
You can use callback-loader for this. This is actualy a workaround, but it do the trick. Just implement a callback which will extract your css-code and replace it with appropriate import. For example:
webpack.config.js
var fs = require('fs');
var cssIndex = 0;
// Do not forget to create and clean temporary folder "cssTemp" before
var webpackConfig = {
...
resolve: {
alias: {
cssTemp: path.resolve('./cssTemp')
}
},
module: {
loaders: [
{ test: /\.jsx$/, loader: "callback!babel" }
]
},
callbackLoader: {
cssCallback: function(code) {
var filename = cssIndex + '.less';
cssIndex++;
// Save the css code from the callback argument
fs.writeFileSync('./cssTemp/' + filename, code);
// Return the import statement which will replace the callback statement
return 'import styles from "cssTemp/' + filename + '";';
}
}
...
};
button.jsx
import React from 'react';
cssCallback(`
#import '~semantic-ui/src/definitions/elements/button.less';
.common {
composes: ui button;
}
.primary {
composes: common primary;
}
`);
export default class Button extends React.Component {
render() {
return <button className={styles.primary}>{this.props.text}</button>;
}
}

Resources