@bookklik/senangstart-css 0.2.0 → 0.2.4
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 +102 -7
- package/dist/senangstart-css.min.js +26 -24
- package/dist/senangstart-tw.js +389 -0
- package/dist/senangstart-tw.min.js +2 -0
- package/docs/.vitepress/config.js +13 -4
- package/docs/SYNTAX-REFERENCE.md +1590 -1555
- package/docs/index.md +6 -0
- package/docs/ms/index.md +6 -0
- package/docs/ms/reference/visual/accent-color.md +6 -6
- package/docs/ms/reference/visual/animation-builtin.md +6 -6
- package/docs/ms/reference/visual/animation-delay.md +4 -2
- package/docs/ms/reference/visual/animation-direction.md +6 -6
- package/docs/ms/reference/visual/animation-duration.md +4 -4
- package/docs/ms/reference/visual/animation-fill.md +33 -9
- package/docs/ms/reference/visual/animation-iteration.md +5 -5
- package/docs/ms/reference/visual/animation-play.md +4 -4
- package/docs/ms/reference/visual/appearance.md +4 -4
- package/docs/ms/reference/visual/blend-modes.md +6 -6
- package/docs/ms/reference/visual/border-radius.md +8 -8
- package/docs/ms/reference/visual/box-shadow.md +6 -6
- package/docs/ms/reference/visual/caret-color.md +2 -2
- package/docs/ms/reference/visual/cursor.md +6 -6
- package/docs/ms/reference/visual/filter-blur.md +7 -7
- package/docs/ms/reference/visual/font-family.md +8 -8
- package/docs/ms/reference/visual/font-smoothing.md +4 -4
- package/docs/ms/reference/visual/font-style.md +4 -4
- package/docs/ms/reference/visual/font-variant-numeric.md +6 -4
- package/docs/ms/reference/visual/font-weight.md +6 -6
- 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/hyphens.md +6 -6
- package/docs/ms/reference/visual/letter-spacing.md +8 -8
- package/docs/ms/reference/visual/line-clamp.md +9 -9
- package/docs/ms/reference/visual/line-height.md +8 -8
- package/docs/ms/reference/visual/list-style.md +7 -7
- package/docs/ms/reference/visual/mask.md +6 -2
- package/docs/ms/reference/visual/opacity.md +8 -8
- package/docs/ms/reference/visual/pointer-events.md +4 -4
- package/docs/ms/reference/visual/state-prefixes.md +5 -3
- package/docs/ms/reference/visual/text-decoration.md +6 -4
- package/docs/ms/reference/visual/text-indent.md +8 -4
- package/docs/ms/reference/visual/text-overflow.md +6 -4
- package/docs/ms/reference/visual/text-shadow.md +8 -2
- package/docs/ms/reference/visual/text-size.md +31 -13
- package/docs/ms/reference/visual/text-transform.md +6 -6
- package/docs/ms/reference/visual/text-wrap.md +8 -8
- package/docs/ms/reference/visual/transform-backface.md +29 -9
- package/docs/ms/reference/visual/transform-origin.md +4 -4
- package/docs/ms/reference/visual/transform-perspective-origin.md +41 -7
- package/docs/ms/reference/visual/transform-perspective.md +41 -7
- package/docs/ms/reference/visual/transform-rotate-3d.md +93 -0
- package/docs/ms/reference/visual/transform-rotate.md +6 -6
- package/docs/ms/reference/visual/transform-scale.md +7 -7
- package/docs/ms/reference/visual/transform-skew.md +6 -6
- package/docs/ms/reference/visual/transform-style.md +31 -11
- package/docs/ms/reference/visual/transform-translate-z.md +90 -0
- package/docs/ms/reference/visual/transform-translate.md +40 -14
- package/docs/ms/reference/visual/transition-delay.md +4 -2
- package/docs/ms/reference/visual/transition-duration.md +4 -4
- package/docs/ms/reference/visual/transition-timing.md +6 -6
- package/docs/ms/reference/visual/typography-keywords.md +8 -8
- package/docs/ms/reference/visual/user-select.md +4 -4
- package/docs/ms/reference/visual/vertical-align.md +10 -8
- package/docs/ms/reference/visual/whitespace.md +8 -8
- package/docs/ms/reference/visual/word-break.md +8 -8
- package/docs/public/assets/senangstart-css.min.js +209 -1545
- package/docs/public/assets/ss-logo.svg +83 -0
- package/docs/reference/visual/accent-color.md +6 -6
- package/docs/reference/visual/animation-builtin.md +6 -6
- package/docs/reference/visual/animation-delay.md +4 -2
- package/docs/reference/visual/animation-direction.md +6 -6
- package/docs/reference/visual/animation-duration.md +4 -4
- package/docs/reference/visual/animation-fill.md +33 -9
- package/docs/reference/visual/animation-iteration.md +5 -5
- package/docs/reference/visual/animation-play.md +4 -4
- package/docs/reference/visual/appearance.md +4 -4
- package/docs/reference/visual/blend-modes.md +6 -6
- package/docs/reference/visual/border-radius.md +8 -8
- package/docs/reference/visual/box-shadow.md +6 -6
- package/docs/reference/visual/caret-color.md +2 -2
- package/docs/reference/visual/cursor.md +6 -6
- package/docs/reference/visual/filter-blur.md +7 -7
- package/docs/reference/visual/font-family.md +8 -8
- package/docs/reference/visual/font-smoothing.md +4 -4
- package/docs/reference/visual/font-style.md +4 -4
- package/docs/reference/visual/font-variant-numeric.md +6 -4
- package/docs/reference/visual/font-weight.md +6 -6
- 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/hyphens.md +6 -6
- package/docs/reference/visual/letter-spacing.md +8 -8
- package/docs/reference/visual/line-clamp.md +9 -9
- package/docs/reference/visual/line-height.md +8 -8
- package/docs/reference/visual/list-style.md +7 -7
- package/docs/reference/visual/mask.md +6 -2
- package/docs/reference/visual/opacity.md +8 -8
- package/docs/reference/visual/pointer-events.md +4 -4
- package/docs/reference/visual/state-prefixes.md +5 -3
- package/docs/reference/visual/text-decoration.md +6 -4
- package/docs/reference/visual/text-indent.md +8 -4
- package/docs/reference/visual/text-overflow.md +6 -4
- package/docs/reference/visual/text-shadow.md +8 -2
- package/docs/reference/visual/text-size.md +31 -13
- package/docs/reference/visual/text-transform.md +6 -6
- package/docs/reference/visual/text-wrap.md +8 -8
- package/docs/reference/visual/transform-backface.md +29 -9
- package/docs/reference/visual/transform-origin.md +4 -4
- package/docs/reference/visual/transform-perspective-origin.md +41 -7
- package/docs/reference/visual/transform-perspective.md +41 -7
- package/docs/reference/visual/transform-rotate-3d.md +93 -0
- package/docs/reference/visual/transform-rotate.md +6 -6
- package/docs/reference/visual/transform-scale.md +7 -7
- package/docs/reference/visual/transform-skew.md +6 -6
- package/docs/reference/visual/transform-style.md +31 -11
- package/docs/reference/visual/transform-translate-z.md +90 -0
- package/docs/reference/visual/transform-translate.md +40 -14
- package/docs/reference/visual/transition-delay.md +4 -2
- package/docs/reference/visual/transition-duration.md +4 -4
- package/docs/reference/visual/transition-timing.md +6 -6
- package/docs/reference/visual/typography-keywords.md +8 -8
- package/docs/reference/visual/user-select.md +4 -4
- package/docs/reference/visual/vertical-align.md +10 -8
- package/docs/reference/visual/whitespace.md +8 -8
- package/docs/reference/visual/word-break.md +8 -8
- package/docs/syntax-reference.json +2009 -1972
- package/package.json +2 -2
- package/playground/index.html +37 -38
- package/playground/sample_code.txt +23 -0
- package/playground/tw-convertor.html +103 -589
- package/scripts/build-dist.js +43 -1
- package/scripts/convert-tailwind.js +24 -0
- package/scripts/generate-docs.js +9 -7
- package/src/cdn/jit.js +70 -7
- package/src/cdn/tw-conversion-engine.js +497 -0
- package/src/compiler/generators/css.js +24 -2
- package/src/config/defaults.js +31 -7
- package/src/definitions/layout-positioning.js +6 -6
- package/src/definitions/visual-backgrounds.js +113 -15
- package/src/definitions/visual-borders.js +1 -1
- package/src/definitions/visual-filters.js +16 -16
- package/src/definitions/visual-svg.js +5 -5
- package/src/definitions/visual-transform3d.js +202 -36
- package/src/definitions/visual-transforms.js +42 -25
- package/src/definitions/visual-transitions.js +40 -26
- package/src/definitions/visual-typography.js +53 -44
- package/src/definitions/visual.js +73 -58
- package/tests/unit/convert-tailwind.test.js +8 -0
|
@@ -0,0 +1,497 @@
|
|
|
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
|
+
const spacingScale = {
|
|
11
|
+
0: "none",
|
|
12
|
+
px: "[1px]",
|
|
13
|
+
0.5: "tiny",
|
|
14
|
+
1: "tiny",
|
|
15
|
+
1.5: "tiny",
|
|
16
|
+
2: "tiny",
|
|
17
|
+
2.5: "small",
|
|
18
|
+
3: "small",
|
|
19
|
+
3.5: "small",
|
|
20
|
+
4: "small",
|
|
21
|
+
5: "medium",
|
|
22
|
+
6: "medium",
|
|
23
|
+
7: "medium",
|
|
24
|
+
8: "big",
|
|
25
|
+
9: "big",
|
|
26
|
+
10: "big",
|
|
27
|
+
11: "big",
|
|
28
|
+
12: "giant",
|
|
29
|
+
14: "giant",
|
|
30
|
+
16: "giant",
|
|
31
|
+
20: "vast",
|
|
32
|
+
24: "vast",
|
|
33
|
+
28: "vast",
|
|
34
|
+
32: "vast",
|
|
35
|
+
36: "vast",
|
|
36
|
+
40: "vast",
|
|
37
|
+
44: "vast",
|
|
38
|
+
48: "vast",
|
|
39
|
+
52: "vast",
|
|
40
|
+
56: "vast",
|
|
41
|
+
60: "vast",
|
|
42
|
+
64: "vast",
|
|
43
|
+
72: "vast",
|
|
44
|
+
80: "vast",
|
|
45
|
+
96: "vast",
|
|
46
|
+
full: "[100%]",
|
|
47
|
+
screen: "[100vw]",
|
|
48
|
+
auto: "auto",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const radiusScale = {
|
|
52
|
+
none: "none",
|
|
53
|
+
sm: "small",
|
|
54
|
+
"": "small",
|
|
55
|
+
md: "medium",
|
|
56
|
+
lg: "medium",
|
|
57
|
+
xl: "big",
|
|
58
|
+
"2xl": "big",
|
|
59
|
+
"3xl": "big",
|
|
60
|
+
full: "round",
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const shadowScale = {
|
|
64
|
+
sm: "small",
|
|
65
|
+
"": "small",
|
|
66
|
+
md: "medium",
|
|
67
|
+
lg: "big",
|
|
68
|
+
xl: "giant",
|
|
69
|
+
"2xl": "giant",
|
|
70
|
+
none: "none",
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const fontSizeScale = {
|
|
74
|
+
xs: "mini", // 0.75rem
|
|
75
|
+
sm: "small", // 0.875rem
|
|
76
|
+
base: "base", // 1rem
|
|
77
|
+
lg: "large", // 1.125rem
|
|
78
|
+
xl: "big", // 1.25rem
|
|
79
|
+
"2xl": "huge", // 1.5rem
|
|
80
|
+
"3xl": "grand", // 1.875rem
|
|
81
|
+
"4xl": "giant", // 2.25rem
|
|
82
|
+
"5xl": "mount", // 3rem
|
|
83
|
+
"6xl": "mega", // 3.75rem
|
|
84
|
+
"7xl": "giga", // 4.5rem
|
|
85
|
+
"8xl": "tera", // 6rem
|
|
86
|
+
"9xl": "hero", // 8rem
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const layoutMappings = {
|
|
90
|
+
container: "container",
|
|
91
|
+
flex: "flex",
|
|
92
|
+
"inline-flex": "inline-flex",
|
|
93
|
+
grid: "grid",
|
|
94
|
+
"inline-grid": "inline-grid",
|
|
95
|
+
block: "block",
|
|
96
|
+
"inline-block": "inline",
|
|
97
|
+
hidden: "hidden",
|
|
98
|
+
"flex-row": "row",
|
|
99
|
+
"flex-col": "col",
|
|
100
|
+
"flex-row-reverse": "row-reverse",
|
|
101
|
+
"flex-col-reverse": "col-reverse",
|
|
102
|
+
"flex-wrap": "wrap",
|
|
103
|
+
"flex-nowrap": "nowrap",
|
|
104
|
+
"flex-wrap-reverse": "wrap-reverse",
|
|
105
|
+
"flex-grow": "grow",
|
|
106
|
+
"flex-grow-0": "grow-0",
|
|
107
|
+
grow: "grow",
|
|
108
|
+
"grow-0": "grow-0",
|
|
109
|
+
"flex-shrink": "shrink",
|
|
110
|
+
"flex-shrink-0": "shrink-0",
|
|
111
|
+
shrink: "shrink",
|
|
112
|
+
"shrink-0": "shrink-0",
|
|
113
|
+
"flex-1": "flex:1",
|
|
114
|
+
"flex-auto": "flex:auto",
|
|
115
|
+
"flex-initial": "flex:initial",
|
|
116
|
+
"flex-none": "flex:none",
|
|
117
|
+
"justify-start": "justify:start",
|
|
118
|
+
"justify-end": "justify:end",
|
|
119
|
+
"justify-center": "justify:center",
|
|
120
|
+
"justify-between": "justify:between",
|
|
121
|
+
"justify-around": "justify:around",
|
|
122
|
+
"justify-evenly": "justify:evenly",
|
|
123
|
+
"items-start": "items:start",
|
|
124
|
+
"items-end": "items:end",
|
|
125
|
+
"items-center": "items:center",
|
|
126
|
+
"items-baseline": "items:baseline",
|
|
127
|
+
"items-stretch": "items:stretch",
|
|
128
|
+
"self-auto": "self:auto",
|
|
129
|
+
"self-start": "self:start",
|
|
130
|
+
"self-end": "self:end",
|
|
131
|
+
"self-center": "self:center",
|
|
132
|
+
"self-stretch": "self:stretch",
|
|
133
|
+
relative: "relative",
|
|
134
|
+
absolute: "absolute",
|
|
135
|
+
fixed: "fixed",
|
|
136
|
+
sticky: "sticky",
|
|
137
|
+
static: "static",
|
|
138
|
+
"overflow-auto": "overflow:auto",
|
|
139
|
+
"overflow-hidden": "overflow:hidden",
|
|
140
|
+
"overflow-visible": "overflow:visible",
|
|
141
|
+
"overflow-scroll": "overflow:scroll",
|
|
142
|
+
"object-contain": "object:contain",
|
|
143
|
+
"object-cover": "object:cover",
|
|
144
|
+
"object-fill": "object:fill",
|
|
145
|
+
"object-none": "object:none",
|
|
146
|
+
"object-scale-down": "object:scale-down",
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const visualKeywords = {
|
|
150
|
+
italic: "italic",
|
|
151
|
+
"not-italic": "not-italic",
|
|
152
|
+
antialiased: "antialiased",
|
|
153
|
+
uppercase: "uppercase",
|
|
154
|
+
lowercase: "lowercase",
|
|
155
|
+
capitalize: "capitalize",
|
|
156
|
+
"normal-case": "normal-case",
|
|
157
|
+
underline: "underline",
|
|
158
|
+
"line-through": "line-through",
|
|
159
|
+
"no-underline": "no-underline",
|
|
160
|
+
truncate: "truncate",
|
|
161
|
+
"cursor-pointer": "cursor:pointer",
|
|
162
|
+
"cursor-default": "cursor:default",
|
|
163
|
+
"cursor-not-allowed": "cursor:not-allowed",
|
|
164
|
+
"select-none": "select:none",
|
|
165
|
+
"select-text": "select:text",
|
|
166
|
+
"select-all": "select:all",
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// ============================
|
|
170
|
+
// HELPER FUNCTIONS
|
|
171
|
+
// ============================
|
|
172
|
+
|
|
173
|
+
function getSpacing(value, exact) {
|
|
174
|
+
if (exact) {
|
|
175
|
+
if (["full", "screen", "auto"].includes(value))
|
|
176
|
+
return spacingScale[value] || `[${value}]`;
|
|
177
|
+
return `tw-${value}`;
|
|
178
|
+
}
|
|
179
|
+
return spacingScale[value] || `[${value}]`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ============================
|
|
183
|
+
// CONVERSION FUNCTIONS
|
|
184
|
+
// ============================
|
|
185
|
+
|
|
186
|
+
function convertClass(twClass, exact) {
|
|
187
|
+
// Handle prefixes (hover:, sm:, md:, etc.)
|
|
188
|
+
const prefixMatch = twClass.match(
|
|
189
|
+
/^(sm:|md:|lg:|xl:|2xl:|hover:|focus:|active:|disabled:|dark:)(.+)$/
|
|
190
|
+
);
|
|
191
|
+
let prefix = "",
|
|
192
|
+
baseClass = twClass;
|
|
193
|
+
if (prefixMatch) {
|
|
194
|
+
const rawPrefix = prefixMatch[1].slice(0, -1); // remove colon
|
|
195
|
+
if (['sm', 'md', 'lg', 'xl', '2xl'].includes(rawPrefix)) {
|
|
196
|
+
prefix = `tw-${rawPrefix}:`;
|
|
197
|
+
} else {
|
|
198
|
+
prefix = prefixMatch[1];
|
|
199
|
+
}
|
|
200
|
+
baseClass = prefixMatch[2];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Layout mappings
|
|
204
|
+
if (layoutMappings[baseClass])
|
|
205
|
+
return { cat: "layout", val: prefix + layoutMappings[baseClass] };
|
|
206
|
+
|
|
207
|
+
// Visual keywords
|
|
208
|
+
if (visualKeywords[baseClass])
|
|
209
|
+
return { cat: "visual", val: prefix + visualKeywords[baseClass] };
|
|
210
|
+
|
|
211
|
+
// Text color
|
|
212
|
+
const textColorMatch = baseClass.match(
|
|
213
|
+
/^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+)?)$/
|
|
214
|
+
);
|
|
215
|
+
if (textColorMatch)
|
|
216
|
+
return { cat: "visual", val: prefix + "text:" + textColorMatch[1] };
|
|
217
|
+
|
|
218
|
+
// Text alignment
|
|
219
|
+
if (
|
|
220
|
+
["text-left", "text-center", "text-right", "text-justify"].includes(
|
|
221
|
+
baseClass
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
return {
|
|
225
|
+
cat: "visual",
|
|
226
|
+
val: prefix + "text:" + baseClass.replace("text-", ""),
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Text size
|
|
230
|
+
const textSizeMatch = baseClass.match(
|
|
231
|
+
/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/
|
|
232
|
+
);
|
|
233
|
+
if (textSizeMatch) {
|
|
234
|
+
const size = exact
|
|
235
|
+
? `tw-${textSizeMatch[1]}`
|
|
236
|
+
: fontSizeScale[textSizeMatch[1]] || textSizeMatch[1];
|
|
237
|
+
return { cat: "visual", val: prefix + "text-size:" + size };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Background color
|
|
241
|
+
const bgMatch = baseClass.match(
|
|
242
|
+
/^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+)?)$/
|
|
243
|
+
);
|
|
244
|
+
if (bgMatch) return { cat: "visual", val: prefix + "bg:" + bgMatch[1] };
|
|
245
|
+
|
|
246
|
+
// Border color
|
|
247
|
+
const borderColorMatch = baseClass.match(
|
|
248
|
+
/^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+)?)$/
|
|
249
|
+
);
|
|
250
|
+
if (borderColorMatch)
|
|
251
|
+
return {
|
|
252
|
+
cat: "visual",
|
|
253
|
+
val: prefix + "border:" + borderColorMatch[1],
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// Padding
|
|
257
|
+
const paddingMatch = baseClass.match(/^p([trblxy])?-(.+)$/);
|
|
258
|
+
if (paddingMatch) {
|
|
259
|
+
const side = paddingMatch[1] ? "-" + paddingMatch[1] : "";
|
|
260
|
+
return {
|
|
261
|
+
cat: "space",
|
|
262
|
+
val: prefix + "p" + side + ":" + getSpacing(paddingMatch[2], exact),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Margin
|
|
267
|
+
const marginMatch = baseClass.match(
|
|
268
|
+
/^-?m([trblxy])?-(\d+\.?\d*|px|auto|full|screen)$/
|
|
269
|
+
);
|
|
270
|
+
if (marginMatch) {
|
|
271
|
+
const isNeg = baseClass.startsWith("-");
|
|
272
|
+
const side = marginMatch[1] ? "-" + marginMatch[1] : "";
|
|
273
|
+
let val = getSpacing(marginMatch[2], exact);
|
|
274
|
+
if (isNeg) val = "[-" + val + "]";
|
|
275
|
+
return { cat: "space", val: prefix + "m" + side + ":" + val };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Gap
|
|
279
|
+
const gapMatch = baseClass.match(/^gap-([xy])?-?(.+)$/);
|
|
280
|
+
if (gapMatch) {
|
|
281
|
+
const axis = gapMatch[1] ? "-" + gapMatch[1] : "";
|
|
282
|
+
return {
|
|
283
|
+
cat: "space",
|
|
284
|
+
val: prefix + "g" + axis + ":" + getSpacing(gapMatch[2], exact),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Width/Height with special values
|
|
289
|
+
const widthMatch = baseClass.match(/^(min-w|max-w|w)-(.+)$/);
|
|
290
|
+
if (widthMatch) {
|
|
291
|
+
const prop = widthMatch[1];
|
|
292
|
+
const rawVal = widthMatch[2];
|
|
293
|
+
// Special width values
|
|
294
|
+
const specialWidthVals = { 'max': '[max-content]', 'min': '[min-content]', 'fit': '[fit-content]', 'prose': '[65ch]' };
|
|
295
|
+
const val = specialWidthVals[rawVal] || getSpacing(rawVal, exact);
|
|
296
|
+
return { cat: "space", val: prefix + prop + ":" + val };
|
|
297
|
+
}
|
|
298
|
+
const heightMatch = baseClass.match(/^(min-h|max-h|h)-(.+)$/);
|
|
299
|
+
if (heightMatch) {
|
|
300
|
+
const prop = heightMatch[1];
|
|
301
|
+
const rawVal = heightMatch[2];
|
|
302
|
+
const specialHeightVals = { 'screen': '[100vh]', 'svh': '[100svh]', 'lvh': '[100lvh]', 'dvh': '[100dvh]', 'max': '[max-content]', 'min': '[min-content]', 'fit': '[fit-content]' };
|
|
303
|
+
const val = specialHeightVals[rawVal] || getSpacing(rawVal, exact);
|
|
304
|
+
return { cat: "space", val: prefix + prop + ":" + val };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Border radius
|
|
308
|
+
const roundedMatch = baseClass.match(/^rounded(?:-(.+))?$/);
|
|
309
|
+
if (roundedMatch) {
|
|
310
|
+
const size = roundedMatch[1] || "";
|
|
311
|
+
const scale = exact
|
|
312
|
+
? size === ""
|
|
313
|
+
? "tw-DEFAULT"
|
|
314
|
+
: `tw-${size}`
|
|
315
|
+
: radiusScale[size] || "medium";
|
|
316
|
+
return { cat: "visual", val: prefix + "rounded:" + scale };
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Shadow
|
|
320
|
+
const shadowMatch = baseClass.match(/^shadow(?:-(.+))?$/);
|
|
321
|
+
if (shadowMatch) {
|
|
322
|
+
const size = shadowMatch[1] || "";
|
|
323
|
+
const scale = exact
|
|
324
|
+
? size === ""
|
|
325
|
+
? "tw-DEFAULT"
|
|
326
|
+
: `tw-${size}`
|
|
327
|
+
: shadowScale[size] || "medium";
|
|
328
|
+
return { cat: "visual", val: prefix + "shadow:" + scale };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Font weight
|
|
332
|
+
const fontWeightMatch = baseClass.match(
|
|
333
|
+
/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/
|
|
334
|
+
);
|
|
335
|
+
if (fontWeightMatch)
|
|
336
|
+
return { cat: "visual", val: prefix + "font:tw-" + fontWeightMatch[1] };
|
|
337
|
+
|
|
338
|
+
// Border width
|
|
339
|
+
const borderWidthMatch = baseClass.match(
|
|
340
|
+
/^border(?:-([trblxy]))?(?:-(\d+))?$/
|
|
341
|
+
);
|
|
342
|
+
if (
|
|
343
|
+
borderWidthMatch &&
|
|
344
|
+
(borderWidthMatch[2] ||
|
|
345
|
+
(!borderWidthMatch[1] && baseClass === "border"))
|
|
346
|
+
) {
|
|
347
|
+
const side = borderWidthMatch[1]
|
|
348
|
+
? "-" + borderWidthMatch[1] + "-w"
|
|
349
|
+
: "-w";
|
|
350
|
+
const width = borderWidthMatch[2] || "1";
|
|
351
|
+
return {
|
|
352
|
+
cat: "visual",
|
|
353
|
+
val: prefix + "border" + side + ":[" + width + "px]",
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Order
|
|
358
|
+
const orderMatch = baseClass.match(/^order-(\d+|first|last|none)$/);
|
|
359
|
+
if (orderMatch) {
|
|
360
|
+
return { cat: "layout", val: prefix + "order:" + orderMatch[1] };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Grid columns
|
|
364
|
+
const gridColsMatch = baseClass.match(/^grid-cols-(\d+|none)$/);
|
|
365
|
+
if (gridColsMatch) {
|
|
366
|
+
return { cat: "layout", val: prefix + "grid-cols:" + gridColsMatch[1] };
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Column span
|
|
370
|
+
const colSpanMatch = baseClass.match(/^col-span-(\d+|full)$/);
|
|
371
|
+
if (colSpanMatch) {
|
|
372
|
+
return { cat: "layout", val: prefix + "col-span:" + colSpanMatch[1] };
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Grid rows
|
|
376
|
+
const gridRowsMatch = baseClass.match(/^grid-rows-(\d+|none)$/);
|
|
377
|
+
if (gridRowsMatch) {
|
|
378
|
+
return { cat: "layout", val: prefix + "grid-rows:" + gridRowsMatch[1] };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Row span
|
|
382
|
+
const rowSpanMatch = baseClass.match(/^row-span-(\d+|full)$/);
|
|
383
|
+
if (rowSpanMatch) {
|
|
384
|
+
return { cat: "layout", val: prefix + "row-span:" + rowSpanMatch[1] };
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Opacity
|
|
388
|
+
const opacityMatch = baseClass.match(/^opacity-(\d+)$/);
|
|
389
|
+
if (opacityMatch) {
|
|
390
|
+
return { cat: "visual", val: prefix + "opacity:" + opacityMatch[1] };
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Gradient direction (bg-gradient-to-*)
|
|
394
|
+
const bgGradientMatch = baseClass.match(/^bg-gradient-to-(t|tr|r|br|b|bl|l|tl)$/);
|
|
395
|
+
if (bgGradientMatch) {
|
|
396
|
+
return { cat: "visual", val: prefix + "bg-image:gradient-to-" + bgGradientMatch[1] };
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Gradient from-* (starting color)
|
|
400
|
+
const fromMatch = baseClass.match(/^from-(.+)$/);
|
|
401
|
+
if (fromMatch) {
|
|
402
|
+
return { cat: "visual", val: prefix + "from:" + fromMatch[1] };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Gradient via-* (middle color)
|
|
406
|
+
const viaMatch = baseClass.match(/^via-(.+)$/);
|
|
407
|
+
if (viaMatch) {
|
|
408
|
+
return { cat: "visual", val: prefix + "via:" + viaMatch[1] };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Gradient to-* (ending color) - Note: must come after bg-gradient-to-*
|
|
412
|
+
const toMatch = baseClass.match(/^to-(.+)$/);
|
|
413
|
+
if (toMatch) {
|
|
414
|
+
return { cat: "visual", val: prefix + "to:" + toMatch[1] };
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function convertClasses(classString, exact) {
|
|
421
|
+
const classes = classString
|
|
422
|
+
.trim()
|
|
423
|
+
.split(/\s+/)
|
|
424
|
+
.filter((c) => c);
|
|
425
|
+
const layout = [],
|
|
426
|
+
space = [],
|
|
427
|
+
visual = [],
|
|
428
|
+
unknown = [];
|
|
429
|
+
|
|
430
|
+
for (const cls of classes) {
|
|
431
|
+
const result = convertClass(cls, exact);
|
|
432
|
+
if (result) {
|
|
433
|
+
if (result.cat === "layout") layout.push(result.val);
|
|
434
|
+
else if (result.cat === "space") space.push(result.val);
|
|
435
|
+
else if (result.cat === "visual") visual.push(result.val);
|
|
436
|
+
} else {
|
|
437
|
+
unknown.push(cls);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return { layout, space, visual, unknown };
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function convertHTML(html, exact) {
|
|
445
|
+
return html.replace(
|
|
446
|
+
/class=(['"])([^"']+)\1/g,
|
|
447
|
+
(match, quote, classValue) => {
|
|
448
|
+
const { layout, space, visual, unknown } = convertClasses(
|
|
449
|
+
classValue,
|
|
450
|
+
exact
|
|
451
|
+
);
|
|
452
|
+
const attrs = [];
|
|
453
|
+
if (layout.length) attrs.push(`layout="${layout.join(" ")}"`);
|
|
454
|
+
if (space.length) attrs.push(`space="${space.join(" ")}"`);
|
|
455
|
+
if (visual.length) attrs.push(`visual="${visual.join(" ")}"`);
|
|
456
|
+
if (unknown.length) attrs.push(`class="${unknown.join(" ")}"`);
|
|
457
|
+
return attrs.join(" ") || 'class=""';
|
|
458
|
+
}
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// ============================
|
|
463
|
+
// EXPORTS
|
|
464
|
+
// ============================
|
|
465
|
+
|
|
466
|
+
// Export for browser (IIFE global)
|
|
467
|
+
if (typeof window !== 'undefined') {
|
|
468
|
+
window.SenangStartTW = {
|
|
469
|
+
convertClass,
|
|
470
|
+
convertClasses,
|
|
471
|
+
convertHTML,
|
|
472
|
+
// Expose scales for customization
|
|
473
|
+
scales: {
|
|
474
|
+
spacing: spacingScale,
|
|
475
|
+
radius: radiusScale,
|
|
476
|
+
shadow: shadowScale,
|
|
477
|
+
fontSize: fontSizeScale,
|
|
478
|
+
},
|
|
479
|
+
mappings: {
|
|
480
|
+
layout: layoutMappings,
|
|
481
|
+
visual: visualKeywords,
|
|
482
|
+
},
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Export for ES modules
|
|
487
|
+
export {
|
|
488
|
+
convertClass,
|
|
489
|
+
convertClasses,
|
|
490
|
+
convertHTML,
|
|
491
|
+
spacingScale,
|
|
492
|
+
radiusScale,
|
|
493
|
+
shadowScale,
|
|
494
|
+
fontSizeScale,
|
|
495
|
+
layoutMappings,
|
|
496
|
+
visualKeywords,
|
|
497
|
+
};
|
|
@@ -51,6 +51,13 @@ export function generateCSSVariables(config) {
|
|
|
51
51
|
css += ` --font-${key}: ${value};\n`;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
// Font size line-height variables (paired with font sizes)
|
|
55
|
+
if (theme.fontSizeLineHeight) {
|
|
56
|
+
for (const [key, value] of Object.entries(theme.fontSizeLineHeight)) {
|
|
57
|
+
css += ` --font-lh-${key}: ${value};\n`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
// Font weight variables
|
|
55
62
|
for (const [key, value] of Object.entries(theme.fontWeight)) {
|
|
56
63
|
css += ` --fw-${key}: ${value};\n`;
|
|
@@ -118,6 +125,16 @@ export function generateCSSVariables(config) {
|
|
|
118
125
|
css += ` --tw-text-${key}: ${value};\n`;
|
|
119
126
|
}
|
|
120
127
|
|
|
128
|
+
// Tailwind Line Height Scale (paired with font sizes)
|
|
129
|
+
const twLeading = {
|
|
130
|
+
'xs': '1rem', 'sm': '1.25rem', 'base': '1.5rem', 'lg': '1.75rem', 'xl': '1.75rem',
|
|
131
|
+
'2xl': '2rem', '3xl': '2.25rem', '4xl': '2.5rem', '5xl': '1',
|
|
132
|
+
'6xl': '1', '7xl': '1', '8xl': '1', '9xl': '1'
|
|
133
|
+
};
|
|
134
|
+
for (const [key, value] of Object.entries(twLeading)) {
|
|
135
|
+
css += ` --tw-leading-${key}: ${value};\n`;
|
|
136
|
+
}
|
|
137
|
+
|
|
121
138
|
// Tailwind Font Weight Scale
|
|
122
139
|
const twFontWeight = {
|
|
123
140
|
'thin': '100',
|
|
@@ -817,18 +834,23 @@ function generateVisualRule(token, config) {
|
|
|
817
834
|
return `text-shadow: ${cssValue};`;
|
|
818
835
|
},
|
|
819
836
|
|
|
820
|
-
// Font size
|
|
837
|
+
// Font size (with paired line-height)
|
|
821
838
|
'text-size': () => {
|
|
822
839
|
let cssValue;
|
|
840
|
+
let lineHeightValue;
|
|
823
841
|
if (isArbitrary) {
|
|
824
842
|
cssValue = value;
|
|
843
|
+
// No line-height for arbitrary values
|
|
844
|
+
return `font-size: ${cssValue};`;
|
|
825
845
|
} else if (value.startsWith('tw-')) {
|
|
826
846
|
const twValue = value.slice(3);
|
|
827
847
|
cssValue = `var(--tw-text-${twValue})`;
|
|
848
|
+
lineHeightValue = `var(--tw-leading-${twValue})`;
|
|
828
849
|
} else {
|
|
829
850
|
cssValue = `var(--font-${value})`;
|
|
851
|
+
lineHeightValue = `var(--font-lh-${value})`;
|
|
830
852
|
}
|
|
831
|
-
return `font-size: ${cssValue};`;
|
|
853
|
+
return `font-size: ${cssValue}; line-height: ${lineHeightValue};`;
|
|
832
854
|
},
|
|
833
855
|
|
|
834
856
|
// Font weight / family
|
package/src/config/defaults.js
CHANGED
|
@@ -65,14 +65,38 @@ export const defaultConfig = {
|
|
|
65
65
|
'giant': '0 25px 50px rgba(0,0,0,0.25)'
|
|
66
66
|
},
|
|
67
67
|
|
|
68
|
-
// 4. FONT SIZES: Reading Scale
|
|
68
|
+
// 4. FONT SIZES: Reading Scale (with paired line-heights)
|
|
69
69
|
fontSize: {
|
|
70
|
-
'
|
|
71
|
-
'small':
|
|
72
|
-
'
|
|
73
|
-
'
|
|
74
|
-
'
|
|
75
|
-
'
|
|
70
|
+
'mini': '0.75rem', // 12px
|
|
71
|
+
'small': '0.875rem', // 14px
|
|
72
|
+
'base': '1rem', // 16px
|
|
73
|
+
'large': '1.125rem', // 18px
|
|
74
|
+
'big': '1.25rem', // 20px (xl)
|
|
75
|
+
'huge': '1.5rem', // 24px (2xl)
|
|
76
|
+
'grand': '1.875rem', // 30px (3xl)
|
|
77
|
+
'giant': '2.25rem', // 36px (4xl)
|
|
78
|
+
'mount': '3rem', // 48px (5xl)
|
|
79
|
+
'mega': '3.75rem', // 60px (6xl)
|
|
80
|
+
'giga': '4.5rem', // 72px (7xl)
|
|
81
|
+
'tera': '6rem', // 96px (8xl)
|
|
82
|
+
'hero': '8rem' // 128px
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
// 4b. FONT SIZE LINE-HEIGHTS: Paired with font sizes
|
|
86
|
+
fontSizeLineHeight: {
|
|
87
|
+
'mini': '1rem', // 16px
|
|
88
|
+
'small': '1.25rem', // 20px
|
|
89
|
+
'base': '1.5rem', // 24px
|
|
90
|
+
'large': '1.75rem', // 28px
|
|
91
|
+
'big': '1.75rem', // 28px
|
|
92
|
+
'huge': '2rem', // 32px
|
|
93
|
+
'grand': '2.25rem', // 36px
|
|
94
|
+
'giant': '2.5rem', // 40px
|
|
95
|
+
'mount': '1', // 48px (unitless 1)
|
|
96
|
+
'mega': '1', // 60px (unitless 1)
|
|
97
|
+
'giga': '1', // 72px (unitless 1)
|
|
98
|
+
'tera': '1', // 96px (unitless 1)
|
|
99
|
+
'hero': '1' // 128px (unitless 1)
|
|
76
100
|
},
|
|
77
101
|
|
|
78
102
|
// 5. FONT WEIGHTS
|
|
@@ -33,7 +33,7 @@ export const position = {
|
|
|
33
33
|
descriptionMs: 'Elemen diletakkan relatif kepada aliran normal',
|
|
34
34
|
html: `<div layout="relative" space="p:medium" visual="bg:neutral-100 dark:bg:neutral-900 rounded:medium">
|
|
35
35
|
<span space="p:small" visual="bg:primary text:white rounded:small">Relative Container</span>
|
|
36
|
-
<span layout="absolute
|
|
36
|
+
<span layout="absolute top:0 right:0" space="p:tiny" visual="bg:danger text:white rounded:small">Abs</span>
|
|
37
37
|
</div>`,
|
|
38
38
|
highlightValue: 'relative'
|
|
39
39
|
},
|
|
@@ -43,7 +43,7 @@ export const position = {
|
|
|
43
43
|
description: 'Element sticks when scrolling past it',
|
|
44
44
|
descriptionMs: 'Elemen melekat apabila skrol melepasi',
|
|
45
45
|
html: `<div space="p:medium" visual="bg:neutral-100 dark:bg:neutral-900 rounded:medium">
|
|
46
|
-
<span layout="sticky
|
|
46
|
+
<span layout="sticky top:0" space="p:small" visual="bg:primary text:white rounded:small">Sticky Header</span>
|
|
47
47
|
</div>`,
|
|
48
48
|
highlightValue: 'sticky'
|
|
49
49
|
}
|
|
@@ -133,10 +133,10 @@ export const zIndex = {
|
|
|
133
133
|
description: 'Control stacking order of positioned elements',
|
|
134
134
|
descriptionMs: 'Kawal susunan tindanan elemen yang diletakkan',
|
|
135
135
|
html: `<div layout="relative" space="p:medium" visual="bg:neutral-100 dark:bg:neutral-900 rounded:medium" style="height: 80px;">
|
|
136
|
-
<span layout="absolute z:base
|
|
137
|
-
<span layout="absolute z:low
|
|
138
|
-
<span layout="absolute z:mid
|
|
139
|
-
<span layout="absolute z:high
|
|
136
|
+
<span layout="absolute z:base left:0 top:10px" space="p:small" visual="bg:neutral-400 text:white rounded:small">z:base</span>
|
|
137
|
+
<span layout="absolute z:low left:30px top:20px" space="p:small" visual="bg:neutral-500 text:white rounded:small">z:low</span>
|
|
138
|
+
<span layout="absolute z:mid left:60px top:30px" space="p:small" visual="bg:neutral-600 text:white rounded:small">z:mid</span>
|
|
139
|
+
<span layout="absolute z:high left:90px top:40px" space="p:small" visual="bg:primary text:white rounded:small">z:high</span>
|
|
140
140
|
</div>`,
|
|
141
141
|
highlightValue: 'z:high'
|
|
142
142
|
}
|