Commit a1bf8115 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Make cluster toolbar collapsible

Collapse the cluster toolbar on initial render and allow user to toggle
it open and closed.

Fixes #4926
parent b394b412
import { import {
Button,
Card, Card,
CardContent, CardContent,
CaretDownIcon,
CaretRightIcon,
HideIcon, HideIcon,
HighlightIcon,
} from '@hypothesis/frontend-shared/lib/next'; } from '@hypothesis/frontend-shared/lib/next';
import classnames from 'classnames'; import classnames from 'classnames';
import { useCallback } from 'preact/hooks'; import { useCallback, useState } from 'preact/hooks';
import type { HighlightCluster } from '../../types/shared'; import type { HighlightCluster } from '../../types/shared';
import type { AppliedStyles, HighlightStyles } from '../highlight-clusters'; import type { AppliedStyles, HighlightStyles } from '../highlight-clusters';
...@@ -120,13 +124,34 @@ export default function ClusterToolbar({ ...@@ -120,13 +124,34 @@ export default function ClusterToolbar({
[onStyleChange] [onStyleChange]
); );
const [isOpen, setOpen] = useState(false);
if (!active) { if (!active) {
return null; return null;
} }
return ( return (
<Card> <Card>
<CardContent size="sm"> <div className="flex flex-col text-annotator-base text-color-text">
<Button
data-testid="control-toggle-button"
onClick={() => setOpen(!isOpen)}
title={isOpen ? 'Hide highlight settings' : 'Show highlight settings'}
>
{isOpen ? (
<>
<CaretDownIcon />
<span>Highlight Appearance</span>
</>
) : (
<>
<CaretRightIcon />
<HighlightIcon />
</>
)}
</Button>
{isOpen && (
<CardContent data-testid="cluster-style-controls" size="sm">
<ClusterStyleControl <ClusterStyleControl
highlightStyles={availableStyles} highlightStyles={availableStyles}
label="My annotations" label="My annotations"
...@@ -149,6 +174,8 @@ export default function ClusterToolbar({ ...@@ -149,6 +174,8 @@ export default function ClusterToolbar({
currentStyles={currentStyles} currentStyles={currentStyles}
/> />
</CardContent> </CardContent>
)}
</div>
</Card> </Card>
); );
} }
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import { highlightStyles, defaultStyles } from '../../highlight-clusters'; import { highlightStyles, defaultStyles } from '../../highlight-clusters';
import ClusterToolbar from '../ClusterToolbar'; import ClusterToolbar from '../ClusterToolbar';
...@@ -17,14 +16,37 @@ describe('ClusterToolbar', () => { ...@@ -17,14 +16,37 @@ describe('ClusterToolbar', () => {
/> />
); );
const toggleOpen = wrapper => {
wrapper
.find('button[data-testid="control-toggle-button"]')
.simulate('click');
};
it('renders nothing if the cluster feature is not active', () => { it('renders nothing if the cluster feature is not active', () => {
const wrapper = createComponent({ active: false }); const wrapper = createComponent({ active: false });
assert.isEmpty(wrapper.html()); assert.isEmpty(wrapper.html());
}); });
it('renders collapsed until expanded', () => {
const wrapper = createComponent();
assert.equal(
wrapper.find('div[data-testid="cluster-style-controls"]').length,
0
);
toggleOpen(wrapper);
assert.equal(
wrapper.find('div[data-testid="cluster-style-controls"]').length,
1
);
});
it('renders a control for each highlight cluster', () => { it('renders a control for each highlight cluster', () => {
const wrapper = createComponent(); const wrapper = createComponent();
toggleOpen(wrapper);
assert.equal( assert.equal(
wrapper.find('ClusterStyleControl').length, wrapper.find('ClusterStyleControl').length,
...@@ -35,6 +57,7 @@ describe('ClusterToolbar', () => { ...@@ -35,6 +57,7 @@ describe('ClusterToolbar', () => {
it('calls style-change callback when user clicks on a style option', () => { it('calls style-change callback when user clicks on a style option', () => {
const onStyleChange = sinon.stub(); const onStyleChange = sinon.stub();
const wrapper = createComponent({ onStyleChange }); const wrapper = createComponent({ onStyleChange });
toggleOpen(wrapper);
wrapper wrapper
.find('#hypothesis-user-annotations-green') .find('#hypothesis-user-annotations-green')
......
...@@ -77,8 +77,8 @@ export class HighlightClusterController implements Destroyable { ...@@ -77,8 +77,8 @@ export class HighlightClusterController implements Destroyable {
// For now, the controls are fixed at top-left of screen. This is temporary. // For now, the controls are fixed at top-left of screen. This is temporary.
Object.assign(this._outerContainer.style, { Object.assign(this._outerContainer.style, {
position: 'fixed', position: 'fixed',
top: 0, top: '4px',
left: 0, left: '4px',
}); });
this.appliedStyles = defaultStyles; this.appliedStyles = defaultStyles;
......
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