gullu-css 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -0
- package/appliers/background.js +27 -0
- package/appliers/boxModel.js +58 -0
- package/appliers/effects.js +18 -0
- package/appliers/image.js +30 -0
- package/appliers/layout.js +27 -0
- package/appliers/position.js +20 -0
- package/appliers/typography.js +44 -0
- package/index.html +588 -0
- package/main.js +31 -0
- package/package.json +19 -0
- package/values.js +406 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# CleanCSS Engine
|
|
2
|
+
|
|
3
|
+
A blazing-fast, **zero-build** runtime utility CSS engine.
|
|
4
|
+
|
|
5
|
+
Instead of waiting for Webpack or Vite to compile hundreds of gigabytes of node modules, **CleanCSS Engine operates entirely in the browser at runtime**. By leveraging modern browser JavaScript, CleanCSS reads your utility classes natively and injects styles dynamically. No complicated configurations. No PostCSS process. Just instantly applied styles.
|
|
6
|
+
|
|
7
|
+
## 🚀 Features
|
|
8
|
+
- **Zero Build Step:** Runs 100% in browser JS. No build pipelines.
|
|
9
|
+
- **O(N) Single-Pass Performance:** Ultra-optimized scanner parses the DOM once.
|
|
10
|
+
- **200+ Semantic Tokens:** Out of the box Oklch color palettes, spacing systems, and scale tiers.
|
|
11
|
+
- **Arbitrary JIT Values:** On-the-fly values using square bracket syntax (e.g., `text-[35px]`).
|
|
12
|
+
- **Lightweight Core:** Modularized rulesets (Layout, Typography, Backgrounds, Effects, etc.).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📦 Installation
|
|
17
|
+
|
|
18
|
+
To install via npm:
|
|
19
|
+
```bash
|
|
20
|
+
npm install clean-css-engine
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
*(Note: Replace `clean-css-engine` with the exact scoped name you push to npm).*
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 🛠️ Usage
|
|
28
|
+
|
|
29
|
+
Because it's an ES6 module, you can easily drop it into standard HTML, React, Vue, Next.js, or any modern framework.
|
|
30
|
+
|
|
31
|
+
### Vanilla JS / HTML
|
|
32
|
+
```html
|
|
33
|
+
<!-- Inside index.html -->
|
|
34
|
+
<script type="module">
|
|
35
|
+
import { initEngine } from "./node_modules/clean-css-engine/main.js";
|
|
36
|
+
|
|
37
|
+
// Call the engine to compile all styles
|
|
38
|
+
initEngine();
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- Build interfaces instantly! -->
|
|
42
|
+
<div class="bg-emerald-500 text-white p-6 rounded-lg shadow-lg d-flex items-center gap-4">
|
|
43
|
+
<h1 class="text-2xl font-bold">Hello World!</h1>
|
|
44
|
+
</div>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### React / Next.js
|
|
48
|
+
You can trigger the engine during page mount or context initialization:
|
|
49
|
+
```jsx
|
|
50
|
+
import { useEffect } from 'react';
|
|
51
|
+
import { initEngine } from 'clean-css-engine';
|
|
52
|
+
|
|
53
|
+
export default function App() {
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
// Run the engine once the DOM mounts
|
|
56
|
+
initEngine();
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div className="bg-slate-900 w-screen h-screen d-flex items-center justify-center">
|
|
61
|
+
<h1 className="text-4xl font-bold text-emerald-400">Powered by CleanCSS</h1>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 📖 API & Feature Reference
|
|
70
|
+
|
|
71
|
+
Below is a complete reference of the modules and utility classes processed by CleanCSS:
|
|
72
|
+
|
|
73
|
+
### 1. Typography
|
|
74
|
+
Control all text styling properties with simple prefixes.
|
|
75
|
+
- **Size Scale:** `text-xs`, `text-sm`, `text-base`, `text-lg`, `text-xl` ... `text-6xl`.
|
|
76
|
+
- **Colors:** Support for `text-white`, `text-gray`, and scales like `text-emerald-500` or `text-blue-700`.
|
|
77
|
+
- **Weight:** `font-medium`, `font-bold`, `font-black`.
|
|
78
|
+
- **Alignment:** `text-center`, `text-right`, `text-left`.
|
|
79
|
+
|
|
80
|
+
### 2. Layout & Flex
|
|
81
|
+
Handle responsive positioning and flexbox models seamlessly.
|
|
82
|
+
- **Display Nodes:** `d-flex`, `d-inline-flex`.
|
|
83
|
+
- **Direction:** `flex-col`, `flex-row`.
|
|
84
|
+
- **Alignment (Items):** `items-start`, `items-center`, `items-end`.
|
|
85
|
+
- **Alignment (Content):** `justify-start`, `justify-center`, `justify-between`, `justify-around`.
|
|
86
|
+
- **Spacing:** `gap-1`, `gap-4`, `gap-8`.
|
|
87
|
+
- **Wrap:** `flex-wrap`, `flex-nowrap`.
|
|
88
|
+
|
|
89
|
+
### 3. Box Model & Spacing
|
|
90
|
+
Precise control over margins, padding, sizing, and borders.
|
|
91
|
+
- **Padding:** `p-4`, `pt-2`, `pb-8`, `px-4`, `py-6`.
|
|
92
|
+
- **Margin:** `m-4`, `mt-2`, `mb-8`, `mx-auto`.
|
|
93
|
+
- **Scale:** Spacing values map evenly from 0px up to 96px (`p-0` to `p-24`).
|
|
94
|
+
- **Sizing:** `w-full`, `h-screen`, `w-64`, `max-w-lg`.
|
|
95
|
+
- **Radius:** `rounded-sm`, `rounded-md`, `rounded-lg`, `rounded-full`.
|
|
96
|
+
- **Borders:** `border-2`, `border-emerald-500`.
|
|
97
|
+
|
|
98
|
+
### 4. Backgrounds & Colors
|
|
99
|
+
Paint any container with deep color system integration.
|
|
100
|
+
- **Standard Colors:** `bg-emerald-500`, `bg-slate-900`, `bg-blue-600`.
|
|
101
|
+
- **Special Values:** `bg-white`, `bg-black`, `bg-transparent`.
|
|
102
|
+
- **Color Scale:** Ranges horizontally from `50` (lightest) to `950` (darkest). All predefined palettes use perceptual color modeling.
|
|
103
|
+
|
|
104
|
+
### 5. Images
|
|
105
|
+
Style responsive web images seamlessly.
|
|
106
|
+
- **Background Size/Position:** `bg-cover`, `bg-contain`, `bg-auto`, `bg-center`, `bg-top`.
|
|
107
|
+
- **Object Fits (for Native Images):** `object-cover`, `object-contain`, `object-center`.
|
|
108
|
+
- **Direct URLs:** Embed background images flawlessly via `bg-[url('https://link.com/photo.jpg')]`.
|
|
109
|
+
|
|
110
|
+
### 6. Effects
|
|
111
|
+
Bring interactions alive.
|
|
112
|
+
- **Shadows:** `shadow-sm`, `shadow-md`, `shadow-lg` (maps high fidelity CSS box-shadows).
|
|
113
|
+
- **Interactivity:** `cursor-pointer`, `transition`, `opacity-50`, `opacity-75`.
|
|
114
|
+
- **Overflow:** `overflow-hidden`, `overflow-visible`.
|
|
115
|
+
|
|
116
|
+
### 7. Arbitrary Constraints JIT `[...]`
|
|
117
|
+
Sometimes you need to escape the token system. Whenever that happens, cleanly use square bracket arbitrary values.
|
|
118
|
+
- **Custom Texts:** `text-[35px]`
|
|
119
|
+
- **Custom Colors:** `bg-[#ff6b6b]`, `text-[oklch(65%_0.2_145)]`
|
|
120
|
+
- **Dynamic Variables:** `bg-(--brand-color)`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## ⚙️ Architecture Core
|
|
125
|
+
CleanCSS is built to be maximally performant at runtime. When `initEngine()` runs, it gathers the DOM layer into `document.querySelectorAll("[class]")` and iterates through standard HTML classes mapping directly up to our array of isolated rule tests (located in cleanly decoupled feature files: `layout.js`, `typography.js`, etc.). If a rule hits dynamically, it instantly overrides the element's inline `.style`, avoiding reflow latency whenever feasible.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
### Building the Future of Styling.
|
|
129
|
+
*Developed for unparalleled runtime simplicity.*
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { bgColors } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyBackground(el, cls) {
|
|
4
|
+
// Arbitrary background color
|
|
5
|
+
if (cls.startsWith("bg-[") && cls.endsWith("]")) {
|
|
6
|
+
const value = cls.slice(4, -1).trim();
|
|
7
|
+
if (!value.startsWith("url(") && !value.match(/gradient\(/)) {
|
|
8
|
+
el.style.backgroundColor = value;
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// CSS Variables
|
|
14
|
+
if (cls.startsWith("bg-(") && cls.endsWith(")")) {
|
|
15
|
+
const varName = cls.slice(4, -1).trim();
|
|
16
|
+
el.style.backgroundColor = `var(${varName})`;
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Standard colors
|
|
21
|
+
if (bgColors[cls]) {
|
|
22
|
+
el.style.backgroundColor = bgColors[cls];
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { boxSizing, spacing, sizing, borderRadius, borderWidth, borderColor } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyBoxModel(el, cls) {
|
|
4
|
+
// 1. Box Sizing
|
|
5
|
+
if (boxSizing[cls]) { el.style.boxSizing = boxSizing[cls]; return true; }
|
|
6
|
+
|
|
7
|
+
// 2. Spacing
|
|
8
|
+
const pmMap = { p: "padding", m: "margin" };
|
|
9
|
+
const sideMap = { t: "Top", b: "Bottom", l: "Left", r: "Right" };
|
|
10
|
+
|
|
11
|
+
for (const [pre, prop] of Object.entries(pmMap)) {
|
|
12
|
+
if (cls.startsWith(`${pre}-`)) {
|
|
13
|
+
const key = cls.split("-").pop();
|
|
14
|
+
if (spacing[key]) { el.style[prop] = spacing[key]; return true; }
|
|
15
|
+
else if (!isNaN(key)) { el.style[prop] = key + "px"; return true; }
|
|
16
|
+
}
|
|
17
|
+
for (const [s, side] of Object.entries(sideMap)) {
|
|
18
|
+
if (cls.startsWith(`${pre}${s}-`)) {
|
|
19
|
+
const key = cls.split("-").pop();
|
|
20
|
+
if (spacing[key]) { el.style[`${prop}${side}`] = spacing[key]; return true; }
|
|
21
|
+
else if (!isNaN(key)) { el.style[`${prop}${side}`] = key + "px"; return true; }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 3. Width and Height
|
|
27
|
+
if (sizing[cls]) {
|
|
28
|
+
if (cls.startsWith("w-")) el.style.width = sizing[cls];
|
|
29
|
+
if (cls.startsWith("h-")) el.style.height = sizing[cls];
|
|
30
|
+
if (cls.startsWith("max-w-")) el.style.maxWidth = sizing[cls];
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (cls.startsWith("w-")) {
|
|
34
|
+
const val = cls.split("-").pop();
|
|
35
|
+
el.style.width = isNaN(val) ? val : val + "px";
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
if (cls.startsWith("h-")) {
|
|
39
|
+
const val = cls.split("-").pop();
|
|
40
|
+
el.style.height = isNaN(val) ? val : val + "px";
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 4. Borders & Radius
|
|
45
|
+
if (borderRadius[cls]) { el.style.borderRadius = borderRadius[cls]; return true; }
|
|
46
|
+
if (borderWidth[cls]) {
|
|
47
|
+
el.style.borderWidth = borderWidth[cls];
|
|
48
|
+
el.style.borderStyle = "solid";
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (borderColor[cls]) {
|
|
52
|
+
el.style.borderColor = borderColor[cls];
|
|
53
|
+
if (!el.style.borderStyle) el.style.borderStyle = "solid";
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { shadows, miscEffects } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyEffects(el, cls) {
|
|
4
|
+
if (shadows[cls]) {
|
|
5
|
+
el.style.boxShadow = shadows[cls];
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (miscEffects[cls]) {
|
|
10
|
+
if (cls.includes("transition")) el.style.transition = miscEffects[cls];
|
|
11
|
+
else if (cls.includes("cursor")) el.style.cursor = miscEffects[cls];
|
|
12
|
+
else if (cls.includes("opacity")) el.style.opacity = miscEffects[cls];
|
|
13
|
+
else if (cls.includes("overflow")) el.style.overflow = miscEffects[cls];
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { objectFits, objectPositions, bgSizes, bgRepeats, bgPositions } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyImage(el, cls) {
|
|
4
|
+
if (cls.startsWith("bg-[url(") && cls.endsWith(")]")) {
|
|
5
|
+
const urlStr = cls.slice(4, -1).trim();
|
|
6
|
+
el.style.backgroundImage = urlStr;
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (objectFits[cls]) {
|
|
10
|
+
el.style.objectFit = objectFits[cls];
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
if (objectPositions[cls]) {
|
|
14
|
+
el.style.objectPosition = objectPositions[cls];
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (bgSizes[cls]) {
|
|
18
|
+
el.style.backgroundSize = bgSizes[cls];
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (bgRepeats[cls]) {
|
|
22
|
+
el.style.backgroundRepeat = bgRepeats[cls];
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (bgPositions[cls]) {
|
|
26
|
+
el.style.backgroundPosition = bgPositions[cls];
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { display, layoutDirection, flexWrap, alignment, spacing } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyLayout(el, cls) {
|
|
4
|
+
if (display[cls]) {
|
|
5
|
+
el.style.display = display[cls];
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
if (layoutDirection[cls]) {
|
|
9
|
+
el.style.flexDirection = layoutDirection[cls];
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (flexWrap[cls]) {
|
|
13
|
+
el.style.flexWrap = flexWrap[cls];
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (alignment[cls]) {
|
|
17
|
+
if (cls.includes("items-")) el.style.alignItems = alignment[cls];
|
|
18
|
+
else if (cls.includes("justify-")) el.style.justifyContent = alignment[cls];
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (cls.startsWith("gap-")) {
|
|
22
|
+
const key = cls.split("-").pop();
|
|
23
|
+
if (spacing[key]) { el.style.gap = spacing[key]; return true; }
|
|
24
|
+
else if (!isNaN(key)) { el.style.gap = key + "px"; return true; }
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { positions, spacing } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyPosition(el, cls) {
|
|
4
|
+
if (positions[cls]) {
|
|
5
|
+
el.style.position = positions[cls];
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const offsets = ["top", "right", "bottom", "left"];
|
|
10
|
+
for (const side of offsets) {
|
|
11
|
+
if (cls.startsWith(`${side}-`)) {
|
|
12
|
+
const val = cls.split("-").pop();
|
|
13
|
+
if (spacing[val]) { el.style[side] = spacing[val]; }
|
|
14
|
+
else if (!isNaN(val)) { el.style[side] = val + "px"; }
|
|
15
|
+
else { el.style[side] = val; }
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { textSizing, textColor, typographyMisc } from "../values.js";
|
|
2
|
+
|
|
3
|
+
export function applyTypography(el, cls) {
|
|
4
|
+
// 1. Arbitrary values: text-[35px]
|
|
5
|
+
if (cls.startsWith("text-[") && cls.endsWith("]")) {
|
|
6
|
+
const value = cls.slice(6, -1).trim();
|
|
7
|
+
if (/^\d+(px|rem|em|vh|vw|%)$/.test(value)) {
|
|
8
|
+
el.style.fontSize = value;
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// 2. Font Sizing & Typography Misc
|
|
14
|
+
if (textSizing[cls]) {
|
|
15
|
+
el.style.fontSize = textSizing[cls];
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (typographyMisc[cls]) {
|
|
20
|
+
if (cls.includes("text-")) el.style.textAlign = typographyMisc[cls];
|
|
21
|
+
else if (cls.includes("font-")) el.style.fontWeight = typographyMisc[cls];
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 3. Text Color
|
|
26
|
+
if (textColor[cls]) {
|
|
27
|
+
el.style.color = textColor[cls];
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (cls.startsWith("text-")) {
|
|
32
|
+
const key = cls.replace("text-", "");
|
|
33
|
+
if (textSizing[key]) {
|
|
34
|
+
el.style.fontSize = textSizing[key];
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (textColor[key]) {
|
|
38
|
+
el.style.color = textColor[key];
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return false;
|
|
44
|
+
}
|