Pular para o conteúdo

Cart Drawer

O Cart Drawer é o componente da Olist Ecommerce 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: (v36).

O Cart Drawer, como todos os outros componentes, já vem implementado nos templates da Olist Ecommerce. 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](/guides/criacao-e-estrutura-de-template/pasta-assets#assets--sass).
{% assign suggested_name = 'Compre também:' %}
{% assign suggested_tags = '' %}
{% load_banners position: 'sugestoes-carrinho' %}
{% for banner in loaded_banners %}
{% if banner.subtitle != blank %}
{% assign suggested_name = banner.subtitle %}
{% endif %}
{% if banner.description != blank %}
{% assign suggested_tags = banner.description | strip_html | strip_newlines | strip %}
{% endif %}
{% endfor %}
<div id="component-cart-drawer-root"></div>
{% assign component_version = '35' %}
{% if current_shop.settings contains 'component_version_cart_drawer' %}
{% assign settings_version = current_shop.settings.component_version_cart_drawer %}
{% if settings_version != blank %}
{% assign component_version = settings_version %}
{% endif %}
{% endif %}
<script>
window.cartDrawerSettings = {
script: "{{ 'cart-drawer.v[version].js' | replace: '[version]', component_version | component_path }}",
styles: "{{ 'cart-drawer.v[version].css' | replace: '[version]', component_version | component_path }}",
showFreeShippingBar: true,
showCashBackBar: true,
showBundleItemsDetails: true,
showBundleItemsShortName: true,
suggestedTags: '{{ suggested_tags }}',
titleSuggested: '{{ suggested_name }}',
instance: false
}
</script>

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',
titleSuggested: window.cartDrawerSettings.titleSuggested,
suggestedProductsTags: suggestedTags,
disableShippingCalculation: true,
showFreeShippingBar: settings.showFreeShippingBar,
showCashBackBar: settings.showCashBackBar,
showBundleItemsDetails: settings.showBundleItemsDetails,
showBundleItemsShortName: settings.showBundleItemsShortName
});

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()
}
},

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çõesDefaultObrigatório
displayDetermina como o Cart Drawer é exibido na tela.grid ou listgridNão
anchorDetermina em que posição o Cart Drawer fica na tela.left ou 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
showFreeShippingBarHabilita a barra de carregamento para frete grátis.true ou falsefalseNão
showCashBackBarHabilita a exibição da barra de cashback.true ou falsefalseNão
suggestedProductsTagsHabilita a seção de Sugestão de produtos. Requer informar as categorias (tags). Máximo 6 tags/produtos.Array de string[]Não
sampleSectionTitleDefine a label (título) da seção de amostras grátis.stringEscolha sua amostraNão
sampleNameMaxLengthLimita a quantidade de caracteres dos nomes das amostras.integer20Nã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 +.true ou falsefalseNão
positionSamplesDetermina a posição da lista de amostra grátis.bottom ou topbottomNão
titleCartDefine a label (nome) do título do carrinho.stringCarrinhoNão
titleSuggestedDefine a label (título) do carrossel de sugeridos.stringSugeridosNão
nameItemSuggestedDetermina como as variantes são exibidas: name ou properties.name ou propertiesnameNão
shippingCalculationStartOpenDefine se a seção de frete inicia aberta.true ou falsefalseNão
suggestedCustomizationNameNome da personalização inclusa em produtos personalizados.string*Não
suggestedCustomizationValueValor da personalização inclusa em produtos personalizados.string*Não
suggestedCustomizationPricePreço da personalização para produtos personalizados.float0Não
suggestedCustomizationRedirectDefine se produtos personalizados redirecionam para página interna.true ou falsefalseNão
suggestedCustomizationAddQuantityQuantidade aplicada em produtos personalizados ao adicionar.integer1Não
suggestedCarouselSpaceDefine margem entre slides do carrossel de sugeridos.integer8Não
suggestedCarouselSlidesDefine quantidade de slides por vez no carrossel.float3.5Não
couponInitialOpenDetermina se o campo de cupom deve iniciar aberto.true ou falsefalseNão
continueBuyingLinkURL do link “Continuar comprando”. Se nulo, apenas fecha o carrinho.stringnullNão
showBundleItemsDetailsExibe nomes das variantes selecionadas no bundle.true ou falsetrueNão
showBundleItemsShortNameDefine se exibe nomes das variantes por completo no bundle.true ou falsetrueNão
showOffersDefine se o Popup de Brindes deve ser exibido.booleantrueNão
offerCarouselSpaceMargem entre os produtos do carrossel de Brindes.number8Não
offerCarouselSlidesDesktopProdutos por vez no carrossel de brindes (Desktop).number3Não
offerCarouselSlidesMobileProdutos por vez no carrossel de brindes (Mobile).number1.1Não
nameItemOfferExibição das variantes dos Brindes: name ou properties.name ou propertiesnameNão
offerPopupButtonLabelTexto do botão de abertura do popup de Brindes.stringBrindes disponíveisNão
offerPopupTitleDefine o título do popup de Brindes.stringEscolha entre os brindes disponíveisNão
cartCountSelectorSeletor CSS para atualizar contador do carrinho na página.string[data-cart-count]Não

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.
  • refresh(): atualiza o Cart Drawer (exemplo de uso: window.cartDrawerSettings.instance.refresh())

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;
let suggestedTags = [];
if (settings.suggestedTags) {
suggestedTags = settings.suggestedTags.split(",").map(tag => tag.trim())
}
// Inicia o componente
const componentCartDrawer = new Vnda.Component.CartDrawer({
anchor: 'right',
display: 'list',
startOpen: false,
titleCart: 'Carrinho de compras',
titleSuggested: window.cartDrawerSettings.titleSuggested,
suggestedProductsTags: suggestedTags,
disableShippingCalculation: true,
showFreeShippingBar: settings.showFreeShippingBar,
showCashBackBar: settings.showCashBackBar,
});
// 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;

A partir da versão 27, a faixa de frete grátis é exibida dinamicamente, sem a necessidade de cadastrar um banner. 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.

A partir da versão 32, a faixa de cashback é exibida dinamicamente, sem a necessidade de cadastrar um banner. Para que a faixa seja exibida, o único requisito é ativar a função de bônus no painel da loja. Para mais detalhes sobre o cadastro, ver a documentação Cashback.

A partir da versão 35, será possível apresentar no Cart Drawer um Modal para a seleção de Brindes e um botão para a sua abertura. Os brindes serão apresentados no Modal de acordo com o cadastro de promoções no painel da loja.

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);
});

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