feat: compact programme selector
This commit is contained in:
parent
a0e9d2c042
commit
c723d46ebf
7 changed files with 81 additions and 27 deletions
|
|
@ -33,6 +33,7 @@ export default defineConfig({
|
|||
},
|
||||
favicon: '/favicon.ico',
|
||||
customCss: ['./src/styles/incognito.css'],
|
||||
routeMiddleware: ['./src/starlight-route-data.ts'],
|
||||
components: {
|
||||
Sidebar: './src/components/Sidebar.astro',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,9 +7,19 @@ const withBase = (path: string) => `${import.meta.env.BASE_URL.replace(/\/$/, ''
|
|||
---
|
||||
|
||||
<nav class="programme-switch" aria-label="Bachelor programme">
|
||||
<span class="programme-switch__label">Course information</span>
|
||||
<span class="programme-switch__label">Bachelor programme</span>
|
||||
<div class="programme-switch__links">
|
||||
<a href={withBase(targets.dataScience)} aria-current={active === 'data-science-and-ai' ? 'page' : undefined}>Data Science & AI</a>
|
||||
<a href={withBase(targets.computerScience)} aria-current={active === 'computer-science' ? 'page' : undefined}>Computer Science</a>
|
||||
<a
|
||||
href={withBase(targets.dataScience)}
|
||||
aria-label="Data Science & AI"
|
||||
title="Data Science & AI"
|
||||
aria-current={active === 'data-science-and-ai' ? 'page' : undefined}
|
||||
>DSAI</a>
|
||||
<a
|
||||
href={withBase(targets.computerScience)}
|
||||
aria-label="Computer Science"
|
||||
title="Computer Science"
|
||||
aria-current={active === 'computer-science' ? 'page' : undefined}
|
||||
>CS</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
import { defineMiddleware } from 'astro:middleware';
|
||||
import { filterResolvedSidebar } from './config/programme-navigation.mjs';
|
||||
|
||||
export const onRequest = defineMiddleware((context, next) => {
|
||||
try {
|
||||
const route = context.locals.starlightRoute;
|
||||
route.sidebar = filterResolvedSidebar(route.sidebar, context.url.pathname);
|
||||
} catch {
|
||||
// Non-Starlight routes such as the generated 404 page have no route data.
|
||||
}
|
||||
return next();
|
||||
});
|
||||
10
src/starlight-route-data.ts
Normal file
10
src/starlight-route-data.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineRouteMiddleware } from '@astrojs/starlight/route-data';
|
||||
import { filterResolvedSidebar } from './config/programme-navigation.mjs';
|
||||
|
||||
export const onRequest = defineRouteMiddleware((context, next) => {
|
||||
const base = import.meta.env.BASE_URL.replace(/\/$/, '');
|
||||
const pathname = context.url.pathname.replace(base, '');
|
||||
const route = context.locals.starlightRoute;
|
||||
route.sidebar = filterResolvedSidebar(route.sidebar, pathname);
|
||||
return next();
|
||||
});
|
||||
|
|
@ -134,7 +134,7 @@
|
|||
}
|
||||
|
||||
.programme-switch {
|
||||
padding: 0.75rem;
|
||||
padding: 0.625rem;
|
||||
margin: 0 0.5rem 0.75rem;
|
||||
border: 1px solid var(--sl-color-gray-5);
|
||||
border-radius: 0.6rem;
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
|
||||
.programme-switch__label {
|
||||
display: block;
|
||||
margin-bottom: 0.45rem;
|
||||
margin-bottom: 0.4rem;
|
||||
color: var(--sl-color-gray-2);
|
||||
font-size: var(--sl-text-xs);
|
||||
font-weight: 600;
|
||||
|
|
@ -151,25 +151,32 @@
|
|||
.programme-switch__links {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.35rem;
|
||||
gap: 0.2rem;
|
||||
padding: 0.2rem;
|
||||
border-radius: 0.45rem;
|
||||
background: var(--sl-color-gray-6);
|
||||
}
|
||||
|
||||
.programme-switch__links a {
|
||||
display: flex;
|
||||
min-height: 2.5rem;
|
||||
min-height: 2.25rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.35rem;
|
||||
border-radius: 0.4rem;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
padding: 0.3rem 0.5rem;
|
||||
border-radius: 0.35rem;
|
||||
color: var(--sl-color-gray-2);
|
||||
font-size: var(--sl-text-xs);
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.programme-switch__links a[aria-current='page'] {
|
||||
color: var(--sl-color-text-accent);
|
||||
background: var(--sl-color-accent-low);
|
||||
color: var(--incognito-light);
|
||||
background: var(--incognito-primary);
|
||||
font-weight: 700;
|
||||
box-shadow: inset 0 0 0 1px var(--sl-color-accent);
|
||||
box-shadow: var(--sl-shadow-sm);
|
||||
}
|
||||
|
||||
.programme-switch__links a:focus-visible {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ async function collectCss(directory) {
|
|||
return chunks.join('\n');
|
||||
}
|
||||
|
||||
test('subpath production build includes the local consent controller and its UI styles', async () => {
|
||||
test('subpath production build includes local UI assets and focused programme navigation', async () => {
|
||||
const output = await mkdtemp(join(process.cwd(), '.matomo-build-'));
|
||||
try {
|
||||
await execFileAsync('node_modules/.bin/astro', ['build', '--outDir', output], {
|
||||
|
|
@ -40,6 +40,32 @@ test('subpath production build includes the local consent controller and its UI
|
|||
assert.equal(scripts[0].hasAttribute('defer'), true);
|
||||
await access(join(output, 'matomo-consent.js'));
|
||||
|
||||
const computerScienceHtml = await readFile(join(output, 'computer-science/index.html'), 'utf8');
|
||||
const { document: computerScienceDocument } = parseHTML(computerScienceHtml);
|
||||
const computerScienceSidebar = computerScienceDocument.querySelector('#starlight__sidebar');
|
||||
assert.ok(computerScienceSidebar);
|
||||
assert.match(computerScienceSidebar.textContent, /Home/);
|
||||
assert.match(computerScienceSidebar.textContent, /Previous exams and documents/);
|
||||
assert.match(computerScienceSidebar.textContent, /Computer Science/);
|
||||
assert.match(computerScienceSidebar.textContent, /Useful Information/);
|
||||
assert.doesNotMatch(computerScienceSidebar.textContent, /About Incognito/);
|
||||
assert.doesNotMatch(computerScienceSidebar.textContent, /Data Science & AI/);
|
||||
assert.doesNotMatch(computerScienceSidebar.textContent, /Master AI/);
|
||||
assert.doesNotMatch(computerScienceSidebar.textContent, /Master DSDM/);
|
||||
|
||||
const dataScienceHtml = await readFile(join(output, 'data-science-and-ai/index.html'), 'utf8');
|
||||
const { document: dataScienceDocument } = parseHTML(dataScienceHtml);
|
||||
const dataScienceSidebar = dataScienceDocument.querySelector('#starlight__sidebar');
|
||||
assert.ok(dataScienceSidebar);
|
||||
assert.match(dataScienceSidebar.textContent, /Home/);
|
||||
assert.match(dataScienceSidebar.textContent, /Previous exams and documents/);
|
||||
assert.match(dataScienceSidebar.textContent, /Data Science & AI/);
|
||||
assert.match(dataScienceSidebar.textContent, /Useful Information/);
|
||||
assert.doesNotMatch(dataScienceSidebar.textContent, /About Incognito/);
|
||||
assert.doesNotMatch(dataScienceSidebar.textContent, /Computer Science/);
|
||||
assert.doesNotMatch(dataScienceSidebar.textContent, /Master AI/);
|
||||
assert.doesNotMatch(dataScienceSidebar.textContent, /Master DSDM/);
|
||||
|
||||
const css = await collectCss(output);
|
||||
assert.match(css, /#incognito-analytics-consent/);
|
||||
assert.match(css, /\.incognito-consent-action/);
|
||||
|
|
|
|||
|
|
@ -10,3 +10,15 @@ test('Sidebar override renders an accessible no-JavaScript programme switch', as
|
|||
assert.doesNotMatch(component, /client:|<script/);
|
||||
assert.match(wrapper, /@astrojs\/starlight\/components\/Sidebar\.astro/);
|
||||
});
|
||||
|
||||
test('programme switch uses compact visible labels with full accessible names', async () => {
|
||||
const component = await readFile('src/components/ProgrammeSwitch.astro', 'utf8');
|
||||
assert.match(component, />DSAI<\/a>/);
|
||||
assert.match(component, />CS<\/a>/);
|
||||
assert.match(component, /aria-label="Data Science & AI"/);
|
||||
assert.match(component, /aria-label="Computer Science"/);
|
||||
assert.match(component, /title="Data Science & AI"/);
|
||||
assert.match(component, /title="Computer Science"/);
|
||||
assert.match(component, />Bachelor programme<\/span>/);
|
||||
assert.doesNotMatch(component, />Course information<\/span>/);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue