Aromática Store — Checkout UI Extension

shopify-polaris-checkout-extensions · aromatica-store.myshopify.com

Shopify Polaris 2026-01
aromatica-checkout-ui/src/Checkout.tsx TSX
/**
 * Aromática Store — Checkout UI Extension
 * Target 1: purchase.checkout.cart-line-list.render-after
 * Target 2: purchase.checkout.cart-line-item.render-after
 * version: 2026-01
 */

import "@shopify/ui-extensions/preact";
import { render } from "preact";
import { useState } from "preact/hooks";
import {
  useApi, useApplyAttributeChange, useCost,
} from "@shopify/ui-extensions/checkout";

// ── 1. Banner progreso + mensaje regalo ──
function FreeShippingAndGift() {
  const cost = useCost();
  const applyAttribute = useApplyAttributeChange();
  const [giftMessage, setGiftMessage] = useState("");
  const [submitted, setSubmitted] = useState(false);

  const FREE_THRESHOLD = 40;
  const subtotal = parseFloat(cost?.subtotalAmount?.amount ?? "0");
  const remaining = Math.max(0, FREE_THRESHOLD - subtotal);
  const progress = Math.min(1, subtotal / FREE_THRESHOLD);

  async function handleSubmit(e: Event) {
    e.preventDefault();
    await applyAttribute({
      key: "gift_message", value: giftMessage
    });
    setSubmitted(true);
  }

  return (
    <s-box padding="base">
      <s-banner tone="info" heading="Envío gratis a 40 €">
        <s-stack direction="block" gap="tight">
          <s-text>Faltan {remaining.toFixed(2)} € más.</s-text>
          <s-progress
            value={progress}
            max={1}
            tone="auto"
          ></s-progress>
        </s-stack>
      </s-banner>
      <s-section heading="¿Es un regalo?">
        <s-form onsubmit={handleSubmit}>
          <s-text-area
            label="Mensaje de regalo"
            name="gift_message"
            rows={3}
          ></s-text-area>
          <s-button type="submit" variant="secondary">
            Guardar mensaje
          </s-button>
        </s-form>
      </s-section>
    </s-box>
  );
}

// ── 2. Badge artesanal por línea ──
function ArtisanalBadge() {
  return (
    <s-box padding-block="tight">
      <s-stack direction="inline" gap="tight">
        <s-badge tone="success">Artesanal</s-badge>
        <s-text tone="subdued">
          Elaborado a mano en España
        </s-text>
      </s-stack>
    </s-box>
  );
}

render(
  "purchase.checkout.cart-line-list.render-after",
  () => <FreeShippingAndGift />
);
render(
  "purchase.checkout.cart-line-item.render-after",
  () => <ArtisanalBadge />
);
Vista previa del checkout
aromatica-store.myshopify.com/checkout
📦 Resumen del pedido
🌹
Aceite Esencial de Rosa de Damasco
10 ml · Natural 100%
E
Artesanal Elaborado a mano en España
18,50 €
🌿
Crema Hidratante con Aloe Vera
50 ml · Sin parabenos
E
Artesanal Elaborado a mano en España
9,00 €
↓ EXTENSION: cart-line-list.render-after

ℹ️ Envío gratis a partir de 40 €

Añade 12,50 € más para conseguir envío gratis.

0 € 27,50 € ahora 40 €
🎁 ¿Es un regalo?

🎯 Extension Targets

purchase.checkout.cart-line-list.render-after
Banner de progreso envío gratis + campo mensaje regalo
purchase.checkout.cart-line-item.render-after
Badge "Artesanal · Elaborado a mano en España" por producto
Componentes Polaris usados
<s-banner> <s-progress> <s-badge> <s-section> <s-form> <s-text-area> <s-button> <s-stack> <s-box>
SCAFFOLD CLI COMMAND
$ shopify app generate extension \
--template checkout_ui \
--name aromatica-checkout-ui