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-02-09 22:04:35 +00:00
|
|
|
/**
|
|
|
|
|
* Label accessible pour la barre de progression
|
|
|
|
|
*
|
|
|
|
|
* @default 'Progress'
|
|
|
|
|
*/
|
|
|
|
|
'aria-label'?: string;
|
|
|
|
|
|
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',
|
2026-02-09 22:04:35 +00:00
|
|
|
'aria-label': ariaLabel = 'Progress',
|
2026-01-13 18:47:57 +00:00
|
|
|
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 = {
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
cyan: 'bg-primary',
|
2026-01-07 09:31:02 +00:00
|
|
|
magenta: 'bg-kodo-magenta',
|
|
|
|
|
lime: 'bg-kodo-lime',
|
2026-02-08 23:20:32 +00:00
|
|
|
gold: 'bg-warning',
|
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 (
|
2026-02-09 22:04:35 +00:00
|
|
|
<div
|
|
|
|
|
className={cn('relative', className)}
|
|
|
|
|
ref={ref}
|
|
|
|
|
role="progressbar"
|
|
|
|
|
aria-valuenow={value}
|
|
|
|
|
aria-valuemin={0}
|
|
|
|
|
aria-valuemax={max}
|
|
|
|
|
aria-label={ariaLabel}
|
|
|
|
|
{...props}
|
|
|
|
|
>
|
2026-02-08 23:20:32 +00:00
|
|
|
<div className="h-4 bg-kodo-void rounded-full overflow-hidden border border-warning/30">
|
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 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) && (
|
2026-02-08 23:20:32 +00:00
|
|
|
<div className="flex justify-between text-xs font-mono font-bold text-warning mt-1 uppercase tracking-wider">
|
2026-01-07 09:31:02 +00:00
|
|
|
<span>{labelLeft}</span>
|
|
|
|
|
<span>{labelRight}</span>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2026-02-09 22:04:35 +00:00
|
|
|
<div
|
|
|
|
|
className={cn('w-full', className)}
|
|
|
|
|
ref={ref}
|
|
|
|
|
role="progressbar"
|
|
|
|
|
aria-valuenow={value}
|
|
|
|
|
aria-valuemin={0}
|
|
|
|
|
aria-valuemax={max}
|
|
|
|
|
aria-label={ariaLabel}
|
|
|
|
|
{...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;
|