Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions packages/material-ui/src/Popper/Popper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ import React from 'react';
import PropTypes from 'prop-types';
import PopperJS from 'popper.js';
import { chainPropTypes, refType } from '@material-ui/utils';
import { useTheme } from '@material-ui/styles';
import Portal from '../Portal';
import createChainedFunction from '../utils/createChainedFunction';
import setRef from '../utils/setRef';
import useForkRef from '../utils/useForkRef';
import ownerWindow from '../utils/ownerWindow';

/**
* Flips placement if in <body dir="rtl" />
* @param {string} placement
*/
function flipPlacement(placement) {
const direction = (typeof window !== 'undefined' && document.body.getAttribute('dir')) || 'ltr';
function flipPlacement(placement, theme) {
const direction = (theme && theme.direction) || 'ltr';

if (direction !== 'rtl') {
if (direction === 'ltr') {
return placement;
}

Expand Down Expand Up @@ -72,7 +69,8 @@ const Popper = React.forwardRef(function Popper(props, ref) {

const [exited, setExited] = React.useState(true);

const rtlPlacement = flipPlacement(initialPlacement);
const theme = useTheme();
const rtlPlacement = flipPlacement(initialPlacement, theme);
/**
* placement initialized from prop but can change during lifetime if modifiers.flip.
* modifiers.flip is essentially a flip for controlled/uncontrolled behavior
Expand Down
57 changes: 31 additions & 26 deletions packages/material-ui/src/Popper/Popper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { assert, expect } from 'chai';
import { spy, useFakeTimers } from 'sinon';
import PropTypes from 'prop-types';
import { createMount } from '@material-ui/core/test-utils';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import describeConformance from '@material-ui/core/test-utils/describeConformance';
import { createClientRender } from 'test/utils/createClientRender';
import consoleErrorMock from 'test/utils/consoleErrorMock';
Expand All @@ -12,6 +13,7 @@ import Popper from './Popper';

describe('<Popper />', () => {
let mount;
let rtlTheme;
const render = createClientRender({ strict: true });
const defaultProps = {
anchorEl: () => document.createElement('svg'),
Expand All @@ -21,6 +23,9 @@ describe('<Popper />', () => {

before(() => {
mount = createMount({ strict: true });
rtlTheme = createMuiTheme({
direction: 'rtl',
});
});

after(() => {
Expand All @@ -40,23 +45,17 @@ describe('<Popper />', () => {
}));

describe('prop: placement', () => {
before(() => {
document.body.setAttribute('dir', 'rtl');
});

after(() => {
document.body.removeAttribute('dir');
});

it('should have top placement', () => {
const renderSpy = spy();
mount(
<Popper {...defaultProps} placement="top">
{({ placement }) => {
renderSpy(placement);
return null;
}}
</Popper>,
<ThemeProvider theme={rtlTheme}>
<Popper {...defaultProps} placement="top">
{({ placement }) => {
renderSpy(placement);
return null;
}}
</Popper>
</ThemeProvider>,
);
assert.strictEqual(renderSpy.callCount, 2); // 2 for strict mode
assert.strictEqual(renderSpy.args[0][0], 'top');
Expand Down Expand Up @@ -87,12 +86,15 @@ describe('<Popper />', () => {
it(`should flip ${test.in} when direction=rtl is used`, () => {
const renderSpy = spy();
mount(
<Popper {...defaultProps} placement={test.in}>
{({ placement }) => {
renderSpy(placement);
return null;
}}
</Popper>,
<ThemeProvider theme={rtlTheme}>
<Popper {...defaultProps} placement={test.in}>
{({ placement }) => {
renderSpy(placement);
return null;
}}
</Popper>
,
</ThemeProvider>,
);
assert.strictEqual(renderSpy.callCount, 2);
assert.strictEqual(renderSpy.args[0][0], test.out);
Expand All @@ -103,12 +105,15 @@ describe('<Popper />', () => {
const renderSpy = spy();
const popperRef = React.createRef();
render(
<Popper popperRef={popperRef} {...defaultProps} placement="bottom">
{({ placement }) => {
renderSpy(placement);
return null;
}}
</Popper>,
<ThemeProvider theme={rtlTheme}>
<Popper popperRef={popperRef} {...defaultProps} placement="bottom">
{({ placement }) => {
renderSpy(placement);
return null;
}}
</Popper>
,
</ThemeProvider>,
);
expect(renderSpy.args).to.deep.equal([['bottom'], ['bottom']]);
popperRef.current.options.onUpdate({
Expand Down