@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.
Files changed (146) hide show
  1. package/+config.ts +17 -0
  2. package/MobileHeader.tsx +68 -0
  3. package/PageLayout.css +42 -0
  4. package/PageLayout.tsx +39 -0
  5. package/algolia/DocSearch.css +34 -0
  6. package/algolia/DocSearch.ts +62 -0
  7. package/autoScrollNav.ts +36 -0
  8. package/components/CodeBlockTransformer.css +9 -0
  9. package/components/CodeBlockTransformer.tsx +18 -0
  10. package/components/Comment.tsx +7 -0
  11. package/components/Consulting.tsx +47 -0
  12. package/components/Contributors.tsx +113 -0
  13. package/components/EditPageNote.tsx +18 -0
  14. package/components/FeatureList/FeatureList.client.ts +66 -0
  15. package/{dist/components/features → components/FeatureList}/FeatureList.css +10 -2
  16. package/components/FeatureList/FeatureList.tsx +114 -0
  17. package/components/HorizontalLine.tsx +20 -0
  18. package/components/ImportMeta.tsx +11 -0
  19. package/components/Link.tsx +144 -0
  20. package/components/Note.css +54 -0
  21. package/components/Note.tsx +78 -0
  22. package/components/P.css +8 -0
  23. package/components/P.tsx +8 -0
  24. package/components/ReadingRecommendation.tsx +56 -0
  25. package/components/RepoLink.tsx +24 -0
  26. package/components/Sponsors/label.draft.svg +108 -0
  27. package/components/Sponsors.tsx +218 -0
  28. package/components/Supporters.tsx +136 -0
  29. package/components/index.ts +14 -0
  30. package/config/getConfig.ts +18 -0
  31. package/config/resolveConfig/resolveHeading.ts +0 -0
  32. package/config/resolvePageContext.ts +186 -0
  33. package/css/button.css +7 -0
  34. package/css/code/block.css +36 -0
  35. package/css/code/inline.css +27 -0
  36. package/css/code.css +20 -0
  37. package/css/colorize-on-hover.css +29 -0
  38. package/css/font.css +25 -0
  39. package/css/heading.css +45 -0
  40. package/css/index.css +12 -0
  41. package/css/link.css +17 -0
  42. package/css/reset.css +12 -0
  43. package/css/table.css +14 -0
  44. package/css/tooltip.css +11 -0
  45. package/data/maintainersList.tsx +92 -0
  46. package/data/sponsorsList.ts +147 -0
  47. package/dist/+config.d.ts +19 -0
  48. package/dist/+config.js +15 -0
  49. package/dist/markdownHeadingsVitePlugin.d.ts +13 -0
  50. package/dist/markdownHeadingsVitePlugin.js +170 -0
  51. package/dist/utils/assert.d.ts +6 -0
  52. package/dist/utils/assert.js +48 -0
  53. package/dist/utils/determineSectionUrlHash.d.ts +4 -0
  54. package/dist/utils/determineSectionUrlHash.js +38 -0
  55. package/dist/vite.config.d.ts +3 -0
  56. package/dist/vite.config.js +32 -0
  57. package/index.ts +4 -0
  58. package/installSectionUrlHashs.ts +60 -0
  59. package/markdownHeadingsVitePlugin.ts +150 -0
  60. package/navigation/Navigation-highlight.css +41 -0
  61. package/navigation/Navigation-items.css +119 -0
  62. package/navigation/Navigation-layout.css +127 -0
  63. package/navigation/Navigation.client.ts +43 -0
  64. package/navigation/Navigation.css +3 -0
  65. package/navigation/Navigation.tsx +211 -0
  66. package/navigation/NavigationHeader.tsx +111 -0
  67. package/navigation/navigation-fullscreen/NavigationFullscreenButton.css +32 -0
  68. package/navigation/navigation-fullscreen/NavigationFullscreenButton.tsx +44 -0
  69. package/navigation/navigation-fullscreen/initNavigationFullscreen.ts +116 -0
  70. package/package.json +38 -53
  71. package/parseEmojis.ts +35 -0
  72. package/parseTitle.ts +139 -0
  73. package/renderer/client.ts +4 -0
  74. package/renderer/onRenderHtml.tsx +69 -0
  75. package/renderer/usePageContext.tsx +25 -0
  76. package/tsconfig.config.json +7 -0
  77. package/tsconfig.json +15 -0
  78. package/types/Config.ts +46 -0
  79. package/types/Heading.ts +49 -0
  80. package/utils/Emoji/Emoji.ts +224 -0
  81. package/utils/Emoji/assets.ts +9 -0
  82. package/utils/Emoji/index.ts +1 -0
  83. package/utils/Emoji/mountain.svg +1 -0
  84. package/utils/assert.ts +51 -0
  85. package/utils/client.ts +2 -0
  86. package/utils/determineSectionUrlHash.ts +44 -0
  87. package/utils/filesystemPathHandling.ts +42 -0
  88. package/utils/filter.ts +12 -0
  89. package/utils/isBrowser.ts +5 -0
  90. package/utils/jsxToTextContent.ts +11 -0
  91. package/utils/objectAssign.ts +9 -0
  92. package/utils/server.ts +7 -0
  93. package/vite.config.ts +36 -0
  94. package/bin.js +0 -3
  95. package/dist/chunk-2ZTPUQGS.js +0 -58
  96. package/dist/chunk-3QC7HYIF.js +0 -7
  97. package/dist/chunk-MGOI4AFO.js +0 -165
  98. package/dist/chunk-NVJING6T.js +0 -91
  99. package/dist/chunk-QWL3MA4E.js +0 -171
  100. package/dist/chunk-UN23G34B.js +0 -157
  101. package/dist/cli/index.d.ts +0 -1
  102. package/dist/cli/index.js +0 -34
  103. package/dist/components/features/FeatureList.d.ts +0 -13
  104. package/dist/components/features/FeatureList.js +0 -7
  105. package/dist/components/features/initFeatureList.d.ts +0 -3
  106. package/dist/components/features/initFeatureList.js +0 -59
  107. package/dist/devServer-JKH6U5PF.js +0 -36
  108. package/dist/index.css +0 -120
  109. package/dist/index.d.ts +0 -221
  110. package/dist/index.js +0 -947
  111. package/dist/renderer/_default.page.client.css +0 -318
  112. package/dist/renderer/_default.page.client.d.ts +0 -1
  113. package/dist/renderer/_default.page.client.js +0 -218
  114. package/dist/renderer/_default.page.server.css +0 -310
  115. package/dist/renderer/_default.page.server.d.ts +0 -22
  116. package/dist/renderer/_default.page.server.js +0 -665
  117. package/readme.md +0 -5
  118. /package/{dist/chevron-R2IYJD62.svg → components/FeatureList/chevron.svg} +0 -0
  119. /package/{dist/label-MP75CTIA.svg → components/Sponsors/label.svg} +0 -0
  120. /package/{dist/medalBronze-CO4CTUR4.svg → components/Sponsors/medalBronze.svg} +0 -0
  121. /package/{dist/medalGold-UP6A73FL.svg → components/Sponsors/medalGold.svg} +0 -0
  122. /package/{dist/medalSilver-FAPGGOBN.svg → components/Sponsors/medalSilver.svg} +0 -0
  123. /package/{dist/Inter-Var-IOAEQULN.ttf → css/Inter-Var.ttf} +0 -0
  124. /package/{dist/alignable-B4QZV4X7.svg → data/sponsorsList/companyLogos/alignable.svg} +0 -0
  125. /package/{dist/bluefin-JQABZFGV.svg → data/sponsorsList/companyLogos/bluefin.svg} +0 -0
  126. /package/{dist/burdaforward-EUGURYZY.png → data/sponsorsList/companyLogos/burdaforward.png} +0 -0
  127. /package/{dist/contra-WLZBOPBV.svg → data/sponsorsList/companyLogos/contra.svg} +0 -0
  128. /package/{dist/ecosia-OYRLTR5T.svg → data/sponsorsList/companyLogos/ecosia.svg} +0 -0
  129. /package/{dist/inlang-GFRWND6X.png → data/sponsorsList/companyLogos/inlang.png} +0 -0
  130. /package/{dist/optimizers-SFEZF3NW.svg → data/sponsorsList/companyLogos/optimizers.svg} +0 -0
  131. /package/{dist/sourcegraph-YR2HADLS.svg → data/sponsorsList/companyLogos/sourcegraph.svg} +0 -0
  132. /package/{dist/changelog-IPI5F42D.svg → icons/changelog.svg} +0 -0
  133. /package/{dist/discord-JD33TUSF.svg → icons/discord.svg} +0 -0
  134. /package/{dist/github-P5ZSKN2N.svg → icons/github.svg} +0 -0
  135. /package/{dist/heart-OINVKOXO.svg → icons/heart.svg} +0 -0
  136. /package/{dist/languages-KXPKJFQL.svg → icons/languages.svg} +0 -0
  137. /package/{dist/people-72KKQHU4.svg → icons/people.svg} +0 -0
  138. /package/{dist/twitter-I7DXDN3J.svg → icons/twitter.svg} +0 -0
  139. /package/{dist/chevron-K3WPYLOP.svg → navigation/navigation-fullscreen/chevron.svg} +0 -0
  140. /package/{dist/close-IQXTDOHV.svg → navigation/navigation-fullscreen/close.svg} +0 -0
  141. /package/{dist/compass-2RWQU3E4.svg → utils/Emoji/compass.svg} +0 -0
  142. /package/{dist/engine-6Q6VSCVA.png → utils/Emoji/engine.png} +0 -0
  143. /package/{dist/mechanical-arm-TR7IQQMG.svg → utils/Emoji/mechanical-arm.svg} +0 -0
  144. /package/{dist/road-fork-3WZLW3HB.svg → utils/Emoji/road-fork.svg} +0 -0
  145. /package/{dist/shield-CU45RG5C.svg → utils/Emoji/shield.svg} +0 -0
  146. /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
+ &mdash; 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.5.40",
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.4.158",
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/_default.page.server.js": "./dist/renderer/_default.page.server.js",
41
- "./renderer/_default.page.client.js": "./dist/renderer/_default.page.client.js",
42
- "./renderer/_default.page.server.css": "./dist/renderer/_default.page.server.css",
43
- "./renderer/_default.page.client.css": "./dist/renderer/_default.page.client.css",
44
- ".": "./dist/index.js",
45
- "./features/FeatureList": "./dist/components/features/FeatureList.js",
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
- "./features/initFeatureList": {
50
- "browser": "./dist/components/features/initFeatureList.js"
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
- "dist/*"
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
- "features/*": [
62
- "dist/components/features/*"
52
+ "config": [
53
+ "./dist/+config.d.ts"
54
+ ],
55
+ "FeatureList/*": [
56
+ "./components/FeatureList/*"
63
57
  ]
64
58
  }
65
59
  },
66
60
  "peerDependencies": {
67
- "react": "18",
68
- "react-dom": "18"
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
- "docpress": "link:",
80
- "react": "^18.1.0",
81
- "react-dom": "^18.1.0",
82
- "rimraf": "^3.0.2",
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
+ }