templating
templating copied to clipboard
[Feature request]: Custom attribute scoped CSS
I'm submitting a feature request
I am not really sure if this is the right project to submit this request in, but I didn't know which one to put it in.
I am building an Aurelia adapter for Material Design and this adapter contains both custom elements and custom attributes. For each component I need to include the component's Material Design CSS file and for elements this is easy (using either <require from="...">
or the viewResources decorator). But I would really like to accomplish the same thing for my custom attributes.
@pndewit and importing css in attribute class does not produce the desired result?
Good point, noticed the css import statements here: http://aurelia.io/docs/tutorials/creating-a-contact-manager#building-the-application-shell.
So I tried something similar like: import 'bootstrap/dist/css/bootstrap.css';
But it's not working :(
@pndewit it should work. how are you bundling/loading?
@Alexander-Taran I now see during my build it is showing the following output (changed paths to the bootstrap example):
------- File not found or not accessible ------
| Location: ....../node_modules/bootstrap/dist/css/bootstrap.css.js
| Requested by: ....../node_modules/some-module/dist/index.js
| Is this a package? Make sure that it is configured in aurelia.json and that it is not a Node.js package
-----------------------------------------------
And as can be read from that piece, I am using Aurelia CLI.
Using the text loader and injecting the styles myself works:
import mycss from 'text!bootstrap/dist/css/bootstrap.css';
@inject(DOM, Element)
export class MyComponent {
constructor(private dom, private element:Element) {}
attached() {
let css = this.dom.injectStyles(mycss);
this.element.appendChild(css);
}
}
Are the docs incorrect? Or am I missing something?
@bigopon @Alexander-Taran
sorry to comment on a closed issue,
This will work when you know the loader for your css is the text
loader, however when writing a plugin which requires to load some css in a custom attribute or element, and beforehand you don't know which loader will be used, you need adhere to the standard means of importing CSS such as import 'mycss.css'
, that will cause errors when using the built-in bundler and having text
loader, for you have not specified text!
on your import.
any solutions to handle this?
See aurelia/cli#976
import "some.css"
is not a standard JS feature, different bundlers might supported differently. If you are developing aurelia plugin:
- in html
<require from="some.css"></require>
, - in js if no view
@noView([PLATFORM.moduleName('some.css')]);
Or use inline css string inside JS file, then do DOM.injectStyles
manually. Like https://github.com/aurelia/dialog/blob/ab7e534c94e2be317e56ec3848185932747eaf34/src/dialog-configuration.ts#L48
@huochunpeng Thanks for the extra options, but I can't use these in my case.
1 and 2 can only be used for customElement
s and I am trying to create a customAttribute with some extra styles.
Inline CSS string inside JS file in combination with DOM.injectStyles
would work, but my customAttribute depends on a CSS component from a third party that distributes a CSS file.
@huochunpeng
import "some.css" is not a standard JS feature
My bad, I thought it is.
I currently use DOM.injectStyles
, and in case of the second approach, I used viewResources
whcih does not work properly. I'll give noView a shot, but I remember it works with custom elements and not attributes as @pndewit said. and unfortunately we are also depending on a third party library.
I'll give noView a shot, but I remember it works with custom elements and not attributes as @pndewit said. and unfortunately we are also depending on a third party library.
I just tested it to be sure and it gets ignored. 😞
I see. It should be doable to implement another decorator which purely brings in css deps. As long as the non-component class is loaded by aurelia DI, it could work.
But I recall a problem with our webpack default setup. aurelia/cli#911
Any css dep, no matter is loaded by <require from="./s.css"></require>
(this can be in a @inlineView
decorator) or @noView([PLATFORM.moduleName('s.css')])
or import 's.css';
, if it is written inside a JS file. Our webpack setup will try to use style-loader to handle it, which injects the css onto html head (we actually only want that behaviour for import 's.css';
.
Since css importing is not a standard js feature. No matter how to write the import, for webpack users, it depends on whether they use style-loader, and how they config the style-loader. It is not in the control of the plugin author.
The reliable way is:
- use
<require from="s.css"></require>
in html file. This is irrelavent to your use case. - manually call
DOM.injectStyles
. That means you need to copy the 3rd party css content to your js file.
Otherwise, do nothing, then instruct the users of your plugin to manually do <require from="3rd/party.css"></require>
in app.html
.
Hope this clarified some bits.
I had seen the issue you mentioned above, I just I have one questions is the built-in bundler using requireJS also depends on webpack? I had the problem with that configuration and not webpack.
Hope this clarified some bits.
That definitely clarified, thanks :pray:
Thanks @huochunpeng! 👍
Otherwise, do nothing, then instruct the users of your plugin to manually do
in app.html.
This is what I have been doing for the last year or so. Since I am having a monorepo for Aurelia components (custom- elements and attributes) that is based on another monorepo (also maintained by myself) which contains the actual styles for a Material theme, this is generating quite a long list of imports in the base HTML in some cases. Thus my motivation to search for another solution 😄
Note: I am also using RequireJS.
Cli requirejs does not use webpack at all. The PR for requirejs setup to support import css in js is not merged yet.