fix(calendar): rtl navigation (#4565)

* fix(calendar): rtl navigation

* chore(changeset): fixed reverse behavior of NextButton and PrevButton in the RTL calendar

* chore(changeset): update package name

* refactor(calendar): prefer isRTL and use className in theme package instead

* chore(changeset): add theme package as well

* chore(calendar): add min theme package to 2.4.7

---------

Co-authored-by: աӄա <wingkwong.code@gmail.com>
This commit is contained in:
Zarin 2025-02-06 01:40:01 +04:30 committed by GitHub
parent e77de2b650
commit ace8406946
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 32 additions and 6 deletions

View File

@ -0,0 +1,6 @@
---
"@heroui/calendar": patch
"@heroui/theme": patch
---
Fixed reversed navigation behavior of nextButton and prevButton in the RTL calendar. The buttons now correctly navigate to the next and previous months, ensuring consistent behavior across all locales and layouts. (#4541)

View File

@ -35,7 +35,7 @@
},
"peerDependencies": {
"@heroui/system": ">=2.4.0",
"@heroui/theme": ">=2.4.0",
"@heroui/theme": ">=2.4.7",
"framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
"react": ">=18 || >=19.0.0-rc.0",
"react-dom": ">=18 || >=19.0.0-rc.0"

View File

@ -8,6 +8,7 @@ import {VisuallyHidden} from "@react-aria/visually-hidden";
import {Button} from "@heroui/button";
import {chain, mergeProps} from "@react-aria/utils";
import {AnimatePresence, LazyMotion, MotionConfig} from "framer-motion";
import {useLocale} from "@react-aria/i18n";
import {ResizablePanel} from "@heroui/framer-utils";
import {ChevronLeftIcon} from "./chevron-left";
@ -70,11 +71,15 @@ export function CalendarBase(props: CalendarBaseProps) {
const [direction, setDirection] = useState<number>(0);
const {direction: localeDirection} = useLocale();
const currentMonth = state.visibleRange.start;
const headers: React.ReactNode[] = [];
const calendars: React.ReactNode[] = [];
const isRTL = localeDirection === "rtl";
for (let i = 0; i < visibleMonths; i++) {
let d = currentMonth.add({months: i});
@ -82,8 +87,10 @@ export function CalendarBase(props: CalendarBaseProps) {
<Fragment key={`calendar-header-${i}`}>
{i === 0 && (
<Button
{...prevButtonProps}
onPress={chain(prevButtonProps.onPress, () => setDirection(-1))}
{...(isRTL ? nextButtonProps : prevButtonProps)}
onPress={chain(isRTL ? nextButtonProps.onPress : prevButtonProps.onPress, () =>
setDirection(-1),
)}
>
<ChevronLeftIcon />
</Button>
@ -96,8 +103,10 @@ export function CalendarBase(props: CalendarBaseProps) {
/>
{i === visibleMonths - 1 && (
<Button
{...nextButtonProps}
onPress={chain(nextButtonProps.onPress, () => setDirection(1))}
{...(isRTL ? prevButtonProps : nextButtonProps)}
onPress={chain(isRTL ? prevButtonProps.onPress : nextButtonProps.onPress, () =>
setDirection(1),
)}
>
<ChevronRightIcon />
</Button>

View File

@ -188,7 +188,9 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
const globalContext = useProviderContext();
const {locale} = useLocale();
const {locale, direction} = useLocale();
const isRTL = direction === "rtl";
const calendarProp = createCalendar(new DateFormatter(locale).resolvedOptions().calendar);
@ -261,6 +263,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
isRange: !!originalProps.isRange,
isHeaderWrapperExpanded: isHeaderExpanded,
className,
isRTL,
}),
[objectToDeps(variantProps), showMonthAndYearPickers, isHeaderExpanded, className],
);

View File

@ -148,12 +148,20 @@ const calendar = tv({
pickerItem: "transition-opacity",
},
},
isRTL: {
true: {
nextButton: "order-1",
prevButton: "order-3",
},
false: {},
},
},
defaultVariants: {
color: "primary",
showShadow: false,
hideDisabledDates: false,
showMonthAndYearPickers: false,
isRTL: false,
},
compoundVariants: [
// !isRange & colors --> Calendar