@brillout/docpress 0.9.8 → 0.10.0
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/Layout.tsx +102 -40
- package/{navigation → MenuModal}/Collapsible.css +7 -0
- package/MenuModal/NavigationWithColumnLayout.css +11 -0
- package/MenuModal/NavigationWithColumnLayout.tsx +253 -0
- package/MenuModal/toggleMenuModal.ts +132 -0
- package/MenuModal.tsx +68 -79
- package/{navigation/Navigation.css → NavItemComponent.css} +1 -23
- package/NavItemComponent.tsx +149 -0
- package/components/Note.css +0 -1
- package/config/resolveHeadingsData.ts +1 -1
- package/css/code/diff.css +10 -5
- package/css/code.css +1 -1
- package/css/colorize-on-hover.css +6 -7
- package/css/heading.css +9 -3
- package/css/index.css +1 -0
- package/dist/NavItemComponent.d.ts +39 -0
- package/dist/NavItemComponent.js +109 -0
- package/dist/config/resolveHeadingsData.d.ts +1 -1
- package/dist/config/resolvePageContext.d.ts +2 -2
- package/dist/renderer/determineNavItemsColumnLayout.d.ts +1 -1
- package/docsearch/SearchLink.tsx +7 -3
- package/icons/books.svg +46 -0
- package/icons/gear.svg +35 -0
- package/icons/index.ts +5 -0
- package/icons/magnifying-glass.svg +31 -0
- package/icons/seedling.svg +24 -0
- package/index.ts +2 -0
- package/initKeyBindings.ts +1 -1
- package/package.json +1 -1
- package/renderer/determineNavItemsColumnLayout.ts +1 -1
- package/renderer/initOnNavigation.ts +1 -1
- package/renderer/onRenderClient.tsx +1 -1
- package/utils/css.ts +0 -6
- package/dist/Layout.d.ts +0 -15
- package/dist/Layout.js +0 -321
- package/dist/MenuModal.d.ts +0 -13
- package/dist/MenuModal.js +0 -124
- package/dist/NavSecondaryContent.d.ts +0 -6
- package/dist/NavSecondaryContent.js +0 -57
- package/dist/autoScrollNav.d.ts +0 -3
- package/dist/autoScrollNav.js +0 -35
- package/dist/components/EditPageNote.d.ts +0 -7
- package/dist/components/EditPageNote.js +0 -11
- package/dist/docsearch/SearchLink.d.ts +0 -4
- package/dist/docsearch/SearchLink.js +0 -25
- package/dist/docsearch/toggleDocsearchModal.d.ts +0 -4
- package/dist/docsearch/toggleDocsearchModal.js +0 -26
- package/dist/navigation/Collapsible.d.ts +0 -10
- package/dist/navigation/Collapsible.js +0 -35
- package/dist/navigation/Navigation.d.ts +0 -21
- package/dist/navigation/Navigation.js +0 -255
- package/dist/utils/PassTrough.d.ts +0 -3
- package/dist/utils/PassTrough.js +0 -6
- package/dist/utils/Style.d.ts +0 -5
- package/dist/utils/Style.js +0 -6
- package/dist/utils/css.d.ts +0 -1
- package/dist/utils/css.js +0 -27
- package/dist/utils/getViewportWidth.d.ts +0 -1
- package/dist/utils/getViewportWidth.js +0 -4
- package/dist/utils/throttle.d.ts +0 -1
- package/dist/utils/throttle.js +0 -14
- package/navigation/Navigation.tsx +0 -382
- /package/{navigation → MenuModal}/Collapsible.tsx +0 -0
package/MenuModal.tsx
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
export { MenuModal }
|
|
2
|
-
export { toggleMenuModal }
|
|
3
|
-
export { openMenuModal }
|
|
4
|
-
export { closeMenuModal }
|
|
5
|
-
export { closeMenuModalWithDelay }
|
|
6
2
|
|
|
7
|
-
import React from 'react'
|
|
3
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
8
4
|
import { usePageContext } from './renderer/usePageContext'
|
|
9
|
-
import { NavigationContent } from './navigation/Navigation'
|
|
10
5
|
import { css } from './utils/css'
|
|
11
|
-
import { containerQueryMobileLayout, containerQueryMobileMenu } from './Layout'
|
|
6
|
+
import { blockMargin, containerQueryMobileLayout, containerQueryMobileMenu } from './Layout'
|
|
12
7
|
import { NavSecondaryContent } from './NavSecondaryContent'
|
|
13
|
-
import { getViewportWidth } from './utils/getViewportWidth'
|
|
14
8
|
import { Style } from './utils/Style'
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
import { NavigationWithColumnLayout } from './MenuModal/NavigationWithColumnLayout'
|
|
10
|
+
import { addListenerOpenMenuModal, closeMenuModal, openMenuModal } from './MenuModal/toggleMenuModal'
|
|
17
11
|
|
|
18
12
|
function MenuModal({ isTopNav }: { isTopNav: boolean }) {
|
|
13
|
+
const ref = useRef<HTMLDivElement>(null)
|
|
14
|
+
const [height, setHeight] = useState<number | undefined>(undefined)
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const updateHeight = () => {
|
|
17
|
+
const { scrollHeight } = ref!.current!.querySelector('.navigation-content')!
|
|
18
|
+
if (height !== scrollHeight) setHeight(scrollHeight + blockMargin)
|
|
19
|
+
}
|
|
20
|
+
addListenerOpenMenuModal(updateHeight)
|
|
21
|
+
updateHeight()
|
|
22
|
+
})
|
|
19
23
|
return (
|
|
20
24
|
<>
|
|
21
25
|
<Style>{getStyle()}</Style>
|
|
@@ -25,51 +29,56 @@ function MenuModal({ isTopNav }: { isTopNav: boolean }) {
|
|
|
25
29
|
style={{
|
|
26
30
|
position: isTopNav ? 'absolute' : 'fixed',
|
|
27
31
|
width: '100%',
|
|
28
|
-
/* Firefox doesn't support `dvh` yet: https://caniuse.com/?search=dvh
|
|
29
|
-
* - Always use `dvh` instead of `vh` once Firefox supports it.
|
|
30
|
-
* - We use dvh because of mobile: https://stackoverflow.com/questions/37112218/css3-100vh-not-constant-in-mobile-browser/72245072#72245072
|
|
31
|
-
height: 'calc(100dvh - var(--nav-head-height))',
|
|
32
|
-
/*/
|
|
33
|
-
height: 'calc(100vh - var(--nav-head-height))',
|
|
34
|
-
maxHeight: 'calc(100dvh - var(--nav-head-height))',
|
|
35
|
-
//*/
|
|
36
32
|
top: 'var(--nav-head-height)',
|
|
37
33
|
left: 0,
|
|
38
34
|
zIndex: 9999,
|
|
39
|
-
|
|
35
|
+
overflowY: 'scroll',
|
|
40
36
|
background: '#ededef',
|
|
41
|
-
transitionProperty: '
|
|
37
|
+
transitionProperty: 'height',
|
|
38
|
+
transitionTimingFunction: 'ease',
|
|
42
39
|
// https://github.com/brillout/docpress/issues/23
|
|
43
40
|
// https://stackoverflow.com/questions/64514118/css-overscroll-behavior-contain-when-target-element-doesnt-overflow
|
|
44
41
|
// https://stackoverflow.com/questions/9538868/prevent-body-from-scrolling-when-a-modal-is-opened
|
|
45
42
|
overscrollBehavior: 'none',
|
|
43
|
+
height,
|
|
46
44
|
}}
|
|
47
|
-
|
|
45
|
+
ref={ref}
|
|
46
|
+
onMouseOver={() => openMenuModal()}
|
|
48
47
|
onMouseLeave={closeMenuModal}
|
|
49
48
|
>
|
|
50
49
|
<div
|
|
51
50
|
style={{
|
|
52
|
-
// Place <
|
|
51
|
+
// Place <NavSecondary /> to the bottom
|
|
53
52
|
display: 'flex',
|
|
54
53
|
flexDirection: 'column',
|
|
55
|
-
minHeight: 'calc(100dvh - var(--nav-head-height))',
|
|
56
54
|
justifyContent: 'space-between',
|
|
57
|
-
|
|
55
|
+
minHeight: '100%',
|
|
56
|
+
position: 'relative',
|
|
57
|
+
// We don't set `container` to the parent #menu-modal beacuse of a Chrome bug (showing a blank <MenuModal>)
|
|
58
58
|
container: 'container-viewport / inline-size',
|
|
59
59
|
}}
|
|
60
60
|
>
|
|
61
61
|
<Nav />
|
|
62
62
|
<NavSecondary className="show-only-for-mobile" />
|
|
63
|
+
<BorderBottom />
|
|
63
64
|
</div>
|
|
64
65
|
<CloseButton className="show-only-for-mobile" />
|
|
65
66
|
</div>
|
|
66
67
|
</>
|
|
67
68
|
)
|
|
68
69
|
}
|
|
70
|
+
function BorderBottom() {
|
|
71
|
+
return (
|
|
72
|
+
<div
|
|
73
|
+
id="border-bottom"
|
|
74
|
+
style={{ position: 'absolute', background: '#fff', height: 'var(--block-margin)', width: '100%', bottom: 0 }}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
69
78
|
function Nav() {
|
|
70
79
|
const pageContext = usePageContext()
|
|
71
80
|
const navItems = pageContext.navItemsAll
|
|
72
|
-
return <
|
|
81
|
+
return <NavigationWithColumnLayout navItems={navItems} />
|
|
73
82
|
}
|
|
74
83
|
function NavSecondary({ className }: { className: string }) {
|
|
75
84
|
return (
|
|
@@ -78,7 +87,7 @@ function NavSecondary({ className }: { className: string }) {
|
|
|
78
87
|
style={{
|
|
79
88
|
display: 'flex',
|
|
80
89
|
justifyContent: 'center',
|
|
81
|
-
marginTop:
|
|
90
|
+
marginTop: 10,
|
|
82
91
|
}}
|
|
83
92
|
>
|
|
84
93
|
<NavSecondaryContent style={{ height: 70 }} />
|
|
@@ -88,23 +97,45 @@ function NavSecondary({ className }: { className: string }) {
|
|
|
88
97
|
|
|
89
98
|
function getStyle() {
|
|
90
99
|
return css`
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
@media(min-width: ${containerQueryMobileMenu + 1}px) {
|
|
101
|
+
#menu-modal {
|
|
102
|
+
${/* Firefox doesn't support `dvh` yet: https://caniuse.com/?search=dvh */ ''}
|
|
103
|
+
${/* Let's always use `dvh` instead of `vh` once Firefox supports it */ ''}
|
|
104
|
+
max-height: calc(100vh - var(--nav-head-height));
|
|
105
|
+
${/* We use dvh because of mobile */ ''}
|
|
106
|
+
${/* https://stackoverflow.com/questions/37112218/css3-100vh-not-constant-in-mobile-browser/72245072#72245072 */ ''}
|
|
107
|
+
max-height: calc(100dvh - var(--nav-head-height));
|
|
108
|
+
}
|
|
109
|
+
html:not(.menu-modal-show) #menu-modal {
|
|
110
|
+
height: 0 !important;
|
|
111
|
+
}
|
|
112
|
+
.show-only-for-mobile {
|
|
113
|
+
display: none !important;
|
|
98
114
|
}
|
|
99
115
|
}
|
|
100
116
|
@media(max-width: ${containerQueryMobileMenu}px) {
|
|
117
|
+
#menu-modal {
|
|
118
|
+
height: calc(100vh) !important;
|
|
119
|
+
height: calc(100dvh) !important;
|
|
120
|
+
}
|
|
121
|
+
#border-bottom {
|
|
122
|
+
display: none;
|
|
123
|
+
}
|
|
124
|
+
html:not(.menu-modal-show) #menu-modal {
|
|
125
|
+
opacity: 0;
|
|
126
|
+
pointer-events: none;
|
|
127
|
+
}
|
|
128
|
+
${/* Disable scrolling of main view */ ''}
|
|
129
|
+
html.menu-modal-show {
|
|
130
|
+
overflow: hidden !important;
|
|
131
|
+
}
|
|
101
132
|
#menu-modal {
|
|
102
133
|
--nav-head-height: 0px !important;
|
|
103
134
|
}
|
|
104
135
|
}
|
|
105
|
-
@
|
|
106
|
-
.
|
|
107
|
-
display: none
|
|
136
|
+
@container container-viewport (min-width: ${containerQueryMobileLayout}px) {
|
|
137
|
+
#menu-modal .nav-item-level-3 {
|
|
138
|
+
display: none;
|
|
108
139
|
}
|
|
109
140
|
}
|
|
110
141
|
`
|
|
@@ -114,7 +145,7 @@ function CloseButton({ className }: { className: string }) {
|
|
|
114
145
|
return (
|
|
115
146
|
<div
|
|
116
147
|
className={className}
|
|
117
|
-
onClick={
|
|
148
|
+
onClick={closeMenuModal}
|
|
118
149
|
style={{ position: 'fixed', top: 0, right: 0, zIndex: 10, padding: 11, cursor: 'pointer' }}
|
|
119
150
|
aria-label={'Escape\nCtrl\xa0+\xa0M'}
|
|
120
151
|
data-label-shift
|
|
@@ -142,45 +173,3 @@ function CloseButton({ className }: { className: string }) {
|
|
|
142
173
|
</div>
|
|
143
174
|
)
|
|
144
175
|
}
|
|
145
|
-
|
|
146
|
-
function toggleMenuModal() {
|
|
147
|
-
document.documentElement.classList.toggle('menu-modal-show')
|
|
148
|
-
if (
|
|
149
|
-
document.documentElement.classList.contains('menu-modal-show') &&
|
|
150
|
-
getViewportWidth() < containerQueryMobileLayout
|
|
151
|
-
) {
|
|
152
|
-
autoScroll()
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function autoScroll() {
|
|
156
|
-
const nav = document.querySelector('#menu-modal .navigation-content')!
|
|
157
|
-
const href = window.location.pathname
|
|
158
|
-
const navLinks = Array.from(nav.querySelectorAll(`a[href="${href}"]`))
|
|
159
|
-
const navLink = navLinks[0] as HTMLElement | undefined
|
|
160
|
-
if (!navLink) return
|
|
161
|
-
// None of the following seemes to be working: https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom
|
|
162
|
-
if (findCollapsibleEl(navLink)!.classList.contains('collapsible-collapsed')) return
|
|
163
|
-
navLink.scrollIntoView({
|
|
164
|
-
behavior: 'instant',
|
|
165
|
-
block: 'center',
|
|
166
|
-
inline: 'start',
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
|
-
function findCollapsibleEl(navLink: HTMLElement | undefined) {
|
|
170
|
-
let parentEl: HTMLElement | null | undefined = navLink
|
|
171
|
-
while (parentEl) {
|
|
172
|
-
if (parentEl.classList.contains('collapsible')) return parentEl
|
|
173
|
-
parentEl = parentEl.parentElement
|
|
174
|
-
}
|
|
175
|
-
return null
|
|
176
|
-
}
|
|
177
|
-
function openMenuModal() {
|
|
178
|
-
clearTimeout(closeMenuModalPending)
|
|
179
|
-
document.documentElement.classList.add('menu-modal-show')
|
|
180
|
-
}
|
|
181
|
-
function closeMenuModal() {
|
|
182
|
-
document.documentElement.classList.remove('menu-modal-show')
|
|
183
|
-
}
|
|
184
|
-
function closeMenuModalWithDelay(delay: number) {
|
|
185
|
-
closeMenuModalPending = setTimeout(closeMenuModal, delay)
|
|
186
|
-
}
|
|
@@ -93,27 +93,5 @@
|
|
|
93
93
|
top: 0;
|
|
94
94
|
left: 0;
|
|
95
95
|
z-index: 1;
|
|
96
|
-
content:
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
:has(> .category-border) {
|
|
100
|
-
position: relative
|
|
101
|
-
}
|
|
102
|
-
.category-border {
|
|
103
|
-
position: absolute;
|
|
104
|
-
top: 0;
|
|
105
|
-
left: 0;
|
|
106
|
-
height: 100%;
|
|
107
|
-
width: 3px;
|
|
108
|
-
z-index: 99;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
:has(> .collapsible-icon) {
|
|
112
|
-
position: relative;
|
|
113
|
-
}
|
|
114
|
-
.collapsible-icon {
|
|
115
|
-
position: absolute;
|
|
116
|
-
top: calc(100% / 2 - 6px);
|
|
117
|
-
margin-left: 9px;
|
|
118
|
-
vertical-align: middle;
|
|
96
|
+
content: '';
|
|
119
97
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export { NavItemComponent }
|
|
2
|
+
export { getNavItemsWithComputed }
|
|
3
|
+
export type { NavItem }
|
|
4
|
+
export type { NavItemComputed }
|
|
5
|
+
export type { ColumnMap }
|
|
6
|
+
|
|
7
|
+
import React from 'react'
|
|
8
|
+
import { assert, assertWarning, jsxToTextContent } from './utils/server'
|
|
9
|
+
import './NavItemComponent.css'
|
|
10
|
+
import { parseTitle } from './parseTitle'
|
|
11
|
+
import './global.d.ts'
|
|
12
|
+
|
|
13
|
+
type NavItemComputed = ReturnType<typeof getNavItemsWithComputed>[number]
|
|
14
|
+
type NavItem = {
|
|
15
|
+
level: number
|
|
16
|
+
url?: string | null
|
|
17
|
+
color?: string
|
|
18
|
+
title: string
|
|
19
|
+
titleInNav: string
|
|
20
|
+
menuModalFullWidth?: true
|
|
21
|
+
isColumnEntry?: ColumnMap
|
|
22
|
+
}
|
|
23
|
+
type ColumnMap = Record<number, number>
|
|
24
|
+
|
|
25
|
+
type PropsNavItem = PropsAnchor & PropsSpan
|
|
26
|
+
type PropsAnchor = React.HTMLProps<HTMLAnchorElement>
|
|
27
|
+
type PropsSpan = React.HTMLProps<HTMLSpanElement>
|
|
28
|
+
function NavItemComponent({
|
|
29
|
+
navItem,
|
|
30
|
+
onClick,
|
|
31
|
+
}: {
|
|
32
|
+
navItem: NavItemComputed
|
|
33
|
+
onClick?: PropsNavItem['onClick']
|
|
34
|
+
}) {
|
|
35
|
+
assert([1, 2, 3, 4].includes(navItem.level), navItem)
|
|
36
|
+
|
|
37
|
+
const titleJsx = parseTitle(navItem.title)
|
|
38
|
+
const titleInNavJsx = parseTitle(navItem.titleInNav)
|
|
39
|
+
|
|
40
|
+
if (navItem.level === 1 || navItem.level === 4) {
|
|
41
|
+
assert(navItem.url === undefined)
|
|
42
|
+
} else {
|
|
43
|
+
const sectionTitle = jsxToTextContent(titleJsx)
|
|
44
|
+
assertWarning(
|
|
45
|
+
navItem.url,
|
|
46
|
+
[
|
|
47
|
+
`${jsxToTextContent(titleInNavJsx)} is missing a URL hash.`,
|
|
48
|
+
`Add a URL hash with: \`## ${sectionTitle}{#some-hash}\`.`,
|
|
49
|
+
/* TODO/eventually: not implemented yet.
|
|
50
|
+
`Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`,
|
|
51
|
+
*/
|
|
52
|
+
].join(' '),
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let children: JSX.Element = titleInNavJsx
|
|
57
|
+
if (navItem.level === 1) {
|
|
58
|
+
children = (
|
|
59
|
+
<>
|
|
60
|
+
{children}
|
|
61
|
+
<Chevron className="collapsible-icon" height={9} />
|
|
62
|
+
</>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const props: PropsNavItem = {
|
|
67
|
+
href: navItem.url ?? undefined,
|
|
68
|
+
children,
|
|
69
|
+
onClick,
|
|
70
|
+
className: [
|
|
71
|
+
'nav-item',
|
|
72
|
+
'nav-item-level-' + navItem.level,
|
|
73
|
+
navItem.url && navItem.isActive && ' is-active',
|
|
74
|
+
navItem.isFirstOfItsKind && 'nav-item-first-of-its-kind',
|
|
75
|
+
navItem.isLastOfItsKind && 'nav-item-last-of-its-kind',
|
|
76
|
+
]
|
|
77
|
+
.filter(Boolean)
|
|
78
|
+
.join(' '),
|
|
79
|
+
}
|
|
80
|
+
if (navItem.level === 1) {
|
|
81
|
+
props.style = {
|
|
82
|
+
['--category-color']: navItem.color!,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (navItem.level === 2 || navItem.level === 3) {
|
|
87
|
+
return <a {...props} />
|
|
88
|
+
} else {
|
|
89
|
+
return <span {...props} />
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getNavItemsWithComputed(navItems: NavItem[], currentUrl: string) {
|
|
94
|
+
let navItemIdx: number | undefined
|
|
95
|
+
const navItemsWithComputed = navItems.map((navItem, i) => {
|
|
96
|
+
assert([1, 2, 3, 4].includes(navItem.level), navItem)
|
|
97
|
+
|
|
98
|
+
const navItemPrevious = navItems[i - 1]
|
|
99
|
+
const navItemNext = navItems[i + 1]
|
|
100
|
+
|
|
101
|
+
let isActive = false
|
|
102
|
+
if (navItem.url === currentUrl) {
|
|
103
|
+
assert(navItem.level === 2, { currentUrl })
|
|
104
|
+
assert(navItemIdx === undefined)
|
|
105
|
+
navItemIdx = i
|
|
106
|
+
isActive = true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const isFirstOfItsKind = navItem.level !== navItemPrevious?.level
|
|
110
|
+
const isLastOfItsKind = navItem.level !== navItemNext?.level
|
|
111
|
+
|
|
112
|
+
const navItemComputed = {
|
|
113
|
+
...navItem,
|
|
114
|
+
isActive,
|
|
115
|
+
isRelevant: false,
|
|
116
|
+
isFirstOfItsKind,
|
|
117
|
+
isLastOfItsKind,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return navItemComputed
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Set `isRelevant`
|
|
124
|
+
if (navItemIdx !== undefined) {
|
|
125
|
+
for (let i = navItemIdx; i >= 0; i--) {
|
|
126
|
+
const navItem = navItemsWithComputed[i]!
|
|
127
|
+
navItem.isRelevant = true
|
|
128
|
+
if (navItem.level === 1) break
|
|
129
|
+
}
|
|
130
|
+
for (let i = navItemIdx; i < navItemsWithComputed.length; i++) {
|
|
131
|
+
const navItem = navItemsWithComputed[i]!
|
|
132
|
+
if (navItem.level === 1) break
|
|
133
|
+
navItem.isRelevant = true
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return navItemsWithComputed
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function Chevron(props: React.HTMLProps<SVGSVGElement>) {
|
|
141
|
+
return (
|
|
142
|
+
<svg viewBox="0 0 512 292.52" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
143
|
+
<path
|
|
144
|
+
fill="#aaa"
|
|
145
|
+
d="M10.725 82.42L230.125 261.82c6.8 6.8 16.2 10.7 25.9 10.7s19.1-3.9 25.9-10.7l219.4-179.4c14.3-14.3 14.3-37.4 0-51.7s-37.4-14.3-51.7 0l-193.6 153.6-193.6-153.6c-14.3-14.3-37.4-14.3-51.7 0s-14.3 37.5 0 51.7z"
|
|
146
|
+
/>
|
|
147
|
+
</svg>
|
|
148
|
+
)
|
|
149
|
+
}
|
package/components/Note.css
CHANGED
|
@@ -46,7 +46,6 @@ blockquote.custom-icon > .blockquote-content > :first-child {
|
|
|
46
46
|
/*** Icon Positioning ***/
|
|
47
47
|
/************************/
|
|
48
48
|
blockquote > p:first-child::before,
|
|
49
|
-
/* blockquote > p:first-of-type::before, */
|
|
50
49
|
blockquote > div.paragraph:first-child::before {
|
|
51
50
|
font-family: emoji;
|
|
52
51
|
content: 'ℹ️';
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
} from '../types/Heading'
|
|
10
10
|
import type { Config } from '../types/Config'
|
|
11
11
|
import { getConfig } from './getConfig'
|
|
12
|
-
import type { NavItem } from '../
|
|
12
|
+
import type { NavItem } from '../NavItemComponent'
|
|
13
13
|
import type { LinkData } from '../components'
|
|
14
14
|
import type { Exports, PageContextOriginal } from './resolvePageContext'
|
|
15
15
|
import pc from '@brillout/picocolors'
|
package/css/code/diff.css
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
pre.has-diff .diff.remove,
|
|
4
4
|
/* For <FileRemoved> */
|
|
5
|
-
|
|
5
|
+
/* biome-ignore format: */
|
|
6
|
+
.diff-entire-file-removed code {
|
|
6
7
|
background-color: #fbdcda !important;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
pre.has-diff .diff.add,
|
|
10
11
|
/* For <FileAdded> */
|
|
11
|
-
|
|
12
|
+
/* biome-ignore format: */
|
|
13
|
+
.diff-entire-file-added code {
|
|
12
14
|
background-color: #d7ecdf !important;
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -19,14 +21,16 @@ pre.has-diff [data-line].diff,
|
|
|
19
21
|
|
|
20
22
|
pre.has-diff .diff::before,
|
|
21
23
|
/* For <FileRemoved> / <FileAdded> */
|
|
22
|
-
|
|
24
|
+
/* biome-ignore format: */
|
|
25
|
+
.diff-entire-file [data-line]::before {
|
|
23
26
|
position: absolute;
|
|
24
27
|
font-weight: 500;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
pre.has-diff .diff.add::before,
|
|
28
31
|
/* For <FileAdded> */
|
|
29
|
-
|
|
32
|
+
/* biome-ignore format: */
|
|
33
|
+
.diff-entire-file-added [data-line]::before {
|
|
30
34
|
content: '+';
|
|
31
35
|
color: #89d189;
|
|
32
36
|
font-size: 1.2em;
|
|
@@ -36,7 +40,8 @@ pre.has-diff .diff.add::before,
|
|
|
36
40
|
|
|
37
41
|
pre.has-diff .diff.remove::before,
|
|
38
42
|
/* For <FileRemoved> */
|
|
39
|
-
|
|
43
|
+
/* biome-ignore format: */
|
|
44
|
+
.diff-entire-file-removed [data-line]::before {
|
|
40
45
|
content: '-';
|
|
41
46
|
color: #f18383;
|
|
42
47
|
font-size: 1.4em;
|
package/css/code.css
CHANGED
|
@@ -4,14 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
@media (hover: hover) and (pointer: fine) {
|
|
6
6
|
.colorize-on-hover:hover [class^='decolorize-'],
|
|
7
|
-
.colorize-on-hover:hover [class*=' decolorize-']
|
|
8
|
-
html.menu-modal-show .menu-toggle [class^='decolorize-'],
|
|
9
|
-
html.menu-modal-show .menu-toggle [class*=' decolorize-'] {
|
|
7
|
+
.colorize-on-hover:hover [class*=' decolorize-'] {
|
|
10
8
|
filter: grayscale(0) opacity(1) !important;
|
|
11
9
|
}
|
|
12
|
-
.link-hover-animation a:hover
|
|
13
|
-
.link-hover-animation .menu-toggle:hover,
|
|
14
|
-
html.menu-modal-show .menu-toggle {
|
|
10
|
+
.link-hover-animation a:hover {
|
|
15
11
|
color: black !important;
|
|
16
12
|
background-color: var(--active-color);
|
|
17
13
|
}
|
|
@@ -26,13 +22,16 @@
|
|
|
26
22
|
}
|
|
27
23
|
[class^='decolorize-'],
|
|
28
24
|
[class*=' decolorize-'] {
|
|
29
|
-
transition-property: filter;
|
|
25
|
+
transition-property: filter, opacity !important;
|
|
30
26
|
}
|
|
31
27
|
.link-hover-animation a,
|
|
32
28
|
.menu-toggle {
|
|
33
29
|
transition-property: color, background-color !important;
|
|
34
30
|
}
|
|
35
31
|
|
|
32
|
+
.decolorize-8 {
|
|
33
|
+
filter: grayscale(1) opacity(0.8);
|
|
34
|
+
}
|
|
36
35
|
.decolorize-7 {
|
|
37
36
|
filter: grayscale(1) opacity(0.7);
|
|
38
37
|
}
|
package/css/heading.css
CHANGED
package/css/index.css
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export { NavItemComponent };
|
|
2
|
+
export { getNavItemsWithComputed };
|
|
3
|
+
export type { NavItem };
|
|
4
|
+
export type { NavItemComputed };
|
|
5
|
+
export type { ColumnMap };
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import './NavItemComponent.css';
|
|
8
|
+
import './global.d.ts';
|
|
9
|
+
type NavItemComputed = ReturnType<typeof getNavItemsWithComputed>[number];
|
|
10
|
+
type NavItem = {
|
|
11
|
+
level: number;
|
|
12
|
+
url?: string | null;
|
|
13
|
+
color?: string;
|
|
14
|
+
title: string;
|
|
15
|
+
titleInNav: string;
|
|
16
|
+
menuModalFullWidth?: true;
|
|
17
|
+
isColumnEntry?: ColumnMap;
|
|
18
|
+
};
|
|
19
|
+
type ColumnMap = Record<number, number>;
|
|
20
|
+
type PropsNavItem = PropsAnchor & PropsSpan;
|
|
21
|
+
type PropsAnchor = React.HTMLProps<HTMLAnchorElement>;
|
|
22
|
+
type PropsSpan = React.HTMLProps<HTMLSpanElement>;
|
|
23
|
+
declare function NavItemComponent({ navItem, onClick, }: {
|
|
24
|
+
navItem: NavItemComputed;
|
|
25
|
+
onClick?: PropsNavItem['onClick'];
|
|
26
|
+
}): React.JSX.Element;
|
|
27
|
+
declare function getNavItemsWithComputed(navItems: NavItem[], currentUrl: string): {
|
|
28
|
+
isActive: boolean;
|
|
29
|
+
isRelevant: boolean;
|
|
30
|
+
isFirstOfItsKind: boolean;
|
|
31
|
+
isLastOfItsKind: boolean;
|
|
32
|
+
level: number;
|
|
33
|
+
url?: string | null;
|
|
34
|
+
color?: string;
|
|
35
|
+
title: string;
|
|
36
|
+
titleInNav: string;
|
|
37
|
+
menuModalFullWidth?: true;
|
|
38
|
+
isColumnEntry?: ColumnMap;
|
|
39
|
+
}[];
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
export { NavItemComponent };
|
|
13
|
+
export { getNavItemsWithComputed };
|
|
14
|
+
import React from 'react';
|
|
15
|
+
import { assert, assertWarning, jsxToTextContent } from './utils/server';
|
|
16
|
+
import './NavItemComponent.css';
|
|
17
|
+
import { parseTitle } from './parseTitle';
|
|
18
|
+
import './global.d.ts';
|
|
19
|
+
function NavItemComponent(_a) {
|
|
20
|
+
var _b;
|
|
21
|
+
var _c;
|
|
22
|
+
var navItem = _a.navItem, onClick = _a.onClick;
|
|
23
|
+
assert([1, 2, 3, 4].includes(navItem.level), navItem);
|
|
24
|
+
var titleJsx = parseTitle(navItem.title);
|
|
25
|
+
var titleInNavJsx = parseTitle(navItem.titleInNav);
|
|
26
|
+
if (navItem.level === 1 || navItem.level === 4) {
|
|
27
|
+
assert(navItem.url === undefined);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
var sectionTitle = jsxToTextContent(titleJsx);
|
|
31
|
+
assertWarning(navItem.url, [
|
|
32
|
+
"".concat(jsxToTextContent(titleInNavJsx), " is missing a URL hash."),
|
|
33
|
+
"Add a URL hash with: `## ".concat(sectionTitle, "{#some-hash}`."),
|
|
34
|
+
/* TODO/eventually: not implemented yet.
|
|
35
|
+
`Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`,
|
|
36
|
+
*/
|
|
37
|
+
].join(' '));
|
|
38
|
+
}
|
|
39
|
+
var children = titleInNavJsx;
|
|
40
|
+
if (navItem.level === 1) {
|
|
41
|
+
children = (React.createElement(React.Fragment, null,
|
|
42
|
+
children,
|
|
43
|
+
React.createElement(Chevron, { className: "collapsible-icon", height: 9 })));
|
|
44
|
+
}
|
|
45
|
+
var props = {
|
|
46
|
+
href: (_c = navItem.url) !== null && _c !== void 0 ? _c : undefined,
|
|
47
|
+
children: children,
|
|
48
|
+
onClick: onClick,
|
|
49
|
+
className: [
|
|
50
|
+
'nav-item',
|
|
51
|
+
'nav-item-level-' + navItem.level,
|
|
52
|
+
navItem.url && navItem.isActive && ' is-active',
|
|
53
|
+
navItem.isFirstOfItsKind && 'nav-item-first-of-its-kind',
|
|
54
|
+
navItem.isLastOfItsKind && 'nav-item-last-of-its-kind',
|
|
55
|
+
]
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join(' '),
|
|
58
|
+
};
|
|
59
|
+
if (navItem.level === 1) {
|
|
60
|
+
props.style = (_b = {},
|
|
61
|
+
_b['--category-color'] = navItem.color,
|
|
62
|
+
_b);
|
|
63
|
+
}
|
|
64
|
+
if (navItem.level === 2 || navItem.level === 3) {
|
|
65
|
+
return React.createElement("a", __assign({}, props));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
return React.createElement("span", __assign({}, props));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function getNavItemsWithComputed(navItems, currentUrl) {
|
|
72
|
+
var navItemIdx;
|
|
73
|
+
var navItemsWithComputed = navItems.map(function (navItem, i) {
|
|
74
|
+
assert([1, 2, 3, 4].includes(navItem.level), navItem);
|
|
75
|
+
var navItemPrevious = navItems[i - 1];
|
|
76
|
+
var navItemNext = navItems[i + 1];
|
|
77
|
+
var isActive = false;
|
|
78
|
+
if (navItem.url === currentUrl) {
|
|
79
|
+
assert(navItem.level === 2, { currentUrl: currentUrl });
|
|
80
|
+
assert(navItemIdx === undefined);
|
|
81
|
+
navItemIdx = i;
|
|
82
|
+
isActive = true;
|
|
83
|
+
}
|
|
84
|
+
var isFirstOfItsKind = navItem.level !== (navItemPrevious === null || navItemPrevious === void 0 ? void 0 : navItemPrevious.level);
|
|
85
|
+
var isLastOfItsKind = navItem.level !== (navItemNext === null || navItemNext === void 0 ? void 0 : navItemNext.level);
|
|
86
|
+
var navItemComputed = __assign(__assign({}, navItem), { isActive: isActive, isRelevant: false, isFirstOfItsKind: isFirstOfItsKind, isLastOfItsKind: isLastOfItsKind });
|
|
87
|
+
return navItemComputed;
|
|
88
|
+
});
|
|
89
|
+
// Set `isRelevant`
|
|
90
|
+
if (navItemIdx !== undefined) {
|
|
91
|
+
for (var i = navItemIdx; i >= 0; i--) {
|
|
92
|
+
var navItem = navItemsWithComputed[i];
|
|
93
|
+
navItem.isRelevant = true;
|
|
94
|
+
if (navItem.level === 1)
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
for (var i = navItemIdx; i < navItemsWithComputed.length; i++) {
|
|
98
|
+
var navItem = navItemsWithComputed[i];
|
|
99
|
+
if (navItem.level === 1)
|
|
100
|
+
break;
|
|
101
|
+
navItem.isRelevant = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return navItemsWithComputed;
|
|
105
|
+
}
|
|
106
|
+
function Chevron(props) {
|
|
107
|
+
return (React.createElement("svg", __assign({ viewBox: "0 0 512 292.52", xmlns: "http://www.w3.org/2000/svg" }, props),
|
|
108
|
+
React.createElement("path", { fill: "#aaa", d: "M10.725 82.42L230.125 261.82c6.8 6.8 16.2 10.7 25.9 10.7s19.1-3.9 25.9-10.7l219.4-179.4c14.3-14.3 14.3-37.4 0-51.7s-37.4-14.3-51.7 0l-193.6 153.6-193.6-153.6c-14.3-14.3-37.4-14.3-51.7 0s-14.3 37.5 0 51.7z" })));
|
|
109
|
+
}
|