@brillout/docpress 0.8.5 → 0.8.7

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.
@@ -99,6 +99,7 @@ function headingToNavItem(heading: HeadingResolved | HeadingDetachedResolved): N
99
99
  title: heading.title,
100
100
  titleInNav: heading.titleInNav,
101
101
  menuModalFullWidth: heading.menuModalFullWidth,
102
+ color: heading.color,
102
103
  }
103
104
  }
104
105
  function headingToLinkData(heading: HeadingResolved | HeadingDetachedResolved): LinkData {
@@ -154,16 +155,18 @@ function getActiveHeading(
154
155
  pageContext: { urlPathname: string; exports: Exports },
155
156
  ) {
156
157
  let activeHeading: HeadingResolved | HeadingDetachedResolved | null = null
157
- let activeCategory: string | undefined
158
+ let activeCategory = 'Miscellaneous'
159
+ let headingCategory: string | undefined
158
160
  const { urlPathname } = pageContext
159
161
  assert(urlPathname)
160
162
  for (const heading of headingsResolved) {
161
163
  if (heading.level === 1) {
162
- activeCategory = heading.title
164
+ headingCategory = heading.title
163
165
  }
164
166
  if (heading.url === urlPathname) {
165
167
  activeHeading = heading
166
- assert(activeCategory)
168
+ assert(headingCategory)
169
+ activeCategory = headingCategory
167
170
  assert(heading.level === 2, { pageUrl: urlPathname, heading })
168
171
  break
169
172
  }
@@ -185,6 +188,7 @@ function getActiveHeading(
185
188
  ].join('\n'),
186
189
  )
187
190
  }
191
+ if (activeHeading.category) activeCategory = activeHeading.category
188
192
  return { activeHeading, isDetachedPage, activeCategory }
189
193
  }
190
194
 
@@ -11,5 +11,5 @@ declare function resolveHeadingsData(pageContext: PageContextOriginal): {
11
11
  pageTitle: string | null;
12
12
  documentTitle: string;
13
13
  columnLayouts: number[][];
14
- activeCategory: string | undefined;
14
+ activeCategory: string;
15
15
  };
@@ -83,6 +83,7 @@ function headingToNavItem(heading) {
83
83
  title: heading.title,
84
84
  titleInNav: heading.titleInNav,
85
85
  menuModalFullWidth: heading.menuModalFullWidth,
86
+ color: heading.color,
86
87
  };
87
88
  }
88
89
  function headingToLinkData(heading) {
@@ -125,17 +126,19 @@ function getTitles(activeHeading, pageContext, config) {
125
126
  function getActiveHeading(headingsResolved, headingsDetachedResolved, pageContext) {
126
127
  var _a;
127
128
  var activeHeading = null;
128
- var activeCategory;
129
+ var activeCategory = 'Miscellaneous';
130
+ var headingCategory;
129
131
  var urlPathname = pageContext.urlPathname;
130
132
  assert(urlPathname);
131
133
  for (var _i = 0, headingsResolved_1 = headingsResolved; _i < headingsResolved_1.length; _i++) {
132
134
  var heading = headingsResolved_1[_i];
133
135
  if (heading.level === 1) {
134
- activeCategory = heading.title;
136
+ headingCategory = heading.title;
135
137
  }
136
138
  if (heading.url === urlPathname) {
137
139
  activeHeading = heading;
138
- assert(activeCategory);
140
+ assert(headingCategory);
141
+ activeCategory = headingCategory;
139
142
  assert(heading.level === 2, { pageUrl: urlPathname, heading: heading });
140
143
  break;
141
144
  }
@@ -157,6 +160,8 @@ function getActiveHeading(headingsResolved, headingsDetachedResolved, pageContex
157
160
  .join('\n'),
158
161
  ].join('\n'));
159
162
  }
163
+ if (activeHeading.category)
164
+ activeCategory = activeHeading.category;
160
165
  return { activeHeading: activeHeading, isDetachedPage: isDetachedPage, activeCategory: activeCategory };
161
166
  }
162
167
  function getPageSectionsResolved(pageContext, activeHeading) {
@@ -18,7 +18,7 @@ declare function resolvePageContext(pageContext: PageContextOriginal): {
18
18
  pageTitle: string | null;
19
19
  documentTitle: string;
20
20
  columnLayouts: number[][];
21
- activeCategory: string | undefined;
21
+ activeCategory: string;
22
22
  } & {
23
23
  urlPathname: string;
24
24
  meta: {
@@ -4,9 +4,11 @@ export type { NavItemAll };
4
4
  import React from 'react';
5
5
  import './Navigation.css';
6
6
  import '@docsearch/css';
7
+ import '../global.d.ts';
7
8
  type NavItem = {
8
9
  level: number;
9
10
  url?: string | null;
11
+ color?: string;
10
12
  title: string;
11
13
  titleInNav: string;
12
14
  menuModalFullWidth?: true;
@@ -17,6 +17,7 @@ import './Navigation.css';
17
17
  import { parseTitle } from '../parseTitle';
18
18
  import { usePageContext } from '../renderer/usePageContext';
19
19
  import '@docsearch/css';
20
+ import '../global.d.ts';
20
21
  function NavigationContent(props) {
21
22
  var pageContext = usePageContext();
22
23
  var navItemsWithComputed = getNavItemsWithComputed(props.navItems, pageContext.urlPathname);
@@ -30,6 +31,7 @@ function NavigationContent(props) {
30
31
  assert(!props.showOnlyRelevant);
31
32
  var navItemsColumnLayout = groupByColumnLayout(navItemsWithComputed);
32
33
  var paddingBottom_1 = 40;
34
+ var categoryBorderParentPosition_1 = 'relative';
33
35
  navContent = (React.createElement(React.Fragment, null, navItemsColumnLayout.map(function (_a, i) {
34
36
  var navItemsColumnEntries = _a.navItemsColumnEntries, isFullWidth = _a.isFullWidth;
35
37
  return (React.createElement("div", { key: i, style: {
@@ -40,19 +42,33 @@ function NavigationContent(props) {
40
42
  flexGrow: 1,
41
43
  columnGap: 20,
42
44
  paddingBottom: isFullWidth ? paddingBottom_1 : undefined,
43
- } }, navItemsColumnEntries.map(function (navItemColumnEntry, j) { return (React.createElement("div", { key: j, className: "column-layout-entry", style: {
44
- breakInside: 'avoid',
45
- paddingBottom: !isFullWidth ? paddingBottom_1 : undefined,
46
- width: '100%',
45
+ position: categoryBorderParentPosition_1,
47
46
  } },
48
- React.createElement(NavItemComponent, { navItem: navItemColumnEntry }),
49
- navItemColumnEntry.navItemChilds.map(function (navItem, k) { return (React.createElement(NavItemComponent, { navItem: navItem, key: k })); }))); }))));
47
+ React.createElement(CategoryBorder, { navItemLevel1: !isFullWidth ? undefined : navItemsColumnEntries[0], paddingBottom: paddingBottom_1 }),
48
+ navItemsColumnEntries.map(function (navItemColumnEntry, j) { return (React.createElement("div", { key: j, className: "column-layout-entry", style: {
49
+ breakInside: 'avoid',
50
+ paddingBottom: !isFullWidth ? paddingBottom_1 : undefined,
51
+ width: '100%',
52
+ position: categoryBorderParentPosition_1,
53
+ } },
54
+ React.createElement(CategoryBorder, { navItemLevel1: isFullWidth ? undefined : navItemColumnEntry, paddingBottom: paddingBottom_1 }),
55
+ React.createElement(NavItemComponent, { navItem: navItemColumnEntry }),
56
+ navItemColumnEntry.navItemChilds.map(function (navItem, k) { return (React.createElement(NavItemComponent, { navItem: navItem, key: k })); }))); }))));
50
57
  })));
51
58
  }
52
59
  return (React.createElement("div", { className: "navigation-content", style: { marginTop: 10 } }, navContent));
53
60
  }
61
+ function CategoryBorder(_a) {
62
+ var navItemLevel1 = _a.navItemLevel1, paddingBottom = _a.paddingBottom;
63
+ return !navItemLevel1 ? null : (React.createElement("div", { className: 'category-border' + ((navItemLevel1.isRelevant && ' is-relevant') || ''), style: {
64
+ width: 6,
65
+ background: navItemLevel1.color,
66
+ height: "calc(100% - ".concat(paddingBottom, "px - 19px)"),
67
+ } }));
68
+ }
54
69
  function NavItemComponent(_a) {
55
70
  var _b;
71
+ var _c;
56
72
  var navItem = _a.navItem;
57
73
  assert([1, 2, 3, 4].includes(navItem.level), navItem);
58
74
  var titleJsx = parseTitle(navItem.title);
@@ -71,7 +87,7 @@ function NavItemComponent(_a) {
71
87
  ].join(' '));
72
88
  }
73
89
  var props = {
74
- href: (_b = navItem.url) !== null && _b !== void 0 ? _b : undefined,
90
+ href: (_c = navItem.url) !== null && _c !== void 0 ? _c : undefined,
75
91
  children: titleInNavJsx,
76
92
  className: [
77
93
  'nav-item',
@@ -79,10 +95,16 @@ function NavItemComponent(_a) {
79
95
  navItem.url && navItem.isActive && ' is-active',
80
96
  navItem.isFirstOfItsKind && 'nav-item-first-of-its-kind',
81
97
  navItem.isLastOfItsKind && 'nav-item-last-of-its-kind',
98
+ navItem.isRelevant && 'is-relevant',
82
99
  ]
83
100
  .filter(Boolean)
84
101
  .join(' '),
85
102
  };
103
+ if (navItem.level === 1) {
104
+ props.style = (_b = {},
105
+ _b['--category-color'] = navItem.color,
106
+ _b);
107
+ }
86
108
  if (navItem.level === 2 || navItem.level === 3) {
87
109
  return React.createElement("a", __assign({}, props));
88
110
  }
@@ -10,6 +10,8 @@ type HeadingResolved = {
10
10
  linkBreadcrumb: string[];
11
11
  sectionTitles?: string[];
12
12
  menuModalFullWidth?: true;
13
+ category?: string;
14
+ color?: string;
13
15
  } & Tmp;
14
16
  type HeadingDetachedResolved = Omit<HeadingResolved, 'level' | 'linkBreadcrumb'> & {
15
17
  level: 2;
@@ -34,6 +36,7 @@ type IsCategory = {
34
36
  };
35
37
  type HeadingDefinitionLevel = ({
36
38
  level: 1;
39
+ color: string;
37
40
  } & IsCategory) | ({
38
41
  level: 4;
39
42
  } & IsCategory) | {
@@ -4,6 +4,9 @@
4
4
  overflow-x: hidden;
5
5
  --padding-left-global: 9px;
6
6
  }
7
+ #menu-modal .nav-item {
8
+ --padding-left-global: 15px;
9
+ }
7
10
  .nav-item code {
8
11
  font-size: 0.9em;
9
12
  }
@@ -19,7 +22,6 @@
19
22
  letter-spacing: 0.15ch;
20
23
  padding-left: var(--padding-left-global);
21
24
  padding-right: 4px;
22
- text-decoration: none;
23
25
  }
24
26
  .nav-item-level-1 {
25
27
  font-size: 19px;
@@ -30,10 +32,20 @@
30
32
  padding: 12px 0;
31
33
  padding-left: calc(var(--padding-left-global) - 2px);
32
34
  padding-right: 4px;
33
- text-decoration: none;
35
+ text-decoration: underline;
36
+ text-underline-offset: .2em;
37
+ text-decoration-thickness: .18em;
38
+ text-decoration-color: var(--category-color);
39
+ transition: text-decoration-color 0.5s ease-in-out;
40
+ }
41
+ #menu-modal .nav-item-level-1 {
42
+ text-decoration-color: color-mix(in srgb, var(--category-color) 15%, transparent);
43
+ }
44
+ :hover > .nav-item-level-1,
45
+ .nav-item-level-1.is-relevant {
46
+ text-decoration-color: var(--category-color) !important;
34
47
  }
35
48
  .nav-item-level-2 {
36
- text-decoration: none;
37
49
  font-size: 14.4px;
38
50
  font-weight: 400;
39
51
  letter-spacing: 0.15ch;
@@ -49,11 +61,10 @@
49
61
  font-weight: 400;
50
62
  letter-spacing: 0.15ch;
51
63
  color: var(--color-text);
52
- text-decoration: none;
53
64
  --padding: 5px;
54
65
 
55
66
  padding: var(--padding) 0;
56
- padding-left: calc(var(--padding-left-global) + 6px);
67
+ padding-left: calc(var(--padding-left-global) + 5px);
57
68
  }
58
69
  #menu-modal .nav-item-level-3 {
59
70
  border-right: 4px solid #eee;
@@ -94,3 +105,15 @@
94
105
  z-index: 1;
95
106
  content: "";
96
107
  }
108
+
109
+ .category-border {
110
+ position: absolute;
111
+ top: 0;
112
+ opacity: 0.15;
113
+ transform: translate(3px, 16px);
114
+ transition: opacity 0.5s ease-in-out;
115
+ }
116
+ :hover > .category-border,
117
+ .category-border.is-relevant{
118
+ opacity: 1;
119
+ }
@@ -10,10 +10,12 @@ import './Navigation.css'
10
10
  import { parseTitle } from '../parseTitle'
11
11
  import { usePageContext } from '../renderer/usePageContext'
12
12
  import '@docsearch/css'
13
+ import '../global.d.ts'
13
14
 
14
15
  type NavItem = {
15
16
  level: number
16
17
  url?: string | null
18
+ color?: string
17
19
  title: string
18
20
  titleInNav: string
19
21
  menuModalFullWidth?: true
@@ -38,6 +40,7 @@ function NavigationContent(props: {
38
40
  assert(!props.showOnlyRelevant)
39
41
  const navItemsColumnLayout = groupByColumnLayout(navItemsWithComputed)
40
42
  const paddingBottom = 40
43
+ const categoryBorderParentPosition = 'relative'
41
44
  navContent = (
42
45
  <>
43
46
  {navItemsColumnLayout.map(({ navItemsColumnEntries, isFullWidth }, i) => (
@@ -54,8 +57,13 @@ function NavigationContent(props: {
54
57
  flexGrow: 1,
55
58
  columnGap: 20,
56
59
  paddingBottom: isFullWidth ? paddingBottom : undefined,
60
+ position: categoryBorderParentPosition,
57
61
  }}
58
62
  >
63
+ <CategoryBorder
64
+ navItemLevel1={!isFullWidth ? undefined : navItemsColumnEntries[0]!}
65
+ paddingBottom={paddingBottom}
66
+ />
59
67
  {navItemsColumnEntries.map((navItemColumnEntry, j) => (
60
68
  <div
61
69
  key={j}
@@ -64,8 +72,13 @@ function NavigationContent(props: {
64
72
  breakInside: 'avoid',
65
73
  paddingBottom: !isFullWidth ? paddingBottom : undefined,
66
74
  width: '100%',
75
+ position: categoryBorderParentPosition,
67
76
  }}
68
77
  >
78
+ <CategoryBorder
79
+ navItemLevel1={isFullWidth ? undefined : navItemColumnEntry!}
80
+ paddingBottom={paddingBottom}
81
+ />
69
82
  <NavItemComponent navItem={navItemColumnEntry} />
70
83
  {navItemColumnEntry.navItemChilds.map((navItem, k) => (
71
84
  <NavItemComponent navItem={navItem} key={k} />
@@ -85,6 +98,18 @@ function NavigationContent(props: {
85
98
  </div>
86
99
  )
87
100
  }
101
+ function CategoryBorder({ navItemLevel1, paddingBottom }: { navItemLevel1?: NavItemComputed; paddingBottom: number }) {
102
+ return !navItemLevel1 ? null : (
103
+ <div
104
+ className={'category-border' + ((navItemLevel1.isRelevant && ' is-relevant') || '')}
105
+ style={{
106
+ width: 6,
107
+ background: navItemLevel1.color!,
108
+ height: `calc(100% - ${paddingBottom}px - 19px)`,
109
+ }}
110
+ />
111
+ )
112
+ }
88
113
 
89
114
  function NavItemComponent({
90
115
  navItem,
@@ -121,10 +146,16 @@ function NavItemComponent({
121
146
  navItem.url && navItem.isActive && ' is-active',
122
147
  navItem.isFirstOfItsKind && 'nav-item-first-of-its-kind',
123
148
  navItem.isLastOfItsKind && 'nav-item-last-of-its-kind',
149
+ navItem.isRelevant && 'is-relevant',
124
150
  ]
125
151
  .filter(Boolean)
126
152
  .join(' '),
127
153
  }
154
+ if (navItem.level === 1) {
155
+ props.style = {
156
+ ['--category-color']: navItem.color!,
157
+ }
158
+ }
128
159
  type PropsAnchor = React.HTMLProps<HTMLAnchorElement>
129
160
  type PropsSpan = React.HTMLProps<HTMLSpanElement>
130
161
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brillout/docpress",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@brillout/picocolors": "^1.0.10",
@@ -34,7 +34,7 @@ Promise<Awaited<ReturnType<OnRenderHtmlAsync>>> => {
34
34
  <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
35
35
  ${getOpenGraphTags(pageContext.urlPathname, pageContextResolved.documentTitle, pageContextResolved.meta)}
36
36
  <style>${dangerouslySkipEscape(styleMenuModalLayout)}</style>
37
- <meta name="docsearch:category" content="${pageContextResolved.activeCategory ?? 'Miscellaneous'}" />
37
+ <meta name="docsearch:category" content="${pageContextResolved.activeCategory}" />
38
38
  </head>
39
39
  <body>
40
40
  <div id="page-view">${dangerouslySkipEscape(pageHtml)}</div>
package/types/Heading.ts CHANGED
@@ -11,6 +11,8 @@ type HeadingResolved = {
11
11
  linkBreadcrumb: string[]
12
12
  sectionTitles?: string[]
13
13
  menuModalFullWidth?: true
14
+ category?: string
15
+ color?: string
14
16
  } & Tmp
15
17
 
16
18
  type HeadingDetachedResolved = Omit<HeadingResolved, 'level' | 'linkBreadcrumb'> & {
@@ -39,7 +41,7 @@ type IsCategory = {
39
41
  titleInNav?: undefined
40
42
  }
41
43
  type HeadingDefinitionLevel =
42
- | ({ level: 1 } & IsCategory)
44
+ | ({ level: 1; color: string } & IsCategory)
43
45
  | ({ level: 4 } & IsCategory)
44
46
  | {
45
47
  level: 2