← Components/Inputs & Forms

NumberInput

numberinput-1779394025949.tsx
'use client'
import { useState } from 'react'

export default function NumberInput({ label = 'Quantity', min = 0, max = 100, step = 1, defaultValue = 1 }) {
  const [value, setValue] = useState(defaultValue)
  const dec = () => setValue(v => Math.max(min, v - step))
  const inc = () => setValue(v => Math.min(max, v + step))
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:'6px' }}>
      {label && <label style={{ fontSize:'13px', fontWeight:600, color:'#374151' }}>{label}</label>}
      <div style={{ display:'flex', alignItems:'center', border:'2px solid #e2e8f0', borderRadius:'10px', overflow:'hidden', width:'fit-content' }}>
        <button onClick={dec} disabled={value <= min} style={{
          width:'40px', height:'42px', border:'none', background:'#f8fafc',
          fontSize:'20px', cursor:value<=min?'not-allowed':'pointer', color:value<=min?'#cbd5e1':'#374151',
          transition:'background 0.15s',
        }}>−</button>
        <input
          type="number" value={value}
          onChange={e => { const v = Number(e.target.value); if (v >= min && v <= max) setValue(v) }}
          style={{
            width:'64px', textAlign:'center', border:'none', outline:'none',
            fontSize:'16px', fontWeight:700, color:'#1e293b', padding:'10px 0',
            background:'transparent',
          }}
        />
        <button onClick={inc} disabled={value >= max} style={{
          width:'40px', height:'42px', border:'none', background:'#f8fafc',
          fontSize:'20px', cursor:value>=max?'not-allowed':'pointer', color:value>=max?'#cbd5e1':'#374151',
        }}>+</button>
      </div>
      <div style={{ fontSize:'11px', color:'#94a3b8' }}>Min: {min} / Max: {max}</div>
    </div>
  )
}

Component info

CategoryInputs & Forms
Frameworkreact
TierFREE
Views0
Copies0

About

Number input with increment/decrement, min/max and step support

More from Inputs & Forms

'use client';

import { useState, useEffect } from 'react';

interface Tag {
  id: number;
  name: string;
}

const TagInput = () => {
  const [tags, setTags] = useState<Tag[]>([]);
  const [inputValue, setInputValue] = useState('');
  const [suggest
TagInput
Inputs & Forms
'use client';

import React, { useState } from 'react';

interface File {
  name: string;
  size: number;
  progress: number;
}

const FileUpload = () => {
  const [dragOver, setDragOver] = useState(false);
  const [files, setFiles] = useState<File[]
FileUpload
Inputs & Forms
import React, { useState } from 'react';

const OTPInput = () => {
  const [otp, setOtp] = useState(new Array(6).fill(''));
  const [activeIndex, setActiveIndex] = useState(0);

  const handleChange = (e, index) => {
    const value = e.target.value;
OTPInput
Inputs & Forms
'use client';

import React, { useState } from 'react';

interface RangeSliderProps {
  min: number;
  max: number;
  defaultValue: [number, number];
}

const RangeSlider: React.FC<RangeSliderProps> = ({ min, max, defaultValue }) => {
  const [minVal
RangeSlider
Inputs & Forms