JSFiddle - React, Tailwind, and code Playground

HTML

<div class="timer" data-time="01.01.2022 18:30">
    <div class="timer__items">
      <div class="timer__item timer__days">00</div>
      <div class="timer__item timer__hours">00</div>
      <div class="timer__item timer__minutes">00</div>
      <div class="timer__item timer__seconds">00</div>
    </div>
  </div>

CSS

*,
 *::before,
 *::after {
   box-sizing: border-box;
 }

body {
      margin: 0;
      font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
      font-size: 1rem;
      font-weight: 400;
      line-height: 1.5;
      color: #212529;
      background-color: #fff;
      -webkit-text-size-adjust: 100%;
      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
      display: flex;
      justify-content: center;
    }

    .timer__items {
      display: flex;
      font-size: 48px;
    }

    .timer__item {
      position: relative;
      min-width: 60px;
      margin-left: 10px;
      margin-right: 10px;
      padding-bottom: 15px;
      text-align: center;
    }

    .timer__item::before {
      content: attr(data-title);
      display: block;
      position: absolute;
      left: 50%;
      bottom: 0;
      transform: translateX(-50%);
      font-size: 14px;
    }

    .timer__item:not(:last-child)::after {
      content: ':';
      position: absolute;
      right: -15px;
    }

JavaScript

document.addEventListener('DOMContentLoaded', function() {
   // конечная дата
   const timerData = document.querySelector('.timer').getAttribute('data-time');

   const [day, month, year, hours, minutes] = timerData.replace(/[:.]/g, ' ').split(' ');

   const deadline = new Date(year, month-1, day, hours, minutes);
   // id таймера
   let timerId = null;
   // склонение числительных
   function declensionNum(num, words) {
     return words[(num % 100 > 4 && num % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(num % 10 < 5) ? num % 10 : 5]];
   }
   // вычисляем разницу дат и устанавливаем оставшееся времени в качестве содержимого элементов
   function countdownTimer() {
     const diff = deadline - new Date();
     if (diff <= 0) {
       clearInterval(timerId);
     }
     const days = diff > 0 ? Math.floor(diff / 1000 / 60 / 60 / 24) : 0;
     const hours = diff > 0 ? Math.floor(diff / 1000 / 60 / 60) % 24 : 0;
     const minutes = diff > 0 ? Math.floor(diff / 1000 / 60) % 60 : 0;
     const seconds = diff > 0 ? Math.floor(diff / 1000) % 60 : 0;
     $days.textContent = days < 10 ? '0' + days : days;
     $hours.textContent = hours < 10 ? '0' + hours : hours;
     $minutes.textContent = minutes < 10 ? '0' + minutes : minutes;
     $seconds.textContent = seconds < 10 ? '0' + seconds : seconds;
     $days.dataset.title = declensionNum(days, ['день', 'дня', 'дней']);
     $hours.dataset.title = declensionNum(hours, ['час', 'часа', 'часов']);
     $minutes.dataset.title = declensionNum(minutes, ['минута', 'минуты', 'минут']);
     $seconds.dataset.title = declensionNum(seconds, ['секунда', 'секунды', 'секунд']);
   }
   // получаем элементы, содержащие компоненты даты
   const $days = document.querySelector('.timer__days');
   const $hours = document.querySelector('.timer__hours');
   const $minutes = document.querySelector('.timer__minutes');
   const $seconds = document.querySelector('.timer__seconds');
   // вызываем функцию countdownTimer
   countdownTimer();
   //...