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 {
Button,
Card,
CardContent,
CaretDownIcon,
CaretRightIcon,
HideIcon,
HighlightIcon,
} from '@hypothesis/frontend-shared/lib/next';
import classnames from 'classnames';
import { useCallback } from 'preact/hooks';
import { useCallback, useState } from 'preact/hooks';
import type { HighlightCluster } from '../../types/shared';
import type { AppliedStyles, HighlightStyles } from '../highlight-clusters';
......@@ -120,13 +124,34 @@ export default function ClusterToolbar({
[onStyleChange]
);
const [isOpen, setOpen] = useState(false);
if (!active) {
return null;
}
return (
<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
highlightStyles={availableStyles}
label="My annotations"
......@@ -149,6 +174,8 @@ export default function ClusterToolbar({
currentStyles={currentStyles}
/>
</CardContent>
)}
</div>
</Card>
);
}
import { mount } from 'enzyme';
import { highlightStyles, defaultStyles } from '../../highlight-clusters';
import ClusterToolbar from '../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', () => {
const wrapper = createComponent({ active: false });
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', () => {
const wrapper = createComponent();
toggleOpen(wrapper);
assert.equal(
wrapper.find('ClusterStyleControl').length,
......@@ -35,6 +57,7 @@ describe('ClusterToolbar', () => {
it('calls style-change callback when user clicks on a style option', () => {
const onStyleChange = sinon.stub();
const wrapper = createComponent({ onStyleChange });
toggleOpen(wrapper);
wrapper
.find('#hypothesis-user-annotations-green')
......
......@@ -77,8 +77,8 @@ export class HighlightClusterController implements Destroyable {
// For now, the controls are fixed at top-left of screen. This is temporary.
Object.assign(this._outerContainer.style, {
position: 'fixed',
top: 0,
left: 0,
top: '4px',
left: '4px',
});
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