ComponentsCommerce
QuantitySelector
Numeric stepper input for selecting product quantities with increment and decrement controls
The QuantitySelector component provides a compact numeric input with increment and decrement buttons for selecting quantities. It enforces minimum and maximum bounds and supports direct keyboard input.
Import
import { QuantitySelector } from '@nim-ui/components';Basic Usage
Code
<QuantitySelector value={1} onChange={(qty) => setQuantity(qty)} />With Min and Max
Set bounds on the allowed quantity range. Buttons are disabled at the limits.
Code
<QuantitySelector
value={5}
min={1}
max={10}
onChange={(qty) => setQuantity(qty)}
/>Sizes
Three size options match the sizing conventions of other form components.
Small ·
smMedium ·
mdLarge ·
lgCode
<QuantitySelector value={1} size="sm" onChange={(qty) => setQuantity(qty)} />
<QuantitySelector value={1} size="md" onChange={(qty) => setQuantity(qty)} />
<QuantitySelector value={1} size="lg" onChange={(qty) => setQuantity(qty)} />Props
| Name | Type | Default | Description |
|---|---|---|---|
value* | number | - | Current quantity value |
min | number | 1 | Minimum allowed value |
max | number | 99 | Maximum allowed value |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the selector |
onChange | (value: number) => void | - | Callback fired when the quantity changes |
className | string | - | Additional CSS classes to apply |
Usage Examples
Product Detail Page
function ProductDetail({ product }: { product: Product }) {
const [quantity, setQuantity] = useState(1);
const handleAddToCart = () => {
addToCart(product.id, quantity);
};
return (
<div className="space-y-4">
<h1>{product.name}</h1>
<p>{product.price}</p>
<div className="flex items-center gap-4">
<QuantitySelector
value={quantity}
min={1}
max={product.stock}
onChange={setQuantity}
/>
<Button onClick={handleAddToCart}>Add to Cart</Button>
</div>
</div>
);
}Cart Line Item with Quantity
function CartLineItem({ item, onUpdate, onRemove }: CartLineItemProps) {
return (
<div className="flex items-center gap-4 py-4 border-b">
<img
src={item.image}
alt={item.name}
className="h-16 w-16 rounded-md object-cover"
/>
<div className="flex-1">
<p className="font-medium">{item.name}</p>
<p className="text-sm text-neutral-500">{item.price}</p>
</div>
<QuantitySelector
value={item.quantity}
min={1}
max={item.maxStock}
size="sm"
onChange={(qty) => onUpdate(item.id, qty)}
/>
<button onClick={() => onRemove(item.id)} className="text-red-500">
Remove
</button>
</div>
);
}Bulk Order Form
function BulkOrderRow({ product }: { product: Product }) {
const [quantity, setQuantity] = useState(0);
return (
<div className="flex items-center justify-between py-2">
<span>{product.name}</span>
<div className="flex items-center gap-4">
<QuantitySelector
value={quantity}
min={0}
max={999}
size="sm"
onChange={setQuantity}
/>
<span className="w-24 text-right font-medium">
${(product.unitPrice * quantity).toFixed(2)}
</span>
</div>
</div>
);
}Related Components
- CartItem - Shopping cart line item with built-in quantity display
- PriceTag - Price display with discounts
- ProductCard - Product display card