tpmjs/packages/ui/src/Textarea/variants.ts
Ajax Davis ded939e643 feat(ui): add comprehensive form component library with playground showcase
Implemented 8 production-ready form components with full accessibility:

Components Added:
- Textarea: Multi-line text input with character counter
- Checkbox: Custom styled with indeterminate state support
- Radio & RadioGroup: Context-based radio button groups
- Switch: Toggle with animated thumb and loading state
- Select: Native select with custom styling and option groups
- Slider: Range input with marks, value display, cross-browser support
- FormField: Wrapper component with label, error, and helper text

Features:
- Full accessibility (ARIA attributes, semantic HTML)
- Controlled/uncontrolled patterns via useControlled hook
- Dark mode support with semantic tokens
- Design tokens and shared variant system
- Comprehensive test coverage (856 tests passing)
- Form-specific design tokens (formTokens)
- Shared form variant base classes (formVariants)

Playground Updates:
- Added comprehensive Forms section showcasing all components
- Interactive examples with state management
- Complete form composition example
- All components fully functional and themed

Test Coverage:
- 10+ describe blocks per component
- All edge cases covered
- Accessibility testing
- Cross-browser compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 01:56:54 +10:00

77 lines
1.6 KiB
TypeScript

import { createVariants } from '../system/variants';
/**
* Textarea variant definitions
* Uses custom variant system for type-safe class composition
*/
export const textareaVariants = createVariants({
base: [
// Layout
'flex w-full',
// Typography
'font-sans',
// Borders & Radius
'rounded-md border',
// Background
'bg-background',
// Transitions
'transition-base',
// Focus
'focus-ring',
// Placeholder
'placeholder:text-foreground-tertiary',
// Disabled state
'disabled:cursor-not-allowed disabled:opacity-50',
].join(' '),
variants: {
state: {
default: [
'border-border text-foreground',
'hover:border-border-strong',
'focus:border-primary',
].join(' '),
error: [
'border-error text-foreground',
'hover:border-error',
'focus:border-error',
'focus:ring-error/20',
].join(' '),
success: [
'border-success text-foreground',
'hover:border-success',
'focus:border-success',
'focus:ring-success/20',
].join(' '),
},
size: {
sm: 'min-h-20 px-3 py-2 text-sm',
md: 'min-h-32 px-3 py-2.5 text-base',
lg: 'min-h-40 px-4 py-3 text-lg',
},
fullWidth: {
true: 'w-full',
false: 'w-auto',
},
resize: {
none: 'resize-none',
vertical: 'resize-y',
horizontal: 'resize-x',
both: 'resize',
},
},
compoundVariants: [],
defaultVariants: {
state: 'default',
size: 'md',
fullWidth: 'true',
resize: 'vertical',
},
});