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,200 @@
1
+ /**
2
+ * JasminCSS Tooltip Component
3
+ * Handles tooltips with positioning and accessibility
4
+ */
5
+
6
+ class Tooltip {
7
+ constructor(element, options = {}) {
8
+ this.element = element;
9
+ this.options = {
10
+ placement: 'top',
11
+ trigger: 'hover focus',
12
+ delay: { show: 0, hide: 0 },
13
+ html: false,
14
+ ...options
15
+ };
16
+
17
+ this.tooltip = null;
18
+ this.isVisible = false;
19
+ this.showTimeout = null;
20
+ this.hideTimeout = null;
21
+
22
+ this.init();
23
+ }
24
+
25
+ init() {
26
+ const content = this.element.dataset.tooltip || this.element.getAttribute('title');
27
+ if (!content) return;
28
+
29
+ // Remove native title to prevent double tooltip
30
+ this.element.removeAttribute('title');
31
+ this.element.dataset.tooltip = content;
32
+
33
+ // Set ARIA
34
+ this.element.setAttribute('aria-describedby', '');
35
+
36
+ // Bind events based on trigger
37
+ const triggers = this.options.trigger.split(' ');
38
+
39
+ if (triggers.includes('hover')) {
40
+ this.element.addEventListener('mouseenter', () => this.show());
41
+ this.element.addEventListener('mouseleave', () => this.hide());
42
+ }
43
+
44
+ if (triggers.includes('focus')) {
45
+ this.element.addEventListener('focus', () => this.show());
46
+ this.element.addEventListener('blur', () => this.hide());
47
+ }
48
+
49
+ if (triggers.includes('click')) {
50
+ this.element.addEventListener('click', (e) => {
51
+ e.preventDefault();
52
+ this.toggle();
53
+ });
54
+ }
55
+ }
56
+
57
+ createTooltip() {
58
+ const content = this.element.dataset.tooltip;
59
+
60
+ this.tooltip = document.createElement('div');
61
+ this.tooltip.className = `tooltip tooltip-${this.options.placement}`;
62
+ this.tooltip.setAttribute('role', 'tooltip');
63
+ this.tooltip.id = `tooltip-${Date.now()}`;
64
+
65
+ const inner = document.createElement('div');
66
+ inner.className = 'tooltip-inner';
67
+
68
+ if (this.options.html) {
69
+ inner.innerHTML = content;
70
+ } else {
71
+ inner.textContent = content;
72
+ }
73
+
74
+ const arrow = document.createElement('div');
75
+ arrow.className = 'tooltip-arrow';
76
+
77
+ this.tooltip.appendChild(inner);
78
+ this.tooltip.appendChild(arrow);
79
+
80
+ document.body.appendChild(this.tooltip);
81
+ this.element.setAttribute('aria-describedby', this.tooltip.id);
82
+
83
+ this.position();
84
+ }
85
+
86
+ position() {
87
+ if (!this.tooltip) return;
88
+
89
+ const rect = this.element.getBoundingClientRect();
90
+ const tooltipRect = this.tooltip.getBoundingClientRect();
91
+ const scrollY = window.scrollY;
92
+ const scrollX = window.scrollX;
93
+
94
+ let top, left;
95
+
96
+ switch (this.options.placement) {
97
+ case 'top':
98
+ top = rect.top + scrollY - tooltipRect.height - 8;
99
+ left = rect.left + scrollX + (rect.width - tooltipRect.width) / 2;
100
+ break;
101
+ case 'bottom':
102
+ top = rect.bottom + scrollY + 8;
103
+ left = rect.left + scrollX + (rect.width - tooltipRect.width) / 2;
104
+ break;
105
+ case 'left':
106
+ top = rect.top + scrollY + (rect.height - tooltipRect.height) / 2;
107
+ left = rect.left + scrollX - tooltipRect.width - 8;
108
+ break;
109
+ case 'right':
110
+ top = rect.top + scrollY + (rect.height - tooltipRect.height) / 2;
111
+ left = rect.right + scrollX + 8;
112
+ break;
113
+ }
114
+
115
+ // Boundary checks
116
+ if (left < 0) left = 8;
117
+ if (left + tooltipRect.width > window.innerWidth) {
118
+ left = window.innerWidth - tooltipRect.width - 8;
119
+ }
120
+
121
+ this.tooltip.style.top = `${top}px`;
122
+ this.tooltip.style.left = `${left}px`;
123
+ }
124
+
125
+ show() {
126
+ clearTimeout(this.hideTimeout);
127
+
128
+ this.showTimeout = setTimeout(() => {
129
+ if (!this.tooltip) {
130
+ this.createTooltip();
131
+ }
132
+
133
+ this.tooltip.classList.add('show');
134
+ this.isVisible = true;
135
+
136
+ this.element.dispatchEvent(new CustomEvent('tooltip:show', { detail: { tooltip: this } }));
137
+ }, this.options.delay.show);
138
+ }
139
+
140
+ hide() {
141
+ clearTimeout(this.showTimeout);
142
+
143
+ this.hideTimeout = setTimeout(() => {
144
+ if (this.tooltip) {
145
+ this.tooltip.classList.remove('show');
146
+
147
+ setTimeout(() => {
148
+ this.tooltip?.remove();
149
+ this.tooltip = null;
150
+ this.element.setAttribute('aria-describedby', '');
151
+ }, 150);
152
+ }
153
+
154
+ this.isVisible = false;
155
+ this.element.dispatchEvent(new CustomEvent('tooltip:hide', { detail: { tooltip: this } }));
156
+ }, this.options.delay.hide);
157
+ }
158
+
159
+ toggle() {
160
+ this.isVisible ? this.hide() : this.show();
161
+ }
162
+
163
+ updateContent(content) {
164
+ this.element.dataset.tooltip = content;
165
+ if (this.tooltip) {
166
+ const inner = this.tooltip.querySelector('.tooltip-inner');
167
+ if (this.options.html) {
168
+ inner.innerHTML = content;
169
+ } else {
170
+ inner.textContent = content;
171
+ }
172
+ this.position();
173
+ }
174
+ }
175
+
176
+ destroy() {
177
+ this.hide();
178
+ clearTimeout(this.showTimeout);
179
+ clearTimeout(this.hideTimeout);
180
+ }
181
+
182
+ // Static methods
183
+ static initAll(selector = '[data-tooltip]') {
184
+ document.querySelectorAll(selector).forEach(el => {
185
+ if (!el._jasminTooltip) {
186
+ el._jasminTooltip = new Tooltip(el, {
187
+ placement: el.dataset.tooltipPlacement || 'top',
188
+ trigger: el.dataset.tooltipTrigger || 'hover focus',
189
+ html: el.dataset.tooltipHtml === 'true'
190
+ });
191
+ }
192
+ });
193
+ }
194
+
195
+ static getInstance(element) {
196
+ return element._jasminTooltip;
197
+ }
198
+ }
199
+
200
+ export default Tooltip;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * JasminCSS JavaScript Components
3
+ * Lightweight, accessible, zero-dependency components
4
+ */
5
+
6
+ import Dropdown from './components/dropdown.js';
7
+ import Modal from './components/modal.js';
8
+ import Accordion from './components/accordion.js';
9
+ import Tabs from './components/tabs.js';
10
+ import Offcanvas from './components/offcanvas.js';
11
+ import Tooltip from './components/tooltip.js';
12
+ import Popover from './components/popover.js';
13
+ import Carousel from './components/carousel.js';
14
+ import { Alert, Toast } from './components/alert.js';
15
+
16
+ // Export individual components
17
+ export {
18
+ Dropdown,
19
+ Modal,
20
+ Accordion,
21
+ Tabs,
22
+ Offcanvas,
23
+ Tooltip,
24
+ Popover,
25
+ Carousel,
26
+ Alert,
27
+ Toast
28
+ };
29
+
30
+ /**
31
+ * Initialize all components automatically
32
+ * Call this after DOM is ready
33
+ */
34
+ export function initAll() {
35
+ Dropdown.initAll();
36
+ Modal.initAll();
37
+ Accordion.initAll();
38
+ Tabs.initAll();
39
+ Offcanvas.initAll();
40
+ Tooltip.initAll();
41
+ Popover.initAll();
42
+ Carousel.initAll();
43
+ Alert.initAll();
44
+ }
45
+
46
+ /**
47
+ * Auto-initialize on DOMContentLoaded
48
+ */
49
+ export function autoInit() {
50
+ if (document.readyState === 'loading') {
51
+ document.addEventListener('DOMContentLoaded', initAll);
52
+ } else {
53
+ initAll();
54
+ }
55
+ }
56
+
57
+ // Default export
58
+ const Jasmin = {
59
+ Dropdown,
60
+ Modal,
61
+ Accordion,
62
+ Tabs,
63
+ Offcanvas,
64
+ Tooltip,
65
+ Popover,
66
+ Carousel,
67
+ Alert,
68
+ Toast,
69
+ initAll,
70
+ autoInit,
71
+ version: '1.0.0'
72
+ };
73
+
74
+ // Auto-initialize if data-jasmin-auto-init is present
75
+ if (document.querySelector('[data-jasmin-auto-init]') || document.querySelector('script[data-jasmin-auto-init]')) {
76
+ autoInit();
77
+ }
78
+
79
+ export default Jasmin;
@@ -0,0 +1,228 @@
1
+ /**
2
+ * JasminCSS Configuration Types
3
+ * For jasmin.config.js / jasmin.config.ts
4
+ */
5
+
6
+ export interface JasminBranding {
7
+ /** Primary brand color (hex, rgb, hsl) */
8
+ primary?: string;
9
+ /** Secondary brand color */
10
+ secondary?: string;
11
+ /** Accent color */
12
+ accent?: string;
13
+ /** Success state color */
14
+ success?: string;
15
+ /** Warning state color */
16
+ warning?: string;
17
+ /** Error state color */
18
+ error?: string;
19
+ /** Info state color */
20
+ info?: string;
21
+ }
22
+
23
+ export interface JasminBreakpoints {
24
+ /** Small breakpoint. Default: '640px' */
25
+ sm?: string;
26
+ /** Medium breakpoint. Default: '768px' */
27
+ md?: string;
28
+ /** Large breakpoint. Default: '1024px' */
29
+ lg?: string;
30
+ /** Extra large breakpoint. Default: '1280px' */
31
+ xl?: string;
32
+ /** 2X large breakpoint. Default: '1536px' */
33
+ '2xl'?: string;
34
+ /** Custom breakpoints */
35
+ [key: string]: string | { raw: string } | undefined;
36
+ }
37
+
38
+ export interface JasminSpacing {
39
+ [key: string]: string;
40
+ }
41
+
42
+ export interface JasminFontFamily {
43
+ /** Sans-serif font stack */
44
+ sans?: string;
45
+ /** Serif font stack */
46
+ serif?: string;
47
+ /** Monospace font stack */
48
+ mono?: string;
49
+ /** Custom font families */
50
+ [key: string]: string | undefined;
51
+ }
52
+
53
+ export interface JasminFontSize {
54
+ xs?: string;
55
+ sm?: string;
56
+ base?: string;
57
+ lg?: string;
58
+ xl?: string;
59
+ '2xl'?: string;
60
+ '3xl'?: string;
61
+ '4xl'?: string;
62
+ '5xl'?: string;
63
+ '6xl'?: string;
64
+ [key: string]: string | undefined;
65
+ }
66
+
67
+ export interface JasminBorderRadius {
68
+ none?: string;
69
+ sm?: string;
70
+ DEFAULT?: string;
71
+ md?: string;
72
+ lg?: string;
73
+ xl?: string;
74
+ '2xl'?: string;
75
+ '3xl'?: string;
76
+ full?: string;
77
+ [key: string]: string | undefined;
78
+ }
79
+
80
+ export interface JasminBoxShadow {
81
+ sm?: string;
82
+ DEFAULT?: string;
83
+ md?: string;
84
+ lg?: string;
85
+ xl?: string;
86
+ '2xl'?: string;
87
+ inner?: string;
88
+ none?: string;
89
+ [key: string]: string | undefined;
90
+ }
91
+
92
+ export interface JasminColors {
93
+ [colorName: string]: string | {
94
+ 50?: string;
95
+ 100?: string;
96
+ 200?: string;
97
+ 300?: string;
98
+ 400?: string;
99
+ 500?: string;
100
+ 600?: string;
101
+ 700?: string;
102
+ 800?: string;
103
+ 900?: string;
104
+ 950?: string;
105
+ [shade: string]: string | undefined;
106
+ };
107
+ }
108
+
109
+ export interface JasminExtend {
110
+ /** Extend color palette */
111
+ colors?: JasminColors;
112
+ /** Extend spacing scale */
113
+ spacing?: JasminSpacing;
114
+ /** Extend breakpoints */
115
+ breakpoints?: JasminBreakpoints;
116
+ /** Extend font families */
117
+ fontFamily?: JasminFontFamily;
118
+ /** Extend font sizes */
119
+ fontSize?: JasminFontSize;
120
+ /** Extend border radius */
121
+ borderRadius?: JasminBorderRadius;
122
+ /** Extend box shadows */
123
+ boxShadow?: JasminBoxShadow;
124
+ }
125
+
126
+ export interface JasminCorePlugins {
127
+ /** Enable/disable layout utilities */
128
+ layout?: boolean;
129
+ /** Enable/disable spacing utilities */
130
+ spacing?: boolean;
131
+ /** Enable/disable typography utilities */
132
+ typography?: boolean;
133
+ /** Enable/disable color utilities */
134
+ colors?: boolean;
135
+ /** Enable/disable effect utilities */
136
+ effects?: boolean;
137
+ /** Enable/disable animation utilities */
138
+ animations?: boolean;
139
+ /** Enable/disable transform utilities */
140
+ transforms?: boolean;
141
+ /** Enable/disable filter utilities */
142
+ filters?: boolean;
143
+ /** Enable/disable icon utilities */
144
+ icons?: boolean;
145
+ /** Enable/disable background utilities */
146
+ background?: boolean;
147
+ /** Enable/disable column utilities */
148
+ columns?: boolean;
149
+ /** Enable/disable scroll utilities */
150
+ scroll?: boolean;
151
+ /** Enable/disable SVG utilities */
152
+ svg?: boolean;
153
+ /** Enable/disable accessibility utilities */
154
+ accessibility?: boolean;
155
+ }
156
+
157
+ export type JasminPlugin = (helpers: {
158
+ addUtilities: (utilities: Record<string, Record<string, string>>) => void;
159
+ addComponents: (components: Record<string, Record<string, string>>) => void;
160
+ addBase: (base: Record<string, Record<string, string>>) => void;
161
+ theme: (path: string) => any;
162
+ config: (path: string) => any;
163
+ }) => void;
164
+
165
+ export type SafelistPattern = string | RegExp | {
166
+ pattern: RegExp;
167
+ variants?: string[];
168
+ };
169
+
170
+ export interface JasminConfig {
171
+ /** Brand colors */
172
+ branding?: JasminBranding;
173
+
174
+ /** Content files to scan for tree-shaking */
175
+ content?: string[];
176
+
177
+ /** Dark mode strategy: 'class' or 'media' */
178
+ darkMode?: 'class' | 'media';
179
+
180
+ /** Responsive breakpoints */
181
+ breakpoints?: JasminBreakpoints;
182
+
183
+ /** Spacing scale */
184
+ spacing?: JasminSpacing;
185
+
186
+ /** Font families */
187
+ fontFamily?: JasminFontFamily;
188
+
189
+ /** Font sizes */
190
+ fontSize?: JasminFontSize;
191
+
192
+ /** Border radius values */
193
+ borderRadius?: JasminBorderRadius;
194
+
195
+ /** Box shadow values */
196
+ boxShadow?: JasminBoxShadow;
197
+
198
+ /** Extend default theme */
199
+ extend?: JasminExtend;
200
+
201
+ /** Enable/disable core plugins */
202
+ corePlugins?: JasminCorePlugins;
203
+
204
+ /** Custom plugins */
205
+ plugins?: JasminPlugin[];
206
+
207
+ /** Safelist classes to always include */
208
+ safelist?: SafelistPattern[];
209
+
210
+ /** Prefix for all classes (e.g., 'j-' produces 'j-flex') */
211
+ prefix?: string;
212
+
213
+ /** Important modifier */
214
+ important?: boolean | string;
215
+
216
+ /** Output file path */
217
+ output?: string;
218
+
219
+ /** Enable source maps */
220
+ sourcemap?: boolean;
221
+
222
+ /** Minify output */
223
+ minify?: boolean;
224
+ }
225
+
226
+ export function defineConfig(config: JasminConfig): JasminConfig;
227
+
228
+ export default JasminConfig;