317 lines
7.7 KiB
TypeScript

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from 'avanza-ui';
// Icon components for examples
const MicIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" />
<path d="M19 10v2a7 7 0 0 1-14 0v-2" />
<line x1="12" y1="19" x2="12" y2="23" />
<line x1="8" y1="23" x2="16" y2="23" />
</svg>
);
const VideoIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<polygon points="23 7 16 12 23 17 23 7" />
<rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
</svg>
);
const PlusIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<line x1="12" y1="5" x2="12" y2="19" />
<line x1="5" y1="12" x2="19" y2="12" />
</svg>
);
const meta = {
title: 'Components/Button',
component: Button,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'danger', 'success', 'ghost'],
},
size: {
control: 'select',
options: ['sm', 'md', 'lg'],
},
loading: {
control: 'boolean',
},
disabled: {
control: 'boolean',
},
fullWidth: {
control: 'boolean',
},
iconOnly: {
control: 'boolean',
},
},
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
// ===== VARIANTES =====
export const Primary: Story = {
args: {
variant: 'primary',
children: 'Primary Button',
},
};
export const Secondary: Story = {
args: {
variant: 'secondary',
children: 'Secondary Button',
},
};
export const Danger: Story = {
args: {
variant: 'danger',
children: 'Danger Button',
},
};
export const Success: Story = {
args: {
variant: 'success',
children: 'Success Button',
},
};
export const Ghost: Story = {
args: {
variant: 'ghost',
children: 'Ghost Button',
},
};
// ===== TAMAÑOS =====
export const Small: Story = {
args: {
size: 'sm',
children: 'Small Button',
},
};
export const Medium: Story = {
args: {
size: 'md',
children: 'Medium Button',
},
};
export const Large: Story = {
args: {
size: 'lg',
children: 'Large Button',
},
};
// ===== CON ÍCONOS =====
export const WithLeftIcon: Story = {
args: {
variant: 'primary',
leftIcon: <MicIcon />,
children: 'With Left Icon',
},
};
export const WithRightIcon: Story = {
args: {
variant: 'secondary',
rightIcon: <VideoIcon />,
children: 'With Right Icon',
},
};
export const IconOnly: Story = {
args: {
variant: 'secondary',
iconOnly: true,
children: <MicIcon />,
},
};
// ===== ESTADOS =====
export const Loading: Story = {
args: {
variant: 'primary',
loading: true,
children: 'Loading...',
},
};
export const Disabled: Story = {
args: {
variant: 'primary',
disabled: true,
children: 'Disabled',
},
};
export const FullWidth: Story = {
args: {
variant: 'primary',
fullWidth: true,
children: 'Full Width Button',
},
parameters: {
layout: 'padded',
},
};
// ===== COMBINACIONES (ESTILO STREAMYARD) =====
export const MicrophoneButton: Story = {
name: 'Microphone (StreamYard Style)',
args: {
variant: 'secondary',
iconOnly: true,
size: 'lg',
children: <MicIcon />,
},
};
export const CameraButton: Story = {
name: 'Camera (StreamYard Style)',
args: {
variant: 'secondary',
iconOnly: true,
size: 'lg',
children: <VideoIcon />,
},
};
export const AddGuestButton: Story = {
name: 'Add Guest (StreamYard Style)',
args: {
variant: 'secondary',
leftIcon: <PlusIcon />,
children: 'Agregar invitados',
},
};
export const StartRecording: Story = {
name: 'Start Recording (StreamYard Style)',
args: {
variant: 'danger',
children: 'Grabar',
},
};
export const LeaveStudio: Story = {
name: 'Leave Studio (StreamYard Style)',
args: {
variant: 'danger',
children: 'Salir del estudio',
},
};
// ===== PLAYGROUND =====
export const Playground: Story = {
args: {
variant: 'primary',
size: 'md',
children: 'Playground',
},
};
// ===== GRUPOS =====
export const AllVariants: Story = {
name: 'All Variants',
render: () => (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', alignItems: 'flex-start' }}>
<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="danger">Danger</Button>
<Button variant="success">Success</Button>
<Button variant="ghost">Ghost</Button>
</div>
</div>
),
};
export const AllSizes: Story = {
name: 'All Sizes',
render: () => (
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
</div>
),
};
export const StreamYardControlBar: Story = {
name: 'StreamYard-style Control Bar',
render: () => (
<div
style={{
display: 'flex',
gap: '8px',
padding: '16px',
backgroundColor: 'var(--studio-bg-secondary)',
borderRadius: 'var(--studio-radius-lg)',
alignItems: 'center',
justifyContent: 'space-between',
minWidth: '600px',
}}
>
<div style={{ display: 'flex', gap: '8px' }}>
<Button variant="secondary" iconOnly size="lg">
<MicIcon />
</Button>
<Button variant="secondary" iconOnly size="lg">
<VideoIcon />
</Button>
<Button variant="secondary" iconOnly size="lg">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<rect x="3" y="3" width="18" height="18" rx="2" />
<path d="M9 3v18M15 3v18" />
</svg>
</Button>
<Button variant="secondary" leftIcon={<PlusIcon />}>
Agregar invitados
</Button>
<Button variant="secondary" iconOnly>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="3" />
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" />
</svg>
</Button>
</div>
<div style={{ display: 'flex', gap: '8px' }}>
<Button variant="danger">Salir del estudio</Button>
<Button variant="ghost" iconOnly>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="10" />
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
<line x1="12" y1="17" x2="12.01" y2="17" />
</svg>
</Button>
</div>
</div>
),
parameters: {
layout: 'centered',
},
};