Buy Box <mv-buy-box>

Bloc d’achat de page produit : marque, titre, note, prix (qui suit la variante choisie), paiement en 3 fois, couleurs et tailles (celles en rupture barrées, « Me prévenir du retour en stock »), quantité plafonnée au stock de la taille, bouton d’ajout au panier avec chargement puis confirmation, estimation de livraison calculée et compte à rebours avant l’heure limite d’expédition, arguments de réassurance et accordéon de détails ; se synchronise avec une galerie.

CatégorieBlocs
TypeBloc (section prête à l’emploi) (<mv-buy-box>)
Statutstable
Installe aussiaccordion, button, like-button, number-field, price, quantity, rating, swatch
Keywordspdp, fiche produit, product page, buy box, add to cart, variant, e-commerce, block, delivery

When to use

  • A product page needs the purchase column: price per variant, colors and sizes, quantity and add to cart
  • Sold-out sizes, stock-capped quantity and a back-in-stock request must be handled on the page
  • Shoppers should see a delivery estimate and a same-day shipping cut-off countdown next to the button

Avoid when

  • Products are shown as tiles in a listing grid with quick add → use Product Card instead
  • Only a formatted price with a compare-at discount is needed → use Price instead

Installation

node scripts/add.mjs buy-box --out ./src/marvelous

Agent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["buy-box"], 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/form.js, core/motion.js, components/buy-box/buy-box.js, components/buy-box/buy-box.css, components/accordion/accordion.css, components/accordion/accordion.js, components/button/button.css, components/like-button/like-button.js, components/like-button/like-button.css, components/number-field/number-field.js, components/number-field/number-field.css, components/price/price.js, components/price/price.css, components/quantity/quantity.js, components/quantity/quantity.css, components/rating/rating.js, components/rating/rating.css, components/swatch/swatch.css, components/swatch/swatch.js.

Utilisation

Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :

<div id="bb-demo" style="container-type:inline-size;width:min(100%,68rem);margin-inline:auto">
  <style>
    #bb-demo .pdp { display:grid; gap:2rem; align-items:start }
    @container (width > 48rem) { #bb-demo .pdp { grid-template-columns: minmax(0,1.15fr) minmax(0,1fr); gap:3rem } #bb-demo .pdp > mv-product-gallery { position:sticky; top:1.5rem } }
  </style>
  <div class="pdp">
    <mv-product-gallery id="bb-demo-gallery" label="Merino Crewneck Sweater" thumbs="start">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.8 0.05 75)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E" alt="Sand sweater, front view">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Crect x='0' y='0' width='400' height='500' fill='white' fill-opacity='.18'/%3E%3Cpath d='M200 58 q0-16 12-16 q12 0 12 12 q0 10-12 14 L200 78' fill='none' stroke='oklch(0.55 0.02 60)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M200 78 L96 124 L304 124 Z' fill='none' stroke='oklch(0.6 0.08 60)' stroke-width='8' stroke-linejoin='round'/%3E%3Cg transform='translate(40 30) scale(.8)'%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.8 0.05 75)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.2'/%3E%3Cpath d='M133 372 Q200 380 267 372 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3C/g%3E%3Cpath d='M300 470 c-4-60 6-110 30-150 c-2 50-10 100-12 150z' fill='oklch(0.55 0.08 150)' opacity='.55'/%3E%3Cpath d='M318 470 c8-52 30-86 58-104 c-14 38-30 72-40 104z' fill='oklch(0.5 0.08 150)' opacity='.5'/%3E%3Crect x='292' y='452' width='64' height='48' rx='6' fill='oklch(0.72 0.06 55)' opacity='.9'/%3E%3C/svg%3E" alt="The sweater on a hanger">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='44' height='36' patternUnits='userSpaceOnUse'%3E%3Cpath d='M2 2l20 30 20-30' fill='none' stroke='black' stroke-opacity='.14' stroke-width='7' stroke-linecap='round'/%3E%3Cpath d='M2 2l20 30 20-30' fill='none' stroke='white' stroke-opacity='.12' stroke-width='2' transform='translate(0 -3)'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='400' height='500' fill='oklch(0.8 0.05 75)'/%3E%3Crect width='400' height='500' fill='url(%23k)'/%3E%3Crect width='400' height='500' fill='url(%23sh)'/%3E%3Cg transform='rotate(-6 250 330)'%3E%3Crect x='190' y='300' width='150' height='74' rx='6' fill='oklch(0.97 0.01 90)'/%3E%3Crect x='190' y='300' width='150' height='74' rx='6' fill='none' stroke='black' stroke-opacity='.12'/%3E%3Ctext x='265' y='333' text-anchor='middle' font-family='Georgia,serif' font-size='20' letter-spacing='3' fill='oklch(0.3 0.02 60)'%3EMERINO%3C/text%3E%3Ctext x='265' y='356' text-anchor='middle' font-family='Arial,sans-serif' font-size='9' letter-spacing='1.2' fill='oklch(0.45 0.02 60)'%3E100%25 WOOL %C2%B7 18.5 %C2%B5m%3C/text%3E%3C/g%3E%3C/svg%3E" alt="Knit detail">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 145)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.03 150)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='392' rx='150' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='oklch(0.7 0.06 150)' style='filter:brightness(.9)'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='url(%23k)'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='url(%23sh)'/%3E%3Cpath d='M104 356h192' stroke='black' stroke-opacity='.12' stroke-width='3'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='oklch(0.7 0.06 150)'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='url(%23k)'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='url(%23sh)'/%3E%3Cpath d='M160 190 Q200 232 240 190' fill='black' fill-opacity='.14'/%3E%3Cpath d='M166 190 Q200 222 234 190' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Cpath d='M118 268h164' stroke='black' stroke-opacity='.1' stroke-width='3'/%3E%3C/svg%3E" alt="Sage colorway, folded">
      <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.012 250)'/%3E%3Cstop offset='1' stop-color='oklch(0.87 0.025 255)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.34 0.05 262)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E" alt="Midnight blue colorway">
    </mv-product-gallery>

    <mv-buy-box data-id="pull-merinos" gallery="#bb-demo-gallery" delivery-days="2-4" cutoff="14">
      <form class="mv-buy-box" novalidate>
        <header class="mv-buy-box-header">
          <p class="mv-buy-box-eyebrow">Lumen Studio · Fall collection</p>
          <h2 class="mv-buy-box-title">Extra-Fine Merino Crewneck Sweater</h2>
          <mv-rating readonly value="4.6" count="128" href="#reviews" show-value data-size="sm"></mv-rating>
        </header>

        <div class="mv-buy-box-pricing">
          <mv-price value="89" compare-at="112" note="tax incl." data-size="lg" data-keep-compare></mv-price>
          <p class="mv-buy-box-installments" data-role="installments" data-count="3">or 3 × $29.67 interest-free</p>
        </div>

        <p class="mv-buy-box-description">Knit in Portugal from 18.5-micron merino wool: soft against the skin and naturally temperature-regulating. Straight fit, slightly dropped shoulders.</p>

        <div class="mv-buy-box-options">
          <mv-swatch>
            <fieldset class="mv-swatch" data-type="color" data-check>
              <legend class="mv-swatch-legend">Color <span class="mv-swatch-value"></span></legend>
              <div class="mv-swatch-options">
                <label class="mv-swatch-option" data-image="0" data-price="89" style="--mv-swatch-color:oklch(0.8 0.05 75)"><input type="radio" name="color" value="sand" checked><span class="mv-swatch-label">Sand</span></label>
                <label class="mv-swatch-option" data-image="4" data-price="99" data-compare-at="119" data-tone="dark" style="--mv-swatch-color:oklch(0.34 0.05 262)"><input type="radio" name="color" value="night"><span class="mv-swatch-label">Midnight blue</span></label>
                <label class="mv-swatch-option" data-image="3" data-price="89" style="--mv-swatch-color:oklch(0.7 0.06 150)"><input type="radio" name="color" value="sage"><span class="mv-swatch-label">Sage</span></label>
                <label class="mv-swatch-option" data-unavailable data-tone="dark" style="--mv-swatch-color:oklch(0.58 0.13 38)"><input type="radio" name="color" value="brick"><span class="mv-swatch-label">Brick</span></label>
              </div>
            </fieldset>
          </mv-swatch>

          <mv-swatch data-message="Choose your size.">
            <fieldset class="mv-swatch" data-type="size">
              <legend class="mv-swatch-legend">Size <span class="mv-swatch-value" data-placeholder="select one"></span></legend>
              <a class="mv-swatch-aside" href="#guide">Size guide</a>
              <div class="mv-swatch-options">
                <label class="mv-swatch-option"><input type="radio" name="size" value="XS" disabled><span class="mv-swatch-label">XS</span></label>
                <label class="mv-swatch-option" data-stock="3"><input type="radio" name="size" value="S" required><span class="mv-swatch-label">S</span></label>
                <label class="mv-swatch-option" data-stock="24"><input type="radio" name="size" value="M"><span class="mv-swatch-label">M</span></label>
                <label class="mv-swatch-option" data-stock="12"><input type="radio" name="size" value="L"><span class="mv-swatch-label">L</span></label>
                <label class="mv-swatch-option" data-unavailable><input type="radio" name="size" value="XL"><span class="mv-swatch-label">XL</span></label>
              </div>
            </fieldset>
          </mv-swatch>
        </div>

        <div class="mv-buy-box-actions">
          <mv-quantity name="quantity" value="1" max="10" data-default-stock="24" caption="none"></mv-quantity>
          <button type="submit" class="mv-button mv-buy-box-buy" data-buy data-sold-out-text="Notify me when it's back">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 7h12l1 13H5L6 7Z"/><path d="M9 7a3 3 0 0 1 6 0"/></svg>
            <span data-role="label">Add to cart</span>
          </button>
          <mv-like label="Add to favorites"></mv-like>
        </div>
        <div class="mv-buy-box-added" hidden>
          <span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg><span data-role="message"></span></span>
          <a href="#cart">View cart</a>
        </div>

        <ul class="mv-buy-box-perks">
          <li>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 7h11v9H3zM14 10h4l3 3v3h-7"/><circle cx="7" cy="17.5" r="1.5"/><circle cx="17" cy="17.5" r="1.5"/></svg>
            <span><strong data-role="eta">Delivered in 2-4 business days</strong><small data-role="cutoff" hidden></small></span>
          </li>
          <li>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 12a8 8 0 1 1-2.3-5.6M20 4v4h-4"/></svg>
            <span><strong>Free returns within 30 days</strong><small data-role="free-shipping" data-threshold="60">Free shipping over $60</small></span>
          </li>
          <li>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 21s-7-4.4-7-11a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 6.6-7 11-7 11Z"/></svg>
            <span><strong>Free in-store pickup</strong><small>Available in New York and London</small></span>
          </li>
        </ul>

        <mv-accordion type="single">
          <div class="mv-accordion">
            <details class="mv-accordion-item">
              <summary>Materials and care</summary>
              <div class="mv-accordion-content"><p>100% extra-fine merino wool, RWS certified. Hand wash or use a wool cycle at 86 °F (30 °C), dry flat. Do not tumble dry.</p></div>
            </details>
            <details class="mv-accordion-item">
              <summary>Size and fit</summary>
              <div class="mv-accordion-content"><p>Straight fit, true to size. Our model is 5′10″ and wears a size M. Back length: 26.8″ in size M.</p></div>
            </details>
            <details class="mv-accordion-item">
              <summary>Shipping and returns</summary>
              <div class="mv-accordion-content"><p>Standard shipping $4.90 (free over $60), express $9.90. Free returns within 30 days from your account.</p></div>
            </details>
          </div>
        </mv-accordion>
      </form>
    </mv-buy-box>
  </div>
</div>
<script type="module">
  document.getElementById("bb-demo").addEventListener("mv-add", (e) => {
    // In an app: send e.detail to the cart API, then update the header badge.
    console.info("mv-add", e.detail);
  });
</script>

API

Attributes

NameTypeDefaultDescription
gallerystringSelector of an <mv-product-gallery>: the chosen option (data-image) shows its image there.
delivery-daysstring2-4Lead time in business days (Sundays excluded) for [data-role=eta]: “Arrives Thu, Sep 25 to Sat, Sep 27”.
cutoffnumberSame-day shipping cut-off hour: [data-role=cutoff] shows “Order within 2 hr 14 min…”.
currency / localestringUSD / en-USFormatting.
added-textstringAdded to cartButton label after adding.
busynumber650Duration of the loading state (ms); 0 with reduced motion.
data-idstringProduct id passed along in mv-add.
data-price / data-compare-at / data-stock / data-imagenumberOn a .mv-swatch-option: variant price, compare-at price, stock and image.
data-stickybooleanOn .mv-buy-box: stays visible while scrolling.

Properties

NameTypeDescription
selectionobjectForm values (color, size, quantity…).

Methods

NameDescription
add()Validates, shows loading then confirmation, emits mv-add; resolves true when added.

Events

NameDescription
mv-addCancelable; detail: { id, title, price, quantity, selection }.
mv-notifySold-out variant; detail: { id, selection }.

Content structure

NameDescription
form.mv-buy-boxContainer; parts: -header, -eyebrow, -title, -pricing, -installments ([data-role=installments] recomputed, data-count = number of installments), -description, -options, -actions, -buy ([data-buy], label in [data-role=label]), -added ([data-role=message]), -perks ([data-role=eta|cutoff|free-shipping]).

CSS classes

NameDescription
mv-buy-box / -header / -eyebrow / -title / -subtitle / -pricing / -installments / -description / -options / -actions / -buy / -added / -perksStructure (container query on .mv-buy-box).

CSS variables

NameDefaultDescription
--mv-buy-box-radiusvar(--mv-radius-md)Buy button radius.
--mv-buy-box-topvar(--mv-space-6)Top offset in sticky mode.

Accessibility

Native form (Enter submits). Required size not chosen: group marked invalid, role=alert message and focus on the first size. Loading via aria-busy on the button, confirmation announced (role=status) and shown with a “View cart” link. Sold-out variant: button label changes to “Notify me when it's back”, quantity disabled. Inner components (rating, price, swatches, quantity, accordion) keep their own accessibility.

Cette page a été traduite par IA. Signaler un problème de traduction