Aurelia: [RFC] DOM.injectStyles with more capabilities

Created on 25 Oct 2020  路  5Comments  路  Source: aurelia/aurelia

馃挰 RFC

A long time ago, I talked with @bigopon about this feature, but I made this issue as a reminder.
In Aurelia 1, we had a good feature as DOM.injectStyles, some features were added over time like Optional Id to it.

I think it is a good time to add two new options as the following in Aurelia 2:

Support Object-based style

You can use css-to-js transformer to convert a CSS text to a JS object and use the result

image

There is a conventional naming approach for defining your rules. Every uppercase character will change to a hyphen and a lowercase character (XyZ => -xy-z). For example, If you want to achieve -webkit-animation you should write WebkitAnimation or flexDirection will change to flex-direction.

So, I got the idea from the above site to support a very simple but useful CSS to JS Object transformation.

Overridable option

By adding the above feature we will have an overhead to convert Object-based styles to its CSS styles every time. But sometimes you have a very static style and you need to add it once, so an overridable option helps us to make it happen by assigning it to false.

馃敠 Context

I want to support JS object-based scenarios in a very simple way, not an alternative to other big frameworks like Styled Components, JSS, Emotion, or...

馃捇 Examples

injectStyle(textOrObject, id, overridable, hostElement)

A functionality to inject your text or object-based style to the HTML document easily!

| Parameter(s) | Description | Optional | Default |
|----------|:-------------|:------:|:------:|
| textOrObject | Text style or object-based style | No | - |
| id | To set an id for your <style>, it helps you to update a specific style tag | Yes | - |
| overridable | If set this to false, you can inject your style just once | Yes | true |
| hostElement | To set your host element to inject your style into it. Useful for shadow DOM | Yes | document.head |

const cssObj = {
  ".main-wrapper": { flexDirection: "row", display: "flex", flex: "1" },
  "#content": { flex: "1" },
  ul: { padding: "20px 0", flex: "1" },
  li: { fontFamily: "'Lato'", color: "whitesmoke", lineHeight: "44px" }
};

injectStyle(cssObj,'my-style-tag');

You can find a standalone implementation here.
Also, you will find a practical sample here too.

RFC

Most helpful comment

If I understood this right, I should say that it can already be achieved with current APIs. The idea is we use portal + interpolation for global injection + binding for dynamic CSS.

If there needs to be a global CSS style sheet:

<style portal="head">
  .main-wrapper {
    height: ${appHeight}px;
    width: var(--appWidth);
  }
</style>

The limitation is it can only be done within a custom element, but maybe we can let custom attribute participate in compilation process via @processContent and silently inject the following:

<style portal="head">...</style>

All 5 comments

Does this seem like a loader/build time feature more than a runtime feature? Ex. when we do:

import style from 'css-to-js-loader!my.css';

style will be a JS object?

@bigopon

Sounds like an interesting case.
In your example, will we depend on different libraries/bundlers? For example, Webpack, Parcel, or ... as I recall css-to-js-loader is a Webpack 3rd party library.

So If your answer is yes, I prefer a very light but native feature inside DOM.injectStyles although I think your idea is better in the performance context.

If I understood this right, I should say that it can already be achieved with current APIs. The idea is we use portal + interpolation for global injection + binding for dynamic CSS.

If there needs to be a global CSS style sheet:

<style portal="head">
  .main-wrapper {
    height: ${appHeight}px;
    width: var(--appWidth);
  }
</style>

The limitation is it can only be done within a custom element, but maybe we can let custom attribute participate in compilation process via @processContent and silently inject the following:

<style portal="head">...</style>

OK, I think there are two different topics.

First, Should we have DOM.injectStyles to support global styles injection when we have portal feature in Aurelia 2?
I have no idea because I had not any experience with this new capability in v2.

Second, Do we want to port DOM.injectStyles to the new version for any reason such as backward compatibility?
If yes, so I am talking about this part plus new options to that functionality.

Second ...

Yes, we can definitely port it. Just for the new capability of turning CSS into JS to inject, I was saying maybe we don't need to do that yet, and if it's needed, we can achieve that with portal for now, to flex out the use cases

Was this page helpful?
0 / 5 - 0 ratings