rynex
Version:
A minimalist TypeScript framework for building reactive web applications with no virtual DOM
134 lines • 3.67 kB
JavaScript
/**
* Rynex Style Utilities
* Advanced styling helpers
*/
import { createElement } from '../dom.js';
let currentTheme = {};
const themeListeners = new Set();
/**
* Set application theme
*/
export function setTheme(theme) {
currentTheme = { ...currentTheme, ...theme };
themeListeners.forEach(listener => listener(currentTheme));
}
/**
* Get current theme
*/
export function getTheme() {
return { ...currentTheme };
}
/**
* Use theme hook
* Returns current theme and updates when theme changes
*/
export function useTheme(callback) {
callback(currentTheme);
themeListeners.add(callback);
return () => {
themeListeners.delete(callback);
};
}
/**
* Styled component creator
* Creates a component with predefined styles
*/
export function styled(tag, styles) {
return (props, ...children) => {
const computedStyles = typeof styles === 'function' ? styles(props) : styles;
const mergedProps = {
...props,
style: {
...(typeof props.style === 'object' ? props.style : {}),
...computedStyles
}
};
return createElement(tag, mergedProps, ...children);
};
}
/**
* Conditional class names helper
* Combines class names based on conditions
*/
export function classNames(...args) {
const classes = [];
args.forEach(arg => {
if (!arg)
return;
if (typeof arg === 'string') {
classes.push(arg);
}
else if (typeof arg === 'object') {
Object.entries(arg).forEach(([key, value]) => {
if (value) {
classes.push(key);
}
});
}
});
return classes.join(' ');
}
/**
* Merge style objects
* Deep merges multiple style objects
*/
export function mergeStyles(...styles) {
const merged = {};
styles.forEach(style => {
if (!style)
return;
Object.entries(style).forEach(([key, value]) => {
if (value !== null && value !== undefined) {
merged[key] = value;
}
});
});
return merged;
}
/**
* Create CSS variables from theme
*/
export function createCSSVariables(theme, prefix = '--theme') {
const vars = [];
const processObject = (obj, path = '') => {
Object.entries(obj).forEach(([key, value]) => {
const varName = path ? `${path}-${key}` : key;
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
processObject(value, varName);
}
else {
vars.push(`${prefix}-${varName}: ${value};`);
}
});
};
processObject(theme);
return vars.join('\n');
}
/**
* Apply theme as CSS variables to root
*/
export function applyThemeVariables(theme, prefix = '--theme') {
const cssVars = createCSSVariables(theme, prefix);
const style = document.createElement('style');
style.setAttribute('data-theme-vars', 'true');
style.textContent = `:root {\n${cssVars}\n}`;
// Remove old theme vars
const oldStyle = document.querySelector('style[data-theme-vars="true"]');
if (oldStyle) {
oldStyle.remove();
}
document.head.appendChild(style);
}
/**
* Get CSS variable value
*/
export function getCSSVariable(name, element = document.documentElement) {
return getComputedStyle(element).getPropertyValue(name).trim();
}
/**
* Set CSS variable value
*/
export function setCSSVariable(name, value, element = document.documentElement) {
element.style.setProperty(name, value);
}
//# sourceMappingURL=styles.js.map