File tree 19 files changed +54
-53
lines changed
docs/docs-theme/built-ins/layout
19 files changed +54
-53
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ " nextra-theme-docs " : minor
3
+ ---
4
+
5
+ allow configuring ` theme.toc ` with ` layout: 'default' ` in ` _meta ` files
Original file line number Diff line number Diff line change @@ -11,7 +11,7 @@ import { cloneElement } from 'react'
11
11
export default function MdxLayout(props ) {
12
12
return cloneElement (props .children , {
13
13
components: {
14
- img: Image
14
+ img : props => < Image { ... props } className = " inline " />
15
15
}
16
16
})
17
17
}
@@ -65,16 +65,12 @@ Feel free to use the Nextra logo and other assets in your project. But please
65
65
don't modify the logo, and don't use the logo to represent your project or
66
66
product.
67
67
68
- <div className = " [&_img]:inline mt-6" >
69
-
70
68
| Name | Description | Preview |
71
69
| :---------: | :----------------------------------------------: | :-----------------------------------: |
72
70
| Icon | Useful for favicons, app icons, link icons, etc. | ![ Nextra icon] ( ../icon.svg ) |
73
71
| Logo | Full Nextra logo | ![ Nextra logo] ( /logo.svg ) |
74
72
| Social Card | The Nextra social card | ![ Nextra card] ( /opengraph-image.jpeg ) |
75
73
76
- </div >
77
-
78
74
## License
79
75
80
76
The Nextra project and themes are licensed under
Original file line number Diff line number Diff line change @@ -154,8 +154,6 @@ The above is also equivalent to `navigation: true{:js}`.
154
154
155
155
## Page Map [ !TODO]
156
156
157
- ## Search [ !TODO]
158
-
159
157
## Sidebar
160
158
161
159
| | | | |
Original file line number Diff line number Diff line change @@ -13,7 +13,7 @@ import { cloneElement } from 'react'
13
13
Projects powered by Nextra
14
14
15
15
{ /* prettier-ignore */ }
16
- <Cards className = " [&_img]:object-cover [&_img]:[aspect-ratio:12/6.3] " >
16
+ <Cards >
17
17
<>[ ![ GraphQL Hive preview] ( ./_logos/graphql-hive.png )] ( https://the-guild.dev/graphql/hive ) </>
18
18
<>[ ![ Speakeasy preview] ( ./_logos/speakeasy.png )] ( https://speakeasyapi.dev/docs ) </>
19
19
<>[ ![ React Flow preview] ( ./_logos/react-flow.jpg )] ( https://reactflow.dev ) </>
@@ -64,7 +64,9 @@ Projects powered by Nextra
64
64
export default function MdxLayout(props ) {
65
65
return cloneElement (props .children , {
66
66
components: {
67
- img: Image ,
67
+ img : props => (
68
+ <Image { ... props } className = " [aspect-ratio:12/6.3] object-cover" />
69
+ ),
68
70
a({ children , href }) {
69
71
const { alt } = children .props
70
72
return (
Original file line number Diff line number Diff line change @@ -23,7 +23,7 @@ import { cloneElement } from 'react'
23
23
</div >
24
24
25
25
{ /* prettier-ignore */ }
26
- <Cards num = { 3 } className = " [&_img]:object-cover [&_img]:[aspect-ratio:12/6.3] " >
26
+ <Cards num = { 3 } >
27
27
<>[ ![ GraphQL Hive preview] ( ../showcase/_logos/graphql-hive.png )] ( https://the-guild.dev/graphql/hive?utm_source=nextra.site&utm_campaign=nextra&utm_content=logolink ) </>
28
28
<>[ ![ Speakeasy preview] ( ../showcase/_logos/speakeasy.png )] ( https://speakeasyapi.dev/docs?utm_source=nextra.site&utm_campaign=nextra&utm_content=logolink ) </>
29
29
<>[ ![ xyflow preview] ( ../showcase/_logos/xyflow.jpg )] ( https://xyflow.com?utm_source=nextra.site&utm_campaign=nextra&utm_content=logolink ) </>
@@ -32,7 +32,9 @@ import { cloneElement } from 'react'
32
32
export default function MdxLayout(props ) {
33
33
return cloneElement (props .children , {
34
34
components: {
35
- img: Image ,
35
+ img : props => (
36
+ <Image { ... props } className = " [aspect-ratio:12/6.3] object-cover" />
37
+ ),
36
38
a({ children , href }) {
37
39
const { alt } = children .props
38
40
return (
Original file line number Diff line number Diff line change @@ -12,10 +12,7 @@ export const GoBack: FC = () => {
12
12
const isNestedPage = segments . length > 2
13
13
if ( ! isNestedPage ) return null
14
14
return (
15
- < Button
16
- onClick = { router . back }
17
- className = "x:print:hidden x:underline x:cursor-pointer"
18
- >
15
+ < Button onClick = { router . back } className = "x:print:hidden x:underline" >
19
16
Back
20
17
</ Button >
21
18
)
Original file line number Diff line number Diff line change @@ -20,7 +20,7 @@ export function ThemeSwitch() {
20
20
return (
21
21
< Button
22
22
aria-label = "Toggle Dark Mode"
23
- className = "x:p-2 x:cursor-pointer "
23
+ className = "x:p-2"
24
24
onClick = { toggleTheme }
25
25
>
26
26
< IconToUse height = "14" />
Original file line number Diff line number Diff line change @@ -30,7 +30,7 @@ export const BackToTop: FC<{
30
30
disabled = { hidden }
31
31
className = { ( { disabled } ) =>
32
32
cn (
33
- 'x:flex x:items-center x:gap-1.5 x:cursor-pointer ' ,
33
+ 'x:flex x:items-center x:gap-1.5' ,
34
34
'x:whitespace-nowrap' , // Safari
35
35
disabled ? 'x:opacity-0' : 'x:opacity-100' ,
36
36
className
@@ -39,7 +39,7 @@ export const BackToTop: FC<{
39
39
>
40
40
{ children }
41
41
< ArrowRightIcon
42
- height = "16 "
42
+ height = "1.1em "
43
43
className = "x:-rotate-90 x:border x:rounded-full x:border-current"
44
44
/>
45
45
</ Button >
Original file line number Diff line number Diff line change @@ -18,7 +18,7 @@ interface LocaleSwitchProps {
18
18
export const LocaleSwitch : FC < LocaleSwitchProps > = ( { lite, className } ) => {
19
19
const { i18n } = useThemeConfig ( )
20
20
const pathname = usePathname ( )
21
- if ( ! i18n . length ) return
21
+ if ( ! i18n . length ) return null
22
22
23
23
const [ , locale ] = pathname . split ( '/' , 2 )
24
24
return (
Original file line number Diff line number Diff line change @@ -456,7 +456,7 @@ export const Sidebar: FC<{ toc: Heading[] }> = ({ toc }) => {
456
456
title = { isExpanded ? 'Collapse sidebar' : 'Expand sidebar' }
457
457
className = { ( { hover } ) =>
458
458
cn (
459
- 'x:rounded-md x:p-2 x:cursor-pointer ' ,
459
+ 'x:rounded-md x:p-2' ,
460
460
hover
461
461
? 'x:bg-gray-100 x:text-gray-900 x:dark:bg-primary-100/5 x:dark:text-gray-50'
462
462
: 'x:text-gray-600 x:dark:text-gray-400'
Original file line number Diff line number Diff line change @@ -18,7 +18,7 @@ export const ThemeSwitch: FC<ThemeSwitchProps> = ({ lite, className }) => {
18
18
const mounted = useMounted ( )
19
19
const { darkMode, themeSwitch } = useThemeConfig ( )
20
20
if ( ! darkMode ) {
21
- return
21
+ return null
22
22
}
23
23
const IconToUse = mounted && resolvedTheme === 'dark' ? MoonIcon : SunIcon
24
24
const id = mounted ? ( theme as keyof typeof themeSwitch ) : 'light'
Original file line number Diff line number Diff line change @@ -28,7 +28,7 @@ export const ClientWrapper: MDXWrapper = ({
28
28
29
29
return (
30
30
< >
31
- { themeContext . layout !== 'full' && (
31
+ { ( themeContext . layout === 'default' || themeContext . toc ) && (
32
32
< nav
33
33
className = "nextra-toc x:order-last x:max-xl:hidden x:w-64 x:shrink-0 x:print:hidden"
34
34
aria-label = "table of contents"
Original file line number Diff line number Diff line change @@ -5,21 +5,23 @@ import { useEffect, useRef } from 'react'
5
5
6
6
export const ClientBanner : FC < ComponentPropsWithoutRef < 'div' > > = props => {
7
7
const banner = useRef < HTMLDivElement > ( null ! )
8
- // Set height on mount because text can be wrapped on next line and height can be different
8
+
9
9
useEffect ( ( ) => {
10
- const height = banner . current . clientHeight
11
- document . documentElement . style . setProperty (
12
- '--nextra-banner-height' ,
13
- `${ height } px`
14
- )
10
+ const resizeObserver = new ResizeObserver ( entries => {
11
+ for ( const entry of entries ) {
12
+ const { height } = entry . contentRect
13
+ // Set height because banner text can be wrapped on next line and his height can be different
14
+ document . documentElement . style . setProperty (
15
+ '--nextra-banner-height' ,
16
+ `${ height } px`
17
+ )
18
+ }
19
+ } )
20
+ resizeObserver . observe ( banner . current )
21
+ return ( ) => {
22
+ resizeObserver . disconnect ( )
23
+ }
15
24
} , [ ] )
16
25
17
- return (
18
- < div
19
- ref = { banner }
20
- // Because we update class in `<script>`
21
- suppressHydrationWarning
22
- { ...props }
23
- />
24
- )
26
+ return < div ref = { banner } { ...props } />
25
27
}
Original file line number Diff line number Diff line change @@ -10,9 +10,9 @@ export const Banner: FC<{
10
10
children : ReactNode
11
11
dismissible ?: boolean
12
12
storageKey ?: string
13
- } > = ( { children, dismissible = true , storageKey = 'nextra-banner' } ) => {
13
+ } > = ( { children, dismissible = true , storageKey = BANNER_CLASS_NAME } ) => {
14
14
if ( ! children ) {
15
- return
15
+ return null
16
16
}
17
17
const hideBannerScript = `try{document.querySelector('.${ BANNER_CLASS_NAME } ').classList.toggle('x:hidden',localStorage.getItem(${ JSON . stringify ( storageKey ) } ))}catch(e){}`
18
18
@@ -24,6 +24,8 @@ export const Banner: FC<{
24
24
'x:text-slate-50 x:dark:text-white x:bg-neutral-900 x:dark:bg-[linear-gradient(1deg,#383838,#212121)]' ,
25
25
'x:print:[display:none]' // to not match `x:[.nextra-banner:not([class$=hidden])~&]` class
26
26
) }
27
+ // Because we update class in `<script>`
28
+ suppressHydrationWarning
27
29
>
28
30
< div className = "x:w-full x:text-center x:font-medium x:text-sm x:py-2.5" >
29
31
{ children }
Original file line number Diff line number Diff line change @@ -20,7 +20,7 @@ export const Button: FC<ButtonProps> = ({
20
20
< HeadlessButton
21
21
className = { args =>
22
22
cn (
23
- 'x:transition' ,
23
+ 'x:transition x:cursor-pointer ' ,
24
24
args . focus && 'x:nextra-focus' ,
25
25
variant === 'outline' && [ classes . border , 'x:rounded-md x:p-1.5' ] ,
26
26
typeof className === 'function' ? className ( args ) : className
Original file line number Diff line number Diff line change @@ -79,7 +79,7 @@ export const Select: FC<MenuProps> = ({
79
79
) }
80
80
>
81
81
{ option . name }
82
- { selected && < CheckIcon height = "16 " /> }
82
+ { selected && < CheckIcon height = "1em " /> }
83
83
</ li >
84
84
) }
85
85
</ ListboxOption >
Original file line number Diff line number Diff line change @@ -40,7 +40,7 @@ export const CopyToClipboard: FC<ComponentProps<'button'>> = props => {
40
40
variant = "outline"
41
41
{ ...props }
42
42
>
43
- < IconToUse height = "16 " className = "nextra-copy-icon" />
43
+ < IconToUse height = "1em " className = "nextra-copy-icon" />
44
44
</ Button >
45
45
)
46
46
}
Original file line number Diff line number Diff line change @@ -32,7 +32,7 @@ export const Pre: FC<PreProps> = ({
32
32
...props
33
33
} ) => {
34
34
const copyButton = copy === '' && (
35
- < CopyToClipboard className = { filename ? 'x:ms-auto' : '' } />
35
+ < CopyToClipboard className = { filename ? 'x:ms-auto x:text-sm ' : '' } />
36
36
)
37
37
38
38
return (
@@ -81,7 +81,7 @@ export const Pre: FC<PreProps> = ({
81
81
>
82
82
{ hasWordWrap === '' && (
83
83
< ToggleWordWrapButton >
84
- < WordWrapIcon height = "16 " />
84
+ < WordWrapIcon height = "1em " />
85
85
</ ToggleWordWrapButton >
86
86
) }
87
87
{ ! filename && copyButton }
Original file line number Diff line number Diff line change 1
1
// should be used on server
2
2
'use no memo'
3
3
4
- import type { ReactElement , ReactNode , ReactPortal } from 'react'
4
+ import type { ReactElement , ReactNode } from 'react'
5
5
import { Children , cloneElement } from 'react'
6
6
7
7
type TOCElement = ReactElement | string
8
8
9
- type WithProps = ReactElement | ReactPortal
10
-
11
- function isLink ( node : ReactNode ) : node is WithProps {
12
- // @ts -expect-error -- fixme
13
- return hasProps ( node ) && ! ! node . props . href
14
- }
15
-
16
- function hasProps ( node : ReactNode ) : node is WithProps {
9
+ function hasProps ( node : ReactNode ) {
17
10
return ! ! node && typeof node === 'object'
18
11
}
19
12
@@ -23,7 +16,11 @@ export function removeLinks(node: ReactNode): TOCElement[] | string {
23
16
}
24
17
// @ts -expect-error fixme
25
18
return Children . map ( node , child => {
26
- if ( isLink ( child ) ) {
19
+ if (
20
+ hasProps ( child ) &&
21
+ // @ts -expect-error -- fixme
22
+ child . props . href
23
+ ) {
27
24
// Skip footnotes links
28
25
// @ts -expect-error -- fixme
29
26
if ( child . props [ 'data-footnote-ref' ] ) {
You can’t perform that action at this time.
0 commit comments