@f5-sales-demo/docs-theme 4.8.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MobileMenuFooter from 'virtual:starlight/components/MobileMenuFooter';
|
|
3
|
+
import SidebarPersister from '@astrojs/starlight/components/SidebarPersister.astro';
|
|
4
|
+
import SidebarSublist from '@astrojs/starlight/components/SidebarSublist.astro';
|
|
5
|
+
import SidebarRestorePoint from '@astrojs/starlight/components/SidebarRestorePoint.astro';
|
|
6
|
+
|
|
7
|
+
const { sidebar } = Astro.locals.starlightRoute;
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<SidebarPersister>
|
|
11
|
+
<ul class="canada-sidebar">
|
|
12
|
+
{sidebar.map((entry) => {
|
|
13
|
+
if (entry.type === 'link') {
|
|
14
|
+
return <li><a class="home-link" href={entry.href} aria-current={entry.isCurrent ? 'page' : undefined}>{entry.label}</a></li>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const [overview, ...children] = entry.entries;
|
|
18
|
+
if (!overview || overview.type !== 'link') {
|
|
19
|
+
return <li><SidebarSublist sublist={[entry]} /></li>;
|
|
20
|
+
}
|
|
21
|
+
const active = overview.isCurrent || children.some((child) => child.type === 'link' && child.isCurrent);
|
|
22
|
+
|
|
23
|
+
return <li class="stage">
|
|
24
|
+
<a class="stage-link" href={overview.href} aria-current={overview.isCurrent ? 'page' : undefined}>{entry.label}</a>
|
|
25
|
+
<details open={active || !entry.collapsed}>
|
|
26
|
+
<summary aria-label={`Toggle ${entry.label} pages`} title={`Toggle ${entry.label} pages`}><span class="caret" aria-hidden="true"></span></summary>
|
|
27
|
+
<SidebarRestorePoint />
|
|
28
|
+
<SidebarSublist sublist={children} nested />
|
|
29
|
+
</details>
|
|
30
|
+
</li>;
|
|
31
|
+
})}
|
|
32
|
+
</ul>
|
|
33
|
+
</SidebarPersister>
|
|
34
|
+
|
|
35
|
+
<div class="md:sl-hidden"><MobileMenuFooter /></div>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
@layer starlight.core {
|
|
39
|
+
.canada-sidebar { list-style: none; margin: 0; padding: 0; }
|
|
40
|
+
.canada-sidebar > li + li { margin-top: 0.5rem; }
|
|
41
|
+
.stage { position: relative; }
|
|
42
|
+
.home-link, .stage-link {
|
|
43
|
+
display: block;
|
|
44
|
+
border-radius: 0.25rem;
|
|
45
|
+
color: var(--sl-color-gray-2);
|
|
46
|
+
line-height: 1.4;
|
|
47
|
+
padding: 0.3em 2.5rem 0.3em 0.5rem;
|
|
48
|
+
text-decoration: none;
|
|
49
|
+
font-size: var(--sl-text-sm);
|
|
50
|
+
}
|
|
51
|
+
.stage-link { color: var(--sl-color-white); font-weight: 600; }
|
|
52
|
+
.home-link:hover, .home-link:focus, .stage-link:hover, .stage-link:focus { color: var(--sl-color-white); }
|
|
53
|
+
a[aria-current='page'], a[aria-current='page']:hover, a[aria-current='page']:focus {
|
|
54
|
+
color: var(--sl-color-text-invert);
|
|
55
|
+
background-color: var(--sl-color-text-accent);
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
}
|
|
58
|
+
summary {
|
|
59
|
+
position: absolute;
|
|
60
|
+
inset-block-start: 0;
|
|
61
|
+
inset-inline-end: 0;
|
|
62
|
+
display: grid;
|
|
63
|
+
place-items: center;
|
|
64
|
+
width: 2rem;
|
|
65
|
+
height: 2rem;
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
border-radius: 0.25rem;
|
|
68
|
+
list-style: none;
|
|
69
|
+
}
|
|
70
|
+
summary::-webkit-details-marker { display: none; }
|
|
71
|
+
summary:hover, summary:focus-visible { color: var(--sl-color-white); background: var(--sl-color-gray-5); }
|
|
72
|
+
.caret { width: 0.55rem; height: 0.55rem; border-block-start: 2px solid currentColor; border-inline-end: 2px solid currentColor; transform: rotate(45deg); transition: transform 0.2s ease; }
|
|
73
|
+
details[open] .caret { transform: rotate(135deg); }
|
|
74
|
+
:global([dir='rtl']) .caret { transform: rotate(225deg); }
|
|
75
|
+
:global([dir='rtl']) details[open] .caret { transform: rotate(135deg); }
|
|
76
|
+
}
|
|
77
|
+
</style>
|
package/config.ts
CHANGED
|
@@ -782,7 +782,7 @@ export function createF5xcDocsConfig(options: F5xcDocsConfigOptions = {}) {
|
|
|
782
782
|
starlightMegaMenu({ items: megaMenuItems, mobileLabels }),
|
|
783
783
|
starlightVideosPlugin(),
|
|
784
784
|
starlightImageZoom(),
|
|
785
|
-
f5xcDocsTheme(),
|
|
785
|
+
f5xcDocsTheme(githubRepository),
|
|
786
786
|
starlightScrollToTop({
|
|
787
787
|
showTooltip: true,
|
|
788
788
|
tooltipText: {
|
package/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
2
2
|
import { translations } from './src/i18n/translations.ts';
|
|
3
3
|
|
|
4
|
-
export default function f5xcDocsTheme(): StarlightPlugin {
|
|
4
|
+
export default function f5xcDocsTheme(repository = process.env.GITHUB_REPOSITORY || ''): StarlightPlugin {
|
|
5
5
|
return {
|
|
6
6
|
name: '@f5-sales-demo/docs-theme',
|
|
7
7
|
hooks: {
|
|
@@ -29,7 +29,11 @@ export default function f5xcDocsTheme(): StarlightPlugin {
|
|
|
29
29
|
? {
|
|
30
30
|
Sidebar: '@f5-sales-demo/docs-theme/components/ProviderSidebar.astro',
|
|
31
31
|
}
|
|
32
|
-
:
|
|
32
|
+
: repository === 'f5-sales-demo/canada'
|
|
33
|
+
? {
|
|
34
|
+
Sidebar: '@f5-sales-demo/docs-theme/components/CanadaSidebar.astro',
|
|
35
|
+
}
|
|
36
|
+
: {}),
|
|
33
37
|
Banner: '@f5-sales-demo/docs-theme/components/Banner.astro',
|
|
34
38
|
EditLink: '@f5-sales-demo/docs-theme/components/EditLink.astro',
|
|
35
39
|
Footer: '@f5-sales-demo/docs-theme/components/Footer.astro',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@f5-sales-demo/docs-theme",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0",
|
|
4
4
|
"description": "F5 Distributed Cloud branded Starlight documentation theme",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"./src/utils/localize-ecosystem-href.ts": "./src/utils/localize-ecosystem-href.ts",
|
|
44
44
|
"./canonical-route-middleware": "./canonical-route-middleware.ts",
|
|
45
45
|
"./components/ProviderSidebar.astro": "./components/ProviderSidebar.astro",
|
|
46
|
+
"./components/CanadaSidebar.astro": "./components/CanadaSidebar.astro",
|
|
46
47
|
"./components/ProviderHeader.astro": "./components/ProviderHeader.astro",
|
|
47
48
|
"./components/SharedHeader.astro": "./components/SharedHeader.astro",
|
|
48
49
|
"./assets/canada-flag.svg": "./assets/canada-flag.svg",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import f5xcDocsTheme from '../../index';
|
|
3
|
+
|
|
4
|
+
function configuredComponents(repository: string) {
|
|
5
|
+
const updateConfig = vi.fn();
|
|
6
|
+
const setup = f5xcDocsTheme(repository).hooks?.['config:setup'];
|
|
7
|
+
if (!setup) throw new Error('theme setup hook is missing');
|
|
8
|
+
setup({
|
|
9
|
+
config: { components: {} },
|
|
10
|
+
updateConfig,
|
|
11
|
+
addRouteMiddleware: vi.fn(),
|
|
12
|
+
logger: { info: vi.fn() },
|
|
13
|
+
} as never);
|
|
14
|
+
return updateConfig.mock.calls[0][0].components;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('Canada-only sidebar override', () => {
|
|
18
|
+
it('selects the linked stage sidebar for Canada', () => {
|
|
19
|
+
expect(configuredComponents('f5-sales-demo/canada').Sidebar).toBe(
|
|
20
|
+
'@f5-sales-demo/docs-theme/components/CanadaSidebar.astro',
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('leaves other repositories on their existing sidebar', () => {
|
|
25
|
+
expect(configuredComponents('f5-sales-demo/multi-cloud-networking')).not.toHaveProperty('Sidebar');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -19,21 +19,36 @@ describe('Canadian publication', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
describe('publication profile sidebar', () => {
|
|
22
|
-
it('
|
|
22
|
+
it('orders four linked stages and covers all 14 pages once', () => {
|
|
23
23
|
const sidebar = publicationSidebar('f5-sales-demo/canada', []);
|
|
24
|
-
expect(sidebar?.
|
|
25
|
-
const
|
|
26
|
-
expect(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
expect(sidebar?.[0]).toEqual({ slug: 'index' });
|
|
25
|
+
const stages = sidebar?.slice(1) ?? [];
|
|
26
|
+
expect(stages.map((stage) => ('label' in stage ? stage.label : ''))).toEqual([
|
|
27
|
+
'Design',
|
|
28
|
+
'Deploy',
|
|
29
|
+
'Verify',
|
|
30
|
+
'Operate',
|
|
31
|
+
]);
|
|
32
|
+
const expected = [
|
|
33
|
+
['design', 'use-case', 'architecture'],
|
|
34
|
+
['deploy', 'deployment', 'terraform'],
|
|
35
|
+
['verify', 'presentation', 'verification'],
|
|
36
|
+
['operate', 'troubleshooting', 'failover', 'teardown'],
|
|
37
|
+
];
|
|
38
|
+
const routes = ['index'];
|
|
39
|
+
stages.forEach((stage, index) => {
|
|
40
|
+
expect(stage).toMatchObject({ collapsed: true });
|
|
41
|
+
if (!('items' in stage)) throw new Error('Canada stage must have items');
|
|
42
|
+
const stageRoutes = stage.items.map((item) => {
|
|
43
|
+
if (!('slug' in item)) throw new Error('Canada stage item must be a page');
|
|
44
|
+
return item.slug;
|
|
45
|
+
});
|
|
46
|
+
expect(stageRoutes).toEqual(expected[index]);
|
|
47
|
+
routes.push(...stageRoutes);
|
|
33
48
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
expect(new Set(routes).size).toBe(14);
|
|
50
|
+
expect(routes).toHaveLength(14);
|
|
51
|
+
expect(stages.every((stage) => 'label' in stage && stage.label.split(/\s+/).length <= 3)).toBe(true);
|
|
37
52
|
});
|
|
38
53
|
it('preserves fallback navigation for every repository without a sidebar profile', () => {
|
|
39
54
|
const fallback = [{ label: 'Existing', slug: 'en/existing' }];
|
|
@@ -17,21 +17,25 @@ export const publicationProfiles: Record<string, PublicationProfile> = {
|
|
|
17
17
|
favicon: '/assets/canada-favicon.svg',
|
|
18
18
|
sidebar: [
|
|
19
19
|
{ slug: 'index' },
|
|
20
|
-
{ slug: 'use-case' },
|
|
21
20
|
{
|
|
22
|
-
label: '
|
|
21
|
+
label: 'Design',
|
|
23
22
|
collapsed: true,
|
|
24
|
-
items: [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
],
|
|
23
|
+
items: [{ slug: 'design' }, { slug: 'use-case' }, { slug: 'architecture' }],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Deploy',
|
|
27
|
+
collapsed: true,
|
|
28
|
+
items: [{ slug: 'deploy' }, { slug: 'deployment' }, { slug: 'terraform' }],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
label: 'Verify',
|
|
32
|
+
collapsed: true,
|
|
33
|
+
items: [{ slug: 'verify' }, { slug: 'presentation' }, { slug: 'verification' }],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: 'Operate',
|
|
37
|
+
collapsed: true,
|
|
38
|
+
items: [{ slug: 'operate' }, { slug: 'troubleshooting' }, { slug: 'failover' }, { slug: 'teardown' }],
|
|
35
39
|
},
|
|
36
40
|
],
|
|
37
41
|
},
|