@bndynet/vue-site 0.1.12 → 1.0.1

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.
@@ -4,5 +4,7 @@ export declare function maxNavDepth(items: ResolvedNavItem[]): number;
4
4
  export declare function subtreeContainsPath(item: ResolvedNavItem, path: string): boolean;
5
5
  /** First top-level item whose subtree contains `path` (fallback: first item). */
6
6
  export declare function findActiveTopLevelItem(items: ResolvedNavItem[], path: string): ResolvedNavItem | undefined;
7
+ /** True for absolute/external links (http(s), protocol-relative, mailto, tel). */
8
+ export declare function isExternalLink(url: string): boolean;
7
9
  /** First routable path in a subtree (for group targets). */
8
10
  export declare function getFirstLeafPath(item: ResolvedNavItem): string | null;
package/dist/router.d.ts CHANGED
@@ -1,3 +1,10 @@
1
- import { NavItem, ResolvedNavItem } from './types';
1
+ import { RouterHistory } from 'vue-router';
2
+ import { NavItem, ResolvedNavItem, StandalonePage } from './types';
3
+ /**
4
+ * Recursively drop nav items whose `visible()` predicate resolves to `false`. Sibling
5
+ * predicates are evaluated in parallel. A hidden parent removes its subtree; a group left
6
+ * with no children and no own `page`/`link` is pruned. Awaited once at startup.
7
+ */
8
+ export declare function filterNavItems(items: NavItem[]): Promise<NavItem[]>;
2
9
  export declare function resolveNavItems(items: NavItem[], parentIndex?: number): ResolvedNavItem[];
3
- export declare function createSiteRouter(resolvedNav: ResolvedNavItem[]): import('vue-router').Router;
10
+ export declare function createSiteRouter(resolvedNav: ResolvedNavItem[], pages?: StandalonePage[], history?: RouterHistory): Promise<import('vue-router').Router>;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .page-view[data-v-98336c56]{min-height:200px}.page-loading[data-v-98336c56]{display:flex;justify-content:center;padding:60px 0}.page-loading-dot[data-v-98336c56]{width:8px;height:8px;border-radius:50%;background:var(--color-link);animation:pulse-98336c56 1s ease-in-out infinite}@keyframes pulse-98336c56{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}.nav-item[data-v-03ee80b4]{display:flex;align-items:center;gap:10px;padding:9px 14px;margin-bottom:2px;border-radius:8px;color:var(--color-sidebar-text);font-size:.9rem;font-weight:500;text-decoration:none;transition:background-color .15s ease,color .15s ease}.nav-item--indent[data-v-03ee80b4]{padding-left:22px;font-size:.85rem}.nav-item[data-v-03ee80b4]:hover{background:var(--color-sidebar-item-hover);text-decoration:none}.nav-item--active[data-v-03ee80b4]{background:var(--color-sidebar-item-active);color:var(--color-sidebar-item-active-text)}.nav-item-label[data-v-03ee80b4]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nav-group-header[data-v-0faf5c71]{display:flex;align-items:center;gap:10px;width:100%;padding:9px 14px;margin-bottom:2px;border:none;border-radius:8px;background:none;color:var(--color-sidebar-text);font-size:.9rem;font-weight:500;cursor:pointer;text-align:left;transition:background-color .15s ease}.nav-group-header[data-v-0faf5c71]:hover{background:var(--color-sidebar-item-hover)}.nav-group-label[data-v-0faf5c71]{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nav-group-chevron[data-v-0faf5c71]{flex-shrink:0;transition:transform .2s ease;opacity:.5}.nav-group--expanded .nav-group-chevron[data-v-0faf5c71]{transform:rotate(90deg)}.nav-group-children[data-v-0faf5c71]{padding-left:8px}.tooltip-overlay[data-v-d0b5d0eb]{max-width:min(280px,calc(100vw - 16px));padding:6px 10px;font-size:.75rem;line-height:1.35;font-weight:500;color:var(--color-sidebar-text, #606770);background:var(--color-sidebar-bg, #f5f6f7);border:1px solid var(--color-sidebar-border, #ebedf0);border-radius:8px;box-shadow:0 4px 12px #0000001f,0 2px 4px #0000000f;pointer-events:none}.ui-tooltip[data-v-c96e8e51]{display:inline-flex;align-items:center;max-width:100%}.site-external-links[data-v-89ad5b4d]{display:flex;align-items:center;gap:6px}.site-external-link[data-v-89ad5b4d]{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border-radius:999px;text-decoration:none;cursor:pointer;background:transparent;color:var(--color-theme-switch-text);border:1px solid transparent;box-shadow:none;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease,color .2s ease}.site-external-link[data-v-89ad5b4d]:hover{background:var(--color-theme-switch-hover);border-color:color-mix(in srgb,var(--color-theme-switch-text) 16%,transparent);box-shadow:0 1px 2px #0000001a,0 6px 14px #00000014;text-decoration:none}.site-external-link[data-v-89ad5b4d]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-sidebar-bg),0 0 0 4px color-mix(in srgb,var(--color-link) 85%,transparent)}.site-external-links--compact .site-external-link[data-v-89ad5b4d]{width:28px;height:28px}.theme-switch[data-v-a636511b]{position:relative;display:inline-flex;flex-direction:column;align-items:center;width:fit-content;max-width:100%;color:var(--color-theme-switch-text)}.theme-switch summary[data-v-a636511b]{list-style:none}.theme-switch summary[data-v-a636511b]::-webkit-details-marker{display:none}.theme-switch-trigger[data-v-a636511b]{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border-radius:999px;cursor:pointer;background:transparent;color:var(--color-theme-switch-text);border:1px solid transparent;box-shadow:none;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease}.theme-switch-trigger[data-v-a636511b]:hover{background:var(--color-theme-switch-hover);border-color:color-mix(in srgb,var(--color-theme-switch-text) 16%,transparent);box-shadow:0 1px 2px #0000001a,0 6px 14px #00000014}.theme-switch-trigger[data-v-a636511b]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-sidebar-bg),0 0 0 4px color-mix(in srgb,var(--color-link) 85%,transparent)}.theme-switch-trigger-icon[data-v-a636511b]{display:flex;align-items:center;justify-content:center}.theme-switch-menu[data-v-a636511b]{position:absolute;left:50%;right:auto;top:calc(100% + 6px);transform:translate(-50%);z-index:40;display:flex;flex-direction:column;align-items:center;gap:4px;min-width:40px;padding:6px;border-radius:12px;background:var(--color-sidebar-bg);border:1px solid var(--color-sidebar-border);box-shadow:0 4px 12px #0000001f,0 12px 28px #0000001a}.theme-switch-option[data-v-a636511b]{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;margin:0;border:none;border-radius:999px;cursor:pointer;color:var(--color-sidebar-text);background:transparent;transition:background-color .15s ease}.theme-switch-option[data-v-a636511b]:hover{background:var(--color-sidebar-item-hover)}.theme-switch-option--active[data-v-a636511b]{background:var(--color-sidebar-item-active);color:var(--color-sidebar-item-active-text)}.theme-switch-option[data-v-a636511b]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-content-bg),0 0 0 4px color-mix(in srgb,var(--color-link) 85%,transparent)}.theme-switch--compact .theme-switch-trigger[data-v-a636511b]{width:28px;height:28px}.theme-switch--compact .theme-switch-menu[data-v-a636511b]{top:auto;bottom:calc(100% + 6px);transform:translate(-50%);padding:4px;gap:2px;border-radius:10px;box-shadow:0 -4px 12px #0000001a,0 -8px 24px #00000014}.theme-switch--compact .theme-switch-option[data-v-a636511b]{width:30px;height:30px}@media(prefers-reduced-motion:reduce){.theme-switch-trigger[data-v-a636511b]{transition:none}}.site-primary-nav-links[data-v-49be0e52]{display:flex;align-items:stretch;gap:0;min-width:0;flex:1;overflow-x:auto;padding:0;-webkit-overflow-scrolling:touch;scrollbar-width:thin}.site-primary-nav-link[data-v-49be0e52]{display:inline-flex;align-items:center;gap:8px;flex-shrink:0;padding:0 14px;border-radius:0;font-size:.9rem;font-weight:600;color:var(--color-sidebar-text);text-decoration:none;background:transparent;transition:background-color .15s ease,color .15s ease}.site-primary-nav-link[data-v-49be0e52]:hover{background:var(--color-sidebar-item-hover);text-decoration:none}.site-primary-nav-link--active[data-v-49be0e52]{background:var(--color-sidebar-item-active);color:var(--color-sidebar-item-active-text)}.site-primary-nav-link-label[data-v-49be0e52]{white-space:nowrap}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1.6;color:var(--color-text);background-color:var(--color-bg);transition:color .2s ease,background-color .2s ease}a{color:var(--color-link);text-decoration:none}a:hover{text-decoration:underline}img{max-width:100%;height:auto}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--color-scrollbar);border-radius:3px}:root{--site-top-nav-height: 48px;--site-sidebar-width: 200px}.site-layout{min-height:100vh}.site-layout--tiered-nav .site-sidebar{top:var(--site-top-nav-height);height:calc(100vh - var(--site-top-nav-height))}.site-layout--tiered-nav .site-content{margin-top:var(--site-top-nav-height)}.site-layout--tiered-no-sidebar .site-content{margin-left:0}.site-footer-standalone{margin-left:0;padding:1rem;text-align:center;border-top:1px solid var(--color-border);background:var(--color-content-bg);transition:background-color .2s ease}.site-primary-nav{position:fixed;top:0;left:0;right:0;z-index:21;display:flex;align-items:stretch;height:var(--site-top-nav-height);padding:0 12px 0 0;box-sizing:border-box;background:var(--color-sidebar-bg);border-bottom:1px solid var(--color-sidebar-border);transition:background-color .2s ease,border-color .2s ease}.site-primary-nav-end{display:flex;align-items:center;gap:6px;flex-shrink:0}.site-primary-nav-theme{flex-shrink:0}.site-primary-nav-brand{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:10px;flex:0 0 var(--site-sidebar-width);width:var(--site-sidebar-width);min-width:0;max-width:var(--site-sidebar-width);box-sizing:border-box;padding:0 12px;text-decoration:none;color:inherit}.site-primary-nav-brand:hover{text-decoration:none;opacity:.9}.site-primary-nav-logo{display:block;height:auto;max-height:32px;width:auto;max-width:100%;object-fit:contain}.site-primary-nav-title{min-width:0;font-size:1.05rem;font-weight:700;color:var(--color-sidebar-title);letter-spacing:-.01em;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.site-layout--tiered-nav .site-sidebar-nav{padding-top:12px}.site-sidebar-toolbar{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:6px;width:100%}.site-sidebar{position:fixed;top:0;left:0;width:var(--site-sidebar-width);height:100vh;background:var(--color-sidebar-bg);border-right:1px solid var(--color-sidebar-border);display:flex;flex-direction:column;overflow:hidden;z-index:10;transition:background-color .2s ease,border-color .2s ease}.site-sidebar-header{flex-shrink:0;padding:1rem 1rem .75rem;display:flex;justify-content:center}.site-sidebar-brand{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:10px;min-width:0;max-width:100%}.site-sidebar-logo{display:block;max-width:100%;height:auto;max-height:40px;width:auto;object-fit:contain}.site-sidebar-title{min-width:0;font-size:1.15rem;font-weight:700;color:var(--color-sidebar-title);letter-spacing:-.01em;line-height:1.25;text-align:center}.site-sidebar-nav{flex:1 1 auto;min-height:0;overflow-x:hidden;overflow-y:auto;padding:0 8px}.site-sidebar-footer{flex-shrink:0;padding:10px 12px 12px;border-top:1px solid var(--color-sidebar-border);display:flex;flex-direction:column;align-items:center;gap:10px}.site-footer-text{margin:0;font-size:.75rem;line-height:1.45;color:var(--color-text-secondary);white-space:pre-wrap;word-break:break-word;text-align:center}.site-content{margin-left:var(--site-sidebar-width);min-height:100vh;background:var(--color-content-bg);transition:background-color .2s ease}.site-content-inner{max-width:860px;margin:0 auto;padding:40px 48px}.markdown-body h1{font-size:2rem;font-weight:700;margin-bottom:.5rem;padding-bottom:.3rem;border-bottom:1px solid var(--color-border);color:var(--color-text)}.markdown-body h2{font-size:1.5rem;font-weight:600;margin-top:2rem;margin-bottom:.75rem;padding-bottom:.25rem;border-bottom:1px solid var(--color-border);color:var(--color-text)}.markdown-body h3{font-size:1.25rem;font-weight:600;margin-top:1.5rem;margin-bottom:.5rem;color:var(--color-text)}.markdown-body h4,.markdown-body h5,.markdown-body h6{font-size:1rem;font-weight:600;margin-top:1.25rem;margin-bottom:.5rem;color:var(--color-text)}.markdown-body p{margin-bottom:1rem;color:var(--color-text-secondary);line-height:1.75}.markdown-body ul,.markdown-body ol{margin-bottom:1rem;padding-left:2em;color:var(--color-text-secondary)}.markdown-body li{margin-bottom:.25rem}.markdown-body li>ul,.markdown-body li>ol{margin-bottom:0}.markdown-body code{font-family:SF Mono,Fira Code,Fira Mono,Menlo,Consolas,monospace;font-size:.875em;padding:.2em .4em;background:var(--color-code-bg);border-radius:4px;color:var(--color-code-text)}.markdown-body pre{margin-bottom:1.25rem;border-radius:8px;overflow-x:auto;border:1px solid var(--color-code-border)}.markdown-body pre code{display:block;padding:16px 20px;background:var(--color-code-block-bg);font-size:.85rem;line-height:1.6;border-radius:0}.markdown-body blockquote{margin-bottom:1rem;padding:12px 20px;border-left:4px solid var(--color-blockquote-border);background:var(--color-blockquote-bg);border-radius:0 6px 6px 0;color:var(--color-blockquote-text)}.markdown-body blockquote p:last-child{margin-bottom:0}.markdown-body table{width:100%;margin-bottom:1rem;border-collapse:collapse;border:1px solid var(--color-table-border)}.markdown-body th{background:var(--color-table-header-bg);padding:10px 14px;text-align:left;font-weight:600;border:1px solid var(--color-table-border);color:var(--color-text)}.markdown-body td{padding:10px 14px;border:1px solid var(--color-table-border);color:var(--color-text-secondary)}.markdown-body tr:hover td{background:var(--color-table-row-hover)}.markdown-body hr{margin:2rem 0;border:none;border-top:1px solid var(--color-border)}.markdown-body a{color:var(--color-link)}.markdown-body a:hover{color:var(--color-link-hover)}.markdown-body img{max-width:100%;border-radius:6px}.markdown-body strong{color:var(--color-text)}[data-theme=light] .hljs{color:#24292f;background:var(--color-code-block-bg)}[data-theme=light] .hljs-comment,[data-theme=light] .hljs-quote{color:#6a737d;font-style:italic}[data-theme=light] .hljs-keyword,[data-theme=light] .hljs-selector-tag,[data-theme=light] .hljs-type{color:#d73a49}[data-theme=light] .hljs-string,[data-theme=light] .hljs-addition{color:#032f62}[data-theme=light] .hljs-number,[data-theme=light] .hljs-literal{color:#005cc5}[data-theme=light] .hljs-built_in,[data-theme=light] .hljs-builtin-name,[data-theme=light] .hljs-title,[data-theme=light] .hljs-title.function_,[data-theme=light] .hljs-section{color:#6f42c1}[data-theme=light] .hljs-attr,[data-theme=light] .hljs-attribute{color:#005cc5}[data-theme=light] .hljs-variable,[data-theme=light] .hljs-template-variable{color:#e36209}[data-theme=light] .hljs-name,[data-theme=light] .hljs-tag{color:#22863a}[data-theme=light] .hljs-selector-class,[data-theme=light] .hljs-selector-id{color:#6f42c1}[data-theme=light] .hljs-deletion{color:#b31d28;background:#ffeef0}[data-theme=light] .hljs-addition{background:#f0fff4}[data-theme=light] .hljs-meta{color:#735c0f}[data-theme=light] .hljs-regexp{color:#032f62}[data-theme=light] .hljs-symbol{color:#005cc5}[data-theme=light] .hljs-params{color:#24292f}[data-theme=dark] .hljs{color:#e2e8f0;background:var(--color-code-block-bg)}[data-theme=dark] .hljs-comment,[data-theme=dark] .hljs-quote{color:#8b949e;font-style:italic}[data-theme=dark] .hljs-keyword,[data-theme=dark] .hljs-selector-tag,[data-theme=dark] .hljs-type{color:#ff7b72}[data-theme=dark] .hljs-string,[data-theme=dark] .hljs-addition{color:#a5d6ff}[data-theme=dark] .hljs-number,[data-theme=dark] .hljs-literal{color:#79c0ff}[data-theme=dark] .hljs-built_in,[data-theme=dark] .hljs-builtin-name,[data-theme=dark] .hljs-title,[data-theme=dark] .hljs-title.function_,[data-theme=dark] .hljs-section{color:#d2a8ff}[data-theme=dark] .hljs-attr,[data-theme=dark] .hljs-attribute{color:#79c0ff}[data-theme=dark] .hljs-variable,[data-theme=dark] .hljs-template-variable{color:#ffa657}[data-theme=dark] .hljs-name,[data-theme=dark] .hljs-tag{color:#7ee787}[data-theme=dark] .hljs-selector-class,[data-theme=dark] .hljs-selector-id{color:#d2a8ff}[data-theme=dark] .hljs-deletion{color:#ffdcd7;background:#67060c}[data-theme=dark] .hljs-addition{background:#0d4429}[data-theme=dark] .hljs-meta{color:#d29922}[data-theme=dark] .hljs-regexp{color:#a5d6ff}[data-theme=dark] .hljs-symbol{color:#79c0ff}[data-theme=dark] .hljs-params{color:#e2e8f0}:root{--el-bg-color-page: var(--color-bg);--el-bg-color: var(--color-content-bg);--el-bg-color-overlay: var(--color-content-bg);--el-text-color-primary: var(--color-text);--el-text-color-regular: var(--color-sidebar-text);--el-text-color-secondary: var(--color-text-secondary);--el-text-color-placeholder: color-mix(in srgb, var(--color-text-secondary) 70%, var(--color-bg));--el-text-color-disabled: color-mix(in srgb, var(--color-text-secondary) 50%, var(--color-bg));--el-border-color: var(--color-border);--el-border-color-light: color-mix(in srgb, var(--color-border) 70%, var(--color-bg));--el-border-color-lighter: color-mix(in srgb, var(--color-border) 50%, var(--color-bg));--el-border-color-extra-light: color-mix(in srgb, var(--color-border) 30%, var(--color-bg));--el-border-color-dark: color-mix(in srgb, var(--color-border) 80%, var(--color-text));--el-border-color-darker: color-mix(in srgb, var(--color-border) 60%, var(--color-text));--el-fill-color: var(--color-table-header-bg);--el-fill-color-light: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-bg));--el-fill-color-lighter: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-fill-color-extra-light: color-mix(in srgb, var(--color-table-header-bg) 30%, var(--color-bg));--el-fill-color-dark: color-mix(in srgb, var(--color-table-header-bg) 120%, var(--color-border));--el-fill-color-darker: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-border));--el-fill-color-blank: var(--color-bg);--el-table-header-bg-color: var(--color-table-header-bg);--el-table-tr-bg-color: var(--color-bg);--el-table-expanded-cell-bg-color: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-table-row-hover-bg-color: var(--color-table-row-hover);--el-menu-bg-color: var(--color-sidebar-bg);--el-menu-text-color: var(--color-sidebar-text);--el-menu-active-color: var(--color-link);--el-menu-hover-bg-color: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-fill: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-color: var(--color-text)}html.dark{--el-bg-color-page: var(--color-bg);--el-bg-color: var(--color-content-bg);--el-bg-color-overlay: var(--color-sidebar-bg);--el-text-color-primary: var(--color-text);--el-text-color-regular: var(--color-sidebar-text);--el-text-color-secondary: var(--color-text-secondary);--el-text-color-placeholder: color-mix(in srgb, var(--color-text-secondary) 70%, var(--color-bg));--el-text-color-disabled: color-mix(in srgb, var(--color-text-secondary) 50%, var(--color-bg));--el-border-color: var(--color-border);--el-border-color-light: color-mix(in srgb, var(--color-border) 70%, var(--color-bg));--el-border-color-lighter: color-mix(in srgb, var(--color-border) 50%, var(--color-bg));--el-border-color-extra-light: color-mix(in srgb, var(--color-border) 30%, var(--color-bg));--el-border-color-dark: color-mix(in srgb, var(--color-border) 80%, var(--color-text));--el-border-color-darker: color-mix(in srgb, var(--color-border) 60%, var(--color-text));--el-fill-color: var(--color-table-header-bg);--el-fill-color-light: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-bg));--el-fill-color-lighter: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-fill-color-extra-light: color-mix(in srgb, var(--color-table-header-bg) 30%, var(--color-bg));--el-fill-color-dark: color-mix(in srgb, var(--color-table-header-bg) 120%, var(--color-border));--el-fill-color-darker: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-border));--el-fill-color-blank: var(--color-bg);--el-table-header-bg-color: var(--color-table-header-bg);--el-table-tr-bg-color: var(--color-bg);--el-table-expanded-cell-bg-color: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-table-row-hover-bg-color: var(--color-table-row-hover);--el-menu-bg-color: var(--color-sidebar-bg);--el-menu-text-color: var(--color-sidebar-text);--el-menu-active-color: var(--color-link);--el-menu-hover-bg-color: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-fill: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-color: var(--color-text);--el-box-shadow: 0 12px 32px 4px rgba(0, 0, 0, .5), 0 8px 20px rgba(0, 0, 0, .6);--el-box-shadow-light: 0 0 12px rgba(0, 0, 0, .6);--el-box-shadow-lighter: 0 0 6px rgba(0, 0, 0, .5);--el-box-shadow-dark: 0 16px 48px 16px rgba(0, 0, 0, .7), 0 12px 32px rgba(0, 0, 0, .6);--el-mask-color: rgba(0, 0, 0, .8);--el-mask-color-extra-light: rgba(0, 0, 0, .3)}
1
+ .page-view[data-v-98336c56]{min-height:200px}.page-loading[data-v-98336c56]{display:flex;justify-content:center;padding:60px 0}.page-loading-dot[data-v-98336c56]{width:8px;height:8px;border-radius:50%;background:var(--color-link);animation:pulse-98336c56 1s ease-in-out infinite}@keyframes pulse-98336c56{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}.nav-item[data-v-a35b68cd]{display:flex;align-items:center;gap:10px;padding:9px 14px;margin-bottom:2px;border-radius:8px;color:var(--color-sidebar-text);font-size:.9rem;font-weight:500;text-decoration:none;transition:background-color .15s ease,color .15s ease}.nav-item--indent[data-v-a35b68cd]{padding-left:22px;font-size:.85rem}.nav-item[data-v-a35b68cd]:hover{background:var(--color-sidebar-item-hover);text-decoration:none}.nav-item--active[data-v-a35b68cd]{background:var(--color-sidebar-item-active);color:var(--color-sidebar-item-active-text)}.nav-item-label[data-v-a35b68cd]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nav-group-header[data-v-0faf5c71]{display:flex;align-items:center;gap:10px;width:100%;padding:9px 14px;margin-bottom:2px;border:none;border-radius:8px;background:none;color:var(--color-sidebar-text);font-size:.9rem;font-weight:500;cursor:pointer;text-align:left;transition:background-color .15s ease}.nav-group-header[data-v-0faf5c71]:hover{background:var(--color-sidebar-item-hover)}.nav-group-label[data-v-0faf5c71]{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nav-group-chevron[data-v-0faf5c71]{flex-shrink:0;transition:transform .2s ease;opacity:.5}.nav-group--expanded .nav-group-chevron[data-v-0faf5c71]{transform:rotate(90deg)}.nav-group-children[data-v-0faf5c71]{padding-left:8px}.tooltip-overlay[data-v-d0b5d0eb]{max-width:min(280px,calc(100vw - 16px));padding:6px 10px;font-size:.75rem;line-height:1.35;font-weight:500;color:var(--color-sidebar-text, #606770);background:var(--color-sidebar-bg, #f5f6f7);border:1px solid var(--color-sidebar-border, #ebedf0);border-radius:8px;box-shadow:0 4px 12px #0000001f,0 2px 4px #0000000f;pointer-events:none}.ui-tooltip[data-v-c96e8e51]{display:inline-flex;align-items:center;max-width:100%}.site-external-links[data-v-89ad5b4d]{display:flex;align-items:center;gap:6px}.site-external-link[data-v-89ad5b4d]{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border-radius:999px;text-decoration:none;cursor:pointer;background:transparent;color:var(--color-theme-switch-text);border:1px solid transparent;box-shadow:none;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease,color .2s ease}.site-external-link[data-v-89ad5b4d]:hover{background:var(--color-theme-switch-hover);border-color:color-mix(in srgb,var(--color-theme-switch-text) 16%,transparent);box-shadow:0 1px 2px #0000001a,0 6px 14px #00000014;text-decoration:none}.site-external-link[data-v-89ad5b4d]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-sidebar-bg),0 0 0 4px color-mix(in srgb,var(--color-link) 85%,transparent)}.site-external-links--compact .site-external-link[data-v-89ad5b4d]{width:28px;height:28px}.theme-switch[data-v-a636511b]{position:relative;display:inline-flex;flex-direction:column;align-items:center;width:fit-content;max-width:100%;color:var(--color-theme-switch-text)}.theme-switch summary[data-v-a636511b]{list-style:none}.theme-switch summary[data-v-a636511b]::-webkit-details-marker{display:none}.theme-switch-trigger[data-v-a636511b]{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border-radius:999px;cursor:pointer;background:transparent;color:var(--color-theme-switch-text);border:1px solid transparent;box-shadow:none;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease}.theme-switch-trigger[data-v-a636511b]:hover{background:var(--color-theme-switch-hover);border-color:color-mix(in srgb,var(--color-theme-switch-text) 16%,transparent);box-shadow:0 1px 2px #0000001a,0 6px 14px #00000014}.theme-switch-trigger[data-v-a636511b]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-sidebar-bg),0 0 0 4px color-mix(in srgb,var(--color-link) 85%,transparent)}.theme-switch-trigger-icon[data-v-a636511b]{display:flex;align-items:center;justify-content:center}.theme-switch-menu[data-v-a636511b]{position:absolute;left:50%;right:auto;top:calc(100% + 6px);transform:translate(-50%);z-index:40;display:flex;flex-direction:column;align-items:center;gap:4px;min-width:40px;padding:6px;border-radius:12px;background:var(--color-sidebar-bg);border:1px solid var(--color-sidebar-border);box-shadow:0 4px 12px #0000001f,0 12px 28px #0000001a}.theme-switch-option[data-v-a636511b]{display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;margin:0;border:none;border-radius:999px;cursor:pointer;color:var(--color-sidebar-text);background:transparent;transition:background-color .15s ease}.theme-switch-option[data-v-a636511b]:hover{background:var(--color-sidebar-item-hover)}.theme-switch-option--active[data-v-a636511b]{background:var(--color-sidebar-item-active);color:var(--color-sidebar-item-active-text)}.theme-switch-option[data-v-a636511b]:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-content-bg),0 0 0 4px color-mix(in srgb,var(--color-link) 85%,transparent)}.theme-switch--compact .theme-switch-trigger[data-v-a636511b]{width:28px;height:28px}.theme-switch--compact .theme-switch-menu[data-v-a636511b]{top:auto;bottom:calc(100% + 6px);transform:translate(-50%);padding:4px;gap:2px;border-radius:10px;box-shadow:0 -4px 12px #0000001a,0 -8px 24px #00000014}.theme-switch--compact .theme-switch-option[data-v-a636511b]{width:30px;height:30px}@media(prefers-reduced-motion:reduce){.theme-switch-trigger[data-v-a636511b]{transition:none}}.site-primary-nav-links[data-v-320c51ce]{display:flex;align-items:stretch;gap:0;min-width:0;flex:1;overflow-x:auto;padding:0;-webkit-overflow-scrolling:touch;scrollbar-width:thin}.site-primary-nav-link[data-v-320c51ce]{display:inline-flex;align-items:center;gap:8px;flex-shrink:0;padding:0 14px;border-radius:0;font-size:.9rem;font-weight:600;color:var(--color-sidebar-text);text-decoration:none;background:transparent;transition:background-color .15s ease,color .15s ease}.site-primary-nav-link[data-v-320c51ce]:hover{background:var(--color-sidebar-item-hover);text-decoration:none}.site-primary-nav-link--active[data-v-320c51ce]{background:var(--color-sidebar-item-active);color:var(--color-sidebar-item-active-text)}.site-primary-nav-link-label[data-v-320c51ce]{white-space:nowrap}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1.6;color:var(--color-text);background-color:var(--color-bg);transition:color .2s ease,background-color .2s ease}a{color:var(--color-link);text-decoration:none}a:hover{text-decoration:underline}img{max-width:100%;height:auto}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--color-scrollbar);border-radius:3px}:root{--site-top-nav-height: 48px;--site-sidebar-width: 200px}.site-layout{min-height:100vh}.site-layout--tiered-nav .site-sidebar{top:var(--site-top-nav-height);height:calc(100vh - var(--site-top-nav-height))}.site-layout--tiered-nav .site-content{margin-top:var(--site-top-nav-height)}.site-layout--tiered-no-sidebar .site-content{margin-left:0}.site-layout--blank .site-content{margin-left:0;margin-top:0}.site-layout--blank .site-content-inner{max-width:none;margin:0;padding:0}.site-footer-standalone{margin-left:0;padding:1rem;text-align:center;border-top:1px solid var(--color-border);background:var(--color-content-bg);transition:background-color .2s ease}.site-primary-nav{position:fixed;top:0;left:0;right:0;z-index:21;display:flex;align-items:stretch;height:var(--site-top-nav-height);padding:0 12px 0 0;box-sizing:border-box;background:var(--color-sidebar-bg);border-bottom:1px solid var(--color-sidebar-border);transition:background-color .2s ease,border-color .2s ease}.site-primary-nav-end{display:flex;align-items:center;gap:6px;flex-shrink:0}.site-primary-nav-theme{flex-shrink:0}.site-primary-nav-brand{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:10px;flex:0 0 var(--site-sidebar-width);width:var(--site-sidebar-width);min-width:0;max-width:var(--site-sidebar-width);box-sizing:border-box;padding:0 12px;text-decoration:none;color:inherit}.site-primary-nav-brand:hover{text-decoration:none;opacity:.9}.site-primary-nav-logo{display:block;height:auto;max-height:32px;width:auto;max-width:100%;object-fit:contain}.site-primary-nav-title{min-width:0;font-size:1.05rem;font-weight:700;color:var(--color-sidebar-title);letter-spacing:-.01em;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.site-layout--tiered-nav .site-sidebar-nav{padding-top:12px}.site-sidebar-toolbar{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:6px;width:100%}.site-sidebar{position:fixed;top:0;left:0;width:var(--site-sidebar-width);height:100vh;background:var(--color-sidebar-bg);border-right:1px solid var(--color-sidebar-border);display:flex;flex-direction:column;overflow:hidden;z-index:10;transition:background-color .2s ease,border-color .2s ease}.site-sidebar-header{flex-shrink:0;padding:1rem 1rem .75rem;display:flex;justify-content:center}.site-sidebar-brand{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:10px;min-width:0;max-width:100%}.site-sidebar-logo{display:block;max-width:100%;height:auto;max-height:40px;width:auto;object-fit:contain}.site-sidebar-title{min-width:0;font-size:1.15rem;font-weight:700;color:var(--color-sidebar-title);letter-spacing:-.01em;line-height:1.25;text-align:center}.site-sidebar-nav{flex:1 1 auto;min-height:0;overflow-x:hidden;overflow-y:auto;padding:0 8px}.site-sidebar-footer{flex-shrink:0;padding:10px 12px 12px;border-top:1px solid var(--color-sidebar-border);display:flex;flex-direction:column;align-items:center;gap:10px}.site-footer-text{margin:0;font-size:.75rem;line-height:1.45;color:var(--color-text-secondary);white-space:pre-wrap;word-break:break-word;text-align:center}.site-content{margin-left:var(--site-sidebar-width);min-height:100vh;background:var(--color-content-bg);transition:background-color .2s ease}.site-content-inner{max-width:860px;margin:0 auto;padding:40px 48px}.markdown-body h1{font-size:2rem;font-weight:700;margin-bottom:.5rem;padding-bottom:.3rem;border-bottom:1px solid var(--color-border);color:var(--color-text)}.markdown-body h2{font-size:1.5rem;font-weight:600;margin-top:2rem;margin-bottom:.75rem;padding-bottom:.25rem;border-bottom:1px solid var(--color-border);color:var(--color-text)}.markdown-body h3{font-size:1.25rem;font-weight:600;margin-top:1.5rem;margin-bottom:.5rem;color:var(--color-text)}.markdown-body h4,.markdown-body h5,.markdown-body h6{font-size:1rem;font-weight:600;margin-top:1.25rem;margin-bottom:.5rem;color:var(--color-text)}.markdown-body p{margin-bottom:1rem;color:var(--color-text-secondary);line-height:1.75}.markdown-body ul,.markdown-body ol{margin-bottom:1rem;padding-left:2em;color:var(--color-text-secondary)}.markdown-body li{margin-bottom:.25rem}.markdown-body li>ul,.markdown-body li>ol{margin-bottom:0}.markdown-body code{font-family:SF Mono,Fira Code,Fira Mono,Menlo,Consolas,monospace;font-size:.875em;padding:.2em .4em;background:var(--color-code-bg);border-radius:4px;color:var(--color-code-text)}.markdown-body pre{margin-bottom:1.25rem;border-radius:8px;overflow-x:auto;border:1px solid var(--color-code-border)}.markdown-body pre code{display:block;padding:16px 20px;background:var(--color-code-block-bg);font-size:.85rem;line-height:1.6;border-radius:0}.markdown-body blockquote{margin-bottom:1rem;padding:12px 20px;border-left:4px solid var(--color-blockquote-border);background:var(--color-blockquote-bg);border-radius:0 6px 6px 0;color:var(--color-blockquote-text)}.markdown-body blockquote p:last-child{margin-bottom:0}.markdown-body table{width:100%;margin-bottom:1rem;border-collapse:collapse;border:1px solid var(--color-table-border)}.markdown-body th{background:var(--color-table-header-bg);padding:10px 14px;text-align:left;font-weight:600;border:1px solid var(--color-table-border);color:var(--color-text)}.markdown-body td{padding:10px 14px;border:1px solid var(--color-table-border);color:var(--color-text-secondary)}.markdown-body tr:hover td{background:var(--color-table-row-hover)}.markdown-body hr{margin:2rem 0;border:none;border-top:1px solid var(--color-border)}.markdown-body a{color:var(--color-link)}.markdown-body a:hover{color:var(--color-link-hover)}.markdown-body img{max-width:100%;border-radius:6px}.markdown-body strong{color:var(--color-text)}[data-theme=light] .hljs{color:#24292f;background:var(--color-code-block-bg)}[data-theme=light] .hljs-comment,[data-theme=light] .hljs-quote{color:#6a737d;font-style:italic}[data-theme=light] .hljs-keyword,[data-theme=light] .hljs-selector-tag,[data-theme=light] .hljs-type{color:#d73a49}[data-theme=light] .hljs-string,[data-theme=light] .hljs-addition{color:#032f62}[data-theme=light] .hljs-number,[data-theme=light] .hljs-literal{color:#005cc5}[data-theme=light] .hljs-built_in,[data-theme=light] .hljs-builtin-name,[data-theme=light] .hljs-title,[data-theme=light] .hljs-title.function_,[data-theme=light] .hljs-section{color:#6f42c1}[data-theme=light] .hljs-attr,[data-theme=light] .hljs-attribute{color:#005cc5}[data-theme=light] .hljs-variable,[data-theme=light] .hljs-template-variable{color:#e36209}[data-theme=light] .hljs-name,[data-theme=light] .hljs-tag{color:#22863a}[data-theme=light] .hljs-selector-class,[data-theme=light] .hljs-selector-id{color:#6f42c1}[data-theme=light] .hljs-deletion{color:#b31d28;background:#ffeef0}[data-theme=light] .hljs-addition{background:#f0fff4}[data-theme=light] .hljs-meta{color:#735c0f}[data-theme=light] .hljs-regexp{color:#032f62}[data-theme=light] .hljs-symbol{color:#005cc5}[data-theme=light] .hljs-params{color:#24292f}[data-theme=dark] .hljs{color:#e2e8f0;background:var(--color-code-block-bg)}[data-theme=dark] .hljs-comment,[data-theme=dark] .hljs-quote{color:#8b949e;font-style:italic}[data-theme=dark] .hljs-keyword,[data-theme=dark] .hljs-selector-tag,[data-theme=dark] .hljs-type{color:#ff7b72}[data-theme=dark] .hljs-string,[data-theme=dark] .hljs-addition{color:#a5d6ff}[data-theme=dark] .hljs-number,[data-theme=dark] .hljs-literal{color:#79c0ff}[data-theme=dark] .hljs-built_in,[data-theme=dark] .hljs-builtin-name,[data-theme=dark] .hljs-title,[data-theme=dark] .hljs-title.function_,[data-theme=dark] .hljs-section{color:#d2a8ff}[data-theme=dark] .hljs-attr,[data-theme=dark] .hljs-attribute{color:#79c0ff}[data-theme=dark] .hljs-variable,[data-theme=dark] .hljs-template-variable{color:#ffa657}[data-theme=dark] .hljs-name,[data-theme=dark] .hljs-tag{color:#7ee787}[data-theme=dark] .hljs-selector-class,[data-theme=dark] .hljs-selector-id{color:#d2a8ff}[data-theme=dark] .hljs-deletion{color:#ffdcd7;background:#67060c}[data-theme=dark] .hljs-addition{background:#0d4429}[data-theme=dark] .hljs-meta{color:#d29922}[data-theme=dark] .hljs-regexp{color:#a5d6ff}[data-theme=dark] .hljs-symbol{color:#79c0ff}[data-theme=dark] .hljs-params{color:#e2e8f0}:root{--el-bg-color-page: var(--color-bg);--el-bg-color: var(--color-content-bg);--el-bg-color-overlay: var(--color-content-bg);--el-text-color-primary: var(--color-text);--el-text-color-regular: var(--color-sidebar-text);--el-text-color-secondary: var(--color-text-secondary);--el-text-color-placeholder: color-mix(in srgb, var(--color-text-secondary) 70%, var(--color-bg));--el-text-color-disabled: color-mix(in srgb, var(--color-text-secondary) 50%, var(--color-bg));--el-border-color: var(--color-border);--el-border-color-light: color-mix(in srgb, var(--color-border) 70%, var(--color-bg));--el-border-color-lighter: color-mix(in srgb, var(--color-border) 50%, var(--color-bg));--el-border-color-extra-light: color-mix(in srgb, var(--color-border) 30%, var(--color-bg));--el-border-color-dark: color-mix(in srgb, var(--color-border) 80%, var(--color-text));--el-border-color-darker: color-mix(in srgb, var(--color-border) 60%, var(--color-text));--el-fill-color: var(--color-table-header-bg);--el-fill-color-light: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-bg));--el-fill-color-lighter: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-fill-color-extra-light: color-mix(in srgb, var(--color-table-header-bg) 30%, var(--color-bg));--el-fill-color-dark: color-mix(in srgb, var(--color-table-header-bg) 120%, var(--color-border));--el-fill-color-darker: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-border));--el-fill-color-blank: var(--color-bg);--el-table-header-bg-color: var(--color-table-header-bg);--el-table-tr-bg-color: var(--color-bg);--el-table-expanded-cell-bg-color: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-table-row-hover-bg-color: var(--color-table-row-hover);--el-menu-bg-color: var(--color-sidebar-bg);--el-menu-text-color: var(--color-sidebar-text);--el-menu-active-color: var(--color-link);--el-menu-hover-bg-color: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-fill: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-color: var(--color-text)}html.dark{--el-bg-color-page: var(--color-bg);--el-bg-color: var(--color-content-bg);--el-bg-color-overlay: var(--color-sidebar-bg);--el-text-color-primary: var(--color-text);--el-text-color-regular: var(--color-sidebar-text);--el-text-color-secondary: var(--color-text-secondary);--el-text-color-placeholder: color-mix(in srgb, var(--color-text-secondary) 70%, var(--color-bg));--el-text-color-disabled: color-mix(in srgb, var(--color-text-secondary) 50%, var(--color-bg));--el-border-color: var(--color-border);--el-border-color-light: color-mix(in srgb, var(--color-border) 70%, var(--color-bg));--el-border-color-lighter: color-mix(in srgb, var(--color-border) 50%, var(--color-bg));--el-border-color-extra-light: color-mix(in srgb, var(--color-border) 30%, var(--color-bg));--el-border-color-dark: color-mix(in srgb, var(--color-border) 80%, var(--color-text));--el-border-color-darker: color-mix(in srgb, var(--color-border) 60%, var(--color-text));--el-fill-color: var(--color-table-header-bg);--el-fill-color-light: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-bg));--el-fill-color-lighter: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-fill-color-extra-light: color-mix(in srgb, var(--color-table-header-bg) 30%, var(--color-bg));--el-fill-color-dark: color-mix(in srgb, var(--color-table-header-bg) 120%, var(--color-border));--el-fill-color-darker: color-mix(in srgb, var(--color-table-header-bg) 80%, var(--color-border));--el-fill-color-blank: var(--color-bg);--el-table-header-bg-color: var(--color-table-header-bg);--el-table-tr-bg-color: var(--color-bg);--el-table-expanded-cell-bg-color: color-mix(in srgb, var(--color-table-header-bg) 50%, var(--color-bg));--el-table-row-hover-bg-color: var(--color-table-row-hover);--el-menu-bg-color: var(--color-sidebar-bg);--el-menu-text-color: var(--color-sidebar-text);--el-menu-active-color: var(--color-link);--el-menu-hover-bg-color: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-fill: var(--color-sidebar-item-hover);--el-dropdown-menuItem-hover-color: var(--color-text);--el-box-shadow: 0 12px 32px 4px rgba(0, 0, 0, .5), 0 8px 20px rgba(0, 0, 0, .6);--el-box-shadow-light: 0 0 12px rgba(0, 0, 0, .6);--el-box-shadow-lighter: 0 0 6px rgba(0, 0, 0, .5);--el-box-shadow-dark: 0 16px 48px 16px rgba(0, 0, 0, .7), 0 12px 32px rgba(0, 0, 0, .6);--el-mask-color: rgba(0, 0, 0, .8);--el-mask-color-extra-light: rgba(0, 0, 0, .3)}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,44 @@
1
1
  import { App, Component } from 'vue';
2
2
  import { UserConfig as ViteUserConfig } from 'vite';
3
+ import { RouteLocationNormalized } from 'vue-router';
4
+ /**
5
+ * Per-page authorization requirement. Attached to a `NavItem` / `StandalonePage` via `auth`
6
+ * and stored on the route's `meta`. It is opaque metadata interpreted by
7
+ * `SiteConfig.auth.authorize` — use `true` for "any authenticated user", a role name or list of
8
+ * roles, or a custom predicate. The framework never inspects the rule itself; it forwards it to
9
+ * `authorize`.
10
+ */
11
+ export type AuthRule = boolean | string | string[] | ((ctx: AuthContext) => boolean | Promise<boolean>);
12
+ /**
13
+ * Context passed to `SiteConfig.auth.authorize`. `to` / `from` are present when the guard runs
14
+ * during navigation; they are absent during the one-time startup pass that filters the nav menu.
15
+ */
16
+ export interface AuthContext {
17
+ /** The `auth` rule declared on the matched nav / standalone item. */
18
+ rule: AuthRule;
19
+ /** The resolved nav item being evaluated, when available. */
20
+ item?: ResolvedNavItem;
21
+ /** Target route (navigation-time only). */
22
+ to?: RouteLocationNormalized;
23
+ /** Previous route (navigation-time only). */
24
+ from?: RouteLocationNormalized;
25
+ }
26
+ /** Central authorization policy. Configure once in `site.config.ts`; pages opt in with `auth`. */
27
+ export interface AuthConfig {
28
+ /**
29
+ * Decide whether the current user may access a route carrying `rule`. Return `true` to allow,
30
+ * `false` to deny, or a path string to redirect (e.g. your login page). Runs at navigation time
31
+ * on every guarded route, and once at startup (with only `rule` / `item`) to filter the nav menu
32
+ * — there, any result other than `true` hides the item.
33
+ */
34
+ authorize: (ctx: AuthContext) => boolean | string | Promise<boolean | string>;
35
+ /**
36
+ * Where to send users when `authorize` returns `false`. The denied target is appended as a
37
+ * `redirect` query param (e.g. `/login?redirect=/admin`). If omitted, denied navigations are
38
+ * simply cancelled.
39
+ */
40
+ loginPath?: string;
41
+ }
3
42
  export interface NavItem {
4
43
  label: string;
5
44
  icon?: string;
@@ -10,6 +49,55 @@ export interface NavItem {
10
49
  }>);
11
50
  children?: NavItem[];
12
51
  path?: string;
52
+ /**
53
+ * Render this item as a plain hyperlink instead of a page route. Use an internal route path
54
+ * (e.g. `/landing` to point at a `pages` entry) or an external URL (e.g. `https://...`, opened
55
+ * in a new tab). When set, no `PageView` route is registered for this item and `page`/`children`
56
+ * are ignored for routing.
57
+ */
58
+ link?: string;
59
+ /**
60
+ * Optional visibility predicate, awaited once at app startup. Return `false` (or a
61
+ * promise resolving to `false`) to hide this item from navigation. Hidden items also
62
+ * get no route registered, so their pages are not reachable by direct URL. When an item
63
+ * has `children`, a hidden parent hides its whole subtree; a group whose children all
64
+ * become hidden is pruned. Evaluated only at startup, so it does not react to later
65
+ * permission changes (e.g. login/logout) without recreating the app.
66
+ */
67
+ visible?: () => boolean | Promise<boolean>;
68
+ /**
69
+ * Per-page authorization rule, interpreted by `SiteConfig.auth.authorize`. Unlike `visible`
70
+ * (a build/startup-time existence switch), `auth` keeps the route registered and is enforced by
71
+ * a navigation guard on every navigation, so it reacts to login/logout and can redirect to a
72
+ * login page. It is also evaluated once at startup to hide unauthorized items from the menu.
73
+ * Requires `SiteConfig.auth` to be set; otherwise it is ignored.
74
+ */
75
+ auth?: AuthRule;
76
+ }
77
+ /**
78
+ * A standalone, full-screen page registered outside the `nav` tree.
79
+ * Standalone pages do not appear in any navigation (no top bar, sidebar, or footer)
80
+ * and render only their content. Use for landing pages, login, embeds, etc.
81
+ */
82
+ export interface StandalonePage {
83
+ /** Route path (used as-is, no label-based derivation), e.g. `/landing`. */
84
+ path: string;
85
+ page: (() => Promise<{
86
+ default: string;
87
+ }>) | (() => Promise<{
88
+ default: Component;
89
+ }>);
90
+ /**
91
+ * Optional visibility predicate, awaited once at app startup. Return `false` (or a
92
+ * promise resolving to `false`) to skip registering this page's route entirely.
93
+ * Evaluated only at startup, so it does not react to later permission changes.
94
+ */
95
+ visible?: () => boolean | Promise<boolean>;
96
+ /**
97
+ * Per-page authorization rule, interpreted by `SiteConfig.auth.authorize` and enforced by a
98
+ * navigation guard. See `NavItem.auth`. Requires `SiteConfig.auth` to be set.
99
+ */
100
+ auth?: AuthRule;
13
101
  }
14
102
  /** CSS custom properties for one theme (`--color-bg`, etc.). */
15
103
  export type ThemePaletteVars = Record<string, string>;
@@ -51,6 +139,24 @@ export interface ThemeConfig {
51
139
  dark?: ThemePaletteVars;
52
140
  };
53
141
  }
142
+ /** Router history configuration. */
143
+ export interface RouterConfig {
144
+ /**
145
+ * History mode:
146
+ * - `'hash'` (default) — URLs use a `#` fragment (e.g. `/app/#/admin`). Works on any static host
147
+ * with no server config; route paths are independent of the public base.
148
+ * - `'web'` — HTML5 history with clean URLs (e.g. `/app/admin`). Requires the host to serve
149
+ * `index.html` for unknown paths (SPA fallback).
150
+ * @default 'hash'
151
+ */
152
+ mode?: 'hash' | 'web';
153
+ /**
154
+ * Base path for `'web'` mode (ignored for `'hash'`). Defaults to the app's public base
155
+ * (`import.meta.env.BASE_URL`, set by the CLI's `--base` / `env.vite.base`). Set this only to
156
+ * override that default (e.g. when calling `createSiteApp` from a custom entry).
157
+ */
158
+ base?: string;
159
+ }
54
160
  export type SiteViteConfig = Partial<Omit<ViteUserConfig, 'root'>> & {
55
161
  /** Options passed to @vitejs/plugin-vue (the Vue plugin is added automatically) */
56
162
  vue?: Record<string, any>;
@@ -85,6 +191,20 @@ export interface SiteConfig {
85
191
  title: string;
86
192
  logo?: string;
87
193
  nav: NavItem[];
194
+ /**
195
+ * Standalone, full-screen pages registered outside the `nav` tree. They do not appear in
196
+ * navigation and render with no top bar, sidebar, or footer (content only). The active theme
197
+ * still applies via root CSS variables.
198
+ */
199
+ pages?: StandalonePage[];
200
+ /**
201
+ * Central authorization policy. When set, any `NavItem` / `StandalonePage` carrying an `auth`
202
+ * rule is enforced by a navigation guard (redirecting to `auth.loginPath` on denial) and hidden
203
+ * from the nav menu at startup when not authorized. Omit to disable authorization entirely.
204
+ */
205
+ auth?: AuthConfig;
206
+ /** Router history configuration (hash vs HTML5). See `RouterConfig`. */
207
+ router?: RouterConfig;
88
208
  theme?: ThemeConfig;
89
209
  footer?: string;
90
210
  readme?: string;
@@ -95,6 +215,12 @@ export interface SiteConfig {
95
215
  * then site root). Injected by the `vue-site` CLI; omit when calling `createSiteApp` manually.
96
216
  */
97
217
  packageRepository?: string | null;
218
+ /**
219
+ * App public base path. Injected by the `vue-site` CLI from `import.meta.env.BASE_URL` (the
220
+ * resolved Vite `base`) and used as the default base for `'web'` history mode. Prefer setting
221
+ * `router.base` to override; omit when calling `createSiteApp` manually.
222
+ */
223
+ baseUrl?: string;
98
224
  /** Development / build environment configuration */
99
225
  env?: SiteEnvConfig;
100
226
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bndynet/vue-site",
3
- "version": "0.1.12",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "A configurable Vue 3 site framework with sidebar navigation, markdown rendering, and theme switching.",
6
6
  "repository": {