Quantity <mv-quantity>
Sélecteur de quantité e-commerce, une variante légère de <mv-number-field> : minimum 1, plafonné automatiquement au stock, une légende « In stock » / « Only 3 left in stock » / « Out of stock » liée au champ, un message et une secousse en atteignant la limite de stock, un état épuisé désactivé qui se réactive au réassort ; variantes pill et subtle pour les lignes de panier.
Catégorie Formulaires Type Web Component (<mv-quantity>) Statut stable Installe aussi number-field Keywords quantity, quantité, stepper, stock, out-of-stock, cart, e-commerce, form-associated
When to use
A product page or cart line needs a quantity picker capped at available stock Shoppers should see In stock, Only 3 left or Out of stock next to the quantity A compact pill or muted variant must fit inside cart rows
Avoid when
The number is not a purchase quantity, like a price, percentage or measurement → use Number Field instead The whole purchase block with variants, price and add to cart is needed → use Buy Box instead
Obtenir Quantity. Inclus dans toutes les offres : le Pro pack contient les 317 composants, avec la CLI et le serveur MCP utilisés ci-dessous.
Voir les offres
Installation
node scripts/add.mjs quantity --out ./src/marvelous
Agent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["quantity"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Fichiers copiés (dépendances comprises) : tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, components/quantity/quantity.js, components/quantity/quantity.css, components/number-field/number-field.js, components/number-field/number-field.css.
Utilisation
Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :
<div id="quantity-demo" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,14rem),1fr));gap:1.25rem;width:min(100%,50rem);margin-inline:auto;font-size:.875rem">
<style>
#quantity-demo .panel { display:grid; gap:.875rem; align-content:start; padding:1.25rem; border:1px solid var(--mv-border); border-radius:var(--mv-radius-xl); background:var(--mv-surface) }
#quantity-demo .cap { margin:0; font-size:.75rem; font-weight:500; color:var(--mv-fg-muted) }
</style>
<form class="panel" id="quantity-demo-form" onsubmit="event.preventDefault()">
<p class="cap">In stock</p>
<mv-quantity label="Quantity" name="quantity" value="1" stock="24"></mv-quantity>
</form>
<div class="panel">
<p class="cap">Low stock · capped</p>
<mv-quantity label="Quantity" name="quantity-2" value="2" stock="3" data-variant="pill"></mv-quantity>
</div>
<div class="panel">
<p class="cap">Out of stock</p>
<mv-quantity label="Quantity" name="quantity-3" value="1" stock="0"></mv-quantity>
<button class="mv-button" data-variant="outline" data-size="sm" id="quantity-demo-restock" style="justify-self:start">Restock (+12)</button>
</div>
<div class="panel">
<p class="cap">Cart line (compact)</p>
<div style="display:flex;align-items:center;justify-content:space-between;gap:.75rem">
<span style="font-weight:500">Stoneware mug</span>
<mv-quantity value="2" max="10" data-size="sm" data-variant="ghost" caption="none" aria-label="Quantity, Stoneware mug"></mv-quantity>
</div>
<div style="display:flex;align-items:center;justify-content:space-between;gap:.75rem">
<span style="font-weight:500">Fig candle</span>
<mv-quantity value="1" max="10" data-size="sm" data-variant="ghost" caption="none" aria-label="Quantity, Fig candle"></mv-quantity>
</div>
</div>
</div>
<script type="module">
const root = document.getElementById("quantity-demo");
root.querySelector("#quantity-demo-restock").addEventListener("click", (e) => {
const q = root.querySelector('mv-quantity[name="quantity-3"]');
q.stock = (q.stock ?? 0) + 12;
e.currentTarget.disabled = true;
});
</script>
API
Attributes
Name Type Default Description value / name / labelnumber / string Same as <mv-number-field> (submits an integer value). minnumber 1Minimum quantity. maxnumber Commercial cap (e.g. 10 per order); combined with stock, the smaller one wins. stocknumber Available stock: caps the value and drives the caption; 0 = out of stock (disabled). low-stocknumber 5Threshold for the “Only n left in stock” caption. captionauto | none | text autoAutomatic caption, none, or free text. data-sizesm | md Height (lg by default, sized to match an “Add to cart” button). data-variantpill | ghost Rounded pill, or muted background without a border. disabled / readonly / requiredboolean Form states.
Properties
Name Type Description valuenumber | null Quantity. stocknumber Stock (assignable: restock). inStockboolean Read-only.
Methods
Name Description stepUp(n) / stepDown(n) / focus()Inherited from <mv-number-field>.
Events
Name Description mv-changedetail: { value, formatted } (inherited).
CSS classes
Name Description mv-quantity-captionStock caption; data-tone = success | warning | danger. data-stockOn the host: none | in | low | out.
CSS variables
Name Default Description --mv-quantity-width8.25remWidth.
Accessibility
Inherits the APG Spinbutton pattern from <mv-number-field> (arrows, Page↑/↓, Home/End, “Decrease” / “Increase” buttons outside the tab order). Default name “Quantity”. The stock caption is linked via aria-describedby; the “Maximum quantity” message is announced (aria-live polite) when trying to exceed the stock. When out of stock, the field is disabled and empty (dash).