@docmd/ui 0.4.11 → 0.5.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/assets/css/docmd-main.css +124 -5
- package/assets/js/docmd-main.js +49 -8
- package/package.json +1 -1
- package/templates/404.ejs +89 -0
- package/templates/layout.ejs +75 -31
- package/templates/no-style.ejs +1 -1
- package/templates/partials/footer.ejs +4 -0
- package/templates/partials/version-dropdown.ejs +50 -0
|
@@ -176,18 +176,19 @@ a:any-link {
|
|
|
176
176
|
.sidebar {
|
|
177
177
|
display: flex;
|
|
178
178
|
flex-direction: column;
|
|
179
|
-
width:
|
|
179
|
+
width: var(--sidebar-width);
|
|
180
180
|
background-color: var(--sidebar-bg);
|
|
181
181
|
color: var(--sidebar-text);
|
|
182
|
-
padding: .5em .25em .5em .5em;
|
|
183
182
|
border-right: 1px solid var(--border-color);
|
|
184
183
|
height: 100vh;
|
|
185
184
|
position: fixed;
|
|
185
|
+
padding: .5em .25em .5em .5em;
|
|
186
186
|
top: 0;
|
|
187
187
|
left: 0;
|
|
188
|
-
overflow
|
|
188
|
+
overflow: hidden;
|
|
189
189
|
box-sizing: border-box;
|
|
190
|
-
flex-shrink: 0
|
|
190
|
+
flex-shrink: 0;
|
|
191
|
+
z-index: 100;
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
.sidebar h1 {
|
|
@@ -527,7 +528,7 @@ body.sidebar-collapsed .main-content-wrapper {
|
|
|
527
528
|
}
|
|
528
529
|
|
|
529
530
|
.sidebar-options-wrapper {
|
|
530
|
-
padding: .
|
|
531
|
+
padding: .25rem 0;
|
|
531
532
|
}
|
|
532
533
|
|
|
533
534
|
.sidebar-options-wrapper.mt-auto {
|
|
@@ -536,6 +537,123 @@ body.sidebar-collapsed .main-content-wrapper {
|
|
|
536
537
|
border-top: 1px solid var(--border-color);
|
|
537
538
|
}
|
|
538
539
|
|
|
540
|
+
/* --- Version Dropdown (Flat UI) --- */
|
|
541
|
+
.sidebar-version-wrapper {
|
|
542
|
+
padding: 0.25rem .5em;
|
|
543
|
+
border-bottom: 1px solid var(--border-color);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
.sidebar-bottom-group.mt-auto {
|
|
547
|
+
margin-top: auto;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.sidebar-bottom-group .sidebar-version-wrapper {
|
|
551
|
+
border-bottom: none;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.docmd-version-dropdown {
|
|
555
|
+
position: relative;
|
|
556
|
+
width: 100%;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
.version-dropdown-toggle {
|
|
560
|
+
display: flex;
|
|
561
|
+
align-items: center;
|
|
562
|
+
justify-content: space-between;
|
|
563
|
+
width: 100%;
|
|
564
|
+
padding: 0.5rem 0.75rem;
|
|
565
|
+
background-color: var(--bg-color);
|
|
566
|
+
border: 1px solid var(--border-color);
|
|
567
|
+
border-radius: var(--ui-border-radius);
|
|
568
|
+
color: var(--text-heading);
|
|
569
|
+
font-size: 0.85rem;
|
|
570
|
+
font-weight: 500;
|
|
571
|
+
cursor: pointer;
|
|
572
|
+
transition: all 0.2s ease;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.version-dropdown-toggle:hover {
|
|
576
|
+
border-color: var(--text-muted);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.version-dropdown-menu {
|
|
580
|
+
position: absolute;
|
|
581
|
+
top: calc(100% + 4px);
|
|
582
|
+
left: 0;
|
|
583
|
+
right: 0;
|
|
584
|
+
margin: 0;
|
|
585
|
+
padding: 0.25rem;
|
|
586
|
+
background-color: var(--bg-color);
|
|
587
|
+
border: 1px solid var(--border-color);
|
|
588
|
+
border-radius: var(--ui-border-radius);
|
|
589
|
+
box-shadow: var(--shadow-md);
|
|
590
|
+
list-style: none;
|
|
591
|
+
z-index: 100;
|
|
592
|
+
opacity: 0;
|
|
593
|
+
visibility: hidden;
|
|
594
|
+
transform: translateY(-5px);
|
|
595
|
+
transition: all 0.2s ease;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.docmd-version-dropdown.open .version-dropdown-menu {
|
|
599
|
+
opacity: 1;
|
|
600
|
+
visibility: visible;
|
|
601
|
+
transform: translateY(0);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.version-dropdown-item {
|
|
605
|
+
display: flex;
|
|
606
|
+
align-items: center;
|
|
607
|
+
justify-content: space-between;
|
|
608
|
+
padding: 0.4rem 0.5rem;
|
|
609
|
+
color: var(--text-color);
|
|
610
|
+
font-size: 0.85rem;
|
|
611
|
+
text-decoration: none;
|
|
612
|
+
border-radius: 4px;
|
|
613
|
+
transition: background-color 0.2s;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.version-dropdown-item:hover {
|
|
617
|
+
background-color: var(--sidebar-link-active-bg);
|
|
618
|
+
color: var(--text-heading);
|
|
619
|
+
text-decoration: none;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
.version-dropdown-item.active {
|
|
623
|
+
font-weight: 600;
|
|
624
|
+
color: var(--link-color);
|
|
625
|
+
background-color: var(--sidebar-link-active-bg);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.version-check {
|
|
629
|
+
width: 1rem;
|
|
630
|
+
height: 1rem;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.version-chevron {
|
|
634
|
+
width: 1rem;
|
|
635
|
+
height: 1rem;
|
|
636
|
+
transition: transform 0.2s ease;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.docmd-version-dropdown.open .version-chevron {
|
|
640
|
+
transform: rotate(180deg);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.sidebar-bottom-group .version-dropdown-menu {
|
|
644
|
+
top: auto;
|
|
645
|
+
bottom: calc(100% + 4px);
|
|
646
|
+
transform: translateY(5px);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.sidebar-bottom-group .docmd-version-dropdown.open .version-dropdown-menu {
|
|
650
|
+
transform: translateY(0);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.sidebar-bottom-group .version-dropdown-toggle .version-chevron {
|
|
654
|
+
transform: rotate(180deg);
|
|
655
|
+
}
|
|
656
|
+
|
|
539
657
|
.card .card-title {
|
|
540
658
|
border-bottom: 1px solid var(--border-color)
|
|
541
659
|
}
|
|
@@ -645,6 +763,7 @@ html[data-theme=dark] .theme-toggle-button .icon-sun {
|
|
|
645
763
|
.sidebar-nav {
|
|
646
764
|
flex-grow: 1;
|
|
647
765
|
overflow-y: auto;
|
|
766
|
+
overflow-x: hidden;
|
|
648
767
|
min-height: 0;
|
|
649
768
|
scrollbar-width: thin;
|
|
650
769
|
}
|
package/assets/js/docmd-main.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* [docmd-source] - Please do not remove this header.
|
|
12
12
|
* --------------------------------------------------------------------
|
|
13
13
|
*/
|
|
14
|
+
|
|
14
15
|
/**
|
|
15
16
|
* --------------------------------------------------------------------
|
|
16
17
|
* docmd : Client-Side Application Logic (SPA Router & UI)
|
|
@@ -18,9 +19,8 @@
|
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
(function() {
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
// 1. EVENT DELEGATION
|
|
23
|
-
// =========================================================================
|
|
24
24
|
document.addEventListener('click', (e) => {
|
|
25
25
|
// Collapsible Navigation
|
|
26
26
|
const navLabel = e.target.closest('.nav-label, .collapse-icon-wrapper');
|
|
@@ -61,6 +61,51 @@
|
|
|
61
61
|
tabItem.classList.add('active');
|
|
62
62
|
if (tabPanes[index]) tabPanes[index].classList.add('active');
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
// Version Dropdown Toggle
|
|
66
|
+
const versionToggle = e.target.closest('.version-dropdown-toggle');
|
|
67
|
+
if (versionToggle) {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
const dropdown = versionToggle.closest('.docmd-version-dropdown');
|
|
70
|
+
dropdown.classList.toggle('open');
|
|
71
|
+
versionToggle.setAttribute('aria-expanded', dropdown.classList.contains('open'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Sticky Version Switching (Path Preservation)
|
|
76
|
+
const versionLink = e.target.closest('.version-dropdown-item');
|
|
77
|
+
if (versionLink) {
|
|
78
|
+
const targetRoot = versionLink.dataset.versionRoot;
|
|
79
|
+
// Use global fallback if undefined (e.g. on 404 pages)
|
|
80
|
+
const currentRoot = window.DOCMD_VERSION_ROOT || '/';
|
|
81
|
+
|
|
82
|
+
if (targetRoot && window.location.pathname) {
|
|
83
|
+
try {
|
|
84
|
+
let currentPath = window.location.pathname;
|
|
85
|
+
const normCurrentRoot = currentRoot.endsWith('/') ? currentRoot : currentRoot + '/';
|
|
86
|
+
|
|
87
|
+
// Only try sticky if we are actually INSIDE the known version path
|
|
88
|
+
if (currentPath.startsWith(normCurrentRoot)) {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
const suffix = currentPath.substring(normCurrentRoot.length);
|
|
91
|
+
const normTargetRoot = targetRoot.endsWith('/') ? targetRoot : targetRoot + '/';
|
|
92
|
+
window.location.href = normTargetRoot + suffix + window.location.hash;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
} catch(e) {
|
|
96
|
+
// Ignore errors, let default click happen
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// If sticky logic skipped (e.g. on 404 page or outside root), default <a> click handles it
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Close Dropdown if clicked outside
|
|
103
|
+
if (!e.target.closest('.docmd-version-dropdown')) {
|
|
104
|
+
document.querySelectorAll('.docmd-version-dropdown.open').forEach(d => {
|
|
105
|
+
d.classList.remove('open');
|
|
106
|
+
d.querySelector('.version-dropdown-toggle').setAttribute('aria-expanded', 'false');
|
|
107
|
+
});
|
|
108
|
+
}
|
|
64
109
|
|
|
65
110
|
// Copy Code Button
|
|
66
111
|
const copyBtn = e.target.closest('.copy-code-button');
|
|
@@ -79,9 +124,7 @@
|
|
|
79
124
|
}
|
|
80
125
|
});
|
|
81
126
|
|
|
82
|
-
// =========================================================================
|
|
83
127
|
// 2. COMPONENT INITIALIZERS
|
|
84
|
-
// =========================================================================
|
|
85
128
|
function injectCopyButtons() {
|
|
86
129
|
if (document.body.dataset.copyCodeEnabled !== 'true') return;
|
|
87
130
|
const svg = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>`;
|
|
@@ -143,9 +186,7 @@
|
|
|
143
186
|
});
|
|
144
187
|
}
|
|
145
188
|
|
|
146
|
-
// =========================================================================
|
|
147
189
|
// 3. TARGETED SPA ROUTER
|
|
148
|
-
// =========================================================================
|
|
149
190
|
function initializeSPA() {
|
|
150
191
|
if (location.protocol === 'file:') return;
|
|
151
192
|
if (document.body.dataset.spaEnabled !== 'true') return;
|
|
@@ -179,6 +220,8 @@
|
|
|
179
220
|
document.addEventListener('click', async (e) => {
|
|
180
221
|
if (e.target.closest('.collapse-icon-wrapper')) return;
|
|
181
222
|
|
|
223
|
+
if (e.target.closest('[data-spa-ignore]')) return;
|
|
224
|
+
|
|
182
225
|
const link = e.target.closest('.sidebar-nav a, .page-navigation a');
|
|
183
226
|
if (!link || link.target === '_blank' || link.hasAttribute('download')) return;
|
|
184
227
|
|
|
@@ -300,9 +343,7 @@
|
|
|
300
343
|
}
|
|
301
344
|
}
|
|
302
345
|
|
|
303
|
-
// =========================================================================
|
|
304
346
|
// 4. BOOTSTRAP
|
|
305
|
-
// =========================================================================
|
|
306
347
|
document.addEventListener('DOMContentLoaded', () => {
|
|
307
348
|
if (localStorage.getItem('docmd-sidebar-collapsed') === 'true') {
|
|
308
349
|
document.body.classList.add('sidebar-collapsed');
|
package/package.json
CHANGED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
---------------------------------------------------------------
|
|
3
|
+
docmd : the minimalist, zero-config documentation generator.
|
|
4
|
+
@website https://docmd.io
|
|
5
|
+
[docmd-source] - Please do not remove this header.
|
|
6
|
+
---------------------------------------------------------------
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
<!DOCTYPE html>
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<head>
|
|
12
|
+
<meta charset="UTF-8">
|
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
14
|
+
<title><%= pageTitle %></title>
|
|
15
|
+
|
|
16
|
+
<!-- Force absolute paths for assets using relativePathToRoot (which we will set to '/') -->
|
|
17
|
+
<%- faviconLinkHtml || '' %>
|
|
18
|
+
|
|
19
|
+
<!-- 1. Core CSS -->
|
|
20
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-main.css?v=<%= buildHash %>">
|
|
21
|
+
|
|
22
|
+
<!-- 2. Highlight.js (Theme aware) -->
|
|
23
|
+
<%
|
|
24
|
+
const isDarkDefault = defaultMode === 'dark';
|
|
25
|
+
%>
|
|
26
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-highlight-light.css?v=<%= buildHash %>" id="hljs-light" <%= isDarkDefault ? 'disabled' : '' %>>
|
|
27
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-highlight-dark.css?v=<%= buildHash %>" id="hljs-dark" <%= isDarkDefault ? '' : 'disabled' %>>
|
|
28
|
+
|
|
29
|
+
<!-- 3. Theme CSS -->
|
|
30
|
+
<% if (theme && theme.name !== 'default') { %>
|
|
31
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-theme-<%= theme.name %>.css?v=<%= buildHash %>">
|
|
32
|
+
<% } %>
|
|
33
|
+
|
|
34
|
+
<!-- 4. Custom CSS -->
|
|
35
|
+
<% (customCssFiles || []).forEach(cssFile => {
|
|
36
|
+
const cleanPath = cssFile.startsWith('/') ? cssFile.substring(1) : cssFile;
|
|
37
|
+
%>
|
|
38
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %><%= cleanPath %>?v=<%= buildHash %>">
|
|
39
|
+
<% }); %>
|
|
40
|
+
|
|
41
|
+
<!-- 5. Theme Init (Dark Mode logic) -->
|
|
42
|
+
<%- themeInitScript %>
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
body {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
min-height: 100vh;
|
|
51
|
+
text-align: center;
|
|
52
|
+
padding: 20px;
|
|
53
|
+
background-color: var(--bg-color);
|
|
54
|
+
color: var(--text-color);
|
|
55
|
+
}
|
|
56
|
+
.error-logo { height: 60px; margin-bottom: 2rem; width: auto; display: block; }
|
|
57
|
+
.error-logo.light { display: var(--display-light, block); }
|
|
58
|
+
.error-logo.dark { display: var(--display-dark, none); }
|
|
59
|
+
|
|
60
|
+
/* Simple theme logic for logo if JS fails */
|
|
61
|
+
@media (prefers-color-scheme: dark) {
|
|
62
|
+
:root[data-theme="system"] .error-logo.light { display: none; }
|
|
63
|
+
:root[data-theme="system"] .error-logo.dark { display: block; }
|
|
64
|
+
}
|
|
65
|
+
:root[data-theme="dark"] .error-logo.light { display: none; }
|
|
66
|
+
:root[data-theme="dark"] .error-logo.dark { display: block; }
|
|
67
|
+
|
|
68
|
+
h1 { font-size: 5rem; margin: 0; line-height: 1; color: var(--link-color); font-weight: 700; }
|
|
69
|
+
h2 { font-size: 2rem; margin: 1rem 0; }
|
|
70
|
+
p { font-size: 1.2rem; color: var(--text-muted); margin-bottom: 2rem; max-width: 500px; }
|
|
71
|
+
.docmd-button { font-size: 1.1rem; padding: 0.8rem 1.5rem; }
|
|
72
|
+
</style>
|
|
73
|
+
</head>
|
|
74
|
+
<body>
|
|
75
|
+
<% if (logo) { %>
|
|
76
|
+
<% if (logo.light) { %>
|
|
77
|
+
<img src="<%= relativePathToRoot %><%= logo.light.replace(/^\//, '') %>" class="error-logo light" alt="Logo">
|
|
78
|
+
<% } %>
|
|
79
|
+
<% if (logo.dark) { %>
|
|
80
|
+
<img src="<%= relativePathToRoot %><%= logo.dark.replace(/^\//, '') %>" class="error-logo dark" alt="Logo">
|
|
81
|
+
<% } %>
|
|
82
|
+
<% } %>
|
|
83
|
+
|
|
84
|
+
<h1>404</h1>
|
|
85
|
+
<h2>Page Not Found</h2>
|
|
86
|
+
<p><%= content %></p>
|
|
87
|
+
<a href="<%= relativePathToRoot %>" class="docmd-button">Return Home</a>
|
|
88
|
+
</body>
|
|
89
|
+
</html>
|
package/templates/layout.ejs
CHANGED
|
@@ -10,14 +10,40 @@
|
|
|
10
10
|
<html lang="en">
|
|
11
11
|
<head>
|
|
12
12
|
<meta charset="UTF-8">
|
|
13
|
-
<meta name="generator" content="docmd v0.
|
|
13
|
+
<meta name="generator" content="docmd v0.5.x">
|
|
14
14
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
15
|
+
<%
|
|
16
|
+
let versionRoot = '/';
|
|
17
|
+
let siteRoot = relativePathToRoot;
|
|
18
|
+
|
|
19
|
+
if (config.versions?.current && config._activeVersion?.id) {
|
|
20
|
+
const isSubVersion = config.versions.current !== config._activeVersion.id;
|
|
21
|
+
versionRoot = isSubVersion ? '/' + config._activeVersion.id + '/' : '/';
|
|
22
|
+
|
|
23
|
+
// If we are in a sub-version (v04/), the relativePathToRoot takes us to /v04/.
|
|
24
|
+
// We need to go up one more level to reach the true site root.
|
|
25
|
+
if (isSubVersion) {
|
|
26
|
+
siteRoot = (relativePathToRoot === './' ? '' : relativePathToRoot) + '../';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (locals.isOfflineMode) {
|
|
31
|
+
versionRoot = '';
|
|
32
|
+
}
|
|
33
|
+
%>
|
|
15
34
|
<script>
|
|
16
35
|
var root = "<%= relativePathToRoot %>";
|
|
17
36
|
if (root && !root.endsWith('/')) root += '/';
|
|
18
37
|
if (root === '') root = './';
|
|
19
|
-
window.DOCMD_ROOT = root;
|
|
38
|
+
window.DOCMD_ROOT = root; // Context Root (Assets)
|
|
39
|
+
|
|
40
|
+
var siteRoot = "<%= siteRoot %>";
|
|
41
|
+
if (siteRoot && !siteRoot.endsWith('/')) siteRoot += '/';
|
|
42
|
+
if (siteRoot === '') siteRoot = './';
|
|
43
|
+
window.DOCMD_SITE_ROOT = siteRoot; // True Site Root (Search Index)
|
|
44
|
+
|
|
20
45
|
window.DOCMD_DEFAULT_MODE = "<%= defaultMode %>";
|
|
46
|
+
window.DOCMD_VERSION_ROOT = "<%- versionRoot %>";
|
|
21
47
|
</script>
|
|
22
48
|
<title><%= pageTitle %></title>
|
|
23
49
|
<%- faviconLinkHtml || '' %>
|
|
@@ -41,42 +67,60 @@
|
|
|
41
67
|
<% }); %>
|
|
42
68
|
<%- themeInitScript %>
|
|
43
69
|
</head>
|
|
44
|
-
<body class="<%= sidebarConfig?.collapsible ? 'sidebar-collapsible' : 'sidebar-not-collapsible' %>"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
70
|
+
<body class="<%= sidebarConfig?.enabled === false ? 'no-sidebar' : (sidebarConfig?.collapsible ? 'sidebar-collapsible' : 'sidebar-not-collapsible') %>"
|
|
71
|
+
data-default-collapsed="<%= sidebarConfig?.defaultCollapsed %>"
|
|
72
|
+
data-copy-code-enabled="<%= config.copyCode === true %>"
|
|
73
|
+
data-spa-enabled="<%= config.layout?.spa !== false %>">
|
|
48
74
|
|
|
49
75
|
<a href="#main-content" class="skip-link">Skip to main content</a>
|
|
50
|
-
|
|
51
|
-
<aside class="sidebar">
|
|
52
|
-
<div class="sidebar-header">
|
|
53
|
-
<% if (logo && logo.light && logo.dark) { %>
|
|
54
|
-
<a href="<%= logo.href || relativePathToRoot %>" class="logo-link">
|
|
55
|
-
<img src="<%= relativePathToRoot %><%- logo.light.startsWith('/') ? logo.light.substring(1) : logo.light %>" alt="<%= logo.alt || siteTitle %>" class="logo-light" <% if (logo.height) { %>style="height: <%= logo.height %>;"<% } %>>
|
|
56
|
-
<img src="<%= relativePathToRoot %><%- logo.dark.startsWith('/') ? logo.dark.substring(1) : logo.dark %>" alt="<%= logo.alt || siteTitle %>" class="logo-dark" <% if (logo.height) { %>style="height: <%= logo.height %>;"<% } %>>
|
|
57
|
-
</a>
|
|
58
|
-
<% } else { %>
|
|
59
|
-
<h1><a href="<%= relativePathToRoot %>index.html"><%= siteTitle %></a></h1>
|
|
60
|
-
<% } %>
|
|
61
|
-
<span class="mobile-view sidebar-menu-button float-right">
|
|
62
|
-
<%- renderIcon("menu") %>
|
|
63
|
-
</span>
|
|
64
|
-
</div>
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
<% if (sidebarConfig?.enabled !== false) { %>
|
|
78
|
+
<aside class="sidebar">
|
|
79
|
+
<div class="sidebar-header">
|
|
80
|
+
<% if (logo && logo.light && logo.dark) { %>
|
|
81
|
+
<a href="<%= logo.href || relativePathToRoot %>" class="logo-link">
|
|
82
|
+
<img src="<%= relativePathToRoot %><%- logo.light.startsWith('/') ? logo.light.substring(1) : logo.light %>" alt="<%= logo.alt || siteTitle %>" class="logo-light" <% if (logo.height) { %>style="height: <%= logo.height %>;"<% } %>>
|
|
83
|
+
<img src="<%= relativePathToRoot %><%- logo.dark.startsWith('/') ? logo.dark.substring(1) : logo.dark %>" alt="<%= logo.alt || siteTitle %>" class="logo-dark" <% if (logo.height) { %>style="height: <%= logo.height %>;"<% } %>>
|
|
84
|
+
</a>
|
|
85
|
+
<% } else { %>
|
|
86
|
+
<h1><a href="<%= relativePathToRoot %>index.html"><%= siteTitle %></a></h1>
|
|
87
|
+
<% } %>
|
|
88
|
+
<span class="mobile-view sidebar-menu-button float-right">
|
|
89
|
+
<%- renderIcon("menu") %>
|
|
90
|
+
</span>
|
|
69
91
|
</div>
|
|
70
|
-
<% } %>
|
|
71
92
|
|
|
72
|
-
|
|
93
|
+
<div class="sidebar-top-group">
|
|
94
|
+
<% if (locals.optionsMenu && optionsMenu.position === 'sidebar-top') { %>
|
|
95
|
+
<div class="sidebar-options-wrapper">
|
|
96
|
+
<%- include('partials/options-menu', { optionsMenu }) %>
|
|
97
|
+
</div>
|
|
98
|
+
<% } %>
|
|
99
|
+
|
|
100
|
+
<% if (config.versions && config.versions.position === 'sidebar-top') { %>
|
|
101
|
+
<div class="sidebar-version-wrapper">
|
|
102
|
+
<%- include('partials/version-dropdown', { versions: config.versions, activeVersion: config._activeVersion, relativePathToRoot }) %>
|
|
103
|
+
</div>
|
|
104
|
+
<% } %>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<%- navigationHtml %>
|
|
108
|
+
|
|
109
|
+
<div class="sidebar-bottom-group mt-auto">
|
|
110
|
+
<% if (config.versions && config.versions.position === 'sidebar-bottom') { %>
|
|
111
|
+
<div class="sidebar-version-wrapper">
|
|
112
|
+
<%- include('partials/version-dropdown', { versions: config.versions, activeVersion: config._activeVersion, relativePathToRoot }) %>
|
|
113
|
+
</div>
|
|
114
|
+
<% } %>
|
|
73
115
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
116
|
+
<% if (locals.optionsMenu && optionsMenu.position === 'sidebar-bottom') { %>
|
|
117
|
+
<div class="sidebar-options-wrapper">
|
|
118
|
+
<%- include('partials/options-menu', { optionsMenu }) %>
|
|
119
|
+
</div>
|
|
120
|
+
<% } %>
|
|
77
121
|
</div>
|
|
78
|
-
|
|
79
|
-
|
|
122
|
+
</aside>
|
|
123
|
+
<% } %>
|
|
80
124
|
|
|
81
125
|
<div class="main-content-wrapper">
|
|
82
126
|
<% if (headerConfig?.enabled !== false) { %>
|
package/templates/no-style.ejs
CHANGED
|
@@ -40,18 +40,22 @@
|
|
|
40
40
|
|
|
41
41
|
<div class="footer-complete-bottom">
|
|
42
42
|
<div class="user-footer"><%- footerHtml || (footerConfig.copyright ? footerConfig.copyright : '') %></div>
|
|
43
|
+
<% if (footerConfig.branding !== false) { %>
|
|
43
44
|
<div class="branding-footer">
|
|
44
45
|
Built with <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"></path><path d="M12 5 9.04 7.96a2.17 2.17 0 0 0 0 3.08c.82.82 2.13.85 3 .07l2.07-1.9a2.82 2.82 0 0 1 3.79 0l2.96 2.66"></path><path d="m18 15-2-2"></path><path d="m15 18-2-2"></path></svg> <a href="https://docmd.io" target="_blank" rel="noopener">docmd.</a>
|
|
45
46
|
</div>
|
|
47
|
+
<% } %>
|
|
46
48
|
</div>
|
|
47
49
|
</footer>
|
|
48
50
|
<% } else { %>
|
|
49
51
|
<footer class="page-footer">
|
|
50
52
|
<div class="footer-content">
|
|
51
53
|
<div class="user-footer"><%- footerHtml || (footerConfig?.copyright ? footerConfig.copyright : '') %></div>
|
|
54
|
+
<% if (footerConfig?.branding !== false) { %>
|
|
52
55
|
<div class="branding-footer">
|
|
53
56
|
Built with <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"></path><path d="M12 5 9.04 7.96a2.17 2.17 0 0 0 0 3.08c.82.82 2.13.85 3 .07l2.07-1.9a2.82 2.82 0 0 1 3.79 0l2.96 2.66"></path><path d="m18 15-2-2"></path><path d="m15 18-2-2"></path></svg> <a href="https://docmd.io" target="_blank" rel="noopener">docmd.</a>
|
|
54
57
|
</div>
|
|
58
|
+
<% } %>
|
|
55
59
|
</div>
|
|
56
60
|
</footer>
|
|
57
61
|
<% } %>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<%# ---------------------------------------------------------------
|
|
2
|
+
# docmd : the minimalist, zero-config documentation generator.
|
|
3
|
+
# @website https://docmd.io
|
|
4
|
+
# [docmd-source] - Please do not remove this header.
|
|
5
|
+
# ---------------------------------------------------------------
|
|
6
|
+
%>
|
|
7
|
+
|
|
8
|
+
<% if (versions && versions.all.length > 0) {
|
|
9
|
+
const current = activeVersion || versions.all.find(v => v.id === versions.current);
|
|
10
|
+
|
|
11
|
+
// If we are in a sub-version (e.g. /v1/), we go up one level (../) to get to root.
|
|
12
|
+
const isCurrentSubVersion = current && current.id !== versions.current;
|
|
13
|
+
const upOneLevel = isCurrentSubVersion ? '../' : '';
|
|
14
|
+
%>
|
|
15
|
+
<div class="docmd-version-dropdown">
|
|
16
|
+
<button class="version-dropdown-toggle" aria-expanded="false" aria-label="Select Version">
|
|
17
|
+
<span class="version-label"><%= current ? current.label : 'Version' %></span>
|
|
18
|
+
<%- renderIcon('chevron-down', { class: 'version-chevron' }) %>
|
|
19
|
+
</button>
|
|
20
|
+
<ul class="version-dropdown-menu">
|
|
21
|
+
<% versions.all.forEach(v => {
|
|
22
|
+
const isCurrentActive = current && v.id === current.id;
|
|
23
|
+
const isTargetRootVersion = v.id === versions.current;
|
|
24
|
+
|
|
25
|
+
// We use the 'config' object which is available in all templates
|
|
26
|
+
|
|
27
|
+
const base = config.base || '/';
|
|
28
|
+
const normalizedBase = base.endsWith('/') ? base : base + '/';
|
|
29
|
+
|
|
30
|
+
const targetSuffix = isTargetRootVersion ? '' : v.id + '/';
|
|
31
|
+
const absoluteHref = normalizedBase + targetSuffix;
|
|
32
|
+
|
|
33
|
+
// Data Root for JS Sticky Logic
|
|
34
|
+
const dataRoot = absoluteHref;
|
|
35
|
+
%>
|
|
36
|
+
<li>
|
|
37
|
+
<a href="<%= absoluteHref %>"
|
|
38
|
+
class="version-dropdown-item <%= isCurrentActive ? 'active' : '' %>"
|
|
39
|
+
data-spa-ignore
|
|
40
|
+
data-version-root="<%= dataRoot %>">
|
|
41
|
+
<%= v.label %>
|
|
42
|
+
<% if (isCurrentActive) { %>
|
|
43
|
+
<%- renderIcon('check', { class: 'version-check' }) %>
|
|
44
|
+
<% } %>
|
|
45
|
+
</a>
|
|
46
|
+
</li>
|
|
47
|
+
<% }) %>
|
|
48
|
+
</ul>
|
|
49
|
+
</div>
|
|
50
|
+
<% } %>
|