DOM style injection
Some users may want to inject their styles into the DOM like v1. There is no equivalent for this functionality in the second version so we can define our injectStyle
function as following:
// inject-style.ts
function caseConverter(str: string): string {
if (str.length === 0) return str;
const isUppercase = str[0] === str[0].toUpperCase();
const result = str
.split(/(?=[A-Z])/)
.join("-")
.toLowerCase();
return isUppercase ? `-${result}` : result;
}
// CSS object to string converter.
export function toCss(obj: any): string {
if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
throw new TypeError(
`expected an argument of type object, but got ${typeof obj}`
);
}
let lines: string[] = [];
for (let index = 0; index < Object.keys(obj).length; index++) {
const id = Object.keys(obj)[index];
const key = caseConverter(id);
const value = obj[id];
if (typeof value === "object") {
const text = toCss(value);
lines.push(`${id}{${text}}`);
} else {
lines.push(`${key}:${value};`);
}
}
return lines.join("");
}
// Inject string/object style to DOM.
export function injectStyle(
textOrObject: string | object,
id?: string,
overridable = true,
hostElement: HTMLElement = document.head
) {
if (!textOrObject || Array.isArray(textOrObject)) return;
if (typeof textOrObject === 'string' && textOrObject.length === 0) return;
if (id) {
let oldStyle = document.getElementById(id);
if (oldStyle) {
let isStyleTag = oldStyle.tagName.toLowerCase() === "style";
if (!isStyleTag) {
throw new Error("The provided id does not indicate a style tag.");
} else if (isStyleTag && overridable) {
oldStyle.innerHTML = typeof textOrObject === "object" ? toCss(textOrObject) : textOrObject;
}
return;
}
}
let style = document.createElement("style");
style.type = "text/css";
style.innerHTML = typeof textOrObject === "object" ? toCss(textOrObject) : textOrObject;
if (id) style.id = id;
hostElement.appendChild(style);
}
toCss(obj)
A very simple object-to-css converter.
obj
Object-based style
No
-
Returns: a css text.
// css-object-style.ts
export 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" }
};
let cssText = toCss(cssObj);
The value of cssText
will be equal to:
.main-wrapper {
flex-direction: row;
display: flex;
flex: 1;
}
#content {
flex: 1;
}
ul {
padding: 20px 0;
flex: 1;
}
li {
font-family:'Lato';
color: whitesmoke;
line-height: 44px;
}
You can use css-to-js transformer to convert a CSS text to a JS object and use the result for toCss(result)
directly!
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
.
This is exactly what the caseConverter
function does.
injectStyle(textOrObject, id, overridable, hostElement)
A functionality to inject your text or object-based style to the html document easily!
textOrObject
Text or object-based style.
No
-
id
To set an id for your <style>
, it helps you to update an specific style tag.
Yes
-
overridable
If set this to false
, your style is only injected once but to do this you must set an id parameter too.
Yes
true
hostElement
To set your host element to inject your style into it. Useful for shadow DOM.
Yes
document.head
import { injectStyle } from 'inject-style';
import { cssObj } from 'css-object-style';
// Object
injectStyle(cssObj, 'my-style-tag', false);
// String
injectStyle(`
.main-wrapper {
flex-direction: row;
display: flex;
flex: 1;
}
#content {
flex: 1;
}
ul {
padding: 20px 0;
flex: 1;
}
li {
font-family:'Lato';
color: whitesmoke;
line-height: 44px;
}
`, 'my-style-tag', false);
Last updated
Was this helpful?