@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
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
export { Navigation }
|
|
2
|
+
export { NavigationMask }
|
|
3
|
+
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import { NavigationHeader } from './NavigationHeader'
|
|
6
|
+
import { Heading, HeadingDetached } from '../types/Heading'
|
|
7
|
+
import { assert, Emoji, assertWarning, jsxToTextContent } from '../utils/server'
|
|
8
|
+
import './Navigation.css'
|
|
9
|
+
import { NavigationFullscreenClose } from './navigation-fullscreen/NavigationFullscreenButton'
|
|
10
|
+
|
|
11
|
+
function Navigation({
|
|
12
|
+
pageContext
|
|
13
|
+
}: {
|
|
14
|
+
pageContext: {
|
|
15
|
+
headingsProcessed: Heading[]
|
|
16
|
+
headingsOfDetachedPage: null | (Heading | HeadingDetached)[]
|
|
17
|
+
urlPathname: string
|
|
18
|
+
}
|
|
19
|
+
}) {
|
|
20
|
+
const currentUrl = pageContext.urlPathname
|
|
21
|
+
return (
|
|
22
|
+
<>
|
|
23
|
+
<div id="navigation-container">
|
|
24
|
+
<NavigationHeader />
|
|
25
|
+
{pageContext.headingsOfDetachedPage && (
|
|
26
|
+
<>
|
|
27
|
+
{pageContext.headingsOfDetachedPage.length > 1 && (
|
|
28
|
+
<NavigationContent
|
|
29
|
+
id="navigation-content-detached"
|
|
30
|
+
headingsProcessed={pageContext.headingsOfDetachedPage}
|
|
31
|
+
currentUrl={currentUrl}
|
|
32
|
+
/>
|
|
33
|
+
)}
|
|
34
|
+
<DetachedPageNote />
|
|
35
|
+
</>
|
|
36
|
+
)}
|
|
37
|
+
<NavigationContent
|
|
38
|
+
id="navigation-content-main"
|
|
39
|
+
headingsProcessed={pageContext.headingsProcessed}
|
|
40
|
+
currentUrl={currentUrl}
|
|
41
|
+
/>
|
|
42
|
+
{/* <ScrollOverlay /> */}
|
|
43
|
+
<NavigationFullscreenClose />
|
|
44
|
+
</div>
|
|
45
|
+
</>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function NavigationMask() {
|
|
50
|
+
return <div id="navigation-mask" />
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function NavigationContent(props: {
|
|
54
|
+
id: 'navigation-content-main' | 'navigation-content-detached'
|
|
55
|
+
headingsProcessed: (Heading | HeadingDetached)[]
|
|
56
|
+
currentUrl: string
|
|
57
|
+
}) {
|
|
58
|
+
const headings = getHeadingsWithComputedProps(props.headingsProcessed, props.currentUrl)
|
|
59
|
+
|
|
60
|
+
const headingsGrouped = groupHeadings(headings)
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div id={props.id} className="navigation-content">
|
|
64
|
+
<div className="nav-column" style={{ position: 'relative' }}>
|
|
65
|
+
{headingsGrouped.map((headingsH1, i) => (
|
|
66
|
+
<div className="nav-h1-group" key={i}>
|
|
67
|
+
<Heading heading={headingsH1} />
|
|
68
|
+
{headingsH1.headings.map((heading, j) => (
|
|
69
|
+
<Heading heading={heading} key={j} />
|
|
70
|
+
))}
|
|
71
|
+
</div>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function Heading({
|
|
79
|
+
heading
|
|
80
|
+
}: {
|
|
81
|
+
heading: {
|
|
82
|
+
level: number
|
|
83
|
+
url?: string | null
|
|
84
|
+
title: string | JSX.Element
|
|
85
|
+
titleInNav: string | JSX.Element
|
|
86
|
+
computed: {
|
|
87
|
+
isActive: boolean
|
|
88
|
+
isActiveFirst: boolean
|
|
89
|
+
isActiveLast: boolean
|
|
90
|
+
isFirstOfItsKind: boolean
|
|
91
|
+
isLastOfItsKind: boolean
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}) {
|
|
95
|
+
assert([1, 2, 3, 4].includes(heading.level), heading)
|
|
96
|
+
if (heading.level === 1 || heading.level === 4) {
|
|
97
|
+
assert(heading.url === undefined)
|
|
98
|
+
} else {
|
|
99
|
+
const sectionTitle = jsxToTextContent(heading.title)
|
|
100
|
+
assertWarning(
|
|
101
|
+
heading.url,
|
|
102
|
+
`${jsxToTextContent(
|
|
103
|
+
heading.titleInNav
|
|
104
|
+
)} is missing a URL hash. Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
return (
|
|
108
|
+
<a
|
|
109
|
+
className={[
|
|
110
|
+
'nav-item',
|
|
111
|
+
'nav-item-h' + heading.level,
|
|
112
|
+
heading.computed.isActive && ' is-active',
|
|
113
|
+
heading.computed.isActiveFirst && ' is-active-first',
|
|
114
|
+
heading.computed.isActiveLast && ' is-active-last',
|
|
115
|
+
heading.computed.isFirstOfItsKind && 'nav-item-first-of-its-kind',
|
|
116
|
+
heading.computed.isLastOfItsKind && 'nav-item-last-of-its-kind'
|
|
117
|
+
]
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.join(' ')}
|
|
120
|
+
href={heading.url ?? undefined}
|
|
121
|
+
>
|
|
122
|
+
{/* <span className="nav-item-text">{heading.titleInNav}</span> */}
|
|
123
|
+
{heading.titleInNav}
|
|
124
|
+
</a>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function groupHeadings<T extends { level: number }>(headings: T[]) {
|
|
129
|
+
const headingsGrouped: (T & { headings: T[] })[] = []
|
|
130
|
+
const headingLevelMin: number = Math.min(...headings.map((h) => h.level))
|
|
131
|
+
headings.forEach((heading) => {
|
|
132
|
+
if (heading.level === headingLevelMin) {
|
|
133
|
+
headingsGrouped.push({ ...heading, headings: [] })
|
|
134
|
+
} else {
|
|
135
|
+
headingsGrouped[headingsGrouped.length - 1].headings.push(heading)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
return headingsGrouped
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getHeadingsWithComputedProps(headings: (Heading | HeadingDetached)[], currentUrl: string) {
|
|
142
|
+
return headings.map((heading, i) => {
|
|
143
|
+
assert([1, 2, 3, 4].includes(heading.level), heading)
|
|
144
|
+
|
|
145
|
+
const headingPrevious = headings[i - 1]
|
|
146
|
+
const headingNext = headings[i + 1]
|
|
147
|
+
|
|
148
|
+
let isActiveFirst = false
|
|
149
|
+
let isActiveLast = false
|
|
150
|
+
let isActive = false
|
|
151
|
+
if (heading.url === currentUrl) {
|
|
152
|
+
assert(heading.level === 2, { currentUrl })
|
|
153
|
+
isActive = true
|
|
154
|
+
isActiveFirst = true
|
|
155
|
+
if (headingNext?.level !== 3) {
|
|
156
|
+
isActiveLast = true
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (heading.level === 3) {
|
|
160
|
+
isActive = true
|
|
161
|
+
if (headingNext?.level !== 3) {
|
|
162
|
+
isActiveLast = true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const isFirstOfItsKind = heading.level !== headingPrevious?.level
|
|
167
|
+
const isLastOfItsKind = heading.level !== headingNext?.level
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
...heading,
|
|
171
|
+
computed: {
|
|
172
|
+
isActive,
|
|
173
|
+
isActiveFirst,
|
|
174
|
+
isActiveLast,
|
|
175
|
+
isFirstOfItsKind,
|
|
176
|
+
isLastOfItsKind
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function DetachedPageNote() {
|
|
183
|
+
return (
|
|
184
|
+
<div
|
|
185
|
+
id="detached-note"
|
|
186
|
+
style={{
|
|
187
|
+
backgroundColor: 'var(--background-color)',
|
|
188
|
+
textAlign: 'left',
|
|
189
|
+
marginLeft: 10,
|
|
190
|
+
marginRight: 10,
|
|
191
|
+
marginTop: 25,
|
|
192
|
+
marginBottom: -5,
|
|
193
|
+
borderRadius: 5,
|
|
194
|
+
padding: 10
|
|
195
|
+
}}
|
|
196
|
+
>
|
|
197
|
+
<Emoji name="info" />{' '}
|
|
198
|
+
<b>
|
|
199
|
+
<em>Detached</em>
|
|
200
|
+
</b>
|
|
201
|
+
<span
|
|
202
|
+
style={{
|
|
203
|
+
opacity: 0.8
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
{' '}
|
|
207
|
+
— this page isn't listed in the navigation below.
|
|
208
|
+
</span>
|
|
209
|
+
</div>
|
|
210
|
+
)
|
|
211
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import iconGithub from '../icons/github.svg'
|
|
3
|
+
import iconTwitter from '../icons/twitter.svg'
|
|
4
|
+
import iconDiscord from '../icons/discord.svg'
|
|
5
|
+
import iconChangelog from '../icons/changelog.svg'
|
|
6
|
+
import iconLanguages from '../icons/languages.svg'
|
|
7
|
+
import { usePageContext } from '../renderer/usePageContext'
|
|
8
|
+
|
|
9
|
+
export { NavigationHeader }
|
|
10
|
+
|
|
11
|
+
function NavigationHeader() {
|
|
12
|
+
const pageContext = usePageContext()
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
id="navigation-header"
|
|
16
|
+
className={pageContext.config.pressKit && 'press-kit'}
|
|
17
|
+
style={{
|
|
18
|
+
display: 'flex',
|
|
19
|
+
flexDirection: 'column',
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
marginBottom: -5
|
|
22
|
+
}}
|
|
23
|
+
>
|
|
24
|
+
<a
|
|
25
|
+
id="navigation-header-logo"
|
|
26
|
+
style={{
|
|
27
|
+
display: 'flex',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
color: 'inherit',
|
|
30
|
+
justifyContent: 'left',
|
|
31
|
+
textDecoration: 'none',
|
|
32
|
+
paddingTop: 12,
|
|
33
|
+
paddingBottom: 7,
|
|
34
|
+
...pageContext.config.navHeaderWrapperStyle
|
|
35
|
+
}}
|
|
36
|
+
href="/"
|
|
37
|
+
>
|
|
38
|
+
{pageContext.config.navHeader}
|
|
39
|
+
</a>
|
|
40
|
+
<Links />
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function Links() {
|
|
46
|
+
const pageContext = usePageContext()
|
|
47
|
+
const { projectInfo, i18n } = pageContext.config
|
|
48
|
+
const iconI18n = !i18n ? null : (
|
|
49
|
+
<LinkIcon
|
|
50
|
+
className="decolorize-4"
|
|
51
|
+
icon={iconLanguages}
|
|
52
|
+
href={'/languages'}
|
|
53
|
+
style={{ height: 21, position: 'relative', top: 0, left: 0 }}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
style={{
|
|
59
|
+
display: 'flex',
|
|
60
|
+
alignItems: 'center',
|
|
61
|
+
paddingTop: 0,
|
|
62
|
+
justifyContent: 'left'
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<LinkIcon className="decolorize-4" icon={iconGithub} href={projectInfo.githubRepository} />
|
|
66
|
+
<LinkIcon className="decolorize-6" icon={iconDiscord} href={projectInfo.discordInvite} />
|
|
67
|
+
<LinkIcon className="decolorize-7" icon={iconTwitter} href={projectInfo.twitterProfile} />
|
|
68
|
+
<div className="decolorize-6 colorize-on-hover" id="docsearch-desktop" />
|
|
69
|
+
{iconI18n}
|
|
70
|
+
<ChangelogButton />
|
|
71
|
+
</div>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function ChangelogButton() {
|
|
76
|
+
const pageContext = usePageContext()
|
|
77
|
+
const { projectInfo } = pageContext.config
|
|
78
|
+
return (
|
|
79
|
+
<a
|
|
80
|
+
href={`${projectInfo.githubRepository}/blob/main/CHANGELOG.md`}
|
|
81
|
+
className="button colorize-on-hover"
|
|
82
|
+
style={{
|
|
83
|
+
display: 'flex',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
padding: '1px 7px',
|
|
86
|
+
marginLeft: 2,
|
|
87
|
+
fontSize: '0.97em',
|
|
88
|
+
color: 'inherit'
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<span id="version-number" className="decolorize-7">
|
|
92
|
+
v{projectInfo.projectVersion}
|
|
93
|
+
</span>
|
|
94
|
+
<img className="decolorize-6" src={iconChangelog} height={16} style={{ marginLeft: 5 }} />
|
|
95
|
+
</a>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function LinkIcon({ className, icon, href, style }: { className: string; icon: string; href: string; style?: any }) {
|
|
100
|
+
return (
|
|
101
|
+
<>
|
|
102
|
+
<a
|
|
103
|
+
className={'colorize-on-hover ' + className}
|
|
104
|
+
href={href}
|
|
105
|
+
style={{ padding: 3, display: 'inline-block', lineHeight: 0 }}
|
|
106
|
+
>
|
|
107
|
+
<img src={icon} height="20" style={style} />
|
|
108
|
+
</a>
|
|
109
|
+
</>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--navigation-fullscreen-button-width: 20px;
|
|
3
|
+
}
|
|
4
|
+
#navigation-fullscreen-button {
|
|
5
|
+
width: var(--navigation-fullscreen-button-width);
|
|
6
|
+
position: relative;
|
|
7
|
+
z-index: 2;
|
|
8
|
+
}
|
|
9
|
+
#navigation-wrapper:hover + #navigation-fullscreen-button > div > div,
|
|
10
|
+
#navigation-fullscreen-button:hover > div > div {
|
|
11
|
+
left: 0px;
|
|
12
|
+
}
|
|
13
|
+
#navigation-fullscreen-button > div > div {
|
|
14
|
+
transition: all 0.3s ease-in-out;
|
|
15
|
+
left: -20px;
|
|
16
|
+
position: absolute;
|
|
17
|
+
height: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
background-color: #eee !important;
|
|
20
|
+
background: url('./chevron.svg');
|
|
21
|
+
background-repeat: no-repeat;
|
|
22
|
+
background-position: center center;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
html:not(.navigation-fullscreen) #navigation-fullscreen-close {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
html.navigation-fullscreen #page-content {
|
|
30
|
+
/* Make `Ctrl-F` browser search only crawl the navigation menu */
|
|
31
|
+
visibility: hidden;
|
|
32
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export { NavigationFullscreenButton }
|
|
2
|
+
export { NavigationFullscreenClose }
|
|
3
|
+
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import './NavigationFullscreenButton.css'
|
|
6
|
+
import closeIcon from './close.svg'
|
|
7
|
+
|
|
8
|
+
function NavigationFullscreenButton() {
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<a id="navigation-fullscreen-button">
|
|
12
|
+
<div
|
|
13
|
+
style={{
|
|
14
|
+
position: 'fixed',
|
|
15
|
+
cursor: 'pointer',
|
|
16
|
+
height: '100vh',
|
|
17
|
+
width: 20,
|
|
18
|
+
overflow: 'hidden'
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
21
|
+
<div></div>
|
|
22
|
+
</div>
|
|
23
|
+
<div
|
|
24
|
+
style={{ position: 'fixed', height: '100vh', width: 20 }}
|
|
25
|
+
aria-label="Press <Esc>"
|
|
26
|
+
data-balloon-pos="right"
|
|
27
|
+
></div>
|
|
28
|
+
</a>
|
|
29
|
+
</>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function NavigationFullscreenClose() {
|
|
34
|
+
return (
|
|
35
|
+
<a
|
|
36
|
+
id="navigation-fullscreen-close"
|
|
37
|
+
style={{ position: 'absolute', top: 11, right: 11, zIndex: 10 }}
|
|
38
|
+
aria-label="Press <Esc>"
|
|
39
|
+
data-balloon-pos="left"
|
|
40
|
+
>
|
|
41
|
+
<img src={closeIcon} height={50} width={50} style={{ display: 'block' }} />
|
|
42
|
+
</a>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export { initNavigationFullscreen }
|
|
2
|
+
|
|
3
|
+
import { assert } from '../../utils/client'
|
|
4
|
+
|
|
5
|
+
let scrollPositionBeforeToggle: number = 0
|
|
6
|
+
|
|
7
|
+
function initNavigationFullscreen() {
|
|
8
|
+
updateColumnWidth()
|
|
9
|
+
window.addEventListener('resize', updateColumnWidth, { passive: true })
|
|
10
|
+
document.getElementById('navigation-fullscreen-button')!.onclick = toggleNavExpend
|
|
11
|
+
document.getElementById('navigation-fullscreen-close')!.onclick = toggleNavExpend
|
|
12
|
+
document.addEventListener(
|
|
13
|
+
// We don't use keydown to not interfere with user pressing `<Esc>` for closing the browser's `<Ctrl-F>` search diablog, see https://stackoverflow.com/questions/66595035/how-to-detect-escape-key-if-search-bar-of-browser-is-open
|
|
14
|
+
'keydown',
|
|
15
|
+
(ev) => {
|
|
16
|
+
if (document.body.classList.contains('DocSearch--active')) return
|
|
17
|
+
if (ev.key === 'Escape') toggleNavExpend()
|
|
18
|
+
},
|
|
19
|
+
false
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function toggleNavExpend() {
|
|
24
|
+
const navContainer = document.getElementById('navigation-container')!
|
|
25
|
+
const scrollPos = navContainer.scrollTop
|
|
26
|
+
document.documentElement.classList.toggle('navigation-fullscreen')
|
|
27
|
+
if (scrollPositionBeforeToggle !== undefined) {
|
|
28
|
+
navContainer.scrollTop = scrollPositionBeforeToggle
|
|
29
|
+
}
|
|
30
|
+
scrollPositionBeforeToggle = scrollPos
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function updateColumnWidth() {
|
|
34
|
+
const navMinWidth = 299
|
|
35
|
+
const navH1Groups = Array.from(document.querySelectorAll('#navigation-content-main .nav-h1-group'))
|
|
36
|
+
const numberOfColumnsMax = navH1Groups.length
|
|
37
|
+
|
|
38
|
+
const widthAvailable = getViewportWidth()
|
|
39
|
+
const numberOfColumns = Math.max(1, Math.min(numberOfColumnsMax, Math.floor(widthAvailable / navMinWidth)))
|
|
40
|
+
|
|
41
|
+
let columns = navH1Groups.map((navH1Group) => {
|
|
42
|
+
const column = [
|
|
43
|
+
{
|
|
44
|
+
element: navH1Group,
|
|
45
|
+
elementHeight: navH1Group.children.length
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
return column
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
mergeColumns(columns, numberOfColumns)
|
|
52
|
+
|
|
53
|
+
const navContent = document.getElementById('navigation-content-main')!
|
|
54
|
+
|
|
55
|
+
Array.from(navContent.children).forEach((child) => {
|
|
56
|
+
assert(child.className === 'nav-column')
|
|
57
|
+
})
|
|
58
|
+
navContent.innerHTML = ''
|
|
59
|
+
|
|
60
|
+
columns.forEach((column) => {
|
|
61
|
+
const columnEl = document.createElement('div')
|
|
62
|
+
columnEl.className = 'nav-column'
|
|
63
|
+
column.forEach(({ element }) => {
|
|
64
|
+
columnEl.appendChild(element)
|
|
65
|
+
})
|
|
66
|
+
navContent.appendChild(columnEl)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const navItemMaxWidth = 350
|
|
70
|
+
navContent.style.maxWidth = `${numberOfColumns * navItemMaxWidth}px`
|
|
71
|
+
}
|
|
72
|
+
function getViewportWidth(): number {
|
|
73
|
+
// `window.innerWidth` inlcudes scrollbar width: https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
|
74
|
+
return document.documentElement.clientWidth
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function mergeColumns<T>(columns: { element: T; elementHeight: number }[][], maxNumberOfColumns: number) {
|
|
78
|
+
assert(columns.length > 0)
|
|
79
|
+
assert(maxNumberOfColumns > 0)
|
|
80
|
+
if (columns.length <= maxNumberOfColumns) {
|
|
81
|
+
return columns
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let mergeCandidate = {
|
|
85
|
+
i: -1,
|
|
86
|
+
mergeHeight: Infinity
|
|
87
|
+
}
|
|
88
|
+
for (let i = 0; i <= columns.length - 2; i++) {
|
|
89
|
+
const column1 = columns[i + 0]
|
|
90
|
+
const column2 = columns[i + 1]
|
|
91
|
+
const column1Height = sum(column1.map((c) => c.elementHeight))
|
|
92
|
+
const column2Height = sum(column2.map((c) => c.elementHeight))
|
|
93
|
+
const mergeHeight = column1Height + column2Height
|
|
94
|
+
if (mergeCandidate.mergeHeight > mergeHeight) {
|
|
95
|
+
mergeCandidate = {
|
|
96
|
+
i,
|
|
97
|
+
mergeHeight
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
{
|
|
103
|
+
const { i } = mergeCandidate
|
|
104
|
+
assert(-1 < i && i < columns.length - 1, { i, columnsLength: columns.length, maxNumberOfColumns })
|
|
105
|
+
columns[i] = [...columns[i], ...columns[i + 1]]
|
|
106
|
+
columns.splice(i + 1, 1)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
mergeColumns(columns, maxNumberOfColumns)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function sum(arr: number[]): number {
|
|
113
|
+
let total = 0
|
|
114
|
+
arr.forEach((n) => (total += n))
|
|
115
|
+
return total
|
|
116
|
+
}
|
package/package.json
CHANGED
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brillout/docpress",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"scripts": {
|
|
5
|
+
"// Build vite.config.ts and +config.ts": "",
|
|
6
|
+
"build": "rm -rf dist/ && tsc --project tsconfig.config.json",
|
|
7
|
+
"// Development": "",
|
|
8
|
+
"dev": "tsc --watch --project tsconfig.config.json",
|
|
5
9
|
"// Check types while developing": "",
|
|
6
10
|
"types": "tsc --noEmit --watch",
|
|
7
|
-
"// Develop Docpress using demo/": "",
|
|
8
|
-
"dev": "pnpm run dev:build && pnpm run dev:start",
|
|
9
|
-
"dev:build": "tsup",
|
|
10
|
-
"dev:start": "node dist/index.js dev",
|
|
11
|
-
"// Build Docpress": "",
|
|
12
|
-
"build": "rimraf dist/ && framework-builder",
|
|
13
|
-
"// Preview build": "",
|
|
14
|
-
"preview": "pnpm run preview:build && pnpm run preview:start",
|
|
15
|
-
"preview:build": "pnpm run build && node dist/cli/index.js build",
|
|
16
|
-
"preview:start": "node dist/cli/index.js preview",
|
|
17
|
-
"// Test": "",
|
|
18
|
-
"test": "test-e2e",
|
|
19
11
|
"// Release": "",
|
|
20
12
|
"release": "release-me patch",
|
|
13
|
+
"release:commit": "release-me commit",
|
|
21
14
|
"release:breaking-change": "release-me minor"
|
|
22
15
|
},
|
|
23
16
|
"dependencies": {
|
|
@@ -26,73 +19,65 @@
|
|
|
26
19
|
"@mdx-js/rollup": "^2.0.0",
|
|
27
20
|
"@vitejs/plugin-react-swc": "^3.3.2",
|
|
28
21
|
"balloon-css": "^1.2.0",
|
|
29
|
-
"express": "^4.17.1",
|
|
30
22
|
"rehype-pretty-code": "^0.3.2",
|
|
31
23
|
"remark-gfm": "^3.0.1",
|
|
32
24
|
"shiki": "^0.10.1",
|
|
33
25
|
"twemoji": "^13.1.0",
|
|
34
|
-
"vike": "^0.
|
|
35
|
-
"vike-contributors": "^0.0.9",
|
|
36
|
-
"vite": "^4.3.9"
|
|
26
|
+
"vike-contributors": "^0.0.9"
|
|
37
27
|
},
|
|
38
28
|
"type": "module",
|
|
39
29
|
"exports": {
|
|
40
|
-
"./renderer/
|
|
41
|
-
"./renderer/
|
|
42
|
-
"
|
|
43
|
-
"./
|
|
44
|
-
".":
|
|
45
|
-
|
|
46
|
-
"./features/FeatureList.css": {
|
|
47
|
-
"browser": "./dist/components/features/FeatureList.css"
|
|
30
|
+
"./renderer/onRenderHtml": "./renderer/onRenderHtml.tsx",
|
|
31
|
+
"./renderer/client": "./renderer/client.ts",
|
|
32
|
+
".": "./index.ts",
|
|
33
|
+
"./FeatureList/FeatureList": "./components/FeatureList/FeatureList.tsx",
|
|
34
|
+
"./FeatureList/FeatureList.client": {
|
|
35
|
+
"browser": "./components/FeatureList/FeatureList.client.ts"
|
|
48
36
|
},
|
|
49
|
-
"./
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
"./vite-config": "./dist/vite.config.js",
|
|
38
|
+
"./config": "./dist/+config.js",
|
|
39
|
+
"./style": "./css/index.css"
|
|
52
40
|
},
|
|
53
41
|
"typesVersions": {
|
|
54
42
|
"*": {
|
|
55
43
|
"*": [
|
|
56
|
-
"
|
|
44
|
+
"./*"
|
|
57
45
|
],
|
|
58
46
|
"types": [
|
|
59
|
-
"types.d.ts"
|
|
47
|
+
"./types.d.ts"
|
|
48
|
+
],
|
|
49
|
+
"vite-config": [
|
|
50
|
+
"./dist/vite.config.d.ts"
|
|
60
51
|
],
|
|
61
|
-
"
|
|
62
|
-
"dist
|
|
52
|
+
"config": [
|
|
53
|
+
"./dist/+config.d.ts"
|
|
54
|
+
],
|
|
55
|
+
"FeatureList/*": [
|
|
56
|
+
"./components/FeatureList/*"
|
|
63
57
|
]
|
|
64
58
|
}
|
|
65
59
|
},
|
|
66
60
|
"peerDependencies": {
|
|
67
|
-
"
|
|
68
|
-
"react
|
|
61
|
+
"@types/node": "*",
|
|
62
|
+
"@types/react": "*",
|
|
63
|
+
"@types/react-dom": "*",
|
|
64
|
+
"react": "^18.0.0",
|
|
65
|
+
"react-dom": "^18.0.0",
|
|
66
|
+
"typescript": "*",
|
|
67
|
+
"vike": "0.4.161-commit-ba539a4",
|
|
68
|
+
"vite": "npm:@brillout/vite@5.1.0-commit-3dc7abd"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@brillout/docpress": "link:.",
|
|
72
|
-
"@brillout/framework-builder": "^0.1.1",
|
|
73
71
|
"@brillout/release-me": "^0.1.13",
|
|
74
|
-
"@brillout/test-e2e": "^0.5.25",
|
|
75
|
-
"@types/express": "^4.17.13",
|
|
76
72
|
"@types/node": "^15.12.1",
|
|
77
73
|
"@types/react": "^17.0.44",
|
|
78
74
|
"@types/react-dom": "^17.0.6",
|
|
79
|
-
"
|
|
80
|
-
"react": "^18.
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"rollup": "^2.74.1",
|
|
84
|
-
"tsup": "^7.0.0",
|
|
85
|
-
"tsx": "^3.12.1",
|
|
75
|
+
"react": "^18.2.0",
|
|
76
|
+
"react-dom": "^18.2.0",
|
|
77
|
+
"vike": "0.4.161-commit-ba539a4",
|
|
78
|
+
"vite": "npm:@brillout/vite@5.1.0-commit-3dc7abd",
|
|
86
79
|
"typescript": "^4.9.4"
|
|
87
80
|
},
|
|
88
|
-
"bin": {
|
|
89
|
-
"docpress": "./bin.js"
|
|
90
|
-
},
|
|
91
|
-
"files": [
|
|
92
|
-
"types.d.ts",
|
|
93
|
-
"bin.js",
|
|
94
|
-
"dist/"
|
|
95
|
-
],
|
|
96
81
|
"license": "MIT",
|
|
97
82
|
"repository": "https://github.com/brillout/docpress",
|
|
98
83
|
"publishConfig": {
|
package/parseEmojis.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { parseEmojis }
|
|
2
|
+
|
|
3
|
+
import twemoji from 'twemoji'
|
|
4
|
+
|
|
5
|
+
const emojiList = {
|
|
6
|
+
// https://emojipedia.org/no-entry/
|
|
7
|
+
':no_entry:': 0x26d4,
|
|
8
|
+
// https://emojipedia.org/warning/
|
|
9
|
+
':warning:': 0x26a0,
|
|
10
|
+
// https://emojipedia.org/trophy/
|
|
11
|
+
':trophy:': 0x1f3c6,
|
|
12
|
+
// https://emojipedia.org/construction/
|
|
13
|
+
':construction:': 0x1f6a7
|
|
14
|
+
/*
|
|
15
|
+
// https://emojipedia.org/red-heart/
|
|
16
|
+
':heart:': 0x2764,
|
|
17
|
+
*/
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseEmojis(html: string) {
|
|
21
|
+
Object.entries(emojiList).forEach(([shortcode, codepoint]) => {
|
|
22
|
+
if (!html.includes(shortcode)) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
const emojiStr = twemoji.convert.fromCodePoint(codepoint as any)
|
|
26
|
+
let emojiImg: any = twemoji.parse(emojiStr, {
|
|
27
|
+
folder: 'svg',
|
|
28
|
+
ext: '.svg'
|
|
29
|
+
})
|
|
30
|
+
const style = 'height: 1.275em; width: 1.275em; vertical-align: -20%'
|
|
31
|
+
emojiImg = emojiImg.replace('<img class="emoji" ', `<img style="${style}" `)
|
|
32
|
+
html = html.split(shortcode).join(emojiImg)
|
|
33
|
+
})
|
|
34
|
+
return html
|
|
35
|
+
}
|