@primer/doctocat-nextjs 0.7.1-rc.a9c9ea3 → 0.8.0-rc.abeed68
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 +16 -9
- package/components/content/caption/Caption.module.css +6 -0
- package/components/content/caption/Caption.tsx +7 -2
- package/components/content/dos-and-donts/DosAndDonts.module.css +5 -1
- package/components/content/dos-and-donts/DosAndDonts.tsx +3 -15
- package/components/layout/article/AccessibilityLabel.module.css +1 -5
- package/components/layout/article/AccessibilityLabel.tsx +8 -5
- package/components/layout/article/ReadinessLabel.module.css +1 -5
- package/components/layout/article/ReadinessLabel.tsx +8 -5
- package/components/layout/code-block/ReactCodeBlock.tsx +4 -4
- package/components/layout/global-search/GlobalSearch.tsx +1 -0
- package/components/layout/header/Header.tsx +10 -1
- package/components/layout/nav-drawer/Drawer.module.css +19 -0
- package/components/layout/nav-drawer/Drawer.tsx +6 -9
- package/components/layout/nav-drawer/NavDrawer.tsx +1 -1
- package/components/layout/related-content-links/getRelatedPages.tsx +5 -2
- package/components/layout/root-layout/Theme.module.css +35 -0
- package/components/layout/root-layout/Theme.tsx +17 -32
- package/components/layout/sidebar/Sidebar.module.css +8 -0
- package/components/layout/sidebar/Sidebar.tsx +3 -4
- package/package.json +8 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# @primer/doctocat-nextjs
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#73](https://github.com/primer/doctocat-nextjs/pull/73) [`a06099d`](https://github.com/primer/doctocat-nextjs/commit/a06099d65d36bdb361fc9a20b2b811990bb6d353) Thanks [@danielguillan](https://github.com/danielguillan)! - Add React 19 support
|
|
8
|
+
|
|
9
|
+
This update is backwards compatible with React 18. However, it upgrades `@primer/react` to v38, which includes breaking changes such as the removal of the `Box` component and `sx` prop. Projects using this theme may need to update their code accordingly.
|
|
10
|
+
- Updated React peer dependency to support React 19
|
|
11
|
+
- Updated @primer/react from v37.11.2 to v38.3.0
|
|
12
|
+
- Updated `@primer/react-brand` from v0.54.0 to v0.60.1
|
|
13
|
+
- Updated `framer-motion` from v12.4.0 to v12.23.24
|
|
14
|
+
- Updated `react-focus-on` from v3.9.4 to v3.10.0
|
|
15
|
+
- Migrated `Label` components to `Token` for React 19 compatibility
|
|
16
|
+
- Fixed type errors in `ReactCodeBlock` and `getRelatedPages` for stricter React 19 types
|
|
17
|
+
- Added explicit `as="button"` to `IconButton` and `as="input"` to `TextInput` components
|
|
18
|
+
- Updated Next.js and related packages from v15.5.2 to v15.5.7
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
6
21
|
|
|
@@ -11,7 +26,6 @@
|
|
|
11
26
|
### Minor Changes
|
|
12
27
|
|
|
13
28
|
- [#65](https://github.com/primer/doctocat-nextjs/pull/65) [`dc680ec`](https://github.com/primer/doctocat-nextjs/commit/dc680ec51605bd7a40dedc71cd3bb107632035dd) Thanks [@rezrah](https://github.com/rezrah)! - Updated Next.js compatibility to v15.5.x, Nextra to v4, and fix React code block rendering
|
|
14
|
-
|
|
15
29
|
- **Next.js v15.5.2**: Upgraded to latest stable version across all workspaces
|
|
16
30
|
- **Nextra v4 compatibility**: Updated type definitions for `ReactNode` titles
|
|
17
31
|
- **Fixed code block rendering**: Added client-side rendering for interactive code examples to handle React lazy components properly
|
|
@@ -69,7 +83,6 @@
|
|
|
69
83
|
```
|
|
70
84
|
|
|
71
85
|
- [#48](https://github.com/primer/doctocat-nextjs/pull/48) [`ce73c24`](https://github.com/primer/doctocat-nextjs/commit/ce73c24b2e4e924667bf7446a504bd88d8f2ccf0) Thanks [@rezrah](https://github.com/rezrah)! - - Fix inline code font-size in markdown headings. Now inherits size used in the heading.
|
|
72
|
-
|
|
73
86
|
- Increased spacing below React code blocks, which was previously too small.
|
|
74
87
|
|
|
75
88
|
- [#50](https://github.com/primer/doctocat-nextjs/pull/50) [`5d67989`](https://github.com/primer/doctocat-nextjs/commit/5d679895408c1a58342419692db4234dfddefd80) Thanks [@rezrah](https://github.com/rezrah)! - Add `menu-position` frontmatter support for custom sidebar navigation ordering
|
|
@@ -87,7 +100,6 @@
|
|
|
87
100
|
### Patch Changes
|
|
88
101
|
|
|
89
102
|
- [#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.
|
|
90
|
-
|
|
91
103
|
- Added active header link as sidebar heading.
|
|
92
104
|
- Made active header the root item of breadcrumbs, if available.
|
|
93
105
|
- Made sidebar group headlines link to the index page.
|
|
@@ -111,7 +123,6 @@
|
|
|
111
123
|
### Minor Changes
|
|
112
124
|
|
|
113
125
|
- [#30](https://github.com/primer/doctocat-nextjs/pull/30) [`cdcb65e`](https://github.com/primer/doctocat-nextjs/commit/cdcb65e087d647a6d61c87d9122f105dcda64e35) Thanks [@joshfarrant](https://github.com/joshfarrant)! - - Arbitrary links can now be added to the sidebar and header using the `Theme` component's `headerLinks` and `sidebarLinks` props.
|
|
114
|
-
|
|
115
126
|
- Updated the header navigation to more closely visually align it with the existing Primer docs navigation.
|
|
116
127
|
- Removed `_meta.global.ts` and instead directly pass header and sidebar links into the Doctocat `Theme` component.
|
|
117
128
|
|
|
@@ -141,7 +152,6 @@
|
|
|
141
152
|
### Patch Changes
|
|
142
153
|
|
|
143
154
|
- [#34](https://github.com/primer/doctocat-nextjs/pull/34) [`ccf198c`](https://github.com/primer/doctocat-nextjs/commit/ccf198cca25b1f021c5ae78b8e2760c141a77dcc) Thanks [@rezrah](https://github.com/rezrah)! - Collection of UI bugfixes:
|
|
144
|
-
|
|
145
155
|
- Sidebar offset added to prevent links being trapped under fixed header
|
|
146
156
|
- Narrow viewport overflow bug fixed
|
|
147
157
|
- Table of contents presentation fixed on narrow viewport, and has improved presentation on wider breakpoints.
|
|
@@ -190,7 +200,6 @@
|
|
|
190
200
|
### Minor Changes
|
|
191
201
|
|
|
192
202
|
- [#20](https://github.com/primer/doctocat-nextjs/pull/20) [`be8bc6a`](https://github.com/primer/doctocat-nextjs/commit/be8bc6af733ba40bdd4393b876b2653017d7e846) Thanks [@rezrah](https://github.com/rezrah)! - Dropped support for Next.js Pages router in favor of App Router + Nextra v4
|
|
193
|
-
|
|
194
203
|
- [Read the migration guide from `v0.1.0` to `v0.2.0`](https://github.com/primer/doctocat-nextjs/blob/main/migration-guides/v0.2.0-app-router.md)
|
|
195
204
|
|
|
196
205
|
## 0.1.0
|
|
@@ -200,7 +209,6 @@
|
|
|
200
209
|
- [#18](https://github.com/primer/doctocat-nextjs/pull/18) [`bfe68b1`](https://github.com/primer/doctocat-nextjs/commit/bfe68b14e8e3b4383ea41dcbf47373df8a130567) Thanks [@rezrah](https://github.com/rezrah)! - Upgraded internal framework to [Nextra v3](https://the-guild.dev/blog/nextra-3).
|
|
201
210
|
|
|
202
211
|
To migrate Doctocat to this release, follow these steps:
|
|
203
|
-
|
|
204
212
|
1. Install the latest version `npm i @primer/doctocat-nextjs@0.1.0`
|
|
205
213
|
2. Rename your `next.config.js` to be `next.config.mjs`. Add `type="module"` to your `package.json` and update the file contents to match the following:
|
|
206
214
|
|
|
@@ -276,7 +284,6 @@
|
|
|
276
284
|
- [`6f21970`](https://github.com/primer/doctocat-nextjs/commit/6f21970c74f7635be89fc4cd20376d7fe5ca35e7) Thanks [@rezrah](https://github.com/rezrah)! - Switch hero image order with description and reduce `h2` block start margin
|
|
277
285
|
|
|
278
286
|
- [#6](https://github.com/primer/doctocat-nextjs/pull/6) [`afd4e17`](https://github.com/primer/doctocat-nextjs/commit/afd4e1762f6294a14942d415c693319a874cd3fb) Thanks [@rezrah](https://github.com/rezrah)! - - Add MDX to HTML overrides mechanism and apply to headings and anchors
|
|
279
|
-
|
|
280
287
|
- Added anchor links to headings to match current functionality on primer.style
|
|
281
288
|
|
|
282
289
|
- [`b49f218`](https://github.com/primer/doctocat-nextjs/commit/b49f218e9bbc2de720476e21888956bee6081967) Thanks [@rezrah](https://github.com/rezrah)! - Removed sidebar links and added skip to main content a11y link
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import React, {PropsWithChildren} from 'react'
|
|
2
|
-
import
|
|
2
|
+
import styles from './Caption.module.css'
|
|
3
3
|
|
|
4
4
|
export function Caption(props: PropsWithChildren) {
|
|
5
|
-
|
|
5
|
+
const {children, ...rest} = props
|
|
6
|
+
return (
|
|
7
|
+
<span className={styles.Caption} {...rest}>
|
|
8
|
+
{children}
|
|
9
|
+
</span>
|
|
10
|
+
)
|
|
6
11
|
}
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
color: var(--base-color-scale-white-0);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
.header {
|
|
43
|
+
color: var(--fgColor-onEmphasis, var(--color-fg-on-emphasis));
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
.content {
|
|
43
47
|
display: flex;
|
|
44
48
|
flex-direction: column;
|
|
@@ -55,6 +59,6 @@
|
|
|
55
59
|
|
|
56
60
|
.indentedContent {
|
|
57
61
|
margin: 0;
|
|
58
|
-
border-left: 4px solid;
|
|
62
|
+
border-left: 4px solid var(--brand-color-border-default);
|
|
59
63
|
padding-left: 1rem;
|
|
60
64
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {Box} from '@primer/react'
|
|
3
2
|
import clsx from 'clsx'
|
|
4
3
|
import styles from './DosAndDonts.module.css'
|
|
5
4
|
|
|
@@ -39,22 +38,11 @@ type DoDontBaseProps = {
|
|
|
39
38
|
export function DoDontBase({children, title, indented, className, ...rest}: React.PropsWithChildren<DoDontBaseProps>) {
|
|
40
39
|
return (
|
|
41
40
|
<div className={clsx(`exclude-from-prose`, styles.doDontBase, className)} {...rest}>
|
|
42
|
-
<
|
|
43
|
-
className={styles.header}
|
|
44
|
-
sx={{
|
|
45
|
-
color: 'var(--fgColor-onEmphasis, var(--color-fg-on-emphasis))',
|
|
46
|
-
}}
|
|
47
|
-
>
|
|
41
|
+
<div className={styles.header}>
|
|
48
42
|
<span className={styles.headerText}>{title}</span>
|
|
49
|
-
</
|
|
43
|
+
</div>
|
|
50
44
|
<div className={styles.content}>
|
|
51
|
-
{indented ?
|
|
52
|
-
<blockquote className={styles.indentedContent} style={{borderLeftColor: 'var(--brand-color-border-default)'}}>
|
|
53
|
-
{children}
|
|
54
|
-
</blockquote>
|
|
55
|
-
) : (
|
|
56
|
-
children
|
|
57
|
-
)}
|
|
45
|
+
{indented ? <blockquote className={styles.indentedContent}>{children}</blockquote> : children}
|
|
58
46
|
</div>
|
|
59
47
|
</div>
|
|
60
48
|
)
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
.reviewedLabel {
|
|
2
|
-
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
gap: var(--base-size-8);
|
|
5
2
|
background-color: var(--base-color-scale-purple-0);
|
|
6
|
-
|
|
7
|
-
color: var(--brand-color-text-default);
|
|
3
|
+
color: var(--brand-color-text-default) !important;
|
|
8
4
|
font-weight: var(--brand-text-weight-300);
|
|
9
5
|
}
|
|
10
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import {
|
|
2
|
+
import {Token} from '@primer/react'
|
|
3
3
|
import {AccessibilityInsetIcon} from '@primer/octicons-react'
|
|
4
4
|
import React from 'react'
|
|
5
5
|
|
|
@@ -11,9 +11,12 @@ type AccessibilityLabelProps = {
|
|
|
11
11
|
|
|
12
12
|
export function AccessibilityLabel({short}: AccessibilityLabelProps) {
|
|
13
13
|
return (
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
<Token
|
|
15
|
+
as="span"
|
|
16
|
+
size="large"
|
|
17
|
+
className={styles.reviewedLabel}
|
|
18
|
+
leadingVisual={() => <AccessibilityInsetIcon className={styles.icon} aria-hidden="true" />}
|
|
19
|
+
text={short ? 'Reviewed' : 'Reviewed for accessibility'}
|
|
20
|
+
/>
|
|
18
21
|
)
|
|
19
22
|
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
.label {
|
|
2
|
-
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
gap: var(--base-size-8);
|
|
5
2
|
background-color: var(--base-color-scale-green-0);
|
|
6
|
-
|
|
7
|
-
color: var(--brand-color-text-default);
|
|
3
|
+
color: var(--brand-color-text-default) !important;
|
|
8
4
|
font-weight: var(--brand-text-weight-300);
|
|
9
5
|
}
|
|
10
6
|
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import React from 'react'
|
|
3
|
-
import {
|
|
3
|
+
import {Token} from '@primer/react'
|
|
4
4
|
import {CheckIcon} from '@primer/octicons-react'
|
|
5
5
|
|
|
6
6
|
import styles from './ReadinessLabel.module.css'
|
|
7
7
|
|
|
8
8
|
export function ReadinessLabel() {
|
|
9
9
|
return (
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
<Token
|
|
11
|
+
as="span"
|
|
12
|
+
size="large"
|
|
13
|
+
className={styles.label}
|
|
14
|
+
leadingVisual={() => <CheckIcon className={styles.icon} aria-hidden="true" />}
|
|
15
|
+
text="Ready to use"
|
|
16
|
+
/>
|
|
14
17
|
)
|
|
15
18
|
}
|
|
@@ -205,13 +205,13 @@ export function ReactCodeBlock(props: ReactCodeBlockProps) {
|
|
|
205
205
|
* Helper function to turn Nextra <code> children into plain text
|
|
206
206
|
*/
|
|
207
207
|
function getCodeFromChildren(children: React.ReactNode) {
|
|
208
|
-
if (!React.isValidElement(children) || !children.props?.children) return ''
|
|
209
|
-
|
|
210
|
-
// Flattens the nested spans and combine their text content if it's a react child
|
|
211
208
|
const extractText = (node: React.ReactNode): string => {
|
|
212
209
|
if (typeof node === 'string') return node
|
|
213
210
|
if (Array.isArray(node)) return node.map(extractText).join('')
|
|
214
|
-
if (React.isValidElement(node)
|
|
211
|
+
if (React.isValidElement(node)) {
|
|
212
|
+
const element = node as React.ReactElement<{children?: React.ReactNode}>
|
|
213
|
+
return extractText(element.props.children)
|
|
214
|
+
}
|
|
215
215
|
return ''
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -170,6 +170,7 @@ export const GlobalSearch = forwardRef<HTMLInputElement, GlobalSearchProps>(
|
|
|
170
170
|
<FormControl>
|
|
171
171
|
<FormControl.Label visuallyHidden>Search</FormControl.Label>
|
|
172
172
|
<TextInput
|
|
173
|
+
as="input"
|
|
173
174
|
contrast
|
|
174
175
|
type="search"
|
|
175
176
|
className={styles.GlobalSearch__searchInput}
|
|
@@ -109,7 +109,13 @@ export function Header({siteTitle, flatDocsDirectories, pageMap}: HeaderProps) {
|
|
|
109
109
|
<Text as="p" size="300" weight="semibold">
|
|
110
110
|
Search
|
|
111
111
|
</Text>
|
|
112
|
-
<IconButton
|
|
112
|
+
<IconButton
|
|
113
|
+
as="button"
|
|
114
|
+
icon={XIcon}
|
|
115
|
+
variant="invisible"
|
|
116
|
+
aria-label="Close search"
|
|
117
|
+
onClick={closeSearch}
|
|
118
|
+
/>
|
|
113
119
|
</Stack>
|
|
114
120
|
</div>
|
|
115
121
|
</FocusOn>
|
|
@@ -117,12 +123,14 @@ export function Header({siteTitle, flatDocsDirectories, pageMap}: HeaderProps) {
|
|
|
117
123
|
<div>
|
|
118
124
|
<Stack direction="horizontal" padding="none" gap={4}>
|
|
119
125
|
<IconButton
|
|
126
|
+
as="button"
|
|
120
127
|
icon={colorMode === 'light' ? SunIcon : MoonIcon}
|
|
121
128
|
variant="invisible"
|
|
122
129
|
aria-label={`Switch to ${colorMode === 'light' ? 'dark' : 'light'} mode`}
|
|
123
130
|
onClick={() => setColorMode(colorMode === 'light' ? 'dark' : 'light')}
|
|
124
131
|
/>
|
|
125
132
|
<IconButton
|
|
133
|
+
as="button"
|
|
126
134
|
ref={searchTriggerRef}
|
|
127
135
|
className={styles.Header__searchButton}
|
|
128
136
|
icon={SearchIcon}
|
|
@@ -132,6 +140,7 @@ export function Header({siteTitle, flatDocsDirectories, pageMap}: HeaderProps) {
|
|
|
132
140
|
/>
|
|
133
141
|
<div className={styles.Header__navDrawerContainer}>
|
|
134
142
|
<IconButton
|
|
143
|
+
as="button"
|
|
135
144
|
icon={ThreeBarsIcon}
|
|
136
145
|
variant="invisible"
|
|
137
146
|
aria-label="Menu"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.DrawerOverlay {
|
|
2
|
+
position: fixed;
|
|
3
|
+
inset: 0;
|
|
4
|
+
background: rgba(0, 0, 0, 0.5);
|
|
5
|
+
z-index: 1;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.DrawerPanel {
|
|
9
|
+
position: fixed;
|
|
10
|
+
top: 0;
|
|
11
|
+
right: 0;
|
|
12
|
+
bottom: 0;
|
|
13
|
+
width: 300px;
|
|
14
|
+
background: var(--brand-color-canvas-default, var(--color-canvas-default));
|
|
15
|
+
z-index: 1;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
}
|
|
19
|
+
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, {PropsWithChildren} from 'react'
|
|
2
|
-
import {Box} from '@primer/react'
|
|
3
2
|
import {AnimatePresence, motion} from 'framer-motion'
|
|
4
3
|
import {FocusOn} from 'react-focus-on'
|
|
4
|
+
import styles from './Drawer.module.css'
|
|
5
5
|
|
|
6
6
|
type Drawer = {
|
|
7
7
|
isOpen: boolean
|
|
@@ -22,29 +22,26 @@ export function Drawer({isOpen, onDismiss, children}: PropsWithChildren<Drawer>)
|
|
|
22
22
|
tabIndex={0}
|
|
23
23
|
>
|
|
24
24
|
<FocusOn returnFocus={true} onEscapeKey={() => onDismiss()}>
|
|
25
|
-
<
|
|
25
|
+
<motion.div
|
|
26
26
|
key="overlay"
|
|
27
|
-
|
|
27
|
+
className={styles.DrawerOverlay}
|
|
28
28
|
initial={{opacity: 0}}
|
|
29
29
|
animate={{opacity: 1}}
|
|
30
30
|
exit={{opacity: 0}}
|
|
31
31
|
transition={{type: 'tween'}}
|
|
32
32
|
onClick={() => onDismiss()}
|
|
33
|
-
sx={{top: 0, right: 0, bottom: 0, left: 0, bg: 'rgba(0, 0, 0, 0.5)', position: 'fixed', zIndex: 1}}
|
|
34
33
|
/>
|
|
35
34
|
|
|
36
|
-
<
|
|
35
|
+
<motion.div
|
|
37
36
|
key="drawer"
|
|
38
|
-
|
|
37
|
+
className={styles.DrawerPanel}
|
|
39
38
|
initial={{x: '100%'}}
|
|
40
39
|
animate={{x: 0}}
|
|
41
40
|
exit={{x: '100%'}}
|
|
42
41
|
transition={{type: 'tween', duration: 0.2}}
|
|
43
|
-
style={{zIndex: 1}}
|
|
44
|
-
sx={{width: 300, top: 0, right: 0, bottom: 0, bg: 'gray.0', position: 'fixed'}}
|
|
45
42
|
>
|
|
46
43
|
{children}
|
|
47
|
-
</
|
|
44
|
+
</motion.div>
|
|
48
45
|
</FocusOn>
|
|
49
46
|
</div>
|
|
50
47
|
) : null}
|
|
@@ -26,7 +26,7 @@ export function NavDrawer({isOpen, onDismiss, pageMap}: NavDrawerProps) {
|
|
|
26
26
|
<Link as={NextLink} href="https://primer.style" className={styles.headerLink}>
|
|
27
27
|
Explore
|
|
28
28
|
</Link>
|
|
29
|
-
<IconButton icon={XIcon} aria-label="Close" onClick={onDismiss} variant="invisible" />
|
|
29
|
+
<IconButton as="button" icon={XIcon} aria-label="Close" onClick={onDismiss} variant="invisible" />
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
32
|
<div className={styles.navContainer}>{/* <PrimerNavItems items={primerNavItems} /> */}</div>
|
|
@@ -66,8 +66,11 @@ function titleToString(title: React.ReactNode): string {
|
|
|
66
66
|
if (typeof child === 'string' || typeof child === 'number') {
|
|
67
67
|
return child.toString()
|
|
68
68
|
}
|
|
69
|
-
if (React.isValidElement(child)
|
|
70
|
-
|
|
69
|
+
if (React.isValidElement(child)) {
|
|
70
|
+
const element = child as React.ReactElement<{children?: React.ReactNode}>
|
|
71
|
+
if (element.props.children) {
|
|
72
|
+
return titleToString(element.props.children)
|
|
73
|
+
}
|
|
71
74
|
}
|
|
72
75
|
return ''
|
|
73
76
|
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.StickyHeader {
|
|
2
|
+
position: sticky;
|
|
3
|
+
top: 0;
|
|
4
|
+
z-index: 99;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.ContentContainer {
|
|
8
|
+
max-width: 1200px;
|
|
9
|
+
width: 100%;
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.BreadcrumbRoot,
|
|
14
|
+
.BreadcrumbItem {
|
|
15
|
+
color: var(--brand-InlineLink-color-rest);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.BreadcrumbItem {
|
|
19
|
+
text-transform: capitalize;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.HeroImageWrapper {
|
|
23
|
+
padding-block-start: var(--base-size-16);
|
|
24
|
+
width: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
.ActionsWrapper {
|
|
29
|
+
padding-block-start: var(--base-size-16);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
.RelatedLinks {
|
|
34
|
+
padding-top: var(--base-size-20);
|
|
35
|
+
}
|
|
@@ -4,13 +4,12 @@ import NextLink from 'next/link'
|
|
|
4
4
|
import Head from 'next/head'
|
|
5
5
|
import type {Folder, MdxFile, PageMapItem} from 'nextra'
|
|
6
6
|
import {useFSRoute} from 'nextra/hooks'
|
|
7
|
-
import {BaseStyles,
|
|
7
|
+
import {BaseStyles, Breadcrumbs, PageLayout, ThemeProvider} from '@primer/react'
|
|
8
8
|
import '@primer/primitives/dist/css/functional/themes/light.css'
|
|
9
9
|
import '@primer/primitives/dist/css/functional/themes/dark.css'
|
|
10
10
|
import {
|
|
11
11
|
Animate,
|
|
12
12
|
AnimationProvider,
|
|
13
|
-
Box,
|
|
14
13
|
ButtonGroup,
|
|
15
14
|
ThemeProvider as BrandThemeProvider,
|
|
16
15
|
Button,
|
|
@@ -38,6 +37,7 @@ import {RelatedContentLinks} from '../related-content-links/RelatedContentLinks'
|
|
|
38
37
|
import {getRelatedPages} from '../related-content-links/getRelatedPages'
|
|
39
38
|
import {hasChildren} from '../../../helpers/hasChildren'
|
|
40
39
|
import {Footer} from '../footer/Footer'
|
|
40
|
+
import styles from './Theme.module.css'
|
|
41
41
|
|
|
42
42
|
const repoSrcPath = process.env.NEXT_PUBLIC_REPO_SRC_PATH || ''
|
|
43
43
|
const repoURL = process.env.NEXT_PUBLIC_REPO || ''
|
|
@@ -119,16 +119,10 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
119
119
|
</Head>
|
|
120
120
|
|
|
121
121
|
<ContentWrapper disableAnimations={disablePageAnimation}>
|
|
122
|
-
<
|
|
123
|
-
sx={{
|
|
124
|
-
position: 'sticky',
|
|
125
|
-
top: 0,
|
|
126
|
-
zIndex: 99,
|
|
127
|
-
}}
|
|
128
|
-
>
|
|
122
|
+
<div className={styles.StickyHeader}>
|
|
129
123
|
<SkipToMainContent href="#main">Skip to main content</SkipToMainContent>
|
|
130
124
|
<Header flatDocsDirectories={flatDocsDirectories} siteTitle={siteTitle} pageMap={pageMap} />
|
|
131
|
-
</
|
|
125
|
+
</div>
|
|
132
126
|
<PageLayout rowGap="none" columnGap="none" padding="none" containerWidth="full">
|
|
133
127
|
<PageLayout.Pane
|
|
134
128
|
width="small"
|
|
@@ -145,20 +139,14 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
145
139
|
</PageLayout.Pane>
|
|
146
140
|
<PageLayout.Content padding="normal">
|
|
147
141
|
<div id="main">
|
|
148
|
-
<
|
|
142
|
+
<div style={!isHomePage ? {maxWidth: 1200, width: '100%', margin: '0 auto'} : undefined}>
|
|
149
143
|
<Stack direction="vertical" padding="none" gap="spacious">
|
|
150
144
|
{!isHomePage && (
|
|
151
145
|
<>
|
|
152
146
|
{activePath.length > 0 && (
|
|
153
|
-
<Breadcrumbs>
|
|
147
|
+
<Breadcrumbs className={styles.BreadcrumbRoot}>
|
|
154
148
|
{(activeHeaderLink || siteTitle) && (
|
|
155
|
-
<Breadcrumbs.Item
|
|
156
|
-
as={NextLink}
|
|
157
|
-
href="/"
|
|
158
|
-
sx={{
|
|
159
|
-
color: 'var(--brand-InlineLink-color-rest)',
|
|
160
|
-
}}
|
|
161
|
-
>
|
|
149
|
+
<Breadcrumbs.Item as={NextLink} href="/">
|
|
162
150
|
{activeHeaderLink ? activeHeaderLink.title : siteTitle}
|
|
163
151
|
</Breadcrumbs.Item>
|
|
164
152
|
)}
|
|
@@ -192,10 +180,7 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
192
180
|
key={item.name}
|
|
193
181
|
href={item.route}
|
|
194
182
|
selected={isLastItem}
|
|
195
|
-
|
|
196
|
-
textTransform: 'capitalize',
|
|
197
|
-
color: 'var(--brand-InlineLink-color-rest)',
|
|
198
|
-
}}
|
|
183
|
+
className={styles.BreadcrumbItem}
|
|
199
184
|
>
|
|
200
185
|
{itemTitle.replace(/-/g, ' ')}
|
|
201
186
|
</Breadcrumbs.Item>
|
|
@@ -204,7 +189,7 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
204
189
|
</Breadcrumbs>
|
|
205
190
|
)}
|
|
206
191
|
|
|
207
|
-
<
|
|
192
|
+
<div>
|
|
208
193
|
<Stack direction="vertical" padding="none" gap={12} alignItems="flex-start">
|
|
209
194
|
{activeMetadata.title && (
|
|
210
195
|
<Heading as="h1" size="3">
|
|
@@ -217,12 +202,12 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
217
202
|
</Text>
|
|
218
203
|
)}
|
|
219
204
|
{activeMetadata.image && (
|
|
220
|
-
<
|
|
205
|
+
<div className={styles.HeroImageWrapper}>
|
|
221
206
|
<Hero.Image src={activeMetadata.image} alt={activeMetadata['image-alt']} />
|
|
222
|
-
</
|
|
207
|
+
</div>
|
|
223
208
|
)}
|
|
224
209
|
{activeMetadata['action-1-text'] && (
|
|
225
|
-
<
|
|
210
|
+
<div className={styles.ActionsWrapper}>
|
|
226
211
|
<ButtonGroup>
|
|
227
212
|
<Button as="a" href={activeMetadata['action-1-link']}>
|
|
228
213
|
{activeMetadata['action-1-text']}
|
|
@@ -233,10 +218,10 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
233
218
|
</Button>
|
|
234
219
|
)}
|
|
235
220
|
</ButtonGroup>
|
|
236
|
-
</
|
|
221
|
+
</div>
|
|
237
222
|
)}
|
|
238
223
|
</Stack>
|
|
239
|
-
</
|
|
224
|
+
</div>
|
|
240
225
|
{activeMetadata['show-tabs'] && <UnderlineNav tabData={filteredTabData} />}
|
|
241
226
|
</>
|
|
242
227
|
)}
|
|
@@ -248,16 +233,16 @@ export function Theme({pageMap, children}: ThemeProps) {
|
|
|
248
233
|
<>{children}</>
|
|
249
234
|
|
|
250
235
|
{relatedLinks.length > 0 && (
|
|
251
|
-
<
|
|
236
|
+
<div className={styles.RelatedLinks}>
|
|
252
237
|
<RelatedContentLinks links={relatedLinks} />
|
|
253
|
-
</
|
|
238
|
+
</div>
|
|
254
239
|
)}
|
|
255
240
|
</>
|
|
256
241
|
)}
|
|
257
242
|
</article>
|
|
258
243
|
<Footer filePath={filePath} repoURL={repoURL} repoSrcPath={repoSrcPath} />
|
|
259
244
|
</Stack>
|
|
260
|
-
</
|
|
245
|
+
</div>
|
|
261
246
|
</div>
|
|
262
247
|
</PageLayout.Content>
|
|
263
248
|
</PageLayout>
|
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
font-size: var(--brand-text-size-100);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
.NavListGroup {
|
|
23
|
+
margin-bottom: var(--base-size-24);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.NavListItemCapitalize {
|
|
27
|
+
text-transform: capitalize;
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
.NavList__Container li a,
|
|
23
31
|
.NavList__Container li button {
|
|
24
32
|
font-size: var(--brand-text-size-200);
|
|
@@ -77,7 +77,7 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
return (
|
|
80
|
-
<NavList.Group title={subNavName} key={item.name}
|
|
80
|
+
<NavList.Group title={subNavName} key={item.name} className={styles.NavListGroup}>
|
|
81
81
|
<NavList.GroupHeading as="h3">
|
|
82
82
|
<NextLink href={item.route}>{subNavName}</NextLink>
|
|
83
83
|
</NavList.GroupHeading>
|
|
@@ -142,9 +142,8 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
142
142
|
as={NextLink}
|
|
143
143
|
key={landingPageItem.route}
|
|
144
144
|
href={landingPageItem.route}
|
|
145
|
-
sx={{textTransform: 'capitalize'}}
|
|
146
145
|
aria-current={isCurrentOrChild ? 'page' : undefined}
|
|
147
|
-
className={styles.NavListItem}
|
|
146
|
+
className={`${styles.NavListItem} ${styles.NavListItemCapitalize}`}
|
|
148
147
|
>
|
|
149
148
|
{landingPageItem.frontMatter?.title || item.name}
|
|
150
149
|
</NavList.Item>
|
|
@@ -155,7 +154,7 @@ export function Sidebar({pageMap}: SidebarProps) {
|
|
|
155
154
|
)
|
|
156
155
|
})}
|
|
157
156
|
{sidebarLinks.length > 0 && (
|
|
158
|
-
<NavList.Group title=""
|
|
157
|
+
<NavList.Group title="" className={styles.NavListGroup}>
|
|
159
158
|
{sidebarLinks.map(link => {
|
|
160
159
|
return (
|
|
161
160
|
<NavList.Item
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primer/doctocat-nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-rc.abeed68",
|
|
4
4
|
"description": "A Next.js theme for building Primer documentation sites",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,16 +25,14 @@
|
|
|
25
25
|
"react-dom": ">=18.0.0 <20.0.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@next/mdx": "15.5.
|
|
28
|
+
"@next/mdx": "15.5.7",
|
|
29
29
|
"@primer/octicons-react": "19.15.1",
|
|
30
|
-
"@primer/react": "^
|
|
30
|
+
"@primer/react": "^38.3.0",
|
|
31
31
|
"@types/lodash.debounce": "^4.0.9",
|
|
32
|
-
"framer-motion": "12.
|
|
32
|
+
"framer-motion": "12.23.24",
|
|
33
33
|
"lodash.debounce": "^4.0.8",
|
|
34
34
|
"nextra": "4.4.0",
|
|
35
|
-
"react": "
|
|
36
|
-
"react-dom": ">=18.0.0 <20.0.0",
|
|
37
|
-
"react-focus-on": "3.9.4",
|
|
35
|
+
"react-focus-on": "^3.10.0",
|
|
38
36
|
"react-live": "^4.1.8"
|
|
39
37
|
},
|
|
40
38
|
"devDependencies": {
|
|
@@ -44,19 +42,15 @@
|
|
|
44
42
|
"@testing-library/react": "^16.1.0",
|
|
45
43
|
"@testing-library/user-event": "^14.5.2",
|
|
46
44
|
"@types/node": "^20.19.0",
|
|
47
|
-
"@types/react": "
|
|
48
|
-
"@types/react-dom": "
|
|
45
|
+
"@types/react": "^19.2.7",
|
|
46
|
+
"@types/react-dom": "^19.2.3",
|
|
49
47
|
"@vitejs/plugin-react": "^4.3.3",
|
|
50
48
|
"@vitest/coverage-v8": "^3.2.4",
|
|
51
49
|
"@vitest/ui": "^3.2.4",
|
|
52
50
|
"clsx": "2.1.1",
|
|
53
51
|
"jsdom": "^26.0.1",
|
|
54
|
-
"next": "15.5.
|
|
52
|
+
"next": "15.5.7",
|
|
55
53
|
"styled-components": "5.3.11",
|
|
56
54
|
"vitest": "^3.2.4"
|
|
57
|
-
},
|
|
58
|
-
"overrides": {
|
|
59
|
-
"@types/react": "18.3.12",
|
|
60
|
-
"@types/react-dom": "18.3.1"
|
|
61
55
|
}
|
|
62
56
|
}
|