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