@brillout/docpress 0.8.13 → 0.8.15
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 +279 -171
- package/MenuModal.tsx +55 -56
- package/{Links.tsx → NavSecondaryContent.tsx} +6 -8
- package/components/HorizontalLine.tsx +4 -3
- package/config/resolveHeadingsData.ts +7 -10
- package/css/code/block.css +5 -5
- package/css/code/inline.css +1 -1
- package/css/colorize-on-hover.css +20 -9
- package/dist/Layout.d.ts +10 -6
- package/dist/Layout.js +181 -102
- package/dist/MenuModal.d.ts +5 -1
- package/dist/MenuModal.js +44 -60
- package/dist/{Links.d.ts → NavSecondaryContent.d.ts} +3 -2
- package/dist/{Links.js → NavSecondaryContent.js} +5 -6
- package/dist/components/HorizontalLine.d.ts +1 -1
- package/dist/components/HorizontalLine.js +3 -2
- package/dist/config/resolveHeadingsData.d.ts +3 -4
- package/dist/config/resolveHeadingsData.js +5 -8
- package/dist/config/resolvePageContext.d.ts +2 -3
- package/dist/docsearch/SearchLink.js +2 -3
- package/dist/navigation/Collapsible.d.ts +10 -0
- package/dist/navigation/Collapsible.js +35 -0
- package/dist/navigation/Navigation.d.ts +0 -3
- package/dist/navigation/Navigation.js +106 -55
- package/dist/renderer/determineNavItemsColumnLayout.d.ts +3 -0
- package/dist/renderer/{determineColumnEntries.js → determineNavItemsColumnLayout.js} +34 -28
- package/dist/renderer/usePageContext.d.ts +2 -2
- package/dist/renderer/usePageContext.js +2 -4
- package/dist/utils/Style.d.ts +5 -0
- package/dist/utils/Style.js +6 -0
- package/dist/utils/cls.d.ts +3 -0
- package/dist/utils/cls.js +5 -0
- package/dist/utils/throttle.d.ts +1 -0
- package/dist/utils/throttle.js +14 -0
- package/docsearch/SearchLink.tsx +4 -13
- package/global.d.ts +1 -1
- package/initKeyBindings.ts +1 -6
- package/navigation/Collapsible.css +11 -0
- package/navigation/Collapsible.tsx +64 -0
- package/navigation/Navigation.css +12 -6
- package/navigation/Navigation.tsx +191 -80
- package/package.json +1 -1
- package/renderer/{determineColumnEntries.ts → determineNavItemsColumnLayout.ts} +35 -29
- package/renderer/initOnNavigation.ts +37 -0
- package/renderer/onRenderClient.tsx +2 -0
- package/renderer/usePageContext.tsx +2 -5
- package/utils/Style.tsx +7 -0
- package/utils/cls.ts +8 -0
- package/utils/throttle.ts +10 -0
- package/dist/renderer/determineColumnEntries.d.ts +0 -3
package/Layout.tsx
CHANGED
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
export { Layout }
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
2
|
+
export { containerQueryMobileLayout }
|
|
3
|
+
export { containerQueryMobileMenu }
|
|
4
|
+
export { navLeftWidthMin }
|
|
5
|
+
export { navLeftWidthMax }
|
|
6
|
+
export { unexpandNav }
|
|
5
7
|
|
|
6
8
|
import React from 'react'
|
|
7
9
|
import { NavigationContent } from './navigation/Navigation'
|
|
8
10
|
import { EditPageNote } from './components/EditPageNote'
|
|
9
11
|
import { parseTitle } from './parseTitle'
|
|
10
12
|
import { usePageContext, usePageContext2 } from './renderer/usePageContext'
|
|
11
|
-
import {
|
|
12
|
-
import { toggleMenuModal } from './MenuModal'
|
|
13
|
+
import { NavSecondaryContent } from './NavSecondaryContent'
|
|
14
|
+
import { closeMenuModal, openMenuModal, toggleMenuModal } from './MenuModal'
|
|
13
15
|
import { MenuModal } from './MenuModal'
|
|
14
16
|
import { autoScrollNav_SSR } from './autoScrollNav'
|
|
15
17
|
import { SearchLink } from './docsearch/SearchLink'
|
|
16
18
|
import { navigate } from 'vike/client/router'
|
|
17
19
|
import { css } from './utils/css'
|
|
18
20
|
import { PassThrough } from './utils/PassTrough'
|
|
21
|
+
import { Style } from './utils/Style'
|
|
22
|
+
import { cls } from './utils/cls'
|
|
19
23
|
|
|
20
|
-
const mainViewWidthMax = 800
|
|
21
|
-
const mainViewPadding = 20
|
|
22
|
-
const navWidthMax = 370
|
|
23
|
-
const navWidthMin = 300
|
|
24
|
-
const navWidth = {
|
|
25
|
-
minWidth: navWidthMin,
|
|
26
|
-
maxWidth: navWidthMax,
|
|
27
|
-
width: '100%',
|
|
28
|
-
}
|
|
29
24
|
const blockMargin = 3
|
|
25
|
+
const mainViewPadding = 20
|
|
26
|
+
const mainViewWidthMax = 800
|
|
27
|
+
const navLeftWidthMax = 370
|
|
28
|
+
const navLeftWidthMin = 300
|
|
29
|
+
// 840 = 800 + 20 * 2
|
|
30
30
|
const mainViewMax = mainViewWidthMax + mainViewPadding * 2
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const containerQueryMobileMenu = 1000
|
|
32
|
+
// 1143 = 840 + 300
|
|
33
|
+
const containerQueryMobileLayout = mainViewMax + navLeftWidthMin
|
|
34
|
+
// 1213 = 840 + 370 + 3
|
|
35
|
+
const containerQueryExtraSpace = mainViewMax + navLeftWidthMax + blockMargin
|
|
33
36
|
|
|
34
37
|
// Avoid whitespace at the bottom of pages with almost no content
|
|
35
38
|
const whitespaceBuster1: React.CSSProperties = {
|
|
@@ -58,18 +61,20 @@ function Layout({ children }: { children: React.ReactNode }) {
|
|
|
58
61
|
['--bg-color']: '#f5f5f7',
|
|
59
62
|
['--block-margin']: `${blockMargin}px`,
|
|
60
63
|
['--icon-text-padding']: '8px',
|
|
64
|
+
['--nav-head-height']: `${isLandingPage ? 70 : 60}px`,
|
|
61
65
|
}}
|
|
62
66
|
>
|
|
63
|
-
<MenuModal />
|
|
67
|
+
<MenuModal isTopNav={isLandingPage} />
|
|
64
68
|
<div
|
|
65
69
|
className={isLandingPage ? '' : 'doc-page'}
|
|
66
70
|
style={{
|
|
67
71
|
// We don't add `container` to `body` nor `html` beacuse in Firefox it breaks the `position: fixed` of <MenuModal>
|
|
68
72
|
// https://stackoverflow.com/questions/74601420/css-container-inline-size-and-fixed-child
|
|
69
|
-
|
|
73
|
+
container: 'container-viewport / inline-size',
|
|
70
74
|
...whitespaceBuster1,
|
|
71
75
|
}}
|
|
72
76
|
>
|
|
77
|
+
<NavHead />
|
|
73
78
|
{content}
|
|
74
79
|
</div>
|
|
75
80
|
</div>
|
|
@@ -78,11 +83,10 @@ function Layout({ children }: { children: React.ReactNode }) {
|
|
|
78
83
|
|
|
79
84
|
function LayoutDocsPage({ children }: { children: React.ReactNode }) {
|
|
80
85
|
const pageContext = usePageContext()
|
|
81
|
-
const hideNavLeftAlways = pageContext.
|
|
86
|
+
const hideNavLeftAlways = pageContext.navItemsDetached && pageContext.navItemsDetached.length <= 1
|
|
82
87
|
return (
|
|
83
88
|
<>
|
|
84
89
|
<style>{getStyle()}</style>
|
|
85
|
-
<NavMobile />
|
|
86
90
|
<div style={{ display: 'flex', ...whitespaceBuster2 }}>
|
|
87
91
|
<NavLeft />
|
|
88
92
|
<div className="low-prio-grow" style={{ width: 0, maxWidth: 50, background: 'var(--bg-color)' }} />
|
|
@@ -92,12 +96,12 @@ function LayoutDocsPage({ children }: { children: React.ReactNode }) {
|
|
|
92
96
|
)
|
|
93
97
|
function getStyle() {
|
|
94
98
|
let style = css`
|
|
95
|
-
@container(min-width: ${
|
|
99
|
+
@container container-viewport (min-width: ${containerQueryExtraSpace}px) {
|
|
96
100
|
.low-prio-grow {
|
|
97
101
|
flex-grow: 1;
|
|
98
102
|
}
|
|
99
103
|
#navigation-container {
|
|
100
|
-
width: ${
|
|
104
|
+
width: ${navLeftWidthMax}px !important;
|
|
101
105
|
}
|
|
102
106
|
}`
|
|
103
107
|
let navLeftHide = css`
|
|
@@ -112,14 +116,17 @@ function LayoutDocsPage({ children }: { children: React.ReactNode }) {
|
|
|
112
116
|
.page-content {
|
|
113
117
|
margin: auto;
|
|
114
118
|
}
|
|
119
|
+
#menu-modal {
|
|
120
|
+
position: absolute !important;
|
|
121
|
+
}
|
|
115
122
|
`
|
|
116
123
|
if (!hideNavLeftAlways) {
|
|
117
124
|
navLeftHide = css`
|
|
118
|
-
@container(max-width: ${
|
|
125
|
+
@container container-viewport (max-width: ${containerQueryMobileLayout - 1}px) {
|
|
119
126
|
${navLeftHide}
|
|
120
127
|
}
|
|
121
|
-
@container(min-width: ${
|
|
122
|
-
|
|
128
|
+
@container container-viewport (min-width: ${containerQueryMobileLayout}px) {
|
|
129
|
+
.nav-head-top {
|
|
123
130
|
display: none !important;
|
|
124
131
|
}
|
|
125
132
|
}
|
|
@@ -132,28 +139,11 @@ function LayoutDocsPage({ children }: { children: React.ReactNode }) {
|
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
function LayoutLandingPage({ children }: { children: React.ReactNode }) {
|
|
135
|
-
const mobile = 800
|
|
136
142
|
return (
|
|
137
143
|
<>
|
|
138
|
-
<style>{getStyle()}</style>
|
|
139
|
-
<NavTop />
|
|
140
|
-
<NavMobile />
|
|
141
144
|
<PageContent>{children}</PageContent>
|
|
142
145
|
</>
|
|
143
146
|
)
|
|
144
|
-
function getStyle() {
|
|
145
|
-
return css`
|
|
146
|
-
@container(min-width: ${mobile}px) {
|
|
147
|
-
#nav-mobile {
|
|
148
|
-
display: none !important;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
@container(max-width: ${mobile - 1}px) {
|
|
152
|
-
#top-navigation {
|
|
153
|
-
display: none !important;
|
|
154
|
-
}
|
|
155
|
-
`
|
|
156
|
-
}
|
|
157
147
|
}
|
|
158
148
|
|
|
159
149
|
function PageContent({ children }: { children: React.ReactNode }) {
|
|
@@ -195,50 +185,9 @@ function PageContent({ children }: { children: React.ReactNode }) {
|
|
|
195
185
|
)
|
|
196
186
|
}
|
|
197
187
|
|
|
198
|
-
function NavMobile() {
|
|
199
|
-
return (
|
|
200
|
-
<div id="nav-mobile">
|
|
201
|
-
<NavigationHeader headerHeight={70} iconSize={40} paddingLeft={12} style={{ justifyContent: 'center' }} />
|
|
202
|
-
</div>
|
|
203
|
-
)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function NavTop() {
|
|
207
|
-
const pageContext2 = usePageContext2()
|
|
208
|
-
const paddingSize = 35
|
|
209
|
-
const padding = `0 ${paddingSize}px`
|
|
210
|
-
const TopNavigation = pageContext2.config.TopNavigation || PassThrough
|
|
211
|
-
return (
|
|
212
|
-
<div
|
|
213
|
-
id="top-navigation"
|
|
214
|
-
className="link-hover-animation"
|
|
215
|
-
style={{
|
|
216
|
-
position: 'relative',
|
|
217
|
-
display: 'flex',
|
|
218
|
-
alignItems: 'center',
|
|
219
|
-
justifyContent: 'center',
|
|
220
|
-
textDecoration: 'none',
|
|
221
|
-
marginBottom: 'var(--block-margin)',
|
|
222
|
-
backgroundColor: 'var(--bg-color)',
|
|
223
|
-
['--padding-side']: `${paddingSize}px`,
|
|
224
|
-
fontSize: '1.06em',
|
|
225
|
-
color: '#666',
|
|
226
|
-
}}
|
|
227
|
-
>
|
|
228
|
-
<div style={{ display: 'flex', alignItems: 'center', height: 70 }}>
|
|
229
|
-
<TopNavigation />
|
|
230
|
-
<SearchLink style={{ padding }} />
|
|
231
|
-
<MenuLink style={{ padding }} />
|
|
232
|
-
<Links style={{ display: 'inline-flex', padding, marginLeft: -8 }} />
|
|
233
|
-
</div>
|
|
234
|
-
</div>
|
|
235
|
-
)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
188
|
function NavLeft() {
|
|
239
189
|
const pageContext = usePageContext()
|
|
240
|
-
const {
|
|
241
|
-
const headerHeight = 60
|
|
190
|
+
const { navItemsAll, navItemsDetached } = pageContext
|
|
242
191
|
return (
|
|
243
192
|
<>
|
|
244
193
|
<div
|
|
@@ -247,6 +196,7 @@ function NavLeft() {
|
|
|
247
196
|
style={{
|
|
248
197
|
flexGrow: 1,
|
|
249
198
|
borderRight: 'var(--block-margin) solid white',
|
|
199
|
+
zIndex: 1,
|
|
250
200
|
}}
|
|
251
201
|
>
|
|
252
202
|
<div
|
|
@@ -255,7 +205,7 @@ function NavLeft() {
|
|
|
255
205
|
top: 0,
|
|
256
206
|
}}
|
|
257
207
|
>
|
|
258
|
-
<
|
|
208
|
+
<NavHead isNavLeft={true} />
|
|
259
209
|
<div
|
|
260
210
|
style={{
|
|
261
211
|
backgroundColor: 'var(--bg-color)',
|
|
@@ -267,21 +217,20 @@ function NavLeft() {
|
|
|
267
217
|
id="navigation-container"
|
|
268
218
|
style={{
|
|
269
219
|
top: 0,
|
|
270
|
-
height: `calc(100vh -
|
|
220
|
+
height: `calc(100vh - var(--nav-head-height) - var(--block-margin))`,
|
|
271
221
|
overflowY: 'auto',
|
|
272
222
|
overscrollBehavior: 'contain',
|
|
273
223
|
paddingBottom: 40,
|
|
274
|
-
|
|
224
|
+
minWidth: navLeftWidthMin,
|
|
225
|
+
maxWidth: navLeftWidthMax,
|
|
226
|
+
width: '100%',
|
|
275
227
|
}}
|
|
276
228
|
>
|
|
277
|
-
{
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
<NavigationContent navItems={navItemsAll} showOnlyRelevant={true} />
|
|
283
|
-
)
|
|
284
|
-
}
|
|
229
|
+
{navItemsDetached ? (
|
|
230
|
+
<NavigationContent navItems={navItemsDetached} />
|
|
231
|
+
) : (
|
|
232
|
+
<NavigationContent navItems={navItemsAll} showOnlyRelevant={true} />
|
|
233
|
+
)}
|
|
285
234
|
</div>
|
|
286
235
|
</div>
|
|
287
236
|
</div>
|
|
@@ -292,125 +241,284 @@ function NavLeft() {
|
|
|
292
241
|
)
|
|
293
242
|
}
|
|
294
243
|
|
|
295
|
-
function
|
|
296
|
-
headerHeight,
|
|
297
|
-
iconSize,
|
|
298
|
-
style,
|
|
299
|
-
paddingLeft,
|
|
300
|
-
}: { headerHeight: number; iconSize: number; paddingLeft: number; style?: React.CSSProperties }) {
|
|
244
|
+
function NavHead({ isNavLeft }: { isNavLeft?: true }) {
|
|
301
245
|
const pageContext = usePageContext()
|
|
302
|
-
|
|
246
|
+
const pageContext2 = usePageContext2()
|
|
303
247
|
const { projectName } = pageContext.meta
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
248
|
+
const { isLandingPage } = pageContext
|
|
249
|
+
|
|
250
|
+
const linkStyle: React.CSSProperties = {
|
|
251
|
+
height: '100%',
|
|
252
|
+
padding: '0 var(--padding-side)',
|
|
309
253
|
justifyContent: 'center',
|
|
310
|
-
fontSize: isProjectNameShort ? '4.8cqw' : '4.5cqw',
|
|
311
|
-
['--icon-text-padding']: '1.8cqw',
|
|
312
254
|
}
|
|
313
|
-
|
|
255
|
+
|
|
256
|
+
const TopNavigation = pageContext2.config.TopNavigation || PassThrough
|
|
257
|
+
const navSecondaryContent = (
|
|
258
|
+
<div
|
|
259
|
+
className={isNavLeft ? 'show-on-nav-hover add-transition' : 'hide-on-shrink'}
|
|
260
|
+
style={{
|
|
261
|
+
padding: 0,
|
|
262
|
+
display: 'flex',
|
|
263
|
+
height: '100%',
|
|
264
|
+
...(!isNavLeft
|
|
265
|
+
? {}
|
|
266
|
+
: {
|
|
267
|
+
position: 'absolute',
|
|
268
|
+
left: '100%',
|
|
269
|
+
top: 0,
|
|
270
|
+
paddingLeft: 'var(--block-margin)',
|
|
271
|
+
'--padding-side': '20px',
|
|
272
|
+
width: mainViewMax, // guaranteed real estate
|
|
273
|
+
}),
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
<TopNavigation />
|
|
277
|
+
<NavSecondaryContent
|
|
278
|
+
style={{
|
|
279
|
+
display: 'inline-flex',
|
|
280
|
+
fontSize: '1.06em',
|
|
281
|
+
padding: '0 var(--padding-side)',
|
|
282
|
+
marginLeft: -8,
|
|
283
|
+
}}
|
|
284
|
+
/>
|
|
285
|
+
</div>
|
|
286
|
+
)
|
|
287
|
+
|
|
314
288
|
return (
|
|
315
289
|
<div
|
|
290
|
+
className={cls(['nav-head-full-width', !isNavLeft && 'nav-head-top', 'link-hover-animation'])}
|
|
316
291
|
style={{
|
|
317
|
-
backgroundColor: 'var(--bg-color)',
|
|
318
292
|
display: 'flex',
|
|
319
|
-
justifyContent: 'flex-end',
|
|
293
|
+
justifyContent: isNavLeft ? 'flex-end' : 'center',
|
|
294
|
+
backgroundColor: 'var(--bg-color)',
|
|
320
295
|
borderBottom: 'var(--block-margin) solid white',
|
|
321
|
-
|
|
296
|
+
position: 'relative',
|
|
322
297
|
}}
|
|
323
298
|
>
|
|
299
|
+
{isNavLeft && <NavHeaderLeftFullWidthBackground />}
|
|
324
300
|
<div
|
|
325
301
|
style={{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
302
|
+
container: 'container-nav-head / inline-size',
|
|
303
|
+
width: '100%',
|
|
304
|
+
minWidth: isNavLeft && navLeftWidthMin,
|
|
305
|
+
maxWidth: isNavLeft && navLeftWidthMax,
|
|
330
306
|
}}
|
|
331
307
|
>
|
|
332
|
-
<
|
|
308
|
+
<div
|
|
309
|
+
className="nav-head-content"
|
|
333
310
|
style={{
|
|
311
|
+
width: '100%',
|
|
312
|
+
height: 'var(--nav-head-height)',
|
|
313
|
+
fontSize: `min(16.96px, ${isProjectNameShort(projectName) ? '4.8cqw' : '4.5cqw'})`,
|
|
314
|
+
color: '#666',
|
|
315
|
+
['--icon-text-padding']: 'min(8px, 1.8cqw)',
|
|
334
316
|
display: 'flex',
|
|
335
|
-
|
|
336
|
-
color: 'inherit',
|
|
337
|
-
textDecoration: 'none',
|
|
338
|
-
height: '100%',
|
|
339
|
-
paddingLeft: paddingLeft + marginLeft * -1,
|
|
340
|
-
marginLeft: marginLeft,
|
|
341
|
-
...childrenStyle,
|
|
342
|
-
justifyContent: 'flex-start',
|
|
343
|
-
flexGrow: 0.5,
|
|
317
|
+
justifyContent: 'center',
|
|
344
318
|
}}
|
|
345
|
-
href="/"
|
|
346
319
|
>
|
|
347
|
-
<
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (!pageContext.config.pressKit) return // no /press page
|
|
353
|
-
if (window.location.pathname === '/press') return
|
|
354
|
-
ev.preventDefault()
|
|
355
|
-
navigate('/press#logo')
|
|
356
|
-
}}
|
|
357
|
-
/>
|
|
358
|
-
<span
|
|
359
|
-
style={{
|
|
360
|
-
marginLeft: `calc(var(--icon-text-padding) + 2px)`,
|
|
361
|
-
fontSize: isProjectNameShort ? '1.65em' : '1.3em',
|
|
362
|
-
}}
|
|
363
|
-
>
|
|
364
|
-
{projectName}
|
|
365
|
-
</span>
|
|
366
|
-
</a>
|
|
367
|
-
<SearchLink
|
|
368
|
-
style={{
|
|
369
|
-
//
|
|
370
|
-
...childrenStyle,
|
|
371
|
-
flexGrow: 0.5,
|
|
372
|
-
}}
|
|
373
|
-
/>
|
|
374
|
-
<MenuLink
|
|
375
|
-
style={{
|
|
376
|
-
//
|
|
377
|
-
...childrenStyle,
|
|
378
|
-
flexGrow: 1,
|
|
379
|
-
}}
|
|
380
|
-
/>
|
|
320
|
+
<NavLogo className="grow-half" />
|
|
321
|
+
<SearchLink className="grow-half" style={linkStyle} />
|
|
322
|
+
<MenuLink className="grow-full" style={linkStyle} />
|
|
323
|
+
{navSecondaryContent}
|
|
324
|
+
</div>
|
|
381
325
|
</div>
|
|
326
|
+
{getStyle()}
|
|
382
327
|
</div>
|
|
383
328
|
)
|
|
329
|
+
|
|
330
|
+
function getStyle() {
|
|
331
|
+
let style = css`
|
|
332
|
+
@container container-nav-head (max-width: 550px) {
|
|
333
|
+
.grow-full {
|
|
334
|
+
flex-grow: 1;
|
|
335
|
+
}
|
|
336
|
+
.grow-half {
|
|
337
|
+
flex-grow: 0.5;
|
|
338
|
+
}
|
|
339
|
+
.nav-head-content {
|
|
340
|
+
--padding-side: 0px;
|
|
341
|
+
}
|
|
342
|
+
.nav-logo {
|
|
343
|
+
padding-left: 15px;
|
|
344
|
+
margin-left: -10px;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
@container container-nav-head (min-width: 501px) {
|
|
348
|
+
.nav-head-content {
|
|
349
|
+
--padding-side: 35px;
|
|
350
|
+
}
|
|
351
|
+
.nav-logo {
|
|
352
|
+
padding: 0 var(--padding-side);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
@media(max-width: ${containerQueryMobileMenu}px) {
|
|
356
|
+
.hide-on-shrink {
|
|
357
|
+
display: none !important;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
`
|
|
361
|
+
if (isLandingPage)
|
|
362
|
+
style += css`
|
|
363
|
+
@media(min-width: ${containerQueryMobileMenu + 1}px) {
|
|
364
|
+
.nav-logo {
|
|
365
|
+
display: none !important;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
`
|
|
369
|
+
if (isNavLeft) {
|
|
370
|
+
style += css`
|
|
371
|
+
|
|
372
|
+
.show-on-nav-hover {
|
|
373
|
+
opacity: 0;
|
|
374
|
+
transition-property: opacity;
|
|
375
|
+
pointer-events: none;
|
|
376
|
+
}
|
|
377
|
+
html:not(.unexpand-nav) :has(.nav-head-full-width:hover) .show-on-nav-hover,
|
|
378
|
+
html:not(.unexpand-nav) :has(.show-on-nav-hover:hover) .show-on-nav-hover,
|
|
379
|
+
html:not(.unexpand-nav).menu-modal-show .show-on-nav-hover {
|
|
380
|
+
opacity: 1;
|
|
381
|
+
pointer-events: all;
|
|
382
|
+
}
|
|
383
|
+
`
|
|
384
|
+
}
|
|
385
|
+
return <Style>{style}</Style>
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function unexpandNav() {
|
|
389
|
+
document.documentElement.classList.add('unexpand-nav')
|
|
390
|
+
// Using setTimeout() because requestAnimationFrame() doesn't delay enough
|
|
391
|
+
setTimeout(() => {
|
|
392
|
+
document.documentElement.classList.remove('unexpand-nav')
|
|
393
|
+
}, 1000)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function NavHeaderLeftFullWidthBackground() {
|
|
397
|
+
return (
|
|
398
|
+
<div
|
|
399
|
+
className="show-on-nav-hover add-transition"
|
|
400
|
+
style={{
|
|
401
|
+
height: '100%',
|
|
402
|
+
width: '100vw',
|
|
403
|
+
zIndex: -1,
|
|
404
|
+
background: 'var(--bg-color)',
|
|
405
|
+
position: 'absolute',
|
|
406
|
+
left: 0,
|
|
407
|
+
top: 0,
|
|
408
|
+
boxSizing: 'content-box',
|
|
409
|
+
borderBottom: 'var(--block-margin) solid white',
|
|
410
|
+
}}
|
|
411
|
+
/>
|
|
412
|
+
)
|
|
384
413
|
}
|
|
385
414
|
|
|
386
|
-
|
|
387
|
-
|
|
415
|
+
function NavLogo({ className }: { className: string }) {
|
|
416
|
+
const pageContext = usePageContext()
|
|
417
|
+
const iconSize = 39
|
|
418
|
+
const { projectName } = pageContext.meta
|
|
388
419
|
return (
|
|
389
420
|
<a
|
|
421
|
+
className={cls(['nav-logo', className])}
|
|
422
|
+
style={{
|
|
423
|
+
display: 'flex',
|
|
424
|
+
alignItems: 'center',
|
|
425
|
+
color: 'inherit',
|
|
426
|
+
height: '100%',
|
|
427
|
+
justifyContent: 'flex-start',
|
|
428
|
+
}}
|
|
429
|
+
href="/"
|
|
430
|
+
>
|
|
431
|
+
<img
|
|
432
|
+
src={pageContext.meta.faviconUrl}
|
|
433
|
+
height={iconSize}
|
|
434
|
+
width={iconSize}
|
|
435
|
+
onContextMenu={(ev) => {
|
|
436
|
+
if (!pageContext.config.pressKit) return // no /press page
|
|
437
|
+
if (window.location.pathname === '/press') return
|
|
438
|
+
ev.preventDefault()
|
|
439
|
+
navigate('/press#logo')
|
|
440
|
+
}}
|
|
441
|
+
/>
|
|
442
|
+
<span
|
|
443
|
+
style={{
|
|
444
|
+
marginLeft: `calc(var(--icon-text-padding) + 2px)`,
|
|
445
|
+
fontSize: isProjectNameShort(projectName) ? '1.65em' : '1.3em',
|
|
446
|
+
}}
|
|
447
|
+
>
|
|
448
|
+
{projectName}
|
|
449
|
+
</span>
|
|
450
|
+
</a>
|
|
451
|
+
)
|
|
452
|
+
}
|
|
453
|
+
function isProjectNameShort(projectName: string) {
|
|
454
|
+
return projectName.length <= 4
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
let onMouseIgnore: ReturnType<typeof setTimeout> | undefined
|
|
458
|
+
type PropsDiv = React.HTMLProps<HTMLDivElement>
|
|
459
|
+
function MenuLink(props: PropsDiv) {
|
|
460
|
+
return (
|
|
461
|
+
<div
|
|
390
462
|
{...props}
|
|
391
463
|
style={{
|
|
392
464
|
height: '100%',
|
|
393
465
|
display: 'flex',
|
|
394
466
|
alignItems: 'center',
|
|
395
|
-
cursor: '
|
|
467
|
+
cursor: 'default',
|
|
468
|
+
userSelect: 'none',
|
|
396
469
|
...props.style,
|
|
397
470
|
}}
|
|
398
|
-
className=
|
|
471
|
+
className={['colorize-on-hover menu-toggle', props.className].filter(Boolean).join(' ')}
|
|
399
472
|
onClick={(ev) => {
|
|
400
473
|
ev.preventDefault()
|
|
401
474
|
toggleMenuModal()
|
|
402
475
|
}}
|
|
403
|
-
|
|
476
|
+
onMouseOver={() => {
|
|
477
|
+
if (onMouseIgnore) return
|
|
478
|
+
openMenuModal()
|
|
479
|
+
}}
|
|
480
|
+
onMouseLeave={() => {
|
|
481
|
+
if (onMouseIgnore) return
|
|
482
|
+
closeMenuModal()
|
|
483
|
+
}}
|
|
484
|
+
onTouchStart={() => {
|
|
485
|
+
onMouseIgnore = setTimeout(() => {
|
|
486
|
+
onMouseIgnore = undefined
|
|
487
|
+
}, 1000)
|
|
488
|
+
}}
|
|
404
489
|
>
|
|
405
|
-
<
|
|
406
|
-
|
|
407
|
-
|
|
490
|
+
<span className="text-docs">
|
|
491
|
+
<DocsIcon /> Docs
|
|
492
|
+
</span>
|
|
493
|
+
<span className="text-menu">
|
|
494
|
+
<MenuIcon /> Menu
|
|
495
|
+
</span>
|
|
496
|
+
<Style>{css`
|
|
497
|
+
@media(max-width: ${containerQueryMobileMenu}px) {
|
|
498
|
+
.text-docs {
|
|
499
|
+
display: none;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
@media(min-width: ${containerQueryMobileMenu + 1}px) {
|
|
503
|
+
.text-menu {
|
|
504
|
+
display: none;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
`}</Style>
|
|
508
|
+
</div>
|
|
509
|
+
)
|
|
510
|
+
}
|
|
511
|
+
function DocsIcon() {
|
|
512
|
+
return (
|
|
513
|
+
<span style={{ marginRight: 'calc(var(--icon-text-padding) + 2px)' }} className="decolorize-6">
|
|
514
|
+
📚
|
|
515
|
+
</span>
|
|
408
516
|
)
|
|
409
517
|
}
|
|
410
518
|
function MenuIcon() {
|
|
411
519
|
return (
|
|
412
520
|
<svg
|
|
413
|
-
style={{ marginRight: 'calc(var(--icon-text-padding) + 2px)',
|
|
521
|
+
style={{ marginRight: 'calc(var(--icon-text-padding) + 2px)', verticalAlign: 'top', width: '1.3em' }}
|
|
414
522
|
className="decolorize-6"
|
|
415
523
|
viewBox="0 0 448 512"
|
|
416
524
|
>
|