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: (v29).

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

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: