@primer/doctocat-nextjs 0.5.2-rc.77cd6c6 → 0.5.2
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 +13 -1
- package/components/layout/index-cards/IndexCards.module.css +4 -11
- package/components/layout/index-cards/IndexCards.tsx +69 -15
- package/components/layout/index-cards/images/dark-1.png +0 -0
- package/components/layout/index-cards/images/dark-2.png +0 -0
- package/components/layout/index-cards/images/dark-3.png +0 -0
- package/components/layout/index-cards/images/dark-4.png +0 -0
- package/components/layout/index-cards/images/dark-5.png +0 -0
- package/components/layout/index-cards/images/dark-6.png +0 -0
- package/components/layout/index-cards/images/light-1.png +0 -0
- package/components/layout/index-cards/images/light-2.png +0 -0
- package/components/layout/index-cards/images/light-3.png +0 -0
- package/components/layout/index-cards/images/light-4.png +0 -0
- package/components/layout/index-cards/images/light-5.png +0 -0
- package/components/layout/index-cards/images/light-6.png +0 -0
- package/components/layout/root-layout/Theme.tsx +7 -2
- package/components/layout/sidebar/Sidebar.module.css +23 -10
- package/components/layout/sidebar/Sidebar.tsx +15 -1
- package/global.types.d.ts +5 -0
- package/package.json +1 -1
- package/types.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- [#
|
|
7
|
+
- [#41](https://github.com/primer/doctocat-nextjs/pull/41) [`e1ffb3a`](https://github.com/primer/doctocat-nextjs/commit/e1ffb3a630c51316a19e25869f731b4ef3660d2b) Thanks [@danielguillan](https://github.com/danielguillan)! - - Updated sidebar styles.
|
|
8
|
+
|
|
9
|
+
- Added active header link as sidebar heading.
|
|
10
|
+
- Made active header the root item of breadcrumbs, if available.
|
|
11
|
+
- Made sidebar group headlines link to the index page.
|
|
12
|
+
|
|
13
|
+
- [#39](https://github.com/primer/doctocat-nextjs/pull/39) [`9090a35`](https://github.com/primer/doctocat-nextjs/commit/9090a3516de8657321ff2217e944cca6466ec9a0) Thanks [@danielguillan](https://github.com/danielguillan)! - Updated index pages to use a grid of Cards with thumbnails.
|
|
14
|
+
|
|
15
|
+
Use `thumbnail` and `thumbnail_darkMode` to set custom thumbnail URLs for light and dark color modes respectively.
|
|
16
|
+
|
|
17
|
+
- [#38](https://github.com/primer/doctocat-nextjs/pull/38) [`e950c9a`](https://github.com/primer/doctocat-nextjs/commit/e950c9af9ad410025437510113172e207e2e30a2) Thanks [@danielguillan](https://github.com/danielguillan)! - Updated Primer Brand library to `v0.54.0`
|
|
18
|
+
|
|
19
|
+
- [#42](https://github.com/primer/doctocat-nextjs/pull/42) [`c9c2d16`](https://github.com/primer/doctocat-nextjs/commit/c9c2d16aa12ad56c71ec5ddbc008a028a378d81d) Thanks [@rezrah](https://github.com/rezrah)! - Added placeholder images to the Index page cards, where `thumbnail` and `thumbnail_darkMode` aren't provided through the frontmatter
|
|
8
20
|
|
|
9
21
|
## 0.5.1
|
|
10
22
|
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
.heading a:hover {
|
|
7
|
-
text-decoration: underline;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.heading a:active {
|
|
11
|
-
color: var(--brand-InlineLink-color-pressed);
|
|
1
|
+
.IndexCards {
|
|
2
|
+
--brand-Grid-spacing-column-gap: var(--base-size-24);
|
|
3
|
+
--brand-Grid-spacing-row: var(--base-size-24);
|
|
4
|
+
padding-inline: 0;
|
|
12
5
|
}
|
|
@@ -1,16 +1,48 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import {
|
|
1
|
+
import React, {useCallback, useRef} from 'react'
|
|
2
|
+
import {Card, Grid} from '@primer/react-brand'
|
|
3
|
+
import {DocsItem} from '../../../types'
|
|
4
|
+
import {useColorMode} from '../../context/color-modes/useColorMode'
|
|
5
|
+
import type {StaticImageData} from 'next/image'
|
|
6
|
+
import placeholderDarkOneThumb from './images/dark-1.png'
|
|
7
|
+
import placeholderDarkTwoThumb from './images/dark-2.png'
|
|
8
|
+
import placeholderDarkThreeThumb from './images/dark-3.png'
|
|
9
|
+
import placeholderDarkFourThumb from './images/dark-4.png'
|
|
10
|
+
import placeholderDarkFiveThumb from './images/dark-5.png'
|
|
11
|
+
import placeholderDarkSixThumb from './images/dark-6.png'
|
|
12
|
+
import placeholderLightOneThumb from './images/light-1.png'
|
|
13
|
+
import placeholderLightTwoThumb from './images/light-2.png'
|
|
14
|
+
import placeholderLightThreeThumb from './images/light-3.png'
|
|
15
|
+
import placeholderLightFourThumb from './images/light-4.png'
|
|
16
|
+
import placeholderLightFiveThumb from './images/light-5.png'
|
|
17
|
+
import placeholderLightSixThumb from './images/light-6.png'
|
|
3
18
|
|
|
4
|
-
import Link from 'next/link'
|
|
5
19
|
import styles from './IndexCards.module.css'
|
|
6
|
-
import {DocsItem} from '../../../types'
|
|
7
20
|
|
|
8
21
|
type IndexCardsProps = {
|
|
9
22
|
route: string
|
|
10
23
|
folderData: DocsItem[]
|
|
11
24
|
}
|
|
12
25
|
|
|
26
|
+
const darkModePlaceholderThumbs = [
|
|
27
|
+
placeholderDarkOneThumb,
|
|
28
|
+
placeholderDarkTwoThumb,
|
|
29
|
+
placeholderDarkThreeThumb,
|
|
30
|
+
placeholderDarkFourThumb,
|
|
31
|
+
placeholderDarkFiveThumb,
|
|
32
|
+
placeholderDarkSixThumb,
|
|
33
|
+
] as unknown as StaticImageData[]
|
|
34
|
+
|
|
35
|
+
const lightModePlaceholderThumbs = [
|
|
36
|
+
placeholderLightOneThumb,
|
|
37
|
+
placeholderLightTwoThumb,
|
|
38
|
+
placeholderLightThreeThumb,
|
|
39
|
+
placeholderLightFourThumb,
|
|
40
|
+
placeholderLightFiveThumb,
|
|
41
|
+
placeholderLightSixThumb,
|
|
42
|
+
] as unknown as StaticImageData[]
|
|
43
|
+
|
|
13
44
|
export function IndexCards({route, folderData}: IndexCardsProps) {
|
|
45
|
+
const lastPlaceholderIndexRef = useRef<number>(-1)
|
|
14
46
|
// We don't want to show children of these pages. E.g. tabbed pages
|
|
15
47
|
const onlyDirectChildren = folderData.filter(item => {
|
|
16
48
|
// Normalize paths regardless of trailing slash enablement
|
|
@@ -27,23 +59,45 @@ export function IndexCards({route, folderData}: IndexCardsProps) {
|
|
|
27
59
|
})
|
|
28
60
|
|
|
29
61
|
const filteredData = onlyDirectChildren.filter(item => item.type === 'doc')
|
|
62
|
+
|
|
63
|
+
const {colorMode} = useColorMode()
|
|
64
|
+
|
|
65
|
+
// This is a better approach to straight randomisation, as it ensures that no adjacent placeholder images will be the same.
|
|
66
|
+
const getNextPlaceholderIndex = useCallback((placeholderArray: StaticImageData[]): StaticImageData => {
|
|
67
|
+
if (placeholderArray.length <= 1) {
|
|
68
|
+
return placeholderArray[0]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const numImagesByIndex = placeholderArray.map((_, index) => index)
|
|
72
|
+
|
|
73
|
+
const filteredIndexes = numImagesByIndex.filter(index => index !== lastPlaceholderIndexRef.current)
|
|
74
|
+
|
|
75
|
+
const nextIndex = filteredIndexes[Math.floor(Math.random() * filteredIndexes.length)]
|
|
76
|
+
|
|
77
|
+
lastPlaceholderIndexRef.current = nextIndex
|
|
78
|
+
return placeholderArray[nextIndex]
|
|
79
|
+
}, [])
|
|
80
|
+
|
|
30
81
|
return (
|
|
31
|
-
<
|
|
82
|
+
<Grid className={styles.IndexCards}>
|
|
32
83
|
{filteredData.map((item: DocsItem) => {
|
|
33
84
|
if (item.type !== 'doc' || !item.frontMatter) return null
|
|
34
85
|
|
|
86
|
+
const thumbnailUrl =
|
|
87
|
+
colorMode === 'dark'
|
|
88
|
+
? item.frontMatter.thumbnail_darkMode || getNextPlaceholderIndex(darkModePlaceholderThumbs).src
|
|
89
|
+
: item.frontMatter.thumbnail || getNextPlaceholderIndex(lightModePlaceholderThumbs).src
|
|
90
|
+
|
|
35
91
|
return (
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
</
|
|
41
|
-
</
|
|
42
|
-
|
|
43
|
-
{item.frontMatter.description && <Text as="p">{item.frontMatter.description}</Text>}
|
|
44
|
-
</Stack>
|
|
92
|
+
<Grid.Column span={{xsmall: 12, small: 12, medium: 12, large: 6, xlarge: 4}} key={item.frontMatter.title}>
|
|
93
|
+
<Card href={item.route} hasBorder>
|
|
94
|
+
<Card.Image src={thumbnailUrl} alt="" aspectRatio="4:3" />
|
|
95
|
+
<Card.Heading>{item.frontMatter.title}</Card.Heading>
|
|
96
|
+
{item.frontMatter.description && <Card.Description>{item.frontMatter.description}</Card.Description>}
|
|
97
|
+
</Card>
|
|
98
|
+
</Grid.Column>
|
|
45
99
|
)
|
|
46
100
|
})}
|
|
47
|
-
</
|
|
101
|
+
</Grid>
|
|
48
102
|
)
|
|
49
103
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -28,6 +28,8 @@ import '@primer/react-brand/lib/css/main.css'
|
|
|
28
28
|
import {normalizePages} from 'nextra/normalize-pages'
|
|
29
29
|
import {usePathname} from 'next/navigation'
|
|
30
30
|
|
|
31
|
+
import {useConfig} from '../../context/useConfig'
|
|
32
|
+
|
|
31
33
|
import {Header} from '../header/Header'
|
|
32
34
|
import {IndexCards} from '../index-cards/IndexCards'
|
|
33
35
|
import {useColorMode} from '../../context/color-modes/useColorMode'
|
|
@@ -75,6 +77,9 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
75
77
|
|
|
76
78
|
// eslint-disable-next-line i18n-text/no-en
|
|
77
79
|
const siteTitle = process.env.NEXT_PUBLIC_SITE_TITLE || 'Example Site'
|
|
80
|
+
const {headerLinks} = useConfig()
|
|
81
|
+
const activeHeaderLink = headerLinks.find(link => link.isActive)
|
|
82
|
+
|
|
78
83
|
const isHomePage = route === '/'
|
|
79
84
|
|
|
80
85
|
const activeFile = isHomePage
|
|
@@ -133,7 +138,7 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
133
138
|
<>
|
|
134
139
|
{activePath.length && (
|
|
135
140
|
<Breadcrumbs>
|
|
136
|
-
{siteTitle && (
|
|
141
|
+
{(activeHeaderLink || siteTitle) && (
|
|
137
142
|
<Breadcrumbs.Item
|
|
138
143
|
as={NextLink}
|
|
139
144
|
href="/"
|
|
@@ -141,7 +146,7 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
141
146
|
color: 'var(--brand-InlineLink-color-rest)',
|
|
142
147
|
}}
|
|
143
148
|
>
|
|
144
|
-
{siteTitle}
|
|
149
|
+
{activeHeaderLink ? activeHeaderLink.title : siteTitle}
|
|
145
150
|
</Breadcrumbs.Item>
|
|
146
151
|
)}
|
|
147
152
|
{activePath.map((item, index) => {
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
.Sidebar__title {
|
|
2
|
+
display: block;
|
|
3
|
+
padding: var(--base-size-24) var(--base-size-16) 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.NavList {
|
|
7
|
+
font-family: var(--brand-fontStack-sansSerif);
|
|
8
|
+
font-size: inherit;
|
|
9
|
+
}
|
|
10
|
+
|
|
1
11
|
@media (min-width: 768px) {
|
|
2
12
|
.Sidebar {
|
|
3
13
|
padding-inline-start: var(--base-size-8);
|
|
@@ -5,18 +15,21 @@
|
|
|
5
15
|
}
|
|
6
16
|
|
|
7
17
|
.NavList h3 {
|
|
8
|
-
|
|
9
|
-
|
|
18
|
+
color: var(--brand-color-text-default);
|
|
19
|
+
font-size: var(--brand-text-size-100);
|
|
10
20
|
}
|
|
11
21
|
|
|
12
|
-
.
|
|
13
|
-
|
|
22
|
+
.NavList__Container li a,
|
|
23
|
+
.NavList__Container li button {
|
|
24
|
+
font-size: var(--brand-text-size-200);
|
|
25
|
+
padding-block: 0.5em;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
|
-
.NavList
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
.NavList .NavListItem {
|
|
29
|
+
margin-top: var(--base-size-4);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.NavList .NavListItem,
|
|
33
|
+
.NavList .NavListItem a {
|
|
34
|
+
font-size: inherit;
|
|
22
35
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, {useMemo} from 'react'
|
|
2
2
|
import NextLink from 'next/link'
|
|
3
3
|
import {NavList} from '@primer/react'
|
|
4
|
+
import {Text} from '@primer/react-brand'
|
|
4
5
|
import type {Folder, MdxFile, PageMapItem} from 'nextra'
|
|
5
6
|
|
|
6
7
|
import styles from './Sidebar.module.css'
|
|
@@ -20,7 +21,8 @@ type SidebarProps = {
|
|
|
20
21
|
|
|
21
22
|
export function Sidebar({pageMap}: SidebarProps) {
|
|
22
23
|
const pathname = usePathname()
|
|
23
|
-
const {sidebarLinks} = useConfig()
|
|
24
|
+
const {headerLinks, sidebarLinks} = useConfig()
|
|
25
|
+
const activeHeaderLink = headerLinks.find(link => link.isActive)
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* Sorts the incoming data so that folders with a menu-position frontmatter value
|
|
@@ -46,6 +48,12 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
46
48
|
|
|
47
49
|
return (
|
|
48
50
|
<div className={styles.Sidebar}>
|
|
51
|
+
{activeHeaderLink && (
|
|
52
|
+
<Text size="400" weight="semibold" className={styles.Sidebar__title}>
|
|
53
|
+
{activeHeaderLink.title}
|
|
54
|
+
</Text>
|
|
55
|
+
)}
|
|
56
|
+
|
|
49
57
|
<NavList className={styles.NavList} aria-label="Menu links">
|
|
50
58
|
{reorderedPageMap.map(item => {
|
|
51
59
|
if (item.hasOwnProperty('data')) return null
|
|
@@ -70,6 +78,9 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
70
78
|
|
|
71
79
|
return (
|
|
72
80
|
<NavList.Group title={subNavName} key={item.name} sx={{mb: 24}}>
|
|
81
|
+
<NavList.GroupHeading as="h3">
|
|
82
|
+
<NextLink href={item.route}>{subNavName}</NextLink>
|
|
83
|
+
</NavList.GroupHeading>
|
|
73
84
|
{item.children
|
|
74
85
|
.sort((a, b) => ((a as MdxFile).name === 'index' ? -1 : (b as MdxFile).name === 'index' ? 1 : 0)) // puts index page first
|
|
75
86
|
// only show index page if it has show-tabs
|
|
@@ -85,6 +96,7 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
85
96
|
key={name}
|
|
86
97
|
href={route}
|
|
87
98
|
aria-current={route === cleanPathname ? 'page' : undefined}
|
|
99
|
+
className={styles.NavListItem}
|
|
88
100
|
>
|
|
89
101
|
{(child as MdxFile).frontMatter?.title || name}
|
|
90
102
|
</NavList.Item>
|
|
@@ -110,6 +122,7 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
110
122
|
href={landingPageItem.route}
|
|
111
123
|
sx={{textTransform: 'capitalize'}}
|
|
112
124
|
aria-current={isCurrentOrChild ? 'page' : undefined}
|
|
125
|
+
className={styles.NavListItem}
|
|
113
126
|
>
|
|
114
127
|
{landingPageItem.frontMatter?.title || item.name}
|
|
115
128
|
</NavList.Item>
|
|
@@ -129,6 +142,7 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
129
142
|
href={link.href}
|
|
130
143
|
{...(link.isExternal && {target: '_blank', rel: 'noopener noreferrer'})}
|
|
131
144
|
aria-current={link.isActive ? 'page' : undefined}
|
|
145
|
+
className={styles.NavListItem}
|
|
132
146
|
>
|
|
133
147
|
{link.title}
|
|
134
148
|
{link.isExternal && (
|
package/package.json
CHANGED