@brillout/docpress 0.7.10 → 0.8.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/+config.ts +2 -10
- package/Layout.tsx +397 -67
- package/{navigation/NavigationHeader.tsx → Links.tsx} +6 -57
- package/MenuModal.tsx +146 -0
- package/autoScrollNav.ts +4 -5
- package/components/CodeBlockTransformer.tsx +0 -2
- package/components/Note.css +4 -4
- package/components/Note.tsx +0 -2
- package/components/Supporters.tsx +1 -0
- package/config/resolveHeadingsData.ts +20 -23
- package/config/resolvePageContext.ts +11 -1
- package/css/code/block.css +5 -5
- package/css/code/inline.css +1 -1
- package/css/code.css +9 -5
- package/css/index.css +0 -4
- package/css/reset.css +0 -6
- package/dist/+config.d.ts +1 -13
- package/dist/+config.js +0 -3
- package/dist/components/CodeBlockTransformer.d.ts +1 -0
- package/dist/components/CodeBlockTransformer.js +1 -0
- package/dist/components/Note.d.ts +1 -0
- package/dist/components/Note.js +1 -0
- package/dist/components/Supporters.js +1 -0
- package/dist/config/resolveHeadingsData.d.ts +5 -8
- package/dist/config/resolveHeadingsData.js +20 -22
- package/dist/config/resolvePageContext.d.ts +5 -7
- package/dist/config/resolvePageContext.js +2 -1
- package/dist/navigation/Navigation.d.ts +12 -17
- package/dist/navigation/Navigation.js +82 -74
- package/dist/renderer/getStyleColumnLayout.d.ts +7 -0
- package/dist/renderer/getStyleColumnLayout.js +183 -0
- package/dist/types/Heading.d.ts +2 -4
- package/dist/utils/client.d.ts +1 -0
- package/dist/utils/client.js +1 -0
- package/dist/utils/css.d.ts +1 -0
- package/dist/utils/css.js +27 -0
- package/dist/utils/getGlobalObject.d.ts +1 -0
- package/dist/utils/getGlobalObject.js +9 -0
- package/docsearch/DocSearchInstall.tsx +23 -0
- package/docsearch/SearchLink.tsx +48 -0
- package/docsearch/toggleDocsearchModal.ts +29 -0
- package/global.d.ts +7 -0
- package/initKeyBindings.ts +41 -0
- package/installSectionUrlHashs.ts +6 -5
- package/navigation/Navigation.css +101 -3
- package/navigation/Navigation.tsx +114 -128
- package/package.json +1 -8
- package/renderer/getPageElement.tsx +19 -7
- package/renderer/getStyleColumnLayout.ts +204 -0
- package/renderer/onRenderClient.tsx +17 -24
- package/renderer/onRenderHtml.tsx +3 -6
- package/types/Heading.ts +2 -5
- package/utils/client.ts +1 -0
- package/utils/css.ts +26 -0
- package/utils/getGlobalObject.ts +11 -0
- package/Layout.css +0 -63
- package/MobileHeader.tsx +0 -70
- package/algolia/DocSearch.css +0 -28
- package/components/FeatureList/FeatureList.client.ts +0 -60
- package/components/FeatureList/FeatureList.css +0 -119
- package/components/FeatureList/FeatureList.tsx +0 -114
- package/components/FeatureList/chevron.svg +0 -7
- package/css/block-design.css +0 -4
- package/dist/autoScrollNav.d.ts +0 -3
- package/dist/autoScrollNav.js +0 -36
- package/dist/components/Algolia/Hit.d.ts +0 -4
- package/dist/components/Algolia/Hit.js +0 -30
- package/dist/components/Algolia/SelectIcon.d.ts +0 -2
- package/dist/components/Algolia/SelectIcon.js +0 -7
- package/dist/components/Algolia/Snippet.d.ts +0 -13
- package/dist/components/Algolia/Snippet.js +0 -37
- package/dist/components/Algolia/SourceIcon.d.ts +0 -4
- package/dist/components/Algolia/SourceIcon.js +0 -23
- package/dist/components/Algolia/types.d.ts +0 -79
- package/dist/components/Algolia/types.js +0 -1
- package/dist/navigation/NavigationHeader.d.ts +0 -8
- package/dist/navigation/NavigationHeader.js +0 -75
- package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.d.ts +0 -6
- package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.js +0 -23
- package/dist/navigation/navigation-fullscreen/hotkeyLabel.d.ts +0 -1
- package/dist/navigation/navigation-fullscreen/hotkeyLabel.js +0 -1
- package/navigation/Navigation-highlight.css +0 -41
- package/navigation/Navigation-items.css +0 -116
- package/navigation/Navigation-layout.css +0 -129
- package/navigation/initMobileNavigation.ts +0 -23
- package/navigation/initPressKit.ts +0 -19
- package/navigation/navigation-fullscreen/NavigationFullscreenButton.css +0 -32
- package/navigation/navigation-fullscreen/NavigationFullscreenButton.tsx +0 -47
- package/navigation/navigation-fullscreen/chevron.svg +0 -1
- package/navigation/navigation-fullscreen/close.svg +0 -4
- package/navigation/navigation-fullscreen/hotkeyLabel.ts +0 -1
- package/navigation/navigation-fullscreen/initNavigationFullscreen.ts +0 -60
- package/renderer/getCSSForResponsiveFullcreenNavItems.ts +0 -127
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export { closeDocsearchModal }
|
|
2
|
+
export { openDocsearchModal }
|
|
3
|
+
|
|
4
|
+
import { assert } from '../utils/client'
|
|
5
|
+
|
|
6
|
+
function closeDocsearchModal() {
|
|
7
|
+
if (isClosed()) return
|
|
8
|
+
toggle()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function openDocsearchModal() {
|
|
12
|
+
if (!isClosed()) return
|
|
13
|
+
toggle()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// There doesn't seem be an official API to open/close the DocSearch modal:
|
|
17
|
+
// - https://github.com/algolia/docsearch/issues/2321
|
|
18
|
+
// - https://github.com/algolia/docsearch/blob/90f3c6aabbc324fe49e9a1dfe0906fcd4d90f27b/packages/docsearch-react/src/DocSearch.tsx#L52
|
|
19
|
+
function toggle() {
|
|
20
|
+
// Trigger https://github.com/algolia/docsearch/blob/90f3c6aabbc324fe49e9a1dfe0906fcd4d90f27b/packages/docsearch-react/src/useDocSearchKeyboardEvents.ts#L71
|
|
21
|
+
window.dispatchEvent(new KeyboardEvent('keydown', { key: 'k', ctrlKey: true }))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isClosed() {
|
|
25
|
+
const test1 = !document.body.classList.contains('DocSearch--active')
|
|
26
|
+
const test2 = document.getElementsByClassName('DocSearch-Modal').length === 0
|
|
27
|
+
assert(test1 === test2)
|
|
28
|
+
return test1 || test2
|
|
29
|
+
}
|
package/global.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { initKeyBindings }
|
|
2
|
+
|
|
3
|
+
import { closeDocsearchModal } from './docsearch/toggleDocsearchModal'
|
|
4
|
+
import { closeMenuModal, toggleMenuModal } from './MenuModal'
|
|
5
|
+
|
|
6
|
+
function initKeyBindings() {
|
|
7
|
+
window.addEventListener(
|
|
8
|
+
// Cannot use `keyup`: https://stackoverflow.com/questions/66595035/how-to-detect-escape-key-if-search-bar-of-browser-is-open/66600548#66600548
|
|
9
|
+
'keydown',
|
|
10
|
+
(ev) => {
|
|
11
|
+
if (ev.key === 'Escape') {
|
|
12
|
+
closeDocsearchModal()
|
|
13
|
+
closeMenuModal()
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const key = (ev.key || '').toLowerCase()
|
|
18
|
+
const isCtrl = ev.metaKey || ev.ctrlKey
|
|
19
|
+
if (isCtrl && key === 'm') {
|
|
20
|
+
ev.preventDefault()
|
|
21
|
+
closeDocsearchModal()
|
|
22
|
+
toggleMenuModal()
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Replicate https://github.com/algolia/docsearch/blob/90f3c6aabbc324fe49e9a1dfe0906fcd4d90f27b/packages/docsearch-react/src/useDocSearchKeyboardEvents.ts#L45-L49
|
|
27
|
+
if ((isCtrl && key === 'k') || (key === '/' && !isEditingContent(ev))) {
|
|
28
|
+
ev.preventDefault()
|
|
29
|
+
closeMenuModal()
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
false,
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
function isEditingContent(event: KeyboardEvent): boolean {
|
|
37
|
+
const element = event.target as HTMLElement
|
|
38
|
+
const tagName = element.tagName
|
|
39
|
+
|
|
40
|
+
return element.isContentEditable || tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA'
|
|
41
|
+
}
|
|
@@ -3,10 +3,11 @@ export { installSectionUrlHashs }
|
|
|
3
3
|
import { assert } from './utils/client'
|
|
4
4
|
|
|
5
5
|
function installSectionUrlHashs() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
{
|
|
7
|
+
const isLandingPage = window.location.pathname === '/'
|
|
8
|
+
const isDocPage = !!document.querySelector('.doc-page')
|
|
9
|
+
assert(isLandingPage !== isDocPage)
|
|
10
|
+
if (!isDocPage) return
|
|
10
11
|
}
|
|
11
12
|
const headings = [...Array.from(document.querySelectorAll('h2')), ...Array.from(document.querySelectorAll('h3'))]
|
|
12
13
|
headings.forEach((heading) => {
|
|
@@ -26,7 +27,7 @@ function installSectionUrlHashs() {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
function assertNavLink(urlHash: string, heading: HTMLHeadingElement) {
|
|
29
|
-
const navigationEl = document.querySelector('#navigation-
|
|
30
|
+
const navigationEl = document.querySelector('#nav-left .navigation-content')!
|
|
30
31
|
{
|
|
31
32
|
const { pathname } = window.location
|
|
32
33
|
const parentNavLinkMatch = Array.from(navigationEl.querySelectorAll(`a[href="${pathname}"]`))
|
|
@@ -1,3 +1,101 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
.nav-item {
|
|
2
|
+
display: block;
|
|
3
|
+
white-space: nowrap;
|
|
4
|
+
overflow-x: hidden;
|
|
5
|
+
--padding-left-global: 9px;
|
|
6
|
+
--padding-left-additional: 0px;
|
|
7
|
+
}
|
|
8
|
+
.nav-item code {
|
|
9
|
+
font-size: 0.9em;
|
|
10
|
+
}
|
|
11
|
+
.nav-item-level-1 + .nav-item-level-4 {
|
|
12
|
+
margin-top: -2px;
|
|
13
|
+
}
|
|
14
|
+
.nav-item-level-4 {
|
|
15
|
+
margin-top: 14px;
|
|
16
|
+
margin-bottom: -1px;
|
|
17
|
+
color: #999;
|
|
18
|
+
font-size: 12px;
|
|
19
|
+
font-weight: 400;
|
|
20
|
+
letter-spacing: 0.15ch;
|
|
21
|
+
padding-left: var(--padding-left-global);
|
|
22
|
+
padding-right: 4px;
|
|
23
|
+
text-decoration: none;
|
|
24
|
+
}
|
|
25
|
+
.nav-item-level-1 {
|
|
26
|
+
font-size: 19px;
|
|
27
|
+
text-transform: uppercase;
|
|
28
|
+
font-weight: 600;
|
|
29
|
+
letter-spacing: 0.14ch;
|
|
30
|
+
color: var(--color-text);
|
|
31
|
+
padding: 12px 0;
|
|
32
|
+
padding-left: calc(var(--padding-left-global) - 2px);
|
|
33
|
+
padding-right: 4px;
|
|
34
|
+
text-decoration: none;
|
|
35
|
+
}
|
|
36
|
+
.nav-item-level-2 {
|
|
37
|
+
text-decoration: none;
|
|
38
|
+
font-size: 14.4px;
|
|
39
|
+
font-weight: 400;
|
|
40
|
+
letter-spacing: 0.15ch;
|
|
41
|
+
color: var(--color-text);
|
|
42
|
+
padding-left: var(--padding-left-global);
|
|
43
|
+
padding-right: 0;
|
|
44
|
+
--padding: 4px;
|
|
45
|
+
padding-top: var(--padding);
|
|
46
|
+
padding-bottom: var(--padding);
|
|
47
|
+
}
|
|
48
|
+
.nav-item-level-3 {
|
|
49
|
+
font-size: 12px;
|
|
50
|
+
font-weight: 400;
|
|
51
|
+
letter-spacing: 0.15ch;
|
|
52
|
+
color: var(--color-text);
|
|
53
|
+
text-decoration: none;
|
|
54
|
+
--padding: 5px;
|
|
55
|
+
|
|
56
|
+
/* #ededed === rgb(237, 237, 237)
|
|
57
|
+
* #f5f5f5 === rgb(245, 245, 245)
|
|
58
|
+
* 1 - (237 / 245) === 0.03265306122
|
|
59
|
+
background-color: #ededed;
|
|
60
|
+
*/
|
|
61
|
+
background-color: rgba(0,0,0, 0.03265306122);
|
|
62
|
+
padding: var(--padding) 0;
|
|
63
|
+
padding-left: calc(var(--padding-left-global) + var(--padding-left-additional));
|
|
64
|
+
}
|
|
65
|
+
#menu-modal .nav-item-level-3 {
|
|
66
|
+
border-right: 4px solid #eee;
|
|
67
|
+
}
|
|
68
|
+
.nav-item {
|
|
69
|
+
/*
|
|
70
|
+
--shadow-size: 14px;
|
|
71
|
+
--shadow-color: rgba(0, 0, 0, 0.09);
|
|
72
|
+
*/
|
|
73
|
+
--shadow-size: 7px;
|
|
74
|
+
--shadow-color: rgba(0, 0, 0, 0.11);
|
|
75
|
+
--shadow-size-minus: calc(-1 * var(--shadow-size));
|
|
76
|
+
--shadow-top: inset 0px var(--shadow-size) var(--shadow-size) var(--shadow-size-minus) var(--shadow-color);
|
|
77
|
+
--shadow-bottom: inset 0px var(--shadow-size-minus) var(--shadow-size) var(--shadow-size-minus) var(--shadow-color);
|
|
78
|
+
--box-shadow-top: 0 0;
|
|
79
|
+
--box-shadow-bottom: 0 0;
|
|
80
|
+
box-shadow: var(--box-shadow-top), var(--box-shadow-bottom);
|
|
81
|
+
}
|
|
82
|
+
.nav-item-level-3.nav-item-first-of-its-kind {
|
|
83
|
+
padding-top: calc(var(--padding) * 1.8);
|
|
84
|
+
--box-shadow-top: var(--shadow-top);
|
|
85
|
+
}
|
|
86
|
+
.nav-item-level-3.nav-item-last-of-its-kind {
|
|
87
|
+
padding-bottom: calc(var(--padding) * 1.8);
|
|
88
|
+
--box-shadow-bottom: var(--shadow-bottom);
|
|
89
|
+
}
|
|
90
|
+
.nav-item-level-2,
|
|
91
|
+
.nav-item-level-3 {
|
|
92
|
+
position: relative;
|
|
93
|
+
}
|
|
94
|
+
.nav-item-level-2.is-active {
|
|
95
|
+
/* #ededed === rgb(237, 237, 237)
|
|
96
|
+
* #f5f5f5 === rgb(245, 245, 245)
|
|
97
|
+
* 1 - (237 / 245) === 0.03265306122
|
|
98
|
+
background-color: #ededed;
|
|
99
|
+
*/
|
|
100
|
+
background-color: rgba(0,0,0, 0.03265306122);
|
|
101
|
+
}
|
|
@@ -1,92 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export type { NavigationData }
|
|
4
|
-
export type { NavItem }
|
|
5
|
-
|
|
1
|
+
// TODO/refactor: rename file and/or component
|
|
2
|
+
export { NavigationContent }
|
|
6
3
|
// TODO/refactor: do this only on the server side?
|
|
7
|
-
export {
|
|
8
|
-
export type {
|
|
4
|
+
export type { NavItem }
|
|
5
|
+
export type { NavItemAll }
|
|
9
6
|
|
|
10
7
|
import React from 'react'
|
|
11
|
-
import {
|
|
12
|
-
import { assert, Emoji, assertWarning, jsxToTextContent } from '../utils/server'
|
|
8
|
+
import { assert, assertWarning, jsxToTextContent } from '../utils/server'
|
|
13
9
|
import './Navigation.css'
|
|
14
|
-
import { NavigationFullscreenClose } from './navigation-fullscreen/NavigationFullscreenButton'
|
|
15
10
|
import { parseTitle } from '../parseTitle'
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
type NavigationData = Parameters<typeof Navigation>[0]
|
|
19
|
-
|
|
20
|
-
function Navigation({
|
|
21
|
-
navItems,
|
|
22
|
-
navItemsAll,
|
|
23
|
-
currentUrl,
|
|
24
|
-
isDetachedPage,
|
|
25
|
-
}: {
|
|
26
|
-
navItems: NavItem[]
|
|
27
|
-
navItemsAll: NavItem[]
|
|
28
|
-
currentUrl: string
|
|
29
|
-
isDetachedPage: boolean
|
|
30
|
-
}) {
|
|
31
|
-
return (
|
|
32
|
-
<>
|
|
33
|
-
<div id="navigation-container">
|
|
34
|
-
<NavigationHeader />
|
|
35
|
-
<div id="navigation-body">
|
|
36
|
-
{isDetachedPage && (
|
|
37
|
-
<>
|
|
38
|
-
{navItems.length > 1 && (
|
|
39
|
-
<NavigationContent id="navigation-content-detached" navItems={navItems} currentUrl={currentUrl} />
|
|
40
|
-
)}
|
|
41
|
-
<DetachedPageNote />
|
|
42
|
-
</>
|
|
43
|
-
)}
|
|
44
|
-
<NavigationContent id="navigation-content-main" navItems={navItemsAll} currentUrl={currentUrl} />
|
|
45
|
-
<NavigationFullscreenClose />
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
{/* Early scrolling, to avoid flashing */}
|
|
49
|
-
<script dangerouslySetInnerHTML={{ __html: autoScrollNav_SSR }}></script>
|
|
50
|
-
</>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function NavigationMask() {
|
|
55
|
-
return <div id="mobile-navigation-mask" />
|
|
56
|
-
}
|
|
11
|
+
import { usePageContext } from '../renderer/usePageContext'
|
|
12
|
+
import '@docsearch/css'
|
|
57
13
|
|
|
58
14
|
type NavItem = {
|
|
59
15
|
level: number
|
|
60
16
|
url?: string | null
|
|
61
17
|
title: string
|
|
62
18
|
titleInNav: string
|
|
19
|
+
menuModalFullWidth?: true
|
|
63
20
|
}
|
|
64
|
-
type
|
|
65
|
-
|
|
66
|
-
isActiveFirst: boolean
|
|
67
|
-
isActiveLast: boolean
|
|
68
|
-
isFirstOfItsKind: boolean
|
|
69
|
-
isLastOfItsKind: boolean
|
|
21
|
+
type NavItemAll = NavItem & {
|
|
22
|
+
isColumnLayoutElement?: true
|
|
70
23
|
}
|
|
71
|
-
|
|
72
24
|
function NavigationContent(props: {
|
|
73
|
-
id: 'navigation-content-main' | 'navigation-content-detached'
|
|
74
25
|
navItems: NavItem[]
|
|
75
|
-
|
|
26
|
+
showOnlyRelevant?: true
|
|
27
|
+
columnLayout?: true
|
|
76
28
|
}) {
|
|
77
|
-
const
|
|
78
|
-
const
|
|
29
|
+
const pageContext = usePageContext()
|
|
30
|
+
const navItemsWithComputed = getNavItemsWithComputed(props.navItems, pageContext.urlPathname)
|
|
31
|
+
|
|
32
|
+
let navContent: React.ReactNode
|
|
33
|
+
if (!props.columnLayout) {
|
|
34
|
+
navContent = navItemsWithComputed
|
|
35
|
+
.filter((navItemGroup) => !props.showOnlyRelevant || navItemGroup.isRelevant)
|
|
36
|
+
.map((navItem, i) => <NavItemComponent navItem={navItem} key={i} />)
|
|
37
|
+
} else {
|
|
38
|
+
assert(!props.showOnlyRelevant)
|
|
39
|
+
const navItemsColumnLayout = groupByColumnLayout(navItemsWithComputed)
|
|
40
|
+
const paddingBottom = 40
|
|
41
|
+
navContent = (
|
|
42
|
+
<>
|
|
43
|
+
{navItemsColumnLayout.map(({ navItemsColumnEntries, isFullWidth }, i) => (
|
|
44
|
+
<div
|
|
45
|
+
key={i}
|
|
46
|
+
style={{
|
|
47
|
+
display: 'flex',
|
|
48
|
+
justifyContent: 'center',
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<div
|
|
52
|
+
className={`column-layout-${i}`}
|
|
53
|
+
style={{
|
|
54
|
+
flexGrow: 1,
|
|
55
|
+
columnGap: 20,
|
|
56
|
+
paddingBottom: isFullWidth ? paddingBottom : undefined,
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
{navItemsColumnEntries.map((navItemColumnEntry, j) => (
|
|
60
|
+
<div
|
|
61
|
+
key={j}
|
|
62
|
+
className="column-layout-entry"
|
|
63
|
+
style={{
|
|
64
|
+
breakInside: 'avoid',
|
|
65
|
+
paddingBottom: !isFullWidth ? paddingBottom : undefined,
|
|
66
|
+
width: '100%',
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
<NavItemComponent navItem={navItemColumnEntry} />
|
|
70
|
+
{navItemColumnEntry.navItemChilds.map((navItem, k) => (
|
|
71
|
+
<NavItemComponent navItem={navItem} key={k} />
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
))}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
))}
|
|
78
|
+
</>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
79
81
|
|
|
80
82
|
return (
|
|
81
|
-
<div
|
|
82
|
-
{
|
|
83
|
-
<div className="nav-items-group" key={i}>
|
|
84
|
-
<NavItemComponent navItem={navItemGroup} />
|
|
85
|
-
{navItemGroup.navItemChilds.map((navItem, j) => (
|
|
86
|
-
<NavItemComponent navItem={navItem} key={j} />
|
|
87
|
-
))}
|
|
88
|
-
</div>
|
|
89
|
-
))}
|
|
83
|
+
<div className="navigation-content" style={{ marginTop: 10 }}>
|
|
84
|
+
{navContent}
|
|
90
85
|
</div>
|
|
91
86
|
)
|
|
92
87
|
}
|
|
@@ -120,8 +115,6 @@ function NavItemComponent({
|
|
|
120
115
|
'nav-item',
|
|
121
116
|
'nav-item-level-' + navItem.level,
|
|
122
117
|
navItem.url && navItem.isActive && ' is-active',
|
|
123
|
-
navItem.url && navItem.isActiveFirst && ' is-active-first',
|
|
124
|
-
navItem.url && navItem.isActiveLast && ' is-active-last',
|
|
125
118
|
navItem.isFirstOfItsKind && 'nav-item-first-of-its-kind',
|
|
126
119
|
navItem.isLastOfItsKind && 'nav-item-last-of-its-kind',
|
|
127
120
|
]
|
|
@@ -135,86 +128,79 @@ function NavItemComponent({
|
|
|
135
128
|
)
|
|
136
129
|
}
|
|
137
130
|
|
|
138
|
-
type
|
|
139
|
-
function
|
|
140
|
-
const
|
|
141
|
-
|
|
131
|
+
type NavItemsColumnEntry = NavItemComputed & { navItemChilds: NavItemComputed[] }
|
|
132
|
+
function groupByColumnLayout(navItems: NavItemComputed[]) {
|
|
133
|
+
const navItemsColumnLayout: { navItemsColumnEntries: NavItemsColumnEntry[]; isFullWidth: boolean }[] = []
|
|
134
|
+
let navItemsColumnEntries: NavItemsColumnEntry[] = []
|
|
135
|
+
let isFullWidth: boolean | undefined
|
|
142
136
|
navItems.forEach((navItem) => {
|
|
143
|
-
if (navItem.level ===
|
|
144
|
-
|
|
137
|
+
if (navItem.level === 1) {
|
|
138
|
+
const isFullWidthPrevious = isFullWidth
|
|
139
|
+
isFullWidth = !!navItem.menuModalFullWidth
|
|
140
|
+
if (isFullWidthPrevious !== undefined && isFullWidthPrevious !== isFullWidth) {
|
|
141
|
+
navItemsColumnLayout.push({ navItemsColumnEntries, isFullWidth: isFullWidthPrevious })
|
|
142
|
+
navItemsColumnEntries = []
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
assert(isFullWidth !== undefined)
|
|
146
|
+
if (navItem.isColumnLayoutElement) {
|
|
147
|
+
assert(navItem.level === 1 || navItem.level === 4)
|
|
148
|
+
const navItemColumnEntry = { ...navItem, navItemChilds: [] }
|
|
149
|
+
navItemsColumnEntries.push(navItemColumnEntry)
|
|
145
150
|
} else {
|
|
146
|
-
|
|
151
|
+
assert(navItem.level !== 1)
|
|
152
|
+
navItemsColumnEntries[navItemsColumnEntries.length - 1].navItemChilds.push(navItem)
|
|
147
153
|
}
|
|
148
154
|
})
|
|
149
|
-
|
|
155
|
+
assert(isFullWidth !== undefined)
|
|
156
|
+
navItemsColumnLayout.push({ navItemsColumnEntries, isFullWidth })
|
|
157
|
+
return navItemsColumnLayout
|
|
150
158
|
}
|
|
151
159
|
|
|
152
|
-
|
|
153
|
-
|
|
160
|
+
type NavItemComputed = ReturnType<typeof getNavItemsWithComputed>[number]
|
|
161
|
+
function getNavItemsWithComputed(navItems: NavItemAll[], currentUrl: string) {
|
|
162
|
+
let navItemIdx: number | undefined
|
|
163
|
+
const navItemsWithComputed = navItems.map((navItem, i) => {
|
|
154
164
|
assert([1, 2, 3, 4].includes(navItem.level), navItem)
|
|
155
165
|
|
|
156
166
|
const navItemPrevious = navItems[i - 1]
|
|
157
167
|
const navItemNext = navItems[i + 1]
|
|
158
168
|
|
|
159
|
-
let isActiveFirst = false
|
|
160
|
-
let isActiveLast = false
|
|
161
169
|
let isActive = false
|
|
162
170
|
if (navItem.url === currentUrl) {
|
|
163
171
|
assert(navItem.level === 2, { currentUrl })
|
|
172
|
+
assert(navItemIdx === undefined)
|
|
173
|
+
navItemIdx = i
|
|
164
174
|
isActive = true
|
|
165
|
-
isActiveFirst = true
|
|
166
|
-
if (navItemNext?.level !== 3) {
|
|
167
|
-
isActiveLast = true
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (navItem.level === 3) {
|
|
171
|
-
isActive = true
|
|
172
|
-
if (navItemNext?.level !== 3) {
|
|
173
|
-
isActiveLast = true
|
|
174
|
-
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
const isFirstOfItsKind = navItem.level !== navItemPrevious?.level
|
|
178
178
|
const isLastOfItsKind = navItem.level !== navItemNext?.level
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
const navItemComputed = {
|
|
181
181
|
...navItem,
|
|
182
182
|
isActive,
|
|
183
|
-
|
|
184
|
-
isActiveLast,
|
|
183
|
+
isRelevant: false,
|
|
185
184
|
isFirstOfItsKind,
|
|
186
185
|
isLastOfItsKind,
|
|
187
186
|
}
|
|
187
|
+
|
|
188
|
+
return navItemComputed
|
|
188
189
|
})
|
|
189
|
-
}
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
<Emoji name="info" />{' '}
|
|
207
|
-
<b>
|
|
208
|
-
<em>Detached</em>
|
|
209
|
-
</b>
|
|
210
|
-
<span
|
|
211
|
-
style={{
|
|
212
|
-
opacity: 0.8,
|
|
213
|
-
}}
|
|
214
|
-
>
|
|
215
|
-
{' '}
|
|
216
|
-
— this page isn't listed in the navigation below.
|
|
217
|
-
</span>
|
|
218
|
-
</div>
|
|
219
|
-
)
|
|
191
|
+
// Set `isRelevant`
|
|
192
|
+
if (navItemIdx !== undefined) {
|
|
193
|
+
for (let i = navItemIdx; i >= 0; i--) {
|
|
194
|
+
const navItem = navItemsWithComputed[i]!
|
|
195
|
+
navItem.isRelevant = true
|
|
196
|
+
if (navItem.level === 1) break
|
|
197
|
+
}
|
|
198
|
+
for (let i = navItemIdx; i < navItemsWithComputed.length; i++) {
|
|
199
|
+
const navItem = navItemsWithComputed[i]!
|
|
200
|
+
if (navItem.level === 1) break
|
|
201
|
+
navItem.isRelevant = true
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return navItemsWithComputed
|
|
220
206
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brillout/docpress",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@brillout/picocolors": "^1.0.10",
|
|
@@ -33,10 +33,6 @@
|
|
|
33
33
|
"./renderer/onBeforeRender": "./renderer/onBeforeRender.ts",
|
|
34
34
|
"./Layout": "./Layout.tsx",
|
|
35
35
|
".": "./index.ts",
|
|
36
|
-
"./FeatureList/FeatureList": "./components/FeatureList/FeatureList.tsx",
|
|
37
|
-
"./FeatureList/FeatureList.client": {
|
|
38
|
-
"browser": "./components/FeatureList/FeatureList.client.ts"
|
|
39
|
-
},
|
|
40
36
|
"./vite-config": "./dist/vite.config.js",
|
|
41
37
|
"./config": "./dist/+config.js",
|
|
42
38
|
"./style": "./css/index.css",
|
|
@@ -57,9 +53,6 @@
|
|
|
57
53
|
],
|
|
58
54
|
"config": [
|
|
59
55
|
"./dist/+config.d.ts"
|
|
60
|
-
],
|
|
61
|
-
"FeatureList/*": [
|
|
62
|
-
"./components/FeatureList/*"
|
|
63
56
|
]
|
|
64
57
|
}
|
|
65
58
|
},
|
|
@@ -4,22 +4,34 @@ import type { PageContext } from 'vike/types'
|
|
|
4
4
|
import type { PageContextResolved } from '../config/resolvePageContext'
|
|
5
5
|
import { PageContextProvider, PageContextProvider2 } from './usePageContext'
|
|
6
6
|
import React from 'react'
|
|
7
|
+
import { DocSearchInstall } from '../docsearch/DocSearchInstall'
|
|
7
8
|
|
|
8
9
|
function getPageElement(pageContext: PageContext, pageContextResolved: PageContextResolved) {
|
|
9
10
|
const { Page } = pageContext
|
|
10
|
-
const
|
|
11
|
+
const Layout = pageContext.config.Layout || PassThrough
|
|
11
12
|
const page = (
|
|
13
|
+
<Wrapper {...{ pageContext, pageContextResolved }}>
|
|
14
|
+
<Layout pageContext={pageContextResolved} pageContext2={pageContext}>
|
|
15
|
+
<Page />
|
|
16
|
+
</Layout>
|
|
17
|
+
<DocSearchInstall />
|
|
18
|
+
</Wrapper>
|
|
19
|
+
)
|
|
20
|
+
return page
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function Wrapper({
|
|
24
|
+
children,
|
|
25
|
+
pageContext,
|
|
26
|
+
pageContextResolved,
|
|
27
|
+
}: { children: React.ReactNode; pageContext: PageContext; pageContextResolved: PageContextResolved }) {
|
|
28
|
+
return (
|
|
12
29
|
<React.StrictMode>
|
|
13
30
|
<PageContextProvider2 pageContext={pageContext}>
|
|
14
|
-
<PageContextProvider pageContext={pageContextResolved}>
|
|
15
|
-
<Layout pageContext={pageContextResolved} pageContext2={pageContext}>
|
|
16
|
-
<Page />
|
|
17
|
-
</Layout>
|
|
18
|
-
</PageContextProvider>
|
|
31
|
+
<PageContextProvider pageContext={pageContextResolved}>{children}</PageContextProvider>
|
|
19
32
|
</PageContextProvider2>
|
|
20
33
|
</React.StrictMode>
|
|
21
34
|
)
|
|
22
|
-
return page
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
function PassThrough({ children }: any) {
|