Component

Date Filter

Date range filter with quick presets (today, this week, this month) and custom date pickers.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

Interactive preview
Open preview
9:41 100%
devsnips.dev/library/tailwind/components/dropdowns/date-filter/
fluid · no fixed width 100%
No dependencies Production-ready

Install

Add to your project

terminal
npx devsnips add Tailwind/Components/Dropdowns/date-filter
registry path: Tailwind/Components/Dropdowns/date-filter

Source

Implementation

code.html
<!-- Date Filter -->
<div class="relative inline-block">
  <button
    id="date-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('date-menu')"
  >
    <svg class="w-5 h-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
    </svg>
    <span id="date-range-label">Select dates</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="date-menu"
    class="hidden absolute left-0 z-20 mt-2 w-80 bg-white rounded-xl shadow-xl border border-gray-200 overflow-hidden"
  >
    <!-- Preset Ranges -->
    <div class="p-4 border-b border-gray-100">
      <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3">Quick Select</p>
      <div class="grid grid-cols-2 gap-2">
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('today')">Today</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('yesterday')">Yesterday</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('last7')">Last 7 days</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('last30')">Last 30 days</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('thisWeek')">This week</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('lastWeek')">Last week</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('thisMonth')">This month</button>
        <button class="date-preset px-3 py-2 text-xs font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors" onclick="setDateRange('lastMonth')">Last month</button>
      </div>
    </div>

    <!-- Custom Range -->
    <div class="p-4">
      <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-3">Custom Range</p>
      <div class="space-y-3">
        <div>
          <label class="block text-xs text-gray-500 mb-1">Start Date</label>
          <input
            type="date"
            id="start-date"
            class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
          />
        </div>
        <div>
          <label class="block text-xs text-gray-500 mb-1">End Date</label>
          <input
            type="date"
            id="end-date"
            class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
          />
        </div>
      </div>
    </div>

    <!-- Footer -->
    <div class="px-4 py-3 bg-gray-50 border-t border-gray-100 flex items-center justify-between">
      <span id="date-summary" class="text-xs text-gray-500">No date range selected</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="applyDateRange()">
        Apply
      </button>
    </div>
  </div>
</div>

<script>
  function toggleDropdown(id) {
    document.getElementById(id).classList.toggle('hidden');
  }

  function setDateRange(preset) {
    const today = new Date();
    const formatDate = (date) => date.toISOString().split('T')[0];
    const labelMap = {
      'today': 'Today',
      'yesterday': 'Yesterday',
      'last7': 'Last 7 days',
      'last30': 'Last 30 days',
      'thisWeek': 'This week',
      'lastWeek': 'Last week',
      'thisMonth': 'This month',
      'lastMonth': 'Last month'
    };

    document.getElementById('date-range-label').textContent = labelMap[preset] || 'Custom';
    document.getElementById('date-summary').textContent = labelMap[preset] || 'Custom range';

    let startDate, endDate = formatDate(today);
    
    switch(preset) {
      case 'today':
        startDate = formatDate(today);
        break;
      case 'yesterday':
        const yesterday = new Date(today);
        yesterday.setDate(yesterday.getDate() - 1);
        startDate = endDate = formatDate(yesterday);
        break;
      case 'last7':
        const weekAgo = new Date(today);
        weekAgo.setDate(weekAgo.getDate() - 7);
        startDate = formatDate(weekAgo);
        break;
      case 'last30':
        const monthAgo = new Date(today);
        monthAgo.setDate(monthAgo.getDate() - 30);
        startDate = formatDate(monthAgo);
        break;
      case 'thisWeek':
        const dayOfWeek = today.getDay();
        const weekStart = new Date(today);
        weekStart.setDate(today.getDate() - dayOfWeek);
        startDate = formatDate(weekStart);
        break;
      case 'lastWeek':
        const lastWeekEnd = new Date(today);
        lastWeekEnd.setDate(today.getDate() - today.getDay() - 1);
        const lastWeekStart = new Date(lastWeekEnd);
        lastWeekStart.setDate(lastWeekEnd.getDate() - 6);
        startDate = formatDate(lastWeekStart);
        endDate = formatDate(lastWeekEnd);
        break;
      case 'thisMonth':
        const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);
        startDate = formatDate(monthStart);
        break;
      case 'lastMonth':
        const lastMonthEnd = new Date(today.getFullYear(), today.getMonth(), 0);
        const lastMonthStart = new Date(today.getFullYear(), today.getMonth() - 1, 1);
        startDate = formatDate(lastMonthStart);
        endDate = formatDate(lastMonthEnd);
        break;
    }

    document.getElementById('start-date').value = startDate;
    document.getElementById('end-date').value = endDate;
  }

  function applyDateRange() {
    toggleDropdown('date-menu');
  }

  document.addEventListener('click', function(event) {
    const container = document.querySelector('.relative.inline-block');
    if (!container.contains(event.target)) {
      document.getElementById('date-menu').classList.add('hidden');
    }
  });
</script>
152 lines UTF-8 · LF · Spaces: 2

AI-ready

Available to your agent.

This component is reachable through the DevSnips CLI, MCP server and Skills integrations — one registry, one resource path.

Resource path

devsnips://components/dropdowns/date-filter

Continue browsing

View all