Cart Drawer

Como adicionar e gerenciar o componente Cart Drawer na sua loja.

O Cart Drawer é o componente da VNDA que permite a visualização do carrinho de compras na lateral das lojas. A partir deste recurso, os clientes podem visualizar os detalhes de suas compras sem precisar entrar no checkout. Dentre as funcionalidades do carrinho, é possível habilitar a opção de frete grátis, amostras grátis, produtos sugeridos, entre outros. Neste artigo, você encontrará as informações necessárias para implementar o Cart Drawer em sua loja e quais funcionalidades podem ser ativadas.

📘

Demonstração do componente

Visualize como é o componente acessando o Cart Drawer Demo. Recomendamos utilizar a versão mais atualizada do componente: (v30).

Implementação

O Cart Drawer, como todos os outros componentes, já vem implementado nos templates da VNDA. Caso você precise fazer esta implementação manualmente, deve-se primeiro criar um arquivo _cart_drawer.liquid no diretório liquids > partials > common. Este arquivo deve ser chamado no layout.liquid junto com o restante dos elementos do site. Deve-se adicionar o seguinte conteúdo ao arquivo _cart_drawer.liquid para carregar o conteúdo do componente.

📘

Saiba mais sobre a organização dos arquivos citado em assets > sass.

    {% assign free_shipping_value = 00001 %}
    
    {% load_banners position: 'frete-gratis' %}
    {% for banner in loaded_banners %}
    {% if banner.title != blank %}
        {% assign free_shipping_value = banner.subtitle | plus: 0 %}
    {% endif %}
    {% endfor %}

    {% assign cashback_value = 00001 %}

    {% load_banners position: 'barra-cashback' %}
    {% for banner in loaded_banners %}
      {% if banner.subtitle != blank and banner.subtitle != banner.title %}
        {% assign cashback_value = banner.subtitle | plus: 0 %}
      {% endif %}
    {% endfor %}

    <div id="component-cart-drawer-root"></div>

    <script>
    window.cartDrawerSettings = {
        script: "{{ 'cart-drawer.v20.js' | component_path }}",
        styles: "{{ 'cart-drawer.v20.css' | component_path }}",
        freeShippingValue: {{ free_shipping_value }},
      	cashbackValue: {{ cashback_value }},
        instance: false
    }
    </script>

No código acima é importante notar que foi utilizado um banner na posição frete-grátis e outra na posição barra-cashback para fornecer, respectivamente, os dados de frete grátis e de cashback para o componente. Tanto o banner quanto a parâmetro freeShippingValue foram descontinuados a partir da versão 27 do componente. Para mais informações, verificar seção Frete Grátis abaixo.

Além disso, os templates contam com os arquivos cartDrawer.js (assets > javascripts > common) e _cart_drawer.scss (assets > sass > common). O arquivo scss é responsável por adaptar a unidade de medidas "rem" às configurações do projeto, além de adaptar o componente ao estilo da loja.

Já o arquivo cartDrawer.js é responsável por iniciar o componente, atribuir valores aos parâmetros e manipular os seus métodos. Dentro da função setCartDrawer o componente é instanciado e são atribuídos os valores ao seus atributos, conforme o exemplo abaixo.

  const componentCartDrawer = new Vnda.Component.CartDrawer({
    anchor: 'right',
    display: 'list',
    startOpen: false,
    titleCart: 'Carrinho de compras',
    disableShippingCalculation: true,
    freeShipping,
    cashbackValue
  });

Já as outras funções do arquivo cartDrawer.js são responsáveis por lidar com o carregamento do componente e associar os seus métodos a eventos disparados pelo frontend da loja. No exemplo a seguir, a função show utiliza o método open para abrir o componente:

  show: function (callback) {

    const { root } = CartDrawer;

    // No mobile, fecha o menu primeiro
    if (window.mmenu) window.mmenu.close()

    // Instancia o componente, caso ainda não exista
    if (!CartDrawer.settings.instance) CartDrawer.loadComponent();

    // Observa criação da instância inicial, caso não tenha
    if (CartDrawer.settings.instance === false) {
      root.addEventListener('vnda:cart-drawer-loaded', () => {
        CartDrawer.settings.instance.open()
        if (typeof callback === 'function') callback()
      })
    } else {
      // Já possui cart drawer instanciado, retorna abertura
      CartDrawer.settings.instance.open();
      if (typeof callback === 'function') callback()
    }
  },

Parâmetros do Cart Drawer

Os parâmetros são responsáveis por configurar o componente e definir quais funcionalidades serão utilizadas. A tabela abaixo lista os parâmetros disponíveis, define as suas aplicações e apresenta o valores aceitos por cada um deles. Note que os parâmetros que possuem valores padrões estão sinalizados na coluna Default, e as opções de entrada que o parâmetro pode receber estão apresentados na coluna Tipos/Opções de entrada.

ParâmetroDescriçãoTipos/Opções de entradaDefaultObrigatório
displayDetermina como o Cart Drawer é exibido na tela.grid ou listgirdNão
anchorDetermina em que posição o Cart Drawer fica na tela.leftou rightrightNão
startOpenDetermina se ao acessar a loja, o Cart Drawer já é carregado.true ou falsefalseNão
disableShippingCalculationDesabilita o cálculo de frete no Cart Drawer.true ou falsefalseNão
enableSamplesHabilita a exibição de amostras grátis no Cart Drawer .true ou falsefalseNão
freeShippingHabilita a exibição da barra de carregamento para frete grátis (valor restante para conseguir a gratuidade). Descontinuado a partir da versão 27.true ou falsefalseNão
cashbackValueHabilita a barra de carregamento para o pedido gerar cashback. Disponível a partir da versão 29.Valor mínimo do pedido para receber cashback0Não
suggestedProductsTagHabilita a seção de Sugestão de produtos. Ao habilitar, você deve informar qual categoria (tag) de produtos você quer vincular à essa seção.Do tipo string.-Não
sampleSectionTitleDefine a label (título) da seção de amostras grátis.Do tipo stringEscolha sua amostraNão
sampleNameMaxLengthLimita a quantidade de caracteres que os nomes das amostras grátis podem ter.Do tipo integer-Não
showSamplesAddedHabilita a visualização de amostras grátis no Cart Drawer.true ou falsefalseNão
showSamplesAddedListHabilita a visualização de amostras grátis no carrinho.true ou falsefalseNão
showSamplesQtdHabilita os botões de incremento de quantidade - e + no Cart Drawer.true ou falsefalseNão
positionSamplesDetermina a posição da lista de amostra grátis no Cart Drawer.bottom ou topbottomNão
titleCartDefine a label (nome) do título do carrinho.Do tipo stringCarrinhoNão
titleSuggestedDefine a label (título) do carrossel de produtos sugeridos.Do tipo stringSugeridosNão
widthItemSuggestedDetermina o tamanho (percentual) que um produto ocupa dentro do carrossel de produtos sugeridos no Cart Drawer.Preencha com um número natural.25Não
nameItemSuggestedDetermina a forma que variantes de um produto sugerido são apresentadas: nome da variante (name) ou o nome das propriedades (properties).
Saiba mais o que são nomes e propriedades de variante no artigo Como preencher planilha de produtos.
name ou propertiesnameNão
shippingCalculationStartOpenDefine se a seção de cálculo de frete deve iniciar aberta ou não.true OU falsefalseNão
showCashbackControla se o valor do cashback deve ou não ser exibido.trueou falsefalseNão
suggestedCustomizationNameDefine nome da personalização que será inclusa em produtos personalizados ao adicionarDo tipo string-Não
suggestedCustomizationValueDefine valor da personalização que será inclusa em produtos personalizados ao adicionarDo tipo string-Não
suggestedCustomizationPriceDefine preço da personalização que será exibido em produtos personalizadosDo tipo float0Não
suggestedCustomizationRedirectDefine se produtos personalizados vão ou não redirecionar para página interna ao clicartrue ou falsefalseNão
suggestedCustomizationAddQuantityDefine quantidade que será aplicada em produtos personalizados ao adicionarDo tipo integer1Não
suggestedCarouselSpaceDefine margem entre slides do carrossel de sugeridosDo tipo integer8Não
suggestedCarouselSlidesDefine quantidade de slides por vez do carrossel de sugeridosDo tipo float3.5Não

Métodos do Cart Drawer

O Cart Drawer possui três métodos responsáveis pelo controle de abertura e fechamento do componente durante a navegação. Esses métodos podem ser associados a eventos disparados pelo frontend, como a adição de um produto às compras e o click no botão do carrinho.

  • open(): abre o Cart Drawer,
  • close(): fecha o Cart Drawer,
  • toggle(): abre o Cart Drawer se ele estiver fechado e o fecha caso ele esteja aberto.
Exemplo no BasicTemplate

O código seguir contém o componente Cart Drawer.

import { addAsset } from '../components/utilities';

const CartDrawer = {
  root: document.querySelector('#component-cart-drawer-root'),
  buttons: document.querySelectorAll('[data-toggle-cart]'),
  countWrapper: document.querySelector('[data-cart-count]'),
  settings: window.cartDrawerSettings || false,

  setCartDrawer: function () {
    const { settings, root } = CartDrawer;

    if (!root || !settings) return;

    const cashbackValue = settings.cashbackValue > 1 ? settings.cashbackValue : 0;

    // Inicia o componente
    const componentCartDrawer = new Vnda.Component.CartDrawer({
      anchor: 'right',
      display: 'list',
      startOpen: false,
      titleCart: 'Carrinho de compras',
      titleSuggested: window.cartDrawerSettings.titleSuggested,
      suggestedProductsTag: 'sugestoes-carrinho',
      widthItemSuggested: 25,
      disableShippingCalculation: true,
      cashbackValue
    });

    // Renderiza o componente
    componentCartDrawer.render(root);

    // Salva instância para acesso global
    window.cartDrawerSettings.instance = componentCartDrawer;
    CartDrawer.settings = window.cartDrawerSettings;

    // dispara evento de carregamento, escutado por CartDrawer.show()
    root.dispatchEvent(new Event('vnda:cart-drawer-loaded'));
  },

  loadComponent: function () {
    const { settings } = CartDrawer;
    addAsset(settings.script, CartDrawer.setCartDrawer);
    addAsset(settings.styles);
  },

  handleCartButton: function (button) {
    // Evita múltiplos cliques caso o carrinho precisa ser instanciado primeiro
    if (button.classList.contains('-loading')) {
      return;
    }

    // Abre o cart drawer
    button.classList.add('-loading');
    CartDrawer.show(() => {
      button.classList.remove('-loading');
    });
  },

  show: function (callback) {
    const { root } = CartDrawer;

    // No mobile, fecha o menu primeiro
    if (window.mmenu) window.mmenu.close();

    // Instancia o componente, caso ainda não exista
    if (!CartDrawer.settings.instance) CartDrawer.loadComponent();

    // Observa criação da instância inicial, caso não tenha
    if (CartDrawer.settings.instance === false) {
      root.addEventListener('vnda:cart-drawer-loaded', () => {
        CartDrawer.settings.instance.open();
        if (typeof callback === 'function') callback();
      });
    } else {
      // Já possui cart drawer instanciado, retorna abertura
      CartDrawer.settings.instance.open();
      if (typeof callback === 'function') callback();
    }
  },

  getCartItens: async function () {
    try {
      const response = await fetch('/carrinho/itens');
      const itens = await response.json();
      return itens;
    } catch (error) {
      console.error('Erro ao buscar a quantidade de produtos do carrinho');
      console.error(error);
      return 0;
    }
  },

  updateCartCount: async function (_itemsCount = null) {
    let items = _itemsCount;
    if (_itemsCount == null) items = await CartDrawer.getCartItens();

    this.countWrapper.innerHTML = items;
  },

  init: function () {
    const _this = this;
    const { buttons } = _this;

    // Atualiza o contador de itens do carrinho
    _this.updateCartCount();

    if (buttons.length > 0)
      buttons.forEach((button) => {
        button.addEventListener('click', () => {
          _this.handleCartButton(button);
        });
      });
  },
};

export default CartDrawer;

Frete Grátis

A partir da versão 27, a faixa de frete grátis é exibida dinamicamente, sem a necessidade de cadastrar um banner ou de passar parâmetros para o componente. Para que a faixa seja exibida, o único requisito é o cadastro de uma promoção no carrinho, com 100% de desconto no frete. Para mais detalhes sobre o cadastro, ver a documentação Frete Grátis.

Eventos

A partir da versão 26, o cart_drawer dispara eventos toda vez que: o carrinho for aberto, o carrinho for fechado, produto for adicionado, produto for excluído, quantidade de algum produto for alterada, cupom for adicionado, cupom for removido e frete for calculado. O trecho abaixo indica os eventos:

window.addEventListener('vnda:cart-drawer-added-item', (event) => {
  console.log('Adicionado ->', event.detail);
});

window.addEventListener('vnda:cart-drawer-deleted-item', (event) => {
  console.log('Removido ->', event.detail);
});

window.addEventListener('vnda:cart-drawer-updated-item', (event) => {
  console.log('Atualizado ->', event.detail);
});

window.addEventListener('vnda:cart-drawer-opened', (event) => {
  console.log('Carrinho aberto');
});

window.addEventListener('vnda:cart-drawer-closed', (event) => {
  console.log('Carrinho fechado');
});

window.addEventListener('vnda:cart-drawer-coupon-added', (event) => {
  console.log('Cupom adicionado ->', event.detail);
});

window.addEventListener('vnda:cart-drawer-coupon-removed', (event) => {
  console.log('Cupom removido ->', event.detail);
});

window.addEventListener('vnda:cart-drawer-shipping-calculate', (event) => {
  console.log('Frete calculado ->', event.detail);
});

Exemplo de implementação

Confira como o Cart Drawer é usado no nosso Template1 acessando os arquivos: