From 1527e11c29e16dab755a4bbaf7c3393f55ef0dfe Mon Sep 17 00:00:00 2001 From: Jessie Keck <jessie.keck@gmail.com> Date: Tue, 12 Mar 2019 12:36:19 -0700 Subject: [PATCH] Add a MiradorMenuButton component to handle button tooltips/labels/etc. --- .../src/components/MiradorMenuButton.test.js | 44 +++++++++++++++++++ src/components/MiradorMenuButton.js | 32 ++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 __tests__/src/components/MiradorMenuButton.test.js create mode 100644 src/components/MiradorMenuButton.js diff --git a/__tests__/src/components/MiradorMenuButton.test.js b/__tests__/src/components/MiradorMenuButton.test.js new file mode 100644 index 000000000..90142b306 --- /dev/null +++ b/__tests__/src/components/MiradorMenuButton.test.js @@ -0,0 +1,44 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { MiradorMenuButton } from '../../../src/components/MiradorMenuButton'; + +/** + * Helper function to wrap creating a MiradorMenuButton component +*/ +function createWrapper(props) { + return shallow( + <MiradorMenuButton aria-label="The Label" {...props}> + <>icon</> + </MiradorMenuButton>, + ); +} + +describe('MiradorMenuButton', () => { + let wrapper; + + it('renders the given a Tooltip -> IconLabel -> Icon', () => { + wrapper = createWrapper(); + + expect(wrapper.find('WithStyles(Tooltip) WithStyles(IconButton)').length).toEqual(1); + expect( + wrapper + .find('WithStyles(Tooltip) WithStyles(IconButton)') + .first() + .children() + .text(), + ).toEqual('icon'); + }); + + it('uses the aria-label prop the the Tooltip title prop', () => { + wrapper = createWrapper(); + + expect(wrapper.find('WithStyles(Tooltip)').props().title).toEqual('The Label'); + expect(wrapper.find('WithStyles(Tooltip) span WithStyles(IconButton)').props()['aria-label']).toEqual('The Label'); + }); + + it('spreads any other props to IconButton', () => { + wrapper = createWrapper({ color: 'inherit' }); + + expect(wrapper.find('WithStyles(Tooltip) WithStyles(IconButton)').props().color).toEqual('inherit'); + }); +}); diff --git a/src/components/MiradorMenuButton.js b/src/components/MiradorMenuButton.js new file mode 100644 index 000000000..c60bb628d --- /dev/null +++ b/src/components/MiradorMenuButton.js @@ -0,0 +1,32 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; + + +/** + * MiradorMenuButton ~ Wrap the given icon prop in an IconButton and a Tooltip. + * This shares the passed in aria-label w/ the Tooltip (as title) and the IconButton + * All props besides icon are spread to the IconButton component +*/ +export function MiradorMenuButton(props) { + const { 'aria-label': ariaLabel } = props; + const { icon, ...iconButtonProps } = props; + + return ( + <Tooltip title={ariaLabel}> + {/* + Wrap IconButton in span so it can receive mouse events + (e.g. show the tooltip) even if the IconButton is disabled + */} + <span> + <IconButton {...iconButtonProps}>{icon}</IconButton> + </span> + </Tooltip> + ); +} + +MiradorMenuButton.propTypes = { + 'aria-label': PropTypes.string.isRequired, + icon: PropTypes.element.isRequired, +}; -- GitLab