JSFiddle - React, Tailwind, and code Playground

by Martin_ATS

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css">
	<div id="header">Header</div>
	<div id="menucontainer" class="container-fluid align-items-center p-2">
		<div class="d-flex">
			<div class="dropdown position-static">
				<div class="btn btn-primary dropdown-toggle me-2" data-bs-toggle="dropdown" data-bs-display="dynamic" data-bs-container="body" data-bs-auto-close="outside" id="country_trigger">
					Select countries
				</div>
				<div id="country" class="dropdown-menu shadow-4-strong p-2" aria-labelledby="country_trigger">
					<div class="d-flex flex-column flex-wrap justify-content-start align-items-stretch">
						<div class="itemwrapper">

							<div class="dropdown-header">
								North America
							</div>

							<div class="colitem">
								<div class="form-check" data-id="US" title="US">
									<input class="form-check-input" type="checkbox" value="" id="countryList-1">
									<label class="form-check-label" for="countryList-1">
										United States
									</label>
								</div>
							</div>

							<div class="colitem">
								<div class="form-check" data-id="CA" title="CA">
									<input class="form-check-input" type="checkbox" value="" id="countryList-2">
									<label class="form-check-label" for="countryList-2">
										Canada
									</label>
								</div>
							</div>

							<div class="dropdown-header">
								Central America
							</div>

							<div class="colitem disabled">
								<div class="form-check disabled menuitemdisabled" data-id="CR" data-pk="-1">
									<input class="form-check-input" type="checkbox" value="" id="countryList-3" disabled="">
									<label class="form-check-label" for="countryList-3">
										Costa...

CSS

body {
			padding: 30px;
		}

		.dropdown-header {
			color: cadetblue;
			font-weight: 600;
			break-after: avoid;
		}

		.ddcols .itemgroup {
			margin-bottom: 16px;
		}

		#header {
			width: 100%;
			font-size: 1.5rem;
			text-align: center;
			background-color: lightgray;
			line-height: 3rem;
			padding: 15px;
		}

		#menucontainer {
			width: 100%;
			background-color: cornflowerblue;
		}

		#menucontainer .dropdown-menu {
			width: calc(100vw - 60px);
			margin-right: 30px;
		}

		.itemwrapper {
			column-width: 150px;
			column-gap: 1.5em;
			column-fill: balance;
			max-height: 50vh;
			overflow-x: auto;
			padding: 0.5em;
			margin-bottom: 0.5em;
			background-color: paleturquoise;
		}

			.itemwrapper .dropdown-header {
				padding-left: 0;
			}

		.colitem {
			break-inside: avoid;
			overflow: hidden;
			line-height: 1.2em;
			margin-bottom: 5px;
		}

			.colitem .form-check .form-check-input {
				margin-top: 1px;
			}

JavaScript

$(() => {
			var autoHideCt = 0;

			function hideDropdown($ddelem, method) {
				$ddelem.removeData('autohide');
				if (method === 1) {
					var dd = bootstrap.Dropdown.getInstance($ddelem.get(0));
					console.log('auto-hide dropdown method 1...');
					dd.hide();
				} else if (method === 2) {
					console.log('auto-hide dropdown method 2...');
					$ddelem.dropdown('hide');
				} else {
					throw `Unknown auto-hide method ${method}`;
				}
			}

			$('.dropdown')
				.on('show.bs.dropdown', (evt) => {
					var dd = bootstrap.Dropdown.getInstance(evt.relatedTarget);
					console.log(`show.bs.dropdown ${evt.relatedTarget.id}`);
				})
				.on('shown.bs.dropdown', (evt) => {
					var dd = bootstrap.Dropdown.getInstance(evt.relatedTarget);
					console.log(`shown.bs.dropdown ${evt.relatedTarget.id}`);

					var $ddelem = $(evt.relatedTarget);
					// auto-hide after 5 seconds
					$ddelem.data('autohide', window.setTimeout(() => { hideDropdown($ddelem, autoHideCt++ % 2 + 1); }, 5000));
				})
				.on('hide.bs.dropdown', (evt) => {
					var $ddelem = $(evt.relatedTarget);
					console.log(`hide.bs.dropdown ${$ddelem.attr('id')}`);
					var tmr = $ddelem.data('autohide');
					if (tmr) {
						window.clearTimeout(tmr);
						$ddelem.removeData('autohide');
					}
				})
				.on('hidden.bs.dropdown', (evt) => {
					console.log(`hidden.bs.dropdown ${evt.relatedTarget.id}`);
				})

		});