Compare commits
4 Commits
main
...
16c2fda843
| Author | SHA1 | Date | |
|---|---|---|---|
| 16c2fda843 | |||
| aea9fde9ff | |||
| 7e847640ad | |||
| f97afc2425 |
@@ -47,7 +47,8 @@ jobs:
|
|||||||
run: yarn test:unit
|
run: yarn test:unit
|
||||||
|
|
||||||
- name: Run Component Tests
|
- name: Run Component Tests
|
||||||
run: yarn test:component
|
timeout-minutes: 5
|
||||||
|
run: yarn test:component --reporter=verbose --logHeapUsage
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
needs: build # Only runs if tests/lint pass
|
needs: build # Only runs if tests/lint pass
|
||||||
|
|||||||
@@ -258,12 +258,13 @@ export function createVirtualizer<T>(
|
|||||||
// Calculate initial offset ONCE
|
// Calculate initial offset ONCE
|
||||||
const getElementOffset = () => {
|
const getElementOffset = () => {
|
||||||
const rect = node.getBoundingClientRect();
|
const rect = node.getBoundingClientRect();
|
||||||
return rect.top + window.scrollY;
|
const scrollY = typeof window !== 'undefined' ? window.scrollY : 0;
|
||||||
|
return rect.top + scrollY;
|
||||||
};
|
};
|
||||||
|
|
||||||
let cachedOffsetTop = 0;
|
let cachedOffsetTop = 0;
|
||||||
let rafId: number | null = null;
|
let rafId: number | null = null;
|
||||||
containerHeight = window.innerHeight;
|
containerHeight = typeof window !== 'undefined' ? window.innerHeight : 0;
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
if (rafId !== null) {
|
if (rafId !== null) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export {
|
|||||||
export {
|
export {
|
||||||
buildQueryString,
|
buildQueryString,
|
||||||
clampNumber,
|
clampNumber,
|
||||||
|
cn,
|
||||||
debounce,
|
debounce,
|
||||||
getDecimalPlaces,
|
getDecimalPlaces,
|
||||||
roundToStepPrecision,
|
roundToStepPrecision,
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
describe,
|
||||||
|
expect,
|
||||||
|
it,
|
||||||
|
} from 'vitest';
|
||||||
|
import { cn } from './cn';
|
||||||
|
|
||||||
|
describe('cn utility', () => {
|
||||||
|
it('should merge classes with clsx', () => {
|
||||||
|
expect(cn('class1', 'class2')).toBe('class1 class2');
|
||||||
|
expect(cn('class1', { class2: true, class3: false })).toBe('class1 class2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve tailwind specificity conflicts', () => {
|
||||||
|
// text-neutral-400 vs text-brand (text-brand should win)
|
||||||
|
expect(cn('text-neutral-400', 'text-brand')).toBe('text-brand');
|
||||||
|
|
||||||
|
// p-4 vs p-2
|
||||||
|
expect(cn('p-4', 'p-2')).toBe('p-2');
|
||||||
|
|
||||||
|
// dark mode classes should be handled correctly too
|
||||||
|
expect(cn('text-neutral-400 dark:text-neutral-400', 'text-brand dark:text-brand')).toBe(
|
||||||
|
'text-brand dark:text-brand',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle undefined and null inputs', () => {
|
||||||
|
expect(cn('class1', undefined, null, 'class2')).toBe('class1 class2');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import {
|
||||||
|
type ClassValue,
|
||||||
|
clsx,
|
||||||
|
} from 'clsx';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility for merging Tailwind classes with clsx and tailwind-merge.
|
||||||
|
* This resolves specificity conflicts between Tailwind classes.
|
||||||
|
*/
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ export {
|
|||||||
type QueryParamValue,
|
type QueryParamValue,
|
||||||
} from './buildQueryString/buildQueryString';
|
} from './buildQueryString/buildQueryString';
|
||||||
export { clampNumber } from './clampNumber/clampNumber';
|
export { clampNumber } from './clampNumber/clampNumber';
|
||||||
|
export { cn } from './cn';
|
||||||
export { debounce } from './debounce/debounce';
|
export { debounce } from './debounce/debounce';
|
||||||
export { getDecimalPlaces } from './getDecimalPlaces/getDecimalPlaces';
|
export { getDecimalPlaces } from './getDecimalPlaces/getDecimalPlaces';
|
||||||
export { getSkeletonWidth } from './getSkeletonWidth/getSkeletonWidth';
|
export { getSkeletonWidth } from './getSkeletonWidth/getSkeletonWidth';
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ export default defineConfig({
|
|||||||
restoreMocks: true,
|
restoreMocks: true,
|
||||||
setupFiles: ['./vitest.setup.component.ts', './vitest.setup.jsdom.ts'],
|
setupFiles: ['./vitest.setup.component.ts', './vitest.setup.jsdom.ts'],
|
||||||
globals: true,
|
globals: true,
|
||||||
|
testTimeout: 15000,
|
||||||
|
maxWorkers: process.env.CI ? 1 : undefined,
|
||||||
},
|
},
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|||||||
Reference in New Issue
Block a user