Skip to content

Commit

Permalink
feat: rendering based on breadcrumbs
Browse files Browse the repository at this point in the history
Cayla Hamann committed Jun 16, 2020
1 parent 20df861 commit 63cfc53
Showing 6 changed files with 195 additions and 129 deletions.
3 changes: 3 additions & 0 deletions src/components/BreadcrumbContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react';

export const BreadcrumbContext = React.createContext([]);
56 changes: 30 additions & 26 deletions src/components/Sidebar.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,51 @@
import React from 'react';
import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'gatsby';
import cx from 'classnames';
import { BreadcrumbContext } from './BreadcrumbContext';

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

// recursively create navigation
const renderNav = (page, index) => (
<li key={index}>
{page.url ? (
<Link to={page.url} className={cx({ [styles.isActive]: page.active })}>
{page.displayName}
</Link>
) : (
<div>{page.displayName}</div>
)}
{page.children && <ul>{page.children.map(renderNav)}</ul>}
</li>
);
const renderNav = (page, index) => {
const crumbs = useContext(BreadcrumbContext).flatMap((x) => x.displayName);
const [isDisplay, setIsDisplay] = useState(crumbs.includes(page.displayName));

return (
<li key={index}>
{page.url ? (
<Link to={page.url}>{page.displayName}</Link>
) : (
<div
role="button"
onClick={() => setIsDisplay(!isDisplay)}
onKeyPress={() => setIsDisplay(!isDisplay)}
tabIndex={0}
>
{page.displayName}
</div>
)}
{page.children && (
<ul className={cx(styles.nestedNav, { [styles.isDisplay]: isDisplay })}>
{page.children.map(renderNav)}
</ul>
)}
</li>
);
};

const Sidebar = ({ className, pages, isOpen, toggle }) => (
const Sidebar = ({ className, pages, isOpen }) => (
<aside className={cx(styles.sidebar, className, { [styles.isOpen]: isOpen })}>
<Link to="/" className={styles.logo} />
<div className={styles.top}>
<button
aria-expanded={isOpen}
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>
<ul className={styles.listNav}>{pages.map(renderNav)}</ul>
</nav>
</aside>
);

Sidebar.propTypes = {
className: PropTypes.string,
toggle: PropTypes.func.isRequired,
pages: PropTypes.arrayOf(link).isRequired,
isOpen: PropTypes.bool,
};
47 changes: 43 additions & 4 deletions src/components/Sidebar.module.scss
Original file line number Diff line number Diff line change
@@ -14,10 +14,6 @@
&:hover {
text-decoration: underline;
}

&.isActive {
font-weight: bold;
}
}

h3 {
@@ -67,3 +63,46 @@
margin-right: 1rem;
background-image: url('../images/developers-logo.svg');
}

.nestedNav {
display: none;
}

.isDisplay {
display: block;
}

.listNav {
div {
margin-bottom: 1rem;
}
li {
color: var(--color-black);
font-weight: bold;
ul {
li {
font-weight: normal;
ul {
padding-left: 0.5rem;
li {
font-weight: bold;
text-transform: uppercase;
color: var(--color-neutrals-600);
font-size: 14px;
ul {
padding-left: 0rem;
li {
font-weight: normal;
text-transform: initial;
color: var(--color-black);
ul {
padding-left: 1rem;
}
}
}
}
}
}
}
}
}
80 changes: 44 additions & 36 deletions src/templates/ApiReferenceTemplate.js
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ import SEO from '../components/Seo';
import templateStyles from './ReferenceTemplate.module.scss';
import useApiDoc from '../hooks/useApiDoc';

import { BreadcrumbContext } from '../components/BreadcrumbContext';
import createBreadcrumbs from '../utils/create-breadcrumbs';
import pages from '../data/sidenav.json';

const ApiReferenceTemplate = ({ data }) => {
const { mdx } = data;
const { frontmatter } = mdx;
@@ -25,49 +29,53 @@ const ApiReferenceTemplate = ({ data }) => {
constants = [],
} = useApiDoc(api) ?? {};

return (
<Layout>
<SEO title={title} description={description} />
<h1>{api}</h1>

<section
className={cx(templateStyles.section, templateStyles.description)}
>
<ReactMarkdown source={apiDescription} />
</section>
const crumbs = createBreadcrumbs(frontmatter.path, pages);

<section className={templateStyles.section}>
<h2>Usage</h2>
<InlineCodeSnippet language="js">{usage}</InlineCodeSnippet>
</section>
return (
<BreadcrumbContext.Provider value={crumbs}>
<Layout>
<SEO title={title} description={description} />
<h1>{api}</h1>

{methods.length > 0 && (
<section className={templateStyles.section}>
<h2>API methods</h2>
{methods.map((method, i) => (
<MethodReference key={i} method={method} />
))}
<section
className={cx(templateStyles.section, templateStyles.description)}
>
<ReactMarkdown source={apiDescription} />
</section>
)}

{typeDefs.length > 0 && (
<section className={templateStyles.section}>
<h2>Type definitions</h2>
{typeDefs.map((typeDef, i) => (
<TypeDefReference key={i} typeDef={typeDef} />
))}
<h2>Usage</h2>
<InlineCodeSnippet language="js">{usage}</InlineCodeSnippet>
</section>
)}

{constants.length > 0 && (
<section className={templateStyles.section}>
<h2>Constants</h2>
{constants.map((constant, i) => (
<ConstantReference key={i} constant={constant} />
))}
</section>
)}
</Layout>
{methods.length > 0 && (
<section className={templateStyles.section}>
<h2>API methods</h2>
{methods.map((method, i) => (
<MethodReference key={i} method={method} />
))}
</section>
)}

{typeDefs.length > 0 && (
<section className={templateStyles.section}>
<h2>Type definitions</h2>
{typeDefs.map((typeDef, i) => (
<TypeDefReference key={i} typeDef={typeDef} />
))}
</section>
)}

{constants.length > 0 && (
<section className={templateStyles.section}>
<h2>Constants</h2>
{constants.map((constant, i) => (
<ConstantReference key={i} constant={constant} />
))}
</section>
)}
</Layout>
</BreadcrumbContext.Provider>
);
};

119 changes: 64 additions & 55 deletions src/templates/ComponentReferenceTemplate.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import React from 'react';
import cx from 'classnames';
import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

import InlineCodeSnippet from '../components/InlineCodeSnippet';
import ReactMarkdown from 'react-markdown';
import ReferenceExample from '../components/ReferenceExample';
@@ -15,6 +16,10 @@ import useComponentDoc from '../hooks/useComponentDoc';
import IconGallery from '../components/IconGallery';
import TypeDefReference from '../components/TypeDefReference';

import { BreadcrumbContext } from '../components/BreadcrumbContext';
import createBreadcrumbs from '../utils/create-breadcrumbs';
import pages from '../data/sidenav.json';

const previewStyles = {
Spinner: {
height: '16px',
@@ -35,71 +40,75 @@ const ComponentReferenceTemplate = ({ data }) => {
propTypes = [],
} = useComponentDoc(component) ?? {};

return (
<Layout>
<SEO title={title} description={description} />
<h1>{component}</h1>
<section
className={cx(
templateStyles.section,
templateStyles.description,
'intro-text'
)}
>
<ReactMarkdown source={componentDescription} />
</section>

<section className={templateStyles.section}>
<h2>Usage</h2>
<InlineCodeSnippet language="js">{usage}</InlineCodeSnippet>
</section>
const crumbs = createBreadcrumbs(frontmatter.path, pages);

{examples.length > 0 && (
<section className={templateStyles.section}>
<h2>Examples</h2>
<div>
{examples.map((example, i) => (
<ReferenceExample
key={i}
useToastManager={component === 'Toast'}
className={styles.componentExample}
example={example}
previewStyle={previewStyles[component]}
/>
))}
</div>
return (
<BreadcrumbContext.Provider value={crumbs}>
<Layout>
<SEO title={title} description={description} />
<h1>{component}</h1>
<section
className={cx(
templateStyles.section,
templateStyles.description,
'intro-text'
)}
>
<ReactMarkdown source={componentDescription} />
</section>
)}

{component === 'Icon' && (
<section className={templateStyles.section}>
<IconGallery />
<h2>Usage</h2>
<InlineCodeSnippet language="js">{usage}</InlineCodeSnippet>
</section>
)}

<section className={templateStyles.section}>
<h2>Props</h2>
<PropList propTypes={propTypes} />
</section>
{examples.length > 0 && (
<section className={templateStyles.section}>
<h2>Examples</h2>
<div>
{examples.map((example, i) => (
<ReferenceExample
key={i}
useToastManager={component === 'Toast'}
className={styles.componentExample}
example={example}
previewStyle={previewStyles[component]}
/>
))}
</div>
</section>
)}

{component === 'Icon' && (
<section className={templateStyles.section}>
<IconGallery />
</section>
)}

{methods.length > 0 && (
<section className={templateStyles.section}>
<h2>Methods</h2>
{methods.map((method, i) => (
<MethodReference key={i} method={method} />
))}
<h2>Props</h2>
<PropList propTypes={propTypes} />
</section>
)}

{typeDefs.length > 0 && (
<section className={templateStyles.section}>
<h2>Type definitions</h2>
{typeDefs.map((typeDef, i) => (
<TypeDefReference key={i} typeDef={typeDef} />
))}
</section>
)}
</Layout>
{methods.length > 0 && (
<section className={templateStyles.section}>
<h2>Methods</h2>
{methods.map((method, i) => (
<MethodReference key={i} method={method} />
))}
</section>
)}

{typeDefs.length > 0 && (
<section className={templateStyles.section}>
<h2>Type definitions</h2>
{typeDefs.map((typeDef, i) => (
<TypeDefReference key={i} typeDef={typeDef} />
))}
</section>
)}
</Layout>
</BreadcrumbContext.Provider>
);
};

19 changes: 11 additions & 8 deletions src/templates/GuideTemplate.js
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import Step from '../components/Step';
import Steps from '../components/Steps';
import Intro from '../components/Intro';
import SEO from '../components/Seo';
import { BreadcrumbContext } from '../components/BreadcrumbContext';

import createBreadcrumbs from '../utils/create-breadcrumbs';
import pages from '../data/sidenav.json';
@@ -32,14 +33,16 @@ const GuideTemplate = ({ data }) => {
const crumbs = createBreadcrumbs(frontmatter.path, pages);

return (
<Layout>
<SEO title={title} description={description} />
<BreadcrumbBar crumbs={crumbs} duration={frontmatter.duration} />
<h1>{title}</h1>
<MDXProvider components={components}>
<MDXRenderer>{body}</MDXRenderer>
</MDXProvider>
</Layout>
<BreadcrumbContext.Provider value={crumbs}>
<Layout>
<SEO title={title} description={description} />
<BreadcrumbBar crumbs={crumbs} duration={frontmatter.duration} />
<h1>{title}</h1>
<MDXProvider components={components}>
<MDXRenderer>{body}</MDXRenderer>
</MDXProvider>
</Layout>
</BreadcrumbContext.Provider>
);
};

0 comments on commit 63cfc53

Please sign in to comment.