@brillout/docpress 0.5.39 → 0.5.40-commit-1ba896e
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/MobileHeader.tsx +68 -0
- package/PageLayout.css +42 -0
- package/PageLayout.tsx +39 -0
- package/algolia/DocSearch.css +34 -0
- package/algolia/DocSearch.ts +62 -0
- package/autoScrollNav.ts +36 -0
- package/components/CodeBlockTransformer.css +9 -0
- package/components/CodeBlockTransformer.tsx +18 -0
- package/components/Comment.tsx +7 -0
- package/components/Consulting.tsx +47 -0
- package/components/Contributors.tsx +113 -0
- package/components/EditPageNote.tsx +18 -0
- package/components/HorizontalLine.tsx +20 -0
- package/components/ImportMeta.tsx +11 -0
- package/components/Link.tsx +144 -0
- package/components/Note.css +54 -0
- package/components/Note.tsx +78 -0
- package/components/P.css +8 -0
- package/components/P.tsx +8 -0
- package/components/ReadingRecommendation.tsx +56 -0
- package/components/RepoLink.tsx +24 -0
- package/components/Sponsors/label.draft.svg +108 -0
- package/components/Sponsors.tsx +218 -0
- package/components/Supporters.tsx +136 -0
- package/{dist/components → components}/features/FeatureList.css +10 -2
- package/components/features/FeatureList.tsx +114 -0
- package/components/features/initFeatureList.ts +66 -0
- package/components/index.ts +15 -0
- package/config/getConfig.ts +18 -0
- package/config/resolveConfig/resolveHeading.ts +0 -0
- package/config/resolvePageContext.ts +186 -0
- package/css/button.css +7 -0
- package/css/code/block.css +36 -0
- package/css/code/inline.css +27 -0
- package/css/code.css +20 -0
- package/css/colorize-on-hover.css +29 -0
- package/css/font.css +25 -0
- package/css/heading.css +45 -0
- package/css/index.css +12 -0
- package/css/link.css +17 -0
- package/css/reset.css +12 -0
- package/css/table.css +14 -0
- package/css/tooltip.css +11 -0
- package/data/maintainersList.tsx +92 -0
- package/data/sponsorsList.ts +147 -0
- package/dist/markdownHeadingsVitePlugin.d.ts +13 -0
- package/dist/markdownHeadingsVitePlugin.js +170 -0
- package/dist/utils/assert.d.ts +6 -0
- package/dist/utils/assert.js +48 -0
- package/dist/utils/determineSectionUrlHash.d.ts +4 -0
- package/dist/utils/determineSectionUrlHash.js +38 -0
- package/dist/vite.config.d.ts +3 -0
- package/dist/vite.config.js +32 -0
- package/index.ts +4 -0
- package/installSectionUrlHashs.ts +60 -0
- package/markdownHeadingsVitePlugin.ts +150 -0
- package/navigation/Navigation-highlight.css +41 -0
- package/navigation/Navigation-items.css +119 -0
- package/navigation/Navigation-layout.css +127 -0
- package/navigation/Navigation.client.ts +43 -0
- package/navigation/Navigation.css +3 -0
- package/navigation/Navigation.tsx +211 -0
- package/navigation/NavigationHeader.tsx +111 -0
- package/navigation/navigation-fullscreen/NavigationFullscreenButton.css +32 -0
- package/navigation/navigation-fullscreen/NavigationFullscreenButton.tsx +44 -0
- package/navigation/navigation-fullscreen/initNavigationFullscreen.ts +116 -0
- package/package.json +27 -47
- package/parseEmojis.ts +35 -0
- package/parseTitle.ts +139 -0
- package/renderer/client.ts +4 -0
- package/renderer/onRenderHtml.tsx +69 -0
- package/renderer/usePageContext.tsx +25 -0
- package/tsconfig.json +15 -0
- package/tsconfig.vite-config.json +7 -0
- package/types/Config.ts +46 -0
- package/types/Heading.ts +49 -0
- package/utils/Emoji/Emoji.ts +224 -0
- package/utils/Emoji/assets.ts +9 -0
- package/utils/Emoji/index.ts +1 -0
- package/utils/Emoji/mountain.svg +1 -0
- package/utils/assert.ts +51 -0
- package/utils/client.ts +2 -0
- package/utils/determineSectionUrlHash.ts +44 -0
- package/utils/filesystemPathHandling.ts +42 -0
- package/utils/filter.ts +12 -0
- package/utils/isBrowser.ts +5 -0
- package/utils/jsxToTextContent.ts +11 -0
- package/utils/objectAssign.ts +9 -0
- package/utils/server.ts +7 -0
- package/vite.config.ts +36 -0
- package/bin.js +0 -3
- package/dist/chunk-2ZTPUQGS.js +0 -58
- package/dist/chunk-3QC7HYIF.js +0 -7
- package/dist/chunk-MGOI4AFO.js +0 -165
- package/dist/chunk-NVJING6T.js +0 -91
- package/dist/chunk-QWL3MA4E.js +0 -171
- package/dist/chunk-UN23G34B.js +0 -157
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +0 -34
- package/dist/components/features/FeatureList.d.ts +0 -13
- package/dist/components/features/FeatureList.js +0 -7
- package/dist/components/features/initFeatureList.d.ts +0 -3
- package/dist/components/features/initFeatureList.js +0 -59
- package/dist/devServer-JKH6U5PF.js +0 -36
- package/dist/index.css +0 -120
- package/dist/index.d.ts +0 -225
- package/dist/index.js +0 -948
- package/dist/renderer/_default.page.client.css +0 -318
- package/dist/renderer/_default.page.client.d.ts +0 -1
- package/dist/renderer/_default.page.client.js +0 -218
- package/dist/renderer/_default.page.server.css +0 -310
- package/dist/renderer/_default.page.server.d.ts +0 -22
- package/dist/renderer/_default.page.server.js +0 -665
- package/readme.md +0 -5
- /package/{dist/label-MP75CTIA.svg → components/Sponsors/label.svg} +0 -0
- /package/{dist/medalBronze-CO4CTUR4.svg → components/Sponsors/medalBronze.svg} +0 -0
- /package/{dist/medalGold-UP6A73FL.svg → components/Sponsors/medalGold.svg} +0 -0
- /package/{dist/medalSilver-FAPGGOBN.svg → components/Sponsors/medalSilver.svg} +0 -0
- /package/{dist/chevron-R2IYJD62.svg → components/features/chevron.svg} +0 -0
- /package/{dist/Inter-Var-IOAEQULN.ttf → css/Inter-Var.ttf} +0 -0
- /package/{dist/alignable-B4QZV4X7.svg → data/sponsorsList/companyLogos/alignable.svg} +0 -0
- /package/{dist/bluefin-JQABZFGV.svg → data/sponsorsList/companyLogos/bluefin.svg} +0 -0
- /package/{dist/burdaforward-EUGURYZY.png → data/sponsorsList/companyLogos/burdaforward.png} +0 -0
- /package/{dist/contra-WLZBOPBV.svg → data/sponsorsList/companyLogos/contra.svg} +0 -0
- /package/{dist/ecosia-OYRLTR5T.svg → data/sponsorsList/companyLogos/ecosia.svg} +0 -0
- /package/{dist/inlang-GFRWND6X.png → data/sponsorsList/companyLogos/inlang.png} +0 -0
- /package/{dist/optimizers-SFEZF3NW.svg → data/sponsorsList/companyLogos/optimizers.svg} +0 -0
- /package/{dist/sourcegraph-YR2HADLS.svg → data/sponsorsList/companyLogos/sourcegraph.svg} +0 -0
- /package/{dist/changelog-IPI5F42D.svg → icons/changelog.svg} +0 -0
- /package/{dist/discord-JD33TUSF.svg → icons/discord.svg} +0 -0
- /package/{dist/github-P5ZSKN2N.svg → icons/github.svg} +0 -0
- /package/{dist/heart-OINVKOXO.svg → icons/heart.svg} +0 -0
- /package/{dist/languages-KXPKJFQL.svg → icons/languages.svg} +0 -0
- /package/{dist/people-72KKQHU4.svg → icons/people.svg} +0 -0
- /package/{dist/twitter-I7DXDN3J.svg → icons/twitter.svg} +0 -0
- /package/{dist/chevron-K3WPYLOP.svg → navigation/navigation-fullscreen/chevron.svg} +0 -0
- /package/{dist/close-IQXTDOHV.svg → navigation/navigation-fullscreen/close.svg} +0 -0
- /package/{dist/compass-2RWQU3E4.svg → utils/Emoji/compass.svg} +0 -0
- /package/{dist/engine-6Q6VSCVA.png → utils/Emoji/engine.png} +0 -0
- /package/{dist/mechanical-arm-TR7IQQMG.svg → utils/Emoji/mechanical-arm.svg} +0 -0
- /package/{dist/road-fork-3WZLW3HB.svg → utils/Emoji/road-fork.svg} +0 -0
- /package/{dist/shield-CU45RG5C.svg → utils/Emoji/shield.svg} +0 -0
- /package/{dist/typescript-ALIPKLRM.svg → utils/Emoji/typescript.svg} +0 -0
package/MobileHeader.tsx
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { usePageContext } from './renderer/usePageContext'
|
|
3
|
+
|
|
4
|
+
export { MobileHeader }
|
|
5
|
+
|
|
6
|
+
function MobileHeader() {
|
|
7
|
+
const pageContext = usePageContext()
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
id="mobile-header"
|
|
11
|
+
style={{
|
|
12
|
+
height: 'var(--mobile-header-height)',
|
|
13
|
+
width: '100%',
|
|
14
|
+
position: 'relative'
|
|
15
|
+
}}
|
|
16
|
+
>
|
|
17
|
+
<div
|
|
18
|
+
style={{
|
|
19
|
+
position: 'fixed',
|
|
20
|
+
display: 'flex',
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
background: 'white',
|
|
23
|
+
zIndex: 99,
|
|
24
|
+
top: 0,
|
|
25
|
+
left: 0,
|
|
26
|
+
height: 'var(--mobile-header-height)',
|
|
27
|
+
width: '100%',
|
|
28
|
+
borderBottom: '1px solid #ddd'
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<MenuToggle />
|
|
32
|
+
<a
|
|
33
|
+
href="/"
|
|
34
|
+
style={{
|
|
35
|
+
color: 'inherit',
|
|
36
|
+
display: 'flex',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
justifyContent: 'left',
|
|
39
|
+
textDecoration: 'none',
|
|
40
|
+
...pageContext.config.navHeaderMobileWrapperStyle
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
{pageContext.config.navHeaderMobile}
|
|
44
|
+
</a>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function MenuToggle() {
|
|
51
|
+
return (
|
|
52
|
+
<div style={{ padding: 20, lineHeight: 0, cursor: 'pointer' }} id="menu-toggle">
|
|
53
|
+
<svg
|
|
54
|
+
style={{ width: 20 }}
|
|
55
|
+
className="icon"
|
|
56
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
role="img"
|
|
59
|
+
viewBox="0 0 448 512"
|
|
60
|
+
>
|
|
61
|
+
<path
|
|
62
|
+
fill="currentColor"
|
|
63
|
+
d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"
|
|
64
|
+
></path>
|
|
65
|
+
</svg>
|
|
66
|
+
</div>
|
|
67
|
+
)
|
|
68
|
+
}
|
package/PageLayout.css
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.doc-page #page-container {
|
|
2
|
+
padding-bottom: 100px;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
#page-layout {
|
|
6
|
+
display: flex;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
width: 100%;
|
|
9
|
+
}
|
|
10
|
+
#page-layout > #navigation-wrapper,
|
|
11
|
+
#page-layout > #page-wrapper {
|
|
12
|
+
flex-grow: 1;
|
|
13
|
+
}
|
|
14
|
+
/* Avoid overflow, see https://stackoverflow.com/questions/36230944/prevent-flex-items-from-overflowing-a-container/66689926#66689926 */
|
|
15
|
+
#page-layout > #page-wrapper {
|
|
16
|
+
min-width: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.doc-page #page-wrapper {
|
|
20
|
+
--main-view-max-width: 800px;
|
|
21
|
+
}
|
|
22
|
+
.landing-page #page-wrapper {
|
|
23
|
+
--main-view-max-width: 1010px;
|
|
24
|
+
}
|
|
25
|
+
#page-wrapper {
|
|
26
|
+
max-width: calc(var(--main-view-max-width) + 80px);
|
|
27
|
+
}
|
|
28
|
+
#page-content {
|
|
29
|
+
box-sizing: content-box;
|
|
30
|
+
max-width: var(--main-view-max-width);
|
|
31
|
+
padding: 20px var(--main-view-padding);
|
|
32
|
+
margin: auto;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#page-content {
|
|
36
|
+
--main-view-padding: 20px;
|
|
37
|
+
}
|
|
38
|
+
@media screen and (max-width: 1139px) {
|
|
39
|
+
#page-content {
|
|
40
|
+
--main-view-padding: 10px;
|
|
41
|
+
}
|
|
42
|
+
}
|
package/PageLayout.tsx
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Navigation, NavigationMask } from './navigation/Navigation'
|
|
3
|
+
import type { PageContextResolved } from './config/resolvePageContext'
|
|
4
|
+
import { MobileHeader } from './MobileHeader'
|
|
5
|
+
import { EditPageNote } from './components/EditPageNote'
|
|
6
|
+
import { PageContextProvider } from './renderer/usePageContext'
|
|
7
|
+
import './PageLayout.css'
|
|
8
|
+
import { NavigationFullscreenButton } from './navigation/navigation-fullscreen/NavigationFullscreenButton'
|
|
9
|
+
|
|
10
|
+
export { PageLayout }
|
|
11
|
+
|
|
12
|
+
function PageLayout({ pageContext, children }: { pageContext: PageContextResolved; children: React.ReactNode }) {
|
|
13
|
+
const { isLandingPage, pageTitle } = pageContext
|
|
14
|
+
const { globalNote } = pageContext.config
|
|
15
|
+
return (
|
|
16
|
+
<React.StrictMode>
|
|
17
|
+
<PageContextProvider pageContext={pageContext}>
|
|
18
|
+
<div id="page-layout" className={isLandingPage ? 'landing-page' : 'doc-page'}>
|
|
19
|
+
<div id="navigation-wrapper">
|
|
20
|
+
<Navigation pageContext={pageContext} />
|
|
21
|
+
</div>
|
|
22
|
+
<NavigationFullscreenButton />
|
|
23
|
+
<div id="page-wrapper">
|
|
24
|
+
<div id="page-container">
|
|
25
|
+
<MobileHeader />
|
|
26
|
+
<div id="page-content">
|
|
27
|
+
{globalNote}
|
|
28
|
+
{pageTitle && <h1>{pageTitle}</h1>}
|
|
29
|
+
{children}
|
|
30
|
+
{!isLandingPage && <EditPageNote pageContext={pageContext} />}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<NavigationMask />
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</PageContextProvider>
|
|
37
|
+
</React.StrictMode>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.DocSearch-Button-Keys {
|
|
2
|
+
margin-left: 6px !important;
|
|
3
|
+
}
|
|
4
|
+
.DocSearch-Search-Icon {
|
|
5
|
+
margin-right: 0 !important;
|
|
6
|
+
}
|
|
7
|
+
.DocSearch-Button-Placeholder {
|
|
8
|
+
padding-right: 6px !important;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#docsearch-desktop {
|
|
12
|
+
max-width: 110px !important;
|
|
13
|
+
}
|
|
14
|
+
#docsearch-desktop .DocSearch-Button-Placeholder,
|
|
15
|
+
#docsearch-desktop .DocSearch-Button-Keys {
|
|
16
|
+
display: none;
|
|
17
|
+
}
|
|
18
|
+
#docsearch-desktop .DocSearch-Button {
|
|
19
|
+
background: transparent !important;
|
|
20
|
+
padding: 0 !important;
|
|
21
|
+
position: relative;
|
|
22
|
+
top: -1px;
|
|
23
|
+
outline: none !important;
|
|
24
|
+
border: none !important;
|
|
25
|
+
box-shadow: none !important;
|
|
26
|
+
}
|
|
27
|
+
#docsearch-desktop .DocSearch-Search-Icon {
|
|
28
|
+
height: 21px !important;
|
|
29
|
+
width: 21px !important;
|
|
30
|
+
}
|
|
31
|
+
#docsearch-desktop .DocSearch-Button {
|
|
32
|
+
margin-right: 3px !important;
|
|
33
|
+
margin-left: 1px !important;
|
|
34
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export { getDocSearchCSS }
|
|
2
|
+
export { getDocSearchJS }
|
|
3
|
+
|
|
4
|
+
import { dangerouslySkipEscape, escapeInject } from 'vike/server'
|
|
5
|
+
import { PageContextResolved } from '../config/resolvePageContext'
|
|
6
|
+
/* Imorted in /src/css/index.css instead
|
|
7
|
+
import './DocSearch.css'
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
function getDocSearchCSS(pageContext: PageContextResolved) {
|
|
11
|
+
const docSearchCSS = !pageContext.meta.algolia
|
|
12
|
+
? ''
|
|
13
|
+
: escapeInject`
|
|
14
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@alpha" />
|
|
15
|
+
`
|
|
16
|
+
return docSearchCSS
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getDocSearchJS(pageContext: PageContextResolved) {
|
|
20
|
+
const { algolia } = pageContext.meta
|
|
21
|
+
// If the docpress website doesn't use algolia => we don't inject the algolia assets => the search icon wrapper stays empty
|
|
22
|
+
// If algolia is PENDING_APPROVAL => we fill a FAKE API key so that the algolia popup shows (while no results are shown).
|
|
23
|
+
// - We show an alert warning users that there aren't any results until algolia's approval is pending (see below).
|
|
24
|
+
let docSearchJS = !algolia
|
|
25
|
+
? ''
|
|
26
|
+
: escapeInject`
|
|
27
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@docsearch/js@alpha"></script>
|
|
28
|
+
<script type="text/javascript">
|
|
29
|
+
const appId = '${algolia.appId || 'FAKE'}';
|
|
30
|
+
const apiKey = '${algolia.apiKey || 'FAKE'}';
|
|
31
|
+
const indexName = '${algolia.indexName || 'FAKE'}';
|
|
32
|
+
const transformItems = ${dangerouslySkipEscape(getTransformItems())};
|
|
33
|
+
docsearch({
|
|
34
|
+
container: '#docsearch-desktop',
|
|
35
|
+
appId, apiKey, indexName, transformItems,
|
|
36
|
+
insights: true,
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
`
|
|
40
|
+
if (algolia?.PENDING_APPROVAL) {
|
|
41
|
+
docSearchJS = escapeInject`
|
|
42
|
+
${docSearchJS}
|
|
43
|
+
<script>document.getElementById('docsearch-desktop').addEventListener('click', () => window.alert("Algolia approval is pending: the search results may be empty until the approval process is completed."))</script>
|
|
44
|
+
`
|
|
45
|
+
}
|
|
46
|
+
return docSearchJS
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Remove superfluous hash '#page-content' from URLs pointing to whole pages
|
|
50
|
+
// - https://github.com/algolia/docsearch/issues/1801
|
|
51
|
+
// - https://discourse.algolia.com/t/how-to-avoid-hash-in-search-result-url/6486
|
|
52
|
+
// - https://discourse.algolia.com/t/docsearchs-transformdata-function-cannot-remove-hashes-from-result-urls/8487
|
|
53
|
+
function getTransformItems() {
|
|
54
|
+
return `function(hits) {
|
|
55
|
+
hits.map(hit => {
|
|
56
|
+
if (hit.url.indexOf('#page-content') > 0) {
|
|
57
|
+
hit.url = hit.url.replace('#page-content', '');
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return hits;
|
|
61
|
+
}`
|
|
62
|
+
}
|
package/autoScrollNav.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { assert } from './utils/client'
|
|
2
|
+
|
|
3
|
+
autoScrollNav()
|
|
4
|
+
|
|
5
|
+
function autoScrollNav() {
|
|
6
|
+
const navigationEl = document.getElementById('navigation-content-main')
|
|
7
|
+
assert(navigationEl)
|
|
8
|
+
const href = window.location.pathname
|
|
9
|
+
const navLinks: HTMLElement[] = Array.from(navigationEl.querySelectorAll(`a[href="${href}"]`))
|
|
10
|
+
assert(navLinks.length <= 1, { navLinks, href })
|
|
11
|
+
const navLink = navLinks[0]
|
|
12
|
+
if (!navLink) return
|
|
13
|
+
|
|
14
|
+
/* Doesn't work: the scrolling is off by hundreds of px (I guess because this function runs too early while the page is still rendering)
|
|
15
|
+
const navigationContainerEl = document.getElementById("navigation-container")
|
|
16
|
+
const offset = navLink.offsetTop - (window.innerHeight / 2)
|
|
17
|
+
navigationContainerEl.scrollTop = offset
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/* Doesn't work: scrollIntoView() still scrolls the main view
|
|
21
|
+
const overflowOriginal = document.documentElement.style.overflow
|
|
22
|
+
document.documentElement.style.overflow = 'hidden'
|
|
23
|
+
...
|
|
24
|
+
document.documentElement.style.overflow = overflowOriginal
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const scrollTopOriginal = document.documentElement.scrollTop
|
|
28
|
+
navLink.scrollIntoView({
|
|
29
|
+
// @ts-ignore https://github.com/microsoft/TypeScript/issues/46654
|
|
30
|
+
behavior: 'instant',
|
|
31
|
+
block: 'center',
|
|
32
|
+
inline: 'start'
|
|
33
|
+
})
|
|
34
|
+
// Avoid scrollIntoView() from scrolling the main view. Alternatively, we could use scrollIntoViewIfNeeded() (https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded) which doesn't scroll the main view but Firefox doesn't support it.
|
|
35
|
+
document.documentElement.scrollTop = scrollTopOriginal
|
|
36
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { CodeBlockTransformer }
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { assert } from '../utils/server'
|
|
5
|
+
/* Imorted in /src/css/index.css instead
|
|
6
|
+
import './CodeBlockTransformer.css'
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
type LineBreak = 'white-space' | 'break-word'
|
|
10
|
+
|
|
11
|
+
function CodeBlockTransformer({ children, lineBreak }: { children: React.ReactNode; lineBreak: LineBreak }) {
|
|
12
|
+
assert(
|
|
13
|
+
lineBreak === 'white-space' || lineBreak === 'break-word',
|
|
14
|
+
'`lineBreak` is currently the only use case for <CodeBlockTransformer>'
|
|
15
|
+
)
|
|
16
|
+
const className = `with-line-break_${lineBreak}` as const
|
|
17
|
+
return <div className={className}>{children}</div>
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export { Consulting, Consultants }
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import iconPeople from '../icons/people.svg'
|
|
5
|
+
import { usePageContext } from '../renderer/usePageContext'
|
|
6
|
+
import { SupporterSection, SectionDescription, CallToAction } from './Supporters'
|
|
7
|
+
import { Maintainer } from './Contributors'
|
|
8
|
+
import { maintainers } from '../data/maintainersList'
|
|
9
|
+
import { Link } from './Link'
|
|
10
|
+
const consultingPageHref = '/consulting'
|
|
11
|
+
|
|
12
|
+
function Consulting() {
|
|
13
|
+
const pageContext = usePageContext()
|
|
14
|
+
const { projectInfo } = pageContext.config
|
|
15
|
+
const { projectName } = projectInfo
|
|
16
|
+
return (
|
|
17
|
+
<SupporterSection>
|
|
18
|
+
<CallToAction iconUrl={iconPeople} text="Consulting" href={consultingPageHref} />
|
|
19
|
+
<div></div>
|
|
20
|
+
<SectionDescription>
|
|
21
|
+
For questions and issues related to {projectName}, open a{' '}
|
|
22
|
+
<a href={projectInfo.githubDiscussions || projectInfo.githubIssues}>GitHub Discussion</a>. For advanced help or
|
|
23
|
+
help not directly related to {projectName}, the {projectName} team offers{' '}
|
|
24
|
+
<Link href={consultingPageHref} noBreadcrumb>
|
|
25
|
+
consulting
|
|
26
|
+
</Link>
|
|
27
|
+
.
|
|
28
|
+
</SectionDescription>
|
|
29
|
+
</SupporterSection>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function Consultants() {
|
|
34
|
+
return (
|
|
35
|
+
<SupporterSection>
|
|
36
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'end' }}>
|
|
37
|
+
{maintainers
|
|
38
|
+
.filter((maintainer) => {
|
|
39
|
+
return !!maintainer.consultingUrl
|
|
40
|
+
})
|
|
41
|
+
.map((maintainer, i) => (
|
|
42
|
+
<Maintainer maintainer={maintainer} key={i} />
|
|
43
|
+
))}
|
|
44
|
+
</div>
|
|
45
|
+
</SupporterSection>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export { Contributors, Maintainer }
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { usePageContext } from '../renderer/usePageContext'
|
|
5
|
+
import { Supporter, SupporterSection, SectionDescription, Individuals, SupporterImg } from './Supporters'
|
|
6
|
+
import { maintainers } from '../data/maintainersList'
|
|
7
|
+
import { contributors } from 'vike-contributors' // sorted by number of contributions
|
|
8
|
+
|
|
9
|
+
function Contributors() {
|
|
10
|
+
const pageContext = usePageContext()
|
|
11
|
+
const { projectInfo } = pageContext.config
|
|
12
|
+
return (
|
|
13
|
+
<SupporterSection>
|
|
14
|
+
<SectionDescription>
|
|
15
|
+
{projectInfo.projectName} is built and maintained by passionate contributors.
|
|
16
|
+
</SectionDescription>
|
|
17
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-evenly', alignItems: 'end' }}>
|
|
18
|
+
{maintainers.map((maintainer, i) => (
|
|
19
|
+
<Maintainer maintainer={maintainer} key={i} />
|
|
20
|
+
))}
|
|
21
|
+
</div>
|
|
22
|
+
<Individuals>
|
|
23
|
+
{contributors
|
|
24
|
+
.filter((contributor) => {
|
|
25
|
+
return (
|
|
26
|
+
!contributor.login.includes('[bot]') && !maintainers.map((m) => m.username).includes(contributor.login)
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
.map((contributor, i) => (
|
|
30
|
+
<Supporter username={contributor.login} avatarUrl={contributor.avatarUrl} key={i} />
|
|
31
|
+
))}
|
|
32
|
+
</Individuals>
|
|
33
|
+
</SupporterSection>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function Maintainer({ maintainer }: { maintainer: (typeof maintainers)[0] }) {
|
|
38
|
+
const marginHeight = 20
|
|
39
|
+
const marginWidth = 10
|
|
40
|
+
const imgSize = 50
|
|
41
|
+
const githubUrl = `https://github.com/${maintainer.username}`
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
style={{
|
|
45
|
+
borderRadius: 7,
|
|
46
|
+
borderWidth: 1,
|
|
47
|
+
borderStyle: 'solid',
|
|
48
|
+
borderColor: '#e0e0e0',
|
|
49
|
+
overflow: 'hidden',
|
|
50
|
+
width: 430,
|
|
51
|
+
maxWidth: `calc(100vw - 2 * var(--main-view-padding) - 2 * ${marginWidth}px)`,
|
|
52
|
+
margin: `${marginHeight}px ${marginWidth}px`,
|
|
53
|
+
display: 'flex',
|
|
54
|
+
flexWrap: 'wrap',
|
|
55
|
+
padding: 20,
|
|
56
|
+
gap: 20,
|
|
57
|
+
textAlign: 'left'
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<a href={githubUrl}>
|
|
61
|
+
<div style={{ width: imgSize, height: imgSize, borderRadius: imgSize / 2, overflow: 'hidden' }}>
|
|
62
|
+
<SupporterImg
|
|
63
|
+
username={maintainer.username}
|
|
64
|
+
avatarUrl={getAvatarUrl(maintainer)}
|
|
65
|
+
imgAlt={maintainer.firstName}
|
|
66
|
+
width={imgSize}
|
|
67
|
+
height={imgSize}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
</a>
|
|
71
|
+
<div>
|
|
72
|
+
<b>{maintainer.firstName}</b> ·{' '}
|
|
73
|
+
<a href={githubUrl}>
|
|
74
|
+
<i style={{ fontSize: '.9em', color: '#505050' }}>{maintainer.username}</i>
|
|
75
|
+
</a>
|
|
76
|
+
{maintainer.consultingUrl ? (
|
|
77
|
+
<>
|
|
78
|
+
{' '}
|
|
79
|
+
·{' '}
|
|
80
|
+
<a href={maintainer.consultingUrl}>
|
|
81
|
+
<b
|
|
82
|
+
style={{
|
|
83
|
+
fontSize: '.7em',
|
|
84
|
+
color: 'white',
|
|
85
|
+
backgroundColor: '#305090',
|
|
86
|
+
padding: '1px 5px 2px 5px',
|
|
87
|
+
verticalAlign: 'text-top',
|
|
88
|
+
borderRadius: 3
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
consulting
|
|
92
|
+
</b>
|
|
93
|
+
</a>
|
|
94
|
+
</>
|
|
95
|
+
) : null}
|
|
96
|
+
<ul style={{ fontSize: '.8em', paddingLeft: 15, marginTop: 5, marginBottom: 0 }}>
|
|
97
|
+
{maintainer.roles.map((role, i) => (
|
|
98
|
+
<li key={i}>{role}</li>
|
|
99
|
+
))}
|
|
100
|
+
</ul>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getAvatarUrl(maintainer: (typeof maintainers)[0]) {
|
|
107
|
+
for (const contributor of contributors) {
|
|
108
|
+
if (maintainer.username === contributor.login) {
|
|
109
|
+
return contributor.avatarUrl
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`Maintainer ${maintainer.username} not found in contributors' list.`)
|
|
113
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { RepoLink } from './RepoLink'
|
|
3
|
+
import { Emoji } from '../utils/server'
|
|
4
|
+
|
|
5
|
+
export { EditPageNote }
|
|
6
|
+
|
|
7
|
+
function EditPageNote({ pageContext }: { pageContext: { urlPathname: string } }) {
|
|
8
|
+
const text = (
|
|
9
|
+
<>
|
|
10
|
+
<Emoji name="writing-hang" /> Edit this page
|
|
11
|
+
</>
|
|
12
|
+
)
|
|
13
|
+
return (
|
|
14
|
+
<div style={{ marginTop: 50 }}>
|
|
15
|
+
<RepoLink path={'/docs/pages' + pageContext.urlPathname + '/+Page.mdx'} text={text} editMode={true} />
|
|
16
|
+
</div>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
export { HorizontalLine }
|
|
4
|
+
|
|
5
|
+
function HorizontalLine({ primary }: { primary?: true }) {
|
|
6
|
+
return (
|
|
7
|
+
<div className={'header-separator-line ' + (primary ? 'primary' : '')} style={{ textAlign: 'center' }}>
|
|
8
|
+
<hr
|
|
9
|
+
style={{
|
|
10
|
+
display: 'inline-block',
|
|
11
|
+
margin: 0,
|
|
12
|
+
border: 0,
|
|
13
|
+
borderTop: '1px solid #eee',
|
|
14
|
+
maxWidth: 500,
|
|
15
|
+
width: '80%'
|
|
16
|
+
}}
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { assert } from '../utils/server'
|
|
3
|
+
|
|
4
|
+
export { ImportMeta }
|
|
5
|
+
|
|
6
|
+
function ImportMeta({ prop }: { prop: string }) {
|
|
7
|
+
assert(!prop.startsWith('import'))
|
|
8
|
+
assert(!prop.startsWith('.'))
|
|
9
|
+
const text = 'imp' + 'ort.meta.' + prop
|
|
10
|
+
return <code>{text}</code>
|
|
11
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export { Link }
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { isRepoLink, RepoLink } from './RepoLink'
|
|
5
|
+
import type { Heading, HeadingDetached } from '../types/Heading'
|
|
6
|
+
import type { PageContextResolved } from '../config/resolvePageContext'
|
|
7
|
+
import { usePageContext } from '../renderer/usePageContext'
|
|
8
|
+
import { assert, assertUsage, determineSectionTitle, determineSectionUrlHash } from '../utils/server'
|
|
9
|
+
import { parseTitle } from '../parseTitle'
|
|
10
|
+
|
|
11
|
+
function Link({
|
|
12
|
+
href,
|
|
13
|
+
text,
|
|
14
|
+
noBreadcrumb,
|
|
15
|
+
doNotInferSectionTitle,
|
|
16
|
+
children
|
|
17
|
+
}: {
|
|
18
|
+
href: string
|
|
19
|
+
text?: string | JSX.Element
|
|
20
|
+
noBreadcrumb?: true
|
|
21
|
+
doNotInferSectionTitle?: true
|
|
22
|
+
children?: React.ReactNode
|
|
23
|
+
}) {
|
|
24
|
+
assertUsage(
|
|
25
|
+
href.startsWith('/') || href.startsWith('#'),
|
|
26
|
+
`<Link href /> prop \`href==='${href}'\` but should start with '/' or '#'`
|
|
27
|
+
)
|
|
28
|
+
assertUsage(!text || !children, 'Cannot use both `text` or `children`')
|
|
29
|
+
|
|
30
|
+
if (isRepoLink(href)) {
|
|
31
|
+
return <RepoLink path={href} text={text} />
|
|
32
|
+
} else {
|
|
33
|
+
const pageContext = usePageContext()
|
|
34
|
+
return (
|
|
35
|
+
<a href={href}>{children || text || getLinkText({ href, noBreadcrumb, pageContext, doNotInferSectionTitle })}</a>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getLinkText({
|
|
41
|
+
href,
|
|
42
|
+
noBreadcrumb,
|
|
43
|
+
pageContext,
|
|
44
|
+
doNotInferSectionTitle
|
|
45
|
+
}: {
|
|
46
|
+
href: string
|
|
47
|
+
noBreadcrumb: true | undefined
|
|
48
|
+
pageContext: PageContextResolved
|
|
49
|
+
doNotInferSectionTitle: true | undefined
|
|
50
|
+
}): string | JSX.Element {
|
|
51
|
+
let urlHash: string | null = null
|
|
52
|
+
let hrefWithoutHash: string = href
|
|
53
|
+
if (href.includes('#')) {
|
|
54
|
+
;[hrefWithoutHash, urlHash] = href.split('#')
|
|
55
|
+
assert(hrefWithoutHash || urlHash)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let heading: Heading | HeadingDetached
|
|
59
|
+
let isLinkOnSamePage: boolean = false
|
|
60
|
+
if (hrefWithoutHash) {
|
|
61
|
+
heading = findHeading(hrefWithoutHash, pageContext)
|
|
62
|
+
if (heading.url === pageContext.urlPathname) {
|
|
63
|
+
isLinkOnSamePage = true
|
|
64
|
+
// heading !== pageContext.activeHeading because activeHeading is a different object holding on-this-page subheadings
|
|
65
|
+
heading = pageContext.activeHeading
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
assert(urlHash)
|
|
69
|
+
isLinkOnSamePage = true
|
|
70
|
+
heading = pageContext.activeHeading
|
|
71
|
+
}
|
|
72
|
+
assert(heading)
|
|
73
|
+
assert(isLinkOnSamePage === (heading.url === pageContext.urlPathname))
|
|
74
|
+
assert(isLinkOnSamePage === (heading.url === pageContext.activeHeading.url))
|
|
75
|
+
assert(isLinkOnSamePage === (heading === pageContext.activeHeading))
|
|
76
|
+
|
|
77
|
+
const breadcrumbParts: (string | JSX.Element)[] = []
|
|
78
|
+
|
|
79
|
+
if (heading.headingsBreadcrumb) {
|
|
80
|
+
breadcrumbParts.push(
|
|
81
|
+
...(heading.headingsBreadcrumb ?? [])
|
|
82
|
+
.slice()
|
|
83
|
+
.reverse()
|
|
84
|
+
.map(({ title }) => title)
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
breadcrumbParts.push(heading.title)
|
|
89
|
+
|
|
90
|
+
if (urlHash) {
|
|
91
|
+
let sectionTitle: string | JSX.Element | undefined = undefined
|
|
92
|
+
assert(!urlHash.startsWith('#'))
|
|
93
|
+
if (isLinkOnSamePage) {
|
|
94
|
+
const pageHeading = findHeading(`#${urlHash}`, pageContext)
|
|
95
|
+
sectionTitle = pageHeading.title
|
|
96
|
+
} else if ('sectionTitles' in heading && heading.sectionTitles) {
|
|
97
|
+
heading.sectionTitles.forEach((title) => {
|
|
98
|
+
if (determineSectionUrlHash(title) === urlHash) {
|
|
99
|
+
sectionTitle = parseTitle(title)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
if (!sectionTitle) {
|
|
104
|
+
assertUsage(
|
|
105
|
+
!doNotInferSectionTitle,
|
|
106
|
+
`Page section title not found for <Link href="\`${href}\`" doNotInferSectionTitle={true} />.`
|
|
107
|
+
)
|
|
108
|
+
sectionTitle = determineSectionTitle(href)
|
|
109
|
+
}
|
|
110
|
+
breadcrumbParts.push(sectionTitle)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
if (noBreadcrumb || isLinkOnSamePage) {
|
|
115
|
+
return breadcrumbParts[breadcrumbParts.length - 1]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<>
|
|
121
|
+
{breadcrumbParts.map((title, i) => {
|
|
122
|
+
const seperator = i === 0 ? <></> : ' > '
|
|
123
|
+
return (
|
|
124
|
+
<React.Fragment key={i}>
|
|
125
|
+
{seperator}
|
|
126
|
+
{title}
|
|
127
|
+
</React.Fragment>
|
|
128
|
+
)
|
|
129
|
+
})}
|
|
130
|
+
</>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function findHeading(href: string, pageContext: PageContextResolved): Heading | HeadingDetached {
|
|
135
|
+
assert(href.startsWith('/') || href.startsWith('#'))
|
|
136
|
+
const { headingsAll } = pageContext
|
|
137
|
+
const heading = headingsAll.find(({ url }) => href === url)
|
|
138
|
+
if (href.startsWith('#')) {
|
|
139
|
+
assertUsage(heading, `Couldn't find ${href} in ${pageContext.urlPathname}, does it exist?`)
|
|
140
|
+
} else {
|
|
141
|
+
assertUsage(heading, `Couldn't find heading for ${href}, did you define the heading for ${href}?`)
|
|
142
|
+
}
|
|
143
|
+
return heading
|
|
144
|
+
}
|