@brillout/docpress 0.6.21 → 0.7.0

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 (107) hide show
  1. package/+config.ts +26 -3
  2. package/MobileHeader.tsx +5 -3
  3. package/PageLayout.tsx +28 -19
  4. package/algolia/DocSearch.css +6 -9
  5. package/autoScrollNav.ts +4 -3
  6. package/components/FeatureList/FeatureList.client.ts +6 -11
  7. package/components/Link.tsx +9 -9
  8. package/config/getConfig.ts +2 -1
  9. package/config/resolveHeadingsData.ts +20 -37
  10. package/config/resolvePageContext.ts +4 -6
  11. package/dist/+config.d.ts +25 -3
  12. package/dist/+config.js +7 -3
  13. package/dist/components/CodeBlockTransformer.d.ts +7 -0
  14. package/dist/components/CodeBlockTransformer.js +9 -0
  15. package/dist/components/Comment.d.ts +5 -0
  16. package/dist/components/Comment.js +6 -0
  17. package/dist/components/Consulting.d.ts +4 -0
  18. package/dist/components/Consulting.js +39 -0
  19. package/dist/components/Contributors.d.ts +7 -0
  20. package/dist/components/Contributors.js +74 -0
  21. package/dist/components/FileRemoved.d.ts +9 -0
  22. package/dist/components/FileRemoved.js +28 -0
  23. package/dist/components/HorizontalLine.d.ts +5 -0
  24. package/dist/components/HorizontalLine.js +15 -0
  25. package/dist/components/ImportMeta.d.ts +5 -0
  26. package/dist/components/ImportMeta.js +10 -0
  27. package/dist/components/Link.d.ts +16 -0
  28. package/dist/components/Link.js +108 -0
  29. package/dist/components/Note.d.ts +22 -0
  30. package/dist/components/Note.js +93 -0
  31. package/dist/components/P.d.ts +4 -0
  32. package/dist/components/P.js +17 -0
  33. package/dist/components/ReadingRecommendation.d.ts +6 -0
  34. package/dist/components/ReadingRecommendation.js +40 -0
  35. package/dist/components/RepoLink.d.ts +9 -0
  36. package/dist/components/RepoLink.js +22 -0
  37. package/dist/components/Sponsors.d.ts +22 -0
  38. package/dist/components/Sponsors.js +161 -0
  39. package/dist/components/Supporters.d.ts +32 -0
  40. package/dist/components/Supporters.js +80 -0
  41. package/dist/components/index.d.ts +15 -0
  42. package/dist/components/index.js +15 -0
  43. package/dist/config/getConfig.d.ts +3 -0
  44. package/dist/config/getConfig.js +14 -0
  45. package/dist/config/resolveHeadingsData.d.ts +16 -0
  46. package/dist/config/resolveHeadingsData.js +215 -0
  47. package/dist/config/resolvePageContext.d.ts +38 -0
  48. package/dist/config/resolvePageContext.js +23 -0
  49. package/dist/data/maintainersList.d.ts +9 -0
  50. package/dist/data/maintainersList.js +83 -0
  51. package/dist/data/sponsorsList.d.ts +3 -0
  52. package/dist/data/sponsorsList.js +151 -0
  53. package/dist/navigation/Navigation.d.ts +20 -0
  54. package/dist/navigation/Navigation.js +134 -0
  55. package/dist/navigation/NavigationHeader.d.ts +4 -0
  56. package/dist/navigation/NavigationHeader.js +85 -0
  57. package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.d.ts +6 -0
  58. package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.js +22 -0
  59. package/dist/parsePageSections.js +7 -3
  60. package/dist/parseTitle.d.ts +5 -0
  61. package/dist/parseTitle.js +52 -0
  62. package/dist/renderer/usePageContext.d.ts +17 -0
  63. package/dist/renderer/usePageContext.js +26 -0
  64. package/dist/types/Config.d.ts +30 -0
  65. package/dist/types/Config.js +1 -0
  66. package/dist/types/Heading.d.ts +43 -0
  67. package/dist/types/Heading.js +1 -0
  68. package/dist/utils/Emoji/Emoji.d.ts +8 -0
  69. package/dist/utils/Emoji/Emoji.js +191 -0
  70. package/dist/utils/Emoji/assets.d.ts +6 -0
  71. package/dist/utils/Emoji/assets.js +7 -0
  72. package/dist/utils/Emoji/index.d.ts +1 -0
  73. package/dist/utils/Emoji/index.js +1 -0
  74. package/dist/utils/client.d.ts +2 -0
  75. package/dist/utils/client.js +2 -0
  76. package/dist/utils/filter.d.ts +2 -0
  77. package/dist/utils/filter.js +11 -0
  78. package/dist/utils/isBrowser.d.ts +2 -0
  79. package/dist/utils/isBrowser.js +4 -0
  80. package/dist/utils/jsxToTextContent.d.ts +2 -0
  81. package/dist/utils/jsxToTextContent.js +12 -0
  82. package/dist/utils/objectAssign.d.ts +2 -0
  83. package/dist/utils/objectAssign.js +5 -0
  84. package/dist/utils/server.d.ts +7 -0
  85. package/dist/utils/server.js +7 -0
  86. package/dist/vite.config.js +5 -3
  87. package/installSectionUrlHashs.ts +7 -13
  88. package/navigation/Navigation.tsx +28 -19
  89. package/navigation/NavigationHeader.tsx +33 -4
  90. package/navigation/initMobileNavigation.ts +2 -11
  91. package/navigation/initPressKit.ts +5 -2
  92. package/navigation/navigation-fullscreen/initNavigationFullscreen.ts +12 -5
  93. package/package.json +21 -15
  94. package/parsePageSections.ts +6 -1
  95. package/renderer/getPageElement.tsx +16 -0
  96. package/renderer/onBeforeRender.ts +12 -0
  97. package/renderer/onRenderClient.tsx +79 -0
  98. package/renderer/onRenderHtml.tsx +7 -22
  99. package/renderer/usePageContext.tsx +20 -0
  100. package/tsconfig.config.json +1 -1
  101. package/tsconfig.json +1 -1
  102. package/types/Config.ts +6 -20
  103. package/types/Heading.ts +5 -5
  104. package/vite.config.ts +5 -3
  105. package/algolia/DocSearch.ts +0 -62
  106. package/navigation/Navigation.client.ts +0 -7
  107. package/renderer/client.ts +0 -4
@@ -0,0 +1,30 @@
1
+ export type { Config };
2
+ import type { HeadingDefinition, HeadingDetachedDefinition } from './Heading';
3
+ type Config = {
4
+ projectInfo: {
5
+ githubRepository: string;
6
+ githubIssues: string;
7
+ githubDiscussions?: string;
8
+ projectName: string;
9
+ projectVersion: string;
10
+ discordInvite?: string;
11
+ twitterProfile: string;
12
+ };
13
+ faviconUrl: string;
14
+ algolia: null | {
15
+ appId: string;
16
+ apiKey: string;
17
+ indexName: string;
18
+ };
19
+ headings: HeadingDefinition[];
20
+ headingsDetached: HeadingDetachedDefinition[];
21
+ /** Sets `<meta name="description" content="${tagline}" />` */
22
+ tagline: string;
23
+ websiteUrl: string;
24
+ bannerUrl?: string;
25
+ twitterHandle: string;
26
+ globalNote?: React.ReactNode;
27
+ i18n?: true;
28
+ pressKit?: true;
29
+ sponsorGithubAccount?: string;
30
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ export { HeadingResolved };
2
+ export { HeadingDetachedResolved };
3
+ export { HeadingDetachedDefinition };
4
+ export { HeadingDefinition };
5
+ type HeadingResolved = {
6
+ url?: null | string;
7
+ level: number;
8
+ title: string;
9
+ titleInNav: string;
10
+ linkBreadcrumb: string[];
11
+ sectionTitles?: string[];
12
+ } & Tmp;
13
+ type HeadingDetachedResolved = Omit<HeadingResolved, 'level' | 'linkBreadcrumb'> & {
14
+ level: 2;
15
+ linkBreadcrumb: null;
16
+ };
17
+ type HeadingDetachedDefinition = {
18
+ url: string;
19
+ title: string;
20
+ sectionTitles?: string[];
21
+ };
22
+ type HeadingDefinition = {
23
+ url?: null | string;
24
+ title: string;
25
+ titleInNav?: string;
26
+ } & HeadingDefinitionLevel & Tmp;
27
+ type IsCategory = {
28
+ url?: undefined;
29
+ titleDocument?: undefined;
30
+ titleInNav?: undefined;
31
+ };
32
+ type HeadingDefinitionLevel = ({
33
+ level: 1;
34
+ } & IsCategory) | ({
35
+ level: 4;
36
+ } & IsCategory) | {
37
+ level: 2;
38
+ sectionTitles?: string[];
39
+ url: null | string;
40
+ };
41
+ type Tmp = {
42
+ titleDocument?: string;
43
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export { Emoji };
3
+ export type { EmojiName };
4
+ type EmojiName = 'warning' | 'typescript' | 'shield' | 'mechanical-arm' | 'mountain' | 'rocket' | 'wrench' | 'compass' | 'seedling' | 'books' | 'plug' | 'earth' | 'gear' | 'red-heart' | 'high-voltage' | 'gem-stone' | 'dizzy' | 'sparkles' | 'writing-hang' | 'engine' | 'red-circle' | 'sparkling-heart' | 'gift' | 'package' | 'info' | 'lab' | 'trophy' | 'ribbon';
5
+ declare function Emoji({ name, style }: {
6
+ name: EmojiName;
7
+ style?: React.CSSProperties;
8
+ }): JSX.Element;
@@ -0,0 +1,191 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import React from 'react';
13
+ import { assert } from '../assert';
14
+ import { iconMechanicalArm, iconCompass, iconShield, iconTypescript, iconEngine } from './assets';
15
+ export { Emoji };
16
+ function Emoji(_a) {
17
+ var name = _a.name, style = _a.style;
18
+ var emoji =
19
+ // ***
20
+ // U+26A0
21
+ // https://emojipedia.org/warning/
22
+ // https://www.unicompat.com/26A0 => 94.1%
23
+ // https://www.unicompat.com/26A0-FE0F => 92.4%
24
+ // https://www.unicompat.com/2697 => 94.1%
25
+ (name === 'warning' && Unicode(0x26a0, { fontFamily: 'emoji' })) ||
26
+ // ***
27
+ // U+2697
28
+ // https://emojipedia.org/alembic/
29
+ // https://www.unicompat.com/2697 => 94.1%
30
+ (name === 'lab' && Unicode(0x2697)) ||
31
+ // ***
32
+ // U+2139
33
+ // https://emojipedia.org/information/
34
+ // https://www.unicompat.com/2139 => 94.8%
35
+ // https://www.unicompat.com/2139-FE0F => 92.4%
36
+ (name === 'info' && Unicode(0x2139, { fontFamily: 'emoji' })) ||
37
+ // ***
38
+ // U+1F4E6
39
+ // https://emojipedia.org/package/
40
+ // https://www.unicompat.com/1F4E6 => 94.1%
41
+ (name === 'package' && Unicode(0x1f4e6)) ||
42
+ // ***
43
+ // U+1F381
44
+ // https://emojipedia.org/wrapped-gift/
45
+ // https://www.unicompat.com/1F381 => 94.1%
46
+ (name === 'gift' && Unicode(0x1f381)) ||
47
+ // ***
48
+ // U+1F496
49
+ // https://emojipedia.org/sparkling-heart/
50
+ // https://www.unicompat.com/1F496 => 94.1%
51
+ (name === 'sparkling-heart' && Unicode(0x1f496)) ||
52
+ // ***
53
+ // U+2B55
54
+ // https://emojipedia.org/hollow-red-circle/
55
+ // https://www.unicompat.com/2B55 => 94.1%
56
+ (name === 'red-circle' && Unicode(0x2b55)) ||
57
+ // ***
58
+ (name === 'engine' && Img(iconEngine)) ||
59
+ // ***
60
+ // https://www.typescriptlang.org/branding/
61
+ (name === 'typescript' && Img(iconTypescript)) ||
62
+ // ***
63
+ // U+FE0F
64
+ // https://emojipedia.org/shield/
65
+ // https://www.unicompat.com/FE0F => 46.5%
66
+ // https://icon-sets.iconify.design/noto/shield/
67
+ (name === 'shield' && Img(iconShield)) ||
68
+ // ***
69
+ // U+270D
70
+ // https://emojipedia.org/writing-hand/
71
+ // https://www.unicompat.com/270D => 93.8%
72
+ (name === 'writing-hang' && Unicode(0x270d)) ||
73
+ // ***
74
+ // U+1F4AB
75
+ // https://emojipedia.org/dizzy/
76
+ // https://www.unicompat.com/1F4AB => 94.1%
77
+ (name === 'dizzy' && Unicode(0x1f4ab)) ||
78
+ // ***
79
+ // U+1F9BE
80
+ // https://iconify.design/icon-sets/noto/mechanical-arm.html
81
+ // https://emojipedia.org/mechanical-arm/
82
+ // https://www.unicompat.com/1f9be => 65.5%
83
+ (name === 'mechanical-arm' && Img(iconMechanicalArm)) ||
84
+ // ***
85
+ // U+1F680
86
+ // https://www.unicompat.com/1F680 => 94.1
87
+ (name === 'rocket' && Unicode(0x1f680)) ||
88
+ // ***
89
+ // U+1F527
90
+ // https://emojipedia.org/wrench/
91
+ // https://www.unicompat.com/1F527 => 94.1%
92
+ (name === 'wrench' && Unicode(0x1f527)) ||
93
+ // ***
94
+ // U+1F9ED
95
+ // https://iconify.design/icon-sets/noto/compass.html
96
+ // https://www.unicompat.com/1F9ED => 67.1%
97
+ (name === 'compass' && Img(iconCompass, '1.4em')) ||
98
+ // ***
99
+ // U+1F331
100
+ // https://www.unicompat.com/1F331 => 94.1%
101
+ (name === 'seedling' && Unicode(0x1f331)) ||
102
+ // ***
103
+ // U+1F4DA
104
+ // https://www.unicompat.com/1F4DA => 94.1%
105
+ (name === 'books' && Unicode(0x1f4da)) ||
106
+ // ***
107
+ // U+1F50C
108
+ // https://www.unicompat.com/1F50C => 94.1%
109
+ (name === 'plug' && Unicode(0x1f50c)) ||
110
+ // ***
111
+ // U+1F30D
112
+ // https://www.unicompat.com/1F30D => 88.8%
113
+ (name === 'earth' && Unicode(0x1f30d)) ||
114
+ // ***
115
+ // U+2699
116
+ // https://www.unicompat.com/2699 => 94.1%
117
+ (name === 'gear' && Unicode(0x2699)) ||
118
+ // ***
119
+ // U+2764
120
+ // https://emojipedia.org/red-heart/
121
+ // https://www.unicompat.com/2764 => 94.4%
122
+ // https://www.unicompat.com/2764-FE0F => 92.4%
123
+ (name === 'red-heart' && Unicode(0x2764, { fontFamily: 'emoji' })) ||
124
+ // U+26A1
125
+ // https://www.unicompat.com/26A1 => 94.1%
126
+ (name === 'high-voltage' && Unicode(0x26a1)) ||
127
+ // U+2728
128
+ // https://emojipedia.org/sparkles/
129
+ // https://www.unicompat.com/2728 => 94.1%
130
+ (name === 'sparkles' && Unicode(0x2728)) ||
131
+ // ***
132
+ // U+1F48E
133
+ // https://emojipedia.org/gem-stone/
134
+ // https://www.unicompat.com/1F48E => 94.1%
135
+ (name === 'gem-stone' && Unicode(0x1f48e)) ||
136
+ // ***
137
+ // 0x1F3C6
138
+ // https://emojipedia.org/trophy/
139
+ // https://www.unicompat.com/1F3C6 => 94.1%
140
+ (name === 'trophy' && Unicode(0x1f3c6)) ||
141
+ // ***
142
+ // U+1F397
143
+ // https://emojipedia.org/reminder-ribbon/
144
+ // unicompat.com is down
145
+ // - https://github.com/gelbartj/unicompat-public/issues/42
146
+ // - https://stackoverflow.com/questions/51042771/unicode-symbols-and-os-browser-font-support
147
+ (name === 'ribbon' && Unicode(0x1f397, { fontFamily: 'emoji' })) ||
148
+ false;
149
+ /* ======= Unused ========
150
+ // ***
151
+ // U+1FAA8
152
+ // https://emojipedia.org/rock/
153
+ // https://www.unicompat.com/1faa8 => 20.7%
154
+ //
155
+ // ***
156
+ // U+26F0
157
+ // https://emojipedia.org/mountain/
158
+ // https://iconify.design/icon-sets/noto/mountain.html
159
+ // https://www.unicompat.com/26F0 => 89.3%
160
+ (name === 'mountain' && Img(iconMountain)) ||
161
+ //
162
+ // ***
163
+ // U+2194
164
+ // https://emojipedia.org/left-right-arrow/
165
+ // https://www.unicompat.com/2194 => 95.0%
166
+ // Couldn't manage to show colored version
167
+ (name === 'left-right-arrow' && Unicode(0x2194)) ||
168
+ (name === 'left-right-arrow' && Unicode(0x2194, { fontFamily: 'reset' })) ||
169
+ (name === 'left-right-arrow' && Unicode(0xFE0F)) ||
170
+ (name === 'left-right-arrow' && Unicode(0xFE0F, { fontFamily: 'reset' })) ||
171
+ ======================== */
172
+ assert(emoji, { name: name });
173
+ return emoji;
174
+ function Unicode(codePoint, styleAddendum) {
175
+ var text = String.fromCodePoint(codePoint);
176
+ if (style || styleAddendum) {
177
+ return React.createElement('span', { style: __assign(__assign({}, style), styleAddendum) }, text);
178
+ }
179
+ else {
180
+ return React.createElement(React.Fragment, null, text);
181
+ }
182
+ }
183
+ function Img(imgSrc, width) {
184
+ if (width === void 0) { width = '1.15em'; }
185
+ var props = {
186
+ src: imgSrc,
187
+ style: __assign({ verticalAlign: 'text-top', fontSize: '1em', width: width }, style),
188
+ };
189
+ return React.createElement('img', props);
190
+ }
191
+ }
@@ -0,0 +1,6 @@
1
+ import iconMechanicalArm from './mechanical-arm.svg';
2
+ import iconCompass from './compass.svg';
3
+ import iconShield from './shield.svg';
4
+ import iconTypescript from './typescript.svg';
5
+ import iconEngine from './engine.png';
6
+ export { iconMechanicalArm, iconCompass, iconShield, iconTypescript, iconEngine };
@@ -0,0 +1,7 @@
1
+ import iconMechanicalArm from './mechanical-arm.svg';
2
+ //import iconMountain from './mountain.svg'
3
+ import iconCompass from './compass.svg';
4
+ import iconShield from './shield.svg';
5
+ import iconTypescript from './typescript.svg';
6
+ import iconEngine from './engine.png';
7
+ export { iconMechanicalArm, iconCompass, iconShield, iconTypescript, iconEngine };
@@ -0,0 +1 @@
1
+ export * from './Emoji';
@@ -0,0 +1 @@
1
+ export * from './Emoji';
@@ -0,0 +1,2 @@
1
+ export * from './assert';
2
+ export * from './isBrowser';
@@ -0,0 +1,2 @@
1
+ export * from './assert';
2
+ export * from './isBrowser';
@@ -0,0 +1,2 @@
1
+ export { filter };
2
+ declare function filter<T extends object>(obj: T, predicate: <K extends keyof T>(value: T[K], key: K) => boolean): T;
@@ -0,0 +1,11 @@
1
+ export { filter };
2
+ // https://stackoverflow.com/questions/66341757/typescript-how-to-filter-the-object
3
+ function filter(obj, predicate) {
4
+ var result = {};
5
+ Object.keys(obj).forEach(function (name) {
6
+ if (predicate(obj[name], name)) {
7
+ result[name] = obj[name];
8
+ }
9
+ });
10
+ return result;
11
+ }
@@ -0,0 +1,2 @@
1
+ export { isBrowser };
2
+ declare function isBrowser(): boolean;
@@ -0,0 +1,4 @@
1
+ export { isBrowser };
2
+ function isBrowser() {
3
+ return typeof window !== 'undefined';
4
+ }
@@ -0,0 +1,2 @@
1
+ export { jsxToTextContent };
2
+ declare function jsxToTextContent(node: JSX.Element | string): string;
@@ -0,0 +1,12 @@
1
+ import { assert } from './assert';
2
+ export { jsxToTextContent };
3
+ // https://stackoverflow.com/questions/34204975/react-is-there-something-similar-to-node-textcontent/60564620#60564620
4
+ function jsxToTextContent(node) {
5
+ if (['string', 'number'].includes(typeof node))
6
+ return String(node);
7
+ if (node instanceof Array)
8
+ return node.map(jsxToTextContent).join('');
9
+ if (typeof node === 'object' && node)
10
+ return jsxToTextContent(node.props.children);
11
+ assert(false);
12
+ }
@@ -0,0 +1,2 @@
1
+ export { objectAssign };
2
+ declare function objectAssign<Obj extends Object, ObjAddendum>(obj: Obj, objAddendum: ObjAddendum): asserts obj is Obj & ObjAddendum;
@@ -0,0 +1,5 @@
1
+ export { objectAssign };
2
+ // Same as `Object.assign()` but with type inference
3
+ function objectAssign(obj, objAddendum) {
4
+ Object.assign(obj, objAddendum);
5
+ }
@@ -0,0 +1,7 @@
1
+ export * from './client';
2
+ export * from './isBrowser';
3
+ export * from './filter';
4
+ export * from './determineSectionUrlHash';
5
+ export * from './jsxToTextContent';
6
+ export * from './objectAssign';
7
+ export * from './Emoji';
@@ -0,0 +1,7 @@
1
+ export * from './client';
2
+ export * from './isBrowser';
3
+ export * from './filter';
4
+ export * from './determineSectionUrlHash';
5
+ export * from './jsxToTextContent';
6
+ export * from './objectAssign';
7
+ export * from './Emoji';
@@ -23,10 +23,12 @@ var config = {
23
23
  includeAssetsImportedByServer: true,
24
24
  }),
25
25
  ],
26
- optimizeDeps: { include: ['@brillout/docpress', 'react-dom'] },
27
- // @ts-ignore
26
+ optimizeDeps: {
27
+ include: ['react', 'react-dom', 'react-dom/client'],
28
+ exclude: ['@brillout/docpress'],
29
+ },
28
30
  ssr: {
29
- noExternal: ['@brillout/docpress'],
31
+ noExternal: ['@brillout/docpress', '@docsearch/react'],
30
32
  },
31
33
  clearScreen: false,
32
34
  };
@@ -1,9 +1,6 @@
1
- import { assert } from './utils/client'
1
+ export { installSectionUrlHashs }
2
2
 
3
- installSectionUrlHashs()
4
- /* Let browser restore previous scroll
5
- jumpToSection()
6
- */
3
+ import { assert } from './utils/client'
7
4
 
8
5
  function installSectionUrlHashs() {
9
6
  const pageContainer = document.querySelector('.doc-page .page-container')
@@ -22,10 +19,14 @@ function installSectionUrlHashs() {
22
19
  jumpToSection()
23
20
  }
24
21
  })
22
+
23
+ /* Let browser restore previous scroll
24
+ jumpToSection()
25
+ */
25
26
  }
26
27
 
27
28
  function assertNavLink(urlHash: string, heading: HTMLHeadingElement) {
28
- const navigationEl = getNavigationEl()
29
+ const navigationEl = document.querySelector('#navigation-body')!
29
30
  {
30
31
  const { pathname } = window.location
31
32
  const parentNavLinkMatch = Array.from(navigationEl.querySelectorAll(`a[href="${pathname}"]`))
@@ -52,10 +53,3 @@ function jumpToSection() {
52
53
  }
53
54
  target.scrollIntoView()
54
55
  }
55
-
56
- function getNavigationEl() {
57
- const elems: HTMLElement[] = Array.from(document.querySelectorAll('#navigation-container'))
58
- assert(elems.length === 1)
59
- const navigationEl = elems[0]!
60
- return navigationEl
61
- }
@@ -8,6 +8,7 @@ import { NavigationHeader } from './NavigationHeader'
8
8
  import { assert, Emoji, assertWarning, jsxToTextContent } from '../utils/server'
9
9
  import './Navigation.css'
10
10
  import { NavigationFullscreenClose } from './navigation-fullscreen/NavigationFullscreenButton'
11
+ import { parseTitle } from '../parseTitle'
11
12
 
12
13
  type NavigationData = Parameters<typeof Navigation>[0]
13
14
 
@@ -26,17 +27,19 @@ function Navigation({
26
27
  <>
27
28
  <div id="navigation-container">
28
29
  <NavigationHeader />
29
- {isDetachedPage && (
30
- <>
31
- {navItems.length > 1 && (
32
- <NavigationContent id="navigation-content-detached" navItems={navItems} currentUrl={currentUrl} />
33
- )}
34
- <DetachedPageNote />
35
- </>
36
- )}
37
- <NavigationContent id="navigation-content-main" navItems={navItemsAll} currentUrl={currentUrl} />
38
- {/* <ScrollOverlay /> */}
39
- <NavigationFullscreenClose />
30
+ <div id="navigation-body">
31
+ {isDetachedPage && (
32
+ <>
33
+ {navItems.length > 1 && (
34
+ <NavigationContent id="navigation-content-detached" navItems={navItems} currentUrl={currentUrl} />
35
+ )}
36
+ <DetachedPageNote />
37
+ </>
38
+ )}
39
+ <NavigationContent id="navigation-content-main" navItems={navItemsAll} currentUrl={currentUrl} />
40
+ {/* <ScrollOverlay /> */}
41
+ <NavigationFullscreenClose />
42
+ </div>
40
43
  </div>
41
44
  </>
42
45
  )
@@ -49,8 +52,8 @@ function NavigationMask() {
49
52
  type NavItem = {
50
53
  level: number
51
54
  url?: string | null
52
- title: string | JSX.Element
53
- titleInNav: string | JSX.Element
55
+ title: string
56
+ titleInNav: string
54
57
  }
55
58
  type NavItemComputed = NavItem & {
56
59
  isActive: boolean
@@ -90,15 +93,21 @@ function NavItemComponent({
90
93
  navItem: NavItemComputed
91
94
  }) {
92
95
  assert([1, 2, 3, 4].includes(navItem.level), navItem)
96
+ const titleJsx = parseTitle(navItem.title)
97
+ const titleInNavJsx = parseTitle(navItem.titleInNav)
93
98
  if (navItem.level === 1 || navItem.level === 4) {
94
99
  assert(navItem.url === undefined)
95
100
  } else {
96
- const sectionTitle = jsxToTextContent(navItem.title)
101
+ const sectionTitle = jsxToTextContent(titleJsx)
97
102
  assertWarning(
98
103
  navItem.url,
99
- `${jsxToTextContent(
100
- navItem.titleInNav,
101
- )} is missing a URL hash. Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`,
104
+ [
105
+ `${jsxToTextContent(titleInNavJsx)} is missing a URL hash.`,
106
+ `Add a URL hash with: \`## ${sectionTitle}{#some-hash}\`.`,
107
+ /* TODO/eventually: not implemented yet.
108
+ `Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`,
109
+ */
110
+ ].join(' '),
102
111
  )
103
112
  }
104
113
  return (
@@ -116,8 +125,8 @@ function NavItemComponent({
116
125
  .join(' ')}
117
126
  href={navItem.url ?? undefined}
118
127
  >
119
- {/* <span className="nav-item-text">{navItem.titleInNav}</span> */}
120
- {navItem.titleInNav}
128
+ {/* <span className="nav-item-text">{titleInNavJsx}</span> */}
129
+ {titleInNavJsx}
121
130
  </a>
122
131
  )
123
132
  }
@@ -4,12 +4,16 @@ import iconTwitter from '../icons/twitter.svg'
4
4
  import iconDiscord from '../icons/discord.svg'
5
5
  import iconChangelog from '../icons/changelog.svg'
6
6
  import iconLanguages from '../icons/languages.svg'
7
- import { usePageContext } from '../renderer/usePageContext'
7
+ import { usePageContext, usePageContext2 } from '../renderer/usePageContext'
8
+ import { DocSearch } from '@docsearch/react'
9
+ import '@docsearch/css'
8
10
 
9
11
  export { NavigationHeader }
10
12
 
11
13
  function NavigationHeader() {
12
14
  const pageContext = usePageContext()
15
+ const pageContext2 = usePageContext2()
16
+ const { NavHeader } = pageContext2.config.NavHeader!
13
17
  return (
14
18
  <div
15
19
  id="navigation-header"
@@ -31,11 +35,11 @@ function NavigationHeader() {
31
35
  textDecoration: 'none',
32
36
  paddingTop: 12,
33
37
  paddingBottom: 7,
34
- ...pageContext.config.navHeaderWrapperStyle,
38
+ ...pageContext2.config.NavHeader?.navHeaderWrapperStyle,
35
39
  }}
36
40
  href="/"
37
41
  >
38
- {pageContext.config.navHeader}
42
+ <NavHeader />
39
43
  </a>
40
44
  <Links />
41
45
  </div>
@@ -53,6 +57,7 @@ function Links() {
53
57
  style={{ height: 21, position: 'relative', top: 0, left: 0 }}
54
58
  />
55
59
  )
60
+ const { algolia } = pageContext.meta
56
61
  return (
57
62
  <div
58
63
  style={{
@@ -67,7 +72,17 @@ function Links() {
67
72
  <LinkIcon className="decolorize-6" icon={iconDiscord} href={projectInfo.discordInvite} />
68
73
  )}
69
74
  <LinkIcon className="decolorize-7" icon={iconTwitter} href={projectInfo.twitterProfile} />
70
- <div className="decolorize-6 colorize-on-hover" id="docsearch-desktop" />
75
+ {algolia && (
76
+ <div className="decolorize-6 colorize-on-hover">
77
+ <DocSearch
78
+ appId={algolia.appId}
79
+ indexName={algolia.indexName}
80
+ apiKey={algolia.apiKey}
81
+ transformItems={transformItems}
82
+ insights={true}
83
+ />
84
+ </div>
85
+ )}
71
86
  {iconI18n}
72
87
  <ChangelogButton />
73
88
  </div>
@@ -111,3 +126,17 @@ function LinkIcon({ className, icon, href, style }: { className: string; icon: s
111
126
  </>
112
127
  )
113
128
  }
129
+
130
+ // Remove superfluous hash '#page-content' from URLs pointing to whole pages
131
+ // - https://github.com/algolia/docsearch/issues/1801
132
+ // - https://discourse.algolia.com/t/how-to-avoid-hash-in-search-result-url/6486
133
+ // - https://discourse.algolia.com/t/docsearchs-transformdata-function-cannot-remove-hashes-from-result-urls/8487
134
+ type TransformItems = Parameters<typeof DocSearch>[0]['transformItems']
135
+ const transformItems: TransformItems = (hits) => {
136
+ hits.map((hit) => {
137
+ if (hit.url.indexOf('#page-content') > 0) {
138
+ hit.url = hit.url.replace('#page-content', '')
139
+ }
140
+ })
141
+ return hits
142
+ }
@@ -1,9 +1,9 @@
1
1
  export { initMobileNavigation }
2
+ export { hideMobileNavigation }
2
3
 
3
4
  function initMobileNavigation() {
4
5
  activateMobileShowNavigationToggle()
5
6
  activateMobileNavigationMask()
6
- autoHideNavigationOverlayOnLinkClick()
7
7
  }
8
8
 
9
9
  function activateMobileShowNavigationToggle() {
@@ -15,18 +15,9 @@ function activateMobileNavigationMask() {
15
15
  navigationMask.onclick = toggleNavigation
16
16
  }
17
17
 
18
- function autoHideNavigationOverlayOnLinkClick() {
19
- document.addEventListener('click', (ev: any) => {
20
- const el = ev.target
21
- if (!el || !('classList' in el)) return
22
- if (!el.classList.contains('nav-item')) return
23
- hideNavigation()
24
- })
25
- }
26
-
27
18
  function toggleNavigation() {
28
19
  document.body.classList.toggle('mobile-show-navigation')
29
20
  }
30
- function hideNavigation() {
21
+ function hideMobileNavigation() {
31
22
  document.body.classList.remove('mobile-show-navigation')
32
23
  }
@@ -1,5 +1,7 @@
1
1
  export { initPressKit }
2
2
 
3
+ import { navigate } from 'vike/client/router'
4
+
3
5
  function initPressKit() {
4
6
  // Right click navigation header => show /press
5
7
  navigationHeaderRightClickInterceptor()
@@ -9,8 +11,9 @@ function navigationHeaderRightClickInterceptor() {
9
11
  const navHeader = document.getElementById('navigation-header')!
10
12
  if (!navHeader.classList.contains('press-kit')) return
11
13
  if (window.location.pathname === '/press') return
12
- navHeader.oncontextmenu = (ev) => {
14
+ const navHeaderImg = document.querySelector('#navigation-header-logo img') as HTMLElement
15
+ navHeaderImg.oncontextmenu = (ev) => {
13
16
  ev.preventDefault()
14
- window.location.href = '/press'
17
+ navigate('/press')
15
18
  }
16
19
  }