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

Update shared components in `MenuArrow`, `AutocompleteList`

As `MenuArrow` now uses two icons — `PointerUpIcon` and
`PointerDownIcon` — instead of a CSS transform (rotate 180 degrees)
for the down variant, absolute positioning had to be adjusted in the
components that use this arrow.

A future enhancement might be to make positioning easier/unnecessary for
components using `MenuArrow`. Some additional comments have been added
for now.

The shared components in `AutocompleteList` are also updated here.
parent 252a168e
......@@ -188,7 +188,7 @@ function AnnotationShareControl({
{showShareLinks && <ShareLinks shareURI={shareUri} />}
<MenuArrow
direction="down"
classes="bottom-[-12px] right-1 touch:right-[9px]"
classes="bottom-[-9px] right-1 touch:right-[9px]"
/>
</Card>
)}
......
import { Card } from '@hypothesis/frontend-shared';
import { Card } from '@hypothesis/frontend-shared/lib/next';
import classnames from 'classnames';
import { useMemo } from 'preact/hooks';
......@@ -85,20 +85,23 @@ export default function AutocompleteList({
const isHidden = list.length === 0 || !open;
return (
<div className="relative">
<Card
classes={classnames(
<div
className={classnames(
{ hidden: isHidden },
// Move the Card down a bit to make room for the up-pointing arrow
'absolute top-[3px] z-3',
// Override full-width of Card, but set a min-width of `10em`
'w-auto min-w-[10em] theme-clean:border p-0'
// Ensure Card width is not too narrow
'min-w-[10em]'
)}
data-testid="autocomplete-list-container"
>
<ul tabIndex={-1} aria-label="Suggestions" role="listbox" {...props}>
{items}
</ul>
<MenuArrow direction="up" classes="top-[-10px] left-[3px]" />
</Card>
<Card width="auto">
<ul tabIndex={-1} aria-label="Suggestions" role="listbox" {...props}>
{items}
</ul>
<MenuArrow direction="up" classes="top-[-8px] left-[3px]" />
</Card>
</div>
</div>
);
}
......@@ -205,7 +205,7 @@ export default function Menu({
direction="up"
classes={classnames(
// Position menu-arrow caret near bottom right of menu label/toggle control
'right-0 top-[calc(100%-6px)] w-[15px]',
'right-0 top-[calc(100%-3px)] w-[15px]',
arrowClass
)}
/>
......
import { Icon } from '@hypothesis/frontend-shared';
import {
PointerDownIcon,
PointerUpIcon,
} from '@hypothesis/frontend-shared/lib/next';
import classnames from 'classnames';
/**
......@@ -11,15 +14,19 @@ import classnames from 'classnames';
* Render a white-filled "pointer" arrow for use in menus and menu-like
* elements
*
* This will set up absolute positioning for this arrow, but the vertical and
* horizontal positioning will need to be tuned in the component using the
* arrow by adding additional utlity classes (`classes` prop here).
*
* @param {MenuArrowProps} props
*/
export default function MenuArrow({ classes, direction = 'up' }) {
const Icon = direction === 'up' ? PointerUpIcon : PointerDownIcon;
return (
<Icon
name="pointer"
classes={classnames(
className={classnames(
'absolute inline z-2 text-grey-3 fill-white',
{ 'rotate-180': direction === 'down' },
classes
)}
/>
......
......@@ -33,12 +33,18 @@ describe('AutocompleteList', () => {
it('hides the list container when `open` is false', () => {
// `open` prop defaults to `false`
const wrapper = createComponent();
assert.include(wrapper.find('Card').props().classes, 'hidden');
const container = wrapper.find(
'[data-testid="autocomplete-list-container"]'
);
assert.isTrue(container.getDOMNode().classList.contains('hidden'));
});
it('hides the list container when `list` is empty', () => {
const wrapper = createComponent({ open: true, list: [] });
assert.include(wrapper.find('Card').props().classes, 'hidden');
const container = wrapper.find(
'[data-testid="autocomplete-list-container"]'
);
assert.isTrue(container.getDOMNode().classList.contains('hidden'));
});
it('renders the items in order of the list prop', () => {
......
......@@ -16,15 +16,11 @@ describe('MenuArrow', () => {
it('should render an arrow pointing up by default', () => {
const wrapper = createComponent();
const arrowClasses = wrapper.find('Icon').props().classes;
assert.notInclude(arrowClasses, 'rotate-180');
assert.isTrue(wrapper.find('PointerUpIcon').exists());
});
it('should render an arrow pointing down if direction is `down`', () => {
const wrapper = createComponent({ direction: 'down' });
const arrowClasses = wrapper.find('Icon').props().classes;
assert.include(arrowClasses, 'rotate-180');
assert.isTrue(wrapper.find('PointerDownIcon').exists());
});
});
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