Commit 6d8a96b7 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Add a more prominent pressed state for top bar buttons

parent 247f7eff
import type { IconButtonProps } from '@hypothesis/frontend-shared';
import { IconButton } from '@hypothesis/frontend-shared';
import classnames from 'classnames';
export type PressableIconButtonProps = IconButtonProps;
/**
* An IconButton which can be used as a toggle with a more visible pressed state.
* Appropriate when the pressed state is not otherwise obvious from the context.
*/
export default function PressableIconButton({
classes,
...rest
}: PressableIconButtonProps) {
return (
<IconButton
{...rest}
classes={classnames(
classes,
'border border-transparent',
'aria-pressed:border-grey-3 aria-pressed:bg-grey-1',
)}
/>
);
}
import { import { LinkButton, HelpIcon, ShareIcon } from '@hypothesis/frontend-shared';
IconButton,
LinkButton,
HelpIcon,
ShareIcon,
} from '@hypothesis/frontend-shared';
import classnames from 'classnames'; import classnames from 'classnames';
import type { SidebarSettings } from '../../types/config'; import type { SidebarSettings } from '../../types/config';
...@@ -14,6 +9,7 @@ import type { FrameSyncService } from '../services/frame-sync'; ...@@ -14,6 +9,7 @@ import type { FrameSyncService } from '../services/frame-sync';
import { useSidebarStore } from '../store'; import { useSidebarStore } from '../store';
import GroupList from './GroupList'; import GroupList from './GroupList';
import PendingUpdatesButton from './PendingUpdatesButton'; import PendingUpdatesButton from './PendingUpdatesButton';
import PressableIconButton from './PressableIconButton';
import SearchInput from './SearchInput'; import SearchInput from './SearchInput';
import SortMenu from './SortMenu'; import SortMenu from './SortMenu';
import StreamSearchInput from './StreamSearchInput'; import StreamSearchInput from './StreamSearchInput';
...@@ -108,28 +104,32 @@ function TopBar({ ...@@ -108,28 +104,32 @@ function TopBar({
/> />
<SortMenu /> <SortMenu />
{showShareButton && ( {showShareButton && (
<IconButton <PressableIconButton
icon={ShareIcon} icon={ShareIcon}
expanded={isAnnotationsPanelOpen} expanded={isAnnotationsPanelOpen}
pressed={isAnnotationsPanelOpen}
onClick={toggleSharePanel} onClick={toggleSharePanel}
size="xs" size="xs"
title="Share annotations on this page" title="Share annotations on this page"
data-testid="share-icon-button"
/> />
)} )}
</> </>
)} )}
<IconButton <PressableIconButton
icon={HelpIcon} icon={HelpIcon}
expanded={isHelpPanelOpen} expanded={isHelpPanelOpen}
pressed={isHelpPanelOpen}
onClick={requestHelp} onClick={requestHelp}
size="xs" size="xs"
title="Help" title="Help"
data-testid="help-icon-button"
/> />
{isLoggedIn ? ( {isLoggedIn ? (
<UserMenu onLogout={onLogout} /> <UserMenu onLogout={onLogout} />
) : ( ) : (
<div <div
className="flex items-center text-md font-medium space-x-1" className="flex items-center text-md font-medium space-x-1 pl-1"
data-testid="login-links" data-testid="login-links"
> >
{!isLoggedIn && !hasFetchedProfile && <span></span>} {!isLoggedIn && !hasFetchedProfile && <span></span>}
......
...@@ -39,17 +39,22 @@ describe('TopBar', () => { ...@@ -39,17 +39,22 @@ describe('TopBar', () => {
'../store': { useSidebarStore: () => fakeStore }, '../store': { useSidebarStore: () => fakeStore },
'../config/service-config': { serviceConfig: fakeServiceConfig }, '../config/service-config': { serviceConfig: fakeServiceConfig },
}); });
$imports.$restore({
// `PressableIconButton` is a presentation-only component. Not mocking it
// allows to get it covered.
'./PressableIconButton': true,
});
}); });
afterEach(() => { afterEach(() => {
$imports.$restore(); $imports.$restore();
}); });
// Helper to retrieve an `Button` by icon name, for convenience // Helper to retrieve an `Button` by test ID, for convenience
function getButton(wrapper, iconName) { function getButton(wrapper, testId) {
return wrapper return wrapper
.find('IconButton') .find('PressableIconButton')
.filterWhere(n => n.find(iconName).exists()); .filterWhere(n => n.find(`[data-testid="${testId}"]`).exists());
} }
function createTopBar(props = {}) { function createTopBar(props = {}) {
...@@ -69,7 +74,7 @@ describe('TopBar', () => { ...@@ -69,7 +74,7 @@ describe('TopBar', () => {
context('no help service handler configured in services (default)', () => { context('no help service handler configured in services (default)', () => {
it('toggles Help Panel on click', () => { it('toggles Help Panel on click', () => {
const wrapper = createTopBar(); const wrapper = createTopBar();
const helpButton = getButton(wrapper, 'HelpIcon'); const helpButton = getButton(wrapper, 'help-icon-button');
helpButton.props().onClick(); helpButton.props().onClick();
...@@ -79,7 +84,7 @@ describe('TopBar', () => { ...@@ -79,7 +84,7 @@ describe('TopBar', () => {
it('displays a help icon active state when help panel active', () => { it('displays a help icon active state when help panel active', () => {
fakeStore.isSidebarPanelOpen.withArgs('help').returns(true); fakeStore.isSidebarPanelOpen.withArgs('help').returns(true);
const wrapper = createTopBar(); const wrapper = createTopBar();
const helpButton = getButton(wrapper, 'HelpIcon'); const helpButton = getButton(wrapper, 'help-icon-button');
wrapper.update(); wrapper.update();
...@@ -91,7 +96,7 @@ describe('TopBar', () => { ...@@ -91,7 +96,7 @@ describe('TopBar', () => {
fakeServiceConfig.returns({ onHelpRequestProvided: true }); fakeServiceConfig.returns({ onHelpRequestProvided: true });
const wrapper = createTopBar(); const wrapper = createTopBar();
const helpButton = getButton(wrapper, 'HelpIcon'); const helpButton = getButton(wrapper, 'help-icon-button');
helpButton.props().onClick(); helpButton.props().onClick();
...@@ -164,7 +169,7 @@ describe('TopBar', () => { ...@@ -164,7 +169,7 @@ describe('TopBar', () => {
it('toggles the share annotations panel when "Share" is clicked', () => { it('toggles the share annotations panel when "Share" is clicked', () => {
const wrapper = createTopBar(); const wrapper = createTopBar();
const shareButton = getButton(wrapper, 'ShareIcon'); const shareButton = getButton(wrapper, 'share-icon-button');
shareButton.props().onClick(); shareButton.props().onClick();
...@@ -176,7 +181,7 @@ describe('TopBar', () => { ...@@ -176,7 +181,7 @@ describe('TopBar', () => {
.withArgs('shareGroupAnnotations') .withArgs('shareGroupAnnotations')
.returns(true); .returns(true);
const wrapper = createTopBar(); const wrapper = createTopBar();
const shareButton = getButton(wrapper, 'ShareIcon'); const shareButton = getButton(wrapper, 'share-icon-button');
assert.isTrue(shareButton.prop('expanded')); assert.isTrue(shareButton.prop('expanded'));
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment