@shohojdhara/atomix 0.4.0 → 0.4.1
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/dist/atomix.css +9231 -9337
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +2 -2
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.js +4 -5
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +87 -10
- package/dist/core.js +673 -480
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +15 -3
- package/dist/forms.js +530 -97
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +5 -6
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +495 -254
- package/dist/index.esm.js +1269 -723
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1273 -723
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +2 -2
- package/scripts/atomix-cli.js +10 -1
- package/scripts/cli/__tests__/utils.test.js +6 -2
- package/scripts/cli/migration-tools.js +2 -2
- package/scripts/cli/theme-bridge.js +7 -9
- package/scripts/cli/utils.js +2 -1
- package/src/components/Accordion/Accordion.stories.tsx +40 -0
- package/src/components/Accordion/Accordion.tsx +174 -56
- package/src/components/Accordion/AccordionCompound.test.tsx +70 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +156 -50
- package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +84 -0
- package/src/components/Callout/Callout.stories.tsx +166 -1011
- package/src/components/Callout/Callout.tsx +196 -84
- package/src/components/Callout/CalloutCompound.test.tsx +72 -0
- package/src/components/Dropdown/Dropdown.tsx +133 -20
- package/src/components/Dropdown/DropdownCompound.test.tsx +64 -0
- package/src/components/EdgePanel/EdgePanel.tsx +164 -112
- package/src/components/EdgePanel/EdgePanelCompound.test.tsx +53 -0
- package/src/components/Form/Select.stories.tsx +23 -0
- package/src/components/Form/Select.test.tsx +99 -0
- package/src/components/Form/Select.tsx +144 -93
- package/src/components/Form/SelectOption.tsx +88 -0
- package/src/components/Hero/Hero.stories.tsx +37 -0
- package/src/components/Hero/Hero.test.tsx +142 -0
- package/src/components/Hero/Hero.tsx +142 -3
- package/src/components/List/List.test.tsx +62 -0
- package/src/components/List/List.tsx +16 -5
- package/src/components/List/ListItem.tsx +20 -0
- package/src/components/Modal/Modal.stories.tsx +65 -1
- package/src/components/Modal/Modal.tsx +115 -35
- package/src/components/Modal/ModalCompound.test.tsx +94 -0
- package/src/components/Steps/Steps.tsx +124 -21
- package/src/components/Steps/StepsCompound.test.tsx +81 -0
- package/src/components/Tabs/Tabs.tsx +197 -44
- package/src/components/Tabs/TabsCompound.test.tsx +64 -0
- package/src/lib/composables/index.ts +0 -4
- package/src/lib/composables/useAtomixGlass.ts +0 -15
- package/src/lib/theme/devtools/CLI.ts +2 -10
- package/src/lib/types/components.ts +8 -2
- package/src/lib/utils/__tests__/componentUtils.test.ts +57 -2
- package/src/lib/utils/__tests__/themeNaming.test.ts +117 -0
- package/src/lib/utils/themeNaming.ts +1 -1
- package/src/styles/02-tools/_tools.breakpoints.scss +1 -1
- package/src/styles/02-tools/_tools.utility-api.scss +6 -6
- package/src/styles/99-utilities/_utilities.text.scss +0 -1
|
@@ -201,7 +201,6 @@ export function useAtomixGlass({
|
|
|
201
201
|
onClick,
|
|
202
202
|
debugCornerRadius = false,
|
|
203
203
|
debugOverLight = false,
|
|
204
|
-
enablePerformanceMonitoring = false,
|
|
205
204
|
children,
|
|
206
205
|
}: UseAtomixGlassOptions): UseAtomixGlassReturn {
|
|
207
206
|
// State
|
|
@@ -558,8 +557,6 @@ export function useAtomixGlass({
|
|
|
558
557
|
return;
|
|
559
558
|
}
|
|
560
559
|
|
|
561
|
-
const startTime = enablePerformanceMonitoring ? performance.now() : 0;
|
|
562
|
-
|
|
563
560
|
// Use cached rect if available, otherwise get new one
|
|
564
561
|
let rect = cachedRectRef.current;
|
|
565
562
|
if (!rect || rect.width === 0 || rect.height === 0) {
|
|
@@ -582,17 +579,6 @@ export function useAtomixGlass({
|
|
|
582
579
|
// React 18 automatically batches these updates
|
|
583
580
|
setInternalMouseOffset(newOffset);
|
|
584
581
|
setInternalGlobalMousePosition(globalPos);
|
|
585
|
-
|
|
586
|
-
if (
|
|
587
|
-
(typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') &&
|
|
588
|
-
enablePerformanceMonitoring
|
|
589
|
-
) {
|
|
590
|
-
const endTime = performance.now();
|
|
591
|
-
// const duration = endTime - startTime;
|
|
592
|
-
// if (duration > 5) {
|
|
593
|
-
// console.warn(`AtomixGlass: Mouse tracking took ${duration.toFixed(2)}ms`);
|
|
594
|
-
// }
|
|
595
|
-
}
|
|
596
582
|
},
|
|
597
583
|
[
|
|
598
584
|
mouseContainer,
|
|
@@ -600,7 +586,6 @@ export function useAtomixGlass({
|
|
|
600
586
|
externalGlobalMousePosition,
|
|
601
587
|
externalMouseOffset,
|
|
602
588
|
effectiveDisableEffects,
|
|
603
|
-
enablePerformanceMonitoring,
|
|
604
589
|
]
|
|
605
590
|
);
|
|
606
591
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Atomix Theme DevTools CLI
|
|
@@ -11,17 +11,9 @@ import { Command } from 'commander';
|
|
|
11
11
|
import chalk from 'chalk';
|
|
12
12
|
import * as fs from 'fs';
|
|
13
13
|
import * as path from 'path';
|
|
14
|
-
|
|
14
|
+
import { ThemeValidator } from './ThemeValidator';
|
|
15
15
|
import boxen from 'boxen';
|
|
16
16
|
|
|
17
|
-
// Stub validator for now to avoid ESM resolution issues in CLI
|
|
18
|
-
// TODO: Fix ESM module resolution for ThemeValidator in CLI context
|
|
19
|
-
class ThemeValidator {
|
|
20
|
-
validate() {
|
|
21
|
-
return { valid: true, errors: [], warnings: [], a11yIssues: [] };
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
17
|
const program = new Command();
|
|
26
18
|
|
|
27
19
|
program.name('atomix-theme').description('Atomix Theme DevTools').version('0.1.0');
|
|
@@ -375,7 +375,7 @@ export type StateModifier =
|
|
|
375
375
|
*/
|
|
376
376
|
export type IconPosition = 'left' | 'right';
|
|
377
377
|
|
|
378
|
-
export type listvariant = 'dash' | 'number' | 'text';
|
|
378
|
+
export type listvariant = 'dash' | 'number' | 'text' | 'default';
|
|
379
379
|
/**;
|
|
380
380
|
* List component properties
|
|
381
381
|
*/
|
|
@@ -1140,6 +1140,12 @@ export interface HeroProps
|
|
|
1140
1140
|
* Granular part-based styling
|
|
1141
1141
|
*/
|
|
1142
1142
|
parts?: HeroParts;
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* Custom background element to render behind the content
|
|
1146
|
+
* @example <Hero.Background src="..." />
|
|
1147
|
+
*/
|
|
1148
|
+
backgroundElement?: ReactNode;
|
|
1143
1149
|
}
|
|
1144
1150
|
|
|
1145
1151
|
/**
|
|
@@ -2440,7 +2446,7 @@ export interface SelectProps extends BaseComponentProps {
|
|
|
2440
2446
|
/**
|
|
2441
2447
|
* Select options
|
|
2442
2448
|
*/
|
|
2443
|
-
options
|
|
2449
|
+
options?: SelectOption[];
|
|
2444
2450
|
|
|
2445
2451
|
/**
|
|
2446
2452
|
* Selected value(s)
|
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
applyPartStyles,
|
|
5
5
|
createCSSVarStyle,
|
|
6
6
|
mergeComponentProps,
|
|
7
|
+
isYouTubeUrl,
|
|
8
|
+
extractYouTubeId,
|
|
7
9
|
} from '../componentUtils';
|
|
8
10
|
|
|
9
11
|
describe('componentUtils', () => {
|
|
@@ -58,6 +60,7 @@ describe('componentUtils', () => {
|
|
|
58
60
|
className: 'base custom',
|
|
59
61
|
id: 'test',
|
|
60
62
|
'data-test': 'value',
|
|
63
|
+
style: {},
|
|
61
64
|
});
|
|
62
65
|
});
|
|
63
66
|
});
|
|
@@ -94,8 +97,8 @@ describe('componentUtils', () => {
|
|
|
94
97
|
};
|
|
95
98
|
const result = createCSSVarStyle(cssVars);
|
|
96
99
|
expect(result).toEqual({
|
|
97
|
-
'--atomix-button-padding-x':
|
|
98
|
-
'--atomix-button-padding-y':
|
|
100
|
+
'--atomix-button-padding-x': '16px',
|
|
101
|
+
'--atomix-button-padding-y': '8px',
|
|
99
102
|
});
|
|
100
103
|
});
|
|
101
104
|
|
|
@@ -141,4 +144,56 @@ describe('componentUtils', () => {
|
|
|
141
144
|
expect(result).toEqual(baseProps);
|
|
142
145
|
});
|
|
143
146
|
});
|
|
147
|
+
|
|
148
|
+
describe('isYouTubeUrl', () => {
|
|
149
|
+
it('should return true for standard YouTube URLs', () => {
|
|
150
|
+
expect(isYouTubeUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ')).toBe(true);
|
|
151
|
+
expect(isYouTubeUrl('http://www.youtube.com/watch?v=dQw4w9WgXcQ')).toBe(true);
|
|
152
|
+
expect(isYouTubeUrl('www.youtube.com/watch?v=dQw4w9WgXcQ')).toBe(true);
|
|
153
|
+
expect(isYouTubeUrl('youtube.com/watch?v=dQw4w9WgXcQ')).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should return true for shortened YouTube URLs', () => {
|
|
157
|
+
expect(isYouTubeUrl('https://youtu.be/dQw4w9WgXcQ')).toBe(true);
|
|
158
|
+
expect(isYouTubeUrl('http://youtu.be/dQw4w9WgXcQ')).toBe(true);
|
|
159
|
+
expect(isYouTubeUrl('youtu.be/dQw4w9WgXcQ')).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should return true for embed YouTube URLs', () => {
|
|
163
|
+
expect(isYouTubeUrl('https://www.youtube.com/embed/dQw4w9WgXcQ')).toBe(true);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should return false for non-YouTube URLs', () => {
|
|
167
|
+
expect(isYouTubeUrl('https://vimeo.com/12345')).toBe(false);
|
|
168
|
+
expect(isYouTubeUrl('https://google.com')).toBe(false);
|
|
169
|
+
expect(isYouTubeUrl('random string')).toBe(false);
|
|
170
|
+
expect(isYouTubeUrl('')).toBe(false);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('extractYouTubeId', () => {
|
|
175
|
+
it('should extract ID from standard YouTube URLs', () => {
|
|
176
|
+
expect(extractYouTubeId('https://www.youtube.com/watch?v=dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should extract ID from shortened YouTube URLs', () => {
|
|
180
|
+
expect(extractYouTubeId('https://youtu.be/dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should extract ID from embed YouTube URLs', () => {
|
|
184
|
+
expect(extractYouTubeId('https://www.youtube.com/embed/dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should extract ID with additional query parameters', () => {
|
|
188
|
+
expect(extractYouTubeId('https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtu.be')).toBe(
|
|
189
|
+
'dQw4w9WgXcQ'
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should return null for non-YouTube URLs', () => {
|
|
194
|
+
expect(extractYouTubeId('https://vimeo.com/12345')).toBe(null);
|
|
195
|
+
expect(extractYouTubeId('https://google.com')).toBe(null);
|
|
196
|
+
expect(extractYouTubeId('')).toBe(null);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
144
199
|
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { ThemeNaming } from '../themeNaming';
|
|
3
|
+
|
|
4
|
+
describe('ThemeNaming', () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
// Reset prefix to default after each test
|
|
7
|
+
ThemeNaming.setPrefix('atomix');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('setPrefix / getPrefix', () => {
|
|
11
|
+
it('should have default prefix "atomix"', () => {
|
|
12
|
+
expect(ThemeNaming.getPrefix()).toBe('atomix');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should update prefix', () => {
|
|
16
|
+
ThemeNaming.setPrefix('custom');
|
|
17
|
+
expect(ThemeNaming.getPrefix()).toBe('custom');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('camelToKebab', () => {
|
|
22
|
+
it('should convert camelCase to kebab-case', () => {
|
|
23
|
+
expect(ThemeNaming.camelToKebab('camelCase')).toBe('camel-case');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should handle PascalCase', () => {
|
|
27
|
+
expect(ThemeNaming.camelToKebab('PascalCase')).toBe('pascal-case');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should handle simple strings', () => {
|
|
31
|
+
expect(ThemeNaming.camelToKebab('simple')).toBe('simple');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should handle empty string', () => {
|
|
35
|
+
expect(ThemeNaming.camelToKebab('')).toBe('');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('kebabToCamel', () => {
|
|
40
|
+
it('should convert kebab-case to camelCase', () => {
|
|
41
|
+
expect(ThemeNaming.kebabToCamel('kebab-case')).toBe('kebabCase');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should handle simple strings', () => {
|
|
45
|
+
expect(ThemeNaming.kebabToCamel('simple')).toBe('simple');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should handle empty string', () => {
|
|
49
|
+
expect(ThemeNaming.kebabToCamel('')).toBe('');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('cssVar', () => {
|
|
54
|
+
it('should create CSS variable with default prefix', () => {
|
|
55
|
+
expect(ThemeNaming.cssVar('tokenName')).toBe('--atomix-token-name');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should create CSS variable with custom prefix', () => {
|
|
59
|
+
ThemeNaming.setPrefix('custom');
|
|
60
|
+
expect(ThemeNaming.cssVar('tokenName')).toBe('--custom-token-name');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('bemClass', () => {
|
|
65
|
+
it('should create block class', () => {
|
|
66
|
+
expect(ThemeNaming.bemClass('block')).toBe('c-block');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should create block element class', () => {
|
|
70
|
+
expect(ThemeNaming.bemClass('block', 'element')).toBe('c-block__element');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should create block modifier class', () => {
|
|
74
|
+
expect(ThemeNaming.bemClass('block', undefined, 'mod')).toBe('c-block--mod');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should create block element modifier class', () => {
|
|
78
|
+
expect(ThemeNaming.bemClass('block', 'element', 'mod')).toBe('c-block__element--mod');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('variantClass', () => {
|
|
83
|
+
it('should create variant class', () => {
|
|
84
|
+
expect(ThemeNaming.variantClass('button', 'primary')).toBe('c-button--primary');
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('sizeClass', () => {
|
|
89
|
+
it('should create size class', () => {
|
|
90
|
+
expect(ThemeNaming.sizeClass('button', 'lg')).toBe('c-button--lg');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('stateClass', () => {
|
|
95
|
+
it('should create state class', () => {
|
|
96
|
+
expect(ThemeNaming.stateClass('input', 'disabled')).toBe('c-input--disabled');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('utilityClass', () => {
|
|
101
|
+
it('should create utility class', () => {
|
|
102
|
+
expect(ThemeNaming.utilityClass('flex')).toBe('u-flex');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('layoutClass', () => {
|
|
107
|
+
it('should create layout class', () => {
|
|
108
|
+
expect(ThemeNaming.layoutClass('grid')).toBe('l-grid');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('objectClass', () => {
|
|
113
|
+
it('should create object class', () => {
|
|
114
|
+
expect(ThemeNaming.objectClass('container')).toBe('o-container');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -28,7 +28,7 @@ export class ThemeNaming {
|
|
|
28
28
|
* @param str - String to convert
|
|
29
29
|
*/
|
|
30
30
|
static camelToKebab(str: string): string {
|
|
31
|
-
return str.replace(/([a-z0-9]
|
|
31
|
+
return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -22,7 +22,7 @@ $utility-defaults: (
|
|
|
22
22
|
class: null,
|
|
23
23
|
state: null,
|
|
24
24
|
local-vars: (),
|
|
25
|
-
|
|
25
|
+
is-important: true,
|
|
26
26
|
) !default;
|
|
27
27
|
|
|
28
28
|
// Core function to generate utility classes
|
|
@@ -77,11 +77,11 @@ $utility-defaults: (
|
|
|
77
77
|
--atomix-u-#{$css-variable-name}: #{$value};
|
|
78
78
|
} @else if $properties {
|
|
79
79
|
@each $property in $properties {
|
|
80
|
-
#{$property}: $value if(map.get($utility,
|
|
80
|
+
#{$property}: $value if(map.get($utility, is-important), !important, null);
|
|
81
81
|
}
|
|
82
82
|
} @else if $value != null {
|
|
83
83
|
// Guard: only emit property declaration if value is not null
|
|
84
|
-
#{$property-class}: $value if(map.get($utility,
|
|
84
|
+
#{$property-class}: $value if(map.get($utility, is-important), !important, null);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// Add local CSS variables if specified
|
|
@@ -111,11 +111,11 @@ $utility-defaults: (
|
|
|
111
111
|
--atomix-u-#{$css-variable-name}#{$modifier}: #{$value};
|
|
112
112
|
} @else if $properties {
|
|
113
113
|
@each $property in $properties {
|
|
114
|
-
#{$property}: $value if(map.get($utility,
|
|
114
|
+
#{$property}: $value if(map.get($utility, is-important), !important, null);
|
|
115
115
|
}
|
|
116
116
|
} @else if $value != null {
|
|
117
117
|
// Guard: only emit property declaration if value is not null
|
|
118
|
-
#{$base-class}: $value if(map.get($utility,
|
|
118
|
+
#{$base-class}: $value if(map.get($utility, is-important), !important, null);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// Add local CSS variables if specified
|
|
@@ -169,7 +169,7 @@ $utility-defaults: (
|
|
|
169
169
|
values: map.get($config, values),
|
|
170
170
|
class: map.get($config, class),
|
|
171
171
|
state: map.get($config, state),
|
|
172
|
-
|
|
172
|
+
is-important: map.get($config, is-important),
|
|
173
173
|
css-var: map.get($config, css-var),
|
|
174
174
|
local-vars: map.get($config, local-vars),
|
|
175
175
|
responsive: map.get($config, responsive),
|