@brillout/docpress 0.8.11 → 0.8.13

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 +2 -5
  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 +69 -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 +94 -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,46 @@ 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
+ var margin = 40;
47
+ return (React.createElement(React.Fragment, null, navItemsByColumnLayouts.map(function (_a, i) {
48
+ var columns = _a.columns, isFullWidth = _a.isFullWidth;
49
+ return (React.createElement("div", { key: i, style: {
50
+ display: 'flex',
51
+ width: columns.length * (navWidthMax + 20),
52
+ justifyContent: 'space-between',
53
+ maxWidth: '100%',
54
+ margin: 'auto',
55
+ marginTop: i === 0 ? -1 * margin : undefined,
56
+ marginBottom: margin,
57
+ } },
58
+ columns.map(function (columnEntry, j) { return (React.createElement("div", { key: j, style: {
59
+ flexGrow: 1,
60
+ maxWidth: navWidthMax,
61
+ display: 'flex',
62
+ flexDirection: 'column',
63
+ paddingTop: isFullWidth && j !== 0 ? 36 : undefined,
64
+ } }, columnEntry.map(function (navItems, k) { return (React.createElement("div", { key: k, style: { marginTop: isFullWidth ? undefined : margin } },
65
+ navItems.map(function (navItem, l) { return (React.createElement(NavItemComponent, { navItem: navItem, key: l })); }),
66
+ React.createElement(CategoryBorder, { navItemLevel1: isFullWidth ? undefined : navItems[0] }))); }))); }),
67
+ React.createElement(CategoryBorder, { navItemLevel1: !isFullWidth ? undefined : columns[0][0][0] })));
68
+ })));
69
+ }
59
70
  function CategoryBorder(_a) {
60
- var navItemLevel1 = _a.navItemLevel1, paddingBottom = _a.paddingBottom;
71
+ var navItemLevel1 = _a.navItemLevel1;
61
72
  return !navItemLevel1 ? null : (React.createElement("div", { className: "category-border", style: {
62
73
  background: navItemLevel1.color,
63
- height: "calc(100% - ".concat(paddingBottom, "px - 53px)"),
64
74
  } }));
65
75
  }
66
76
  function NavItemComponent(_a) {
@@ -108,33 +118,54 @@ function NavItemComponent(_a) {
108
118
  return React.createElement("span", __assign({}, props));
109
119
  }
110
120
  }
111
- function groupByColumnLayout(navItems) {
112
- var navItemsColumnLayout = [];
113
- var navItemsColumnEntries = [];
121
+ function getNavItemsByColumnLayouts(navItems, viewportWidth) {
122
+ if (viewportWidth === void 0) { viewportWidth = 0; }
123
+ var navItemsByColumnEntries = getNavItemsByColumnEntries(navItems);
124
+ var numberOfColumnsMax = Math.floor(viewportWidth / navWidthMin) || 1;
125
+ var navItemsByColumnLayouts = navItemsByColumnEntries.map(function (_a) {
126
+ var columnEntries = _a.columnEntries, isFullWidth = _a.isFullWidth;
127
+ var numberOfColumns = Math.min(numberOfColumnsMax, columnEntries.length);
128
+ var columns = [];
129
+ columnEntries.forEach(function (columnEntry) {
130
+ var _a;
131
+ var idx = numberOfColumns === 1 ? 0 : columnEntry.columnMap[numberOfColumns];
132
+ assert(idx >= 0);
133
+ (_a = columns[idx]) !== null && _a !== void 0 ? _a : (columns[idx] = []);
134
+ columns[idx].push(columnEntry.navItems);
135
+ });
136
+ var navItemsByColumnLayout = { columns: columns, isFullWidth: isFullWidth };
137
+ return navItemsByColumnLayout;
138
+ });
139
+ return navItemsByColumnLayouts;
140
+ }
141
+ function getNavItemsByColumnEntries(navItems) {
142
+ var navItemsByColumnEntries = [];
143
+ var columnEntries = [];
144
+ var columnEntry;
114
145
  var isFullWidth;
115
146
  navItems.forEach(function (navItem) {
116
147
  if (navItem.level === 1) {
117
148
  var isFullWidthPrevious = isFullWidth;
118
149
  isFullWidth = !!navItem.menuModalFullWidth;
119
150
  if (isFullWidthPrevious !== undefined && isFullWidthPrevious !== isFullWidth) {
120
- navItemsColumnLayout.push({ navItemsColumnEntries: navItemsColumnEntries, isFullWidth: isFullWidthPrevious });
121
- navItemsColumnEntries = [];
151
+ navItemsByColumnEntries.push({ columnEntries: columnEntries, isFullWidth: isFullWidthPrevious });
152
+ columnEntries = [];
122
153
  }
123
154
  }
124
155
  assert(isFullWidth !== undefined);
125
- if (navItem.isColumnLayoutElement) {
156
+ if (navItem.isColumnEntry) {
126
157
  assert(navItem.level === 1 || navItem.level === 4);
127
- var navItemColumnEntry = __assign(__assign({}, navItem), { navItemChilds: [] });
128
- navItemsColumnEntries.push(navItemColumnEntry);
158
+ columnEntry = { navItems: [navItem], columnMap: navItem.isColumnEntry };
159
+ columnEntries.push(columnEntry);
129
160
  }
130
161
  else {
131
162
  assert(navItem.level !== 1);
132
- navItemsColumnEntries[navItemsColumnEntries.length - 1].navItemChilds.push(navItem);
163
+ columnEntry.navItems.push(navItem);
133
164
  }
134
165
  });
135
166
  assert(isFullWidth !== undefined);
136
- navItemsColumnLayout.push({ navItemsColumnEntries: navItemsColumnEntries, isFullWidth: isFullWidth });
137
- return navItemsColumnLayout;
167
+ navItemsByColumnEntries.push({ columnEntries: columnEntries, isFullWidth: isFullWidth });
168
+ return navItemsByColumnEntries;
138
169
  }
139
170
  function getNavItemsWithComputed(navItems, currentUrl) {
140
171
  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,76 @@ 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
+ const margin = 40
63
+
64
+ return (
65
+ <>
66
+ {navItemsByColumnLayouts.map(({ columns, isFullWidth }, i) => (
67
+ <div
68
+ key={i}
69
+ style={{
70
+ display: 'flex',
71
+ width: columns.length * (navWidthMax + 20),
72
+ justifyContent: 'space-between',
73
+ maxWidth: '100%',
74
+ margin: 'auto',
75
+ marginTop: i === 0 ? -1 * margin : undefined,
76
+ marginBottom: margin,
77
+ }}
78
+ >
79
+ {columns.map((columnEntry, j) => (
53
80
  <div
54
- className={`column-layout-${i}` + (!isFullWidth ? '' : ' nav-category nav-category-full-width')}
81
+ key={j}
55
82
  style={{
56
83
  flexGrow: 1,
57
- columnGap: 20,
58
- paddingBottom: isFullWidth ? paddingBottom : undefined,
84
+ maxWidth: navWidthMax,
85
+ display: 'flex',
86
+ flexDirection: 'column',
87
+ paddingTop: isFullWidth && j !== 0 ? 36 : undefined,
59
88
  }}
60
89
  >
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} />
90
+ {columnEntry.map((navItems, k) => (
91
+ <div key={k} style={{ marginTop: isFullWidth ? undefined : margin }}>
92
+ {navItems.map((navItem, l) => (
93
+ <NavItemComponent navItem={navItem} key={l} />
75
94
  ))}
76
- <CategoryBorder
77
- navItemLevel1={isFullWidth ? undefined : navItemColumnEntry!}
78
- paddingBottom={paddingBottom}
79
- />
95
+ <CategoryBorder navItemLevel1={isFullWidth ? undefined : navItems[0]!} />
80
96
  </div>
81
97
  ))}
82
- <CategoryBorder
83
- navItemLevel1={!isFullWidth ? undefined : navItemsColumnEntries[0]!}
84
- paddingBottom={paddingBottom}
85
- />
86
98
  </div>
87
- </div>
88
- ))}
89
- </>
90
- )
91
- }
92
-
93
- return (
94
- <div className="navigation-content" style={{ marginTop: 10 }}>
95
- {navContent}
96
- </div>
99
+ ))}
100
+ <CategoryBorder navItemLevel1={!isFullWidth ? undefined : columns[0][0][0]!} />
101
+ </div>
102
+ ))}
103
+ </>
97
104
  )
98
105
  }
99
- function CategoryBorder({ navItemLevel1, paddingBottom }: { navItemLevel1?: NavItemComputed; paddingBottom: number }) {
106
+
107
+ function CategoryBorder({ navItemLevel1 }: { navItemLevel1?: NavItemComputed }) {
100
108
  return !navItemLevel1 ? null : (
101
109
  <div
102
110
  className="category-border"
103
111
  style={{
104
112
  background: navItemLevel1.color!,
105
- height: `calc(100% - ${paddingBottom}px - 53px)`,
106
113
  }}
107
114
  />
108
115
  )
@@ -162,33 +169,57 @@ function NavItemComponent({
162
169
  }
163
170
  }
164
171
 
165
- type NavItemsColumnEntry = NavItemComputed & { navItemChilds: NavItemComputed[] }
166
- function groupByColumnLayout(navItems: NavItemComputed[]) {
167
- const navItemsColumnLayout: { navItemsColumnEntries: NavItemsColumnEntry[]; isFullWidth: boolean }[] = []
168
- let navItemsColumnEntries: NavItemsColumnEntry[] = []
172
+ type NavItemsByColumnLayout = { columns: NavItemComputed[][][]; isFullWidth: boolean }
173
+ function getNavItemsByColumnLayouts(navItems: NavItemComputed[], viewportWidth: number = 0): NavItemsByColumnLayout[] {
174
+ const navItemsByColumnEntries = getNavItemsByColumnEntries(navItems)
175
+ const numberOfColumnsMax = Math.floor(viewportWidth / navWidthMin) || 1
176
+ const navItemsByColumnLayouts: NavItemsByColumnLayout[] = navItemsByColumnEntries.map(
177
+ ({ columnEntries, isFullWidth }) => {
178
+ const numberOfColumns = Math.min(numberOfColumnsMax, columnEntries.length)
179
+ const columns: NavItemComputed[][][] = []
180
+ columnEntries.forEach((columnEntry) => {
181
+ const idx = numberOfColumns === 1 ? 0 : columnEntry.columnMap[numberOfColumns]!
182
+ assert(idx >= 0)
183
+ columns[idx] ??= []
184
+ columns[idx].push(columnEntry.navItems)
185
+ })
186
+ const navItemsByColumnLayout: NavItemsByColumnLayout = { columns, isFullWidth }
187
+ return navItemsByColumnLayout
188
+ },
189
+ )
190
+ return navItemsByColumnLayouts
191
+ }
192
+
193
+ type NavItemsByColumnEntries = { columnEntries: ColumnEntry[]; isFullWidth: boolean }[]
194
+ type ColumnEntry = { navItems: NavItemComputed[]; columnMap: ColumnMap }
195
+ type ColumnMap = Record<number, number>
196
+ function getNavItemsByColumnEntries(navItems: NavItemComputed[]): NavItemsByColumnEntries {
197
+ const navItemsByColumnEntries: NavItemsByColumnEntries = []
198
+ let columnEntries: ColumnEntry[] = []
199
+ let columnEntry: ColumnEntry
169
200
  let isFullWidth: boolean | undefined
170
201
  navItems.forEach((navItem) => {
171
202
  if (navItem.level === 1) {
172
203
  const isFullWidthPrevious = isFullWidth
173
204
  isFullWidth = !!navItem.menuModalFullWidth
174
205
  if (isFullWidthPrevious !== undefined && isFullWidthPrevious !== isFullWidth) {
175
- navItemsColumnLayout.push({ navItemsColumnEntries, isFullWidth: isFullWidthPrevious })
176
- navItemsColumnEntries = []
206
+ navItemsByColumnEntries.push({ columnEntries, isFullWidth: isFullWidthPrevious })
207
+ columnEntries = []
177
208
  }
178
209
  }
179
210
  assert(isFullWidth !== undefined)
180
- if (navItem.isColumnLayoutElement) {
211
+ if (navItem.isColumnEntry) {
181
212
  assert(navItem.level === 1 || navItem.level === 4)
182
- const navItemColumnEntry = { ...navItem, navItemChilds: [] }
183
- navItemsColumnEntries.push(navItemColumnEntry)
213
+ columnEntry = { navItems: [navItem], columnMap: navItem.isColumnEntry }
214
+ columnEntries.push(columnEntry)
184
215
  } else {
185
216
  assert(navItem.level !== 1)
186
- navItemsColumnEntries[navItemsColumnEntries.length - 1].navItemChilds.push(navItem)
217
+ columnEntry.navItems.push(navItem)
187
218
  }
188
219
  })
189
220
  assert(isFullWidth !== undefined)
190
- navItemsColumnLayout.push({ navItemsColumnEntries, isFullWidth })
191
- return navItemsColumnLayout
221
+ navItemsByColumnEntries.push({ columnEntries, isFullWidth })
222
+ return navItemsByColumnEntries
192
223
  }
193
224
 
194
225
  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.13",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@brillout/picocolors": "^1.0.10",