style(TrackListSelectionActions): elevate visual fidelity to premium standards

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
senke 2026-02-07 09:01:35 +01:00
parent 0e9bcb8e99
commit 6832aeed39
2 changed files with 40 additions and 35 deletions

View file

@ -4,10 +4,15 @@ import { TrackListSelectionActions } from './TrackListSelectionActions';
const meta: Meta<typeof TrackListSelectionActions> = {
title: 'Components/Features/Tracks/TrackListSelectionActions',
component: TrackListSelectionActions,
parameters: {
layout: 'padded',
},
parameters: { layout: 'centered' },
tags: ['autodocs'],
decorators: [
(Story) => (
<div className="w-full max-w-2xl p-4 bg-background border border-border rounded-[var(--radius-xl)] min-h-layout-story flex flex-col justify-end">
<Story />
</div>
),
],
argTypes: {
onPlay: { action: 'onPlay' },
onDelete: { action: 'onDelete' },
@ -53,3 +58,17 @@ export const PartialActions: Story = {
onDelete: () => { },
},
};
/** All actions + clear to validate bar and button tokens. */
export const VisualStressTest: Story = {
args: {
selectedCount: 12,
selectedTrackIds: Array.from({ length: 12 }, (_, i) => String(i + 1)),
onPlay: () => { },
onDelete: () => { },
onLike: () => { },
onDownload: () => { },
onMore: () => { },
onClearSelection: () => { },
},
};

View file

@ -53,21 +53,28 @@ export function TrackListSelectionActions({
onMore?.(selectedTrackIds);
};
const actionButtonClass = [
'p-2 rounded-[var(--radius-md)]',
'transition-[background-color,transform] duration-[var(--duration-normal)]',
'hover:bg-primary-foreground/15 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-foreground/40 focus-visible:ring-offset-2 focus-visible:ring-offset-primary',
'active:scale-95',
].join(' ');
return (
<div
className={cn(
'fixed bottom-0 left-0 right-0 z-50',
'bg-kodo-cyan dark:bg-kodo-cyan text-white',
'px-4 py-4 shadow-lg',
'bg-primary text-primary-foreground',
'px-4 py-4 shadow-lg border-t border-primary-foreground/10 rounded-t-[var(--radius-xl)]',
'flex items-center justify-between gap-4',
'transition-transform duration-300 ease-in-out',
'transition-[opacity,transform,box-shadow] duration-[var(--duration-normal)]',
className,
)}
role="toolbar"
aria-label={`Actions pour ${selectedCount} piste${selectedCount > 1 ? 's' : ''} sélectionnée${selectedCount > 1 ? 's' : ''}`}
>
<div className="flex items-center gap-4">
<span className="text-sm font-medium">
<span className="text-sm font-medium tracking-tight text-primary-foreground/95 tabular-nums">
{selectedCount} piste{selectedCount > 1 ? 's' : ''} sélectionnée
{selectedCount > 1 ? 's' : ''}
</span>
@ -77,11 +84,7 @@ export function TrackListSelectionActions({
<button
type="button"
onClick={handlePlay}
className={cn(
'p-2 rounded-md transition-colors',
'hover:bg-white/5 dark:hover:bg-white/5',
'focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-blue-600',
)}
className={actionButtonClass}
aria-label={`Lire ${selectedCount} piste${selectedCount > 1 ? 's' : ''}`}
>
<Play className="h-5 w-5" aria-hidden="true" />
@ -93,11 +96,7 @@ export function TrackListSelectionActions({
<button
type="button"
onClick={handleLike}
className={cn(
'p-2 rounded-md transition-colors',
'hover:bg-white/5 dark:hover:bg-white/5',
'focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-blue-600',
)}
className={actionButtonClass}
aria-label={`Ajouter ${selectedCount} piste${selectedCount > 1 ? 's' : ''} aux favoris`}
>
<Heart className="h-5 w-5" aria-hidden="true" />
@ -109,11 +108,7 @@ export function TrackListSelectionActions({
<button
type="button"
onClick={handleDownload}
className={cn(
'p-2 rounded-md transition-colors',
'hover:bg-white/5 dark:hover:bg-white/5',
'focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-blue-600',
)}
className={actionButtonClass}
aria-label={`Télécharger ${selectedCount} piste${selectedCount > 1 ? 's' : ''}`}
>
<Download className="h-5 w-5" aria-hidden="true" />
@ -126,9 +121,8 @@ export function TrackListSelectionActions({
type="button"
onClick={handleDelete}
className={cn(
'p-2 rounded-md transition-colors',
'hover:bg-kodo-red dark:hover:bg-kodo-red',
'focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-blue-600',
actionButtonClass,
'hover:bg-destructive/30 focus-visible:ring-destructive/50',
)}
aria-label={`Supprimer ${selectedCount} piste${selectedCount > 1 ? 's' : ''}`}
>
@ -141,11 +135,7 @@ export function TrackListSelectionActions({
<button
type="button"
onClick={handleMore}
className={cn(
'p-2 rounded-md transition-colors',
'hover:bg-white/5 dark:hover:bg-white/5',
'focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-blue-600',
)}
className={actionButtonClass}
aria-label={`Plus d'options pour ${selectedCount} piste${selectedCount > 1 ? 's' : ''}`}
>
<MoreVertical className="h-5 w-5" aria-hidden="true" />
@ -159,11 +149,7 @@ export function TrackListSelectionActions({
<button
type="button"
onClick={onClearSelection}
className={cn(
'p-2 rounded-md transition-colors',
'hover:bg-white/5 dark:hover:bg-white/5',
'focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-blue-600',
)}
className={actionButtonClass}
aria-label="Désélectionner toutes les pistes"
>
<X className="h-5 w-5" aria-hidden="true" />