-
Notifications
You must be signed in to change notification settings - Fork 5
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
feat(theme): implement release notes page layout #336
Conversation
This pull request is being automatically deployed with ZEIT Now (learn more). 🔍 Inspect: https://zeit.co/commercetools/commercetools-docs-kit/jqmw4sld4 |
This comment has been minimized.
This comment has been minimized.
5bd4ad4
to
ccb1cbb
Compare
@@ -19,6 +19,7 @@ const defaultOptions = { | |||
beta: false, | |||
gaTrackingId: undefined, | |||
excludeFromSearchIndex: true, | |||
hasReleaseNotes: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The link to the release notes is toggled by this config flag.
node, | ||
name: 'isGlobalBeta', | ||
value: Boolean(pluginOptions.beta), | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are used by all templates, because of the sidebar. Therefore we always generate those fields.
fragment MdxPageFields on MdxFields { | ||
slug | ||
title | ||
beta | ||
isGlobalBeta | ||
excludeFromSearchIndex | ||
hasReleaseNotes | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These fields are shared by all pages. Extra fields (for example for the release notes) should be listed in the specific query.
component: isOverviewPage | ||
? require.resolve('./src/templates/release-notes-list.js') | ||
: require.resolve('./src/templates/release-notes-detail.js'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some back and forth I think it's better to just have two separate templates, it makes things easier to implement and separates a bit the concerns, as the pages are indeed different.
@@ -0,0 +1,5 @@ | |||
import React from 'react'; | |||
|
|||
const ReleaseNotesSubscribeLinks = () => <div>{'TODO subscribe links'}</div>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we will add the "subscribe" links (rss feed, etc.). To be done in a separate PR.
@@ -0,0 +1,51 @@ | |||
import React from 'react'; | |||
|
|||
const useLayoutState = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved all this state into a hook, to make is easier to reuse across the different layout components.
const LayoutHeaderLogo = () => ( | ||
<Container> | ||
<LogoButton /> | ||
</Container> | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just extracted for better reusability
|
||
const LayoutPageReleaseNotesFilters = () => ( | ||
<GridContainer> | ||
<StickyContainer>{'TODO: filters'}</StickyContainer> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is where the filters will be implemented. To be done in a separate PR.
const linkStyles = ` | ||
border-left: ${designSystem.dimensions.spacings.xs} solid ${designSystem.colors.light.surfaceSecondary1}; | ||
padding-left: calc(${designSystem.dimensions.spacings.m} - ${designSystem.dimensions.spacings.xs}); | ||
text-decoration: none; | ||
color: ${designSystem.colors.light.textSecondary}; | ||
display: flex; | ||
flex-direction: row; | ||
align-items: flex-end; | ||
|
||
:hover { | ||
color: ${designSystem.colors.light.linkNavigation} !important; | ||
} | ||
|
||
> * + * { | ||
margin: 0 0 0 ${designSystem.dimensions.spacings.s}; | ||
} | ||
`; | ||
const activeLinkStyles = ` | ||
border-left: ${designSystem.dimensions.spacings.xs} solid ${designSystem.colors.light.linkNavigation} !important; | ||
color: ${designSystem.colors.light.linkNavigation} !important; | ||
`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extracted into variables for better readability
customStyles, | ||
customActiveStyles, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two props are new, to allow to override some of the link styles.
customActiveStyles: PropTypes.string, | ||
}; | ||
|
||
const SidebarLinkWrapper = (props) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I split the SidebarLink
component into two, with the wrapper containing the logic for the scrolling position.
The base link component is use for the release notes link.
}; | ||
|
||
const Sidebar = (props) => { | ||
const SidebarNavigationLinks = (props) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component is also extracted and contains the normal navigation links.
{props.hasReleaseNotes && ( | ||
<ReleaseNotesTitle> | ||
<SidebarLink | ||
to="/releases" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the link to the release notes.
</SidebarLink> | ||
</ReleaseNotesTitle> | ||
)} | ||
{props.hasReleaseNotes && isReleasePage ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this condition is true, we render the "back" link
<SpacingsInline alignItems="center"> | ||
<AngleLeftIcon size="medium" color="primary" /> | ||
<Link href="/releases" noUnderline={true}> | ||
<span | ||
css={css` | ||
font-size: ${designSystem.typography.fontSizes.small}; | ||
`} | ||
> | ||
{'Back to all releases'} | ||
</span> | ||
</Link> | ||
</SpacingsInline> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The detail page has this "back" link at the top
// NOTE: release notes content can only have headings starting from h4. | ||
h1: Markdown.withAnchorLink(Markdown.H4), | ||
h2: Markdown.withAnchorLink(Markdown.H5), | ||
h3: Markdown.withAnchorLink(Markdown.H6), | ||
h4: Markdown.withAnchorLink(Markdown.H6), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the mapped list of headings for the release notes content.
cc @nkuehn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we ended up saying that release notes should not have any headings but I think it's a good idea to treat that decision as a technical writing / lectoring convention but have the implementation still render them as a lower "level". You never know what comes up in the future.
H4 is correct to start with since we skip H2 in that page layout.
5ba7b73
to
b4e6927
Compare
b4e6927
to
4a08d4d
Compare
internal: { mediaType: { eq: "text/mdx" } } | ||
} | ||
) { | ||
allContentPage { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now have our own custom query fields.
allReleaseNotePage { | ||
totalCount | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use this to determine if there are any release notes in the website.
We can then be more specific and define some filters to which release notes we want to include. For example, we can exclude all the ones that are not marked as published.
// You can use the values in this context in | ||
// our page layout component | ||
component: isOverviewPage | ||
? require.resolve('./src/templates/release-notes-list.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The release overview page needs to be rendered here now. It still has its own template but from a graphql type perspective is considered a "content page" and therefore is queried with all other content pages.
The file is now src/content/releases.mdx
instead of src/releases/index.mdx
, for the reasons mentioned above.
4a08d4d
to
7861024
Compare
contentPage(slug: { eq: $slug }) { | ||
title | ||
beta | ||
isGlobalBeta | ||
excludeFromSearchIndex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those fields should be queried here, we don't need to pass them with the page context.
Also note the we are using the contentPage
query field.
title | ||
isGlobalBeta | ||
excludeFromSearchIndex | ||
date(formatString: "YYYY-MM-DD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can format the date here.
allReleaseNotePage(sort: { order: DESC, fields: date }) { | ||
nodes { | ||
slug | ||
title | ||
date(formatString: "YYYY-MM-DD") | ||
description | ||
type | ||
topics | ||
body | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we query all release notes and sort them by date descending.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! It's definitely the best way to directly switch to using a fully custom graphQL API surface. It matches the experiences we made in building the API types stuff. Plus I really really like the look of the left menu now that it's even cleaner.
!! One bug remains when opening a build (not development): The main nav link to the release notes has a flash of unstyled content (it moves from right to left).
To not block this another full day I leave this here as an approval, please manage yourself whether to directly fix it or to open a separate issue to track it.
d41ccf9
to
1d8d0b5
Compare
parent { | ||
id | ||
... on File { | ||
relativePath | ||
ext | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now necessary because the slug
is not created as a MDX field anymore.
@nkuehn the FOUC bug is fixed now, I'll merge the PR once CI passes. |
This PR implements the page layout structure for the release note pages. The layout is the same as for the content pages, except for the absence of the site navigation and the page filters (to be done separately).
This does not implement the designs of the release notes, only the layout.