@brillout/docpress 0.9.8 → 0.10.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.
- package/Layout.tsx +102 -40
- package/{navigation → MenuModal}/Collapsible.css +7 -0
- package/MenuModal/NavigationWithColumnLayout.css +11 -0
- package/MenuModal/NavigationWithColumnLayout.tsx +253 -0
- package/MenuModal/toggleMenuModal.ts +132 -0
- package/MenuModal.tsx +68 -79
- package/{navigation/Navigation.css → NavItemComponent.css} +1 -23
- package/NavItemComponent.tsx +149 -0
- package/components/Note.css +0 -1
- package/config/resolveHeadingsData.ts +1 -1
- package/css/code/diff.css +10 -5
- package/css/code.css +1 -1
- package/css/colorize-on-hover.css +6 -7
- package/css/heading.css +9 -3
- package/css/index.css +1 -0
- package/dist/NavItemComponent.d.ts +39 -0
- package/dist/NavItemComponent.js +109 -0
- package/dist/config/resolveHeadingsData.d.ts +1 -1
- package/dist/config/resolvePageContext.d.ts +2 -2
- package/dist/renderer/determineNavItemsColumnLayout.d.ts +1 -1
- package/docsearch/SearchLink.tsx +7 -3
- package/icons/books.svg +46 -0
- package/icons/gear.svg +35 -0
- package/icons/index.ts +5 -0
- package/icons/magnifying-glass.svg +31 -0
- package/icons/seedling.svg +24 -0
- package/index.ts +2 -0
- package/initKeyBindings.ts +1 -1
- package/package.json +1 -1
- package/renderer/determineNavItemsColumnLayout.ts +1 -1
- package/renderer/initOnNavigation.ts +1 -1
- package/renderer/onRenderClient.tsx +1 -1
- package/utils/css.ts +0 -6
- package/dist/Layout.d.ts +0 -15
- package/dist/Layout.js +0 -321
- package/dist/MenuModal.d.ts +0 -13
- package/dist/MenuModal.js +0 -124
- package/dist/NavSecondaryContent.d.ts +0 -6
- package/dist/NavSecondaryContent.js +0 -57
- package/dist/autoScrollNav.d.ts +0 -3
- package/dist/autoScrollNav.js +0 -35
- package/dist/components/EditPageNote.d.ts +0 -7
- package/dist/components/EditPageNote.js +0 -11
- package/dist/docsearch/SearchLink.d.ts +0 -4
- package/dist/docsearch/SearchLink.js +0 -25
- package/dist/docsearch/toggleDocsearchModal.d.ts +0 -4
- package/dist/docsearch/toggleDocsearchModal.js +0 -26
- package/dist/navigation/Collapsible.d.ts +0 -10
- package/dist/navigation/Collapsible.js +0 -35
- package/dist/navigation/Navigation.d.ts +0 -21
- package/dist/navigation/Navigation.js +0 -255
- package/dist/utils/PassTrough.d.ts +0 -3
- package/dist/utils/PassTrough.js +0 -6
- package/dist/utils/Style.d.ts +0 -5
- package/dist/utils/Style.js +0 -6
- package/dist/utils/css.d.ts +0 -1
- package/dist/utils/css.js +0 -27
- package/dist/utils/getViewportWidth.d.ts +0 -1
- package/dist/utils/getViewportWidth.js +0 -4
- package/dist/utils/throttle.d.ts +0 -1
- package/dist/utils/throttle.js +0 -14
- package/navigation/Navigation.tsx +0 -382
- /package/{navigation → MenuModal}/Collapsible.tsx +0 -0
package/dist/utils/PassTrough.js
DELETED
package/dist/utils/Style.d.ts
DELETED
package/dist/utils/Style.js
DELETED
package/dist/utils/css.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function css(strings: TemplateStringsArray | string[], ...values: (string | number)[]): string;
|
package/dist/utils/css.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export function css(strings) {
|
|
2
|
-
var values = [];
|
|
3
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
4
|
-
values[_i - 1] = arguments[_i];
|
|
5
|
-
}
|
|
6
|
-
// The boring part
|
|
7
|
-
var result = strings
|
|
8
|
-
.map(function (str, i) {
|
|
9
|
-
var s = str;
|
|
10
|
-
if (i !== strings.length - 1) {
|
|
11
|
-
s += values[i];
|
|
12
|
-
}
|
|
13
|
-
return s;
|
|
14
|
-
})
|
|
15
|
-
.join('');
|
|
16
|
-
// Remove comments
|
|
17
|
-
result = result
|
|
18
|
-
.split('\n')
|
|
19
|
-
.filter(function (line) { return !line.startsWith('// '); })
|
|
20
|
-
.join('\n');
|
|
21
|
-
// Minifiy
|
|
22
|
-
result = result
|
|
23
|
-
.replace(/\s+/g, ' ') // Replace all whitespace sequences with a single space
|
|
24
|
-
.replace(/\s*([{}:;])\s*/g, '$1') // Remove space around {, }, :, ;
|
|
25
|
-
.trim(); // Trim any leading/trailing whitespace
|
|
26
|
-
return result;
|
|
27
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function getViewportWidth(): number;
|
package/dist/utils/throttle.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function throttle<T extends (...args: any[]) => void>(func: T, limit: number): T;
|
package/dist/utils/throttle.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export function throttle(func, limit) {
|
|
2
|
-
var inThrottle;
|
|
3
|
-
return function () {
|
|
4
|
-
var args = [];
|
|
5
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
6
|
-
args[_i] = arguments[_i];
|
|
7
|
-
}
|
|
8
|
-
if (!inThrottle) {
|
|
9
|
-
func.apply(this, args);
|
|
10
|
-
inThrottle = true;
|
|
11
|
-
setTimeout(function () { return (inThrottle = false); }, limit);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
// TODO/refactor: rename file and/or component
|
|
2
|
-
export { NavigationContent }
|
|
3
|
-
// TODO/refactor: do this only on the server side?
|
|
4
|
-
export type { NavItem }
|
|
5
|
-
|
|
6
|
-
import React, { useEffect, useState } from 'react'
|
|
7
|
-
import { assert, assertWarning, jsxToTextContent } from '../utils/server'
|
|
8
|
-
import './Navigation.css'
|
|
9
|
-
import { parseTitle } from '../parseTitle'
|
|
10
|
-
import { usePageContext } from '../renderer/usePageContext'
|
|
11
|
-
import '@docsearch/css'
|
|
12
|
-
import '../global.d.ts'
|
|
13
|
-
import { getViewportWidth } from '../utils/getViewportWidth'
|
|
14
|
-
import { navLeftWidthMax, navLeftWidthMin } from '../Layout'
|
|
15
|
-
import { throttle } from '../utils/throttle'
|
|
16
|
-
import { Collapsible } from './Collapsible'
|
|
17
|
-
|
|
18
|
-
type NavItem = {
|
|
19
|
-
level: number
|
|
20
|
-
url?: string | null
|
|
21
|
-
color?: string
|
|
22
|
-
title: string
|
|
23
|
-
titleInNav: string
|
|
24
|
-
menuModalFullWidth?: true
|
|
25
|
-
isColumnEntry?: ColumnMap
|
|
26
|
-
}
|
|
27
|
-
function NavigationContent(props: {
|
|
28
|
-
navItems: NavItem[]
|
|
29
|
-
showOnlyRelevant?: true
|
|
30
|
-
columnLayout?: true
|
|
31
|
-
}) {
|
|
32
|
-
const pageContext = usePageContext()
|
|
33
|
-
const navItemsWithComputed = getNavItemsWithComputed(props.navItems, pageContext.urlPathname)
|
|
34
|
-
|
|
35
|
-
let navContent: React.ReactNode
|
|
36
|
-
if (!props.columnLayout) {
|
|
37
|
-
let navItemsRelevant = navItemsWithComputed
|
|
38
|
-
if (props.showOnlyRelevant) navItemsRelevant = navItemsRelevant.filter((navItemGroup) => navItemGroup.isRelevant)
|
|
39
|
-
navContent = navItemsRelevant.map((navItem, i) => <NavItemComponent navItem={navItem} key={i} />)
|
|
40
|
-
} else {
|
|
41
|
-
assert(!props.showOnlyRelevant)
|
|
42
|
-
navContent = <NavigationWithColumnLayout navItemsWithComputed={navItemsWithComputed} />
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div className="navigation-content" style={{ marginTop: 10 }}>
|
|
47
|
-
{navContent}
|
|
48
|
-
</div>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function NavigationWithColumnLayout(props: { navItemsWithComputed: NavItemComputed[] }) {
|
|
53
|
-
let [viewportWidth, setViewportWidth] = useState<number | undefined>()
|
|
54
|
-
const updateviewportwidth = () => setViewportWidth(getViewportWidth())
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
updateviewportwidth()
|
|
57
|
-
window.addEventListener('resize', throttle(updateviewportwidth, 300), { passive: true })
|
|
58
|
-
})
|
|
59
|
-
const navItemsByColumnLayouts = getNavItemsByColumnLayouts(props.navItemsWithComputed, viewportWidth)
|
|
60
|
-
return (
|
|
61
|
-
<>
|
|
62
|
-
{navItemsByColumnLayouts.map((columnLayout, i) => (
|
|
63
|
-
<div key={i}>
|
|
64
|
-
{columnLayout.isFullWidthCategory ? (
|
|
65
|
-
<div style={{ marginTop: 0 }}>
|
|
66
|
-
<ColumnsWrapper numberOfColumns={columnLayout.columns.length}>
|
|
67
|
-
<Collapsible
|
|
68
|
-
head={(onClick) => <NavItemComponent navItem={columnLayout.navItemLevel1} onClick={onClick} />}
|
|
69
|
-
disabled={columnLayout.columns.length > 1}
|
|
70
|
-
collapsedInit={!columnLayout.navItemLevel1.isRelevant}
|
|
71
|
-
marginBottomOnExpand={10}
|
|
72
|
-
>
|
|
73
|
-
<ColumnsLayout className="collapsible">
|
|
74
|
-
{columnLayout.columns.map((column, j) => (
|
|
75
|
-
<Column key={j}>
|
|
76
|
-
{column.navItems.map((navItem, k) => (
|
|
77
|
-
<NavItemComponent key={k} navItem={navItem} />
|
|
78
|
-
))}
|
|
79
|
-
</Column>
|
|
80
|
-
))}
|
|
81
|
-
<CategoryBorder navItemLevel1={columnLayout.navItemLevel1} />
|
|
82
|
-
</ColumnsLayout>
|
|
83
|
-
</Collapsible>
|
|
84
|
-
</ColumnsWrapper>
|
|
85
|
-
</div>
|
|
86
|
-
) : (
|
|
87
|
-
<ColumnsWrapper numberOfColumns={columnLayout.columns.length}>
|
|
88
|
-
<ColumnsLayout>
|
|
89
|
-
{columnLayout.columns.map((column, j) => (
|
|
90
|
-
<Column key={j}>
|
|
91
|
-
{column.categories.map((category, k) => (
|
|
92
|
-
<div key={k} style={{ marginBottom: 0 }}>
|
|
93
|
-
<Collapsible
|
|
94
|
-
head={(onClick) => <NavItemComponent navItem={category.navItemLevel1} onClick={onClick} />}
|
|
95
|
-
disabled={columnLayout.columns.length > 1}
|
|
96
|
-
collapsedInit={!category.navItemLevel1.isRelevant}
|
|
97
|
-
marginBottomOnExpand={40}
|
|
98
|
-
>
|
|
99
|
-
{category.navItems.map((navItem, l) => (
|
|
100
|
-
<NavItemComponent key={l} navItem={navItem} />
|
|
101
|
-
))}
|
|
102
|
-
<CategoryBorder navItemLevel1={category.navItemLevel1} />
|
|
103
|
-
</Collapsible>
|
|
104
|
-
</div>
|
|
105
|
-
))}
|
|
106
|
-
</Column>
|
|
107
|
-
))}
|
|
108
|
-
</ColumnsLayout>
|
|
109
|
-
</ColumnsWrapper>
|
|
110
|
-
)}
|
|
111
|
-
</div>
|
|
112
|
-
))}
|
|
113
|
-
</>
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
function Column({ children }: { children: React.ReactNode }) {
|
|
117
|
-
return (
|
|
118
|
-
<div
|
|
119
|
-
style={{
|
|
120
|
-
flexGrow: 1,
|
|
121
|
-
maxWidth: navLeftWidthMax,
|
|
122
|
-
display: 'flex',
|
|
123
|
-
flexDirection: 'column',
|
|
124
|
-
}}
|
|
125
|
-
>
|
|
126
|
-
{children}
|
|
127
|
-
</div>
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
function ColumnsWrapper({ children, numberOfColumns }: { children: React.ReactNode; numberOfColumns: number }) {
|
|
131
|
-
return (
|
|
132
|
-
<div
|
|
133
|
-
style={{
|
|
134
|
-
width: numberOfColumns * (navLeftWidthMax + 20),
|
|
135
|
-
maxWidth: '100%',
|
|
136
|
-
margin: 'auto',
|
|
137
|
-
}}
|
|
138
|
-
>
|
|
139
|
-
{children}
|
|
140
|
-
</div>
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
function ColumnsLayout({ children, className }: { children: React.ReactNode; className?: string }) {
|
|
144
|
-
return (
|
|
145
|
-
<div
|
|
146
|
-
className={className}
|
|
147
|
-
style={{
|
|
148
|
-
display: 'flex',
|
|
149
|
-
justifyContent: 'space-between',
|
|
150
|
-
}}
|
|
151
|
-
>
|
|
152
|
-
{children}
|
|
153
|
-
</div>
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
function CategoryBorder({ navItemLevel1 }: { navItemLevel1: NavItemComputed }) {
|
|
157
|
-
assert(navItemLevel1.level === 1)
|
|
158
|
-
return <div className="category-border" style={{ background: navItemLevel1.color! }} />
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
type PropsNavItem = PropsAnchor & PropsSpan
|
|
162
|
-
type PropsAnchor = React.HTMLProps<HTMLAnchorElement>
|
|
163
|
-
type PropsSpan = React.HTMLProps<HTMLSpanElement>
|
|
164
|
-
function NavItemComponent({
|
|
165
|
-
navItem,
|
|
166
|
-
onClick,
|
|
167
|
-
}: {
|
|
168
|
-
navItem: NavItemComputed
|
|
169
|
-
onClick?: PropsNavItem['onClick']
|
|
170
|
-
}) {
|
|
171
|
-
assert([1, 2, 3, 4].includes(navItem.level), navItem)
|
|
172
|
-
|
|
173
|
-
const titleJsx = parseTitle(navItem.title)
|
|
174
|
-
const titleInNavJsx = parseTitle(navItem.titleInNav)
|
|
175
|
-
|
|
176
|
-
if (navItem.level === 1 || navItem.level === 4) {
|
|
177
|
-
assert(navItem.url === undefined)
|
|
178
|
-
} else {
|
|
179
|
-
const sectionTitle = jsxToTextContent(titleJsx)
|
|
180
|
-
assertWarning(
|
|
181
|
-
navItem.url,
|
|
182
|
-
[
|
|
183
|
-
`${jsxToTextContent(titleInNavJsx)} is missing a URL hash.`,
|
|
184
|
-
`Add a URL hash with: \`## ${sectionTitle}{#some-hash}\`.`,
|
|
185
|
-
/* TODO/eventually: not implemented yet.
|
|
186
|
-
`Use \`<h2 id="url-hash">${sectionTitle}</h2>\` instead of \`## ${sectionTitle}\`.`,
|
|
187
|
-
*/
|
|
188
|
-
].join(' '),
|
|
189
|
-
)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
let children: JSX.Element = titleInNavJsx
|
|
193
|
-
if (navItem.level === 1) {
|
|
194
|
-
children = (
|
|
195
|
-
<>
|
|
196
|
-
{children}
|
|
197
|
-
<Chevron className="collapsible-icon" height={9} />
|
|
198
|
-
</>
|
|
199
|
-
)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const props: PropsNavItem = {
|
|
203
|
-
href: navItem.url ?? undefined,
|
|
204
|
-
children,
|
|
205
|
-
onClick,
|
|
206
|
-
className: [
|
|
207
|
-
'nav-item',
|
|
208
|
-
'nav-item-level-' + navItem.level,
|
|
209
|
-
navItem.url && navItem.isActive && ' is-active',
|
|
210
|
-
navItem.isFirstOfItsKind && 'nav-item-first-of-its-kind',
|
|
211
|
-
navItem.isLastOfItsKind && 'nav-item-last-of-its-kind',
|
|
212
|
-
]
|
|
213
|
-
.filter(Boolean)
|
|
214
|
-
.join(' '),
|
|
215
|
-
}
|
|
216
|
-
if (navItem.level === 1) {
|
|
217
|
-
props.style = {
|
|
218
|
-
['--category-color']: navItem.color!,
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (navItem.level === 2 || navItem.level === 3) {
|
|
223
|
-
return <a {...props} />
|
|
224
|
-
} else {
|
|
225
|
-
return <span {...props} />
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
type NavItemsByColumnLayout =
|
|
230
|
-
| {
|
|
231
|
-
columns: {
|
|
232
|
-
categories: {
|
|
233
|
-
navItemLevel1: NavItemComputed
|
|
234
|
-
navItems: NavItemComputed[]
|
|
235
|
-
}[]
|
|
236
|
-
}[]
|
|
237
|
-
isFullWidthCategory: false
|
|
238
|
-
}
|
|
239
|
-
| {
|
|
240
|
-
navItemLevel1: NavItemComputed
|
|
241
|
-
columns: { navItems: NavItemComputed[] }[]
|
|
242
|
-
isFullWidthCategory: true
|
|
243
|
-
}
|
|
244
|
-
type NavItemsByColumnLayout2 = { columns: NavItemComputed[][][]; isFullWidthCategory: boolean }
|
|
245
|
-
function getNavItemsByColumnLayouts(navItems: NavItemComputed[], viewportWidth: number = 0): NavItemsByColumnLayout[] {
|
|
246
|
-
const navItemsByColumnEntries = getNavItemsByColumnEntries(navItems)
|
|
247
|
-
const numberOfColumnsMax = Math.floor(viewportWidth / navLeftWidthMin) || 1
|
|
248
|
-
const navItemsByColumnLayouts: NavItemsByColumnLayout[] = navItemsByColumnEntries.map(
|
|
249
|
-
({ columnEntries, isFullWidthCategory }) => {
|
|
250
|
-
const numberOfColumns = Math.min(numberOfColumnsMax, columnEntries.length)
|
|
251
|
-
if (!isFullWidthCategory) {
|
|
252
|
-
const columns: {
|
|
253
|
-
categories: {
|
|
254
|
-
navItemLevel1: NavItemComputed
|
|
255
|
-
navItems: NavItemComputed[]
|
|
256
|
-
}[]
|
|
257
|
-
}[] = []
|
|
258
|
-
columnEntries.forEach((columnEntry) => {
|
|
259
|
-
const idx = numberOfColumns === 1 ? 0 : columnEntry.columnMap[numberOfColumns]!
|
|
260
|
-
assert(idx >= 0)
|
|
261
|
-
columns[idx] ??= { categories: [] }
|
|
262
|
-
const navItemLevel1 = columnEntry.navItems[0]
|
|
263
|
-
const navItems = columnEntry.navItems.slice(1)
|
|
264
|
-
columns[idx].categories.push({ navItemLevel1, navItems })
|
|
265
|
-
})
|
|
266
|
-
const navItemsByColumnLayout: NavItemsByColumnLayout = { columns, isFullWidthCategory }
|
|
267
|
-
return navItemsByColumnLayout
|
|
268
|
-
} else {
|
|
269
|
-
let navItemLevel1: NavItemComputed
|
|
270
|
-
const columns: { navItems: NavItemComputed[] }[] = []
|
|
271
|
-
columnEntries.forEach((columnEntry, i) => {
|
|
272
|
-
const idx = numberOfColumns === 1 ? 0 : columnEntry.columnMap[numberOfColumns]!
|
|
273
|
-
assert(idx >= 0)
|
|
274
|
-
columns[idx] ??= { navItems: [] }
|
|
275
|
-
let { navItems } = columnEntry
|
|
276
|
-
if (i === 0) {
|
|
277
|
-
navItemLevel1 = navItems[0]
|
|
278
|
-
navItems = navItems.slice(1)
|
|
279
|
-
}
|
|
280
|
-
columns[idx].navItems.push(...navItems)
|
|
281
|
-
})
|
|
282
|
-
const navItemsByColumnLayout: NavItemsByColumnLayout = {
|
|
283
|
-
columns,
|
|
284
|
-
navItemLevel1: navItemLevel1!,
|
|
285
|
-
isFullWidthCategory,
|
|
286
|
-
}
|
|
287
|
-
return navItemsByColumnLayout
|
|
288
|
-
}
|
|
289
|
-
},
|
|
290
|
-
)
|
|
291
|
-
return navItemsByColumnLayouts
|
|
292
|
-
}
|
|
293
|
-
type NavItemsByColumnEntries = { columnEntries: ColumnEntry[]; isFullWidthCategory: boolean }[]
|
|
294
|
-
type ColumnEntry = { navItems: NavItemComputed[]; columnMap: ColumnMap }
|
|
295
|
-
type ColumnMap = Record<number, number>
|
|
296
|
-
function getNavItemsByColumnEntries(navItems: NavItemComputed[]): NavItemsByColumnEntries {
|
|
297
|
-
const navItemsByColumnEntries: NavItemsByColumnEntries = []
|
|
298
|
-
let columnEntries: ColumnEntry[] = []
|
|
299
|
-
let columnEntry: ColumnEntry
|
|
300
|
-
let isFullWidthCategory: boolean | undefined
|
|
301
|
-
navItems.forEach((navItem) => {
|
|
302
|
-
if (navItem.level === 1) {
|
|
303
|
-
const isFullWidthCategoryPrevious = isFullWidthCategory
|
|
304
|
-
isFullWidthCategory = !!navItem.menuModalFullWidth
|
|
305
|
-
if (isFullWidthCategoryPrevious !== undefined && isFullWidthCategoryPrevious !== isFullWidthCategory) {
|
|
306
|
-
navItemsByColumnEntries.push({ columnEntries, isFullWidthCategory: isFullWidthCategoryPrevious })
|
|
307
|
-
columnEntries = []
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
assert(isFullWidthCategory !== undefined)
|
|
311
|
-
if (navItem.isColumnEntry) {
|
|
312
|
-
assert(navItem.level === 1 || navItem.level === 4)
|
|
313
|
-
columnEntry = { navItems: [navItem], columnMap: navItem.isColumnEntry }
|
|
314
|
-
columnEntries.push(columnEntry)
|
|
315
|
-
} else {
|
|
316
|
-
assert(navItem.level !== 1)
|
|
317
|
-
columnEntry.navItems.push(navItem)
|
|
318
|
-
}
|
|
319
|
-
})
|
|
320
|
-
assert(isFullWidthCategory !== undefined)
|
|
321
|
-
navItemsByColumnEntries.push({ columnEntries, isFullWidthCategory })
|
|
322
|
-
return navItemsByColumnEntries
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
type NavItemComputed = ReturnType<typeof getNavItemsWithComputed>[number]
|
|
326
|
-
function getNavItemsWithComputed(navItems: NavItem[], currentUrl: string) {
|
|
327
|
-
let navItemIdx: number | undefined
|
|
328
|
-
const navItemsWithComputed = navItems.map((navItem, i) => {
|
|
329
|
-
assert([1, 2, 3, 4].includes(navItem.level), navItem)
|
|
330
|
-
|
|
331
|
-
const navItemPrevious = navItems[i - 1]
|
|
332
|
-
const navItemNext = navItems[i + 1]
|
|
333
|
-
|
|
334
|
-
let isActive = false
|
|
335
|
-
if (navItem.url === currentUrl) {
|
|
336
|
-
assert(navItem.level === 2, { currentUrl })
|
|
337
|
-
assert(navItemIdx === undefined)
|
|
338
|
-
navItemIdx = i
|
|
339
|
-
isActive = true
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const isFirstOfItsKind = navItem.level !== navItemPrevious?.level
|
|
343
|
-
const isLastOfItsKind = navItem.level !== navItemNext?.level
|
|
344
|
-
|
|
345
|
-
const navItemComputed = {
|
|
346
|
-
...navItem,
|
|
347
|
-
isActive,
|
|
348
|
-
isRelevant: false,
|
|
349
|
-
isFirstOfItsKind,
|
|
350
|
-
isLastOfItsKind,
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
return navItemComputed
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
// Set `isRelevant`
|
|
357
|
-
if (navItemIdx !== undefined) {
|
|
358
|
-
for (let i = navItemIdx; i >= 0; i--) {
|
|
359
|
-
const navItem = navItemsWithComputed[i]!
|
|
360
|
-
navItem.isRelevant = true
|
|
361
|
-
if (navItem.level === 1) break
|
|
362
|
-
}
|
|
363
|
-
for (let i = navItemIdx; i < navItemsWithComputed.length; i++) {
|
|
364
|
-
const navItem = navItemsWithComputed[i]!
|
|
365
|
-
if (navItem.level === 1) break
|
|
366
|
-
navItem.isRelevant = true
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return navItemsWithComputed
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function Chevron(props: React.HTMLProps<SVGSVGElement>) {
|
|
374
|
-
return (
|
|
375
|
-
<svg viewBox="0 0 512 292.52" xmlns="http://www.w3.org/2000/svg" {...props}>
|
|
376
|
-
<path
|
|
377
|
-
fill="#aaa"
|
|
378
|
-
d="M10.725 82.42L230.125 261.82c6.8 6.8 16.2 10.7 25.9 10.7s19.1-3.9 25.9-10.7l219.4-179.4c14.3-14.3 14.3-37.4 0-51.7s-37.4-14.3-51.7 0l-193.6 153.6-193.6-153.6c-14.3-14.3-37.4-14.3-51.7 0s-14.3 37.5 0 51.7z"
|
|
379
|
-
/>
|
|
380
|
-
</svg>
|
|
381
|
-
)
|
|
382
|
-
}
|
|
File without changes
|