feat: Add more base component to UI
This commit is contained in:
116 files changed
+10379
-3473
No files matched your search
@@ -19,10 +19,10 @@ describe('shared/helpers/cn/cn', () => {
|
||||
// Test with actual conditional values (simulating real usage)
|
||||
const activeCondition = Math.random() > -1; // Always true but not constant
|
||||
const inactiveCondition = Math.random() < -1; // Always false but not constant
|
||||
|
||||
|
||||
expect(cn('p-4', activeCondition && 'bg-red-500')).toBe('p-4 bg-red-500');
|
||||
expect(cn('p-4', inactiveCondition && 'bg-red-500')).toBe('p-4');
|
||||
|
||||
|
||||
// Test null and undefined conditions
|
||||
const nullCondition: string | null = null;
|
||||
const undefinedCondition: string | undefined = undefined;
|
||||
@@ -36,7 +36,9 @@ describe('shared/helpers/cn/cn', () => {
|
||||
});
|
||||
|
||||
it('handles array inputs', () => {
|
||||
expect(cn(['flex', 'items-center'], 'justify-between')).toBe('flex items-center justify-between');
|
||||
expect(cn(['flex', 'items-center'], 'justify-between')).toBe(
|
||||
'flex items-center justify-between'
|
||||
);
|
||||
expect(cn(['p-4', null, 'bg-red-500'])).toBe('p-4 bg-red-500');
|
||||
});
|
||||
|
||||
@@ -50,11 +52,11 @@ describe('shared/helpers/cn/cn', () => {
|
||||
const getIsActive = (): boolean => true;
|
||||
const getPrimaryVariant = (): 'primary' | 'secondary' => 'primary';
|
||||
const getSecondaryVariant = (): 'primary' | 'secondary' => 'secondary';
|
||||
|
||||
|
||||
const isActive = getIsActive();
|
||||
const primaryVariant = getPrimaryVariant();
|
||||
const secondaryVariant = getSecondaryVariant();
|
||||
|
||||
|
||||
// Test primary variant
|
||||
expect(
|
||||
cn(
|
||||
@@ -84,12 +86,8 @@ describe('shared/helpers/cn/cn', () => {
|
||||
});
|
||||
|
||||
it('properly handles spacing and responsive classes', () => {
|
||||
expect(
|
||||
cn('p-2 p-4', 'sm:p-6', 'md:p-8')
|
||||
).toBe('p-4 sm:p-6 md:p-8');
|
||||
|
||||
expect(
|
||||
cn('m-2', 'mx-4', 'ml-6')
|
||||
).toBe('m-2 mx-4 ml-6');
|
||||
expect(cn('p-2 p-4', 'sm:p-6', 'md:p-8')).toBe('p-4 sm:p-6 md:p-8');
|
||||
|
||||
expect(cn('m-2', 'mx-4', 'ml-6')).toBe('m-2 mx-4 ml-6');
|
||||
});
|
||||
});
|
||||
@@ -3,13 +3,13 @@ import { twMerge } from 'tailwind-merge';
|
||||
|
||||
/**
|
||||
* Combines and merges CSS class names using clsx and tailwind-merge.
|
||||
*
|
||||
*
|
||||
* This utility function combines the power of clsx for conditional class handling
|
||||
* with tailwind-merge for proper Tailwind CSS class deduplication and conflict resolution.
|
||||
*
|
||||
*
|
||||
* @param inputs - Class values to combine (strings, objects, arrays, etc.)
|
||||
* @returns Merged class string with conflicts resolved
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* cn('px-4 py-2', 'bg-blue-500') // 'px-4 py-2 bg-blue-500'
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
* Shared helper utilities for common functionality.
|
||||
*/
|
||||
|
||||
export { cn } from './cn/cn';
|
||||
export { cn } from './cn/cn';
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from './types';
|
||||
export * from './functions';
|
||||
export * from './react';
|
||||
export * from './react';
|
||||
@@ -2,9 +2,9 @@ import type React from 'react';
|
||||
|
||||
/**
|
||||
* Safely casts a React ref to a specific type.
|
||||
* This is a controlled escape hatch for situations where TypeScript's
|
||||
* This is a controlled escape hatch for situations where TypeScript's
|
||||
* built-in Ref types are too restrictive (e.g., in generic forwardRef components).
|
||||
*
|
||||
*
|
||||
* @param ref - The ref to cast
|
||||
* @returns The casted ref
|
||||
* @example
|
||||
@@ -13,7 +13,7 @@ import type React from 'react';
|
||||
* ```
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function castRef<T>(ref: React.ForwardedRef<any>): React.ForwardedRef<T> {
|
||||
export function castRef<T>(ref: React.ForwardedRef<any>): React.RefObject<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return ref as React.ForwardedRef<T>;
|
||||
}
|
||||
return ref as unknown as React.RefObject<T>;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ describe('react/genericMemo', () => {
|
||||
it('should memoize a component', () => {
|
||||
const Component = ({ name }: { name: string }) => <div>{name}</div>;
|
||||
const Memoized = genericMemo(Component);
|
||||
|
||||
|
||||
expect(Memoized).toBeDefined();
|
||||
// In React, memo returns a special object with type: component
|
||||
expect((Memoized as any).type).toBe(Component);
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
/**
|
||||
* A type-safe version of React.memo that preserves generic types.
|
||||
*
|
||||
*
|
||||
* @param component - The component to memoize
|
||||
* @returns The memoized component
|
||||
* @example
|
||||
@@ -13,4 +13,4 @@ import React from 'react';
|
||||
export function genericMemo<T>(component: T): T {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
|
||||
return React.memo(component as any) as any as T;
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,5 @@ import type React from 'react';
|
||||
* Common props for any React element.
|
||||
* Useful for forwarding props to dynamic components.
|
||||
*/
|
||||
export type ReactElementProps = React.HTMLAttributes<HTMLElement> & React.AllHTMLAttributes<HTMLElement>;
|
||||
export type ReactElementProps = React.HTMLAttributes<HTMLElement> &
|
||||
React.AllHTMLAttributes<HTMLElement>;
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Props interface for components that accept a className prop.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* interface ButtonProps extends ClassNameProps {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Props interface for components that accept a test ID prop for React Testing Library.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* interface ButtonProps extends TestIdProps {
|
||||
|
||||
Reference in new issue
Block a user