Skip to content

Commit

Permalink
Merge pull request #18 from newrelic/zstickles/reference-page
Browse files Browse the repository at this point in the history
Reference Template
  • Loading branch information
zstix authored Apr 27, 2020
2 parents 28a48fe + 899797c commit 045b4ce
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 33 deletions.
6 changes: 4 additions & 2 deletions src/components/Container.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';

import './Container.scss';

const Container = ({ children }) => (
<div className="u-container">{children}</div>
const Container = ({ children, className }) => (
<div className={cx('u-container', className)}>{children}</div>
);

Container.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
};

export default Container;
10 changes: 5 additions & 5 deletions src/components/HamburgerMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import cx from 'classnames';

import './HamburgerMenu.scss';

const HamburgerMenu = ({ toggle, open }) => (
const HamburgerMenu = ({ toggle, isOpen }) => (
<button
aria-expanded={open}
aria-expanded={isOpen}
aria-label="Mobile Menu"
type="button"
className={cx('HamburgerMenu', { 'is-open': open })}
className={cx('HamburgerMenu', { 'is-open': isOpen })}
onClick={() => toggle()}
>
<div />
Expand All @@ -20,11 +20,11 @@ const HamburgerMenu = ({ toggle, open }) => (

HamburgerMenu.propTypes = {
toggle: PropTypes.func.isRequired,
open: PropTypes.bool,
isOpen: PropTypes.bool,
};

HamburgerMenu.defaultProps = {
open: false,
isOpen: false,
};

export default HamburgerMenu;
36 changes: 15 additions & 21 deletions src/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import './Header.scss';

import { Link, graphql, useStaticQuery } from 'gatsby';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Link, graphql, useStaticQuery } from 'gatsby';
import cx from 'classnames';

import { link } from '../types';
import Container from './Container';
import ExternalLink from './ExternalLink';
import HamburgerMenu from './HamburgerMenu';
import PropTypes from 'prop-types';
import cx from 'classnames';
import './Header.scss';

const Header = ({ pages }) => {
const [menuOpen, setMenuOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);

// NOTE: we may want to abstract this
const data = useStaticQuery(graphql`
Expand All @@ -33,7 +33,7 @@ const Header = ({ pages }) => {
`);

return (
<header className={cx('Header--main', { 'is-open': menuOpen })}>
<header className={cx('Header--main', { 'is-open': isOpen })}>
<Container>
<nav
role="navigation"
Expand Down Expand Up @@ -70,14 +70,14 @@ const Header = ({ pages }) => {
<Link to="/">{'</>'} New Relic Developers</Link>
</h1>

<HamburgerMenu toggle={() => setMenuOpen(!menuOpen)} open={menuOpen} />
<HamburgerMenu toggle={() => setIsOpen(!isOpen)} isOpen={isOpen} />

<nav role="navigation" aria-label="Main" className="Header-nav--main">
<h3 className="u-hideOnDesktop">Developers</h3>
<ul>
{pages.map((page, i) => (
<li key={i}>
<Link to={page.path}>{page.displayName}</Link>
<Link to={page.url}>{page.displayName}</Link>
</li>
))}
</ul>
Expand All @@ -103,22 +103,16 @@ const Header = ({ pages }) => {
};

Header.propTypes = {
pages: PropTypes.arrayOf(
PropTypes.shape({
displayName: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
active: PropTypes.bool,
})
),
pages: PropTypes.arrayOf(link),
};

Header.defaultProps = {
pages: [
{ displayName: 'Collect Data', path: '' },
{ displayName: 'Explore Data', path: 'explore-data' },
{ displayName: 'Build Apps', path: '' },
{ displayName: 'Automate New Relic', path: '' },
{ displayName: 'Reference Docs', path: '' },
{ displayName: 'Collect Data', url: '' },
{ displayName: 'Explore Data', url: 'explore-data' },
{ displayName: 'Build Apps', url: '' },
{ displayName: 'Automate New Relic', url: '' },
{ displayName: 'Reference Docs', url: '' },
],
};

Expand Down
5 changes: 0 additions & 5 deletions src/components/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ const Layout = ({ children }) => (
<>
<Header />
<main>{children}</main>
<footer>
© {new Date().getFullYear()}, Built with
{` `}
<a href="https://www.gatsbyjs.org">Gatsby</a>
</footer>
</>
);

Expand Down
49 changes: 49 additions & 0 deletions src/components/Sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'gatsby';
import cx from 'classnames';

import { link } from '../types';
import './Sidebar.scss';

// recursively create navigation
const renderNav = (page, index) => (
<li key={index}>
<Link to={page.url} className={cx({ 'is-active': page.active })}>
{page.displayName}
</Link>
{page.children && <ul>{page.children.map(renderNav)}</ul>}
</li>
);

const Sidebar = ({ pages, isOpen, toggle }) => (
<aside className={cx('Sidebar', { 'is-open': isOpen })}>
<div className="Sidebar-top">
<h3>Pages</h3>
<button
aria-expanded={isOpen}
className="Sidebar-toggle"
aria-label="Main Menu Toggle"
type="button"
onClick={() => toggle()}
>
{isOpen ? 'close' : 'open'}
</button>
</div>
<nav role="navigation" aria-label="Sidebar">
<ul>{pages.map(renderNav)}</ul>
</nav>
</aside>
);

Sidebar.propTypes = {
toggle: PropTypes.func.isRequired,
pages: PropTypes.arrayOf(link).isRequired,
isOpen: PropTypes.bool,
};

Sidebar.defaultProps = {
isOpen: false,
};

export default Sidebar;
61 changes: 61 additions & 0 deletions src/components/Sidebar.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.Sidebar {
padding: 1rem;

ul {
margin: 0;
padding-left: 1rem;
list-style: none;
}

a {
text-decoration: none;
color: var(--color-black);
display: inline-block;
padding: 0.2rem 0;

&:hover {
text-decoration: underline;
}

&.is-active {
font-weight: bold;
}
}

h3 {
margin: 0;
}

button {
background: none;
border: 0;
cursor: pointer;
width: 3rem;
display: none;

@media (max-width: 760px) {
display: block;
}
}

.Sidebar-top {
display: flex;
justify-content: space-between;
}

nav {
margin-top: 1rem;

@media (max-width: 760px) {
display: none;
}
}

&.is-open {
nav {
@media (max-width: 760px) {
display: block;
}
}
}
}
78 changes: 78 additions & 0 deletions src/pages/reference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, { useState } from 'react';

import Container from '../components/Container';
import Layout from '../components/Layout';
import Sidebar from '../components/Sidebar';

// TODO: move this js file to same directory and update import
import '../templates/Reference.scss';

// TODO: pull this in from Gatsby
const pages = [
{ displayName: 'Overview', url: '' },
{
displayName: 'CLI',
url: '',
children: [
{ displayName: 'newrelic', url: '' },
{ displayName: 'nr1', url: '' },
],
},
{ displayName: 'GraphQL', url: '' },
{
displayName: 'Applications',
url: '',
children: [
{ displayName: 'Component Library', url: '', active: true },
{ displayName: 'File structure', url: '' },
],
},
{
displayName: 'Data Collectors',
url: '',
children: [
{ displayName: 'Custom Attributes', url: '' },
{ displayName: 'Custom Events', url: '' },
{ displayName: 'Open Telemetry', url: '' },
{ displayName: 'Telemetry SDK', url: '' },
],
},
{
displayName: 'Automation',
url: '',
children: [
{ displayName: 'Cloud Formation Provider', url: '' },
{ displayName: 'Terraform Provider', url: '' },
{
displayName: 'Agent Deploy',
url: '',
children: [
{ displayName: 'Ansible', url: '' },
{ displayName: 'Chef', url: '' },
{ displayName: 'Puppet', url: '' },
],
},
],
},
];

const Reference = () => {
const [isOpen, setIsOpen] = useState(false);

return (
<Layout>
<Container className="ReferenceTemplate">
<Sidebar
pages={pages}
isOpen={isOpen}
toggle={() => setIsOpen(!isOpen)}
/>
<main className="ReferenceTemplate-content">
The main page content goes here
</main>
</Container>
</Layout>
);
};

export default Reference;
18 changes: 18 additions & 0 deletions src/templates/Reference.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.ReferenceTemplate {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas: 'sidebar main';

@media (max-width: 760px) {
grid-template-columns: none;
grid-template-areas: 'sidebar' 'main';
}

.Sidebar {
grid-area: sidebar;
}

.ReferenceTemplate-content {
grid-area: main;
}
}
10 changes: 10 additions & 0 deletions src/types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import PropTypes from 'prop-types';

// NOTE: while creating a recursive data structure is feasible,
// it is not very performant.
export const link = PropTypes.shape({
displayName: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
active: PropTypes.bool,
children: PropTypes.array,
});

0 comments on commit 045b4ce

Please sign in to comment.