JSFiddle - React, Tailwind, and code Playground

by NickU

HTML

<div class="button-container">
  <button type="button" value="All" title="01/01/1999 - 02/25/2023" class="bntWhen selected">All </button>
  <button type="button" value="Today" title="02/25/2023 - 02/25/2023" class="bntWhen">Today </button>
  <button type="button" value="PreviousDay" title="02/24/2023 - 02/24/2023" class="bntWhen">Previous Day </button>
  <button type="button" value="WeekToDate" title="02/20/2023 - 02/25/2023" class="bntWhen">Week To Date </button>
  <button type="button" value="PreviousWeek" title="02/13/2023 - 02/17/2023" class="bntWhen">Previous Week </button>
  <button type="button" value="MonthToDate" title="02/01/2023 - 02/25/2023" class="bntWhen">Month To Date </button>
  <button type="button" value="YearToDate" title="01/01/2023 - 02/25/2023" class="bntWhen">Year To Date </button>
  <button type="button" value="LastCalendYear" title="01/01/2022 - 12/31/2022" class="bntWhen">Last Year </button>
  <button type="button" value="CustomRange" title="Click to enter Custom Date Range ..." class="bntWhen">Custom Date...  </button>
  <div class="custom-range">
    <input type="date" name="startDate" id="startDate">
    <input type="date" name="endDate" id="endDate">
  </div>
  <form name="f1" id="f1">
  <input type="hidden" name="DateAddedPeriod" id="DateAddedPeriod" value="All">
  <input type="hidden" id="DateAddedPeriodTitle" name="DateAddedPeriodTitle" value="">
  </form>
</div>

CSS

#date-filter-table {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  position: relative;
  margin-top: 10px;
}

#date-filter-table .bntWhen {
  position: relative;
  z-index: 1;
}

#date-filter-table .bntWhen.selected:before {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(90deg, #FFFFFF00 0%, #FFFFFFAA 100%);
  z-index: -1;
}

.custom-range {
  visibility: hidden;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  width: 100%;
  background-color: #fff;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
  padding: 10px;
  box-sizing: border-box;
}

.custom-range.show {
  display: block;
  animation: slide-down 0.3s;
}

.custom-range input[type="date"] {
  border: 1px solid #c0c0c0b3;
  margin: 5px;
  border-radius: 3px;
  padding: 5px;
  font-size: 12px;
}

.custom-range .actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.custom-range .actions button {
  margin-left: 10px;
}

@keyframes slide-down {
  0% {
    opacity: 0;
    top: -100%;
  }
  100% {
    opacity: 1;
    top: 0;
  }
}

JavaScript

// Get the custom range div and its width
const customRangeDiv = document.querySelector(".custom-range");
const customRangeWidth = 900;


// Position the buttons
const buttons = document.querySelectorAll(".bntWhen");
const numButtons = buttons.length;
const buttonWidth = buttons[0].offsetWidth;
const buttonOverlap = buttonWidth / 2;
const buttonMargin = (customRangeWidth - numButtons * buttonWidth + (numButtons - 1) * buttonOverlap) / 2;

for (let i = 0; i < numButtons; i++) {
    const button = buttons[i];
    const buttonLeft = i * (buttonWidth - buttonOverlap) + buttonMargin;
    button.style.position = "absolute";
    button.style.left = `${buttonLeft}px`;
}

// Animate the button positions
function animateButtonPositions(targetMargin) {
    const startMargin = parseFloat(buttons[0].style.marginLeft);
    const numSteps = 100;
    const stepSize = (targetMargin - startMargin) / numSteps;
    let step = 1;
    
    const interval = setInterval(() => {
        if (step >= numSteps) {
            clearInterval(interval);
        }
        
        const newMargin = startMargin + step * stepSize;
        
        for (let i = 0; i < numButtons; i++) {
            const button = buttons[i];
            const buttonLeft = i * (buttonWidth - buttonOverlap) + newMargin;
            button.style.left = `${buttonLeft}px`;
        }
        
        step++;
        console.log("step="+ step);
    }, 50);
}

// Add a click event listener to the CustomRange button
const customRangeButton = document.querySelector(".bntWhen[value=CustomRange]");
customRangeButton.addEventListener("click", () => {
    //customRangeDiv.style.visibility = "visible";
    animateButtonPositions(-customRangeWidth / 2);
});