-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: ensure date/time segments are ordered correctly in RTL #7423
base: main
Are you sure you want to change the base?
Conversation
Hey, Thanks for working on this PR Is this also going to fix keyboard focus management on RTL too? For example
|
@sadeghbarati Yes, the plan is to also correct the keyboard navigation for RTL as well. The PR is still in the early stages so there's a lot that has yet to be implemented. |
@@ -181,6 +181,9 @@ export function useDateField<T extends DateValue>(props: AriaDateFieldOptions<T> | |||
if (props.onKeyUp) { | |||
props.onKeyUp(e); | |||
} | |||
}, | |||
style: { | |||
unicodeBidi: 'isolate' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added for DateRangePicker because things were looking a little funky without it. wraps around each datefield. see codepen for reproduction
i could update this so that it only applies in rtl locales but it also doesn't seem to have any affect for ltr locales.
@@ -170,6 +173,7 @@ function PopoverInner({state, isExiting, UNSTABLE_portalContainer, ...props}: Po | |||
ref={ref} | |||
slot={props.slot || undefined} | |||
style={style} | |||
dir={props.dir} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
popovers are portaled outside which means they don't get the direction of the locale causing the keyboard navigation to behave incorrectly for rac datepickers in rtl. in v3, we wrap the popovers in a provider so this doesn't happen. happy to change the implementation if there's a better way to do this
@@ -104,3 +129,19 @@ export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | |||
|
|||
return mergeProps(pressProps, {onKeyDown}); | |||
} | |||
|
|||
function orderSegments(editableSegments: NodeListOf<Element> | undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adjacent segments might not necessarily be adjacent in the DOM. therefore, we can't just use focusPrevious and focusNext. instead, calculate their positions and use those to determine which segment to move to
@@ -9,6 +9,8 @@ import {usePress} from '@react-aria/interactions'; | |||
export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DateFieldState, ref: RefObject<Element | null>, disableArrowNavigation?: boolean) { | |||
let {direction} = useLocale(); | |||
let focusManager = useMemo(() => createFocusManager(ref), [ref]); | |||
let editableSegments: NodeListOf<Element> | undefined = ref.current?.querySelectorAll('span[role="spinbutton"], span[role="textbox"]'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to be done in a useLayoutEffect and the result should be stored in a ref as other parts of state will determine if the effects needs to update
let segmentArr = segments.map(node => { | ||
return { | ||
element: node as FocusableElement, | ||
rectX: node?.getBoundingClientRect().left |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you run segments.filter(Boolean).map..., you may not need this ?
might need to do it the line above so you can set the type correctly
let segments = Array.from(editableSegments).filter...
Close #4711
Need to double check that nothing broke in #6562 with these changes.
✅ Pull Request Checklist:
📝 Test Instructions:
Arabic should render in the following order:
TimeZone DayPeriod Hour:Minute Year/Month/Day
Hebrew should render in the following order:
TimeZone DayPeriod Hour:Minute Day/Month/Year
Tab order should be:
Day -> Month -> Year -> Hour -> Minute -> DayPeriod -> TimeZone
Arabic Placeholders:
يوم / شهر / سنة
Hebrew Placeholders:
שנה.חודש.יום
Also be sure to test keyboard navigation
🧢 Your Project: