You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The order of the date and time fields is incorrectly displayed by the date/time-related RSP components, for the RTL languages (Arabic, Hebrew).
🤔 Expected Behavior
The date and time field order should follow the same order observed with the values returned by Intl.DateTimeFormat / DateFormatter (@internationalized/date), when rendered in elements with the dir attribute set to"rtl".
The example below (using the options: day: "numeric", month: "numeric", year: "numeric", hour: "numeric", minute: "2-digit", timeZoneName: "short"), illustrates the order for all available fields currently used by all components:
ar-AE
he-IL
timezone dayPeriod hour:minute year/month/day
timezone hour:minute ,day.month.year
😯 Current Behavior
Calendar
with zoned time story
ar-AE
he-IL
DateField
Date Time Value Zoned story
ar-AE
he-IL
DatePicker
Default story
ar-AE
he-IL
(سنة = year, شهر = month, يوم = day) (no issue)
(שנה = year, חודש = month, יום = day)
Date Time Value Zoned story
ar-AE
he-IL
DateRangePicker
defaultValue story
ar-AE
he-IL
(no issue)
(no issue)
defaultValue, zoned story
ar-AE
he-IL
RangeCalendar
default story
ar-AE
he-IL
(no issue)
with zoned time story
ar-AE
he-IL
TimeField
default story
ar-AE
he-IL
💁 Possible Solution
I only looked closely at the DatePicker component code, the actual solution might differ slightly across components.
This seems to be happening because the date and time segment objects are rendered in the exact array order in which they are stored:
While this works fine for LTR languages, for RTL this is a problem because the date and time segments should not be mirrored, e.g.:
17:45 should be displayed as 17:45, not 45:17, and
23.06.2023 (in Hebrew) should be displayed as 23.06.2023 instead of 2023.06.23.
Looking at a more detailed example, when using the DatePicker component with time zones for Hebrew, the object array stores segments in this (logical) order of types:
day literal month literal year literal hour literal minute literal timeZoneName
which is then displayed in the exact mirrored order of types:
timeZoneName literal minute literal hour literal year literal month literal day
The expected result should not mirror every segment, but rather only the segment groups ( date_segments , time_segments , timezone_segment -> timezone_segment , time_segments , date_segments):
timeZoneName literal hour literal minute literal day literal month literal year literal
One potential fix is to split the object array into segment subgroups (i.e. date, time, dayPeriod, timezone), and then force an LTR direction attribute on the date and time segment subgroups only.
Arabic poses an additional problem in that the date-related segments seem to be stored in the wrong logical order (day literal month literal year literal). Because of the way segments are rendered currently, this is not manifesting itself as a problem, but it will be once the underlying problem is addressed. Further investigation is required to identify why this is occurring.
💻 Code Sample
Used the latest storybook for testing
🧢 Your Company/Team
Adobe Globalization team
The text was updated successfully, but these errors were encountered:
lreis
changed the title
Incorrect date / time field order in several components, for RTL languages
Incorrect date / time segment order in several components, for RTL languages
Jun 26, 2023
Did a small experiment and found that it seems to work as expected automatically if you get rid of display: flex on .react-spectrum-Datepicker-inputContents, and make each segment (.react-spectrum-Datepicker-cell) have display: inline. The placeholder inside each segment (.react-spectrum-Datepicker-placeholder) also seem to mess things up. Setting them to display: none "fixes" it. I guess this works because the Unicode bidi algorithm operates over the entire field as opposed to at the individual segment level.
If that is the only solution, then we'll need to find another way of rendering the placeholders so they reserve space even when there is a value present. The current method won't work with display: inline.
🐛 Bug Report
The order of the date and time fields is incorrectly displayed by the date/time-related RSP components, for the RTL languages (Arabic, Hebrew).
🤔 Expected Behavior
The date and time field order should follow the same order observed with the values returned by Intl.DateTimeFormat / DateFormatter (@internationalized/date), when rendered in elements with the dir attribute set to"rtl".
The example below (using the options: day: "numeric", month: "numeric", year: "numeric", hour: "numeric", minute: "2-digit", timeZoneName: "short"), illustrates the order for all available fields currently used by all components:
😯 Current Behavior
Calendar
with zoned time story
DateField
Date Time Value Zoned story
DatePicker
Default story
(سنة = year, شهر = month, يوم = day)
(no issue)
(שנה = year, חודש = month, יום = day)
Date Time Value Zoned story
DateRangePicker
defaultValue story
(no issue)
(no issue)
defaultValue, zoned story
RangeCalendar
default story
(no issue)
with zoned time story
TimeField
default story
💁 Possible Solution
I only looked closely at the DatePicker component code, the actual solution might differ slightly across components.
This seems to be happening because the date and time segment objects are rendered in the exact array order in which they are stored:
https://github.com/adobe/react-spectrum/blob/main/packages/%40react-spectrum/datepicker/src/DatePickerField.tsx#L48-L56
While this works fine for LTR languages, for RTL this is a problem because the date and time segments should not be mirrored, e.g.:
Looking at a more detailed example, when using the DatePicker component with time zones for Hebrew, the object array stores segments in this (logical) order of types:
day literal month literal year literal hour literal minute literal timeZoneName
which is then displayed in the exact mirrored order of types:
timeZoneName literal minute literal hour literal year literal month literal day
The expected result should not mirror every segment, but rather only the segment groups ( date_segments , time_segments , timezone_segment -> timezone_segment , time_segments , date_segments):
timeZoneName literal hour literal minute literal day literal month literal year literal
One potential fix is to split the object array into segment subgroups (i.e. date, time, dayPeriod, timezone), and then force an LTR direction attribute on the date and time segment subgroups only.
Arabic poses an additional problem in that the date-related segments seem to be stored in the wrong logical order (day literal month literal year literal). Because of the way segments are rendered currently, this is not manifesting itself as a problem, but it will be once the underlying problem is addressed. Further investigation is required to identify why this is occurring.
💻 Code Sample
Used the latest storybook for testing
🧢 Your Company/Team
Adobe Globalization team
The text was updated successfully, but these errors were encountered: