A clickable card component featuring an icon (top-left) and label text with arrow (bottom). Supports two color variants with responsive sizing that adapts at breakpoints.
- Two Color Variants: Neutral (gray) and Green
- Five Interaction States: Default, Hover, Focused, Pressed, Disabled
- Responsive Sizing: Automatically adapts at SM/MD/LG breakpoints
- Window Shade Animation: Smooth hover effect with color wipe
- Accessible: Full keyboard navigation and ARIA support
- Flexible Rendering: Renders as
<a>or<button>based on props
The component automatically adapts its dimensions based on viewport width:
| Breakpoint | Height | Icon Size | Padding |
|---|---|---|---|
| SM (< 576px) | 136px | 56x56 | 8px |
| MD (576px - 991px) | 140px | 60x60 | 12px |
| LG (>= 992px) | 144px | 64x64 | 16px |
- Default: Gray 200 (#E6EAF0) - black text
- Hover: Gray 300 (#CAD4DF) - black text
- Focused: Gray 300 + 2px black border - black text
- Pressed: Gray 400 (#8A919A) - black text
- Disabled: Gray 100 (#F0F3F7) - muted text (Gray 400), 50% icon opacity
- Default: Green 200 (#70EE97) - black text
- Hover: Green 300 (#21E46B) - black text
- Focused: Green 300 + 2px black border - black text
- Pressed: Green 400 (#0DAA3E) - black text
- Disabled: Green 100 (#EAFCF1) - muted text (Gray 400), 50% icon opacity
- Default: Gray 500 (#72777E) - white text; icons forced white (
filter) - Hover: Gray 400 (#8A919A) - white text
- Focused: Gray 400 overlay + 2px white focus outline - white text
- Pressed:
$gray-500-pressed-dark(#56595E) — neutral/500 (#72777E) with 70% black tint - Disabled: Gray 500 at 30% opacity - white text; icons stay white (same filter)
- Default: Green 300 (#21E46B) - black text
- Hover: Green 200 (#70EE97) - black text
- Focused: Green 200 overlay + 2px white focus outline - black text
- Pressed: Green 400 (#0DAA3E) - black text
- Disabled: Gray 500 at 30% opacity - white text; icon forced white for contrast
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'neutral' | 'green' | 'neutral' | Color variant |
icon | string | required | Icon image source (URL or path) |
iconAlt | string | '' | Alt text for the icon image |
label | string | required | Card label text |
href | string | - | Link destination (renders as <a>) |
onClick | () => void | - | Click handler (renders as <button>) |
disabled | boolean | false | Disabled state |
className | string | '' | Additional CSS classes |
import { CardIcon } from '@/shared/components/CardIcon';
<CardIcon
variant="neutral"
icon="/icons/javascript.svg"
iconAlt="JavaScript logo"
label="Get Started with Javascript"
href="/docs/tutorials/javascript"
/><CardIcon
variant="green"
icon="/icons/python.svg"
iconAlt="Python logo"
label="Python Tutorial"
onClick={() => openTutorial('python')}
/><CardIcon
variant="neutral"
icon="/icons/coming-soon.svg"
label="Coming Soon"
disabled
/>import { PageGrid, PageGridItem } from '@/shared/components/PageGrid';
import { CardIcon } from '@/shared/components/CardIcon';
<PageGrid>
<PageGridItem colSpan={{ sm: 2, md: 4, lg: 3 }}>
<CardIcon
variant="neutral"
icon="/icons/javascript.svg"
label="JavaScript"
href="/docs/javascript"
/>
</PageGridItem>
<PageGridItem colSpan={{ sm: 2, md: 4, lg: 3 }}>
<CardIcon
variant="green"
icon="/icons/python.svg"
label="Python"
href="/docs/python"
/>
</PageGridItem>
</PageGrid>- Uses semantic
<a>or<button>elements based on interaction type - Includes
aria-labelfor screen readers - Supports keyboard navigation (Tab, Enter, Space)
- Focus states meet WCAG 2.1 AA contrast requirements
- Disabled state includes
aria-disabledattribute
| Class | Description |
|---|---|
.bds-card-icon | Base card styles |
.bds-card-icon--neutral | Neutral color variant |
.bds-card-icon--green | Green color variant |
.bds-card-icon--hovered | Hover state (JS-controlled) |
.bds-card-icon--disabled | Disabled state |
.bds-card-icon__overlay | Hover animation overlay |
.bds-card-icon__icon | Icon container |
.bds-card-icon__icon-img | Icon image |
.bds-card-icon__content | Bottom content row |
.bds-card-icon__label | Text label |
.bds-card-icon__arrow | Arrow icon wrapper |
The component uses these design tokens from the style system:
- Colors:
$gray-100through$gray-400,$green-100through$green-400 - Typography:
body-rtoken from_font.scss - Breakpoints:
$grid-breakpointsfrom_breakpoints.scss - Animation:
cubic-bezier(0.98, 0.12, 0.12, 0.98)timing function