2025-12-13 02:34:34 +00:00
|
|
|
import * as React from 'react';
|
|
|
|
|
import { cn } from '@/lib/utils';
|
|
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* ProgressProps - Propriétés du composant Progress
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @interface ProgressProps
|
|
|
|
|
* @extends React.HTMLAttributes<HTMLDivElement>
|
|
|
|
|
*/
|
|
|
|
|
export interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
|
|
/**
|
|
|
|
|
* Valeur actuelle de la progression (entre 0 et max)
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @example
|
|
|
|
|
* ```tsx
|
|
|
|
|
* <Progress value={75} max={100} />
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
|
|
|
|
value: number;
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* Valeur maximale (par défaut 100)
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @default 100
|
|
|
|
|
*/
|
|
|
|
|
max?: number;
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* Variant du composant de progression
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* - `default`: Barre de progression standard
|
|
|
|
|
* - `gaming`: Style gaming avec bordure dorée et effet glow
|
|
|
|
|
* - `segmented`: Non implémenté (réservé pour usage futur)
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @default 'default'
|
|
|
|
|
*/
|
|
|
|
|
variant?: 'default' | 'gaming' | 'segmented';
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* Couleur de la barre de progression
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* - `cyan`: Cyan (par défaut)
|
|
|
|
|
* - `magenta`: Magenta
|
|
|
|
|
* - `lime`: Lime
|
|
|
|
|
* - `gold`: Or
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @default 'cyan'
|
|
|
|
|
*/
|
|
|
|
|
color?: 'cyan' | 'magenta' | 'lime' | 'gold';
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* Label à afficher à gauche de la barre
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @example
|
|
|
|
|
* ```tsx
|
|
|
|
|
* <Progress value={50} labelLeft="50%" labelRight="100%" />
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
|
|
|
|
labelLeft?: string;
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
/**
|
|
|
|
|
* Label à afficher à droite de la barre
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @example
|
|
|
|
|
* ```tsx
|
|
|
|
|
* <Progress value={50} labelLeft="50%" labelRight="100%" />
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
|
|
|
|
labelRight?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Progress - Composant de barre de progression avec design system Kodo
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* Composant de barre de progression pour afficher l'avancement d'une tâche.
|
|
|
|
|
* Supporte plusieurs variants et couleurs selon le design system Kodo.
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @example
|
|
|
|
|
* ```tsx
|
|
|
|
|
* // Barre de progression simple
|
|
|
|
|
* <Progress value={75} />
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* // Barre avec labels
|
2026-01-13 18:47:57 +00:00
|
|
|
* <Progress
|
|
|
|
|
* value={60}
|
|
|
|
|
* labelLeft="60%"
|
|
|
|
|
* labelRight="100%"
|
2026-01-07 09:31:02 +00:00
|
|
|
* />
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* // Style gaming
|
2026-01-13 18:47:57 +00:00
|
|
|
* <Progress
|
|
|
|
|
* value={85}
|
2026-01-26 13:12:17 +00:00
|
|
|
* variant="glass"
|
2026-01-13 18:47:57 +00:00
|
|
|
* labelLeft="HP"
|
|
|
|
|
* labelRight="100%"
|
2026-01-07 09:31:02 +00:00
|
|
|
* />
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* // Avec couleur personnalisée
|
|
|
|
|
* <Progress value={50} color="magenta" />
|
|
|
|
|
* ```
|
2026-01-13 18:47:57 +00:00
|
|
|
*
|
2026-01-07 09:31:02 +00:00
|
|
|
* @component
|
|
|
|
|
* @param {ProgressProps} props - Propriétés du composant
|
|
|
|
|
* @returns {JSX.Element} Élément div contenant une barre de progression stylisée
|
|
|
|
|
*/
|
|
|
|
|
export const Progress = React.forwardRef<HTMLDivElement, ProgressProps>(
|
2026-01-13 18:47:57 +00:00
|
|
|
(
|
|
|
|
|
{
|
|
|
|
|
value,
|
|
|
|
|
max = 100,
|
|
|
|
|
variant = 'default',
|
|
|
|
|
color = 'cyan',
|
|
|
|
|
labelLeft,
|
|
|
|
|
labelRight,
|
|
|
|
|
className,
|
|
|
|
|
...props
|
|
|
|
|
},
|
|
|
|
|
ref,
|
|
|
|
|
) => {
|
2026-01-07 09:31:02 +00:00
|
|
|
const percentage = Math.min(100, Math.max(0, (value / max) * 100));
|
|
|
|
|
|
|
|
|
|
const colorStyles = {
|
|
|
|
|
cyan: 'bg-kodo-cyan',
|
|
|
|
|
magenta: 'bg-kodo-magenta',
|
|
|
|
|
lime: 'bg-kodo-lime',
|
2026-01-13 18:47:57 +00:00
|
|
|
gold: 'bg-kodo-gold',
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const gradientStyles = {
|
2026-01-16 00:58:12 +00:00
|
|
|
cyan: 'from-kodo-cyan to-kodo-cyan',
|
2026-01-07 09:31:02 +00:00
|
|
|
magenta: 'from-kodo-magenta to-purple-600',
|
|
|
|
|
lime: 'from-kodo-lime to-green-600',
|
2026-01-13 18:47:57 +00:00
|
|
|
gold: 'from-kodo-gold to-orange-500',
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (variant === 'gaming') {
|
|
|
|
|
return (
|
|
|
|
|
<div className={cn('relative', className)} ref={ref} {...props}>
|
|
|
|
|
<div className="h-4 bg-kodo-void rounded-full overflow-hidden border border-kodo-gold/30">
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
feat(web): UI premium Discord/Spotify-like — tokens, shadows, focus, layout
Plan UI premium 6–8 semaines (design system, shell, Storybook, a11y):
- Design system: DESIGN_TOKENS.md, APP_SHELL.md, FULL_LAYOUT_PAGE.md. Single source
for layout/shell (index.css), shadows (design-system.css), durations/easing.
- Tokens: shadow-cover-depth, shadow-gold-glow, shadow-fab-glow; layout max-height
(max-h-layout-drawer, max-h-layout-panel, max-h-layout-list). All duration-200/300/500
replaced by --duration-fast/normal/slow. Arbitrary shadows replaced by token classes.
- Shell & player: Sidebar, Header, GlobalPlayer, MiniPlayer, PlayerQueue, PlayerControls,
AudioPlayer use tokens; focus-visible on Sidebar, PlayerQueue, DropdownMenuTrigger/Item,
TabsTrigger. Typography: text-[10px]/[9px] → text-xs where applicable.
- ESLint: no-restricted-syntax (warn) for w-/h-/rounded-/shadow-/text-/spacing arbitrary.
- Scripts: report-arbitrary-values.mjs, capture/compare/generate visual; visual-complete.spec.ts.
- Stories full layout: Dashboard, Playlists, Library, Settings, Profile in DashboardLayout.stories.
- .cursorrules + README: DESIGN_TOKENS, APP_SHELL, visual commands, no arbitrary without justification.
- apps/web/.gitignore: e2e test artifacts (test-results-visual, playwright-report-visual).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 16:15:58 +00:00
|
|
|
'h-full bg-gradient-to-r shadow-gold-glow transition-all duration-[var(--duration-slow)]',
|
2026-01-13 18:47:57 +00:00
|
|
|
gradientStyles.gold,
|
2026-01-07 09:31:02 +00:00
|
|
|
)}
|
|
|
|
|
style={{ width: `${percentage}%` }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
{(labelLeft || labelRight) && (
|
feat(web): UI premium Discord/Spotify-like — tokens, shadows, focus, layout
Plan UI premium 6–8 semaines (design system, shell, Storybook, a11y):
- Design system: DESIGN_TOKENS.md, APP_SHELL.md, FULL_LAYOUT_PAGE.md. Single source
for layout/shell (index.css), shadows (design-system.css), durations/easing.
- Tokens: shadow-cover-depth, shadow-gold-glow, shadow-fab-glow; layout max-height
(max-h-layout-drawer, max-h-layout-panel, max-h-layout-list). All duration-200/300/500
replaced by --duration-fast/normal/slow. Arbitrary shadows replaced by token classes.
- Shell & player: Sidebar, Header, GlobalPlayer, MiniPlayer, PlayerQueue, PlayerControls,
AudioPlayer use tokens; focus-visible on Sidebar, PlayerQueue, DropdownMenuTrigger/Item,
TabsTrigger. Typography: text-[10px]/[9px] → text-xs where applicable.
- ESLint: no-restricted-syntax (warn) for w-/h-/rounded-/shadow-/text-/spacing arbitrary.
- Scripts: report-arbitrary-values.mjs, capture/compare/generate visual; visual-complete.spec.ts.
- Stories full layout: Dashboard, Playlists, Library, Settings, Profile in DashboardLayout.stories.
- .cursorrules + README: DESIGN_TOKENS, APP_SHELL, visual commands, no arbitrary without justification.
- apps/web/.gitignore: e2e test artifacts (test-results-visual, playwright-report-visual).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 16:15:58 +00:00
|
|
|
<div className="flex justify-between text-xs font-mono font-bold text-kodo-gold mt-1 uppercase tracking-wider">
|
2026-01-07 09:31:02 +00:00
|
|
|
<span>{labelLeft}</span>
|
|
|
|
|
<span>{labelRight}</span>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={cn('w-full', className)} ref={ref} {...props}>
|
2026-02-08 23:08:42 +00:00
|
|
|
<div className="h-2 bg-muted rounded-full overflow-hidden">
|
2026-01-07 09:31:02 +00:00
|
|
|
<div
|
|
|
|
|
className={cn(
|
feat(web): UI premium Discord/Spotify-like — tokens, shadows, focus, layout
Plan UI premium 6–8 semaines (design system, shell, Storybook, a11y):
- Design system: DESIGN_TOKENS.md, APP_SHELL.md, FULL_LAYOUT_PAGE.md. Single source
for layout/shell (index.css), shadows (design-system.css), durations/easing.
- Tokens: shadow-cover-depth, shadow-gold-glow, shadow-fab-glow; layout max-height
(max-h-layout-drawer, max-h-layout-panel, max-h-layout-list). All duration-200/300/500
replaced by --duration-fast/normal/slow. Arbitrary shadows replaced by token classes.
- Shell & player: Sidebar, Header, GlobalPlayer, MiniPlayer, PlayerQueue, PlayerControls,
AudioPlayer use tokens; focus-visible on Sidebar, PlayerQueue, DropdownMenuTrigger/Item,
TabsTrigger. Typography: text-[10px]/[9px] → text-xs where applicable.
- ESLint: no-restricted-syntax (warn) for w-/h-/rounded-/shadow-/text-/spacing arbitrary.
- Scripts: report-arbitrary-values.mjs, capture/compare/generate visual; visual-complete.spec.ts.
- Stories full layout: Dashboard, Playlists, Library, Settings, Profile in DashboardLayout.stories.
- .cursorrules + README: DESIGN_TOKENS, APP_SHELL, visual commands, no arbitrary without justification.
- apps/web/.gitignore: e2e test artifacts (test-results-visual, playwright-report-visual).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 16:15:58 +00:00
|
|
|
'h-full transition-all duration-[var(--duration-normal)] shadow-slider-thumb',
|
2026-01-13 18:47:57 +00:00
|
|
|
colorStyles[color],
|
2026-01-07 09:31:02 +00:00
|
|
|
)}
|
|
|
|
|
style={{ width: `${percentage}%` }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
{(labelLeft || labelRight) && (
|
2026-02-08 23:04:51 +00:00
|
|
|
<div className="flex justify-between text-xs text-muted-foreground mt-1 font-mono">
|
2026-01-07 09:31:02 +00:00
|
|
|
<span>{labelLeft}</span>
|
|
|
|
|
<span>{labelRight}</span>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2026-01-13 18:47:57 +00:00
|
|
|
},
|
2026-01-07 09:31:02 +00:00
|
|
|
);
|
2025-12-13 02:34:34 +00:00
|
|
|
Progress.displayName = 'Progress';
|
|
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
// Alias for compatibility
|
|
|
|
|
export const ProgressBar = Progress;
|