2
React + MotionChamps

Sélecteur de quantité

Des boutons moins et plus autour d’un chiffre qui glisse vers le haut ou le bas à chaque changement.

Réglages

2
12

Code

import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { Minus, Plus } from "lucide-react";

interface AnimatedQuantityProps {
  value?: number;
  defaultValue?: number;
  max?: number;
  onChange?: (value: number) => void;
}

export default function AnimatedQuantity({
  value,
  defaultValue = 2,
  max = 12,
  onChange,
}: AnimatedQuantityProps) {
  const [internal, setInternal] = useState(defaultValue);
  const n = value ?? internal;

  const set = (next: number) => {
    if (value === undefined) setInternal(next);
    onChange?.(next);
  };

  return (
    <div className="flex items-center gap-5 rounded-full bg-white p-2 text-[#1d1d1f] shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)] dark:bg-[#1c1c1e] dark:text-[#f5f5f7]">
      <button
        type="button"
        aria-label="Diminuer"
        onClick={() => set(Math.max(0, n - 1))}
        className="grid h-9 w-9 place-items-center rounded-full bg-black/5 dark:bg-white/10"
      >
        <Minus className="h-4 w-4" />
      </button>
      <AnimatePresence mode="popLayout" initial={false}>
        <motion.strong
          key={n}
          initial={{ y: 12, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          exit={{ y: -12, opacity: 0 }}
          className="w-7 text-center"
        >
          {n}
        </motion.strong>
      </AnimatePresence>
      <button
        type="button"
        aria-label="Ajouter"
        onClick={() => set(Math.min(max, n + 1))}
        className="grid h-9 w-9 place-items-center rounded-full bg-black/5 dark:bg-white/10"
      >
        <Plus className="h-4 w-4" />
      </button>
    </div>
  );
}

Prompt pour l’IA

Collez-le dans ChatGPT, Claude ou Cursor : le bloc sera adapté à votre projet avec ces réglages, même sans React.

Plus dans Champs

Où l’utiliser

Un sélecteur de quantité apparaît partout où l’on commande : le panier d’une boutique en ligne, les billets d’un concert, les portions d’une application de livraison ou les chambres d’un hôtel. Le chiffre qui glisse rend chaque appui visible, et personne n’ajoute trois bouteilles de vin par erreur. Ça paraît anodin, mais c’est l’un des éléments qu’on touche le plus.

Fixez un maximum qui a du sens, comme votre stock réel ou le nombre de billets par commande. Par défaut, il s’arrête à zéro ; si zéro n’a pas de sens, dans une ligne de panier par exemple, commencez plutôt à un.