tadka-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/LICENSE +21 -0
- package/README.md +154 -0
- package/dist/tadka-css.cjs.js +1385 -0
- package/dist/tadka-css.cjs.js.map +1 -0
- package/dist/tadka-css.esm.js +1383 -0
- package/dist/tadka-css.esm.js.map +1 -0
- package/dist/tadka-css.js +1391 -0
- package/dist/tadka-css.js.map +1 -0
- package/dist/tadka-css.min.js +1 -0
- package/package.json +45 -0
- package/types/index.d.ts +45 -0
|
@@ -0,0 +1,1385 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const BREAKPOINTS = {
|
|
4
|
+
sm: "640px",
|
|
5
|
+
md: "768px",
|
|
6
|
+
lg: "1024px",
|
|
7
|
+
xl: "1280px",
|
|
8
|
+
"2xl": "1536px",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const SCALE = {
|
|
12
|
+
0: 0,
|
|
13
|
+
0.5: 0.125,
|
|
14
|
+
1: 0.25,
|
|
15
|
+
1.5: 0.375,
|
|
16
|
+
2: 0.5,
|
|
17
|
+
2.5: 0.625,
|
|
18
|
+
3: 0.75,
|
|
19
|
+
3.5: 0.875,
|
|
20
|
+
4: 1,
|
|
21
|
+
5: 1.25,
|
|
22
|
+
6: 1.5,
|
|
23
|
+
7: 1.75,
|
|
24
|
+
8: 2,
|
|
25
|
+
9: 2.25,
|
|
26
|
+
10: 2.5,
|
|
27
|
+
11: 2.75,
|
|
28
|
+
12: 3,
|
|
29
|
+
14: 3.5,
|
|
30
|
+
16: 4,
|
|
31
|
+
20: 5,
|
|
32
|
+
24: 6,
|
|
33
|
+
28: 7,
|
|
34
|
+
32: 8,
|
|
35
|
+
36: 9,
|
|
36
|
+
40: 10,
|
|
37
|
+
44: 11,
|
|
38
|
+
48: 12,
|
|
39
|
+
52: 13,
|
|
40
|
+
56: 14,
|
|
41
|
+
60: 15,
|
|
42
|
+
64: 16,
|
|
43
|
+
72: 18,
|
|
44
|
+
80: 20,
|
|
45
|
+
96: 24,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function clamp(value, min, max) {
|
|
49
|
+
return Math.min(max, Math.max(min, value));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function hslToHex(h, s, l) {
|
|
53
|
+
s /= 100;
|
|
54
|
+
l /= 100;
|
|
55
|
+
const a = s * Math.min(l, 1 - l);
|
|
56
|
+
const f = (n) => {
|
|
57
|
+
const k = (n + h / 30) % 12;
|
|
58
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
59
|
+
return Math.round(255 * color)
|
|
60
|
+
.toString(16)
|
|
61
|
+
.padStart(2, "0");
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return `#${f(0)}${f(8)}${f(4)}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createShades(hue, saturation = 70) {
|
|
68
|
+
const levels = {
|
|
69
|
+
50: 97,
|
|
70
|
+
100: 93,
|
|
71
|
+
200: 86,
|
|
72
|
+
300: 76,
|
|
73
|
+
400: 64,
|
|
74
|
+
500: 54,
|
|
75
|
+
600: 46,
|
|
76
|
+
700: 39,
|
|
77
|
+
800: 31,
|
|
78
|
+
900: 24,
|
|
79
|
+
950: 16,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return Object.fromEntries(
|
|
83
|
+
Object.entries(levels).map(([key, lightness]) => [
|
|
84
|
+
key,
|
|
85
|
+
hslToHex(hue, clamp(saturation, 25, 90), lightness),
|
|
86
|
+
]),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function createDefaultPalette() {
|
|
91
|
+
return {
|
|
92
|
+
slate: createShades(220, 18),
|
|
93
|
+
gray: createShades(220, 8),
|
|
94
|
+
zinc: createShades(240, 8),
|
|
95
|
+
neutral: createShades(30, 7),
|
|
96
|
+
stone: createShades(28, 14),
|
|
97
|
+
red: createShades(2, 80),
|
|
98
|
+
orange: createShades(24, 85),
|
|
99
|
+
amber: createShades(39, 90),
|
|
100
|
+
yellow: createShades(52, 88),
|
|
101
|
+
lime: createShades(79, 70),
|
|
102
|
+
green: createShades(140, 62),
|
|
103
|
+
emerald: createShades(160, 65),
|
|
104
|
+
teal: createShades(176, 70),
|
|
105
|
+
cyan: createShades(190, 78),
|
|
106
|
+
sky: createShades(205, 85),
|
|
107
|
+
blue: createShades(220, 88),
|
|
108
|
+
indigo: createShades(240, 76),
|
|
109
|
+
violet: createShades(262, 77),
|
|
110
|
+
purple: createShades(276, 75),
|
|
111
|
+
fuchsia: createShades(300, 76),
|
|
112
|
+
pink: createShades(336, 84),
|
|
113
|
+
rose: createShades(348, 84),
|
|
114
|
+
white: "#ffffff",
|
|
115
|
+
black: "#000000",
|
|
116
|
+
transparent: "transparent",
|
|
117
|
+
inherit: "inherit",
|
|
118
|
+
current: "currentColor",
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const defaultConfig = {
|
|
123
|
+
prefix: "tadka",
|
|
124
|
+
scale: 4,
|
|
125
|
+
removeClasses: false,
|
|
126
|
+
watch: true,
|
|
127
|
+
breakpoints: BREAKPOINTS,
|
|
128
|
+
spacingScale: SCALE,
|
|
129
|
+
colors: createDefaultPalette(),
|
|
130
|
+
extend: {},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
function deepMerge(base, next) {
|
|
134
|
+
const output = { ...base };
|
|
135
|
+
for (const [key, value] of Object.entries(next || {})) {
|
|
136
|
+
if (
|
|
137
|
+
value &&
|
|
138
|
+
typeof value === "object" &&
|
|
139
|
+
!Array.isArray(value) &&
|
|
140
|
+
base[key] &&
|
|
141
|
+
typeof base[key] === "object" &&
|
|
142
|
+
!Array.isArray(base[key])
|
|
143
|
+
) {
|
|
144
|
+
output[key] = deepMerge(base[key], value);
|
|
145
|
+
} else {
|
|
146
|
+
output[key] = value;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return output;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function createConfig(options = {}) {
|
|
153
|
+
return deepMerge(defaultConfig, options);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const pseudoState = new WeakMap();
|
|
157
|
+
|
|
158
|
+
function getHandlers(el) {
|
|
159
|
+
if (!pseudoState.has(el)) pseudoState.set(el, new Map());
|
|
160
|
+
return pseudoState.get(el);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function setStyles(el, styles, apply) {
|
|
164
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
165
|
+
if (apply) {
|
|
166
|
+
el.style[key] = value;
|
|
167
|
+
} else {
|
|
168
|
+
el.style[key] = "";
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function attachPseudoListener(el, parsed) {
|
|
174
|
+
const map = getHandlers(el);
|
|
175
|
+
const key = `${parsed.pseudo}:${parsed.token}`;
|
|
176
|
+
if (map.has(key)) return;
|
|
177
|
+
|
|
178
|
+
let on;
|
|
179
|
+
let off;
|
|
180
|
+
|
|
181
|
+
if (parsed.pseudo === "hover") {
|
|
182
|
+
on = () => setStyles(el, parsed.styles, true);
|
|
183
|
+
off = () => setStyles(el, parsed.styles, false);
|
|
184
|
+
el.addEventListener("mouseenter", on);
|
|
185
|
+
el.addEventListener("mouseleave", off);
|
|
186
|
+
} else if (parsed.pseudo === "focus") {
|
|
187
|
+
on = () => setStyles(el, parsed.styles, true);
|
|
188
|
+
off = () => setStyles(el, parsed.styles, false);
|
|
189
|
+
el.addEventListener("focus", on);
|
|
190
|
+
el.addEventListener("blur", off);
|
|
191
|
+
} else if (parsed.pseudo === "active") {
|
|
192
|
+
on = () => setStyles(el, parsed.styles, true);
|
|
193
|
+
off = () => setStyles(el, parsed.styles, false);
|
|
194
|
+
el.addEventListener("mousedown", on);
|
|
195
|
+
el.addEventListener("mouseup", off);
|
|
196
|
+
el.addEventListener("mouseleave", off);
|
|
197
|
+
} else if (parsed.pseudo === "disabled") {
|
|
198
|
+
if (el.hasAttribute("disabled")) setStyles(el, parsed.styles, true);
|
|
199
|
+
} else if (parsed.pseudo === "checked") {
|
|
200
|
+
const sync = () => setStyles(el, parsed.styles, Boolean(el.checked));
|
|
201
|
+
sync();
|
|
202
|
+
el.addEventListener("change", sync);
|
|
203
|
+
on = sync;
|
|
204
|
+
off = null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
map.set(key, { on, off, pseudo: parsed.pseudo });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function clearPseudoListeners(root = document) {
|
|
211
|
+
const nodes = root.querySelectorAll("*");
|
|
212
|
+
nodes.forEach((el) => {
|
|
213
|
+
const map = pseudoState.get(el);
|
|
214
|
+
if (!map) return;
|
|
215
|
+
|
|
216
|
+
for (const entry of map.values()) {
|
|
217
|
+
if (entry.pseudo === "hover") {
|
|
218
|
+
el.removeEventListener("mouseenter", entry.on);
|
|
219
|
+
el.removeEventListener("mouseleave", entry.off);
|
|
220
|
+
} else if (entry.pseudo === "focus") {
|
|
221
|
+
el.removeEventListener("focus", entry.on);
|
|
222
|
+
el.removeEventListener("blur", entry.off);
|
|
223
|
+
} else if (entry.pseudo === "active") {
|
|
224
|
+
el.removeEventListener("mousedown", entry.on);
|
|
225
|
+
el.removeEventListener("mouseup", entry.off);
|
|
226
|
+
el.removeEventListener("mouseleave", entry.off);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
map.clear();
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function toKebab(str) {
|
|
235
|
+
return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function isArbitrary(value) {
|
|
239
|
+
return /^\[.+\]$/.test(value);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function readArbitrary(value) {
|
|
243
|
+
if (!isArbitrary(value)) return null;
|
|
244
|
+
return value.slice(1, -1).replace(/_/g, " ");
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function parseNumberish(value) {
|
|
248
|
+
const num = Number(value);
|
|
249
|
+
return Number.isFinite(num) ? num : null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function resolveScaleValue(raw, scaleMap) {
|
|
253
|
+
if (raw in scaleMap) return `${scaleMap[raw]}rem`;
|
|
254
|
+
const num = parseNumberish(raw);
|
|
255
|
+
if (num === null) return null;
|
|
256
|
+
return `${num * 0.25}rem`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function normalizeClassName(className) {
|
|
260
|
+
return className.trim().replace(/\s+/g, " ");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
let styleSheet = null;
|
|
264
|
+
let idCounter = 0;
|
|
265
|
+
const inserted = new Set();
|
|
266
|
+
|
|
267
|
+
function ensureSheet() {
|
|
268
|
+
if (styleSheet) return styleSheet;
|
|
269
|
+
const style = document.createElement("style");
|
|
270
|
+
style.id = "tadka-responsive";
|
|
271
|
+
document.head.appendChild(style);
|
|
272
|
+
styleSheet = style.sheet;
|
|
273
|
+
return styleSheet;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function toStyleBlock(styles) {
|
|
277
|
+
return Object.entries(styles)
|
|
278
|
+
.map(([property, value]) => `${toKebab(property)}: ${value}`)
|
|
279
|
+
.join("; ");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function injectMediaQuery(el, parsed, config) {
|
|
283
|
+
const sheet = ensureSheet();
|
|
284
|
+
|
|
285
|
+
if (!el.dataset.tadkaId) {
|
|
286
|
+
idCounter += 1;
|
|
287
|
+
el.dataset.tadkaId = `tadka-${idCounter}`;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const selector = `[data-tadka-id='${el.dataset.tadkaId}']`;
|
|
291
|
+
const declarations = toStyleBlock(parsed.styles);
|
|
292
|
+
const minWidth = config.breakpoints[parsed.breakpoint];
|
|
293
|
+
const rule = `@media (min-width: ${minWidth}) { ${selector} { ${declarations} } }`;
|
|
294
|
+
|
|
295
|
+
if (inserted.has(rule)) return;
|
|
296
|
+
inserted.add(rule);
|
|
297
|
+
sheet.insertRule(rule, sheet.cssRules.length);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function resetResponsiveStyles() {
|
|
301
|
+
inserted.clear();
|
|
302
|
+
idCounter = 0;
|
|
303
|
+
if (!styleSheet) return;
|
|
304
|
+
|
|
305
|
+
const owner = styleSheet.ownerNode;
|
|
306
|
+
owner?.parentNode?.removeChild(owner);
|
|
307
|
+
styleSheet = null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const originalStyleMap = new WeakMap();
|
|
311
|
+
|
|
312
|
+
function rememberOriginalStyle(el) {
|
|
313
|
+
if (!originalStyleMap.has(el)) {
|
|
314
|
+
originalStyleMap.set(el, el.getAttribute("style") || "");
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function applyInlineStyles(el, styles) {
|
|
319
|
+
rememberOriginalStyle(el);
|
|
320
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
321
|
+
el.style[key] = value;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function createEngine(config, parseClass, eventBus) {
|
|
326
|
+
const prefix = config.prefix;
|
|
327
|
+
|
|
328
|
+
function processElement(el) {
|
|
329
|
+
if (!el?.classList) return false;
|
|
330
|
+
|
|
331
|
+
const classes = [...el.classList].filter((cls) => cls === prefix || cls.startsWith(`${prefix}-`));
|
|
332
|
+
if (classes.length === 0) return false;
|
|
333
|
+
|
|
334
|
+
for (const cls of classes) {
|
|
335
|
+
const parsed = parseClass(cls);
|
|
336
|
+
|
|
337
|
+
if (parsed.type === "style") {
|
|
338
|
+
applyInlineStyles(el, parsed.styles);
|
|
339
|
+
} else if (parsed.type === "responsive") {
|
|
340
|
+
injectMediaQuery(el, parsed, config);
|
|
341
|
+
} else if (parsed.type === "pseudo") {
|
|
342
|
+
attachPseudoListener(el, parsed);
|
|
343
|
+
} else if (parsed.type === "unknown") {
|
|
344
|
+
eventBus.emit("parse-error", { className: cls });
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
eventBus.emit("apply", { element: el, className: cls, styles: parsed.styles || null });
|
|
348
|
+
if (config.removeClasses) el.classList.remove(cls);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function scanAndApply(root = document) {
|
|
355
|
+
const selector = `[class*='${prefix}-']`;
|
|
356
|
+
const candidates = root.matches?.(selector) ? [root, ...root.querySelectorAll(selector)] : [...root.querySelectorAll(selector)];
|
|
357
|
+
let count = 0;
|
|
358
|
+
|
|
359
|
+
candidates.forEach((el) => {
|
|
360
|
+
if (processElement(el)) count += 1;
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
return count;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function reset(root = document) {
|
|
367
|
+
const nodes = root.querySelectorAll("*");
|
|
368
|
+
nodes.forEach((el) => {
|
|
369
|
+
if (!originalStyleMap.has(el)) return;
|
|
370
|
+
const original = originalStyleMap.get(el);
|
|
371
|
+
if (original) {
|
|
372
|
+
el.setAttribute("style", original);
|
|
373
|
+
} else {
|
|
374
|
+
el.removeAttribute("style");
|
|
375
|
+
}
|
|
376
|
+
originalStyleMap.delete(el);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
clearPseudoListeners(root);
|
|
380
|
+
resetResponsiveStyles();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
scanAndApply,
|
|
385
|
+
apply: processElement,
|
|
386
|
+
reset,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function createEventBus() {
|
|
391
|
+
const handlers = new Map();
|
|
392
|
+
|
|
393
|
+
return {
|
|
394
|
+
on(event, handler) {
|
|
395
|
+
if (!handlers.has(event)) handlers.set(event, new Set());
|
|
396
|
+
handlers.get(event).add(handler);
|
|
397
|
+
return () => handlers.get(event)?.delete(handler);
|
|
398
|
+
},
|
|
399
|
+
emit(event, payload) {
|
|
400
|
+
const set = handlers.get(event);
|
|
401
|
+
if (!set) return;
|
|
402
|
+
for (const handler of set) {
|
|
403
|
+
try {
|
|
404
|
+
handler(payload);
|
|
405
|
+
} catch {
|
|
406
|
+
// Event listeners should never crash the engine.
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
clear() {
|
|
411
|
+
handlers.clear();
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function watchDOM(scanAndApply) {
|
|
417
|
+
const observer = new MutationObserver((mutations) => {
|
|
418
|
+
for (const mutation of mutations) {
|
|
419
|
+
if (mutation.type === "attributes" && mutation.target?.nodeType === Node.ELEMENT_NODE) {
|
|
420
|
+
scanAndApply(mutation.target);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
for (const node of mutation.addedNodes) {
|
|
424
|
+
if (node.nodeType !== Node.ELEMENT_NODE) continue;
|
|
425
|
+
scanAndApply(node);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
observer.observe(document.body, {
|
|
431
|
+
childList: true,
|
|
432
|
+
subtree: true,
|
|
433
|
+
attributes: true,
|
|
434
|
+
attributeFilter: ["class"],
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
return observer;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const animationMap = {
|
|
441
|
+
"animate-none": "none",
|
|
442
|
+
"animate-spin": "tadka-spin 1s linear infinite",
|
|
443
|
+
"animate-ping": "tadka-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite",
|
|
444
|
+
"animate-pulse": "tadka-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
|
|
445
|
+
"animate-bounce": "tadka-bounce 1s infinite",
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
let injected = false;
|
|
449
|
+
|
|
450
|
+
function ensureAnimationKeyframes() {
|
|
451
|
+
if (injected || typeof document === "undefined") return;
|
|
452
|
+
const style = document.createElement("style");
|
|
453
|
+
style.id = "tadka-keyframes";
|
|
454
|
+
style.textContent = `
|
|
455
|
+
@keyframes tadka-spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }
|
|
456
|
+
@keyframes tadka-ping { 75%, 100% { transform: scale(2); opacity: 0; } }
|
|
457
|
+
@keyframes tadka-pulse { 50% { opacity: .5; } }
|
|
458
|
+
@keyframes tadka-bounce {
|
|
459
|
+
0%,100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(.8,0,1,1); }
|
|
460
|
+
50% { transform: none; animation-timing-function: cubic-bezier(0,0,.2,1); }
|
|
461
|
+
}`;
|
|
462
|
+
document.head.appendChild(style);
|
|
463
|
+
injected = true;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function resolveAnimations(token) {
|
|
467
|
+
if (!animationMap[token]) return null;
|
|
468
|
+
ensureAnimationKeyframes();
|
|
469
|
+
return { animation: animationMap[token] };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const radiusMap = {
|
|
473
|
+
none: "0px",
|
|
474
|
+
sm: "0.125rem",
|
|
475
|
+
DEFAULT: "0.25rem",
|
|
476
|
+
md: "0.375rem",
|
|
477
|
+
lg: "0.5rem",
|
|
478
|
+
xl: "0.75rem",
|
|
479
|
+
"2xl": "1rem",
|
|
480
|
+
"3xl": "1.5rem",
|
|
481
|
+
full: "9999px",
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
function resolveBorders(token) {
|
|
485
|
+
if (token === "border") return { borderWidth: "1px", borderStyle: "solid" };
|
|
486
|
+
if (token.startsWith("border-")) {
|
|
487
|
+
const value = token.slice(7);
|
|
488
|
+
const styleSet = new Set(["solid", "dashed", "dotted", "double", "hidden", "none"]);
|
|
489
|
+
if (styleSet.has(value)) return { borderStyle: value };
|
|
490
|
+
const n = parseNumberish(value);
|
|
491
|
+
if (n !== null) return { borderWidth: `${n}px`, borderStyle: "solid" };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (token === "rounded") return { borderRadius: radiusMap.DEFAULT };
|
|
495
|
+
if (token.startsWith("rounded-")) {
|
|
496
|
+
const key = token.slice(8);
|
|
497
|
+
if (radiusMap[key]) return { borderRadius: radiusMap[key] };
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (token.startsWith("ring-")) {
|
|
501
|
+
const size = parseNumberish(token.slice(5));
|
|
502
|
+
if (size !== null) {
|
|
503
|
+
return { boxShadow: `0 0 0 ${size}px var(--tadka-ring-color, rgba(59,130,246,0.5))` };
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (token === "outline-none") {
|
|
508
|
+
return { outline: "2px solid transparent", outlineOffset: "2px" };
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function resolvePaletteColor(colors, colorName, shade) {
|
|
515
|
+
const entry = colors[colorName];
|
|
516
|
+
if (!entry) return null;
|
|
517
|
+
if (typeof entry === "string") return entry;
|
|
518
|
+
if (!shade) return entry[500] || null;
|
|
519
|
+
return entry[shade] || null;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function parseColorParts(input) {
|
|
523
|
+
if (isArbitrary(input)) {
|
|
524
|
+
return { value: readArbitrary(input) };
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const [name, maybeShade] = input.split("-");
|
|
528
|
+
return { name, shade: maybeShade };
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const colorProps = {
|
|
532
|
+
bg: "backgroundColor",
|
|
533
|
+
text: "color",
|
|
534
|
+
border: "borderColor",
|
|
535
|
+
accent: "accentColor",
|
|
536
|
+
caret: "caretColor",
|
|
537
|
+
fill: "fill",
|
|
538
|
+
stroke: "stroke",
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
function resolveColors(token, config) {
|
|
542
|
+
if (token.startsWith("from-")) {
|
|
543
|
+
const payload = token.slice(5);
|
|
544
|
+
const parsed = parseColorParts(payload);
|
|
545
|
+
const color = parsed.value || resolvePaletteColor(config.colors, parsed.name, parsed.shade);
|
|
546
|
+
if (!color) return null;
|
|
547
|
+
return {
|
|
548
|
+
"--tadka-gradient-from": color,
|
|
549
|
+
"--tadka-gradient-to": "rgba(255,255,255,0)",
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (token.startsWith("to-")) {
|
|
554
|
+
const payload = token.slice(3);
|
|
555
|
+
const parsed = parseColorParts(payload);
|
|
556
|
+
const color = parsed.value || resolvePaletteColor(config.colors, parsed.name, parsed.shade);
|
|
557
|
+
if (!color) return null;
|
|
558
|
+
return { "--tadka-gradient-to": color };
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
for (const [prefix, property] of Object.entries(colorProps)) {
|
|
562
|
+
if (!token.startsWith(`${prefix}-`)) continue;
|
|
563
|
+
const colorRaw = token.slice(prefix.length + 1);
|
|
564
|
+
const parsed = parseColorParts(colorRaw);
|
|
565
|
+
|
|
566
|
+
if (parsed.value) return { [property]: parsed.value };
|
|
567
|
+
|
|
568
|
+
const color = resolvePaletteColor(config.colors, parsed.name, parsed.shade);
|
|
569
|
+
if (!color) return null;
|
|
570
|
+
return { [property]: color };
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
if (token.startsWith("bg-opacity-")) {
|
|
574
|
+
const value = parseNumberish(token.replace("bg-opacity-", ""));
|
|
575
|
+
if (value === null) return null;
|
|
576
|
+
return { "--tadka-bg-opacity": `${Math.max(0, Math.min(100, value)) / 100}` };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (token.startsWith("text-opacity-")) {
|
|
580
|
+
const value = parseNumberish(token.replace("text-opacity-", ""));
|
|
581
|
+
if (value === null) return null;
|
|
582
|
+
return { "--tadka-text-opacity": `${Math.max(0, Math.min(100, value)) / 100}` };
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
if (token.startsWith("ring-")) {
|
|
586
|
+
const payload = token.slice(5);
|
|
587
|
+
const parsed = parseColorParts(payload);
|
|
588
|
+
if (parsed.value) return { "--tadka-ring-color": parsed.value };
|
|
589
|
+
const color = resolvePaletteColor(config.colors, parsed.name, parsed.shade);
|
|
590
|
+
if (!color) return null;
|
|
591
|
+
return { "--tadka-ring-color": color };
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const shadowMap = {
|
|
598
|
+
"shadow-none": "none",
|
|
599
|
+
"shadow-sm": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
600
|
+
shadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
|
|
601
|
+
"shadow-md": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
602
|
+
"shadow-lg": "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
603
|
+
"shadow-xl": "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
|
|
604
|
+
"shadow-2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
|
|
605
|
+
"shadow-inner": "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
const blurMap = {
|
|
609
|
+
"blur-none": "blur(0)",
|
|
610
|
+
"blur-sm": "blur(4px)",
|
|
611
|
+
blur: "blur(8px)",
|
|
612
|
+
"blur-md": "blur(12px)",
|
|
613
|
+
"blur-lg": "blur(16px)",
|
|
614
|
+
"blur-xl": "blur(24px)",
|
|
615
|
+
"blur-2xl": "blur(40px)",
|
|
616
|
+
"blur-3xl": "blur(64px)",
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
function resolveEffects(token) {
|
|
620
|
+
if (token === "bg-gradient-to-r") {
|
|
621
|
+
return {
|
|
622
|
+
backgroundImage: "linear-gradient(to right, var(--tadka-gradient-from), var(--tadka-gradient-to))",
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (token.startsWith("opacity-")) {
|
|
627
|
+
const n = parseNumberish(token.slice(8));
|
|
628
|
+
if (n === null) return null;
|
|
629
|
+
return { opacity: `${Math.max(0, Math.min(100, n)) / 100}` };
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (shadowMap[token]) return { boxShadow: shadowMap[token] };
|
|
633
|
+
if (blurMap[token]) return { filter: blurMap[token] };
|
|
634
|
+
|
|
635
|
+
if (token.startsWith("brightness-")) {
|
|
636
|
+
const n = parseNumberish(token.slice(11));
|
|
637
|
+
if (n === null) return null;
|
|
638
|
+
return { filter: `brightness(${n / 100})` };
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if (token.startsWith("contrast-")) {
|
|
642
|
+
const n = parseNumberish(token.slice(9));
|
|
643
|
+
if (n === null) return null;
|
|
644
|
+
return { filter: `contrast(${n / 100})` };
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
if (token === "grayscale") return { filter: "grayscale(100%)" };
|
|
648
|
+
if (token === "grayscale-0") return { filter: "grayscale(0%)" };
|
|
649
|
+
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
const displayMap = {
|
|
654
|
+
block: "block",
|
|
655
|
+
"inline-block": "inline-block",
|
|
656
|
+
inline: "inline",
|
|
657
|
+
flex: "flex",
|
|
658
|
+
"inline-flex": "inline-flex",
|
|
659
|
+
grid: "grid",
|
|
660
|
+
hidden: "none",
|
|
661
|
+
contents: "contents",
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
function resolveLayout(token, config) {
|
|
665
|
+
if (displayMap[token]) return { display: displayMap[token] };
|
|
666
|
+
|
|
667
|
+
const flexDirection = {
|
|
668
|
+
"flex-row": "row",
|
|
669
|
+
"flex-col": "column",
|
|
670
|
+
"flex-row-reverse": "row-reverse",
|
|
671
|
+
"flex-col-reverse": "column-reverse",
|
|
672
|
+
};
|
|
673
|
+
if (flexDirection[token]) return { display: "flex", flexDirection: flexDirection[token] };
|
|
674
|
+
|
|
675
|
+
const justifyMap = {
|
|
676
|
+
"justify-start": "flex-start",
|
|
677
|
+
"justify-end": "flex-end",
|
|
678
|
+
"justify-center": "center",
|
|
679
|
+
"justify-between": "space-between",
|
|
680
|
+
"justify-around": "space-around",
|
|
681
|
+
"justify-evenly": "space-evenly",
|
|
682
|
+
};
|
|
683
|
+
if (justifyMap[token]) return { justifyContent: justifyMap[token] };
|
|
684
|
+
|
|
685
|
+
const itemsMap = {
|
|
686
|
+
"items-start": "flex-start",
|
|
687
|
+
"items-end": "flex-end",
|
|
688
|
+
"items-center": "center",
|
|
689
|
+
"items-baseline": "baseline",
|
|
690
|
+
"items-stretch": "stretch",
|
|
691
|
+
};
|
|
692
|
+
if (itemsMap[token]) return { alignItems: itemsMap[token] };
|
|
693
|
+
|
|
694
|
+
if (token.startsWith("grid-cols-")) {
|
|
695
|
+
const v = token.replace("grid-cols-", "");
|
|
696
|
+
const n = parseNumberish(v);
|
|
697
|
+
if (n !== null) return { display: "grid", gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` };
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if (token.startsWith("grid-rows-")) {
|
|
701
|
+
const v = token.replace("grid-rows-", "");
|
|
702
|
+
const n = parseNumberish(v);
|
|
703
|
+
if (n !== null) return { display: "grid", gridTemplateRows: `repeat(${n}, minmax(0, 1fr))` };
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (token.startsWith("basis-")) {
|
|
707
|
+
const value = token.replace("basis-", "");
|
|
708
|
+
if (value === "full") return { flexBasis: "100%" };
|
|
709
|
+
if (value === "auto") return { flexBasis: "auto" };
|
|
710
|
+
const scaled = resolveScaleValue(value, config.spacingScale);
|
|
711
|
+
if (scaled) return { flexBasis: scaled };
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (token === "flex-1") return { flex: "1 1 0%" };
|
|
715
|
+
if (token === "flex-auto") return { flex: "1 1 auto" };
|
|
716
|
+
if (token === "flex-none") return { flex: "none" };
|
|
717
|
+
if (token === "flex-wrap") return { flexWrap: "wrap" };
|
|
718
|
+
if (token === "flex-nowrap") return { flexWrap: "nowrap" };
|
|
719
|
+
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function resolveOverflow(token, config) {
|
|
724
|
+
const direct = {
|
|
725
|
+
"overflow-auto": { overflow: "auto" },
|
|
726
|
+
"overflow-hidden": { overflow: "hidden" },
|
|
727
|
+
"overflow-visible": { overflow: "visible" },
|
|
728
|
+
"overflow-scroll": { overflow: "scroll" },
|
|
729
|
+
"overflow-clip": { overflow: "clip" },
|
|
730
|
+
"overflow-x-auto": { overflowX: "auto" },
|
|
731
|
+
"overflow-x-hidden": { overflowX: "hidden" },
|
|
732
|
+
"overflow-x-scroll": { overflowX: "scroll" },
|
|
733
|
+
"overflow-y-auto": { overflowY: "auto" },
|
|
734
|
+
"overflow-y-hidden": { overflowY: "hidden" },
|
|
735
|
+
"overflow-y-scroll": { overflowY: "scroll" },
|
|
736
|
+
"scroll-smooth": { scrollBehavior: "smooth" },
|
|
737
|
+
"scroll-auto": { scrollBehavior: "auto" },
|
|
738
|
+
"cursor-pointer": { cursor: "pointer" },
|
|
739
|
+
"cursor-default": { cursor: "default" },
|
|
740
|
+
"cursor-text": { cursor: "text" },
|
|
741
|
+
"cursor-not-allowed": { cursor: "not-allowed" },
|
|
742
|
+
"select-none": { userSelect: "none" },
|
|
743
|
+
"select-text": { userSelect: "text" },
|
|
744
|
+
"pointer-events-none": { pointerEvents: "none" },
|
|
745
|
+
"pointer-events-auto": { pointerEvents: "auto" },
|
|
746
|
+
resize: { resize: "both" },
|
|
747
|
+
"resize-x": { resize: "horizontal" },
|
|
748
|
+
"resize-y": { resize: "vertical" },
|
|
749
|
+
"resize-none": { resize: "none" },
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
if (direct[token]) return direct[token];
|
|
753
|
+
|
|
754
|
+
if (token.startsWith("scroll-p-")) {
|
|
755
|
+
const raw = token.slice(9);
|
|
756
|
+
const val = resolveScaleValue(raw, config.spacingScale);
|
|
757
|
+
if (val) return { scrollPadding: val };
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (token.startsWith("scroll-m-")) {
|
|
761
|
+
const raw = token.slice(9);
|
|
762
|
+
const val = resolveScaleValue(raw, config.spacingScale);
|
|
763
|
+
if (val) return { scrollMargin: val };
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (token.startsWith("z-")) {
|
|
767
|
+
const n = parseNumberish(token.slice(2));
|
|
768
|
+
if (n !== null) return { zIndex: `${n}` };
|
|
769
|
+
}
|
|
770
|
+
if (token === "z-auto") return { zIndex: "auto" };
|
|
771
|
+
|
|
772
|
+
return null;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const posMap = {
|
|
776
|
+
static: "static",
|
|
777
|
+
relative: "relative",
|
|
778
|
+
absolute: "absolute",
|
|
779
|
+
fixed: "fixed",
|
|
780
|
+
sticky: "sticky",
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
const floatMap = {
|
|
784
|
+
"float-left": "left",
|
|
785
|
+
"float-right": "right",
|
|
786
|
+
"float-none": "none",
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
function resolvePositioning(token, config) {
|
|
790
|
+
if (posMap[token]) return { position: posMap[token] };
|
|
791
|
+
if (floatMap[token]) return { float: floatMap[token] };
|
|
792
|
+
|
|
793
|
+
const sides = ["top", "right", "bottom", "left"];
|
|
794
|
+
for (const side of sides) {
|
|
795
|
+
if (!token.startsWith(`${side}-`)) continue;
|
|
796
|
+
const raw = token.slice(side.length + 1);
|
|
797
|
+
if (raw === "auto") return { [side]: "auto" };
|
|
798
|
+
if (raw === "full") return { [side]: "100%" };
|
|
799
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
800
|
+
if (value) return { [side]: value };
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (token.startsWith("inset-")) {
|
|
804
|
+
const raw = token.slice(6);
|
|
805
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
806
|
+
if (value) return { inset: value };
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
if (token.startsWith("inset-x-")) {
|
|
810
|
+
const raw = token.slice(8);
|
|
811
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
812
|
+
if (value) return { left: value, right: value };
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
if (token.startsWith("inset-y-")) {
|
|
816
|
+
const raw = token.slice(8);
|
|
817
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
818
|
+
if (value) return { top: value, bottom: value };
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (token === "isolate") return { isolation: "isolate" };
|
|
822
|
+
if (token === "isolation-auto") return { isolation: "auto" };
|
|
823
|
+
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const fractionMap = {
|
|
828
|
+
"1/2": "50%",
|
|
829
|
+
"1/3": "33.333333%",
|
|
830
|
+
"2/3": "66.666667%",
|
|
831
|
+
"1/4": "25%",
|
|
832
|
+
"3/4": "75%",
|
|
833
|
+
"1/5": "20%",
|
|
834
|
+
"2/5": "40%",
|
|
835
|
+
"3/5": "60%",
|
|
836
|
+
"4/5": "80%",
|
|
837
|
+
"1/6": "16.666667%",
|
|
838
|
+
"5/6": "83.333333%",
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
function resolveLength(raw, config) {
|
|
842
|
+
if (isArbitrary(raw)) return readArbitrary(raw);
|
|
843
|
+
const named = {
|
|
844
|
+
auto: "auto",
|
|
845
|
+
full: "100%",
|
|
846
|
+
screen: "100vw",
|
|
847
|
+
svw: "100svw",
|
|
848
|
+
lvw: "100lvw",
|
|
849
|
+
dvw: "100dvw",
|
|
850
|
+
min: "min-content",
|
|
851
|
+
max: "max-content",
|
|
852
|
+
fit: "fit-content",
|
|
853
|
+
};
|
|
854
|
+
if (named[raw]) return named[raw];
|
|
855
|
+
if (fractionMap[raw]) return fractionMap[raw];
|
|
856
|
+
return resolveScaleValue(raw, config.spacingScale);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
function resolveSizing(token, config) {
|
|
860
|
+
if (token.startsWith("min-w-")) {
|
|
861
|
+
const value = resolveLength(token.slice(6), config);
|
|
862
|
+
if (!value) return null;
|
|
863
|
+
return { minWidth: value };
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
if (token.startsWith("max-w-")) {
|
|
867
|
+
const raw = token.slice(6);
|
|
868
|
+
const named = {
|
|
869
|
+
none: "none",
|
|
870
|
+
full: "100%",
|
|
871
|
+
screen: "100vw",
|
|
872
|
+
prose: "65ch",
|
|
873
|
+
xs: "20rem",
|
|
874
|
+
sm: "24rem",
|
|
875
|
+
md: "28rem",
|
|
876
|
+
lg: "32rem",
|
|
877
|
+
xl: "36rem",
|
|
878
|
+
"2xl": "42rem",
|
|
879
|
+
"3xl": "48rem",
|
|
880
|
+
"4xl": "56rem",
|
|
881
|
+
"5xl": "64rem",
|
|
882
|
+
"6xl": "72rem",
|
|
883
|
+
"7xl": "80rem",
|
|
884
|
+
};
|
|
885
|
+
if (named[raw]) return { maxWidth: named[raw] };
|
|
886
|
+
const value = resolveLength(raw, config);
|
|
887
|
+
if (!value) return null;
|
|
888
|
+
return { maxWidth: value };
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if (token.startsWith("min-h-")) {
|
|
892
|
+
const raw = token.slice(6);
|
|
893
|
+
const named = { full: "100%", screen: "100vh" };
|
|
894
|
+
if (named[raw]) return { minHeight: named[raw] };
|
|
895
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
896
|
+
if (!value) return null;
|
|
897
|
+
return { minHeight: value };
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
if (token.startsWith("max-h-")) {
|
|
901
|
+
const raw = token.slice(6);
|
|
902
|
+
const named = { none: "none", full: "100%", screen: "100vh" };
|
|
903
|
+
if (named[raw]) return { maxHeight: named[raw] };
|
|
904
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
905
|
+
if (!value) return null;
|
|
906
|
+
return { maxHeight: value };
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (token.startsWith("w-")) {
|
|
910
|
+
const value = resolveLength(token.slice(2), config);
|
|
911
|
+
if (!value) return null;
|
|
912
|
+
return { width: value };
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (token.startsWith("h-")) {
|
|
916
|
+
const raw = token.slice(2);
|
|
917
|
+
const named = {
|
|
918
|
+
auto: "auto",
|
|
919
|
+
full: "100%",
|
|
920
|
+
screen: "100vh",
|
|
921
|
+
svh: "100svh",
|
|
922
|
+
lvh: "100lvh",
|
|
923
|
+
dvh: "100dvh",
|
|
924
|
+
min: "min-content",
|
|
925
|
+
max: "max-content",
|
|
926
|
+
fit: "fit-content",
|
|
927
|
+
};
|
|
928
|
+
if (named[raw]) return { height: named[raw] };
|
|
929
|
+
const value = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
930
|
+
if (!value) return null;
|
|
931
|
+
return { height: value };
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (token.startsWith("size-")) {
|
|
935
|
+
const value = resolveLength(token.slice(5), config);
|
|
936
|
+
if (!value) return null;
|
|
937
|
+
return { width: value, height: value };
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (token === "aspect-square") return { aspectRatio: "1 / 1" };
|
|
941
|
+
if (token === "aspect-video") return { aspectRatio: "16 / 9" };
|
|
942
|
+
if (token === "aspect-auto") return { aspectRatio: "auto" };
|
|
943
|
+
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
const directMap = {
|
|
948
|
+
p: ["padding"],
|
|
949
|
+
px: ["paddingLeft", "paddingRight"],
|
|
950
|
+
py: ["paddingTop", "paddingBottom"],
|
|
951
|
+
pt: ["paddingTop"],
|
|
952
|
+
pr: ["paddingRight"],
|
|
953
|
+
pb: ["paddingBottom"],
|
|
954
|
+
pl: ["paddingLeft"],
|
|
955
|
+
m: ["margin"],
|
|
956
|
+
mx: ["marginLeft", "marginRight"],
|
|
957
|
+
my: ["marginTop", "marginBottom"],
|
|
958
|
+
mt: ["marginTop"],
|
|
959
|
+
mr: ["marginRight"],
|
|
960
|
+
mb: ["marginBottom"],
|
|
961
|
+
ml: ["marginLeft"],
|
|
962
|
+
gap: ["gap"],
|
|
963
|
+
"gap-x": ["columnGap"],
|
|
964
|
+
"gap-y": ["rowGap"],
|
|
965
|
+
};
|
|
966
|
+
|
|
967
|
+
function setAll(keys, value) {
|
|
968
|
+
return Object.fromEntries(keys.map((key) => [key, value]));
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
function resolveSpacing(token, config) {
|
|
972
|
+
if (token === "mx-auto") return { marginLeft: "auto", marginRight: "auto" };
|
|
973
|
+
|
|
974
|
+
const parts = token.split("-");
|
|
975
|
+
const candidates = [parts[0], parts.slice(0, 2).join("-")];
|
|
976
|
+
|
|
977
|
+
for (const key of candidates) {
|
|
978
|
+
const cssKeys = directMap[key];
|
|
979
|
+
if (!cssKeys) continue;
|
|
980
|
+
|
|
981
|
+
const raw = token.slice(key.length + 1);
|
|
982
|
+
const value = isArbitrary(raw)
|
|
983
|
+
? readArbitrary(raw)
|
|
984
|
+
: resolveScaleValue(raw, config.spacingScale);
|
|
985
|
+
|
|
986
|
+
if (!value) return null;
|
|
987
|
+
return setAll(cssKeys, value);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
return null;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
const originMap = {
|
|
994
|
+
"origin-center": "center",
|
|
995
|
+
"origin-top": "top",
|
|
996
|
+
"origin-bottom": "bottom",
|
|
997
|
+
"origin-left": "left",
|
|
998
|
+
"origin-right": "right",
|
|
999
|
+
"origin-top-left": "top left",
|
|
1000
|
+
"origin-top-right": "top right",
|
|
1001
|
+
"origin-bottom-left": "bottom left",
|
|
1002
|
+
"origin-bottom-right": "bottom right",
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
function resolveTransforms(token, config) {
|
|
1006
|
+
if (token.startsWith("scale-")) {
|
|
1007
|
+
const n = parseNumberish(token.slice(6));
|
|
1008
|
+
if (n !== null) return { transform: `scale(${n / 100})` };
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
if (token.startsWith("rotate-")) {
|
|
1012
|
+
const value = token.slice(7);
|
|
1013
|
+
const v = isArbitrary(value) ? readArbitrary(value) : `${value}deg`;
|
|
1014
|
+
return { transform: `rotate(${v})` };
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
if (token.startsWith("-rotate-")) {
|
|
1018
|
+
const value = token.slice(8);
|
|
1019
|
+
const v = isArbitrary(value) ? readArbitrary(value) : `${value}deg`;
|
|
1020
|
+
return { transform: `rotate(-${v.replace("-", "")})` };
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
if (token.startsWith("translate-x-")) {
|
|
1024
|
+
const raw = token.slice(12);
|
|
1025
|
+
const v = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
1026
|
+
if (v) return { transform: `translateX(${v})` };
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
if (token.startsWith("translate-y-")) {
|
|
1030
|
+
const raw = token.slice(12);
|
|
1031
|
+
const v = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
1032
|
+
if (v) return { transform: `translateY(${v})` };
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
if (token.startsWith("-translate-x-")) {
|
|
1036
|
+
const raw = token.slice(13);
|
|
1037
|
+
const v = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
1038
|
+
if (v) return { transform: `translateX(-${v})` };
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
if (token.startsWith("-translate-y-")) {
|
|
1042
|
+
const raw = token.slice(13);
|
|
1043
|
+
const v = isArbitrary(raw) ? readArbitrary(raw) : resolveScaleValue(raw, config.spacingScale);
|
|
1044
|
+
if (v) return { transform: `translateY(-${v})` };
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (originMap[token]) return { transformOrigin: originMap[token] };
|
|
1048
|
+
|
|
1049
|
+
if (token.startsWith("skew-x-")) {
|
|
1050
|
+
const value = token.slice(7);
|
|
1051
|
+
return { transform: `skewX(${value}deg)` };
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
if (token.startsWith("skew-y-")) {
|
|
1055
|
+
const value = token.slice(7);
|
|
1056
|
+
return { transform: `skewY(${value}deg)` };
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
if (token.startsWith("perspective-")) {
|
|
1060
|
+
const n = parseNumberish(token.slice(12));
|
|
1061
|
+
if (n !== null) return { perspective: `${n}px` };
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
return null;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
const transitionMap = {
|
|
1068
|
+
transition:
|
|
1069
|
+
"color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter 150ms ease",
|
|
1070
|
+
"transition-none": "none",
|
|
1071
|
+
"transition-all": "all 150ms cubic-bezier(0.4, 0, 0.2, 1)",
|
|
1072
|
+
"transition-colors":
|
|
1073
|
+
"color, background-color, border-color, text-decoration-color, fill, stroke 150ms ease",
|
|
1074
|
+
"transition-opacity": "opacity 150ms ease",
|
|
1075
|
+
"transition-shadow": "box-shadow 150ms ease",
|
|
1076
|
+
"transition-transform": "transform 150ms ease",
|
|
1077
|
+
};
|
|
1078
|
+
|
|
1079
|
+
const easeMap = {
|
|
1080
|
+
"ease-linear": "linear",
|
|
1081
|
+
"ease-in": "cubic-bezier(0.4, 0, 1, 1)",
|
|
1082
|
+
"ease-out": "cubic-bezier(0, 0, 0.2, 1)",
|
|
1083
|
+
"ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
function resolveTransitions(token) {
|
|
1087
|
+
if (transitionMap[token]) return { transition: transitionMap[token] };
|
|
1088
|
+
if (easeMap[token]) return { transitionTimingFunction: easeMap[token] };
|
|
1089
|
+
|
|
1090
|
+
if (token.startsWith("duration-")) {
|
|
1091
|
+
const n = parseNumberish(token.slice(9));
|
|
1092
|
+
if (n !== null) return { transitionDuration: `${n}ms` };
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
if (token.startsWith("delay-")) {
|
|
1096
|
+
const n = parseNumberish(token.slice(6));
|
|
1097
|
+
if (n !== null) return { transitionDelay: `${n}ms` };
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
return null;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
const fontSizeMap = {
|
|
1104
|
+
xs: ["0.75rem", "1rem"],
|
|
1105
|
+
sm: ["0.875rem", "1.25rem"],
|
|
1106
|
+
base: ["1rem", "1.5rem"],
|
|
1107
|
+
lg: ["1.125rem", "1.75rem"],
|
|
1108
|
+
xl: ["1.25rem", "1.75rem"],
|
|
1109
|
+
"2xl": ["1.5rem", "2rem"],
|
|
1110
|
+
"3xl": ["1.875rem", "2.25rem"],
|
|
1111
|
+
"4xl": ["2.25rem", "2.5rem"],
|
|
1112
|
+
"5xl": ["3rem", "1"],
|
|
1113
|
+
"6xl": ["3.75rem", "1"],
|
|
1114
|
+
"7xl": ["4.5rem", "1"],
|
|
1115
|
+
"8xl": ["6rem", "1"],
|
|
1116
|
+
"9xl": ["8rem", "1"],
|
|
1117
|
+
};
|
|
1118
|
+
|
|
1119
|
+
const textAlignMap = {
|
|
1120
|
+
left: "left",
|
|
1121
|
+
center: "center",
|
|
1122
|
+
right: "right",
|
|
1123
|
+
justify: "justify",
|
|
1124
|
+
start: "start",
|
|
1125
|
+
end: "end",
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
const weightMap = {
|
|
1129
|
+
thin: 100,
|
|
1130
|
+
extralight: 200,
|
|
1131
|
+
light: 300,
|
|
1132
|
+
normal: 400,
|
|
1133
|
+
medium: 500,
|
|
1134
|
+
semibold: 600,
|
|
1135
|
+
bold: 700,
|
|
1136
|
+
extrabold: 800,
|
|
1137
|
+
black: 900,
|
|
1138
|
+
};
|
|
1139
|
+
|
|
1140
|
+
function resolveTypography(token, config) {
|
|
1141
|
+
if (token.startsWith("text-")) {
|
|
1142
|
+
const key = token.slice(5);
|
|
1143
|
+
if (fontSizeMap[key]) {
|
|
1144
|
+
const [fontSize, lineHeight] = fontSizeMap[key];
|
|
1145
|
+
return { fontSize, lineHeight };
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
if (textAlignMap[key]) return { textAlign: textAlignMap[key] };
|
|
1149
|
+
|
|
1150
|
+
if (isArbitrary(key)) {
|
|
1151
|
+
const value = readArbitrary(key);
|
|
1152
|
+
return { fontSize: value };
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
if (token.startsWith("font-")) {
|
|
1157
|
+
const key = token.slice(5);
|
|
1158
|
+
if (weightMap[key]) return { fontWeight: String(weightMap[key]) };
|
|
1159
|
+
if (key === "sans") return { fontFamily: "ui-sans-serif, system-ui, sans-serif" };
|
|
1160
|
+
if (key === "serif") return { fontFamily: "ui-serif, Georgia, serif" };
|
|
1161
|
+
if (key === "mono") return { fontFamily: "ui-monospace, SFMono-Regular, monospace" };
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
if (token === "italic") return { fontStyle: "italic" };
|
|
1165
|
+
if (token === "not-italic") return { fontStyle: "normal" };
|
|
1166
|
+
if (token === "underline") return { textDecorationLine: "underline" };
|
|
1167
|
+
if (token === "line-through") return { textDecorationLine: "line-through" };
|
|
1168
|
+
if (token === "no-underline") return { textDecorationLine: "none" };
|
|
1169
|
+
if (token === "uppercase") return { textTransform: "uppercase" };
|
|
1170
|
+
if (token === "lowercase") return { textTransform: "lowercase" };
|
|
1171
|
+
if (token === "capitalize") return { textTransform: "capitalize" };
|
|
1172
|
+
if (token === "truncate") return { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" };
|
|
1173
|
+
|
|
1174
|
+
if (token.startsWith("leading-")) {
|
|
1175
|
+
const key = token.slice(8);
|
|
1176
|
+
const map = {
|
|
1177
|
+
none: "1",
|
|
1178
|
+
tight: "1.25",
|
|
1179
|
+
snug: "1.375",
|
|
1180
|
+
normal: "1.5",
|
|
1181
|
+
relaxed: "1.625",
|
|
1182
|
+
loose: "2",
|
|
1183
|
+
};
|
|
1184
|
+
if (map[key]) return { lineHeight: map[key] };
|
|
1185
|
+
const val = isArbitrary(key) ? readArbitrary(key) : resolveScaleValue(key, config.spacingScale);
|
|
1186
|
+
if (val) return { lineHeight: val };
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
return null;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
const pseudoVariants = new Set([
|
|
1193
|
+
"hover",
|
|
1194
|
+
"focus",
|
|
1195
|
+
"active",
|
|
1196
|
+
"group-hover",
|
|
1197
|
+
"group-focus",
|
|
1198
|
+
"peer-hover",
|
|
1199
|
+
"disabled",
|
|
1200
|
+
"checked",
|
|
1201
|
+
"visited",
|
|
1202
|
+
]);
|
|
1203
|
+
|
|
1204
|
+
const resolvers = [
|
|
1205
|
+
resolveSpacing,
|
|
1206
|
+
resolveColors,
|
|
1207
|
+
resolveTypography,
|
|
1208
|
+
resolveBorders,
|
|
1209
|
+
resolveLayout,
|
|
1210
|
+
resolvePositioning,
|
|
1211
|
+
resolveSizing,
|
|
1212
|
+
resolveEffects,
|
|
1213
|
+
resolveOverflow,
|
|
1214
|
+
resolveTransitions,
|
|
1215
|
+
resolveTransforms,
|
|
1216
|
+
resolveAnimations,
|
|
1217
|
+
];
|
|
1218
|
+
|
|
1219
|
+
function resolveWithBuiltins(token, config) {
|
|
1220
|
+
for (const fn of resolvers) {
|
|
1221
|
+
const styles = fn(token, config);
|
|
1222
|
+
if (styles) return styles;
|
|
1223
|
+
}
|
|
1224
|
+
return null;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
function resolveExtended(token, config) {
|
|
1228
|
+
const ext = config.extend || {};
|
|
1229
|
+
if (ext[token] && typeof ext[token] === "object") return ext[token];
|
|
1230
|
+
|
|
1231
|
+
const dash = token.lastIndexOf("-");
|
|
1232
|
+
if (dash === -1) return null;
|
|
1233
|
+
|
|
1234
|
+
const name = token.slice(0, dash);
|
|
1235
|
+
const rawValue = token.slice(dash + 1);
|
|
1236
|
+
const rule = ext[name];
|
|
1237
|
+
if (typeof rule === "function") return rule(Number.isNaN(Number(rawValue)) ? rawValue : Number(rawValue));
|
|
1238
|
+
|
|
1239
|
+
return null;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
function createParser(config) {
|
|
1243
|
+
const cache = new Map();
|
|
1244
|
+
const prefixRoot = `${config.prefix}-`;
|
|
1245
|
+
|
|
1246
|
+
return function parseClass(className) {
|
|
1247
|
+
const source = normalizeClassName(className);
|
|
1248
|
+
if (cache.has(source)) return cache.get(source);
|
|
1249
|
+
|
|
1250
|
+
if (!(source === config.prefix || source.startsWith(prefixRoot))) {
|
|
1251
|
+
const result = { type: "ignore", className: source };
|
|
1252
|
+
cache.set(source, result);
|
|
1253
|
+
return result;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
let body = source.slice(prefixRoot.length);
|
|
1257
|
+
const parts = body.split(":");
|
|
1258
|
+
const utilityToken = parts.pop();
|
|
1259
|
+
let breakpoint = null;
|
|
1260
|
+
let pseudo = null;
|
|
1261
|
+
|
|
1262
|
+
for (const variant of parts) {
|
|
1263
|
+
if (config.breakpoints[variant]) {
|
|
1264
|
+
breakpoint = variant;
|
|
1265
|
+
continue;
|
|
1266
|
+
}
|
|
1267
|
+
if (pseudoVariants.has(variant)) {
|
|
1268
|
+
pseudo = variant;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
const extended = resolveExtended(utilityToken, config);
|
|
1273
|
+
const styles = extended || resolveWithBuiltins(utilityToken, config);
|
|
1274
|
+
|
|
1275
|
+
if (!styles) {
|
|
1276
|
+
const unknown = { type: "unknown", className: source, token: utilityToken };
|
|
1277
|
+
cache.set(source, unknown);
|
|
1278
|
+
return unknown;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
const result = {
|
|
1282
|
+
type: pseudo ? "pseudo" : breakpoint ? "responsive" : "style",
|
|
1283
|
+
className: source,
|
|
1284
|
+
token: utilityToken,
|
|
1285
|
+
pseudo,
|
|
1286
|
+
breakpoint,
|
|
1287
|
+
styles,
|
|
1288
|
+
};
|
|
1289
|
+
|
|
1290
|
+
cache.set(source, result);
|
|
1291
|
+
return result;
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
let config = createConfig();
|
|
1296
|
+
let parser = createParser(config);
|
|
1297
|
+
let bus = createEventBus();
|
|
1298
|
+
let engine = createEngine(config, parser, bus);
|
|
1299
|
+
let observer = null;
|
|
1300
|
+
|
|
1301
|
+
function rebuild(options = {}) {
|
|
1302
|
+
config = deepMerge(defaultConfig, config);
|
|
1303
|
+
config = deepMerge(config, options);
|
|
1304
|
+
parser = createParser(config);
|
|
1305
|
+
engine = createEngine(config, parser, bus);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
const TadkaCSS = {
|
|
1309
|
+
version: "1.0.0",
|
|
1310
|
+
|
|
1311
|
+
init(options = {}) {
|
|
1312
|
+
rebuild(options);
|
|
1313
|
+
const count = engine.scanAndApply(document);
|
|
1314
|
+
|
|
1315
|
+
if (observer) observer.disconnect();
|
|
1316
|
+
if (config.watch && typeof MutationObserver !== "undefined") {
|
|
1317
|
+
observer = watchDOM((root) => engine.scanAndApply(root));
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
bus.emit("ready", { count });
|
|
1321
|
+
return count;
|
|
1322
|
+
},
|
|
1323
|
+
|
|
1324
|
+
refresh() {
|
|
1325
|
+
const count = engine.scanAndApply(document);
|
|
1326
|
+
bus.emit("refresh", { count });
|
|
1327
|
+
return count;
|
|
1328
|
+
},
|
|
1329
|
+
|
|
1330
|
+
apply(element) {
|
|
1331
|
+
return engine.apply(element);
|
|
1332
|
+
},
|
|
1333
|
+
|
|
1334
|
+
applyAll(nodeList) {
|
|
1335
|
+
return Array.from(nodeList || []).map((el) => engine.apply(el));
|
|
1336
|
+
},
|
|
1337
|
+
|
|
1338
|
+
parse(className) {
|
|
1339
|
+
const parsed = parser(className);
|
|
1340
|
+
return parsed.styles || null;
|
|
1341
|
+
},
|
|
1342
|
+
|
|
1343
|
+
register(name, styles) {
|
|
1344
|
+
config.extend[name] = styles;
|
|
1345
|
+
parser = createParser(config);
|
|
1346
|
+
},
|
|
1347
|
+
|
|
1348
|
+
unregister(name) {
|
|
1349
|
+
delete config.extend[name];
|
|
1350
|
+
parser = createParser(config);
|
|
1351
|
+
},
|
|
1352
|
+
|
|
1353
|
+
getConfig() {
|
|
1354
|
+
return config;
|
|
1355
|
+
},
|
|
1356
|
+
|
|
1357
|
+
setConfig(options) {
|
|
1358
|
+
rebuild(options);
|
|
1359
|
+
return config;
|
|
1360
|
+
},
|
|
1361
|
+
|
|
1362
|
+
reset() {
|
|
1363
|
+
if (observer) {
|
|
1364
|
+
observer.disconnect();
|
|
1365
|
+
observer = null;
|
|
1366
|
+
}
|
|
1367
|
+
engine.reset(document);
|
|
1368
|
+
},
|
|
1369
|
+
|
|
1370
|
+
on(event, handler) {
|
|
1371
|
+
return bus.on(event, handler);
|
|
1372
|
+
},
|
|
1373
|
+
};
|
|
1374
|
+
|
|
1375
|
+
if (typeof window !== "undefined") {
|
|
1376
|
+
window.TadkaCSS = TadkaCSS;
|
|
1377
|
+
if (document.readyState === "loading") {
|
|
1378
|
+
document.addEventListener("DOMContentLoaded", () => TadkaCSS.init());
|
|
1379
|
+
} else {
|
|
1380
|
+
TadkaCSS.init();
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
module.exports = TadkaCSS;
|
|
1385
|
+
//# sourceMappingURL=tadka-css.cjs.js.map
|