Skip to content

Commit 9db91d6

Browse files
Never wrap a link card in an anchor when it carries a control of its own
1 parent 250a4f6 commit 9db91d6

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

web/components/links/resource-card.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ describe('ResourceCard', () => {
9191
expect(screen.getByText('at://did:plc:x/c/r').className).toContain('break-all');
9292
});
9393

94+
it('will not wrap a card that carries something interactive of its own', () => {
95+
// A button nested inside a link is not something a browser can represent.
96+
render(
97+
<ResourceCard icon={Github} title="Dataset" href="https://example.org">
98+
<button type="button">Load in Python</button>
99+
</ResourceCard>
100+
);
101+
expect(screen.queryByRole('link')).toBeNull();
102+
expect(screen.getByRole('button', { name: 'Load in Python' })).toBeInTheDocument();
103+
});
104+
94105
it('renders anything it is given below its own content', () => {
95106
render(
96107
<ResourceCard icon={Github} title="Dataset">

web/components/links/resource-card.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,10 @@ export function ResourceCard({
137137
children,
138138
className,
139139
}: ResourceCardProps) {
140-
const linkWraps = Boolean(href) && !actions?.length;
140+
// Wrapping the card in an anchor is only safe when nothing inside it is
141+
// interactive: a button nested in a link is not something a browser can
142+
// represent, and the dataset snippet a card can carry has one.
143+
const linkWraps = Boolean(href) && !actions?.length && !children;
141144

142145
const body = (
143146
<div className="flex items-start gap-3">

0 commit comments

Comments
 (0)