diff --git a/docs/ui-components/Button.md b/docs/ui-components/Button.md new file mode 100644 index 0000000..424099c --- /dev/null +++ b/docs/ui-components/Button.md @@ -0,0 +1,198 @@ +# Button Component + +The Button component is a versatile and reusable UI element that follows our design system guidelines. It supports multiple variants, sizes, and states while maintaining accessibility standards. + +## Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| children | ReactNode | - | The content to be displayed inside the button | +| variant | 'primary' \| 'secondary' \| 'outline' | 'primary' | The variant style of the button | +| onClick | () => void | - | Optional click handler | +| disabled | boolean | false | Whether the button is disabled | +| size | 'small' \| 'medium' \| 'large' | 'medium' | The size of the button | +| className | string | '' | Additional CSS classes | + +## Usage Examples + +```tsx +import Button from '@/components/Button'; + +// Primary Button (Default) + + +// Secondary Button + + +// Outline Button (Disabled) + + +// Small Primary Button with Custom Class + +``` + +## Style Guide + +The Button component uses Tailwind CSS for styling and follows these design principles: + +### Colors +- Primary: Green-based theme (matches PlantPal's nature-focused brand) +- Secondary: Gray-scale for less prominent actions +- Outline: Bordered version for tertiary actions + +### Variants + +1. **Primary** (Default) + - High emphasis + - Used for main actions + - Filled background with white text + - Example: "Save Changes", "Submit", "Next" + +2. **Secondary** + - Medium emphasis + - Used for secondary actions + - Light background with dark text + - Example: "Cancel", "Back", "See More" + +3. **Outline** + - Low emphasis + - Used for tertiary actions + - Bordered with no fill + - Example: "Learn More", "Skip" + +### Sizes + +1. **Small** (`small`) + - Compact size: 24px height + - Used in tight spaces or dense UIs + - Font size: 14px (sm) + +2. **Medium** (`medium`) - Default + - Standard size: 32px height + - Used for most button instances + - Font size: 16px (base) + +3. **Large** (`large`) + - Prominent size: 40px height + - Used for main call-to-action buttons + - Font size: 18px (lg) + +## Theming + +The Button component uses these Tailwind CSS classes which can be customized in your `tailwind.config.js`: + +```js +// tailwind.config.js +module.exports = { + theme: { + extend: { + colors: { + green: { + 50: '#f0fdf4', + // ... other shades + 600: '#16a34a', + 700: '#15803d', + }, + gray: { + 200: '#e5e7eb', + 300: '#d1d5db', + 800: '#1f2937', + } + } + } + } +} +``` + +## Accessibility + +The Button component follows WCAG 2.1 guidelines: + +### Keyboard Navigation +- Fully focusable with keyboard (Tab key) +- Activatable with Enter or Space key +- Visual focus indicator with ring outline + +### Screen Readers +- Uses semantic `); + expect(getByText('Click me')).toBeInTheDocument(); + }); + + // Click Handler Test + it('handles click events', () => { + const handleClick = jest.fn(); + const { getByRole } = render( + + ); + fireEvent.click(getByRole('button')); + expect(handleClick).toHaveBeenCalled(); + }); + + // Disabled State Test + it('respects disabled state', () => { + const handleClick = jest.fn(); + const { getByRole } = render( + + ); + const button = getByRole('button'); + fireEvent.click(button); + expect(handleClick).not.toHaveBeenCalled(); + expect(button).toBeDisabled(); + }); + + // Style Tests + it('applies variant styles correctly', () => { + const { container } = render( + + ); + expect(container.firstChild).toHaveClass('bg-green-600'); + }); + + it('applies size styles correctly', () => { + const { container } = render( + + ); + expect(container.firstChild).toHaveClass('px-6 py-3 text-lg'); + }); +}); +``` \ No newline at end of file diff --git a/docs/ui-components/README.md b/docs/ui-components/README.md new file mode 100644 index 0000000..c6f9b79 --- /dev/null +++ b/docs/ui-components/README.md @@ -0,0 +1,108 @@ +# PlantPal UI Component Documentation + +Welcome to PlantPal's UI Component Documentation. This guide provides comprehensive information about our component library, including usage examples, styling guidelines, and best practices. + +## Table of Contents + +1. [Components](#components) +2. [Design System](#design-system) +3. [Accessibility](#accessibility) +4. [Testing](#testing) +5. [Contributing](#contributing) + +## Components + +Our component library includes the following components: + +- [Button](./Button.md) - A versatile button component with multiple variants + +## Design System + +Our components follow these core principles: + +### Colors +- **Primary**: Green-based theme reflecting our nature-focused brand +- **Secondary**: Neutral grays for supporting elements +- **Accent**: Strategic use of complementary colors + +### Typography +- **Font Family**: System-native fonts for optimal performance +- **Scale**: Consistent sizing using Tailwind's scale +- **Weights**: Regular (400), Medium (500), Bold (700) + +### Spacing +- Based on a 4px grid system +- Consistent spacing using Tailwind's scale +- Responsive spacing utilities + +### Elevation +- Subtle shadows for interactive elements +- Clear visual hierarchy +- Consistent z-index scale + +## Accessibility + +All components are built with accessibility in mind: + +### Standards +- WCAG 2.1 AA compliance +- Semantic HTML +- ARIA attributes where necessary +- Keyboard navigation support + +### Testing +- Regular accessibility audits +- Screen reader testing +- Keyboard navigation testing +- Color contrast verification + +## Testing + +Our testing strategy includes: + +### Unit Tests +- Component rendering +- Props validation +- Event handling +- State management + +### Integration Tests +- Component interactions +- Form submissions +- API interactions + +### E2E Tests +- User flows +- Critical paths +- Edge cases + +## Contributing + +### Adding New Components + +1. Create component in `src/frontend/components` +2. Add documentation in `docs/ui-components` +3. Include: + - Props documentation + - Usage examples + - Style guidelines + - Accessibility considerations + - Test cases + +### Documentation Structure + +Each component's documentation should include: + +1. Overview +2. Props API +3. Usage Examples +4. Style Guide +5. Accessibility Notes +6. Testing Guide + +### Review Process + +1. Code review +2. Documentation review +3. Accessibility review +4. Performance review \ No newline at end of file diff --git a/src/frontend/components/Button.tsx b/src/frontend/components/Button.tsx new file mode 100644 index 0000000..e700ff7 --- /dev/null +++ b/src/frontend/components/Button.tsx @@ -0,0 +1,72 @@ +import React from 'react'; + +interface ButtonProps { + /** + * The content to be displayed inside the button + */ + children: React.ReactNode; + + /** + * The variant style of the button + */ + variant?: 'primary' | 'secondary' | 'outline'; + + /** + * Optional click handler + */ + onClick?: () => void; + + /** + * Whether the button is disabled + */ + disabled?: boolean; + + /** + * The size of the button + */ + size?: 'small' | 'medium' | 'large'; + + /** + * Additional CSS classes + */ + className?: string; +} + +/** + * Primary UI component for user interaction + */ +export const Button: React.FC = ({ + children, + variant = 'primary', + onClick, + disabled = false, + size = 'medium', + className = '', +}) => { + const baseStyles = 'rounded-md font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2'; + + const variantStyles = { + primary: 'bg-green-600 text-white hover:bg-green-700 focus:ring-green-500', + secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300 focus:ring-gray-500', + outline: 'border-2 border-green-600 text-green-600 hover:bg-green-50 focus:ring-green-500' + }; + + const sizeStyles = { + small: 'px-3 py-1.5 text-sm', + medium: 'px-4 py-2 text-base', + large: 'px-6 py-3 text-lg' + }; + + return ( + + ); +}; + +export default Button; \ No newline at end of file