@bookklik/senangstart-css 0.2.8 → 0.2.10
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/dist/senangstart-css.js +2751 -1952
- package/dist/senangstart-css.min.js +266 -225
- package/dist/senangstart-tw.js +440 -77
- package/dist/senangstart-tw.min.js +1 -1
- package/docs/SYNTAX-REFERENCE.md +1731 -1590
- package/docs/guide/configuration.md +2 -2
- package/docs/guide/preflight.md +20 -1
- package/docs/guide/states.md +60 -0
- package/docs/ms/guide/configuration.md +2 -2
- package/docs/ms/guide/preflight.md +19 -0
- package/docs/ms/guide/states.md +60 -0
- package/docs/ms/reference/breakpoints.md +14 -0
- package/docs/ms/reference/colors.md +2 -2
- package/docs/ms/reference/space/height.md +10 -10
- package/docs/ms/reference/space/width.md +12 -12
- package/docs/ms/reference/visual/border-radius.md +50 -10
- package/docs/ms/reference/visual/contain.md +57 -0
- package/docs/ms/reference/visual/content-visibility.md +53 -0
- package/docs/ms/reference/visual/placeholder-color.md +92 -0
- package/docs/ms/reference/visual/writing-mode.md +53 -0
- package/docs/ms/reference/visual.md +6 -0
- package/docs/public/assets/senangstart-css.min.js +266 -225
- package/docs/public/llms.txt +63 -2
- package/docs/reference/breakpoints.md +14 -0
- package/docs/reference/colors.md +2 -2
- package/docs/reference/space/height.md +10 -10
- package/docs/reference/space/width.md +12 -12
- package/docs/reference/visual/border-radius.md +50 -10
- package/docs/reference/visual/contain.md +57 -0
- package/docs/reference/visual/content-visibility.md +53 -0
- package/docs/reference/visual/placeholder-color.md +92 -0
- package/docs/reference/visual/writing-mode.md +53 -0
- package/docs/reference/visual.md +7 -0
- package/docs/syntax-reference.json +2185 -2009
- package/package.json +1 -1
- package/public/senangstart.css +1 -1
- package/scripts/convert-tailwind.js +486 -89
- package/scripts/generate-docs.js +403 -403
- package/scripts/generate-llms-txt.js +28 -0
- package/src/cdn/senangstart-engine.js +37 -1927
- package/src/cdn/tw-conversion-engine.js +504 -78
- package/src/cli/commands/build.js +10 -0
- package/src/compiler/generators/css.js +400 -67
- package/src/compiler/generators/preflight.js +26 -13
- package/src/compiler/generators/typescript.js +3 -1
- package/src/compiler/index.js +27 -3
- package/src/compiler/parser.js +24 -7
- package/src/config/defaults.js +4 -1
- package/src/core/constants.js +5 -3
- package/src/definitions/index.js +7 -3
- package/src/definitions/layout.js +2 -2
- package/src/definitions/space.js +45 -19
- package/src/definitions/visual-performance.js +126 -0
- package/src/definitions/visual.js +25 -9
- package/src/index.js +47 -0
- package/src/utils/common.js +17 -5
- package/templates/senangstart.config.js +1 -1
- package/tests/helpers/test-utils.js +1 -1
- package/tests/integration/compiler.test.js +12 -1
- package/tests/unit/compiler/generators/css.coverage.test.js +833 -0
- package/tests/unit/compiler/generators/css.test.js +1520 -6
- package/tests/unit/compiler/generators/preflight.test.js +31 -0
- package/tests/unit/compiler/parser.test.js +26 -0
- package/tests/unit/config/defaults.test.js +2 -2
- package/tests/unit/convert-tailwind.cli.test.js +95 -0
- package/tests/unit/convert-tailwind.coverage.test.js +225 -0
- package/tests/unit/convert-tailwind.test.js +61 -21
- package/tests/unit/core/tokenizer-core.test.js +102 -0
- package/tests/unit/definitions/index.test.js +108 -0
- package/tests/unit/definitions/layout_definitions.test.js +40 -0
- package/tests/unit/utils/common.test.js +26 -0
- package/scripts/bundle-jit.js +0 -45
|
@@ -108,6 +108,57 @@ const fontSizeScale = {
|
|
|
108
108
|
"9xl": "hero", // 8rem → hero
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
+
// Line height scale mapping Tailwind values to SenangStart semantic values
|
|
112
|
+
// Engine native values: none(1), tight(1.25), snug(1.375), normal(1.5), relaxed(1.625), loose(2)
|
|
113
|
+
const lineHeightScale = {
|
|
114
|
+
none: "none", // line-height: 1
|
|
115
|
+
tight: "tight", // line-height: 1.25
|
|
116
|
+
snug: "snug", // line-height: 1.375
|
|
117
|
+
normal: "normal", // line-height: 1.5
|
|
118
|
+
relaxed: "relaxed", // line-height: 1.625
|
|
119
|
+
loose: "loose" // line-height: 2
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Letter spacing scale mapping Tailwind values to SenangStart semantic values
|
|
123
|
+
// Engine native values: tighter(-0.05em), tight(-0.025em), normal(0), wide(0.025em), wider(0.05em), widest(0.1em)
|
|
124
|
+
const letterSpacingScale = {
|
|
125
|
+
tighter: "tighter", // letter-spacing: -0.05em
|
|
126
|
+
tight: "tight", // letter-spacing: -0.025em
|
|
127
|
+
normal: "normal", // letter-spacing: 0
|
|
128
|
+
wide: "wide", // letter-spacing: 0.025em
|
|
129
|
+
wider: "wider", // letter-spacing: 0.05em
|
|
130
|
+
widest: "widest" // letter-spacing: 0.1em
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Z-index scale mapping Tailwind values to SenangStart semantic values
|
|
134
|
+
// Engine native values: base(0), low(10), mid(50), high(100), top(9999)
|
|
135
|
+
const zIndexScale = {
|
|
136
|
+
0: "base", // z-index: 0
|
|
137
|
+
10: "low", // z-index: 10
|
|
138
|
+
20: "low", // z-index: 20
|
|
139
|
+
30: "low", // z-index: 30
|
|
140
|
+
40: "low", // z-index: 40
|
|
141
|
+
50: "mid", // z-index: 50
|
|
142
|
+
60: "high", // z-index: 60
|
|
143
|
+
70: "high", // z-index: 70
|
|
144
|
+
80: "high", // z-index: 80
|
|
145
|
+
90: "high", // z-index: 90
|
|
146
|
+
100: "high", // z-index: 100
|
|
147
|
+
auto: "auto" // z-index: auto
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// Fraction scale mapping Tailwind fractions to SenangStart semantic values
|
|
151
|
+
// Used for positioning (left-1/2) and transforms (translate-x-1/2)
|
|
152
|
+
const fractionScale = {
|
|
153
|
+
'1/2': 'half', // 50%
|
|
154
|
+
'1/3': 'third', // 33.33%
|
|
155
|
+
'2/3': 'third-2x', // 66.67%
|
|
156
|
+
'1/4': 'quarter', // 25%
|
|
157
|
+
'2/4': 'half', // 50% (alias)
|
|
158
|
+
'3/4': 'quarter-3x', // 75%
|
|
159
|
+
'full': 'full', // 100%
|
|
160
|
+
};
|
|
161
|
+
|
|
111
162
|
const layoutMappings = {
|
|
112
163
|
container: "container",
|
|
113
164
|
flex: "flex",
|
|
@@ -169,23 +220,108 @@ const layoutMappings = {
|
|
|
169
220
|
};
|
|
170
221
|
|
|
171
222
|
const visualKeywords = {
|
|
223
|
+
// Font style
|
|
172
224
|
italic: "italic",
|
|
173
225
|
"not-italic": "not-italic",
|
|
226
|
+
|
|
227
|
+
// Font smoothing
|
|
174
228
|
antialiased: "antialiased",
|
|
229
|
+
"subpixel-antialiased": "subpixel-antialiased",
|
|
230
|
+
|
|
231
|
+
// Text transform
|
|
175
232
|
uppercase: "uppercase",
|
|
176
233
|
lowercase: "lowercase",
|
|
177
234
|
capitalize: "capitalize",
|
|
178
235
|
"normal-case": "normal-case",
|
|
236
|
+
|
|
237
|
+
// Text decoration
|
|
179
238
|
underline: "underline",
|
|
239
|
+
overline: "overline",
|
|
180
240
|
"line-through": "line-through",
|
|
181
241
|
"no-underline": "no-underline",
|
|
242
|
+
|
|
243
|
+
// Text decoration style
|
|
244
|
+
"decoration-solid": "decoration-solid",
|
|
245
|
+
"decoration-double": "decoration-double",
|
|
246
|
+
"decoration-dotted": "decoration-dotted",
|
|
247
|
+
"decoration-dashed": "decoration-dashed",
|
|
248
|
+
"decoration-wavy": "decoration-wavy",
|
|
249
|
+
|
|
250
|
+
// Text overflow
|
|
182
251
|
truncate: "truncate",
|
|
183
|
-
"
|
|
252
|
+
"text-ellipsis": "text-ellipsis",
|
|
253
|
+
"text-clip": "text-clip",
|
|
254
|
+
|
|
255
|
+
// Text wrap
|
|
256
|
+
"text-wrap": "text-wrap",
|
|
257
|
+
"text-nowrap": "text-nowrap",
|
|
258
|
+
"text-balance": "text-balance",
|
|
259
|
+
"text-pretty": "text-pretty",
|
|
260
|
+
|
|
261
|
+
// Whitespace
|
|
262
|
+
"whitespace-normal": "whitespace-normal",
|
|
263
|
+
"whitespace-nowrap": "whitespace-nowrap",
|
|
264
|
+
"whitespace-pre": "whitespace-pre",
|
|
265
|
+
"whitespace-pre-line": "whitespace-pre-line",
|
|
266
|
+
"whitespace-pre-wrap": "whitespace-pre-wrap",
|
|
267
|
+
"whitespace-break-spaces": "whitespace-break-spaces",
|
|
268
|
+
|
|
269
|
+
// Word break
|
|
270
|
+
"break-normal": "break-normal",
|
|
271
|
+
"break-words": "break-words",
|
|
272
|
+
"break-all": "break-all",
|
|
273
|
+
"break-keep": "break-keep",
|
|
274
|
+
|
|
275
|
+
// Hyphens
|
|
276
|
+
"hyphens-none": "hyphens-none",
|
|
277
|
+
"hyphens-manual": "hyphens-manual",
|
|
278
|
+
"hyphens-auto": "hyphens-auto",
|
|
279
|
+
|
|
280
|
+
// List style
|
|
281
|
+
"list-none": "list-none",
|
|
282
|
+
"list-disc": "list-disc",
|
|
283
|
+
"list-decimal": "list-decimal",
|
|
284
|
+
"list-inside": "list-inside",
|
|
285
|
+
"list-outside": "list-outside",
|
|
286
|
+
|
|
287
|
+
// Cursor
|
|
288
|
+
"cursor-auto": "cursor:auto",
|
|
184
289
|
"cursor-default": "cursor:default",
|
|
290
|
+
"cursor-pointer": "cursor:pointer",
|
|
291
|
+
"cursor-wait": "cursor:wait",
|
|
292
|
+
"cursor-text": "cursor:text",
|
|
293
|
+
"cursor-move": "cursor:move",
|
|
185
294
|
"cursor-not-allowed": "cursor:not-allowed",
|
|
295
|
+
"cursor-grab": "cursor:grab",
|
|
296
|
+
"cursor-grabbing": "cursor:grabbing",
|
|
297
|
+
|
|
298
|
+
// User select
|
|
186
299
|
"select-none": "select:none",
|
|
187
300
|
"select-text": "select:text",
|
|
188
301
|
"select-all": "select:all",
|
|
302
|
+
"select-auto": "select:auto",
|
|
303
|
+
|
|
304
|
+
// Pointer events
|
|
305
|
+
"pointer-events-none": "pointer-events:none",
|
|
306
|
+
"pointer-events-auto": "pointer-events:auto",
|
|
307
|
+
|
|
308
|
+
// Appearance
|
|
309
|
+
"appearance-none": "appearance:none",
|
|
310
|
+
"appearance-auto": "appearance:auto",
|
|
311
|
+
|
|
312
|
+
// 3D Transforms
|
|
313
|
+
perspective: "perspective",
|
|
314
|
+
"perspective-origin": "perspective-origin",
|
|
315
|
+
"transform-style": "transform-style",
|
|
316
|
+
"backface-visibility": "backface",
|
|
317
|
+
mask: "mask",
|
|
318
|
+
"mask-image": "mask-image",
|
|
319
|
+
"mask-mode": "mask-mode",
|
|
320
|
+
"mask-origin": "mask-origin",
|
|
321
|
+
"mask-position": "mask-position",
|
|
322
|
+
"mask-repeat": "mask-repeat",
|
|
323
|
+
"mask-size": "mask-size",
|
|
324
|
+
"mask-type": "mask-type"
|
|
189
325
|
};
|
|
190
326
|
|
|
191
327
|
// ============================
|
|
@@ -229,35 +365,85 @@ function getBorderWidth(value, exact) {
|
|
|
229
365
|
|
|
230
366
|
function convertClass(twClass, exact) {
|
|
231
367
|
// Handle prefixes (hover:, sm:, md:, etc.)
|
|
368
|
+
// Added group-* and peer-* variant support
|
|
232
369
|
const prefixMatch = twClass.match(
|
|
233
|
-
/^(sm:|md:|lg:|xl:|2xl:|hover:|focus:|focus-visible:|active:|disabled:|dark:)(.+)$/
|
|
370
|
+
/^(sm:|md:|lg:|xl:|2xl:|hover:|focus:|focus-visible:|active:|disabled:|dark:|group-hover:|peer-hover:|group-focus:|peer-focus:|group-active:|peer-active:|peer-check:|group-open:|peer-open:)(.+)$/
|
|
234
371
|
);
|
|
235
372
|
let prefix = "",
|
|
236
|
-
baseClass = twClass
|
|
373
|
+
baseClass = twClass,
|
|
374
|
+
extraAttr = null;
|
|
375
|
+
|
|
237
376
|
if (prefixMatch) {
|
|
238
377
|
const rawPrefix = prefixMatch[1].slice(0, -1); // remove colon
|
|
378
|
+
|
|
379
|
+
// Responsive prefixes
|
|
239
380
|
if (['sm', 'md', 'lg', 'xl', '2xl'].includes(rawPrefix)) {
|
|
240
381
|
prefix = `tw-${rawPrefix}:`;
|
|
241
|
-
}
|
|
382
|
+
}
|
|
383
|
+
// Group/Peer prefixes (map to standard state prefixes)
|
|
384
|
+
else if (rawPrefix.startsWith('group-') || rawPrefix.startsWith('peer-')) {
|
|
385
|
+
const stateMap = {
|
|
386
|
+
'hover': 'hover',
|
|
387
|
+
'focus': 'focus', // or focus-within if we strictly follow group logic, but SenangStart group logic handles mapped state triggers
|
|
388
|
+
'active': 'active',
|
|
389
|
+
'open': 'expanded', // map open -> expanded
|
|
390
|
+
'check': 'checked' // map check -> checked
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
const variant = rawPrefix.split('-')[1]; // get 'hover' from 'group-hover'
|
|
394
|
+
const mappedState = stateMap[variant] || variant;
|
|
395
|
+
|
|
396
|
+
prefix = `${mappedState}:`;
|
|
397
|
+
|
|
398
|
+
// For peer variants, we must ensure the element listens to "peer"
|
|
399
|
+
if (rawPrefix.startsWith('peer-')) {
|
|
400
|
+
extraAttr = { cat: 'listens', val: 'peer' };
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Standard prefixes
|
|
404
|
+
else {
|
|
242
405
|
prefix = prefixMatch[1];
|
|
243
406
|
}
|
|
407
|
+
|
|
244
408
|
baseClass = prefixMatch[2];
|
|
245
409
|
}
|
|
246
410
|
|
|
411
|
+
// Handle 'group' class mapping
|
|
412
|
+
if (baseClass === 'group') {
|
|
413
|
+
return { cat: 'layout', val: 'hoverable focusable pressable expandable' };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Handle 'peer' class mapping
|
|
417
|
+
if (baseClass === 'peer') {
|
|
418
|
+
return [
|
|
419
|
+
{ cat: 'layout', val: 'hoverable focusable pressable expandable' },
|
|
420
|
+
{ cat: 'interact', val: 'peer' }
|
|
421
|
+
];
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Helper to attach extra attributes (like listens="peer")
|
|
425
|
+
const attachExtra = (result) => {
|
|
426
|
+
if (!result) return null;
|
|
427
|
+
if (extraAttr) {
|
|
428
|
+
return Array.isArray(result) ? [...result, extraAttr] : [result, extraAttr];
|
|
429
|
+
}
|
|
430
|
+
return result;
|
|
431
|
+
};
|
|
432
|
+
|
|
247
433
|
// Layout mappings
|
|
248
434
|
if (layoutMappings[baseClass])
|
|
249
|
-
return { cat: "layout", val: prefix + layoutMappings[baseClass] };
|
|
435
|
+
return attachExtra({ cat: "layout", val: prefix + layoutMappings[baseClass] });
|
|
250
436
|
|
|
251
437
|
// Visual keywords
|
|
252
438
|
if (visualKeywords[baseClass])
|
|
253
|
-
return { cat: "visual", val: prefix + visualKeywords[baseClass] };
|
|
439
|
+
return attachExtra({ cat: "visual", val: prefix + visualKeywords[baseClass] });
|
|
254
440
|
|
|
255
441
|
// Text color
|
|
256
442
|
const textColorMatch = baseClass.match(
|
|
257
443
|
/^text-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black)(?:-\d+)?)$/
|
|
258
444
|
);
|
|
259
445
|
if (textColorMatch)
|
|
260
|
-
return { cat: "visual", val: prefix + "text:" + textColorMatch[1] };
|
|
446
|
+
return attachExtra({ cat: "visual", val: prefix + "text:" + textColorMatch[1] });
|
|
261
447
|
|
|
262
448
|
// Text alignment
|
|
263
449
|
if (
|
|
@@ -265,10 +451,10 @@ function convertClass(twClass, exact) {
|
|
|
265
451
|
baseClass
|
|
266
452
|
)
|
|
267
453
|
)
|
|
268
|
-
return {
|
|
454
|
+
return attachExtra({
|
|
269
455
|
cat: "visual",
|
|
270
456
|
val: prefix + "text:" + baseClass.replace("text-", ""),
|
|
271
|
-
};
|
|
457
|
+
});
|
|
272
458
|
|
|
273
459
|
// Text size
|
|
274
460
|
const textSizeMatch = baseClass.match(
|
|
@@ -278,7 +464,21 @@ function convertClass(twClass, exact) {
|
|
|
278
464
|
const size = exact
|
|
279
465
|
? `tw-${textSizeMatch[1]}`
|
|
280
466
|
: fontSizeScale[textSizeMatch[1]] || textSizeMatch[1];
|
|
281
|
-
return { cat: "visual", val: prefix + "text-size:" + size };
|
|
467
|
+
return attachExtra({ cat: "visual", val: prefix + "text-size:" + size });
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Line height
|
|
471
|
+
const leadingMatch = baseClass.match(/^leading-(\[.+\]|none|tight|snug|normal|relaxed|loose)$/);
|
|
472
|
+
if (leadingMatch) {
|
|
473
|
+
const val = leadingMatch[1];
|
|
474
|
+
return attachExtra({ cat: "visual", val: prefix + "leading:" + (lineHeightScale[val] || val) });
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Letter spacing
|
|
478
|
+
const trackingMatch = baseClass.match(/^tracking-(\[.+\]|tighter|tight|normal|wide|wider|widest)$/);
|
|
479
|
+
if (trackingMatch) {
|
|
480
|
+
const val = trackingMatch[1];
|
|
481
|
+
return attachExtra({ cat: "visual", val: prefix + "tracking:" + (letterSpacingScale[val] || val) });
|
|
282
482
|
}
|
|
283
483
|
|
|
284
484
|
// Background color
|
|
@@ -287,37 +487,56 @@ function convertClass(twClass, exact) {
|
|
|
287
487
|
);
|
|
288
488
|
if (bgMatch) {
|
|
289
489
|
const colorVal = bgMatch[1];
|
|
290
|
-
// Handle special values
|
|
490
|
+
// Handle special CSS keyword values - these are now natively supported
|
|
291
491
|
if (colorVal === 'transparent') {
|
|
292
|
-
return { cat: "visual", val: prefix + "bg:
|
|
492
|
+
return attachExtra({ cat: "visual", val: prefix + "bg:transparent" });
|
|
293
493
|
}
|
|
294
494
|
if (colorVal === 'current') {
|
|
295
|
-
return { cat: "visual", val: prefix + "bg:
|
|
495
|
+
return attachExtra({ cat: "visual", val: prefix + "bg:currentColor" });
|
|
296
496
|
}
|
|
297
497
|
if (colorVal === 'inherit') {
|
|
298
|
-
return { cat: "visual", val: prefix + "bg:
|
|
498
|
+
return attachExtra({ cat: "visual", val: prefix + "bg:inherit" });
|
|
299
499
|
}
|
|
300
|
-
return { cat: "visual", val: prefix + "bg:" + colorVal };
|
|
500
|
+
return attachExtra({ cat: "visual", val: prefix + "bg:" + colorVal });
|
|
301
501
|
}
|
|
302
502
|
|
|
303
503
|
// Border color
|
|
304
504
|
const borderColorMatch = baseClass.match(
|
|
305
|
-
/^border-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black)(?:-\d+)?)$/
|
|
505
|
+
/^border-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black|transparent|current|inherit)(?:-\d+)?)$/
|
|
306
506
|
);
|
|
307
|
-
if (borderColorMatch)
|
|
308
|
-
|
|
507
|
+
if (borderColorMatch) {
|
|
508
|
+
let colorVal = borderColorMatch[1];
|
|
509
|
+
// Map 'current' to 'currentColor' for CSS compatibility
|
|
510
|
+
if (colorVal === 'current') colorVal = 'currentColor';
|
|
511
|
+
return attachExtra({
|
|
309
512
|
cat: "visual",
|
|
310
|
-
val: prefix + "border:" +
|
|
311
|
-
};
|
|
513
|
+
val: prefix + "border:" + colorVal,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Directional border colors (border-t-*, border-r-*, border-b-*, border-l-*)
|
|
518
|
+
const borderSideColorMatch = baseClass.match(
|
|
519
|
+
/^border-([trbl])-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black|transparent|current|inherit)(?:-\d+)?)$/
|
|
520
|
+
);
|
|
521
|
+
if (borderSideColorMatch) {
|
|
522
|
+
const side = borderSideColorMatch[1]; // t, r, b, or l
|
|
523
|
+
let colorVal = borderSideColorMatch[2];
|
|
524
|
+
// Map 'current' to 'currentColor' for CSS compatibility
|
|
525
|
+
if (colorVal === 'current') colorVal = 'currentColor';
|
|
526
|
+
return attachExtra({
|
|
527
|
+
cat: "visual",
|
|
528
|
+
val: prefix + `border-${side}:${colorVal}`,
|
|
529
|
+
});
|
|
530
|
+
}
|
|
312
531
|
|
|
313
532
|
// Padding
|
|
314
533
|
const paddingMatch = baseClass.match(/^p([trblxy])?-(.+)$/);
|
|
315
534
|
if (paddingMatch) {
|
|
316
535
|
const side = paddingMatch[1] ? "-" + paddingMatch[1] : "";
|
|
317
|
-
return {
|
|
536
|
+
return attachExtra({
|
|
318
537
|
cat: "space",
|
|
319
538
|
val: prefix + "p" + side + ":" + getSpacing(paddingMatch[2], exact),
|
|
320
|
-
};
|
|
539
|
+
});
|
|
321
540
|
}
|
|
322
541
|
|
|
323
542
|
// Margin
|
|
@@ -339,17 +558,17 @@ function convertClass(twClass, exact) {
|
|
|
339
558
|
val = `-${val}`;
|
|
340
559
|
}
|
|
341
560
|
}
|
|
342
|
-
return { cat: "space", val: prefix + "m" + side + ":" + val };
|
|
561
|
+
return attachExtra({ cat: "space", val: prefix + "m" + side + ":" + val });
|
|
343
562
|
}
|
|
344
563
|
|
|
345
564
|
// Gap
|
|
346
565
|
const gapMatch = baseClass.match(/^gap-([xy])?-?(.+)$/);
|
|
347
566
|
if (gapMatch) {
|
|
348
567
|
const axis = gapMatch[1] ? "-" + gapMatch[1] : "";
|
|
349
|
-
return {
|
|
568
|
+
return attachExtra({
|
|
350
569
|
cat: "space",
|
|
351
570
|
val: prefix + "g" + axis + ":" + getSpacing(gapMatch[2], exact),
|
|
352
|
-
};
|
|
571
|
+
});
|
|
353
572
|
}
|
|
354
573
|
|
|
355
574
|
// Width/Height with special values
|
|
@@ -360,7 +579,7 @@ function convertClass(twClass, exact) {
|
|
|
360
579
|
// Special width values
|
|
361
580
|
const specialWidthVals = { 'max': '[max-content]', 'min': '[min-content]', 'fit': '[fit-content]', 'prose': '[65ch]' };
|
|
362
581
|
const val = specialWidthVals[rawVal] || getSpacing(rawVal, exact);
|
|
363
|
-
return { cat: "space", val: prefix + prop + ":" + val };
|
|
582
|
+
return attachExtra({ cat: "space", val: prefix + prop + ":" + val });
|
|
364
583
|
}
|
|
365
584
|
const heightMatch = baseClass.match(/^(min-h|max-h|h)-(.+)$/);
|
|
366
585
|
if (heightMatch) {
|
|
@@ -368,7 +587,7 @@ function convertClass(twClass, exact) {
|
|
|
368
587
|
const rawVal = heightMatch[2];
|
|
369
588
|
const specialHeightVals = { 'screen': '[100vh]', 'svh': '[100svh]', 'lvh': '[100lvh]', 'dvh': '[100dvh]', 'max': '[max-content]', 'min': '[min-content]', 'fit': '[fit-content]' };
|
|
370
589
|
const val = specialHeightVals[rawVal] || getSpacing(rawVal, exact);
|
|
371
|
-
return { cat: "space", val: prefix + prop + ":" + val };
|
|
590
|
+
return attachExtra({ cat: "space", val: prefix + prop + ":" + val });
|
|
372
591
|
}
|
|
373
592
|
|
|
374
593
|
// Border radius
|
|
@@ -380,7 +599,7 @@ function convertClass(twClass, exact) {
|
|
|
380
599
|
? "tw-DEFAULT"
|
|
381
600
|
: `tw-${size}`
|
|
382
601
|
: radiusScale[size] || "medium";
|
|
383
|
-
return { cat: "visual", val: prefix + "rounded:" + scale };
|
|
602
|
+
return attachExtra({ cat: "visual", val: prefix + "rounded:" + scale });
|
|
384
603
|
}
|
|
385
604
|
|
|
386
605
|
// Shadow
|
|
@@ -392,7 +611,7 @@ function convertClass(twClass, exact) {
|
|
|
392
611
|
? "tw-DEFAULT"
|
|
393
612
|
: `tw-${size}`
|
|
394
613
|
: shadowScale[size] || "medium";
|
|
395
|
-
return { cat: "visual", val: prefix + "shadow:" + scale };
|
|
614
|
+
return attachExtra({ cat: "visual", val: prefix + "shadow:" + scale });
|
|
396
615
|
}
|
|
397
616
|
|
|
398
617
|
// Font weight
|
|
@@ -400,7 +619,7 @@ function convertClass(twClass, exact) {
|
|
|
400
619
|
/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/
|
|
401
620
|
);
|
|
402
621
|
if (fontWeightMatch)
|
|
403
|
-
return { cat: "visual", val: prefix + "font:tw-" + fontWeightMatch[1] };
|
|
622
|
+
return attachExtra({ cat: "visual", val: prefix + "font:tw-" + fontWeightMatch[1] });
|
|
404
623
|
|
|
405
624
|
// Border width
|
|
406
625
|
const borderWidthMatch = baseClass.match(
|
|
@@ -415,98 +634,156 @@ function convertClass(twClass, exact) {
|
|
|
415
634
|
? "-" + borderWidthMatch[1] + "-w"
|
|
416
635
|
: "-w";
|
|
417
636
|
const width = borderWidthMatch[2] || "1";
|
|
418
|
-
return {
|
|
637
|
+
return attachExtra({
|
|
419
638
|
cat: "visual",
|
|
420
639
|
val: prefix + "border" + side + ":" + getBorderWidth(width, exact),
|
|
421
|
-
};
|
|
640
|
+
});
|
|
422
641
|
}
|
|
423
642
|
|
|
424
643
|
// Positional properties (top-0, right-0, bottom-0, left-0, inset-0, etc.)
|
|
425
|
-
|
|
644
|
+
// Includes fraction support: left-1/2, top-1/3, etc.
|
|
645
|
+
const positionMatch = baseClass.match(/^(top|right|bottom|left|inset|inset-x|inset-y)-(\d+|px|auto|full|1\/2|1\/3|2\/3|1\/4|2\/4|3\/4|\[.+\])$/);
|
|
426
646
|
if (positionMatch) {
|
|
427
647
|
const prop = positionMatch[1];
|
|
428
648
|
let val = positionMatch[2];
|
|
429
|
-
|
|
430
|
-
if (val === '0') {
|
|
431
|
-
val = 'none';
|
|
432
|
-
} else if (val.startsWith('[') && val.endsWith(']')) {
|
|
649
|
+
if (val.startsWith('[') && val.endsWith(']')) {
|
|
433
650
|
// Keep arbitrary values as-is
|
|
651
|
+
} else if (fractionScale[val]) {
|
|
652
|
+
// Map fractions to semantic names (1/2 → half, etc.)
|
|
653
|
+
val = fractionScale[val];
|
|
654
|
+
} else if (val === '0') {
|
|
655
|
+
// Keep 0 as-is for positioning (CSS: top: 0, not top: none)
|
|
656
|
+
val = '0';
|
|
434
657
|
} else {
|
|
435
658
|
val = getSpacing(val, exact);
|
|
436
659
|
}
|
|
437
|
-
return { cat: "layout", val: prefix + prop + ":" + val };
|
|
660
|
+
return attachExtra({ cat: "layout", val: prefix + prop + ":" + val });
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Translate transform utilities: translate-x-*, translate-y-*, -translate-x-*, -translate-y-*
|
|
664
|
+
const translateMatch = baseClass.match(/^(-?)translate-([xy])-(\d+|px|full|1\/2|1\/3|2\/3|1\/4|2\/4|3\/4|\[.+\])$/);
|
|
665
|
+
if (translateMatch) {
|
|
666
|
+
const isNeg = translateMatch[1] === '-';
|
|
667
|
+
const axis = translateMatch[2];
|
|
668
|
+
let val = translateMatch[3];
|
|
669
|
+
|
|
670
|
+
// Map fractions and values
|
|
671
|
+
if (val.startsWith('[') && val.endsWith(']')) {
|
|
672
|
+
// Keep arbitrary values as-is, but handle negative
|
|
673
|
+
if (isNeg) {
|
|
674
|
+
const inner = val.slice(1, -1);
|
|
675
|
+
val = `[-${inner}]`;
|
|
676
|
+
}
|
|
677
|
+
} else if (fractionScale[val]) {
|
|
678
|
+
val = fractionScale[val];
|
|
679
|
+
if (isNeg) val = `-${val}`;
|
|
680
|
+
} else if (val === '0') {
|
|
681
|
+
val = '0';
|
|
682
|
+
} else {
|
|
683
|
+
val = getSpacing(val, exact);
|
|
684
|
+
if (isNeg) val = `-${val}`;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
return attachExtra({ cat: "visual", val: prefix + `translate-${axis}:${val}` });
|
|
438
688
|
}
|
|
439
689
|
|
|
440
690
|
// Outline none
|
|
441
691
|
if (baseClass === 'outline-none') {
|
|
442
|
-
return { cat: "visual", val: prefix + "outline:none" };
|
|
692
|
+
return attachExtra({ cat: "visual", val: prefix + "outline:none" });
|
|
443
693
|
}
|
|
444
694
|
|
|
445
695
|
// Order
|
|
446
696
|
const orderMatch = baseClass.match(/^order-(\d+|first|last|none)$/);
|
|
447
697
|
if (orderMatch) {
|
|
448
|
-
return { cat: "layout", val: prefix + "order:" + orderMatch[1] };
|
|
698
|
+
return attachExtra({ cat: "layout", val: prefix + "order:" + orderMatch[1] });
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Z-index
|
|
702
|
+
const zIndexMatch = baseClass.match(/^-?z-(\d+|auto)$/);
|
|
703
|
+
if (zIndexMatch) {
|
|
704
|
+
const isNeg = baseClass.startsWith("-");
|
|
705
|
+
const val = zIndexMatch[1];
|
|
706
|
+
let zIndexVal = zIndexScale[val] || val;
|
|
707
|
+
if (isNeg) {
|
|
708
|
+
zIndexVal = `-${zIndexVal}`;
|
|
709
|
+
}
|
|
710
|
+
return attachExtra({ cat: "layout", val: prefix + "z:" + zIndexVal });
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Flex basis
|
|
714
|
+
const basisMatch = baseClass.match(/^basis-(\[.+\]|\d+\.?\d*|auto|full|1\/2|1\/3|2\/3|1\/4|2\/4|3\/4)$/);
|
|
715
|
+
if (basisMatch) {
|
|
716
|
+
let val = basisMatch[1];
|
|
717
|
+
if (val.startsWith('[') && val.endsWith(']')) {
|
|
718
|
+
// Keep arbitrary values as-is
|
|
719
|
+
} else if (fractionScale[val]) {
|
|
720
|
+
// Map fractions to semantic names (1/2 → half, etc.)
|
|
721
|
+
val = fractionScale[val];
|
|
722
|
+
} else if (val === '0') {
|
|
723
|
+
val = '0';
|
|
724
|
+
}
|
|
725
|
+
return attachExtra({ cat: "layout", val: prefix + "basis:" + val });
|
|
449
726
|
}
|
|
450
727
|
|
|
451
728
|
// Grid columns
|
|
452
729
|
const gridColsMatch = baseClass.match(/^grid-cols-(\d+|none)$/);
|
|
453
730
|
if (gridColsMatch) {
|
|
454
|
-
return { cat: "layout", val: prefix + "grid-cols:" + gridColsMatch[1] };
|
|
731
|
+
return attachExtra({ cat: "layout", val: prefix + "grid-cols:" + gridColsMatch[1] });
|
|
455
732
|
}
|
|
456
733
|
|
|
457
734
|
// Column span
|
|
458
735
|
const colSpanMatch = baseClass.match(/^col-span-(\d+|full)$/);
|
|
459
736
|
if (colSpanMatch) {
|
|
460
|
-
return { cat: "layout", val: prefix + "col-span:" + colSpanMatch[1] };
|
|
737
|
+
return attachExtra({ cat: "layout", val: prefix + "col-span:" + colSpanMatch[1] });
|
|
461
738
|
}
|
|
462
739
|
|
|
463
740
|
// Grid rows
|
|
464
741
|
const gridRowsMatch = baseClass.match(/^grid-rows-(\d+|none)$/);
|
|
465
742
|
if (gridRowsMatch) {
|
|
466
|
-
return { cat: "layout", val: prefix + "grid-rows:" + gridRowsMatch[1] };
|
|
743
|
+
return attachExtra({ cat: "layout", val: prefix + "grid-rows:" + gridRowsMatch[1] });
|
|
467
744
|
}
|
|
468
745
|
|
|
469
746
|
// Row span
|
|
470
747
|
const rowSpanMatch = baseClass.match(/^row-span-(\d+|full)$/);
|
|
471
748
|
if (rowSpanMatch) {
|
|
472
|
-
return { cat: "layout", val: prefix + "row-span:" + rowSpanMatch[1] };
|
|
749
|
+
return attachExtra({ cat: "layout", val: prefix + "row-span:" + rowSpanMatch[1] });
|
|
473
750
|
}
|
|
474
751
|
|
|
475
752
|
// Opacity
|
|
476
753
|
const opacityMatch = baseClass.match(/^opacity-(\d+)$/);
|
|
477
754
|
if (opacityMatch) {
|
|
478
|
-
return { cat: "visual", val: prefix + "opacity:" + opacityMatch[1] };
|
|
755
|
+
return attachExtra({ cat: "visual", val: prefix + "opacity:" + opacityMatch[1] });
|
|
479
756
|
}
|
|
480
757
|
|
|
481
758
|
// Gradient direction (bg-gradient-to-*)
|
|
482
759
|
const bgGradientMatch = baseClass.match(/^bg-gradient-to-(t|tr|r|br|b|bl|l|tl)$/);
|
|
483
760
|
if (bgGradientMatch) {
|
|
484
|
-
return { cat: "visual", val: prefix + "bg-image:gradient-to-" + bgGradientMatch[1] };
|
|
761
|
+
return attachExtra({ cat: "visual", val: prefix + "bg-image:gradient-to-" + bgGradientMatch[1] });
|
|
485
762
|
}
|
|
486
763
|
|
|
487
764
|
// Gradient from-* (starting color)
|
|
488
765
|
const fromMatch = baseClass.match(/^from-(.+)$/);
|
|
489
766
|
if (fromMatch) {
|
|
490
|
-
return { cat: "visual", val: prefix + "from:" + fromMatch[1] };
|
|
767
|
+
return attachExtra({ cat: "visual", val: prefix + "from:" + fromMatch[1] });
|
|
491
768
|
}
|
|
492
769
|
|
|
493
770
|
// Gradient via-* (middle color)
|
|
494
771
|
const viaMatch = baseClass.match(/^via-(.+)$/);
|
|
495
772
|
if (viaMatch) {
|
|
496
|
-
return { cat: "visual", val: prefix + "via:" + viaMatch[1] };
|
|
773
|
+
return attachExtra({ cat: "visual", val: prefix + "via:" + viaMatch[1] });
|
|
497
774
|
}
|
|
498
775
|
|
|
499
776
|
// Gradient to-* (ending color) - Note: must come after bg-gradient-to-*
|
|
500
777
|
const toMatch = baseClass.match(/^to-(.+)$/);
|
|
501
778
|
if (toMatch) {
|
|
502
|
-
return { cat: "visual", val: prefix + "to:" + toMatch[1] };
|
|
779
|
+
return attachExtra({ cat: "visual", val: prefix + "to:" + toMatch[1] });
|
|
503
780
|
}
|
|
504
781
|
|
|
505
782
|
// Transition utilities
|
|
506
783
|
const transitionMatch = baseClass.match(/^transition(?:-(all|colors|opacity|shadow|transform|none))?$/);
|
|
507
784
|
if (transitionMatch) {
|
|
508
785
|
const type = transitionMatch[1] || 'all';
|
|
509
|
-
return { cat: "visual", val: prefix + "transition:" + type };
|
|
786
|
+
return attachExtra({ cat: "visual", val: prefix + "transition:" + type });
|
|
510
787
|
}
|
|
511
788
|
|
|
512
789
|
// Duration utilities
|
|
@@ -522,13 +799,13 @@ function convertClass(twClass, exact) {
|
|
|
522
799
|
else if (ms <= 300) durationVal = 'slow';
|
|
523
800
|
else if (ms <= 500) durationVal = 'slower';
|
|
524
801
|
else durationVal = 'lazy';
|
|
525
|
-
return { cat: "visual", val: prefix + "duration:" + durationVal };
|
|
802
|
+
return attachExtra({ cat: "visual", val: prefix + "duration:" + durationVal });
|
|
526
803
|
}
|
|
527
804
|
|
|
528
805
|
// Ease utilities
|
|
529
806
|
const easeMatch = baseClass.match(/^ease-(linear|in|out|in-out)$/);
|
|
530
807
|
if (easeMatch) {
|
|
531
|
-
return { cat: "visual", val: prefix + "ease:" + easeMatch[1] };
|
|
808
|
+
return attachExtra({ cat: "visual", val: prefix + "ease:" + easeMatch[1] });
|
|
532
809
|
}
|
|
533
810
|
|
|
534
811
|
// Ring utilities - Convert to native ring utilities
|
|
@@ -537,105 +814,237 @@ function convertClass(twClass, exact) {
|
|
|
537
814
|
if (ringMatch) {
|
|
538
815
|
const width = ringMatch[1] || '3';
|
|
539
816
|
if (width === '0') {
|
|
540
|
-
return { cat: "visual", val: prefix + "ring:none" };
|
|
817
|
+
return attachExtra({ cat: "visual", val: prefix + "ring:none" });
|
|
541
818
|
}
|
|
542
819
|
// Map Tailwind ring widths to SenangStart semantic values
|
|
543
820
|
const ringScale = {
|
|
544
821
|
'1': 'thin', '2': 'regular', '3': 'small', '4': 'medium', '8': 'big'
|
|
545
822
|
};
|
|
546
823
|
const scale = ringScale[width] || `[${width}px]`;
|
|
547
|
-
return { cat: "visual", val: prefix + "ring:" + scale };
|
|
824
|
+
return attachExtra({ cat: "visual", val: prefix + "ring:" + scale });
|
|
548
825
|
}
|
|
549
826
|
|
|
550
827
|
// Ring offset - converts to native ring-offset utility
|
|
551
828
|
const ringOffsetMatch = baseClass.match(/^ring-offset-(\d+)$/);
|
|
552
829
|
if (ringOffsetMatch) {
|
|
553
|
-
return { cat: "visual", val: prefix + "ring-offset:" + ringOffsetMatch[1] };
|
|
830
|
+
return attachExtra({ cat: "visual", val: prefix + "ring-offset:" + ringOffsetMatch[1] });
|
|
554
831
|
}
|
|
555
832
|
|
|
556
833
|
// Ring color - converts to native ring-color utility
|
|
557
834
|
const ringColorMatch = baseClass.match(/^ring-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black)(?:-\d+)?)$/);
|
|
558
835
|
if (ringColorMatch) {
|
|
559
|
-
return { cat: "visual", val: prefix + "ring-color:" + ringColorMatch[1] };
|
|
836
|
+
return attachExtra({ cat: "visual", val: prefix + "ring-color:" + ringColorMatch[1] });
|
|
560
837
|
}
|
|
561
838
|
|
|
562
839
|
// Divide color - directional (check divide-x and divide-y BEFORE generic divide)
|
|
563
840
|
const divideXMatch = baseClass.match(/^divide-x-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black)(?:-\d+)?)$/);
|
|
564
841
|
if (divideXMatch) {
|
|
565
|
-
return {
|
|
842
|
+
return attachExtra({
|
|
566
843
|
cat: "visual",
|
|
567
844
|
val: prefix + "divide-x:" + divideXMatch[1],
|
|
568
|
-
};
|
|
845
|
+
});
|
|
569
846
|
}
|
|
570
847
|
|
|
571
848
|
const divideYMatch = baseClass.match(/^divide-y-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black)(?:-\d+)?)$/);
|
|
572
849
|
if (divideYMatch) {
|
|
573
|
-
return {
|
|
850
|
+
return attachExtra({
|
|
574
851
|
cat: "visual",
|
|
575
852
|
val: prefix + "divide-y:" + divideYMatch[1],
|
|
576
|
-
};
|
|
853
|
+
});
|
|
577
854
|
}
|
|
578
855
|
|
|
579
856
|
// Divide color - all directions (check divide-x and divide-y AFTER generic divide)
|
|
580
857
|
const divideColorMatch = baseClass.match(/^divide-((?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|white|black)(?:-\d+)?)$/);
|
|
581
858
|
if (divideColorMatch) {
|
|
582
|
-
return {
|
|
859
|
+
return attachExtra({
|
|
583
860
|
cat: "visual",
|
|
584
861
|
val: prefix + "divide:" + divideColorMatch[1],
|
|
585
|
-
};
|
|
862
|
+
});
|
|
586
863
|
}
|
|
587
864
|
|
|
588
865
|
// Divide width - all directions
|
|
589
866
|
const divideWidthMatch = baseClass.match(/^divide-(\d+)$/);
|
|
590
867
|
if (divideWidthMatch) {
|
|
591
|
-
return {
|
|
868
|
+
return attachExtra({
|
|
592
869
|
cat: "visual",
|
|
593
870
|
val: prefix + "divide-w:" + getBorderWidth(divideWidthMatch[1], exact),
|
|
594
|
-
};
|
|
871
|
+
});
|
|
595
872
|
}
|
|
596
873
|
|
|
597
874
|
// Divide reverse (check these FIRST as they are specific)
|
|
598
875
|
if (baseClass === 'divide-x-reverse') {
|
|
599
|
-
return { cat: "visual", val: prefix + "divide-x:reverse" };
|
|
876
|
+
return attachExtra({ cat: "visual", val: prefix + "divide-x:reverse" });
|
|
600
877
|
}
|
|
601
878
|
if (baseClass === 'divide-y-reverse') {
|
|
602
|
-
return { cat: "visual", val: prefix + "divide-y:reverse" };
|
|
879
|
+
return attachExtra({ cat: "visual", val: prefix + "divide-y:reverse" });
|
|
603
880
|
}
|
|
604
881
|
|
|
605
882
|
// Divide width - directional
|
|
606
883
|
const divideXWidthMatch = baseClass.match(/^divide-x-(\d+)$/);
|
|
607
884
|
if (divideXWidthMatch) {
|
|
608
|
-
return {
|
|
885
|
+
return attachExtra({
|
|
609
886
|
cat: "visual",
|
|
610
887
|
val: prefix + "divide-x-w:" + getBorderWidth(divideXWidthMatch[1], exact),
|
|
611
|
-
};
|
|
888
|
+
});
|
|
612
889
|
}
|
|
613
890
|
|
|
614
891
|
// Divide width (implicit x/y from Tailwind divide-x/y without number is usually 1px)
|
|
615
892
|
// Tailwind: divide-x = border-right-width: 1px (or left if reverse).
|
|
616
893
|
// SenangStart: divide-x-w:thin
|
|
617
894
|
if (baseClass === 'divide-x') {
|
|
618
|
-
return { cat: "visual", val: prefix + "divide-x-w:thin" };
|
|
895
|
+
return attachExtra({ cat: "visual", val: prefix + "divide-x-w:thin" });
|
|
619
896
|
}
|
|
620
897
|
if (baseClass === 'divide-y') {
|
|
621
|
-
return { cat: "visual", val: prefix + "divide-y-w:thin" };
|
|
898
|
+
return attachExtra({ cat: "visual", val: prefix + "divide-y-w:thin" });
|
|
622
899
|
}
|
|
623
900
|
|
|
624
901
|
const divideYWidthMatch = baseClass.match(/^divide-y-(\d+)$/);
|
|
625
902
|
if (divideYWidthMatch) {
|
|
626
|
-
return {
|
|
903
|
+
return attachExtra({
|
|
627
904
|
cat: "visual",
|
|
628
905
|
val: prefix + "divide-y-w:" + getBorderWidth(divideYWidthMatch[1], exact),
|
|
629
|
-
};
|
|
906
|
+
});
|
|
630
907
|
}
|
|
631
908
|
|
|
632
909
|
// Divide style
|
|
633
910
|
const divideStyleMatch = baseClass.match(/^divide-(solid|dashed|dotted|double|none)$/);
|
|
634
911
|
if (divideStyleMatch) {
|
|
635
|
-
return {
|
|
912
|
+
return attachExtra({
|
|
636
913
|
cat: "visual",
|
|
637
914
|
val: prefix + "divide-style:" + divideStyleMatch[1], // Fixed category from 'color' to 'visual'
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// Border style
|
|
919
|
+
const borderStyleMatch = baseClass.match(/^border-(solid|dashed|dotted|double|none)$/);
|
|
920
|
+
if (borderStyleMatch) {
|
|
921
|
+
return attachExtra({
|
|
922
|
+
cat: "visual",
|
|
923
|
+
val: prefix + "border-style:" + borderStyleMatch[1],
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// Filter utilities
|
|
928
|
+
// Blur
|
|
929
|
+
const blurMatch = baseClass.match(/^blur-(0|sm|md|lg|xl|2xl|3xl)$/);
|
|
930
|
+
if (blurMatch) {
|
|
931
|
+
const blurScale = {
|
|
932
|
+
'0': 'none',
|
|
933
|
+
'sm': 'tiny',
|
|
934
|
+
'md': 'small',
|
|
935
|
+
'lg': 'medium',
|
|
936
|
+
'xl': 'big',
|
|
937
|
+
'2xl': 'giant',
|
|
938
|
+
'3xl': 'vast'
|
|
939
|
+
};
|
|
940
|
+
return attachExtra({
|
|
941
|
+
cat: "visual",
|
|
942
|
+
val: prefix + "blur:" + blurScale[blurMatch[1]],
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// Brightness
|
|
947
|
+
const brightnessMatch = baseClass.match(/^brightness-(0|50|75|90|95|100|105|110|125|150|200)$/);
|
|
948
|
+
if (brightnessMatch) {
|
|
949
|
+
const brightnessScale = {
|
|
950
|
+
'0': 'dim',
|
|
951
|
+
'50': 'dim',
|
|
952
|
+
'75': 'dark',
|
|
953
|
+
'90': 'dark',
|
|
954
|
+
'95': 'dark',
|
|
955
|
+
'100': 'normal',
|
|
956
|
+
'105': 'bright',
|
|
957
|
+
'110': 'bright',
|
|
958
|
+
'125': 'vivid',
|
|
959
|
+
'150': 'vivid',
|
|
960
|
+
'200': 'vivid'
|
|
638
961
|
};
|
|
962
|
+
return attachExtra({
|
|
963
|
+
cat: "visual",
|
|
964
|
+
val: prefix + "brightness:" + brightnessScale[brightnessMatch[1]],
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// Contrast
|
|
969
|
+
const contrastMatch = baseClass.match(/^contrast-(0|50|75|100|125|150|200)$/);
|
|
970
|
+
if (contrastMatch) {
|
|
971
|
+
const contrastScale = {
|
|
972
|
+
'0': 'low',
|
|
973
|
+
'50': 'low',
|
|
974
|
+
'75': 'reduced',
|
|
975
|
+
'100': 'normal',
|
|
976
|
+
'125': 'high',
|
|
977
|
+
'150': 'high',
|
|
978
|
+
'200': 'max'
|
|
979
|
+
};
|
|
980
|
+
return attachExtra({
|
|
981
|
+
cat: "visual",
|
|
982
|
+
val: prefix + "contrast:" + contrastScale[contrastMatch[1]],
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// Grayscale
|
|
987
|
+
const grayscaleMatch = baseClass.match(/^grayscale(0)?$/);
|
|
988
|
+
if (grayscaleMatch) {
|
|
989
|
+
const val = grayscaleMatch[1] === '0' ? 'none' : 'full';
|
|
990
|
+
return attachExtra({
|
|
991
|
+
cat: "visual",
|
|
992
|
+
val: prefix + "grayscale:" + val,
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Hue rotate
|
|
997
|
+
const hueRotateMatch = baseClass.match(/^hue-rotate-(0|15|30|60|90|180)$/);
|
|
998
|
+
if (hueRotateMatch) {
|
|
999
|
+
return attachExtra({
|
|
1000
|
+
cat: "visual",
|
|
1001
|
+
val: prefix + "hue-rotate:" + hueRotateMatch[1],
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// Invert
|
|
1006
|
+
const invertMatch = baseClass.match(/^invert(0)?$/);
|
|
1007
|
+
if (invertMatch) {
|
|
1008
|
+
const val = invertMatch[1] === '0' ? 'none' : 'full';
|
|
1009
|
+
return attachExtra({
|
|
1010
|
+
cat: "visual",
|
|
1011
|
+
val: prefix + "invert:" + val,
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Saturate
|
|
1016
|
+
const saturateMatch = baseClass.match(/^saturate-(0|50|100|150|200)$/);
|
|
1017
|
+
if (saturateMatch) {
|
|
1018
|
+
const saturateScale = {
|
|
1019
|
+
'0': 'none',
|
|
1020
|
+
'50': 'low',
|
|
1021
|
+
'100': 'normal',
|
|
1022
|
+
'150': 'high',
|
|
1023
|
+
'200': 'vivid'
|
|
1024
|
+
};
|
|
1025
|
+
return attachExtra({
|
|
1026
|
+
cat: "visual",
|
|
1027
|
+
val: prefix + "saturate:" + saturateScale[saturateMatch[1]],
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Sepia
|
|
1032
|
+
const sepiaMatch = baseClass.match(/^sepia(0)?$/);
|
|
1033
|
+
if (sepiaMatch) {
|
|
1034
|
+
const val = sepiaMatch[1] === '0' ? 'none' : 'full';
|
|
1035
|
+
return attachExtra({
|
|
1036
|
+
cat: "visual",
|
|
1037
|
+
val: prefix + "sepia:" + val,
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// Animation utilities
|
|
1042
|
+
const animateMatch = baseClass.match(/^animate-(none|spin|ping|pulse|bounce)$/);
|
|
1043
|
+
if (animateMatch) {
|
|
1044
|
+
return attachExtra({
|
|
1045
|
+
cat: "visual",
|
|
1046
|
+
val: prefix + "animate:" + animateMatch[1],
|
|
1047
|
+
});
|
|
639
1048
|
}
|
|
640
1049
|
|
|
641
1050
|
return null;
|
|
@@ -649,27 +1058,42 @@ function convertClasses(classString, exact) {
|
|
|
649
1058
|
const layout = [],
|
|
650
1059
|
space = [],
|
|
651
1060
|
visual = [],
|
|
1061
|
+
interact = [],
|
|
1062
|
+
listens = [],
|
|
652
1063
|
unknown = [];
|
|
653
1064
|
|
|
1065
|
+
// Helper to push unique
|
|
1066
|
+
const pushUnique = (arr, val) => {
|
|
1067
|
+
if (!arr.includes(val)) arr.push(val);
|
|
1068
|
+
};
|
|
1069
|
+
|
|
654
1070
|
for (const cls of classes) {
|
|
655
1071
|
const result = convertClass(cls, exact);
|
|
1072
|
+
|
|
656
1073
|
if (result) {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
1074
|
+
// Normalize to array to support 1-to-many mapping
|
|
1075
|
+
const results = Array.isArray(result) ? result : [result];
|
|
1076
|
+
|
|
1077
|
+
for (const res of results) {
|
|
1078
|
+
if (res.cat === "layout") pushUnique(layout, res.val);
|
|
1079
|
+
else if (res.cat === "space") pushUnique(space, res.val);
|
|
1080
|
+
else if (res.cat === "visual") pushUnique(visual, res.val);
|
|
1081
|
+
else if (res.cat === "interact") pushUnique(interact, res.val);
|
|
1082
|
+
else if (res.cat === "listens") pushUnique(listens, res.val);
|
|
1083
|
+
}
|
|
660
1084
|
} else {
|
|
661
1085
|
unknown.push(cls);
|
|
662
1086
|
}
|
|
663
1087
|
}
|
|
664
1088
|
|
|
665
|
-
return { layout, space, visual, unknown };
|
|
1089
|
+
return { layout, space, visual, interact, listens, unknown };
|
|
666
1090
|
}
|
|
667
1091
|
|
|
668
1092
|
function convertHTML(html, exact) {
|
|
669
1093
|
return html.replace(
|
|
670
1094
|
/class=(['"])([^"']+)\1/g,
|
|
671
1095
|
(match, quote, classValue) => {
|
|
672
|
-
const { layout, space, visual, unknown } = convertClasses(
|
|
1096
|
+
const { layout, space, visual, interact, listens, unknown } = convertClasses(
|
|
673
1097
|
classValue,
|
|
674
1098
|
exact
|
|
675
1099
|
);
|
|
@@ -677,6 +1101,8 @@ function convertHTML(html, exact) {
|
|
|
677
1101
|
if (layout.length) attrs.push(`layout="${layout.join(" ")}"`);
|
|
678
1102
|
if (space.length) attrs.push(`space="${space.join(" ")}"`);
|
|
679
1103
|
if (visual.length) attrs.push(`visual="${visual.join(" ")}"`);
|
|
1104
|
+
if (interact.length) attrs.push(`interact="${interact.join(" ")}"`);
|
|
1105
|
+
if (listens.length) attrs.push(`listens="${listens.join(" ")}"`);
|
|
680
1106
|
if (unknown.length) attrs.push(`class="${unknown.join(" ")}"`);
|
|
681
1107
|
return attrs.join(" ") || 'class=""';
|
|
682
1108
|
}
|