The Prop Consistency Problem
Without Consistency
// Every component is different
<Button disabled size="sm" />
<Input isDisabled size="small" />
<Select isDisabled={true} size="s" />
<Badge inactive size={1} /> With Buoy Enforcing
// Predictable everywhere
<Button isDisabled size="sm" />
<Input isDisabled size="sm" />
<Select isDisabled size="sm" />
<Badge isDisabled size="sm" /> See it in action
buoy-cli
$
âš“ Analyzing prop patterns...
âš Found 4 prop inconsistencies
Boolean naming:
Button.tsx uses disabled
Input.tsx uses isDisabled
→ Inconsistent across 8 components
Size variants:
Button.tsx: size="sm" | "md" | "lg"
Badge.tsx: size="small" | "medium" | "large"
→ Use consistent size naming
Common Inconsistencies We Catch
Boolean Props
Problems
- ✗ disabled vs isDisabled
- ✗ loading vs isLoading
- ✗ open vs isOpen
Solution
✓ Pick one pattern and use it everywhere
Size Variants
Problems
- ✗ sm/md/lg vs small/medium/large
- ✗ xs/s/m/l/xl vs 1/2/3/4/5
Solution
✓ Standardize on sm/md/lg across all components
Color Props
Problems
- ✗ color vs variant vs intent
- ✗ primary/secondary vs blue/gray
Solution
✓ Use variant for semantic, color for literal
Event Handlers
Problems
- ✗ onClick vs handleClick
- ✗ onChange vs onValueChange
Solution
✓ Always use on* prefix for callbacks
Define Your Prop Standards
buoy.config.mjs
export default {
props: {
// Boolean props must use is* prefix
booleans: {
pattern: 'is*',
exceptions: ['disabled', 'required', 'checked'], // HTML native
},
// Standard size values
sizes: ['xs', 'sm', 'md', 'lg', 'xl'],
// Standard variant values
variants: ['primary', 'secondary', 'ghost', 'danger'],
// Event handler naming
handlers: {
pattern: 'on*',
// onChange, onClick, onSubmit, etc.
},
// Required props for specific components
required: {
'Button': ['children'],
'Input': ['name', 'label'],
'Image': ['alt'],
}
}
}