Chats: How to add a Close button to the chat bubble

Want to let users close the Chat bubble when needed? We’ve got a solution!

Just add this code to the Custom CSS field on the Appearance tab of your widget’s settings:

.es-hidden {
	display: none;
}

.global-styles, 
.es-floating-button-close-button {
	position: absolute;
	top: -25px;
	right: -25px;
	
	border: none;
	outline: none;
	
	background-color: rgba(0,0,0,.7);
	color: white;
	
	z-index: 99;
	
	display: flex;
	align-items: center;
	justify-content: center;
	
	border-radius: 50px;
	width: 30px;
	height: 30px;
	
	font-weight: bold;
	
	opacity: .7;
}

.global-styles, 
.es-floating-button-close-button > svg {
	fill: white;
	width: 10px;
	height: 10px;
}

.global-styles, 
.es-floating-button-close-button:hover {
	opacity: 1;
	cursor: pointer;
}

And this script should be placed in the Custom JS field on the Settings tab:

// Bubble close button code

const crossIcon = `<svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.06645 11.8966L3.8917 17.0714C3.11017 17.8529 1.84307 17.8529 1.06154 17.0714V17.0714C0.280008 16.2899 0.280009 15.0228 1.06154 14.2412L6.23629 9.06648L1.06154 3.89173C0.280008 3.1102 0.280008 1.8431 1.06154 1.06157V1.06157C1.84307 0.280039 3.11017 0.28004 3.8917 1.06157L9.06645 6.23632L14.2412 1.06157C15.0227 0.280038 16.2898 0.280039 17.0714 1.06157V1.06157C17.8529 1.8431 17.8529 3.1102 17.0714 3.89173L11.8966 9.06648L17.0714 14.2412C17.8529 15.0228 17.8529 16.2899 17.0714 17.0714V17.0714C16.2898 17.8529 15.0227 17.8529 14.2412 17.0714L9.06645 11.8966Z"/>
</svg>
`;

const LISTEN_TYPES = {
	one: {
		select: (selector, root) => root.querySelector(selector),
		validate: (node) => !!node,
	},
	all: {
		select: (selector, root) => root.querySelectorAll(selector),
		validate: (node) => node?.length > 0,
	},
};

function listenStep(args) {
	args.node = args.select(args.selector, args.root);

	if (!args.validate(args.node)) {
		args.step++;
		if (args.step < args.limit)
			setTimeout(() => {
				listenStep(args);
			}, args.delay);
		else args.reject();
	} else {
		args.resolve(args.node);
	}
}

async function asyncListenFor(selector, type = 'one', customArgs = {}) {
	const args = {
		root: document,
		node: undefined,
		selector,
		delay: 100,
		limit: 50,
		step: 0,
		select: LISTEN_TYPES[type].select,
		validate: LISTEN_TYPES[type].validate,
		...customArgs,
	};

	if (type === 'one' || type === 'all') {
		return new Promise((resolve, reject) => {
			listenStep({ ...args, resolve, reject });
		});
	}
}

const floatingButtonContainerSelector =
	"[class*='FloatingButton__FloatingButtonContainer-sc']";

function createCloseButton(onClick) {
	const closeButton = document.createElement('button');
	closeButton.classList.add('es-floating-button-close-button');
	closeButton.innerHTML = crossIcon;
	closeButton.onclick = onClick;

	return closeButton;
}

function hideElem(elem) {
	elem.classList.add('es-hidden');
}

function addCloseButton(elem) {
	const closeButton = createCloseButton(() => {
		hideElem(elem);
	});

	elem.appendChild(closeButton);
}

setTimeout(() => {
	asyncListenFor(floatingButtonContainerSelector).then(
		(floatingButtonContainer) => {
			addCloseButton(floatingButtonContainer);
		}
	);
}, 100);

//End of bubble close button code


Note: Custom JS doesn’t function in the preview mode, so you can check the result right on your website or through the Share Link


Guys, was this solution helpful? Let us know in the comments :slightly_smiling_face:

2 Likes