Commit 3cf30772 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Update shared components in FilterStatus

Note that customization was needed on the "clear results" button:

The cancel icon SVG (used by `CancelIcon`) is problematic — not a
  new issue — because it doesn't fill its viewbox and has to be
  manually sized. This prevents us from using the `icon` prop of the
  `Button` component for now. Tracked in
  https://github.com/hypothesis/frontend-shared/issues/675
parent 15384d56
import { Card, LabeledButton, Spinner } from '@hypothesis/frontend-shared';
import classNames from 'classnames';
import {
Button,
CancelIcon,
Card,
CardContent,
Spinner,
} from '@hypothesis/frontend-shared/lib/next';
import classnames from 'classnames';
import { useMemo } from 'preact/hooks';
import { countVisible } from '../helpers/thread';
......@@ -195,63 +201,67 @@ export default function FilterStatus() {
]);
return (
<Card
classes={classNames('mb-3 p-3', {
// This container element needs to be present at all times but
// should only be visible when there are applied filters
'sr-only': !filterMode,
})}
<div
// This container element needs to be present at all times but
// should only be visible when there are applied filters
className={classnames('mb-3', { 'sr-only': !filterMode })}
data-testid="filter-status-container"
>
<div className="flex items-center justify-center space-x-1">
{store.isLoading() ? (
<Spinner />
) : (
<>
<div
className={classNames(
// Setting `min-width: 0` here allows wrapping to work as
// expected for long `filterQuery` strings. See
// https://css-tricks.com/flexbox-truncated-text/
'grow min-w-[0]'
)}
role="status"
>
<Card>
<CardContent>
{store.isLoading() ? (
<Spinner size="md" />
) : (
<div className="flex items-center justify-center space-x-1">
<div
className={classnames(
// Setting `min-width: 0` here allows wrapping to work as
// expected for long `filterQuery` strings. See
// https://css-tricks.com/flexbox-truncated-text/
'grow min-w-[0]'
)}
role="status"
>
{filterMode && (
<FilterStatusMessage
additionalCount={additionalCount}
entitySingular={
filterMode === 'query' ? 'result' : 'annotation'
}
entityPlural={
filterMode === 'query' ? 'results' : 'annotations'
}
filterQuery={filterQuery}
focusDisplayName={
filterMode !== 'selection' && focusState.active
? focusState.displayName
: ''
}
resultCount={resultCount}
/>
)}
</div>
{filterMode && (
<FilterStatusMessage
additionalCount={additionalCount}
entitySingular={
filterMode === 'query' ? 'result' : 'annotation'
}
entityPlural={
filterMode === 'query' ? 'results' : 'annotations'
<Button
onClick={
filterMode === 'focus' && !forcedVisibleCount
? () => store.toggleFocusMode()
: () => store.clearSelection()
}
filterQuery={filterQuery}
focusDisplayName={
filterMode !== 'selection' && focusState.active
? focusState.displayName
: ''
}
resultCount={resultCount}
/>
size="sm"
title={buttonText}
variant="primary"
data-testid="clear-button"
>
{/** @TODO: Set `icon` prop in `Button` instead when https://github.com/hypothesis/frontend-shared/issues/675 is fixed*/}
{filterMode !== 'focus' && <CancelIcon />}
{buttonText}
</Button>
)}
</div>
{filterMode && (
<LabeledButton
icon={filterMode === 'focus' ? undefined : 'cancel'}
onClick={
filterMode === 'focus' && !forcedVisibleCount
? () => store.toggleFocusMode()
: () => store.clearSelection()
}
title={buttonText}
variant="primary"
>
{buttonText}
</LabeledButton>
)}
</>
)}
</div>
</Card>
)}
</CardContent>
</Card>
</div>
);
}
......@@ -52,20 +52,21 @@ describe('FilterStatus', () => {
}
function assertButton(wrapper, expected) {
const buttonProps = wrapper.find('LabeledButton').props();
const button = wrapper.find('Button[data-testid="clear-button"]');
const buttonProps = button.props();
assert.equal(buttonProps.title, expected.text);
assert.equal(buttonProps.icon, expected.icon);
assert.equal(button.find('CancelIcon').exists(), !!expected.icon);
buttonProps.onClick();
assert.calledOnce(expected.callback);
}
function assertClearButton(wrapper) {
assertButton(wrapper, {
text: 'Clear search',
icon: 'cancel',
callback: fakeStore.clearSelection,
});
const button = wrapper.find('Button[data-testid="clear-button"]');
assert.equal(button.text(), 'Clear search');
assert.isTrue(button.find('CancelIcon').exists());
button.props().onClick();
assert.calledOnce(fakeStore.clearSelection);
}
context('Loading', () => {
......@@ -81,7 +82,9 @@ describe('FilterStatus', () => {
context('(State 1): no search filters active', () => {
it('should render hidden but available to screen readers', () => {
const wrapper = createComponent();
const containerEl = wrapper.find('Card').getDOMNode();
const containerEl = wrapper
.find('div[data-testid="filter-status-container"]')
.getDOMNode();
assert.include(containerEl.className, 'sr-only');
assertFilterText(wrapper, '');
......@@ -177,7 +180,7 @@ describe('FilterStatus', () => {
fakeStore.annotationCount.returns(5);
assertButton(createComponent(), {
text: 'Show all (5)',
icon: 'cancel',
icon: true,
callback: fakeStore.clearSelection,
});
});
......@@ -187,7 +190,7 @@ describe('FilterStatus', () => {
fakeStore.directLinkedAnnotationId.returns(1);
assertButton(createComponent(), {
text: 'Show all',
icon: 'cancel',
icon: true,
callback: fakeStore.clearSelection,
});
});
......@@ -229,7 +232,7 @@ describe('FilterStatus', () => {
it('should provide a "Show all" button that toggles user focus mode', () => {
assertButton(createComponent(), {
text: 'Show all',
icon: null,
icon: false,
callback: fakeStore.toggleFocusMode,
});
});
......@@ -318,7 +321,7 @@ describe('FilterStatus', () => {
it('should provide a "Show all" button', () => {
assertButton(createComponent(), {
text: 'Show all',
icon: 'cancel',
icon: true,
callback: fakeStore.clearSelection,
});
});
......@@ -353,7 +356,7 @@ describe('FilterStatus', () => {
it('should provide a "Reset filters" button', () => {
assertButton(createComponent(), {
text: 'Reset filters',
icon: null,
icon: false,
callback: fakeStore.clearSelection,
});
});
......@@ -376,7 +379,7 @@ describe('FilterStatus', () => {
it('should provide a button to activate user-focused mode', () => {
assertButton(createComponent(), {
text: 'Show only Ebenezer Studentolog',
icon: null,
icon: false,
callback: fakeStore.toggleFocusMode,
});
});
......
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