veza/apps/web/src/components/ui/button-loading.tsx
senke ae586f6134 Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales

Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config

Bloc C - Backend:
- Extraction routes_auth.go depuis router.go

Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 17:23:32 +01:00

100 lines
2.3 KiB
TypeScript

import { Button, ButtonProps } from './button';
import { LoadingSpinner } from './loading-spinner';
import { cn } from '@/lib/utils';
// FE-COMP-001: Add loading states to all async operations
/**
* ButtonLoadingProps - Propriétés du composant ButtonLoading
*
* @interface ButtonLoadingProps
* @extends ButtonProps
*/
interface ButtonLoadingProps extends ButtonProps {
/**
* Si `true`, affiche un spinner et désactive le bouton
*
* @default false
*
* @example
* ```tsx
* <ButtonLoading isLoading={isSubmitting}>
* Envoyer
* </ButtonLoading>
* ```
*/
isLoading?: boolean;
/**
* Texte à afficher pendant le chargement (remplace le contenu du bouton)
* Si non fourni, le contenu original est conservé avec le spinner
*
* @example
* ```tsx
* <ButtonLoading
* isLoading={isSubmitting}
* loadingText="Envoi en cours..."
* >
* Envoyer
* </ButtonLoading>
* ```
*/
loadingText?: string;
}
/**
* ButtonLoading - Composant de bouton avec état de chargement intégré
*
* Extension du composant Button avec support pour l'état de chargement.
* Affiche automatiquement un spinner et désactive le bouton pendant le chargement.
*
* FE-COMP-001: Add loading states to all async operations
*
* @example
* ```tsx
* // Bouton avec état de chargement
* <ButtonLoading
* isLoading={isSubmitting}
* onClick={handleSubmit}
* >
* Envoyer
* </ButtonLoading>
* ```
*
* @example
* ```tsx
* // Avec texte de chargement personnalisé
* <ButtonLoading
* isLoading={isProcessing}
* loadingText="Traitement..."
* variant="primary"
* >
* Traiter
* </ButtonLoading>
* ```
*
* @component
* @param {ButtonLoadingProps} props - Propriétés du composant (hérite de ButtonProps)
* @returns {JSX.Element} Bouton avec spinner et état disabled pendant le chargement
*/
export function ButtonLoading({
isLoading = false,
loadingText,
children,
disabled,
className,
...props
}: ButtonLoadingProps) {
return (
<Button
disabled={disabled || isLoading}
className={cn(className)}
{...props}
>
{isLoading && (
<LoadingSpinner size="sm" inline className="mr-2" />
)}
{isLoading && loadingText ? loadingText : children}
</Button>
);
}