Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/__tests__/settings/settingsModal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ describe('SettingsModal — backdrop', () => {
fireEvent.click(backdrop)
expect(useEditorStore.getState().isSettingsOpen).toBe(false)
})

it('clicking the Esc keycap closes the modal it advertises', () => {
// The keycap depresses on `:active` like every other `Kbd`, and sits
// beside the word "close". It used to be inert markup, so clicking it
// played the press animation and did nothing.
openModal()
render(<SettingsModal />)
fireEvent.click(screen.getByRole('button', { name: /esc\s*close/i }))
expect(useEditorStore.getState().isSettingsOpen).toBe(false)
})
})

// ---------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions src/admin/modals/Settings/SettingsModal.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,19 @@
border-top: 1px solid var(--overlay-10);
}

/* Sits on the footer's close Button. Keeps the row reading as a quiet hint
rather than a control — the keycap already carries the affordance — while
the element underneath is a real button. `justify-content: start` because a
Button centres its content by default and this row aligns with the nav
above it. */
.shortcutHint {
display: flex;
align-items: center;
justify-content: start;
gap: var(--space-xs);
flex-wrap: wrap;
width: 100%;
padding: 0;
color: var(--text-subtle);
font-size: var(--text-s);
}
Expand Down
21 changes: 16 additions & 5 deletions src/admin/modals/Settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* Shares the visual language of the Spotlight palette and the Module
* Inserter: a direct-token panel shell, an `--bg-surface-2` rail with
* categorical accent icon chips, an accent-bar section header, and a
* shared `Esc` keycap affordance (backdrop click / Esc both close — there
* is no dedicated close button, matching the other two modals).
* shared `Esc` keycap affordance, which is also the close button — backdrop
* click and Esc close it too.
*
* Guideline #225 (Modal Shell Requirements, WCAG 2.1 AA):
* - role="dialog" + aria-modal="true" + aria-labelledby
Expand Down Expand Up @@ -230,11 +230,22 @@ export function SettingsModal() {

<div className={s.railSpring} />

<div className={s.shortcutFooter} aria-label="Settings keyboard shortcuts">
<div className={s.shortcutHint}>
{/* The keycap reads as a button — it depresses on :active like every
other `Kbd` — so it has to behave like one. It was a hint beside
the word "close", which meant clicking it played the press
animation and did nothing, and the pointer over the label turned
into a text caret. Backdrop click and Esc still work; this just
stops the affordance lying about itself. */}
<div className={s.shortcutFooter}>
<Button
variant="ghost"
size="sm"
onClick={handleClose}
className={s.shortcutHint}
>
<Kbd>Esc</Kbd>
<span>close</span>
</div>
</Button>
</div>
</div>

Expand Down
Loading