jasmincss 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +524 -0
  2. package/bin/jasmin.js +45 -0
  3. package/dist/index.d.ts +62 -0
  4. package/dist/index.js +14568 -0
  5. package/dist/index.mjs +14524 -0
  6. package/dist/jasmin.css +63308 -0
  7. package/dist/jasmin.min.css +1 -0
  8. package/dist/plugins/nextjs.js +14777 -0
  9. package/dist/plugins/nextjs.mjs +14747 -0
  10. package/dist/plugins/vite.js +14889 -0
  11. package/dist/plugins/vite.mjs +14860 -0
  12. package/package.json +101 -0
  13. package/src/cli/add.js +83 -0
  14. package/src/cli/init.js +210 -0
  15. package/src/cli/run.js +142 -0
  16. package/src/components/accordion.js +309 -0
  17. package/src/components/alerts.js +357 -0
  18. package/src/components/avatars.js +331 -0
  19. package/src/components/badges.js +353 -0
  20. package/src/components/buttons.js +412 -0
  21. package/src/components/cards.js +342 -0
  22. package/src/components/carousel.js +495 -0
  23. package/src/components/chips.js +440 -0
  24. package/src/components/command-palette.js +434 -0
  25. package/src/components/datepicker.js +517 -0
  26. package/src/components/dropdown.js +411 -0
  27. package/src/components/forms.js +516 -0
  28. package/src/components/index.js +81 -0
  29. package/src/components/modals.js +349 -0
  30. package/src/components/navigation.js +463 -0
  31. package/src/components/offcanvas.js +390 -0
  32. package/src/components/popover.js +427 -0
  33. package/src/components/progress.js +396 -0
  34. package/src/components/rating.js +394 -0
  35. package/src/components/skeleton.js +408 -0
  36. package/src/components/spinner.js +453 -0
  37. package/src/components/stepper.js +389 -0
  38. package/src/components/tables.js +304 -0
  39. package/src/components/timeline.js +452 -0
  40. package/src/components/timepicker.js +529 -0
  41. package/src/components/tooltips.js +345 -0
  42. package/src/components/upload.js +490 -0
  43. package/src/config/defaults.js +263 -0
  44. package/src/config/loader.js +109 -0
  45. package/src/core/base.js +241 -0
  46. package/src/core/compiler.js +135 -0
  47. package/src/core/utilities/accessibility.js +290 -0
  48. package/src/core/utilities/animations.js +205 -0
  49. package/src/core/utilities/background.js +109 -0
  50. package/src/core/utilities/colors.js +234 -0
  51. package/src/core/utilities/columns.js +161 -0
  52. package/src/core/utilities/effects.js +261 -0
  53. package/src/core/utilities/filters.js +135 -0
  54. package/src/core/utilities/icons.js +806 -0
  55. package/src/core/utilities/index.js +239 -0
  56. package/src/core/utilities/layout.js +321 -0
  57. package/src/core/utilities/scroll.js +205 -0
  58. package/src/core/utilities/spacing.js +120 -0
  59. package/src/core/utilities/svg.js +191 -0
  60. package/src/core/utilities/transforms.js +116 -0
  61. package/src/core/utilities/typography.js +188 -0
  62. package/src/index.js +7 -0
  63. package/src/js/components/accordion.js +154 -0
  64. package/src/js/components/alert.js +198 -0
  65. package/src/js/components/carousel.js +226 -0
  66. package/src/js/components/dropdown.js +166 -0
  67. package/src/js/components/modal.js +169 -0
  68. package/src/js/components/offcanvas.js +175 -0
  69. package/src/js/components/popover.js +221 -0
  70. package/src/js/components/tabs.js +163 -0
  71. package/src/js/components/tooltip.js +200 -0
  72. package/src/js/index.js +79 -0
  73. package/src/js/types/config.d.ts +228 -0
  74. package/src/js/types/index.d.ts +439 -0
  75. package/src/plugins/nextjs.js +100 -0
  76. package/src/plugins/vite.js +133 -0
@@ -0,0 +1,239 @@
1
+ import { shouldIncludeClass } from '../compiler.js';
2
+ import { generateLayoutUtilities } from './layout.js';
3
+ import { generateSpacingUtilities } from './spacing.js';
4
+ import { generateTypographyUtilities } from './typography.js';
5
+ import { generateColorUtilities } from './colors.js';
6
+ import { generateEffectUtilities } from './effects.js';
7
+ import { generateAnimationUtilities } from './animations.js';
8
+ import { generateTransformUtilities } from './transforms.js';
9
+ import { generateFilterUtilities } from './filters.js';
10
+ import { generateIconUtilities } from './icons.js';
11
+ import { generateBackgroundUtilities } from './background.js';
12
+ import { generateColumnUtilities } from './columns.js';
13
+ import { generateScrollUtilities } from './scroll.js';
14
+ import { generateSvgUtilities } from './svg.js';
15
+ import { generateAccessibilityUtilities } from './accessibility.js';
16
+
17
+ const utilityGenerators = {
18
+ layout: generateLayoutUtilities,
19
+ spacing: generateSpacingUtilities,
20
+ typography: generateTypographyUtilities,
21
+ colors: generateColorUtilities,
22
+ effects: generateEffectUtilities,
23
+ animations: generateAnimationUtilities,
24
+ transforms: generateTransformUtilities,
25
+ filters: generateFilterUtilities,
26
+ icons: generateIconUtilities,
27
+ background: generateBackgroundUtilities,
28
+ columns: generateColumnUtilities,
29
+ scroll: generateScrollUtilities,
30
+ svg: generateSvgUtilities,
31
+ accessibility: generateAccessibilityUtilities
32
+ };
33
+
34
+ export function generateUtilities(config, options = {}) {
35
+ const { usedClasses, includeAll = false } = options;
36
+ const selectedUtilities = config.utilities || Object.keys(utilityGenerators);
37
+
38
+ const parts = [];
39
+ let totalCount = 0;
40
+
41
+ parts.push('/* ==================== UTILITIES ==================== */');
42
+
43
+ for (const utilityName of selectedUtilities) {
44
+ const generator = utilityGenerators[utilityName];
45
+ if (!generator) continue;
46
+
47
+ const { css, classes } = generator(config);
48
+
49
+ // Filter classes based on usage
50
+ if (!includeAll && usedClasses) {
51
+ const filteredClasses = classes.filter(c =>
52
+ shouldIncludeClass(c.name, usedClasses, includeAll)
53
+ );
54
+
55
+ if (filteredClasses.length > 0) {
56
+ parts.push(`\n/* ${utilityName} utilities */`);
57
+ parts.push(filteredClasses.map(c => c.css).join('\n'));
58
+ totalCount += filteredClasses.length;
59
+ }
60
+ } else {
61
+ parts.push(`\n/* ${utilityName} utilities */`);
62
+ parts.push(css);
63
+ totalCount += classes.length;
64
+ }
65
+ }
66
+
67
+ // Generate responsive variants
68
+ parts.push(generateResponsiveUtilities(config, selectedUtilities, usedClasses, includeAll));
69
+
70
+ // Generate state variants
71
+ parts.push(generateStateUtilities(config, selectedUtilities, usedClasses, includeAll));
72
+
73
+ return {
74
+ css: parts.join('\n'),
75
+ count: totalCount
76
+ };
77
+ }
78
+
79
+ function generateResponsiveUtilities(config, selectedUtilities, usedClasses, includeAll) {
80
+ const breakpoints = config.breakpoints || {
81
+ sm: '640px',
82
+ md: '768px',
83
+ lg: '1024px',
84
+ xl: '1280px',
85
+ '2xl': '1536px'
86
+ };
87
+
88
+ const parts = ['\n/* ==================== RESPONSIVE VARIANTS ==================== */'];
89
+
90
+ for (const [bp, minWidth] of Object.entries(breakpoints)) {
91
+ const bpClasses = [];
92
+
93
+ for (const utilityName of selectedUtilities) {
94
+ const generator = utilityGenerators[utilityName];
95
+ if (!generator) continue;
96
+
97
+ const { classes } = generator(config);
98
+
99
+ for (const cls of classes) {
100
+ const responsiveClassName = `${bp}\\:${cls.name}`;
101
+ const shouldInclude = includeAll ||
102
+ !usedClasses ||
103
+ usedClasses.has(`${bp}:${cls.name}`);
104
+
105
+ if (shouldInclude) {
106
+ bpClasses.push(cls.css.replace(
107
+ new RegExp(`\\.${escapeRegex(cls.name)}`, 'g'),
108
+ `.${responsiveClassName}`
109
+ ));
110
+ }
111
+ }
112
+ }
113
+
114
+ if (bpClasses.length > 0) {
115
+ parts.push(`\n@media (min-width: ${minWidth}) {`);
116
+ parts.push(bpClasses.join('\n'));
117
+ parts.push('}');
118
+ }
119
+ }
120
+
121
+ return parts.join('\n');
122
+ }
123
+
124
+ function generateStateUtilities(config, selectedUtilities, usedClasses, includeAll) {
125
+ const states = {
126
+ hover: 'hover',
127
+ focus: 'focus',
128
+ 'focus-visible': 'focus-visible',
129
+ 'focus-within': 'focus-within',
130
+ active: 'active',
131
+ disabled: 'disabled',
132
+ first: 'first-child',
133
+ last: 'last-child',
134
+ odd: 'nth-child(odd)',
135
+ even: 'nth-child(even)'
136
+ };
137
+
138
+ const parts = ['\n/* ==================== STATE VARIANTS ==================== */'];
139
+
140
+ for (const [state, pseudoClass] of Object.entries(states)) {
141
+ const stateClasses = [];
142
+
143
+ for (const utilityName of selectedUtilities) {
144
+ const generator = utilityGenerators[utilityName];
145
+ if (!generator) continue;
146
+
147
+ const { classes } = generator(config);
148
+
149
+ for (const cls of classes) {
150
+ // Skip classes that contain media queries or complex selectors
151
+ if (cls.css.includes('@media') || cls.css.includes('@keyframes')) continue;
152
+
153
+ const stateClassName = `${state}\\:${cls.name}`;
154
+ const shouldInclude = includeAll ||
155
+ !usedClasses ||
156
+ usedClasses.has(`${state}:${cls.name}`);
157
+
158
+ if (shouldInclude) {
159
+ // Extract properties from simple CSS rules only
160
+ const propsMatch = cls.css.match(/\{([^{}]+)\}/);
161
+ if (propsMatch) {
162
+ stateClasses.push(`.${stateClassName}:${pseudoClass} {${propsMatch[1]}}`);
163
+ }
164
+ }
165
+ }
166
+ }
167
+
168
+ if (stateClasses.length > 0) {
169
+ parts.push(`\n/* ${state} variants */`);
170
+ parts.push(stateClasses.join('\n'));
171
+ }
172
+ }
173
+
174
+ // Group hover variant
175
+ parts.push('\n/* group-hover variants */');
176
+ const groupHoverClasses = [];
177
+ for (const utilityName of selectedUtilities) {
178
+ const generator = utilityGenerators[utilityName];
179
+ if (!generator) continue;
180
+
181
+ const { classes } = generator(config);
182
+
183
+ for (const cls of classes) {
184
+ if (cls.css.includes('@media') || cls.css.includes('@keyframes')) continue;
185
+
186
+ const stateClassName = `group-hover\\:${cls.name}`;
187
+ const shouldInclude = includeAll ||
188
+ !usedClasses ||
189
+ usedClasses.has(`group-hover:${cls.name}`);
190
+
191
+ if (shouldInclude) {
192
+ const propsMatch = cls.css.match(/\{([^{}]+)\}/);
193
+ if (propsMatch) {
194
+ groupHoverClasses.push(`.group:hover .${stateClassName} {${propsMatch[1]}}`);
195
+ }
196
+ }
197
+ }
198
+ }
199
+ if (groupHoverClasses.length > 0) {
200
+ parts.push(groupHoverClasses.join('\n'));
201
+ }
202
+
203
+ // Dark mode variant
204
+ if (config.darkMode) {
205
+ parts.push('\n/* dark mode variants */');
206
+ const darkClasses = [];
207
+ for (const utilityName of selectedUtilities) {
208
+ const generator = utilityGenerators[utilityName];
209
+ if (!generator) continue;
210
+
211
+ const { classes } = generator(config);
212
+
213
+ for (const cls of classes) {
214
+ if (cls.css.includes('@media') || cls.css.includes('@keyframes')) continue;
215
+
216
+ const darkClassName = `dark\\:${cls.name}`;
217
+ const shouldInclude = includeAll ||
218
+ !usedClasses ||
219
+ usedClasses.has(`dark:${cls.name}`);
220
+
221
+ if (shouldInclude) {
222
+ const propsMatch = cls.css.match(/\{([^{}]+)\}/);
223
+ if (propsMatch) {
224
+ darkClasses.push(`.dark .${darkClassName} {${propsMatch[1]}}`);
225
+ }
226
+ }
227
+ }
228
+ }
229
+ if (darkClasses.length > 0) {
230
+ parts.push(darkClasses.join('\n'));
231
+ }
232
+ }
233
+
234
+ return parts.join('\n');
235
+ }
236
+
237
+ function escapeRegex(string) {
238
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
239
+ }
@@ -0,0 +1,321 @@
1
+ export function generateLayoutUtilities(config) {
2
+ const classes = [];
3
+
4
+ // Display
5
+ const displays = ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'grid', 'inline-grid', 'contents', 'hidden', 'flow-root'];
6
+ displays.forEach(d => {
7
+ const value = d === 'hidden' ? 'none' : d;
8
+ classes.push({ name: d, css: `.${d} { display: ${value}; }` });
9
+ });
10
+
11
+ // Flex Direction
12
+ ['row', 'row-reverse', 'col', 'col-reverse'].forEach(d => {
13
+ const value = d.replace('col', 'column');
14
+ classes.push({ name: `flex-${d}`, css: `.flex-${d} { flex-direction: ${value}; }` });
15
+ });
16
+
17
+ // Flex Wrap
18
+ ['wrap', 'wrap-reverse', 'nowrap'].forEach(w => {
19
+ classes.push({ name: `flex-${w}`, css: `.flex-${w} { flex-wrap: ${w}; }` });
20
+ });
21
+
22
+ // Flex
23
+ ['1', 'auto', 'initial', 'none'].forEach(f => {
24
+ const values = { '1': '1 1 0%', 'auto': '1 1 auto', 'initial': '0 1 auto', 'none': 'none' };
25
+ classes.push({ name: `flex-${f}`, css: `.flex-${f} { flex: ${values[f]}; }` });
26
+ });
27
+
28
+ // Flex Grow/Shrink
29
+ ['0', '1'].forEach(n => {
30
+ classes.push({ name: `grow-${n}`, css: `.grow-${n} { flex-grow: ${n}; }` });
31
+ classes.push({ name: `shrink-${n}`, css: `.shrink-${n} { flex-shrink: ${n}; }` });
32
+ });
33
+ classes.push({ name: 'grow', css: '.grow { flex-grow: 1; }' });
34
+ classes.push({ name: 'shrink', css: '.shrink { flex-shrink: 1; }' });
35
+
36
+ // Justify Content
37
+ const justifyContent = {
38
+ 'justify-start': 'flex-start',
39
+ 'justify-end': 'flex-end',
40
+ 'justify-center': 'center',
41
+ 'justify-between': 'space-between',
42
+ 'justify-around': 'space-around',
43
+ 'justify-evenly': 'space-evenly',
44
+ 'justify-stretch': 'stretch'
45
+ };
46
+ Object.entries(justifyContent).forEach(([name, value]) => {
47
+ classes.push({ name, css: `.${name} { justify-content: ${value}; }` });
48
+ });
49
+
50
+ // Align Items
51
+ const alignItems = {
52
+ 'items-start': 'flex-start',
53
+ 'items-end': 'flex-end',
54
+ 'items-center': 'center',
55
+ 'items-baseline': 'baseline',
56
+ 'items-stretch': 'stretch'
57
+ };
58
+ Object.entries(alignItems).forEach(([name, value]) => {
59
+ classes.push({ name, css: `.${name} { align-items: ${value}; }` });
60
+ });
61
+
62
+ // Align Self
63
+ const alignSelf = {
64
+ 'self-auto': 'auto',
65
+ 'self-start': 'flex-start',
66
+ 'self-end': 'flex-end',
67
+ 'self-center': 'center',
68
+ 'self-stretch': 'stretch',
69
+ 'self-baseline': 'baseline'
70
+ };
71
+ Object.entries(alignSelf).forEach(([name, value]) => {
72
+ classes.push({ name, css: `.${name} { align-self: ${value}; }` });
73
+ });
74
+
75
+ // Align Content
76
+ const alignContent = {
77
+ 'content-start': 'flex-start',
78
+ 'content-end': 'flex-end',
79
+ 'content-center': 'center',
80
+ 'content-between': 'space-between',
81
+ 'content-around': 'space-around',
82
+ 'content-evenly': 'space-evenly',
83
+ 'content-stretch': 'stretch',
84
+ 'content-baseline': 'baseline'
85
+ };
86
+ Object.entries(alignContent).forEach(([name, value]) => {
87
+ classes.push({ name, css: `.${name} { align-content: ${value}; }` });
88
+ });
89
+
90
+ // Gap
91
+ const spacing = config.spacing || {};
92
+ Object.entries(spacing).forEach(([key, value]) => {
93
+ classes.push({ name: `gap-${key}`, css: `.gap-${key} { gap: ${value}; }` });
94
+ classes.push({ name: `gap-x-${key}`, css: `.gap-x-${key} { column-gap: ${value}; }` });
95
+ classes.push({ name: `gap-y-${key}`, css: `.gap-y-${key} { row-gap: ${value}; }` });
96
+ });
97
+
98
+ // Grid Template Columns
99
+ for (let i = 1; i <= 12; i++) {
100
+ classes.push({
101
+ name: `grid-cols-${i}`,
102
+ css: `.grid-cols-${i} { grid-template-columns: repeat(${i}, minmax(0, 1fr)); }`
103
+ });
104
+ }
105
+ classes.push({ name: 'grid-cols-none', css: '.grid-cols-none { grid-template-columns: none; }' });
106
+ classes.push({ name: 'grid-cols-subgrid', css: '.grid-cols-subgrid { grid-template-columns: subgrid; }' });
107
+
108
+ // Grid Template Rows
109
+ for (let i = 1; i <= 6; i++) {
110
+ classes.push({
111
+ name: `grid-rows-${i}`,
112
+ css: `.grid-rows-${i} { grid-template-rows: repeat(${i}, minmax(0, 1fr)); }`
113
+ });
114
+ }
115
+ classes.push({ name: 'grid-rows-none', css: '.grid-rows-none { grid-template-rows: none; }' });
116
+ classes.push({ name: 'grid-rows-subgrid', css: '.grid-rows-subgrid { grid-template-rows: subgrid; }' });
117
+
118
+ // Grid Column Span
119
+ for (let i = 1; i <= 12; i++) {
120
+ classes.push({ name: `col-span-${i}`, css: `.col-span-${i} { grid-column: span ${i} / span ${i}; }` });
121
+ }
122
+ classes.push({ name: 'col-span-full', css: '.col-span-full { grid-column: 1 / -1; }' });
123
+ classes.push({ name: 'col-auto', css: '.col-auto { grid-column: auto; }' });
124
+
125
+ // Grid Row Span
126
+ for (let i = 1; i <= 6; i++) {
127
+ classes.push({ name: `row-span-${i}`, css: `.row-span-${i} { grid-row: span ${i} / span ${i}; }` });
128
+ }
129
+ classes.push({ name: 'row-span-full', css: '.row-span-full { grid-row: 1 / -1; }' });
130
+ classes.push({ name: 'row-auto', css: '.row-auto { grid-row: auto; }' });
131
+
132
+ // Grid Start/End
133
+ for (let i = 1; i <= 13; i++) {
134
+ classes.push({ name: `col-start-${i}`, css: `.col-start-${i} { grid-column-start: ${i}; }` });
135
+ classes.push({ name: `col-end-${i}`, css: `.col-end-${i} { grid-column-end: ${i}; }` });
136
+ }
137
+ for (let i = 1; i <= 7; i++) {
138
+ classes.push({ name: `row-start-${i}`, css: `.row-start-${i} { grid-row-start: ${i}; }` });
139
+ classes.push({ name: `row-end-${i}`, css: `.row-end-${i} { grid-row-end: ${i}; }` });
140
+ }
141
+
142
+ // Grid Auto Flow
143
+ ['row', 'col', 'dense', 'row-dense', 'col-dense'].forEach(f => {
144
+ const value = f.replace('col', 'column');
145
+ classes.push({ name: `grid-flow-${f}`, css: `.grid-flow-${f} { grid-auto-flow: ${value}; }` });
146
+ });
147
+
148
+ // Place Content/Items/Self
149
+ ['start', 'end', 'center', 'stretch', 'between', 'around', 'evenly'].forEach(p => {
150
+ const value = p === 'between' ? 'space-between' : p === 'around' ? 'space-around' : p === 'evenly' ? 'space-evenly' : p;
151
+ classes.push({ name: `place-content-${p}`, css: `.place-content-${p} { place-content: ${value}; }` });
152
+ });
153
+ ['start', 'end', 'center', 'stretch', 'baseline'].forEach(p => {
154
+ classes.push({ name: `place-items-${p}`, css: `.place-items-${p} { place-items: ${p}; }` });
155
+ classes.push({ name: `place-self-${p}`, css: `.place-self-${p} { place-self: ${p}; }` });
156
+ });
157
+ classes.push({ name: 'place-self-auto', css: '.place-self-auto { place-self: auto; }' });
158
+
159
+ // Position
160
+ ['static', 'fixed', 'absolute', 'relative', 'sticky'].forEach(p => {
161
+ classes.push({ name: p, css: `.${p} { position: ${p}; }` });
162
+ });
163
+
164
+ // Inset (top, right, bottom, left)
165
+ const insetValues = { '0': '0', 'auto': 'auto', 'full': '100%', '1/2': '50%', '1/3': '33.333333%', '2/3': '66.666667%', '1/4': '25%', '3/4': '75%' };
166
+ Object.entries({ ...spacing, ...insetValues }).forEach(([key, value]) => {
167
+ const safeName = key.replace('/', '\\/');
168
+ classes.push({ name: `inset-${safeName}`, css: `.inset-${safeName} { inset: ${value}; }` });
169
+ classes.push({ name: `inset-x-${safeName}`, css: `.inset-x-${safeName} { left: ${value}; right: ${value}; }` });
170
+ classes.push({ name: `inset-y-${safeName}`, css: `.inset-y-${safeName} { top: ${value}; bottom: ${value}; }` });
171
+ classes.push({ name: `top-${safeName}`, css: `.top-${safeName} { top: ${value}; }` });
172
+ classes.push({ name: `right-${safeName}`, css: `.right-${safeName} { right: ${value}; }` });
173
+ classes.push({ name: `bottom-${safeName}`, css: `.bottom-${safeName} { bottom: ${value}; }` });
174
+ classes.push({ name: `left-${safeName}`, css: `.left-${safeName} { left: ${value}; }` });
175
+
176
+ // Negative values
177
+ if (key !== 'auto' && key !== 'full' && !key.includes('/')) {
178
+ classes.push({ name: `-inset-${safeName}`, css: `.-inset-${safeName} { inset: -${value}; }` });
179
+ classes.push({ name: `-top-${safeName}`, css: `.-top-${safeName} { top: -${value}; }` });
180
+ classes.push({ name: `-right-${safeName}`, css: `.-right-${safeName} { right: -${value}; }` });
181
+ classes.push({ name: `-bottom-${safeName}`, css: `.-bottom-${safeName} { bottom: -${value}; }` });
182
+ classes.push({ name: `-left-${safeName}`, css: `.-left-${safeName} { left: -${value}; }` });
183
+ }
184
+ });
185
+
186
+ // Z-Index
187
+ ['auto', '0', '10', '20', '30', '40', '50'].forEach(z => {
188
+ classes.push({ name: `z-${z}`, css: `.z-${z} { z-index: ${z}; }` });
189
+ });
190
+
191
+ // Container
192
+ classes.push({
193
+ name: 'container',
194
+ css: `.container {
195
+ width: 100%;
196
+ margin-left: auto;
197
+ margin-right: auto;
198
+ padding-left: 1rem;
199
+ padding-right: 1rem;
200
+ }
201
+ @media (min-width: 640px) { .container { max-width: 640px; } }
202
+ @media (min-width: 768px) { .container { max-width: 768px; } }
203
+ @media (min-width: 1024px) { .container { max-width: 1024px; } }
204
+ @media (min-width: 1280px) { .container { max-width: 1280px; } }
205
+ @media (min-width: 1536px) { .container { max-width: 1536px; } }`
206
+ });
207
+
208
+ // Width
209
+ const widthSizes = {
210
+ '0': '0', 'px': '1px', 'auto': 'auto', 'full': '100%', 'screen': '100vw',
211
+ 'svw': '100svw', 'lvw': '100lvw', 'dvw': '100dvw',
212
+ 'min': 'min-content', 'max': 'max-content', 'fit': 'fit-content',
213
+ '1/2': '50%', '1/3': '33.333333%', '2/3': '66.666667%',
214
+ '1/4': '25%', '2/4': '50%', '3/4': '75%',
215
+ '1/5': '20%', '2/5': '40%', '3/5': '60%', '4/5': '80%',
216
+ '1/6': '16.666667%', '5/6': '83.333333%',
217
+ '1/12': '8.333333%', '5/12': '41.666667%', '7/12': '58.333333%', '11/12': '91.666667%'
218
+ };
219
+ Object.entries({ ...spacing, ...widthSizes }).forEach(([key, value]) => {
220
+ const safeName = key.replace('/', '\\/').replace('.', '\\.');
221
+ classes.push({ name: `w-${safeName}`, css: `.w-${safeName} { width: ${value}; }` });
222
+ });
223
+
224
+ // Height
225
+ const heightSizes = {
226
+ '0': '0', 'px': '1px', 'auto': 'auto', 'full': '100%', 'screen': '100vh',
227
+ 'svh': '100svh', 'lvh': '100lvh', 'dvh': '100dvh',
228
+ 'min': 'min-content', 'max': 'max-content', 'fit': 'fit-content',
229
+ '1/2': '50%', '1/3': '33.333333%', '2/3': '66.666667%',
230
+ '1/4': '25%', '2/4': '50%', '3/4': '75%',
231
+ '1/5': '20%', '2/5': '40%', '3/5': '60%', '4/5': '80%',
232
+ '1/6': '16.666667%', '5/6': '83.333333%'
233
+ };
234
+ Object.entries({ ...spacing, ...heightSizes }).forEach(([key, value]) => {
235
+ const safeName = key.replace('/', '\\/').replace('.', '\\.');
236
+ classes.push({ name: `h-${safeName}`, css: `.h-${safeName} { height: ${value}; }` });
237
+ });
238
+
239
+ // Min/Max Width
240
+ const minMaxWidths = { '0': '0', 'none': 'none', 'xs': '20rem', 'sm': '24rem', 'md': '28rem', 'lg': '32rem', 'xl': '36rem', '2xl': '42rem', '3xl': '48rem', '4xl': '56rem', '5xl': '64rem', '6xl': '72rem', '7xl': '80rem', 'full': '100%', 'min': 'min-content', 'max': 'max-content', 'fit': 'fit-content', 'prose': '65ch', 'screen-sm': '640px', 'screen-md': '768px', 'screen-lg': '1024px', 'screen-xl': '1280px', 'screen-2xl': '1536px' };
241
+ Object.entries(minMaxWidths).forEach(([key, value]) => {
242
+ classes.push({ name: `min-w-${key}`, css: `.min-w-${key} { min-width: ${value}; }` });
243
+ classes.push({ name: `max-w-${key}`, css: `.max-w-${key} { max-width: ${value}; }` });
244
+ });
245
+
246
+ // Min/Max Height
247
+ const minMaxHeights = { '0': '0', 'full': '100%', 'screen': '100vh', 'svh': '100svh', 'lvh': '100lvh', 'dvh': '100dvh', 'min': 'min-content', 'max': 'max-content', 'fit': 'fit-content', 'none': 'none' };
248
+ Object.entries(minMaxHeights).forEach(([key, value]) => {
249
+ classes.push({ name: `min-h-${key}`, css: `.min-h-${key} { min-height: ${value}; }` });
250
+ classes.push({ name: `max-h-${key}`, css: `.max-h-${key} { max-height: ${value}; }` });
251
+ });
252
+ Object.entries(spacing).forEach(([key, value]) => {
253
+ classes.push({ name: `min-h-${key}`, css: `.min-h-${key} { min-height: ${value}; }` });
254
+ classes.push({ name: `max-h-${key}`, css: `.max-h-${key} { max-height: ${value}; }` });
255
+ });
256
+
257
+ // Size (width and height)
258
+ Object.entries({ ...spacing, ...widthSizes }).forEach(([key, value]) => {
259
+ if (key !== 'screen' && key !== 'svw' && key !== 'lvw' && key !== 'dvw') {
260
+ const safeName = key.replace('/', '\\/').replace('.', '\\.');
261
+ classes.push({ name: `size-${safeName}`, css: `.size-${safeName} { width: ${value}; height: ${value}; }` });
262
+ }
263
+ });
264
+
265
+ // Overflow
266
+ ['auto', 'hidden', 'clip', 'visible', 'scroll'].forEach(o => {
267
+ classes.push({ name: `overflow-${o}`, css: `.overflow-${o} { overflow: ${o}; }` });
268
+ classes.push({ name: `overflow-x-${o}`, css: `.overflow-x-${o} { overflow-x: ${o}; }` });
269
+ classes.push({ name: `overflow-y-${o}`, css: `.overflow-y-${o} { overflow-y: ${o}; }` });
270
+ });
271
+
272
+ // Object Fit
273
+ ['contain', 'cover', 'fill', 'none', 'scale-down'].forEach(f => {
274
+ classes.push({ name: `object-${f}`, css: `.object-${f} { object-fit: ${f}; }` });
275
+ });
276
+
277
+ // Object Position
278
+ ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'].forEach(p => {
279
+ classes.push({ name: `object-${p}`, css: `.object-${p} { object-position: ${p.replace('-', ' ')}; }` });
280
+ });
281
+
282
+ // Aspect Ratio
283
+ classes.push({ name: 'aspect-auto', css: '.aspect-auto { aspect-ratio: auto; }' });
284
+ classes.push({ name: 'aspect-square', css: '.aspect-square { aspect-ratio: 1 / 1; }' });
285
+ classes.push({ name: 'aspect-video', css: '.aspect-video { aspect-ratio: 16 / 9; }' });
286
+ classes.push({ name: 'aspect-4\\/3', css: '.aspect-4\\/3 { aspect-ratio: 4 / 3; }' });
287
+
288
+ // Visibility
289
+ classes.push({ name: 'visible', css: '.visible { visibility: visible; }' });
290
+ classes.push({ name: 'invisible', css: '.invisible { visibility: hidden; }' });
291
+ classes.push({ name: 'collapse', css: '.collapse { visibility: collapse; }' });
292
+
293
+ // Isolation
294
+ classes.push({ name: 'isolate', css: '.isolate { isolation: isolate; }' });
295
+ classes.push({ name: 'isolation-auto', css: '.isolation-auto { isolation: auto; }' });
296
+
297
+ // Float & Clear
298
+ ['left', 'right', 'none', 'start', 'end'].forEach(f => {
299
+ classes.push({ name: `float-${f}`, css: `.float-${f} { float: ${f}; }` });
300
+ });
301
+ ['left', 'right', 'both', 'none', 'start', 'end'].forEach(c => {
302
+ classes.push({ name: `clear-${c}`, css: `.clear-${c} { clear: ${c}; }` });
303
+ });
304
+
305
+ // Box Sizing
306
+ classes.push({ name: 'box-border', css: '.box-border { box-sizing: border-box; }' });
307
+ classes.push({ name: 'box-content', css: '.box-content { box-sizing: content-box; }' });
308
+
309
+ // Order
310
+ for (let i = 1; i <= 12; i++) {
311
+ classes.push({ name: `order-${i}`, css: `.order-${i} { order: ${i}; }` });
312
+ }
313
+ classes.push({ name: 'order-first', css: '.order-first { order: -9999; }' });
314
+ classes.push({ name: 'order-last', css: '.order-last { order: 9999; }' });
315
+ classes.push({ name: 'order-none', css: '.order-none { order: 0; }' });
316
+
317
+ return {
318
+ css: classes.map(c => c.css).join('\n'),
319
+ classes
320
+ };
321
+ }