diff --git a/ui/package-lock.json b/ui/package-lock.json
index d9251d434..333bcf3cc 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -38,7 +38,7 @@
"react": "17.0.2",
"react-app-polyfill": "3.0.0",
"react-cool-dimensions": "3.0.1",
- "react-day-picker": "8.10.1",
+ "react-day-picker": "9.6.7",
"react-dom": "17.0.2",
"react-hotkeys-hook": "5.2.4",
"react-idle-timer": "5.7.2",
@@ -2077,6 +2077,12 @@
"node": ">=18"
}
},
+ "node_modules/@date-fns/tz": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.2.0.tgz",
+ "integrity": "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==",
+ "license": "MIT"
+ },
"node_modules/@emnapi/core": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
@@ -6521,6 +6527,12 @@
"url": "https://github.com/sponsors/kossnocorp"
}
},
+ "node_modules/date-fns-jalali": {
+ "version": "4.1.0-0",
+ "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz",
+ "integrity": "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==",
+ "license": "MIT"
+ },
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
@@ -11141,17 +11153,24 @@
}
},
"node_modules/react-day-picker": {
- "version": "8.10.1",
- "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz",
- "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==",
+ "version": "9.6.7",
+ "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.6.7.tgz",
+ "integrity": "sha512-rCSt6X8FXQWpjykns/azRXjJk3cMSzkzGbDEXuEveFGNZgOjZULdJQ5wsu8Zfyo8ZgPBoYCBKQ5wRrgJfhJGbg==",
"license": "MIT",
+ "dependencies": {
+ "@date-fns/tz": "1.2.0",
+ "date-fns": "4.1.0",
+ "date-fns-jalali": "4.1.0-0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/gpbl"
},
"peerDependencies": {
- "date-fns": "^2.28.0 || ^3.0.0",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ "react": ">=16.8.0"
}
},
"node_modules/react-dom": {
diff --git a/ui/package.json b/ui/package.json
index 06c67dc40..552239e1c 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -34,7 +34,7 @@
"react": "17.0.2",
"react-app-polyfill": "3.0.0",
"react-cool-dimensions": "3.0.1",
- "react-day-picker": "8.10.1",
+ "react-day-picker": "9.6.7",
"react-dom": "17.0.2",
"react-hotkeys-hook": "5.2.4",
"react-idle-timer": "5.7.2",
@@ -90,11 +90,6 @@
"vite": "7.3.1",
"vite-tsconfig-paths": "6.1.1"
},
- "overrides": {
- "react-day-picker@8.10.1": {
- "date-fns": "4.1.0"
- }
- },
"scripts": {
"start": "VITE_APP_BACKEND_URI=http://localhost:8080 vite",
"build": "tsc && vite build",
diff --git a/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.tsx.snap b/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.tsx.snap
index 324097d12..ba4231191 100644
--- a/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.tsx.snap
+++ b/ui/src/Components/SilenceModal/DateTimeSelect/__snapshots__/index.test.tsx.snap
@@ -369,123 +369,120 @@ exports[` 'Ends' tab matches snapshot 1`] = `
class="d-flex justify-content-center align-items-center"
>
+
|
Su
|
Mo
|
Tu
|
We
|
Th
|
Fr
|
Sa
@@ -493,36 +490,41 @@ exports[` 'Ends' tab matches snapshot 1`] = `
|
|
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2061-01-30"
+ data-hidden="true"
+ data-month="2061-01"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2061-01-31"
+ data-hidden="true"
+ data-month="2061-01"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
- |
+ class="rdp-day rdp-hidden rdp-outside"
+ data-day="2061-03-01"
+ data-hidden="true"
+ data-month="2061-03"
+ data-outside="true"
+ role="gridcell"
+ />
-
- |
+ class="rdp-day rdp-hidden rdp-outside"
+ data-day="2061-03-02"
+ data-hidden="true"
+ data-month="2061-03"
+ data-outside="true"
+ role="gridcell"
+ />
-
- |
+ class="rdp-day rdp-hidden rdp-outside"
+ data-day="2061-03-03"
+ data-hidden="true"
+ data-month="2061-03"
+ data-outside="true"
+ role="gridcell"
+ />
-
- |
+ class="rdp-day rdp-hidden rdp-outside"
+ data-day="2061-03-04"
+ data-hidden="true"
+ data-month="2061-03"
+ data-outside="true"
+ role="gridcell"
+ />
-
- |
+ class="rdp-day rdp-hidden rdp-outside"
+ data-day="2061-03-05"
+ data-hidden="true"
+ data-month="2061-03"
+ data-outside="true"
+ role="gridcell"
+ />
-
+
'Starts' tab matches snapshot 1`] = `
class="d-flex justify-content-center align-items-center"
>
+
|
Su
|
Mo
|
Tu
|
We
|
Th
|
Fr
|
Sa
@@ -1316,20 +1311,22 @@ exports[` 'Starts' tab matches snapshot 1`] = `
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2060-03-01"
+ data-hidden="true"
+ data-month="2060-03"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2060-03-02"
+ data-hidden="true"
+ data-month="2060-03"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2060-03-03"
+ data-hidden="true"
+ data-month="2060-03"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2060-03-04"
+ data-hidden="true"
+ data-month="2060-03"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2060-03-05"
+ data-hidden="true"
+ data-month="2060-03"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
- |
+ aria-selected="true"
+ class="rdp-day rdp-hidden rdp-outside rdp-selected rdp-range_middle"
+ data-day="2060-03-06"
+ data-hidden="true"
+ data-month="2060-03"
+ data-outside="true"
+ data-selected="true"
+ role="gridcell"
+ />
-
+
{
describe("", () => {
it("selecting date on DayPicker updates startsAt", () => {
+ // Verifies clicking a day in the calendar updates the startsAt date
const { container } = renderTabContentStart();
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
new Date(2060, 1, 1, 0, 0, 0).toISOString(),
);
- const dayButtons = container.querySelectorAll("button.rdp-button.rdp-day");
+ // In v9, day buttons use .rdp-day_button class
+ const dayButtons = container.querySelectorAll("button.rdp-day_button");
fireEvent.click(dayButtons[17]);
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
new Date(2060, 1, 18, 0, 0, 0).toISOString(),
@@ -222,17 +224,15 @@ describe("", () => {
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
new Date(2060, 1, 1, 0, 0, 0).toISOString(),
);
- expect(container.querySelector(".rdp-caption_label")?.textContent).toBe(
+ expect(container.querySelector(".rdp-month_caption")?.textContent).toBe(
"February 2060",
);
- fireEvent.click(
- container.querySelector("button.rdp-button.rdp-nav_button_next")!,
- );
- expect(container.querySelector(".rdp-caption_label")?.textContent).toBe(
+ fireEvent.click(container.querySelector("button.rdp-button_next")!);
+ expect(container.querySelector(".rdp-month_caption")?.textContent).toBe(
"March 2060",
);
fireEvent.click(container.querySelector("button.btn.btn-light.btn-sm")!);
- expect(container.querySelector(".rdp-caption_label")?.textContent).toBe(
+ expect(container.querySelector(".rdp-month_caption")?.textContent).toBe(
format(new Date(), "LLLL yyyy"),
);
});
@@ -353,11 +353,13 @@ const renderTabContentEnd = () => {
describe("", () => {
it("Selecting date on DayPicker updates endsAt", () => {
+ // Verifies clicking a day in the calendar updates the endsAt date
const { container } = renderTabContentEnd();
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
new Date(2061, 1, 1, 0, 0, 0).toISOString(),
);
- const dayButtons = container.querySelectorAll("button.rdp-button.rdp-day");
+ // In v9, day buttons use .rdp-day_button class
+ const dayButtons = container.querySelectorAll("button.rdp-day_button");
fireEvent.click(dayButtons[23]);
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
new Date(2061, 1, 24, 0, 0, 0).toISOString(),
@@ -374,17 +376,15 @@ describe("", () => {
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
new Date(2061, 1, 1, 0, 0, 0).toISOString(),
);
- expect(container.querySelector(".rdp-caption_label")?.textContent).toBe(
+ expect(container.querySelector(".rdp-month_caption")?.textContent).toBe(
"February 2061",
);
- fireEvent.click(
- container.querySelector("button.rdp-button.rdp-nav_button_next")!,
- );
- expect(container.querySelector(".rdp-caption_label")?.textContent).toBe(
+ fireEvent.click(container.querySelector("button.rdp-button_next")!);
+ expect(container.querySelector(".rdp-month_caption")?.textContent).toBe(
"March 2061",
);
fireEvent.click(container.querySelector("button.btn.btn-light.btn-sm")!);
- expect(container.querySelector(".rdp-caption_label")?.textContent).toBe(
+ expect(container.querySelector(".rdp-month_caption")?.textContent).toBe(
format(new Date(), "LLLL yyyy"),
);
});
diff --git a/ui/src/Components/SilenceModal/DateTimeSelect/index.tsx b/ui/src/Components/SilenceModal/DateTimeSelect/index.tsx
index 2320a6748..cf2f15040 100644
--- a/ui/src/Components/SilenceModal/DateTimeSelect/index.tsx
+++ b/ui/src/Components/SilenceModal/DateTimeSelect/index.tsx
@@ -9,7 +9,7 @@ import { setSeconds } from "date-fns/setSeconds";
import { isSameMonth } from "date-fns/isSameMonth";
import { DayPicker } from "react-day-picker";
-import "react-day-picker/dist/style.css";
+import "react-day-picker/style.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCalendarDay } from "@fortawesome/free-solid-svg-icons/faCalendarDay";
@@ -89,8 +89,8 @@ const TabContentStart: FC<{
disabled={{
before: nowZeroSeconds(),
}}
- onDayClick={(val) => {
- const startsAt = new Date(val);
+ onDayClick={(date) => {
+ const startsAt = new Date(date);
startsAt.setHours(silenceFormStore.data.startsAt.getHours());
startsAt.setMinutes(silenceFormStore.data.startsAt.getMinutes());
startsAt.setSeconds(0);
@@ -148,8 +148,8 @@ const TabContentEnd: FC<{ silenceFormStore: SilenceFormStore }> = observer(
disabled={{
before: setSeconds(silenceFormStore.data.startsAt, 0),
}}
- onDayClick={(val) => {
- const endsAt = new Date(val);
+ onDayClick={(date) => {
+ const endsAt = new Date(date);
endsAt.setHours(silenceFormStore.data.endsAt.getHours());
endsAt.setMinutes(silenceFormStore.data.endsAt.getMinutes());
endsAt.setSeconds(0);
diff --git a/ui/src/Styles/Components/_DateTimeSelect.scss b/ui/src/Styles/Components/_DateTimeSelect.scss
index f18862a0f..da0e99e06 100644
--- a/ui/src/Styles/Components/_DateTimeSelect.scss
+++ b/ui/src/Styles/Components/_DateTimeSelect.scss
@@ -1,12 +1,30 @@
.components-date-range {
--rdp-cell-size: 40px;
+ --rdp-accent-color: #{$secondary};
+ --rdp-selected-border: none;
+ --rdp-range_middle-background-color: #{$light};
- .rdp-cell {
+ .rdp-day_button {
+ padding: 0;
+ }
+
+ .rdp-selected {
+ font-weight: inherit;
+ font-size: inherit;
+ }
+
+ .rdp-button_previous,
+ .rdp-button_next {
+ color: $secondary;
+ }
+
+ .rdp-day {
+ padding: 0;
width: 36px;
height: 36px;
}
- .rdp-button {
+ .rdp-day_button {
&:focus,
&:active {
outline: none;
@@ -19,67 +37,75 @@
background-color: $light;
}
- &.rdp-day_disabled {
+ &.rdp-disabled {
opacity: 1;
}
}
- .rdp-caption_label {
+ .rdp-month_caption {
font-weight: 400;
font-size: 120%;
}
- .rdp-table {
+ .rdp-month_grid {
border-collapse: inherit;
border-spacing: 0 1px;
}
- .rdp-day {
+ .rdp-day_button {
&:hover,
&:active {
border-radius: 0.5rem;
}
- &:not(.rdp-day_disabled):not(.rdp-day_range_middle):not(.rdp-day_selected):hover {
+ &:not(.rdp-disabled):not(.rdp-range_middle):not(.rdp-selected):hover {
background-color: $light;
}
+ }
- &.rdp-day_disabled {
- color: $secondary;
- }
+ .rdp-day.rdp-disabled .rdp-day_button {
+ color: $secondary;
+ }
- &.rdp-day_today {
- font-weight: 600;
- }
+ .rdp-day.rdp-today .rdp-day_button {
+ font-weight: 600;
+ }
- &.rdp-day_selected {
- border-radius: 0;
+ .rdp-day.rdp-selected .rdp-day_button {
+ border-radius: 0;
+ font-weight: 400;
+ font-size: inherit;
+ }
- &.rdp-day_range_start,
- &.rdp-day_range_end {
- font-weight: 600;
- background-color: $primary;
- }
+ .rdp-day.rdp-selected.rdp-range_start .rdp-day_button,
+ .rdp-day.rdp-selected.rdp-range_end .rdp-day_button {
+ font-weight: 600;
+ background-color: $primary;
- &.rdp-day_range_start {
- border-top-left-radius: 0.5rem;
- border-bottom-left-radius: 0.5rem;
- }
-
- &.rdp-day_range_end {
- border-top-right-radius: 0.5rem;
- border-bottom-right-radius: 0.5rem;
- }
-
- &.rdp-day_start:not(.rdp-day_range_middle),
- &.rdp-day_end:not(.rdp-day_range_middle) {
- background-color: $primary;
- color: $white;
- }
- &.rdp-day_range_middle:not(.rdp-day_range_start):not(.rdp-day_range_end) {
- background-color: $light;
- color: $components-date-range-sub-color;
- }
+ &:hover,
+ &:active,
+ &:focus {
+ background-color: $primary;
}
}
+
+ .rdp-day.rdp-selected.rdp-range_start .rdp-day_button {
+ border-top-left-radius: 0.5rem;
+ border-bottom-left-radius: 0.5rem;
+ }
+
+ .rdp-day.rdp-selected.rdp-range_end .rdp-day_button {
+ border-top-right-radius: 0.5rem;
+ border-bottom-right-radius: 0.5rem;
+ }
+
+ .rdp-day.rdp-selected:not(.rdp-range_middle) .rdp-day_button {
+ background-color: $primary;
+ color: $white;
+ }
+
+ .rdp-day.rdp-selected.rdp-range_middle:not(.rdp-range_start):not(.rdp-range_end) .rdp-day_button {
+ background-color: $light;
+ color: $components-date-range-sub-color;
+ }
}