@brillout/docpress 0.8.11 → 0.8.12

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 (35) hide show
  1. package/Layout.tsx +2 -0
  2. package/MenuModal.tsx +1 -4
  3. package/config/resolveHeadingsData.ts +2 -6
  4. package/dist/Layout.d.ts +11 -0
  5. package/dist/Layout.js +235 -0
  6. package/dist/Links.d.ts +6 -0
  7. package/dist/Links.js +58 -0
  8. package/dist/MenuModal.d.ts +7 -0
  9. package/dist/MenuModal.js +123 -0
  10. package/dist/autoScrollNav.d.ts +3 -0
  11. package/dist/autoScrollNav.js +35 -0
  12. package/dist/components/EditPageNote.d.ts +7 -0
  13. package/dist/components/EditPageNote.js +11 -0
  14. package/dist/config/resolveHeadingsData.d.ts +0 -1
  15. package/dist/config/resolveHeadingsData.js +2 -6
  16. package/dist/config/resolvePageContext.d.ts +0 -1
  17. package/dist/docsearch/SearchLink.d.ts +4 -0
  18. package/dist/docsearch/SearchLink.js +26 -0
  19. package/dist/docsearch/toggleDocsearchModal.d.ts +4 -0
  20. package/dist/docsearch/toggleDocsearchModal.js +26 -0
  21. package/dist/navigation/Navigation.d.ts +2 -1
  22. package/dist/navigation/Navigation.js +67 -38
  23. package/dist/renderer/determineColumnEntries.d.ts +3 -0
  24. package/dist/renderer/{getStyleColumnLayout.js → determineColumnEntries.js} +16 -64
  25. package/dist/utils/PassTrough.d.ts +3 -0
  26. package/dist/utils/PassTrough.js +6 -0
  27. package/dist/utils/getViewportWidth.d.ts +1 -0
  28. package/dist/utils/getViewportWidth.js +4 -0
  29. package/navigation/Navigation.css +2 -1
  30. package/navigation/Navigation.tsx +92 -63
  31. package/package.json +1 -1
  32. package/renderer/{getStyleColumnLayout.ts → determineColumnEntries.ts} +20 -90
  33. package/renderer/onRenderHtml.tsx +0 -4
  34. package/utils/getViewportWidth.ts +4 -0
  35. package/dist/renderer/getStyleColumnLayout.d.ts +0 -7
@@ -0,0 +1,26 @@
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
+ export { SearchLink };
13
+ import React from 'react';
14
+ import { openDocsearchModal } from './toggleDocsearchModal';
15
+ function SearchLink(props) {
16
+ return (React.createElement("a", __assign({}, props, { style: __assign({ height: '100%', display: 'flex', alignItems: 'center', cursor: 'pointer' }, props.style), className: "colorize-on-hover", onClick: function (ev) {
17
+ ev.preventDefault();
18
+ openDocsearchModal();
19
+ }, "aria-label": 'Ctrl\xa0+\xa0K' }),
20
+ React.createElement(SearchIcon, null),
21
+ "Search"));
22
+ }
23
+ function SearchIcon() {
24
+ return (React.createElement("svg", { style: { marginRight: 'var(--icon-text-padding)', lineHeight: 0, width: '1.3em' }, className: "decolorize-7", viewBox: "0 0 20 20" },
25
+ React.createElement("path", { d: "M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z", fill: "none", stroke: "currentColor", strokeWidth: "2" })));
26
+ }
@@ -0,0 +1,4 @@
1
+ export { closeDocsearchModal };
2
+ export { openDocsearchModal };
3
+ declare function closeDocsearchModal(): void;
4
+ declare function openDocsearchModal(): void;
@@ -0,0 +1,26 @@
1
+ export { closeDocsearchModal };
2
+ export { openDocsearchModal };
3
+ import { assert } from '../utils/client';
4
+ function closeDocsearchModal() {
5
+ if (isClosed())
6
+ return;
7
+ toggle();
8
+ }
9
+ function openDocsearchModal() {
10
+ if (!isClosed())
11
+ return;
12
+ toggle();
13
+ }
14
+ // There doesn't seem be an official API to open/close the DocSearch modal:
15
+ // - https://github.com/algolia/docsearch/issues/2321
16
+ // - https://github.com/algolia/docsearch/blob/90f3c6aabbc324fe49e9a1dfe0906fcd4d90f27b/packages/docsearch-react/src/DocSearch.tsx#L52
17
+ function toggle() {
18
+ // Trigger https://github.com/algolia/docsearch/blob/90f3c6aabbc324fe49e9a1dfe0906fcd4d90f27b/packages/docsearch-react/src/useDocSearchKeyboardEvents.ts#L71
19
+ window.dispatchEvent(new KeyboardEvent('keydown', { key: 'k', ctrlKey: true }));
20
+ }
21
+ function isClosed() {
22
+ var test1 = !document.body.classList.contains('DocSearch--active');
23
+ var test2 = document.getElementsByClassName('DocSearch-Modal').length === 0;
24
+ assert(test1 === test2);
25
+ return test1 || test2;
26
+ }
@@ -14,10 +14,11 @@ type NavItem = {
14
14
  menuModalFullWidth?: true;
15
15
  };
16
16
  type NavItemAll = NavItem & {
17
- isColumnLayoutElement?: true;
17
+ isColumnEntry?: ColumnMap;
18
18
  };
19
19
  declare function NavigationContent(props: {
20
20
  navItems: NavItem[];
21
21
  showOnlyRelevant?: true;
22
22
  columnLayout?: true;
23
23
  }): React.JSX.Element;
24
+ type ColumnMap = Record<number, number>;
@@ -11,13 +11,15 @@ var __assign = (this && this.__assign) || function () {
11
11
  };
12
12
  // TODO/refactor: rename file and/or component
13
13
  export { NavigationContent };
14
- import React from 'react';
14
+ import React, { useEffect, useState } from 'react';
15
15
  import { assert, assertWarning, jsxToTextContent } from '../utils/server';
16
16
  import './Navigation.css';
17
17
  import { parseTitle } from '../parseTitle';
18
18
  import { usePageContext } from '../renderer/usePageContext';
19
19
  import '@docsearch/css';
20
20
  import '../global.d.ts';
21
+ import { getViewportWidth } from '../utils/getViewportWidth';
22
+ import { navWidthMax, navWidthMin } from '../Layout';
21
23
  function NavigationContent(props) {
22
24
  var pageContext = usePageContext();
23
25
  var navItemsWithComputed = getNavItemsWithComputed(props.navItems, pageContext.urlPathname);
@@ -29,38 +31,44 @@ function NavigationContent(props) {
29
31
  }
30
32
  else {
31
33
  assert(!props.showOnlyRelevant);
32
- var navItemsColumnLayout = groupByColumnLayout(navItemsWithComputed);
33
- var paddingBottom_1 = 40;
34
- navContent = (React.createElement(React.Fragment, null, navItemsColumnLayout.map(function (_a, i) {
35
- var navItemsColumnEntries = _a.navItemsColumnEntries, isFullWidth = _a.isFullWidth;
36
- return (React.createElement("div", { key: i, style: {
37
- display: 'flex',
38
- justifyContent: 'center',
39
- } },
40
- React.createElement("div", { className: "column-layout-".concat(i) + (!isFullWidth ? '' : ' nav-category nav-category-full-width'), style: {
41
- flexGrow: 1,
42
- columnGap: 20,
43
- paddingBottom: isFullWidth ? paddingBottom_1 : undefined,
44
- } },
45
- navItemsColumnEntries.map(function (navItemColumnEntry, j) { return (React.createElement("div", { key: j, className: 'column-layout-entry' + (isFullWidth ? '' : ' nav-category'), style: {
46
- breakInside: 'avoid',
47
- paddingBottom: !isFullWidth ? paddingBottom_1 : undefined,
48
- paddingTop: isFullWidth ? undefined : 0,
49
- width: '100%',
50
- } },
51
- React.createElement(NavItemComponent, { navItem: navItemColumnEntry }),
52
- navItemColumnEntry.navItemChilds.map(function (navItem, k) { return (React.createElement(NavItemComponent, { navItem: navItem, key: k })); }),
53
- React.createElement(CategoryBorder, { navItemLevel1: isFullWidth ? undefined : navItemColumnEntry, paddingBottom: paddingBottom_1 }))); }),
54
- React.createElement(CategoryBorder, { navItemLevel1: !isFullWidth ? undefined : navItemsColumnEntries[0], paddingBottom: paddingBottom_1 }))));
55
- })));
34
+ navContent = React.createElement(NavigationColumnLayout, { navItemsWithComputed: navItemsWithComputed });
56
35
  }
57
36
  return (React.createElement("div", { className: "navigation-content", style: { marginTop: 10 } }, navContent));
58
37
  }
38
+ function NavigationColumnLayout(props) {
39
+ var _a = useState(), viewportWidth = _a[0], setViewportWidth = _a[1];
40
+ var updateviewportwidth = function () { return setViewportWidth(getViewportWidth()); };
41
+ useEffect(function () {
42
+ updateviewportwidth();
43
+ window.addEventListener('resize', updateviewportwidth, { passive: true });
44
+ });
45
+ var navItemsByColumnLayouts = getNavItemsByColumnLayouts(props.navItemsWithComputed, viewportWidth);
46
+ return (React.createElement(React.Fragment, null, navItemsByColumnLayouts.map(function (_a, i) {
47
+ var columns = _a.columns, isFullWidth = _a.isFullWidth;
48
+ return (React.createElement("div", { key: i, style: {
49
+ display: 'flex',
50
+ width: columns.length * (navWidthMax + 20),
51
+ justifyContent: 'space-between',
52
+ maxWidth: '100%',
53
+ margin: 'auto',
54
+ marginBottom: 40,
55
+ } },
56
+ columns.map(function (columnEntry, j) { return (React.createElement("div", { key: j, style: {
57
+ flexGrow: 1,
58
+ maxWidth: navWidthMax,
59
+ display: 'flex',
60
+ flexDirection: 'column',
61
+ paddingTop: isFullWidth && j !== 0 ? 36 : undefined,
62
+ } }, columnEntry.map(function (navItems, k) { return (React.createElement("div", { key: k },
63
+ navItems.map(function (navItem, l) { return (React.createElement(NavItemComponent, { navItem: navItem, key: l })); }),
64
+ React.createElement(CategoryBorder, { navItemLevel1: isFullWidth ? undefined : navItems[0] }))); }))); }),
65
+ React.createElement(CategoryBorder, { navItemLevel1: !isFullWidth ? undefined : columns[0][0][0] })));
66
+ })));
67
+ }
59
68
  function CategoryBorder(_a) {
60
- var navItemLevel1 = _a.navItemLevel1, paddingBottom = _a.paddingBottom;
69
+ var navItemLevel1 = _a.navItemLevel1;
61
70
  return !navItemLevel1 ? null : (React.createElement("div", { className: "category-border", style: {
62
71
  background: navItemLevel1.color,
63
- height: "calc(100% - ".concat(paddingBottom, "px - 53px)"),
64
72
  } }));
65
73
  }
66
74
  function NavItemComponent(_a) {
@@ -108,33 +116,54 @@ function NavItemComponent(_a) {
108
116
  return React.createElement("span", __assign({}, props));
109
117
  }
110
118
  }
111
- function groupByColumnLayout(navItems) {
112
- var navItemsColumnLayout = [];
113
- var navItemsColumnEntries = [];
119
+ function getNavItemsByColumnLayouts(navItems, viewportWidth) {
120
+ if (viewportWidth === void 0) { viewportWidth = 0; }
121
+ var navItemsByColumnEntries = getNavItemsByColumnEntries(navItems);
122
+ var numberOfColumnsMax = Math.floor(viewportWidth / navWidthMin) || 1;
123
+ var navItemsByColumnLayouts = navItemsByColumnEntries.map(function (_a) {
124
+ var columnEntries = _a.columnEntries, isFullWidth = _a.isFullWidth;
125
+ var numberOfColumns = Math.min(numberOfColumnsMax, columnEntries.length);
126
+ var columns = [];
127
+ columnEntries.forEach(function (columnEntry) {
128
+ var _a;
129
+ var idx = numberOfColumns === 1 ? 0 : columnEntry.columnMap[numberOfColumns];
130
+ assert(idx >= 0);
131
+ (_a = columns[idx]) !== null && _a !== void 0 ? _a : (columns[idx] = []);
132
+ columns[idx].push(columnEntry.navItems);
133
+ });
134
+ var navItemsByColumnLayout = { columns: columns, isFullWidth: isFullWidth };
135
+ return navItemsByColumnLayout;
136
+ });
137
+ return navItemsByColumnLayouts;
138
+ }
139
+ function getNavItemsByColumnEntries(navItems) {
140
+ var navItemsByColumnEntries = [];
141
+ var columnEntries = [];
142
+ var columnEntry;
114
143
  var isFullWidth;
115
144
  navItems.forEach(function (navItem) {
116
145
  if (navItem.level === 1) {
117
146
  var isFullWidthPrevious = isFullWidth;
118
147
  isFullWidth = !!navItem.menuModalFullWidth;
119
148
  if (isFullWidthPrevious !== undefined && isFullWidthPrevious !== isFullWidth) {
120
- navItemsColumnLayout.push({ navItemsColumnEntries: navItemsColumnEntries, isFullWidth: isFullWidthPrevious });
121
- navItemsColumnEntries = [];
149
+ navItemsByColumnEntries.push({ columnEntries: columnEntries, isFullWidth: isFullWidthPrevious });
150
+ columnEntries = [];
122
151
  }
123
152
  }
124
153
  assert(isFullWidth !== undefined);
125
- if (navItem.isColumnLayoutElement) {
154
+ if (navItem.isColumnEntry) {
126
155
  assert(navItem.level === 1 || navItem.level === 4);
127
- var navItemColumnEntry = __assign(__assign({}, navItem), { navItemChilds: [] });
128
- navItemsColumnEntries.push(navItemColumnEntry);
156
+ columnEntry = { navItems: [navItem], columnMap: navItem.isColumnEntry };
157
+ columnEntries.push(columnEntry);
129
158
  }
130
159
  else {
131
160
  assert(navItem.level !== 1);
132
- navItemsColumnEntries[navItemsColumnEntries.length - 1].navItemChilds.push(navItem);
161
+ columnEntry.navItems.push(navItem);
133
162
  }
134
163
  });
135
164
  assert(isFullWidth !== undefined);
136
- navItemsColumnLayout.push({ navItemsColumnEntries: navItemsColumnEntries, isFullWidth: isFullWidth });
137
- return navItemsColumnLayout;
165
+ navItemsByColumnEntries.push({ columnEntries: columnEntries, isFullWidth: isFullWidth });
166
+ return navItemsByColumnEntries;
138
167
  }
139
168
  function getNavItemsWithComputed(navItems, currentUrl) {
140
169
  var navItemIdx;
@@ -0,0 +1,3 @@
1
+ export { determineColumnEntries };
2
+ import { type NavItemAll } from '../navigation/Navigation';
3
+ declare function determineColumnEntries(navItems: NavItemAll[]): undefined;
@@ -1,7 +1,3 @@
1
- var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
2
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
3
- return cooked;
4
- };
5
1
  var __assign = (this && this.__assign) || function () {
6
2
  __assign = Object.assign || function(t) {
7
3
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -22,14 +18,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
22
18
  }
23
19
  return to.concat(ar || Array.prototype.slice.call(from));
24
20
  };
25
- export { getStyleColumnLayout };
26
- export { determineColumnLayoutEntries };
27
- import { css } from '../utils/css';
21
+ export { determineColumnEntries };
28
22
  import { assert, assertUsage, isBrowser } from '../utils/server';
29
23
  assert(!isBrowser());
30
- var columnWidthMin = 300;
31
- var columnWidthMax = 350;
32
- function determineColumnLayoutEntries(navItems) {
24
+ function determineColumnEntries(navItems) {
33
25
  var navItemsWithLength = navItems.map(function (navItem) { return (__assign(__assign({}, navItem), { numberOfHeadings: navItem.level === 1 || navItem.level === 4 ? 0 : null })); });
34
26
  var navItemLevel1;
35
27
  var navItemLevel4;
@@ -54,7 +46,7 @@ function determineColumnLayoutEntries(navItems) {
54
46
  }
55
47
  });
56
48
  var columnLayouts = [];
57
- var columns = [];
49
+ var columnEntries = [];
58
50
  var isFullWidth;
59
51
  navItemsWithLength.forEach(function (navItem, i) {
60
52
  var isFullWidthBegin = false;
@@ -64,8 +56,8 @@ function determineColumnLayoutEntries(navItems) {
64
56
  if (isFullWidth)
65
57
  isFullWidthBegin = true;
66
58
  if (isFullWidthPrevious !== undefined && isFullWidthPrevious !== isFullWidth) {
67
- columnLayouts.push(columns);
68
- columns = [];
59
+ columnLayouts.push(columnEntries);
60
+ columnEntries = [];
69
61
  }
70
62
  }
71
63
  var navItemPrevious = navItemsWithLength[i - 1];
@@ -87,64 +79,25 @@ function determineColumnLayoutEntries(navItems) {
87
79
  assert(navItemNext.numberOfHeadings);
88
80
  numberOfHeadings = navItemNext.numberOfHeadings;
89
81
  }
90
- columns.push(numberOfHeadings);
91
- navItems[i].isColumnLayoutElement = true;
82
+ columnEntries.push({ navItemLeader: navItems[i], numberOfEntries: numberOfHeadings });
92
83
  }
93
84
  });
94
- columnLayouts.push(columns);
95
- return { columnLayouts: columnLayouts };
96
- }
97
- function getStyleColumnLayout(columnLayouts) {
98
- var style = '\n' + css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n.column-layout-entry {\n break-before: avoid;\n}\n"], ["\n.column-layout-entry {\n break-before: avoid;\n}\n"])));
99
- style += '\n';
100
- columnLayouts.forEach(function (columns, i) {
85
+ assert(columnEntries);
86
+ columnLayouts.push(columnEntries);
87
+ columnLayouts.forEach(function (columnEntries) {
101
88
  var _loop_1 = function (numberOfColumns) {
102
- var styleGivenNumberOfColumns = [];
103
- styleGivenNumberOfColumns.push(css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n.column-layout-", " {\n column-count: ", ";\n max-width: min(100%, ", "px);\n}\n"], ["\n.column-layout-", " {\n column-count: ", ";\n max-width: min(100%, ", "px);\n}\n"])), i, numberOfColumns, columnWidthMax * numberOfColumns));
104
- var columnsIdMap = determineColumns(columns, numberOfColumns);
105
- var columnBreakPoints = determineColumnBreakPoints(columnsIdMap);
106
- columnBreakPoints.forEach(function (columnBreakPoint, columnUngroupedId) {
107
- if (!columnBreakPoint)
108
- return;
109
- styleGivenNumberOfColumns.push(css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n.column-layout-", " .column-layout-entry:nth-child(", ") {\n break-before: column;\n padding-top: 36px;\n}\n"], ["\n.column-layout-", " .column-layout-entry:nth-child(", ") {\n break-before: column;\n padding-top: 36px;\n}\n"])), i, columnUngroupedId + 1));
89
+ var columnsIdMap = determineColumns(columnEntries.map(function (columnEntry) { return columnEntry.numberOfEntries; }), numberOfColumns);
90
+ columnEntries.forEach(function (columnEntry, i) {
91
+ var _a;
92
+ var _b;
93
+ (_a = (_b = columnEntry.navItemLeader).isColumnEntry) !== null && _a !== void 0 ? _a : (_b.isColumnEntry = {});
94
+ columnEntry.navItemLeader.isColumnEntry[numberOfColumns] = columnsIdMap[i];
110
95
  });
111
- {
112
- assert(styleGivenNumberOfColumns.length > 0);
113
- var getMaxWidth = function (columns) { return (columns + 1) * columnWidthMin - 1; };
114
- var isFirst = numberOfColumns === 1;
115
- var isLast = numberOfColumns === columns.length;
116
- var query = [
117
- !isFirst && "(min-width: ".concat(getMaxWidth(numberOfColumns - 1) + 1, "px)"),
118
- !isLast && "(max-width: ".concat(getMaxWidth(numberOfColumns), "px)"),
119
- ]
120
- .filter(Boolean)
121
- .join(' and ');
122
- if (query) {
123
- styleGivenNumberOfColumns = __spreadArray(__spreadArray(["@container ".concat(query, " {")], styleGivenNumberOfColumns, true), ["}"], false);
124
- }
125
- }
126
- style += styleGivenNumberOfColumns.join('\n') + '\n';
127
96
  };
128
- for (var numberOfColumns = columns.length; numberOfColumns >= 1; numberOfColumns--) {
97
+ for (var numberOfColumns = columnEntries.length; numberOfColumns >= 1; numberOfColumns--) {
129
98
  _loop_1(numberOfColumns);
130
99
  }
131
100
  });
132
- return style;
133
- }
134
- function determineColumnBreakPoints(columnsIdMap) {
135
- assert(columnsIdMap[0] === 0);
136
- var columnGroupedIdBefore = 0;
137
- var columnBreakPoints = columnsIdMap.map(function (columnGroupedId) {
138
- assert([
139
- //
140
- columnGroupedIdBefore,
141
- columnGroupedIdBefore + 1,
142
- ].includes(columnGroupedId));
143
- var val = columnGroupedId !== columnGroupedIdBefore;
144
- columnGroupedIdBefore = columnGroupedId;
145
- return val;
146
- });
147
- return columnBreakPoints;
148
101
  }
149
102
  function determineColumns(columnsUnmerged, numberOfColumns) {
150
103
  assert(numberOfColumns <= columnsUnmerged.length);
@@ -188,4 +141,3 @@ function mergeColumns(columnsMerging, numberOfColumns) {
188
141
  assert(columnsMergingMod.length === columnsMerging.length - 1);
189
142
  return mergeColumns(columnsMergingMod, numberOfColumns);
190
143
  }
191
- var templateObject_1, templateObject_2, templateObject_3;
@@ -0,0 +1,3 @@
1
+ export { PassThrough };
2
+ import React from 'react';
3
+ declare function PassThrough({ children }: any): React.JSX.Element;
@@ -0,0 +1,6 @@
1
+ export { PassThrough };
2
+ import React from 'react';
3
+ function PassThrough(_a) {
4
+ var children = _a.children;
5
+ return React.createElement(React.Fragment, null, children);
6
+ }
@@ -0,0 +1 @@
1
+ export declare function getViewportWidth(): number;
@@ -0,0 +1,4 @@
1
+ export function getViewportWidth() {
2
+ // `window.innerWidth` inlcudes scrollbar width: https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
3
+ return document.documentElement.clientWidth;
4
+ }
@@ -99,7 +99,7 @@
99
99
  content: "";
100
100
  }
101
101
 
102
- .nav-category {
102
+ :has(> .category-border) {
103
103
  position: relative
104
104
  }
105
105
  .category-border {
@@ -107,6 +107,7 @@
107
107
  top: 0;
108
108
  left: 0;
109
109
  transform: translate(0, 53px);
110
+ height: calc(100% - 53px);
110
111
  width: 3px;
111
112
  z-index: 99;
112
113
  }
@@ -4,13 +4,15 @@ export { NavigationContent }
4
4
  export type { NavItem }
5
5
  export type { NavItemAll }
6
6
 
7
- import React from 'react'
7
+ import React, { useEffect, useState } from 'react'
8
8
  import { assert, assertWarning, jsxToTextContent } from '../utils/server'
9
9
  import './Navigation.css'
10
10
  import { parseTitle } from '../parseTitle'
11
11
  import { usePageContext } from '../renderer/usePageContext'
12
12
  import '@docsearch/css'
13
13
  import '../global.d.ts'
14
+ import { getViewportWidth } from '../utils/getViewportWidth'
15
+ import { navWidthMax, navWidthMin } from '../Layout'
14
16
 
15
17
  type NavItem = {
16
18
  level: number
@@ -21,7 +23,7 @@ type NavItem = {
21
23
  menuModalFullWidth?: true
22
24
  }
23
25
  type NavItemAll = NavItem & {
24
- isColumnLayoutElement?: true
26
+ isColumnEntry?: ColumnMap
25
27
  }
26
28
  function NavigationContent(props: {
27
29
  navItems: NavItem[]
@@ -38,71 +40,74 @@ function NavigationContent(props: {
38
40
  .map((navItem, i) => <NavItemComponent navItem={navItem} key={i} />)
39
41
  } else {
40
42
  assert(!props.showOnlyRelevant)
41
- const navItemsColumnLayout = groupByColumnLayout(navItemsWithComputed)
42
- const paddingBottom = 40
43
- navContent = (
44
- <>
45
- {navItemsColumnLayout.map(({ navItemsColumnEntries, isFullWidth }, i) => (
46
- <div
47
- key={i}
48
- style={{
49
- display: 'flex',
50
- justifyContent: 'center',
51
- }}
52
- >
43
+ navContent = <NavigationColumnLayout navItemsWithComputed={navItemsWithComputed} />
44
+ }
45
+
46
+ return (
47
+ <div className="navigation-content" style={{ marginTop: 10 }}>
48
+ {navContent}
49
+ </div>
50
+ )
51
+ }
52
+
53
+ function NavigationColumnLayout(props: { navItemsWithComputed: NavItemComputed[] }) {
54
+ let [viewportWidth, setViewportWidth] = useState<number | undefined>()
55
+ const updateviewportwidth = () => setViewportWidth(getViewportWidth())
56
+ useEffect(() => {
57
+ updateviewportwidth()
58
+ window.addEventListener('resize', updateviewportwidth, { passive: true })
59
+ })
60
+
61
+ const navItemsByColumnLayouts = getNavItemsByColumnLayouts(props.navItemsWithComputed, viewportWidth)
62
+
63
+ return (
64
+ <>
65
+ {navItemsByColumnLayouts.map(({ columns, isFullWidth }, i) => (
66
+ <div
67
+ key={i}
68
+ style={{
69
+ display: 'flex',
70
+ width: columns.length * (navWidthMax + 20),
71
+ justifyContent: 'space-between',
72
+ maxWidth: '100%',
73
+ margin: 'auto',
74
+ marginBottom: 40,
75
+ }}
76
+ >
77
+ {columns.map((columnEntry, j) => (
53
78
  <div
54
- className={`column-layout-${i}` + (!isFullWidth ? '' : ' nav-category nav-category-full-width')}
79
+ key={j}
55
80
  style={{
56
81
  flexGrow: 1,
57
- columnGap: 20,
58
- paddingBottom: isFullWidth ? paddingBottom : undefined,
82
+ maxWidth: navWidthMax,
83
+ display: 'flex',
84
+ flexDirection: 'column',
85
+ paddingTop: isFullWidth && j !== 0 ? 36 : undefined,
59
86
  }}
60
87
  >
61
- {navItemsColumnEntries.map((navItemColumnEntry, j) => (
62
- <div
63
- key={j}
64
- className={'column-layout-entry' + (isFullWidth ? '' : ' nav-category')}
65
- style={{
66
- breakInside: 'avoid',
67
- paddingBottom: !isFullWidth ? paddingBottom : undefined,
68
- paddingTop: isFullWidth ? undefined : 0,
69
- width: '100%',
70
- }}
71
- >
72
- <NavItemComponent navItem={navItemColumnEntry} />
73
- {navItemColumnEntry.navItemChilds.map((navItem, k) => (
74
- <NavItemComponent navItem={navItem} key={k} />
88
+ {columnEntry.map((navItems, k) => (
89
+ <div key={k}>
90
+ {navItems.map((navItem, l) => (
91
+ <NavItemComponent navItem={navItem} key={l} />
75
92
  ))}
76
- <CategoryBorder
77
- navItemLevel1={isFullWidth ? undefined : navItemColumnEntry!}
78
- paddingBottom={paddingBottom}
79
- />
93
+ <CategoryBorder navItemLevel1={isFullWidth ? undefined : navItems[0]!} />
80
94
  </div>
81
95
  ))}
82
- <CategoryBorder
83
- navItemLevel1={!isFullWidth ? undefined : navItemsColumnEntries[0]!}
84
- paddingBottom={paddingBottom}
85
- />
86
96
  </div>
87
- </div>
88
- ))}
89
- </>
90
- )
91
- }
92
-
93
- return (
94
- <div className="navigation-content" style={{ marginTop: 10 }}>
95
- {navContent}
96
- </div>
97
+ ))}
98
+ <CategoryBorder navItemLevel1={!isFullWidth ? undefined : columns[0][0][0]!} />
99
+ </div>
100
+ ))}
101
+ </>
97
102
  )
98
103
  }
99
- function CategoryBorder({ navItemLevel1, paddingBottom }: { navItemLevel1?: NavItemComputed; paddingBottom: number }) {
104
+
105
+ function CategoryBorder({ navItemLevel1 }: { navItemLevel1?: NavItemComputed }) {
100
106
  return !navItemLevel1 ? null : (
101
107
  <div
102
108
  className="category-border"
103
109
  style={{
104
110
  background: navItemLevel1.color!,
105
- height: `calc(100% - ${paddingBottom}px - 53px)`,
106
111
  }}
107
112
  />
108
113
  )
@@ -162,33 +167,57 @@ function NavItemComponent({
162
167
  }
163
168
  }
164
169
 
165
- type NavItemsColumnEntry = NavItemComputed & { navItemChilds: NavItemComputed[] }
166
- function groupByColumnLayout(navItems: NavItemComputed[]) {
167
- const navItemsColumnLayout: { navItemsColumnEntries: NavItemsColumnEntry[]; isFullWidth: boolean }[] = []
168
- let navItemsColumnEntries: NavItemsColumnEntry[] = []
170
+ type NavItemsByColumnLayout = { columns: NavItemComputed[][][]; isFullWidth: boolean }
171
+ function getNavItemsByColumnLayouts(navItems: NavItemComputed[], viewportWidth: number = 0): NavItemsByColumnLayout[] {
172
+ const navItemsByColumnEntries = getNavItemsByColumnEntries(navItems)
173
+ const numberOfColumnsMax = Math.floor(viewportWidth / navWidthMin) || 1
174
+ const navItemsByColumnLayouts: NavItemsByColumnLayout[] = navItemsByColumnEntries.map(
175
+ ({ columnEntries, isFullWidth }) => {
176
+ const numberOfColumns = Math.min(numberOfColumnsMax, columnEntries.length)
177
+ const columns: NavItemComputed[][][] = []
178
+ columnEntries.forEach((columnEntry) => {
179
+ const idx = numberOfColumns === 1 ? 0 : columnEntry.columnMap[numberOfColumns]!
180
+ assert(idx >= 0)
181
+ columns[idx] ??= []
182
+ columns[idx].push(columnEntry.navItems)
183
+ })
184
+ const navItemsByColumnLayout: NavItemsByColumnLayout = { columns, isFullWidth }
185
+ return navItemsByColumnLayout
186
+ },
187
+ )
188
+ return navItemsByColumnLayouts
189
+ }
190
+
191
+ type NavItemsByColumnEntries = { columnEntries: ColumnEntry[]; isFullWidth: boolean }[]
192
+ type ColumnEntry = { navItems: NavItemComputed[]; columnMap: ColumnMap }
193
+ type ColumnMap = Record<number, number>
194
+ function getNavItemsByColumnEntries(navItems: NavItemComputed[]): NavItemsByColumnEntries {
195
+ const navItemsByColumnEntries: NavItemsByColumnEntries = []
196
+ let columnEntries: ColumnEntry[] = []
197
+ let columnEntry: ColumnEntry
169
198
  let isFullWidth: boolean | undefined
170
199
  navItems.forEach((navItem) => {
171
200
  if (navItem.level === 1) {
172
201
  const isFullWidthPrevious = isFullWidth
173
202
  isFullWidth = !!navItem.menuModalFullWidth
174
203
  if (isFullWidthPrevious !== undefined && isFullWidthPrevious !== isFullWidth) {
175
- navItemsColumnLayout.push({ navItemsColumnEntries, isFullWidth: isFullWidthPrevious })
176
- navItemsColumnEntries = []
204
+ navItemsByColumnEntries.push({ columnEntries, isFullWidth: isFullWidthPrevious })
205
+ columnEntries = []
177
206
  }
178
207
  }
179
208
  assert(isFullWidth !== undefined)
180
- if (navItem.isColumnLayoutElement) {
209
+ if (navItem.isColumnEntry) {
181
210
  assert(navItem.level === 1 || navItem.level === 4)
182
- const navItemColumnEntry = { ...navItem, navItemChilds: [] }
183
- navItemsColumnEntries.push(navItemColumnEntry)
211
+ columnEntry = { navItems: [navItem], columnMap: navItem.isColumnEntry }
212
+ columnEntries.push(columnEntry)
184
213
  } else {
185
214
  assert(navItem.level !== 1)
186
- navItemsColumnEntries[navItemsColumnEntries.length - 1].navItemChilds.push(navItem)
215
+ columnEntry.navItems.push(navItem)
187
216
  }
188
217
  })
189
218
  assert(isFullWidth !== undefined)
190
- navItemsColumnLayout.push({ navItemsColumnEntries, isFullWidth })
191
- return navItemsColumnLayout
219
+ navItemsByColumnEntries.push({ columnEntries, isFullWidth })
220
+ return navItemsByColumnEntries
192
221
  }
193
222
 
194
223
  type NavItemComputed = ReturnType<typeof getNavItemsWithComputed>[number]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brillout/docpress",
3
- "version": "0.8.11",
3
+ "version": "0.8.12",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@brillout/picocolors": "^1.0.10",