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

Convert `HelpPanel` to Tailwind

parent 40d3fa84
import { Icon } from '@hypothesis/frontend-shared'; import { Icon, Link, LinkButton } from '@hypothesis/frontend-shared';
import { useCallback, useMemo, useState } from 'preact/hooks'; import { useCallback, useMemo, useState } from 'preact/hooks';
import { useStoreProxy } from '../store/use-store'; import { useStoreProxy } from '../store/use-store';
...@@ -11,8 +11,25 @@ import VersionInfo from './VersionInfo'; ...@@ -11,8 +11,25 @@ import VersionInfo from './VersionInfo';
/** /**
* @typedef {import('../helpers/version-data').AuthState} AuthState * @typedef {import('../helpers/version-data').AuthState} AuthState
* @typedef {import("preact").ComponentChildren} Children
*/ */
/**
* Navigation link-button to swap between sub-panels in the help panel
*
* @param {object} props
* @param {Children} props.children
* @param {() => void} props.onClick
*/
function HelpPanelNavigationButton({ children, onClick }) {
return (
<LinkButton classes="leading-none text-brand" onClick={onClick}>
{children}
<Icon classes="ml-1" name="arrow-right" />
</LinkButton>
);
}
/** /**
* External link "tabs" inside of the help panel. * External link "tabs" inside of the help panel.
* *
...@@ -22,15 +39,14 @@ import VersionInfo from './VersionInfo'; ...@@ -22,15 +39,14 @@ import VersionInfo from './VersionInfo';
*/ */
function HelpPanelTab({ linkText, url }) { function HelpPanelTab({ linkText, url }) {
return ( return (
<div className="HelpPanel-tabs__tab"> <div className="flex-1 border-r last-of-type:border-r-0">
<a <Link
href={url} href={url}
className="hyp-u-horizontal-spacing--2 hyp-u-layout-row--center HelpPanel-tabs__link" classes="flex items-center justify-center space-x-2 text-color-text-light text-lg font-medium"
target="_blank" target="_blank"
rel="noopener noreferrer"
> >
<span>{linkText}</span> <Icon name="external" classes="u-icon--small" /> <span>{linkText}</span> <Icon name="external" classes="w-3 h-3" />
</a> </Link>
</div> </div>
); );
} }
...@@ -112,41 +128,33 @@ function HelpPanel({ auth, session }) { ...@@ -112,41 +128,33 @@ function HelpPanel({ auth, session }) {
panelName="help" panelName="help"
onActiveChanged={onActiveChanged} onActiveChanged={onActiveChanged}
> >
<div className="hyp-u-vertical-spacing HelpPanel__content"> <div className="space-y-4">
<div className="hyp-u-layout-row--align-center"> <div className="flex items-center">
<h3 className="HelpPanel__sub-panel-title"> <h3 className="grow text-lg font-medium" data-testid="subpanel-title">
{subPanelTitles[activeSubPanel]} {subPanelTitles[activeSubPanel]}
</h3> </h3>
<div> {activeSubPanel === 'versionInfo' && (
{activeSubPanel === 'versionInfo' && ( <HelpPanelNavigationButton
<button onClick={e => openSubPanel(e, 'tutorial')}
className="HelpPanel__sub-panel-navigation-button" >
onClick={e => openSubPanel(e, 'tutorial')} Getting started
aria-label="Show tutorial panel" </HelpPanelNavigationButton>
> )}
Getting started {activeSubPanel === 'tutorial' && (
<Icon name="arrow-right" /> <HelpPanelNavigationButton
</button> onClick={e => openSubPanel(e, 'versionInfo')}
)} >
{activeSubPanel === 'tutorial' && ( About this version
<button </HelpPanelNavigationButton>
className="HelpPanel__sub-panel-navigation-button" )}
onClick={e => openSubPanel(e, 'versionInfo')}
aria-label="Show version information panel"
>
About this version
<Icon name="arrow-right" />
</button>
)}
</div>
</div> </div>
<div className="HelpPanel__subcontent"> <div className="border-y py-4">
{activeSubPanel === 'tutorial' && <Tutorial />} {activeSubPanel === 'tutorial' && <Tutorial />}
{activeSubPanel === 'versionInfo' && ( {activeSubPanel === 'versionInfo' && (
<VersionInfo versionData={versionData} /> <VersionInfo versionData={versionData} />
)} )}
</div> </div>
<div className="HelpPanel-tabs"> <div className="flex items-center">
<HelpPanelTab <HelpPanelTab
linkText="Help topics" linkText="Help topics"
url="https://web.hypothes.is/help/" url="https://web.hypothes.is/help/"
......
...@@ -43,6 +43,7 @@ function Tutorial({ settings }) { ...@@ -43,6 +43,7 @@ function Tutorial({ settings }) {
<li> <li>
To create a highlight ( To create a highlight (
<Link <Link
classes="underline hover:underline"
href="https://web.hypothes.is/help/why-are-highlights-private-by-default/" href="https://web.hypothes.is/help/why-are-highlights-private-by-default/"
target="_blank" target="_blank"
> >
...@@ -57,6 +58,7 @@ function Tutorial({ settings }) { ...@@ -57,6 +58,7 @@ function Tutorial({ settings }) {
To annotate in a private group, select the group from the groups To annotate in a private group, select the group from the groups
dropdown. Don&apos;t see your group? Ask the group creator to send a{' '} dropdown. Don&apos;t see your group? Ask the group creator to send a{' '}
<Link <Link
classes="underline hover:underline"
href="https://web.hypothes.is/help/how-to-join-a-private-group/" href="https://web.hypothes.is/help/how-to-join-a-private-group/"
target="_blank" target="_blank"
> >
......
...@@ -52,7 +52,7 @@ describe('HelpPanel', () => { ...@@ -52,7 +52,7 @@ describe('HelpPanel', () => {
context('when viewing tutorial sub-panel', () => { context('when viewing tutorial sub-panel', () => {
it('should show tutorial by default', () => { it('should show tutorial by default', () => {
const wrapper = createComponent(); const wrapper = createComponent();
const subHeader = wrapper.find('.HelpPanel__sub-panel-title'); const subHeader = wrapper.find('[data-testid="subpanel-title"]');
assert.include(subHeader.text(), 'Getting started'); assert.include(subHeader.text(), 'Getting started');
assert.isTrue(wrapper.find('Tutorial').exists()); assert.isTrue(wrapper.find('Tutorial').exists());
...@@ -61,19 +61,21 @@ describe('HelpPanel', () => { ...@@ -61,19 +61,21 @@ describe('HelpPanel', () => {
it('should show navigation link to versionInfo sub-panel', () => { it('should show navigation link to versionInfo sub-panel', () => {
const wrapper = createComponent(); const wrapper = createComponent();
const link = wrapper.find('.HelpPanel__sub-panel-navigation-button'); const button = wrapper.find('HelpPanelNavigationButton');
assert.include(link.text(), 'About this version'); assert.include(button.text(), 'About this version');
}); });
it('should switch to versionInfo sub-panel when footer link clicked', () => { it('should switch to versionInfo sub-panel when navigation button clicked', async () => {
const wrapper = createComponent(); const wrapper = createComponent();
wrapper.find('.HelpPanel__sub-panel-navigation-button').simulate('click'); act(() => {
wrapper
.find('LinkButton')
.getDOMNode()
.dispatchEvent(new Event('click'));
});
wrapper.update();
assert.include(
wrapper.find('.HelpPanel__sub-panel-title').text(),
'About this version'
);
assert.isTrue(wrapper.find('VersionInfo').exists()); assert.isTrue(wrapper.find('VersionInfo').exists());
assert.equal( assert.equal(
wrapper.find('VersionInfo').prop('versionData'), wrapper.find('VersionInfo').prop('versionData'),
...@@ -125,9 +127,15 @@ describe('HelpPanel', () => { ...@@ -125,9 +127,15 @@ describe('HelpPanel', () => {
it('should show navigation link back to tutorial sub-panel', () => { it('should show navigation link back to tutorial sub-panel', () => {
const wrapper = createComponent(); const wrapper = createComponent();
wrapper.find('.HelpPanel__sub-panel-navigation-button').simulate('click'); act(() => {
wrapper
.find('LinkButton')
.getDOMNode()
.dispatchEvent(new Event('click'));
});
wrapper.update();
const link = wrapper.find('.HelpPanel__sub-panel-navigation-button'); const link = wrapper.find('LinkButton');
assert.isTrue(wrapper.find('VersionInfo').exists()); assert.isTrue(wrapper.find('VersionInfo').exists());
assert.isFalse(wrapper.find('Tutorial').exists()); assert.isFalse(wrapper.find('Tutorial').exists());
...@@ -138,11 +146,22 @@ describe('HelpPanel', () => { ...@@ -138,11 +146,22 @@ describe('HelpPanel', () => {
const wrapper = createComponent(); const wrapper = createComponent();
// Click to get to VersionInfo sub-panel... // Click to get to VersionInfo sub-panel...
wrapper.find('.HelpPanel__sub-panel-navigation-button').simulate('click'); act(() => {
wrapper
.find('LinkButton')
.getDOMNode()
.dispatchEvent(new Event('click'));
});
wrapper.update();
const link = wrapper.find('.HelpPanel__sub-panel-navigation-button');
// Click again to get back to tutorial sub-panel // Click again to get back to tutorial sub-panel
link.simulate('click'); act(() => {
wrapper
.find('LinkButton')
.getDOMNode()
.dispatchEvent(new Event('click'));
});
wrapper.update();
assert.isFalse(wrapper.find('VersionInfo').exists()); assert.isFalse(wrapper.find('VersionInfo').exists());
assert.isTrue(wrapper.find('Tutorial').exists()); assert.isTrue(wrapper.find('Tutorial').exists());
......
...@@ -140,22 +140,6 @@ ...@@ -140,22 +140,6 @@
} }
} }
/**
* A button pattern that looks like a link with a small icon on the right
* Used, e.g., in the help panel to navigate between sub-panels
*/
@mixin button--navigation {
@include reset-native-btn-styles;
@include layout.row($justify: right, $align: center);
color: var.$color-brand;
svg {
margin-left: 2px;
width: 12px;
height: 12px;
}
}
/** /**
* Mixins that style buttons to appear as lozenges with an integrated arrow * Mixins that style buttons to appear as lozenges with an integrated arrow
* pointing left, up or down (right doesn't exist yet but could easily be added). * pointing left, up or down (right doesn't exist yet but could easily be added).
......
...@@ -141,33 +141,6 @@ ...@@ -141,33 +141,6 @@
} }
} }
/**
* Styled external-linked "tabs" with icons, intended for use in a panel
*/
@mixin panel-tabs {
@include layout.row($align: center);
&__tab {
@include utils.font--large;
@include utils.border--right;
flex: 1 1;
text-align: center;
color: var.$color-text--light;
&:last-of-type {
border-right: none;
}
}
&__link {
color: var.$color-text--light;
}
&__icon {
@include utils.icon--xsmall;
}
}
/** /**
* A full-width banner with optional "type" and styled icon at left * A full-width banner with optional "type" and styled icon at left
*/ */
......
@use '../../mixins/buttons';
@use '../../mixins/layout';
@use '../../mixins/molecules';
@use '../../mixins/utils';
@use '../../variables' as var;
.HelpPanel {
&__sub-panel-title {
@include utils.font--large;
flex-grow: 1;
}
&__subcontent {
@include utils.border--top;
@include utils.border--bottom;
@include layout.vertical-space;
a {
text-decoration: underline;
}
}
&__icon {
@include utils.icon--xsmall;
}
&__sub-panel-navigation-button {
@include buttons.button--navigation;
}
&-tabs {
@include molecules.panel-tabs;
}
}
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
@use './components/FilterStatus'; @use './components/FilterStatus';
@use './components/GroupList'; @use './components/GroupList';
@use './components/GroupListItem'; @use './components/GroupListItem';
@use './components/HelpPanel';
@use './components/HypothesisApp'; @use './components/HypothesisApp';
@use './components/LaunchErrorPanel'; @use './components/LaunchErrorPanel';
@use './components/LoggedOutMessage'; @use './components/LoggedOutMessage';
......
...@@ -10,6 +10,9 @@ export default { ...@@ -10,6 +10,9 @@ export default {
], ],
theme: { theme: {
extend: { extend: {
borderColor: {
DEFAULT: '#dbdbdb',
},
colors: { colors: {
'color-text': { 'color-text': {
DEFAULT: '#202020', DEFAULT: '#202020',
...@@ -27,6 +30,7 @@ export default { ...@@ -27,6 +30,7 @@ export default {
}, },
fontSize: { fontSize: {
base: ['13px', '1.4'], base: ['13px', '1.4'],
lg: ['14px'],
}, },
}, },
}, },
......
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