diff --git a/src/Viewer.module.css b/src/Viewer.module.css index d3f62b0ec..4ca75a700 100644 --- a/src/Viewer.module.css +++ b/src/Viewer.module.css @@ -1,47 +1,3 @@ -.header { - --header-content-height: 24px; - - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - width: auto; - height: fit-content; - min-height: var(--header-content-height); - padding: 12px 30px; - border-bottom: 1px solid var(--color-borders); - gap: 10px; - position: sticky; - background-color: var(--color-background); - z-index: 100; - top: 0; - left: 0; -} - -.header > div { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; -} - -.headerLeft { - gap: 20px; -} - -.header h2 { - margin: 0; - line-height: normal; -} - -.verticalDivider { - height: var(--header-content-height); - width: 1px; - background-color: var(--color-dividers); - display: inline-block; -} - .mainContent { margin: 8px 30px; } diff --git a/src/Viewer.tsx b/src/Viewer.tsx index 0699d5733..653a0ed27 100644 --- a/src/Viewer.tsx +++ b/src/Viewer.tsx @@ -9,9 +9,7 @@ import { import { Checkbox, notification, Slider, Tabs } from "antd"; import { NotificationConfig } from "antd/es/notification/interface"; import React, { ReactElement, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react"; -import styled from "styled-components"; -import { AicsLogoSVG } from "./assets"; import { ColorizeCanvas, Dataset, Track } from "./colorizer"; import { DEFAULT_CATEGORICAL_PALETTE_KEY, @@ -46,6 +44,7 @@ import ColorRampDropdown from "./components/Dropdowns/ColorRampDropdown"; import HelpDropdown from "./components/Dropdowns/HelpDropdown"; import SelectionDropdown from "./components/Dropdowns/SelectionDropdown"; import Export from "./components/Export"; +import Header from "./components/Header"; import HoverTooltip from "./components/HoverTooltip"; import IconButton from "./components/IconButton"; import LabeledRangeSlider from "./components/LabeledRangeSlider"; @@ -57,18 +56,6 @@ import { FeatureThresholdsTab, PlotTab, ScatterPlotTab, SettingsTab } from "./co // TODO: Refactor with styled-components import styles from "./Viewer.module.css"; -const AicsLogoLink = styled.a` - position: relative; - width: 180px; - height: 46px; -`; - -const StyledAicsLogo = styled(AicsLogoSVG)` - left: 0; - top: 0; - position: absolute; -`; - function Viewer(): ReactElement { // STATE INITIALIZATION ///////////////////////////////////////////////////////// const theme = useContext(AppThemeContext); @@ -708,16 +695,7 @@ function Viewer(): ReactElement {
{notificationContextHolder}
- {/* Header bar: Contains dataset, feature, color ramp, and other top-level functionality. */} - {/* TODO: Split into its own component? */} -
-
- - - - -

Timelapse Colorizer

-
+
{/*

Dataset Name

*/} @@ -740,7 +718,7 @@ function Viewer(): ReactElement { -
+ {/** Main Content: Contains canvas and plot, ramp controls, time controls, etc. */}
diff --git a/src/assets/AICS-logo-and-name.svg b/src/assets/AICS-logo-and-name.svg index bd975ee28..60a595f94 100644 --- a/src/assets/AICS-logo-and-name.svg +++ b/src/assets/AICS-logo-and-name.svg @@ -1 +1 @@ -Asset 5 \ No newline at end of file +Allen Institute for Cell Science \ No newline at end of file diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 000000000..ee2c5040f --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,75 @@ +import React, { PropsWithChildren, ReactElement } from "react"; +import { Link } from "react-router-dom"; +import styled from "styled-components"; + +import { AicsLogoSVG } from "../assets"; +import { FlexRowAlignCenter } from "../styles/utils"; + +const AicsLogoLink = styled.a` + position: relative; + width: 180px; + height: 46px; +`; + +const StyledAicsLogo = styled(AicsLogoSVG)` + left: 0; + top: 0; + position: absolute; +`; + +const VerticalDivider = styled.div` + height: 24px; + width: 1px; + background-color: var(--color-dividers); + display: inline-block; +`; + +/** + * The logo and title of the app, to be used with the Header component. + * Both the logo and app title are links that can be used for navigation. + */ +function HeaderLogo(): ReactElement { + return ( + + + + + + +

Timelapse Colorizer

+ +
+ ); +} + +/** + * Top title bar for the app, which will stick to the top of the page. + * Child components will be spaced apart evenly. + * */ +const HeaderContainer = styled.div` + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + width: auto; + height: fit-content; + min-height: var(--header-content-height); + padding: 12px 30px; + border-bottom: 1px solid var(--color-borders); + gap: 10px; + position: sticky; + background-color: var(--color-background); + z-index: 100; + top: 0; + left: 0; +`; + +export default function Header(props: PropsWithChildren): ReactElement { + return ( + + + {props.children} + + ); +} diff --git a/src/routes/ErrorPage.tsx b/src/routes/ErrorPage.tsx index f84a4bb41..bcef42eb0 100644 --- a/src/routes/ErrorPage.tsx +++ b/src/routes/ErrorPage.tsx @@ -4,6 +4,8 @@ import { ErrorResponse, Link, useRouteError } from "react-router-dom"; import { FlexColumnAlignCenter } from "../styles/utils"; +import Header from "../components/Header"; + const isErrorResponse = (error: unknown): error is ErrorResponse => { return typeof (error as ErrorResponse).status === "number" && typeof (error as ErrorResponse).statusText === "string"; }; @@ -21,13 +23,16 @@ export default function ErrorPage(): ReactElement { } return ( - -

{errorMessage}

-

Sorry, something went wrong.

-
- - - -
+
+
+ +

{errorMessage}

+

Sorry, something went wrong.

+
+ + + +
+
); }