diff --git a/src/chat-sidebar.tsx b/src/chat-sidebar.tsx index 47d9f849..cd3c7c74 100644 --- a/src/chat-sidebar.tsx +++ b/src/chat-sidebar.tsx @@ -3552,31 +3552,35 @@ function SidebarComponent(props: any) {
Notebook Intelligence
{NBIAPI.config.isInClaudeCodeMode && ( <> -
startNewChatSession()} title="Start a new chat session (restarts the Claude client)" aria-label="Start a new chat session" > -
-
+
+ )} -
handleSettingsButtonClick()} - title="Open Notebook Intelligence settings" aria-label="Open Notebook Intelligence settings" + title="Configure providers, API keys, MCP servers, and skills" > -
+
{skillsReloadedVisible && ( @@ -3871,7 +3875,8 @@ function SidebarComponent(props: any) {
)} {chatMode !== 'ask' && !NBIAPI.config.isInClaudeCodeMode && ( -
0 ? 'tools-button-active' : ''}`} onClick={() => handleChatToolsButtonClick()} title={ @@ -3879,10 +3884,15 @@ function SidebarComponent(props: any) { ? `Tool selection can cause irreversible changes! Review each tool execution carefully.\n${toolSelectionTitle}` : toolSelectionTitle } + aria-label={ + unsafeToolSelected + ? 'Configure tools (warning: irreversible tools selected)' + : 'Configure tools' + } > {selectedToolCount > 0 && <>{selectedToolCount}} -
+ )} {NBIAPI.config.isInClaudeCodeMode && ( - so they line up visually with the older
variants. */ + so they line up visually with the older
variants. + `line-height: 1` keeps the tools-button badge from drifting a pixel + relative to the icon when rendered inside a button vs a div. */ button.user-input-footer-button { background: none; border: none; font: inherit; + line-height: 1; display: inline-flex; align-items: center; justify-content: center; } +/* Visible focus ring for keyboard users. :focus-visible keeps it from + firing on a plain click. Matches the brand-color focus indicator + the other NBI buttons use elsewhere in this stylesheet. */ +.user-input-footer-button:focus-visible { + outline: 2px solid var(--jp-brand-color1); + outline-offset: 1px; + border-radius: 3px; + color: var(--jp-ui-font-color1); +} + /* The slash-button (mentions and commands) renders text rather than an svg, so size and center the glyph instead of relying on the svg rule. */ .user-input-footer-slash-button { diff --git a/ui-tests/tests/chat-sidebar.spec.ts b/ui-tests/tests/chat-sidebar.spec.ts index 11617d4c..1affe4d0 100644 --- a/ui-tests/tests/chat-sidebar.spec.ts +++ b/ui-tests/tests/chat-sidebar.spec.ts @@ -35,14 +35,30 @@ test.describe('chat sidebar layout', () => { await expect(slash).toHaveText('/'); }); - test('sidebar-header gear icon carries a title', async ({ page }) => { - // The gear used to ship without a title attribute while its neighbours - // had one; users hovering the icon got no affordance. Pin the title. + test('sidebar-header gear is a focusable, labelled button', async ({ + page + }) => { + // Regression guard for D155 / D156: the gear used to be a
+ // so keyboard users could not reach it. Pin that it is now a real + //