- Set up Tailwind CSS configuration for styling - Create Button component with variants (primary, secondary, outline, ghost, danger) - Create Input component with label, error, and helper text support - Create Card component with composable subcomponents (Header, Title, Description, Content, Footer) - Create LoadingSpinner component with size and fullscreen options - Create ErrorMessage component with retry and dismiss actions - Add comprehensive test suite using Jest and React Testing Library - Configure ESLint and Jest for quality assurance All components follow consistent design patterns from mobile app and include proper TypeScript types and accessibility features. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
58 lines
1.3 KiB
TypeScript
58 lines
1.3 KiB
TypeScript
import React from 'react';
|
|
|
|
interface LoadingSpinnerProps {
|
|
size?: 'sm' | 'md' | 'lg';
|
|
color?: string;
|
|
message?: string;
|
|
fullScreen?: boolean;
|
|
}
|
|
|
|
export function LoadingSpinner({
|
|
size = 'md',
|
|
color = 'text-primary',
|
|
message,
|
|
fullScreen = false,
|
|
}: LoadingSpinnerProps) {
|
|
const sizeClasses = {
|
|
sm: 'h-4 w-4',
|
|
md: 'h-8 w-8',
|
|
lg: 'h-12 w-12',
|
|
};
|
|
|
|
const spinner = (
|
|
<div className="flex flex-col items-center justify-center gap-3">
|
|
<svg
|
|
className={`animate-spin ${sizeClasses[size]} ${color}`}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<circle
|
|
className="opacity-25"
|
|
cx="12"
|
|
cy="12"
|
|
r="10"
|
|
stroke="currentColor"
|
|
strokeWidth="4"
|
|
/>
|
|
<path
|
|
className="opacity-75"
|
|
fill="currentColor"
|
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
/>
|
|
</svg>
|
|
{message && <p className="text-sm text-textSecondary">{message}</p>}
|
|
</div>
|
|
);
|
|
|
|
if (fullScreen) {
|
|
return (
|
|
<div className="flex items-center justify-center min-h-screen bg-background">
|
|
{spinner}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return <div className="flex items-center justify-center p-6">{spinner}</div>;
|
|
}
|