@brillout/docpress 0.7.9-commit-ec0a3b5 → 0.7.10-commit-776b1fc

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 (94) hide show
  1. package/+config.ts +2 -10
  2. package/Layout.tsx +397 -67
  3. package/{navigation/NavigationHeader.tsx → Links.tsx} +6 -57
  4. package/MenuModal.tsx +146 -0
  5. package/autoScrollNav.ts +4 -5
  6. package/components/CodeBlockTransformer.tsx +0 -2
  7. package/components/Note.css +4 -4
  8. package/components/Note.tsx +0 -2
  9. package/components/Supporters.tsx +1 -0
  10. package/config/resolveHeadingsData.ts +20 -23
  11. package/config/resolvePageContext.ts +11 -1
  12. package/css/code/block.css +5 -5
  13. package/css/code/inline.css +1 -1
  14. package/css/code.css +9 -5
  15. package/css/index.css +0 -4
  16. package/css/reset.css +0 -6
  17. package/dist/+config.d.ts +1 -13
  18. package/dist/+config.js +0 -3
  19. package/dist/components/CodeBlockTransformer.d.ts +1 -0
  20. package/dist/components/CodeBlockTransformer.js +1 -0
  21. package/dist/components/Note.d.ts +1 -0
  22. package/dist/components/Note.js +1 -0
  23. package/dist/components/Supporters.js +1 -0
  24. package/dist/config/resolveHeadingsData.d.ts +5 -8
  25. package/dist/config/resolveHeadingsData.js +20 -22
  26. package/dist/config/resolvePageContext.d.ts +5 -7
  27. package/dist/config/resolvePageContext.js +2 -1
  28. package/dist/navigation/Navigation.d.ts +12 -17
  29. package/dist/navigation/Navigation.js +75 -74
  30. package/dist/renderer/getStyleColumnLayout.d.ts +7 -0
  31. package/dist/renderer/getStyleColumnLayout.js +167 -0
  32. package/dist/types/Heading.d.ts +2 -4
  33. package/dist/utils/client.d.ts +1 -0
  34. package/dist/utils/client.js +1 -0
  35. package/dist/utils/css.d.ts +1 -0
  36. package/dist/utils/css.js +27 -0
  37. package/dist/utils/getGlobalObject.d.ts +1 -0
  38. package/dist/utils/getGlobalObject.js +9 -0
  39. package/docsearch/DocSearchInstall.tsx +23 -0
  40. package/docsearch/SearchLink.tsx +48 -0
  41. package/docsearch/closeDocsearchModal.ts +29 -0
  42. package/initKeyBindings.ts +41 -0
  43. package/installSectionUrlHashs.ts +6 -5
  44. package/navigation/Navigation.css +101 -3
  45. package/navigation/Navigation.tsx +110 -128
  46. package/package.json +1 -8
  47. package/renderer/getPageContextCurrent.ts +16 -0
  48. package/renderer/getPageElement.tsx +19 -7
  49. package/renderer/getStyleColumnLayout.ts +187 -0
  50. package/renderer/onRenderClient.tsx +20 -24
  51. package/renderer/onRenderHtml.tsx +3 -8
  52. package/types/Heading.ts +2 -5
  53. package/types.d.ts +8 -0
  54. package/utils/client.ts +1 -0
  55. package/utils/css.ts +26 -0
  56. package/utils/getGlobalObject.ts +11 -0
  57. package/Layout.css +0 -63
  58. package/MobileHeader.tsx +0 -70
  59. package/algolia/DocSearch.css +0 -28
  60. package/components/FeatureList/FeatureList.client.ts +0 -60
  61. package/components/FeatureList/FeatureList.css +0 -119
  62. package/components/FeatureList/FeatureList.tsx +0 -114
  63. package/components/FeatureList/chevron.svg +0 -7
  64. package/css/block-design.css +0 -4
  65. package/dist/autoScrollNav.d.ts +0 -3
  66. package/dist/autoScrollNav.js +0 -36
  67. package/dist/components/Algolia/Hit.d.ts +0 -4
  68. package/dist/components/Algolia/Hit.js +0 -30
  69. package/dist/components/Algolia/SelectIcon.d.ts +0 -2
  70. package/dist/components/Algolia/SelectIcon.js +0 -7
  71. package/dist/components/Algolia/Snippet.d.ts +0 -13
  72. package/dist/components/Algolia/Snippet.js +0 -37
  73. package/dist/components/Algolia/SourceIcon.d.ts +0 -4
  74. package/dist/components/Algolia/SourceIcon.js +0 -23
  75. package/dist/components/Algolia/types.d.ts +0 -79
  76. package/dist/components/Algolia/types.js +0 -1
  77. package/dist/navigation/NavigationHeader.d.ts +0 -8
  78. package/dist/navigation/NavigationHeader.js +0 -75
  79. package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.d.ts +0 -6
  80. package/dist/navigation/navigation-fullscreen/NavigationFullscreenButton.js +0 -23
  81. package/dist/navigation/navigation-fullscreen/hotkeyLabel.d.ts +0 -1
  82. package/dist/navigation/navigation-fullscreen/hotkeyLabel.js +0 -1
  83. package/navigation/Navigation-highlight.css +0 -41
  84. package/navigation/Navigation-items.css +0 -116
  85. package/navigation/Navigation-layout.css +0 -129
  86. package/navigation/initMobileNavigation.ts +0 -23
  87. package/navigation/initPressKit.ts +0 -19
  88. package/navigation/navigation-fullscreen/NavigationFullscreenButton.css +0 -32
  89. package/navigation/navigation-fullscreen/NavigationFullscreenButton.tsx +0 -47
  90. package/navigation/navigation-fullscreen/chevron.svg +0 -1
  91. package/navigation/navigation-fullscreen/close.svg +0 -4
  92. package/navigation/navigation-fullscreen/hotkeyLabel.ts +0 -1
  93. package/navigation/navigation-fullscreen/initNavigationFullscreen.ts +0 -60
  94. package/renderer/getCSSForResponsiveFullcreenNavItems.ts +0 -128
@@ -1,41 +0,0 @@
1
- /*
2
- .nav-item {
3
- border-top: 1px solid transparent;
4
- }
5
- .nav-item.is-active {
6
- border-color: #eaeaea;
7
- }
8
- .nav-item[is-active] {
9
- background-color: attr(is-active)
10
- }
11
- */
12
-
13
- /*
14
- #navigation-container:not(:hover) ::-webkit-scrollbar {
15
- display: none;
16
- }
17
- #navigation-container ::-webkit-scrollbar-thumb {
18
- opacity: 0;
19
- }
20
- #navigation-container ::-webkit-scrollbar-track {
21
- opacity: 0;
22
- }
23
- */
24
-
25
- /*
26
- .nav-tree:not(.expanded) > .nav-tree {
27
- edisplay: none;
28
- background:red;
29
- }
30
- */
31
- /*
32
- .nav-tree.expanded,
33
- .nav-tree.expanded > .nav-tree {
34
- display: inherit;
35
- }
36
- .nav-tree.expanded,
37
- .nav-tree.expanded > .nav-tree {
38
- display: inherit;
39
- background:red;
40
- }
41
- */
@@ -1,116 +0,0 @@
1
- .nav-item {
2
- display: block;
3
- white-space: nowrap;
4
- overflow-x: hidden;
5
- --padding-left-global: 9px;
6
- --padding-left-additional: 0px;
7
- }
8
- .nav-item code {
9
- font-size: 0.9em;
10
- }
11
- .nav-item-level-1 + .nav-item-level-4 {
12
- margin-top: -2px;
13
- }
14
- .nav-item-level-4 {
15
- margin-top: 14px;
16
- margin-bottom: -1px;
17
- color: #999;
18
- font-size: 12px;
19
- font-weight: 400;
20
- letter-spacing: 0.15ch;
21
- padding-left: var(--padding-left-global);
22
- padding-right: 4px;
23
- text-decoration: none;
24
- }
25
- .nav-item-level-1 {
26
- margin-top: 30px;
27
- font-size: 15.4px;
28
- text-transform: uppercase;
29
- font-weight: 600;
30
- letter-spacing: 0.15ch;
31
- color: var(--color-text);
32
- padding: 12px 0;
33
- padding-left: calc(var(--padding-left-global) - 2px);
34
- padding-right: 4px;
35
- text-decoration: none;
36
- }
37
- .nav-item-level-2 {
38
- text-decoration: none;
39
- font-size: 14.4px;
40
- font-weight: 400;
41
- letter-spacing: 0.15ch;
42
- color: var(--color-text);
43
- padding-left: var(--padding-left-global);
44
- padding-right: 0;
45
- --padding: 4px;
46
- padding-top: var(--padding);
47
- padding-bottom: var(--padding);
48
- }
49
- .nav-item-level-3 {
50
- font-size: 12px;
51
- font-weight: 400;
52
- letter-spacing: 0.15ch;
53
- color: var(--color-text);
54
- text-decoration: none;
55
- --padding: 5px;
56
-
57
- background-color: #f9f9f9;
58
- padding: var(--padding) 0;
59
- padding-left: calc(var(--padding-left-global) + var(--padding-left-additional));
60
- }
61
- html.navigation-fullscreen .nav-item-level-3 {
62
- border-right: 4px solid #eee;
63
- }
64
- .nav-item-level-3.nav-item-first-of-its-kind {
65
- padding-top: calc(var(--padding) * 1.6);
66
- }
67
- .nav-item-level-3.nav-item-last-of-its-kind {
68
- padding-bottom: calc(var(--padding) * 2);
69
- }
70
- .nav-item-level-2,
71
- .nav-item-level-3 {
72
- position: relative;
73
- }
74
- /*
75
- .nav-item-level-2.is-active .nav-item-text{
76
- background-color: var(--background-color);
77
- }
78
- */
79
- .nav-item-level-2.is-active {
80
- background-color: var(--background-color);
81
- }
82
- .nav-item-level-3.is-active:before {
83
- display: block;
84
- content: '';
85
- position: absolute;
86
- width: 4px;
87
- left: 0;
88
- top: 0;
89
- height: 100%;
90
- background-color: var(--background-color);
91
- z-index: 10;
92
- }
93
- .nav-item-level-3.is-active-last:after {
94
- display: block;
95
- content: '';
96
- position: absolute;
97
- height: 4px;
98
- left: 0;
99
- bottom: 0;
100
- width: 100%;
101
- background-color: var(--background-color);
102
- z-index: 10;
103
- border-bottom-left-radius: 5px;
104
- }
105
- html.navigation-fullscreen .nav-item {
106
- --expend-border-radius: 5px;
107
- }
108
- .nav-item.is-active-first {
109
- border-top-left-radius: 5px;
110
- border-top-right-radius: var(--expend-border-radius);
111
- }
112
- .nav-item.is-active-last,
113
- .nav-item.is-active-last:before {
114
- border-bottom-left-radius: 5px;
115
- border-bottom-right-radius: var(--expend-border-radius);
116
- }
@@ -1,129 +0,0 @@
1
- :root {
2
- --mobile-header-height: 60px;
3
- --navigation-min-width: 300px;
4
- --navigation-max-width: 350px;
5
- }
6
- #navigation-wrapper {
7
- min-width: var(--navigation-min-width);
8
- }
9
- .doc-page #navigation-wrapper {
10
- max-width: var(--navigation-max-width);
11
- }
12
- .landing-page #navigation-wrapper {
13
- /* prettier-ignore */
14
- max-width: min(var(--navigation-max-width), max(var(--navigation-min-width), calc(var(--navigation-min-width) + 100% - 1240px)));
15
- }
16
- #navigation-container {
17
- /* `position: fixed` doesn't inherit the parent's width */
18
- position: sticky;
19
- overflow-y: auto;
20
- overscroll-behavior: contain;
21
- border-right: 1px solid #eee;
22
- --background-color: #f0f0f0;
23
- padding-bottom: 70px;
24
- }
25
- .navigation-content {
26
- margin-top: 20px;
27
- }
28
- #navigation-content-detached {
29
- margin-top: 25px;
30
- }
31
-
32
- #mobile-navigation-mask {
33
- position: fixed;
34
- width: 100%;
35
- height: 100vh;
36
- top: 0;
37
- left: 0;
38
- z-index: 2;
39
- }
40
- /* `1140px` is the breaking point that preserves the width of code blocks. */
41
- /* BEFORE EDITING THIS: also change the `1139px` value below */
42
- @media screen and (min-width: 1140px) {
43
- #mobile-header {
44
- display: none !important;
45
- }
46
- #navigation-container {
47
- height: 100vh;
48
- top: 0;
49
- }
50
- #mobile-navigation-mask {
51
- display: none;
52
- }
53
- }
54
- #navigation-container {
55
- transition: transform 0.25s ease;
56
- background: white;
57
- z-index: 3;
58
- }
59
- .page-wrapper {
60
- margin-left: calc(-1 * var(--navigation-fullscreen-button-width));
61
- }
62
- @media screen and (max-width: 1139px) {
63
- #navigation-header-logo {
64
- display: none !important;
65
- }
66
- #navigation-wrapper {
67
- min-width: 0px !important;
68
- max-width: 0px !important;
69
- }
70
- #navigation-fullscreen-button {
71
- display: none;
72
- }
73
- .page-wrapper {
74
- margin-left: 0 !important;
75
- }
76
- #navigation-container {
77
- --width: min(100%, 350px);
78
- width: var(--width);
79
- left: 0;
80
- height: calc(100vh - var(--mobile-header-height));
81
- top: var(--mobile-header-height);
82
- padding-top: 20px;
83
- /* `position: sticky` doesn't seem to work on mobile */
84
- position: fixed;
85
- }
86
- body:not(.mobile-show-navigation) #navigation-container {
87
- transform: translateX(calc(-1 * var(--width)));
88
- }
89
- body:not(.mobile-show-navigation) #mobile-navigation-mask {
90
- display: none;
91
- }
92
- #mobile-header {
93
- display: inherit;
94
- }
95
- .doc-page h2 {
96
- --padding-top: calc(var(--mobile-header-height) + 12px) !important;
97
- }
98
- }
99
-
100
- html.navigation-fullscreen #navigation-container {
101
- width: 100%;
102
- height: 100vh;
103
- position: fixed;
104
- top: 0;
105
- left: 0;
106
- background-color: white;
107
- }
108
- html.navigation-fullscreen #navigation-header,
109
- html.navigation-fullscreen #navigation-content-detached,
110
- html.navigation-fullscreen #detached-note {
111
- display: none !important;
112
- }
113
- html.navigation-fullscreen {
114
- /* disable scroll of main view */
115
- overflow: hidden !important;
116
- }
117
- html.navigation-fullscreen #navigation-body {
118
- display: flex;
119
- justify-content: center;
120
- }
121
- html.navigation-fullscreen #navigation-content-main {
122
- flex-grow: 1;
123
- margin-top: -25px;
124
- column-gap: 20px;
125
- }
126
- html.navigation-fullscreen .nav-items-group {
127
- break-inside: avoid;
128
- width: 100%;
129
- }
@@ -1,23 +0,0 @@
1
- export { initMobileNavigation }
2
- export { hideMobileNavigation }
3
-
4
- function initMobileNavigation() {
5
- activateMobileShowNavigationToggle()
6
- activateMobileNavigationMask()
7
- }
8
-
9
- function activateMobileShowNavigationToggle() {
10
- const toggle = document.getElementById('mobile-show-navigation-toggle')!
11
- toggle.onclick = toggleNavigation
12
- }
13
- function activateMobileNavigationMask() {
14
- const navigationMask = document.getElementById('mobile-navigation-mask')!
15
- navigationMask.onclick = toggleNavigation
16
- }
17
-
18
- function toggleNavigation() {
19
- document.body.classList.toggle('mobile-show-navigation')
20
- }
21
- function hideMobileNavigation() {
22
- document.body.classList.remove('mobile-show-navigation')
23
- }
@@ -1,19 +0,0 @@
1
- export { initPressKit }
2
-
3
- import { navigate } from 'vike/client/router'
4
-
5
- function initPressKit() {
6
- // Right click navigation header => show /press
7
- navigationHeaderRightClickInterceptor()
8
- }
9
-
10
- function navigationHeaderRightClickInterceptor() {
11
- const navHeader = document.getElementById('navigation-header')!
12
- if (!navHeader.classList.contains('press-kit')) return
13
- if (window.location.pathname === '/press') return
14
- const navHeaderImg = document.querySelector('#navigation-header-logo img') as HTMLElement
15
- navHeaderImg.oncontextmenu = (ev) => {
16
- ev.preventDefault()
17
- navigate('/press#logo')
18
- }
19
- }
@@ -1,32 +0,0 @@
1
- :root {
2
- --navigation-fullscreen-button-width: 20px;
3
- }
4
- #navigation-fullscreen-button {
5
- width: var(--navigation-fullscreen-button-width);
6
- position: relative;
7
- z-index: 2;
8
- }
9
- #navigation-wrapper:hover + #navigation-fullscreen-button > div > div,
10
- #navigation-fullscreen-button:hover > div > div {
11
- left: 0px;
12
- }
13
- #navigation-fullscreen-button > div > div {
14
- transition: all 0.3s ease-in-out;
15
- left: -20px;
16
- position: absolute;
17
- height: 100%;
18
- width: 100%;
19
- background-color: #eee !important;
20
- background: url('./chevron.svg');
21
- background-repeat: no-repeat;
22
- background-position: center center;
23
- }
24
-
25
- html:not(.navigation-fullscreen) #navigation-fullscreen-close {
26
- display: none;
27
- }
28
-
29
- html.navigation-fullscreen #page-content {
30
- /* Make `Ctrl-F` browser search only crawl the navigation */
31
- visibility: hidden;
32
- }
@@ -1,47 +0,0 @@
1
- export { NavigationFullscreenButton }
2
- export { NavigationFullscreenClose }
3
-
4
- import React from 'react'
5
- import './NavigationFullscreenButton.css'
6
- import closeIcon from './close.svg'
7
- import { hotkeyLabel } from './hotkeyLabel'
8
-
9
- function NavigationFullscreenButton() {
10
- return (
11
- <>
12
- <a id="navigation-fullscreen-button">
13
- <div
14
- style={{
15
- position: 'fixed',
16
- cursor: 'pointer',
17
- height: '100vh',
18
- width: 20,
19
- overflow: 'hidden',
20
- }}
21
- >
22
- <div></div>
23
- </div>
24
- <div
25
- style={{ position: 'fixed', height: '100vh', width: 20 }}
26
- aria-label={hotkeyLabel}
27
- data-balloon-pos="right"
28
- data-balloon-blunt
29
- ></div>
30
- </a>
31
- </>
32
- )
33
- }
34
-
35
- function NavigationFullscreenClose() {
36
- return (
37
- <a
38
- id="navigation-fullscreen-close"
39
- style={{ position: 'absolute', top: 11, right: 11, zIndex: 10 }}
40
- aria-label={hotkeyLabel}
41
- data-balloon-pos="left"
42
- data-balloon-blunt
43
- >
44
- <img src={closeIcon} height={50} width={50} style={{ display: 'block' }} />
45
- </a>
46
- )
47
- }
@@ -1 +0,0 @@
1
- <svg width="32" height="32" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="#666" stroke-width="1" fill="#666" fill-rule="evenodd" d="M6.776 1.553a.5.5 0 0 1 .671.223l3 6a.5.5 0 0 1 0 .448l-3 6a.5.5 0 1 1-.894-.448L9.44 8L6.553 2.224a.5.5 0 0 1 .223-.671z"/></svg>
@@ -1,4 +0,0 @@
1
- <svg width="48.855" height="48.855" version="1.1" viewBox="0 0 22.901 22.901" xmlns="http://www.w3.org/2000/svg">
2
- <circle cx="11.45" cy="11.45" r="10.607" fill="#fff" stroke="#666" stroke-dashoffset="251.44" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.6875" style="paint-order:normal"/>
3
- <path d="m7.5904 6.2204 3.86 3.86 3.84-3.84a0.92 0.92 0 0 1 0.66-0.29 1 1 0 0 1 1 1 0.9 0.9 0 0 1-0.27 0.66l-3.89 3.84 3.89 3.89a0.9 0.9 0 0 1 0.27 0.61 1 1 0 0 1-1 1 0.92 0.92 0 0 1-0.69-0.27l-3.81-3.86-3.85 3.85a0.92 0.92 0 0 1-0.65 0.28 1 1 0 0 1-1-1 0.9 0.9 0 0 1 0.27-0.66l3.89-3.84-3.89-3.89a0.9 0.9 0 0 1-0.27-0.61 1 1 0 0 1 1-1c0.24 3e-3 0.47 0.1 0.64 0.27z" fill="#666" stroke="#666" stroke-width=".11719"/>
4
- </svg>
@@ -1 +0,0 @@
1
- export const hotkeyLabel = 'Hotkey <Esc>'
@@ -1,60 +0,0 @@
1
- export { initNavigationFullscreen }
2
- export { initNavigationFullscreenOnce }
3
- export { hideNavigationFullScreen }
4
-
5
- import { assert } from '../../utils/client'
6
-
7
- let scrollPositionBeforeToggle: number
8
-
9
- function initNavigationFullscreenOnce() {
10
- scrollPositionBeforeToggle = 0 // Initial scroll of fullscreen navigation is 0
11
- initKeyBindings()
12
- }
13
- function initKeyBindings() {
14
- document.addEventListener(
15
- // We don't use keydown to not interfere with user pressing `<Esc>` for closing the browser's `<Ctrl-F>` search diablog, see https://stackoverflow.com/questions/66595035/how-to-detect-escape-key-if-search-bar-of-browser-is-open
16
- 'keydown',
17
- (ev) => {
18
- if (document.body.classList.contains('DocSearch--active')) return
19
- if (ev.key === 'Escape') toggleNavExpend()
20
- },
21
- false,
22
- )
23
- initTopNavigation()
24
- }
25
- function initNavigationFullscreen() {
26
- document.getElementById('navigation-fullscreen-button')!.onclick = toggleNavExpend
27
- document.getElementById('navigation-fullscreen-close')!.onclick = toggleNavExpend
28
- }
29
-
30
- function toggleNavExpend() {
31
- assert(scrollPositionBeforeToggle !== undefined)
32
- const navContainer = document.getElementById('navigation-container')!
33
- const scrollPos = navContainer.scrollTop
34
- document.documentElement.classList.toggle('navigation-fullscreen')
35
- navContainer.scrollTop = scrollPositionBeforeToggle
36
- scrollPositionBeforeToggle = scrollPos
37
- }
38
- function hideNavigationFullScreen() {
39
- if (!document.documentElement.classList.contains('navigation-fullscreen')) return
40
- toggleNavExpend()
41
- }
42
-
43
- function initTopNavigation() {
44
- document.addEventListener('click', (ev) => {
45
- const linkTag = findLinkTag(ev.target as HTMLElement)
46
- if (!linkTag) return
47
- if (linkTag.id !== 'doclink') return
48
- toggleNavExpend()
49
- })
50
- }
51
- function findLinkTag(target: HTMLElement): null | HTMLElement {
52
- while (target.tagName !== 'A') {
53
- const { parentNode } = target
54
- if (!parentNode) {
55
- return null
56
- }
57
- target = parentNode as HTMLElement
58
- }
59
- return target
60
- }
@@ -1,128 +0,0 @@
1
- export { getCSSForResponsiveFullcreenNavItems }
2
-
3
- // There doens't seem to be as simpler way to have a column layout that uses the whole width real estate.
4
- // - https://stackoverflow.com/questions/9683425/css-column-count-not-respected
5
- // - https://stackoverflow.com/questions/25446921/get-flexbox-column-wrap-to-use-full-width-and-minimize-height
6
- // - https://stackoverflow.com/questions/74873283/how-to-create-a-css-grid-with-3-columns-having-column-flow
7
- // - https://stackoverflow.com/questions/50693793/3-columns-grid-top-to-bottom-using-grid-css
8
- // - https://stackoverflow.com/questions/9119347/html-css-vertical-flow-layout-columnar-style-how-to-implement
9
- // - https://stackoverflow.com/questions/27119691/how-to-start-a-new-column-in-flex-column-wrap-layout
10
- // - https://stackoverflow.com/questions/45264354/is-it-possible-to-place-more-than-one-element-into-a-css-grid-cell-without-overl/49047281#49047281
11
-
12
- import assert from 'assert'
13
- import { type NavItemGrouped } from '../navigation/Navigation'
14
-
15
- function getCSSForResponsiveFullcreenNavItems(navItemsGrouped: NavItemGrouped[]) {
16
- const columnWidthMin = 300
17
- const columnWidthMax = 350
18
- const columnsUnmerged = navItemsGrouped.map((navItem) => navItem.navItemChilds.length)
19
- let CSS = '\n'
20
- for (let numberOfColumns = navItemsGrouped.length; numberOfColumns >= 1; numberOfColumns--) {
21
- let CSS_block: string[] = []
22
- CSS_block.push(
23
- ...[
24
- //
25
- ` html.navigation-fullscreen #navigation-content-main {`,
26
- ` column-count: ${numberOfColumns};`,
27
- ` max-width: min(100%, ${columnWidthMax * numberOfColumns}px);`,
28
- ` }`,
29
- ],
30
- )
31
- const columnsIdMap = determineColumns(columnsUnmerged, numberOfColumns)
32
- const columnBreakPoints = determineColumnBreakPoints(columnsIdMap)
33
- columnBreakPoints.forEach((columnBreakPoint, columnUngroupedId) => {
34
- CSS_block.push(
35
- ...[
36
- //
37
- ` .nav-items-group:nth-child(${columnUngroupedId + 1}) {`,
38
- ` break-before: ${columnBreakPoint ? 'column' : 'avoid'};`,
39
- ` }`,
40
- ],
41
- )
42
- })
43
- const noMediaQuery = numberOfColumns === navItemsGrouped.length
44
- if (!noMediaQuery) {
45
- const maxWidth = (numberOfColumns + 1) * columnWidthMin - 1
46
- CSS_block = [
47
- //
48
- `@media screen and (max-width: ${maxWidth}px) {`,
49
- ...CSS_block,
50
- `}`,
51
- ]
52
- }
53
- CSS += CSS_block.join('\n') + '\n'
54
- }
55
- return CSS
56
- }
57
-
58
- function determineColumnBreakPoints(columnsIdMap: number[]): boolean[] {
59
- assert(columnsIdMap[0] === 0)
60
- let columnGroupedIdBefore = 0
61
- const columnBreakPoints = columnsIdMap.map((columnGroupedId, columnUngroupedId) => {
62
- assert(
63
- [
64
- //
65
- columnGroupedIdBefore,
66
- columnGroupedIdBefore + 1,
67
- ].includes(columnGroupedId),
68
- )
69
- const val = columnGroupedId !== columnGroupedIdBefore
70
- columnGroupedIdBefore = columnGroupedId
71
- return val
72
- })
73
- return columnBreakPoints
74
- }
75
-
76
- function determineColumns(columnsUnmerged: number[], numberOfColumns: number): number[] {
77
- assert(numberOfColumns <= columnsUnmerged.length)
78
- const columnsMergingInit: ColumnMerging[] = columnsUnmerged.map((columnHeight, i) => ({
79
- columnIdsMerged: [i],
80
- heightTotal: columnHeight,
81
- }))
82
- const columnsMerged = mergeColumns(columnsMergingInit, numberOfColumns)
83
- const columnsIdMap: number[] = new Array(columnsUnmerged.length)
84
- assert(columnsMerged.length === numberOfColumns)
85
- columnsMerged.forEach((columnMerged, columnMergedId) => {
86
- columnMerged.columnIdsMerged.forEach((columnId) => {
87
- columnsIdMap[columnId] = columnMergedId
88
- })
89
- })
90
- assert(columnsIdMap.length === columnsUnmerged.length)
91
-
92
- return columnsIdMap
93
- }
94
- type ColumnMerging = { columnIdsMerged: number[]; heightTotal: number }
95
- function mergeColumns(columnsMerging: ColumnMerging[], maxNumberOfColumns: number): ColumnMerging[] {
96
- if (columnsMerging.length <= maxNumberOfColumns) return columnsMerging
97
-
98
- let mergeCandidate: null | (ColumnMerging & { i: number }) = null
99
- for (let i = 0; i <= columnsMerging.length - 2; i++) {
100
- const column1 = columnsMerging[i + 0]
101
- const column2 = columnsMerging[i + 1]
102
- const heightTotal = column1.heightTotal + column2.heightTotal
103
- if (!mergeCandidate || mergeCandidate.heightTotal > heightTotal) {
104
- mergeCandidate = {
105
- i,
106
- columnIdsMerged: [
107
- //
108
- ...column1.columnIdsMerged,
109
- ...column2.columnIdsMerged,
110
- ],
111
- heightTotal,
112
- }
113
- }
114
- }
115
- assert(mergeCandidate)
116
-
117
- const { i } = mergeCandidate
118
- assert(-1 < i && i < columnsMerging.length - 1)
119
- const columnsMergingMod = [
120
- //
121
- ...columnsMerging.slice(0, i),
122
- mergeCandidate,
123
- ...columnsMerging.slice(i + 2),
124
- ]
125
-
126
- assert(columnsMergingMod.length === columnsMerging.length - 1)
127
- return mergeColumns(columnsMergingMod, maxNumberOfColumns)
128
- }