React Counter App

I’ll help you create a Counter App with increment, decrement, and reset functionality with limits. Here’s a complete implementation:

Counter App Component

import React, { useState } from 'react';
import './Counter.css'; // We'll create this for styling

const Counter = () => {
  const [count, setCount] = useState(0);

  // Set your limits here
  const MIN_LIMIT = -10;
  const MAX_LIMIT = 10;

  const increment = () => {
    if (count < MAX_LIMIT) {
      setCount(count + 1);
    }
  };

  const decrement = () => {
    if (count > MIN_LIMIT) {
      setCount(count - 1);
    }
  };

  const reset = () => {
    setCount(0);
  };

  return (
    <div className="counter-container">
      <div className="counter-card">
        <h1>Counter App</h1>

        <div className="counter-value">
          <span className={count > 0 ? 'positive' : count < 0 ? 'negative' : 'zero'}>
            {count}
          </span>
        </div>

        <div className="limit-info">
          <span>Min: {MIN_LIMIT} | Max: {MAX_LIMIT}</span>
        </div>

        <div className="counter-buttons">
          <button 
            onClick={decrement} 
            disabled={count === MIN_LIMIT}
            className="btn btn-decrement"
          >
            -
          </button>

          <button 
            onClick={reset} 
            className="btn btn-reset"
          >
            Reset
          </button>

          <button 
            onClick={increment} 
            disabled={count === MAX_LIMIT}
            className="btn btn-increment"
          >
            +
          </button>
        </div>

        <div className="status">
          {count === MAX_LIMIT && (
            <p className="warning">Maximum limit reached!</p>
          )}
          {count === MIN_LIMIT && (
            <p className="warning">Minimum limit reached!</p>
          )}
        </div>
      </div>
    </div>
  );
};

export default Counter;

CSS Styling (Counter.css)

.counter-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  font-family: 'Arial', sans-serif;
}

.counter-card {
  background: white;
  border-radius: 20px;
  padding: 40px;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
  min-width: 350px;
}

.counter-card h1 {
  color: #333;
  margin-bottom: 30px;
  font-size: 2em;
}

.counter-value {
  margin-bottom: 20px;
}

.counter-value span {
  font-size: 4em;
  font-weight: bold;
  display: inline-block;
  min-width: 120px;
  padding: 20px;
  border-radius: 10px;
  transition: all 0.3s ease;
}

.counter-value .positive {
  color: #4caf50;
  text-shadow: 0 2px 10px rgba(76, 175, 80, 0.3);
}

.counter-value .negative {
  color: #f44336;
  text-shadow: 0 2px 10px rgba(244, 67, 54, 0.3);
}

.counter-value .zero {
  color: #666;
}

.limit-info {
  color: #666;
  font-size: 0.9em;
  margin-bottom: 20px;
  padding: 10px;
  background: #f5f5f5;
  border-radius: 8px;
  display: inline-block;
}

.counter-buttons {
  display: flex;
  gap: 15px;
  justify-content: center;
  margin-bottom: 20px;
}

.btn {
  font-size: 1.5em;
  padding: 10px 20px;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: bold;
}

.btn:active {
  transform: scale(0.95);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn-decrement {
  background-color: #f44336;
  color: white;
}

.btn-decrement:hover:not(:disabled) {
  background-color: #d32f2f;
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(244, 67, 54, 0.3);
}

.btn-reset {
  background-color: #ff9800;
  color: white;
}

.btn-reset:hover {
  background-color: #f57c00;
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(255, 152, 0, 0.3);
}

.btn-increment {
  background-color: #4caf50;
  color: white;
}

.btn-increment:hover:not(:disabled) {
  background-color: #388e3c;
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
}

.status {
  min-height: 50px;
}

.warning {
  color: #ff9800;
  font-size: 0.9em;
  margin-top: 15px;
  animation: fadeIn 0.5s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Responsive design */
@media (max-width: 480px) {
  .counter-card {
    min-width: 280px;
    padding: 30px;
  }

  .counter-value span {
    font-size: 3em;
  }

  .btn {
    font-size: 1.2em;
    padding: 8px 16px;
  }
}

Alternative Version with Customizable Limits

If you want to make the limits dynamic, here’s an enhanced version:

import { useState } from 'react';

const EnhancedCounter = () => {
  const [count, setCount] = useState(0);
  const [minLimit, setMinLimit] = useState(-10);
  const [maxLimit, setMaxLimit] = useState(10);

  const increment = () => {
    if (count < maxLimit) {
      setCount(count + 1);
    }
  };

  const decrement = () => {
    if (count > minLimit) {
      setCount(count - 1);
    }
  };

  const reset = () => {
    setCount(0);
  };

  const handleMinLimitChange = (e) => {
    const newMin = parseInt(e.target.value);
    setMinLimit(newMin);
    if (count < newMin) {
      setCount(newMin);
    }
  };

  const handleMaxLimitChange = (e) => {
    const newMax = parseInt(e.target.value);
    setMaxLimit(newMax);
    if (count > newMax) {
      setCount(newMax);
    }
  };

  return (
    <div style={{
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center',
      minHeight: '100vh',
      background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
    }}>
      <div style={{
        background: 'white',
        borderRadius: '20px',
        padding: '40px',
        textAlign: 'center',
        boxShadow: '0 20px 60px rgba(0,0,0,0.3)',
        minWidth: '350px'
      }}>
        <h1>Enhanced Counter App</h1>

        <div style={{ marginBottom: '20px' }}>
          <div style={{ marginBottom: '15px' }}>
            <label>Min Limit: </label>
            <input
              type="number"
              value={minLimit}
              onChange={handleMinLimitChange}
              style={{ padding: '5px', marginLeft: '10px', borderRadius: '5px' }}
            />
          </div>
          <div style={{ marginBottom: '15px' }}>
            <label>Max Limit: </label>
            <input
              type="number"
              value={maxLimit}
              onChange={handleMaxLimitChange}
              style={{ padding: '5px', marginLeft: '10px', borderRadius: '5px' }}
            />
          </div>
        </div>

        <div style={{ fontSize: '4em', fontWeight: 'bold', margin: '20px 0' }}>
          {count}
        </div>

        <div style={{ display: 'flex', gap: '15px', justifyContent: 'center' }}>
          <button
            onClick={decrement}
            disabled={count === minLimit}
            style={{
              fontSize: '1.5em',
              padding: '10px 20px',
              backgroundColor: '#f44336',
              color: 'white',
              border: 'none',
              borderRadius: '10px',
              cursor: 'pointer'
            }}
          >
            -
          </button>

          <button
            onClick={reset}
            style={{
              fontSize: '1.5em',
              padding: '10px 20px',
              backgroundColor: '#ff9800',
              color: 'white',
              border: 'none',
              borderRadius: '10px',
              cursor: 'pointer'
            }}
          >
            Reset
          </button>

          <button
            onClick={increment}
            disabled={count === maxLimit}
            style={{
              fontSize: '1.5em',
              padding: '10px 20px',
              backgroundColor: '#4caf50',
              color: 'white',
              border: 'none',
              borderRadius: '10px',
              cursor: 'pointer'
            }}
          >
            +
          </button>
        </div>

        {(count === maxLimit || count === minLimit) && (
          <p style={{ color: '#ff9800', marginTop: '20px' }}>
            {count === maxLimit ? 'Maximum' : 'Minimum'} limit reached!
          </p>
        )}
      </div>
    </div>
  );
};

export default EnhancedCounter;

How to Use

  1. Create a new React app (if you don’t have one):
npx create-react-app counter-app
cd counter-app
  1. Replace the default App.js with the Counter component
  2. Add the CSS file (Counter.css) to the same directory
  3. Run the app:
npm start

Features Included:

  • Increment with maximum limit
  • Decrement with minimum limit
  • Reset to zero
  • Visual feedback when limits are reached
  • Disabled buttons when limits are reached
  • Responsive design
  • Animations and hover effects
  • Color-coded numbers (positive/negative/zero)
  • Warning messages when reaching limits

The app is fully functional and ready to use! You can customize the limits by changing the MIN_LIMIT and MAX_LIMIT constants in the code.