picasso-paint
Version:
Paint , a simple CSS-in-JS library that allows you to write CSS in JavaScript cssText/Object
228 lines (194 loc) • 6.22 kB
Markdown
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Paint.js Documentation</title>
<style>
body {
font-family: sans-serif;
line-height: 1.6;
background-color: #fdfdfd;
color: #222;
padding: 2rem;
}
h1, h2, h3 {
color: #3366cc;
}
code {
background: #f4f4f4;
padding: 2px 4px;
border-radius: 4px;
font-family: monospace;
}
pre {
background: #f4f4f4;
padding: 1rem;
overflow-x: auto;
border-left: 3px solid #3366cc;
border-radius: 4px;
}
</style>
</head>
<body>
<h1>Paint.js</h1>
<p>A lightweight JavaScript utility for dynamically manipulating CSS styles at runtime using the CSSOM and Constructable Stylesheets.</p>
<h2>Usage Examples</h2>
<h3>Basic Styling</h3>
<pre><code>
Paint('#header', 'background-color: #f0f0f0; padding: 20px;');
Paint('.card', 'border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);');
</code></pre>
<h3>Pseudo-Classes</h3>
<pre><code>
Paint('.button')
.hover('background-color: #0066cc', 'color: white');
Paint('input[type="text"]')
.focus('border-color: #0066cc', 'outline: none');
const navLink = Paint('.nav-link');
navLink.hover('color: #0066cc');
navLink.active('font-weight: bold');
navLink.visited('color: #6600cc');
</code></pre>
<h3>CSS Variables</h3>
<pre><code>
Paint.root('--primary-color', '#0066cc');
Paint.root('--secondary-color', '#ff9900');
Paint.root('--text-color', '#333333');
Paint('.button', 'background-color: var(--primary-color); color: white;');
Paint('.alert', 'background-color: var(--secondary-color); color: var(--text-color);');
Paint.root('--primary-color', '#009933');
Paint.removeRoot('--secondary-color');
</code></pre>
<h3>Style Inspection</h3>
<pre><code>
const buttonCSS = Paint.getCSS('.button');
console.log(buttonCSS);
const buttonStyles = Paint.getCSSObj('.button');
console.log(buttonStyles.backgroundColor);
</code></pre>
<h2>Advanced Usage</h2>
<h3>Dynamic Theming</h3>
<pre><code>
function setTheme(isDark) {
if (isDark) {
Paint.root('--bg-color', '#222222');
Paint.root('--text-color', '#ffffff');
} else {
Paint.root('--bg-color', '#ffffff');
Paint.root('--text-color', '#222222');
}
}
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setTheme(prefersDark);
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', e => setTheme(e.matches));
</code></pre>
<h3>Responsive Design</h3>
<pre><code>
function updateResponsiveStyles() {
const isMobile = window.innerWidth < 768;
if (isMobile) {
Paint('.container', 'width: 100%; padding: 10px;');
Paint('.sidebar', 'display: none;');
} else {
Paint('.container', 'width: 80%; max-width: 1200px; padding: 20px;');
Paint('.sidebar', 'display: block; width: 250px;');
}
}
updateResponsiveStyles();
window.addEventListener('resize', updateResponsiveStyles);
</code></pre>
<h2>Installation</h2>
<pre><code><script src="path/to/paint.js"></script></code></pre>
<h2>Technical Considerations</h2>
<ul>
<li><strong>Performance:</strong> Constructable Stylesheets are optimized</li>
<li><strong>Memory:</strong> Single stylesheet minimizes usage</li>
<li><strong>Compatibility:</strong> Modern browsers only (no IE)</li>
</ul>
<h2>Technical Overview</h2>
<p>Paint.js provides a programmatic interface to the browser's CSSOM, allowing developers to create, modify, and remove CSS rules without DOM manipulation. It uses the Constructable Stylesheets API for efficiency and performance.</p>
<h3>Core Architecture</h3>
<ul>
<li><strong>Performance:</strong> Avoids expensive DOM reflows</li>
<li><strong>Encapsulation:</strong> Keeps styles separate from static CSS</li>
<li><strong>Maintainability:</strong> Structured API for style management</li>
</ul>
<h2>Technical Implementation</h2>
<h3>Initialization</h3>
<pre><code>
// Initialize a global CSSStyleSheet
if (!window.Rules) {
window.Rules = new CSSStyleSheet();
document.adoptedStyleSheets = [...document.adoptedStyleSheets, window.Rules];
}
</code></pre>
<h3>Basic Style Application</h3>
<pre><code>
// Apply styles to an element
Paint('.my-element', 'color: red; font-size: 16px;');
</code></pre>
<h3>Core Function</h3>
<pre><code>
function Paint(selector, CSSTXT) {
if(CSSTXT) {
window.Rules.insertRule(`${selector}{${CSSTXT}}`, window.Rules.cssRules.length);
}
return new Proxy({}, {
get(_, pseudoClass) {
return (...styles) => {
let rule = `${selector}:${pseudoClass} {${styles.join("; ")}}`;
window.Rules.insertRule(rule, window.Rules.cssRules.length);
};
}
});
}
</code></pre>
<h3>CSS Variables</h3>
<pre><code>
window.CSSRootRules = "";
Paint.root = function(variable, value) {
window.CSSRootRules += `${variable}:${value};\n`;
let rule = `:root{\n${window.CSSRootRules}}`;
for (let i = 0; i < window.Rules.cssRules.length; i++) {
if (window.Rules.cssRules[i].selectorText === ":root") {
window.Rules.deleteRule(i);
break;
}
}
window.Rules.insertRule(rule, window.Rules.cssRules.length);
};
Paint.removeRoot = function(variable) {
let regex = new RegExp(`${variable}:.*?;\\n`, "g");
window.CSSRootRules = window.CSSRootRules.replace(regex, '');
let rule = `:root{\n${window.CSSRootRules}}`;
for (let i = 0; i < window.Rules.cssRules.length; i++) {
if (window.Rules.cssRules[i].selectorText === ":root") {
window.Rules.deleteRule(i);
break;
}
}
window.Rules.insertRule(rule, window.Rules.cssRules.length);
};
</code></pre>
<h3>Style Inspection</h3>
<pre><code>
Paint.getCSS = function(selector) {
window.Rules.cssRules.forEach(function(D) {
if(D.selectorText == selector) {
window.cssText = `${selector}{\n${D.style.cssText.replaceAll(";",";\n")}}`;
}
});
return cssText;
};
Paint.getCSSObj = function(selector) {
window.Rules.cssRules.forEach(function(D) {
if(D.selectorText == selector) {
window.cssObj = D.style;
}
});
return cssObj;
};
</code></pre>
</body>
</html>