93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
/**
|
|
* Composant PlayPauseButton
|
|
* Bouton pour contrôler la lecture/pause du player
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { Play, Pause, Loader2 } from 'lucide-react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
export interface PlayPauseButtonProps
|
|
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
isPlaying: boolean;
|
|
isLoading?: boolean;
|
|
size?: 'sm' | 'md' | 'lg';
|
|
variant?: 'default' | 'ghost' | 'outline';
|
|
}
|
|
|
|
export function PlayPauseButton({
|
|
isPlaying,
|
|
isLoading = false,
|
|
size = 'md',
|
|
variant = 'default',
|
|
className,
|
|
disabled,
|
|
onClick,
|
|
...props
|
|
}: PlayPauseButtonProps) {
|
|
const sizeClasses = {
|
|
sm: 'h-8 w-8',
|
|
md: 'h-10 w-10',
|
|
lg: 'h-12 w-12',
|
|
};
|
|
|
|
const iconSizes = {
|
|
sm: 'h-4 w-4',
|
|
md: 'h-5 w-5',
|
|
lg: 'h-6 w-6',
|
|
};
|
|
|
|
const variantClasses = {
|
|
default:
|
|
'bg-primary text-primary-foreground hover:bg-primary focus:ring-primary',
|
|
ghost:
|
|
'bg-transparent text-foreground hover:bg-muted focus:ring-primary',
|
|
outline:
|
|
'border border-border bg-card text-foreground hover:bg-muted focus:ring-muted',
|
|
};
|
|
|
|
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
if (disabled || isLoading) return;
|
|
onClick?.(e);
|
|
};
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
className={cn(
|
|
'rounded-full flex items-center justify-center transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2',
|
|
sizeClasses[size],
|
|
variantClasses[variant],
|
|
(disabled || isLoading) && 'opacity-50 cursor-not-allowed',
|
|
className,
|
|
)}
|
|
disabled={disabled || isLoading}
|
|
onClick={handleClick}
|
|
aria-label={isPlaying ? 'Mettre en pause' : 'Lire'}
|
|
aria-busy={isLoading}
|
|
{...props}
|
|
>
|
|
{isLoading ? (
|
|
<>
|
|
<Loader2
|
|
className={cn(iconSizes[size], 'animate-spin')}
|
|
aria-hidden="true"
|
|
/>
|
|
<span className="sr-only">Chargement...</span>
|
|
</>
|
|
) : isPlaying ? (
|
|
<>
|
|
<Pause className={iconSizes[size]} aria-hidden="true" />
|
|
<span className="sr-only">Mettre en pause</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Play className={cn(iconSizes[size], 'ml-0.5')} aria-hidden="true" />
|
|
<span className="sr-only">Lire</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
);
|
|
}
|
|
|
|
export default PlayPauseButton;
|