@bookklik/senangstart-css 0.2.3 → 0.2.5
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 +100 -6
- package/dist/senangstart-css.min.js +26 -22
- package/dist/senangstart-tw.js +537 -0
- package/dist/senangstart-tw.min.js +2 -0
- package/docs/.vitepress/config.js +6 -0
- package/docs/guide/cdn.md +1 -1
- package/docs/ms/guide/cdn.md +1 -1
- package/docs/ms/reference/layout/position.md +4 -4
- package/docs/ms/reference/layout/z-index.md +8 -8
- package/docs/ms/reference/space/gap.md +1 -1
- package/docs/ms/reference/space/height.md +1 -1
- package/docs/ms/reference/space/margin.md +1 -1
- package/docs/ms/reference/space/padding.md +1 -1
- package/docs/ms/reference/space/scale-reference.md +46 -17
- package/docs/ms/reference/space/width.md +1 -1
- package/docs/ms/reference/space.md +1 -1
- package/docs/ms/reference/spacing.md +103 -21
- package/docs/ms/reference/visual/animation-fill.md +8 -8
- package/docs/ms/reference/visual/backdrop-blur.md +4 -4
- package/docs/ms/reference/visual/backdrop-brightness.md +8 -8
- package/docs/ms/reference/visual/backdrop-grayscale.md +6 -6
- package/docs/ms/reference/visual/backdrop-sepia.md +6 -6
- package/docs/ms/reference/visual/background-clip.md +2 -2
- package/docs/ms/reference/visual/background-image.md +4 -4
- package/docs/ms/reference/visual/filter-brightness.md +4 -4
- package/docs/ms/reference/visual/filter-contrast.md +4 -4
- package/docs/ms/reference/visual/filter-drop-shadow.md +6 -6
- package/docs/ms/reference/visual/filter-grayscale.md +4 -4
- package/docs/ms/reference/visual/filter-hue-rotate.md +4 -4
- package/docs/ms/reference/visual/filter-invert.md +2 -2
- package/docs/ms/reference/visual/filter-saturate.md +4 -4
- package/docs/ms/reference/visual/filter-sepia.md +4 -4
- package/docs/ms/reference/visual/font-family.md +2 -2
- package/docs/ms/reference/visual/gradient-from.md +57 -0
- package/docs/ms/reference/visual/gradient-to.md +57 -0
- package/docs/ms/reference/visual/gradient-via.md +54 -0
- package/docs/ms/reference/visual/letter-spacing.md +2 -2
- package/docs/ms/reference/visual/line-clamp.md +2 -2
- package/docs/ms/reference/visual/line-height.md +2 -2
- package/docs/ms/reference/visual/outline.md +2 -2
- package/docs/ms/reference/visual/ring-color.md +29 -0
- package/docs/ms/reference/visual/ring-offset.md +30 -0
- package/docs/ms/reference/visual/ring.md +62 -0
- package/docs/ms/reference/visual/stroke-width.md +6 -6
- package/docs/ms/reference/visual/stroke.md +4 -4
- package/docs/ms/reference/visual/text-indent.md +2 -2
- package/docs/ms/reference/visual/text-overflow.md +2 -2
- package/docs/ms/reference/visual/text-size.md +84 -84
- package/docs/ms/reference/visual/text-wrap.md +2 -2
- package/docs/ms/reference/visual/transform-backface.md +4 -4
- package/docs/ms/reference/visual/transform-perspective-origin.md +6 -6
- package/docs/ms/reference/visual/transform-perspective.md +6 -6
- package/docs/ms/reference/visual/transform-rotate-3d.md +6 -6
- package/docs/ms/reference/visual/transform-style.md +4 -4
- package/docs/ms/reference/visual/transform-translate-z.md +6 -6
- package/docs/ms/reference/visual/transform-translate.md +2 -2
- package/docs/ms/reference/visual/whitespace.md +2 -2
- package/docs/ms/reference/visual/word-break.md +2 -2
- package/docs/public/assets/senangstart-css.min.js +213 -1545
- package/docs/public/llms.txt +1718 -0
- package/docs/reference/layout/position.md +4 -4
- package/docs/reference/layout/z-index.md +8 -8
- package/docs/reference/space/gap.md +1 -1
- package/docs/reference/space/height.md +1 -1
- package/docs/reference/space/margin.md +1 -1
- package/docs/reference/space/padding.md +1 -1
- package/docs/reference/space/scale-reference.md +46 -17
- package/docs/reference/space/width.md +1 -1
- package/docs/reference/space.md +1 -1
- package/docs/reference/spacing.md +103 -21
- package/docs/reference/visual/animation-fill.md +8 -8
- package/docs/reference/visual/backdrop-blur.md +4 -4
- package/docs/reference/visual/backdrop-brightness.md +8 -8
- package/docs/reference/visual/backdrop-grayscale.md +6 -6
- package/docs/reference/visual/backdrop-sepia.md +6 -6
- package/docs/reference/visual/background-clip.md +2 -2
- package/docs/reference/visual/background-image.md +4 -4
- package/docs/reference/visual/filter-brightness.md +4 -4
- package/docs/reference/visual/filter-contrast.md +4 -4
- package/docs/reference/visual/filter-drop-shadow.md +6 -6
- package/docs/reference/visual/filter-grayscale.md +4 -4
- package/docs/reference/visual/filter-hue-rotate.md +4 -4
- package/docs/reference/visual/filter-invert.md +2 -2
- package/docs/reference/visual/filter-saturate.md +4 -4
- package/docs/reference/visual/filter-sepia.md +4 -4
- package/docs/reference/visual/font-family.md +2 -2
- package/docs/reference/visual/gradient-from.md +57 -0
- package/docs/reference/visual/gradient-to.md +57 -0
- package/docs/reference/visual/gradient-via.md +54 -0
- package/docs/reference/visual/letter-spacing.md +2 -2
- package/docs/reference/visual/line-clamp.md +2 -2
- package/docs/reference/visual/line-height.md +2 -2
- package/docs/reference/visual/outline.md +2 -2
- package/docs/reference/visual/ring-color.md +29 -0
- package/docs/reference/visual/ring-offset.md +30 -0
- package/docs/reference/visual/ring.md +62 -0
- package/docs/reference/visual/stroke-width.md +6 -6
- package/docs/reference/visual/stroke.md +4 -4
- package/docs/reference/visual/text-indent.md +2 -2
- package/docs/reference/visual/text-overflow.md +2 -2
- package/docs/reference/visual/text-size.md +84 -84
- package/docs/reference/visual/text-wrap.md +2 -2
- package/docs/reference/visual/transform-backface.md +4 -4
- package/docs/reference/visual/transform-perspective-origin.md +6 -6
- package/docs/reference/visual/transform-perspective.md +6 -6
- package/docs/reference/visual/transform-rotate-3d.md +6 -6
- package/docs/reference/visual/transform-style.md +4 -4
- package/docs/reference/visual/transform-translate-z.md +6 -6
- package/docs/reference/visual/transform-translate.md +2 -2
- package/docs/reference/visual/whitespace.md +2 -2
- package/docs/reference/visual/word-break.md +2 -2
- package/package.json +4 -2
- package/playground/tw-convertor.html +103 -589
- package/scripts/build-dist.js +45 -3
- package/scripts/bundle-jit.js +3 -3
- package/scripts/convert-tailwind.js +180 -1
- package/scripts/generate-llms-txt.js +264 -0
- package/src/cdn/{jit.js → senangstart-engine.js} +97 -8
- package/src/cdn/tw-conversion-engine.js +632 -0
- package/src/compiler/generators/css.js +27 -0
- package/src/config/defaults.js +37 -11
- package/src/core/constants.js +37 -8
- package/src/definitions/layout-positioning.js +6 -6
- package/src/definitions/space.js +46 -5
- package/src/definitions/visual-backgrounds.js +113 -15
- package/src/definitions/visual-borders.js +81 -2
- package/src/definitions/visual-filters.js +16 -16
- package/src/definitions/visual-svg.js +5 -5
- package/src/definitions/visual-transform3d.js +16 -16
- package/src/definitions/visual-transforms.js +1 -1
- package/src/definitions/visual-transitions.js +4 -4
- package/src/definitions/visual-typography.js +6 -6
- package/src/definitions/visual.js +4 -4
- package/tests/unit/compiler/generators/css.test.js +192 -0
- package/tests/unit/convert-tailwind.test.js +8 -0
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SenangStart CSS - Tailwind to SenangStart Conversion Engine
|
|
3
|
+
* Converts Tailwind CSS class syntax to SenangStart CSS attribute syntax
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================
|
|
7
|
+
// MAPPING SCALES
|
|
8
|
+
// ============================
|
|
9
|
+
|
|
10
|
+
// Spacing scale mapping Tailwind values to SenangStart semantic values
|
|
11
|
+
// Engine native values: none(0px), thin(1px), regular(2px), thick(3px), tiny(4px), tiny-2x(6px),
|
|
12
|
+
// small(8px), small-2x(10px), small-3x(12px), small-4x(14px),
|
|
13
|
+
// medium(16px), medium-2x(20px), medium-3x(24px), medium-4x(28px),
|
|
14
|
+
// large(32px), large-2x(36px), large-3x(40px), large-4x(44px),
|
|
15
|
+
// big(48px), big-2x(56px), big-3x(64px), big-4x(80px),
|
|
16
|
+
// giant(96px), giant-2x(112px), giant-3x(128px), giant-4x(144px),
|
|
17
|
+
// vast(160px), vast-2x(176px), vast-3x(192px), vast-4x(208px),
|
|
18
|
+
// vast-5x(224px), vast-6x(240px), vast-7x(256px), vast-8x(288px),
|
|
19
|
+
// vast-9x(320px), vast-10x(384px)
|
|
20
|
+
// Tailwind base: 4px per unit (1 = 0.25rem = 4px)
|
|
21
|
+
const spacingScale = {
|
|
22
|
+
0: "none", // 0px → none
|
|
23
|
+
px: "thin", // 1px → thin
|
|
24
|
+
0.5: "regular", // 2px → regular
|
|
25
|
+
1: "tiny", // 4px → tiny
|
|
26
|
+
1.5: "tiny-2x", // 6px → tiny-2x
|
|
27
|
+
2: "small", // 8px → small
|
|
28
|
+
2.5: "small-2x", // 10px → small-2x
|
|
29
|
+
3: "small-3x", // 12px → small-3x
|
|
30
|
+
3.5: "small-4x", // 14px → small-4x
|
|
31
|
+
4: "medium", // 16px → medium
|
|
32
|
+
5: "medium-2x", // 20px → medium-2x
|
|
33
|
+
6: "medium-3x", // 24px → medium-3x
|
|
34
|
+
7: "medium-4x", // 28px → medium-4x
|
|
35
|
+
8: "large", // 32px → large
|
|
36
|
+
9: "large-2x", // 36px → large-2x
|
|
37
|
+
10: "large-3x", // 40px → large-3x
|
|
38
|
+
11: "large-4x", // 44px → large-4x
|
|
39
|
+
12: "big", // 48px → big
|
|
40
|
+
14: "big-2x", // 56px → big-2x
|
|
41
|
+
16: "big-3x", // 64px → big-3x
|
|
42
|
+
20: "big-4x", // 80px → big-4x
|
|
43
|
+
24: "giant", // 96px → giant
|
|
44
|
+
28: "giant-2x", // 112px → giant-2x
|
|
45
|
+
32: "giant-3x", // 128px → giant-3x
|
|
46
|
+
36: "giant-4x", // 144px → giant-4x
|
|
47
|
+
40: "vast", // 160px → vast
|
|
48
|
+
44: "vast-2x", // 176px → vast-2x
|
|
49
|
+
48: "vast-3x", // 192px → vast-3x
|
|
50
|
+
52: "vast-4x", // 208px → vast-4x
|
|
51
|
+
56: "vast-5x", // 224px → vast-5x
|
|
52
|
+
60: "vast-6x", // 240px → vast-6x
|
|
53
|
+
64: "vast-7x", // 256px → vast-7x
|
|
54
|
+
72: "vast-8x", // 288px → vast-8x
|
|
55
|
+
80: "vast-9x", // 320px → vast-9x
|
|
56
|
+
96: "vast-10x", // 384px → vast-10x
|
|
57
|
+
full: "[100%]",
|
|
58
|
+
screen: "[100vw]",
|
|
59
|
+
auto: "auto",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Radius scale mapping Tailwind values to SenangStart semantic values
|
|
63
|
+
// Engine native values: none(0px), small(4px), medium(8px), big(16px), round(9999px)
|
|
64
|
+
// Tailwind: none(0), sm(0.125rem=2px), DEFAULT(0.25rem=4px), md(0.375rem=6px),
|
|
65
|
+
// lg(0.5rem=8px), xl(0.75rem=12px), 2xl(1rem=16px), 3xl(1.5rem=24px), full(9999px)
|
|
66
|
+
const radiusScale = {
|
|
67
|
+
none: "none", // 0px → none
|
|
68
|
+
sm: "small", // 2px → small (closest to 4px)
|
|
69
|
+
"": "small", // 4px → small (Tailwind DEFAULT)
|
|
70
|
+
md: "small", // 6px → small (closest to 4px)
|
|
71
|
+
lg: "medium", // 8px → medium
|
|
72
|
+
xl: "medium", // 12px → medium (closest to 8px)
|
|
73
|
+
"2xl": "big", // 16px → big
|
|
74
|
+
"3xl": "big", // 24px → big (closest to 16px)
|
|
75
|
+
full: "round", // 9999px → round
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Shadow scale mapping Tailwind values to SenangStart semantic values
|
|
79
|
+
// Engine native values: none, small, medium, big, giant
|
|
80
|
+
const shadowScale = {
|
|
81
|
+
none: "none", // none → none
|
|
82
|
+
sm: "small", // small shadow → small
|
|
83
|
+
"": "small", // DEFAULT shadow → small
|
|
84
|
+
md: "medium", // medium shadow → medium
|
|
85
|
+
lg: "big", // large shadow → big
|
|
86
|
+
xl: "giant", // xl shadow → giant
|
|
87
|
+
"2xl": "giant", // 2xl shadow → giant
|
|
88
|
+
inner: "none", // inner shadow not directly supported
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// Font size scale mapping Tailwind values to SenangStart semantic values
|
|
92
|
+
// Engine native values: mini(0.75rem), small(0.875rem), base(1rem), large(1.125rem),
|
|
93
|
+
// big(1.25rem), huge(1.5rem), grand(1.875rem), giant(2.25rem),
|
|
94
|
+
// mount(3rem), mega(3.75rem), giga(4.5rem), tera(6rem), hero(8rem)
|
|
95
|
+
const fontSizeScale = {
|
|
96
|
+
xs: "mini", // 0.75rem → mini
|
|
97
|
+
sm: "small", // 0.875rem → small
|
|
98
|
+
base: "base", // 1rem → base
|
|
99
|
+
lg: "large", // 1.125rem → large
|
|
100
|
+
xl: "big", // 1.25rem → big
|
|
101
|
+
"2xl": "huge", // 1.5rem → huge
|
|
102
|
+
"3xl": "grand", // 1.875rem → grand
|
|
103
|
+
"4xl": "giant", // 2.25rem → giant
|
|
104
|
+
"5xl": "mount", // 3rem → mount
|
|
105
|
+
"6xl": "mega", // 3.75rem → mega
|
|
106
|
+
"7xl": "giga", // 4.5rem → giga
|
|
107
|
+
"8xl": "tera", // 6rem → tera
|
|
108
|
+
"9xl": "hero", // 8rem → hero
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const layoutMappings = {
|
|
112
|
+
container: "container",
|
|
113
|
+
flex: "flex",
|
|
114
|
+
"inline-flex": "inline-flex",
|
|
115
|
+
grid: "grid",
|
|
116
|
+
"inline-grid": "inline-grid",
|
|
117
|
+
block: "block",
|
|
118
|
+
"inline-block": "inline",
|
|
119
|
+
hidden: "hidden",
|
|
120
|
+
"flex-row": "row",
|
|
121
|
+
"flex-col": "col",
|
|
122
|
+
"flex-row-reverse": "row-reverse",
|
|
123
|
+
"flex-col-reverse": "col-reverse",
|
|
124
|
+
"flex-wrap": "wrap",
|
|
125
|
+
"flex-nowrap": "nowrap",
|
|
126
|
+
"flex-wrap-reverse": "wrap-reverse",
|
|
127
|
+
"flex-grow": "grow",
|
|
128
|
+
"flex-grow-0": "grow-0",
|
|
129
|
+
grow: "grow",
|
|
130
|
+
"grow-0": "grow-0",
|
|
131
|
+
"flex-shrink": "shrink",
|
|
132
|
+
"flex-shrink-0": "shrink-0",
|
|
133
|
+
shrink: "shrink",
|
|
134
|
+
"shrink-0": "shrink-0",
|
|
135
|
+
"flex-1": "flex:1",
|
|
136
|
+
"flex-auto": "flex:auto",
|
|
137
|
+
"flex-initial": "flex:initial",
|
|
138
|
+
"flex-none": "flex:none",
|
|
139
|
+
"justify-start": "justify:start",
|
|
140
|
+
"justify-end": "justify:end",
|
|
141
|
+
"justify-center": "justify:center",
|
|
142
|
+
"justify-between": "justify:between",
|
|
143
|
+
"justify-around": "justify:around",
|
|
144
|
+
"justify-evenly": "justify:evenly",
|
|
145
|
+
"items-start": "items:start",
|
|
146
|
+
"items-end": "items:end",
|
|
147
|
+
"items-center": "items:center",
|
|
148
|
+
"items-baseline": "items:baseline",
|
|
149
|
+
"items-stretch": "items:stretch",
|
|
150
|
+
"self-auto": "self:auto",
|
|
151
|
+
"self-start": "self:start",
|
|
152
|
+
"self-end": "self:end",
|
|
153
|
+
"self-center": "self:center",
|
|
154
|
+
"self-stretch": "self:stretch",
|
|
155
|
+
relative: "relative",
|
|
156
|
+
absolute: "absolute",
|
|
157
|
+
fixed: "fixed",
|
|
158
|
+
sticky: "sticky",
|
|
159
|
+
static: "static",
|
|
160
|
+
"overflow-auto": "overflow:auto",
|
|
161
|
+
"overflow-hidden": "overflow:hidden",
|
|
162
|
+
"overflow-visible": "overflow:visible",
|
|
163
|
+
"overflow-scroll": "overflow:scroll",
|
|
164
|
+
"object-contain": "object:contain",
|
|
165
|
+
"object-cover": "object:cover",
|
|
166
|
+
"object-fill": "object:fill",
|
|
167
|
+
"object-none": "object:none",
|
|
168
|
+
"object-scale-down": "object:scale-down",
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const visualKeywords = {
|
|
172
|
+
italic: "italic",
|
|
173
|
+
"not-italic": "not-italic",
|
|
174
|
+
antialiased: "antialiased",
|
|
175
|
+
uppercase: "uppercase",
|
|
176
|
+
lowercase: "lowercase",
|
|
177
|
+
capitalize: "capitalize",
|
|
178
|
+
"normal-case": "normal-case",
|
|
179
|
+
underline: "underline",
|
|
180
|
+
"line-through": "line-through",
|
|
181
|
+
"no-underline": "no-underline",
|
|
182
|
+
truncate: "truncate",
|
|
183
|
+
"cursor-pointer": "cursor:pointer",
|
|
184
|
+
"cursor-default": "cursor:default",
|
|
185
|
+
"cursor-not-allowed": "cursor:not-allowed",
|
|
186
|
+
"select-none": "select:none",
|
|
187
|
+
"select-text": "select:text",
|
|
188
|
+
"select-all": "select:all",
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// ============================
|
|
192
|
+
// HELPER FUNCTIONS
|
|
193
|
+
// ============================
|
|
194
|
+
|
|
195
|
+
function getSpacing(value, exact) {
|
|
196
|
+
// Check if it's already an arbitrary value with brackets
|
|
197
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
198
|
+
return value; // Return as-is, don't double-wrap
|
|
199
|
+
}
|
|
200
|
+
if (exact) {
|
|
201
|
+
if (["full", "screen", "auto"].includes(value))
|
|
202
|
+
return spacingScale[value] || `[${value}]`;
|
|
203
|
+
return `tw-${value}`;
|
|
204
|
+
}
|
|
205
|
+
return spacingScale[value] || `[${value}]`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Border width scale mapping Tailwind values to SenangStart semantic values
|
|
209
|
+
// Engine native values: none(0), thin(1px), regular(2px), thick(3px)
|
|
210
|
+
const borderWidthScale = {
|
|
211
|
+
0: "none",
|
|
212
|
+
1: "thin", // 1px → thin (was [1px])
|
|
213
|
+
2: "regular", // 2px → regular
|
|
214
|
+
3: "thick", // 3px → thick
|
|
215
|
+
4: "tiny", // 4px → tiny
|
|
216
|
+
8: "small", // 8px → small
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
function getBorderWidth(value, exact) {
|
|
220
|
+
if (exact) {
|
|
221
|
+
return `tw-${value}`;
|
|
222
|
+
}
|
|
223
|
+
return borderWidthScale[value] || `[${value}px]`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============================
|
|
227
|
+
// CONVERSION FUNCTIONS
|
|
228
|
+
// ============================
|
|
229
|
+
|
|
230
|
+
function convertClass(twClass, exact) {
|
|
231
|
+
// Handle prefixes (hover:, sm:, md:, etc.)
|
|
232
|
+
const prefixMatch = twClass.match(
|
|
233
|
+
/^(sm:|md:|lg:|xl:|2xl:|hover:|focus:|focus-visible:|active:|disabled:|dark:)(.+)$/
|
|
234
|
+
);
|
|
235
|
+
let prefix = "",
|
|
236
|
+
baseClass = twClass;
|
|
237
|
+
if (prefixMatch) {
|
|
238
|
+
const rawPrefix = prefixMatch[1].slice(0, -1); // remove colon
|
|
239
|
+
if (['sm', 'md', 'lg', 'xl', '2xl'].includes(rawPrefix)) {
|
|
240
|
+
prefix = `tw-${rawPrefix}:`;
|
|
241
|
+
} else {
|
|
242
|
+
prefix = prefixMatch[1];
|
|
243
|
+
}
|
|
244
|
+
baseClass = prefixMatch[2];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Layout mappings
|
|
248
|
+
if (layoutMappings[baseClass])
|
|
249
|
+
return { cat: "layout", val: prefix + layoutMappings[baseClass] };
|
|
250
|
+
|
|
251
|
+
// Visual keywords
|
|
252
|
+
if (visualKeywords[baseClass])
|
|
253
|
+
return { cat: "visual", val: prefix + visualKeywords[baseClass] };
|
|
254
|
+
|
|
255
|
+
// Text color
|
|
256
|
+
const textColorMatch = baseClass.match(
|
|
257
|
+
/^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
|
+
);
|
|
259
|
+
if (textColorMatch)
|
|
260
|
+
return { cat: "visual", val: prefix + "text:" + textColorMatch[1] };
|
|
261
|
+
|
|
262
|
+
// Text alignment
|
|
263
|
+
if (
|
|
264
|
+
["text-left", "text-center", "text-right", "text-justify"].includes(
|
|
265
|
+
baseClass
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
return {
|
|
269
|
+
cat: "visual",
|
|
270
|
+
val: prefix + "text:" + baseClass.replace("text-", ""),
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// Text size
|
|
274
|
+
const textSizeMatch = baseClass.match(
|
|
275
|
+
/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/
|
|
276
|
+
);
|
|
277
|
+
if (textSizeMatch) {
|
|
278
|
+
const size = exact
|
|
279
|
+
? `tw-${textSizeMatch[1]}`
|
|
280
|
+
: fontSizeScale[textSizeMatch[1]] || textSizeMatch[1];
|
|
281
|
+
return { cat: "visual", val: prefix + "text-size:" + size };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Background color
|
|
285
|
+
const bgMatch = baseClass.match(
|
|
286
|
+
/^bg-((?: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+)?|transparent|current|inherit)$/
|
|
287
|
+
);
|
|
288
|
+
if (bgMatch) {
|
|
289
|
+
const colorVal = bgMatch[1];
|
|
290
|
+
// Handle special values
|
|
291
|
+
if (colorVal === 'transparent') {
|
|
292
|
+
return { cat: "visual", val: prefix + "bg:[transparent]" };
|
|
293
|
+
}
|
|
294
|
+
if (colorVal === 'current') {
|
|
295
|
+
return { cat: "visual", val: prefix + "bg:[currentColor]" };
|
|
296
|
+
}
|
|
297
|
+
if (colorVal === 'inherit') {
|
|
298
|
+
return { cat: "visual", val: prefix + "bg:[inherit]" };
|
|
299
|
+
}
|
|
300
|
+
return { cat: "visual", val: prefix + "bg:" + colorVal };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Border color
|
|
304
|
+
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+)?)$/
|
|
306
|
+
);
|
|
307
|
+
if (borderColorMatch)
|
|
308
|
+
return {
|
|
309
|
+
cat: "visual",
|
|
310
|
+
val: prefix + "border:" + borderColorMatch[1],
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// Padding
|
|
314
|
+
const paddingMatch = baseClass.match(/^p([trblxy])?-(.+)$/);
|
|
315
|
+
if (paddingMatch) {
|
|
316
|
+
const side = paddingMatch[1] ? "-" + paddingMatch[1] : "";
|
|
317
|
+
return {
|
|
318
|
+
cat: "space",
|
|
319
|
+
val: prefix + "p" + side + ":" + getSpacing(paddingMatch[2], exact),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Margin
|
|
324
|
+
const marginMatch = baseClass.match(
|
|
325
|
+
/^-?m([trblxy])?-(\d+\.?\d*|px|auto|full|screen)$/
|
|
326
|
+
);
|
|
327
|
+
if (marginMatch) {
|
|
328
|
+
const isNeg = baseClass.startsWith("-");
|
|
329
|
+
const side = marginMatch[1] ? "-" + marginMatch[1] : "";
|
|
330
|
+
let val = getSpacing(marginMatch[2], exact);
|
|
331
|
+
if (isNeg) val = "[-" + val + "]";
|
|
332
|
+
return { cat: "space", val: prefix + "m" + side + ":" + val };
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Gap
|
|
336
|
+
const gapMatch = baseClass.match(/^gap-([xy])?-?(.+)$/);
|
|
337
|
+
if (gapMatch) {
|
|
338
|
+
const axis = gapMatch[1] ? "-" + gapMatch[1] : "";
|
|
339
|
+
return {
|
|
340
|
+
cat: "space",
|
|
341
|
+
val: prefix + "g" + axis + ":" + getSpacing(gapMatch[2], exact),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Width/Height with special values
|
|
346
|
+
const widthMatch = baseClass.match(/^(min-w|max-w|w)-(.+)$/);
|
|
347
|
+
if (widthMatch) {
|
|
348
|
+
const prop = widthMatch[1];
|
|
349
|
+
const rawVal = widthMatch[2];
|
|
350
|
+
// Special width values
|
|
351
|
+
const specialWidthVals = { 'max': '[max-content]', 'min': '[min-content]', 'fit': '[fit-content]', 'prose': '[65ch]' };
|
|
352
|
+
const val = specialWidthVals[rawVal] || getSpacing(rawVal, exact);
|
|
353
|
+
return { cat: "space", val: prefix + prop + ":" + val };
|
|
354
|
+
}
|
|
355
|
+
const heightMatch = baseClass.match(/^(min-h|max-h|h)-(.+)$/);
|
|
356
|
+
if (heightMatch) {
|
|
357
|
+
const prop = heightMatch[1];
|
|
358
|
+
const rawVal = heightMatch[2];
|
|
359
|
+
const specialHeightVals = { 'screen': '[100vh]', 'svh': '[100svh]', 'lvh': '[100lvh]', 'dvh': '[100dvh]', 'max': '[max-content]', 'min': '[min-content]', 'fit': '[fit-content]' };
|
|
360
|
+
const val = specialHeightVals[rawVal] || getSpacing(rawVal, exact);
|
|
361
|
+
return { cat: "space", val: prefix + prop + ":" + val };
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Border radius
|
|
365
|
+
const roundedMatch = baseClass.match(/^rounded(?:-(.+))?$/);
|
|
366
|
+
if (roundedMatch) {
|
|
367
|
+
const size = roundedMatch[1] || "";
|
|
368
|
+
const scale = exact
|
|
369
|
+
? size === ""
|
|
370
|
+
? "tw-DEFAULT"
|
|
371
|
+
: `tw-${size}`
|
|
372
|
+
: radiusScale[size] || "medium";
|
|
373
|
+
return { cat: "visual", val: prefix + "rounded:" + scale };
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Shadow
|
|
377
|
+
const shadowMatch = baseClass.match(/^shadow(?:-(.+))?$/);
|
|
378
|
+
if (shadowMatch) {
|
|
379
|
+
const size = shadowMatch[1] || "";
|
|
380
|
+
const scale = exact
|
|
381
|
+
? size === ""
|
|
382
|
+
? "tw-DEFAULT"
|
|
383
|
+
: `tw-${size}`
|
|
384
|
+
: shadowScale[size] || "medium";
|
|
385
|
+
return { cat: "visual", val: prefix + "shadow:" + scale };
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Font weight
|
|
389
|
+
const fontWeightMatch = baseClass.match(
|
|
390
|
+
/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/
|
|
391
|
+
);
|
|
392
|
+
if (fontWeightMatch)
|
|
393
|
+
return { cat: "visual", val: prefix + "font:tw-" + fontWeightMatch[1] };
|
|
394
|
+
|
|
395
|
+
// Border width
|
|
396
|
+
const borderWidthMatch = baseClass.match(
|
|
397
|
+
/^border(?:-([trblxy]))?(?:-(\d+))?$/
|
|
398
|
+
);
|
|
399
|
+
if (
|
|
400
|
+
borderWidthMatch &&
|
|
401
|
+
(borderWidthMatch[2] ||
|
|
402
|
+
(!borderWidthMatch[1] && baseClass === "border"))
|
|
403
|
+
) {
|
|
404
|
+
const side = borderWidthMatch[1]
|
|
405
|
+
? "-" + borderWidthMatch[1] + "-w"
|
|
406
|
+
: "-w";
|
|
407
|
+
const width = borderWidthMatch[2] || "1";
|
|
408
|
+
return {
|
|
409
|
+
cat: "visual",
|
|
410
|
+
val: prefix + "border" + side + ":" + getBorderWidth(width, exact),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Positional properties (top-0, right-0, bottom-0, left-0, inset-0, etc.)
|
|
415
|
+
const positionMatch = baseClass.match(/^(top|right|bottom|left|inset|inset-x|inset-y)-(\d+|px|auto|full|\[.+\])$/);
|
|
416
|
+
if (positionMatch) {
|
|
417
|
+
const prop = positionMatch[1];
|
|
418
|
+
let val = positionMatch[2];
|
|
419
|
+
// Handle 0 specially
|
|
420
|
+
if (val === '0') {
|
|
421
|
+
val = 'none';
|
|
422
|
+
} else if (val.startsWith('[') && val.endsWith(']')) {
|
|
423
|
+
// Keep arbitrary values as-is
|
|
424
|
+
} else {
|
|
425
|
+
val = getSpacing(val, exact);
|
|
426
|
+
}
|
|
427
|
+
return { cat: "layout", val: prefix + prop + ":" + val };
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Outline none
|
|
431
|
+
if (baseClass === 'outline-none') {
|
|
432
|
+
return { cat: "visual", val: prefix + "outline:none" };
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Order
|
|
436
|
+
const orderMatch = baseClass.match(/^order-(\d+|first|last|none)$/);
|
|
437
|
+
if (orderMatch) {
|
|
438
|
+
return { cat: "layout", val: prefix + "order:" + orderMatch[1] };
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Grid columns
|
|
442
|
+
const gridColsMatch = baseClass.match(/^grid-cols-(\d+|none)$/);
|
|
443
|
+
if (gridColsMatch) {
|
|
444
|
+
return { cat: "layout", val: prefix + "grid-cols:" + gridColsMatch[1] };
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Column span
|
|
448
|
+
const colSpanMatch = baseClass.match(/^col-span-(\d+|full)$/);
|
|
449
|
+
if (colSpanMatch) {
|
|
450
|
+
return { cat: "layout", val: prefix + "col-span:" + colSpanMatch[1] };
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Grid rows
|
|
454
|
+
const gridRowsMatch = baseClass.match(/^grid-rows-(\d+|none)$/);
|
|
455
|
+
if (gridRowsMatch) {
|
|
456
|
+
return { cat: "layout", val: prefix + "grid-rows:" + gridRowsMatch[1] };
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Row span
|
|
460
|
+
const rowSpanMatch = baseClass.match(/^row-span-(\d+|full)$/);
|
|
461
|
+
if (rowSpanMatch) {
|
|
462
|
+
return { cat: "layout", val: prefix + "row-span:" + rowSpanMatch[1] };
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Opacity
|
|
466
|
+
const opacityMatch = baseClass.match(/^opacity-(\d+)$/);
|
|
467
|
+
if (opacityMatch) {
|
|
468
|
+
return { cat: "visual", val: prefix + "opacity:" + opacityMatch[1] };
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Gradient direction (bg-gradient-to-*)
|
|
472
|
+
const bgGradientMatch = baseClass.match(/^bg-gradient-to-(t|tr|r|br|b|bl|l|tl)$/);
|
|
473
|
+
if (bgGradientMatch) {
|
|
474
|
+
return { cat: "visual", val: prefix + "bg-image:gradient-to-" + bgGradientMatch[1] };
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Gradient from-* (starting color)
|
|
478
|
+
const fromMatch = baseClass.match(/^from-(.+)$/);
|
|
479
|
+
if (fromMatch) {
|
|
480
|
+
return { cat: "visual", val: prefix + "from:" + fromMatch[1] };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Gradient via-* (middle color)
|
|
484
|
+
const viaMatch = baseClass.match(/^via-(.+)$/);
|
|
485
|
+
if (viaMatch) {
|
|
486
|
+
return { cat: "visual", val: prefix + "via:" + viaMatch[1] };
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Gradient to-* (ending color) - Note: must come after bg-gradient-to-*
|
|
490
|
+
const toMatch = baseClass.match(/^to-(.+)$/);
|
|
491
|
+
if (toMatch) {
|
|
492
|
+
return { cat: "visual", val: prefix + "to:" + toMatch[1] };
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Transition utilities
|
|
496
|
+
const transitionMatch = baseClass.match(/^transition(?:-(all|colors|opacity|shadow|transform|none))?$/);
|
|
497
|
+
if (transitionMatch) {
|
|
498
|
+
const type = transitionMatch[1] || 'all';
|
|
499
|
+
return { cat: "visual", val: prefix + "transition:" + type };
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Duration utilities
|
|
503
|
+
const durationMatch = baseClass.match(/^duration-(\d+)$/);
|
|
504
|
+
if (durationMatch) {
|
|
505
|
+
// Map Tailwind duration (ms) to SenangStart semantic values
|
|
506
|
+
const ms = parseInt(durationMatch[1]);
|
|
507
|
+
let durationVal;
|
|
508
|
+
if (ms <= 75) durationVal = 'instant';
|
|
509
|
+
else if (ms <= 100) durationVal = 'quick';
|
|
510
|
+
else if (ms <= 150) durationVal = 'fast';
|
|
511
|
+
else if (ms <= 200) durationVal = 'normal';
|
|
512
|
+
else if (ms <= 300) durationVal = 'slow';
|
|
513
|
+
else if (ms <= 500) durationVal = 'slower';
|
|
514
|
+
else durationVal = 'lazy';
|
|
515
|
+
return { cat: "visual", val: prefix + "duration:" + durationVal };
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Ease utilities
|
|
519
|
+
const easeMatch = baseClass.match(/^ease-(linear|in|out|in-out)$/);
|
|
520
|
+
if (easeMatch) {
|
|
521
|
+
return { cat: "visual", val: prefix + "ease:" + easeMatch[1] };
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Ring utilities - Convert to native ring utilities
|
|
525
|
+
// Tailwind ring-4 generates: box-shadow: 0 0 0 4px var(--tw-ring-color)
|
|
526
|
+
const ringMatch = baseClass.match(/^ring(?:-(\d+))?$/);
|
|
527
|
+
if (ringMatch) {
|
|
528
|
+
const width = ringMatch[1] || '3';
|
|
529
|
+
if (width === '0') {
|
|
530
|
+
return { cat: "visual", val: prefix + "ring:none" };
|
|
531
|
+
}
|
|
532
|
+
// Map Tailwind ring widths to SenangStart semantic values
|
|
533
|
+
const ringScale = {
|
|
534
|
+
'1': 'thin', '2': 'regular', '3': 'small', '4': 'medium', '8': 'big'
|
|
535
|
+
};
|
|
536
|
+
const scale = ringScale[width] || `[${width}px]`;
|
|
537
|
+
return { cat: "visual", val: prefix + "ring:" + scale };
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Ring offset - converts to native ring-offset utility
|
|
541
|
+
const ringOffsetMatch = baseClass.match(/^ring-offset-(\d+)$/);
|
|
542
|
+
if (ringOffsetMatch) {
|
|
543
|
+
return { cat: "visual", val: prefix + "ring-offset:" + ringOffsetMatch[1] };
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Ring color - converts to native ring-color utility
|
|
547
|
+
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+)?)$/);
|
|
548
|
+
if (ringColorMatch) {
|
|
549
|
+
return { cat: "visual", val: prefix + "ring-color:" + ringColorMatch[1] };
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function convertClasses(classString, exact) {
|
|
556
|
+
const classes = classString
|
|
557
|
+
.trim()
|
|
558
|
+
.split(/\s+/)
|
|
559
|
+
.filter((c) => c);
|
|
560
|
+
const layout = [],
|
|
561
|
+
space = [],
|
|
562
|
+
visual = [],
|
|
563
|
+
unknown = [];
|
|
564
|
+
|
|
565
|
+
for (const cls of classes) {
|
|
566
|
+
const result = convertClass(cls, exact);
|
|
567
|
+
if (result) {
|
|
568
|
+
if (result.cat === "layout") layout.push(result.val);
|
|
569
|
+
else if (result.cat === "space") space.push(result.val);
|
|
570
|
+
else if (result.cat === "visual") visual.push(result.val);
|
|
571
|
+
} else {
|
|
572
|
+
unknown.push(cls);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return { layout, space, visual, unknown };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
function convertHTML(html, exact) {
|
|
580
|
+
return html.replace(
|
|
581
|
+
/class=(['"])([^"']+)\1/g,
|
|
582
|
+
(match, quote, classValue) => {
|
|
583
|
+
const { layout, space, visual, unknown } = convertClasses(
|
|
584
|
+
classValue,
|
|
585
|
+
exact
|
|
586
|
+
);
|
|
587
|
+
const attrs = [];
|
|
588
|
+
if (layout.length) attrs.push(`layout="${layout.join(" ")}"`);
|
|
589
|
+
if (space.length) attrs.push(`space="${space.join(" ")}"`);
|
|
590
|
+
if (visual.length) attrs.push(`visual="${visual.join(" ")}"`);
|
|
591
|
+
if (unknown.length) attrs.push(`class="${unknown.join(" ")}"`);
|
|
592
|
+
return attrs.join(" ") || 'class=""';
|
|
593
|
+
}
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// ============================
|
|
598
|
+
// EXPORTS
|
|
599
|
+
// ============================
|
|
600
|
+
|
|
601
|
+
// Export for browser (IIFE global)
|
|
602
|
+
if (typeof window !== 'undefined') {
|
|
603
|
+
window.SenangStartTW = {
|
|
604
|
+
convertClass,
|
|
605
|
+
convertClasses,
|
|
606
|
+
convertHTML,
|
|
607
|
+
// Expose scales for customization
|
|
608
|
+
scales: {
|
|
609
|
+
spacing: spacingScale,
|
|
610
|
+
radius: radiusScale,
|
|
611
|
+
shadow: shadowScale,
|
|
612
|
+
fontSize: fontSizeScale,
|
|
613
|
+
},
|
|
614
|
+
mappings: {
|
|
615
|
+
layout: layoutMappings,
|
|
616
|
+
visual: visualKeywords,
|
|
617
|
+
},
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// Export for ES modules
|
|
622
|
+
export {
|
|
623
|
+
convertClass,
|
|
624
|
+
convertClasses,
|
|
625
|
+
convertHTML,
|
|
626
|
+
spacingScale,
|
|
627
|
+
radiusScale,
|
|
628
|
+
shadowScale,
|
|
629
|
+
fontSizeScale,
|
|
630
|
+
layoutMappings,
|
|
631
|
+
visualKeywords,
|
|
632
|
+
};
|
|
@@ -1577,6 +1577,33 @@ function generateVisualRule(token, config) {
|
|
|
1577
1577
|
return `transform: skewY(${cssValue});`;
|
|
1578
1578
|
},
|
|
1579
1579
|
|
|
1580
|
+
// 3D Rotation (Rotate X/Y/Z)
|
|
1581
|
+
'rotate-x': () => {
|
|
1582
|
+
const cssValue = isArbitrary ? value : `${value}deg`;
|
|
1583
|
+
return `transform: rotateX(${cssValue});`;
|
|
1584
|
+
},
|
|
1585
|
+
|
|
1586
|
+
'rotate-y': () => {
|
|
1587
|
+
const cssValue = isArbitrary ? value : `${value}deg`;
|
|
1588
|
+
return `transform: rotateY(${cssValue});`;
|
|
1589
|
+
},
|
|
1590
|
+
|
|
1591
|
+
'rotate-z': () => {
|
|
1592
|
+
const cssValue = isArbitrary ? value : `${value}deg`;
|
|
1593
|
+
return `transform: rotateZ(${cssValue});`;
|
|
1594
|
+
},
|
|
1595
|
+
|
|
1596
|
+
// 3D Translation (Translate Z)
|
|
1597
|
+
'translate-z': () => {
|
|
1598
|
+
const translatePresets = {
|
|
1599
|
+
'near': '50px',
|
|
1600
|
+
'far': '-50px',
|
|
1601
|
+
'0': '0'
|
|
1602
|
+
};
|
|
1603
|
+
const cssValue = isArbitrary ? value : (translatePresets[value] || `var(--s-${value})`);
|
|
1604
|
+
return `transform: translateZ(${cssValue});`;
|
|
1605
|
+
},
|
|
1606
|
+
|
|
1580
1607
|
// Transform Origin
|
|
1581
1608
|
'origin': () => {
|
|
1582
1609
|
const originMap = {
|