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,205 @@
1
+ // Scroll utilities for JasminCSS
2
+
3
+ export function generateScrollUtilities(config) {
4
+ const classes = [];
5
+
6
+ // Spacing scale for scroll padding/margin
7
+ const spacing = {
8
+ '0': '0px',
9
+ 'px': '1px',
10
+ '0.5': '0.125rem',
11
+ '1': '0.25rem',
12
+ '1.5': '0.375rem',
13
+ '2': '0.5rem',
14
+ '2.5': '0.625rem',
15
+ '3': '0.75rem',
16
+ '3.5': '0.875rem',
17
+ '4': '1rem',
18
+ '5': '1.25rem',
19
+ '6': '1.5rem',
20
+ '7': '1.75rem',
21
+ '8': '2rem',
22
+ '9': '2.25rem',
23
+ '10': '2.5rem',
24
+ '11': '2.75rem',
25
+ '12': '3rem',
26
+ '14': '3.5rem',
27
+ '16': '4rem',
28
+ '20': '5rem',
29
+ '24': '6rem',
30
+ '28': '7rem',
31
+ '32': '8rem',
32
+ '36': '9rem',
33
+ '40': '10rem',
34
+ '44': '11rem',
35
+ '48': '12rem',
36
+ '52': '13rem',
37
+ '56': '14rem',
38
+ '60': '15rem',
39
+ '64': '16rem',
40
+ '72': '18rem',
41
+ '80': '20rem',
42
+ '96': '24rem'
43
+ };
44
+
45
+ // Scroll Padding
46
+ Object.entries(spacing).forEach(([name, value]) => {
47
+ const className = name.includes('.') ? name.replace('.', '\\.') : name;
48
+
49
+ // All sides
50
+ classes.push({
51
+ name: `scroll-p-${name}`,
52
+ css: `.scroll-p-${className} { scroll-padding: ${value}; }`
53
+ });
54
+
55
+ // X axis
56
+ classes.push({
57
+ name: `scroll-px-${name}`,
58
+ css: `.scroll-px-${className} { scroll-padding-left: ${value}; scroll-padding-right: ${value}; }`
59
+ });
60
+
61
+ // Y axis
62
+ classes.push({
63
+ name: `scroll-py-${name}`,
64
+ css: `.scroll-py-${className} { scroll-padding-top: ${value}; scroll-padding-bottom: ${value}; }`
65
+ });
66
+
67
+ // Individual sides
68
+ classes.push({
69
+ name: `scroll-pt-${name}`,
70
+ css: `.scroll-pt-${className} { scroll-padding-top: ${value}; }`
71
+ });
72
+ classes.push({
73
+ name: `scroll-pr-${name}`,
74
+ css: `.scroll-pr-${className} { scroll-padding-right: ${value}; }`
75
+ });
76
+ classes.push({
77
+ name: `scroll-pb-${name}`,
78
+ css: `.scroll-pb-${className} { scroll-padding-bottom: ${value}; }`
79
+ });
80
+ classes.push({
81
+ name: `scroll-pl-${name}`,
82
+ css: `.scroll-pl-${className} { scroll-padding-left: ${value}; }`
83
+ });
84
+
85
+ // Logical properties
86
+ classes.push({
87
+ name: `scroll-ps-${name}`,
88
+ css: `.scroll-ps-${className} { scroll-padding-inline-start: ${value}; }`
89
+ });
90
+ classes.push({
91
+ name: `scroll-pe-${name}`,
92
+ css: `.scroll-pe-${className} { scroll-padding-inline-end: ${value}; }`
93
+ });
94
+ });
95
+
96
+ // Scroll Margin
97
+ Object.entries(spacing).forEach(([name, value]) => {
98
+ const className = name.includes('.') ? name.replace('.', '\\.') : name;
99
+
100
+ // All sides
101
+ classes.push({
102
+ name: `scroll-m-${name}`,
103
+ css: `.scroll-m-${className} { scroll-margin: ${value}; }`
104
+ });
105
+
106
+ // X axis
107
+ classes.push({
108
+ name: `scroll-mx-${name}`,
109
+ css: `.scroll-mx-${className} { scroll-margin-left: ${value}; scroll-margin-right: ${value}; }`
110
+ });
111
+
112
+ // Y axis
113
+ classes.push({
114
+ name: `scroll-my-${name}`,
115
+ css: `.scroll-my-${className} { scroll-margin-top: ${value}; scroll-margin-bottom: ${value}; }`
116
+ });
117
+
118
+ // Individual sides
119
+ classes.push({
120
+ name: `scroll-mt-${name}`,
121
+ css: `.scroll-mt-${className} { scroll-margin-top: ${value}; }`
122
+ });
123
+ classes.push({
124
+ name: `scroll-mr-${name}`,
125
+ css: `.scroll-mr-${className} { scroll-margin-right: ${value}; }`
126
+ });
127
+ classes.push({
128
+ name: `scroll-mb-${name}`,
129
+ css: `.scroll-mb-${className} { scroll-margin-bottom: ${value}; }`
130
+ });
131
+ classes.push({
132
+ name: `scroll-ml-${name}`,
133
+ css: `.scroll-ml-${className} { scroll-margin-left: ${value}; }`
134
+ });
135
+
136
+ // Logical properties
137
+ classes.push({
138
+ name: `scroll-ms-${name}`,
139
+ css: `.scroll-ms-${className} { scroll-margin-inline-start: ${value}; }`
140
+ });
141
+ classes.push({
142
+ name: `scroll-me-${name}`,
143
+ css: `.scroll-me-${className} { scroll-margin-inline-end: ${value}; }`
144
+ });
145
+ });
146
+
147
+ // Overscroll Behavior
148
+ const overscroll = ['auto', 'contain', 'none'];
149
+ overscroll.forEach(value => {
150
+ classes.push({
151
+ name: `overscroll-${value}`,
152
+ css: `.overscroll-${value} { overscroll-behavior: ${value}; }`
153
+ });
154
+ classes.push({
155
+ name: `overscroll-x-${value}`,
156
+ css: `.overscroll-x-${value} { overscroll-behavior-x: ${value}; }`
157
+ });
158
+ classes.push({
159
+ name: `overscroll-y-${value}`,
160
+ css: `.overscroll-y-${value} { overscroll-behavior-y: ${value}; }`
161
+ });
162
+ });
163
+
164
+ // Scrollbar Width
165
+ classes.push({
166
+ name: 'scrollbar-auto',
167
+ css: '.scrollbar-auto { scrollbar-width: auto; }'
168
+ });
169
+ classes.push({
170
+ name: 'scrollbar-thin',
171
+ css: '.scrollbar-thin { scrollbar-width: thin; }'
172
+ });
173
+ classes.push({
174
+ name: 'scrollbar-none',
175
+ css: '.scrollbar-none { scrollbar-width: none; -ms-overflow-style: none; }'
176
+ });
177
+ classes.push({
178
+ name: 'scrollbar-none',
179
+ css: '.scrollbar-none::-webkit-scrollbar { display: none; }'
180
+ });
181
+
182
+ // Scrollbar Color
183
+ const colors = ['primary', 'secondary', 'accent', 'neutral'];
184
+ colors.forEach(color => {
185
+ classes.push({
186
+ name: `scrollbar-${color}`,
187
+ css: `.scrollbar-${color} { scrollbar-color: var(--j-${color}) transparent; }`
188
+ });
189
+ });
190
+
191
+ // Scroll Snap Stop
192
+ classes.push({
193
+ name: 'snap-normal',
194
+ css: '.snap-normal { scroll-snap-stop: normal; }'
195
+ });
196
+ classes.push({
197
+ name: 'snap-always',
198
+ css: '.snap-always { scroll-snap-stop: always; }'
199
+ });
200
+
201
+ return {
202
+ css: classes.map(c => c.css).join('\n'),
203
+ classes
204
+ };
205
+ }
@@ -0,0 +1,120 @@
1
+ export function generateSpacingUtilities(config) {
2
+ const classes = [];
3
+ const spacing = config.spacing || {};
4
+
5
+ // Padding
6
+ Object.entries(spacing).forEach(([key, value]) => {
7
+ const safeName = key.replace('.', '\\.');
8
+
9
+ // All sides
10
+ classes.push({ name: `p-${safeName}`, css: `.p-${safeName} { padding: ${value}; }` });
11
+
12
+ // Individual sides
13
+ classes.push({ name: `pt-${safeName}`, css: `.pt-${safeName} { padding-top: ${value}; }` });
14
+ classes.push({ name: `pr-${safeName}`, css: `.pr-${safeName} { padding-right: ${value}; }` });
15
+ classes.push({ name: `pb-${safeName}`, css: `.pb-${safeName} { padding-bottom: ${value}; }` });
16
+ classes.push({ name: `pl-${safeName}`, css: `.pl-${safeName} { padding-left: ${value}; }` });
17
+
18
+ // Horizontal and vertical
19
+ classes.push({ name: `px-${safeName}`, css: `.px-${safeName} { padding-left: ${value}; padding-right: ${value}; }` });
20
+ classes.push({ name: `py-${safeName}`, css: `.py-${safeName} { padding-top: ${value}; padding-bottom: ${value}; }` });
21
+
22
+ // Logical properties
23
+ classes.push({ name: `ps-${safeName}`, css: `.ps-${safeName} { padding-inline-start: ${value}; }` });
24
+ classes.push({ name: `pe-${safeName}`, css: `.pe-${safeName} { padding-inline-end: ${value}; }` });
25
+ });
26
+
27
+ // Margin (positive values)
28
+ Object.entries(spacing).forEach(([key, value]) => {
29
+ const safeName = key.replace('.', '\\.');
30
+
31
+ // All sides
32
+ classes.push({ name: `m-${safeName}`, css: `.m-${safeName} { margin: ${value}; }` });
33
+
34
+ // Individual sides
35
+ classes.push({ name: `mt-${safeName}`, css: `.mt-${safeName} { margin-top: ${value}; }` });
36
+ classes.push({ name: `mr-${safeName}`, css: `.mr-${safeName} { margin-right: ${value}; }` });
37
+ classes.push({ name: `mb-${safeName}`, css: `.mb-${safeName} { margin-bottom: ${value}; }` });
38
+ classes.push({ name: `ml-${safeName}`, css: `.ml-${safeName} { margin-left: ${value}; }` });
39
+
40
+ // Horizontal and vertical
41
+ classes.push({ name: `mx-${safeName}`, css: `.mx-${safeName} { margin-left: ${value}; margin-right: ${value}; }` });
42
+ classes.push({ name: `my-${safeName}`, css: `.my-${safeName} { margin-top: ${value}; margin-bottom: ${value}; }` });
43
+
44
+ // Logical properties
45
+ classes.push({ name: `ms-${safeName}`, css: `.ms-${safeName} { margin-inline-start: ${value}; }` });
46
+ classes.push({ name: `me-${safeName}`, css: `.me-${safeName} { margin-inline-end: ${value}; }` });
47
+ });
48
+
49
+ // Margin auto
50
+ classes.push({ name: 'm-auto', css: '.m-auto { margin: auto; }' });
51
+ classes.push({ name: 'mx-auto', css: '.mx-auto { margin-left: auto; margin-right: auto; }' });
52
+ classes.push({ name: 'my-auto', css: '.my-auto { margin-top: auto; margin-bottom: auto; }' });
53
+ classes.push({ name: 'mt-auto', css: '.mt-auto { margin-top: auto; }' });
54
+ classes.push({ name: 'mr-auto', css: '.mr-auto { margin-right: auto; }' });
55
+ classes.push({ name: 'mb-auto', css: '.mb-auto { margin-bottom: auto; }' });
56
+ classes.push({ name: 'ml-auto', css: '.ml-auto { margin-left: auto; }' });
57
+ classes.push({ name: 'ms-auto', css: '.ms-auto { margin-inline-start: auto; }' });
58
+ classes.push({ name: 'me-auto', css: '.me-auto { margin-inline-end: auto; }' });
59
+
60
+ // Negative margins
61
+ Object.entries(spacing).forEach(([key, value]) => {
62
+ if (key === '0' || key === 'px') return; // Skip 0 and px for negative
63
+
64
+ const safeName = key.replace('.', '\\.');
65
+
66
+ // All sides
67
+ classes.push({ name: `-m-${safeName}`, css: `.-m-${safeName} { margin: -${value}; }` });
68
+
69
+ // Individual sides
70
+ classes.push({ name: `-mt-${safeName}`, css: `.-mt-${safeName} { margin-top: -${value}; }` });
71
+ classes.push({ name: `-mr-${safeName}`, css: `.-mr-${safeName} { margin-right: -${value}; }` });
72
+ classes.push({ name: `-mb-${safeName}`, css: `.-mb-${safeName} { margin-bottom: -${value}; }` });
73
+ classes.push({ name: `-ml-${safeName}`, css: `.-ml-${safeName} { margin-left: -${value}; }` });
74
+
75
+ // Horizontal and vertical
76
+ classes.push({ name: `-mx-${safeName}`, css: `.-mx-${safeName} { margin-left: -${value}; margin-right: -${value}; }` });
77
+ classes.push({ name: `-my-${safeName}`, css: `.-my-${safeName} { margin-top: -${value}; margin-bottom: -${value}; }` });
78
+ });
79
+
80
+ // Space Between (for flex/grid children)
81
+ Object.entries(spacing).forEach(([key, value]) => {
82
+ const safeName = key.replace('.', '\\.');
83
+
84
+ classes.push({
85
+ name: `space-x-${safeName}`,
86
+ css: `.space-x-${safeName} > :not([hidden]) ~ :not([hidden]) { margin-left: ${value}; }`
87
+ });
88
+ classes.push({
89
+ name: `space-y-${safeName}`,
90
+ css: `.space-y-${safeName} > :not([hidden]) ~ :not([hidden]) { margin-top: ${value}; }`
91
+ });
92
+
93
+ // Negative space
94
+ if (key !== '0' && key !== 'px') {
95
+ classes.push({
96
+ name: `-space-x-${safeName}`,
97
+ css: `.-space-x-${safeName} > :not([hidden]) ~ :not([hidden]) { margin-left: -${value}; }`
98
+ });
99
+ classes.push({
100
+ name: `-space-y-${safeName}`,
101
+ css: `.-space-y-${safeName} > :not([hidden]) ~ :not([hidden]) { margin-top: -${value}; }`
102
+ });
103
+ }
104
+ });
105
+
106
+ // Space reverse (for flex-row-reverse and flex-col-reverse)
107
+ classes.push({
108
+ name: 'space-x-reverse',
109
+ css: `.space-x-reverse > :not([hidden]) ~ :not([hidden]) { --j-space-x-reverse: 1; margin-right: calc(var(--j-space-x, 0) * var(--j-space-x-reverse)); margin-left: calc(var(--j-space-x, 0) * calc(1 - var(--j-space-x-reverse))); }`
110
+ });
111
+ classes.push({
112
+ name: 'space-y-reverse',
113
+ css: `.space-y-reverse > :not([hidden]) ~ :not([hidden]) { --j-space-y-reverse: 1; margin-bottom: calc(var(--j-space-y, 0) * var(--j-space-y-reverse)); margin-top: calc(var(--j-space-y, 0) * calc(1 - var(--j-space-y-reverse))); }`
114
+ });
115
+
116
+ return {
117
+ css: classes.map(c => c.css).join('\n'),
118
+ classes
119
+ };
120
+ }
@@ -0,0 +1,191 @@
1
+ // SVG utilities for JasminCSS
2
+
3
+ export function generateSvgUtilities(config) {
4
+ const classes = [];
5
+
6
+ // Fill utilities
7
+ classes.push({
8
+ name: 'fill-none',
9
+ css: '.fill-none { fill: none; }'
10
+ });
11
+ classes.push({
12
+ name: 'fill-inherit',
13
+ css: '.fill-inherit { fill: inherit; }'
14
+ });
15
+ classes.push({
16
+ name: 'fill-current',
17
+ css: '.fill-current { fill: currentColor; }'
18
+ });
19
+ classes.push({
20
+ name: 'fill-transparent',
21
+ css: '.fill-transparent { fill: transparent; }'
22
+ });
23
+ classes.push({
24
+ name: 'fill-black',
25
+ css: '.fill-black { fill: #000; }'
26
+ });
27
+ classes.push({
28
+ name: 'fill-white',
29
+ css: '.fill-white { fill: #fff; }'
30
+ });
31
+
32
+ // Fill semantic colors
33
+ const colors = ['primary', 'secondary', 'accent', 'success', 'warning', 'error', 'info', 'neutral'];
34
+ colors.forEach(color => {
35
+ classes.push({
36
+ name: `fill-${color}`,
37
+ css: `.fill-${color} { fill: var(--j-${color}); }`
38
+ });
39
+ // Color shades
40
+ [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].forEach(shade => {
41
+ classes.push({
42
+ name: `fill-${color}-${shade}`,
43
+ css: `.fill-${color}-${shade} { fill: var(--color-${color}-${shade}); }`
44
+ });
45
+ });
46
+ });
47
+
48
+ // Stroke utilities
49
+ classes.push({
50
+ name: 'stroke-none',
51
+ css: '.stroke-none { stroke: none; }'
52
+ });
53
+ classes.push({
54
+ name: 'stroke-inherit',
55
+ css: '.stroke-inherit { stroke: inherit; }'
56
+ });
57
+ classes.push({
58
+ name: 'stroke-current',
59
+ css: '.stroke-current { stroke: currentColor; }'
60
+ });
61
+ classes.push({
62
+ name: 'stroke-transparent',
63
+ css: '.stroke-transparent { stroke: transparent; }'
64
+ });
65
+ classes.push({
66
+ name: 'stroke-black',
67
+ css: '.stroke-black { stroke: #000; }'
68
+ });
69
+ classes.push({
70
+ name: 'stroke-white',
71
+ css: '.stroke-white { stroke: #fff; }'
72
+ });
73
+
74
+ // Stroke semantic colors
75
+ colors.forEach(color => {
76
+ classes.push({
77
+ name: `stroke-${color}`,
78
+ css: `.stroke-${color} { stroke: var(--j-${color}); }`
79
+ });
80
+ // Color shades
81
+ [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].forEach(shade => {
82
+ classes.push({
83
+ name: `stroke-${color}-${shade}`,
84
+ css: `.stroke-${color}-${shade} { stroke: var(--color-${color}-${shade}); }`
85
+ });
86
+ });
87
+ });
88
+
89
+ // Stroke Width
90
+ const strokeWidths = {
91
+ '0': '0',
92
+ '1': '1',
93
+ '2': '2'
94
+ };
95
+ Object.entries(strokeWidths).forEach(([name, value]) => {
96
+ classes.push({
97
+ name: `stroke-${name}`,
98
+ css: `.stroke-${name} { stroke-width: ${value}; }`
99
+ });
100
+ });
101
+
102
+ // Stroke Linecap
103
+ const linecaps = ['butt', 'round', 'square'];
104
+ linecaps.forEach(value => {
105
+ classes.push({
106
+ name: `stroke-cap-${value}`,
107
+ css: `.stroke-cap-${value} { stroke-linecap: ${value}; }`
108
+ });
109
+ });
110
+
111
+ // Stroke Linejoin
112
+ const linejoins = ['arcs', 'bevel', 'miter', 'miter-clip', 'round'];
113
+ linejoins.forEach(value => {
114
+ classes.push({
115
+ name: `stroke-join-${value}`,
116
+ css: `.stroke-join-${value} { stroke-linejoin: ${value}; }`
117
+ });
118
+ });
119
+
120
+ // Stroke Dasharray
121
+ classes.push({
122
+ name: 'stroke-dash-none',
123
+ css: '.stroke-dash-none { stroke-dasharray: none; }'
124
+ });
125
+ classes.push({
126
+ name: 'stroke-dash-1',
127
+ css: '.stroke-dash-1 { stroke-dasharray: 1; }'
128
+ });
129
+ classes.push({
130
+ name: 'stroke-dash-2',
131
+ css: '.stroke-dash-2 { stroke-dasharray: 2; }'
132
+ });
133
+ classes.push({
134
+ name: 'stroke-dash-4',
135
+ css: '.stroke-dash-4 { stroke-dasharray: 4; }'
136
+ });
137
+ classes.push({
138
+ name: 'stroke-dash-6',
139
+ css: '.stroke-dash-6 { stroke-dasharray: 6; }'
140
+ });
141
+
142
+ // Stroke Dashoffset
143
+ [0, 1, 2, 4, 8].forEach(value => {
144
+ classes.push({
145
+ name: `stroke-offset-${value}`,
146
+ css: `.stroke-offset-${value} { stroke-dashoffset: ${value}; }`
147
+ });
148
+ });
149
+
150
+ // Stroke Opacity
151
+ const opacities = [0, 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 95, 100];
152
+ opacities.forEach(value => {
153
+ classes.push({
154
+ name: `stroke-opacity-${value}`,
155
+ css: `.stroke-opacity-${value} { stroke-opacity: ${value / 100}; }`
156
+ });
157
+ });
158
+
159
+ // Fill Opacity
160
+ opacities.forEach(value => {
161
+ classes.push({
162
+ name: `fill-opacity-${value}`,
163
+ css: `.fill-opacity-${value} { fill-opacity: ${value / 100}; }`
164
+ });
165
+ });
166
+
167
+ // Fill Rule
168
+ classes.push({
169
+ name: 'fill-rule-nonzero',
170
+ css: '.fill-rule-nonzero { fill-rule: nonzero; }'
171
+ });
172
+ classes.push({
173
+ name: 'fill-rule-evenodd',
174
+ css: '.fill-rule-evenodd { fill-rule: evenodd; }'
175
+ });
176
+
177
+ // Clip Rule
178
+ classes.push({
179
+ name: 'clip-rule-nonzero',
180
+ css: '.clip-rule-nonzero { clip-rule: nonzero; }'
181
+ });
182
+ classes.push({
183
+ name: 'clip-rule-evenodd',
184
+ css: '.clip-rule-evenodd { clip-rule: evenodd; }'
185
+ });
186
+
187
+ return {
188
+ css: classes.map(c => c.css).join('\n'),
189
+ classes
190
+ };
191
+ }
@@ -0,0 +1,116 @@
1
+ export function generateTransformUtilities(config) {
2
+ const classes = [];
3
+
4
+ // Transform
5
+ classes.push({
6
+ name: 'transform',
7
+ css: `.transform { transform: translate(var(--j-translate-x, 0), var(--j-translate-y, 0)) rotate(var(--j-rotate, 0)) skewX(var(--j-skew-x, 0)) skewY(var(--j-skew-y, 0)) scaleX(var(--j-scale-x, 1)) scaleY(var(--j-scale-y, 1)); }`
8
+ });
9
+ classes.push({ name: 'transform-cpu', css: '.transform-cpu { transform: translate(var(--j-translate-x, 0), var(--j-translate-y, 0)) rotate(var(--j-rotate, 0)) skewX(var(--j-skew-x, 0)) skewY(var(--j-skew-y, 0)) scaleX(var(--j-scale-x, 1)) scaleY(var(--j-scale-y, 1)); }' });
10
+ classes.push({ name: 'transform-gpu', css: '.transform-gpu { transform: translate3d(var(--j-translate-x, 0), var(--j-translate-y, 0), 0) rotate(var(--j-rotate, 0)) skewX(var(--j-skew-x, 0)) skewY(var(--j-skew-y, 0)) scaleX(var(--j-scale-x, 1)) scaleY(var(--j-scale-y, 1)); }' });
11
+ classes.push({ name: 'transform-none', css: '.transform-none { transform: none; }' });
12
+
13
+ // Transform Origin
14
+ const origins = ['center', 'top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left'];
15
+ origins.forEach(o => {
16
+ classes.push({ name: `origin-${o}`, css: `.origin-${o} { transform-origin: ${o.replace('-', ' ')}; }` });
17
+ });
18
+
19
+ // Scale
20
+ const scales = [0, 50, 75, 90, 95, 100, 105, 110, 125, 150, 200];
21
+ scales.forEach(s => {
22
+ const value = s / 100;
23
+ classes.push({ name: `scale-${s}`, css: `.scale-${s} { --j-scale-x: ${value}; --j-scale-y: ${value}; transform: scale(${value}); }` });
24
+ classes.push({ name: `scale-x-${s}`, css: `.scale-x-${s} { --j-scale-x: ${value}; transform: scaleX(${value}); }` });
25
+ classes.push({ name: `scale-y-${s}`, css: `.scale-y-${s} { --j-scale-y: ${value}; transform: scaleY(${value}); }` });
26
+ });
27
+
28
+ // Rotate
29
+ const rotations = [0, 1, 2, 3, 6, 12, 45, 90, 180];
30
+ rotations.forEach(r => {
31
+ classes.push({ name: `rotate-${r}`, css: `.rotate-${r} { --j-rotate: ${r}deg; transform: rotate(${r}deg); }` });
32
+ classes.push({ name: `-rotate-${r}`, css: `.-rotate-${r} { --j-rotate: -${r}deg; transform: rotate(-${r}deg); }` });
33
+ });
34
+
35
+ // Translate
36
+ const spacing = config.spacing || {};
37
+ const translateValues = {
38
+ ...spacing,
39
+ '1/2': '50%',
40
+ '1/3': '33.333333%',
41
+ '2/3': '66.666667%',
42
+ '1/4': '25%',
43
+ '2/4': '50%',
44
+ '3/4': '75%',
45
+ 'full': '100%'
46
+ };
47
+
48
+ Object.entries(translateValues).forEach(([key, value]) => {
49
+ const safeName = key.replace('/', '\\/').replace('.', '\\.');
50
+ classes.push({ name: `translate-x-${safeName}`, css: `.translate-x-${safeName} { --j-translate-x: ${value}; transform: translateX(${value}); }` });
51
+ classes.push({ name: `translate-y-${safeName}`, css: `.translate-y-${safeName} { --j-translate-y: ${value}; transform: translateY(${value}); }` });
52
+
53
+ // Negative values
54
+ if (!key.includes('/')) {
55
+ classes.push({ name: `-translate-x-${safeName}`, css: `.-translate-x-${safeName} { --j-translate-x: -${value}; transform: translateX(-${value}); }` });
56
+ classes.push({ name: `-translate-y-${safeName}`, css: `.-translate-y-${safeName} { --j-translate-y: -${value}; transform: translateY(-${value}); }` });
57
+ }
58
+ });
59
+
60
+ // Negative percentage translations
61
+ ['1/2', '1/3', '2/3', '1/4', '3/4', 'full'].forEach(key => {
62
+ const value = translateValues[key];
63
+ const safeName = key.replace('/', '\\/');
64
+ classes.push({ name: `-translate-x-${safeName}`, css: `.-translate-x-${safeName} { --j-translate-x: -${value}; transform: translateX(-${value}); }` });
65
+ classes.push({ name: `-translate-y-${safeName}`, css: `.-translate-y-${safeName} { --j-translate-y: -${value}; transform: translateY(-${value}); }` });
66
+ });
67
+
68
+ // Skew
69
+ const skews = [0, 1, 2, 3, 6, 12];
70
+ skews.forEach(s => {
71
+ classes.push({ name: `skew-x-${s}`, css: `.skew-x-${s} { --j-skew-x: ${s}deg; transform: skewX(${s}deg); }` });
72
+ classes.push({ name: `skew-y-${s}`, css: `.skew-y-${s} { --j-skew-y: ${s}deg; transform: skewY(${s}deg); }` });
73
+ classes.push({ name: `-skew-x-${s}`, css: `.-skew-x-${s} { --j-skew-x: -${s}deg; transform: skewX(-${s}deg); }` });
74
+ classes.push({ name: `-skew-y-${s}`, css: `.-skew-y-${s} { --j-skew-y: -${s}deg; transform: skewY(-${s}deg); }` });
75
+ });
76
+
77
+ // Perspective
78
+ const perspectives = ['none', 'sm', 'md', 'lg', 'xl'];
79
+ const perspectiveValues = { none: 'none', sm: '200px', md: '500px', lg: '1000px', xl: '2000px' };
80
+ perspectives.forEach(p => {
81
+ classes.push({ name: `perspective-${p}`, css: `.perspective-${p} { perspective: ${perspectiveValues[p]}; }` });
82
+ });
83
+
84
+ // Perspective Origin
85
+ origins.forEach(o => {
86
+ classes.push({ name: `perspective-origin-${o}`, css: `.perspective-origin-${o} { perspective-origin: ${o.replace('-', ' ')}; }` });
87
+ });
88
+
89
+ // Transform Style
90
+ classes.push({ name: 'transform-flat', css: '.transform-flat { transform-style: flat; }' });
91
+ classes.push({ name: 'transform-3d', css: '.transform-3d { transform-style: preserve-3d; }' });
92
+
93
+ // Backface Visibility
94
+ classes.push({ name: 'backface-visible', css: '.backface-visible { backface-visibility: visible; }' });
95
+ classes.push({ name: 'backface-hidden', css: '.backface-hidden { backface-visibility: hidden; }' });
96
+
97
+ // 3D Transforms
98
+ const rotations3d = [0, 45, 90, 180];
99
+ rotations3d.forEach(r => {
100
+ classes.push({ name: `rotate-x-${r}`, css: `.rotate-x-${r} { transform: rotateX(${r}deg); }` });
101
+ classes.push({ name: `rotate-y-${r}`, css: `.rotate-y-${r} { transform: rotateY(${r}deg); }` });
102
+ classes.push({ name: `rotate-z-${r}`, css: `.rotate-z-${r} { transform: rotateZ(${r}deg); }` });
103
+ });
104
+
105
+ // Translate Z (for 3D)
106
+ const translateZValues = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100'];
107
+ translateZValues.forEach(z => {
108
+ classes.push({ name: `translate-z-${z}`, css: `.translate-z-${z} { transform: translateZ(${z}px); }` });
109
+ classes.push({ name: `-translate-z-${z}`, css: `.-translate-z-${z} { transform: translateZ(-${z}px); }` });
110
+ });
111
+
112
+ return {
113
+ css: classes.map(c => c.css).join('\n'),
114
+ classes
115
+ };
116
+ }