@howssatoshi/quantumcss 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -22
- package/dist/quantum.min.css +1 -1
- package/package.json +1 -1
- package/src/defaults.js +33 -164
- package/src/generator.js +141 -132
- package/src/styles/quantum-components.css +60 -28
- package/src/styles/quantum.css +19 -7
- package/src/styles/starlight-ui.css +252 -60
package/src/defaults.js
CHANGED
|
@@ -2,164 +2,76 @@ const defaultTheme = {
|
|
|
2
2
|
colors: {
|
|
3
3
|
white: '#ffffff',
|
|
4
4
|
black: '#000000',
|
|
5
|
-
|
|
6
|
-
50: '#
|
|
7
|
-
|
|
8
|
-
200: '#e5e7eb',
|
|
9
|
-
300: '#d1d5db',
|
|
10
|
-
400: '#9ca3af',
|
|
11
|
-
500: '#6b7280',
|
|
12
|
-
600: '#4b5563',
|
|
13
|
-
700: '#374151',
|
|
14
|
-
800: '#1f2937',
|
|
15
|
-
900: '#111827',
|
|
5
|
+
slate: {
|
|
6
|
+
50: '#f8fafc', 100: '#f1f5f9', 200: '#e2e8f0', 300: '#cbd5e1', 400: '#94a3b8',
|
|
7
|
+
500: '#64748b', 600: '#475569', 700: '#334155', 800: '#1e293b', 900: '#0f172a', 950: '#020617'
|
|
16
8
|
},
|
|
17
9
|
blue: {
|
|
18
|
-
50: '#eff6ff',
|
|
19
|
-
500: '#3b82f6',
|
|
20
|
-
600: '#2563eb',
|
|
10
|
+
50: '#eff6ff', 100: '#dbeafe', 200: '#bfdbfe', 300: '#93c5fd', 400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb'
|
|
21
11
|
},
|
|
22
|
-
|
|
23
|
-
500: '#
|
|
12
|
+
orange: {
|
|
13
|
+
50: '#fff7ed', 100: '#ffedd5', 200: '#fed7aa', 300: '#fdba74', 400: '#fb923c', 500: '#f97316', 600: '#ea580c'
|
|
24
14
|
},
|
|
15
|
+
red: { 500: '#ef4444' },
|
|
25
16
|
green: {
|
|
26
|
-
|
|
17
|
+
100: '#d1fae5',
|
|
18
|
+
500: '#10b981'
|
|
27
19
|
},
|
|
28
20
|
starlight: {
|
|
29
|
-
blue: '#00d4ff',
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
deep: '#08081a',
|
|
33
|
-
}
|
|
21
|
+
blue: '#00d4ff', peach: '#ffb38a', orange: '#ff7e5f', deep: '#08081a',
|
|
22
|
+
},
|
|
23
|
+
transparent: 'transparent',
|
|
34
24
|
},
|
|
35
25
|
spacing: {
|
|
36
|
-
0: '0px',
|
|
37
|
-
1: '
|
|
38
|
-
|
|
39
|
-
3: '0.75rem',
|
|
40
|
-
4: '1rem',
|
|
41
|
-
5: '1.25rem',
|
|
42
|
-
6: '1.5rem',
|
|
43
|
-
8: '2rem',
|
|
44
|
-
10: '2.5rem',
|
|
45
|
-
12: '3rem',
|
|
46
|
-
16: '4rem',
|
|
47
|
-
20: '5rem',
|
|
48
|
-
24: '6rem',
|
|
49
|
-
32: '8rem',
|
|
50
|
-
64: '16rem',
|
|
51
|
-
128: '32rem',
|
|
52
|
-
144: '36rem',
|
|
26
|
+
0: '0px', px: '1px', 1: '0.25rem', 2: '0.5rem', 3: '0.75rem', 4: '1rem', 5: '1.25rem',
|
|
27
|
+
6: '1.5rem', 8: '2rem', 10: '2.5rem', 12: '3rem', 14: '3.5rem', 16: '4rem', 20: '5rem',
|
|
28
|
+
24: '6rem', 32: '8rem', 40: '10rem', 48: '12rem', 64: '16rem', 128: '32rem',
|
|
53
29
|
},
|
|
54
30
|
fontSize: {
|
|
55
|
-
xs: '0.75rem',
|
|
56
|
-
|
|
57
|
-
base: '1rem',
|
|
58
|
-
lg: '1.125rem',
|
|
59
|
-
xl: '1.25rem',
|
|
60
|
-
'2xl': '1.5rem',
|
|
61
|
-
'3xl': '2rem',
|
|
62
|
-
'4xl': '2.5rem',
|
|
63
|
-
'5xl': '3.5rem',
|
|
64
|
-
'6xl': '4.5rem',
|
|
31
|
+
xs: '0.75rem', sm: '0.875rem', base: '1rem', lg: '1.125rem', xl: '1.25rem',
|
|
32
|
+
'2xl': '1.5rem', '3xl': '2rem', '4xl': '2.5rem', '5xl': '3rem', '6xl': '4rem',
|
|
65
33
|
},
|
|
66
34
|
shadows: {
|
|
67
35
|
sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
|
68
36
|
md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
|
|
69
37
|
lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
|
|
70
38
|
xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
|
|
39
|
+
'2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
|
|
71
40
|
}
|
|
72
41
|
};
|
|
73
42
|
|
|
74
43
|
const utilityMaps = {
|
|
75
|
-
// Layout
|
|
76
44
|
flex: { property: 'display', value: 'flex' },
|
|
77
45
|
grid: { property: 'display', value: 'grid' },
|
|
78
46
|
hidden: { property: 'display', value: 'none' },
|
|
79
47
|
block: { property: 'display', value: 'block' },
|
|
80
48
|
'inline-block': { property: 'display', value: 'inline-block' },
|
|
81
|
-
|
|
82
|
-
// Alignment
|
|
83
49
|
'items-center': { property: 'align-items', value: 'center' },
|
|
84
50
|
'items-start': { property: 'align-items', value: 'flex-start' },
|
|
85
51
|
'items-end': { property: 'align-items', value: 'flex-end' },
|
|
86
52
|
'justify-center': { property: 'justify-content', value: 'center' },
|
|
87
53
|
'justify-between': { property: 'justify-content', value: 'space-between' },
|
|
88
|
-
'justify-start': { property: 'justify-content', value: 'flex-start' },
|
|
89
|
-
'justify-end': { property: 'justify-content', value: 'flex-end' },
|
|
90
|
-
|
|
91
|
-
// Flex/Grid specific
|
|
92
54
|
'flex-col': { property: 'flex-direction', value: 'column' },
|
|
93
|
-
'flex-
|
|
94
|
-
'flex-
|
|
95
|
-
|
|
96
|
-
// Sizing
|
|
97
|
-
w: 'width',
|
|
98
|
-
h: 'height',
|
|
55
|
+
'flex-row': { property: 'flex-direction', value: 'row' },
|
|
56
|
+
'flex-1': { property: 'flex', value: '1 1 0%' },
|
|
57
|
+
'flex-shrink-0': { property: 'flex-shrink', value: '0' },
|
|
99
58
|
'w-full': { property: 'width', value: '100%' },
|
|
100
59
|
'h-full': { property: 'height', value: '100%' },
|
|
101
|
-
'
|
|
102
|
-
'min-h-screen': { property: 'min-height', value: '100vh' },
|
|
103
|
-
|
|
104
|
-
// Spacing
|
|
105
|
-
m: 'margin',
|
|
106
|
-
mt: 'margin-top',
|
|
107
|
-
mr: 'margin-right',
|
|
108
|
-
mb: 'margin-bottom',
|
|
109
|
-
ml: 'margin-left',
|
|
110
|
-
mx: ['margin-left', 'margin-right'],
|
|
111
|
-
my: ['margin-top', 'margin-bottom'],
|
|
112
|
-
p: 'padding',
|
|
113
|
-
pt: 'padding-top',
|
|
114
|
-
pr: 'padding-right',
|
|
115
|
-
pb: 'padding-bottom',
|
|
116
|
-
pl: 'padding-left',
|
|
117
|
-
px: ['padding-left', 'padding-right'],
|
|
118
|
-
py: ['padding-top', 'padding-bottom'],
|
|
119
|
-
gap: 'gap',
|
|
120
|
-
|
|
121
|
-
// Typography
|
|
122
|
-
text: 'font-size',
|
|
123
|
-
'font-bold': { property: 'font-weight', value: '700' },
|
|
124
|
-
'font-medium': { property: 'font-weight', value: '500' },
|
|
125
|
-
'font-light': { property: 'font-weight', value: '300' },
|
|
126
|
-
'tracking-tighter': { property: 'letter-spacing', value: '-0.05em' },
|
|
127
|
-
'tracking-tight': { property: 'letter-spacing', value: '-0.025em' },
|
|
128
|
-
'text-center': { property: 'text-align', value: 'center' },
|
|
129
|
-
'text-left': { property: 'text-align', value: 'left' },
|
|
130
|
-
'text-right': { property: 'text-align', value: 'right' },
|
|
131
|
-
|
|
132
|
-
// Visuals
|
|
133
|
-
bg: 'background-color',
|
|
134
|
-
rounded: 'border-radius',
|
|
135
|
-
'rounded-full': { property: 'border-radius', value: '9999px' },
|
|
136
|
-
'rounded-xl': { property: 'border-radius', value: '0.75rem' },
|
|
137
|
-
border: { property: 'border-width', value: '1px' },
|
|
138
|
-
'border-t': { property: 'border-top-width', value: '1px' },
|
|
139
|
-
'border-b': { property: 'border-bottom-width', value: '1px' },
|
|
140
|
-
shadow: 'box-shadow',
|
|
141
|
-
|
|
142
|
-
// Interactivity & States
|
|
143
|
-
transition: { property: 'transition', value: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)' },
|
|
144
|
-
'scale-105': { property: 'transform', value: 'scale(1.05)' },
|
|
145
|
-
'active-scale': { property: 'transform', value: 'scale(0.96)' },
|
|
146
|
-
'cursor-pointer': { property: 'cursor', value: 'pointer' },
|
|
60
|
+
'min-w-0': { property: 'min-width', value: '0' },
|
|
147
61
|
'overflow-hidden': { property: 'overflow', value: 'hidden' },
|
|
148
|
-
|
|
149
|
-
|
|
62
|
+
'overflow-visible': { property: 'overflow', value: 'visible' },
|
|
63
|
+
'border-none': { property: 'border-width', value: '0' },
|
|
64
|
+
'bg-transparent': { property: 'background-color', value: 'transparent' },
|
|
150
65
|
'glass': {
|
|
151
|
-
property: ['background-color', 'backdrop-filter', '-webkit-backdrop-filter', 'border', '
|
|
152
|
-
value: ['rgba(255, 255, 255, 0.03)', 'blur(16px)', 'blur(16px)', '1px
|
|
66
|
+
property: ['background-color', 'backdrop-filter', '-webkit-backdrop-filter', 'border-width', 'border-color'],
|
|
67
|
+
value: ['rgba(255, 255, 255, 0.03)', 'blur(16px)', 'blur(16px)', '1px', 'rgba(255, 255, 255, 0.1)']
|
|
153
68
|
},
|
|
154
69
|
'glow-blue': { property: 'box-shadow', value: '0 0 30px rgba(0, 212, 255, 0.25)' },
|
|
155
|
-
'glow-peach': { property: 'box-shadow', value: '0 0 30px rgba(255, 179, 138, 0.2)' },
|
|
156
70
|
'bg-starlight': { property: 'background', value: 'linear-gradient(135deg, #ffb38a 0%, #00d4ff 100%)' },
|
|
157
71
|
'text-gradient-starlight': {
|
|
158
72
|
property: ['background', '-webkit-background-clip', '-webkit-text-fill-color', 'display'],
|
|
159
73
|
value: ['linear-gradient(to right, #ffb38a, #00d4ff)', 'text', 'transparent', 'inline-block']
|
|
160
74
|
},
|
|
161
|
-
|
|
162
|
-
// Components
|
|
163
75
|
'btn-starlight': {
|
|
164
76
|
property: ['background', 'color', 'border', 'box-shadow', 'font-weight', 'transition', 'height', 'padding', 'display', 'align-items', 'justify-content', 'border-radius', 'cursor'],
|
|
165
77
|
value: ['linear-gradient(135deg, #ffb38a 0%, #00d4ff 100%)', '#000', 'none', '0 0 20px rgba(0, 212, 255, 0.3)', '700', 'all 0.2s ease', '3rem', '0 1.5rem', 'inline-flex', 'center', 'center', '0.75rem', 'pointer']
|
|
@@ -169,59 +81,16 @@ const utilityMaps = {
|
|
|
169
81
|
value: ['rgba(255, 255, 255, 0.05)', 'inherit', '1px solid rgba(255, 255, 255, 0.15)', '700', 'all 0.2s ease', '3rem', '0 1.5rem', 'inline-flex', 'center', 'center', '0.75rem', 'pointer']
|
|
170
82
|
},
|
|
171
83
|
'input-starlight': {
|
|
172
|
-
property: ['background-color', 'border', 'color', 'border-radius', 'padding', 'appearance', '
|
|
173
|
-
value: [
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
'0 2.5rem 0 1rem',
|
|
179
|
-
'none',
|
|
180
|
-
'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' fill=\'none\' viewBox=\'0 0 24 24\' stroke=\'rgba(255,255,255,0.4)\'%3E%3Cpath stroke-linecap=\'round\' stroke-linejoin=\'round\' stroke-width=\'2\' d=\'M8 9l4 4 4-4\' /%3E%3C/svg%3E")',
|
|
181
|
-
'no-repeat',
|
|
182
|
-
'right 1rem center',
|
|
183
|
-
'1rem',
|
|
184
|
-
'all 0.2s ease',
|
|
185
|
-
'3rem'
|
|
186
|
-
]
|
|
84
|
+
property: ['background-color', 'border', 'color', 'border-radius', 'padding', 'appearance', 'transition', 'height'],
|
|
85
|
+
value: ['rgba(255, 255, 255, 0.04)', '1px solid rgba(255, 255, 255, 0.15)', 'inherit', '0.75rem', '0 1rem', 'none', 'all 0.2s ease', '3rem']
|
|
86
|
+
},
|
|
87
|
+
'textarea-starlight': {
|
|
88
|
+
property: ['background-color', 'border', 'color', 'border-radius', 'padding', 'appearance', 'transition', 'min-height', 'width', 'display'],
|
|
89
|
+
value: ['rgba(255, 255, 255, 0.04)', '1px solid rgba(255, 255, 255, 0.15)', 'inherit', '0.75rem', '1rem', 'none', 'all 0.2s ease', '8rem', '100%', 'block']
|
|
187
90
|
},
|
|
188
91
|
'checkbox-starlight': {
|
|
189
92
|
property: ['appearance', 'width', 'height', 'background', 'border', 'border-radius', 'cursor', 'transition', 'position', 'display', 'align-items', 'justify-content'],
|
|
190
93
|
value: ['none', '1.25rem', '1.25rem', 'rgba(255, 255, 255, 0.05)', '1px solid rgba(255, 255, 255, 0.2)', '0.375rem', 'pointer', 'all 0.2s ease', 'relative', 'inline-flex', 'center', 'center']
|
|
191
|
-
},
|
|
192
|
-
'radio-starlight': {
|
|
193
|
-
property: ['appearance', 'width', 'height', 'background', 'border', 'border-radius', 'cursor', 'transition', 'position', 'display', 'align-items', 'justify-content'],
|
|
194
|
-
value: ['none', '1.25rem', '1.25rem', 'rgba(255, 255, 255, 0.05)', '1px solid rgba(255, 255, 255, 0.2)', '50%', 'pointer', 'all 0.2s ease', 'relative', 'inline-flex', 'center', 'center']
|
|
195
|
-
},
|
|
196
|
-
|
|
197
|
-
// Dialog & Menu
|
|
198
|
-
'dialog-overlay': {
|
|
199
|
-
property: ['position', 'top', 'left', 'width', 'height', 'background', 'backdrop-filter', 'display', 'align-items', 'justify-content', 'z-index'],
|
|
200
|
-
value: ['fixed', '0', '0', '100vw', '100vh', 'rgba(0, 0, 0, 0.6)', 'blur(12px)', 'flex', 'center', 'center', '400']
|
|
201
|
-
},
|
|
202
|
-
'dialog-content': {
|
|
203
|
-
property: ['background-color', 'backdrop-filter', 'border', 'border-radius', 'width', 'max-width', 'box-shadow', 'overflow', 'position'],
|
|
204
|
-
value: ['rgba(10, 10, 20, 0.98)', 'blur(20px)', '1px solid rgba(255, 255, 255, 0.1)', '1.5rem', '90%', '600px', '0 25px 50px -12px rgba(0, 0, 0, 0.5)', 'hidden', 'relative']
|
|
205
|
-
},
|
|
206
|
-
'dropdown-menu': {
|
|
207
|
-
property: ['background-color', 'backdrop-filter', 'border', 'border-radius', 'padding', 'box-shadow', 'min-width', 'z-index', 'margin-top'],
|
|
208
|
-
value: ['rgba(15, 15, 30, 0.98)', 'blur(20px)', '1px solid rgba(255, 255, 255, 0.1)', '1rem', '0.5rem', '0 20px 40px rgba(0,0,0,0.4)', '200px', '600', '0.5rem']
|
|
209
|
-
},
|
|
210
|
-
'dropdown-item': {
|
|
211
|
-
property: ['padding', 'color', 'border-radius', 'display', 'width', 'text-align', 'transition', 'cursor', 'font-size'],
|
|
212
|
-
value: ['0.625rem 1rem', 'rgba(255,255,255,0.7)', '0.625rem', 'block', '100%', 'left', 'all 0.2s', 'pointer', '0.875rem']
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
// Tooltip
|
|
216
|
-
'tooltip': {
|
|
217
|
-
property: ['position', 'bottom', 'left', 'transform', 'padding', 'background-color', 'backdrop-filter', 'border', 'border-radius', 'color', 'font-size', 'white-space', 'pointer-events', 'opacity', 'transition', 'z-index', 'box-shadow'],
|
|
218
|
-
value: ['absolute', '125%', '50%', 'translateX(-50%)', '0.5rem 0.75rem', 'rgba(10, 10, 30, 0.98)', 'blur(12px)', '1px solid rgba(0, 212, 255, 0.3)', '0.5rem', '#f1f5f9', '0.75rem', 'nowrap', 'none', '0', 'all 0.2s ease', '800', '0 4px 15px rgba(0, 0, 0, 0.4)']
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
// Skeleton
|
|
222
|
-
'skeleton': {
|
|
223
|
-
property: ['background-color', 'background-image', 'background-size', 'background-repeat', 'border-radius', 'width', 'height'],
|
|
224
|
-
value: ['rgba(255, 255, 255, 0.1)', 'linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent)', '200% 100%', 'no-repeat', '0.5rem', '100%', '1rem']
|
|
225
94
|
}
|
|
226
95
|
};
|
|
227
96
|
|
package/src/generator.js
CHANGED
|
@@ -3,181 +3,190 @@ const path = require('path');
|
|
|
3
3
|
const { glob } = require('glob');
|
|
4
4
|
const { defaultTheme, utilityMaps } = require('./defaults');
|
|
5
5
|
|
|
6
|
-
const breakpoints = {
|
|
7
|
-
sm: '640px',
|
|
8
|
-
md: '768px',
|
|
9
|
-
lg: '1024px',
|
|
10
|
-
xl: '1280px',
|
|
11
|
-
};
|
|
6
|
+
const breakpoints = { sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px' };
|
|
12
7
|
|
|
13
8
|
function generateCSS(configPath) {
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
const resolvedPath = path.resolve(configPath);
|
|
10
|
+
if (fs.existsSync(resolvedPath)) delete require.cache[resolvedPath];
|
|
11
|
+
const config = fs.existsSync(resolvedPath) ? require(resolvedPath) : { content: [], theme: {} };
|
|
16
12
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
13
|
+
const theme = JSON.parse(JSON.stringify(defaultTheme || {}));
|
|
14
|
+
theme.colors = theme.colors || {};
|
|
15
|
+
theme.spacing = theme.spacing || {};
|
|
16
|
+
theme.borderRadius = theme.borderRadius || {};
|
|
17
|
+
theme.fontSize = theme.fontSize || {};
|
|
18
|
+
|
|
19
|
+
if (config.theme && config.theme.extend) {
|
|
20
|
+
const ext = config.theme.extend;
|
|
21
|
+
if (ext.colors) Object.assign(theme.colors, ext.colors);
|
|
22
|
+
if (ext.spacing) Object.assign(theme.spacing, ext.spacing);
|
|
23
|
+
if (ext.borderRadius) Object.assign(theme.borderRadius, ext.borderRadius);
|
|
24
|
+
if (ext.fontSize) Object.assign(theme.fontSize, ext.fontSize);
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const flattenedColors = {};
|
|
31
28
|
Object.entries(theme.colors).forEach(([name, value]) => {
|
|
32
|
-
if (typeof value === 'string')
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
flattenedColors[`${name}-${shade}`] = hex;
|
|
37
|
-
});
|
|
29
|
+
if (typeof value === 'string') flattenedColors[name] = value;
|
|
30
|
+
else {
|
|
31
|
+
Object.entries(value || {}).forEach(([shade, hex]) => { flattenedColors[`${name}-${shade}`] = hex; });
|
|
32
|
+
if (value && value['500']) flattenedColors[name] = value['500'];
|
|
38
33
|
}
|
|
39
34
|
});
|
|
40
35
|
|
|
41
|
-
|
|
36
|
+
function resolveColor(key) {
|
|
37
|
+
if (!key) return null;
|
|
38
|
+
if (flattenedColors[key]) return flattenedColors[key];
|
|
39
|
+
if (key.includes('/')) {
|
|
40
|
+
const [base, opacity] = key.split('/');
|
|
41
|
+
const color = flattenedColors[base] || flattenedColors[`${base}-500`];
|
|
42
|
+
if (color && color.startsWith('#')) {
|
|
43
|
+
const r = parseInt(color.slice(1, 3), 16), g = parseInt(color.slice(3, 5), 16), b = parseInt(color.slice(5, 7), 16);
|
|
44
|
+
return `rgba(${r}, ${g}, ${b}, ${parseInt(opacity) / 100})`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const files = (config.content || []).flatMap(p => glob.sync(p));
|
|
42
51
|
const rawClasses = new Set();
|
|
52
|
+
const classAttrRegex = /class="([^"]+)"/g;
|
|
43
53
|
|
|
44
54
|
files.forEach(file => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
try {
|
|
56
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
57
|
+
let match;
|
|
58
|
+
while ((match = classAttrRegex.exec(content)) !== null) {
|
|
59
|
+
match[1].split(/\s+/).forEach(cls => { if (cls) rawClasses.add(cls); });
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {}
|
|
50
62
|
});
|
|
51
63
|
|
|
52
|
-
let css = '/* Quantum CSS - High Performance Output */\n';
|
|
53
|
-
css += '*, ::before, ::after { box-sizing: border-box; border-width: 0; border-style: solid; border-color: #e5e7eb; }\n';
|
|
54
|
-
css += 'html { line-height: 1.5; -webkit-text-size-adjust: 100%; font-family: Inter, ui-sans-serif, system-ui, sans-serif; }\n';
|
|
55
|
-
css += 'body { margin: 0; line-height: inherit; }\n';
|
|
56
|
-
css += 'img { display: block; max-width: 100%; height: auto; }\n';
|
|
57
|
-
css += 'button { cursor: pointer; background: transparent; padding: 0; color: inherit; font: inherit; }\n\n';
|
|
58
|
-
|
|
59
64
|
const utilities = new Set();
|
|
60
|
-
const responsiveUtils = { sm: new Set(), md: new Set(), lg: new Set(), xl: new Set() };
|
|
65
|
+
const responsiveUtils = { sm: new Set(), md: new Set(), lg: new Set(), xl: new Set(), '2xl': new Set() };
|
|
66
|
+
|
|
67
|
+
const sideMap = {
|
|
68
|
+
p: 'padding', pt: 'padding-top', pr: 'padding-right', pb: 'padding-bottom', pl: 'padding-left',
|
|
69
|
+
px: ['padding-left', 'padding-right'], py: ['padding-top', 'padding-bottom'],
|
|
70
|
+
m: 'margin', mt: 'margin-top', mr: 'margin-right', mb: 'margin-bottom', ml: 'margin-left',
|
|
71
|
+
mx: ['margin-left', 'margin-right'], my: ['margin-top', 'margin-bottom'],
|
|
72
|
+
w: 'width', h: 'height', top: 'top', right: 'right', bottom: 'bottom', left: 'left',
|
|
73
|
+
'max-w': 'max-width', 'max-h': 'max-height', 'min-w': 'min-width', 'min-h': 'min-height',
|
|
74
|
+
gap: 'gap', 'gap-x': 'column-gap', 'gap-y': 'row-gap'
|
|
75
|
+
};
|
|
61
76
|
|
|
62
77
|
function processClass(fullCls) {
|
|
63
|
-
let cls = fullCls;
|
|
64
|
-
|
|
65
|
-
let breakpoint = null;
|
|
66
|
-
|
|
78
|
+
let cls = fullCls, variant = null, breakpoint = null, isNeg = false;
|
|
79
|
+
if (cls.startsWith('-')) { isNeg = true; cls = cls.substring(1); }
|
|
67
80
|
const parts = cls.split(':');
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
variant = subParts[0];
|
|
76
|
-
cls = subParts[1];
|
|
77
|
-
} else if (!breakpoint) {
|
|
78
|
-
variant = parts[0];
|
|
79
|
-
cls = parts[1];
|
|
80
|
-
}
|
|
81
|
+
let currentPart = 0;
|
|
82
|
+
while (currentPart < parts.length) {
|
|
83
|
+
const p = parts[currentPart];
|
|
84
|
+
if (breakpoints[p]) { breakpoint = p; }
|
|
85
|
+
else if (['hover', 'focus', 'placeholder', 'group-hover'].includes(p)) { variant = p; }
|
|
86
|
+
else { cls = parts.slice(currentPart).join(':'); break; }
|
|
87
|
+
currentPart++;
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
let property = null;
|
|
84
|
-
let value = null;
|
|
85
|
-
|
|
90
|
+
let property = null, value = null, customSelector = null;
|
|
86
91
|
if (utilityMaps[cls]) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} else {
|
|
91
|
-
property = utilityMaps[cls];
|
|
92
|
-
}
|
|
92
|
+
const entry = utilityMaps[cls];
|
|
93
|
+
if (typeof entry === 'object' && !Array.isArray(entry)) { property = entry.property; value = entry.value; }
|
|
94
|
+
else { property = entry; }
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
if (!property || !value) {
|
|
96
98
|
const cParts = cls.split('-');
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
let prefix = cParts[0], valKey = cParts.slice(1).join('-');
|
|
100
|
+
|
|
101
|
+
if ((prefix === 'max' || prefix === 'min' || prefix === 'gap' || prefix === 'gap-x' || prefix === 'gap-y') && cParts[1]) {
|
|
102
|
+
if (['w', 'h', 'x', 'y'].includes(cParts[1])) {
|
|
103
|
+
prefix = `${cParts[0]}-${cParts[1]}`;
|
|
104
|
+
valKey = cParts.slice(2).join('-');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
99
107
|
|
|
100
108
|
if (prefix === 'text') {
|
|
101
|
-
if (theme.fontSize[valKey]) { property = 'font-size'; value = theme.fontSize[valKey]; }
|
|
102
|
-
else
|
|
103
|
-
} else if (prefix === 'bg') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
property = '
|
|
109
|
+
if (theme.fontSize[valKey]) { property = ['font-size', 'line-height']; value = [theme.fontSize[valKey], (valKey.includes('xl') || parseInt(valKey) >= 3) ? '1.2' : '1.5']; }
|
|
110
|
+
else { const color = resolveColor(valKey); if (color) { property = 'color'; value = color; } }
|
|
111
|
+
} else if (prefix === 'bg') { const color = resolveColor(valKey); if (color) { property = 'background-color'; value = color; } }
|
|
112
|
+
else if (prefix === 'z') { property = 'z-index'; value = isNeg ? `-${valKey}` : valKey; }
|
|
113
|
+
else if (prefix === 'aspect') {
|
|
114
|
+
property = ['aspect-ratio', 'width', 'height'];
|
|
115
|
+
let ratio = 'auto';
|
|
116
|
+
if (valKey.startsWith('[') && valKey.endsWith(']')) ratio = valKey.slice(1, -1).replace(/\//g, ' / ');
|
|
117
|
+
else if (valKey === 'video') ratio = '16 / 9';
|
|
118
|
+
else if (valKey === 'square') ratio = '1 / 1';
|
|
119
|
+
else ratio = valKey.replace(/\//g, ' / ');
|
|
120
|
+
value = [ratio, '100%', 'auto'];
|
|
121
|
+
} else if (prefix === 'grid' && cParts[1] === 'cols') {
|
|
122
|
+
property = 'grid-template-columns'; value = `repeat(${cParts[2]}, minmax(0, 1fr))`;
|
|
123
|
+
} else if (prefix === 'col' && cParts[1] === 'span') {
|
|
124
|
+
property = 'grid-column'; value = `span ${cParts[2]} / span ${cParts[2]}`;
|
|
125
|
+
} else if (prefix === 'space') {
|
|
126
|
+
const amount = theme.spacing[cParts[2]] || `${parseInt(cParts[2]) * 0.25}rem`;
|
|
127
|
+
const escaped = fullCls.replace(/([:[\/])/g, '\\$1');
|
|
128
|
+
customSelector = `.${escaped} > * + *`;
|
|
129
|
+
property = cParts[1] === 'y' ? 'margin-top' : 'margin-left';
|
|
130
|
+
value = isNeg ? `-${amount}` : amount;
|
|
107
131
|
} else if (prefix === 'rounded') {
|
|
108
132
|
property = 'border-radius';
|
|
109
|
-
if (valKey
|
|
110
|
-
else if (valKey
|
|
111
|
-
else
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
property = 'border-color'; value = flattenedColors[valKey];
|
|
115
|
-
} else if (cParts[1] === 'l' || cParts[1] === 'r' || cParts[1] === 't' || cParts[1] === 'b') {
|
|
116
|
-
const sideMap = { l: 'left', r: 'right', t: 'top', b: 'bottom' };
|
|
117
|
-
property = `border-${sideMap[cParts[1]]}-width`;
|
|
118
|
-
value = `${cParts[2]}px`;
|
|
119
|
-
}
|
|
120
|
-
} else if (prefix === 'gap') {
|
|
121
|
-
property = 'gap'; value = theme.spacing[valKey] || (valKey ? (isNaN(valKey) ? valKey : `${valKey}rem`) : '0px');
|
|
122
|
-
} else if (prefix === 'grid' && cParts[1] === 'cols') {
|
|
123
|
-
property = 'grid-template-columns';
|
|
124
|
-
value = `repeat(${cParts[2]}, minmax(0, 1fr))`;
|
|
125
|
-
} else if (prefix === 'flex' && cParts[1] === 'row') {
|
|
126
|
-
property = 'flex-direction';
|
|
127
|
-
value = 'row';
|
|
128
|
-
} else if (prefix === 'w' || prefix === 'h') {
|
|
129
|
-
property = utilityMaps[prefix];
|
|
130
|
-
if (valKey.includes('/')) {
|
|
131
|
-
const [n, d] = valKey.split('/');
|
|
132
|
-
value = `${(parseInt(n)/parseInt(d)*100).toFixed(2)}%`;
|
|
133
|
-
} else {
|
|
134
|
-
value = theme.spacing[valKey] || valKey;
|
|
135
|
-
}
|
|
136
|
-
} else if (utilityMaps[prefix]) {
|
|
137
|
-
const mapEntry = utilityMaps[prefix];
|
|
138
|
-
if (typeof mapEntry === 'object' && !Array.isArray(mapEntry)) {
|
|
139
|
-
property = mapEntry.property;
|
|
140
|
-
value = mapEntry.value;
|
|
141
|
-
} else {
|
|
142
|
-
property = mapEntry;
|
|
143
|
-
value = theme.spacing[valKey] || valKey;
|
|
133
|
+
if (valKey.startsWith('[') && valKey.endsWith(']')) value = valKey.slice(1, -1);
|
|
134
|
+
else if (theme.borderRadius[valKey]) value = theme.borderRadius[valKey];
|
|
135
|
+
else {
|
|
136
|
+
const num = parseInt(valKey);
|
|
137
|
+
value = isNaN(num) ? '0.375rem' : `${num * 0.125}rem`;
|
|
144
138
|
}
|
|
139
|
+
} else if (prefix === 'scale') {
|
|
140
|
+
property = 'transform';
|
|
141
|
+
value = `scale(${parseInt(valKey) / 100})`;
|
|
142
|
+
} else if (prefix === 'transition') {
|
|
143
|
+
property = 'transition-property';
|
|
144
|
+
if (valKey === 'all') value = 'all';
|
|
145
|
+
else if (valKey === 'colors') value = 'color, background-color, border-color, text-decoration-color, fill, stroke';
|
|
146
|
+
else if (valKey === 'transform') value = 'transform';
|
|
147
|
+
else value = valKey;
|
|
148
|
+
} else if (prefix === 'duration') {
|
|
149
|
+
property = 'transition-duration';
|
|
150
|
+
value = `${valKey}ms`;
|
|
151
|
+
} else if (sideMap[prefix]) {
|
|
152
|
+
property = sideMap[prefix];
|
|
153
|
+
let v = valKey;
|
|
154
|
+
if (v.startsWith('[') && v.endsWith(']')) v = v.slice(1, -1);
|
|
155
|
+
else if (v.includes('/')) v = `${(parseInt(v.split('/')[0])/parseInt(v.split('/')[1])*100).toFixed(2)}%`;
|
|
156
|
+
else v = theme.spacing[v] || v;
|
|
157
|
+
value = isNeg ? (Array.isArray(v) ? v.map(x => `-${x}`) : `-${v}`) : v;
|
|
158
|
+
} else if (prefix === 'border') {
|
|
159
|
+
const color = resolveColor(valKey);
|
|
160
|
+
if (color) { property = 'border-color'; value = color; }
|
|
161
|
+
else if (['l', 'r', 't', 'b'].includes(cParts[1])) {
|
|
162
|
+
const sideMapSide = { l: 'left', r: 'right', t: 'top', b: 'bottom' };
|
|
163
|
+
property = `border-${sideMapSide[cParts[1]]}-width`;
|
|
164
|
+
value = `${cParts[2]}px`;
|
|
165
|
+
} else if (!isNaN(parseInt(valKey))) { property = 'border-width'; value = `${parseInt(valKey)}px`; }
|
|
145
166
|
}
|
|
146
167
|
}
|
|
147
168
|
|
|
148
169
|
if (property && value) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
let rules = ''
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
rules = ` ${property}: ${value};`;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const cssBlock = `${selector} {\n${rules}\n}\n`;
|
|
164
|
-
if (breakpoint) { responsiveUtils[breakpoint].add(cssBlock); }
|
|
165
|
-
else { utilities.add(cssBlock); }
|
|
170
|
+
const escapedFull = fullCls.replace(/([:[\/])/g, '\\$1');
|
|
171
|
+
let selector = customSelector || `.${escapedFull}`;
|
|
172
|
+
if (variant) { if (variant === 'group-hover') selector = `.group:hover ${selector}`; else selector += `:${variant}`}
|
|
173
|
+
let rules = Array.isArray(property) ? property.map((p, i) => ` ${p}: ${Array.isArray(value) ? value[i] : value};`).join('\n') : ` ${property}: ${value};`;
|
|
174
|
+
const block = `${selector} {
|
|
175
|
+
${rules}
|
|
176
|
+
}
|
|
177
|
+
`;
|
|
178
|
+
if (breakpoint) responsiveUtils[breakpoint].add(block); else utilities.add(block);
|
|
166
179
|
}
|
|
167
180
|
}
|
|
168
181
|
|
|
169
182
|
rawClasses.forEach(processClass);
|
|
170
|
-
|
|
171
|
-
css += Array.from(utilities).join('\n');
|
|
183
|
+
let css = '/* Quantum CSS JIT Output */\n' + Array.from(utilities).join('\n');
|
|
172
184
|
Object.entries(breakpoints).forEach(([name, width]) => {
|
|
173
185
|
if (responsiveUtils[name].size > 0) {
|
|
174
|
-
css += `\n@media (min-width: ${width}) {\n`;
|
|
175
|
-
css += Array.from(responsiveUtils[name]).map(u => ' ' + u.replace(/\n/g, '\n ')).join('\n').trimEnd();
|
|
176
|
-
css += '\n}\n';
|
|
186
|
+
css += `\n@media (min-width: ${width}) {\n${Array.from(responsiveUtils[name]).map(u => ' ' + u.replace(/\n/g, '\n ')).join('\n').trimEnd()}\n}\n`;
|
|
177
187
|
}
|
|
178
188
|
});
|
|
179
|
-
|
|
180
189
|
return css;
|
|
181
190
|
}
|
|
182
191
|
|
|
183
|
-
module.exports = { generateCSS };
|
|
192
|
+
module.exports = { generateCSS };
|