Skip to content

Commit 3968452

Browse files
committed
Cleanup
1 parent 04f5130 commit 3968452

5 files changed

Lines changed: 79 additions & 21 deletions

File tree

apps/next-docs/content/components/Card/react.mdx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ Use `ctaVariant="none"` when the card should remain fully clickable without visi
7272

7373
### Arrow CTA
7474

75-
Use `ctaVariant="arrow"` when the card should present an icon-only call to action instead of the default text-plus-arrow treatment.
75+
Use `ctaVariant="arrow"` for a compact call to action. On devices that support hover, the label is visually
76+
hidden until the Card is hovered or focused. On devices without hover, the label remains visible so the call
77+
to action does not rely on an unavailable interaction.
78+
79+
Set `disableAnimation` to `true` when CTA state changes should occur without animated transitions.
7680

7781
```jsx live
7882
<Card href="https://github.com" ctaVariant="arrow">
@@ -192,18 +196,18 @@ Use `Card.Tokens` to display more than one [Token](/components/Token).
192196

193197
### Card <Label>Required</Label>
194198

195-
| name | type | default | required | description |
196-
| ------------------ | -------------------------------------------------------------- | ------------ | -------- | ---------------------------------------------------------------- |
197-
| `align` | <PropTableValues values={['start', 'center']} addLineBreaks /> | `'start'` | `false` | Aligns the card content |
198-
| `backgroundColor` | <CardBackgroundColorsProp /> | `'default'` | `false` | Optional background color override for the card |
199-
| `ctaText` | `string` | `Learn more` | `false` | Label of the link at the bottom of the card |
200-
| `ctaVariant` | <CardCTAVariantsProp /> | `'text'` | `false` | Presentation of the call-to-action area |
201-
| `disableAnimation` | `boolean` | `false` | `false` | A flag to disable the default hover animation effect of the card |
202-
| `fullWidth` | `boolean` | `false` | `false` | A flag to optionally fill the width of the parent container |
203-
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the card |
204-
| `href` | `string` | | `true` | URL to the card content |
205-
| `leadingVisual` | `ReactElement` | | `false` | Logo or brand mark shown above the card content |
206-
| `variant` | <CardVariantsProp /> | `'default'` | `false` | The variant of the card |
199+
| name | type | default | required | description |
200+
| ------------------ | -------------------------------------------------------------- | ------------ | -------- | ----------------------------------------------------------- |
201+
| `align` | <PropTableValues values={['start', 'center']} addLineBreaks /> | `'start'` | `false` | Aligns the card content |
202+
| `backgroundColor` | <CardBackgroundColorsProp /> | `'default'` | `false` | Optional background color override for the card |
203+
| `ctaText` | `string` | `Learn more` | `false` | Label of the link at the bottom of the card |
204+
| `ctaVariant` | <CardCTAVariantsProp /> | `'text'` | `false` | Presentation of the call-to-action area |
205+
| `disableAnimation` | `boolean` | `false` | `false` | Disables transitions and animations within the Card |
206+
| `fullWidth` | `boolean` | `false` | `false` | A flag to optionally fill the width of the parent container |
207+
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the card |
208+
| `href` | `string` | | `true` | URL to the card content |
209+
| `leadingVisual` | `ReactElement` | | `false` | Logo or brand mark shown above the card content |
210+
| `variant` | <CardVariantsProp /> | `'default'` | `false` | The variant of the card |
207211

208212
### Card.Image
209213

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {expect, test} from '@playwright/test'
2+
3+
const ArrowCTAStory =
4+
'http://localhost:6006/iframe.html?args=&id=components-card-features--arrow-cta-long-label&viewMode=story'
5+
6+
// eslint-disable-next-line i18n-text/no-en
7+
test.describe('Card interaction behavior', () => {
8+
test('keeps the arrow CTA label visible on non-hover devices', async ({context, page}) => {
9+
const client = await context.newCDPSession(page)
10+
11+
await client.send('Emulation.setTouchEmulationEnabled', {enabled: true, maxTouchPoints: 1})
12+
await client.send('Emulation.setEmulatedMedia', {
13+
features: [
14+
{name: 'hover', value: 'none'},
15+
{name: 'any-hover', value: 'none'},
16+
{name: 'pointer', value: 'coarse'},
17+
{name: 'any-pointer', value: 'coarse'},
18+
],
19+
})
20+
await page.setViewportSize({width: 375, height: 812})
21+
await page.goto(ArrowCTAStory, {waitUntil: 'networkidle'})
22+
23+
const action = page.locator('[class*="Card__action--arrowOnly"]').first()
24+
const label = action.locator('[class*="Card__actionLabel__"]')
25+
const labelClip = action.locator('[class*="Card__actionLabelClip__"]')
26+
27+
await expect(label).toBeVisible()
28+
await expect(action).toHaveCSS('column-gap', '8px')
29+
await expect(label).toHaveCSS('white-space', 'normal')
30+
await expect(labelClip).toHaveCSS('display', 'contents')
31+
expect(await page.evaluate(() => window.matchMedia('(hover: none)').matches)).toBe(true)
32+
})
33+
34+
test('disables the remaining Card transitions and animations', async ({page}) => {
35+
await page.goto(
36+
'http://localhost:6006/iframe.html?args=&id=components-card-features--with-inline-code-element&viewMode=story',
37+
{waitUntil: 'networkidle'},
38+
)
39+
40+
const card = page.locator('[class*="Card--disableAnimation"]').first()
41+
const action = card.locator('[class*="Card__action__"]')
42+
const arrow = action.locator('[class*="Card--expandableArrow"]')
43+
44+
await card.hover()
45+
46+
await expect(card).toHaveCSS('transition-duration', '0s')
47+
await expect(action).toHaveCSS('transition-duration', '0s')
48+
await expect(arrow).toHaveCSS('transition-duration', '0s')
49+
})
50+
})

packages/react/src/Card/Card.module.css

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@
214214
text-decoration: underline !important;
215215
}
216216

217+
.Card--disableAnimation,
218+
.Card--disableAnimation * {
219+
animation: none;
220+
transition: none;
221+
}
222+
217223
/* The focus outline will appear around the entire card, not just the title */
218224
.Card__link:focus {
219225
outline: none;
@@ -485,10 +491,6 @@
485491
margin-bottom: var(--base-size-12);
486492
}
487493

488-
.Card--ctaVariant-arrow:not(.Card--disableAnimation):hover {
489-
transform: none;
490-
}
491-
492494
.Card--ctaVariant-arrow .Card__action {
493495
min-inline-size: 0;
494496
justify-self: start;

packages/react/src/Card/Card.stories.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ const meta = {
8989
},
9090
},
9191
ctaText: {
92-
description: 'Visible CTA text when `ctaVariant="text"` is used.',
92+
description:
93+
'CTA label. With `ctaVariant="arrow"`, it is revealed on hover or focus and remains visible on non-hover devices.',
9394
control: {
9495
type: 'text',
9596
},
@@ -136,14 +137,15 @@ const meta = {
136137
},
137138
},
138139
ctaVariant: {
139-
description: 'Presentation of the Card call-to-action.',
140+
description:
141+
'Presentation of the Card call-to-action. The arrow variant keeps its label visible on non-hover devices.',
140142
control: {
141143
type: 'inline-radio',
142144
},
143145
options: [...CardCTAVariants],
144146
},
145147
disableAnimation: {
146-
description: 'Disable the default hover animation.',
148+
description: 'Disable transitions and animations within the Card.',
147149
control: {
148150
type: 'boolean',
149151
},

packages/react/src/Card/Card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export type CardProps = {
6060
| React.ReactElement<CardHeadingProps>
6161
| React.ReactElement<CardDescriptionProps>
6262
/**
63-
* Disable the default hover animation
63+
* Disable transitions and animations within the Card
6464
*/
6565
disableAnimation?: boolean
6666
/**

0 commit comments

Comments
 (0)