diff --git a/__tests__/src/components/CompanionArea.test.js b/__tests__/src/components/CompanionArea.test.js index f896ddb434ceec168bd9976b43061ddf2c6f6299..87382872ed665d76c310f1d7ec976c70ac2bfeb6 100644 --- a/__tests__/src/components/CompanionArea.test.js +++ b/__tests__/src/components/CompanionArea.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { shallow } from 'enzyme'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; import { CompanionArea } from '../../../src/components/CompanionArea'; import CompanionWindowFactory from '../../../src/containers/CompanionWindowFactory'; @@ -45,13 +46,13 @@ describe('CompanionArea', () => { position: 'left', sideBarOpen: true, setCompanionAreaOpen, companionAreaOpen: false, }); - expect(wrapper.find('MiradorMenuButton').length).toBe(1); - expect(wrapper.find('MiradorMenuButton').first().children('pure(ArrowRightSharpIcon)').length).toBe(1); + expect(wrapper.find(MiradorMenuButton).length).toBe(1); + expect(wrapper.find(MiradorMenuButton).first().children('pure(ArrowRightSharpIcon)').length).toBe(1); expect(wrapper.find('div.mirador-companion-windows').length).toBe(1); expect(wrapper.find('div.mirador-companion-windows').props().style.display).toBe('none'); - wrapper.find('MiradorMenuButton').first().props().onClick(); // Trigger the onClick prop + wrapper.find(MiradorMenuButton).first().props().onClick(); // Trigger the onClick prop expect(setCompanionAreaOpen).toHaveBeenCalledWith('abc123', true); }); @@ -63,13 +64,13 @@ describe('CompanionArea', () => { position: 'left', sideBarOpen: true, setCompanionAreaOpen, companionAreaOpen: true, }); - expect(wrapper.find('MiradorMenuButton').length).toBe(1); - expect(wrapper.find('MiradorMenuButton').first().children('pure(ArrowLeftSharpIcon)').length).toBe(1); + expect(wrapper.find(MiradorMenuButton).length).toBe(1); + expect(wrapper.find(MiradorMenuButton).first().children('pure(ArrowLeftSharpIcon)').length).toBe(1); expect(wrapper.find('div.mirador-companion-windows').length).toBe(1); expect(wrapper.find('div.mirador-companion-windows').props().style.display).toBe('flex'); - wrapper.find('MiradorMenuButton').first().props().onClick(); // Trigger the onClick prop + wrapper.find(MiradorMenuButton).first().props().onClick(); // Trigger the onClick prop expect(setCompanionAreaOpen).toHaveBeenCalledWith('abc123', false); }); @@ -79,7 +80,7 @@ describe('CompanionArea', () => { position: 'left', sideBarOpen: false, setCompanionAreaOpen: () => {}, companionAreaOpen: true, }); - expect(wrapper.find('MiradorMenuButton').length).toBe(0); + expect(wrapper.find(MiradorMenuButton).length).toBe(0); }); it('does not show a toggle in other positions', () => { @@ -87,6 +88,6 @@ describe('CompanionArea', () => { position: 'whatever', sideBarOpen: true, setCompanionAreaOpen: () => {}, companionAreaOpen: true, }); - expect(wrapper.find('MiradorMenuButton').length).toBe(0); + expect(wrapper.find(MiradorMenuButton).length).toBe(0); }); }); diff --git a/__tests__/src/components/CompanionWindow.test.js b/__tests__/src/components/CompanionWindow.test.js index 632362db1f89ed0538718d0976623bdf6c18e225..c69f9291e76b6fb23840dbfed15642ed6f42b420 100644 --- a/__tests__/src/components/CompanionWindow.test.js +++ b/__tests__/src/components/CompanionWindow.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { shallow } from 'enzyme'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; import { CompanionWindow } from '../../../src/components/CompanionWindow'; /** create wrapper */ @@ -27,7 +28,7 @@ describe('CompanionWindow', () => { position: 'left', }); - const button = companionWindow.find('MiradorMenuButton'); + const button = companionWindow.find(MiradorMenuButton); button.props().onClick(); // Trigger the onClick prop expect(updateCompanionWindow).toHaveBeenCalledTimes(1); expect(updateCompanionWindow).toHaveBeenCalledWith('x', 'abc123', { position: 'right' }); @@ -41,7 +42,7 @@ describe('CompanionWindow', () => { onCloseClick: removeCompanionWindowEvent, }); - const button = companionWindow.find('MiradorMenuButton'); + const button = companionWindow.find(MiradorMenuButton); button.props().onClick(); // Trigger the onClick prop expect(removeCompanionWindowEvent).toHaveBeenCalledTimes(1); }); @@ -53,7 +54,7 @@ describe('CompanionWindow', () => { expect(companionWindow.find('WithStyles(Paper).vertical').length).toBe(1); - const button = companionWindow.find('MiradorMenuButton').first(); + const button = companionWindow.find(MiradorMenuButton).first(); button.props().onClick(); // Trigger the onClick prop expect(updateCompanionWindow).toHaveBeenCalledTimes(1); expect(updateCompanionWindow).toHaveBeenCalledWith('x', 'abc123', { position: 'bottom' }); @@ -65,7 +66,7 @@ describe('CompanionWindow', () => { expect(companionWindow.find('WithStyles(Paper).horizontal').length).toBe(1); - const button = companionWindow.find('MiradorMenuButton').first(); + const button = companionWindow.find(MiradorMenuButton).first(); button.props().onClick(); // Trigger the onClick prop expect(updateCompanionWindow).toHaveBeenCalledTimes(1); expect(updateCompanionWindow).toHaveBeenCalledWith('x', 'abc123', { position: 'right' }); diff --git a/__tests__/src/components/MiradorMenuButton.test.js b/__tests__/src/components/MiradorMenuButton.test.js index f993d4af225c75421908661d1d54e35d295f04ae..816b67e5b43398d389caed442c82d1351334926c 100644 --- a/__tests__/src/components/MiradorMenuButton.test.js +++ b/__tests__/src/components/MiradorMenuButton.test.js @@ -7,7 +7,7 @@ import { MiradorMenuButton } from '../../../src/components/MiradorMenuButton'; */ function createWrapper(props) { return shallow( - <MiradorMenuButton aria-label="The Label" {...props}> + <MiradorMenuButton aria-label="The Label" containerId="mirador" {...props}> <>icon</> </MiradorMenuButton>, ); @@ -42,6 +42,12 @@ describe('MiradorMenuButton', () => { expect(wrapper.find('WithStyles(Tooltip) span').props().className).toEqual('someClass'); }); + it('spreads TooltipProps to the Tooltip component', () => { + wrapper = createWrapper({ TooltipProps: { style: { color: 'red' } } }); + + expect(wrapper.find('WithStyles(Tooltip)').props().style).toEqual({ color: 'red' }); + }); + it('spreads any other props to IconButton', () => { wrapper = createWrapper({ color: 'inherit' }); diff --git a/__tests__/src/components/WindowTopBar.test.js b/__tests__/src/components/WindowTopBar.test.js index 4706ceefc41b2a5f2e58c9e7ec23e45d2d90eb40..14085b7bdc9a1e67cb0006487b4b0676bd370f16 100644 --- a/__tests__/src/components/WindowTopBar.test.js +++ b/__tests__/src/components/WindowTopBar.test.js @@ -7,7 +7,7 @@ import AppBar from '@material-ui/core/AppBar'; import WindowTopMenuButton from '../../../src/containers/WindowTopMenuButton'; import WindowTopBarButtons from '../../../src/containers/WindowTopBarButtons'; -import { MiradorMenuButton } from '../../../src/components/MiradorMenuButton'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; import { WindowTopBar } from '../../../src/components/WindowTopBar'; /** create wrapper */ diff --git a/__tests__/src/components/WindowTopMenuButton.test.js b/__tests__/src/components/WindowTopMenuButton.test.js index a797287baf750e47988a42818d66dc741d626d4c..37c147c0496fb2337ea2e84ae232ca115411efb9 100644 --- a/__tests__/src/components/WindowTopMenuButton.test.js +++ b/__tests__/src/components/WindowTopMenuButton.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import WindowTopMenu from '../../../src/containers/WindowTopMenu'; import { WindowTopMenuButton } from '../../../src/components/WindowTopMenuButton'; -import { MiradorMenuButton } from '../../../src/components/MiradorMenuButton'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; /** create wrapper */ function createWrapper(props) { diff --git a/__tests__/src/components/WorkspaceFullScreenButton.test.js b/__tests__/src/components/WorkspaceFullScreenButton.test.js index 1981f9ce6ae1f1c7fe03d590e935d3644c76a742..41e8f63710650e8a7ec12c3a1eea48dfcab4e0e1 100644 --- a/__tests__/src/components/WorkspaceFullScreenButton.test.js +++ b/__tests__/src/components/WorkspaceFullScreenButton.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { shallow } from 'enzyme'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; import { WorkspaceFullScreenButton } from '../../../src/components/WorkspaceFullScreenButton'; /** */ @@ -21,7 +22,7 @@ describe('WorkspaceFullScreenButton', () => { it('renders without an error', () => { wrapper = createWrapper(); - expect(wrapper.find('MiradorMenuButton').length).toBe(1); + expect(wrapper.find(MiradorMenuButton).length).toBe(1); }); describe('when not in fullscreen', () => { @@ -29,7 +30,7 @@ describe('WorkspaceFullScreenButton', () => { beforeAll(() => { setWorkspaceFullscreen = jest.fn(); wrapper = createWrapper({ setWorkspaceFullscreen }); - menuButton = wrapper.find('MiradorMenuButton'); + menuButton = wrapper.find(MiradorMenuButton); }); it('has the FullscreenIcon', () => { @@ -51,7 +52,7 @@ describe('WorkspaceFullScreenButton', () => { beforeAll(() => { setWorkspaceFullscreen = jest.fn(); wrapper = createWrapper({ setWorkspaceFullscreen, isFullscreenEnabled: true }); - menuButton = wrapper.find('MiradorMenuButton'); + menuButton = wrapper.find(MiradorMenuButton); }); it('has the FullscreenExitIcon', () => { diff --git a/__tests__/src/components/WorkspaceMenuButton.test.js b/__tests__/src/components/WorkspaceMenuButton.test.js index 879ffd878ed3d9a6ba64219ce3316b9a0702e67f..219c39b10f85a8a1f2aac54bf0267c5bfa0b0bc7 100644 --- a/__tests__/src/components/WorkspaceMenuButton.test.js +++ b/__tests__/src/components/WorkspaceMenuButton.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { shallow } from 'enzyme'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; import { WorkspaceMenuButton } from '../../../src/components/WorkspaceMenuButton'; describe('WorkspaceMenuButton', () => { @@ -11,16 +12,16 @@ describe('WorkspaceMenuButton', () => { }); it('renders without an error', () => { - expect(wrapper.find('MiradorMenuButton').length).toBe(1); + expect(wrapper.find(MiradorMenuButton).length).toBe(1); }); it('the button has a class indicating that it is "selected" once it is clicked', () => { - const menuButton = wrapper.find('MiradorMenuButton').first(); + const menuButton = wrapper.find(MiradorMenuButton).first(); - expect(wrapper.find('MiradorMenuButton').first().props().className).toEqual(''); + expect(wrapper.find(MiradorMenuButton).first().props().className).toEqual(''); menuButton.props().onClick({ currentTarget: 'anElement' }); - expect(wrapper.find('MiradorMenuButton').first().props().className).toEqual('ctrlBtnSelected'); + expect(wrapper.find(MiradorMenuButton).first().props().className).toEqual('ctrlBtnSelected'); menuButton.props().onClick({}); - expect(wrapper.find('MiradorMenuButton').first().props().className).toEqual(''); + expect(wrapper.find(MiradorMenuButton).first().props().className).toEqual(''); }); }); diff --git a/__tests__/src/components/ZoomControls.test.js b/__tests__/src/components/ZoomControls.test.js index 98d792acb8a9a5eea74352e956304e0422e3b8c0..27ecd4ffc396c814a99d345ebd433e3b56380f5b 100644 --- a/__tests__/src/components/ZoomControls.test.js +++ b/__tests__/src/components/ZoomControls.test.js @@ -1,5 +1,6 @@ import React from 'react'; import { shallow } from 'enzyme'; +import MiradorMenuButton from '../../../src/containers/MiradorMenuButton'; import { ZoomControls } from '../../../src/components/ZoomControls'; describe('ZoomControls', () => { @@ -47,7 +48,7 @@ describe('ZoomControls', () => { it('renders a couple buttons', () => { expect(wrapper.find('div.zoom_controls').length).toBe(1); - expect(wrapper.find('MiradorMenuButton').length).toBe(3); + expect(wrapper.find(MiradorMenuButton).length).toBe(3); }); it('has a zoom-in button', () => { diff --git a/src/components/CompanionArea.js b/src/components/CompanionArea.js index 15d4f7ac505f8de6a4d1b27f992c8e28dcf30f86..3a00400a7dcde62fe60fe7226594689a8a753b28 100644 --- a/src/components/CompanionArea.js +++ b/src/components/CompanionArea.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import ArrowLeftIcon from '@material-ui/icons/ArrowLeftSharp'; import ArrowRightIcon from '@material-ui/icons/ArrowRightSharp'; import CompanionWindowFactory from '../containers/CompanionWindowFactory'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; import ns from '../config/css-ns'; /** */ @@ -33,6 +33,7 @@ export class CompanionArea extends Component { aria-label={companionAreaOpen ? t('collapseSidePanel') : t('expandSidePanel')} className={classes.toggle} onClick={() => { setCompanionAreaOpen(windowId, !companionAreaOpen); }} + TooltipProps={{ style: { right: '0', position: 'absolute' } }} > {companionAreaOpen ? <ArrowLeftIcon /> : <ArrowRightIcon />} </MiradorMenuButton> diff --git a/src/components/CompanionWindow.js b/src/components/CompanionWindow.js index 620a5e26d5cc8a25143575fd1fbe9d93e706816d..0fc4093f5cfb61f5f3af662bde675db689d5e462 100644 --- a/src/components/CompanionWindow.js +++ b/src/components/CompanionWindow.js @@ -7,7 +7,7 @@ import Typography from '@material-ui/core/Typography'; import Toolbar from '@material-ui/core/Toolbar'; import ThumbnailNavigationBottomIcon from './icons/ThumbnailNavigationBottomIcon'; import ThumbnailNavigationRightIcon from './icons/ThumbnailNavigationRightIcon'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; import ns from '../config/css-ns'; /** diff --git a/src/components/MiradorMenuButton.js b/src/components/MiradorMenuButton.js index 40d9564e71c730643e8b2cd2de98f01232f4c907..8b3bf1e529f14d6da59fe635989b55b64663f507 100644 --- a/src/components/MiradorMenuButton.js +++ b/src/components/MiradorMenuButton.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import IconButton from '@material-ui/core/IconButton'; import Tooltip from '@material-ui/core/Tooltip'; - +import ns from '../config/css-ns'; /** * MiradorMenuButton ~ Wrap the given icon prop in an IconButton and a Tooltip. @@ -11,16 +11,31 @@ import Tooltip from '@material-ui/core/Tooltip'; */ export function MiradorMenuButton(props) { const { 'aria-label': ariaLabel } = props; - const { children, wrapperClassName, ...iconButtonProps } = props; + const { + children, + containerId, + dispatch, + TooltipProps, + wrapperClassName, + ...iconButtonProps + } = props; return ( - <Tooltip title={ariaLabel}> + <Tooltip + PopperProps={{ + container: document.querySelector(`#${containerId} .${ns('viewer')}`), + }} + title={ariaLabel} + {...TooltipProps} + > {/* Wrap IconButton in span so it can receive mouse events (e.g. show the tooltip) even if the IconButton is disabled */} <span className={wrapperClassName}> - <IconButton {...iconButtonProps}>{children}</IconButton> + <IconButton {...iconButtonProps}> + {children} + </IconButton> </span> </Tooltip> ); @@ -29,9 +44,14 @@ export function MiradorMenuButton(props) { MiradorMenuButton.propTypes = { 'aria-label': PropTypes.string.isRequired, children: PropTypes.element.isRequired, + containerId: PropTypes.string.isRequired, + dispatch: PropTypes.func, + TooltipProps: PropTypes.object, // eslint-disable-line react/forbid-prop-types wrapperClassName: PropTypes.string, }; MiradorMenuButton.defaultProps = { + dispatch: () => {}, + TooltipProps: {}, wrapperClassName: null, }; diff --git a/src/components/ViewerNavigation.js b/src/components/ViewerNavigation.js index de84484d1fa6e8648e25613f280be26ec919c855..00d47a7c64e6d7736c2adb1f27e100413a635f94 100644 --- a/src/components/ViewerNavigation.js +++ b/src/components/ViewerNavigation.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import NavigationIcon from '@material-ui/icons/PlayCircleOutlineSharp'; import PropTypes from 'prop-types'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; import ns from '../config/css-ns'; /** diff --git a/src/components/WindowTopBar.js b/src/components/WindowTopBar.js index 0dfdce86fea22c964d9a862e934a10878c808714..739611b05c25c28e8b3dbb55bb2994e9a2b4063f 100644 --- a/src/components/WindowTopBar.js +++ b/src/components/WindowTopBar.js @@ -10,7 +10,7 @@ import AppBar from '@material-ui/core/AppBar'; import classNames from 'classnames'; import WindowTopMenuButton from '../containers/WindowTopMenuButton'; import WindowTopBarButtons from '../containers/WindowTopBarButtons'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; import ns from '../config/css-ns'; diff --git a/src/components/WindowTopMenuButton.js b/src/components/WindowTopMenuButton.js index 901d6349cb6e3dca15cc6538065e68bb3c089655..94df821248b4b254d15bd038ba8a497a872cc2e7 100644 --- a/src/components/WindowTopMenuButton.js +++ b/src/components/WindowTopMenuButton.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import MoreVertIcon from '@material-ui/icons/MoreVertSharp'; import PropTypes from 'prop-types'; import WindowTopMenu from '../containers/WindowTopMenu'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; /** */ diff --git a/src/components/WorkspaceAdd.js b/src/components/WorkspaceAdd.js index da05970f60d9e0d106beb802c9490848aa2c82db..5b78d76d80f409fd59b3564f51c84774bf872ec9 100644 --- a/src/components/WorkspaceAdd.js +++ b/src/components/WorkspaceAdd.js @@ -13,7 +13,7 @@ import Typography from '@material-ui/core/Typography'; import ns from '../config/css-ns'; import ManifestForm from '../containers/ManifestForm'; import ManifestListItem from '../containers/ManifestListItem'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; /** * An area for managing manifests and adding them to workspace diff --git a/src/components/WorkspaceFullScreenButton.js b/src/components/WorkspaceFullScreenButton.js index 09fd5528144325ede9faed174e9e7f9c3bc1255a..20b74c455a1443dbdd4c627c4b57890c61a6b2d8 100644 --- a/src/components/WorkspaceFullScreenButton.js +++ b/src/components/WorkspaceFullScreenButton.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import FullscreenIcon from '@material-ui/icons/FullscreenSharp'; import FullscreenExitIcon from '@material-ui/icons/FullscreenExitSharp'; import PropTypes from 'prop-types'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; /** */ export class WorkspaceFullScreenButton extends Component { diff --git a/src/components/WorkspaceMenuButton.js b/src/components/WorkspaceMenuButton.js index 18980d48b8831fd14876206de704014889653425..94bab421356c0fed34b974b7b558e92443f896dc 100644 --- a/src/components/WorkspaceMenuButton.js +++ b/src/components/WorkspaceMenuButton.js @@ -3,7 +3,7 @@ import MenuIcon from '@material-ui/icons/MenuSharp'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import WorkspaceMenu from '../containers/WorkspaceMenu'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; /** */ diff --git a/src/components/ZoomControls.js b/src/components/ZoomControls.js index f96c52a4e49413e1302e8d0d6651a4602bc33422..71e1d7702454d0f43a324d966d3aedbc05441fe6 100644 --- a/src/components/ZoomControls.js +++ b/src/components/ZoomControls.js @@ -3,7 +3,7 @@ import AddCircleIcon from '@material-ui/icons/AddCircleOutlineSharp'; import RemoveCircleIcon from '@material-ui/icons/RemoveCircleOutlineSharp'; import PropTypes from 'prop-types'; import RestoreZoomIcon from './icons/RestoreZoomIcon'; -import { MiradorMenuButton } from './MiradorMenuButton'; +import MiradorMenuButton from '../containers/MiradorMenuButton'; /** */ diff --git a/src/containers/CompanionArea.js b/src/containers/CompanionArea.js index f9d577e2489addb37b578fb708a282a7271a7269..3eacbb201c24bff3b597a26bc2afe33606dc2834 100644 --- a/src/containers/CompanionArea.js +++ b/src/containers/CompanionArea.js @@ -32,7 +32,6 @@ const styles = theme => ({ }, toggle: { position: 'absolute', - left: '100%', width: '1rem', zIndex: theme.zIndex.drawer, backgroundColor: theme.palette.background.paper, diff --git a/src/containers/MiradorMenuButton.js b/src/containers/MiradorMenuButton.js new file mode 100644 index 0000000000000000000000000000000000000000..7cb1b3a00505e5aebf80e0f0695c694c07a5f080 --- /dev/null +++ b/src/containers/MiradorMenuButton.js @@ -0,0 +1,16 @@ +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withPlugins } from '../extend'; +import { MiradorMenuButton } from '../components/MiradorMenuButton'; + +/** */ +const mapStateToProps = state => ({ + containerId: state.config.id, +}); + +const enhance = compose( + connect(mapStateToProps, null), + withPlugins('MiradorMenuButton'), +); + +export default enhance(MiradorMenuButton);