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

Transition `HypothesisApp` to Tailwind

- Use `SidebarContent` component
- Remove unused CSS
parent 163f3899
...@@ -16,6 +16,7 @@ import StreamView from './StreamView'; ...@@ -16,6 +16,7 @@ import StreamView from './StreamView';
import HelpPanel from './HelpPanel'; import HelpPanel from './HelpPanel';
import NotebookView from './NotebookView'; import NotebookView from './NotebookView';
import ShareAnnotationsPanel from './ShareAnnotationsPanel'; import ShareAnnotationsPanel from './ShareAnnotationsPanel';
import SidebarContent from './SidebarContent';
import ToastMessages from './ToastMessages'; import ToastMessages from './ToastMessages';
import TopBar from './TopBar'; import TopBar from './TopBar';
...@@ -164,10 +165,21 @@ function HypothesisApp({ auth, frameSync, settings, session, toastMessenger }) { ...@@ -164,10 +165,21 @@ function HypothesisApp({ auth, frameSync, settings, session, toastMessenger }) {
return ( return (
<div <div
className={classnames('HypothesisApp', 'js-thread-list-scroll-root', { className={classnames(
'theme-clean': isThemeClean, 'h-full min-h-full overflow-scroll',
'HypothesisApp--notebook': route === 'notebook', // Precise padding to align with annotation cards in content
})} // Larger padding on bottom for wide screens
'p-[9px] lg:pb-16 bg-grey-2',
'js-thread-list-scroll-root',
{
'theme-clean': isThemeClean,
// Make room at top for the TopBar (40px) plus custom padding (9px)
// but not in the Notebook, which doesn't use the TopBar
'pt-[49px]': route !== 'notebook',
'p-4 lg:p-12': route === 'notebook',
}
)}
data-testid="hypothesis-app"
style={backgroundStyle} style={backgroundStyle}
> >
{route !== 'notebook' && ( {route !== 'notebook' && (
...@@ -179,7 +191,7 @@ function HypothesisApp({ auth, frameSync, settings, session, toastMessenger }) { ...@@ -179,7 +191,7 @@ function HypothesisApp({ auth, frameSync, settings, session, toastMessenger }) {
isSidebar={isSidebar} isSidebar={isSidebar}
/> />
)} )}
<div className="HypothesisApp__content"> <SidebarContent>
<ToastMessages /> <ToastMessages />
<HelpPanel auth={authState.status === 'logged-in' ? authState : {}} /> <HelpPanel auth={authState.status === 'logged-in' ? authState : {}} />
<ShareAnnotationsPanel /> <ShareAnnotationsPanel />
...@@ -194,7 +206,7 @@ function HypothesisApp({ auth, frameSync, settings, session, toastMessenger }) { ...@@ -194,7 +206,7 @@ function HypothesisApp({ auth, frameSync, settings, session, toastMessenger }) {
)} )}
</main> </main>
)} )}
</div> </SidebarContent>
</div> </div>
); );
} }
......
...@@ -428,33 +428,34 @@ describe('HypothesisApp', () => { ...@@ -428,33 +428,34 @@ describe('HypothesisApp', () => {
}); });
describe('theming', () => { describe('theming', () => {
const appSelector = '[data-testid="hypothesis-app"]';
it('applies theme config', () => { it('applies theme config', () => {
const style = { backgroundColor: 'red' }; const style = { backgroundColor: 'red' };
fakeApplyTheme.returns({ backgroundColor: 'red' }); fakeApplyTheme.returns({ backgroundColor: 'red' });
const wrapper = createComponent(); const wrapper = createComponent();
const background = wrapper.find('.HypothesisApp'); const background = wrapper.find(appSelector);
assert.calledWith(fakeApplyTheme, ['appBackgroundColor'], fakeSettings); assert.calledWith(fakeApplyTheme, ['appBackgroundColor'], fakeSettings);
assert.deepEqual(background.prop('style'), style); assert.deepEqual(background.prop('style'), style);
}); });
});
it('applies a clean-theme style when config sets theme to "clean"', () => { it('applies a clean-theme style when config sets theme to "clean"', () => {
fakeSettings.theme = 'clean'; fakeSettings.theme = 'clean';
const wrapper = createComponent(); const wrapper = createComponent();
const container = wrapper.find('.HypothesisApp'); const container = wrapper.find(appSelector);
assert.isTrue(container.hasClass('theme-clean')); assert.isTrue(container.hasClass('theme-clean'));
}); });
it('does not apply clean-theme style when config does not assert `clean` theme', () => { it('does not apply clean-theme style when config does not assert `clean` theme', () => {
fakeSettings.theme = ''; fakeSettings.theme = '';
const wrapper = createComponent(); const wrapper = createComponent();
const container = wrapper.find('.HypothesisApp'); const container = wrapper.find(appSelector);
assert.isFalse(container.hasClass('HypothesisApp--theme-clean')); assert.isFalse(container.hasClass('theme-clean'));
});
}); });
}); });
@use '../../variables' as var;
@use '../mixins/layout';
@use '../mixins/responsive';
.HypothesisApp {
$sidebar-h-padding: 9px;
background: var.$grey-2;
min-height: 100%;
height: 100%;
overflow: scroll;
-webkit-overflow-scrolling: touch;
padding: $sidebar-h-padding;
padding-top: $sidebar-h-padding + var.$top-bar-height;
@include responsive.respond-to(tablets desktops) {
padding-bottom: 4rem;
}
&__content {
@include layout.sidebar-content;
}
// FIXME: Temporary affordance for the Notebook view to override some
// layout spacing that assumes the presence of the top bar
&--notebook {
padding: var.$layout-space;
@include responsive.respond-to(tablets desktops) {
padding: var.$layout-space--xlarge;
}
}
}
// Disable scroll anchoring as it interferes with `ThreadList` and
// `visible-threads` calculations and can cause a render loop
.js-thread-list-scroll-root {
overflow-anchor: none;
}
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
@use './FilterStatus'; @use './FilterStatus';
@use './GroupList'; @use './GroupList';
@use './GroupListItem'; @use './GroupListItem';
@use './HypothesisApp';
@use './LaunchErrorPanel'; @use './LaunchErrorPanel';
@use './Menu'; @use './Menu';
@use './MenuItem'; @use './MenuItem';
...@@ -31,10 +30,11 @@ ...@@ -31,10 +30,11 @@
@use './ToastMessages'; @use './ToastMessages';
@use './VersionInfo'; @use './VersionInfo';
// TODO: Put these in @layer components after shared component styles have // TODO: Evaluate all classes below after components have been converted to
// been converted to Tailwind (and are contained in the components layer // Tailwind. If retaining, put them in @layer components after `frontend-shared`
// themselves). They need to come after shared-component styles in the // component styles have been converted to Tailwind (and are contained in the
// output stylesheet. // components layer themselves). They need to come after shared-component
// styles in the output stylesheet.
// Applies to <Link> // Applies to <Link>
.p-muted-link { .p-muted-link {
...@@ -45,3 +45,9 @@ ...@@ -45,3 +45,9 @@
.p-redacted-text { .p-redacted-text {
@apply line-through grayscale contrast-50 text-color-text-light; @apply line-through grayscale contrast-50 text-color-text-light;
} }
// Disable scroll anchoring as it interferes with `ThreadList` and
// `visible-threads` calculations and can cause a render loop
.js-thread-list-scroll-root {
overflow-anchor: none;
}
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