style(ViewToggle): elevate visual fidelity to premium standards
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c18771df09
commit
0e9bcb8e99
2 changed files with 44 additions and 19 deletions
|
|
@ -6,6 +6,14 @@ const meta = {
|
|||
title: 'Components/Features/Tracks/ViewToggle',
|
||||
component: ViewToggle,
|
||||
tags: ['autodocs'],
|
||||
parameters: { layout: 'centered' },
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="p-4 bg-background border border-border rounded-[var(--radius-xl)] min-h-layout-story">
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
argTypes: {
|
||||
onChange: { action: 'changed' },
|
||||
value: {
|
||||
|
|
@ -31,9 +39,26 @@ export const Default: Story = {
|
|||
};
|
||||
|
||||
export const IconOnly: Story = {
|
||||
render: (args) => {
|
||||
const [{ value }, updateArgs] = useArgs();
|
||||
return <ViewToggle {...args} value={value} onChange={(newValue) => updateArgs({ value: newValue })} />;
|
||||
},
|
||||
args: {
|
||||
value: 'grid' as const,
|
||||
showLabels: false,
|
||||
onChange: () => { },
|
||||
}
|
||||
};
|
||||
|
||||
/** Both states to validate tokens and hover/active. */
|
||||
export const VisualStressTest: Story = {
|
||||
render: (args) => {
|
||||
const [{ value }, updateArgs] = useArgs();
|
||||
return <ViewToggle {...args} value={value} onChange={(newValue) => updateArgs({ value: newValue })} />;
|
||||
},
|
||||
args: {
|
||||
value: 'list' as const,
|
||||
showLabels: true,
|
||||
onChange: () => { },
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,18 +56,26 @@ export function ViewToggle({
|
|||
setIsTransitioning(true);
|
||||
onChange(mode);
|
||||
|
||||
// Réinitialiser l'état de transition après un court délai
|
||||
// Réinitialiser l'état de transition après la durée de transition (aligné sur --duration-normal)
|
||||
setTimeout(() => {
|
||||
setIsTransitioning(false);
|
||||
}, 300);
|
||||
}, 250);
|
||||
};
|
||||
|
||||
const buttonBase = [
|
||||
'flex items-center gap-2 px-4 py-1.5 rounded-[var(--radius-md)]',
|
||||
'text-sm font-medium tracking-tight',
|
||||
'transition-[color,background-color,transform,opacity] duration-[var(--duration-normal)]',
|
||||
'hover:bg-muted/70 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
|
||||
'disabled:opacity-50 disabled:cursor-not-allowed active:scale-95',
|
||||
].join(' ');
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'inline-flex items-center gap-1 p-1 rounded-lg',
|
||||
'bg-kodo-void dark:bg-kodo-graphite border border-kodo-steel dark:border-kodo-steel',
|
||||
'transition-all duration-300',
|
||||
'inline-flex items-center gap-1 p-1 rounded-[var(--radius-lg)]',
|
||||
'bg-muted/40 border border-border',
|
||||
'transition-[opacity,box-shadow] duration-[var(--duration-normal)]',
|
||||
isTransitioning && 'opacity-75',
|
||||
className,
|
||||
)}
|
||||
|
|
@ -78,14 +86,10 @@ export function ViewToggle({
|
|||
type="button"
|
||||
onClick={() => handleModeChange('list')}
|
||||
className={cn(
|
||||
'flex items-center gap-2 px-4 py-1.5 rounded-md',
|
||||
'text-sm font-medium transition-all duration-200',
|
||||
'hover:bg-kodo-slate dark:hover:bg-kodo-steel',
|
||||
'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
|
||||
'disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
buttonBase,
|
||||
value === 'list'
|
||||
? 'bg-white dark:bg-kodo-steel text-kodo-cyan dark:text-kodo-cyan shadow-sm'
|
||||
: 'text-kodo-content-dim dark:text-kodo-content-dim',
|
||||
? 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90'
|
||||
: 'text-muted-foreground/90',
|
||||
)}
|
||||
aria-label="Vue liste"
|
||||
aria-pressed={value === 'list'}
|
||||
|
|
@ -101,14 +105,10 @@ export function ViewToggle({
|
|||
type="button"
|
||||
onClick={() => handleModeChange('grid')}
|
||||
className={cn(
|
||||
'flex items-center gap-2 px-4 py-1.5 rounded-md',
|
||||
'text-sm font-medium transition-all duration-200',
|
||||
'hover:bg-kodo-slate dark:hover:bg-kodo-steel',
|
||||
'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
|
||||
'disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
buttonBase,
|
||||
value === 'grid'
|
||||
? 'bg-white dark:bg-kodo-steel text-kodo-cyan dark:text-kodo-cyan shadow-sm'
|
||||
: 'text-kodo-content-dim dark:text-kodo-content-dim',
|
||||
? 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90'
|
||||
: 'text-muted-foreground/90',
|
||||
)}
|
||||
aria-label="Vue grille"
|
||||
aria-pressed={value === 'grid'}
|
||||
|
|
|
|||
Loading…
Reference in a new issue