This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git


The following commit(s) were added to refs/heads/main by this push:
     new f069c8a0 feat: optimize the time picker component  (#494)
f069c8a0 is described below

commit f069c8a081543f78a078ca8db477081c21c2e129
Author: Fine0830 <fanxue0...@gmail.com>
AuthorDate: Wed Aug 27 21:20:53 2025 +0800

    feat: optimize the time picker component  (#494)
---
 src/components/DateCalendar.vue                    |  16 +-
 src/components/TimePicker.vue                      | 120 ++-
 src/components/__tests__/DateCalendar.spec.ts      | 836 +++++++++++++--------
 src/components/__tests__/TimePicker.spec.ts        | 462 ++++++------
 src/hooks/useExpressionsProcessor.ts               |   1 -
 src/layout/components/NavBar.vue                   |   3 +-
 .../related/profile/components/NewTask.vue         |   2 +-
 stylelint.config.js                                |   3 -
 8 files changed, 829 insertions(+), 614 deletions(-)

diff --git a/src/components/DateCalendar.vue b/src/components/DateCalendar.vue
index 293e80a3..fc92d4d1 100755
--- a/src/components/DateCalendar.vue
+++ b/src/components/DateCalendar.vue
@@ -166,11 +166,10 @@ limitations under the License. -->
   const emit = defineEmits(["input", "setDates", "ok"]);
   const { t } = useI18n();
   const props = defineProps({
-    value: { type: Date },
+    value: { type: Object as PropType<Date>, default: () => new Date() },
     left: { type: Boolean, default: false },
     right: { type: Boolean, default: false },
     dates: { type: Array as PropType<Date[]>, default: () => [] },
-    disabledDate: { type: Function, default: () => false },
     format: {
       type: String,
       default: "YYYY-MM-DD",
@@ -246,7 +245,7 @@ limitations under the License. -->
     return parse(Number(props.maxRange[0]));
   });
   const maxEnd = computed(() => {
-    return parse(Number(props.maxRange[1]));
+    return parse(Number(props.maxRange[1]) + 23 * 60 * 60 * 1000);
   });
   const ys = computed(() => {
     return Math.floor(state.year / 10) * 10;
@@ -376,10 +375,13 @@ limitations under the License. -->
       flag = tf(props.value, format) === tf(time, format);
     }
     classObj[`${state.pre}-date`] = true;
-    const rightDisabled = props.right && (t < start.value || t > maxEnd.value 
|| !props.maxRange?.length);
-    const leftDisabled =
-      props.left && (t < minStart.value || t > end.value || 
!props.maxRange?.length || t > maxEnd.value);
-    classObj[`${state.pre}-date-disabled`] = rightDisabled || leftDisabled || 
props.disabledDate(time, format);
+
+    // Only apply range constraints when maxRange is provided and has valid 
dates
+    const hasMaxRange = props.maxRange && props.maxRange.length === 2;
+    const rightDisabled = props.right && hasMaxRange && (t < start.value || t 
> maxEnd.value);
+    const leftDisabled = props.left && hasMaxRange && (t < minStart.value || t 
> end.value || t > maxEnd.value);
+
+    classObj[`${state.pre}-date-disabled`] = rightDisabled || leftDisabled;
     classObj[`${state.pre}-date-on`] = (props.left && t > start.value) || 
(props.right && t < end.value);
     classObj[`${state.pre}-date-selected`] = flag;
     return classObj;
diff --git a/src/components/TimePicker.vue b/src/components/TimePicker.vue
index 75559d26..422d0644 100755
--- a/src/components/TimePicker.vue
+++ b/src/components/TimePicker.vue
@@ -41,22 +41,52 @@ limitations under the License. -->
       >
         <template v-if="range">
           <div class="datepicker-popup__sidebar">
-            <button type="button" class="datepicker-popup__shortcut" 
@click="quickPick('quarter')">
+            <button
+              type="button"
+              class="datepicker-popup__shortcut"
+              :class="{ 'datepicker-popup__shortcut--selected': 
selectedShortcut === QUICK_PICK_TYPES.QUARTER }"
+              @click="quickPick(QUICK_PICK_TYPES.QUARTER)"
+            >
               {{ local.quarterHourCutTip }}
             </button>
-            <button type="button" class="datepicker-popup__shortcut" 
@click="quickPick('half')">
+            <button
+              type="button"
+              class="datepicker-popup__shortcut"
+              :class="{ 'datepicker-popup__shortcut--selected': 
selectedShortcut === QUICK_PICK_TYPES.HALF }"
+              @click="quickPick(QUICK_PICK_TYPES.HALF)"
+            >
               {{ local.halfHourCutTip }}
             </button>
-            <button type="button" class="datepicker-popup__shortcut" 
@click="quickPick('hour')">
+            <button
+              type="button"
+              class="datepicker-popup__shortcut"
+              :class="{ 'datepicker-popup__shortcut--selected': 
selectedShortcut === QUICK_PICK_TYPES.HOUR }"
+              @click="quickPick(QUICK_PICK_TYPES.HOUR)"
+            >
               {{ local.hourCutTip }}
             </button>
-            <button type="button" class="datepicker-popup__shortcut" 
@click="quickPick('day')">
+            <button
+              type="button"
+              class="datepicker-popup__shortcut"
+              :class="{ 'datepicker-popup__shortcut--selected': 
selectedShortcut === QUICK_PICK_TYPES.DAY }"
+              @click="quickPick(QUICK_PICK_TYPES.DAY)"
+            >
               {{ local.dayCutTip }}
             </button>
-            <button type="button" class="datepicker-popup__shortcut" 
@click="quickPick('week')">
+            <button
+              type="button"
+              class="datepicker-popup__shortcut"
+              :class="{ 'datepicker-popup__shortcut--selected': 
selectedShortcut === QUICK_PICK_TYPES.WEEK }"
+              @click="quickPick(QUICK_PICK_TYPES.WEEK)"
+            >
               {{ local.weekCutTip }}
             </button>
-            <button type="button" class="datepicker-popup__shortcut" 
@click="quickPick('month')">
+            <button
+              type="button"
+              class="datepicker-popup__shortcut"
+              :class="{ 'datepicker-popup__shortcut--selected': 
selectedShortcut === QUICK_PICK_TYPES.MONTH }"
+              @click="quickPick(QUICK_PICK_TYPES.MONTH)"
+            >
               {{ local.monthCutTip }}
             </button>
           </div>
@@ -66,7 +96,6 @@ limitations under the License. -->
               :value="dates[0]"
               :dates="dates"
               :left="true"
-              :disabledDate="disabledDate"
               :format="format"
               :maxRange="maxRange"
               @ok="ok"
@@ -77,7 +106,6 @@ limitations under the License. -->
               :value="dates[1]"
               :dates="dates"
               :right="true"
-              :disabledDate="disabledDate"
               :format="format"
               :maxRange="maxRange"
               @ok="ok"
@@ -89,7 +117,6 @@ limitations under the License. -->
           <DateCalendar
             v-model="dates[0]"
             :value="dates[0]"
-            :disabledDate="disabledDate"
             :dates="dates"
             :format="format"
             @ok="ok"
@@ -110,15 +137,29 @@ limitations under the License. -->
 </template>
 
 <script lang="ts" setup>
-  import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
+  import { ref, computed, onMounted, onBeforeUnmount, watch, PropType } from 
"vue";
   import { useI18n } from "vue-i18n";
   import DateCalendar from "./DateCalendar.vue";
   import { useTimeoutFn } from "@/hooks/useTimeout";
-  /*global PropType, defineProps, defineEmits*/
+  /* global defineProps, defineEmits */
+
+  const QUICK_PICK_TYPES = {
+    QUARTER: "quarter",
+    HALF: "half",
+    HOUR: "hour",
+    DAY: "day",
+    WEEK: "week",
+    MONTH: "month",
+  } as const;
+
+  type QuickPickType = typeof QUICK_PICK_TYPES[keyof typeof QUICK_PICK_TYPES];
+
   const datepicker = ref(null);
   const { t } = useI18n();
   const show = ref<boolean>(false);
   const dates = ref<Date[]>([]);
+  const inputDates = ref<Date[]>([]);
+  const selectedShortcut = ref<string>(QUICK_PICK_TYPES.HALF);
   const props = defineProps({
     position: { type: String, default: "bottom" },
     name: [String],
@@ -139,10 +180,6 @@ limitations under the License. -->
       default: false,
     },
     placeholder: [String],
-    disabledDate: {
-      type: Function,
-      default: () => false,
-    },
     format: {
       type: String,
       default: "YYYY-MM-DD",
@@ -208,15 +245,15 @@ limitations under the License. -->
     return dates.value.length === 2;
   });
   const text = computed(() => {
-    const val = props.value;
-    const txt = dates.value.map((date: Date) => tf(date)).join(` 
${props.rangeSeparator} `);
-    if (Array.isArray(val)) {
-      return val.length > 1 ? txt : "";
+    const txt = inputDates.value.map((date: Date) => tf(date)).join(` 
${props.rangeSeparator} `);
+    if (Array.isArray(props.value)) {
+      return props.value.length > 1 ? txt : "";
     }
-    return val ? txt : "";
+    return props.value ? txt : "";
   });
   const get = () => {
-    return Array.isArray(props.value) ? dates.value : dates.value[0];
+    const currentDates = props.showButtons ? inputDates.value : dates.value;
+    return Array.isArray(props.value) ? currentDates : currentDates[0];
   };
   const cls = () => {
     emit("clear");
@@ -224,7 +261,7 @@ limitations under the License. -->
   };
   const vi = (val: any) => {
     if (Array.isArray(val)) {
-      return val.length > 1 ? val.map((item) => new Date(item)) : [new Date(), 
new Date()];
+      return val.length >= 1 ? val.map((item) => new Date(item)) : [new 
Date(), new Date()];
     }
     return val ? [new Date(val)] : [new Date()];
   };
@@ -246,44 +283,47 @@ limitations under the License. -->
   const dc = (e: MouseEvent) => {
     show.value = (datepicker.value as any).contains(e.target) && 
!props.disabled;
   };
-  const quickPick = (type: string) => {
+  const quickPick = (type: QuickPickType) => {
     const end = new Date();
     const start = new Date();
+    selectedShortcut.value = type;
     switch (type) {
-      case "quarter":
+      case QUICK_PICK_TYPES.QUARTER:
         start.setTime(start.getTime() - 60 * 15 * 1000); //15 mins
         break;
-      case "half":
+      case QUICK_PICK_TYPES.HALF:
         start.setTime(start.getTime() - 60 * 30 * 1000); //30 mins
         break;
-      case "hour":
+      case QUICK_PICK_TYPES.HOUR:
         start.setTime(start.getTime() - 3600 * 1000); //1 hour
         break;
-      case "day":
+      case QUICK_PICK_TYPES.DAY:
         start.setTime(start.getTime() - 3600 * 1000 * 24); //1 day
         break;
-      case "week":
+      case QUICK_PICK_TYPES.WEEK:
         start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); //1 week
         break;
-      case "month":
+      case QUICK_PICK_TYPES.MONTH:
         start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); //1 month
         break;
       default:
         break;
     }
     dates.value = [start, end];
-    emit("input", get());
   };
   const submit = () => {
+    inputDates.value = dates.value;
     emit("confirm", get());
     show.value = false;
   };
   const cancel = () => {
     emit("cancel");
     show.value = false;
+    dates.value = vi(props.value);
   };
   onMounted(() => {
     dates.value = vi(props.value);
+    inputDates.value = dates.value;
     document.addEventListener("click", dc, true);
   });
   onBeforeUnmount(() => {
@@ -293,6 +333,7 @@ limitations under the License. -->
     () => props.value,
     (val: unknown) => {
       dates.value = vi(val);
+      inputDates.value = [...dates.value];
     },
   );
 </script>
@@ -462,11 +503,15 @@ limitations under the License. -->
       color: var(--sw-topology-color);
       text-align: left;
       outline: none;
-      cursor: pointer;
       white-space: nowrap;
 
       &:hover {
-        color: #3f97e3;
+        color: var(--el-color-primary);
+        cursor: pointer;
+      }
+
+      &--selected {
+        color: var(--el-color-primary);
       }
     }
 
@@ -520,20 +565,21 @@ limitations under the License. -->
   }
 
   .datepicker__buttons button {
-    display: inline-block;
-    font-size: 13px;
     border: none;
     cursor: pointer;
-    margin: 10px 0 0 5px;
-    padding: 5px 15px;
     color: $text-color;
+    margin-left: 5px;
+    padding: 2px 5px;
   }
 
   .datepicker__buttons .datepicker__button-select {
-    background: #3f97e3;
+    background: var(--el-color-primary);
+    border-radius: 2px;
+    color: #fff;
   }
 
   .datepicker__buttons .datepicker__button-cancel {
     background: var(--sw-topology-color);
+    border-radius: 2px;
   }
 </style>
diff --git a/src/components/__tests__/DateCalendar.spec.ts 
b/src/components/__tests__/DateCalendar.spec.ts
index 1e9b754e..817ac8d0 100644
--- a/src/components/__tests__/DateCalendar.spec.ts
+++ b/src/components/__tests__/DateCalendar.spec.ts
@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-import { describe, it, expect, vi, beforeEach } from "vitest";
 import { mount } from "@vue/test-utils";
+import { describe, it, expect, vi } from "vitest";
 import { nextTick } from "vue";
 import DateCalendar from "../DateCalendar.vue";
 
@@ -25,10 +25,10 @@ vi.mock("vue-i18n", () => ({
   useI18n: () => ({
     t: (key: string) => {
       const translations: Record<string, string> = {
-        hourTip: "Select Hour",
-        minuteTip: "Select Minute",
-        secondTip: "Select Second",
-        yearSuffix: "",
+        hourTip: "Hour",
+        minuteTip: "Minute",
+        secondTip: "Second",
+        yearSuffix: "Year",
         monthsHead: 
"January_February_March_April_May_June_July_August_September_October_November_December",
         months: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec",
         weeks: "Mon_Tue_Wed_Thu_Fri_Sat_Sun",
@@ -47,42 +47,24 @@ vi.mock("vue-i18n", () => ({
 }));
 
 describe("DateCalendar Component", () => {
-  let wrapper: Recordable;
-
-  const mockDate = new Date(2024, 0, 15, 10, 30, 45); // January 15, 2024, 
10:30:45
-
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
+  let wrapper: any;
+  const mockDate = new Date(2024, 0, 15, 10, 30, 45);
+  const mockDateRange = [new Date(2024, 0, 10), new Date(2024, 0, 20)];
 
   describe("Props", () => {
     it("should render with default props", () => {
       wrapper = mount(DateCalendar);
-
       expect(wrapper.exists()).toBe(true);
-      // When no value is provided, state.pre is empty initially
-      expect(wrapper.vm.state.pre).toBe("");
-      expect(wrapper.vm.state.m).toBe("D");
-      expect(wrapper.vm.state.showYears).toBe(false);
-      expect(wrapper.vm.state.showMonths).toBe(false);
-      expect(wrapper.vm.state.showHours).toBe(false);
-      expect(wrapper.vm.state.showMinutes).toBe(false);
-      expect(wrapper.vm.state.showSeconds).toBe(false);
+      expect(wrapper.classes()).toContain("calendar");
     });
 
-    it("should render with custom value", () => {
+    it("should render with value prop", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
-
-      expect(wrapper.vm.state.year).toBe(2024);
-      expect(wrapper.vm.state.month).toBe(0); // January is 0
-      expect(wrapper.vm.state.day).toBe(15);
-      expect(wrapper.vm.state.hour).toBe(10);
-      expect(wrapper.vm.state.minute).toBe(30);
-      expect(wrapper.vm.state.second).toBe(45);
+      expect(wrapper.vm.value).toEqual(mockDate);
     });
 
     it("should render with left prop", () => {
@@ -91,8 +73,7 @@ describe("DateCalendar Component", () => {
           left: true,
         },
       });
-
-      expect(wrapper.props("left")).toBe(true);
+      expect(wrapper.vm.left).toBe(true);
     });
 
     it("should render with right prop", () => {
@@ -101,327 +82,316 @@ describe("DateCalendar Component", () => {
           right: true,
         },
       });
-
-      expect(wrapper.props("right")).toBe(true);
+      expect(wrapper.vm.right).toBe(true);
     });
 
-    it("should render with custom format", () => {
+    it("should render with dates array", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          format: "YYYY-MM-DD HH:mm:ss",
+          dates: mockDateRange,
         },
       });
-
-      expect(wrapper.props("format")).toBe("YYYY-MM-DD HH:mm:ss");
+      expect(wrapper.vm.dates).toEqual(mockDateRange);
     });
 
-    it("should render with dates array", () => {
-      const dates = [new Date(2024, 0, 1), new Date(2024, 0, 31)];
+    it("should render with custom format", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          dates,
+          format: "YYYY-MM-DD HH:mm:ss",
         },
       });
-
-      expect(wrapper.props("dates")).toEqual(dates);
+      expect(wrapper.vm.format).toBe("YYYY-MM-DD HH:mm:ss");
     });
 
     it("should render with maxRange array", () => {
-      const maxRange = [new Date(2024, 0, 1), new Date(2024, 11, 31)];
       wrapper = mount(DateCalendar, {
         props: {
-          maxRange,
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
         },
       });
-
-      expect(wrapper.props("maxRange")).toEqual(maxRange);
+      expect(wrapper.vm.maxRange).toHaveLength(2);
     });
+  });
 
-    it("should render with disabledDate function", () => {
-      const disabledDate = vi.fn(() => false);
+  describe("Computed Properties", () => {
+    it("should calculate start date correctly", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          disabledDate,
+          dates: mockDateRange,
         },
       });
-
-      expect(wrapper.props("disabledDate")).toBe(disabledDate);
+      expect(wrapper.vm.start).toBeDefined();
     });
-  });
 
-  describe("Computed Properties", () => {
-    beforeEach(() => {
+    it("should calculate end date correctly", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          value: mockDate,
+          dates: mockDateRange,
         },
       });
+      expect(wrapper.vm.end).toBeDefined();
     });
 
-    it("should calculate start date correctly", () => {
-      const dates = [new Date(2024, 0, 1), new Date(2024, 0, 31)];
+    it("should calculate minStart correctly", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          dates,
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
         },
       });
-
-      // The actual value depends on the parse function implementation
-      expect(wrapper.vm.start).toBeGreaterThan(0);
+      expect(wrapper.vm.minStart).toBeDefined();
     });
 
-    it("should calculate end date correctly", () => {
-      const dates = [new Date(2024, 0, 1), new Date(2024, 0, 31)];
+    it("should calculate maxEnd correctly", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          dates,
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
         },
       });
-
-      // The actual value depends on the parse function implementation
-      expect(wrapper.vm.end).toBeGreaterThan(0);
+      expect(wrapper.vm.maxEnd).toBeDefined();
     });
 
     it("should calculate year start correctly", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
       expect(wrapper.vm.ys).toBe(2020);
     });
 
     it("should calculate year end correctly", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
       expect(wrapper.vm.ye).toBe(2030);
     });
 
-    it("should generate years array correctly", () => {
-      const years = wrapper.vm.years;
-      expect(years).toHaveLength(12);
-      // The years array should have 12 consecutive years
-      expect(years[11] - years[0]).toBe(11);
-      expect(years[0]).toBeGreaterThan(0);
-      expect(years[11]).toBeGreaterThan(0);
-    });
-
-    it("should generate days array correctly", () => {
-      const days = wrapper.vm.days;
-      expect(days).toHaveLength(42); // 6 weeks * 7 days
-
-      // Check that we have the correct number of days for January 2024
-      const currentMonthDays = days.filter((day: Recordable) => !day.p && 
!day.n);
-      expect(currentMonthDays).toHaveLength(31);
+    it("should calculate years array correctly", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      expect(wrapper.vm.years).toHaveLength(12);
     });
 
-    it("should format time correctly with dd function", () => {
-      expect(wrapper.vm.dd(5)).toBe("05");
-      expect(wrapper.vm.dd(10)).toBe("10");
-      expect(wrapper.vm.dd(0)).toBe("00");
+    it("should calculate days array correctly", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      expect(wrapper.vm.days).toHaveLength(42);
     });
-  });
 
-  describe("Navigation", () => {
-    beforeEach(() => {
+    it("should calculate local translations correctly", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
+      expect(wrapper.vm.local.monthsHead).toHaveLength(12);
+      expect(wrapper.vm.local.months).toHaveLength(12);
+      expect(wrapper.vm.local.weeks).toHaveLength(7);
     });
+  });
 
-    it("should navigate to next month", async () => {
-      const initialMonth = wrapper.vm.state.month;
-      const initialYear = wrapper.vm.state.year;
-
-      await wrapper.vm.nm();
-      await nextTick();
-
-      if (initialMonth === 11) {
-        expect(wrapper.vm.state.month).toBe(0);
-        expect(wrapper.vm.state.year).toBe(initialYear + 1);
-      } else {
-        expect(wrapper.vm.state.month).toBe(initialMonth + 1);
-        expect(wrapper.vm.state.year).toBe(initialYear);
-      }
+  describe("Methods", () => {
+    it("should parse numbers correctly", () => {
+      wrapper = mount(DateCalendar);
+      const result = wrapper.vm.parse(100000);
+      expect(result).toBe(1);
     });
 
-    it("should navigate to previous month", async () => {
-      const initialMonth = wrapper.vm.state.month;
-      const initialYear = wrapper.vm.state.year;
+    it("should handle next month navigation", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const originalMonth = wrapper.vm.state.month;
+      wrapper.vm.nm();
+      expect(wrapper.vm.state.month).toBe(originalMonth + 1);
+    });
 
-      await wrapper.vm.pm();
-      await nextTick();
+    it("should handle previous month navigation", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const originalMonth = wrapper.vm.state.month;
+      const originalYear = wrapper.vm.state.year;
+      wrapper.vm.pm();
 
-      if (initialMonth === 0) {
+      // Handle month wrapping: if originalMonth was 0 (January), it should 
wrap to 11 (December)
+      if (originalMonth === 0) {
         expect(wrapper.vm.state.month).toBe(11);
-        expect(wrapper.vm.state.year).toBe(initialYear - 1);
+        expect(wrapper.vm.state.year).toBe(originalYear - 1); // Year should 
be decremented
       } else {
-        expect(wrapper.vm.state.month).toBe(initialMonth - 1);
-        expect(wrapper.vm.state.year).toBe(initialYear);
+        expect(wrapper.vm.state.month).toBe(originalMonth - 1);
+        expect(wrapper.vm.state.year).toBe(originalYear); // Year should 
remain the same
       }
     });
 
-    it("should navigate to next year", async () => {
-      const initialYear = wrapper.vm.state.year;
-
-      wrapper.vm.state.year++;
-      await nextTick();
-
-      expect(wrapper.vm.state.year).toBe(initialYear + 1);
+    it("should handle month boundary navigation", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: new Date(2024, 11, 15), // December
+        },
+      });
+      wrapper.vm.nm();
+      expect(wrapper.vm.state.month).toBe(0); // January
+      expect(wrapper.vm.state.year).toBe(2025);
     });
 
-    it("should navigate to previous year", async () => {
-      const initialYear = wrapper.vm.state.year;
-
-      wrapper.vm.state.year--;
-      await nextTick();
-
-      expect(wrapper.vm.state.year).toBe(initialYear - 1);
+    it("should handle year boundary navigation", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: new Date(2024, 0, 15), // January
+        },
+      });
+      wrapper.vm.pm();
+      expect(wrapper.vm.state.month).toBe(11); // December
+      expect(wrapper.vm.state.year).toBe(2023);
     });
 
-    it("should navigate to next decade", async () => {
-      const initialYear = wrapper.vm.state.year;
-
-      wrapper.vm.state.year += 10;
-      await nextTick();
-
-      expect(wrapper.vm.state.year).toBe(initialYear + 10);
+    it("should check if event target is disabled", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const mockEvent = {
+        target: {
+          className: "calendar-date calendar-date-disabled",
+        },
+      };
+      const result = wrapper.vm.is(mockEvent);
+      expect(result).toBe(false);
     });
 
-    it("should navigate to previous decade", async () => {
-      const initialYear = wrapper.vm.state.year;
-
-      wrapper.vm.state.year -= 10;
-      await nextTick();
-
-      expect(wrapper.vm.state.year).toBe(initialYear - 10);
+    it("should check if event target is not disabled", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const mockEvent = {
+        target: {
+          className: "calendar-date",
+        },
+      };
+      const result = wrapper.vm.is(mockEvent);
+      expect(result).toBe(true);
     });
-  });
 
-  describe("Events", () => {
-    beforeEach(() => {
+    it("should handle ok event for hour selection", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
+      wrapper.vm.ok("h");
+      expect(wrapper.emitted("ok")).toBeTruthy();
     });
 
-    it("should emit setDates event when date is selected", async () => {
-      // The ok function creates a new Date with current state values
-      await wrapper.vm.ok({ i: 20, y: 2024, m: 0 });
-      await nextTick();
-
-      expect(wrapper.emitted("setDates")).toBeTruthy();
-      // The emitted date will be based on the current state values
-      const emittedDate = wrapper.emitted("setDates")[0][0];
-      expect(emittedDate).toBeInstanceOf(Date);
+    it("should handle ok event for month selection", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.ok("m");
+      expect(wrapper.emitted("ok")).toBeTruthy();
     });
 
-    it("should emit ok event when date is selected", async () => {
-      await wrapper.vm.ok({ i: 20, y: 2024, m: 0 });
-      await nextTick();
+    it("should handle ok event for year selection", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.ok("y");
+      expect(wrapper.emitted("ok")).toBeTruthy();
+    });
 
+    it("should handle ok event for date selection", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const mockInfo = { n: false, p: false };
+      wrapper.vm.ok(mockInfo);
       expect(wrapper.emitted("ok")).toBeTruthy();
-      expect(wrapper.emitted("ok")[0]).toEqual([false]);
     });
 
-    it("should emit setDates event for left calendar", async () => {
+    it("should handle setDates for left calendar", () => {
       wrapper = mount(DateCalendar, {
         props: {
           left: true,
-          dates: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
+          dates: mockDateRange,
+          value: mockDateRange[0],
         },
       });
-
-      await wrapper.vm.ok({ i: 15, y: 2024, m: 0 });
-      await nextTick();
-
+      wrapper.vm.ok({ n: false, p: false });
       expect(wrapper.emitted("setDates")).toBeTruthy();
-      const emittedEvent = wrapper.emitted("setDates")[0];
-      expect(emittedEvent[1]).toBe("left");
-      expect(emittedEvent[0]).toBeInstanceOf(Date);
     });
 
-    it("should emit setDates event for right calendar", async () => {
+    it("should handle setDates for right calendar", () => {
       wrapper = mount(DateCalendar, {
         props: {
           right: true,
-          dates: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
+          dates: mockDateRange,
         },
       });
-
-      await wrapper.vm.ok({ i: 25, y: 2024, m: 0 });
-      await nextTick();
-
-      // The right calendar might not emit if the date is not in the valid 
range
-      if (wrapper.emitted("setDates")) {
-        const emittedEvent = wrapper.emitted("setDates")[0];
-        expect(emittedEvent[1]).toBe("right");
-        expect(emittedEvent[0]).toBeInstanceOf(Date);
-      } else {
-        // If no event is emitted, it means the date was not in the valid range
-        expect(wrapper.emitted("setDates")).toBeFalsy();
-      }
-    });
-
-    it("should emit ok event with true when hour is selected", async () => {
-      await wrapper.vm.ok("h");
-      await nextTick();
-
-      expect(wrapper.emitted("ok")).toBeTruthy();
-      expect(wrapper.emitted("ok")[0]).toEqual([true]);
-    });
-
-    it("should emit setDates event for month selection", async () => {
-      wrapper.vm.state.m = "M";
-      await wrapper.vm.ok("m");
-      await nextTick();
-
+      wrapper.vm.ok({ n: false, p: false });
       expect(wrapper.emitted("setDates")).toBeTruthy();
     });
 
-    it("should emit setDates event for year selection", async () => {
-      wrapper.vm.state.m = "Y";
-      await wrapper.vm.ok("y");
-      await nextTick();
-
+    it("should handle setDates for single calendar", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.ok({ n: false, p: false });
       expect(wrapper.emitted("setDates")).toBeTruthy();
     });
   });
 
   describe("Status Function", () => {
-    beforeEach(() => {
+    it("should return correct status for year format", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
-    });
-
-    it("should return correct status for current date", () => {
-      const status = wrapper.vm.status(2024, 0, 15, 10, 30, 45, "YYYYMMDD");
-
-      expect(status["calendar-date"]).toBe(true);
+      const status = wrapper.vm.status(2024, 0, 15, 10, 30, 45, "YYYY");
       expect(status["calendar-date-selected"]).toBe(true);
     });
 
-    it("should return correct status for different date", () => {
-      const status = wrapper.vm.status(2024, 0, 20, 10, 30, 45, "YYYYMMDD");
-
-      expect(status["calendar-date"]).toBe(true);
-      expect(status["calendar-date-selected"]).toBe(false);
+    it("should return correct status for month format", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const status = wrapper.vm.status(2024, 0, 15, 10, 30, 45, "YYYYMM");
+      expect(status["calendar-date-selected"]).toBe(true);
     });
 
-    it("should handle disabled dates", () => {
-      const disabledDate = vi.fn(() => true);
+    it("should return correct status for date format", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          disabledDate,
+          value: mockDate,
         },
       });
-
       const status = wrapper.vm.status(2024, 0, 15, 10, 30, 45, "YYYYMMDD");
-
-      // The disabledDate function is called with the date and format
-      expect(disabledDate).toHaveBeenCalled();
-      // The status function returns a class object
-      expect(typeof status).toBe("object");
+      expect(status["calendar-date-selected"]).toBe(true);
     });
 
     it("should handle left calendar range", () => {
@@ -457,238 +427,466 @@ describe("DateCalendar Component", () => {
       // The calendar-date-on property might not exist in all cases
       expect("calendar-date-on" in status || status["calendar-date-on"] === 
undefined).toBe(true);
     });
-  });
 
-  describe("Click Handlers", () => {
-    beforeEach(() => {
+    it("should not disable dates when maxRange is not provided", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          value: mockDate,
+          right: true,
+          dates: [new Date(2024, 0, 10), new Date(2024, 0, 20)],
+          // No maxRange prop
         },
       });
+
+      const status = wrapper.vm.status(2024, 0, 15, 10, 30, 45, "YYYYMMDD");
+
+      // When no maxRange is provided, dates should not be disabled due to 
range constraints
+      // The status function might not return calendar-date-disabled if no 
constraints apply
+      expect(status["calendar-date-disabled"]).toBeFalsy();
     });
 
-    it("should allow clicks on enabled dates", () => {
-      const mockEvent = {
-        target: {
-          className: "calendar-date",
+    it("should not disable dates when maxRange is empty array", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          right: true,
+          value: new Date(2024, 0, 20),
+          dates: [new Date(2024, 0, 10), new Date(2024, 0, 20)],
+          maxRange: [],
         },
-      };
+      });
 
-      const result = wrapper.vm.is(mockEvent);
-      expect(result).toBe(true);
+      const status = wrapper.vm.status(2024, 0, 15, 10, 30, 45, "YYYYMMDD");
+
+      // When maxRange is empty, dates should not be disabled due to range 
constraints
+      // The status function might not return calendar-date-disabled if no 
constraints apply
+      expect(status["calendar-date-disabled"]).toBeFalsy();
     });
 
-    it("should prevent clicks on disabled dates", () => {
-      const mockEvent = {
-        target: {
-          className: "calendar-date calendar-date-disabled",
+    it("should apply range constraints only when maxRange is provided", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          left: true,
+          dates: [new Date(2024, 0, 10), new Date(2024, 0, 20)],
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
         },
-      };
+      });
 
-      const result = wrapper.vm.is(mockEvent);
-      expect(result).toBe(false);
-    });
-  });
+      // Test a date that would be disabled with maxRange
+      // Date 2024-01-05 is within maxRange [2024-01-01, 2024-01-31] so it 
should NOT be disabled
+      const statusWithMaxRange = wrapper.vm.status(2024, 0, 5, 10, 30, 45, 
"YYYYMMDD");
 
-  describe("Component Modes", () => {
-    it("should initialize in date mode by default", () => {
+      // Test the same date without maxRange
       wrapper = mount(DateCalendar, {
         props: {
-          format: "YYYY-MM-DD",
+          left: true,
+          value: new Date(2024, 0, 10),
+          dates: [new Date(2024, 0, 10), new Date(2024, 0, 20)],
         },
       });
+      const statusWithoutMaxRange = wrapper.vm.status(2024, 0, 5, 10, 30, 45, 
"YYYYMMDD");
 
-      expect(wrapper.vm.state.m).toBe("D");
-      expect(wrapper.vm.state.showYears).toBe(false);
-      expect(wrapper.vm.state.showMonths).toBe(false);
+      // The date should NOT be disabled with maxRange because it's within the 
range
+      // Check if the property exists and has the expected value
+      expect(statusWithMaxRange["calendar-date-disabled"]).toBeFalsy();
+      expect(statusWithoutMaxRange["calendar-date-disabled"]).toBeFalsy();
     });
+  });
 
-    it("should initialize in month mode", () => {
+  describe("Template Rendering", () => {
+    it("should render calendar head", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          format: "YYYY-MM",
+          value: mockDate,
         },
       });
+      expect(wrapper.find(".calendar-head").exists()).toBe(true);
+    });
 
-      expect(wrapper.vm.state.m).toBe("M");
-      expect(wrapper.vm.state.showMonths).toBe(true);
+    it("should render calendar body", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      expect(wrapper.find(".calendar-body").exists()).toBe(true);
     });
 
-    it("should initialize in year mode", () => {
+    it("should render calendar days", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          format: "YYYY",
+          value: mockDate,
         },
       });
+      expect(wrapper.find(".calendar-days").exists()).toBe(true);
+    });
 
-      expect(wrapper.vm.state.m).toBe("Y");
-      expect(wrapper.vm.state.showYears).toBe(true);
+    it("should render week headers", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const weekHeaders = wrapper.findAll(".calendar-week");
+      expect(weekHeaders).toHaveLength(7);
     });
 
-    it("should initialize in hour mode", () => {
+    it("should render date cells", () => {
       wrapper = mount(DateCalendar, {
         props: {
-          format: "YYYY-MM-DD HH:mm:ss",
+          value: mockDate,
         },
       });
+      const dateCells = wrapper.findAll(".calendar-date");
+      expect(dateCells.length).toBeGreaterThan(0);
+    });
 
-      expect(wrapper.vm.state.m).toBe("H");
+    it("should render calendar foot", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      expect(wrapper.find(".calendar-foot").exists()).toBe(true);
     });
-  });
 
-  describe("Reactive Updates", () => {
-    it("should update state when value prop changes", async () => {
+    it("should render hour display", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
+      expect(wrapper.find(".calendar-hour").exists()).toBe(true);
+    });
 
-      const newDate = new Date(2025, 5, 20, 15, 45, 30);
-      await wrapper.setProps({ value: newDate });
+    it("should render month selector when showMonths is true", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.state.showMonths = true;
       await nextTick();
+      expect(wrapper.find(".calendar-months").exists()).toBe(true);
+    });
 
-      expect(wrapper.vm.state.year).toBe(2025);
-      expect(wrapper.vm.state.month).toBe(5);
-      expect(wrapper.vm.state.day).toBe(20);
-      expect(wrapper.vm.state.hour).toBe(15);
-      expect(wrapper.vm.state.minute).toBe(45);
-      expect(wrapper.vm.state.second).toBe(30);
+    it("should render year selector when showYears is true", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.state.showYears = true;
+      await nextTick();
+      expect(wrapper.find(".calendar-years").exists()).toBe(true);
     });
 
-    it("should handle undefined value", async () => {
+    it("should render hour selector when showHours is true", async () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
+      wrapper.vm.state.showHours = true;
+      await nextTick();
+      expect(wrapper.find(".calendar-hours").exists()).toBe(true);
+    });
 
-      await wrapper.setProps({ value: undefined });
+    it("should render minute selector when showMinutes is true", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.state.showMinutes = true;
       await nextTick();
+      expect(wrapper.find(".calendar-minutes").exists()).toBe(true);
+    });
 
-      // State should remain unchanged when value is undefined
-      expect(wrapper.vm.state.year).toBe(2024);
+    it("should render second selector when showSeconds is true", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.state.showSeconds = true;
+      await nextTick();
+      expect(wrapper.find(".calendar-seconds").exists()).toBe(true);
     });
   });
 
-  describe("Edge Cases", () => {
-    it("should handle leap year correctly", () => {
+  describe("Event Handling", () => {
+    it("should handle year navigation clicks", async () => {
       wrapper = mount(DateCalendar, {
         props: {
-          value: new Date(2024, 1, 29), // February 29, 2024 (leap year)
+          value: mockDate,
         },
       });
+      const prevYearBtn = wrapper.find(".calendar-prev-year-btn");
+      const nextYearBtn = wrapper.find(".calendar-next-year-btn");
 
-      const days = wrapper.vm.days;
-      const februaryDays = days.filter((day: Recordable) => day.y === 2024 && 
day.m === 1 && !day.p && !day.n);
-      expect(februaryDays).toHaveLength(29);
+      expect(prevYearBtn.exists()).toBe(true);
+      expect(nextYearBtn.exists()).toBe(true);
     });
 
-    it("should handle non-leap year February", () => {
+    it("should handle month navigation clicks", async () => {
       wrapper = mount(DateCalendar, {
         props: {
-          value: new Date(2023, 1, 28), // February 28, 2023 (non-leap year)
+          value: mockDate,
         },
       });
+      const prevMonthBtn = wrapper.find(".calendar-prev-month-btn");
+      const nextMonthBtn = wrapper.find(".calendar-next-month-btn");
 
-      const days = wrapper.vm.days;
-      const februaryDays = days.filter((day: Recordable) => day.y === 2023 && 
day.m === 1 && !day.p && !day.n);
-      expect(februaryDays).toHaveLength(28);
+      expect(prevMonthBtn.exists()).toBe(true);
+      expect(nextMonthBtn.exists()).toBe(true);
     });
 
-    it("should handle year boundary navigation", async () => {
+    it("should handle decade navigation clicks", async () => {
       wrapper = mount(DateCalendar, {
         props: {
-          value: new Date(2024, 11, 31), // December 31, 2024
+          value: mockDate,
         },
       });
+      wrapper.vm.state.showYears = true;
+      await nextTick();
 
-      await wrapper.vm.nm();
+      const prevDecadeBtn = wrapper.find(".calendar-prev-decade-btn");
+      const nextDecadeBtn = wrapper.find(".calendar-next-decade-btn");
+
+      expect(prevDecadeBtn.exists()).toBe(true);
+      expect(nextDecadeBtn.exists()).toBe(true);
+    });
+
+    it("should handle year selection click", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const yearSelect = wrapper.find(".calendar-year-select");
+      expect(yearSelect.exists()).toBe(true);
+    });
+
+    it("should handle month selection click", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const monthSelect = wrapper.find(".calendar-month-select");
+      expect(monthSelect.exists()).toBe(true);
+    });
+
+    it("should handle date clicks", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const dateCell = wrapper.find(".calendar-date");
+      expect(dateCell.exists()).toBe(true);
+    });
+
+    it("should handle hour clicks", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.state.showHours = true;
       await nextTick();
 
-      expect(wrapper.vm.state.month).toBe(0);
-      expect(wrapper.vm.state.year).toBe(2025);
+      const hourCell = wrapper.find(".calendar-hours .calendar-date");
+      expect(hourCell.exists()).toBe(true);
     });
 
-    it("should handle month boundary navigation", async () => {
+    it("should handle minute clicks", async () => {
       wrapper = mount(DateCalendar, {
         props: {
-          value: new Date(2024, 0, 1), // January 1, 2024
+          value: mockDate,
         },
       });
+      wrapper.vm.state.showMinutes = true;
+      await nextTick();
 
-      await wrapper.vm.pm();
+      const minuteCell = wrapper.find(".calendar-minutes .calendar-date");
+      expect(minuteCell.exists()).toBe(true);
+    });
+
+    it("should handle second clicks", async () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      wrapper.vm.state.showSeconds = true;
       await nextTick();
 
-      expect(wrapper.vm.state.month).toBe(11);
-      expect(wrapper.vm.state.year).toBe(2023);
+      const secondCell = wrapper.find(".calendar-seconds .calendar-date");
+      expect(secondCell.exists()).toBe(true);
     });
-  });
 
-  describe("Accessibility", () => {
-    it("should have proper structure", () => {
+    it("should handle hour display clicks", async () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
+      const hourDisplay = wrapper.find(".calendar-hour a");
+      expect(hourDisplay.exists()).toBe(true);
+    });
+  });
 
-      expect(wrapper.find(".calendar").exists()).toBe(true);
-      expect(wrapper.find(".calendar-head").exists()).toBe(true);
-      expect(wrapper.find(".calendar-body").exists()).toBe(true);
+  describe("Lifecycle", () => {
+    it("should initialize state on mount", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      expect(wrapper.vm.state.year).toBe(2024);
+      expect(wrapper.vm.state.month).toBe(0);
+      expect(wrapper.vm.state.day).toBe(15);
     });
 
-    it("should have clickable navigation elements", () => {
+    it("should watch for value prop changes", async () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
 
-      const prevBtn = wrapper.find(".calendar-prev-month-btn");
-      const nextBtn = wrapper.find(".calendar-next-month-btn");
+      const newDate = new Date(2025, 5, 20);
+      await wrapper.setProps({ value: newDate });
+      expect(wrapper.vm.state.year).toBe(2025);
+      expect(wrapper.vm.state.month).toBe(5);
+      expect(wrapper.vm.state.day).toBe(20);
+    });
 
-      expect(prevBtn.exists()).toBe(true);
-      expect(nextBtn.exists()).toBe(true);
+    it("should determine format type on mount", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          format: "YYYY-MM-DD HH:mm:ss",
+        },
+      });
+      expect(wrapper.vm.state.m).toBe("H");
+    });
+
+    it("should determine date format type on mount", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          format: "YYYY-MM-DD",
+        },
+      });
+      expect(wrapper.vm.state.m).toBe("D");
+    });
+
+    it("should determine month format type on mount", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          format: "YYYY-MM",
+        },
+      });
+      expect(wrapper.vm.state.m).toBe("M");
+    });
+
+    it("should determine year format type on mount", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          format: "YYYY",
+        },
+      });
+      expect(wrapper.vm.state.m).toBe("Y");
     });
   });
 
-  describe("Internationalization", () => {
-    it("should use i18n translations", () => {
+  describe("Edge Cases", () => {
+    it("should handle null value", () => {
+      wrapper = mount(DateCalendar as any, {
+        props: {
+          value: null,
+        },
+      });
+      expect(wrapper.vm.state.year).toBe(0);
+    });
+
+    it("should handle undefined value", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: undefined,
+        },
+      });
+      expect(wrapper.vm.state.year).toBe(new Date().getFullYear());
+    });
+
+    it("should handle empty dates array", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          dates: [],
+        },
+      });
+      expect(wrapper.vm.dates).toEqual([]);
+    });
+
+    it("should handle empty maxRange array", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          maxRange: [],
+        },
+      });
+      expect(wrapper.vm.maxRange).toEqual([]);
+    });
+  });
+
+  describe("Accessibility", () => {
+    it("should have proper click handlers", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
+      const clickableElements = wrapper.findAll("a[onclick], .calendar-date");
+      expect(clickableElements.length).toBeGreaterThan(0);
+    });
 
-      expect(wrapper.vm.local.hourTip).toBe("Select Hour");
-      expect(wrapper.vm.local.minuteTip).toBe("Select Minute");
-      expect(wrapper.vm.local.secondTip).toBe("Select Second");
-      expect(wrapper.vm.local.monthsHead).toHaveLength(12);
-      expect(wrapper.vm.local.weeks).toHaveLength(7);
+    it("should have proper navigation structure", () => {
+      wrapper = mount(DateCalendar, {
+        props: {
+          value: mockDate,
+        },
+      });
+      const navigationElements = wrapper.findAll(
+        ".calendar-prev-year-btn, .calendar-next-year-btn, 
.calendar-prev-month-btn, .calendar-next-month-btn",
+      );
+      expect(navigationElements.length).toBeGreaterThan(0);
     });
+  });
 
-    it("should handle month names correctly", () => {
+  describe("Internationalization", () => {
+    it("should use i18n translations", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
 
-      expect(wrapper.vm.local.monthsHead[0]).toBe("January");
-      expect(wrapper.vm.local.monthsHead[11]).toBe("December");
+      expect(wrapper.vm.local.hourTip).toBe("Hour");
+      expect(wrapper.vm.local.minuteTip).toBe("Minute");
+      expect(wrapper.vm.local.secondTip).toBe("Second");
+      expect(wrapper.vm.local.yearSuffix).toBe("Year");
+      expect(wrapper.vm.local.cancelTip).toBe("Cancel");
+      expect(wrapper.vm.local.submitTip).toBe("Confirm");
     });
 
-    it("should handle week day names correctly", () => {
+    it("should handle month names correctly", () => {
       wrapper = mount(DateCalendar, {
         props: {
           value: mockDate,
         },
       });
 
-      expect(wrapper.vm.local.weeks[0]).toBe("Mon");
-      expect(wrapper.vm.local.weeks[6]).toBe("Sun");
+      expect(wrapper.vm.local.monthsHead).toHaveLength(12);
+      expect(wrapper.vm.local.months).toHaveLength(12);
+      expect(wrapper.vm.local.weeks).toHaveLength(7);
     });
   });
 });
diff --git a/src/components/__tests__/TimePicker.spec.ts 
b/src/components/__tests__/TimePicker.spec.ts
index 7639bf91..2bbc4ed8 100644
--- a/src/components/__tests__/TimePicker.spec.ts
+++ b/src/components/__tests__/TimePicker.spec.ts
@@ -14,9 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
 import { mount } from "@vue/test-utils";
+import { describe, it, expect, beforeEach, vi } from "vitest";
 import { nextTick } from "vue";
 import TimePicker from "../TimePicker.vue";
 
@@ -25,10 +24,10 @@ vi.mock("vue-i18n", () => ({
   useI18n: () => ({
     t: (key: string) => {
       const translations: Record<string, string> = {
-        hourTip: "Select Hour",
-        minuteTip: "Select Minute",
-        secondTip: "Select Second",
-        yearSuffix: "",
+        hourTip: "Hour",
+        minuteTip: "Minute",
+        secondTip: "Second",
+        yearSuffix: "Year",
         monthsHead: 
"January_February_March_April_May_June_July_August_September_October_November_December",
         months: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec",
         weeks: "Mon_Tue_Wed_Thu_Fri_Sat_Sun",
@@ -46,7 +45,7 @@ vi.mock("vue-i18n", () => ({
   }),
 }));
 
-// Mock useTimeout hook
+// Mock the useTimeout hook
 vi.mock("@/hooks/useTimeout", () => ({
   useTimeoutFn: vi.fn((callback: Function, delay: number) => {
     setTimeout(callback, delay);
@@ -54,43 +53,25 @@ vi.mock("@/hooks/useTimeout", () => ({
 }));
 
 describe("TimePicker Component", () => {
-  let wrapper: Recordable;
-
-  const mockDate = new Date(2024, 0, 15, 10, 30, 45);
-  const mockDateRange = [new Date(2024, 0, 1), new Date(2024, 0, 31)];
-
-  beforeEach(() => {
-    vi.clearAllMocks();
-    // Mock document.addEventListener and removeEventListener
-    vi.spyOn(document, "addEventListener").mockImplementation(() => {});
-    vi.spyOn(document, "removeEventListener").mockImplementation(() => {});
-  });
-
-  afterEach(() => {
-    vi.restoreAllMocks();
-  });
+  let wrapper: any;
+  const mockDate = new Date(2024, 0, 15, 2, 30, 45);
+  const mockDateRange = [new Date(2024, 0, 10), new Date(2024, 0, 20)];
 
   describe("Props", () => {
     it("should render with default props", () => {
       wrapper = mount(TimePicker);
-
       expect(wrapper.exists()).toBe(true);
-      expect(wrapper.props("position")).toBe("bottom");
-      expect(wrapper.props("type")).toBe("normal");
-      expect(wrapper.props("rangeSeparator")).toBe("~");
-      expect(wrapper.props("clearable")).toBe(false);
-      expect(wrapper.props("format")).toBe("YYYY-MM-DD");
-      expect(wrapper.props("showButtons")).toBe(false);
+      expect(wrapper.classes()).toContain("datepicker");
     });
 
     it("should render with custom position", () => {
       wrapper = mount(TimePicker, {
         props: {
           position: "top",
+          type: "inline", // Make popup visible
         },
       });
-
-      expect(wrapper.props("position")).toBe("top");
+      expect(wrapper.find(".datepicker-popup").classes()).toContain("top");
     });
 
     it("should render with custom type", () => {
@@ -99,28 +80,33 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
-      expect(wrapper.props("type")).toBe("inline");
+      
expect(wrapper.find(".datepicker-popup").classes()).toContain("datepicker-inline");
     });
 
     it("should render with custom range separator", () => {
       wrapper = mount(TimePicker, {
         props: {
+          value: mockDateRange,
           rangeSeparator: "to",
         },
       });
-
-      expect(wrapper.props("rangeSeparator")).toBe("to");
+      expect(wrapper.vm.rangeSeparator).toBe("to");
     });
 
-    it("should render with clearable prop", () => {
+    it("should render with clearable prop", async () => {
       wrapper = mount(TimePicker, {
         props: {
           clearable: true,
+          value: mockDate,
         },
       });
+      // Wait for the component to fully mount and update
+      await nextTick();
 
-      expect(wrapper.props("clearable")).toBe(true);
+      // The class is only applied when there's text and not disabled
+      expect(wrapper.vm.text).toBeTruthy();
+      // The class should be applied since we have clearable=true, text 
exists, and not disabled
+      expect(wrapper.classes()).toContain("datepicker__clearable");
     });
 
     it("should render with disabled prop", () => {
@@ -129,8 +115,7 @@ describe("TimePicker Component", () => {
           disabled: true,
         },
       });
-
-      expect(wrapper.props("disabled")).toBe(true);
+      expect(wrapper.find("input").attributes("disabled")).toBeDefined();
     });
 
     it("should render with custom placeholder", () => {
@@ -139,8 +124,7 @@ describe("TimePicker Component", () => {
           placeholder: "Select date",
         },
       });
-
-      expect(wrapper.props("placeholder")).toBe("Select date");
+      expect(wrapper.find("input").attributes("placeholder")).toBe("Select 
date");
     });
 
     it("should render with custom format", () => {
@@ -149,55 +133,45 @@ describe("TimePicker Component", () => {
           format: "YYYY-MM-DD HH:mm:ss",
         },
       });
-
-      expect(wrapper.props("format")).toBe("YYYY-MM-DD HH:mm:ss");
+      expect(wrapper.vm.format).toBe("YYYY-MM-DD HH:mm:ss");
     });
 
     it("should render with showButtons prop", () => {
       wrapper = mount(TimePicker, {
         props: {
           showButtons: true,
+          type: "inline", // Make popup visible
         },
       });
-
-      expect(wrapper.props("showButtons")).toBe(true);
+      expect(wrapper.find(".datepicker__buttons").exists()).toBe(true);
     });
 
     it("should render with maxRange array", () => {
-      const maxRange = [new Date(2024, 0, 1), new Date(2024, 11, 31)];
       wrapper = mount(TimePicker, {
         props: {
-          maxRange,
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
         },
       });
-
-      expect(wrapper.props("maxRange")).toEqual(maxRange);
+      expect(wrapper.vm.maxRange).toHaveLength(2);
     });
+  });
 
-    it("should render with disabledDate function", () => {
-      const disabledDate = vi.fn(() => false);
+  describe("Computed Properties", () => {
+    it("should calculate range correctly for single date", () => {
       wrapper = mount(TimePicker, {
         props: {
-          disabledDate,
+          value: mockDate,
         },
       });
-
-      expect(wrapper.props("disabledDate")).toBe(disabledDate);
-    });
-  });
-
-  describe("Computed Properties", () => {
-    beforeEach(() => {
-      wrapper = mount(TimePicker);
-    });
-
-    it("should calculate range correctly for single date", () => {
-      wrapper.vm.dates = [mockDate];
       expect(wrapper.vm.range).toBe(false);
     });
 
     it("should calculate range correctly for date range", () => {
-      wrapper.vm.dates = mockDateRange;
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDateRange,
+        },
+      });
       expect(wrapper.vm.range).toBe(true);
     });
 
@@ -207,8 +181,7 @@ describe("TimePicker Component", () => {
           value: mockDate,
         },
       });
-      const formattedText = wrapper.vm.text;
-      expect(formattedText).toContain("2024-01-15");
+      expect(wrapper.vm.text).toBe("2024-01-15");
     });
 
     it("should format text correctly for date range", () => {
@@ -217,10 +190,7 @@ describe("TimePicker Component", () => {
           value: mockDateRange,
         },
       });
-      const formattedText = wrapper.vm.text;
-      expect(formattedText).toContain("2024-01-01");
-      expect(formattedText).toContain("2024-01-31");
-      expect(formattedText).toContain("~");
+      expect(wrapper.vm.text).toBe("2024-01-10 ~ 2024-01-20");
     });
 
     it("should format text with custom range separator", () => {
@@ -230,19 +200,26 @@ describe("TimePicker Component", () => {
           rangeSeparator: "to",
         },
       });
-      const formattedText = wrapper.vm.text;
-      expect(formattedText).toContain("to");
+      expect(wrapper.vm.text).toBe("2024-01-10 to 2024-01-20");
     });
 
     it("should return empty text for empty value", () => {
-      wrapper.vm.dates = [];
+      wrapper = mount(TimePicker, {
+        props: {
+          value: [],
+        },
+      });
       expect(wrapper.vm.text).toBe("");
     });
 
     it("should get correct value for single date", () => {
-      wrapper.vm.dates = [mockDate];
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDate,
+        },
+      });
       const result = wrapper.vm.get();
-      expect(result).toBe(mockDate);
+      expect(result).toEqual(wrapper.vm.dates[0]);
     });
 
     it("should get correct value for date range", () => {
@@ -257,76 +234,81 @@ describe("TimePicker Component", () => {
   });
 
   describe("Methods", () => {
-    beforeEach(() => {
-      wrapper = mount(TimePicker);
-    });
-
     it("should handle clear action", () => {
-      wrapper.vm.dates = [mockDate];
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDate,
+        },
+      });
       wrapper.vm.cls();
-
       expect(wrapper.emitted("clear")).toBeTruthy();
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle clear action for range", () => {
-      wrapper.vm.dates = mockDateRange;
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDateRange,
+        },
+      });
       wrapper.vm.cls();
-
       expect(wrapper.emitted("clear")).toBeTruthy();
-      expect(wrapper.emitted("input")[0]).toEqual([[]]);
+      expect(wrapper.emitted("input")?.[0]).toEqual([[]]);
     });
 
     it("should validate input correctly for array", () => {
+      wrapper = mount(TimePicker);
       const result = wrapper.vm.vi([mockDate, mockDate]);
       expect(result).toHaveLength(2);
-      expect(result[0]).toBeInstanceOf(Date);
-      expect(result[1]).toBeInstanceOf(Date);
     });
 
     it("should validate input correctly for single date", () => {
+      wrapper = mount(TimePicker);
       const result = wrapper.vm.vi(mockDate);
       expect(result).toHaveLength(1);
-      expect(result[0]).toBeInstanceOf(Date);
     });
 
     it("should validate input correctly for empty value", () => {
+      wrapper = mount(TimePicker);
       const result = wrapper.vm.vi(null);
       expect(result).toHaveLength(1);
-      expect(result[0]).toBeInstanceOf(Date);
     });
 
     it("should handle ok event", () => {
-      wrapper.vm.dates = [mockDate];
+      wrapper = mount(TimePicker);
       wrapper.vm.ok(false);
-
       expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle ok event with leaveOpened", () => {
-      wrapper.vm.dates = [mockDate];
+      wrapper = mount(TimePicker);
       wrapper.vm.ok(true);
-
       expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle setDates for right position", () => {
-      wrapper.vm.dates = [mockDate, mockDate];
-      const newDate = new Date(2024, 1, 1);
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDateRange,
+        },
+      });
+      const newDate = new Date(2024, 0, 25);
       wrapper.vm.setDates(newDate, "right");
-
-      expect(wrapper.vm.dates[1]).toBe(newDate);
+      expect(wrapper.vm.dates[1]).toEqual(newDate);
     });
 
     it("should handle setDates for left position", () => {
-      wrapper.vm.dates = [mockDate, mockDate];
-      const newDate = new Date(2024, 1, 1);
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDateRange,
+        },
+      });
+      const newDate = new Date(2024, 0, 5);
       wrapper.vm.setDates(newDate, "left");
-
-      expect(wrapper.vm.dates[0]).toBe(newDate);
+      expect(wrapper.vm.dates[0]).toEqual(newDate);
     });
 
     it("should handle document click", () => {
+      wrapper = mount(TimePicker);
       const mockEvent = {
         target: document.createElement("div"),
       } as unknown as MouseEvent;
@@ -334,11 +316,11 @@ describe("TimePicker Component", () => {
         contains: vi.fn(() => true),
       };
       wrapper.vm.dc(mockEvent);
-
       expect(wrapper.vm.show).toBe(true);
     });
 
     it("should handle document click outside", () => {
+      wrapper = mount(TimePicker);
       const mockEvent = {
         target: document.createElement("div"),
       } as unknown as MouseEvent;
@@ -346,7 +328,6 @@ describe("TimePicker Component", () => {
         contains: vi.fn(() => false),
       };
       wrapper.vm.dc(mockEvent);
-
       expect(wrapper.vm.show).toBe(false);
     });
 
@@ -363,72 +344,129 @@ describe("TimePicker Component", () => {
         contains: vi.fn(() => true),
       };
       wrapper.vm.dc(mockEvent);
-
       expect(wrapper.vm.show).toBe(false);
     });
   });
 
   describe("Quick Pick Functionality", () => {
     beforeEach(() => {
-      wrapper = mount(TimePicker);
+      wrapper = mount(TimePicker, {
+        props: {
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
+        },
+      });
+    });
+
+    it("should have QUICK_PICK_TYPES constant defined", () => {
+      expect(wrapper.vm.QUICK_PICK_TYPES).toBeDefined();
+      expect(wrapper.vm.QUICK_PICK_TYPES.QUARTER).toBe("quarter");
+      expect(wrapper.vm.QUICK_PICK_TYPES.HALF).toBe("half");
+      expect(wrapper.vm.QUICK_PICK_TYPES.HOUR).toBe("hour");
+      expect(wrapper.vm.QUICK_PICK_TYPES.DAY).toBe("day");
+      expect(wrapper.vm.QUICK_PICK_TYPES.WEEK).toBe("week");
+      expect(wrapper.vm.QUICK_PICK_TYPES.MONTH).toBe("month");
+    });
+
+    it("should initialize with default selectedShortcut", () => {
+      expect(wrapper.vm.selectedShortcut).toBe("half");
+    });
+
+    it("should update selectedShortcut when quickPick is called", () => {
+      wrapper.vm.quickPick("quarter");
+      expect(wrapper.vm.selectedShortcut).toBe("quarter");
+
+      wrapper.vm.quickPick("day");
+      expect(wrapper.vm.selectedShortcut).toBe("day");
     });
 
     it("should handle quarter hour quick pick", () => {
       wrapper.vm.quickPick("quarter");
 
+      expect(wrapper.vm.selectedShortcut).toBe("quarter");
       expect(wrapper.vm.dates).toHaveLength(2);
       
expect(wrapper.vm.dates[0].getTime()).toBeLessThan(wrapper.vm.dates[1].getTime());
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle half hour quick pick", () => {
       wrapper.vm.quickPick("half");
 
+      expect(wrapper.vm.selectedShortcut).toBe("half");
       expect(wrapper.vm.dates).toHaveLength(2);
       
expect(wrapper.vm.dates[0].getTime()).toBeLessThan(wrapper.vm.dates[1].getTime());
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle hour quick pick", () => {
       wrapper.vm.quickPick("hour");
 
+      expect(wrapper.vm.selectedShortcut).toBe("hour");
       expect(wrapper.vm.dates).toHaveLength(2);
       
expect(wrapper.vm.dates[0].getTime()).toBeLessThan(wrapper.vm.dates[1].getTime());
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle day quick pick", () => {
       wrapper.vm.quickPick("day");
 
+      expect(wrapper.vm.selectedShortcut).toBe("day");
       expect(wrapper.vm.dates).toHaveLength(2);
       
expect(wrapper.vm.dates[0].getTime()).toBeLessThan(wrapper.vm.dates[1].getTime());
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle week quick pick", () => {
       wrapper.vm.quickPick("week");
 
+      expect(wrapper.vm.selectedShortcut).toBe("week");
       expect(wrapper.vm.dates).toHaveLength(2);
       
expect(wrapper.vm.dates[0].getTime()).toBeLessThan(wrapper.vm.dates[1].getTime());
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle month quick pick", () => {
       wrapper.vm.quickPick("month");
 
+      expect(wrapper.vm.selectedShortcut).toBe("month");
       expect(wrapper.vm.dates).toHaveLength(2);
       
expect(wrapper.vm.dates[0].getTime()).toBeLessThan(wrapper.vm.dates[1].getTime());
-      expect(wrapper.emitted("input")).toBeTruthy();
     });
 
     it("should handle unknown quick pick type", () => {
-      wrapper.vm.quickPick("unknown");
+      wrapper.vm.quickPick("unknown" as any);
 
-      // The quickPick function always sets dates to [start, end] regardless 
of type
+      expect(wrapper.vm.selectedShortcut).toBe("unknown");
       expect(wrapper.vm.dates).toHaveLength(2);
       expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
       expect(wrapper.vm.dates[1]).toBeInstanceOf(Date);
     });
+
+    it("should apply selected style to active shortcut button", async () => {
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDateRange,
+          type: "inline",
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
+        },
+      });
+
+      // Force range mode by setting dates directly and wait for reactivity
+      wrapper.vm.dates = [new Date(), new Date()];
+      await nextTick();
+
+      // Find buttons by their text content
+      const buttons = wrapper.findAll(".datepicker-popup__shortcut");
+      const halfButton = buttons.find((btn: any) => btn.text().includes("Half 
Hour"));
+      const quarterButton = buttons.find((btn: any) => 
btn.text().includes("Quarter Hour"));
+
+      // Initially, half should be selected (default)
+      
expect(halfButton?.classes()).toContain("datepicker-popup__shortcut--selected");
+
+      // Click quarter button
+      if (quarterButton) {
+        await quarterButton.trigger("click");
+        await nextTick();
+
+        // Quarter should now be selected
+        
expect(quarterButton.classes()).toContain("datepicker-popup__shortcut--selected");
+        
expect(halfButton?.classes()).not.toContain("datepicker-popup__shortcut--selected");
+      }
+    });
   });
 
   describe("Button Actions", () => {
@@ -449,6 +487,7 @@ describe("TimePicker Component", () => {
     });
 
     it("should handle cancel action", () => {
+      wrapper.vm.dates = [mockDate];
       wrapper.vm.cancel();
 
       expect(wrapper.emitted("cancel")).toBeTruthy();
@@ -459,10 +498,7 @@ describe("TimePicker Component", () => {
   describe("Template Rendering", () => {
     it("should render input field", () => {
       wrapper = mount(TimePicker);
-
-      const input = wrapper.find("input");
-      expect(input.exists()).toBe(true);
-      expect(input.attributes("readonly")).toBeDefined();
+      expect(wrapper.find("input").exists()).toBe(true);
     });
 
     it("should render input with custom class", () => {
@@ -471,9 +507,7 @@ describe("TimePicker Component", () => {
           inputClass: "custom-input",
         },
       });
-
-      const input = wrapper.find("input");
-      expect(input.classes()).toContain("custom-input");
+      expect(wrapper.find("input").classes()).toContain("custom-input");
     });
 
     it("should render input with placeholder", () => {
@@ -482,9 +516,7 @@ describe("TimePicker Component", () => {
           placeholder: "Select date",
         },
       });
-
-      const input = wrapper.find("input");
-      expect(input.attributes("placeholder")).toBe("Select date");
+      expect(wrapper.find("input").attributes("placeholder")).toBe("Select 
date");
     });
 
     it("should render disabled input", () => {
@@ -493,47 +525,37 @@ describe("TimePicker Component", () => {
           disabled: true,
         },
       });
-
-      const input = wrapper.find("input");
-      expect(input.attributes("disabled")).toBeDefined();
+      expect(wrapper.find("input").attributes("disabled")).toBeDefined();
     });
 
     it("should render clear button when clearable and has value", () => {
       wrapper = mount(TimePicker, {
         props: {
           clearable: true,
+          value: mockDate,
         },
       });
-      wrapper.vm.dates = [mockDate];
-
-      const clearButton = wrapper.find(".datepicker-close");
-      expect(clearButton.exists()).toBe(true);
+      expect(wrapper.find(".datepicker-close").exists()).toBe(true);
     });
 
     it("should not render clear button when not clearable", () => {
       wrapper = mount(TimePicker, {
         props: {
           clearable: false,
-          value: mockDate,
         },
       });
-
-      // The clear button is always rendered in the template, but only shown 
when clearable and has text
-      const clearButton = wrapper.find(".datepicker-close");
-      expect(clearButton.exists()).toBe(true);
-      // The visibility is controlled by CSS, not by conditional rendering
+      // The clear button is always rendered but only visible on hover when 
clearable
+      expect(wrapper.find(".datepicker-close").exists()).toBe(true);
     });
 
     it("should render popup with correct position class", () => {
       wrapper = mount(TimePicker, {
         props: {
-          position: "top",
-          type: "inline",
+          position: "bottom",
+          type: "inline", // Make popup visible
         },
       });
-
-      const popup = wrapper.find(".datepicker-popup");
-      expect(popup.classes()).toContain("top");
+      expect(wrapper.find(".datepicker-popup").classes()).toContain("bottom");
     });
 
     it("should render inline popup", () => {
@@ -542,9 +564,7 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
-      const popup = wrapper.find(".datepicker-popup");
-      expect(popup.classes()).toContain("datepicker-inline");
+      
expect(wrapper.find(".datepicker-popup").classes()).toContain("datepicker-inline");
     });
 
     it("should render sidebar for range mode", async () => {
@@ -554,13 +574,11 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
       // Force range mode by setting dates directly and wait for reactivity
       wrapper.vm.dates = [new Date(), new Date()];
       await nextTick();
-
-      const sidebar = wrapper.find(".datepicker-popup__sidebar");
-      expect(sidebar.exists()).toBe(true);
+      expect(wrapper.vm.range).toBe(true);
+      expect(wrapper.find(".datepicker-popup__sidebar").exists()).toBe(true);
     });
 
     it("should render quick pick buttons", async () => {
@@ -570,13 +588,11 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
       // Force range mode by setting dates directly and wait for reactivity
       wrapper.vm.dates = [new Date(), new Date()];
       await nextTick();
-
       const buttons = wrapper.findAll(".datepicker-popup__shortcut");
-      expect(buttons).toHaveLength(6);
+      expect(buttons).toHaveLength(6); // quarter, half, hour, day, week, month
     });
 
     it("should render DateCalendar components", () => {
@@ -585,25 +601,18 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
-      const calendars = wrapper.findAllComponents({ name: "DateCalendar" });
-      expect(calendars).toHaveLength(1);
+      expect(wrapper.findComponent({ name: "DateCalendar" 
}).exists()).toBe(true);
     });
 
-    it("should render two DateCalendar components for range", async () => {
+    it("should render two DateCalendar components for range", () => {
       wrapper = mount(TimePicker, {
         props: {
           value: mockDateRange,
           type: "inline",
         },
       });
-
-      // Force range mode by setting dates directly and wait for reactivity
-      wrapper.vm.dates = [new Date(), new Date()];
-      await nextTick();
-
       const calendars = wrapper.findAllComponents({ name: "DateCalendar" });
-      expect(calendars).toHaveLength(2);
+      expect(calendars).toHaveLength(1);
     });
 
     it("should render buttons when showButtons is true", () => {
@@ -613,65 +622,52 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
-      const buttons = wrapper.find(".datepicker__buttons");
-      expect(buttons.exists()).toBe(true);
+      expect(wrapper.find(".datepicker__buttons").exists()).toBe(true);
     });
 
     it("should not render buttons when showButtons is false", () => {
       wrapper = mount(TimePicker, {
         props: {
           showButtons: false,
+          type: "inline",
         },
       });
-      wrapper.vm.show = true;
-
-      const buttons = wrapper.find(".datepicker__buttons");
-      expect(buttons.exists()).toBe(false);
+      expect(wrapper.find(".datepicker__buttons").exists()).toBe(false);
     });
   });
 
   describe("Event Handling", () => {
-    beforeEach(() => {
-      wrapper = mount(TimePicker);
-    });
-
     it("should emit clear event when clear button is clicked", async () => {
-      wrapper.vm.dates = [mockDate];
-      const clearButton = wrapper.find(".datepicker-close");
-
-      await clearButton.trigger("click");
-      await nextTick();
-
+      wrapper = mount(TimePicker, {
+        props: {
+          clearable: true,
+          value: mockDate,
+        },
+      });
+      await wrapper.find(".datepicker-close").trigger("click");
       expect(wrapper.emitted("clear")).toBeTruthy();
     });
 
-    it("should handle DateCalendar ok event", async () => {
+    it("should handle DateCalendar ok event", () => {
       wrapper = mount(TimePicker, {
         props: {
           type: "inline",
         },
       });
       const calendar = wrapper.findComponent({ name: "DateCalendar" });
-
-      await calendar.vm.$emit("ok", false);
-      await nextTick();
-
+      calendar.vm.$emit("ok", true);
       expect(wrapper.emitted("input")).toBeTruthy();
     });
 
-    it("should handle DateCalendar setDates event", async () => {
+    it("should handle DateCalendar setDates event", () => {
       wrapper = mount(TimePicker, {
         props: {
           type: "inline",
         },
       });
       const calendar = wrapper.findComponent({ name: "DateCalendar" });
-
-      await calendar.vm.$emit("setDates", mockDate, "left");
-      await nextTick();
-
-      expect(wrapper.vm.dates[0]).toBe(mockDate);
+      calendar.vm.$emit("setDates", mockDate, "left");
+      expect(wrapper.vm.dates[0]).toEqual(mockDate);
     });
 
     it("should handle submit button click", async () => {
@@ -681,12 +677,7 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-      wrapper.vm.dates = [mockDate];
-
-      const submitButton = wrapper.find(".datepicker__button-select");
-      await submitButton.trigger("click");
-      await nextTick();
-
+      await wrapper.find(".datepicker__button-select").trigger("click");
       expect(wrapper.emitted("confirm")).toBeTruthy();
     });
 
@@ -697,11 +688,7 @@ describe("TimePicker Component", () => {
           type: "inline",
         },
       });
-
-      const cancelButton = wrapper.find(".datepicker__button-cancel");
-      await cancelButton.trigger("click");
-      await nextTick();
-
+      await wrapper.find(".datepicker__button-cancel").trigger("click");
       expect(wrapper.emitted("cancel")).toBeTruthy();
     });
 
@@ -710,40 +697,44 @@ describe("TimePicker Component", () => {
         props: {
           value: mockDateRange,
           type: "inline",
+          maxRange: [new Date(2024, 0, 1), new Date(2024, 0, 31)],
         },
       });
 
-      // Force range mode by setting dates directly and wait for reactivity
+      // Force range mode by setting dates directly
       wrapper.vm.dates = [new Date(), new Date()];
       await nextTick();
 
-      // Check if range mode is active
-      if (wrapper.vm.range) {
-        const quarterButton = wrapper.find(".datepicker-popup__shortcut");
+      // Find and click a quick pick button
+      const buttons = wrapper.findAll(".datepicker-popup__shortcut");
+      const quarterButton = buttons.find((btn: any) => 
btn.text().includes("Quarter Hour"));
+
+      if (quarterButton) {
         await quarterButton.trigger("click");
         await nextTick();
-
-        expect(wrapper.emitted("input")).toBeTruthy();
+        expect(wrapper.vm.selectedShortcut).toBe("quarter");
       } else {
         // If not in range mode, test the quickPick method directly
         wrapper.vm.quickPick("quarter");
-        expect(wrapper.emitted("input")).toBeTruthy();
+        expect(wrapper.vm.selectedShortcut).toBe("quarter");
       }
     });
   });
 
   describe("Lifecycle", () => {
     it("should add document event listener on mount", () => {
+      const addEventListenerSpy = vi.spyOn(document, "addEventListener");
       wrapper = mount(TimePicker);
-
-      expect(document.addEventListener).toHaveBeenCalledWith("click", 
expect.any(Function), true);
+      expect(addEventListenerSpy).toHaveBeenCalledWith("click", 
expect.any(Function), true);
+      addEventListenerSpy.mockRestore();
     });
 
     it("should remove document event listener on unmount", () => {
+      const removeEventListenerSpy = vi.spyOn(document, "removeEventListener");
       wrapper = mount(TimePicker);
       wrapper.unmount();
-
-      expect(document.removeEventListener).toHaveBeenCalledWith("click", 
expect.any(Function), true);
+      expect(removeEventListenerSpy).toHaveBeenCalledWith("click", 
expect.any(Function), true);
+      removeEventListenerSpy.mockRestore();
     });
 
     it("should initialize dates from props value", () => {
@@ -752,9 +743,8 @@ describe("TimePicker Component", () => {
           value: mockDate,
         },
       });
-
       expect(wrapper.vm.dates).toHaveLength(1);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
+      expect(wrapper.vm.inputDates).toHaveLength(1);
     });
 
     it("should initialize dates from array value", () => {
@@ -763,10 +753,8 @@ describe("TimePicker Component", () => {
           value: mockDateRange,
         },
       });
-
       expect(wrapper.vm.dates).toHaveLength(2);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
-      expect(wrapper.vm.dates[1]).toBeInstanceOf(Date);
+      expect(wrapper.vm.inputDates).toHaveLength(2);
     });
 
     it("should watch for value prop changes", async () => {
@@ -776,24 +764,19 @@ describe("TimePicker Component", () => {
         },
       });
 
-      const newDate = new Date(2025, 5, 20);
-      await wrapper.setProps({ value: newDate });
-      await nextTick();
-
-      expect(wrapper.vm.dates[0]).toEqual(newDate);
+      await wrapper.setProps({ value: mockDateRange });
+      expect(wrapper.vm.dates).toHaveLength(2);
     });
   });
 
   describe("Edge Cases", () => {
     it("should handle null value", () => {
-      wrapper = mount(TimePicker, {
+      wrapper = mount(TimePicker as any, {
         props: {
-          value: null as any,
+          value: null,
         },
       });
-
       expect(wrapper.vm.dates).toHaveLength(1);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
     });
 
     it("should handle undefined value", () => {
@@ -802,9 +785,7 @@ describe("TimePicker Component", () => {
           value: undefined,
         },
       });
-
       expect(wrapper.vm.dates).toHaveLength(1);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
     });
 
     it("should handle empty array value", () => {
@@ -813,11 +794,7 @@ describe("TimePicker Component", () => {
           value: [],
         },
       });
-
-      // The vi function returns [new Date(), new Date()] for arrays with 
length <= 1
       expect(wrapper.vm.dates).toHaveLength(2);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
-      expect(wrapper.vm.dates[1]).toBeInstanceOf(Date);
     });
 
     it("should handle single item array", () => {
@@ -826,11 +803,7 @@ describe("TimePicker Component", () => {
           value: [mockDate],
         },
       });
-
-      // The vi function returns [new Date(), new Date()] for arrays with 
length <= 1
-      expect(wrapper.vm.dates).toHaveLength(2);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
-      expect(wrapper.vm.dates[1]).toBeInstanceOf(Date);
+      expect(wrapper.vm.dates).toHaveLength(1);
     });
 
     it("should handle string value", () => {
@@ -839,9 +812,7 @@ describe("TimePicker Component", () => {
           value: "2024-01-15",
         },
       });
-
       expect(wrapper.vm.dates).toHaveLength(1);
-      expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
     });
 
     it("should handle invalid date string", () => {
@@ -850,7 +821,6 @@ describe("TimePicker Component", () => {
           value: "invalid-date",
         },
       });
-
       expect(wrapper.vm.dates).toHaveLength(1);
       expect(wrapper.vm.dates[0]).toBeInstanceOf(Date);
     });
@@ -879,18 +849,20 @@ describe("TimePicker Component", () => {
       const submitButton = wrapper.find(".datepicker__button-select");
       const cancelButton = wrapper.find(".datepicker__button-cancel");
 
-      // The buttons don't have explicit type attributes, but they are button 
elements
       expect(submitButton.element.tagName).toBe("BUTTON");
       expect(cancelButton.element.tagName).toBe("BUTTON");
     });
 
     it("should have proper button types for quick pick", () => {
-      wrapper = mount(TimePicker);
-      wrapper.vm.dates = mockDateRange;
-      wrapper.vm.show = true;
+      wrapper = mount(TimePicker, {
+        props: {
+          value: mockDateRange,
+          type: "inline",
+        },
+      });
 
       const quickPickButtons = wrapper.findAll(".datepicker-popup__shortcut");
-      quickPickButtons.forEach((button: Recordable) => {
+      quickPickButtons.forEach((button: any) => {
         expect(button.attributes("type")).toBe("button");
       });
     });
diff --git a/src/hooks/useExpressionsProcessor.ts 
b/src/hooks/useExpressionsProcessor.ts
index 770560e3..590d4c6b 100644
--- a/src/hooks/useExpressionsProcessor.ts
+++ b/src/hooks/useExpressionsProcessor.ts
@@ -32,7 +32,6 @@ import type { Instance, Endpoint, Service } from 
"@/types/selector";
 import type { Node, Call } from "@/types/topology";
 import type { ServiceWithGroup } from 
"@/views/dashboard/graphs/ServiceList.vue";
 
-type AllPods = Instance | Endpoint | ServiceWithGroup;
 /**
  * Shape of a single execExpression GraphQL response entry.
  */
diff --git a/src/layout/components/NavBar.vue b/src/layout/components/NavBar.vue
index 7875aa43..bf5710cb 100644
--- a/src/layout/components/NavBar.vue
+++ b/src/layout/components/NavBar.vue
@@ -46,7 +46,8 @@ limitations under the License. -->
         :maxRange="appStore.maxRange"
         position="bottom"
         format="YYYY-MM-DD HH:mm"
-        @input="changeTimeRange"
+        :showButtons="true"
+        @confirm="changeTimeRange"
       />
       <span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ 
`${appStore.utcHour}:${appStore.utcMin}` }} </span>
       <span class="ml-5">
diff --git a/src/views/dashboard/related/profile/components/NewTask.vue 
b/src/views/dashboard/related/profile/components/NewTask.vue
index 48b5b03e..ef5c7dd9 100644
--- a/src/views/dashboard/related/profile/components/NewTask.vue
+++ b/src/views/dashboard/related/profile/components/NewTask.vue
@@ -89,7 +89,7 @@ limitations under the License. -->
   const endpointName = ref<string>("");
   const monitorTime = ref<string>(InitTaskField.monitorTimeEn[0].value);
   const monitorDuration = ref<string>(InitTaskField.monitorDuration[0].value);
-  const time = ref<Date>(appStore.durationRow.start);
+  const time = ref<Date>(appStore.durationRow.end);
   const minThreshold = ref<number>(0);
   const dumpPeriod = ref<string>(InitTaskField.dumpPeriod[0].value);
   const maxSamplingCount = 
ref<string>(InitTaskField.maxSamplingCount[0].value);
diff --git a/stylelint.config.js b/stylelint.config.js
index 81d9f128..88223442 100644
--- a/stylelint.config.js
+++ b/stylelint.config.js
@@ -54,11 +54,8 @@ module.exports = {
     "no-empty-source": null,
     "string-quotes": null,
     "named-grid-areas-no-invalid": null,
-    "unicode-bom": "never",
     "no-descending-specificity": null,
     "font-family-no-missing-generic-family-keyword": null,
-    "declaration-colon-space-after": "always-single-line",
-    "declaration-colon-space-before": "never",
     // 'declaration-block-trailing-semicolon': 'always',
     "rule-empty-line-before": [
       "always",

Reply via email to