Component
Filter Menu
Data filtering dropdown with checkboxes, status indicators, categories, count badges, and date range picker.
- Component
- Tailwind
- HTML
- MIT
Preview
Live component
9:41 100%
devsnips.dev/library/tailwind/components/dropdowns/filter-menu/ fluid · no fixed width 100%
Install
Add to your project
npx devsnips add Tailwind/Components/Dropdowns/filter-menu Tailwind/Components/Dropdowns/filter-menu <!-- Filter Menu -->
<div class="relative inline-block">
<button
id="filter-button"
class="inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors"
onclick="toggleDropdown('filter-menu')"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"></path>
</svg>
<span>Filters</span>
<span id="filter-count" class="hidden px-1.5 py-0.5 text-xs font-medium text-white bg-blue-600 rounded-full">0</span>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</button>
<div
id="filter-menu"
class="hidden absolute left-0 z-20 mt-2 w-80 bg-white rounded-xl shadow-xl border border-gray-200 overflow-hidden"
>
<div class="px-4 py-3 border-b border-gray-100 flex items-center justify-between">
<h3 class="font-semibold text-gray-900">Filters</h3>
<button class="text-xs font-medium text-blue-600 hover:text-blue-700" onclick="clearFilters()">Clear all</button>
</div>
<!-- Status Filter -->
<div class="p-4 border-b border-gray-100">
<h4 class="text-sm font-medium text-gray-700 mb-3">Status</h4>
<div class="space-y-2">
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="status" data-value="active" onchange="updateFilters()">
<span class="flex items-center gap-2 text-sm text-gray-600 group-hover:text-gray-900">
<span class="w-2 h-2 bg-emerald-500 rounded-full"></span>
Active
</span>
<span class="ml-auto text-xs text-gray-400">(124)</span>
</label>
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="status" data-value="pending" onchange="updateFilters()">
<span class="flex items-center gap-2 text-sm text-gray-600 group-hover:text-gray-900">
<span class="w-2 h-2 bg-amber-500 rounded-full"></span>
Pending
</span>
<span class="ml-auto text-xs text-gray-400">(38)</span>
</label>
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="status" data-value="inactive" onchange="updateFilters()">
<span class="flex items-center gap-2 text-sm text-gray-600 group-hover:text-gray-900">
<span class="w-2 h-2 bg-gray-400 rounded-full"></span>
Inactive
</span>
<span class="ml-auto text-xs text-gray-400">(12)</span>
</label>
</div>
</div>
<!-- Category Filter -->
<div class="p-4 border-b border-gray-100">
<h4 class="text-sm font-medium text-gray-700 mb-3">Category</h4>
<div class="space-y-2">
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="category" data-value="design" onchange="updateFilters()">
<span class="text-sm text-gray-600 group-hover:text-gray-900">Design</span>
<span class="ml-auto text-xs text-gray-400">(56)</span>
</label>
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="category" data-value="development" onchange="updateFilters()">
<span class="text-sm text-gray-600 group-hover:text-gray-900">Development</span>
<span class="ml-auto text-xs text-gray-400">(89)</span>
</label>
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="category" data-value="marketing" onchange="updateFilters()">
<span class="text-sm text-gray-600 group-hover:text-gray-900">Marketing</span>
<span class="ml-auto text-xs text-gray-400">(34)</span>
</label>
<label class="flex items-center gap-3 cursor-pointer group">
<input type="checkbox" class="filter-checkbox w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" data-filter="category" data-value="sales" onchange="updateFilters()">
<span class="text-sm text-gray-600 group-hover:text-gray-900">Sales</span>
<span class="ml-auto text-xs text-gray-400">(45)</span>
</label>
</div>
</div>
<!-- Date Range Filter -->
<div class="p-4">
<h4 class="text-sm font-medium text-gray-700 mb-3">Date Range</h4>
<div class="grid grid-cols-2 gap-2">
<input type="date" class="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="From">
<input type="date" class="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="To">
</div>
</div>
<!-- Footer -->
<div class="px-4 py-3 bg-gray-50 border-t border-gray-100 flex items-center justify-between">
<span id="filter-summary" class="text-xs text-gray-500">No filters applied</span>
<button class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 transition-colors" onclick="applyFilters()">
Apply Filters
</button>
</div>
</div>
</div>
<script>
function toggleDropdown(id) {
document.getElementById(id).classList.toggle('hidden');
}
function updateFilters() {
const checked = document.querySelectorAll('.filter-checkbox:checked');
const countEl = document.getElementById('filter-count');
const summaryEl = document.getElementById('filter-summary');
if (checked.length > 0) {
countEl.textContent = checked.length;
countEl.classList.remove('hidden');
summaryEl.textContent = `${checked.length} filter${checked.length > 1 ? 's' : ''} applied`;
} else {
countEl.classList.add('hidden');
summaryEl.textContent = 'No filters applied';
}
}
function clearFilters() {
document.querySelectorAll('.filter-checkbox').forEach(cb => cb.checked = false);
updateFilters();
}
function applyFilters() {
toggleDropdown('filter-menu');
}
document.addEventListener('click', function(event) {
const container = document.querySelector('.relative.inline-block');
if (!container.contains(event.target)) {
document.getElementById('filter-menu').classList.add('hidden');
}
});
</script> # Filter Menu
Filter options dropdown.
## Preview
Open `preview.html` for a standalone demonstration.
## Features
- Filter choices in a menu
## Usage
```bash
npx devsnips add Tailwind/Components/Dropdowns/filter-menu
```
Copy from `code.html`.
## Customization
- Option and trigger styles
## Accessibility
- Selected state should be exposed accessibly
## Dependencies
- Tailwind CSS; JS as present
## File Structure
- `code.html` · `preview.html` · `metadata.json` · `README.md` 139 lines UTF-8 · LF · Spaces: 2
Continue browsing