@ducor/react
Version:
admin template ui interface
126 lines (123 loc) • 3.92 kB
JavaScript
import { createElement, memo } from "react";
const Style = memo(({ href, value, onLoad }) => {
if (typeof href === 'string') {
return createElement("link", {
rel: "stylesheet",
href: href,
"data-du": 'injected-style',
onLoad: () => {
if (typeof onLoad === 'function') {
onLoad();
}
}
});
}
if (typeof value === 'string') {
return createElement("style", {
"data-du": 'injected-style',
onLoad: () => {
if (typeof onLoad === 'function') {
onLoad();
}
}
}, value);
}
if (typeof value === 'object') {
return createElement("style", {
"data-du": 'injected-style',
onLoad: () => {
if (typeof onLoad === 'function') {
onLoad();
}
}
}, css(value));
}
return null;
});
export const css = (cssObj, minify = false) => {
const processBlock = (selector, styles, indent = '') => {
const rules = Object.entries(styles)
.map(([prop, value]) => minify ? `${prop}:${value}` : `${indent} ${prop}: ${value};`);
const ruleSeparator = minify ? '' : '\n';
const blockOpen = minify ? `${selector}{` : `${selector} {\n`;
const blockClose = minify ? '}' : `\n${indent}}\n`;
return `${blockOpen}${rules.join(minify ? ';' : ruleSeparator)}${blockClose}`;
};
const processEntry = (key, entry, indent = '') => {
if (Array.isArray(entry)) {
const [selectors, styles] = entry;
return processBlock(selectors.join(minify ? ',' : ', '), styles, indent);
}
return processBlock(key, entry, indent);
};
let output = '';
for (const [key, value] of Object.entries(cssObj)) {
if (key.startsWith('@')) {
// Handle media queries
const mediaContent = Object.entries(value)
.map(([selector, styles]) => processBlock(selector, styles, minify ? '' : ' '))
.join(minify ? '' : '\n');
const mediaOpen = minify ? `${key}{` : `${key} {\n`;
const mediaClose = minify ? '}' : '\n}\n';
output += `${mediaOpen}${mediaContent}${mediaClose}`;
}
else if (/^\d+$/.test(key)) {
// Handle numeric keys with array format
output += processEntry(key, value);
}
else {
// Handle regular selectors
output += processBlock(key, value);
}
}
return output;
};
// Example usage
// const myStyles = {
// 0: [
// ['asfsd', 'p', 'ts'],
// {
// '--sidebar-width': 'var(--du-sidebar-vertical-full)',
// '--font-sans': 'Roboto, sans-serif',
// '--font-sans-rtl': 'Roboto, serif',
// }
// ],
// root: {
// "--sidebar-width": "var(--du-sidebar-vertical-full)",
// "--font-sans": "Roboto, sans-serif",
// "--font-sans-rtl": "Roboto, serif",
// },
// "@media (min-width: 768px)": {
// root: {
// "--sidebar-width": "var(--du-sidebar-vertical-full)",
// "--font-sans": "Roboto, sans-serif",
// "--font-sans-rtl": "Roboto, serif",
// }
// }
// };
// Regular output
// console.log(css(myStyles));
/* Output:
asfsd, p, ts {
--sidebar-width: var(--du-sidebar-vertical-full);
--font-sans: Roboto, sans-serif;
--font-sans-rtl: Roboto, serif;
}
root {
--sidebar-width: var(--du-sidebar-vertical-full);
--font-sans: Roboto, sans-serif;
--font-sans-rtl: Roboto, serif;
}
@media (min-width: 768px) {
root {
--sidebar-width: var(--du-sidebar-vertical-full);
--font-sans: Roboto, sans-serif;
--font-sans-rtl: Roboto, serif;
}
}
*/
// Minified output
/* Output:
asfsd,p,ts{--sidebar-width:var
*/
export default Style;