@mgks/docmd 0.2.1 → 0.2.3
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/config.js +5 -1
- package/docs/configuration.md +4 -1
- package/docs/content/containers/steps.md +2 -2
- package/package.json +1 -1
- package/src/assets/css/docmd-main.css +2 -2
- package/src/assets/css/docmd-theme-ruby.css +1 -1
- package/src/assets/js/docmd-main.js +75 -0
- package/src/commands/build.js +15 -16
- package/src/commands/init.js +2 -1
- package/src/core/file-processor.js +21 -11
- package/src/templates/navigation.ejs +69 -98
package/config.js
CHANGED
|
@@ -28,7 +28,7 @@ module.exports = {
|
|
|
28
28
|
|
|
29
29
|
// Theme Configuration
|
|
30
30
|
theme: {
|
|
31
|
-
name: 'sky',
|
|
31
|
+
name: 'sky', // Themes: 'default', 'sky', 'retro', 'ruby'
|
|
32
32
|
defaultMode: 'light', // Initial color mode: 'light' or 'dark'
|
|
33
33
|
enableModeToggle: true, // Show UI button to toggle light/dark modes
|
|
34
34
|
positionMode: 'top', // 'top' or 'bottom' for the theme toggle
|
|
@@ -107,6 +107,7 @@ module.exports = {
|
|
|
107
107
|
title: 'Content',
|
|
108
108
|
icon: 'layout-template',
|
|
109
109
|
path: '/content/',
|
|
110
|
+
collapsible: true,
|
|
110
111
|
children: [
|
|
111
112
|
{ title: 'Frontmatter', path: '/content/frontmatter', icon: 'file-text' },
|
|
112
113
|
{ title: 'Markdown Syntax', path: '/content/markdown-syntax', icon: 'code-2' },
|
|
@@ -115,6 +116,7 @@ module.exports = {
|
|
|
115
116
|
title: 'Custom Containers',
|
|
116
117
|
path: '/content/containers/',
|
|
117
118
|
icon: 'box',
|
|
119
|
+
collapsible: true,
|
|
118
120
|
children: [
|
|
119
121
|
{ title: 'Callouts', path: '/content/containers/callouts', icon: 'megaphone' },
|
|
120
122
|
{ title: 'Cards', path: '/content/containers/cards', icon: 'panel-top' },
|
|
@@ -133,6 +135,7 @@ module.exports = {
|
|
|
133
135
|
title: 'Theming',
|
|
134
136
|
icon: 'palette',
|
|
135
137
|
path: '/theming/',
|
|
138
|
+
collapsible: true,
|
|
136
139
|
children: [
|
|
137
140
|
{ title: 'Available Themes', path: '/theming/available-themes', icon: 'layout-grid' },
|
|
138
141
|
{ title: 'Light & Dark Mode', path: '/theming/light-dark-mode', icon: 'sun-moon' },
|
|
@@ -144,6 +147,7 @@ module.exports = {
|
|
|
144
147
|
title: 'Plugins',
|
|
145
148
|
icon: 'puzzle',
|
|
146
149
|
path: '/plugins/',
|
|
150
|
+
collapsible: true,
|
|
147
151
|
children: [
|
|
148
152
|
{ title: 'SEO & Meta Tags', path: '/plugins/seo', icon: 'search' },
|
|
149
153
|
{ title: 'Analytics', path: '/plugins/analytics', icon: 'bar-chart' },
|
package/docs/configuration.md
CHANGED
|
@@ -32,7 +32,7 @@ module.exports = {
|
|
|
32
32
|
name: 'sky',
|
|
33
33
|
defaultMode: 'light',
|
|
34
34
|
enableModeToggle: true,
|
|
35
|
-
positionMode: '
|
|
35
|
+
positionMode: 'top', // 'top' or 'bottom'
|
|
36
36
|
customCss: [ // Array of paths to your custom CSS files
|
|
37
37
|
// '/css/override-styles.css', // Paths are relative to the outputDir root
|
|
38
38
|
],
|
|
@@ -84,6 +84,7 @@ module.exports = {
|
|
|
84
84
|
{
|
|
85
85
|
title: 'Guides',
|
|
86
86
|
icon: 'book-open',
|
|
87
|
+
collapsible: true, // This makes the 'Guides' section collapsible
|
|
87
88
|
children: [
|
|
88
89
|
{ title: 'Installation', path: '/guides/installation', icon: 'download' },
|
|
89
90
|
{ title: 'Project GitHub', path: 'https://github.com/mgks/docmd', icon: 'github', external: true }
|
|
@@ -225,7 +226,9 @@ Configures the visual theme of your site.
|
|
|
225
226
|
* `path` (String, Required for direct links)
|
|
226
227
|
* `children` (Array, Optional)
|
|
227
228
|
* `icon` (String, Optional): The name of an SVG icon to display next to the navigation item. `docmd` will look for an SVG file named `icon-name.svg` in its bundled assets (e.g., `home` for `home.svg`). Ensure the chosen icon name corresponds to an available SVG. See [Theming > Icons](/theming/icons/) for more details.
|
|
229
|
+
* `collapsible` (Boolean, Optional): If set to `true` on a parent item (an item with `children`), the item will become a collapsible accordion. It will be collapsed by default unless one of its children is the currently active page. User interactions (opening/closing) are saved in `sessionStorage`. Defaults to `false`.
|
|
228
230
|
* `external` (Boolean, Optional): If set to `true`, the `path` is treated as an absolute external URL and the link will open in a new tab (`target="_blank"`). Defaults to `false`.
|
|
231
|
+
* `collapsible` (Boolean, Optional): If set to `true` on a parent item (an item with `children`), the item will become a collapsible accordion. It will be collapsed by default unless one of its children is the currently active page. User interactions (opening/closing) are saved in `sessionStorage`. Defaults to `false`.
|
|
229
232
|
|
|
230
233
|
## `footer` (String, Optional)
|
|
231
234
|
* **Description:** Custom footer text (Markdown supported). **Note:** For noStyle pages, the footer must be explicitly enabled via `components.footer: true`.
|
|
@@ -74,7 +74,7 @@ You can include cards, callouts, and buttons inside steps for richer content:
|
|
|
74
74
|
3. **Initialize Project**
|
|
75
75
|
Create the project structure and configuration files.
|
|
76
76
|
|
|
77
|
-
::: button Create_Project external:https://github.com/new color
|
|
77
|
+
::: button Create_Project external:https://github.com/new color:#2564e4
|
|
78
78
|
|
|
79
79
|
4. **Start Coding**
|
|
80
80
|
Begin implementing your application features.
|
|
@@ -110,7 +110,7 @@ You can include cards, callouts, and buttons inside steps for richer content:
|
|
|
110
110
|
3. **Initialize Project**
|
|
111
111
|
Create the project structure and configuration files.
|
|
112
112
|
|
|
113
|
-
::: button Create_Project external:https://github.com/new color
|
|
113
|
+
::: button Create_Project external:https://github.com/new color:#2564e4
|
|
114
114
|
|
|
115
115
|
4. **Start Coding**
|
|
116
116
|
Begin implementing your application features.
|
package/package.json
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
/*
|
|
4
4
|
* Main CSS file for docmd
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
.docmd-container.steps-reset .docmd-container.steps-reset ol.steps-list>li.step-item::before,.docmd-container.steps-reset ol.steps-list>li.step-item::before,.docmd-container.steps-reset ol.steps-list[start]>li.step-item::before{content:counter(list-counter) ".";font-weight:700;margin-right:.5em;color:var(--accent-color,#007acc)}.docmd-tab-pane.active,.logo-link img,.logo-link img.logo-light,.tab-panel.active,.theme-toggle-button .icon-sun,body.sidebar-collapsible .sidebar-toggle-button,html[data-theme=dark] .logo-link img.logo-dark,html[data-theme=dark] .theme-toggle-button .icon-moon,img{display:block}:root{--font-family-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--font-family-mono:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;--bg-color:#ffffff;--text-color:#333333;--sidebar-bg:#f4f7f9;--sidebar-text:#2c3e50;--sidebar-link-active-bg:#e0e7ec;--sidebar-link-active-parent-bg:#e9eff3;--link-color:#007bff;--border-color:#e0e0e0;--code-bg:#f8f8f8;--code-text:#333;--header-bg:#ffffff;--header-border:#e0e0e0;--image-border-color:#e0e0e0;--image-shadow:0 2px 8px rgba(0, 0, 0, 0.1);--image-caption-bg:#f8f8f8;--image-caption-text:#666;--lightbox-bg:rgba(0, 0, 0, 0.9);--lightbox-text:#fff}[data-theme=dark]{--bg-color:#1a1a1a;--text-color:#e0e0e0;--sidebar-bg:#2c2c2c;--sidebar-text:#bdc3c7;--sidebar-link-active-bg:#3a3a3a;--sidebar-link-active-parent-bg:#343434;--link-color:#58a6ff;--border-color:#444444;--code-bg:#282c34;--code-text:#abb2bf;--header-bg:#1a1a1a;--header-border:#444444;--image-border-color:#444444;--image-shadow:0 2px 8px rgba(0, 0, 0, 0.3);--image-caption-bg:#2c2c2c;--image-caption-text:#bdc3c7;--lightbox-bg:rgba(0, 0, 0, 0.95);--lightbox-text:#fff}body{font-family:var(--font-family-sans);background-color:var(--bg-color);color:var(--text-color);margin:0;display:flex;min-height:100vh;line-height:1.6}code,pre{font-family:var(--font-family-mono);background-color:var(--code-bg)}.sidebar{width:260px;background-color:var(--sidebar-bg);color:var(--sidebar-text);padding:20px;border-right:1px solid var(--border-color);height:100vh;position:fixed;top:0;left:0;overflow-y:auto;box-sizing:border-box;flex-shrink:0}.sidebar h1{font-size:1.5em;margin-top:0;margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid var(--border-color)}.sidebar nav ul{list-style:none;padding:0;margin:0}.sidebar nav li a{display:block;padding:8px 10px;text-decoration:none;color:var(--sidebar-text);border-radius:4px;transition:background-color .2s}.copy-code-button:hover,.docmd-tabs-nav-item:hover,.sidebar nav li a.active,.sidebar nav li a:hover,.theme-toggle-button:hover{background-color:var(--sidebar-link-active-bg)}.sidebar nav li a.active{font-weight:600;color:var(--link-color)}.sidebar nav li.active-parent>a{background-color:var(--sidebar-link-active-parent-bg);font-weight:500;position:relative}.sidebar nav li.active-parent>a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background-color:var(--link-color);opacity:.5}.sidebar nav li.active-parent>a.active::before,div:hover>.copy-code-button,.copy-code-button:hover{opacity:1}.sidebar nav ul ul{padding-left:20px;margin-top:5px}.sidebar-toggle-button{background:0 0;border:1px solid transparent;color:var(--text-color);cursor:pointer;padding:0;margin:.5em 0 0;display:none;border-radius:4px}.sidebar-toggle-button:hover{background-color:var(--sidebar-bg);border-color:var(--border-color)}.sidebar-toggle-button .lucide-icon{width:2em;height:2em}body.sidebar-collapsed .sidebar{transform:translateX(-100%);visibility:hidden}.toc-level-2,body.sidebar-collapsed .main-content-wrapper{margin-left:0}.main-content-wrapper,.sidebar{transition:transform .3s,margin-left .3s,visibility .3s}.main-content-wrapper{margin-left:260px;flex-grow:1;display:flex;flex-direction:column;overflow:hidden}.header-left,.page-header{align-items:center;display:flex}.page-header{padding:15px 30px;border-bottom:1px solid var(--header-border);background-color:var(--header-bg);justify-content:space-between;min-height:2.5em}.header-left{gap:15px}.header-right{display:flex;align-items:center}.page-header h1{margin:0;font-size:1.8em}.theme-toggle-header{padding:8px;background:var(--content-bg);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;transition:.2s}.theme-toggle-header:hover{background:var(--sidebar-bg);border-color:var(--accent-color)}.card .card-title,.sidebar-header{border-bottom:1px solid var(--border-color)}.content-area{padding:2.5rem 2rem;max-width:1200px;margin:0 auto;width:100%;box-sizing:border-box}pre{color:var(--code-text);padding:1em;border-radius:4px;overflow-x:auto;position:relative}code{padding:.2em .4em;border-radius:3px;font-size:.9em}pre code{background-color:transparent;padding:0;font-size:inherit}.sidebar-header{padding-bottom:10px;margin-bottom:10px;text-align:center;height:2.5em}.sidebar-header h1{font-size:1.5em;margin-top:0;margin-bottom:0}.logo-link img{max-height:40px;width:auto;margin:0 auto}.docmd-tab-pane,.logo-link img.logo-dark,.tab-panel,.theme-toggle-button .icon-moon,html[data-theme=dark] .logo-link img.logo-light,html[data-theme=dark] .theme-toggle-button .icon-sun{display:none}.sidebar-nav .lucide-icon{width:1em;height:1em;margin-right:.5em;vertical-align:-.15em;stroke-width:2}.sidebar-nav .nav-external-icon{width:1em;height:1.5em;float:right;margin-left:.3em;opacity:.7}.theme-toggle-button{background:0 0;border:1px solid var(--border-color);color:var(--sidebar-text);padding:8px;border-radius:4px;cursor:pointer;margin-top:.5em;display:flex;align-items:center;justify-content:center;width:100%}.next-page,.prev-page,.step::before{color:var(--link-color);display:flex}.callout .callout-content>:first-child,.card .card-content>:first-child,.docmd-container>:first-child,.step-content>:first-child,.step-title{margin-top:0}.theme-toggle-button .lucide-icon{width:1.2em;height:1.2em}.docmd-container{padding:1rem 1.5rem;margin-bottom:1.5rem;border-radius:6px;border:1px solid var(--border-color);background-color:var(--code-bg)}.callout .callout-content>:last-child,.card .card-content>:last-child,.docmd-container>:last-child,.step-content>:last-child{margin-bottom:0}.callout{border-left-width:5px;background-color:transparent}.callout-title{font-weight:700;margin-bottom:.5em}.callout-info{border-left-color:#3498db;background-color:rgba(52,152,219,.07)}.callout-warning{border-left-color:#f39c12;background-color:rgba(243,156,18,.07)}.callout-success,.callout-tip{border-left-color:#2ecc71;background-color:rgba(46,204,113,.07)}.callout-danger{border-left-color:#e74c3c;background-color:rgba(231,76,60,.07)}.card .card-title{font-weight:700;font-size:1.1em;margin:-1rem -1.5rem 1rem;padding:.75rem 1.5rem}.docmd-container.steps{position:relative;padding-left:3rem;border:none;background:0 0;box-shadow:none}.docmd-container.steps::before{content:"";position:absolute;top:1rem;bottom:1rem;left:2.5rem;width:2px;background-color:var(--border-color)}.step{position:relative;padding-bottom:1.5rem}.step:last-child{padding-bottom:0}.step::before{content:attr(data-step);position:absolute;left:-3rem;top:.1rem;width:2.5rem;height:2.5rem;background-color:var(--bg-color);border:2px solid var(--border-color);border-radius:50%;align-items:center;justify-content:center;font-size:1rem;font-weight:600;z-index:1}.step-title{font-size:1.25rem;font-weight:600;margin-bottom:.5rem}.docmd-container.steps-reset{counter-reset:step-counter 0}.docmd-container.steps-reset ol.steps-list{counter-reset:list-counter 0;list-style:none}.docmd-container.steps-reset ol.steps-list>li.step-item{counter-increment:list-counter 1;position:relative;padding-left:0;margin-bottom:2.5rem}.docmd-container.steps-reset ol.steps-list>li.step-item::before{font-size:2rem}.docmd-container.steps-reset .docmd-container.steps-reset ol.steps-list,.docmd-container.steps-reset ol.steps-list[start]{counter-reset:list-counter 0}.docmd-container.steps-reset .docmd-container.steps-reset ol.steps-list>li.step-item,.docmd-container.steps-reset ol.steps-list[start]>li.step-item{counter-increment:list-counter 1}.docmd-container.steps-reset ol:not(.steps-list)::before,.docmd-container.steps-reset ol:not(.steps-list)>li::before,.docmd-container.steps-reset ul::before,.docmd-container.steps-reset ul>li::before{width:.75rem;height:.75rem;left:-1.5rem;top:.5rem;content:""!important}:focus-visible{outline:2px solid var(--link-color);outline-offset:2px}:focus:not(:focus-visible){outline:currentcolor}.sidebar nav li a:focus-visible{background-color:var(--sidebar-link-active-bg);outline:2px solid var(--link-color);outline-offset:-2px}.theme-toggle-button:focus-visible{border-color:var(--link-color);box-shadow:0 0 0 2px var(--link-color)}.page-footer,.page-navigation{border-top:1px solid var(--border-color)}.page-navigation{display:flex;justify-content:space-between;margin-top:3rem;padding-top:1.5rem}.next-page,.prev-page{align-items:center;text-decoration:none;padding:.75rem;border-radius:6px;transition:background-color .2s;width:48%;max-width:48%}.next-page:hover,.prev-page:hover{background-color:rgba(0,0,0,.05);text-decoration:none}[data-theme=dark] .next-page:hover,[data-theme=dark] .prev-page:hover{background-color:rgba(255,255,255,.05)}.prev-page{justify-content:flex-start}.next-page{justify-content:flex-end;text-align:right}.next-page-placeholder,.prev-page-placeholder{width:48%}.next-page span,.prev-page span{display:flex;flex-direction:column}.next-page small,.prev-page small{font-size:.8rem;opacity:.8;margin-bottom:.25rem}.next-page strong,.prev-page strong{font-weight:500}.page-nav-icon{width:1.2rem;height:1.2rem}.prev-page .page-nav-icon{margin-right:.75rem}.next-page .page-nav-icon{margin-left:.75rem}.page-footer{text-align:center;padding:20px 30px;margin-top:auto;font-size:.9em;color:var(--text-color);background-color:var(--sidebar-bg)}.footer-content{display:flex;justify-content:space-between;align-items:center;margin:0 auto;width:100%}.user-footer{text-align:left}.branding-footer{text-align:right;opacity:.9;font-weight:500}.branding-footer svg{color:#fb3a3a}.page-footer a{color:var(--link-color);text-decoration:none}.page-footer a:hover,.toc-link:hover{text-decoration:underline}.content-layout{display:flex;gap:2rem;width:100%}.main-content{flex:1 1 0%;min-inline-size:0px}.toc-container{margin:0;padding:0;border:none;background-color:transparent}.docmd-container figure img,.toc-title{margin-bottom:.5rem}.toc-title{margin-top:0;font-size:1rem;font-weight:700;color:var(--text-muted)}.toc-list{list-style:none;padding-left:0;margin:0}.toc-item{margin-bottom:.25rem;line-height:1.4}.toc-link{text-decoration:none;color:var(--link-color);display:inline-block;padding:.1rem 0;font-size:.9rem;font-weight:500}.toc-level-3{margin-left:.75rem;font-size:.85rem}.toc-level-4{margin-left:1.5rem;font-size:.8rem}.toc-sidebar{width:180px;position:sticky;top:2rem;max-height:calc(-4rem + 100vh);overflow-y:auto;align-self:flex-start}@media (max-width:1024px){.content-layout{flex-direction:column;display:flex;flex-direction:column-reverse}.toc-sidebar{width:100%;position:static;margin-bottom:1rem}}.docmd-tabs,img{margin:1.5rem 0}img{max-width:100%;height:auto}img.align-left{float:left;margin-right:1.5rem;margin-bottom:1rem}img.align-center{margin-left:auto;margin-right:auto}img.align-right{float:right;margin-left:1.5rem;margin-bottom:1rem}img.size-small{max-width:300px}img.size-medium{max-width:500px}img.size-large{max-width:800px}img.with-border{border:1px solid var(--image-border-color);padding:4px}img.with-shadow{box-shadow:var(--image-shadow)}.docmd-container figure{margin:2rem 0}.docmd-container figcaption{font-size:.9rem;color:var(--image-caption-text);text-align:center;padding:.5rem;background-color:var(--image-caption-bg);border-radius:0 0 4px 4px}.docmd-container .image-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:1rem;margin:2rem 0}.docmd-container .image-gallery figure{margin:0}.docmd-container .clear-float::after{content:"";display:table;clear:both}.docmd-tabs{border:1px solid var(--border-color);border-radius:6px;overflow:hidden;box-shadow:rgba(0,0,0,.05) 0 1px 3px}.docmd-tabs-nav{display:flex;background-color:var(--sidebar-bg);border-bottom:1px solid var(--border-color);overflow:auto hidden}.docmd-tabs-nav-item{padding:.75rem 1.25rem;cursor:pointer;border-bottom:3px solid transparent;margin-bottom:-1px;font-weight:500;color:var(--sidebar-text);white-space:nowrap}.docmd-tabs-nav-item.active{color:var(--link-color);border-bottom-color:var(--link-color);background-color:var(--bg-color)}.docmd-tabs-content{padding:1.5rem}.tabs-container{margin:1rem 0;border:1px solid #e1e5e9;border-radius:.375rem}.tab-navigation{display:flex;background-color:#f8f9fa;border-bottom:1px solid #e1e5e9;border-radius:.375rem .375rem 0 0}.tab-button{padding:.75rem 1rem;border-width:medium medium 2px;border-style:none none solid;border-color:currentcolor currentcolor transparent;border-image:none;background:0 0;cursor:pointer;transition:.2s}.tab-button:hover{background-color:#e9ecef}.tab-button.active{border-bottom-color:#007bff;background-color:#fff}.tab-content{padding:1rem}.docmd-lightbox{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:var(--lightbox-bg);z-index:9999;justify-content:center;align-items:center;flex-direction:column}.copy-code-button svg,.sponsor-icon{width:1rem;height:1rem}.docmd-lightbox-content{position:relative;max-width:90%;max-height:90%;text-align:center}.docmd-lightbox-content img{max-width:100%;max-height:80vh;object-fit:contain;margin:0 auto;box-shadow:rgba(0,0,0,.3) 0 0 20px}.docmd-lightbox-caption{color:var(--lightbox-text);padding:1rem;font-size:1rem;max-width:100%}.docmd-lightbox-close{position:absolute;top:20px;right:30px;color:var(--lightbox-text);font-size:2.5rem;cursor:pointer;z-index:10000}.docmd-lightbox-close:hover{color:#ddd}.docmd-button,.sponsor-link,.sponsor-link:hover{color:#fff;text-decoration:none}.docmd-container .image-gallery img,img.lightbox{cursor:zoom-in}.docmd-button{display:inline-block;padding:.6rem 1.2rem;margin:.5rem;border-radius:6px;background-color:var(--link-color);font-weight:500;transition:background-color .2s,transform .2s;border:none;cursor:pointer}.docmd-button:hover{text-decoration:none;filter:brightness(90%);transform:translateY(-1px)}.sponsor-ribbon{position:fixed;bottom:60px;right:10px;z-index:1000;transform:rotate(0);transform-origin:center}.sponsor-link{display:flex;align-items:center;gap:.5rem;background:linear-gradient(135deg,#ff6b6b,#ee5a24);padding:.75rem 1.5rem;border-radius:5px;box-shadow:0 4px 12px rgba(255,107,107,.3);font-weight:600;font-size:.875rem;transition:.3s;white-space:nowrap}.sponsor-link:hover{transform:scale(1.02);box-shadow:0 6px 20px rgba(255,107,107,.4)}.sponsor-icon{animation:2s ease-in-out infinite heartbeat}.sponsor-text{font-family:inherit}@keyframes heartbeat{0%,100%{transform:scale(1)}50%{transform:scale(1.1)}}@media (max-width:768px){body{flex-direction:column}.sidebar{width:100%;height:auto;position:static;border-right:currentcolor;border-bottom:1px solid var(--border-color)}.sidebar-toggle-button{display:block}.main-content-wrapper{margin-left:0}.content-area{padding:15px}.footer-content,.page-navigation{flex-direction:column;gap:1rem}.branding-footer,.user-footer{text-align:center}.next-page,.next-page-placeholder,.prev-page,.prev-page-placeholder{width:100%;max-width:100%}img.align-left,img.align-right{float:none;margin-left:auto;margin-right:auto}.docmd-container .image-gallery{grid-template-columns:1fr}.sponsor-ribbon{bottom:10px;right:10px}.sponsor-link{padding:.5rem 1rem;font-size:.75rem}.sponsor-icon{width:.875rem;height:.875rem}}html[data-theme=dark] .sponsor-link{background:linear-gradient(135deg,#ff6b6b,#c44569);box-shadow:0 4px 12px rgba(255,107,107,.2)}html[data-theme=dark] .sponsor-link:hover{box-shadow:0 6px 20px rgba(255,107,107,.3)}.copy-code-button{position:absolute;top:.75rem;right:.75rem;padding:.5rem;background-color:var(--code-bg);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;opacity:0;transition:opacity .2s ease-in-out,background-color .2s;color:var(--sidebar-text);display:flex;align-items:center;justify-content:center;z-index:10;pointer-events:auto}.copy-code-button.copied{color:#10b981;opacity:1}
|
|
6
|
+
|
|
7
|
+
.docmd-container.steps-reset .docmd-container.steps-reset ol.steps-list>li.step-item::before,.docmd-container.steps-reset ol.steps-list>li.step-item::before,.docmd-container.steps-reset ol.steps-list[start]>li.step-item::before{content:counter(list-counter) ".";font-weight:700;margin-right:.5em;color:var(--accent-color,#007acc)}.docmd-tab-pane.active,.logo-link img,.logo-link img.logo-light,.tab-panel.active,.theme-toggle-button .icon-sun,body.sidebar-collapsible .sidebar-toggle-button,html[data-theme=dark] .logo-link img.logo-dark,html[data-theme=dark] .theme-toggle-button .icon-moon,img{display:block}:root{--font-family-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--font-family-mono:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;--bg-color:#ffffff;--text-color:#333333;--sidebar-bg:#f4f7f9;--sidebar-text:#2c3e50;--sidebar-link-active-bg:#e0e7ec;--sidebar-link-active-parent-bg:#e9eff3;--link-color:#007bff;--border-color:#e0e0e0;--code-bg:#f8f8f8;--code-text:#333;--header-bg:#ffffff;--header-border:#e0e0e0;--image-border-color:#e0e0e0;--image-shadow:0 2px 8px rgba(0, 0, 0, 0.1);--image-caption-bg:#f8f8f8;--image-caption-text:#666;--lightbox-bg:rgba(0, 0, 0, 0.9);--lightbox-text:#fff}[data-theme=dark]{--bg-color:#1a1a1a;--text-color:#e0e0e0;--sidebar-bg:#2c2c2c;--sidebar-text:#bdc3c7;--sidebar-link-active-bg:#3a3a3a;--sidebar-link-active-parent-bg:#343434;--link-color:#58a6ff;--border-color:#444444;--code-bg:#282c34;--code-text:#abb2bf;--header-bg:#1a1a1a;--header-border:#444444;--image-border-color:#444444;--image-shadow:0 2px 8px rgba(0, 0, 0, 0.3);--image-caption-bg:#2c2c2c;--image-caption-text:#bdc3c7;--lightbox-bg:rgba(0, 0, 0, 0.95);--lightbox-text:#fff}body{font-family:var(--font-family-sans);background-color:var(--bg-color);color:var(--text-color);margin:0;display:flex;min-height:100vh;line-height:1.6}code,pre{font-family:var(--font-family-mono);background-color:var(--code-bg)}.sidebar{width:260px;background-color:var(--sidebar-bg);color:var(--sidebar-text);padding:20px;border-right:1px solid var(--border-color);height:100vh;position:fixed;top:0;left:0;overflow-y:auto;box-sizing:border-box;flex-shrink:0}.sidebar h1{font-size:1.5em;margin-top:0;margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid var(--border-color)}.sidebar nav ul{list-style:none;padding:0;margin:0}.sidebar nav li a{display:block;padding:8px 10px;text-decoration:none;color:var(--sidebar-text);border-radius:4px;transition:background-color .2s}.copy-code-button:hover,.docmd-tabs-nav-item:hover,.sidebar nav li a.active,.sidebar nav li a:hover,.theme-toggle-button:hover{background-color:var(--sidebar-link-active-bg)}.sidebar nav li a.active{font-weight:600;color:var(--link-color)}.sidebar nav li.active-parent>a{background-color:var(--sidebar-link-active-parent-bg);font-weight:500;position:relative}.sidebar nav li.active-parent>a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background-color:var(--link-color);opacity:.5}.copy-code-button:hover,.sidebar nav li.active-parent>a.active::before,div:hover>.copy-code-button{opacity:1}.sidebar nav ul ul{padding-left:20px;margin-top:5px}.sidebar-toggle-button{background:0 0;border:1px solid transparent;color:var(--text-color);cursor:pointer;padding:0;margin:.5em 0 0;display:none;border-radius:4px}.sidebar-toggle-button:hover{background-color:var(--sidebar-bg);border-color:var(--border-color)}.sidebar-toggle-button .lucide-icon{width:2em;height:2em}body.sidebar-collapsed .sidebar{transform:translateX(-100%);visibility:hidden}.toc-level-2,body.sidebar-collapsed .main-content-wrapper{margin-left:0}.main-content-wrapper,.sidebar{transition:transform .3s,margin-left .3s,visibility .3s}.main-content-wrapper{margin-left:260px;flex-grow:1;display:flex;flex-direction:column;overflow:hidden}.header-left,.page-header{align-items:center;display:flex}.page-header{padding:15px 30px;border-bottom:1px solid var(--header-border);background-color:var(--header-bg);justify-content:space-between;min-height:2.5em}.header-left{gap:15px}.header-right{display:flex;align-items:center}.page-header h1{margin:0;font-size:1.8em}.theme-toggle-header{padding:8px;background:var(--content-bg);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;transition:.2s}.theme-toggle-header:hover{background:var(--sidebar-bg);border-color:var(--accent-color)}.card .card-title,.sidebar-header{border-bottom:1px solid var(--border-color)}.content-area{padding:2.5rem 2rem;max-width:1200px;margin:0 auto;width:100%;box-sizing:border-box}pre{color:var(--code-text);padding:1em;border-radius:4px;overflow-x:auto;position:relative}code{padding:.2em .4em;border-radius:3px;font-size:.9em}pre code{background-color:transparent;padding:0;font-size:inherit}.sidebar-header{padding-bottom:10px;margin-bottom:10px;text-align:center;height:2.5em}.sidebar-header h1{font-size:1.5em;margin-top:0;margin-bottom:0}.logo-link img{max-height:40px;width:auto;margin:0 auto}.docmd-tab-pane,.logo-link img.logo-dark,.tab-panel,.theme-toggle-button .icon-moon,html[data-theme=dark] .logo-link img.logo-light,html[data-theme=dark] .theme-toggle-button .icon-sun,.sidebar nav li.collapsible:not([aria-expanded=true])>.submenu{display:none}.sidebar-nav .lucide-icon{width:1em;height:1em;margin-right:.5em;vertical-align:-.15em;stroke-width:2}.sidebar-nav .nav-external-icon{width:1em;height:1.5em;float:right;margin-left:.3em;opacity:.7}.theme-toggle-button{background:0 0;border:1px solid var(--border-color);color:var(--sidebar-text);padding:8px;border-radius:4px;cursor:pointer;margin-top:.5em;display:flex;align-items:center;justify-content:center;width:100%}.next-page,.prev-page,.step::before{color:var(--link-color);display:flex}.callout .callout-content>:first-child,.card .card-content>:first-child,.docmd-container>:first-child,.step-content>:first-child,.step-title{margin-top:0}.theme-toggle-button .lucide-icon{width:1.2em;height:1.2em}.docmd-container{padding:1rem 1.5rem;margin-bottom:1.5rem;border-radius:6px;border:1px solid var(--border-color);background-color:var(--code-bg)}.callout .callout-content>:last-child,.card .card-content>:last-child,.docmd-container>:last-child,.step-content>:last-child{margin-bottom:0}.callout{border-left-width:5px;background-color:transparent}.callout-title{font-weight:700;margin-bottom:.5em}.callout-info{border-left-color:#3498db;background-color:rgba(52,152,219,.07)}.callout-warning{border-left-color:#f39c12;background-color:rgba(243,156,18,.07)}.callout-success,.callout-tip{border-left-color:#2ecc71;background-color:rgba(46,204,113,.07)}.callout-danger{border-left-color:#e74c3c;background-color:rgba(231,76,60,.07)}.card .card-title{font-weight:700;font-size:1.1em;margin:-1rem -1.5rem 1rem;padding:.75rem 1.5rem}.docmd-container.steps{position:relative;padding-left:3rem;border:none;background:0 0;box-shadow:none}.docmd-container.steps::before{content:"";position:absolute;top:1rem;bottom:1rem;left:2.5rem;width:2px;background-color:var(--border-color)}.step{position:relative;padding-bottom:1.5rem}.step:last-child{padding-bottom:0}.step::before{content:attr(data-step);position:absolute;left:-3rem;top:.1rem;width:2.5rem;height:2.5rem;background-color:var(--bg-color);border:2px solid var(--border-color);border-radius:50%;align-items:center;justify-content:center;font-size:1rem;font-weight:600;z-index:1}.step-title{font-size:1.25rem;font-weight:600;margin-bottom:.5rem}.docmd-container.steps-reset{counter-reset:step-counter 0}.docmd-container.steps-reset ol.steps-list{counter-reset:list-counter 0;list-style:none}.docmd-container.steps-reset ol.steps-list>li.step-item{counter-increment:list-counter 1;position:relative;padding-left:0;margin-bottom:2.5rem}.docmd-container.steps-reset ol.steps-list>li.step-item::before{font-size:2rem}.docmd-container.steps-reset .docmd-container.steps-reset ol.steps-list,.docmd-container.steps-reset ol.steps-list[start]{counter-reset:list-counter 0}.docmd-container.steps-reset .docmd-container.steps-reset ol.steps-list>li.step-item,.docmd-container.steps-reset ol.steps-list[start]>li.step-item{counter-increment:list-counter 1}.docmd-container.steps-reset ol:not(.steps-list)::before,.docmd-container.steps-reset ol:not(.steps-list)>li::before,.docmd-container.steps-reset ul::before,.docmd-container.steps-reset ul>li::before{width:.75rem;height:.75rem;left:-1.5rem;top:.5rem;content:""!important}:focus-visible{outline:2px solid var(--link-color);outline-offset:2px}:focus:not(:focus-visible){outline:currentcolor}.sidebar nav li a:focus-visible{background-color:var(--sidebar-link-active-bg);outline:2px solid var(--link-color);outline-offset:-2px}.theme-toggle-button:focus-visible{border-color:var(--link-color);box-shadow:0 0 0 2px var(--link-color)}.page-footer,.page-navigation{border-top:1px solid var(--border-color)}.page-navigation{display:flex;justify-content:space-between;margin-top:3rem;padding-top:1.5rem}.next-page,.prev-page{align-items:center;text-decoration:none;padding:.75rem;border-radius:6px;transition:background-color .2s;width:48%;max-width:48%}.next-page:hover,.prev-page:hover{background-color:rgba(0,0,0,.05);text-decoration:none}[data-theme=dark] .next-page:hover,[data-theme=dark] .prev-page:hover{background-color:rgba(255,255,255,.05)}.prev-page{justify-content:flex-start}.next-page{justify-content:flex-end;text-align:right}.next-page-placeholder,.prev-page-placeholder{width:48%}.next-page span,.prev-page span{display:flex;flex-direction:column}.next-page small,.prev-page small{font-size:.8rem;opacity:.8;margin-bottom:.25rem}.next-page strong,.prev-page strong{font-weight:500}.page-nav-icon{width:1.2rem;height:1.2rem}.prev-page .page-nav-icon{margin-right:.75rem}.next-page .page-nav-icon{margin-left:.75rem}.page-footer{text-align:center;padding:20px 30px;margin-top:auto;font-size:.9em;color:var(--text-color);background-color:var(--sidebar-bg)}.footer-content{display:flex;justify-content:space-between;align-items:center;margin:0 auto;width:100%}.user-footer{text-align:left}.branding-footer{text-align:right;opacity:.9;font-weight:500}.branding-footer svg{color:#fb3a3a}.page-footer a{color:var(--link-color);text-decoration:none}.page-footer a:hover,.toc-link:hover{text-decoration:underline}.content-layout{display:flex;gap:2rem;width:100%}.main-content{flex:1 1 0%;min-inline-size:0px}.toc-container{margin:0;padding:0;border:none;background-color:transparent}.docmd-container figure img,.toc-title{margin-bottom:.5rem}.toc-title{margin-top:0;font-size:1rem;font-weight:700;color:var(--text-muted)}.toc-list{list-style:none;padding-left:0;margin:0}.toc-item{margin-bottom:.25rem;line-height:1.4}.toc-link{text-decoration:none;color:var(--link-color);display:inline-block;padding:.1rem 0;font-size:.9rem;font-weight:500}.toc-level-3{margin-left:.75rem;font-size:.85rem}.toc-level-4{margin-left:1.5rem;font-size:.8rem}.toc-sidebar{width:180px;position:sticky;top:2rem;max-height:calc(-4rem + 100vh);overflow-y:auto;align-self:flex-start}@media (max-width:1024px){.content-layout{display:flex;flex-direction:column-reverse}.toc-sidebar{width:100%;position:static;margin-bottom:1rem}}.docmd-tabs,img{margin:1.5rem 0}img{max-width:100%;height:auto}img.align-left{float:left;margin-right:1.5rem;margin-bottom:1rem}img.align-center{margin-left:auto;margin-right:auto}img.align-right{float:right;margin-left:1.5rem;margin-bottom:1rem}img.size-small{max-width:300px}img.size-medium{max-width:500px}img.size-large{max-width:800px}img.with-border{border:1px solid var(--image-border-color);padding:4px}img.with-shadow{box-shadow:var(--image-shadow)}.docmd-container figure{margin:2rem 0}.docmd-container figcaption{font-size:.9rem;color:var(--image-caption-text);text-align:center;padding:.5rem;background-color:var(--image-caption-bg);border-radius:0 0 4px 4px}.docmd-container .image-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:1rem;margin:2rem 0}.docmd-container .image-gallery figure{margin:0}.docmd-container .clear-float::after{content:"";display:table;clear:both}.docmd-tabs{border:1px solid var(--border-color);border-radius:6px;overflow:hidden;box-shadow:rgba(0,0,0,.05) 0 1px 3px}.docmd-tabs-nav{display:flex;background-color:var(--sidebar-bg);border-bottom:1px solid var(--border-color);overflow:auto hidden}.docmd-tabs-nav-item{padding:.75rem 1.25rem;cursor:pointer;border-bottom:3px solid transparent;margin-bottom:-1px;font-weight:500;color:var(--sidebar-text);white-space:nowrap}.docmd-tabs-nav-item.active{color:var(--link-color);border-bottom-color:var(--link-color);background-color:var(--bg-color)}.docmd-tabs-content{padding:1.5rem}.tabs-container{margin:1rem 0;border:1px solid #e1e5e9;border-radius:.375rem}.tab-navigation{display:flex;background-color:#f8f9fa;border-bottom:1px solid #e1e5e9;border-radius:.375rem .375rem 0 0}.tab-button{padding:.75rem 1rem;border-width:medium medium 2px;border-style:none none solid;border-color:currentcolor currentcolor transparent;border-image:none;background:0 0;cursor:pointer;transition:.2s}.tab-button:hover{background-color:#e9ecef}.tab-button.active{border-bottom-color:#007bff;background-color:#fff}.tab-content{padding:1rem}.docmd-lightbox{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background-color:var(--lightbox-bg);z-index:9999;justify-content:center;align-items:center;flex-direction:column}.copy-code-button svg,.sponsor-icon{width:1rem;height:1rem}.docmd-lightbox-content{position:relative;max-width:90%;max-height:90%;text-align:center}.docmd-lightbox-content img{max-width:100%;max-height:80vh;object-fit:contain;margin:0 auto;box-shadow:rgba(0,0,0,.3) 0 0 20px}.docmd-lightbox-caption{color:var(--lightbox-text);padding:1rem;font-size:1rem;max-width:100%}.docmd-lightbox-close{position:absolute;top:20px;right:30px;color:var(--lightbox-text);font-size:2.5rem;cursor:pointer;z-index:10000}.docmd-lightbox-close:hover{color:#ddd}.docmd-button,.sponsor-link,.sponsor-link:hover{color:#fff;text-decoration:none}.docmd-container .image-gallery img,img.lightbox{cursor:zoom-in}.docmd-button{display:inline-block;padding:.6rem 1.2rem;margin:.5rem;border-radius:6px;background-color:var(--link-color);font-weight:500;transition:background-color .2s,transform .2s;border:none;cursor:pointer}.docmd-button:hover{text-decoration:none;filter:brightness(90%);transform:translateY(-1px)}.sponsor-ribbon{position:fixed;bottom:75px;right:10px;z-index:1000;transform:rotate(0);transform-origin:center center;opacity:.75}.sponsor-link{display:flex;align-items:center;gap:.5rem;background:linear-gradient(135deg,#ff6b6b,#ee5a24);padding:.75rem 1.5rem;border-radius:5px;box-shadow:rgba(255,107,107,.3) 0 4px 12px;font-weight:600;font-size:.875rem;transition:.3s;white-space:nowrap}.sponsor-link:hover{transform:scale(1.02);box-shadow:rgba(255,107,107,.4) 0 6px 20px}.sponsor-icon{animation:2s ease-in-out infinite heartbeat}.sponsor-text{font-family:inherit}@keyframes heartbeat{0%,100%{transform:scale(1)}50%{transform:scale(1.1)}}@media (max-width:768px){body{flex-direction:column}.sidebar{width:100%;height:auto;position:static;border-right:currentcolor;border-bottom:1px solid var(--border-color)}.sidebar-toggle-button{display:block}.main-content-wrapper{margin-left:0}.content-area{padding:15px}.footer-content,.page-navigation{flex-direction:column;gap:1rem}.branding-footer,.user-footer{text-align:center}.next-page,.next-page-placeholder,.prev-page,.prev-page-placeholder{width:100%;max-width:100%}img.align-left,img.align-right{float:none;margin-left:auto;margin-right:auto}.docmd-container .image-gallery{grid-template-columns:1fr}.sponsor-ribbon{bottom:10px;right:10px}.sponsor-link{padding:.5rem 1rem;font-size:.75rem}.sponsor-icon{width:.875rem;height:.875rem}}html[data-theme=dark] .sponsor-link{background:linear-gradient(135deg,#ff6b6b,#c44569);box-shadow:rgba(255,107,107,.2) 0 4px 12px}html[data-theme=dark] .sponsor-link:hover{box-shadow:rgba(255,107,107,.3) 0 6px 20px}.copy-code-button{position:absolute;top:.75rem;right:.75rem;padding:.5rem;background-color:var(--code-bg);border:1px solid var(--border-color);border-radius:6px;cursor:pointer;opacity:0;transition:opacity .2s ease-in-out,background-color .2s;color:var(--sidebar-text);display:flex;align-items:center;justify-content:center;z-index:10;pointer-events:auto}.copy-code-button.copied{color:#10b981;opacity:1}.sidebar nav li.collapsible>a{display:flex;justify-content:space-between;align-items:center}.sidebar nav li.collapsible>a .nav-item-title{flex-grow:1}.sidebar nav .collapse-icon{transition:transform .2s ease-in-out;flex-shrink:0;margin-left:.5em}.sidebar nav li.collapsible[aria-expanded=true]>a>.collapse-icon{transform:rotate(90deg)}hr{color:rgba(245,245,245,.27);border-top-width:1px}
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* Features: Deep ruby red, elegant serif fonts, subtle gem-like effects
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
@import url(https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Source+Sans+Pro:wght@300;400;600;700&display=swap)
|
|
9
|
+
@import url(https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Source+Sans+Pro:wght@300;400;600;700&display=swap);.docmd-container,.sidebar,pre,table{box-shadow:var(--shadow-sm)}h1,h2{padding-bottom:.5rem}.sidebar nav li a.active,pre{border-left:3px solid var(--ruby-primary)}pre,table{margin:1.5em 0}a:hover,th{color:var(--ruby-primary-dark)}.sidebar-header,th{border-bottom:2px solid var(--ruby-border)}td,th{padding:.75rem 1rem}.content-area a:not(.button):not(.no-underline)::after,.docmd-container::before,h1::after{background:linear-gradient(90deg,var(--ruby-primary),var(--ruby-accent));position:absolute;left:0}.callout,.docmd-container,.steps,.steps h4,a,h1{position:relative}.callout-info .callout-title,.docmd-container.steps-reset ol.steps-list>li.step-item::before,.sidebar nav li a:hover{color:var(--ruby-primary)}.card .card-content,.card .card-title{padding:1rem 1.5rem}figure img,img{max-width:100%}.image-gallery img,.image-gallery.zoom img{transition:transform .3s}:root{--ruby-font-family-sans:"Source Sans Pro",system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--ruby-font-family-serif:"Playfair Display",Georgia,"Times New Roman",serif;--ruby-font-family-mono:"JetBrains Mono","SFMono-Regular",Consolas,"Liberation Mono",Menlo,monospace}:root[data-theme=light]{--ruby-primary:#b30000;--ruby-primary-light:#ffebee;--ruby-primary-dark:#8e0000;--ruby-accent:#7b1fa2;--ruby-accent-light:#f3e5f5;--ruby-text:#2d2d2d;--ruby-text-light:#5a5a5a;--ruby-text-lightest:#757575;--ruby-background:#ffffff;--ruby-background-alt:#fafafa;--ruby-border:#e0e0e0;--ruby-border-light:#f0f0f0;--bg-color:var(--ruby-background);--text-color:var(--ruby-text);--sidebar-bg:#f8f5f5;--sidebar-text:var(--ruby-text-light);--sidebar-link-active-bg:#f8e7e7;--sidebar-link-active-text:var(--ruby-primary);--link-color:var(--ruby-primary);--border-color:var(--ruby-border);--code-bg:var(--ruby-primary-light);--code-text:var(--ruby-primary-dark);--header-bg:var(--ruby-background);--header-border:var(--ruby-border);--shadow-sm:0 2px 4px rgba(179, 0, 0, 0.05);--shadow-md:0 4px 8px rgba(179, 0, 0, 0.1);--shadow-lg:0 8px 16px rgba(179, 0, 0, 0.15);--image-border-color:var(--ruby-border);--image-shadow:var(--shadow-md);--image-caption-bg:var(--ruby-background-alt);--image-caption-text:var(--ruby-text-light);--image-hover-transform:translateY(-3px);--image-hover-shadow:var(--shadow-lg);--image-border-radius:6px;--image-transition:all 0.3s ease}:root[data-theme=dark]{--ruby-primary:#ff5252;--ruby-primary-light:#3c1a1a;--ruby-primary-dark:#ff7b7b;--ruby-accent:#ce93d8;--ruby-accent-light:#2a1a2a;--ruby-text:#f0f0f0;--ruby-text-light:#c0c0c0;--ruby-text-lightest:#a0a0a0;--ruby-background:#1a0a0a;--ruby-background-alt:#2a1515;--ruby-border:#3a2020;--ruby-border-light:#2a1818;--bg-color:var(--ruby-background);--text-color:var(--ruby-text);--sidebar-bg:#1a0a0a;--sidebar-text:var(--ruby-text-light);--sidebar-link-active-bg:#2a1515;--sidebar-link-active-text:var(--ruby-primary);--link-color:var(--ruby-primary);--border-color:var(--ruby-border);--code-bg:var(--ruby-primary-light);--code-text:var(--ruby-text);--header-bg:var(--ruby-background);--header-border:var(--ruby-border);--shadow-sm:0 2px 4px rgba(0, 0, 0, 0.3);--shadow-md:0 4px 8px rgba(0, 0, 0, 0.4);--shadow-lg:0 8px 16px rgba(0, 0, 0, 0.5);--image-border-color:var(--ruby-border);--image-shadow:0 4px 8px rgba(0, 0, 0, 0.5);--image-caption-bg:var(--ruby-background-alt);--image-caption-text:var(--ruby-text-light);--image-hover-transform:translateY(-3px);--image-hover-shadow:0 6px 12px rgba(0, 0, 0, 0.7);--image-border-radius:6px;--image-transition:all 0.3s ease}body{font-family:var(--ruby-font-family-sans);line-height:1.7;letter-spacing:.01em}.callout-title,.card .card-title,.steps h4,figure.polaroid figcaption,h1,h2,h3,h4,h5,h6{font-family:var(--ruby-font-family-serif)}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.3;margin-top:2em;margin-bottom:.7em;color:var(--ruby-text);letter-spacing:-.01em}h1{font-size:2.5rem;font-weight:700;margin-top:0}h1::after{content:"";bottom:0;width:60px;height:3px;border-radius:3px}h2{font-size:1.9rem;border-bottom:1px solid var(--ruby-border-light)}h3{font-size:1.6rem}h4{font-size:1.3rem}a{color:var(--link-color);text-decoration:none;transition:color .2s}.content-area a:not(.button):not(.no-underline)::after{content:"";width:100%;height:1px;bottom:0;transform:scaleX(0);transform-origin:right bottom;transition:transform .3s}.content-area a:not(.button):not(.no-underline):hover::after{transform:scaleX(1);transform-origin:left bottom}p{margin:.7em 0;padding:.3em 0;line-height:1.8}.sidebar{border-right:1px solid var(--ruby-border)}.sidebar-header{margin-bottom:1.5rem;padding-bottom:1rem}.sidebar nav li a{border-radius:4px;margin-bottom:3px;transition:.3s;padding:.6rem .8rem;font-weight:400}.sidebar nav li a:hover{background-color:var(--sidebar-link-active-bg);transform:translateX(3px)}.sidebar nav li a.active{background-color:var(--sidebar-link-active-bg);color:var(--sidebar-link-active-text);font-weight:600}.content-area{padding:2.5rem 5%}pre{background-color:var(--code-bg);border-radius:6px;padding:1.25em}code{font-family:var(--ruby-font-family-mono);font-size:.9em;border-radius:4px;padding:.2em .4em}.docmd-container,table{border-radius:6px;overflow:hidden}table{width:100%;border-collapse:separate;border-spacing:0px}th{background-color:var(--ruby-primary-light);text-align:left;font-weight:600}td{border-top:1px solid var(--ruby-border-light)}tr:hover{background-color:var(--ruby-background-alt)}.docmd-container{padding:1.2rem 1.5rem;margin:1.75rem 0;border:1px solid var(--ruby-border-light);background-color:var(--ruby-background)}.docmd-container::before{content:"";top:0;width:100%;height:3px}.docmd-container.steps::before{height:initial!important}.callout{border-width:medium medium medium 4px;border-style:none none none solid;border-color:currentcolor;border-image:none;background-color:var(--ruby-background-alt)}.callout-title{font-weight:600;margin-bottom:.75em;display:flex;align-items:center;font-size:1.1em}.callout-title::before{margin-right:.5rem;font-size:1.1em}.callout-info{border-left-color:var(--ruby-primary)}.callout-warning{border-left-color:#f39c12}.callout-warning .callout-title{color:#f39c12}.callout-success,.callout-tip{border-left-color:#2ecc71}.callout-success .callout-title,.callout-tip .callout-title{color:#2ecc71}.callout-danger{border-left-color:#e74c3c}.callout-danger .callout-title{color:#e74c3c}.card{border:none;border-radius:6px;background:linear-gradient(135deg,var(--ruby-background) 0,var(--ruby-background-alt) 100%);box-shadow:var(--shadow-md);transition:.3s;overflow:hidden}.button,.steps h4::before,button{background:linear-gradient(135deg,var(--ruby-primary) 0,var(--ruby-accent) 100%);font-weight:600;box-shadow:var(--shadow-sm)}.card:hover{transform:translateY(-5px);box-shadow:var(--shadow-lg)}.card .card-title{font-weight:600;margin:0;background:linear-gradient(90deg,var(--ruby-primary-light),var(--ruby-accent-light));color:var(--ruby-primary-dark);border-bottom:1px solid var(--ruby-border)}.steps{counter-reset:step-counter 0;padding-left:1rem}.steps h4{padding-left:2.5rem;margin-top:2rem;margin-bottom:1rem}.steps h4::before{content:counter(step-counter);counter-increment:step-counter 1;position:absolute;left:0;top:50%;transform:translateY(-50%);width:1.8rem;height:1.8rem;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.9rem}.button,button{color:#fff;border:none;padding:.6rem 1.2rem;border-radius:4px;cursor:pointer;transition:.3s}.image-gallery figcaption,figcaption{background-color:var(--image-caption-bg);color:var(--image-caption-text)}figure,img{transition:var(--image-transition)}.docmd-button:hover{color:#fff}.button:hover,button:hover{box-shadow:var(--shadow-md);transform:translateY(-2px)}figure:hover,img.with-shadow:hover{transform:var(--image-hover-transform)}.theme-toggle-button{background:0 0;color:var(--ruby-text-light);box-shadow:none}.theme-toggle-button:hover{background:var(--ruby-background-alt);color:var(--ruby-primary);box-shadow:var(--shadow-sm);transform:translateY(0)}img{height:auto;border-radius:var(--image-border-radius)}img.with-border{border:1px solid var(--image-border-color);padding:4px}.image-gallery figure,figure img{border-radius:var(--image-border-radius)}img.with-shadow{box-shadow:var(--image-shadow)}img.with-shadow:hover{box-shadow:var(--image-hover-shadow)}figure{margin:1.5em 0;text-align:center}figcaption{padding:.5em;font-size:.9em;border-radius:0 0 var(--image-border-radius) var(--image-border-radius);font-style:italic}.image-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:1rem;margin:1.5em 0}.image-gallery figure{margin:0;height:100%;display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shadow-sm)}.image-gallery figure:hover{box-shadow:var(--shadow-md)}.image-gallery img{width:100%;height:100%;object-fit:cover;border-radius:var(--image-border-radius) var(--image-border-radius) 0 0}.image-gallery figcaption{padding:.5rem;font-size:.85rem;border-radius:0}.image-gallery.zoom figure:hover img{transform:scale(1.05)}img.lightbox{cursor:zoom-in}img.framed{border:8px solid #fff;box-shadow:0 0 0 1px var(--ruby-border),var(--shadow-md);border-radius:3px}figure.polaroid{background:#fff;padding:10px 10px 20px;box-shadow:var(--shadow-md);border-radius:3px}figure.polaroid img{border-radius:2px}figure.polaroid figcaption{background:#fff;color:var(--ruby-text);font-style:italic}@media (max-width:768px){.content-area{padding:1.5rem 1rem}h1{font-size:2rem}h2{font-size:1.6rem}h3{font-size:1.3rem}.image-gallery{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}.image-gallery img{height:120px}}.page-header{border-bottom:1px solid var(--ruby-border)}
|
|
@@ -3,6 +3,79 @@
|
|
|
3
3
|
/*
|
|
4
4
|
* Main client-side script for docmd UI interactions
|
|
5
5
|
*/
|
|
6
|
+
// --- Collapsible Navigation Logic ---
|
|
7
|
+
function initializeCollapsibleNav() {
|
|
8
|
+
const nav = document.querySelector('.sidebar-nav');
|
|
9
|
+
if (!nav) return;
|
|
10
|
+
|
|
11
|
+
let navStates = {};
|
|
12
|
+
try {
|
|
13
|
+
// Use sessionStorage to remember state only for the current session
|
|
14
|
+
navStates = JSON.parse(sessionStorage.getItem('docmd-nav-states')) || {};
|
|
15
|
+
} catch (e) { /* silent fail */ }
|
|
16
|
+
|
|
17
|
+
nav.querySelectorAll('li.collapsible').forEach(item => {
|
|
18
|
+
const navId = item.dataset.navId;
|
|
19
|
+
const anchor = item.querySelector('a');
|
|
20
|
+
const submenu = item.querySelector('.submenu');
|
|
21
|
+
|
|
22
|
+
if (!navId || !anchor || !submenu) return;
|
|
23
|
+
|
|
24
|
+
const isParentActive = item.classList.contains('active-parent');
|
|
25
|
+
// Default to expanded if it's a parent of the active page, otherwise check stored state.
|
|
26
|
+
let isExpanded = isParentActive || (navStates[navId] === true);
|
|
27
|
+
|
|
28
|
+
const toggleSubmenu = (expand) => {
|
|
29
|
+
item.setAttribute('aria-expanded', expand);
|
|
30
|
+
submenu.style.display = expand ? 'block' : 'none';
|
|
31
|
+
navStates[navId] = expand;
|
|
32
|
+
sessionStorage.setItem('docmd-nav-states', JSON.stringify(navStates));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Set initial state on page load
|
|
36
|
+
toggleSubmenu(isExpanded);
|
|
37
|
+
|
|
38
|
+
anchor.addEventListener('click', (e) => {
|
|
39
|
+
// If the click target is the icon, ALWAYS prevent navigation and toggle.
|
|
40
|
+
if (e.target.closest('.collapse-icon')) {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
toggleSubmenu(item.getAttribute('aria-expanded') !== 'true');
|
|
43
|
+
}
|
|
44
|
+
// If the link is just a placeholder, also prevent navigation and toggle.
|
|
45
|
+
else if (anchor.getAttribute('href') === '#') {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
toggleSubmenu(item.getAttribute('aria-expanded') !== 'true');
|
|
48
|
+
}
|
|
49
|
+
// Otherwise, let the click proceed to navigate to the link.
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// --- Sidebar Scroll Preservation ---
|
|
55
|
+
function initializeSidebarScroll() {
|
|
56
|
+
const sidebar = document.querySelector('.sidebar');
|
|
57
|
+
if (!sidebar) return;
|
|
58
|
+
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
const activeElement = sidebar.querySelector('a.active') || sidebar.querySelector('.active-parent > a');
|
|
61
|
+
|
|
62
|
+
if (activeElement) {
|
|
63
|
+
const sidebarRect = sidebar.getBoundingClientRect();
|
|
64
|
+
const elementRect = activeElement.getBoundingClientRect();
|
|
65
|
+
|
|
66
|
+
// Check if the element's top or bottom is outside the sidebar's visible area
|
|
67
|
+
const isNotInView = elementRect.top < sidebarRect.top || elementRect.bottom > sidebarRect.bottom;
|
|
68
|
+
|
|
69
|
+
if (isNotInView) {
|
|
70
|
+
activeElement.scrollIntoView({
|
|
71
|
+
behavior: 'auto',
|
|
72
|
+
block: 'center',
|
|
73
|
+
inline: 'nearest'
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, 10);
|
|
78
|
+
}
|
|
6
79
|
|
|
7
80
|
// --- Theme Toggle Logic ---
|
|
8
81
|
function setupThemeToggleListener() {
|
|
@@ -154,4 +227,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
154
227
|
initializeSidebarToggle();
|
|
155
228
|
initializeTabs();
|
|
156
229
|
initializeCopyCodeButtons();
|
|
230
|
+
initializeCollapsibleNav();
|
|
231
|
+
initializeSidebarScroll();
|
|
157
232
|
});
|
package/src/commands/build.js
CHANGED
|
@@ -221,25 +221,24 @@ async function buildSite(configPath, options = { isDev: false, preserve: false,
|
|
|
221
221
|
const depth = outputHtmlPath.split(path.sep).length - 1;
|
|
222
222
|
const relativePathToRoot = depth > 0 ? '../'.repeat(depth) : './';
|
|
223
223
|
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (dirPath === '.') {
|
|
230
|
-
currentPagePathForNav = 'index.html';
|
|
231
|
-
normalizedPath = '/';
|
|
232
|
-
} else {
|
|
233
|
-
currentPagePathForNav = dirPath + '/';
|
|
234
|
-
normalizedPath = '/' + dirPath;
|
|
224
|
+
let normalizedPath = path.relative(SRC_DIR, filePath).replace(/\\/g, '/');
|
|
225
|
+
if (path.basename(normalizedPath) === 'index.md') {
|
|
226
|
+
normalizedPath = path.dirname(normalizedPath);
|
|
227
|
+
if (normalizedPath === '.') {
|
|
228
|
+
normalizedPath = '';
|
|
235
229
|
}
|
|
236
230
|
} else {
|
|
237
|
-
|
|
238
|
-
currentPagePathForNav = pathWithoutExt + '/';
|
|
239
|
-
normalizedPath = '/' + pathWithoutExt;
|
|
231
|
+
normalizedPath = normalizedPath.replace(/\.md$/, '');
|
|
240
232
|
}
|
|
241
|
-
|
|
242
|
-
|
|
233
|
+
|
|
234
|
+
if (!normalizedPath.startsWith('/')) {
|
|
235
|
+
normalizedPath = '/' + normalizedPath;
|
|
236
|
+
}
|
|
237
|
+
if (normalizedPath.length > 1 && !normalizedPath.endsWith('/')) {
|
|
238
|
+
normalizedPath += '/';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const currentPagePathForNav = normalizedPath;
|
|
243
242
|
|
|
244
243
|
const navigationHtml = await generateNavigationHtml(
|
|
245
244
|
config.navigation,
|
package/src/commands/init.js
CHANGED
|
@@ -35,7 +35,7 @@ module.exports = {
|
|
|
35
35
|
name: 'sky', // Themes: 'default', 'sky'
|
|
36
36
|
defaultMode: 'light', // Initial color mode: 'light' or 'dark'
|
|
37
37
|
enableModeToggle: true, // Show UI button to toggle light/dark modes
|
|
38
|
-
positionMode: '
|
|
38
|
+
positionMode: 'top', // 'top' or 'bottom' for the theme toggle
|
|
39
39
|
codeHighlight: true, // Enable/disable codeblock highlighting and import of highlight.js
|
|
40
40
|
customCss: [ // Array of paths to custom CSS files
|
|
41
41
|
// '/assets/css/custom.css', // Custom TOC styles
|
|
@@ -96,6 +96,7 @@ module.exports = {
|
|
|
96
96
|
title: 'Getting Started',
|
|
97
97
|
icon: 'rocket',
|
|
98
98
|
path: '#',
|
|
99
|
+
collapsible: true, // This makes the menu section collapsible
|
|
99
100
|
children: [
|
|
100
101
|
{ title: 'Documentation', path: 'https://docmd.mgks.dev', icon: 'scroll', external: true },
|
|
101
102
|
{ title: 'Installation', path: 'https://docmd.mgks.dev/getting-started/installation', icon: 'download', external: true },
|
|
@@ -51,6 +51,7 @@ function createMarkdownItInstance(config) {
|
|
|
51
51
|
md.use(markdown_it_task_lists);
|
|
52
52
|
md.use(markdown_it_abbr);
|
|
53
53
|
md.use(markdown_it_deflist);
|
|
54
|
+
md.use(headingIdPlugin);
|
|
54
55
|
|
|
55
56
|
// Register renderers for all containers
|
|
56
57
|
Object.keys(containers).forEach(containerName => {
|
|
@@ -184,8 +185,6 @@ const containers = {
|
|
|
184
185
|
// }
|
|
185
186
|
};
|
|
186
187
|
|
|
187
|
-
|
|
188
|
-
|
|
189
188
|
// Advanced container rule with proper nesting support
|
|
190
189
|
function advancedContainerRule(state, startLine, endLine, silent) {
|
|
191
190
|
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
@@ -660,21 +659,32 @@ const customImageRenderer = function(tokens, idx, options, env, self) {
|
|
|
660
659
|
|
|
661
660
|
// Add IDs to headings for anchor links, used by the Table of Contents.
|
|
662
661
|
const headingIdPlugin = (md) => {
|
|
663
|
-
const
|
|
662
|
+
const originalHeadingOpen = md.renderer.rules.heading_open || function(tokens, idx, options, env, self) {
|
|
664
663
|
return self.renderToken(tokens, idx, options);
|
|
665
664
|
};
|
|
666
|
-
|
|
665
|
+
|
|
666
|
+
md.renderer.rules.heading_open = function(tokens, idx, options, env, self) {
|
|
667
667
|
const token = tokens[idx];
|
|
668
668
|
const contentToken = tokens[idx + 1];
|
|
669
|
-
|
|
669
|
+
|
|
670
|
+
if (contentToken && contentToken.type === 'inline' && contentToken.content) {
|
|
670
671
|
const headingText = contentToken.content;
|
|
671
|
-
const id = headingText
|
|
672
|
-
|
|
672
|
+
const id = headingText
|
|
673
|
+
.toLowerCase()
|
|
674
|
+
.replace(/\s+/g, '-') // Replace spaces with -
|
|
675
|
+
.replace(/[^\w-]+/g, '') // Remove all non-word chars
|
|
676
|
+
.replace(/--+/g, '-') // Replace multiple - with single -
|
|
677
|
+
.replace(/^-+/, '') // Trim - from start of text
|
|
678
|
+
.replace(/-+$/, ''); // Trim - from end of text
|
|
679
|
+
|
|
680
|
+
if (id) {
|
|
681
|
+
token.attrSet('id', id);
|
|
682
|
+
}
|
|
673
683
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
}
|
|
677
|
-
|
|
684
|
+
|
|
685
|
+
return originalHeadingOpen(tokens, idx, options, env, self);
|
|
686
|
+
};
|
|
687
|
+
};
|
|
678
688
|
|
|
679
689
|
// ===================================================================
|
|
680
690
|
// --- SAFE CONTAINER WRAPPER (FOR SIMPLE CONTAINERS) ---
|
|
@@ -1,107 +1,78 @@
|
|
|
1
|
-
<%#
|
|
2
|
-
|
|
3
|
-
<%# renderIcon is passed from html-generator.js %>
|
|
4
|
-
|
|
5
|
-
<%
|
|
6
|
-
// Debug function - uncomment to troubleshoot paths
|
|
7
|
-
function debugNavPaths(item, itemPath, currentPath, isActive, isParentActive) {
|
|
8
|
-
console.log('\nDEBUG NAV ITEM:');
|
|
9
|
-
console.log(`Title: ${item.title}`);
|
|
10
|
-
console.log(`Path: ${item.path}`);
|
|
11
|
-
console.log(`Computed item path: ${itemPath}`);
|
|
12
|
-
console.log(`Current page path: ${currentPath}`);
|
|
13
|
-
console.log(`Is directly active: ${isActive}`);
|
|
14
|
-
console.log(`Is parent active: ${isParentActive}`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function renderNavItems(items, currentLevelPagePath, rootPath) { %>
|
|
1
|
+
<%# navigation.ejs - Renders the sidebar navigation %>
|
|
2
|
+
<nav class="sidebar-nav" aria-label="Main navigation">
|
|
18
3
|
<ul>
|
|
19
|
-
<%
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (item.icon) {
|
|
30
|
-
// Use custom class for nav icons for specific styling
|
|
31
|
-
iconHtml = renderIcon(item.icon, { class: 'nav-item-icon' });
|
|
4
|
+
<%
|
|
5
|
+
// A robust, centralized function to normalize navigation paths
|
|
6
|
+
function normalizePath(p) {
|
|
7
|
+
if (!p) return '#';
|
|
8
|
+
let path = p.replace(/\\/g, '/');
|
|
9
|
+
|
|
10
|
+
if (path.endsWith('index.md')) {
|
|
11
|
+
path = path.slice(0, -'index.md'.length);
|
|
12
|
+
} else {
|
|
13
|
+
path = path.replace(/\.md$/, '');
|
|
32
14
|
}
|
|
33
15
|
|
|
34
|
-
if (
|
|
35
|
-
itemHref = item.path; // Full URL for external links
|
|
36
|
-
// Use a Lucide icon like 'arrow-up-right' or 'external-link'
|
|
37
|
-
externalLinkIconHtml = renderIcon('arrow-up-right', { class: 'nav-external-icon', width: '0.8em', height: '0.8em' });
|
|
38
|
-
} else {
|
|
39
|
-
// Path normalization for internal links
|
|
40
|
-
let cleanPath = item.path.startsWith('/') ? item.path : '/' + item.path; // Ensure leading slash
|
|
16
|
+
if (!path.startsWith('/')) path = '/' + path;
|
|
41
17
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
18
|
+
if (path.length > 1 && !path.endsWith('/')) {
|
|
19
|
+
path += '/';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Handle root case where path might be "" after stripping index.md
|
|
23
|
+
if (path === '') path = '/';
|
|
24
|
+
|
|
25
|
+
return path;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Helper to check for active children recursively
|
|
29
|
+
function hasActiveChild(item, currentPagePath) {
|
|
30
|
+
if (!item.children || !Array.isArray(item.children)) return false;
|
|
31
|
+
return item.children.some(child => {
|
|
32
|
+
if (!child.path || child.external) return false;
|
|
33
|
+
const childPath = normalizePath(child.path);
|
|
34
|
+
if (currentPagePath === childPath) return true;
|
|
35
|
+
return hasActiveChild(child, currentPagePath);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
55
38
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
39
|
+
// Recursive function to render navigation items
|
|
40
|
+
function renderNav(items) {
|
|
41
|
+
if (!items || !Array.isArray(items)) return;
|
|
42
|
+
items.forEach(item => {
|
|
43
|
+
const isExternal = item.external || false;
|
|
44
|
+
let itemPath = item.path || '#';
|
|
60
45
|
|
|
61
|
-
|
|
62
|
-
if (cleanPath === '/') {
|
|
63
|
-
isActivePage = currentLevelPagePath === 'index.html';
|
|
64
|
-
isCurrentPageActive = isActivePage;
|
|
65
|
-
}
|
|
66
|
-
// Parent folder with index.md
|
|
67
|
-
else if (cleanPath.endsWith('/')) {
|
|
68
|
-
// Direct match for folder/index.html pages
|
|
69
|
-
const folderPath = cleanPath.substring(1, cleanPath.length - 1); // Remove leading / and trailing /
|
|
70
|
-
isActivePage = currentLevelPagePath === folderPath + '/';
|
|
71
|
-
isCurrentPageActive = isActivePage;
|
|
72
|
-
|
|
73
|
-
// Check if any children are active
|
|
74
|
-
// If current path starts with this item's path, it's a parent of the active page
|
|
75
|
-
if (!isActivePage && currentLevelPagePath.startsWith(normalizedItemPath)) {
|
|
76
|
-
isCurrentPageActive = true;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Regular page
|
|
80
|
-
else {
|
|
81
|
-
const pagePath = cleanPath.substring(1) + '/';
|
|
82
|
-
isActivePage = currentLevelPagePath === pagePath;
|
|
83
|
-
isCurrentPageActive = isActivePage;
|
|
84
|
-
}
|
|
85
|
-
// SIMPLIFIED ACTIVE STATE LOGIC - END
|
|
86
|
-
}
|
|
87
|
-
%>
|
|
88
|
-
<li class="<%= isCurrentPageActive ? 'active-parent' : '' %>">
|
|
89
|
-
<a href="<%= itemHref %>"
|
|
90
|
-
class="<%= isActivePage ? 'active' : '' %>"
|
|
91
|
-
<%- targetBlank %>>
|
|
92
|
-
<% if (iconHtml) { %><%- iconHtml %><% } %>
|
|
93
|
-
<span><%- item.title %></span> <%# Wrap title in span for styling if needed %>
|
|
94
|
-
<% if (externalLinkIconHtml) { %><%- externalLinkIconHtml %><% } %>
|
|
95
|
-
</a>
|
|
46
|
+
const normalizedItemPath = isExternal ? itemPath : normalizePath(itemPath);
|
|
96
47
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
</li>
|
|
101
|
-
<% }); %>
|
|
102
|
-
</ul>
|
|
103
|
-
<% } %>
|
|
48
|
+
const isActive = !isExternal && currentPagePath === normalizedItemPath;
|
|
49
|
+
const isParentOfActive = !isActive && hasActiveChild(item, currentPagePath);
|
|
50
|
+
const isCollapsible = item.children && item.collapsible;
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
|
|
52
|
+
const liClasses = [];
|
|
53
|
+
if (isActive) liClasses.push('active');
|
|
54
|
+
if (isParentOfActive) liClasses.push('active-parent');
|
|
55
|
+
if (isCollapsible) liClasses.push('collapsible');
|
|
56
|
+
|
|
57
|
+
const finalHref = isExternal ? item.path : (itemPath === '#' ? '#' : (relativePathToRoot + (item.path.startsWith('/') ? item.path.substring(1) : item.path)));
|
|
58
|
+
%>
|
|
59
|
+
<li class="<%= liClasses.join(' ') %>" <%- isCollapsible ? `data-nav-id="${item.path}"` : '' %>>
|
|
60
|
+
<a href="<%- finalHref %>" class="<%- isActive ? 'active' : '' %>" <%- isExternal ? 'target="_blank" rel="noopener"' : '' %>>
|
|
61
|
+
<% if (item.icon) { %> <%- renderIcon(item.icon) %> <% } %>
|
|
62
|
+
<span class="nav-item-title"><%= item.title %></span>
|
|
63
|
+
<% if (isCollapsible) { %> <%- renderIcon('chevron-right', { class: 'collapse-icon' }) %> <% } %>
|
|
64
|
+
<% if (isExternal) { %> <%- renderIcon('external-link', { class: 'nav-external-icon' }) %> <% } %>
|
|
65
|
+
</a>
|
|
66
|
+
<% if (item.children) { %>
|
|
67
|
+
<ul class="submenu">
|
|
68
|
+
<% renderNav(item.children); %>
|
|
69
|
+
</ul>
|
|
70
|
+
<% } %>
|
|
71
|
+
</li>
|
|
72
|
+
<%
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
renderNav(navItems);
|
|
76
|
+
%>
|
|
77
|
+
</ul>
|
|
107
78
|
</nav>
|