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.
- package/README.md +524 -0
- package/bin/jasmin.js +45 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +14568 -0
- package/dist/index.mjs +14524 -0
- package/dist/jasmin.css +63308 -0
- package/dist/jasmin.min.css +1 -0
- package/dist/plugins/nextjs.js +14777 -0
- package/dist/plugins/nextjs.mjs +14747 -0
- package/dist/plugins/vite.js +14889 -0
- package/dist/plugins/vite.mjs +14860 -0
- package/package.json +101 -0
- package/src/cli/add.js +83 -0
- package/src/cli/init.js +210 -0
- package/src/cli/run.js +142 -0
- package/src/components/accordion.js +309 -0
- package/src/components/alerts.js +357 -0
- package/src/components/avatars.js +331 -0
- package/src/components/badges.js +353 -0
- package/src/components/buttons.js +412 -0
- package/src/components/cards.js +342 -0
- package/src/components/carousel.js +495 -0
- package/src/components/chips.js +440 -0
- package/src/components/command-palette.js +434 -0
- package/src/components/datepicker.js +517 -0
- package/src/components/dropdown.js +411 -0
- package/src/components/forms.js +516 -0
- package/src/components/index.js +81 -0
- package/src/components/modals.js +349 -0
- package/src/components/navigation.js +463 -0
- package/src/components/offcanvas.js +390 -0
- package/src/components/popover.js +427 -0
- package/src/components/progress.js +396 -0
- package/src/components/rating.js +394 -0
- package/src/components/skeleton.js +408 -0
- package/src/components/spinner.js +453 -0
- package/src/components/stepper.js +389 -0
- package/src/components/tables.js +304 -0
- package/src/components/timeline.js +452 -0
- package/src/components/timepicker.js +529 -0
- package/src/components/tooltips.js +345 -0
- package/src/components/upload.js +490 -0
- package/src/config/defaults.js +263 -0
- package/src/config/loader.js +109 -0
- package/src/core/base.js +241 -0
- package/src/core/compiler.js +135 -0
- package/src/core/utilities/accessibility.js +290 -0
- package/src/core/utilities/animations.js +205 -0
- package/src/core/utilities/background.js +109 -0
- package/src/core/utilities/colors.js +234 -0
- package/src/core/utilities/columns.js +161 -0
- package/src/core/utilities/effects.js +261 -0
- package/src/core/utilities/filters.js +135 -0
- package/src/core/utilities/icons.js +806 -0
- package/src/core/utilities/index.js +239 -0
- package/src/core/utilities/layout.js +321 -0
- package/src/core/utilities/scroll.js +205 -0
- package/src/core/utilities/spacing.js +120 -0
- package/src/core/utilities/svg.js +191 -0
- package/src/core/utilities/transforms.js +116 -0
- package/src/core/utilities/typography.js +188 -0
- package/src/index.js +7 -0
- package/src/js/components/accordion.js +154 -0
- package/src/js/components/alert.js +198 -0
- package/src/js/components/carousel.js +226 -0
- package/src/js/components/dropdown.js +166 -0
- package/src/js/components/modal.js +169 -0
- package/src/js/components/offcanvas.js +175 -0
- package/src/js/components/popover.js +221 -0
- package/src/js/components/tabs.js +163 -0
- package/src/js/components/tooltip.js +200 -0
- package/src/js/index.js +79 -0
- package/src/js/types/config.d.ts +228 -0
- package/src/js/types/index.d.ts +439 -0
- package/src/plugins/nextjs.js +100 -0
- package/src/plugins/vite.js +133 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fg from 'fast-glob';
|
|
4
|
+
import postcss from 'postcss';
|
|
5
|
+
import cssnano from 'cssnano';
|
|
6
|
+
import { resolveConfig } from '../config/loader.js';
|
|
7
|
+
import { generateUtilities } from './utilities/index.js';
|
|
8
|
+
import { generateComponents } from '../components/index.js';
|
|
9
|
+
import { generateBase } from './base.js';
|
|
10
|
+
|
|
11
|
+
export async function compileCSS(config, options = {}) {
|
|
12
|
+
const { usedClasses, minify = false, includeAll = false } = options;
|
|
13
|
+
|
|
14
|
+
// Resolve configuration
|
|
15
|
+
const resolvedConfig = resolveConfig(config);
|
|
16
|
+
|
|
17
|
+
// Generate CSS parts
|
|
18
|
+
const parts = [];
|
|
19
|
+
|
|
20
|
+
// 1. Base styles and CSS variables
|
|
21
|
+
parts.push(generateBase(resolvedConfig));
|
|
22
|
+
|
|
23
|
+
// 2. Utility classes
|
|
24
|
+
const utilities = generateUtilities(resolvedConfig, {
|
|
25
|
+
usedClasses,
|
|
26
|
+
includeAll
|
|
27
|
+
});
|
|
28
|
+
parts.push(utilities.css);
|
|
29
|
+
|
|
30
|
+
// 3. Component styles
|
|
31
|
+
const components = generateComponents(resolvedConfig, {
|
|
32
|
+
selected: config.components,
|
|
33
|
+
usedClasses,
|
|
34
|
+
includeAll
|
|
35
|
+
});
|
|
36
|
+
parts.push(components.css);
|
|
37
|
+
|
|
38
|
+
// Combine all CSS
|
|
39
|
+
let css = parts.join('\n\n');
|
|
40
|
+
|
|
41
|
+
// Process with PostCSS
|
|
42
|
+
let minified = null;
|
|
43
|
+
if (minify) {
|
|
44
|
+
const result = await postcss([
|
|
45
|
+
cssnano({
|
|
46
|
+
preset: ['default', {
|
|
47
|
+
discardComments: { removeAll: true },
|
|
48
|
+
normalizeWhitespace: true
|
|
49
|
+
}]
|
|
50
|
+
})
|
|
51
|
+
]).process(css, { from: undefined });
|
|
52
|
+
|
|
53
|
+
minified = result.css;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
css,
|
|
58
|
+
minified,
|
|
59
|
+
stats: {
|
|
60
|
+
utilities: utilities.count,
|
|
61
|
+
components: components.count
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function scanForUsedClasses(cwd, patterns) {
|
|
67
|
+
const usedClasses = new Set();
|
|
68
|
+
|
|
69
|
+
// Find all matching files
|
|
70
|
+
const files = await fg(patterns, {
|
|
71
|
+
cwd,
|
|
72
|
+
absolute: true,
|
|
73
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/.git/**']
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Regex to match class-like patterns
|
|
77
|
+
// Matches: class="...", className="...", :class="...", class:..., etc.
|
|
78
|
+
const classPatterns = [
|
|
79
|
+
/class(?:Name)?=["'`]([^"'`]+)["'`]/g,
|
|
80
|
+
/class(?:Name)?=\{["'`]([^"'`]+)["'`]\}/g,
|
|
81
|
+
/class:([a-zA-Z0-9_-]+)/g,
|
|
82
|
+
/:class=["'`]\{([^}]+)\}["'`]/g,
|
|
83
|
+
/classList\.(?:add|toggle)\(["'`]([^"'`]+)["'`]\)/g,
|
|
84
|
+
/clsx\(([^)]+)\)/g,
|
|
85
|
+
/cn\(([^)]+)\)/g,
|
|
86
|
+
/classnames\(([^)]+)\)/g
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
for (const file of files) {
|
|
90
|
+
try {
|
|
91
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
92
|
+
|
|
93
|
+
for (const pattern of classPatterns) {
|
|
94
|
+
let match;
|
|
95
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
96
|
+
// Extract individual classes
|
|
97
|
+
const classes = match[1]
|
|
98
|
+
.split(/\s+/)
|
|
99
|
+
.map(c => c.trim())
|
|
100
|
+
.filter(c => c && !c.includes('{') && !c.includes('$'));
|
|
101
|
+
|
|
102
|
+
classes.forEach(cls => usedClasses.add(cls));
|
|
103
|
+
}
|
|
104
|
+
// Reset regex lastIndex
|
|
105
|
+
pattern.lastIndex = 0;
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
// Skip files that can't be read
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return usedClasses;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function shouldIncludeClass(className, usedClasses, includeAll) {
|
|
116
|
+
if (includeAll) return true;
|
|
117
|
+
if (!usedClasses) return true;
|
|
118
|
+
|
|
119
|
+
// Check exact match
|
|
120
|
+
if (usedClasses.has(className)) return true;
|
|
121
|
+
|
|
122
|
+
// Check responsive variants
|
|
123
|
+
const breakpoints = ['sm', 'md', 'lg', 'xl', '2xl'];
|
|
124
|
+
for (const bp of breakpoints) {
|
|
125
|
+
if (usedClasses.has(`${bp}:${className}`)) return true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Check state variants
|
|
129
|
+
const states = ['hover', 'focus', 'active', 'disabled', 'dark'];
|
|
130
|
+
for (const state of states) {
|
|
131
|
+
if (usedClasses.has(`${state}:${className}`)) return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
// Accessibility utilities for JasminCSS
|
|
2
|
+
|
|
3
|
+
export function generateAccessibilityUtilities(config) {
|
|
4
|
+
const classes = [];
|
|
5
|
+
|
|
6
|
+
// Screen Reader Only - visually hidden but accessible
|
|
7
|
+
classes.push({
|
|
8
|
+
name: 'sr-only',
|
|
9
|
+
css: `.sr-only {
|
|
10
|
+
position: absolute;
|
|
11
|
+
width: 1px;
|
|
12
|
+
height: 1px;
|
|
13
|
+
padding: 0;
|
|
14
|
+
margin: -1px;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
clip: rect(0, 0, 0, 0);
|
|
17
|
+
white-space: nowrap;
|
|
18
|
+
border-width: 0;
|
|
19
|
+
}`
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Not Screen Reader Only - reverses sr-only
|
|
23
|
+
classes.push({
|
|
24
|
+
name: 'not-sr-only',
|
|
25
|
+
css: `.not-sr-only {
|
|
26
|
+
position: static;
|
|
27
|
+
width: auto;
|
|
28
|
+
height: auto;
|
|
29
|
+
padding: 0;
|
|
30
|
+
margin: 0;
|
|
31
|
+
overflow: visible;
|
|
32
|
+
clip: auto;
|
|
33
|
+
white-space: normal;
|
|
34
|
+
}`
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Focus variants for sr-only (show on focus)
|
|
38
|
+
classes.push({
|
|
39
|
+
name: 'sr-only-focusable',
|
|
40
|
+
css: `.sr-only-focusable:not(:focus):not(:focus-within) {
|
|
41
|
+
position: absolute;
|
|
42
|
+
width: 1px;
|
|
43
|
+
height: 1px;
|
|
44
|
+
padding: 0;
|
|
45
|
+
margin: -1px;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
clip: rect(0, 0, 0, 0);
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
border-width: 0;
|
|
50
|
+
}`
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Focus Visible - only show focus ring on keyboard navigation
|
|
54
|
+
classes.push({
|
|
55
|
+
name: 'focus-visible-ring',
|
|
56
|
+
css: `.focus-visible-ring:focus {
|
|
57
|
+
outline: none;
|
|
58
|
+
}
|
|
59
|
+
.focus-visible-ring:focus-visible {
|
|
60
|
+
outline: 2px solid var(--j-primary);
|
|
61
|
+
outline-offset: 2px;
|
|
62
|
+
}`
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Focus Within
|
|
66
|
+
classes.push({
|
|
67
|
+
name: 'focus-within-ring',
|
|
68
|
+
css: `.focus-within-ring:focus-within {
|
|
69
|
+
outline: 2px solid var(--j-primary);
|
|
70
|
+
outline-offset: 2px;
|
|
71
|
+
}`
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Skip Link - for skip to main content
|
|
75
|
+
classes.push({
|
|
76
|
+
name: 'skip-link',
|
|
77
|
+
css: `.skip-link {
|
|
78
|
+
position: absolute;
|
|
79
|
+
top: -100%;
|
|
80
|
+
left: 0;
|
|
81
|
+
z-index: 9999;
|
|
82
|
+
padding: 1rem 1.5rem;
|
|
83
|
+
background-color: var(--j-primary);
|
|
84
|
+
color: white;
|
|
85
|
+
font-weight: 600;
|
|
86
|
+
text-decoration: none;
|
|
87
|
+
transition: top 150ms ease-in-out;
|
|
88
|
+
}
|
|
89
|
+
.skip-link:focus {
|
|
90
|
+
top: 0;
|
|
91
|
+
}`
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Reduced Motion - respect user preference
|
|
95
|
+
classes.push({
|
|
96
|
+
name: 'motion-safe',
|
|
97
|
+
css: `@media (prefers-reduced-motion: no-preference) {
|
|
98
|
+
.motion-safe\\:animate { animation-play-state: running; }
|
|
99
|
+
.motion-safe\\:transition { transition-property: all; }
|
|
100
|
+
}`
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
classes.push({
|
|
104
|
+
name: 'motion-reduce',
|
|
105
|
+
css: `@media (prefers-reduced-motion: reduce) {
|
|
106
|
+
.motion-reduce\\:animate-none { animation: none; }
|
|
107
|
+
.motion-reduce\\:transition-none { transition: none; }
|
|
108
|
+
}`
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Global reduced motion
|
|
112
|
+
classes.push({
|
|
113
|
+
name: 'reduce-motion',
|
|
114
|
+
css: `@media (prefers-reduced-motion: reduce) {
|
|
115
|
+
.reduce-motion,
|
|
116
|
+
.reduce-motion * {
|
|
117
|
+
animation-duration: 0.01ms !important;
|
|
118
|
+
animation-iteration-count: 1 !important;
|
|
119
|
+
transition-duration: 0.01ms !important;
|
|
120
|
+
scroll-behavior: auto !important;
|
|
121
|
+
}
|
|
122
|
+
}`
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// High Contrast Mode
|
|
126
|
+
classes.push({
|
|
127
|
+
name: 'forced-colors',
|
|
128
|
+
css: `@media (forced-colors: active) {
|
|
129
|
+
.forced-colors\\:visible { visibility: visible; }
|
|
130
|
+
.forced-colors\\:border { border: 1px solid CanvasText; }
|
|
131
|
+
}`
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Focus trap container (visual indicator)
|
|
135
|
+
classes.push({
|
|
136
|
+
name: 'focus-trap',
|
|
137
|
+
css: `.focus-trap { position: relative; }`
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Keyboard focus indicator enhancement
|
|
141
|
+
classes.push({
|
|
142
|
+
name: 'focus-ring',
|
|
143
|
+
css: `.focus-ring:focus {
|
|
144
|
+
outline: 2px solid var(--j-primary);
|
|
145
|
+
outline-offset: 2px;
|
|
146
|
+
}`
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
classes.push({
|
|
150
|
+
name: 'focus-ring-inset',
|
|
151
|
+
css: `.focus-ring-inset:focus {
|
|
152
|
+
outline: 2px solid var(--j-primary);
|
|
153
|
+
outline-offset: -2px;
|
|
154
|
+
}`
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Focus ring colors
|
|
158
|
+
const colors = ['primary', 'secondary', 'success', 'warning', 'error', 'info'];
|
|
159
|
+
colors.forEach(color => {
|
|
160
|
+
classes.push({
|
|
161
|
+
name: `focus-ring-${color}`,
|
|
162
|
+
css: `.focus-ring-${color}:focus {
|
|
163
|
+
outline: 2px solid var(--j-${color});
|
|
164
|
+
outline-offset: 2px;
|
|
165
|
+
}`
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// No focus outline (use sparingly, only with alternative indication)
|
|
170
|
+
classes.push({
|
|
171
|
+
name: 'focus-none',
|
|
172
|
+
css: `.focus-none:focus { outline: none; }`
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Touch target sizing (minimum 44x44px for accessibility)
|
|
176
|
+
classes.push({
|
|
177
|
+
name: 'touch-target',
|
|
178
|
+
css: `.touch-target {
|
|
179
|
+
min-width: 44px;
|
|
180
|
+
min-height: 44px;
|
|
181
|
+
}`
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
classes.push({
|
|
185
|
+
name: 'touch-target-sm',
|
|
186
|
+
css: `.touch-target-sm {
|
|
187
|
+
min-width: 36px;
|
|
188
|
+
min-height: 36px;
|
|
189
|
+
}`
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Aria hidden visual
|
|
193
|
+
classes.push({
|
|
194
|
+
name: 'aria-hidden',
|
|
195
|
+
css: `.aria-hidden[aria-hidden="true"] { display: none; }`
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Disabled state styling
|
|
199
|
+
classes.push({
|
|
200
|
+
name: 'disabled',
|
|
201
|
+
css: `.disabled, [disabled], [aria-disabled="true"] {
|
|
202
|
+
opacity: 0.6;
|
|
203
|
+
cursor: not-allowed;
|
|
204
|
+
pointer-events: none;
|
|
205
|
+
}`
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Live region announcement (for dynamic content)
|
|
209
|
+
classes.push({
|
|
210
|
+
name: 'live-polite',
|
|
211
|
+
css: `.live-polite { /* Use with aria-live="polite" */ }`
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
classes.push({
|
|
215
|
+
name: 'live-assertive',
|
|
216
|
+
css: `.live-assertive { /* Use with aria-live="assertive" */ }`
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Selection customization
|
|
220
|
+
classes.push({
|
|
221
|
+
name: 'selection-primary',
|
|
222
|
+
css: `.selection-primary::selection {
|
|
223
|
+
background-color: var(--j-primary);
|
|
224
|
+
color: white;
|
|
225
|
+
}`
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Caret/cursor color
|
|
229
|
+
classes.push({
|
|
230
|
+
name: 'caret-primary',
|
|
231
|
+
css: `.caret-primary { caret-color: var(--j-primary); }`
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
classes.push({
|
|
235
|
+
name: 'caret-transparent',
|
|
236
|
+
css: `.caret-transparent { caret-color: transparent; }`
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
colors.forEach(color => {
|
|
240
|
+
classes.push({
|
|
241
|
+
name: `caret-${color}`,
|
|
242
|
+
css: `.caret-${color} { caret-color: var(--j-${color}); }`
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Accent color (for form elements)
|
|
247
|
+
classes.push({
|
|
248
|
+
name: 'accent-primary',
|
|
249
|
+
css: `.accent-primary { accent-color: var(--j-primary); }`
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
colors.forEach(color => {
|
|
253
|
+
classes.push({
|
|
254
|
+
name: `accent-${color}`,
|
|
255
|
+
css: `.accent-${color} { accent-color: var(--j-${color}); }`
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Print utilities
|
|
260
|
+
classes.push({
|
|
261
|
+
name: 'print-hidden',
|
|
262
|
+
css: `@media print { .print-hidden { display: none !important; } }`
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
classes.push({
|
|
266
|
+
name: 'print-only',
|
|
267
|
+
css: `.print-only { display: none; }
|
|
268
|
+
@media print { .print-only { display: block; } }`
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
classes.push({
|
|
272
|
+
name: 'print-break-before',
|
|
273
|
+
css: `@media print { .print-break-before { break-before: page; } }`
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
classes.push({
|
|
277
|
+
name: 'print-break-after',
|
|
278
|
+
css: `@media print { .print-break-after { break-after: page; } }`
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
classes.push({
|
|
282
|
+
name: 'print-break-inside-avoid',
|
|
283
|
+
css: `@media print { .print-break-inside-avoid { break-inside: avoid; } }`
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
css: classes.map(c => c.css).join('\n'),
|
|
288
|
+
classes
|
|
289
|
+
};
|
|
290
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export function generateAnimationUtilities(config) {
|
|
2
|
+
const classes = [];
|
|
3
|
+
|
|
4
|
+
// Transition Property
|
|
5
|
+
classes.push({ name: 'transition-none', css: '.transition-none { transition-property: none; }' });
|
|
6
|
+
classes.push({ name: 'transition-all', css: '.transition-all { transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }' });
|
|
7
|
+
classes.push({ name: 'transition', css: '.transition { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }' });
|
|
8
|
+
classes.push({ name: 'transition-colors', css: '.transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }' });
|
|
9
|
+
classes.push({ name: 'transition-opacity', css: '.transition-opacity { transition-property: opacity; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }' });
|
|
10
|
+
classes.push({ name: 'transition-shadow', css: '.transition-shadow { transition-property: box-shadow; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }' });
|
|
11
|
+
classes.push({ name: 'transition-transform', css: '.transition-transform { transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }' });
|
|
12
|
+
|
|
13
|
+
// Transition Duration
|
|
14
|
+
const durations = [0, 75, 100, 150, 200, 300, 500, 700, 1000];
|
|
15
|
+
durations.forEach(d => {
|
|
16
|
+
classes.push({ name: `duration-${d}`, css: `.duration-${d} { transition-duration: ${d}ms; }` });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Transition Timing Function
|
|
20
|
+
classes.push({ name: 'ease-linear', css: '.ease-linear { transition-timing-function: linear; }' });
|
|
21
|
+
classes.push({ name: 'ease-in', css: '.ease-in { transition-timing-function: cubic-bezier(0.4, 0, 1, 1); }' });
|
|
22
|
+
classes.push({ name: 'ease-out', css: '.ease-out { transition-timing-function: cubic-bezier(0, 0, 0.2, 1); }' });
|
|
23
|
+
classes.push({ name: 'ease-in-out', css: '.ease-in-out { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }' });
|
|
24
|
+
classes.push({ name: 'ease-spring', css: '.ease-spring { transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); }' });
|
|
25
|
+
classes.push({ name: 'ease-bounce', css: '.ease-bounce { transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); }' });
|
|
26
|
+
|
|
27
|
+
// Transition Delay
|
|
28
|
+
durations.forEach(d => {
|
|
29
|
+
classes.push({ name: `delay-${d}`, css: `.delay-${d} { transition-delay: ${d}ms; }` });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Keyframe Animations
|
|
33
|
+
const keyframes = `
|
|
34
|
+
@keyframes j-spin {
|
|
35
|
+
to { transform: rotate(360deg); }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@keyframes j-ping {
|
|
39
|
+
75%, 100% { transform: scale(2); opacity: 0; }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@keyframes j-pulse {
|
|
43
|
+
50% { opacity: .5; }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@keyframes j-bounce {
|
|
47
|
+
0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8, 0, 1, 1); }
|
|
48
|
+
50% { transform: none; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@keyframes j-shake {
|
|
52
|
+
0%, 100% { transform: translateX(0); }
|
|
53
|
+
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
|
|
54
|
+
20%, 40%, 60%, 80% { transform: translateX(5px); }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@keyframes j-wiggle {
|
|
58
|
+
0%, 100% { transform: rotate(-3deg); }
|
|
59
|
+
50% { transform: rotate(3deg); }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@keyframes j-fade-in {
|
|
63
|
+
from { opacity: 0; }
|
|
64
|
+
to { opacity: 1; }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@keyframes j-fade-out {
|
|
68
|
+
from { opacity: 1; }
|
|
69
|
+
to { opacity: 0; }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@keyframes j-slide-in-up {
|
|
73
|
+
from { transform: translateY(100%); opacity: 0; }
|
|
74
|
+
to { transform: translateY(0); opacity: 1; }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@keyframes j-slide-in-down {
|
|
78
|
+
from { transform: translateY(-100%); opacity: 0; }
|
|
79
|
+
to { transform: translateY(0); opacity: 1; }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@keyframes j-slide-in-left {
|
|
83
|
+
from { transform: translateX(-100%); opacity: 0; }
|
|
84
|
+
to { transform: translateX(0); opacity: 1; }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@keyframes j-slide-in-right {
|
|
88
|
+
from { transform: translateX(100%); opacity: 0; }
|
|
89
|
+
to { transform: translateX(0); opacity: 1; }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@keyframes j-zoom-in {
|
|
93
|
+
from { transform: scale(0.95); opacity: 0; }
|
|
94
|
+
to { transform: scale(1); opacity: 1; }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@keyframes j-zoom-out {
|
|
98
|
+
from { transform: scale(1); opacity: 1; }
|
|
99
|
+
to { transform: scale(0.95); opacity: 0; }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@keyframes j-float {
|
|
103
|
+
0%, 100% { transform: translateY(0); }
|
|
104
|
+
50% { transform: translateY(-10px); }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@keyframes j-glow {
|
|
108
|
+
0%, 100% { box-shadow: 0 0 5px var(--j-primary), 0 0 10px var(--j-primary); }
|
|
109
|
+
50% { box-shadow: 0 0 20px var(--j-primary), 0 0 30px var(--j-primary); }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@keyframes j-shimmer {
|
|
113
|
+
0% { background-position: -200% 0; }
|
|
114
|
+
100% { background-position: 200% 0; }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@keyframes j-heartbeat {
|
|
118
|
+
0%, 100% { transform: scale(1); }
|
|
119
|
+
14% { transform: scale(1.3); }
|
|
120
|
+
28% { transform: scale(1); }
|
|
121
|
+
42% { transform: scale(1.3); }
|
|
122
|
+
70% { transform: scale(1); }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@keyframes j-flip {
|
|
126
|
+
0% { transform: perspective(400px) rotateY(0); }
|
|
127
|
+
100% { transform: perspective(400px) rotateY(360deg); }
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
classes.push({ name: 'keyframes', css: keyframes });
|
|
132
|
+
|
|
133
|
+
// Animation Classes
|
|
134
|
+
classes.push({ name: 'animate-none', css: '.animate-none { animation: none; }' });
|
|
135
|
+
classes.push({ name: 'animate-spin', css: '.animate-spin { animation: j-spin 1s linear infinite; }' });
|
|
136
|
+
classes.push({ name: 'animate-ping', css: '.animate-ping { animation: j-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite; }' });
|
|
137
|
+
classes.push({ name: 'animate-pulse', css: '.animate-pulse { animation: j-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }' });
|
|
138
|
+
classes.push({ name: 'animate-bounce', css: '.animate-bounce { animation: j-bounce 1s infinite; }' });
|
|
139
|
+
classes.push({ name: 'animate-shake', css: '.animate-shake { animation: j-shake 0.5s ease-in-out; }' });
|
|
140
|
+
classes.push({ name: 'animate-wiggle', css: '.animate-wiggle { animation: j-wiggle 0.5s ease-in-out infinite; }' });
|
|
141
|
+
|
|
142
|
+
// Fade animations
|
|
143
|
+
classes.push({ name: 'animate-fade-in', css: '.animate-fade-in { animation: j-fade-in 0.3s ease-out forwards; }' });
|
|
144
|
+
classes.push({ name: 'animate-fade-out', css: '.animate-fade-out { animation: j-fade-out 0.3s ease-out forwards; }' });
|
|
145
|
+
|
|
146
|
+
// Slide animations
|
|
147
|
+
classes.push({ name: 'animate-slide-in-up', css: '.animate-slide-in-up { animation: j-slide-in-up 0.3s ease-out forwards; }' });
|
|
148
|
+
classes.push({ name: 'animate-slide-in-down', css: '.animate-slide-in-down { animation: j-slide-in-down 0.3s ease-out forwards; }' });
|
|
149
|
+
classes.push({ name: 'animate-slide-in-left', css: '.animate-slide-in-left { animation: j-slide-in-left 0.3s ease-out forwards; }' });
|
|
150
|
+
classes.push({ name: 'animate-slide-in-right', css: '.animate-slide-in-right { animation: j-slide-in-right 0.3s ease-out forwards; }' });
|
|
151
|
+
|
|
152
|
+
// Zoom animations
|
|
153
|
+
classes.push({ name: 'animate-zoom-in', css: '.animate-zoom-in { animation: j-zoom-in 0.3s ease-out forwards; }' });
|
|
154
|
+
classes.push({ name: 'animate-zoom-out', css: '.animate-zoom-out { animation: j-zoom-out 0.3s ease-out forwards; }' });
|
|
155
|
+
|
|
156
|
+
// Futuristic animations
|
|
157
|
+
classes.push({ name: 'animate-float', css: '.animate-float { animation: j-float 3s ease-in-out infinite; }' });
|
|
158
|
+
classes.push({ name: 'animate-glow', css: '.animate-glow { animation: j-glow 2s ease-in-out infinite; }' });
|
|
159
|
+
classes.push({ name: 'animate-shimmer', css: `.animate-shimmer { background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); background-size: 200% 100%; animation: j-shimmer 1.5s infinite; }` });
|
|
160
|
+
classes.push({ name: 'animate-heartbeat', css: '.animate-heartbeat { animation: j-heartbeat 1.5s ease-in-out infinite; }' });
|
|
161
|
+
classes.push({ name: 'animate-flip', css: '.animate-flip { animation: j-flip 1s ease-in-out; }' });
|
|
162
|
+
|
|
163
|
+
// Animation Duration
|
|
164
|
+
const animDurations = ['75', '100', '150', '200', '300', '500', '700', '1000', '2000', '3000'];
|
|
165
|
+
animDurations.forEach(d => {
|
|
166
|
+
classes.push({
|
|
167
|
+
name: `animate-duration-${d}`,
|
|
168
|
+
css: `.animate-duration-${d} { animation-duration: ${d}ms; }`
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Animation Delay
|
|
173
|
+
animDurations.forEach(d => {
|
|
174
|
+
classes.push({
|
|
175
|
+
name: `animate-delay-${d}`,
|
|
176
|
+
css: `.animate-delay-${d} { animation-delay: ${d}ms; }`
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Animation Iteration Count
|
|
181
|
+
classes.push({ name: 'animate-infinite', css: '.animate-infinite { animation-iteration-count: infinite; }' });
|
|
182
|
+
classes.push({ name: 'animate-once', css: '.animate-once { animation-iteration-count: 1; }' });
|
|
183
|
+
classes.push({ name: 'animate-twice', css: '.animate-twice { animation-iteration-count: 2; }' });
|
|
184
|
+
|
|
185
|
+
// Animation Direction
|
|
186
|
+
classes.push({ name: 'animate-normal', css: '.animate-normal { animation-direction: normal; }' });
|
|
187
|
+
classes.push({ name: 'animate-reverse', css: '.animate-reverse { animation-direction: reverse; }' });
|
|
188
|
+
classes.push({ name: 'animate-alternate', css: '.animate-alternate { animation-direction: alternate; }' });
|
|
189
|
+
classes.push({ name: 'animate-alternate-reverse', css: '.animate-alternate-reverse { animation-direction: alternate-reverse; }' });
|
|
190
|
+
|
|
191
|
+
// Animation Fill Mode
|
|
192
|
+
classes.push({ name: 'animate-fill-none', css: '.animate-fill-none { animation-fill-mode: none; }' });
|
|
193
|
+
classes.push({ name: 'animate-fill-forwards', css: '.animate-fill-forwards { animation-fill-mode: forwards; }' });
|
|
194
|
+
classes.push({ name: 'animate-fill-backwards', css: '.animate-fill-backwards { animation-fill-mode: backwards; }' });
|
|
195
|
+
classes.push({ name: 'animate-fill-both', css: '.animate-fill-both { animation-fill-mode: both; }' });
|
|
196
|
+
|
|
197
|
+
// Animation Play State
|
|
198
|
+
classes.push({ name: 'animate-running', css: '.animate-running { animation-play-state: running; }' });
|
|
199
|
+
classes.push({ name: 'animate-paused', css: '.animate-paused { animation-play-state: paused; }' });
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
css: classes.map(c => c.css).join('\n'),
|
|
203
|
+
classes
|
|
204
|
+
};
|
|
205
|
+
}
|