Skip to content

Commit 277296b

Browse files
committed
Update jkcss.runtime.js
1 parent e66695d commit 277296b

File tree

1 file changed

+79
-16
lines changed

1 file changed

+79
-16
lines changed

jkcss.runtime.js

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,105 @@
55
const allElements = document.querySelectorAll("*");
66

77
allElements.forEach(el => {
8-
el.classList.forEach(cls => {
8+
// Use Array.from because classList is a live collection and we'll mutate it
9+
Array.from(el.classList).forEach(cls => {
910
let prefix = null;
1011
let className = cls;
1112

12-
const matchPrefix = cls.match(/^([a-z]+):(.+)$/);
13+
// Detect responsive prefix (allow digits like 2xl)
14+
const matchPrefix = cls.match(/^([a-z0-9]+):(.+)$/i);
1315
if (matchPrefix) { prefix = matchPrefix[1]; className = matchPrefix[2]; }
1416

17+
// Background color (bracket form) e.g. bg-[#123456]
1518
const bgMatch = className.match(/^bg-\[#([0-9A-Fa-f]{3,6})\]$/);
1619
if (bgMatch) {
17-
const color = `#${bgMatch[1]}`;
18-
if (!prefix) el.style.backgroundColor = color;
19-
else applyResponsive(el, prefix, "backgroundColor", color);
20+
applyStyle(el, prefix, "backgroundColor", `#${bgMatch[1]}`);
21+
return;
2022
}
2123

24+
// Text color (bracket form) e.g. text-[#123456]
2225
const textMatch = className.match(/^text-\[#([0-9A-Fa-f]{3,6})\]$/);
2326
if (textMatch) {
24-
const color = `#${textMatch[1]}`;
25-
if (!prefix) el.style.color = color;
26-
else applyResponsive(el, prefix, "color", color);
27+
applyStyle(el, prefix, "color", `#${textMatch[1]}`);
28+
return;
2729
}
30+
31+
// Padding classes (bracket form) p-[20px], pt-[10px], etc.
32+
const paddingMatch = className.match(/^p([trbl]?)-\[(.+)\]$/);
33+
if (paddingMatch) {
34+
const dir = paddingMatch[1];
35+
const value = paddingMatch[2];
36+
const prop = getSpacingProperty("padding", dir);
37+
applyStyle(el, prefix, prop, value);
38+
return;
39+
}
40+
41+
// Margin classes (bracket form) m-[10px], mt-[5px], etc.
42+
const marginMatch = className.match(/^m([trbl]?)-\[(.+)\]$/);
43+
if (marginMatch) {
44+
const dir = marginMatch[1];
45+
const value = marginMatch[2];
46+
const prop = getSpacingProperty("margin", dir);
47+
applyStyle(el, prefix, prop, value);
48+
return;
49+
}
50+
51+
// If there's a prefix and this is a normal utility like text-blue-500 / bg-red-500 etc.
52+
if (prefix) {
53+
const width = breakpoints[prefix];
54+
if (!width) return; // unknown prefix (skip)
55+
56+
const mql = window.matchMedia(`(min-width: ${width}px)`);
57+
const update = e => {
58+
// When matches, ensure the unprefixed utility is present; otherwise remove it.
59+
if (e.matches) {
60+
if (!el.classList.contains(className)) el.classList.add(className);
61+
} else {
62+
if (el.classList.contains(className)) el.classList.remove(className);
63+
}
64+
};
65+
// run once to set initial state
66+
update(mql);
67+
// listen for changes (modern and fallback)
68+
if (mql.addEventListener) mql.addEventListener("change", update);
69+
else if (mql.addListener) mql.addListener(update);
70+
return;
71+
}
72+
73+
// No prefix and no bracketed handler -> nothing to do here (regular classes come from CSS)
2874
});
2975
});
3076
}
3177

32-
function applyResponsive(el, prefix, prop, value) {
33-
const width = breakpoints[prefix];
34-
if (!width) return;
78+
function getSpacingProperty(type, dir) {
79+
switch (dir) {
80+
case "t": return `${type}Top`;
81+
case "b": return `${type}Bottom`;
82+
case "l": return `${type}Left`;
83+
case "r": return `${type}Right`;
84+
case "": return type; // p-[16px] or m-[16px]
85+
default: return type;
86+
}
87+
}
3588

36-
const mql = window.matchMedia(`(min-width: ${width}px)`);
37-
const applyStyle = e => { if (e.matches) el.style[prop] = value; else el.style[prop] = ""; };
89+
function applyStyle(el, prefix, prop, value) {
90+
if (!prefix) {
91+
el.style[prop] = value;
92+
} else {
93+
const width = breakpoints[prefix];
94+
if (!width) return;
3895

39-
mql.addEventListener("change", applyStyle);
40-
applyStyle(mql);
96+
const mql = window.matchMedia(`(min-width: ${width}px)`);
97+
const update = e => { if (e.matches) el.style[prop] = value; else el.style[prop] = ""; };
98+
update(mql);
99+
if (mql.addEventListener) mql.addEventListener("change", update);
100+
else if (mql.addListener) mql.addListener(update);
101+
}
41102
}
42103

43104
if (document.readyState === "loading") {
44105
document.addEventListener("DOMContentLoaded", applyDynamicClasses);
45-
} else { applyDynamicClasses(); }
106+
} else {
107+
applyDynamicClasses();
108+
}
46109
})();

0 commit comments

Comments
 (0)