@brillout/docpress 0.15.12 → 0.15.13-commit-ffe283f

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.
@@ -3,7 +3,7 @@ export { NavigationWithColumnLayout }
3
3
  import React, { useEffect, useState } from 'react'
4
4
  import { assert } from '../utils/server'
5
5
  import { getViewportWidth } from '../utils/getViewportWidth'
6
- import { containerQueryMobileMenu, navLeftWidthMax, navLeftWidthMin } from '../Layout'
6
+ import { viewTablet, navLeftWidthMax, navLeftWidthMin } from '../Layout'
7
7
  import { throttle } from '../utils/throttle'
8
8
  import { Collapsible } from './Collapsible'
9
9
  import { ColumnMap, getNavItemsWithComputed, NavItem, NavItemComponent, NavItemComputed } from '../NavItemComponent'
@@ -23,6 +23,7 @@ function NavigationWithColumnLayout(props: { navItems: NavItem[] }) {
23
23
  window.addEventListener('resize', throttle(updateviewportwidth, 300), { passive: true })
24
24
  })
25
25
  const navItemsByColumnLayouts = getNavItemsByColumnLayouts(navItemsWithComputed, viewportWidth)
26
+ const maxColumns = Math.max(...navItemsByColumnLayouts.map((layout) => layout.columns.length), 1)
26
27
  return (
27
28
  <>
28
29
  <Style>{getStyle()}</Style>
@@ -40,10 +41,10 @@ function NavigationWithColumnLayout(props: { navItems: NavItem[] }) {
40
41
  >
41
42
  {columnLayout.isFullWidthCategory ? (
42
43
  <div style={{ marginTop: 0 }}>
43
- <ColumnsWrapper numberOfColumns={columnLayout.columns.length}>
44
+ <ColumnsWrapper numberOfColumns={maxColumns}>
44
45
  <Collapsible
45
46
  head={(onClick) => <NavItemComponent navItem={columnLayout.navItemLevel1} onClick={onClick} />}
46
- disabled={columnLayout.columns.length > 1}
47
+ disabled={maxColumns > 1}
47
48
  collapsedInit={!columnLayout.navItemLevel1.isRelevant}
48
49
  marginBottomOnExpand={marginBottomOnExpand}
49
50
  >
@@ -61,7 +62,7 @@ function NavigationWithColumnLayout(props: { navItems: NavItem[] }) {
61
62
  </ColumnsWrapper>
62
63
  </div>
63
64
  ) : (
64
- <ColumnsWrapper numberOfColumns={columnLayout.columns.length}>
65
+ <ColumnsWrapper numberOfColumns={maxColumns}>
65
66
  <ColumnsLayout>
66
67
  {columnLayout.columns.map((column, j) => (
67
68
  <Column key={j}>
@@ -69,7 +70,7 @@ function NavigationWithColumnLayout(props: { navItems: NavItem[] }) {
69
70
  <div key={k} style={{ marginBottom: 0 }}>
70
71
  <Collapsible
71
72
  head={(onClick) => <NavItemComponent navItem={category.navItemLevel1} onClick={onClick} />}
72
- disabled={columnLayout.columns.length > 1}
73
+ disabled={maxColumns > 1}
73
74
  collapsedInit={!category.navItemLevel1.isRelevant}
74
75
  marginBottomOnExpand={marginBottomOnExpand}
75
76
  >
@@ -93,7 +94,7 @@ function NavigationWithColumnLayout(props: { navItems: NavItem[] }) {
93
94
 
94
95
  function getStyle() {
95
96
  const style = css`
96
- @media(min-width: ${containerQueryMobileMenu + 1}px) {
97
+ @media(min-width: ${viewTablet + 1}px) {
97
98
  .menu-navigation-content {
98
99
  position: absolute;
99
100
  width: 100%;
@@ -269,17 +270,23 @@ function getNavItemsByColumnEntries(navItems: NavItemComputed[]): NavItemsByColu
269
270
  let isFullWidthCategory: boolean | undefined
270
271
  navItems.forEach((navItem) => {
271
272
  if (navItem.level === 1) {
272
- const isFullWidthCategoryPrevious = isFullWidthCategory
273
- isFullWidthCategory = !!navItem.menuModalFullWidth
274
- if (isFullWidthCategoryPrevious !== undefined && isFullWidthCategoryPrevious !== isFullWidthCategory) {
273
+ if (isFullWidthCategory) {
274
+ assert(navItem.menuModalFullWidth)
275
+ }
276
+ const isFullWidthCategoryPrevious = !!isFullWidthCategory
277
+ if (navItem.menuModalFullWidth) {
278
+ isFullWidthCategory = true
279
+ // Flush
275
280
  navItemsByColumnEntries.push({ columnEntries, isFullWidthCategory: isFullWidthCategoryPrevious })
276
281
  columnEntries = []
282
+ } else {
283
+ isFullWidthCategory = false
277
284
  }
278
285
  }
279
286
  assert(isFullWidthCategory !== undefined)
280
- if (navItem.isColumnEntry) {
287
+ if (navItem.isPotentialColumn) {
281
288
  assert(navItem.level === 1 || navItem.level === 4)
282
- columnEntry = { navItems: [navItem], columnMap: navItem.isColumnEntry }
289
+ columnEntry = { navItems: [navItem], columnMap: navItem.isPotentialColumn }
283
290
  columnEntries.push(columnEntry)
284
291
  } else {
285
292
  assert(navItem.level !== 1)
@@ -4,7 +4,7 @@ export { keepMenuModalOpen }
4
4
  export { closeMenuModal }
5
5
  export { coseMenuModalOnMouseLeave }
6
6
 
7
- import { containerQueryMobileMenu } from '../Layout'
7
+ import { viewTablet } from '../Layout'
8
8
  import { getHydrationPromise } from '../renderer/getHydrationPromise'
9
9
  import { getViewportWidth } from '../utils/getViewportWidth'
10
10
  import { isBrowser } from '../utils/isBrowser'
@@ -111,7 +111,7 @@ function toggleMenuModal(menuId: number) {
111
111
  closeMenuModal()
112
112
  } else {
113
113
  openMenuModal(menuId)
114
- if (getViewportWidth() < containerQueryMobileMenu) autoScroll()
114
+ if (getViewportWidth() < viewTablet) autoScroll()
115
115
  }
116
116
  }
117
117
 
package/MenuModal.tsx CHANGED
@@ -3,7 +3,7 @@ export { MenuModal }
3
3
  import React from 'react'
4
4
  import { usePageContext } from './renderer/usePageContext'
5
5
  import { css } from './utils/css'
6
- import { containerQueryMobileLayout, containerQueryMobileMenu } from './Layout'
6
+ import { viewDesktop, viewTablet } from './Layout'
7
7
  import { ExternalLinks } from './ExternalLinks'
8
8
  import { Style } from './utils/Style'
9
9
  import { NavigationWithColumnLayout } from './MenuModal/NavigationWithColumnLayout'
@@ -79,7 +79,7 @@ function Nav() {
79
79
 
80
80
  function getStyle() {
81
81
  return css`
82
- @media(min-width: ${containerQueryMobileMenu + 1}px) {
82
+ @media(min-width: ${viewTablet + 1}px) {
83
83
  #menu-modal-scroll-container {
84
84
  max-height: calc(100vh - var(--nav-head-height) - var(--block-margin));
85
85
  ${/* https://github.com/brillout/docpress/issues/23 */ ''}
@@ -99,7 +99,7 @@ function getStyle() {
99
99
  display: none !important;
100
100
  }
101
101
  }
102
- @media(max-width: ${containerQueryMobileMenu}px) {
102
+ @media(max-width: ${viewTablet}px) {
103
103
  #menu-modal-scroll-container {
104
104
  ${/* Fallback for Firefox: it doesn't support `dvh` yet: https://caniuse.com/?search=dvh */ ''}
105
105
  ${/* Let's always and systematically use `dvh` instead of `vh` once Firefox supports it */ ''}
@@ -135,7 +135,7 @@ function getStyle() {
135
135
  }
136
136
 
137
137
  ${/* Hide same-page headings navigation */ ''}
138
- @container container-viewport (min-width: ${containerQueryMobileLayout}px) {
138
+ @container container-viewport (min-width: ${viewDesktop}px) {
139
139
  #menu-modal-wrapper .nav-item-level-3 {
140
140
  display: none;
141
141
  }
@@ -31,8 +31,22 @@ type NavItem = {
31
31
  title: string
32
32
  titleInNav: string
33
33
  menuModalFullWidth?: true
34
- isColumnEntry?: ColumnMap
34
+ /**
35
+ * Maps viewport column counts to column indices.
36
+ * Indicates this nav item is a "column entry" (a level-1 or level-4 heading that starts a new column section).
37
+ * Example: `{ 1: 0, 2: 1, 3: 0 }` means:
38
+ * - When there's 1 column, put this item in column 0
39
+ * - When there are 2 columns, put it in column 1
40
+ * - When there are 3 columns, put it in column 0
41
+ */
42
+ isPotentialColumn?: ColumnMap
35
43
  }
44
+ /**
45
+ * A mapping of viewport column counts to column indices.
46
+ * Used to determine which column a nav item should be placed in for different viewport widths.
47
+ * Key: number of columns in the viewport
48
+ * Value: the column index (0-based) where this item should be placed
49
+ */
36
50
  type ColumnMap = Record<number, number>
37
51
 
38
52
  type PropsNavItem = PropsAnchor & PropsSpan
@@ -0,0 +1,518 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { determineNavItemsColumnLayout } from './determineNavItemsColumnLayout'
3
+ import type { NavItem } from './NavItemComponent'
4
+
5
+ describe('determineNavItemsColumnLayout', () => {
6
+ it('should handle simple non-fullWidth categories', () => {
7
+ const navItems: NavItem[] = [
8
+ { level: 1, title: 'API', titleInNav: 'API' },
9
+ { level: 2, title: 'Endpoint 1', titleInNav: 'Endpoint 1' },
10
+ { level: 2, title: 'Endpoint 2', titleInNav: 'Endpoint 2' },
11
+ { level: 1, title: 'Guides', titleInNav: 'Guides' },
12
+ { level: 2, title: 'Guide 1', titleInNav: 'Guide 1' },
13
+ ]
14
+
15
+ determineNavItemsColumnLayout(navItems)
16
+
17
+ expect(navItems).toMatchInlineSnapshot(`
18
+ [
19
+ {
20
+ "isPotentialColumn": {
21
+ "1": 0,
22
+ "2": 0,
23
+ },
24
+ "level": 1,
25
+ "title": "API",
26
+ "titleInNav": "API",
27
+ },
28
+ {
29
+ "level": 2,
30
+ "title": "Endpoint 1",
31
+ "titleInNav": "Endpoint 1",
32
+ },
33
+ {
34
+ "level": 2,
35
+ "title": "Endpoint 2",
36
+ "titleInNav": "Endpoint 2",
37
+ },
38
+ {
39
+ "isPotentialColumn": {
40
+ "1": 0,
41
+ "2": 1,
42
+ },
43
+ "level": 1,
44
+ "title": "Guides",
45
+ "titleInNav": "Guides",
46
+ },
47
+ {
48
+ "level": 2,
49
+ "title": "Guide 1",
50
+ "titleInNav": "Guide 1",
51
+ },
52
+ ]
53
+ `)
54
+ })
55
+
56
+ it('should handle fullWidth categories with level-4 items', () => {
57
+ const navItems: NavItem[] = [
58
+ { level: 1, title: 'Blog', titleInNav: 'Blog', menuModalFullWidth: true },
59
+ { level: 4, title: 'Category 1', titleInNav: 'Category 1' },
60
+ { level: 2, title: 'Post 1', titleInNav: 'Post 1' },
61
+ { level: 2, title: 'Post 2', titleInNav: 'Post 2' },
62
+ { level: 4, title: 'Category 2', titleInNav: 'Category 2' },
63
+ { level: 2, title: 'Post 3', titleInNav: 'Post 3' },
64
+ ]
65
+
66
+ determineNavItemsColumnLayout(navItems)
67
+
68
+ expect(navItems).toMatchInlineSnapshot(`
69
+ [
70
+ {
71
+ "isPotentialColumn": {
72
+ "1": 0,
73
+ "2": 0,
74
+ },
75
+ "level": 1,
76
+ "menuModalFullWidth": true,
77
+ "title": "Blog",
78
+ "titleInNav": "Blog",
79
+ },
80
+ {
81
+ "level": 4,
82
+ "title": "Category 1",
83
+ "titleInNav": "Category 1",
84
+ },
85
+ {
86
+ "level": 2,
87
+ "title": "Post 1",
88
+ "titleInNav": "Post 1",
89
+ },
90
+ {
91
+ "level": 2,
92
+ "title": "Post 2",
93
+ "titleInNav": "Post 2",
94
+ },
95
+ {
96
+ "isPotentialColumn": {
97
+ "1": 0,
98
+ "2": 1,
99
+ },
100
+ "level": 4,
101
+ "title": "Category 2",
102
+ "titleInNav": "Category 2",
103
+ },
104
+ {
105
+ "level": 2,
106
+ "title": "Post 3",
107
+ "titleInNav": "Post 3",
108
+ },
109
+ ]
110
+ `)
111
+ })
112
+
113
+ it('should handle mix of fullWidth and non-fullWidth categories', () => {
114
+ const navItems: NavItem[] = [
115
+ { level: 1, title: 'API', titleInNav: 'API' },
116
+ { level: 2, title: 'Endpoint 1', titleInNav: 'Endpoint 1' },
117
+ { level: 1, title: 'Blog', titleInNav: 'Blog', menuModalFullWidth: true },
118
+ { level: 4, title: 'Category 1', titleInNav: 'Category 1' },
119
+ { level: 2, title: 'Post 1', titleInNav: 'Post 1' },
120
+ ]
121
+
122
+ determineNavItemsColumnLayout(navItems)
123
+
124
+ expect(navItems).toMatchInlineSnapshot(`
125
+ [
126
+ {
127
+ "isPotentialColumn": {
128
+ "1": 0,
129
+ },
130
+ "level": 1,
131
+ "title": "API",
132
+ "titleInNav": "API",
133
+ },
134
+ {
135
+ "level": 2,
136
+ "title": "Endpoint 1",
137
+ "titleInNav": "Endpoint 1",
138
+ },
139
+ {
140
+ "isPotentialColumn": {
141
+ "1": 0,
142
+ },
143
+ "level": 1,
144
+ "menuModalFullWidth": true,
145
+ "title": "Blog",
146
+ "titleInNav": "Blog",
147
+ },
148
+ {
149
+ "level": 4,
150
+ "title": "Category 1",
151
+ "titleInNav": "Category 1",
152
+ },
153
+ {
154
+ "level": 2,
155
+ "title": "Post 1",
156
+ "titleInNav": "Post 1",
157
+ },
158
+ ]
159
+ `)
160
+ })
161
+
162
+ it('should handle single category', () => {
163
+ const navItems: NavItem[] = [
164
+ { level: 1, title: 'Single', titleInNav: 'Single' },
165
+ { level: 2, title: 'Item 1', titleInNav: 'Item 1' },
166
+ ]
167
+
168
+ determineNavItemsColumnLayout(navItems)
169
+
170
+ expect(navItems).toMatchInlineSnapshot(`
171
+ [
172
+ {
173
+ "isPotentialColumn": {
174
+ "1": 0,
175
+ },
176
+ "level": 1,
177
+ "title": "Single",
178
+ "titleInNav": "Single",
179
+ },
180
+ {
181
+ "level": 2,
182
+ "title": "Item 1",
183
+ "titleInNav": "Item 1",
184
+ },
185
+ ]
186
+ `)
187
+ })
188
+
189
+ it('should handle empty array', () => {
190
+ const navItems: NavItem[] = []
191
+
192
+ determineNavItemsColumnLayout(navItems)
193
+
194
+ expect(navItems).toMatchInlineSnapshot(`
195
+ []
196
+ `)
197
+ })
198
+
199
+ it('should handle multiple level-4 entries in fullWidth category', () => {
200
+ const navItems: NavItem[] = [
201
+ { level: 1, title: 'Blog', titleInNav: 'Blog', menuModalFullWidth: true },
202
+ { level: 4, title: 'Category 1', titleInNav: 'Category 1' },
203
+ { level: 2, title: 'Post 1', titleInNav: 'Post 1' },
204
+ { level: 4, title: 'Category 2', titleInNav: 'Category 2' },
205
+ { level: 2, title: 'Post 2', titleInNav: 'Post 2' },
206
+ { level: 4, title: 'Category 3', titleInNav: 'Category 3' },
207
+ { level: 2, title: 'Post 3', titleInNav: 'Post 3' },
208
+ ]
209
+
210
+ determineNavItemsColumnLayout(navItems)
211
+
212
+ expect(navItems).toMatchInlineSnapshot(`
213
+ [
214
+ {
215
+ "isPotentialColumn": {
216
+ "1": 0,
217
+ "2": 0,
218
+ "3": 0,
219
+ },
220
+ "level": 1,
221
+ "menuModalFullWidth": true,
222
+ "title": "Blog",
223
+ "titleInNav": "Blog",
224
+ },
225
+ {
226
+ "level": 4,
227
+ "title": "Category 1",
228
+ "titleInNav": "Category 1",
229
+ },
230
+ {
231
+ "level": 2,
232
+ "title": "Post 1",
233
+ "titleInNav": "Post 1",
234
+ },
235
+ {
236
+ "isPotentialColumn": {
237
+ "1": 0,
238
+ "2": 0,
239
+ "3": 1,
240
+ },
241
+ "level": 4,
242
+ "title": "Category 2",
243
+ "titleInNav": "Category 2",
244
+ },
245
+ {
246
+ "level": 2,
247
+ "title": "Post 2",
248
+ "titleInNav": "Post 2",
249
+ },
250
+ {
251
+ "isPotentialColumn": {
252
+ "1": 0,
253
+ "2": 1,
254
+ "3": 2,
255
+ },
256
+ "level": 4,
257
+ "title": "Category 3",
258
+ "titleInNav": "Category 3",
259
+ },
260
+ {
261
+ "level": 2,
262
+ "title": "Post 3",
263
+ "titleInNav": "Post 3",
264
+ },
265
+ ]
266
+ `)
267
+ })
268
+
269
+ it('should handle many items in single category', () => {
270
+ const navItems: NavItem[] = [
271
+ { level: 1, title: 'API', titleInNav: 'API' },
272
+ { level: 2, title: 'Item 1', titleInNav: 'Item 1' },
273
+ { level: 2, title: 'Item 2', titleInNav: 'Item 2' },
274
+ { level: 2, title: 'Item 3', titleInNav: 'Item 3' },
275
+ { level: 2, title: 'Item 4', titleInNav: 'Item 4' },
276
+ { level: 2, title: 'Item 5', titleInNav: 'Item 5' },
277
+ ]
278
+
279
+ determineNavItemsColumnLayout(navItems)
280
+
281
+ expect(navItems).toMatchInlineSnapshot(`
282
+ [
283
+ {
284
+ "isPotentialColumn": {
285
+ "1": 0,
286
+ },
287
+ "level": 1,
288
+ "title": "API",
289
+ "titleInNav": "API",
290
+ },
291
+ {
292
+ "level": 2,
293
+ "title": "Item 1",
294
+ "titleInNav": "Item 1",
295
+ },
296
+ {
297
+ "level": 2,
298
+ "title": "Item 2",
299
+ "titleInNav": "Item 2",
300
+ },
301
+ {
302
+ "level": 2,
303
+ "title": "Item 3",
304
+ "titleInNav": "Item 3",
305
+ },
306
+ {
307
+ "level": 2,
308
+ "title": "Item 4",
309
+ "titleInNav": "Item 4",
310
+ },
311
+ {
312
+ "level": 2,
313
+ "title": "Item 5",
314
+ "titleInNav": "Item 5",
315
+ },
316
+ ]
317
+ `)
318
+ })
319
+
320
+ it('should handle demo headings structure', () => {
321
+ // Duplicated from demo/headings.ts
322
+ const navItems: NavItem[] = [
323
+ { level: 1, title: 'Overview', titleInNav: 'Overview' },
324
+ { level: 2, title: 'Introduction', titleInNav: 'Introduction' },
325
+ { level: 2, title: 'Notes', titleInNav: 'Notes' },
326
+ { level: 2, title: 'Features', titleInNav: 'Features' },
327
+ { level: 2, title: 'Open Source Pricing', titleInNav: 'Open Source Pricing' },
328
+
329
+ { level: 1, title: 'Guides', titleInNav: 'Guides' },
330
+ { level: 2, title: 'Some Page', titleInNav: 'Some Page' },
331
+ { level: 4, title: 'Some category', titleInNav: 'Some category' },
332
+ { level: 2, title: 'Tiny Page', titleInNav: 'Tiny Page' },
333
+ { level: 2, title: 'June Releases', titleInNav: 'June Releases' },
334
+ { level: 2, title: 'Press Kit', titleInNav: 'Press Kit' },
335
+ { level: 2, title: 'Page wiht error', titleInNav: 'Page wiht error' },
336
+
337
+ { level: 1, title: 'API', titleInNav: 'API', menuModalFullWidth: true },
338
+ { level: 4, title: 'Category 1', titleInNav: 'Category 1' },
339
+ { level: 2, title: '`Page 1`', titleInNav: '`Page 1`' },
340
+ { level: 4, title: 'Category 2', titleInNav: 'Category 2' },
341
+ { level: 2, title: 'Page 2', titleInNav: 'Page 2' },
342
+ { level: 4, title: 'Category 3', titleInNav: 'Category 3' },
343
+ { level: 2, title: 'Page 3', titleInNav: 'Page 3' },
344
+ { level: 2, title: 'Page 4', titleInNav: 'Page 4' },
345
+
346
+ { level: 1, title: 'Blog', titleInNav: 'Blog', menuModalFullWidth: true },
347
+ { level: 4, title: 'Blog Category 1', titleInNav: 'Blog Category 1' },
348
+ { level: 2, title: 'Some Blog Post', titleInNav: 'Some Blog Post' },
349
+ { level: 4, title: 'Blog Category 2', titleInNav: 'Blog Category 2' },
350
+ { level: 2, title: 'Some Other Blog Post', titleInNav: 'Some Other Blog Post' },
351
+ ]
352
+
353
+ determineNavItemsColumnLayout(navItems)
354
+
355
+ expect(navItems).toMatchInlineSnapshot(`
356
+ [
357
+ {
358
+ "isPotentialColumn": {
359
+ "1": 0,
360
+ "2": 0,
361
+ },
362
+ "level": 1,
363
+ "title": "Overview",
364
+ "titleInNav": "Overview",
365
+ },
366
+ {
367
+ "level": 2,
368
+ "title": "Introduction",
369
+ "titleInNav": "Introduction",
370
+ },
371
+ {
372
+ "level": 2,
373
+ "title": "Notes",
374
+ "titleInNav": "Notes",
375
+ },
376
+ {
377
+ "level": 2,
378
+ "title": "Features",
379
+ "titleInNav": "Features",
380
+ },
381
+ {
382
+ "level": 2,
383
+ "title": "Open Source Pricing",
384
+ "titleInNav": "Open Source Pricing",
385
+ },
386
+ {
387
+ "isPotentialColumn": {
388
+ "1": 0,
389
+ "2": 1,
390
+ },
391
+ "level": 1,
392
+ "title": "Guides",
393
+ "titleInNav": "Guides",
394
+ },
395
+ {
396
+ "level": 2,
397
+ "title": "Some Page",
398
+ "titleInNav": "Some Page",
399
+ },
400
+ {
401
+ "level": 4,
402
+ "title": "Some category",
403
+ "titleInNav": "Some category",
404
+ },
405
+ {
406
+ "level": 2,
407
+ "title": "Tiny Page",
408
+ "titleInNav": "Tiny Page",
409
+ },
410
+ {
411
+ "level": 2,
412
+ "title": "June Releases",
413
+ "titleInNav": "June Releases",
414
+ },
415
+ {
416
+ "level": 2,
417
+ "title": "Press Kit",
418
+ "titleInNav": "Press Kit",
419
+ },
420
+ {
421
+ "level": 2,
422
+ "title": "Page wiht error",
423
+ "titleInNav": "Page wiht error",
424
+ },
425
+ {
426
+ "isPotentialColumn": {
427
+ "1": 0,
428
+ "2": 0,
429
+ "3": 0,
430
+ },
431
+ "level": 1,
432
+ "menuModalFullWidth": true,
433
+ "title": "API",
434
+ "titleInNav": "API",
435
+ },
436
+ {
437
+ "level": 4,
438
+ "title": "Category 1",
439
+ "titleInNav": "Category 1",
440
+ },
441
+ {
442
+ "level": 2,
443
+ "title": "\`Page 1\`",
444
+ "titleInNav": "\`Page 1\`",
445
+ },
446
+ {
447
+ "isPotentialColumn": {
448
+ "1": 0,
449
+ "2": 0,
450
+ "3": 1,
451
+ },
452
+ "level": 4,
453
+ "title": "Category 2",
454
+ "titleInNav": "Category 2",
455
+ },
456
+ {
457
+ "level": 2,
458
+ "title": "Page 2",
459
+ "titleInNav": "Page 2",
460
+ },
461
+ {
462
+ "isPotentialColumn": {
463
+ "1": 0,
464
+ "2": 1,
465
+ "3": 2,
466
+ },
467
+ "level": 4,
468
+ "title": "Category 3",
469
+ "titleInNav": "Category 3",
470
+ },
471
+ {
472
+ "level": 2,
473
+ "title": "Page 3",
474
+ "titleInNav": "Page 3",
475
+ },
476
+ {
477
+ "level": 2,
478
+ "title": "Page 4",
479
+ "titleInNav": "Page 4",
480
+ },
481
+ {
482
+ "isPotentialColumn": {
483
+ "1": 0,
484
+ "2": 0,
485
+ },
486
+ "level": 1,
487
+ "menuModalFullWidth": true,
488
+ "title": "Blog",
489
+ "titleInNav": "Blog",
490
+ },
491
+ {
492
+ "level": 4,
493
+ "title": "Blog Category 1",
494
+ "titleInNav": "Blog Category 1",
495
+ },
496
+ {
497
+ "level": 2,
498
+ "title": "Some Blog Post",
499
+ "titleInNav": "Some Blog Post",
500
+ },
501
+ {
502
+ "isPotentialColumn": {
503
+ "1": 0,
504
+ "2": 1,
505
+ },
506
+ "level": 4,
507
+ "title": "Blog Category 2",
508
+ "titleInNav": "Blog Category 2",
509
+ },
510
+ {
511
+ "level": 2,
512
+ "title": "Some Other Blog Post",
513
+ "titleInNav": "Some Other Blog Post",
514
+ },
515
+ ]
516
+ `)
517
+ })
518
+ })