-
Notifications
You must be signed in to change notification settings - Fork 15
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
feat: rtl support for components [LIBS-525] #1448
Conversation
🚀 Deployed on https://pr-1448--dhis2-ui.netlify.app |
`}</style> | ||
</div> | ||
) | ||
const flipMargin = (margin) => { |
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.
I'm not totally sure if we want to try to remap margin provided as a prop, but this seemed probably more helpful to attempt?
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 is the best we can do for now .. I am collecting some breaking changes we should do for the library, and this should be one of them at some point (dropping the margin prop)
@@ -22,8 +22,10 @@ import { Chip } from '@dhis2-ui/chip' | |||
|dragging|boolean|||| | |||
|icon|element|||| | |||
|marginBottom|number|`4`||`margin-bottom` value, applied in `px`| | |||
|marginLeft|number|`4`||`margin-left` value, applied in `px`| | |||
|marginRight|number|`4`||`margin-right` value, applied in `px`| | |||
|marginInlineStart|number|`4`||`margin-inline-start` value, applied in `px`| |
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.
I thought we would want to leave the existing marginLeft
and marginRight
properties and not treat them as equivalent to inline-start inline-end, but that going forward it would be better to also provide for people to enter the margin in a logical-property-compliant manner (hence addition of marginInlineStart
and marginInlineEnd
here)
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.
shouldn't this include an update to the TypeScript definitions?
@@ -32,7 +42,10 @@ const Popper = ({ | |||
const { styles, attributes } = usePopper(referenceElement, popperElement, { | |||
strategy, | |||
onFirstUpdate, | |||
placement, | |||
placement: | |||
document.documentElement.dir === 'rtl' |
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.
I don't know what the ideal is here? The popper library that we're using says that it handles RTL, but it seems to provide placement only with physical properties. I assume we want to switch these, so I have done so based on the document.documentElement direction that is being set by app-platform, but I'm not sure if there's a reason why we might want to strictly interpret the placement as a physical property?
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.
again, not ideal - I think the main reason we wouldn't want to do the flipping, is that people who are actually writing apps for an RTL-language would set the placement correctly, and then we will go ahead and flip it.
But we can assume for backwards-compatibility that any implementation out there are LTR, and keep this logic. In the future, maybe the flipping can be controlled with a different prop
@@ -5,6 +5,12 @@ import PropTypes from 'prop-types' | |||
import React, { forwardRef } from 'react' | |||
import styles from './table-data-cell.styles.js' | |||
|
|||
const rtlCorrespondingAlignments = { |
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.
here it also seemed like we would want to assume that the physical properties we have on this component for alignment should actually behave as logical properties. Though I guess we could also add new options like inline-start
, inline-end
for alignment?
Passing run #3210 ↗︎
Details:
Review all test suite changes for PR #1448 ↗︎ |
@@ -12,7 +12,7 @@ function icon(kind) { | |||
} | |||
|
|||
export const NotificationIcon = ({ count, href, kind, dataTestId }) => ( | |||
<a href={href} className={kind} data-test={dataTestId}> | |||
<a dir="ltr" href={href} className={kind} data-test={dataTestId}> |
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 is set to ltr
so that the count bubbles appear on the right of the icons. I think the number + icon effectively behaves as an icon unto itself, and moving the number to the left dir=rtl, makes the icon harder to interpret (particularly the messages one)
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.
great stuff @tomzemp 💯 - some minor comments, but let's merge it asap (at least to alpha) and see how it works in an app
@@ -22,8 +22,10 @@ import { Chip } from '@dhis2-ui/chip' | |||
|dragging|boolean|||| | |||
|icon|element|||| | |||
|marginBottom|number|`4`||`margin-bottom` value, applied in `px`| | |||
|marginLeft|number|`4`||`margin-left` value, applied in `px`| | |||
|marginRight|number|`4`||`margin-right` value, applied in `px`| | |||
|marginInlineStart|number|`4`||`margin-inline-start` value, applied in `px`| |
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.
shouldn't this include an update to the TypeScript definitions?
`}</style> | ||
</div> | ||
) | ||
const flipMargin = (margin) => { |
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 is the best we can do for now .. I am collecting some breaking changes we should do for the library, and this should be one of them at some point (dropping the margin prop)
components/divider/src/divider.js
Outdated
</div> | ||
) | ||
const flipMargin = (margin) => { | ||
const splitMargin = margin.split(' ') |
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.
I guess this logic would break if you had multiple spaces between the marging values? .split(/\s+/)
would be safer, I'd say
@@ -32,7 +42,10 @@ const Popper = ({ | |||
const { styles, attributes } = usePopper(referenceElement, popperElement, { | |||
strategy, | |||
onFirstUpdate, | |||
placement, | |||
placement: | |||
document.documentElement.dir === 'rtl' |
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.
again, not ideal - I think the main reason we wouldn't want to do the flipping, is that people who are actually writing apps for an RTL-language would set the placement correctly, and then we will go ahead and flip it.
But we can assume for backwards-compatibility that any implementation out there are LTR, and keep this logic. In the future, maybe the flipping can be controlled with a different prop
</td> | ||
) | ||
) => { | ||
const rtlAlign = rtlCorrespondingAlignments[align] |
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.
shouldn't be the case, but let's fallback to what they pass if no match const rtlAlign = rtlCorrespondingAlignments[align] ?? align
# [9.3.0-alpha.1](v9.2.0...v9.3.0-alpha.1) (2024-02-08) ### Features * rtl support for components [LIBS-525] ([#1448](#1448)) ([d8b5fec](d8b5fec))
Implements LIBS-525
Description
This PR adds RTL support to our existing components. This involves:
padding-inline-start
instead ofpadding-left
):dir(rtl)
) (e.g. to transform arrows in transfer component) to make sense with dir=rtlleft
toright
(and vice versa) where this is provided (e.g. in Tables)margin
in divider if dir=rtl)Note on approach: I've made these changes manually rather than using a code mode, in part because the code mods I saw seemed to mostly be focused on css files where we have styling as jsx for most components. Also, making manual changes allowed more control over the actual changes (see points below). Finally, there were a number of issues that would not be addressed by updating logical properties.
Note on logical properties: For the most part I have only updated to logical properties to convert left/right to inline. This simplifies things a bit as some existing shorthand notation does not need updating (e.g.
padding: 4px 8px
has equal values on left/right, so doesn't need to be converted to logical property). I opted for mostly minimally intrusive changes, so I left valid values that did not cause issues.I didn't think it was worth it to convert top/bottom to block logical properties because the changes needed to support tb text is much more comprehensive (and involves updating css with changes like
width
toinline-size
and also settingwriting-mode
(which we're not doing)). There's only one major script (traditional Mongolian) that is written exclusively TB, and DHIS2 is only used by NGOs in Mongolia; also the Mongolian language can be written in Cyrillic (which seems to be the more common script). So, in general I've just kept top/bottom references and only switched to block in a couple cases where I was already breaking out something likemargin: 1px 5px 10px 2px
.Known issues
LTR:
RTL:
This is because I've applied a transformation on the entire switch icon, which would also rotate the checkmark (undesired), so I have defaulted to hiding it until we make more comprehensive update to Switch
Checklist
I've generally not updated API docs because I haven't changed the API. I think we want people to generally assume that the component will display correctly in RTL? I have updated the chip component documentation because I have added
marginInlineStart
andmarginInlineEnd
to complementmarginLeft
andmarginRight
props we already hadWe discussed this before in context of previous updates and decided that adding tests for RTL was not necessary (at least for logical properties updates). If we think there should be tests for non-logical-property changes, I could add some?
I've added a demo (generally called RTL) for components that will look different in RTL (i.e. most of them). I've added a story even in a few cases where there are no actual updates to the component itself (e.g. Linear Loader) just to illustrate how things will look.
Note because of the portal, I sometimes need to use useEffect within the storybook demos to set the document direction (with app-platform the portal direction should also be set, so this is strictly a step for making the storybook demos behave appropriately)
Screenshots
There are a lot of changes, so probably best to run the storybook locally and review the RTL stories.