Skip to content

Commit

Permalink
fix(Listbox): rtl mode (#1144)
Browse files Browse the repository at this point in the history
* fix(Listbox): rtl mode

* fix: updated snapshots

* fix: review comments

* fix: failing tests

* fix: rendering snapshots

* fix: auto merge fails

* fix: rendering snapshots
  • Loading branch information
PurwaShrivastava committed Mar 16, 2023
1 parent d88e765 commit b25bddc
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 16 deletions.
20 changes: 16 additions & 4 deletions apis/nucleus/src/components/ActionsToolbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ const ActionToolbarElement = {
};

const ActionsGroup = React.forwardRef(
({ ariaExpanded = false, actions = [], first = false, last = false, addAnchor = false }, ref) =>
({ ariaExpanded = false, actions = [], first = false, last = false, addAnchor = false, isRtl = false }, ref) =>
actions.length > 0 ? (
<Grid item container gap={0} wrap="nowrap">
<Grid item container gap={0} flexDirection={isRtl ? 'row-reverse' : 'row'} wrap="nowrap">
{actions.map((e, ix) => {
let cls = [];
const isFirstItem = first && ix === 0;
Expand Down Expand Up @@ -111,6 +111,7 @@ function ActionsToolbar({
},
focusHandler = null,
actionsRefMock = null, // for testing
direction = 'ltr',
}) {
const defaultSelectionActions = useDefaultSelectionActions(selections);

Expand Down Expand Up @@ -196,8 +197,17 @@ function ActionsToolbar({
const showActions = newActions.length > 0;
const showMore = moreActions.length > 0;
const showDivider = (showActions && selections.show) || (showMore && selections.show);
const isRtl = direction === 'rtl';

const Actions = (
<Grid ref={actionsRef} onKeyDown={tabCallback} container gap={0} wrap="nowrap">
<Grid
ref={actionsRef}
onKeyDown={tabCallback}
container
gap={0}
wrap="nowrap"
sx={{ flexDirection: isRtl ? 'row-reverse' : 'row' }}
>
{showActions && <ActionsGroup actions={newActions} first last={!showMore && !selections.show} />}
{showMore && (
<ActionsGroup
Expand All @@ -214,7 +224,9 @@ function ActionsToolbar({
<Divider orientation="vertical" />
</Grid>
)}
{selections.show && <ActionsGroup actions={defaultSelectionActions} first={!showActions && !showMore} last />}
{selections.show && (
<ActionsGroup actions={defaultSelectionActions} first={!showActions && !showMore} last isRtl={isRtl} />
)}
{showMoreItems && (
<More
show={showMoreItems}
Expand Down
30 changes: 23 additions & 7 deletions apis/nucleus/src/components/listbox/ListBoxInline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const StyledGrid = styled(Grid, { shouldForwardProp: (p) => !['containerPadding'
backgroundColor: theme.listBox?.backgroundColor ?? theme.palette.background.default,
[`& .${classes.listBoxHeader}`]: {
alignSelf: 'center',
display: 'inline-flex',
display: 'flex',
width: `calc(100% - ${BUTTON_ICON_WIDTH}px)`,
},
[`& .${classes.screenReaderOnly}`]: {
Expand Down Expand Up @@ -187,7 +187,7 @@ function ListBoxInline({ options, layout }) {
}

const isLocked = layout.qListObject.qDimensionInfo.qLocked === true;

const isRtl = direction === 'rtl';
const isDrillDown = layout.qListObject.qDimensionInfo.qGrouping === 'H';
const listboxSelectionToolbarItems = createListboxSelectionToolbar({
layout,
Expand Down Expand Up @@ -228,6 +228,7 @@ function ListBoxInline({ options, layout }) {
const showIcons = showSearchOrLockIcon || isDrillDown;
const iconsWidth = (showSearchOrLockIcon ? BUTTON_ICON_WIDTH : 0) + (isDrillDown ? ICON_WIDTH + ICON_PADDING : 0); // Drill-down icon needs padding right so there is space between the icon and the title
const headerPaddingLeft = CELL_PADDING_LEFT - (showSearchOrLockIcon ? ICON_PADDING : 0);
const headerPaddingRight = isRtl ? CELL_PADDING_LEFT - (showIcons ? ICON_PADDING : 0) : 0;

// Add a container padding for grid mode to harmonize with the grid item margins (should sum to 8px).
const isGridMode = layoutOptions?.dataLayout === 'grid';
Expand All @@ -238,7 +239,7 @@ function ListBoxInline({ options, layout }) {

return (
<>
{toolbarDetachedOnly && <ActionsToolbar {...getActionToolbarProps(true)} />}
{toolbarDetachedOnly && <ActionsToolbar direction={direction} {...getActionToolbarProps(true)} />}
<StyledGrid
className="listbox-container"
container
Expand All @@ -256,10 +257,21 @@ function ListBoxInline({ options, layout }) {
<Grid
item
container
style={{ padding: theme.spacing(1), paddingLeft: `${headerPaddingLeft}px` }}
style={{
padding: theme.spacing(1),
paddingLeft: `${headerPaddingLeft}px`,
paddingRight: `${headerPaddingRight}px`,
}}
sx={{ flexDirection: isRtl ? 'row-reverse' : 'row' }}
wrap="nowrap"
>
<Grid item container height={headerHeight} wrap="nowrap">
<Grid
item
container
height={headerHeight}
sx={{ flexDirection: isRtl ? 'row-reverse' : 'row' }}
wrap="nowrap"
>
{showIcons && (
<Grid item sx={{ display: 'flex', alignItems: 'center', width: iconsWidth }}>
{isLocked ? (
Expand Down Expand Up @@ -290,7 +302,7 @@ function ListBoxInline({ options, layout }) {
)}
</Grid>
)}
<Grid item className={classes.listBoxHeader}>
<Grid item sx={{ justifyContent: isRtl ? 'flex-end' : 'flex-start' }} className={classes.listBoxHeader}>
{showTitle && (
<Title variant="h6" noWrap ref={titleRef} title={layout.title}>
{layout.title}
Expand All @@ -300,7 +312,10 @@ function ListBoxInline({ options, layout }) {
</Grid>
<Grid item xs />
<Grid item>
<ActionsToolbar {...getActionToolbarProps(showToolbarDetached({ containerRef, titleRef, iconsWidth }))} />
<ActionsToolbar
direction={direction}
{...getActionToolbarProps(showToolbarDetached({ containerRef, titleRef, iconsWidth }))}
/>
</Grid>
</Grid>
)}
Expand All @@ -326,6 +341,7 @@ function ListBoxInline({ options, layout }) {
searchContainerRef={searchContainerRef}
wildCardSearch={wildCardSearch}
searchEnabled={searchEnabled}
direction={direction}
/>
</Grid>
<Grid item xs className={classes.listboxWrapper}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-nested-ternary */
import React, { useEffect, useCallback, useRef, useMemo } from 'react';

import { Grid } from '@mui/material';
Expand Down Expand Up @@ -123,7 +124,11 @@ function RowColumn({ index, rowIndex, columnIndex, style, data }) {
};

if (isAutoTextAlign) {
valueTextAlign = isNumeric ? 'right' : dirToTextAlignMap[direction];
if (!isNumeric) {
valueTextAlign = dirToTextAlignMap[direction];
} else {
valueTextAlign = direction === 'rtl' ? 'left' : 'right';
}
} else {
valueTextAlign = textAlign?.align || 'left';
}
Expand Down Expand Up @@ -151,7 +156,8 @@ function RowColumn({ index, rowIndex, columnIndex, style, data }) {
alignItems: 'center',
minWidth: 0,
flexGrow: 1,
paddingLeft: checkboxes ? 0 : undefined,
paddingLeft: direction === 'rtl' ? 8 : checkboxes ? 0 : undefined,
paddingRight: checkboxes ? 0 : direction === 'rtl' ? 8 : 0,
justifyContent: valueTextAlign,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -935,14 +935,19 @@ describe('<ListBoxRowColumn />', () => {
expect(type.props.children[1].props.style.justifyContent).toEqual('center');
});

test('should get right text direction', async () => {
test('should get right text direction for non-numeric values', async () => {
const index = 0;
const style = {};
// Just replace qNum with 'NaN' so that we can test alignment for non-numeric values.
const nonNumericPages = defaultPages.map((p) => ({
...p,
qMatrix: p.qMatrix.map(([mx]) => [{ ...mx, qNum: 'NaN' }]),
}));
const data = {
keyboard,
textAlign: { auto: true },
direction: 'rtl',
pages: defaultPages,
pages: nonNumericPages,
dataOffset: 0,
};
const testRenderer = await render(
Expand All @@ -955,6 +960,26 @@ describe('<ListBoxRowColumn />', () => {
expect(type.props.children[1].props.style.justifyContent).toEqual('right');
});

test('should get left text direction for numeric values', async () => {
const index = 0;
const style = {};
const data = {
keyboard,
textAlign: { auto: true },
direction: 'rtl',
pages: defaultPages,
dataOffset: 0,
};
const testRenderer = await render(
<ThemeProvider theme={theme}>
<ListBoxRowColumn index={index} style={style} data={data} column={rowCol === 'column'} />
</ThemeProvider>
);
const testInstance = testRenderer.root;
const type = testInstance.findByType(Grid);
expect(type.props.children[1].props.style.justifyContent).toEqual('left');
});

test('should get left text direction', async () => {
const index = 0;
const style = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ function ValueField({ label, color, highlighted = false, dense, showGray = true,
color={color}
align={valueTextAlign}
>
<span style={{ whiteSpace: 'pre' }}>{label}</span>
<span dir="auto" style={{ whiteSpace: 'pre' }}>
{label}
</span>
</Typography>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const StyledInputAdornment = styled(InputAdornment)(({ theme }) => ({

const StyledOutlinedInput = styled(OutlinedInput)(({ theme }) => ({
color: theme.listBox?.content?.color,
display: 'flex',
}));

export default function ListBoxSearch({
Expand All @@ -28,6 +29,7 @@ export default function ListBoxSearch({
autoFocus = true,
wildCardSearch = false,
searchEnabled,
direction,
}) {
const { translator } = useContext(InstanceContext);
const [value, setValue] = useState('');
Expand All @@ -37,6 +39,8 @@ export default function ListBoxSearch({

const theme = useTheme();
const { getStoreValue } = useDataStore(model);
const isRtl = direction === 'rtl';
const inpuTextAlign = isRtl ? 'right' : 'left';

const cancel = () => selections.isActive() && selections.cancel();

Expand Down Expand Up @@ -160,6 +164,7 @@ export default function ListBoxSearch({
paddingBottom: '5px',
},
},
{ flexDirection: isRtl ? 'row-reverse' : 'row' },
]}
inputRef={inputRef}
size="small"
Expand All @@ -172,6 +177,7 @@ export default function ListBoxSearch({
autoFocus={autoFocus}
inputProps={{
tabIndex: keyboard && (!keyboard.enabled || keyboard.active) ? 0 : -1,
style: { textAlign: `${inpuTextAlign}` },
}}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ exports[`grid-list-components should create a Grid component 1`] = `
"column": undefined,
"columnCount": 2,
"dataOffset": undefined,
"direction": "ltr",
"focusListItems": undefined,
"freqIsAllowed": true,
"frequencyMax": undefined,
Expand Down Expand Up @@ -73,6 +74,7 @@ exports[`grid-list-components should create a List component 1`] = `
"checkboxes": false,
"column": false,
"dataOffset": undefined,
"direction": "ltr",
"focusListItems": undefined,
"freqIsAllowed": true,
"frequencyMax": undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export default function getListBoxComponents({
showTick,
dataOffset: local.current.dataOffset,
focusListItems,
direction,
};

const List = ({ onItemsRendered, ref }) => {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b25bddc

Please sign in to comment.