From d681c3885f8beb951ed404f42d820fd63e7e3c78 Mon Sep 17 00:00:00 2001 From: franmc01 Date: Tue, 7 Jul 2026 15:22:45 -0500 Subject: [PATCH] fix: keep sr-only weekday header text visually hidden with inline styles Fixes #6302 --- src/calendar.tsx | 26 ++++++++++++++++++++++++-- src/test/calendar_test.test.tsx | 29 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/calendar.tsx b/src/calendar.tsx index 4bedbdc06..39c350767 100644 --- a/src/calendar.tsx +++ b/src/calendar.tsx @@ -56,6 +56,18 @@ import YearDropdown from "./year_dropdown"; import type { ClickOutsideHandler } from "./click_outside_wrapper"; import type { Day } from "date-fns"; +const visuallyHiddenStyle: React.CSSProperties = { + position: "absolute", + width: "1px", + height: "1px", + padding: 0, + margin: "-1px", + overflow: "hidden", + clipPath: "inset(50%)", + whiteSpace: "nowrap", + border: 0, +}; + interface YearDropdownProps extends React.ComponentPropsWithoutRef< typeof YearDropdown > {} @@ -517,7 +529,12 @@ export default class Calendar extends Component { className={`react-datepicker__day-name ${disabled ? "react-datepicker__day-name--disabled" : ""}`} role="columnheader" > - Week number + + Week number + , ); @@ -568,7 +585,12 @@ export default class Calendar extends Component { disabled ? "react-datepicker__day-name--disabled" : "", )} > - {fullDayName} + + {fullDayName} + ); diff --git a/src/test/calendar_test.test.tsx b/src/test/calendar_test.test.tsx index 721ee0523..75598121a 100644 --- a/src/test/calendar_test.test.tsx +++ b/src/test/calendar_test.test.tsx @@ -2446,6 +2446,35 @@ describe("Calendar", () => { }); }); + it("should keep sr-only day name and week number spans visually hidden via inline styles", () => { + const { container } = render( + {}} + onClickOutside={() => {}} + dropdownMode="scroll" + showWeekNumbers + />, + ); + + const srOnlySpans = container.querySelectorAll( + ".react-datepicker__day-name > span.react-datepicker__sr-only", + ); + expect(srOnlySpans).toHaveLength(8); + + srOnlySpans.forEach((span) => { + const { style } = span as HTMLElement; + expect(style.position).toBe("absolute"); + expect(style.width).toBe("1px"); + expect(style.height).toBe("1px"); + expect(style.padding).toBe("0px"); + expect(style.margin).toBe("-1px"); + expect(style.overflow).toBe("hidden"); + expect(style.clipPath).toBe("inset(50%)"); + expect(style.whiteSpace).toBe("nowrap"); + }); + }); + it("should have a next-button with the provided aria-label for year", () => { const ariaLabel = "A label in my native language for next year"; const { container } = render(