From ced04ae47ad007e16faac55e8a5aa0d189264599 Mon Sep 17 00:00:00 2001 From: XOP Date: Mon, 19 Oct 2026 14:31:52 +0200 Subject: [PATCH 1/3] fix(a11y): keyboard-operable cards --- .changeset/fix-cui-308-clickable-cards.md | 5 + eslint-suppressions.json | 10 -- .../CardHorizontal/CardHorizontal.test.tsx | 9 ++ .../CardHorizontal/CardHorizontal.tsx | 47 ++++--- .../CardPrimary/CardPrimary.stories.tsx | 18 +++ .../CardPrimary/CardPrimary.test.tsx | 110 ++++++++++++++- src/components/CardPrimary/CardPrimary.tsx | 24 +++- .../CardSecondary/CardSecondary.stories.tsx | 21 +++ .../CardSecondary/CardSecondary.test.tsx | 127 +++++++++++++++++- .../CardSecondary/CardSecondary.tsx | 22 +++ src/utils/keyboard.ts | 16 +++ 11 files changed, 372 insertions(+), 37 deletions(-) create mode 100644 .changeset/fix-cui-308-clickable-cards.md create mode 100644 src/utils/keyboard.ts diff --git a/.changeset/fix-cui-308-clickable-cards.md b/.changeset/fix-cui-308-clickable-cards.md new file mode 100644 index 000000000..2dacec5ef --- /dev/null +++ b/.changeset/fix-cui-308-clickable-cards.md @@ -0,0 +1,5 @@ +--- +'@clickhouse/click-ui': patch +--- + +`CardPrimary` and `CardSecondary` with `onClick` are exposed as buttons and activate with Enter and Space, unless the card renders its own `infoText` button (`CardPrimary`) or `infoUrl` link (`CardSecondary`); then that control stays the only one. Display-only cards keep the default key behavior. A disabled card no longer calls `onClick`, on any card. Do not put links or buttons inside the title, description or children of a clickable card. diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 8995126cc..0c450b270 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -7,16 +7,6 @@ "count": 1 } }, - "src/components/CardPrimary/CardPrimary.tsx": { - "jsx-a11y/no-noninteractive-tabindex": { - "count": 1 - } - }, - "src/components/CardSecondary/CardSecondary.tsx": { - "jsx-a11y/no-noninteractive-tabindex": { - "count": 1 - } - }, "src/components/Collapsible/Collapsible.tsx": { "jsx-a11y/click-events-have-key-events": { "count": 1 diff --git a/src/components/CardHorizontal/CardHorizontal.test.tsx b/src/components/CardHorizontal/CardHorizontal.test.tsx index 1a6d8e4f1..6f7af20f3 100644 --- a/src/components/CardHorizontal/CardHorizontal.test.tsx +++ b/src/components/CardHorizontal/CardHorizontal.test.tsx @@ -497,5 +497,14 @@ describe('CardHorizontal Component', () => { expect(screen.queryByRole('button')).not.toBeInTheDocument(); }); + + it('should not run a consumer onClick on a disabled card', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ title: 'Test Card', disabled: true, onClick }); + + fireEvent.click(container.firstChild as HTMLElement); + + expect(onClick).not.toHaveBeenCalled(); + }); }); }); diff --git a/src/components/CardHorizontal/CardHorizontal.tsx b/src/components/CardHorizontal/CardHorizontal.tsx index d6693ac86..1c9282acd 100644 --- a/src/components/CardHorizontal/CardHorizontal.tsx +++ b/src/components/CardHorizontal/CardHorizontal.tsx @@ -3,6 +3,7 @@ import { Button } from '@/components/Button'; import { Container } from '@/components/Container'; import { Icon } from '@/components/Icon'; import { cn, cva } from '@/lib/cva'; +import { clickOnActivationKey } from '@/utils/keyboard'; import { openInNewTab } from '@/utils/url'; import { CardHorizontalProps } from './CardHorizontal.types'; import styles from './CardHorizontal.module.css'; @@ -80,16 +81,12 @@ export const CardHorizontal = ({ badgeIcon, badgeIconDir, onButtonClick, + onClick, onKeyDown, className, ...props }: CardHorizontalProps) => { - const handleClick = (e: React.MouseEvent) => { - if (disabled) { - e.preventDefault(); - return; - } - + const fireAction = (e: React.MouseEvent) => { if (typeof onButtonClick === 'function') { onButtonClick(e); } @@ -97,33 +94,35 @@ export const CardHorizontal = ({ openInNewTab(infoUrl); } }; + const handleClick = (e: React.MouseEvent) => { + if (disabled) { + e.preventDefault(); + return; + } + if (typeof onClick === 'function') { + onClick(e); + return; + } + fireAction(e); + }; const handleButtonClick = (e: React.MouseEvent) => { e.stopPropagation(); - handleClick(e); + if (disabled) { + e.preventDefault(); + return; + } + fireAction(e); }; const isActionable = - typeof props.onClick === 'function' || + typeof onClick === 'function' || typeof onButtonClick === 'function' || Boolean(infoUrl); // With an inner info button, that button is the keyboard action, so the card leaves Enter and Space alone. const isButton = isActionable && !infoText; const handleKeyDown = (e: React.KeyboardEvent) => { - if (typeof onKeyDown === 'function') { - onKeyDown(e); - } - // Keys from nested controls bubble up here and must not activate the card. - const shouldSkipActivation = - !isButton || e.defaultPrevented || disabled || e.target !== e.currentTarget; - if (shouldSkipActivation) { - return; - } - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - // A held key repeats keydown, so only the first press activates the card. - if (!e.repeat) { - // Runs whichever onClick is attached. - e.currentTarget.click(); - } + onKeyDown?.(e); + if (isButton && !disabled) { + clickOnActivationKey(e); } }; return ( diff --git a/src/components/CardPrimary/CardPrimary.stories.tsx b/src/components/CardPrimary/CardPrimary.stories.tsx index e49aa3f7f..d2f037a8c 100644 --- a/src/components/CardPrimary/CardPrimary.stories.tsx +++ b/src/components/CardPrimary/CardPrimary.stories.tsx @@ -1,4 +1,5 @@ import { Meta, StoryObj } from '@storybook/react-vite'; +import { expect, fn, userEvent, within } from 'storybook/test'; import { CardPrimary } from '@/components/CardPrimary'; const meta: Meta = { @@ -101,3 +102,20 @@ export const WithoutButton: Story = { alignContent: 'center', }, }; + +export const Keyboard: Story = { + args: { + ...WithoutButton.args, + onClick: fn(), + }, + play: async ({ canvasElement, args }) => { + const card = within(canvasElement).getByRole('button', { name: /Card title/ }); + + await userEvent.tab(); + await expect(card).toHaveFocus(); + + await userEvent.keyboard('{Enter}'); + await userEvent.keyboard(' '); + await expect(args.onClick).toHaveBeenCalledTimes(2); + }, +}; diff --git a/src/components/CardPrimary/CardPrimary.test.tsx b/src/components/CardPrimary/CardPrimary.test.tsx index b97f31199..411e93089 100644 --- a/src/components/CardPrimary/CardPrimary.test.tsx +++ b/src/components/CardPrimary/CardPrimary.test.tsx @@ -1,4 +1,4 @@ -import { screen } from '@testing-library/react'; +import { fireEvent, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderCUI } from '@/utils/test-utils'; import { CardPrimary, CardPrimaryProps } from '@/components/CardPrimary'; @@ -170,4 +170,112 @@ describe('CardPrimary Component', () => { expect(warnSpy.mock.calls[0][0]).toContain('javascript:alert(1)'); }); }); + + describe('keyboard', () => { + const renderCard = (props: CardPrimaryProps) => renderCUI(); + const getCard = (container: HTMLElement) => + container.querySelector('[aria-disabled]') as HTMLElement; + + it.each(['{Enter}', ' '])( + 'should call onClick on "%s" and expose a button', + async key => { + const onClick = vitest.fn(); + const { container } = renderCard({ title: 'Test Card', onClick }); + + const card = screen.getByRole('button', { name: /Test Card/ }); + expect(card).toBe(getCard(container)); + card.focus(); + await userEvent.keyboard(key); + + expect(onClick).toHaveBeenCalledTimes(1); + } + ); + + it('should activate only once while Space is held and keep the page from scrolling', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ title: 'Test Card', onClick }); + + const card = getCard(container); + expect(fireEvent.keyDown(card, { key: ' ' })).toBe(false); + expect(fireEvent.keyDown(card, { key: ' ', repeat: true })).toBe(false); + + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it('should leave other keys and keys from controls inside the card alone', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + onClick, + children: , + }); + + expect(fireEvent.keyDown(getCard(container), { key: 'Tab' })).toBe(true); + expect(fireEvent.keyDown(screen.getByRole('textbox'), { key: ' ' })).toBe(true); + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should run the consumer onKeyDown and still activate', () => { + const onClick = vitest.fn(); + const onKeyDown = vitest.fn(); + const { container } = renderCard({ title: 'Test Card', onClick, onKeyDown }); + + fireEvent.keyDown(getCard(container), { key: 'Enter' }); + + expect(onKeyDown).toHaveBeenCalledTimes(1); + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it.each([ + ['infoText only', { infoText: 'Go' }], + ['infoUrl without infoText', { infoUrl: 'https://example.com' }], + ['onButtonClick without infoText', { onButtonClick: vitest.fn() }], + ])('should be the only button when it has %s', (_name, extra) => { + const onClick = vitest.fn(); + renderCard({ title: 'Test Card', onClick, ...extra }); + + fireEvent.keyDown(screen.getByRole('button', { name: /Test Card/ }), { + key: 'Enter', + }); + + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it('should not run a consumer onClick on a disabled card', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ title: 'Test Card', onClick, disabled: true }); + + fireEvent.click(getCard(container)); + + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should leave the keys to the inner button and not be a button itself', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + infoText: 'Go', + onButtonClick: vitest.fn(), + onClick, + }); + + const card = getCard(container); + expect(card).not.toHaveAttribute('role'); + expect(fireEvent.keyDown(card, { key: 'Enter' })).toBe(true); + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should keep the default key behavior on a display-only or disabled card', () => { + const onClick = vitest.fn(); + const plain = getCard(renderCard({ title: 'Summary' }).container); + expect(plain).not.toHaveAttribute('role'); + expect(fireEvent.keyDown(plain, { key: ' ' })).toBe(true); + + const disabled = getCard( + renderCard({ title: 'Test Card', onClick, disabled: true }).container + ); + fireEvent.keyDown(disabled, { key: 'Enter' }); + expect(onClick).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/components/CardPrimary/CardPrimary.tsx b/src/components/CardPrimary/CardPrimary.tsx index 942a5387e..3c3e5c2f0 100644 --- a/src/components/CardPrimary/CardPrimary.tsx +++ b/src/components/CardPrimary/CardPrimary.tsx @@ -5,6 +5,7 @@ import { Button } from '@/components/Button'; import { Icon } from '@/components/Icon'; import { Spacer } from '@/components/Spacer'; import { cn, cva } from '@/lib/cva'; +import { clickOnActivationKey } from '@/utils/keyboard'; import { openInNewTab } from '@/utils/url'; import { CardPrimaryProps } from './CardPrimary.types'; import styles from './CardPrimary.module.css'; @@ -95,6 +96,8 @@ const Card = ({ onButtonClick, isSelected, children, + onClick, + onKeyDown, className, ...props }: CardPrimaryProps) => { @@ -106,12 +109,31 @@ const Card = ({ openInNewTab(infoUrl); } }; + const handleCardClick = (e: React.MouseEvent) => { + if (disabled) { + e.preventDefault(); + return; + } + onClick?.(e); + }; - const Component = !!infoUrl || typeof onButtonClick === 'function' ? Button : 'div'; + const hasInnerButton = !!infoUrl || typeof onButtonClick === 'function'; + const Component = hasInnerButton ? Button : 'div'; + // With an inner info button, that button is the keyboard action, so the card leaves Enter and Space alone. + const isButton = typeof onClick === 'function' && !(infoText && hasInnerButton); + const handleKeyDown = (e: React.KeyboardEvent) => { + onKeyDown?.(e); + if (isButton && !disabled) { + clickOnActivationKey(e); + } + }; return (
= { @@ -63,3 +64,23 @@ export const Disabled: Story = { disabled: true, }, }; + +export const Keyboard: Story = { + args: { + title: baseArgs.title, + icon: baseArgs.icon, + description: baseArgs.description, + infoText: baseArgs.infoText, + onClick: fn(), + }, + play: async ({ canvasElement, args }) => { + const card = within(canvasElement).getByRole('button', { name: /Card title/ }); + + await userEvent.tab(); + await expect(card).toHaveFocus(); + + await userEvent.keyboard('{Enter}'); + await userEvent.keyboard(' '); + await expect(args.onClick).toHaveBeenCalledTimes(2); + }, +}; diff --git a/src/components/CardSecondary/CardSecondary.test.tsx b/src/components/CardSecondary/CardSecondary.test.tsx index e04e17b74..c770aa321 100644 --- a/src/components/CardSecondary/CardSecondary.test.tsx +++ b/src/components/CardSecondary/CardSecondary.test.tsx @@ -1,4 +1,5 @@ -import { screen } from '@testing-library/react'; +import { fireEvent, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { CardSecondary, CardSecondaryProps } from '@/components/CardSecondary'; import { renderCUI } from '@/utils/test-utils'; @@ -97,4 +98,128 @@ describe('CardSecondary Component', () => { expect(screen.getAllByLabelText('chevron-right').length).toEqual(1); }); + + describe('keyboard', () => { + const getCard = (container: HTMLElement) => container.firstChild as HTMLElement; + + it.each(['{Enter}', ' '])( + 'should call onClick on "%s" and expose a button', + async key => { + const onClick = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + description: 'Desc', + onClick, + }); + + const card = screen.getByRole('button', { name: /Test Card/ }); + expect(card).toBe(getCard(container)); + card.focus(); + await userEvent.keyboard(key); + + expect(onClick).toHaveBeenCalledTimes(1); + } + ); + + it('should run the consumer onKeyDown and still activate', () => { + const onClick = vitest.fn(); + const onKeyDown = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + description: 'Desc', + onClick, + onKeyDown, + }); + + fireEvent.keyDown(getCard(container), { key: 'Enter' }); + + expect(onKeyDown).toHaveBeenCalledTimes(1); + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it('should stay a link, not a button, with infoUrl and no infoText', () => { + const { container } = renderCard({ + title: 'Test Card', + description: 'Desc', + infoUrl: 'https://example.com', + onClick: vitest.fn(), + }); + + expect(getCard(container)).not.toHaveAttribute('role'); + expect(screen.getByRole('link')).toBeInTheDocument(); + }); + + it('should hide the info icon from the button name', () => { + renderCard({ + title: 'Test Card', + description: 'Desc', + infoText: 'Read more', + onClick: vitest.fn(), + }); + + expect(screen.getByRole('button')).toHaveAccessibleName('Test Card Desc Read more'); + }); + + it('should not run a consumer onClick on a disabled card', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + description: 'Desc', + onClick, + disabled: true, + }); + + fireEvent.click(getCard(container)); + + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should activate only once while Space is held and keep the page from scrolling', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + description: 'Desc', + onClick, + }); + + const card = getCard(container); + expect(fireEvent.keyDown(card, { key: ' ' })).toBe(false); + expect(fireEvent.keyDown(card, { key: ' ', repeat: true })).toBe(false); + + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it('should leave the keys to the info link and not be a button itself', () => { + const onClick = vitest.fn(); + const { container } = renderCard({ + title: 'Test Card', + description: 'Desc', + infoUrl: 'https://example.com', + infoText: 'Read more', + onClick, + }); + + const card = getCard(container); + expect(card).not.toHaveAttribute('role'); + expect(screen.getByRole('link')).toBeInTheDocument(); + expect(fireEvent.keyDown(card, { key: 'Enter' })).toBe(true); + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should keep the default key behavior on a display-only or disabled card', () => { + const onClick = vitest.fn(); + const plain = getCard( + renderCard({ title: 'Summary', description: 'Desc' }).container + ); + expect(plain).not.toHaveAttribute('role'); + expect(fireEvent.keyDown(plain, { key: ' ' })).toBe(true); + + const disabled = getCard( + renderCard({ title: 'Test Card', description: 'Desc', onClick, disabled: true }) + .container + ); + fireEvent.keyDown(disabled, { key: 'Enter' }); + expect(onClick).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/components/CardSecondary/CardSecondary.tsx b/src/components/CardSecondary/CardSecondary.tsx index 31007d122..911df518e 100644 --- a/src/components/CardSecondary/CardSecondary.tsx +++ b/src/components/CardSecondary/CardSecondary.tsx @@ -3,6 +3,7 @@ import { Icon } from '@/components/Icon'; import { Title } from '@/components/Title'; import { Text } from '@/components/Text'; import { cn, cva } from '@/lib/cva'; +import { clickOnActivationKey } from '@/utils/keyboard'; import { CardSecondaryProps } from './CardSecondary.types'; import styles from './CardSecondary.module.css'; @@ -35,15 +36,35 @@ export const CardSecondary = ({ infoText, infoIcon = 'chevron-right', infoAssetSize = 'md', + onClick, + onKeyDown, className, ...props }: CardSecondaryProps) => { const isInfoLink = !disabled && !!infoUrl && infoUrl.length > 0; const InfoComponent = isInfoLink ? 'a' : 'div'; + // With an info link, that link is the keyboard action, so the card leaves Enter and Space alone. + const isButton = typeof onClick === 'function' && !infoUrl; + const handleCardClick = (e: React.MouseEvent) => { + if (disabled) { + e.preventDefault(); + return; + } + onClick?.(e); + }; + const handleKeyDown = (e: React.KeyboardEvent) => { + onKeyDown?.(e); + if (isButton && !disabled) { + clickOnActivationKey(e); + } + }; return (
@@ -88,6 +109,7 @@ export const CardSecondary = ({ className={styles.infolink__icon} size={infoAssetSize} name={infoIcon} + aria-hidden={infoText ? true : undefined} /> )} diff --git a/src/utils/keyboard.ts b/src/utils/keyboard.ts new file mode 100644 index 000000000..3c2580285 --- /dev/null +++ b/src/utils/keyboard.ts @@ -0,0 +1,16 @@ +import type { KeyboardEvent } from 'react'; + +/** Enter and Space click the element itself, once per press; keys from a focusable descendant are left alone. */ +export const clickOnActivationKey = (event: KeyboardEvent): void => { + if (event.defaultPrevented || event.target !== event.currentTarget) { + return; + } + if (event.key !== 'Enter' && event.key !== ' ') { + return; + } + event.preventDefault(); + if (event.repeat) { + return; + } + event.currentTarget.click(); +}; From 37e7053dfa8875baa03c031985ebe13b5602ad62 Mon Sep 17 00:00:00 2001 From: XOP Date: Tue, 20 Oct 2026 10:53:27 +0200 Subject: [PATCH 2/3] fix(a11y): undefined fix --- .changeset/fix-cui-308-clickable-cards.md | 2 +- .../CardHorizontal/CardHorizontal.test.tsx | 16 ++++++++++++++++ .../CardHorizontal/CardHorizontal.tsx | 17 +++++++++-------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.changeset/fix-cui-308-clickable-cards.md b/.changeset/fix-cui-308-clickable-cards.md index 2dacec5ef..1994a2ec7 100644 --- a/.changeset/fix-cui-308-clickable-cards.md +++ b/.changeset/fix-cui-308-clickable-cards.md @@ -2,4 +2,4 @@ '@clickhouse/click-ui': patch --- -`CardPrimary` and `CardSecondary` with `onClick` are exposed as buttons and activate with Enter and Space, unless the card renders its own `infoText` button (`CardPrimary`) or `infoUrl` link (`CardSecondary`); then that control stays the only one. Display-only cards keep the default key behavior. A disabled card no longer calls `onClick`, on any card. Do not put links or buttons inside the title, description or children of a clickable card. +`CardPrimary` and `CardSecondary` with `onClick` are exposed as buttons and activate with Enter and Space, unless the card renders its own `infoText` button (`CardPrimary`) or `infoUrl` link (`CardSecondary`); then the card gets no button role and that control keeps Enter and Space. Display-only cards keep the default key behavior. A disabled `CardPrimary`, `CardSecondary` or `CardHorizontal` no longer calls `onClick`. Do not put links or buttons inside the title, description or children of a clickable card. diff --git a/src/components/CardHorizontal/CardHorizontal.test.tsx b/src/components/CardHorizontal/CardHorizontal.test.tsx index 6f7af20f3..92f1ee0b9 100644 --- a/src/components/CardHorizontal/CardHorizontal.test.tsx +++ b/src/components/CardHorizontal/CardHorizontal.test.tsx @@ -225,6 +225,22 @@ describe('CardHorizontal Component', () => { expect(onButtonClick).toHaveBeenCalledTimes(1); }); + it('should not run onButtonClick on a body click when onClick is explicitly undefined', async () => { + const onButtonClick = vitest.fn(); + const { container, getByRole } = renderCard({ + title: 'Test Card', + infoText: 'Continue', + onClick: undefined, + onButtonClick, + }); + + fireEvent.click(container.firstChild as HTMLElement); + expect(onButtonClick).not.toHaveBeenCalled(); + + await userEvent.click(getByRole('button', { name: 'Continue' })); + expect(onButtonClick).toHaveBeenCalledTimes(1); + }); + it('should open infoUrl only once when the inner button is clicked', async () => { const windowOpenSpy = vitest.spyOn(window, 'open').mockImplementation(() => null); const { getByRole } = renderCard({ diff --git a/src/components/CardHorizontal/CardHorizontal.tsx b/src/components/CardHorizontal/CardHorizontal.tsx index 1c9282acd..1330c2b3b 100644 --- a/src/components/CardHorizontal/CardHorizontal.tsx +++ b/src/components/CardHorizontal/CardHorizontal.tsx @@ -81,11 +81,13 @@ export const CardHorizontal = ({ badgeIcon, badgeIconDir, onButtonClick, - onClick, onKeyDown, className, - ...props + ...rest }: CardHorizontalProps) => { + const { onClick, ...props } = rest; + // An explicit onClick={undefined} turns the card body off; consumers use it to keep only the inner button. + const hasOnClickProp = 'onClick' in rest; const fireAction = (e: React.MouseEvent) => { if (typeof onButtonClick === 'function') { onButtonClick(e); @@ -99,8 +101,8 @@ export const CardHorizontal = ({ e.preventDefault(); return; } - if (typeof onClick === 'function') { - onClick(e); + if (hasOnClickProp) { + onClick?.(e); return; } fireAction(e); @@ -113,10 +115,9 @@ export const CardHorizontal = ({ } fireAction(e); }; - const isActionable = - typeof onClick === 'function' || - typeof onButtonClick === 'function' || - Boolean(infoUrl); + const isActionable = hasOnClickProp + ? typeof onClick === 'function' + : typeof onButtonClick === 'function' || Boolean(infoUrl); // With an inner info button, that button is the keyboard action, so the card leaves Enter and Space alone. const isButton = isActionable && !infoText; const handleKeyDown = (e: React.KeyboardEvent) => { From a47e13eb2264df4eeb5f1a40677a02ffe2fe3e60 Mon Sep 17 00:00:00 2001 From: XOP Date: Fri, 23 Oct 2026 14:20:43 +0200 Subject: [PATCH 3/3] fix(a11y): button fix --- .changeset/fix-cui-308-clickable-cards.md | 2 +- .../CardHorizontal/CardHorizontal.test.tsx | 20 +++++++++++++++++- .../CardHorizontal/CardHorizontal.tsx | 2 +- .../CardPrimary/CardPrimary.test.tsx | 1 + src/components/CardPrimary/CardPrimary.tsx | 2 +- .../CardSecondary/CardSecondary.test.tsx | 1 + .../CardSecondary/CardSecondary.tsx | 2 +- tests/cards/cardprimary.spec.ts | 9 +++++--- .../cardprimary-focus-dark-chromium-linux.png | Bin 9719 -> 10178 bytes ...cardprimary-focus-light-chromium-linux.png | Bin 9684 -> 9982 bytes tests/cards/cardsecondary.spec.ts | 9 +++++--- ...ardsecondary-focus-dark-chromium-linux.png | Bin 7570 -> 7969 bytes ...rdsecondary-focus-light-chromium-linux.png | Bin 7486 -> 7656 bytes 13 files changed, 37 insertions(+), 11 deletions(-) diff --git a/.changeset/fix-cui-308-clickable-cards.md b/.changeset/fix-cui-308-clickable-cards.md index 1994a2ec7..628efc109 100644 --- a/.changeset/fix-cui-308-clickable-cards.md +++ b/.changeset/fix-cui-308-clickable-cards.md @@ -2,4 +2,4 @@ '@clickhouse/click-ui': patch --- -`CardPrimary` and `CardSecondary` with `onClick` are exposed as buttons and activate with Enter and Space, unless the card renders its own `infoText` button (`CardPrimary`) or `infoUrl` link (`CardSecondary`); then the card gets no button role and that control keeps Enter and Space. Display-only cards keep the default key behavior. A disabled `CardPrimary`, `CardSecondary` or `CardHorizontal` no longer calls `onClick`. Do not put links or buttons inside the title, description or children of a clickable card. +`CardPrimary` and `CardSecondary` with `onClick` are exposed as buttons and activate with Enter and Space, unless the card renders its own `infoText` button (`CardPrimary`) or `infoUrl` link (`CardSecondary`); then the card gets no button role and that control keeps Enter and Space. A card that is not a button is no longer a Tab stop, on all three cards; display-only cards keep the default key behavior. A disabled `CardPrimary`, `CardSecondary` or `CardHorizontal` no longer calls `onClick`. Do not put links or buttons inside the title, description or children of a clickable card. diff --git a/src/components/CardHorizontal/CardHorizontal.test.tsx b/src/components/CardHorizontal/CardHorizontal.test.tsx index 92f1ee0b9..84065019c 100644 --- a/src/components/CardHorizontal/CardHorizontal.test.tsx +++ b/src/components/CardHorizontal/CardHorizontal.test.tsx @@ -123,6 +123,7 @@ describe('CardHorizontal Component', () => { const { container } = renderCard({ title: 'Test Card', disabled: true, + onClick: () => undefined, }); const wrapper = container.firstChild; @@ -133,12 +134,25 @@ describe('CardHorizontal Component', () => { const { container } = renderCard({ title: 'Test Card', disabled: false, + onClick: () => undefined, }); const wrapper = container.firstChild; expect(wrapper).toHaveAttribute('tabIndex', '0'); }); + it('should not be a Tab stop without a body action or with an inner button', () => { + const plain = renderCard({ title: 'Summary' }).container.firstChild; + expect(plain).not.toHaveAttribute('tabIndex'); + + const withButton = renderCard({ + title: 'Test Card', + infoText: 'Continue', + onButtonClick: () => undefined, + }).container.firstChild; + expect(withButton).not.toHaveAttribute('tabIndex'); + }); + it('should not call onClick when disabled', () => { const onClickMock = vitest.fn(); const { container } = renderCard({ @@ -466,7 +480,11 @@ describe('CardHorizontal Component', () => { it("should call the consumer's onKeyDown", async () => { const onKeyDown = vitest.fn(); - const { container } = renderCard({ title: 'Test Card', onKeyDown }); + const { container } = renderCard({ + title: 'Test Card', + onClick: () => undefined, + onKeyDown, + }); (container.firstChild as HTMLElement).focus(); await userEvent.keyboard('{Enter}'); diff --git a/src/components/CardHorizontal/CardHorizontal.tsx b/src/components/CardHorizontal/CardHorizontal.tsx index 1330c2b3b..e04ca5392 100644 --- a/src/components/CardHorizontal/CardHorizontal.tsx +++ b/src/components/CardHorizontal/CardHorizontal.tsx @@ -128,7 +128,7 @@ export const CardHorizontal = ({ }; return (
{ const onClick = vitest.fn(); const plain = getCard(renderCard({ title: 'Summary' }).container); expect(plain).not.toHaveAttribute('role'); + expect(plain).not.toHaveAttribute('tabIndex'); expect(fireEvent.keyDown(plain, { key: ' ' })).toBe(true); const disabled = getCard( diff --git a/src/components/CardPrimary/CardPrimary.tsx b/src/components/CardPrimary/CardPrimary.tsx index 3c3e5c2f0..5fde2122e 100644 --- a/src/components/CardPrimary/CardPrimary.tsx +++ b/src/components/CardPrimary/CardPrimary.tsx @@ -130,7 +130,7 @@ const Card = ({ return (
{ renderCard({ title: 'Summary', description: 'Desc' }).container ); expect(plain).not.toHaveAttribute('role'); + expect(plain).not.toHaveAttribute('tabIndex'); expect(fireEvent.keyDown(plain, { key: ' ' })).toBe(true); const disabled = getCard( diff --git a/src/components/CardSecondary/CardSecondary.tsx b/src/components/CardSecondary/CardSecondary.tsx index 911df518e..d77c63072 100644 --- a/src/components/CardSecondary/CardSecondary.tsx +++ b/src/components/CardSecondary/CardSecondary.tsx @@ -61,7 +61,7 @@ export const CardSecondary = ({ return (
{ }); const card = page.locator(cardLocator).first(); await expect(card).toBeVisible({ timeout: 10000 }); - await card.focus(); + await page.locator('body').click(); + await page.keyboard.press('Tab'); await page.waitForTimeout(100); await expect(card).toHaveScreenshot('cardprimary-focus-light.png', { maxDiffPixels: 100, @@ -308,7 +309,8 @@ describe('CardPrimary Visual Regression', () => { }); const card = page.locator(cardLocator).first(); await expect(card).toBeVisible({ timeout: 10000 }); - await card.focus(); + await page.locator('body').click(); + await page.keyboard.press('Tab'); await page.waitForTimeout(100); await expect(card).toHaveScreenshot('cardprimary-focus-dark.png', { maxDiffPixels: 100, @@ -319,11 +321,12 @@ describe('CardPrimary Visual Regression', () => { describe('Accessibility', () => { it('card is focusable via Tab', async ({ page }) => { - await page.goto(getStoryUrl('cards-primary-card--default', 'light'), { + await page.goto(getStoryUrl('cards-primary-card--keyboard', 'light'), { waitUntil: 'networkidle', }); const card = page.locator(cardLocator).first(); await expect(card).toBeVisible({ timeout: 10000 }); + await expect(card).toHaveAttribute('role', 'button'); await page.locator('body').click(); await page.keyboard.press('Tab'); diff --git a/tests/cards/cardprimary.spec.ts-snapshots/cardprimary-focus-dark-chromium-linux.png b/tests/cards/cardprimary.spec.ts-snapshots/cardprimary-focus-dark-chromium-linux.png index bcbba1f643e01122292e1699f8fb225abf67e709..2fb366b768d93031a4684435ef41302a1dd0e05a 100644 GIT binary patch literal 10178 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 NPFneO$t#nO{|kwUquT%g diff --git a/tests/cards/cardprimary.spec.ts-snapshots/cardprimary-focus-light-chromium-linux.png b/tests/cards/cardprimary.spec.ts-snapshots/cardprimary-focus-light-chromium-linux.png index 086f544c3a94ec06aa64fbb13d02d9a7754d830b..51efa14cab87900f949ebade59dee4f3dca6c9b8 100644 GIT binary patch literal 9982 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 literal 9684 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 { }); const card = page.locator(cardLocator).first(); await expect(card).toBeVisible({ timeout: 10000 }); - await card.focus(); + await page.locator('body').click(); + await page.keyboard.press('Tab'); await page.waitForTimeout(100); await expect(card).toHaveScreenshot('cardsecondary-focus-light.png', { maxDiffPixels: 100, @@ -178,7 +179,8 @@ describe('CardSecondary Visual Regression', () => { }); const card = page.locator(cardLocator).first(); await expect(card).toBeVisible({ timeout: 10000 }); - await card.focus(); + await page.locator('body').click(); + await page.keyboard.press('Tab'); await page.waitForTimeout(100); await expect(card).toHaveScreenshot('cardsecondary-focus-dark.png', { maxDiffPixels: 100, @@ -189,11 +191,12 @@ describe('CardSecondary Visual Regression', () => { describe('Accessibility', () => { it('enabled card is focusable via Tab', async ({ page }) => { - await page.goto(getStoryUrl('cards-secondary-card--default', 'light'), { + await page.goto(getStoryUrl('cards-secondary-card--keyboard', 'light'), { waitUntil: 'networkidle', }); const card = page.locator(cardLocator).first(); await expect(card).toBeVisible({ timeout: 10000 }); + await expect(card).toHaveAttribute('role', 'button'); await page.locator('body').click(); await page.keyboard.press('Tab'); diff --git a/tests/cards/cardsecondary.spec.ts-snapshots/cardsecondary-focus-dark-chromium-linux.png b/tests/cards/cardsecondary.spec.ts-snapshots/cardsecondary-focus-dark-chromium-linux.png index 8c4fe1f33d161f0b964aacf03ce7cf5b0dc38b41..7d1e5b48d516dbfcb993e4adb6f39c9fcb1c8493 100644 GIT binary patch literal 7969 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 Pj{uYvG~_E~EkFGiH~o_} literal 7570 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 diff --git a/tests/cards/cardsecondary.spec.ts-snapshots/cardsecondary-focus-light-chromium-linux.png b/tests/cards/cardsecondary.spec.ts-snapshots/cardsecondary-focus-light-chromium-linux.png index d0297ffd31c6f8cc427d4d7409593319e981ce9d..ee814c3297c5418b55f0c31a633dafa235a09d86 100644 GIT binary patch literal 7656 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
S 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