Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
String inline style with prefix in React. DEPRECATED FOR `import {createInlineStyle} from '@xialvjun/create-react-style'`
import * as React from "react";
import { isValidElement } from "react";
import { createStyle } from "@xialvjun/create-react-style";
const StyleContext = createStyle();
function format_style(style) {
if (!style) {
return "";
}
if (style instanceof Array) {
return style.map(s => format_style(s)).join("");
}
if (typeof style === "object") {
return (
Object.keys(style)
.map(
k =>
`${k.replace(
/[A-Z]/g,
C => "-" + String.fromCharCode(C.charCodeAt(0) + 32).toString()
)}:${style[k]}`
)
.join(";") + ";"
);
}
return style + ";";
}
function is_lowercase(str: string) {
str = str + "";
return str.toLowerCase() === str;
}
function is_valid_css_ele(ele) {
return isValidElement(ele) && is_lowercase((ele as any).type);
}
function make_css({ rc, children }, cascade) {
let css = format_style(rc);
if (
cascade &&
(is_valid_css_ele(children) ||
(children instanceof Array && children.every(c => is_valid_css_ele(c))))
) {
css += []
.concat(children)
.map(
(c, idx) =>
`& > :nth-child(${idx + 1}){${make_css(c.props || {}, cascade - 1)}}`
);
}
return css;
}
type InlineStylePropsType = {
as?: string;
className?: string;
cascade?: number | boolean;
rc?: string;
children?: React.ReactNode;
};
export const InlineStyle = ({
as = "div",
className = "",
cascade = 1,
rc = "",
children = []
}: InlineStylePropsType) => {
const AS = as;
if (typeof cascade !== "number") {
cascade = !!cascade ? Number.MAX_SAFE_INTEGER : 0;
}
const css = make_css({ rc, children }, cascade);
return (
<StyleContext.Consumer css={css}>
{cn => (
<AS className={className ? `${className} ${cn}` : cn}>{children}</AS>
)}
</StyleContext.Consumer>
);
};
export const Provider: typeof StyleContext.Provider = StyleContext.Provider;
export const Style: typeof StyleContext.Consumer = StyleContext.Consumer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment