Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port over the Header component used across all sites #210

Merged
merged 2 commits into from
Oct 9, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"polished": "^3.6.4",
"prismjs": "1.20.0",
"prop-types": "^15.5.4",
"react-github-button": "^0.1.11",
"react-modal": "^3.11.2",
"react-popper-tooltip": "^2.11.1",
"styled-components": "^4.4.1",
Expand Down
271 changes: 271 additions & 0 deletions src/components/header/Header.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
import React from 'react';
import styled from 'styled-components';
import GitHubButton from 'react-github-button';
import 'react-github-button/assets/style.css';
import { Header } from './Header';
import { Link } from '../Link';
import { Button } from '../Button';
import StorybookLogo from '../../images/logo-storybook.svg';
import StorybookLogoInverted from '../../images/logo-storybook-inverted.svg';
import { breakpoint, typography, color } from '../shared/styles';
import { NavLink } from './NavLink';
import { NavItem } from './NavItem';
import { TooltipLinkList } from '../tooltip/TooltipLinkList';
import WithTooltip from '../tooltip/WithTooltip';
import { Icon } from '../Icon';
import { StoryLinkWrapper } from '../StoryLinkWrapper';

export default {
title: 'Design System/Header',
component: Header,
subcomponents: { NavLink, NavItem },
parameters: { layout: 'fullscreen' },
};

const LogoWrapper = styled.div`
display: inline-block;
align-self: stretch;
`;

const LogotypeWrapper = styled(Link)`
display: inline-block;

img {
height: 22px;
width: auto;
margin-top: 14px;
@media (min-width: ${breakpoint}px) {
height: 26px;
margin-top: 10px;
}
display: block;
transition: all 150ms ease-out;
transform: translate3d(0, 0, 0);
&:hover {
transform: translate3d(0, -1px, 0);
}
&:active {
transform: translate3d(0, 0, 0);
}
}
`;

const Version = styled(Link)`
display: inline-block;
vertical-align: top;
margin-left: 10px;
position: relative;
top: 2px;
font-size: ${typography.size.s1}px;
color: ${color.mediumdark};
`;

const Logo = () => (
<LogoWrapper>
<LogotypeWrapper href="/">
<img src={StorybookLogo} alt="Storybook" />
</LogotypeWrapper>
<Version href="https://github.com/storybookjs/storybook/releases">v6.0</Version>
</LogoWrapper>
);

const links = (
<>
<NavItem showDesktop>
<NavLink href="/docs">Docs</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink href="/tutorials">Tutorials</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink href="/releases">Releases</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink href="/addons">Addons</NavLink>
</NavItem>
</>
);

const mobileMenu = (
<TooltipLinkList
links={[
{
title: 'Docs',
href: '/docs',
},
{
title: 'Tutorials',
href: '/tutorials',
},
{
title: 'Releases',
href: '/releases',
},
{
title: 'Addons',
href: '/addons',
},
]}
/>
);

export const Basic = () => <Header logo={<Logo />} links={links} mobileMenu={mobileMenu} />;

export const WithLinkWrapper = () => (
<Header
logo={<Logo />}
links={
<>
<NavItem showDesktop>
<NavLink LinkWrapper={StoryLinkWrapper} to="/docs">
Docs
</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink LinkWrapper={StoryLinkWrapper} to="/tutorials">
Tutorials
</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink LinkWrapper={StoryLinkWrapper} to="/releases">
Releases
</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink LinkWrapper={StoryLinkWrapper} to="/addons">
Addons
</NavLink>
</NavItem>
</>
}
mobileMenu={mobileMenu}
/>
);

export const WithGithubButton = () => (
<Header
logo={<Logo />}
links={links}
mobileMenu={mobileMenu}
github={<GitHubButton type="stargazers" namespace="storybookjs" repo="design-system" />}
/>
);

export const WithDropDown = () => (
<Header
logo={<Logo />}
links={
<>
{links}
<NavItem showDesktop>
<WithTooltip
tagName="span"
placement="top"
trigger="click"
tooltip={
<TooltipLinkList
links={[
{
title: 'Get involved',
href: '#',
},
{
title: 'Use cases',
href: '#',
},
{
title: 'Support',
href: '#',
},
{
title: 'team',
href: '#',
},
]}
/>
}
>
<NavLink>
Community <Icon icon="arrowdown" />
</NavLink>
</WithTooltip>
</NavItem>
</>
}
mobileMenu={mobileMenu}
/>
);

export const WithCustomLink = () => (
<Header
logo={<Logo />}
links={
<>
{links}
<NavItem showDesktop>
<NavLink primary href="/start">
Go to app <Icon icon="arrowrightalt" aria-hidden />
</NavLink>
</NavItem>
</>
}
mobileMenu={mobileMenu}
/>
);

const InvertedLogotypeWrapper = styled(Link)`
display: inline-block;

img {
height: 22px;
width: auto;

@media (min-width: ${breakpoint}px) {
height: 26px;
}
display: block;
transition: all 150ms ease-out;
transform: translate3d(0, 0, 0);
&:hover {
transform: translate3d(0, -1px, 0);
}
&:active {
transform: translate3d(0, 0, 0);
}
}
`;

export const Inverted = () => (
<div style={{ backgroundColor: color.darkest, paddingBottom: 16 }}>
<Header
inverse
logo={
<InvertedLogotypeWrapper href="/" inverse>
<img src={StorybookLogoInverted} alt="Learn Storybook" />
</InvertedLogotypeWrapper>
}
links={
<>
<NavItem showDesktop>
<NavLink href="/docs">Docs</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink href="/tutorials">Tutorials</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink href="/releases">Releases</NavLink>
</NavItem>
<NavItem showDesktop>
<NavLink href="/addons">Addons</NavLink>
</NavItem>
<NavItem showDesktop>
<Button appearance="inverseOutline" isLink href="/start">
Sign in
</Button>
</NavItem>
</>
}
mobileMenu={mobileMenu}
/>
</div>
);
116 changes: 116 additions & 0 deletions src/components/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from 'react';
import styled from 'styled-components';
import { color } from '../shared/styles';
// @ts-ignore
import WithTooltip from '../tooltip/WithTooltip';
// @ts-ignore
import { Link } from '../Link';
// @ts-ignore
import { Icon } from '../Icon';
import { NavGroup, Nav, NavWrapper } from './Nav';
import { NavItem } from './NavItem';
import { HeaderContext, defaultHeaderContext } from './HeaderContext';

const GitHubWrapper = styled.div`
transform: scale(0.84);
${'' /* Overrides to make a medium sized button */};
.github-btn {
font: bold 14px/14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: auto;
.gh-btn,
.gh-count {
padding: 4px 8px;
}
}
`;

const GithubNavItem = styled(NavItem)`
display: none;

@media (min-width: 375px) {
display: inline-flex;
align-items: center;
}
`;

const MobileMenuTooltip = styled(WithTooltip)`
outline: none;
&:focus svg {
color: ${color.secondary};
}
`;

const Menu = styled(Link)`
width: 3rem;
border: none !important;
text-decoration: none !important;
svg {
height: 18px;
width: 18px;
margin: 0;
margin-right: -4px !important;
}
`;

type HeaderProps = {
logo: React.ReactNode;
github?: React.ReactNode;
links: React.ReactNode;
mobileMenu: React.ReactNode | (() => React.ReactNode);
inverse?: boolean;
navBreakpoint?: number;
};

export function Header({
logo,
links,
github,
mobileMenu,
inverse = defaultHeaderContext.inverse,
navBreakpoint = defaultHeaderContext.navBreakpoint,
...props
}: HeaderProps) {
return (
<HeaderContext.Provider
value={{
navBreakpoint,
inverse,
}}
>
<NavWrapper {...props}>
<Nav>
<NavGroup navBreakpoint={navBreakpoint}>
<NavItem>{logo}</NavItem>
</NavGroup>

<NavGroup navBreakpoint={navBreakpoint} withRightAlignment>
{links}

{github && (
<GithubNavItem showDesktop className="chromatic-ignore">
<GitHubWrapper>{github}</GitHubWrapper>
</GithubNavItem>
)}

<NavItem showMobile>
<MobileMenuTooltip
tagName="span"
placement="top"
trigger="click"
tooltip={mobileMenu}
>
<Menu secondary inverse={inverse} icon={1} isButton>
<Icon icon="menu" aria-label="Menu" />
</Menu>
</MobileMenuTooltip>
</NavItem>
</NavGroup>
</Nav>
</NavWrapper>
</HeaderContext.Provider>
);
}

Header.defaultProps = {
inverse: false,
};
Loading