33// found in the LICENSE file.
44
55import 'package:jaspr/jaspr.dart' ;
6+ import 'package:jaspr_content/jaspr_content.dart' ;
67
7- import '../../models/on_this_page_model.dart' ;
8+ import '../../models/page_navigation_model.dart' ;
9+ import '../../util.dart' ;
810import '../common/client/on_this_page_button.dart' ;
911import '../common/material_icon.dart' ;
1012import '../util/component_ref.dart' ;
@@ -13,7 +15,7 @@ import 'client/pagenav.dart';
1315final class DashTableOfContents extends StatelessComponent {
1416 const DashTableOfContents (this .data);
1517
16- final OnThisPageData data;
18+ final TocNavigationData data;
1719
1820 @override
1921 Component build (BuildContext _) {
@@ -22,54 +24,102 @@ final class DashTableOfContents extends StatelessComponent {
2224 _TocContents (data),
2325 ]);
2426 }
27+ }
2528
26- static Component asDropdown (
27- OnThisPageData data, {
28- required String currentTitle,
29- }) {
30- return Builder (
31- builder: (context) {
32- return PageNav (
33- title: currentTitle,
34- content: context.ref (
35- div ([
36- a (
37- href: '#site-content-title' ,
38- id: 'return-to-top' ,
39- [
40- const MaterialIcon ('vertical_align_top' ),
41- span ([text (currentTitle)]),
42- ],
43- ),
44- div (
45- classes: 'dropdown-divider' ,
46- attributes: {'aria-hidden' : 'true' , 'role' : 'separator' },
47- [],
48- ),
29+ final class PageNavBar extends StatelessComponent {
30+ const PageNavBar (this .data);
31+
32+ final PageNavigationData data;
33+
34+ @override
35+ Component build (BuildContext context) {
36+ final currentLinkedPage = data.pageEntries
37+ .where ((page) => page.url == context.page.url)
38+ .firstOrNull;
39+
40+ final linkedPageTitle = currentLinkedPage? .title;
41+ final currentTitle = context.page.data.page['title' ] as String ;
42+
43+ var pageEntryNumber = 1 ;
44+
45+ return PageNav (
46+ label: linkedPageTitle,
47+ title: currentTitle,
48+ content: context.ref (
49+ div ([
50+ if (data.pageEntries.isEmpty) ...[
51+ a (
52+ href: '#site-content-title' ,
53+ id: 'return-to-top' ,
54+ [
55+ const MaterialIcon ('vertical_align_top' ),
56+ span ([text (currentTitle)]),
57+ ],
58+ ),
59+ div (
60+ classes: 'dropdown-divider' ,
61+ attributes: {'aria-hidden' : 'true' , 'role' : 'separator' },
62+ [],
63+ ),
64+ if (data.toc != null )
4965 nav (
5066 attributes: {'role' : 'menu' },
51- [_TocContents (data)],
67+ [_TocContents (data.toc ! )],
5268 ),
53- ]),
54- ),
55- );
56- },
69+ ] else ...[
70+ for (final page in data.pageEntries) ...[
71+ if (! page.isDivider) ...[
72+ a (
73+ classes: [
74+ 'page-link' ,
75+ if (page == currentLinkedPage) 'active' ,
76+ ].toClasses,
77+ href: page.url,
78+ attributes: {'role' : 'menuitem' },
79+ [
80+ span (classes: 'page-number' , [
81+ text ('${pageEntryNumber ++}' ),
82+ ]),
83+ text (page.title),
84+ ],
85+ ),
86+ if (currentLinkedPage == page && data.toc != null )
87+ nav (
88+ attributes: {'role' : 'menu' },
89+ [_TocContents (data.toc! )],
90+ ),
91+ ] else ...[
92+ if (page != data.pageEntries.first)
93+ div (
94+ classes: 'dropdown-divider' ,
95+ attributes: {'aria-hidden' : 'true' , 'role' : 'separator' },
96+ [],
97+ ),
98+ div (
99+ classes: 'page-divider' ,
100+ [text (page.title)],
101+ ),
102+ ],
103+ ],
104+ ],
105+ ]),
106+ ),
57107 );
58108 }
59109}
60110
61111final class _TocContents extends StatelessComponent {
62112 const _TocContents (this .data);
63113
64- final OnThisPageData data;
114+ final TocNavigationData data;
65115
66116 @override
67117 Component build (BuildContext _) => ul (
68118 classes: 'toc-list' ,
69119 _buildEntries (data.topLevelEntries, 0 ),
70120 );
71121
72- List <Component > _buildEntries (List <OnThisPageEntry > entries, int depth) {
122+ List <Component > _buildEntries (List <TocNavigationEntry > entries, int depth) {
73123 final nextDepth = depth + 1 ;
74124
75125 return [
0 commit comments