signature: add systems map, command palette and motion primitives

Ship the Signature UX as standalone, SSR-safe pieces: bilingual copy, a dual SVG/list systems map, a Map-backed command palette in the shell, opt-in reveal and metric primitives, and a leak-free decorative canvas.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-25 17:37:25 +02:00
parent 9ea2885c7b
commit 7813499ee3
25 changed files with 2902 additions and 73 deletions

View File

@@ -0,0 +1,277 @@
import { DOCUMENT } from '@angular/common';
import { ApplicationRef, PLATFORM_ID } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { provideRouter, Router } from '@angular/router';
import { SIGNATURE_COPY } from '../../core/content/signature-copy';
import { SITE_CONFIG } from '../../core/content/site-config';
import { APP_LOCALES, type AppLocale } from '../../core/i18n/locale';
import { LocaleService } from '../../core/i18n/locale.service';
import { NavigationService } from '../../core/navigation/navigation.service';
import { CommandPalette } from './command-palette';
import { COMMAND_IDS, COMMANDS } from './commands';
describe('CommandPalette', () => {
afterEach(() => {
vi.restoreAllMocks();
});
async function createFixture(
locale: AppLocale = 'de',
extraProviders: { provide: unknown; useValue: unknown }[] = [],
): Promise<ComponentFixture<CommandPalette>> {
TestBed.resetTestingModule();
await TestBed.configureTestingModule({
imports: [CommandPalette],
providers: [provideRouter([]), ...extraProviders],
}).compileComponents();
TestBed.inject(LocaleService).setLocale(locale);
const fixture = TestBed.createComponent(CommandPalette);
fixture.detectChanges();
await fixture.whenStable();
return fixture;
}
async function flush(fixture: ComponentFixture<CommandPalette>): Promise<void> {
fixture.detectChanges();
await fixture.whenStable();
TestBed.inject(ApplicationRef).tick();
fixture.detectChanges();
await fixture.whenStable();
}
function trigger(fixture: ComponentFixture<CommandPalette>): HTMLButtonElement {
return fixture.nativeElement.querySelector('.command-palette-trigger');
}
function dialog(fixture: ComponentFixture<CommandPalette>): HTMLElement | null {
return fixture.nativeElement.querySelector('[role="dialog"]');
}
async function openViaTrigger(fixture: ComponentFixture<CommandPalette>): Promise<void> {
trigger(fixture).click();
await flush(fixture);
}
async function submitQuery(
fixture: ComponentFixture<CommandPalette>,
value: string,
): Promise<void> {
const input = fixture.nativeElement.querySelector('input');
expect(input).toBeTruthy();
input.value = value;
input.dispatchEvent(new Event('input', { bubbles: true }));
fixture.nativeElement
.querySelector('form')
.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
await flush(fixture);
}
function outputText(fixture: ComponentFixture<CommandPalette>): string {
return fixture.nativeElement.querySelector('.command-palette-output')?.textContent ?? '';
}
function focusable(container: HTMLElement): HTMLElement[] {
return Array.from(
container.querySelectorAll<HTMLElement>(
'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',
),
).filter((element) => element.tabIndex >= 0);
}
it.each(APP_LOCALES)(
'renders the trigger and not the dialog on the server (%s)',
async (locale) => {
const fixture = await createFixture(locale, [{ provide: PLATFORM_ID, useValue: 'server' }]);
expect(trigger(fixture)).toBeTruthy();
expect(dialog(fixture)).toBeNull();
},
);
it.each(APP_LOCALES)('opens from the trigger and focuses the input (%s)', async (locale) => {
const fixture = await createFixture(locale);
await openViaTrigger(fixture);
const input = fixture.nativeElement.querySelector('input');
expect(dialog(fixture)).toBeTruthy();
expect(document.activeElement).toBe(input);
});
it.each(APP_LOCALES)(
'opens from Ctrl+K and Meta+K and prevents the default (%s)',
async (locale) => {
const fixture = await createFixture(locale);
await flush(fixture);
for (const modifier of [{ ctrlKey: true }, { metaKey: true }] as const) {
const openDialog = dialog(fixture);
if (openDialog) {
openDialog.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
await flush(fixture);
}
const event = new KeyboardEvent('keydown', {
key: 'k',
bubbles: true,
cancelable: true,
...modifier,
});
const prevent = vi.spyOn(event, 'preventDefault');
document.dispatchEvent(event);
await flush(fixture);
expect(prevent).toHaveBeenCalled();
expect(dialog(fixture)).toBeTruthy();
}
},
);
it.each(APP_LOCALES)('closes on Escape and returns focus to the trigger (%s)', async (locale) => {
const fixture = await createFixture(locale);
await openViaTrigger(fixture);
const openDialog = dialog(fixture);
expect(openDialog).toBeTruthy();
openDialog?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
await flush(fixture);
expect(dialog(fixture)).toBeNull();
expect(document.activeElement).toBe(trigger(fixture));
});
it.each(APP_LOCALES)('closes from the close button and restores focus (%s)', async (locale) => {
const fixture = await createFixture(locale);
await openViaTrigger(fixture);
const closeButton = fixture.nativeElement.querySelector('.command-palette-close');
closeButton.click();
await flush(fixture);
expect(dialog(fixture)).toBeNull();
expect(document.activeElement).toBe(trigger(fixture));
});
it.each(APP_LOCALES)('wraps Tab and Shift+Tab inside the dialog (%s)', async (locale) => {
const fixture = await createFixture(locale);
await openViaTrigger(fixture);
const openDialog = dialog(fixture);
expect(openDialog).toBeTruthy();
const items = focusable(openDialog as HTMLElement);
const first = items[0];
const last = items[items.length - 1];
last.focus();
openDialog?.dispatchEvent(
new KeyboardEvent('keydown', { key: 'Tab', bubbles: true, cancelable: true }),
);
expect(document.activeElement).toBe(first);
first.focus();
openDialog?.dispatchEvent(
new KeyboardEvent('keydown', { key: 'Tab', shiftKey: true, bubbles: true, cancelable: true }),
);
expect(document.activeElement).toBe(last);
});
it.each(APP_LOCALES)('writes localized help, playful replies and clear (%s)', async (locale) => {
const fixture = await createFixture(locale);
await openViaTrigger(fixture);
const copy = SIGNATURE_COPY[locale].palette;
await submitQuery(fixture, 'help');
const helpText = outputText(fixture);
expect(helpText).toContain(copy.helpIntro);
for (const command of COMMANDS) {
expect(helpText).toContain(command.input);
expect(helpText).toContain(copy.commandDescriptions[command.id]);
}
expect(COMMAND_IDS.every((id) => helpText.includes(copy.commandDescriptions[id]))).toBe(true);
await submitQuery(fixture, 'brew');
expect(outputText(fixture)).toContain(copy.responses.brew);
await submitQuery(fixture, 'ignite');
expect(outputText(fixture)).toContain(copy.responses.ignite);
await submitQuery(fixture, 'rev');
expect(outputText(fixture)).toContain(copy.responses.rev);
await submitQuery(fixture, 'clear');
expect(outputText(fixture).trim()).toBe(copy.clearedMessage);
});
it.each(APP_LOCALES)(
'navigates projects, services ai and contact through NavigationService (%s)',
async (locale) => {
const fixture = await createFixture(locale);
const router = TestBed.inject(Router);
const navigation = TestBed.inject(NavigationService);
const navigate = vi.spyOn(router, 'navigate').mockResolvedValue(true);
await openViaTrigger(fixture);
await submitQuery(fixture, 'projects');
expect(navigate).toHaveBeenCalledWith(navigation.link('projects'));
await openViaTrigger(fixture);
await submitQuery(fixture, 'services ai');
expect(navigate).toHaveBeenCalledWith(navigation.link('servicesAi'));
await openViaTrigger(fixture);
await submitQuery(fixture, 'contact');
expect(navigate).toHaveBeenCalledWith(navigation.link('contact'));
},
);
it.each(APP_LOCALES)('opens the CV in a new tab and never navigates (%s)', async (locale) => {
const fixture = await createFixture(locale);
const router = TestBed.inject(Router);
const navigate = vi.spyOn(router, 'navigate').mockResolvedValue(true);
const view = TestBed.inject(DOCUMENT).defaultView;
const open = vi.spyOn(view as Window, 'open').mockReturnValue(null);
await openViaTrigger(fixture);
await submitQuery(fixture, 'cv');
expect(open).toHaveBeenCalledWith(SITE_CONFIG.cvAssetPath, '_blank', 'noopener,noreferrer');
expect(navigate).not.toHaveBeenCalled();
expect(outputText(fixture)).toContain(SIGNATURE_COPY[locale].palette.cvOpened);
});
it.each(APP_LOCALES)(
'reports unknown input without navigating or opening a window (%s)',
async (locale) => {
const fixture = await createFixture(locale);
const router = TestBed.inject(Router);
const navigate = vi.spyOn(router, 'navigate').mockResolvedValue(true);
const view = TestBed.inject(DOCUMENT).defaultView;
const open = vi.spyOn(view as Window, 'open').mockReturnValue(null);
const raw = 'rm -rf /';
await openViaTrigger(fixture);
await submitQuery(fixture, raw);
expect(outputText(fixture)).toContain(
SIGNATURE_COPY[locale].palette.unknownCommand.replace('{command}', raw),
);
expect(navigate).not.toHaveBeenCalled();
expect(open).not.toHaveBeenCalled();
},
);
it('removes the document keydown listener on destroy', async () => {
const add = vi.spyOn(document, 'addEventListener');
const fixture = await createFixture();
await flush(fixture);
const added = add.mock.calls.find((call) => call[0] === 'keydown');
expect(added).toBeTruthy();
const remove = vi.spyOn(document, 'removeEventListener');
fixture.destroy();
expect(remove).toHaveBeenCalledWith('keydown', added?.[1]);
});
it('registers no document listener on the server', async () => {
const add = vi.spyOn(document, 'addEventListener');
await createFixture('de', [{ provide: PLATFORM_ID, useValue: 'server' }]);
expect(add.mock.calls.some((call) => call[0] === 'keydown')).toBe(false);
});
});