Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request]: Custom attribute scoped CSS #581

Open
pndewit opened this issue Nov 21, 2017 · 14 comments
Open

[Feature request]: Custom attribute scoped CSS #581

pndewit opened this issue Nov 21, 2017 · 14 comments

Comments

@pndewit
Copy link
Contributor

pndewit commented Nov 21, 2017

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 pndewit changed the title Custom attribute scoped CSS [Feature request]: Custom attribute scoped CSS Dec 18, 2017
@Alexander-Taran
Copy link

Alexander-Taran commented Mar 22, 2018

@pndewit and importing css in attribute class does not produce the desired result?

@pndewit
Copy link
Contributor Author

pndewit commented Mar 23, 2018

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 :(

@Alexander-Taran
Copy link

@pndewit it should work. how are you bundling/loading?

@pndewit
Copy link
Contributor Author

pndewit commented Mar 23, 2018

@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.

@pndewit
Copy link
Contributor Author

pndewit commented Mar 23, 2018

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?

@shahabganji
Copy link

shahabganji commented Dec 17, 2018

@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?

@3cp
Copy link
Member

3cp commented Dec 17, 2018

See aurelia/cli#976

import "some.css" is not a standard JS feature, different bundlers might supported differently. If you are developing aurelia plugin:

  1. in html <require from="some.css"></require>,
  2. 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

@pndewit
Copy link
Contributor Author

pndewit commented Dec 18, 2018

@huochunpeng Thanks for the extra options, but I can't use these in my case.
1 and 2 can only be used for customElements 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.

@shahabganji
Copy link

@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.

@pndewit
Copy link
Contributor Author

pndewit commented Dec 18, 2018

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. 😞

@3cp
Copy link
Member

3cp commented Dec 18, 2018

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:

  1. use <require from="s.css"></require> in html file. This is irrelavent to your use case.
  2. 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.

@shahabganji
Copy link

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 🙏

@pndewit
Copy link
Contributor Author

pndewit commented Dec 19, 2018

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.

@3cp
Copy link
Member

3cp commented Dec 19, 2018

Cli requirejs does not use webpack at all. The PR for requirejs setup to support import css in js is not merged yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants