@brillout/docpress 0.6.20 → 0.6.21-commit-f22016e

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 (106) hide show
  1. package/+config.ts +26 -7
  2. package/MobileHeader.tsx +5 -3
  3. package/PageLayout.css +11 -11
  4. package/PageLayout.tsx +27 -20
  5. package/algolia/DocSearch.css +6 -9
  6. package/autoScrollNav.ts +4 -3
  7. package/components/FeatureList/FeatureList.client.ts +6 -11
  8. package/components/Link.tsx +9 -9
  9. package/config/getConfig.ts +2 -1
  10. package/config/resolveHeadingsData.ts +22 -30
  11. package/config/resolvePageContext.ts +4 -6
  12. package/dist/+config.d.ts +25 -8
  13. package/dist/+config.js +7 -7
  14. package/dist/components/CodeBlockTransformer.d.ts +7 -0
  15. package/dist/components/CodeBlockTransformer.js +9 -0
  16. package/dist/components/Comment.d.ts +5 -0
  17. package/dist/components/Comment.js +6 -0
  18. package/dist/components/Consulting.d.ts +4 -0
  19. package/dist/components/Consulting.js +39 -0
  20. package/dist/components/Contributors.d.ts +7 -0
  21. package/dist/components/Contributors.js +74 -0
  22. package/dist/components/FileRemoved.d.ts +9 -0
  23. package/dist/components/FileRemoved.js +28 -0
  24. package/dist/components/HorizontalLine.d.ts +5 -0
  25. package/dist/components/HorizontalLine.js +15 -0
  26. package/dist/components/ImportMeta.d.ts +5 -0
  27. package/dist/components/ImportMeta.js +10 -0
  28. package/dist/components/Link.d.ts +16 -0
  29. package/dist/components/Link.js +108 -0
  30. package/dist/components/Note.d.ts +22 -0
  31. package/dist/components/Note.js +93 -0
  32. package/dist/components/P.d.ts +4 -0
  33. package/dist/components/P.js +17 -0
  34. package/dist/components/ReadingRecommendation.d.ts +6 -0
  35. package/dist/components/ReadingRecommendation.js +40 -0
  36. package/dist/components/RepoLink.d.ts +9 -0
  37. package/dist/components/RepoLink.js +22 -0
  38. package/dist/components/Sponsors.d.ts +22 -0
  39. package/dist/components/Sponsors.js +161 -0
  40. package/dist/components/Supporters.d.ts +32 -0
  41. package/dist/components/Supporters.js +80 -0
  42. package/dist/components/index.d.ts +15 -0
  43. package/dist/components/index.js +15 -0
  44. package/dist/config/getConfig.d.ts +3 -0
  45. package/dist/config/getConfig.js +14 -0
  46. package/dist/config/resolveHeadingsData.d.ts +16 -0
  47. package/dist/config/resolveHeadingsData.js +223 -0
  48. package/dist/config/resolvePageContext.d.ts +38 -0
  49. package/dist/config/resolvePageContext.js +23 -0
  50. package/dist/data/maintainersList.d.ts +9 -0
  51. package/dist/data/maintainersList.js +83 -0
  52. package/dist/data/sponsorsList.d.ts +3 -0
  53. package/dist/data/sponsorsList.js +151 -0
  54. package/dist/navigation/Navigation.d.ts +20 -0
  55. package/dist/navigation/Navigation.js +128 -0
  56. package/dist/navigation/NavigationHeader.d.ts +4 -0
  57. package/dist/navigation/NavigationHeader.js +85 -0
  58. package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.d.ts +6 -0
  59. package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.js +22 -0
  60. package/dist/parsePageSections.js +2 -2
  61. package/dist/parseTitle.d.ts +5 -0
  62. package/dist/parseTitle.js +52 -0
  63. package/dist/renderer/usePageContext.d.ts +17 -0
  64. package/dist/renderer/usePageContext.js +26 -0
  65. package/dist/types/Config.d.ts +30 -0
  66. package/dist/types/Config.js +1 -0
  67. package/dist/types/Heading.d.ts +45 -0
  68. package/dist/types/Heading.js +1 -0
  69. package/dist/utils/Emoji/Emoji.d.ts +8 -0
  70. package/dist/utils/Emoji/Emoji.js +191 -0
  71. package/dist/utils/Emoji/assets.d.ts +6 -0
  72. package/dist/utils/Emoji/assets.js +7 -0
  73. package/dist/utils/Emoji/index.d.ts +1 -0
  74. package/dist/utils/Emoji/index.js +1 -0
  75. package/dist/utils/client.d.ts +2 -0
  76. package/dist/utils/client.js +2 -0
  77. package/dist/utils/filter.d.ts +2 -0
  78. package/dist/utils/filter.js +11 -0
  79. package/dist/utils/isBrowser.d.ts +2 -0
  80. package/dist/utils/isBrowser.js +4 -0
  81. package/dist/utils/jsxToTextContent.d.ts +2 -0
  82. package/dist/utils/jsxToTextContent.js +12 -0
  83. package/dist/utils/objectAssign.d.ts +2 -0
  84. package/dist/utils/objectAssign.js +5 -0
  85. package/dist/utils/server.d.ts +7 -0
  86. package/dist/utils/server.js +7 -0
  87. package/dist/vite.config.js +5 -3
  88. package/installSectionUrlHashs.ts +8 -14
  89. package/navigation/Navigation-layout.css +2 -2
  90. package/navigation/Navigation.tsx +22 -17
  91. package/navigation/NavigationHeader.tsx +33 -4
  92. package/navigation/initMobileNavigation.ts +16 -6
  93. package/navigation/initPressKit.ts +5 -2
  94. package/package.json +15 -12
  95. package/renderer/getPageElement.tsx +16 -0
  96. package/renderer/onBeforeRender.ts +12 -0
  97. package/renderer/onRenderClient.tsx +53 -0
  98. package/renderer/onRenderHtml.tsx +7 -22
  99. package/renderer/usePageContext.tsx +20 -0
  100. package/tsconfig.json +1 -1
  101. package/types/Config.ts +6 -20
  102. package/types/Heading.ts +4 -4
  103. package/vite.config.ts +5 -3
  104. package/algolia/DocSearch.ts +0 -62
  105. package/navigation/Navigation.client.ts +0 -7
  106. package/renderer/client.ts +0 -4
@@ -0,0 +1,45 @@
1
+ export { HeadingResolved };
2
+ export { HeadingDetachedResolved };
3
+ export { HeadingDetachedDefinition };
4
+ export { HeadingDefinition };
5
+ import type { EmojiName } from '../utils/server';
6
+ type HeadingResolved = {
7
+ url?: null | string;
8
+ level: number;
9
+ title: string;
10
+ titleInNav: string;
11
+ linkBreadcrumb: string[];
12
+ sectionTitles?: string[];
13
+ } & Tmp;
14
+ type HeadingDetachedResolved = Omit<HeadingResolved, 'level' | 'linkBreadcrumb'> & {
15
+ level: 2;
16
+ linkBreadcrumb: null;
17
+ };
18
+ type HeadingDetachedDefinition = {
19
+ url: string;
20
+ title: string;
21
+ sectionTitles?: string[];
22
+ };
23
+ type HeadingDefinition = {
24
+ url?: null | string;
25
+ title: string;
26
+ titleInNav?: string;
27
+ } & HeadingDefinitionLevel & Tmp;
28
+ type IsCategory = {
29
+ url?: undefined;
30
+ titleDocument?: undefined;
31
+ titleInNav?: undefined;
32
+ };
33
+ type HeadingDefinitionLevel = ({
34
+ level: 1;
35
+ titleEmoji: EmojiName;
36
+ } & IsCategory) | ({
37
+ level: 4;
38
+ } & IsCategory) | {
39
+ level: 2;
40
+ sectionTitles?: string[];
41
+ url: null | string;
42
+ };
43
+ type Tmp = {
44
+ titleDocument?: string;
45
+ };
@@ -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', '@docsearch/react', 'vike-contributors'],
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,12 +1,9 @@
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
- const pageContainer = document.querySelector('.doc-page #page-container')
6
+ const pageContainer = document.querySelector('.doc-page .page-container')
10
7
  if (!pageContainer) {
11
8
  assert(window.location.pathname === '/')
12
9
  return
@@ -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
- }
@@ -56,7 +56,7 @@
56
56
  background: white;
57
57
  z-index: 3;
58
58
  }
59
- #page-wrapper {
59
+ .page-wrapper {
60
60
  margin-left: calc(-1 * var(--navigation-fullscreen-button-width));
61
61
  }
62
62
  @media screen and (max-width: 1139px) {
@@ -70,7 +70,7 @@
70
70
  #navigation-fullscreen-button {
71
71
  display: none;
72
72
  }
73
- #page-wrapper {
73
+ .page-wrapper {
74
74
  margin-left: 0 !important;
75
75
  }
76
76
  #navigation-container {
@@ -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,14 +93,16 @@ 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
104
  `${jsxToTextContent(
100
- navItem.titleInNav,
105
+ titleInNavJsx,
101
106
  )} is missing a URL hash. Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`,
102
107
  )
103
108
  }
@@ -116,8 +121,8 @@ function NavItemComponent({
116
121
  .join(' ')}
117
122
  href={navItem.url ?? undefined}
118
123
  >
119
- {/* <span className="nav-item-text">{navItem.titleInNav}</span> */}
120
- {navItem.titleInNav}
124
+ {/* <span className="nav-item-text">{titleInNavJsx}</span> */}
125
+ {titleInNavJsx}
121
126
  </a>
122
127
  )
123
128
  }
@@ -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,10 @@
1
1
  export { initMobileNavigation }
2
2
 
3
+ hideNavigationOnLinkClick()
4
+
3
5
  function initMobileNavigation() {
4
6
  activateMobileShowNavigationToggle()
5
7
  activateMobileNavigationMask()
6
- autoHideNavigationOverlayOnLinkClick()
7
8
  }
8
9
 
9
10
  function activateMobileShowNavigationToggle() {
@@ -15,14 +16,23 @@ function activateMobileNavigationMask() {
15
16
  navigationMask.onclick = toggleNavigation
16
17
  }
17
18
 
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
19
+ function hideNavigationOnLinkClick() {
20
+ document.addEventListener('click', (ev) => {
21
+ const linkTag = findLinkTag(ev.target as HTMLElement)
22
+ if (!linkTag) return
23
23
  hideNavigation()
24
24
  })
25
25
  }
26
+ function findLinkTag(target: HTMLElement): null | HTMLElement {
27
+ while (target.tagName !== 'A') {
28
+ const { parentNode } = target
29
+ if (!parentNode) {
30
+ return null
31
+ }
32
+ target = parentNode as HTMLElement
33
+ }
34
+ return target
35
+ }
26
36
 
27
37
  function toggleNavigation() {
28
38
  document.body.classList.toggle('mobile-show-navigation')
@@ -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
  }