@primer/gatsby-theme-doctocat 4.4.3 → 4.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @primer/gatsby-theme-doctocat
2
2
 
3
+ ## 4.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`169049b`](https://github.com/primer/doctocat/commit/169049bd3d8d43ad412e20b842144a04a97ac365) [#605](https://github.com/primer/doctocat/pull/605) Thanks [@mperrotti](https://github.com/mperrotti)! - Updates the base layout with latest designs.
8
+
9
+ ## 4.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`c5156b0`](https://github.com/primer/doctocat/commit/c5156b06c8f72ec267fb186be2705c421462f409) [#602](https://github.com/primer/doctocat/pull/602) Thanks [@mperrotti](https://github.com/mperrotti)! - Add breadcrumb nav to default layout
14
+
15
+ * [`4960db2`](https://github.com/primer/doctocat/commit/4960db2a305fe39a529585036c5943119a0c326e) [#594](https://github.com/primer/doctocat/pull/594) Thanks [@kendallgassner](https://github.com/kendallgassner)! - Add visually hidden header to the top navigation. Utilize the ActionMenu component in top nav.
16
+
3
17
  ## 4.4.3
4
18
 
5
19
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/gatsby-theme-doctocat",
3
- "version": "4.4.3",
3
+ "version": "4.5.1",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -1,5 +1,6 @@
1
1
  import {MarkGithubIcon, SearchIcon, ThreeBarsIcon} from '@primer/octicons-react'
2
2
  import {Box, Button, Link, StyledOcticon, Text, ThemeProvider, useTheme} from '@primer/react'
3
+ import VisuallyHidden from './visually-hidden'
3
4
  import {Link as GatsbyLink} from 'gatsby'
4
5
  import React from 'react'
5
6
  import primerNavItems from '../primer-nav.yml'
@@ -96,7 +97,7 @@ function Header({isSearchEnabled}) {
96
97
  </Box>
97
98
  <Box>
98
99
  <Box sx={{display: ['none', null, null, 'block']}}>
99
- <PrimerNavItems items={primerNavItems} />
100
+ <PrimerNavItems siteMetadata={siteMetadata} items={primerNavItems} />
100
101
  </Box>
101
102
  <Box sx={{display: ['flex', null, null, 'none']}}>
102
103
  {isSearchEnabled ? (
@@ -137,39 +138,50 @@ Header.defaultProps = {
137
138
  isSearchEnabled: true
138
139
  }
139
140
 
140
- function PrimerNavItems({items}) {
141
+ function PrimerNavItems({siteMetadata, items}) {
141
142
  return (
142
- <Box sx={{display: 'flex', alignItems: 'center', color: 'fg.default'}}>
143
- {items.map((item, index) => {
144
- if (item.children) {
143
+ <>
144
+ <VisuallyHidden>
145
+ <h3 aria-labelledby="site-header">{siteMetadata.header.title} </h3>
146
+ </VisuallyHidden>
147
+ <Box
148
+ as={'nav'}
149
+ sx={{display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: 'fg.default', gap: 2}}
150
+ >
151
+ {items.map((item, index) => {
152
+ if (item.children) {
153
+ return (
154
+ <Box key={index}>
155
+ <NavDropdown title={item.title}>
156
+ {item.children.map(child => (
157
+ <NavDropdownItem key={child.title} href={child.url}>
158
+ {child.title}
159
+ </NavDropdownItem>
160
+ ))}
161
+ </NavDropdown>
162
+ </Box>
163
+ )
164
+ }
165
+
145
166
  return (
146
- <Box key={index} sx={{ml: 4}}>
147
- <NavDropdown title={item.title}>
148
- {item.children.map(child => (
149
- <NavDropdownItem key={child.title} href={child.url}>
150
- {child.title}
151
- </NavDropdownItem>
152
- ))}
153
- </NavDropdown>
154
- </Box>
167
+ <Link
168
+ key={index}
169
+ href={item.url}
170
+ sx={{
171
+ display: 'block',
172
+ color: 'fg.default',
173
+ fontSize: 2,
174
+ fontWeight: 'bold',
175
+ ml: 2,
176
+ mr: 2
177
+ }}
178
+ >
179
+ {item.title}
180
+ </Link>
155
181
  )
156
- }
157
-
158
- return (
159
- <Link
160
- key={index}
161
- href={item.url}
162
- sx={{
163
- display: 'block',
164
- color: 'inherit',
165
- ml: 4
166
- }}
167
- >
168
- {item.title}
169
- </Link>
170
- )
171
- })}
172
- </Box>
182
+ })}
183
+ </Box>
184
+ </>
173
185
  )
174
186
  }
175
187
 
@@ -59,7 +59,7 @@ function MarkdownHeading({children, ...props}) {
59
59
 
60
60
  const StyledH1 = styled(StyledHeading).attrs({as: 'h1'})`
61
61
  padding-bottom: ${themeGet('space.2')};
62
- font-size: ${themeGet('fontSizes.5')};
62
+ font-size: ${themeGet('fontSizes.7')};
63
63
  border-bottom: 1px solid ${themeGet('colors.border.default')};
64
64
  `
65
65
 
@@ -67,14 +67,17 @@ const StyledH2 = styled(StyledHeading).attrs({as: 'h2'})`
67
67
  padding-bottom: ${themeGet('space.2')};
68
68
  font-size: ${themeGet('fontSizes.4')};
69
69
  border-bottom: 1px solid ${themeGet('colors.border.default')};
70
+ font-weight: ${themeGet('fontWeights.semibold')};
70
71
  `
71
72
 
72
73
  const StyledH3 = styled(StyledHeading).attrs({as: 'h3'})`
73
74
  font-size: ${themeGet('fontSizes.3')};
75
+ font-weight: ${themeGet('fontWeights.semibold')};
74
76
  `
75
77
 
76
78
  const StyledH4 = styled(StyledHeading).attrs({as: 'h4'})`
77
79
  font-size: ${themeGet('fontSizes.2')};
80
+ font-weight: ${themeGet('fontWeights.semibold')};
78
81
  `
79
82
 
80
83
  const StyledH5 = styled(StyledHeading).attrs({as: 'h5'})`
@@ -1,5 +1,5 @@
1
1
  import componentMetadata from '@primer/component-metadata'
2
- import {Box, Heading, Text} from '@primer/react'
2
+ import {Box, Breadcrumbs, Heading, Text} from '@primer/react'
3
3
  import React from 'react'
4
4
  import Head from './head'
5
5
  import Header, {HEADER_HEIGHT} from './header'
@@ -14,8 +14,33 @@ import LookbookLink from './lookbook-link'
14
14
  import StorybookLink from './storybook-link'
15
15
  import FigmaLink from './figma-link'
16
16
  import TableOfContents from './table-of-contents'
17
+ import navItems from '../nav.yml'
17
18
 
18
- function Layout({children, pageContext}) {
19
+ const getPageAncestry = (url, object) => {
20
+ const result = []
21
+ const buildArray = (node, path) => {
22
+ if (node.url === path) {
23
+ result.push({title: node.title, url: node.url})
24
+ } else if (node.children) {
25
+ for (const child of node.children) {
26
+ buildArray(child, path)
27
+ if (result.length > 0) {
28
+ result.unshift({title: node.title, url: node.url})
29
+ break
30
+ }
31
+ }
32
+ }
33
+ }
34
+ for (const node of object) {
35
+ buildArray(node, url)
36
+ if (result.length > 0) {
37
+ break
38
+ }
39
+ }
40
+ return result
41
+ }
42
+
43
+ function Layout({children, pageContext, path}) {
19
44
  let {
20
45
  title,
21
46
  description,
@@ -42,6 +67,7 @@ function Layout({children, pageContext}) {
42
67
  title ||= component.displayName
43
68
  description ||= component.description
44
69
  }
70
+ const breadcrumbData = getPageAncestry(path, navItems).filter(item => item.url)
45
71
 
46
72
  return (
47
73
  <Box sx={{flexDirection: 'column', minHeight: '100vh', display: 'flex'}}>
@@ -65,7 +91,7 @@ function Layout({children, pageContext}) {
65
91
  sx={{
66
92
  width: 220,
67
93
  flex: '0 0 auto',
68
- marginLeft: 6,
94
+ marginLeft: [null, 7, 8, 9],
69
95
  display: ['none', null, 'block'],
70
96
  position: 'sticky',
71
97
  top: HEADER_HEIGHT + 48,
@@ -73,7 +99,7 @@ function Layout({children, pageContext}) {
73
99
  }}
74
100
  css={{gridArea: 'table-of-contents', overflow: 'auto'}}
75
101
  >
76
- <Heading as="h3" sx={{fontSize: 2, display: 'inline-block', fontWeight: 'bold', pl: 3}} id="toc-heading">
102
+ <Heading as="h3" sx={{fontSize: 1, display: 'inline-block', fontWeight: 'bold', pl: 3}} id="toc-heading">
77
103
  On this page
78
104
  </Heading>
79
105
  <TableOfContents aria-labelledby="toc-heading" items={pageContext.tableOfContents.items} />
@@ -81,8 +107,19 @@ function Layout({children, pageContext}) {
81
107
  ) : null}
82
108
  <Box sx={{width: '100%', maxWidth: '960px'}}>
83
109
  <Box as="main" id="skip-nav" sx={{mb: 4}}>
110
+ <Breadcrumbs sx={{mb: 4}}>
111
+ {breadcrumbData.length > 1
112
+ ? breadcrumbData.map(item => (
113
+ <Breadcrumbs.Item key={item.url} href={item.url} selected={path === item.url}>
114
+ {item.title}
115
+ </Breadcrumbs.Item>
116
+ ))
117
+ : null}
118
+ </Breadcrumbs>
84
119
  <Box sx={{alignItems: 'center', display: 'flex'}}>
85
- <Heading as="h1">{title}</Heading>{' '}
120
+ <Heading as="h1" sx={{fontSize: 7}}>
121
+ {title}
122
+ </Heading>
86
123
  </Box>
87
124
  {description ? <Box sx={{fontSize: 3, mb: 3}}>{description}</Box> : null}
88
125
  <Box
@@ -1,36 +1,31 @@
1
- import {Box, Details, StyledOcticon, Text, themeGet, useDetails} from '@primer/react'
2
- import {TriangleDownIcon} from '@primer/octicons-react'
1
+ import {ActionMenu, ActionList, themeGet, useDetails} from '@primer/react'
3
2
  import React from 'react'
4
3
  import styled from 'styled-components'
5
4
 
6
5
  function NavDropdown({title, children}) {
7
6
  const {getDetailsProps} = useDetails({closeOnOutsideClick: true})
8
7
  return (
9
- <Details {...getDetailsProps()}>
10
- <summary style={{cursor: 'pointer'}}>
11
- <Text>{title}</Text>
12
- <StyledOcticon icon={TriangleDownIcon} sx={{ml: 1}} />
13
- </summary>
14
- <Box sx={{position: 'absolute'}}>
15
- <Box
16
- sx={{
17
- bg: 'canvas.overlay',
18
- p: 2,
19
- mt: 2,
20
- borderWidth: '1px',
21
- borderStyle: 'solid',
22
- borderColor: 'border.default',
23
- borderRadius: '12px'
24
- }}
25
- >
26
- {children}
27
- </Box>
28
- </Box>
29
- </Details>
8
+ <ActionMenu {...getDetailsProps()}>
9
+ <ActionMenu.Button
10
+ variant="invisible"
11
+ sx={{
12
+ fontSize: 2,
13
+ color: 'fg.default',
14
+ ':hover:not([disabled])': {
15
+ backgroundColor: 'canvas.subtle'
16
+ }
17
+ }}
18
+ >
19
+ {title}
20
+ </ActionMenu.Button>
21
+ <ActionMenu.Overlay width="auto">
22
+ <ActionList>{children}</ActionList>
23
+ </ActionMenu.Overlay>
24
+ </ActionMenu>
30
25
  )
31
26
  }
32
27
 
33
- export const NavDropdownItem = styled.a`
28
+ export const NavDropdownItem = styled(ActionList.LinkItem)`
34
29
  display: block;
35
30
  padding: ${themeGet('space.2')};
36
31
  color: inherit;