@mgks/docmd 0.3.9 → 0.3.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mgks/docmd",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "description": "Generate beautiful, lightweight static documentation sites directly from your Markdown files. Zero clutter, just content.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -852,13 +852,6 @@ details[open]>.collapsible-summary .collapsible-arrow svg {
852
852
  margin-bottom: .5rem
853
853
  }
854
854
 
855
- .toc-title {
856
- margin-top: 0;
857
- font-size: 1rem;
858
- font-weight: 700;
859
- color: var(--text-muted)
860
- }
861
-
862
855
  .toc-list {
863
856
  list-style: none;
864
857
  padding-left: 0;
@@ -870,39 +863,67 @@ details[open]>.collapsible-summary .collapsible-arrow svg {
870
863
  line-height: 1.4
871
864
  }
872
865
 
866
+ /* Base Link State */
873
867
  .toc-link {
874
- text-decoration: none;
875
- color: var(--link-color);
876
- display: inline-block;
877
- padding: .1rem 0;
878
- font-size: .9rem;
879
- font-weight: 500
868
+ display: block;
869
+ padding: 0.3rem 1rem;
870
+ font-size: 0.85rem;
871
+ color: var(--text-secondary);
872
+ /* Pre-allocate border space to prevent jumping */
873
+ border-left: 2px solid transparent;
874
+ margin-left: -1px; /* Overlap the sidebar's border-left */
875
+ transition: all 0.2s ease;
876
+ white-space: nowrap;
877
+ overflow: hidden;
878
+ text-overflow: ellipsis;
880
879
  }
881
880
 
882
- .toc-level-3 {
883
- margin-left: .75rem;
884
- font-size: .85rem
881
+ .toc-link:hover {
882
+ color: var(--text-primary);
883
+ background-color: var(--bg-surface);
885
884
  }
886
885
 
887
- .toc-level-4 {
888
- margin-left: 1.5rem;
889
- font-size: .8rem
886
+ /* Active State - Only changes color, no layout shift */
887
+ .toc-link.active {
888
+ color: var(--primary);
889
+ border-left-color: var(--primary);
890
+ background-color: var(--primary-light);
890
891
  }
891
892
 
893
+ /* Nesting Levels */
894
+ .toc-level-3 { padding-left: 2rem; }
895
+ .toc-level-4 { padding-left: 3rem; }
896
+
897
+ /* Handle Dark Mode specifics for the trail */
898
+ :root[data-theme="dark"] .toc-link.active {
899
+ background-color: rgba(59, 130, 246, 0.1);
900
+ }
901
+
902
+ /* TOC Sidebar Container */
892
903
  .toc-sidebar {
893
904
  position: -webkit-sticky;
894
905
  position: sticky;
895
- top: 2rem;
906
+ top: 5rem;
896
907
  max-height: calc(100vh - 15rem);
897
908
  overflow-y: auto;
909
+ align-self: flex-start;
910
+ /* Create the vertical guide rail */
911
+ border-left: 1px solid var(--border-color);
912
+ padding-left: 0;
913
+ margin-left: 1rem;
898
914
  }
899
915
 
900
- .toc-link.active {
901
- font-weight: 700;
902
- color: var(--link-color);
903
- border-left: 2px solid var(--link-color);
904
- padding-left: 8px;
905
- margin-left: -10px;
916
+ .toc-container {
917
+ padding: 0;
918
+ }
919
+
920
+ .toc-title {
921
+ padding-left: 1rem;
922
+ margin-bottom: 1rem;
923
+ font-size: 0.75rem;
924
+ color: var(--text-tertiary);
925
+ text-transform: uppercase;
926
+ letter-spacing: 0.05em;
906
927
  }
907
928
 
908
929
  @media (max-width: 1024px) {
@@ -24,7 +24,8 @@ let themeInitScript = '';
24
24
  // Basic whitespace cleanup (keep this simple version)
25
25
  function cleanupHtml(html) {
26
26
  if (!html) return '';
27
- return html.replace(/^\s*[\r\n]/gm, '').trim();
27
+ // return html.replace(/^\s*[\r\n]/gm, '').trim(); // Remove leading/trailing blank lines from each line
28
+ return html.trim(); // Only trim the start/end of the whole document
28
29
  }
29
30
 
30
31
  function fixHtmlLinks(htmlContent, relativePathToRoot, isOfflineMode, configBase = '/') {
@@ -1,5 +1,6 @@
1
1
  <%# Source file from the docmd project — https://github.com/docmd-io/docmd %>
2
2
 
3
+ <%# src/templates/navigation.ejs %>
3
4
  <nav class="sidebar-nav" aria-label="Main navigation">
4
5
  <ul>
5
6
  <%
@@ -33,19 +34,28 @@
33
34
  let itemPath = item.path || '#';
34
35
  const isAbsoluteUrl = itemPath.startsWith('http://') || itemPath.startsWith('https://');
35
36
  const normalizedItemPath = (isExplicitExternal || isAbsoluteUrl) ? itemPath : normalizePath(itemPath);
37
+
36
38
  const isActive = !isExplicitExternal && !isAbsoluteUrl && currentPagePath === normalizedItemPath;
37
39
  const isParentOfActive = !isActive && hasActiveChild(item, currentPagePath);
38
- const isCollapsible = item.children && item.collapsible;
40
+
41
+ // Logic: An item is only "collapsible" if children exist AND collapsible flag is true
42
+ const isCollapsible = item.children && item.collapsible === true;
43
+
44
+ // Logic: It should be open if it's the active parent or it's simply not a collapsible menu
39
45
  const shouldBeOpen = isParentOfActive || (isActive && item.children && item.children.length > 0);
46
+
40
47
  const liClasses = [];
41
48
  if (isActive) liClasses.push('active');
42
49
  if (isParentOfActive) liClasses.push('active-parent');
43
50
  if (isCollapsible) liClasses.push('collapsible');
51
+
44
52
  let liAttributes = `class="${liClasses.join(' ')}"`;
45
53
  if (isCollapsible) {
46
54
  liAttributes += ` data-nav-id="${item.path}"`;
47
55
  if (shouldBeOpen) liAttributes += ` aria-expanded="true"`;
56
+ else liAttributes += ` aria-expanded="false"`;
48
57
  }
58
+
49
59
  let finalHref = item.path;
50
60
  if (!isExplicitExternal && !isAbsoluteUrl) {
51
61
  if (!itemPath || itemPath === '#') {
@@ -77,7 +87,7 @@
77
87
  <% if (isExplicitExternal) { %> <%- renderIcon('external-link', { class: 'nav-external-icon' }) %> <% } %>
78
88
  </a>
79
89
  <% if (item.children) { %>
80
- <ul class="submenu" style="<%= (isCollapsible && shouldBeOpen) ? 'display: block;' : 'display: none;' %>">
90
+ <ul class="submenu" style="display: <%= (!isCollapsible || shouldBeOpen) ? 'block' : 'none' %>;">
81
91
  <% renderNav(item.children); %>
82
92
  </ul>
83
93
  <% } %>
@@ -6,22 +6,28 @@
6
6
  var configValue = window.DOCMD_DEFAULT_MODE || 'light';
7
7
  var theme = localValue ? localValue : configValue;
8
8
 
9
- // Set HTML Attribute
10
- document.documentElement.setAttribute('data-theme', theme);
11
-
12
- // Resolve 'system' to actual mode for Highlight.js
13
- var effectiveTheme = theme;
9
+ // Resolve system preference immediately
14
10
  if (theme === 'system') {
15
- effectiveTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
11
+ theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
16
12
  }
17
13
 
14
+ // Apply to HTML and Body to ensure all CSS selectors catch it
15
+ document.documentElement.setAttribute('data-theme', theme);
16
+
17
+ // We use a small interval to ensure body exists (since this script is in head)
18
+ var checkBody = setInterval(function() {
19
+ if (document.body) {
20
+ document.body.setAttribute('data-theme', theme);
21
+ clearInterval(checkBody);
22
+ }
23
+ }, 10);
24
+
18
25
  // Handle Highlight.js Theme
19
26
  var highlightLink = document.getElementById('highlight-theme');
20
27
  if (highlightLink) {
21
28
  var baseHref = highlightLink.getAttribute('data-base-href');
22
29
  if (baseHref) {
23
- // Force load the resolved theme (light/dark)
24
- highlightLink.href = baseHref + 'docmd-highlight-' + effectiveTheme + '.css';
30
+ highlightLink.href = baseHref + 'docmd-highlight-' + theme + '.css';
25
31
  }
26
32
  }
27
33
  } catch (e) {