fix: add toc to mobile views and account for branding on shared view layouts (#2997)

* fix: add toc to mobile views and center the branding

* add padding to bottom of sidebar

* put the mobile branding inline

* finesse the padding

* make spelling of sign-in email less crazy looking

* move mobile sidebar button into header

* adds scene to search and 404 pages

* fix title alignment

* make filter buttons tight

* clean up unused imports

* lint

Co-authored-by: Tom Moor <tom.moor@gmail.com>
This commit is contained in:
Nan Yu
2022-02-01 20:58:24 -08:00
committed by GitHub
parent 516e2f1b6e
commit 735aaa668a
12 changed files with 119 additions and 99 deletions

View File

@@ -1,5 +1,6 @@
import * as React from "react";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import env from "~/env";
import OutlineLogo from "./OutlineLogo";
@@ -17,10 +18,8 @@ function Branding({ href = env.URL }: Props) {
}
const Link = styled.a`
z-index: ${(props) => props.theme.depths.sidebar + 1};
position: fixed;
bottom: 0;
left: 0;
justify-content: center;
padding-bottom: 16px;
font-weight: 600;
font-size: 14px;
@@ -29,7 +28,6 @@ const Link = styled.a`
color: ${(props) => props.theme.text};
display: flex;
align-items: center;
padding: 16px;
svg {
fill: ${(props) => props.theme.text};
@@ -38,6 +36,14 @@ const Link = styled.a`
&:hover {
background: ${(props) => props.theme.sidebarBackground};
}
${breakpoint("tablet")`
z-index: ${(props: any) => props.theme.depths.sidebar + 1};
position: fixed;
bottom: 0;
left: 0;
padding: 16px;
`};
`;
export default Branding;

View File

@@ -94,13 +94,15 @@ const StyledButton = styled(Button)`
box-shadow: none;
text-transform: none;
border-color: transparent;
height: auto;
&:hover {
background: transparent;
}
${Inner} {
line-height: 28px;
line-height: 24px;
min-height: auto;
}
`;

View File

@@ -1,19 +1,31 @@
import { throttle } from "lodash";
import { observer } from "mobx-react";
import { MenuIcon } from "outline-icons";
import { transparentize } from "polished";
import * as React from "react";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import Button from "~/components/Button";
import Fade from "~/components/Fade";
import Flex from "~/components/Flex";
import useMobile from "~/hooks/useMobile";
import useStores from "~/hooks/useStores";
type Props = {
breadcrumb?: React.ReactNode;
title: React.ReactNode;
actions?: React.ReactNode;
hasSidebar?: boolean;
};
function Header({ breadcrumb, title, actions }: Props) {
function Header({ breadcrumb, title, actions, hasSidebar }: Props) {
const { ui } = useStores();
const isMobile = useMobile();
const hasMobileSidebar = hasSidebar && isMobile;
const passThrough = !actions && !breadcrumb && !title;
const [isScrolled, setScrolled] = React.useState(false);
const handleScroll = React.useCallback(
throttle(() => setScrolled(window.scrollY > 75), 50),
@@ -33,8 +45,21 @@ function Header({ breadcrumb, title, actions }: Props) {
}, []);
return (
<Wrapper align="center" shrink={false}>
{breadcrumb ? <Breadcrumbs>{breadcrumb}</Breadcrumbs> : null}
<Wrapper align="center" shrink={false} $passThrough={passThrough}>
{breadcrumb || hasMobileSidebar ? (
<Breadcrumbs>
{hasMobileSidebar && (
<MobileMenuButton
onClick={ui.toggleMobileSidebar}
icon={<MenuIcon />}
iconColor="currentColor"
neutral
/>
)}
{breadcrumb}
</Breadcrumbs>
) : null}
{isScrolled ? (
<Title onClick={handleClickTitle}>
<Fade>{title}</Fade>
@@ -42,11 +67,9 @@ function Header({ breadcrumb, title, actions }: Props) {
) : (
<div />
)}
{actions && (
<Actions align="center" justify="flex-end">
{actions}
</Actions>
)}
<Actions align="center" justify="flex-end">
{actions}
</Actions>
</Wrapper>
);
}
@@ -56,12 +79,7 @@ const Breadcrumbs = styled("div")`
flex-basis: 0;
align-items: center;
padding-right: 8px;
/* Don't show breadcrumbs on mobile */
display: none;
${breakpoint("tablet")`
display: flex;
`};
`;
const Actions = styled(Flex)`
@@ -75,11 +93,23 @@ const Actions = styled(Flex)`
`};
`;
const Wrapper = styled(Flex)`
position: sticky;
const Wrapper = styled(Flex)<{ $passThrough?: boolean }>`
top: 0;
z-index: ${(props) => props.theme.depths.header};
position: sticky;
background: ${(props) => props.theme.background};
${(props) =>
props.$passThrough
? `
background: transparent;
pointer-events: none;
`
: `
background: ${transparentize(0.2, props.theme.background)};
backdrop-filter: blur(20px);
`};
padding: 12px;
transition: all 100ms ease-out;
transform: translate3d(0, 0, 0);
@@ -111,7 +141,7 @@ const Title = styled("div")`
cursor: pointer;
min-width: 0;
${breakpoint("tablet")`
${breakpoint("tablet")`
padding-left: 0;
display: block;
`};
@@ -126,4 +156,13 @@ const Title = styled("div")`
}
`;
const MobileMenuButton = styled(Button)`
margin-right: 8px;
pointer-events: auto;
@media print {
display: none;
}
`;
export default observer(Header);

View File

@@ -1,10 +1,8 @@
import { observer } from "mobx-react";
import { MenuIcon } from "outline-icons";
import * as React from "react";
import { Helmet } from "react-helmet";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import { LoadingIndicatorBar } from "~/components/LoadingIndicator";
import SkipNavContent from "~/components/SkipNavContent";
@@ -41,15 +39,6 @@ function Layout({ title, children, sidebar, rightRail }: Props) {
{ui.progressBarVisible && <LoadingIndicatorBar />}
{sidebar && (
<MobileMenuButton
onClick={ui.toggleMobileSidebar}
icon={<MenuIcon />}
iconColor="currentColor"
neutral
/>
)}
<Container auto>
{sidebar}
@@ -85,21 +74,6 @@ const Container = styled(Flex)`
min-height: 100%;
`;
const MobileMenuButton = styled(Button)`
position: fixed;
top: 12px;
left: 12px;
z-index: ${(props) => props.theme.depths.sidebar - 1};
${breakpoint("tablet")`
display: none;
`};
@media print {
display: none;
}
`;
const Content = styled(Flex)<{
$isResizing?: boolean;
$sidebarCollapsed?: boolean;

View File

@@ -6,7 +6,7 @@ import PageTitle from "~/components/PageTitle";
type Props = {
icon?: React.ReactNode;
title: React.ReactNode;
title?: React.ReactNode;
textTitle?: string;
children: React.ReactNode;
breadcrumb?: React.ReactNode;
@@ -27,6 +27,7 @@ function Scene({
<FillWidth>
<PageTitle title={textTitle || title} />
<Header
hasSidebar
title={
icon ? (
<>

View File

@@ -1,5 +1,6 @@
import { observer } from "mobx-react";
import * as React from "react";
import styled from "styled-components";
import Scrollable from "~/components/Scrollable";
import useStores from "~/hooks/useStores";
import { NavigationNode } from "~/types";
@@ -17,7 +18,7 @@ function SharedSidebar({ rootNode, shareId }: Props) {
return (
<Sidebar>
<Scrollable flex>
<ScrollContainer flex>
<Section>
<DocumentLink
index={0}
@@ -27,9 +28,13 @@ function SharedSidebar({ rootNode, shareId }: Props) {
activeDocument={documents.active}
/>
</Section>
</Scrollable>
</ScrollContainer>
</Sidebar>
);
}
const ScrollContainer = styled(Scrollable)`
padding-bottom: 16px;
`;
export default observer(SharedSidebar);