@brillout/docpress 0.5.40 → 0.6.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 +17 -0
- 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/FeatureList/FeatureList.client.ts +66 -0
- package/{dist/components/features → components/FeatureList}/FeatureList.css +10 -2
- package/components/FeatureList/FeatureList.tsx +114 -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/components/index.ts +14 -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/+config.d.ts +19 -0
- package/dist/+config.js +15 -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 +38 -53
- 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.config.json +7 -0
- package/tsconfig.json +15 -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 -221
- package/dist/index.js +0 -947
- 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/chevron-R2IYJD62.svg → components/FeatureList/chevron.svg} +0 -0
- /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/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/+config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Config } from 'vike/types'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
// @ts-expect-error remove this @ts-expect-error once Vike's new version is released
|
|
5
|
+
name: '@brillout/docpress' ,
|
|
6
|
+
onRenderHtml: 'import:@brillout/docpress/renderer/onRenderHtml:onRenderHtml',
|
|
7
|
+
client: 'import:@brillout/docpress/renderer/client:doesNotExist',
|
|
8
|
+
meta: {
|
|
9
|
+
Page: {
|
|
10
|
+
env: { client: false, server: true }
|
|
11
|
+
},
|
|
12
|
+
// Vike already defines the setting 'name', but we redundantly define it here for older Vike versions (otherwise older Vike versions will complain that 'name` is an unknown config).
|
|
13
|
+
name: {
|
|
14
|
+
env: { config: true }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
} satisfies Config
|
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,66 @@
|
|
|
1
|
+
import { assert } from '../../utils/client'
|
|
2
|
+
|
|
3
|
+
addTwitterWidgets()
|
|
4
|
+
addFeatureClickHandlers()
|
|
5
|
+
window.__docpress_hydrationFinished = true
|
|
6
|
+
|
|
7
|
+
function addTwitterWidgets() {
|
|
8
|
+
loadScript('https://platform.twitter.com/widgets.js')
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function addFeatureClickHandlers() {
|
|
12
|
+
const featureEls: HTMLElement[] = Array.from(
|
|
13
|
+
document.getElementById('features')!.querySelectorAll('.feature.has-learn-more')
|
|
14
|
+
)
|
|
15
|
+
featureEls.forEach((featureEl) => {
|
|
16
|
+
featureEl.onclick = () => {
|
|
17
|
+
expandLearnMore(featureEl)
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function expandLearnMore(featureEl: HTMLElement) {
|
|
23
|
+
const featureId = featureEl.id
|
|
24
|
+
assert(featureId.startsWith('feature-'), { featureId })
|
|
25
|
+
const featureName = featureId.slice('feature-'.length)
|
|
26
|
+
|
|
27
|
+
const selectedClass = 'selected'
|
|
28
|
+
const learnId = 'learn-more-' + featureName
|
|
29
|
+
const learnEl = document.getElementById(learnId)
|
|
30
|
+
assert(learnEl, { learnId })
|
|
31
|
+
|
|
32
|
+
const isExpanded = featureEl.classList.contains(selectedClass)
|
|
33
|
+
|
|
34
|
+
if (!isExpanded) {
|
|
35
|
+
const rowEl = featureEl.parentNode as HTMLElement
|
|
36
|
+
if (getComputedStyle(rowEl, 'display') === 'grid') {
|
|
37
|
+
;[
|
|
38
|
+
...(rowEl.querySelectorAll('.learn-more') as any as HTMLElement[]),
|
|
39
|
+
...(rowEl.querySelectorAll('.feature') as any as HTMLElement[])
|
|
40
|
+
].forEach((el) => {
|
|
41
|
+
el.classList.remove(selectedClass)
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
;[featureEl, learnEl].forEach((el) => {
|
|
47
|
+
el.classList.toggle(selectedClass)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function loadScript(scriptUrl: string): void {
|
|
52
|
+
assert(scriptUrl.startsWith('https://'))
|
|
53
|
+
const scriptEl = document.createElement('script')
|
|
54
|
+
scriptEl.src = scriptUrl
|
|
55
|
+
scriptEl.async = true
|
|
56
|
+
scriptEl.setAttribute('charset', 'utf-8')
|
|
57
|
+
document.getElementsByTagName('head')[0].appendChild(scriptEl)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getComputedStyle(el: HTMLElement, styleProp: string) {
|
|
61
|
+
return window.document.defaultView!.getComputedStyle(el).getPropertyValue(styleProp)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare global {
|
|
65
|
+
var __docpress_hydrationFinished: undefined | true
|
|
66
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* src/components/features/FeatureList.css */
|
|
2
1
|
@media screen and (min-width: 840px) {
|
|
3
2
|
.features-row {
|
|
4
3
|
display: grid;
|
|
@@ -17,6 +16,7 @@
|
|
|
17
16
|
grid-column: 1 / 3;
|
|
18
17
|
}
|
|
19
18
|
}
|
|
19
|
+
|
|
20
20
|
@media screen and (min-width: 840px) {
|
|
21
21
|
.features-row.single-column .feature {
|
|
22
22
|
grid-column: 1 / span 2 !important;
|
|
@@ -25,11 +25,13 @@
|
|
|
25
25
|
margin: auto !important;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
|
|
28
29
|
#features {
|
|
29
30
|
margin: auto;
|
|
30
31
|
margin-top: 0;
|
|
31
32
|
max-width: 1080px;
|
|
32
33
|
}
|
|
34
|
+
|
|
33
35
|
#features summary p {
|
|
34
36
|
margin: 10px 0;
|
|
35
37
|
}
|
|
@@ -44,6 +46,7 @@
|
|
|
44
46
|
.learn-more h3:first-of-type {
|
|
45
47
|
margin-top: 15px;
|
|
46
48
|
}
|
|
49
|
+
|
|
47
50
|
.learn-more {
|
|
48
51
|
border: var(--border-width) solid var(--border-color);
|
|
49
52
|
padding: 10px 8px;
|
|
@@ -95,6 +98,8 @@ aside.learn-more.right-side {
|
|
|
95
98
|
border-bottom: 0 !important;
|
|
96
99
|
z-index: 1;
|
|
97
100
|
}
|
|
101
|
+
|
|
102
|
+
/* Hide top border of .learn-more */
|
|
98
103
|
.learn-more {
|
|
99
104
|
position: relative;
|
|
100
105
|
top: calc(-1 * var(--border-width));
|
|
@@ -103,8 +108,11 @@ aside.learn-more.right-side {
|
|
|
103
108
|
position: relative;
|
|
104
109
|
z-index: 1;
|
|
105
110
|
}
|
|
111
|
+
|
|
106
112
|
.feature .chevron {
|
|
107
|
-
transition:
|
|
113
|
+
transition:
|
|
114
|
+
filter 0.3s ease-in-out,
|
|
115
|
+
transform 0.3s ease-in-out !important;
|
|
108
116
|
}
|
|
109
117
|
.feature.selected .chevron {
|
|
110
118
|
transform: rotate(180deg);
|