Quantity <mv-quantity>
<mv-number-field>를 얇게 변형한 이커머스 수량 선택기입니다. 최솟값 1, 재고 수량으로 자동 제한, 필드에 연결된 “In stock” / “Only 3 left in stock” / “Out of stock” 캡션, 재고 한도에 도달하면 표시되는 메시지와 흔들림 효과, 재입고 시 다시 활성화되는 비활성 품절 상태를 제공하며, 장바구니 행을 위한 pill 및 subtle 변형도 있습니다.
일시 정지 재생
카테고리 폼 유형 Web Component (<mv-quantity>) 상태 안정 함께 설치되는 항목 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
설치
node scripts/add.mjs quantity --out ./src/marvelous
Marvelous UI MCP 서버를 사용하는 AI 에이전트: install_components({ slugs: ["quantity"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
복사되는 파일(의존성 포함): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, components/number-field/number-field.js, components/number-field/number-field.css, components/quantity/quantity.js, components/quantity/quantity.css.
사용법
기본 마크업입니다. 여기서 시작해 속성, data-*, 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 유형 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 유형 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).