feat(nexus): add CmdKButton shim for layout overhaul (phase 8)

Top-strip button that renders the ⌘K glyph and opens the existing
CommandPalette by dispatching a synthetic Meta+K keydown on document,
which CommandPalette.tsx already listens for at its useEffect
(lines 42-51). This is explicitly a Phase 8 shim; Phase 14 of
docs/specs/2026-04-11-nexus-layout-overhaul.md replaces it with a
proper command-palette context when globalizing the palette's
search index.

Part of Phase 8 of the Nexus layout overhaul (task 3 of 7).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nexus Dev 2026-04-11 11:12:55 +00:00
parent 1de78f855f
commit c1647e70d7
2 changed files with 99 additions and 0 deletions

View file

@ -0,0 +1,62 @@
// @vitest-environment jsdom
import { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { CmdKButton } from "./CmdKButton";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;
describe("CmdKButton", () => {
let container: HTMLDivElement;
let root: ReturnType<typeof createRoot> | null = null;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
root = null;
});
afterEach(() => {
if (root) {
act(() => { root!.unmount(); });
root = null;
}
if (container.parentNode) container.remove();
});
function renderButton() {
root = createRoot(container);
act(() => {
root!.render(<CmdKButton />);
});
return {
getButton: () => container.querySelector("button[aria-label='Open command palette']") as HTMLButtonElement,
getKbd: () => container.querySelector("kbd")?.textContent?.trim(),
};
}
it("renders a button with the ⌘K kbd glyph", () => {
const { getButton, getKbd } = renderButton();
expect(getButton()).not.toBeNull();
expect(getKbd()).toBe("⌘K");
});
it("dispatches a Meta+K keydown on document when clicked", () => {
const listener = vi.fn();
document.addEventListener("keydown", listener);
const { getButton } = renderButton();
act(() => {
getButton().click();
});
expect(listener).toHaveBeenCalledTimes(1);
const event = listener.mock.calls[0]![0] as KeyboardEvent;
expect(event.key).toBe("k");
expect(event.metaKey).toBe(true);
document.removeEventListener("keydown", listener);
});
});

View file

@ -0,0 +1,37 @@
/**
* CmdKButton Phase 8 shim for the top-strip command palette trigger.
*
* Renders the K keyboard glyph and, when clicked, dispatches a synthetic
* Meta+K keydown event on `document`. The existing CommandPalette component
* in ui/src/components/CommandPalette.tsx installs a document-level keydown
* listener for Meta+K (see its useEffect at lines 42-51) and opens itself
* when that key is pressed, so the synthetic event reaches it without
* needing a refactor to share state.
*
* Phase 14 of docs/specs/2026-04-11-nexus-layout-overhaul.md replaces this
* shim with a proper command-palette context and globalizes the palette's
* search index. This file will either be deleted or gutted at that point.
*/
export function CmdKButton() {
const handleClick = () => {
const event = new KeyboardEvent("keydown", {
key: "k",
metaKey: true,
bubbles: true,
cancelable: true,
});
document.dispatchEvent(event);
};
return (
<button
type="button"
onClick={handleClick}
aria-label="Open command palette"
title="Open command palette (⌘K)"
className="inline-flex h-8 items-center gap-2 rounded-[4px] border border-border bg-card px-2 text-[12px] font-medium text-muted-foreground transition-colors hover:text-primary hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background"
>
<kbd className="font-mono text-[12px]">K</kbd>
</button>
);
}